From 8fd159ef873d1113ed99692ef21822dd687de99d Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Sat, 13 Dec 2003 15:46:09 +0000 Subject: [PATCH] update leader 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@102043 13f79535-47bb-0310-9956-ffa450edef68 --- server/mpm/experimental/leader/leader.c | 66 ++++++++++++++++--------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/server/mpm/experimental/leader/leader.c b/server/mpm/experimental/leader/leader.c index c8e10b04f9..01f8bde87d 100644 --- a/server/mpm/experimental/leader/leader.c +++ b/server/mpm/experimental/leader/leader.c @@ -703,11 +703,12 @@ static void *worker_thread(apr_thread_t *thd, void * dummy) apr_allocator_t *allocator; apr_pool_t *ptrans; /* Pool for per-transaction stuff */ apr_bucket_alloc_t *bucket_alloc; - int n; - apr_pollfd_t *pollset; + int numdesc; + apr_pollset_t *pollset; apr_status_t rv; - ap_listen_rec *lr, *last_lr = ap_listeners; + ap_listen_rec *lr; int is_listener; + int last_poll_idx = 0; ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); @@ -720,10 +721,19 @@ static void *worker_thread(apr_thread_t *thd, void * dummy) apr_allocator_owner_set(allocator, ptrans); bucket_alloc = apr_bucket_alloc_create_ex(allocator); - 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); + 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); + } + /* TODO: Switch to a system where threads reuse the results from earlier poll calls - manoj */ is_listener = 0; @@ -778,37 +788,45 @@ static void *worker_thread(apr_thread_t *thd, void * dummy) else { while (!workers_may_exit) { apr_status_t ret; - apr_int16_t event; + 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 (workers_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; + goto got_fd; } } got_fd: -- 2.50.1