r13482: Push the FAM notification file descriptor into the select
authorJames Peach <jpeach@samba.org>
Mon, 13 Feb 2006 04:07:15 +0000 (04:07 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:10:05 +0000 (11:10 -0500)
set to avoid unnecessary polling.

source/include/smb.h
source/smbd/notify.c
source/smbd/notify_fam.c
source/smbd/notify_hash.c
source/smbd/notify_kernel.c
source/smbd/oplock.c
source/smbd/process.c

index dc03ba44d497957c626b67d99ab4632e2e588404..fd3c23e57560f802c4e50e63372d3097a9f19d26 100644 (file)
@@ -1581,6 +1581,7 @@ struct cnotify_fns {
        BOOL (*check_notify)(connection_struct *conn, uint16 vuid, char *path, uint32 flags, void *data, time_t t);
        void (*remove_notify)(void *data);
        int select_time;
+       int notification_fd;
 };
 
 #include "smb_macros.h"
index df3d45d20b5005a0f73ccd4ee1441ddd64204308..b2d0fc332624d95394fcf33ae963ee9c853f0ddb 100644 (file)
@@ -206,6 +206,15 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
        return True;
 }
 
+int change_notify_fd(void)
+{
+       if (cnotify) {
+               return cnotify->notification_fd;
+       }
+
+       return -1;
+}
+
 /****************************************************************************
  Initialise the change notify subsystem.
 ****************************************************************************/
index 413340266ecdbd0b043440441f2e4a27d6b0238c..9f02bfdee93c90b575d36ae1e9b9b963b2ac0399 100644 (file)
@@ -63,9 +63,30 @@ static int           global_fc_generation;
 #define FAM_TRACE      8
 #define FAM_TRACE_LOW  10
 
-#define FAM_NOTIFY_CHECK_TIMEOUT    1 /* secs */
 #define FAM_EVENT_DRAIN                    ((uint32_t)(-1))
 
+static void * fam_register_notify(connection_struct * conn,
+                   char *              path,
+                   uint32              flags);
+
+static BOOL fam_check_notify(connection_struct * conn,
+                uint16_t               vuid,
+                char *                 path,
+                uint32_t               flags,
+                void *                 data,
+                time_t                 when);
+
+static void fam_remove_notify(void * data)
+
+static struct cnotify_fns global_fam_notify =
+{
+    fam_register_notify,
+    fam_check_notify,
+    fam_remove_notify,
+    -1,
+    -1
+};
+
 /* Turn a FAM event code into a string. Don't rely on specific code values,
  * because that might not work across all flavours of FAM.
  */
@@ -110,6 +131,7 @@ fam_check_reconnect(void)
        }
     }
 
+    global_fam_notify.notification_fd = FAMCONNECTION_GETFD(&global_fc);
     return(True);
 }
 
@@ -420,18 +442,6 @@ fam_remove_notify(void * data)
 
 struct cnotify_fns * fam_notify_init(void)
 {
-    static struct cnotify_fns global_fam_notify =
-    {
-       fam_register_notify,
-       fam_check_notify,
-       fam_remove_notify,
-       FAM_NOTIFY_CHECK_TIMEOUT
-    };
-
-    /* TODO: rather than relying on FAM_NOTIFY_CHECK_TIMEOUT, we should have an
-     * API to push the FAM fd into the global server fd set.
-     */
-
     FAMCONNECTION_GETFD(&global_fc) = -1;
 
     if (!fam_test_connection()) {
index 859a92a61e3c293253aeac82286e6be6f09effb6..a98a028fae057402efe0882b6af3966e0d3f71bd 100644 (file)
@@ -230,6 +230,7 @@ struct cnotify_fns *hash_notify_init(void)
        cnotify.check_notify = hash_check_notify;
        cnotify.remove_notify = hash_remove_notify;
        cnotify.select_time = lp_change_notify_timeout();
+       cnotify.notification_fd = -1;
 
        return &cnotify;
 }
index 02abe0b4b60eccaa159ba8f649a6f48b615f6ea7..0c20effc3d1122375e4deb023665286fd2e24c4c 100644 (file)
@@ -232,6 +232,7 @@ struct cnotify_fns *kernel_notify_init(void)
        cnotify.check_notify = kernel_check_notify;
        cnotify.remove_notify = kernel_remove_notify;
        cnotify.select_time = -1;
+       cnotify.notification_fd = -1;
 
        /* the signal can start off blocked due to a bug in bash */
        BlockSignals(False, RT_SIGNAL_NOTIFY);
index 755bcffc7f77ed4cbe70cddbf739ecce8aa73faa..41eb809909c19f07b336c7576ce1cc3324d0d5ad 100644 (file)
@@ -240,21 +240,16 @@ BOOL downgrade_oplock(files_struct *fsp)
 }
 
 /****************************************************************************
- Setup the listening set of file descriptors for an oplock break
- message either from the UDP socket or from the kernel. Returns the maximum
- fd used.
+ Return the fd (if any) used for receiving oplock notifications.
 ****************************************************************************/
 
-int setup_oplock_select_set( fd_set *fds)
+int oplock_notify_fd(void)
 {
-       int maxfd = 0;
-
-       if (koplocks && koplocks->notification_fd != -1) {
-               FD_SET(koplocks->notification_fd, fds);
-               maxfd = MAX(maxfd, koplocks->notification_fd);
+       if (koplocks) {
+               return koplocks->notification_fd;
        }
 
-       return maxfd;
+       return -1;
 }
 
 /****************************************************************************
index d646ebe02db1a64ea79ed43f5a73e0bb7011432f..2f19f909f2e4df841a5a42c705ca0d6f0e8fbef4 100644 (file)
@@ -283,7 +283,7 @@ struct idle_event *add_idle_event(TALLOC_CTX *mem_ctx,
 
        return result;
 }
-       
+
 /****************************************************************************
  Do all async processing in here. This includes kernel oplock messages, change
  notify events etc.
@@ -318,6 +318,20 @@ static void async_processing(void)
        }
 }
 
+/****************************************************************************
+ Add a fd to the set we will be select(2)ing on.
+****************************************************************************/
+
+static int select_on_fd(int fd, int maxfd, fd_set *fds)
+{
+       if (fd != -1) {
+               FD_SET(fd, fds);
+               maxfd = MAX(maxfd, fd);
+       }
+
+       return maxfd;
+}
+
 /****************************************************************************
   Do a select on an two fd's - with timeout. 
 
@@ -344,7 +358,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
        fd_set fds;
        int selrtn;
        struct timeval to = timeval_set(SMBD_SELECT_TIMEOUT, 0);
-       int maxfd;
+       int maxfd = 0;
 
        smb_read_error = 0;
 
@@ -437,10 +451,11 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
                }
        }
        
-       FD_SET(smbd_server_fd(),&fds);
-       maxfd = setup_oplock_select_set(&fds);
+       maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds);
+       maxfd = select_on_fd(change_notify_fd(), maxfd, &fds);
+       maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds);
 
-       selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL,NULL,&to);
+       selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to);
 
        /* if we get EINTR then maybe we have received an oplock
           signal - treat this as select returning 1. This is ugly, but