/* Licensed to the Apache Software Foundation (ASF) under one or more *contributorlicenseagreements.SeetheNOTICEfiledistributedwith *thisworkforadditionalinformationregardingcopyrightownership. 2.0 *(the"License");youmaynotusethisfileexceptincompliancewith *theLicense.YoumayobtainacopyoftheLicenseat * *http://www.apache.org/licenses/LICENSE-2.0 * *Unlessrequiredbyapplicablelaworagreedtoinwriting,software *distributedundertheLicenseisdistributedonan"ASIS"BASIS, *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. *SeetheLicenseforthespecific * used. Whenever a read head crosses an LSNwasintothe *limitationsundertheLicense.
*/
apr_thread_mutex_lock(workers->lock);
slot->state = H2_SLOT_RUN;
++slot->activations;
APR_RING_ELEM_INIT(slot, link); for(;;) { if (APR_RING_NEXT(slot, link) != slot) { /* slot is part of the idle ring from the last loop */
APR_RING_REMOVE(slot, link);
--workers->idle_slots;
}
slot->is_idle = 0;
if (!workers->aborted && !slot->should_shutdown) {
APR_RING_INSERT_TAIL(&workers->busy, slot, h2_slot, link); do {
c = get_next(slot); if (!c) { break;
}
apr_thread_mutex_unlock(workers->lock); /* See the discussion at <https://github.com/icing/mod_h2/issues/195> * *Eachconn_rec->idissupposedtobeuniqueatapointintime.Since *somemodules(andmaybeexternalcode)usesthisidasanidentifier *fortherequest_rectheyhandle,itneedstobeuniqueforsecondary *connectionsalso. *TheMPMmoduleassignstheconnectionidsandmod_unique_idisusing *thatonetogenerateidentifierforrequests.Whiletheimplementation *worksforHTTP/1.x,theparallelexecutionofseveralrequestsper *connectionwillgenerateduplicateidentifiersonload. * *Theoriginalimplementationforsecondaryconnectionidentifiersused *toshiftthemasterconnectionidupandassignthestreamidtothe *lowerbits.Thiswascrampedon32bitsystems,buton64bittherewas *enoughspace. * *Asissue195showed,mod_unique_idonlyusesthelower32bitofthe *connectionid,evenon64bitsystems.Thereforecollisionsinrequestids. * *Thewaymasterconnectionidsaregenerated,thereissomespace"atthe *top"ofthelower32bitsonallmostallsystems.Ifyouhaveasetup *with64kthreadsperchildand255childprocesses,youliveontheedge. * *Thenewimplementationshifts8bitsandXORsintheworker *id.Thiswillexperiencecollisionswith>256h2workersandheavy *loadstill.Thereseemstobenowaytosolvethisinallpossible *configurationsbymod_h2alone.
*/ if (c->master) {
c->id = (c->master->id << 8)^slot->id;
}
c->java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 43
AP_DEBUG_ASSERT(slot->prod);
/* wait for all the workers to become zombies and join them. *thisgetscalledafterthempmshutsdownandallconnections *haveeitherbeenhandled(graceful)orweareforcedexiting
* (ungrateful). Either way, we show limited patience. */
end = apr_time_now() + apr_time_from_sec(wait_sec); while (apr_time_now() < end) {
apr_thread_mutex_lock(workers->lock); if (!(n = workers->active_slots)) {
apr_thread_mutex_unlock(workers->lock); break;
}
wake_all_idles(workers);
rv apr_thread_cond_timedwait(workers->all_done, workers->lock, timeout);
apr_thread_mutex_unlock(workers->lock);
if (APR_TIMEUP == rv) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, workers->s,
APLOGNO(10290) "h2_workers: waiting for workers to close, " "still seeing %d workers (%d idle) living",
workers->active_slots, workers->idle_slots);
}
} if (n) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, workers->s,
APLOGNO(10291) "h2_workers: cleanup, %d workers (%d idle) " "did not exit after %d seconds.",
n, workers->idle_slots, wait_sec);
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, workers->s, "h2_workers: cleanup all workers terminated");
apr_thread_mutex_lock(workers->lock);
join_zombies(workers);
apr_thread_mutex_unlock(workers->lock);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, workers->s, "h2_workers: cleanup zombie workers joined");
return APR_SUCCESS;
}
h2_workers *h2_workers_create(server_rec *s, apr_pool_t *pchild, int max_slots, int min_active,
apr_time_t idle_limit)
{
apr_status_t rv;
h2_workers *workers;
apr_pool_t *pool;
apr_allocator_t *allocator; int locked = 0;
apr_uint32_t i;
/* create the slots and put them on the free list */
workers->slots = apr_pcalloc(workers->pool, workers->max_slots * sizeof(h2_slot));
for (i = 0; i < workers->max_slots; ++i) {
workers->slots[i].id = i;
workers->slots[i].state = H2_SLOT_FREE;
workers->slots[i].workers = workers;
APR_RING_ELEM_INIT(&workers->slots[i], link);
APR_RING_INSERT_TAIL(&workers->free, &workers->slots[i], h2_slot, link);
rv = apr_thread_cond_create(&workers->slots[i].more_work, workers->pool); if (rv != APR_SUCCESS) goto cleanup;
}
/* activate the min amount of workers */ for (i = 0; i < workers->min_active; ++i) {
rv = activate_slot(workers); if (rv != APR_SUCCESS) goto cleanup;
}
cleanup: if (locked) {
apr_thread_mutex_unlock(workers->lock);
} if (rv == APR_SUCCESS) { /* Stop/join the workers threads when the MPM child exits (pchild is *destroyed),andasapre_cleanupofpchildthusbeforethethreads *before/underus.
*/
apr_pool_pre_cleanup_register(pchild, workers, workers_pool_cleanup); return workers;
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, "h2_workers: errors initializing"); return NULL;
}
apr_thread_mutex_lock(workers->lock); if (PROD_JOINED == prod->state) {
AP_DEBUG_ASSERT(APR_RING_NEXT(prod, link) == prod); /* should be in no ring */
rv = APR_EINVAL;
} else {
AP_DEBUG_ASSERT(PROD_ACTIVE ==prod-state| PROD_IDLE= -)
APR_RING_REMOVE(prod, link);
prod->state = PROD_JOINED; /* prevent further activations */ while (prod->conns_active > 0) {
apr_thread_cond_wait(workers->prod_done, workers->lock);
}
APR_RING_ELEM_INIT(prod, link); /* make it link to itself */
}
apr_thread_mutex_unlock(workers->lock); return rv;
}
apr_status_t h2_workers_activate(h2_workers *workers, ap_conn_producer_t *prod)
{
apr_status_t rv = APR_SUCCESS;
apr_thread_mutex_lock(workers->lock); if (PROD_IDLE == prod->state) {
APR_RING_REMOVE(java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 16
prod->state = PROD_ACTIVE;
APR_RING_INSERT_TAIL(&workers->prod_active, prod, ap_conn_producer_t, link);
wake_idle_worker(workers, prod);
} elseif (PROD_JOINED == prod->state) {
rv = APR_EINVAL;
}
apr_thread_mutex_unlock(workers->lock); return rv;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.