summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/event.h2
-rw-r--r--source3/lib/events.c22
-rw-r--r--source3/nmbd/nmbd_packets.c6
-rw-r--r--source3/smbd/process.c35
-rw-r--r--source3/winbindd/winbindd_dual.c6
5 files changed, 38 insertions, 33 deletions
diff --git a/source3/include/event.h b/source3/include/event.h
index 493bc15925..6b41b1d81b 100644
--- a/source3/include/event.h
+++ b/source3/include/event.h
@@ -31,7 +31,7 @@ bool event_add_to_select_args(struct event_context *event_ctx,
fd_set *read_fds, fd_set *write_fds,
struct timeval *timeout, int *maxfd);
bool run_events(struct event_context *event_ctx,
- int selrtn, fd_set *read_fds, fd_set *write_fds);
+ int *selrtn, fd_set *read_fds, fd_set *write_fds);
struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
struct timeval *to_ret);
void dump_event_list(struct event_context *event_ctx);
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 70a0d7c302..0e127f02dc 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -67,7 +67,7 @@ bool event_add_to_select_args(struct tevent_context *ev,
}
bool run_events(struct tevent_context *ev,
- int selrtn, fd_set *read_fds, fd_set *write_fds)
+ int *selrtn, fd_set *read_fds, fd_set *write_fds)
{
struct tevent_fd *fde;
struct timeval now;
@@ -112,7 +112,7 @@ bool run_events(struct tevent_context *ev,
return true;
}
- if (selrtn == 0) {
+ if (*selrtn <= 0) {
/*
* No fd ready
*/
@@ -122,8 +122,16 @@ bool run_events(struct tevent_context *ev,
for (fde = ev->fd_events; fde; fde = fde->next) {
uint16 flags = 0;
- if (FD_ISSET(fde->fd, read_fds)) flags |= EVENT_FD_READ;
- if (FD_ISSET(fde->fd, write_fds)) flags |= EVENT_FD_WRITE;
+ if (FD_ISSET(fde->fd, read_fds)) {
+ flags |= EVENT_FD_READ;
+ FD_CLR(fde->fd, read_fds);
+ (*selrtn)--;
+ }
+ if (FD_ISSET(fde->fd, write_fds)) {
+ flags |= EVENT_FD_WRITE;
+ FD_CLR(fde->fd, write_fds);
+ (*selrtn)--;
+ }
if (flags & fde->flags) {
fde->handler(ev, fde, flags, fde->private_data);
@@ -162,7 +170,7 @@ static int s3_event_loop_once(struct tevent_context *ev, const char *location)
struct timeval now, to;
fd_set r_fds, w_fds;
int maxfd = 0;
- int ret;
+ int ret = 0;
FD_ZERO(&r_fds);
FD_ZERO(&w_fds);
@@ -170,7 +178,7 @@ static int s3_event_loop_once(struct tevent_context *ev, const char *location)
to.tv_sec = 9999; /* Max timeout */
to.tv_usec = 0;
- if (run_events(ev, 0, NULL, NULL)) {
+ if (run_events(ev, &ret, NULL, NULL)) {
return 0;
}
@@ -189,7 +197,7 @@ static int s3_event_loop_once(struct tevent_context *ev, const char *location)
return -1;
}
- run_events(ev, ret, &r_fds, &w_fds);
+ run_events(ev, &ret, &r_fds, &w_fds);
return 0;
}
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index 5d5a67bf62..c80bac46b5 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -1840,7 +1840,7 @@ bool listen_for_packets(bool run_election)
fd_set r_fds;
fd_set w_fds;
- int selrtn;
+ int selrtn = 0;
struct timeval timeout;
#ifndef SYNC_DNS
int dns_fd;
@@ -1867,7 +1867,7 @@ bool listen_for_packets(bool run_election)
#endif
/* Process a signal and timer events now... */
- if (run_events(nmbd_event_context(), 0, NULL, NULL)) {
+ if (run_events(nmbd_event_context(), &selrtn, NULL, NULL)) {
return False;
}
@@ -1889,7 +1889,7 @@ bool listen_for_packets(bool run_election)
selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&timeout);
- if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) {
+ if (run_events(nmbd_event_context(), &selrtn, &r_fds, &w_fds)) {
return False;
}
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index a484dfd3f2..8d36dd3c89 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -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;
}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index a4d8b8ac41..5dfd123b7c 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -1374,7 +1374,7 @@ static bool fork_domain_child(struct winbindd_child *child)
while (1) {
- int ret;
+ int ret = 0;
fd_set r_fds;
fd_set w_fds;
int maxfd;
@@ -1386,7 +1386,7 @@ static bool fork_domain_child(struct winbindd_child *child)
int iov_count;
NTSTATUS status;
- if (run_events(winbind_event_context(), 0, NULL, NULL)) {
+ if (run_events(winbind_event_context(), &ret, NULL, NULL)) {
TALLOC_FREE(frame);
continue;
}
@@ -1424,7 +1424,7 @@ static bool fork_domain_child(struct winbindd_child *child)
ret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, tp);
- if (run_events(winbind_event_context(), ret, &r_fds, &w_fds)) {
+ if (run_events(winbind_event_context(), &ret, &r_fds, &w_fds)) {
/* We got a signal - continue. */
TALLOC_FREE(frame);
continue;