summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2004-09-09 10:02:44 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:52:38 -0500
commit39a9c5dcc6e8c155bb102c7659460f2e738a6e13 (patch)
tree5dfcdba484875887a9aea935b9569db3d36d0970 /source3/nsswitch
parent516753896a6eb713ccaac53e261a833d082b79e8 (diff)
downloadsamba-39a9c5dcc6e8c155bb102c7659460f2e738a6e13.tar.gz
samba-39a9c5dcc6e8c155bb102c7659460f2e738a6e13.tar.bz2
samba-39a9c5dcc6e8c155bb102c7659460f2e738a6e13.zip
r2265: Volkers change to HEAD looks very good. Commit message
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. (This used to be commit bfdeb22c69d09eb73305b6034fa6d0ec67275789)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/winbindd.c17
-rw-r--r--source3/nsswitch/winbindd_util.c8
2 files changed, 20 insertions, 5 deletions
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index d08aa84fac..78e71b1186 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -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();
@@ -715,6 +716,15 @@ static void process_loop(void)
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)) {
@@ -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);
}
}
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index faa6e8d8da..a9197d3561 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -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)