svn commit: samba r2237 - in trunk/source/nsswitch: .

vlendec at samba.org vlendec at samba.org
Tue Sep 7 12:14:43 GMT 2004


Author: vlendec
Date: 2004-09-07 12:14:43 +0000 (Tue, 07 Sep 2004)
New Revision: 2237

WebSVN: http://websvn.samba.org/websvn/changeset.php?rep=samba&path=/trunk/source/nsswitch&rev=2237&nolog=1

Log:
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.

Please revisit this change and possibly apply to 3_0, I'm not really sure
whether this is serious enough to be included in 3_0.

Volker

Modified:
   trunk/source/nsswitch/winbindd.c
   trunk/source/nsswitch/winbindd_util.c


Changeset:
Modified: trunk/source/nsswitch/winbindd.c
===================================================================
--- trunk/source/nsswitch/winbindd.c	2004-09-06 11:09:27 UTC (rev 2236)
+++ trunk/source/nsswitch/winbindd.c	2004-09-07 12:14:43 UTC (rev 2237)
@@ -708,6 +708,7 @@
 		int maxfd, listen_sock, listen_priv_sock, selret;
 		struct timeval timeout;
 
+	again:
 		/* Handle messages */
 
 		message_dispatch();
@@ -858,6 +859,15 @@
 			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) {
+                
 				/* Data available for reading */
                 
 				if (FD_ISSET(state->sock, &r_fds)) {
@@ -890,13 +900,10 @@
 					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);
 			}
 		}
 

Modified: trunk/source/nsswitch/winbindd_util.c
===================================================================
--- trunk/source/nsswitch/winbindd_util.c	2004-09-06 11:09:27 UTC (rev 2236)
+++ trunk/source/nsswitch/winbindd_util.c	2004-09-07 12:14:43 UTC (rev 2237)
@@ -743,6 +743,14 @@
 	_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)



More information about the samba-cvs mailing list