--- server/mpm/event/event.c (revision 1603862) +++ server/mpm/event/event.c (working copy) @@ -328,6 +328,32 @@ unsigned int signaled:1; } socket_callback_baton_t; +static apr_array_header_t* te_array; + +static void te_array_init(apr_pool_t *p){ + te_array = apr_array_make(p, 0, sizeof(timer_event_t*)); +} + +static timer_event_t *te_array_pop(void){ + timer_event_t **foo = apr_array_pop(te_array); + return foo == NULL ? NULL: *foo; +} + +static void te_array_push(timer_event_t* te){ + timer_event_t **foo = apr_array_push(te_array); + *foo = te; +} + +static timer_event_t *te_array_peek(void){ + timer_event_t *foo = te_array_pop(); + if(foo != NULL){ + te_array_push(foo); + } + return foo; +} + + + /* data retained by event across load/unload of the module * allocated on first call to pre-config hook; located on * subsequent calls to pre-config hook @@ -1433,6 +1459,25 @@ static apr_thread_mutex_t *g_timer_skiplist_mtx; +static apr_status_t g_timer_skiplist_mtx_lock(const char *file, int line, int module_index){ + apr_status_t rv = apr_thread_mutex_lock(g_timer_skiplist_mtx); + if(rv != APR_SUCCESS){ + ap_log_error(file, line, module_index, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_mutex_lock(g_timer_skiplist_mtx) failed"); + } + return rv; +} + +static apr_status_t g_timer_skiplist_mtx_unlock(const char *file, int line, int module_index){ + apr_status_t rv = apr_thread_mutex_unlock(g_timer_skiplist_mtx); + if(rv != APR_SUCCESS){ + ap_log_error(file, line, module_index, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_mutex_unlock(g_timer_skiplist_mtx) failed"); + } + return rv; +} + + static timer_event_t * event_get_timer_event(apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton, @@ -1442,7 +1487,7 @@ timer_event_t *te; /* oh yeah, and make locking smarter/fine grained. */ - apr_thread_mutex_lock(g_timer_skiplist_mtx); + g_timer_skiplist_mtx_lock(APLOG_MARK); if (!APR_RING_EMPTY(&timer_free_ring, timer_event_t, link)) { te = APR_RING_FIRST(&timer_free_ring); @@ -1460,10 +1505,12 @@ te->remove = remove; if (insert) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "skiplist insert, when: %llu", te->when); /* Okay, insert sorted by when.. */ - apr_skiplist_insert(timer_skiplist, (void *)te); + te_array_push(te); } - apr_thread_mutex_unlock(g_timer_skiplist_mtx); + g_timer_skiplist_mtx_unlock(APLOG_MARK); return te; } @@ -1740,8 +1787,8 @@ } } - apr_thread_mutex_lock(g_timer_skiplist_mtx); - te = apr_skiplist_peek(timer_skiplist); + g_timer_skiplist_mtx_lock(APLOG_MARK); + te = te_array_peek(); if (te) { if (te->when > now) { timeout_interval = te->when - now; @@ -1753,7 +1800,7 @@ else { timeout_interval = apr_time_from_msec(100); } - apr_thread_mutex_unlock(g_timer_skiplist_mtx); + g_timer_skiplist_mtx_unlock(APLOG_MARK); #if HAVE_SERF rc = serf_context_prerun(g_serf); @@ -1762,26 +1809,31 @@ } #endif now = apr_time_now(); - apr_thread_mutex_lock(g_timer_skiplist_mtx); - ep = apr_skiplist_peek(timer_skiplist); + g_timer_skiplist_mtx_lock(APLOG_MARK); + ep = te_array_peek(); while (ep) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "when: %llu, now+EFF: %llu, result: %d", ep->when, now + EVENT_FUDGE_FACTOR, ep->when < now + EVENT_FUDGE_FACTOR); if (ep->when < now + EVENT_FUDGE_FACTOR) { - apr_skiplist_pop(timer_skiplist, NULL); + timer_event_t *foo = te_array_pop(); + ap_assert(ep == foo); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "skiplist poped, when: %llu", ep->when); if (!ep->canceled) { if (ep->remove != NULL) { for (apr_pollfd_t **pfds = (ep->remove); *pfds != NULL; pfds++) { apr_pollset_remove(event_pollset, *pfds); } } + push_timer2worker(ep); } - push_timer2worker(ep); } else { break; } - ep = apr_skiplist_peek(timer_skiplist); + ep = te_array_peek(); } - apr_thread_mutex_unlock(g_timer_skiplist_mtx); + g_timer_skiplist_mtx_unlock(APLOG_MARK); rc = apr_pollset_poll(event_pollset, timeout_interval, &num, &out_pfd); if (rc != APR_SUCCESS) { @@ -1976,6 +2028,9 @@ socket_callback_baton_t *baton = (socket_callback_baton_t *) pt->baton; if (baton->cancel_event) { baton->cancel_event->canceled = 1; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, + ap_server_conf, + "timer_event canceled."); } /* We only signal once per N sockets with this baton */ @@ -2148,9 +2203,9 @@ if (te != NULL) { te->cbfunc(te->baton); { - apr_thread_mutex_lock(g_timer_skiplist_mtx); + g_timer_skiplist_mtx_lock(APLOG_MARK); APR_RING_INSERT_TAIL(&timer_free_ring, te, timer_event_t, link); - apr_thread_mutex_unlock(g_timer_skiplist_mtx); + g_timer_skiplist_mtx_unlock(APLOG_MARK); } } else { @@ -2472,6 +2527,7 @@ apr_pool_create(&pskip, pchild); apr_skiplist_init(&timer_skiplist, pskip); apr_skiplist_set_compare(timer_skiplist, indexing_comp, indexing_compk); + te_array_init(pskip); ap_run_child_init(pchild, ap_server_conf); /* done with init critical section */