$Log$
+Revision 1.400 1999/10/28 05:08:49 ajc
+* Removed all of the thread cancellation cruft that is no longer necessary
+* Moved the now non-system-dependent RemoveContext() out of sysdep.c (now
+ it's part of cleanup() in citserver.c)
+* Removed all references to pthread_* from all modules except sysdep.c
+
Revision 1.399 1999/10/28 03:20:17 ajc
* Fixed the problem of worker threads waking up prematurely.
* 'QUIT'-terminated sessions now exit properly. Still need to fix code for
Fri Jul 10 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
* Initial CVS import
+
#include <string.h>
#include <errno.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include <syslog.h>
#include <dlfcn.h>
#include <netdb.h>
/*
- * 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;
- }
/*
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);
else if (!strncasecmp(cmdbuf,"QUIT",4)) {
cprintf("%d Goodbye.\n",OK);
- cleanup(0);
+ CC->state = CON_DYING;
}
else if (!strncasecmp(cmdbuf,"LOUT",4)) {
/* $Id$ */
void master_startup (void);
void master_cleanup (void);
-void cleanup (int);
+void cleanup (struct CitContext *);
void set_wtmpsupp (char *newtext);
void set_wtmpsupp_to_current_room(void);
void cmd_info (void);
#include <string.h>
#include <errno.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include <syslog.h>
#include "citadel.h"
#include "server.h"
#include <ctype.h>
#include <string.h>
#include <errno.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#ifdef HAVE_GDBM_H
#include <gdbm.h>
#endif
#include <dirent.h>
#include <strings.h>
#include <syslog.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include <limits.h>
#include <ctype.h>
#include "citadel.h"
#include <sys/stat.h>
#include <time.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "server.h"
#include "config.h"
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "tools.h"
#include "citadel.h"
#include "server.h"
#include <string.h>
#include <errno.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include <syslog.h>
#include "citadel.h"
#include "server.h"
#include <limits.h>
#include <netdb.h>
#include <string.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "server.h"
#include "locate_host.h"
#include <ctype.h>
#include <string.h>
#include <errno.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include <syslog.h>
#include "citadel.h"
#include "server.h"
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "mime_parser.h"
#include "sysdep_decls.h"
#include <ctype.h>
#include <string.h>
#include <syslog.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include <limits.h>
#include "citadel.h"
#include "server.h"
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include <time.h>
#include <limits.h>
#include "citadel.h"
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include <time.h>
#include <limits.h>
#include <errno.h>
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "server.h"
#include <syslog.h>
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "server.h"
#include <syslog.h>
#include <sys/stat.h>
#include <limits.h>
#include "sysdep.h"
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "server.h"
#include "dynloader.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "server.h"
-#include <syslog.h>
#include <time.h>
#include "sysdep_decls.h"
#include "citserver.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "server.h"
-#include <syslog.h>
#include <time.h>
#include "sysdep_decls.h"
#include "citserver.h"
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "server.h"
-#include <syslog.h>
#include <time.h>
#include "sysdep_decls.h"
#include "citserver.h"
/* $Id$ */
-typedef pthread_t THREAD;
/* Uncomment this if you want to track memory leaks.
* This incurs some overhead, so don't use it unless you're debugging the code!
#include <ctype.h>
#include <stdio.h>
#include <string.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#include "citadel.h"
#include "server.h"
#include "support.h"
* editor installed, and you want to make it the default, set this to 46
* to make it use your editor by default.
*/
-#define DEFAULT_ENTRY 4
+#define DEFAULT_ENTRY 4
+/*
+ * Logging level to use if none is specified on the command line.
+ */
+#define DEFAULT_VERBOSITY 9
+
/*
* HOUSEKEEPING_WAKEUP is the number of seconds which pass between each pass
pthread_key_t MyConKey; /* TSD key for MyContext() */
int msock; /* master listening socket */
-int verbosity = 9; /* Logging level */
+int verbosity = DEFAULT_VERBOSITY; /* Logging level */
struct CitContext masterCC;
int rescan[2]; /* The Rescan Pipe */
}
#endif
-static pthread_t main_thread_id;
-
-#ifndef HAVE_PTHREAD_CANCEL
-/*
- * signal handler to fake thread cancellation; only required on BSDI as far
- * as I know.
- */
-static RETSIGTYPE cancel_thread(int signum) {
- pthread_exit(NULL);
- }
-#endif
/*
* we used to use master_cleanup() as a signal handler to shut down the server.
signal(SIGQUIT, signal_cleanup);
signal(SIGHUP, signal_cleanup);
signal(SIGTERM, signal_cleanup);
+
+ /*
+ * Do not shut down the server on broken pipe signals, otherwise the
+ * whole Citadel service would come down whenever a single client
+ * socket breaks.
+ */
signal(SIGPIPE, SIG_IGN);
- main_thread_id = pthread_self();
-#ifndef HAVE_PTHREAD_CANCEL /* fake it - only BSDI afaik */
- signal(SIGUSR1, cancel_thread);
-#endif
}
/*
- * Return a pointer to a thread's own CitContext structure (new)
+ * Return a pointer to the CitContext structure bound to the thread which
+ * called this function. If there's no such binding (for example, if it's
+ * called by the housekeeper thread) then a generic 'master' CC is returned.
*/
struct CitContext *MyContext(void) {
struct CitContext *retCC;
/*
- * Wedge our way into the context list.
+ * Initialize a new context and place it in the list.
*/
struct CitContext *CreateNewContext(void) {
struct CitContext *me;
return(me);
}
-/*
- * Remove a context from the context list.
- */
-void RemoveContext(struct CitContext *con)
-{
- struct CitContext *ptr = NULL;
- struct CitContext *ToFree = NULL;
-
- lprintf(7, "Starting RemoveContext()\n");
- if (con==NULL) {
- lprintf(5, "WARNING: RemoveContext() called with NULL!\n");
- return;
- }
-
- /*
- * session_count() starts its own S_SESSION_TABLE critical section;
- * so do not call it from within this loop.
- */
- 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 RemoveContext\n");
- }
/*
if (retval < 1) {
lprintf(2, "client_write() failed: %s\n",
strerror(errno));
- cleanup(errno);
+ CC->state = CON_DYING;
}
bytes_written = bytes_written + retval;
}
if (rlen<1) {
lprintf(2, "client_read() failed: %s\n",
strerror(errno));
- cleanup(errno);
+ CC->state = CON_DYING;
}
len = len + rlen;
}
/*
* Terminate another session.
+ * FIX ... now we need some way to wake that session up so it knows it
+ * needs to terminate.
*/
void kill_session(int session_to_kill) {
struct CitContext *ptr;
*/
int main(int argc, char **argv)
{
- THREAD HousekeepingThread; /* Thread descriptor */
+ pthread_t HousekeepingThread; /* Thread descriptor */
pthread_attr_t attr; /* Thread attributes */
char tracefile[128]; /* Name of file to log traces to */
int a, i; /* General-purpose variables */
/* Initialize... */
init_sysdep();
openlog("citserver",LOG_PID,LOG_USER);
+
/* Load site-specific parameters */
lprintf(7, "Loading citadel.config\n");
get_config();
struct CitContext *con= NULL; /* Temporary context pointer */
struct sockaddr_in fsin; /* Data for master socket */
int alen; /* Data for master socket */
- int ssock; /* Descriptor for master socket */
+ int ssock; /* Descriptor for client socket */
while (!time_to_die) {
do_command_loop();
pthread_setspecific(MyConKey, (void *)NULL);
if (bind_me->state == CON_DYING) {
- RemoveContext(bind_me);
+ cleanup(bind_me);
}
else {
bind_me->state = CON_IDLE;
struct CitContext *MyContext (void);
struct CitContext *CreateNewContext (void);
void InitMyContext (struct CitContext *con);
-void RemoveContext (struct CitContext *con);
int session_count (void);
void client_write (char *buf, int nbytes);
void cprintf (const char *format, ...);
#include <string.h>
#include <syslog.h>
#include <limits.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#ifndef ENABLE_CHKPWD
#include "auth.h"
#endif