s3:smbd: make kernel oplocks event driven
[metze/samba/wip.git] / source3 / smbd / process.c
index a07b71e5ac3df0fe55d292117dc23b13400b2e64..d617ef19157e864b695eded741136a977dd6fa5d 100644 (file)
@@ -692,57 +692,55 @@ struct idle_event *event_add_idle(struct event_context *event_ctx,
        return result;
 }
 
-/****************************************************************************
- Do all async processing in here. This includes kernel oplock messages, change
- notify events etc.
-****************************************************************************/
-
-static void async_processing(void)
+static void smbd_sig_term_handler(struct tevent_context *ev,
+                                 struct tevent_signal *se,
+                                 int signum,
+                                 int count,
+                                 void *siginfo,
+                                 void *private_data)
 {
-       DEBUG(10,("async_processing: Doing async processing.\n"));
-
-       process_aio_queue();
-
-       process_kernel_oplocks(smbd_messaging_context());
-
-       /* Do the aio check again after receive_local_message as it does a
-          select and may have eaten our signal. */
-       /* Is this till true? -- vl */
-       process_aio_queue();
+       exit_server_cleanly("termination signal");
+}
 
-       if (got_sig_term) {
-               exit_server_cleanly("termination signal");
-       }
+void smbd_setup_sig_term_handler(void)
+{
+       struct tevent_signal *se;
 
-       /* check for sighup processing */
-       if (reload_after_sighup) {
-               change_to_root_user();
-               DEBUG(1,("Reloading services after SIGHUP\n"));
-               reload_services(False);
-               reload_after_sighup = 0;
+       se = tevent_add_signal(smbd_event_context(),
+                              smbd_event_context(),
+                              SIGTERM, 0,
+                              smbd_sig_term_handler,
+                              NULL);
+       if (!se) {
+               exit_server("failed to setup SIGTERM handler");
        }
 }
 
-/****************************************************************************
-  Do a select on an two fd's - with timeout. 
-
-  If a local udp message has been pushed onto the
-  queue (this can only happen during oplock break
-  processing) call async_processing()
-
-  If a pending smb message has been pushed onto the
-  queue (this can only happen during oplock break
-  processing) return this next.
+static void smbd_sig_hup_handler(struct tevent_context *ev,
+                                 struct tevent_signal *se,
+                                 int signum,
+                                 int count,
+                                 void *siginfo,
+                                 void *private_data)
+{
+       change_to_root_user();
+       DEBUG(1,("Reloading services after SIGHUP\n"));
+       reload_services(False);
+}
 
-  If the first smbfd is ready then read an smb from it.
-  if the second (loopback UDP) fd is ready then read a message
-  from it and setup the buffer header to identify the length
-  and from address.
-  Returns False on timeout or error.
-  Else returns True.
+void smbd_setup_sig_hup_handler(void)
+{
+       struct tevent_signal *se;
 
-The timeout is in milliseconds
-****************************************************************************/
+       se = tevent_add_signal(smbd_event_context(),
+                              smbd_event_context(),
+                              SIGHUP, 0,
+                              smbd_sig_hup_handler,
+                              NULL);
+       if (!se) {
+               exit_server("failed to setup SIGHUP handler");
+       }
+}
 
 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
 {
@@ -761,26 +759,6 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *
        FD_ZERO(&r_fds);
        FD_ZERO(&w_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()) {
-               DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
-               async_processing();
-               /*
-                * 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.
-                */
-               return NT_STATUS_RETRY;
-       }
-
        /*
         * Are there any timed events waiting ? If so, ensure we don't
         * select for longer than it would take to wait for them.
@@ -814,20 +792,6 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *
                return NT_STATUS_RETRY;
        }
 
-       /* 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();
-               /*
-                * 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.
-                */
-               return NT_STATUS_RETRY;
-       }
-
        /* Check if error */
        if (selrtn == -1) {
                /* something is wrong. Maybe the socket is dead? */
@@ -866,31 +830,6 @@ NTSTATUS allow_new_trans(struct trans_state *list, int mid)
        return NT_STATUS_OK;
 }
 
-/****************************************************************************
- We're terminating and have closed all our files/connections etc.
- If there are any pending local messages we need to respond to them
- before termination so that other smbds don't think we just died whilst
- holding oplocks.
-****************************************************************************/
-
-void respond_to_all_remaining_local_messages(void)
-{
-       /*
-        * Assert we have no exclusive open oplocks.
-        */
-
-       if(get_number_of_exclusive_open_oplocks()) {
-               DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
-                       get_number_of_exclusive_open_oplocks() ));
-               return;
-       }
-
-       process_kernel_oplocks(smbd_messaging_context());
-
-       return;
-}
-
-
 /*
 These flags determine some of the permissions required to do an operation 
 
@@ -1830,9 +1769,8 @@ void check_reload(time_t t)
                mypid = getpid();
        }
 
-       if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
+       if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
                reload_services(True);
-               reload_after_sighup = False;
                last_smb_conf_reload_time = t;
        }