diff src/event/modules/ngx_devpoll_module.c @ 316:a0beefedaf94

nginx-0.0.3-2004-04-15-00:34:05 import
author Igor Sysoev <igor@sysoev.ru>
date Wed, 14 Apr 2004 20:34:05 +0000
parents 4b1a3a4acc60
children 1308b98496a2
line wrap: on
line diff
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -236,6 +236,7 @@ static int ngx_devpoll_del_event(ngx_eve
     }
 
     ev->active = 0;
+    ev->posted = 0;
 
     if (flags & NGX_CLOSE_EVENT) {
         return NGX_OK;
@@ -312,7 +313,7 @@ int ngx_devpoll_process_events(ngx_cycle
 {
     int                 events;
     ngx_int_t           i;
-    ngx_uint_t          j;
+    ngx_uint_t          j, lock, expire;
     size_t              n;
     ngx_msec_t          timer;
     ngx_err_t           err;
@@ -322,13 +323,43 @@ int ngx_devpoll_process_events(ngx_cycle
     struct dvpoll       dvp;
     struct timeval      tv;
 
-    timer = ngx_event_find_timer();
-    ngx_old_elapsed_msec = ngx_elapsed_msec;
+    for ( ;; ) {
+        timer = ngx_event_find_timer();
+
+        if (timer != 0) {
+            break;
+        }
+
+        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                       "devpoll expired timer");
+
+        ngx_event_expire_timers(0);
+    }
+
+    /* NGX_TIMER_INFINITE == INFTIM */
+
+    if (timer == NGX_TIMER_INFINITE) {
+        expire = 0;
 
-    if (timer == 0) {
-        timer = (ngx_msec_t) INFTIM;
+    } else {
+        expire = 1;
     }
 
+    if (ngx_accept_mutex) {
+        if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
+            return NGX_ERROR;
+        }
+
+        if (ngx_accept_mutex_held == 0
+            && (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay))
+        {
+            timer = ngx_accept_mutex_delay;
+            expire = 0;
+        }
+    }
+
+    ngx_old_elapsed_msec = ngx_elapsed_msec;
+
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    "devpoll timer: %d", timer);
 
@@ -337,6 +368,7 @@ int ngx_devpoll_process_events(ngx_cycle
         if (write(dp, change_list, n) != (ssize_t) n) {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                           "write(/dev/poll) failed");
+            ngx_accept_mutex_unlock();
             return NGX_ERROR;
         }
     }
@@ -363,10 +395,11 @@ int ngx_devpoll_process_events(ngx_cycle
     if (err) {
         ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
                       cycle->log, err, "ioctl(DP_POLL) failed");
+        ngx_accept_mutex_unlock();
         return NGX_ERROR;
     }
 
-    if (timer != (ngx_msec_t) INFTIM) {
+    if (timer != NGX_TIMER_INFINITE) {
         delta = ngx_elapsed_msec - delta;
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
@@ -375,10 +408,18 @@ int ngx_devpoll_process_events(ngx_cycle
         if (events == 0) {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                           "ioctl(DP_POLL) returned no events without timeout");
+            ngx_accept_mutex_unlock();
             return NGX_ERROR;
         }
     }
 
+    if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+        ngx_accept_mutex_unlock();
+        return NGX_ERROR;
+    }
+
+    lock = 1;
+
     for (i = 0; i < events; i++) {
         c = &ngx_cycle->connections[event_list[i].fd];
 
@@ -421,25 +462,68 @@ int ngx_devpoll_process_events(ngx_cycle
                           event_list[i].events, event_list[i].revents);
         }
 
+        if ((event_list[i].events & (POLLOUT|POLLERR|POLLHUP))
+            && c->write->active)
+        {
+            c->write->ready = 1;
+
+            if (!ngx_threaded && !ngx_accept_mutex_held) {
+                c->write->event_handler(c->write);
+
+            } else {
+                ngx_post_event(c->write);
+            }
+        }
+
+        /*
+         * POLLIN must be handled after POLLOUT because we use
+         * the optimization to avoid the unnecessary mutex locking/unlocking
+         * if the accept event is the last one.
+         */
+
         if ((event_list[i].events & (POLLIN|POLLERR|POLLHUP))
             && c->read->active)
         {
             c->read->ready = 1;
-            c->read->event_handler(c->read);
-        }
+
+            if (!ngx_threaded && !ngx_accept_mutex_held) {
+                c->read->event_handler(c->read);
+
+            } else if (!c->read->accept) {
+                ngx_post_event(c->read);
+
+            } else {
+                ngx_mutex_unlock(ngx_posted_events_mutex);
 
-        if ((event_list[i].events & (POLLOUT|POLLERR|POLLHUP))
-            && c->write->active)
-        {
-            c->write->ready = 1;
-            c->write->event_handler(c->write);
+                c->read->event_handler(c->read);
+
+                if (i + 1 == events) {
+                    lock = 0;
+                    break;
+                }
+
+                if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+                    ngx_accept_mutex_unlock();
+                    return NGX_ERROR;
+                }
+            }
         }
     }
 
-    if (timer != (ngx_msec_t) INFTIM && delta) {
+    if (lock) {
+        ngx_mutex_unlock(ngx_posted_events_mutex);
+    }
+
+    ngx_accept_mutex_unlock();
+
+    if (expire && delta) {
         ngx_event_expire_timers((ngx_msec_t) delta);
     }
 
+    if (!ngx_threaded) {
+        ngx_event_process_posted(cycle);
+    }
+
     return NGX_OK;
 }