src/server/daemon/httprequest.c

changeset 37
360b9aabe17e
parent 36
450d2d5f4735
child 38
d07810b02147
--- a/src/server/daemon/httprequest.c	Sat Oct 06 13:00:07 2012 +0200
+++ b/src/server/daemon/httprequest.c	Sat Dec 15 16:05:03 2012 +0100
@@ -57,7 +57,7 @@
     return req;
 }
 
-int handle_request(HTTPRequest *request) {
+int handle_request(HTTPRequest *request, threadpool_t *thrpool) {
     // handle nsapi request
 
     // create pool
@@ -250,9 +250,20 @@
         sn->sn.inbuf = NULL;
     }
     
-    
+    //
     // Send the request to the NSAPI system
-    nsapi_handle_request(sn, rq);
+    //
+    
+    // compare current and listener thread pool
+    threadpool_t *lstp = request->connection->listener->threadpool;
+    sn->defaultpool = lstp;
+    if(lstp == thrpool) {
+        sn->currentpool = thrpool;
+        nsapi_handle_request(sn, rq);
+    } else {
+        // execute nsapi functions on a different thread pool
+        nsapi_change_threadpool(sn, rq, lstp);
+    }
 
     return 0;
 }
@@ -283,8 +294,6 @@
  */
 
 int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq) {
-    // TODO: threadpool
-
     int r = REQ_NOACTION;
 
     do {
@@ -350,7 +359,9 @@
         
     } while (r == REQ_RESTART);
 
-    r = nsapi_finish_request(sn, rq);
+    if(r != REQ_PROCESSING) {
+        r = nsapi_finish_request(sn, rq);
+    }
 
     return r;
 }
@@ -375,9 +386,11 @@
 
     int ret = rq->context.last_req_code;
     for(int i=NCX_DI(rq);i<dt->ndir;i++) {
-        directive *d = dt->dirs[i];
-
-        ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
+        if(ret == REQ_NOACTION) {
+            directive *d = dt->dirs[i];
+            ret = nsapi_exec(d, sn, rq);
+        }
+        
         if(ret != REQ_NOACTION) {
             /*
              * if a saf is still processing, we need to save the context, to
@@ -413,9 +426,10 @@
     char *name = NULL;
     char *ppath = NULL;
     for(int i=NCX_DI(rq);i<dt->ndir;i++) {
-        directive *d = dt->dirs[i];
-
-        ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
+        if(ret == REQ_NOACTION) {
+            directive *d = dt->dirs[i];
+            ret = nsapi_exec(d, sn, rq);
+        }
 
         /* check for name or ppath */
         name = pblock_findkeyval(pb_key_name, rq->rq.vars);
@@ -486,11 +500,12 @@
         dtable *dt = object_get_dtable(obj, NSAPIPathCheck);
 
         // execute directives
-        for(int j=0;j<dt->ndir;j++) {
-            directive *d = dt->dirs[j];   
-
-            /* execute the saf */
-            ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
+        for(int j=NCX_DI(rq);j<dt->ndir;j++) {
+            if(ret == REQ_NOACTION) {
+                directive *d = dt->dirs[j];
+                ret = nsapi_exec(d, sn, rq);
+            }
+            
             if(ret != REQ_NOACTION) {
                 if(ret == REQ_PROCESSING) {
                     /* save nsapi context */
@@ -528,10 +543,12 @@
         dtable *dt = object_get_dtable(obj, NSAPIObjectType);
 
         // execute directives
-        for(int j=0;j<dt->ndir;j++) {
-            directive *d = dt->dirs[j];
-
-            ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
+        for(int j=NCX_DI(rq);j<dt->ndir;j++) {
+            if(ret == REQ_NOACTION) {
+                directive *d = dt->dirs[j];
+                ret = nsapi_exec(d, sn, rq);
+            }
+            
             switch(ret) {
                 case REQ_PROCEED: {
                     char *type = pblock_findkeyval(
@@ -596,38 +613,42 @@
         dtable *dt = object_get_dtable(obj, NSAPIService);
 
         // execute directives
-        for(int j=0;j<dt->ndir;j++) {
-            directive *d = dt->dirs[j];
+        for(int j=NCX_DI(rq);j<dt->ndir;j++) {
+            if(ret == REQ_NOACTION) {
+                directive *d = dt->dirs[j];
 
-            /* check type parameter */           
-            char *dtp = pblock_findkeyval(pb_key_type, d->param);
-            if(dtp) {
-                /* type parameter for directive */
-                if(!content_type) {
-                    content_type = pblock_findkeyval(
-                            pb_key_content_type,
-                            rq->rq.srvhdrs);
-                }
-                /* compare types */
-                if(strcmp(dtp, content_type) != 0) {
-                    continue;
-                }
-            }
-
-            /* check method parameter */
-            char *dmt = pblock_findkeyval(pb_key_method, d->param);
-            if(dmt) {
-                if(!method) {
-                    method = pblock_findkeyval(pb_key_method, rq->rq.reqpb);
+                /* check type parameter */           
+                char *dtp = pblock_findkeyval(pb_key_type, d->param);
+                if(dtp) {
+                    /* type parameter for directive */
+                    if(!content_type) {
+                        content_type = pblock_findkeyval(
+                                pb_key_content_type,
+                                rq->rq.srvhdrs);
+                    }
+                    /* compare types */
+                    if(strcmp(dtp, content_type) != 0) {
+                        continue;
+                    }
                 }
 
-                if(!method_match(dmt, method)) {
-                    continue;
+                /* check method parameter */
+                char *dmt = pblock_findkeyval(pb_key_method, d->param);
+                if(dmt) {
+                    if(!method) {
+                        method = pblock_findkeyval(pb_key_method, rq->rq.reqpb);
+                    }
+                    
+                    if(!method_match(dmt, method)) {
+                        continue;
+                    }
                 }
+
+                /* execute the saf */
+                ret = nsapi_exec(d, sn, rq);
             }
-
-            /* execute the saf */
-            ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
+            
+            
             if(ret != REQ_PROCEED) {
                 fprintf(stderr, "saf not proceed\n");
             }
@@ -648,6 +669,105 @@
     return ret;
 }
 
+struct _tpd_data {
+    NSAPISession *sn;
+    NSAPIRequest *rq;
+    directive    *directive;
+    threadpool_t *threadpool;
+};
+
+int nsapi_exec(directive *d, NSAPISession *sn, NSAPIRequest *rq) {
+    // TODO: condition
+    
+    char *poolname = pblock_findkeyval(pb_key_pool, d->param);
+    if(poolname) {
+        threadpool_t *pool = get_threadpool(sstr(poolname));
+        if(pool && pool != sn->currentpool) {
+            // execute directive in different thread pool
+            return nsapi_exec_tp(d, sn, rq, pool);
+        }
+    } else if(sn->currentpool != sn->defaultpool) {
+        // if no pool is set, use always the default thread pool
+        return nsapi_exec_tp(d, sn, rq, sn->defaultpool);
+    }
+    
+    return d->func->func(d->param, (Session*)sn, (Request*)rq);
+}
+
+int nsapi_exec_tp(
+        directive *d,
+        NSAPISession *sn,
+        NSAPIRequest *rq,
+        threadpool_t *pool)
+{
+    struct  _tpd_data *data = malloc(sizeof(struct _tpd_data));
+    if(data == NULL) {
+        // TODO: set error
+        return REQ_ABORTED;
+    }
+    data->sn = sn;
+    data->rq = rq;
+    data->directive  = d;
+    data->threadpool = pool;
+    
+    sn->currentpool = pool;
+    threadpool_run(pool, thrpool_exec, data);
+    
+    return REQ_PROCESSING;
+}
+
+void nsapi_function_return(Session *session, Request *request, int ret) {
+    NSAPISession *sn = (NSAPISession*)session;
+    NSAPIRequest *rq = (NSAPIRequest*)request;
+    
+    rq->context.last_req_code = ret;
+    
+    if(sn->currentpool != sn->defaultpool) {
+        nsapi_change_threadpool(sn, rq, sn->defaultpool);
+    } else {
+        nsapi_handle_request(sn, rq);
+    }
+}
+
+void nsapi_change_threadpool(
+        NSAPISession *sn,
+        NSAPIRequest *rq,
+        threadpool_t *thrpool)
+{ 
+    struct  _tpd_data *data = malloc(sizeof(struct _tpd_data));
+    data->sn = sn;
+    data->rq = rq;
+    data->threadpool = thrpool;
+    
+    threadpool_run(thrpool, thrpool_change, data);
+}
+
+void* thrpool_exec(void *d) {
+    struct _tpd_data *data = d;
+    
+    data->sn->currentpool = data->threadpool;
+    int r = data->directive->func->func(
+            data->directive->param,
+            (Session*)data->sn,
+            (Request*)data->rq);
+    
+    free(data);
+    
+    nsapi_function_return((Session*)data->sn, (Request*)data->rq, r);
+    
+    return NULL;
+}
+
+void* thrpool_change(void *d) {
+    struct _tpd_data *data = d;
+    
+    data->sn->currentpool = data->threadpool;
+    nsapi_handle_request(data->sn, data->rq);
+    
+    free(data);
+    return NULL;
+}
+
 
 /*
  * checks if the method matches the cmp string

mercurial