From bbf9f09ee5c58e348eef33448d2c38e588adb66a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 30 Jan 2003 23:55:58 +0000 Subject: Add 3 second timeout when terminating server and sending print notify messages. Stops build-up of large numbers of smbd's waiting to terminate on large print throughput. Jeremy. (This used to be commit 07efebb98473cb3d4adc6b2e0afef3f06dcc99b8) --- source3/lib/messages.c | 50 +++++++++++++++++++++++++++++++++++++++++----- source3/printing/notify.c | 8 ++++---- source3/smbd/process.c | 2 +- source3/smbd/server.c | 2 +- source3/tdb/tdbutil.c | 17 ++++++++++++---- source3/utils/smbcontrol.c | 2 +- 6 files changed, 65 insertions(+), 16 deletions(-) (limited to 'source3') diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 53c9e3d2bc..3603758e9f 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -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. ****************************************************************************/ diff --git a/source3/printing/notify.c b/source3/printing/notify.c index a89eb3f13c..62169e982e 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -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); } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 98ec6ce184..c002abad16 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -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 diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 1d1061f6d8..e3cf9b92fd 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -550,7 +550,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,""); diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index da155de4d7..0d8f6128cc 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/tdb/tdbutil.c @@ -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); } /**************************************************************************** diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 10ebf019c5..8b5909e77a 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -644,7 +644,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); } -- cgit