summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-09-10 22:54:57 +0000
committerJeremy Allison <jra@samba.org>2001-09-10 22:54:57 +0000
commitf8a4e20e70cb0f92f8c35b33e0aa5a0293b95638 (patch)
treec48c2ff4c2eb93bf348f0056d8ccdcb3b018f50c
parent9d53fa9ede9abf1f9cf33a63dc36be5d37419c15 (diff)
downloadsamba-f8a4e20e70cb0f92f8c35b33e0aa5a0293b95638.tar.gz
samba-f8a4e20e70cb0f92f8c35b33e0aa5a0293b95638.tar.xz
samba-f8a4e20e70cb0f92f8c35b33e0aa5a0293b95638.zip
Nailed the "oplock hang" problem. Found the logic bug. It was an
optimisation someone... :-) added to process an incoming smbd if both the oplock fd and server fd because active simultaneously. This of course is wrong as processing the oplock break message can involve I/O on the server fd which makes the stored FD_SET state completely bogus. Also added debug 10 messages I will remove once Gerry has confirmed the fix. Jeremy.
-rw-r--r--source/lib/messages.c7
-rw-r--r--source/smbd/process.c28
2 files changed, 34 insertions, 1 deletions
diff --git a/source/lib/messages.c b/source/lib/messages.c
index ac8ce7399bc..0ff09032100 100644
--- a/source/lib/messages.c
+++ b/source/lib/messages.c
@@ -298,17 +298,24 @@ void message_dispatch(void)
size_t len;
struct dispatch_fns *dfn;
+ /* JRATEMP */
+ DEBUG(10,("message_dispatch: received_signal = %d\n", received_signal));
+
if (!received_signal) return;
received_signal = 0;
while (message_recv(&msg_type, &src, &buf, &len)) {
for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
if (dfn->msg_type == msg_type) {
+ DEBUG(10,("message_dispatch: processing message.\n"));
dfn->fn(msg_type, src, buf, len);
}
}
if (buf) free(buf);
}
+
+ /* JRATEMP */
+ DEBUG(10,("message_dispatch: exit\n"));
}
diff --git a/source/smbd/process.c b/source/smbd/process.c
index e67d8728b1a..3e795d0e30f 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -115,11 +115,17 @@ oplock messages, change notify events etc.
****************************************************************************/
static void async_processing(fd_set *fds, char *buffer, int buffer_len)
{
+ /* JRATEMP */
+ DEBUG(10,("async_processing: doing async_processing...\n"));
+
/* check for oplock messages (both UDP and kernel) */
if (receive_local_message(fds, buffer, buffer_len, 0)) {
process_local_message(buffer, buffer_len);
}
+ /* JRATEMP */
+ DEBUG(10,("async_processing: doing pending_change_notify_queue...\n"));
+
/* check for async change notify events */
process_pending_change_notify_queue(0);
@@ -130,6 +136,9 @@ static void async_processing(fd_set *fds, char *buffer, int buffer_len)
reload_services(False);
reload_after_sighup = False;
}
+
+ /* JRATEMP */
+ DEBUG(10,("async_processing: end async_processing...\n"));
}
/****************************************************************************
@@ -199,14 +208,25 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout % 1000) * 1000;
+ /* JRATEMP */
+ DEBUG(10,("receive_message_or_smb: Entering main select with maxfd = %d\n", maxfd));
+
selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,timeout>0?&to:NULL);
+ /* JRATEMP */
+ DEBUG(10,("receive_message_or_smb: exited main select with return = %d\n", selrtn ));
+
/* if we get EINTR then maybe we have received an oplock
signal - treat this as select returning 1. This is ugly, but
is the best we can do until the oplock code knows more about
signals */
if (selrtn == -1 && errno == EINTR) {
async_processing(&fds, buffer, buffer_len);
+ /*
+ * After async processing we must go and do the select again, as
+ * the state of the flag in fds for the server file descriptor is
+ * indeterminate - we may have done I/O on it in the oplock processing. JRA.
+ */
goto again;
}
@@ -230,8 +250,14 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
*/
if (oplock_message_waiting(&fds)) {
+ DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
async_processing(&fds, buffer, buffer_len);
- if (!FD_ISSET(smbd_server_fd(),&fds)) goto again;
+ /*
+ * After async processing we must go and do the select again, as
+ * the state of the flag in fds for the server file descriptor is
+ * indeterminate - we may have done I/O on it in the oplock processing. JRA.
+ */
+ goto again;
}
return receive_smb(smbd_server_fd(), buffer, 0);