void WorkerBridge_ChildInit()

in src/mod_rivet_ng/rivet_worker_mpm.c [440:531]


void WorkerBridge_ChildInit (apr_pool_t* pool, server_rec* server)
{
    apr_status_t        rv;

    apr_atomic_init(pool);

#ifdef RIVET_SERIALIZE_HTTP_REQUESTS
    apr_thread_mutex_create(&module_globals->req_mutex, APR_THREAD_MUTEX_UNNESTED, pool);
#endif

    /* First of all we allocate and initialize the mpm status */

    module_globals->mpm = apr_pcalloc(pool,sizeof(mpm_bridge_status));

    /* apr_calloc is supposed to allocate zeroed memory,
     * but we still make esplicit the initialization
     * of some of its fields
     */

    module_globals->mpm->exiting            = NULL;
    module_globals->mpm->max_threads        = 0;
    module_globals->mpm->min_spare_threads  = 0;
    module_globals->mpm->max_spare_threads  = 0;
    module_globals->mpm->workers            = NULL;
    module_globals->mpm->server_shutdown    = 0;
    //module_globals->mpm->exit_command     = 0;
    module_globals->mpm->skip_thread_on_exit = 0;

    /* We keep some atomic counters that could provide basic data for a workload balancer */

    module_globals->mpm->threads_count = (apr_uint32_t *) apr_pcalloc(pool,sizeof(apr_uint32_t));
    module_globals->mpm->running_threads_count = (apr_uint32_t *) apr_pcalloc(pool,sizeof(apr_uint32_t));
    apr_atomic_set32(module_globals->mpm->threads_count,0);
    apr_atomic_set32(module_globals->mpm->running_threads_count,0);

    ap_assert(apr_thread_mutex_create(&module_globals->mpm->job_mutex,APR_THREAD_MUTEX_UNNESTED,pool) == APR_SUCCESS);
    ap_assert(apr_thread_cond_create(&module_globals->mpm->job_cond,pool) == APR_SUCCESS);

    /* This is the thread key for the framework thread calling the content generation callback */

    // ap_assert (apr_threadkey_private_create(&handler_thread_key,NULL,pool) == APR_SUCCESS);

    /* This bridge keeps an array of the ids of threads about to exit. This array is protected by
     * the mutex module_globals->job_mutex and signals through module_globals->job_cond
     */

    module_globals->mpm->exiting = apr_array_make(pool,100,sizeof(apr_thread_t*));

    /* This APR-Util queue object is the central communication channel from the Apache
     * framework to the Tcl threads through the request handler */

    if (apr_queue_create(&module_globals->mpm->queue, MOD_RIVET_QUEUE_SIZE, module_globals->pool) != APR_SUCCESS)
    {
        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, server,
                     MODNAME ": could not initialize mod_rivet request queue");
        exit(1);
    }

    /* In order to set up some workload balancing let's
     * query apache some configuration parameters of
     * the worker MPM
     */

    if (ap_mpm_query(AP_MPMQ_MAX_THREADS,&module_globals->mpm->max_threads) != APR_SUCCESS)
    {
        module_globals->mpm->max_threads = TCL_INTERPS;
    }
    if (ap_mpm_query(AP_MPMQ_MIN_SPARE_THREADS,&module_globals->mpm->min_spare_threads) != APR_SUCCESS)
    {
        module_globals->mpm->min_spare_threads = TCL_INTERPS;
    }
    if (ap_mpm_query(AP_MPMQ_MAX_SPARE_THREADS,&module_globals->mpm->max_spare_threads) != APR_SUCCESS)
    {
        module_globals->mpm->max_spare_threads = TCL_INTERPS;
    }

    /* We allocate the array of Tcl threads id. We require it to have AP_MPMQ_MAX_THREADS slots */

    module_globals->mpm->workers = apr_pcalloc(pool,module_globals->mpm->max_threads * sizeof(void *));

    rv = apr_thread_create( &module_globals->mpm->supervisor, NULL,
                            threaded_bridge_supervisor, server, module_globals->pool);

    if (rv != APR_SUCCESS) {
        char errorbuf[RIVET_MSG_BUFFER_SIZE];

        apr_strerror(rv, errorbuf,RIVET_MSG_BUFFER_SIZE);
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, server,
                     MODNAME "Error starting supervisor thread rv=%d:%s\n",rv,errorbuf);
        exit(1);
    }
}