From 1f5bb4497765f2f56c4caaf14b2bc66c4f97b397 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 4 Oct 1999 03:19:52 +0000 Subject: [PATCH] * We now have a housekeeping thread and a housekeeping queue. --- citadel/ChangeLog | 4 +- citadel/citserver.c | 6 +-- citadel/citserver.h | 2 + citadel/housekeeping.c | 113 ++++++++++++++++++++++++++++++++--------- citadel/housekeeping.h | 1 + citadel/serv_chat.c | 3 -- citadel/sysconfig.h | 9 ++++ citadel/sysdep.c | 40 ++++----------- 8 files changed, 116 insertions(+), 62 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index caa7b8dd5..c62219b14 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,7 @@ $Log$ +Revision 1.377 1999/10/04 03:19:52 ajc +* We now have a housekeeping thread and a housekeeping queue. + Revision 1.376 1999/10/03 21:48:21 ajc * Added serv_upgrade.h to automagically convert pre-5.55 format user records to 5.55 format user records and generate vCards. @@ -1291,4 +1294,3 @@ 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 d800ad5db..195b42637 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -146,10 +146,8 @@ void cleanup_stuff(void *arg) lprintf(7, "cleanup_stuff() calling RemoveContext(%d)\n", CC->cs_pid); RemoveContext(CC); - /* While we still have an extra thread with no user attached to it, - * take the opportunity to do some housekeeping before exiting. - */ - do_housekeeping(); + /* Wake up the housekeeping thread */ + enter_housekeeping_cmd("SCHED_SHUTDOWN"); } diff --git a/citadel/citserver.h b/citadel/citserver.h index 0db931cb8..61b832647 100644 --- a/citadel/citserver.h +++ b/citadel/citserver.h @@ -27,5 +27,7 @@ void deallocate_user_data(struct CitContext *con); void *CtdlGetUserData(unsigned long requested_sym); void CtdlAllocUserData(unsigned long requested_sym, size_t num_bytes); int CtdlGetDynamicSymbol(void); +void enter_housekeeping_cmd(char *); + extern int do_defrag; diff --git a/citadel/housekeeping.c b/citadel/housekeeping.c index d273298b8..ac6d8882e 100644 --- a/citadel/housekeeping.c +++ b/citadel/housekeeping.c @@ -1,6 +1,6 @@ /* * This file contains housekeeping tasks which periodically - * need to be executed. + * need to be executed. It keeps a nice little queue... * * $Id$ */ @@ -9,14 +9,21 @@ #include #include #include +#include #include #include #include #include #include +#include +#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif #ifdef HAVE_PTHREAD_H #include #endif +#include "tools.h" #include "citadel.h" #include "server.h" #include "citserver.h" @@ -25,6 +32,10 @@ #include "sysdep_decls.h" #include "room_ops.h" + +int housepipe[2]; /* This is the queue for housekeeping tasks */ + + /* * Terminate idle sessions. This function pounds through the session table * comparing the current time to each session's time-of-last-command. If an @@ -39,7 +50,6 @@ void terminate_idle_sessions(void) { do { now = time(NULL); session_to_kill = 0; - lprintf(9, "Scanning for timed out sessions...\n"); begin_critical_section(S_SESSION_TABLE); for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) { if ( (ccptr!=CC) @@ -49,43 +59,98 @@ void terminate_idle_sessions(void) { } } end_critical_section(S_SESSION_TABLE); - lprintf(9, "...done scanning.\n"); if (session_to_kill > 0) { lprintf(3, "Session %d timed out. Terminating it...\n", session_to_kill); kill_session(session_to_kill); - lprintf(9, "...done terminating it.\n"); } } while(session_to_kill > 0); } -/* - * Main housekeeping function. This gets run whenever a session terminates. - */ -void do_housekeeping(void) { - lprintf(9, "--- begin housekeeping ---\n"); - begin_critical_section(S_HOUSEKEEPING); - /* - * Terminate idle sessions. - */ - lprintf(7, "Calling terminate_idle_sessions()\n"); - terminate_idle_sessions(); - lprintf(9, "Done with terminate_idle_sessions()\n"); - - /* - * If the server is scheduled to shut down the next time all - * users are logged out, now's the time to do it. - */ +void check_sched_shutdown(void) { if ((ScheduledShutdown == 1) && (ContextList == NULL)) { lprintf(3, "Scheduled shutdown initiating.\n"); master_cleanup(); - } - end_critical_section(S_HOUSEKEEPING); - lprintf(9, "--- end housekeeping ---\n"); } +} + + + +/* + * 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 */ + + 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, 0L, 0L, &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"); + } + + + /* Do whatever this cmd requires */ + if (!strcmp(house_cmd, "MINUTE")) { + terminate_idle_sessions(); + } + + else if (!strcmp(house_cmd, "SCHED_SHUTDOWN")) { + check_sched_shutdown(); + } + + else { + lprintf(7, "Unknown housekeeping command\n"); + } + + } while (did_something); + } +} + + + + + + +void enter_housekeeping_cmd(char *cmd) { + char cmdbuf[256]; + + safestrncpy(cmdbuf, cmd, 256); + begin_critical_section(S_HOUSEKEEPING); + write(housepipe[1], cmdbuf, 256); + end_critical_section(S_HOUSEKEEPING); +} + /* diff --git a/citadel/housekeeping.h b/citadel/housekeeping.h index b10acf351..e6f2d82e5 100644 --- a/citadel/housekeeping.h +++ b/citadel/housekeeping.h @@ -2,3 +2,4 @@ void terminate_idle_sessions (void); void do_housekeeping (void); void check_ref_counts (void); +void housekeeping_loop (void); diff --git a/citadel/serv_chat.c b/citadel/serv_chat.c index ad79093c3..9a3813f7d 100644 --- a/citadel/serv_chat.c +++ b/citadel/serv_chat.c @@ -25,9 +25,6 @@ #include "citadel.h" #include "server.h" #include -#ifdef HAVE_SYS_SELECT_H -#include -#endif #include "serv_chat.h" #include "sysdep_decls.h" #include "citserver.h" diff --git a/citadel/sysconfig.h b/citadel/sysconfig.h index ebee9008e..200fc27ea 100644 --- a/citadel/sysconfig.h +++ b/citadel/sysconfig.h @@ -54,6 +54,15 @@ #define DEFAULT_ENTRY 4 + +/* + * HOUSEKEEPING_WAKEUP is the number of seconds which pass between each pass + * of the housekeeping thread. This normally happens once per minute and there + * isn't any good reason to change it. + */ +#define HOUSEKEEPING_WAKEUP 60 + + /*** STRUCTURE SIZE VARIABLES ***/ /* You may NOT change this value once you set up your system. */ diff --git a/citadel/sysdep.c b/citadel/sysdep.c index 1e8a00fab..2a74ce9cb 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -392,7 +392,6 @@ struct CitContext *MyContext(void) { struct CitContext *CreateNewContext(void) { struct CitContext *me; - lprintf(9, "CreateNewContext: calling malloc()\n"); me = (struct CitContext *) mallok(sizeof(struct CitContext)); if (me == NULL) { lprintf(1, "citserver: can't allocate memory!!\n"); @@ -435,8 +434,6 @@ void RemoveContext(struct CitContext *con) struct CitContext *ptr; lprintf(7, "Starting RemoveContext()\n"); - lprintf(9, "Session count before RemoveContext is %d\n", - session_count()); if (con==NULL) { lprintf(7, "WARNING: RemoveContext() called with null!\n"); return; @@ -450,7 +447,6 @@ void RemoveContext(struct CitContext *con) lprintf(7, "Closing socket %d\n", con->client_socket); close(con->client_socket); - lprintf(9, "Dereferencing session context\n"); if (ContextList==con) { ContextList = ContextList->next; } @@ -462,14 +458,8 @@ void RemoveContext(struct CitContext *con) } } - lprintf(9, "Freeing session context...\n"); phree(con); - lprintf(9, "...done.\n"); end_critical_section(S_SESSION_TABLE); - - lprintf(9, "Session count after RemoveContext is %d\n", - session_count()); - lprintf(7, "Done with RemoveContext\n"); } @@ -482,15 +472,12 @@ int session_count(void) { struct CitContext *ptr; int TheCount = 0; - lprintf(9, "session_count() starting\n"); begin_critical_section(S_SESSION_TABLE); for (ptr = ContextList; ptr != NULL; ptr = ptr->next) { ++TheCount; - lprintf(9, "Counted session %3d (%d)\n", ptr->cs_pid, TheCount); } end_critical_section(S_SESSION_TABLE); - lprintf(9, "session_count() finishing\n"); return(TheCount); } @@ -641,7 +628,6 @@ void kill_session(int session_to_kill) { struct CitContext *ptr; THREAD killme = 0; - lprintf(9, "kill_session() scanning for thread to cancel...\n"); begin_critical_section(S_SESSION_TABLE); for (ptr = ContextList; ptr != NULL; ptr = ptr->next) { if (ptr->cs_pid == session_to_kill) { @@ -649,11 +635,9 @@ void kill_session(int session_to_kill) { } } end_critical_section(S_SESSION_TABLE); - lprintf(9, "kill_session() finished scanning.\n"); if (killme != 0) { #ifdef HAVE_PTHREAD_CANCEL - lprintf(9, "calling pthread_cancel()\n"); pthread_cancel(killme); #else pthread_kill(killme, SIGUSR1); @@ -800,6 +784,7 @@ int main(int argc, char **argv) int alen; /* Data for master socket */ int ssock; /* Descriptor for master socket */ THREAD SessThread; /* Thread descriptor */ + THREAD HousekeepingThread; /* Thread descriptor */ pthread_attr_t attr; /* Thread attributes */ struct CitContext *con; /* Temporary context pointer */ char tracefile[128]; /* Name of file to log traces to */ @@ -921,7 +906,15 @@ int main(int argc, char **argv) DLoader_Init(moddir); free(moddir); } - lprintf(9, "Modules done initializing.\n"); + + 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)); + } /* * Endless loop. Listen on the master socket. When a connection @@ -946,24 +939,20 @@ int main(int argc, char **argv) } else { lprintf(7, "citserver: Client socket %d\n", ssock); - lprintf(9, "creating context\n"); con = CreateNewContext(); con->client_socket = ssock; /* Set the SO_REUSEADDR socket option */ - lprintf(9, "setting socket options\n"); i = 1; setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); /* set attributes for the new thread */ - lprintf(9, "setting thread attributes\n"); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); /* now create the thread */ - lprintf(9, "creating thread\n"); if (pthread_create(&SessThread, &attr, (void* (*)(void*)) sd_context_loop, con) @@ -973,15 +962,6 @@ int main(int argc, char **argv) strerror(errno)); } - /* detach the thread - * (defunct -- now done at thread creation time) - * if (pthread_detach(&SessThread) != 0) { - * lprintf(1, - * "citserver: can't detach thread: %s\n", - * strerror(errno)); - * } - */ - lprintf(9, "done!\n"); } } master_cleanup(); -- 2.30.2