* Logging to stderr no longer uses syslog()
authorArt Cancro <ajc@citadel.org>
Sun, 20 Mar 2005 22:55:58 +0000 (22:55 +0000)
committerArt Cancro <ajc@citadel.org>
Sun, 20 Mar 2005 22:55:58 +0000 (22:55 +0000)
* Reworked the way dead sessions are purged.  More efficient and more
  reliable now.

citadel/ChangeLog
citadel/citserver.c
citadel/server_main.c
citadel/sysdep.c
citadel/sysdep_decls.h

index 5c382d9e50c03b9013d9853e5407930855a8e8a7..bd015638baedcf859d2e4feb5f1a4e9510a24867 100644 (file)
@@ -1,4 +1,9 @@
  $Log$
+ Revision 641.29  2005/03/20 22:55:58  ajc
+ * Logging to stderr no longer uses syslog()
+ * Reworked the way dead sessions are purged.  More efficient and more
+   reliable now.
+
  Revision 641.28  2005/03/18 21:40:36  ajc
  * Minor bugfix to previous checkin
 
@@ -6548,4 +6553,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
-
index edc26d9d4c7023c566bf2cb9b8d476108f4ab829..909bdfd24c0138811d9887694d9cca4215b2dc30 100644 (file)
@@ -170,33 +170,16 @@ void master_cleanup(int exitcode) {
 
 
 /*
- * Terminate a session and remove its context data structure.
+ * Terminate a session.
  */
 void RemoveContext (struct CitContext *con)
 {
        if (con==NULL) {
-               lprintf(CTDL_ERR, "WARNING: RemoveContext() called with NULL!\n");
+               lprintf(CTDL_ERR,
+                       "WARNING: RemoveContext() called with NULL!\n");
                return;
        }
-       lprintf(CTDL_DEBUG, "RemoveContext() called\n");
-
-       /* Remove the context from the global context list.  This needs
-        * to get done FIRST to avoid concurrency problems.  It is *vitally*
-        * important to keep num_sessions accurate!!
-        */
-       lprintf(CTDL_DEBUG, "Removing context for session %d\n", con->cs_pid);
-       begin_critical_section(S_SESSION_TABLE);
-       if (con->prev) {
-               con->prev->next = con->next;
-       }
-       else {
-               ContextList = con->next;
-       }
-       if (con->next) {
-               con->next->prev = con->prev;
-       }
-       --num_sessions;
-       end_critical_section(S_SESSION_TABLE);
+       lprintf(CTDL_DEBUG, "RemoveContext() session %d\n", con->cs_pid);
 
        /* Run any cleanup routines registered by loadable modules.
         * Note: We have to "become_session()" because the cleanup functions
@@ -217,11 +200,6 @@ void RemoveContext (struct CitContext *con)
        lprintf(CTDL_DEBUG, "Closing socket %d\n", con->client_socket);
        close(con->client_socket);
 
-       /* This is where we used to check for scheduled shutdowns. */
-
-       /* Free up the memory used by this context */
-       free(con);
-
        lprintf(CTDL_DEBUG, "Done with RemoveContext()\n");
 }
 
index 9e2f1d54782128a3df9c2ccaadec87d498e5fdf7..b7b1ac0c87ebe5724f915477e8979dfa1d882b30 100644 (file)
@@ -87,6 +87,7 @@ int main(int argc, char **argv)
                if (!strncmp(argv[a], "-l", 2)) {
                        safestrncpy(facility, argv[a], sizeof(facility));
                        syslog_facility = SyslogFacility(facility);
+                       enable_syslog = 1;
                }
 
                /* run in the background if -d was specified */
@@ -133,12 +134,22 @@ int main(int argc, char **argv)
        }
 
        /* daemonize, if we were asked to */
-       if (running_as_daemon) { start_daemon(0); drop_root_perms = 1; }
+       if (running_as_daemon) {
+               start_daemon(0);
+               drop_root_perms = 1;
+       }
 
        /* initialize the syslog facility */
-       if (running_as_daemon) openlog("Citadel", LOG_NDELAY, syslog_facility);
-       else openlog("Citadel", LOG_PERROR|LOG_NDELAY, syslog_facility);
-       setlogmask(LOG_UPTO(verbosity));
+       if (enable_syslog) {
+               if (running_as_daemon) {
+                       openlog("citadel", LOG_NDELAY, syslog_facility);
+               }
+               else {
+                       openlog("citadel", LOG_PERROR|LOG_NDELAY,
+                               syslog_facility);
+               }
+               setlogmask(LOG_UPTO(verbosity));
+       }
        
        /* Tell 'em who's in da house */
        lprintf(CTDL_NOTICE, "\n");
index b571b8b478674dbc558c7c41d32f78a997f4d56e..1380be84eb9a3dc89ef9559a7c25b27fac87dacd 100644 (file)
@@ -99,13 +99,12 @@ static int num_threads = 0;                 /* Current number of threads */
 int num_sessions = 0;                          /* Current number of sessions */
 
 int syslog_facility = (-1);
-
+int enable_syslog = 0;
+extern int running_as_daemon;
 
 /*
  * lprintf()  ...   Write logging information
  */
-extern int running_as_daemon;
-static int enable_syslog = 1;
 void lprintf(enum LogLevel loglevel, const char *format, ...) {   
        va_list arg_ptr;
 
@@ -199,7 +198,8 @@ void init_sysdep(void) {
         * session to which the calling thread is currently bound.
         */
        if (pthread_key_create(&MyConKey, NULL) != 0) {
-               lprintf(CTDL_CRIT, "Can't create TSD key!!  %s\n", strerror(errno));
+               lprintf(CTDL_CRIT, "Can't create TSD key: %s\n",
+                       strerror(errno));
        }
 
        /*
@@ -312,14 +312,16 @@ int ig_tcp_server(char *ip_addr, int port_number, int queue_len)
 
        /* set to nonblock - we need this for some obscure situations */
        if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't set socket to non-blocking: %s\n",
+               lprintf(CTDL_EMERG,
+                       "citserver: Can't set socket to non-blocking: %s\n",
                        strerror(errno));
                close(s);
                return(-1);
        }
 
        if (listen(s, actual_queue_len) < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't listen: %s\n", strerror(errno));
+               lprintf(CTDL_EMERG, "citserver: Can't listen: %s\n",
+                       strerror(errno));
                close(s);
                return(-1);
        }
@@ -368,14 +370,16 @@ int ig_uds_server(char *sockpath, int queue_len)
 
        /* set to nonblock - we need this for some obscure situations */
        if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't set socket to non-blocking: %s\n",
+               lprintf(CTDL_EMERG,
+                       "citserver: Can't set socket to non-blocking: %s\n",
                        strerror(errno));
                close(s);
                return(-1);
        }
 
        if (listen(s, actual_queue_len) < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't listen: %s\n", strerror(errno));
+               lprintf(CTDL_EMERG, "citserver: Can't listen: %s\n",
+                       strerror(errno));
                return(-1);
        }
 
@@ -426,7 +430,6 @@ struct CitContext *CreateNewContext(void) {
         */
        me->state = CON_EXECUTING;
 
-
        /*
         * Generate a unique session number and insert this context into
         * the list.
@@ -826,7 +829,8 @@ void create_worker(void) {
  * if such an action is appropriate.
  */
 void dead_session_purge(int force) {
-       struct CitContext *ptr, *rem;
+       struct CitContext *ptr;         /* general-purpose utility pointer */
+       struct CitContext *rem = NULL;  /* list of sessions to be destroyed */
 
        if (force == 0) {
                if ( (time(NULL) - last_purge) < 5 ) {
@@ -835,28 +839,44 @@ void dead_session_purge(int force) {
        }
        time(&last_purge);
 
-       do {
-               rem = NULL;
-               begin_critical_section(S_SESSION_TABLE);
-               for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
-                       if ( (ptr->state == CON_IDLE) && (ptr->kill_me) ) {
-                               rem = ptr;
+       begin_critical_section(S_SESSION_TABLE);
+       for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
+               if ( (ptr->state == CON_IDLE) && (ptr->kill_me) ) {
+
+                       /* Remove the session from the active list */
+                       if (ptr->prev) {
+                               ptr->prev->next = ptr->next;
                        }
-               }
-               end_critical_section(S_SESSION_TABLE);
+                       else {
+                               ContextList = ptr->next;
+                       }
+                       if (ptr->next) {
+                               ptr->next->prev = ptr->prev;
+                       }
+
+                       --num_sessions;
+
+                       /* And put it on our to-be-destroyed list */
+                       ptr->next = rem;
+                       rem = ptr;
 
-               /* RemoveContext() enters its own S_SESSION_TABLE critical
-                * section, so we have to do it like this.
-                */     
-               if (rem != NULL) {
-                       lprintf(CTDL_DEBUG, "Purging session %d\n", rem->cs_pid);
-                       RemoveContext(rem);
                }
+       }
+       end_critical_section(S_SESSION_TABLE);
 
-       } while (rem != NULL);
+       /* Now that we no longer have the session list locked, we can take
+        * our time and destroy any sessions on the to-be-killed list, which
+        * is allocated privately on this thread's stack.
+        */
+       while (rem != NULL) {
+               lprintf(CTDL_DEBUG, "Purging session %d\n", rem->cs_pid);
+               RemoveContext(rem);
+               ptr = rem;
+               rem = rem->next;
+               free(ptr);
+       }
 
        /* Raise the size of the worker thread pool if necessary. */
-
        if ( (num_sessions > num_threads)
           && (num_threads < config.c_max_workers) ) {
                begin_critical_section(S_WORKER_LIST);
index f2b6fe50b29b45870366a8f6510c831f3d3df388..d80a1baf6556cbcec932958a70f95c64af7e575e 100644 (file)
@@ -41,6 +41,8 @@ void lprintf (enum LogLevel loglevel, const char *format, ...);
 void cprintf (const char *format, ...);
 #endif
 
+extern int enable_syslog;
+
 void init_sysdep (void);
 void begin_critical_section (int which_one);
 void end_critical_section (int which_one);