--- 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