summaryrefslogtreecommitdiff
path: root/source3/smbd/oplock.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2002-06-06 23:55:41 +0000
committerJeremy Allison <jra@samba.org>2002-06-06 23:55:41 +0000
commit651efe158a506b9dfe2af7ecd8db8034848abac0 (patch)
treed9cd5ad1a5f87cb56c14a5fe527e0ec0765a2989 /source3/smbd/oplock.c
parent9595b60fe25916350c10224066b270e7d2b152b4 (diff)
downloadsamba-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/oplock.c')
-rw-r--r--source3/smbd/oplock.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index f20885a7e1..14b243b36e 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -83,6 +83,16 @@ BOOL receive_local_message( char *buffer, int buffer_len, int timeout)
FD_ZERO(&fds);
smb_read_error = 0;
+ /*
+ * We need to check for kernel oplocks before going into the select
+ * here, as the EINTR generated by the linux kernel oplock may have
+ * already been eaten. JRA.
+ */
+
+ if (koplocks && koplocks->msg_waiting(&fds)) {
+ return koplocks->receive_message(&fds, buffer, buffer_len);
+ }
+
while (timeout > 0 && selrtn == -1) {
struct timeval to;
int maxfd = oplock_sock;