diff options
author | Jeremy Allison <jra@samba.org> | 2001-09-10 22:54:57 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2001-09-10 22:54:57 +0000 |
commit | f8a4e20e70cb0f92f8c35b33e0aa5a0293b95638 (patch) | |
tree | c48c2ff4c2eb93bf348f0056d8ccdcb3b018f50c /source/smbd/process.c | |
parent | 9d53fa9ede9abf1f9cf33a63dc36be5d37419c15 (diff) | |
download | samba-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.
Diffstat (limited to 'source/smbd/process.c')
-rw-r--r-- | source/smbd/process.c | 28 |
1 files changed, 27 insertions, 1 deletions
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); |