X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fcitserver.c;h=c9e9c1af3059f44dfe4d0cb3c05d8bf58e1486b6;hb=4d9a00d2846d49086faf8dfefb832925be9e19b3;hp=0e5c9e90856aebed5bd2d4ddf7861e8d55cc9a59;hpb=d6afb4bcf56a594be1833988b5cc485ff797b671;p=citadel.git diff --git a/citadel/citserver.c b/citadel/citserver.c index 0e5c9e908..c9e9c1af3 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -10,9 +10,6 @@ #include #include #include -#ifdef HAVE_PTHREAD_H -#include -#endif #include #include #include @@ -116,34 +113,72 @@ void deallocate_user_data(struct CitContext *con) /* - * Gracefully terminate the session and thread. - * (This is called as a cleanup handler by the thread library.) - * - * All NON-system-dependent stuff is done in this function. - * System-dependent session/thread cleanup is in cleanup() in sysdep.c + * Gracefully terminate a session which is marked as CON_DYING. */ -void cleanup(int exit_code) +void cleanup(struct CitContext *con) { - lprintf(9, "cleanup(%d) called\n", exit_code); + struct CitContext *ptr = NULL; + struct CitContext *ToFree = NULL; + + lprintf(9, "cleanup() called\n"); + if (con==NULL) { + lprintf(5, "WARNING: cleanup() called with NULL!\n"); + return; + } - lprintf(7, "Calling logout(%d)\n", CC->cs_pid); - logout(CC); + lprintf(7, "Calling logout(%d)\n", con->cs_pid); + logout(con); - rec_log(CL_TERMINATE,CC->curr_user); - unlink(CC->temp); - lprintf(3, "citserver[%3d]: ended.\n",CC->cs_pid); + rec_log(CL_TERMINATE, con->curr_user); + unlink(con->temp); + lprintf(3, "citserver[%3d]: ended.\n", con->cs_pid); /* Run any cleanup routines registered by loadable modules */ PerformSessionHooks(EVT_STOP); - syslog(LOG_NOTICE,"session %d ended", CC->cs_pid); + syslog(LOG_NOTICE,"session %d ended", con->cs_pid); /* Deallocate any user-data attached to this session */ - deallocate_user_data(CC); + deallocate_user_data(con); + + /* And flag the context as in need of being killed. + * (Probably done already, but just in case) + */ + con->state = CON_DYING; + + /* delete context */ + + lprintf(7, "Removing context\n"); + + begin_critical_section(S_SESSION_TABLE); + if (ContextList == con) { + ToFree = ContextList; + ContextList = ContextList->next; + } + else { + for (ptr = ContextList; ptr != NULL; ptr = ptr->next) { + if (ptr->next == con) { + ToFree = ptr->next; + ptr->next = ptr->next->next; + } + } + } + end_critical_section(S_SESSION_TABLE); + + lprintf(7, "Closing socket %d\n", ToFree->client_socket); + close(ToFree->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"); + + /* Free up the memory used by this context */ + phree(ToFree); + + lprintf(7, "Done with cleanup()\n"); +} - /* And flag the context as in need of being killed */ - CC->state = CON_DYING; - } /* @@ -866,7 +901,8 @@ void do_command_loop(void) { memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */ if (client_gets(cmdbuf) < 1) { lprintf(3, "Client socket is broken. Ending session.\n"); - cleanup(EXIT_NULL); + CC->state = CON_DYING; + return; } lprintf(5, "citserver[%3d]: %s\n", CC->cs_pid, cmdbuf); @@ -896,7 +932,7 @@ void do_command_loop(void) { else if (!strncasecmp(cmdbuf,"QUIT",4)) { cprintf("%d Goodbye.\n",OK); - cleanup(0); + CC->state = CON_DYING; } else if (!strncasecmp(cmdbuf,"LOUT",4)) {