]> granicus.if.org Git - apache/commitdiff
update leader MPM to build and appear to work with the current APR
authorJeff Trawick <trawick@apache.org>
Sat, 13 Dec 2003 15:46:09 +0000 (15:46 +0000)
committerJeff Trawick <trawick@apache.org>
Sat, 13 Dec 2003 15:46:09 +0000 (15:46 +0000)
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

index c8e10b04f97d329e0aca581dc4cdf460e77dc0fe..01f8bde87d7d3567f94c4f3670fb0d853d4c925c 100644 (file)
@@ -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: