}
/****************************************************************************
- Read an oplock break message from either the oplock UDP fd or the
- kernel (if kernel oplocks are supported).
-
- If timeout is zero then *fds contains the file descriptors that
- are ready to be read and acted upon. If timeout is non-zero then
- *fds contains the file descriptors to be selected on for read.
- The timeout is in milliseconds
-
+ Find out if there are any kernel oplock messages waiting and process them
+ if so. pfds is the fd_set from the main select loop (which contains any
+ kernel oplock fd if that's what the system uses (IRIX). If may be NULL if
+ we're calling this in a shutting down state.
****************************************************************************/
-void process_kernel_oplocks(void)
+void process_kernel_oplocks(fd_set *pfds)
{
- fd_set fds;
-
- 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
return;
}
- while (koplocks->msg_waiting(&fds)) {
+ while (koplocks->msg_waiting(pfds)) {
files_struct *fsp;
char msg[MSG_SMB_KERNEL_BREAK_SIZE];
- fsp = koplocks->receive_message(&fds);
+ fsp = koplocks->receive_message(pfds);
if (fsp == NULL) {
DEBUG(3, ("Kernel oplock message announced, but none "
char dummy;
files_struct *fsp;
+ /* Ensure we only get one call per select fd set. */
+ FD_CLR(fds, oplock_pipe_read);
+
/*
* Read one byte of zero to clear the
* kernel break notify message.
/****************************************************************************
Set *maxfd to include oplock read pipe.
+ Note that fds MAY BE NULL ! If so we must do our own select.
****************************************************************************/
static BOOL irix_oplock_msg_waiting(fd_set *fds)
{
+ int maxfd, selrtn;
+ fd_set myfds;
+ struct timeval to;
+
if (oplock_pipe_read == -1)
return False;
- return FD_ISSET(oplock_pipe_read,fds);
+ if (fds) {
+ return FD_ISSET(oplock_pipe_read,fds);
+ }
+
+ FD_ZERO(&myfds);
+ maxfd = setup_oplock_select_set(&myfds);
+ /* Only do the select if we have something to select *on*. */
+ if (maxfd == 0) {
+ return False;
+ }
+
+ /* Do a zero-time select. We just need to find out if there
+ * are any outstanding messages. We use sys_select_intr as
+ * we need to ignore any signals. */
+
+ to = timeval_set(0, 0);
+ selrtn = sys_select_intr(maxfd+1,&myfds,NULL,NULL,&to);
+ return (selrtn == 1) ? True : False;
}
/****************************************************************************
notify events etc.
****************************************************************************/
-static void async_processing(void)
+static void async_processing(fd_set *pfds)
{
DEBUG(10,("async_processing: Doing async processing.\n"));
process_aio_queue();
- process_kernel_oplocks();
+ process_kernel_oplocks(pfds);
/* Do the aio check again after receive_local_message as it does a
select and may have eaten our signal. */
if (oplock_message_waiting(&fds)) {
DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
- async_processing();
+ async_processing(&fds);
/*
* 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
is the best we can do until the oplock code knows more about
signals */
if (selrtn == -1 && errno == EINTR) {
- async_processing();
+ async_processing(&fds);
/*
* 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
*/
if (oplock_message_waiting(&fds)) {
- async_processing();
+ async_processing(&fds);
/*
* 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
return;
}
- process_kernel_oplocks();
+ process_kernel_oplocks(NULL);
return;
}