From: Jeff Trawick Date: Sat, 13 Dec 2003 18:25:57 +0000 (+0000) Subject: update threadpool MPM to build and appear to work with the current APR X-Git-Tag: pre_ajp_proxy~931 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=50351f79aaae2faf4d44451b015e870d813b5293;p=apache update threadpool MPM to build and appear to work with the current APR pollset API git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@102044 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/mpm/experimental/threadpool/threadpool.c b/server/mpm/experimental/threadpool/threadpool.c index 7f09933477..281056d585 100644 --- a/server/mpm/experimental/threadpool/threadpool.c +++ b/server/mpm/experimental/threadpool/threadpool.c @@ -779,18 +779,29 @@ static void *listener_thread(apr_thread_t *thd, void * dummy) int process_slot = ti->pid; apr_pool_t *tpool = apr_thread_pool_get(thd); void *csd = NULL; - apr_pool_t *ptrans; /* Pool for per-transaction stuff */ - int n; - apr_pollfd_t *pollset; + apr_pool_t *ptrans = NULL; /* Pool for per-transaction stuff */ + apr_pollset_t *pollset; apr_status_t rv; - ap_listen_rec *lr, *last_lr = ap_listeners; + ap_listen_rec *lr; worker_wakeup_info *worker = NULL; + int last_poll_idx = 0; free(ti); - apr_poll_setup(&pollset, num_listensocks, tpool); - for(lr = ap_listeners ; lr != NULL ; lr = lr->next) - apr_poll_socket_add(pollset, lr->sd, APR_POLLIN); + /* ### check the status */ + (void) apr_pollset_create(&pollset, num_listensocks, tpool, 0); + + for (lr = ap_listeners; lr != NULL; lr = lr->next) { + apr_pollfd_t pfd = { 0 }; + + pfd.desc_type = APR_POLL_SOCKET; + pfd.desc.s = lr->sd; + pfd.reqevents = APR_POLLIN; + pfd.client_data = lr; + + /* ### check the status */ + (void) apr_pollset_add(pollset, &pfd); + } /* Unblock the signal used to wake this thread up, and set a handler for * it. @@ -846,40 +857,48 @@ static void *listener_thread(apr_thread_t *thd, void * dummy) else { while (!listener_may_exit) { apr_status_t ret; - apr_int16_t event; + apr_int32_t numdesc; + const apr_pollfd_t *pdesc; - ret = apr_poll(pollset, num_listensocks, &n, -1); + ret = apr_pollset_poll(pollset, -1, &numdesc, &pdesc); if (ret != APR_SUCCESS) { if (APR_STATUS_IS_EINTR(ret)) { continue; } - /* apr_poll() will only return errors in catastrophic + /* apr_pollset_poll() will only return errors in catastrophic * circumstances. Let's try exiting gracefully, for now. */ ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *) - ap_server_conf, "apr_poll: (listen)"); + ap_server_conf, "apr_pollset_poll: (listen)"); signal_threads(ST_GRACEFUL); } if (listener_may_exit) break; - /* find a listener */ - lr = last_lr; - do { - lr = lr->next; - if (lr == NULL) { - lr = ap_listeners; - } - /* XXX: Should we check for POLLERR? */ - apr_poll_revents_get(&event, lr->sd, pollset); - if (event & APR_POLLIN) { - last_lr = lr; - goto got_fd; - } - } while (lr != last_lr); + /* We can always use pdesc[0], but sockets at position N + * could end up completely starved of attention in a very + * busy server. Therefore, we round-robin across the + * returned set of descriptors. While it is possible that + * the returned set of descriptors might flip around and + * continue to starve some sockets, we happen to know the + * internal pollset implementation retains ordering + * stability of the sockets. Thus, the round-robin should + * ensure that a socket will eventually be serviced. + */ + if (last_poll_idx >= numdesc) + last_poll_idx = 0; + + /* Grab a listener record from the client_data of the poll + * descriptor, and advance our saved index to round-robin + * the next fetch. + * + * ### hmm... this descriptor might have POLLERR rather + * ### than POLLIN + */ + lr = pdesc[last_poll_idx++].client_data; + break; } } - got_fd: if (!listener_may_exit) { rv = lr->accept_func(&csd, lr, ptrans); /* later we trash rv and rely on csd to indicate success/failure */