Fixed the clean up of Contexts when we exit.
authorDave West <davew@uncensored.citadel.org>
Mon, 26 Nov 2007 01:20:56 +0000 (01:20 +0000)
committerDave West <davew@uncensored.citadel.org>
Mon, 26 Nov 2007 01:20:56 +0000 (01:20 +0000)
Do we need to clean up some of the contexts pointers too?
serv_calendar.c now cleans up with a CleanupHook.

citadel/modules/calendar/serv_calendar.c
citadel/modules/chat/serv_chat.c
citadel/server_main.c
citadel/sysdep.c
citadel/sysdep_decls.h

index a560993376eddc6e92a9d8e82deb1e47e38bcf81..345aaa5a80bb16b4fcabe626e8ffc73c0b085086 100644 (file)
@@ -2160,6 +2160,12 @@ void ical_fixed_output(char *ptr, int len) {
 }
 
 
+
+void serv_calendar_destroy(void)
+{
+       icaltimezone_free_builtin_timezones();
+}
+
 #endif /* CITADEL_WITH_CALENDAR_SERVICE */
 
 /*
@@ -2177,6 +2183,7 @@ CTDL_MODULE_INIT(calendar)
                CtdlRegisterSessionHook(ical_session_startup, EVT_START);
                CtdlRegisterSessionHook(ical_session_shutdown, EVT_STOP);
                CtdlRegisterFixedOutputHook("text/calendar", ical_fixed_output);
+               CtdlRegisterCleanupHook(serv_calendar_destroy);
 #endif
        }
        
@@ -2184,11 +2191,3 @@ CTDL_MODULE_INIT(calendar)
        return "$Id$";
 }
 
-
-
-void serv_calendar_destroy(void)
-{
-#ifdef CITADEL_WITH_CALENDAR_SERVICE
-       icaltimezone_free_builtin_timezones();
-#endif
-}
index c77b36ab902f7cc700d7ded0eb3d5c8fc866c7ba..836e0affaae2f6dca2b5dec3463c5dc1a132b5f2 100644 (file)
@@ -424,9 +424,9 @@ void delete_instant_messages(void) {
                        free(CC->FirstExpressMessage->text);
                free(CC->FirstExpressMessage);
                CC->FirstExpressMessage = ptr;
-               }
-       end_critical_section(S_SESSION_TABLE);
        }
+       end_critical_section(S_SESSION_TABLE);
+}
 
 
 
index b553904f0d08922bce0cb88805ece323cb24c199..e0f3e5c613825d9e643251e0cb0717561e8f3d30 100644 (file)
@@ -349,7 +349,6 @@ int main(int argc, char **argv)
        /*
         * If the above loop exits we must be shutting down since we obviously have no threads
         */
-               
        master_cleanup(exit_signal);
        return(0);
 }
index 87c7a9e8d0428f8ab61effb3cbcdd40f7daf1133..7f6dbc075589a6e934b789a18d250416b0d84c34 100644 (file)
@@ -259,7 +259,8 @@ void init_sysdep(void) {
         * whole Citadel service would come down whenever a single client
         * socket breaks.
         */
-       signal(SIGPIPE, SIG_IGN);
+       //signal(SIGPIPE, SIG_IGN);
+       signal(SIGPIPE, signal_cleanup);
 }
 
 
@@ -754,13 +755,39 @@ int client_getln(char *buf, int bufsize)
 }
 
 
+/*
+ * Cleanup any contexts that are left lying around
+ */
+void context_cleanup(void)
+{
+       struct CitContext *ptr = NULL;
+       struct CitContext *rem = NULL;
+
+       /*
+        * Clean up the contexts.
+        * There are no threads so no critical_section stuff is needed.
+        */
+       ptr = ContextList;
+       while (ptr != NULL){
+               /* Remove the session from the active list */
+               rem = ptr->next;
+               --num_sessions;
+               
+               lprintf(CTDL_DEBUG, "Purging session %d\n", ptr->cs_pid);
+               RemoveContext(ptr);
+               free (ptr);
+               ptr = rem;
+       }
+       
+}
+
 
 /*
  * The system-dependent part of master_cleanup() - close the master socket.
  */
 void sysdep_master_cleanup(void) {
        struct ServiceFunctionHook *serviceptr;
-
+       
        /*
         * close all protocol master sockets
         */
@@ -782,10 +809,12 @@ void sysdep_master_cleanup(void) {
                        unlink(serviceptr->sockpath);
                }
        }
+       
+       context_cleanup();
+       
 #ifdef HAVE_OPENSSL
        destruct_ssl();
 #endif
-       serv_calendar_destroy();        // FIXME: Shouldn't be here, should be by a cleanup hook surely.
        CtdlDestroyProtoHooks();
        CtdlDestroyDeleteHooks();
        CtdlDestroyXmsgHooks();
@@ -803,7 +832,6 @@ void sysdep_master_cleanup(void) {
 
 
 
-
 /*
  * Terminate another session.
  * (This could justifiably be moved out of sysdep.c because it
@@ -1544,6 +1572,8 @@ struct CtdlThreadNode *ctdl_internal_create_thread(char *name, long flags, void
 
        this_thread->next = CtdlThreadList;
        CtdlThreadList = this_thread;
+       if (this_thread->next)
+               this_thread->next->prev = this_thread;
        // Register for tracing
        #ifdef HAVE_BACKTRACE
        eCrash_RegisterThread(this_thread->name, 0);
@@ -1582,7 +1612,7 @@ struct CtdlThreadNode *CtdlThreadCreate(char *name, long flags, void *(*thread_f
  * if such an action is appropriate.
  */
 void dead_session_purge(int force) {
-       struct CitContext *ptr;         /* general-purpose utility pointer */
+       struct CitContext *ptr, *ptr2;          /* general-purpose utility pointer */
        struct CitContext *rem = NULL;  /* list of sessions to be destroyed */
 
        if (force == 0) {
@@ -1593,25 +1623,28 @@ void dead_session_purge(int force) {
        time(&last_purge);
 
        begin_critical_section(S_SESSION_TABLE);
-       for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
-               if ( (ptr->state == CON_IDLE) && (ptr->kill_me) ) {
-
+       ptr = ContextList;
+       while (ptr) {
+               ptr2 = ptr;
+               ptr = ptr->next;
+               
+               if ( (ptr2->state == CON_IDLE) && (ptr2->kill_me) ) {
                        /* Remove the session from the active list */
-                       if (ptr->prev) {
-                               ptr->prev->next = ptr->next;
+                       if (ptr2->prev) {
+                               ptr2->prev->next = ptr2->next;
                        }
                        else {
-                               ContextList = ptr->next;
+                               ContextList = ptr2->next;
                        }
-                       if (ptr->next) {
-                               ptr->next->prev = ptr->prev;
+                       if (ptr2->next) {
+                               ptr2->next->prev = ptr2->prev;
                        }
 
                        --num_sessions;
 
                        /* And put it on our to-be-destroyed list */
-                       ptr->next = rem;
-                       rem = ptr;
+                       ptr2->next = rem;
+                       rem = ptr2;
 
                }
        }
@@ -1867,10 +1900,7 @@ SKIP_SELECT:
                do_housekeeping();
                check_sched_shutdown();
        }
-       if (con != NULL) free (con);//// TODO: could this harm other threads? 
        /* If control reaches this point, the server is shutting down */        
-       begin_critical_section(S_THREAD_LIST);
-       end_critical_section(S_THREAD_LIST);
        return(NULL);
 }
 
index 3adcf61f6b3ca1a9db664f3f4b771fd5a2bd057a..d7953b99f75cf908bd901e7e0b59702a3d15e839 100644 (file)
@@ -79,6 +79,7 @@ void start_daemon (int do_close_stdio);
 void cmd_nset (char *cmdbuf);
 int convert_login (char *NameToConvert);
 void *worker_thread (void *arg);
+void *context_cleanup_thread (void *arg);
 void become_session(struct CitContext *which_con);
 void InitializeMasterCC(void);
 void init_master_fdset(void);