diff options
author | Jeremy Allison <jra@samba.org> | 2002-06-06 23:55:41 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2002-06-06 23:55:41 +0000 |
commit | 651efe158a506b9dfe2af7ecd8db8034848abac0 (patch) | |
tree | d9cd5ad1a5f87cb56c14a5fe527e0ec0765a2989 /source3/smbd/process.c | |
parent | 9595b60fe25916350c10224066b270e7d2b152b4 (diff) | |
download | samba-651efe158a506b9dfe2af7ecd8db8034848abac0.tar.gz samba-651efe158a506b9dfe2af7ecd8db8034848abac0.tar.bz2 samba-651efe158a506b9dfe2af7ecd8db8034848abac0.zip |
Overly complex but neccessary fix for kernel oplock problems. The issue
is that there are some times when we should return an EINTR from a select,
some times when we should not. As we can take a signal at any time, we
have to eat EINTR's in some selects. This means we need to check for
kernel oplock breaks more often in the main loop, as well as add the
queuing mechanism needed for the changenotify code (due to the mistake
in understanding POSIX semantics w.r.t. setting a signal mask in a
signal handler). This code now passes all my tests.
However, (and IMHO and I know tridge disagrees) - the correct way to
fix this is to run with RT signals blocked and explicitly unblock
them just before the main select, block them after and then process
them all in one place. Just my 2cents :-).
Jeremy.
(This used to be commit a8c85372e2826a07117c89b39270cde8641ce55d)
Diffstat (limited to 'source3/smbd/process.c')
-rw-r--r-- | source3/smbd/process.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 010b188701..0cfb4a6264 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -195,6 +195,27 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout) */ FD_ZERO(&fds); + + /* + * Ensure we process oplock break messages by preference. + * We have to do this before the select, after the select + * and if the select returns EINTR. This is due to the fact + * that the selects called from async_processing can eat an EINTR + * caused by a signal (we can't take the break message there). + * This is hideously complex - *MUST* be simplified for 3.0 ! JRA. + */ + + if (oplock_message_waiting(&fds)) { + DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n")); + async_processing(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; + } + FD_SET(smbd_server_fd(),&fds); maxfd = setup_oplock_select_set(&fds); |