From 7c951cae9394503de49af38b5231ed049f2cac5e Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 11 Dec 2000 06:08:41 +0000 Subject: [PATCH] * Removed the housekeeper thread, moved terminate_idle_sessions() out to a timer event, and check_sched_shutdown() to the end of the worker thread loop. Seems to have improved reliability (but why?) --- citadel/ChangeLog | 6 +++ citadel/citserver.c | 5 +- citadel/database_sleepycat.c | 1 + citadel/housekeeping.c | 92 ++---------------------------------- citadel/housekeeping.h | 7 ++- citadel/sysdep.c | 30 ++++-------- 6 files changed, 25 insertions(+), 116 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index f8b1d9121..43342a3e9 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,9 @@ $Log$ + Revision 573.47 2000/12/11 06:08:41 ajc + * Removed the housekeeper thread, moved terminate_idle_sessions() out to a + timer event, and check_sched_shutdown() to the end of the worker thread + loop. Seems to have improved reliability (but why?) + Revision 573.46 2000/12/11 03:22:11 ajc * Added server-side REQT command to issue client termination requests @@ -2207,3 +2212,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/citserver.c b/citadel/citserver.c index 8b8477175..3c7f6cc29 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -203,10 +203,7 @@ void RemoveContext (struct CitContext *con) lprintf(7, "Closing socket %d\n", con->client_socket); close(con->client_socket); - /* Tell the housekeeping thread to check to see if this is the time - * to initiate a scheduled shutdown event. - */ - enter_housekeeping_cmd("SCHED_SHUTDOWN"); + /* This is where we used to check for scheduled shutdowns. */ /* Free up the memory used by this context */ phree(con); diff --git a/citadel/database_sleepycat.c b/citadel/database_sleepycat.c index 2781ea9d0..10be08d78 100644 --- a/citadel/database_sleepycat.c +++ b/citadel/database_sleepycat.c @@ -405,6 +405,7 @@ void cdb_begin_transaction(void) { void cdb_end_transaction(void) { #ifdef TRANSACTION_BASED begin_critical_section(S_DATABASE); + if (MYTID == NULL) lprintf(1, "WARNING: txn_commit(NULL) !!\n"); txn_commit(MYTID, 0); end_critical_section(S_DATABASE); #endif diff --git a/citadel/housekeeping.c b/citadel/housekeeping.c index 15f43df16..a16ce58a6 100644 --- a/citadel/housekeeping.c +++ b/citadel/housekeeping.c @@ -1,8 +1,7 @@ /* * $Id$ * - * This file contains housekeeping tasks which periodically - * need to be executed. It keeps a nice little queue... + * This file contains miscellaneous housekeeping tasks. * */ @@ -45,6 +44,7 @@ void terminate_idle_sessions(void) { struct CitContext *ccptr; time_t now; int session_to_kill; + int killed = 0; now = time(NULL); session_to_kill = 0; @@ -54,9 +54,11 @@ void terminate_idle_sessions(void) { && (config.c_sleeping > 0) && (now - (ccptr->lastcmd) > config.c_sleeping) ) { ccptr->kill_me = 1; + ++killed; } } end_critical_section(S_SESSION_TABLE); + lprintf(9, "Terminated %d idle sessions\n", killed); } @@ -70,92 +72,6 @@ void check_sched_shutdown(void) { -/* - * This is the main loop for the housekeeping thread. It remains active - * during the entire run of the server. - */ -void housekeeping_loop(void) { - long flags; - struct timeval tv; - fd_set readfds; - int did_something; - char house_cmd[256]; /* Housekeep cmds are always 256 bytes long */ - char cmd[256]; - - if (pipe(housepipe) != 0) { - lprintf(1, "FATAL ERROR: can't create housekeeping pipe: %s\n", - strerror(errno)); - exit(0); - } - - flags = (long) fcntl(housepipe[1], F_GETFL); - flags |= O_NONBLOCK; - fcntl(housepipe[1], F_SETFL, flags); - - while(1) { - do { - did_something = 0; - tv.tv_sec = HOUSEKEEPING_WAKEUP; - tv.tv_usec = 0; - FD_ZERO(&readfds); - FD_SET(housepipe[0], &readfds); - select(housepipe[0] + 1, &readfds, NULL, NULL, &tv); - if (FD_ISSET(housepipe[0], &readfds)) { - did_something = 1; - } - - if (did_something) { - read(housepipe[0], house_cmd, 256); - } - else { - memset(house_cmd, 0, 256); - strcpy(house_cmd, "MINUTE"); - } - - extract(cmd, house_cmd, 0); - cdb_begin_transaction(); - - /* Do whatever this cmd requires */ - - /* Once-every-minute housekeeper */ - if (!strcmp(cmd, "MINUTE")) { - terminate_idle_sessions(); - } - - /* Scheduled shutdown housekeeper */ - else if (!strcmp(cmd, "SCHED_SHUTDOWN")) { - check_sched_shutdown(); - } - - /* Unknown */ - else { - lprintf(7, "Unknown housekeeping command\n"); - } - - cdb_end_transaction(); - - } while (did_something); - } -} - - - - - - -void enter_housekeeping_cmd(char *cmd) { - char cmdbuf[256]; - - lprintf(9, "enter_housekeeping_cmd(%s)\n", cmd); - safestrncpy(cmdbuf, cmd, 256); - begin_critical_section(S_HOUSEKEEPING); - write(housepipe[1], cmdbuf, 256); - end_critical_section(S_HOUSEKEEPING); - lprintf(9, "leaving enter_housekeeping_cmd()\n"); -} - - - /* * Check (and fix) floor reference counts. This doesn't need to be done * very often, since the counts should remain correct during normal operation. diff --git a/citadel/housekeeping.h b/citadel/housekeeping.h index e6f2d82e5..f7b99bc5f 100644 --- a/citadel/housekeeping.h +++ b/citadel/housekeeping.h @@ -1,5 +1,4 @@ /* $Id$ */ -void terminate_idle_sessions (void); -void do_housekeeping (void); -void check_ref_counts (void); -void housekeeping_loop (void); +void terminate_idle_sessions(void); +void check_sched_shutdown(void); +void check_ref_counts(void); diff --git a/citadel/sysdep.c b/citadel/sysdep.c index 4ec3c514e..e592b1415 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -848,7 +848,7 @@ void init_master_fdset(void) { */ int main(int argc, char **argv) { - pthread_t HousekeepingThread; /* Thread descriptor */ + pthread_t WorkerThread; /* Thread descriptor */ pthread_attr_t attr; /* Thread attributes */ char tracefile[128]; /* Name of file to log traces to */ int a, i; /* General-purpose variables */ @@ -995,20 +995,8 @@ int main(int argc, char **argv) } } - - - /* - * Create the housekeeper thread - */ - lprintf(7, "Starting housekeeper thread\n"); - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if (pthread_create(&HousekeepingThread, &attr, - (void* (*)(void*)) housekeeping_loop, NULL) != 0) { - lprintf(1, "Can't create housekeeping thead: %s\n", - strerror(errno)); - } - + /* We want to check for idle sessions once per minute */ + CtdlRegisterSessionHook(terminate_idle_sessions, EVT_TIMER); /* * Now create a bunch of worker threads. @@ -1016,7 +1004,7 @@ int main(int argc, char **argv) for (i=0; i<(config.c_min_workers-1); ++i) { pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if (pthread_create(&HousekeepingThread, &attr, + if (pthread_create(&WorkerThread, &attr, (void* (*)(void*)) worker_thread, NULL) != 0) { lprintf(1, "Can't create worker thead: %s\n", strerror(errno)); @@ -1061,6 +1049,8 @@ void worker_thread(void) { while (!time_to_die) { + cdb_begin_transaction(); + /* * A naive implementation would have all idle threads * calling select() and then they'd all wake up at once. We @@ -1185,9 +1175,7 @@ SETUP_FD: memcpy(&readfds, &masterfds, sizeof masterfds); /* We're bound to a session, now do *one* command */ if (bind_me != NULL) { become_session(bind_me); - cdb_begin_transaction(); CC->h_command_function(); - cdb_end_transaction(); become_session(NULL); bind_me->state = CON_IDLE; if (bind_me->kill_me == 1) { @@ -1200,10 +1188,12 @@ SETUP_FD: memcpy(&readfds, &masterfds, sizeof masterfds); dead_session_purge(); if ((time(NULL) - last_timer) > 60L) { last_timer = time(NULL); - cdb_begin_transaction(); PerformSessionHooks(EVT_TIMER); - cdb_end_transaction(); } + + check_sched_shutdown(); + + cdb_end_transaction(); } /* If control reaches this point, the server is shutting down */ -- 2.30.2