s3:events: Call all ready fd event handlers on each iteration of the main loop
[idra/samba.git] / source3 / smbd / process.c
index a484dfd3f25909159f4ac04b4b8ba12e4c38fdb3..8d36dd3c89ff1971672f6069267bea03aacb2b91 100644 (file)
@@ -949,7 +949,7 @@ void smbd_setup_sig_hup_handler(struct tevent_context *ev,
 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
 {
        fd_set r_fds, w_fds;
-       int selrtn;
+       int selrtn = 0;
        struct timeval to;
        int maxfd = 0;
 
@@ -977,7 +977,7 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *
        }
 
        /* Process a signal and timed events now... */
-       if (run_events(smbd_event_context(), 0, NULL, NULL)) {
+       if (run_events(smbd_event_context(), &selrtn, NULL, NULL)) {
                return NT_STATUS_RETRY;
        }
 
@@ -994,26 +994,23 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *
 
        /* Check if error */
        if (selrtn == -1) {
-               /* something is wrong. Maybe the socket is dead? */
-               return map_nt_error_from_unix(errno);
+               if (errno == EINTR)
+                       return NT_STATUS_RETRY;
+               else
+                       /* Maybe the socket is dead? */
+                       return map_nt_error_from_unix(errno);
        }
 
-        if ((conn->smb1.echo_handler.trusted_fd != -1)
-           && FD_ISSET(conn->sock, &r_fds)
-           && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
-               /*
-                * Prefer to read pending requests from the echo handler. To
-                * quote Jeremy (da70f8ab1): This is a hack of monstrous
-                * proportions...
-                */
-               FD_CLR(conn->sock, &r_fds);
-        }
-
-       if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
-               return NT_STATUS_RETRY;
-       }
+       /* Process events until all available fds have been handled.
+        * This allows for fair round-robin handling of all available fds
+        * on each select() wakeup, while still maintaining responsiveness
+        * by re-checking for signal and timed events between the handling
+        * of each ready fd. */
+       do {
+               run_events(smbd_event_context(), &selrtn, &r_fds, &w_fds);
+       } while (selrtn > 0);
 
-       /* Did we timeout ? */
+       /* Processed all fds or timed out */
        if (selrtn == 0) {
                return NT_STATUS_RETRY;
        }