in src/mod_rivet_ng/rivet_lazy_mpm.c [359:422]
int LazyBridge_Request (request_rec* r,rivet_req_ctype ctype)
{
lazy_tcl_worker* w;
int ap_sts;
rivet_server_conf* conf = RIVET_SERVER_CONF(r->server->module_config);
apr_array_header_t* array;
apr_thread_mutex_t* mutex;
mutex = module_globals->mpm->vhosts[conf->idx].mutex;
array = module_globals->mpm->vhosts[conf->idx].array;
apr_thread_mutex_lock(mutex);
/* This request may have come while the child process was
* shutting down. We cannot run the risk that incoming requests
* may hang the child process by keeping its threads busy,
* so we simply return an HTTP_INTERNAL_SERVER_ERROR.
* This is hideous and explains why the 'exit' commands must
* be avoided at any costs when programming with mod_rivet
*/
if (module_globals->mpm->server_shutdown == 1)
{
ap_log_rerror(APLOG_MARK,APLOG_ERR,APR_EGENERAL,r,
MODNAME ": http request aborted during child process shutdown");
apr_thread_mutex_unlock(mutex);
return HTTP_INTERNAL_SERVER_ERROR;
}
/* If the array is empty we create a new worker thread */
if (apr_is_empty_array(array))
{
w = create_worker(module_globals->pool,r->server);
}
else
{
w = *(lazy_tcl_worker**) apr_array_pop(array);
}
apr_thread_mutex_unlock(mutex);
/* Locking the thread descriptor structure mutex */
apr_thread_mutex_lock(w->mutex);
w->r = r;
w->ctype = ctype;
w->status = init;
w->conf = conf;
apr_thread_cond_signal(w->condition);
/* we wait for the Tcl worker thread to finish its job */
while (w->status != done) {
apr_thread_cond_wait(w->condition,w->mutex);
}
ap_sts = w->ap_sts;
w->status = idle;
w->r = NULL;
apr_thread_cond_signal(w->condition);
apr_thread_mutex_unlock(w->mutex);
return ap_sts;
}