mirror of
https://github.com/samba-team/samba.git
synced 2025-08-05 12:22:11 +03:00
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 07efebb984
)
This commit is contained in:
@ -160,8 +160,8 @@ static BOOL message_notify(pid_t pid)
|
|||||||
Send a message to a particular pid.
|
Send a message to a particular pid.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
|
static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf, size_t len,
|
||||||
BOOL duplicates_allowed)
|
BOOL duplicates_allowed, unsigned int timeout)
|
||||||
{
|
{
|
||||||
TDB_DATA kbuf;
|
TDB_DATA kbuf;
|
||||||
TDB_DATA dbuf;
|
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. */
|
/* If duplicates are allowed we can just append the message and return. */
|
||||||
|
|
||||||
/* lock the record for the destination */
|
/* 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_append(tdb, kbuf, dbuf);
|
||||||
tdb_chainunlock(tdb, kbuf);
|
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 */
|
/* 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);
|
old_dbuf = tdb_fetch(tdb, kbuf);
|
||||||
|
|
||||||
if (!old_dbuf.dptr) {
|
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 (!memcmp(ptr, &rec, sizeof(rec))) {
|
||||||
if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
|
if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
|
||||||
tdb_chainunlock(tdb, kbuf);
|
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(dbuf.dptr);
|
||||||
SAFE_FREE(old_dbuf.dptr);
|
SAFE_FREE(old_dbuf.dptr);
|
||||||
return True;
|
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);
|
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.
|
Retrieve all messages for the current process.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -56,7 +56,7 @@ BOOL print_notify_messages_pending(void)
|
|||||||
Send the batched messages - on a per-printer basis.
|
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;
|
char *buf;
|
||||||
struct notify_queue *pq, *pq_next;
|
struct notify_queue *pq, *pq_next;
|
||||||
@ -109,14 +109,14 @@ static void print_notify_send_messages_to_printer(const char *printer)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < num_pids; i++)
|
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.
|
Actually send the batched messages.
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
|
||||||
void print_notify_send_messages(void)
|
void print_notify_send_messages(unsigned int timeout)
|
||||||
{
|
{
|
||||||
if (!print_notify_messages_pending())
|
if (!print_notify_messages_pending())
|
||||||
return;
|
return;
|
||||||
@ -125,7 +125,7 @@ void print_notify_send_messages(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
while (print_notify_messages_pending())
|
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);
|
talloc_destroy_pool(send_ctx);
|
||||||
}
|
}
|
||||||
|
@ -1228,7 +1228,7 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
|
|||||||
|
|
||||||
/* Send any queued printer notify message to interested smbd's. */
|
/* 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
|
* Modify the select timeout depending upon
|
||||||
|
@ -550,7 +550,7 @@ void exit_server(const char *reason)
|
|||||||
|
|
||||||
invalidate_all_vuids();
|
invalidate_all_vuids();
|
||||||
|
|
||||||
print_notify_send_messages();
|
print_notify_send_messages(3); /* 3 second timeout. */
|
||||||
|
|
||||||
/* delete our entry in the connections database. */
|
/* delete our entry in the connections database. */
|
||||||
yield_connection(NULL,"");
|
yield_connection(NULL,"");
|
||||||
|
@ -51,7 +51,7 @@ static TDB_DATA make_tdb_data(const char *dptr, size_t dsize)
|
|||||||
Lock a chain with timeout (in seconds).
|
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. */
|
/* Allow tdb_chainlock to be interrupted by an alarm. */
|
||||||
int ret;
|
int ret;
|
||||||
@ -72,7 +72,7 @@ static int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned
|
|||||||
alarm(0);
|
alarm(0);
|
||||||
CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
|
CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
|
||||||
if (gotalarm) {
|
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 ));
|
timeout, key.dptr, tdb->name ));
|
||||||
/* TODO: If we time out waiting for a lock, it might
|
/* TODO: If we time out waiting for a lock, it might
|
||||||
* be nice to use F_GETLK to get the pid of the
|
* 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;
|
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.
|
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);
|
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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -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 */
|
/* check if we have any pending print notify messages */
|
||||||
|
|
||||||
if ( check_notify_msgs )
|
if ( check_notify_msgs )
|
||||||
print_notify_send_messages();
|
print_notify_send_messages(0);
|
||||||
|
|
||||||
return (True);
|
return (True);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user