]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
r2265: Volkers change to HEAD looks very good. Commit message
authorJeremy Allison <jra@samba.org>
Thu, 9 Sep 2004 10:02:44 +0000 (10:02 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:52:38 +0000 (10:52 -0500)
from HEAD follows :
While torturing winbind a bit I found the following unfortunate behaviour:

Sending multiple requests at a high rate for a slow operation exposed that no
response comes back until the last request in the queue has been
processed. This is an unfortunate result of serially going through all sockets> that have shown to be readable or writable. All client sockets become readable> at the same time, none of them is writable. We go through them, read the
request, process the complete request. Before we enter the select system call
the next time all requests have to have completed.

This patch optimizes this by first looking at the sockets for writability. A
write on a socket that came back from select does not block, so this
additional loop might have a non-zero cost, but it can't prevent other
operations from proceeding.

After a possibly long-running winbindd_process() we directly start select()
again. To avoid starvation the currently processed client is demoted to be the> last one in the list of clients.

Jeremy.

source/nsswitch/winbindd.c
source/nsswitch/winbindd_util.c

index d08aa84face0263c02dac35161b0a35c784db0cd..78e71b11864b186abeb519b941e17042ac52b60a 100644 (file)
@@ -587,6 +587,7 @@ static void process_loop(void)
                int maxfd, listen_sock, listen_priv_sock, selret;
                struct timeval timeout;
 
+       again:
                /* Handle messages */
 
                message_dispatch();
@@ -712,6 +713,15 @@ static void process_loop(void)
             
                        /* Process activity on client connections */
             
+                       for (state = winbindd_client_list(); state; 
+                            state = state->next) {
+                
+                               /* Data available for writing */
+                
+                               if (FD_ISSET(state->sock, &w_fds))
+                                       client_write(state);
+                       }
+                
                        for (state = winbindd_client_list(); state; 
                             state = state->next) {
                 
@@ -747,13 +757,10 @@ static void process_loop(void)
                                        if (state->read_buf_len == 
                                            sizeof(state->request)) {
                                                winbind_process_packet(state);
+                                               winbindd_demote_client(state);
+                                               goto again;
                                        }
                                }
-                
-                               /* Data available for writing */
-                
-                               if (FD_ISSET(state->sock, &w_fds))
-                                       client_write(state);
                        }
                }
 
index faa6e8d8da45720f3663d7cacafd6fcd33bb540f..a9197d356163df3b0e5266c7d840875c547c9c70 100644 (file)
@@ -736,6 +736,14 @@ void winbindd_remove_client(struct winbindd_cli_state *cli)
        _num_clients--;
 }
 
+/* Demote a client to be the last in the list */
+
+void winbindd_demote_client(struct winbindd_cli_state *cli)
+{
+       struct winbindd_cli_state *tmp;
+       DLIST_DEMOTE(_client_list, cli, tmp);
+}
+
 /* Close all open clients */
 
 void winbindd_kill_all_clients(void)