cleaning up resources after requests

Sat, 12 Jan 2013 14:00:47 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 12 Jan 2013 14:00:47 +0100
changeset 46
636e05eb48f6
parent 45
a24aa388f02f
child 47
ce9790523346

cleaning up resources after requests

Makefile file | annotate | diff | comparison | revisions
make/install.mk file | annotate | diff | comparison | revisions
src/server/config/serverconf.c file | annotate | diff | comparison | revisions
src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/event.h file | annotate | diff | comparison | revisions
src/server/daemon/event_linux.c file | annotate | diff | comparison | revisions
src/server/daemon/event_solaris.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.h file | annotate | diff | comparison | revisions
src/server/daemon/session.c file | annotate | diff | comparison | revisions
src/server/daemon/session.h file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.c file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.h file | annotate | diff | comparison | revisions
src/server/util/io.c file | annotate | diff | comparison | revisions
src/server/util/io.h file | annotate | diff | comparison | revisions
--- a/Makefile	Wed Jan 02 16:03:50 2013 +0100
+++ b/Makefile	Sat Jan 12 14:00:47 2013 +0100
@@ -43,6 +43,12 @@
 	@echo "clean build"
 	rm -f -R build
 
+cleanall:
+	@echo "clean all"
+	rm -f -R build
+	rm -f -R work
+	rm -f config.mk
+
 install: all
 	cd make; $(MAKE) -f install.mk install
 
--- a/make/install.mk	Wed Jan 02 16:03:50 2013 +0100
+++ b/make/install.mk	Sat Jan 12 14:00:47 2013 +0100
@@ -55,6 +55,6 @@
 	sed s:%%WS_INSTALL_DIR%%:$(INSTALL_DIR):g ../templates/bin/stopserv.template > $(INSTALL_DIR)/bin/stopserv
 	chmod +x $(INSTALL_DIR)/bin/stopserv
 	sed s:%%WS_INSTALL_DIR%%:$(INSTALL_DIR):g ../templates/bin/reconfig.template > $(INSTALL_DIR)/bin/reconfig
-	chmod -x $(INSTALL_DIR)/bin/reconfig
+	chmod +x $(INSTALL_DIR)/bin/reconfig
 	@echo "copy docs"
 	cp -R ../templates/docs $(INSTALL_DIR)/
--- a/src/server/config/serverconf.c	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/config/serverconf.c	Sat Jan 12 14:00:47 2013 +0100
@@ -44,7 +44,7 @@
     conf->objects = ucx_map_new(161);
     
     conf->obj = NULL;
-
+    
     int r = cfg_parse_basic_file((ConfigParser*)conf, in);
     if(r != 0) {
         // TODO: free
@@ -60,7 +60,7 @@
 
 int serverconf_parse(void *p, ConfigLine *begin, ConfigLine *end, sstr_t line){
     ServerConfig *conf = p;
-
+    
     begin->type = cfg_get_line_type(line);
     switch(begin->type) {
         case LINE_BEGIN_TAG: {
--- a/src/server/daemon/config.c	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/config.c	Sat Jan 12 14:00:47 2013 +0100
@@ -113,7 +113,7 @@
     if(serverconf == NULL) {
         fprintf(stderr, "Cannot load server.conf\n");
     }
-    ServerConfiguration *serverconfig = malloc(sizeof(ServerConfiguration));
+    ServerConfiguration *serverconfig = calloc(1, sizeof(ServerConfiguration));
     serverconfig->ref = 1;
     serverconfig->pool = pool_create();
     serverconfig->listeners = NULL;
@@ -153,7 +153,7 @@
         /* horrible error */
         return NULL;
     }
-    
+     
     UcxList *list = ucx_map_sstr_get(serverconf->objects, sstrn("Runtime", 7));
     UCX_FOREACH(UcxList*, list, elm) {
         ServerConfigObject *scfgobj = elm->data;
--- a/src/server/daemon/event.h	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/event.h	Sat Jan 12 14:00:47 2013 +0100
@@ -46,6 +46,7 @@
     Session      *sn;
     Request      *rq;
     event_func   fn;
+    event_func   finish;
     intptr_t     object;
     int          events;
     void         *cookie;
--- a/src/server/daemon/event_linux.c	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/event_linux.c	Sat Jan 12 14:00:47 2013 +0100
@@ -116,6 +116,11 @@
                     if(epoll_ctl(ep, EPOLL_CTL_DEL, event->object, NULL)) {
                         perror("epoll_ctl");
                     }
+                    
+                    // if set, execute event->finish
+                    if(event->finish) {
+                        event->finish(ev, event);
+                    }
                 }
             }
         }
--- a/src/server/daemon/event_solaris.c	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/event_solaris.c	Sat Jan 12 14:00:47 2013 +0100
@@ -112,6 +112,8 @@
                      if(ev_poll(ev, event)) {
                          perror("port_associate");
                      }                 
+                } else if(event->finish) {
+                    event->finish(ev, event);
                 }
             }
         }
--- a/src/server/daemon/httplistener.c	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/httplistener.c	Sat Jan 12 14:00:47 2013 +0100
@@ -281,8 +281,8 @@
 
         /* ready for new connection */
         
-        // this acceptor is outdated
         if(acceptor_exit) {
+            // this acceptor is outdated
             break;
         }
     }
--- a/src/server/daemon/httprequest.c	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/httprequest.c	Sat Jan 12 14:00:47 2013 +0100
@@ -42,8 +42,7 @@
 #include "httplistener.h"
 #include "error.h"
 
-HTTPRequest *http_request_new() {
-    HTTPRequest *req = malloc(sizeof(HTTPRequest));
+void http_request_init(HTTPRequest *req) {
     req->connection = NULL;
     req->uri.ptr = NULL;
 
@@ -54,22 +53,20 @@
     hd->alloc = 16;
 
     req->headers = hd;
-
-    return req;
 }
 
 int handle_request(HTTPRequest *request, threadpool_t *thrpool) {
     // handle nsapi request
 
     // create pool
-    request->pool = pool_create();
+    pool_handle_t *pool = pool_create();
 
     // create nsapi data structures
-    NSAPISession *sn = malloc(sizeof(NSAPISession));
+    NSAPISession *sn = pool_malloc(pool, sizeof(NSAPISession));
     if(sn == NULL) {
         /* TODO: error */
     }
-    NSAPIRequest *rq = malloc(sizeof(NSAPIRequest));
+    NSAPIRequest *rq = pool_malloc(pool, sizeof(NSAPIRequest));
     if(rq == NULL) {
         /* TODO: error */
     }
@@ -77,9 +74,10 @@
     rq->phase = NSAPIAuthTrans;
 
     // fill session structure
-    sn->sys_fd = request->connection->fd;
-    sn->sn.pool = pool_create();
-    sn->sn.csd = stream_new_from_fd(request->connection->fd);
+    sn->connection = request->connection;
+    sn->netbuf = request->netbuf;
+    sn->sn.pool = pool;
+    sn->sn.csd = stream_new_from_fd(pool, request->connection->fd);
     sn->sn.client = pblock_create_pool(sn->sn.pool, 8);
     sn->sn.next = NULL;
     sn->sn.fill = 1;
@@ -88,7 +86,7 @@
     // the session needs the current server configuration
     sn->config = request->connection->listener->cfg; // TODO: ref
 
-    /* add ip to sn->client pblock */
+    // add ip to sn->client pblock
     char ip_str[INET_ADDRSTRLEN];
     if(inet_ntop(
             AF_INET,
@@ -100,7 +98,7 @@
     }
 
     // init NSAPI request structure
-    if(request_initialize(request->pool, request, rq) != 0) {
+    if(request_initialize(pool, request, rq) != 0) {
         printf("Cannot initialize request structure\n");
         return 1;
     }
@@ -108,9 +106,8 @@
     // set default virtual server
     rq->vs = request->connection->listener->default_vs.vs;
 
-    /* Pass request line as "clf-request" */
-    /* TODO: with or without \r\n ? */
-    // hack to remove \r\n 
+    // Pass request line as "clf-request"
+    // remove \r\n 
     sstr_t clfreq = request->request_line;
     while(clfreq.ptr[clfreq.length - 1] < 33) {
         clfreq.length--;
@@ -170,7 +167,7 @@
     
     /* Get abs_path part of request URI, and canonicalize the path */
     absPath.ptr = util_canonicalize_uri(
-            request->pool,
+            pool,
             absPath.ptr,
             absPath.length,
             (int*)&absPath.length);
@@ -202,7 +199,7 @@
             ha->headers[i].name[0] += 32;
         }
 
-        /* change to lower case */
+        // change to lower case
         char *header_name = ha->headers[i].name;
         for(int i=0;header_name[i]!=0;i++) {
             if(header_name[i] > 64 && header_name[i] < 97) {
@@ -216,7 +213,7 @@
                 rq->rq.headers);
     }
        
-    /* check for request body and prepare input buffer */
+    // check for request body and prepare input buffer
     char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers);
     if(ctlen_str) {
         int ctlen = atoi(ctlen_str);
@@ -227,14 +224,15 @@
 
         /* create new netbuf */
         NetIOStream *net_io = (NetIOStream*)net_stream_from_fd(
+                pool,
                 request->connection->fd);
         net_io->max_read = ctlen;
         
-        sn->sn.inbuf = malloc(sizeof(netbuf));
+        sn->sn.inbuf = pool_malloc(pool, sizeof(netbuf));
         sn->sn.inbuf->sd = net_io;
         sn->sn.inbuf->pos = 0;
         
-        /* prepare buffer */
+        // prepare buffer
         int cur_input_len = nb->cursize - nb->pos;
         
         if(cur_input_len >= ctlen) {
@@ -247,10 +245,10 @@
             sn->sn.inbuf->inbuf = nb->inbuf + nb->pos;
         } else {
             sn->sn.inbuf->maxsize = (ctlen > 2048) ? (2048) : (ctlen);
-            sn->sn.inbuf->inbuf = malloc(sn->sn.inbuf->maxsize);
+            sn->sn.inbuf->inbuf = pool_malloc(pool, sn->sn.inbuf->maxsize);
 
             if(cur_input_len > 0) {
-                /* we have read a part of the request body -> copy to netbuf */
+                // we have read a part of the request body -> copy to netbuf
                 memcpy(sn->sn.inbuf->inbuf, nb->inbuf+nb->pos, cur_input_len);
             }
 
@@ -297,6 +295,16 @@
     hd->len++;
 }
 
+void header_array_free(HeaderArray *hd) {
+    HeaderArray *next;
+    while(hd) {
+        next = hd->next;
+        free(hd->headers);
+        free(hd);
+        hd = next;
+    }
+}
+
 
 /*
  * NSAPI Processing
@@ -383,8 +391,17 @@
 }
 
 int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq) {
-    // TODO: free memory
-    close(sn->sys_fd);
+    // TODO: keep alive
+    close(sn->connection->fd);
+    
+    // free all memory
+    free(sn->connection);
+    
+    free(sn->netbuf->inbuf);
+    free(sn->netbuf);
+    
+    pool_destroy(sn->sn.pool);
+    
 
     return 0;
 }
--- a/src/server/daemon/httprequest.h	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/httprequest.h	Sat Jan 12 14:00:47 2013 +0100
@@ -52,9 +52,8 @@
     sstr_t         httpv;
     HeaderArray    *headers;
     netbuf         *netbuf;
-    NSAPISession   *sn;
-    NSAPIRequest   *rq;
-    pool_handle_t  *pool;
+    NSAPISession   *sn; // TODO: remove
+    NSAPIRequest   *rq; // TODO: remove
 };
 
 struct _header {
@@ -69,7 +68,8 @@
     int         alloc;
 };
 
-HTTPRequest *http_request_new();
+void http_request_init(HTTPRequest *req);
+void http_request_cleanup(HTTPRequest *req);
 
 /*
  * starts request processing after reading the request header
@@ -82,6 +82,7 @@
 
 
 void header_add(HeaderArray *hd, char *name, char *value);
+void header_array_free(HeaderArray *hd);
 
 int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq);
 int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq);
--- a/src/server/daemon/session.c	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/session.c	Sat Jan 12 14:00:47 2013 +0100
@@ -35,7 +35,7 @@
     return NULL;
 }
 
-
+// new
 NSAPI_PUBLIC void* session_get_config(Session *s) {
     NSAPISession *sn = (NSAPISession*)s;
     return sn->config;
--- a/src/server/daemon/session.h	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/session.h	Sat Jan 12 14:00:47 2013 +0100
@@ -32,6 +32,7 @@
 #include "../public/nsapi.h"
 #include "../util/thrpool.h"
 #include "config.h"
+#include "sessionhandler.h"
 
 #ifdef	__cplusplus
 extern "C" {
@@ -41,7 +42,8 @@
 
 struct NSAPISession {
     Session      sn; /* public session structure */
-    int          sys_fd; /* system file descriptor */
+    Connection   *connection;
+    netbuf       *netbuf;
     threadpool_t *currentpool;
     threadpool_t *defaultpool;
     
--- a/src/server/daemon/sessionhandler.c	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/sessionhandler.c	Sat Jan 12 14:00:47 2013 +0100
@@ -58,8 +58,9 @@
 void* basic_run_session(void *data) {
     Connection *conn = (Connection*)data;
 
-    HTTPRequest *request = http_request_new();
-    request->connection = conn;
+    HTTPRequest request;
+    http_request_init(&request);
+    request.connection = conn;
 
     // read request
     netbuf *buf = malloc(sizeof(netbuf));
@@ -71,9 +72,9 @@
     buf->inbuf = malloc(2048);
     buf->errmsg = NULL;
 
-    request->netbuf = buf;
+    request.netbuf = buf;
 
-    HttpParser *parser = http_parser_new(request);
+    HttpParser *parser = http_parser_new(&request);
     int state;
     int r;
     r = read(conn->fd, buf->inbuf + buf->pos, buf->maxsize - buf->pos);
@@ -99,8 +100,9 @@
     }
 
     // process request
-    r = handle_request(request, NULL); // TODO: use correct thread pool
-
+    r = handle_request(&request, NULL); // TODO: use correct thread pool
+    
+    // TODO: free, see evt_request_finish
 
     return NULL;
 }
@@ -115,8 +117,10 @@
 }
 
 void evt_enq_conn(SessionHandler *handler, Connection *conn) {
-    HTTPRequest *request = http_request_new();
+    HTTPRequest *request = malloc(sizeof(HTTPRequest));
+    http_request_init(request);
     request->connection = conn;
+    conn->session_handler = handler;
     
     // set socket non blocking
     int flags;
@@ -161,6 +165,7 @@
     
     event_t *event = malloc(sizeof(event_t));
     event->fn = evt_request_input;
+    event->finish = evt_request_finish;
     event->cookie = io;
     
     if(ev_pollin(ev, conn->fd, event) != 0) {
@@ -211,9 +216,37 @@
         perror("Error: evt_request_input: fcntl");
         // TODO: critical error
     }
+     
+    /*
+     * process request
+     * 
+     * We return 0 to finish request input. The event handler than stops
+     * polling and executes event->finish (evt_request_input_finish)
+     */
+    return 0;
+}
+
+int evt_request_finish(event_handler_t *h, event_t *event) {
+    EventHttpIO *io = event->cookie;
+    HttpParser  *parser  = io->parser;
+    HTTPRequest *request = io->request;
     
-    // process request
-    r = handle_request(request, NULL);
+    int r = handle_request(request, NULL);
+    // TODO: if r != REQ_PROCEED ...
     
-    return 0; // TODO: return before handle_request
+    /*
+     * handle_request can return before the request is finished, but it copies
+     * all important data. We can free request, parser and event
+     * 
+     * don't free request->netbuf and request->connection
+     */
+    header_array_free(request->headers);
+    free(request);
+    
+    http_parser_free(parser);
+    
+    free(io);
+    free(event);
+    
+    return 0;
 }
--- a/src/server/daemon/sessionhandler.h	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/daemon/sessionhandler.h	Sat Jan 12 14:00:47 2013 +0100
@@ -93,6 +93,7 @@
 void evt_enq_conn(SessionHandler *handler, Connection *conn);
 
 int evt_request_input(event_handler_t *h, event_t *event);
+int evt_request_finish(event_handler_t *h, event_t *event);
 
 
 #ifdef	__cplusplus
--- a/src/server/util/io.c	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/util/io.c	Sat Jan 12 14:00:47 2013 +0100
@@ -50,8 +50,8 @@
 };
 
 
-IOStream* stream_new_from_fd(int fd) {
-    SystemIOStream *st = malloc(sizeof(SystemIOStream));
+IOStream* stream_new_from_fd(pool_handle_t *pool, int fd) {
+    SystemIOStream *st = pool_malloc(pool, sizeof(SystemIOStream));
     st->st = native_io_funcs;
     st->fd = fd;
     return (IOStream*)st;
@@ -66,8 +66,8 @@
 }
 
 
-IOStream* net_stream_from_fd(int fd) {
-    NetIOStream *st = malloc(sizeof(NetIOStream));
+IOStream* net_stream_from_fd(pool_handle_t *pool, int fd) {
+    NetIOStream *st = pool_malloc(pool, sizeof(NetIOStream));
     st->st = net_io_funcs;
     st->fd = fd;
     st->max_read = 0;
--- a/src/server/util/io.h	Wed Jan 02 16:03:50 2013 +0100
+++ b/src/server/util/io.h	Sat Jan 12 14:00:47 2013 +0100
@@ -73,13 +73,13 @@
 
 
 /* system stream */
-IOStream* stream_new_from_fd(int fd);
+IOStream* stream_new_from_fd(pool_handle_t *pool, int fd);
 
 ssize_t system_write(IOStream *st, void *buf, size_t nbytes);
 ssize_t system_read(IOStream *st, void *buf, size_t nbytes);
 
 /* net stream */
-IOStream* net_stream_from_fd(int fd);
+IOStream* net_stream_from_fd(pool_handle_t *pool, int fd);
 
 ssize_t net_stream_write(IOStream *st, void *buf, size_t nbytes);
 ssize_t net_stream_read(IOStream *st, void *buf, size_t nbytes);

mercurial