summaryrefslogtreecommitdiff
path: root/source3/lib/events.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2011-05-31 13:24:22 +0200
committerVolker Lendecke <vlendec@samba.org>2011-05-31 20:59:10 +0200
commit5f6f71956460d6840c1433b59e20555268b622ac (patch)
treefd6c234f5c6d50536facd572549c07a6b63b9eb7 /source3/lib/events.c
parentcfef10a0a2a16221eac27b6b7d3b3d7d952a418e (diff)
downloadsamba-5f6f71956460d6840c1433b59e20555268b622ac.tar.gz
samba-5f6f71956460d6840c1433b59e20555268b622ac.tar.bz2
samba-5f6f71956460d6840c1433b59e20555268b622ac.zip
s3: Mark sockets in error state writable
Without this patch, when a socket only has a write event pending, we will never detect an error condition. I've seen winbind doing 12:19:13.659964 gettimeofday({1306837153, 659984}, NULL) = 0 <0.000016> 12:19:13.660109 poll([{fd=35, events=POLLOUT}, {fd=32, events=POLLIN|POLLHUP}], 2, 9996) = 1 ([{fd=35, revents=POLLERR|POLLHUP}]) <0.000015> 12:19:13.660253 gettimeofday({1306837153, 660269}, NULL) = 0 <0.000013> 12:19:13.660298 poll([{fd=35, events=POLLOUT}, {fd=32, events=POLLIN|POLLHUP}], 2, 9996) = 1 ([{fd=35, revents=POLLERR|POLLHUP}]) <0.000015> for a while when trying to connect to a DC when the socket had died already. Volker Autobuild-User: Volker Lendecke <vlendec@samba.org> Autobuild-Date: Tue May 31 20:59:10 CEST 2011 on sn-devel-104
Diffstat (limited to 'source3/lib/events.c')
-rw-r--r--source3/lib/events.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 9ff14880ec..499d92edd2 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -260,6 +260,29 @@ bool run_events_poll(struct tevent_context *ev, int pollrtn,
if (pfd->revents & (POLLIN|POLLHUP|POLLERR)) {
flags |= EVENT_FD_READ;
+
+ if ((fde->flags & EVENT_FD_READ) == 0) {
+ /*
+ * This one is a bit subtle. If a socket is
+ * not being asked for readability and dies
+ * with POLLHUP|POLLERR, then the write
+ * handler must be activated to detect the
+ * dead socket with a failed write(2)
+ * call. The error I've seen is winbind
+ * spinning in poll trying to send something
+ * to a DC on a dead socket. poll gave
+ * POLLHUP|POLLERR, but because winbind at
+ * this moment only had asked for socket
+ * writability, it spun.
+ *
+ * We can't activate EVENT_FD_WRITE though
+ * whenever we have an error condition via
+ * POLLHUP|POLLERR, because at least smbd
+ * monitors EVENT_FD_WRITE in its callback,
+ * doing nothing.
+ */
+ flags |= EVENT_FD_WRITE;
+ }
}
if (pfd->revents & POLLOUT) {
flags |= EVENT_FD_WRITE;