Add 3 second timeout when terminating server and sending print notify
authorJeremy Allison <jra@samba.org>
Thu, 30 Jan 2003 23:55:13 +0000 (23:55 +0000)
committerJeremy Allison <jra@samba.org>
Thu, 30 Jan 2003 23:55:13 +0000 (23:55 +0000)
messages. Stops build-up of large numbers of smbd's waiting to terminate
on large print throughput.
Jeremy.
(This used to be commit 4ae130bfa82be60de6a6f357f65207fcb24f45fb)

source3/lib/messages.c
source3/printing/notify.c
source3/smbd/process.c
source3/smbd/server.c
source3/tdb/tdbutil.c
source3/utils/smbcontrol.c

index 53c9e3d2bc52984c2d0af30a758025e18be5195f..3603758e9fec22f960858074413842360e34fbdc 100644 (file)
@@ -160,8 +160,8 @@ static BOOL message_notify(pid_t pid)
  Send a message to a particular pid.
 ****************************************************************************/
 
-BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
-                     BOOL duplicates_allowed)
+static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf, size_t len,
+                     BOOL duplicates_allowed, unsigned int timeout)
 {
        TDB_DATA kbuf;
        TDB_DATA dbuf;
@@ -200,7 +200,17 @@ BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
                /* If duplicates are allowed we can just append the message and return. */
 
                /* lock the record for the destination */
-               tdb_chainlock(tdb, kbuf);
+               if (timeout) {
+                       if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
+                               DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout));
+                               return False;
+                       }
+               } else {
+                       if (tdb_chainlock(tdb, kbuf) == -1) {
+                               DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n"));
+                               return False;
+                       }
+               }       
                tdb_append(tdb, kbuf, dbuf);
                tdb_chainunlock(tdb, kbuf);
 
@@ -210,7 +220,18 @@ BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
        }
 
        /* lock the record for the destination */
-       tdb_chainlock(tdb, kbuf);
+       if (timeout) {
+               if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
+                       DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout));
+                       return False;
+               }
+       } else {
+               if (tdb_chainlock(tdb, kbuf) == -1) {
+                       DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n"));
+                       return False;
+               }
+       }       
+
        old_dbuf = tdb_fetch(tdb, kbuf);
 
        if (!old_dbuf.dptr) {
@@ -236,7 +257,7 @@ BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
                if (!memcmp(ptr, &rec, sizeof(rec))) {
                        if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
                                tdb_chainunlock(tdb, kbuf);
-                               DEBUG(10,("message_send_pid: discarding duplicate message.\n"));
+                               DEBUG(10,("message_send_pid_internal: discarding duplicate message.\n"));
                                SAFE_FREE(dbuf.dptr);
                                SAFE_FREE(old_dbuf.dptr);
                                return True;
@@ -258,6 +279,25 @@ BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
        return message_notify(pid);
 }
 
+/****************************************************************************
+ Send a message to a particular pid - no timeout.
+****************************************************************************/
+
+BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed)
+{
+       return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, 0);
+}
+
+/****************************************************************************
+ Send a message to a particular pid, with timeout in seconds.
+****************************************************************************/
+
+BOOL message_send_pid_with_timeout(pid_t pid, int msg_type, const void *buf, size_t len,
+               BOOL duplicates_allowed, unsigned int timeout)
+{
+       return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, timeout);
+}
+
 /****************************************************************************
  Retrieve all messages for the current process.
 ****************************************************************************/
index a89eb3f13c0c5613af9b17530a867f43a0c3e806..62169e982ee8205bf605d9b19553d68d8a976d9b 100644 (file)
@@ -56,7 +56,7 @@ BOOL print_notify_messages_pending(void)
  Send the batched messages - on a per-printer basis.
 *******************************************************************/
 
-static void print_notify_send_messages_to_printer(const char *printer)
+static void print_notify_send_messages_to_printer(const char *printer, unsigned int timeout)
 {
        char *buf;
        struct notify_queue *pq, *pq_next;
@@ -109,14 +109,14 @@ static void print_notify_send_messages_to_printer(const char *printer)
                return;
 
        for (i = 0; i < num_pids; i++)
-               message_send_pid(pid_list[i], MSG_PRINTER_NOTIFY2, buf, offset, True);
+               message_send_pid_with_timeout(pid_list[i], MSG_PRINTER_NOTIFY2, buf, offset, True, timeout);
 }
 
 /*******************************************************************
  Actually send the batched messages.
 *******************************************************************/
 
-void print_notify_send_messages(void)
+void print_notify_send_messages(unsigned int timeout)
 {
        if (!print_notify_messages_pending())
                return;
@@ -125,7 +125,7 @@ void print_notify_send_messages(void)
                return;
 
        while (print_notify_messages_pending())
-               print_notify_send_messages_to_printer(notify_queue_head->printername);
+               print_notify_send_messages_to_printer(notify_queue_head->printername, timeout);
 
        talloc_destroy_pool(send_ctx);
 }
index 98ec6ce184171819086e411e756663b5242ae4f4..c002abad162ecf365dc20678030cf5716b95f9a8 100644 (file)
@@ -1228,7 +1228,7 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
 
   /* Send any queued printer notify message to interested smbd's. */
 
-  print_notify_send_messages();
+  print_notify_send_messages(0);
 
   /*
    * Modify the select timeout depending upon
index 194f9f2300cb0559445c627b16d1f27ecd5cdccd..9da431e3138061b483b147069df57b9139e0554d 100644 (file)
@@ -554,7 +554,7 @@ void exit_server(const char *reason)
 
        invalidate_all_vuids();
 
-       print_notify_send_messages();   
+       print_notify_send_messages(3); /* 3 second timeout. */
 
        /* delete our entry in the connections database. */
        yield_connection(NULL,"");
index da155de4d7566f0e3854ce567a31ba4a738acdb4..0d8f6128cc5f8e7d0cec89d3b2822227026bdf7d 100644 (file)
@@ -51,7 +51,7 @@ static TDB_DATA make_tdb_data(const char *dptr, size_t dsize)
  Lock a chain with timeout (in seconds).
 ****************************************************************************/
 
-static int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type)
+static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type)
 {
        /* Allow tdb_chainlock to be interrupted by an alarm. */
        int ret;
@@ -72,7 +72,7 @@ static int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned
                alarm(0);
                CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
                if (gotalarm) {
-                       DEBUG(0,("tdb_chainlock_with_timeout: alarm (%u) timed out for key %s in tdb %s\n",
+                       DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n",
                                timeout, key.dptr, tdb->name ));
                        /* TODO: If we time out waiting for a lock, it might
                         * be nice to use F_GETLK to get the pid of the
@@ -85,6 +85,15 @@ static int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned
        return ret;
 }
 
+/****************************************************************************
+ Write lock a chain. Return -1 if timeout or lock failed.
+****************************************************************************/
+
+int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout)
+{
+       return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK);
+}
+
 /****************************************************************************
  Lock a chain by string. Return -1 if timeout or lock failed.
 ****************************************************************************/
@@ -93,7 +102,7 @@ int tdb_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout
 {
        TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);
        
-       return tdb_chainlock_with_timeout(tdb, key, timeout, F_WRLCK);
+       return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK);
 }
 
 /****************************************************************************
@@ -115,7 +124,7 @@ int tdb_read_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int ti
 {
        TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1);
        
-       return tdb_chainlock_with_timeout(tdb, key, timeout, F_RDLCK);
+       return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_RDLCK);
 }
 
 /****************************************************************************
index b22f697dd39402b1bd67bf85ee8ce0e95a3ffc82..d622edd69fd0e93e477aa756e8eb99375d99e2e4 100644 (file)
@@ -641,7 +641,7 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
        /* check if we have any pending print notify messages */
 
        if ( check_notify_msgs )
-               print_notify_send_messages();
+               print_notify_send_messages(0);
                
        return (True);
 }