]> code.citadel.org Git - citadel.git/blobdiff - citadel/sysdep.c
* The size constant "256" which shows up everywhere as a buffer size has now
[citadel.git] / citadel / sysdep.c
index 4331e11eca7170a3e0752792082bdd19b70cd40d..a50bb0818fe0f7a9d3a8c561f0439d536aafb425 100644 (file)
@@ -7,8 +7,8 @@
  * Here's where we (hopefully) have most parts of the Citadel server that
  * would need to be altered to run the server in a non-POSIX environment.
  * 
- * Eventually we'll try porting to a different platform and either have
- * multiple variants of this file or simply load it up with #ifdefs.
+ * If we ever port to a different platform and either have multiple
+ * variants of this file or simply load it up with #ifdefs.
  *
  */
 
@@ -186,7 +186,7 @@ void dump_tracked() {
 
 
 /*
- * we used to use master_cleanup() as a signal handler to shut down the server.
+ * We used to use master_cleanup() as a signal handler to shut down the server.
  * however, master_cleanup() and the functions it calls do some things that
  * aren't such a good idea to do from a signal handler: acquiring mutexes,
  * playing with signal masks on BSDI systems, etc. so instead we install the
@@ -215,7 +215,8 @@ void init_sysdep(void) {
        /*
         * Set up a place to put thread-specific data.
         * We only need a single pointer per thread - it points to the
-        * thread's CitContext structure in the ContextList linked list.
+        * CitContext structure (in the ContextList linked list) of the
+        * session to which the calling thread is currently bound.
         */
        if (pthread_key_create(&MyConKey, NULL) != 0) {
                lprintf(1, "Can't create TSD key!!  %s\n", strerror(errno));
@@ -268,6 +269,10 @@ int ig_tcp_server(int port_number, int queue_len)
 {
        struct sockaddr_in sin;
        int s, i;
+       int actual_queue_len;
+
+       actual_queue_len = queue_len;
+       if (actual_queue_len < 5) actual_queue_len = 5;
 
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
@@ -293,7 +298,7 @@ int ig_tcp_server(int port_number, int queue_len)
                return(-1);
        }
 
-       if (listen(s, queue_len) < 0) {
+       if (listen(s, actual_queue_len) < 0) {
                lprintf(1, "citserver: Can't listen: %s\n", strerror(errno));
                close(s);
                return(-1);
@@ -312,6 +317,10 @@ int ig_uds_server(char *sockpath, int queue_len)
        struct sockaddr_un addr;
        int s;
        int i;
+       int actual_queue_len;
+
+       actual_queue_len = queue_len;
+       if (actual_queue_len < 5) actual_queue_len = 5;
 
        i = unlink(sockpath);
        if (i != 0) if (errno != ENOENT) {
@@ -337,7 +346,7 @@ int ig_uds_server(char *sockpath, int queue_len)
                return(-1);
        }
 
-       if (listen(s, queue_len) < 0) {
+       if (listen(s, actual_queue_len) < 0) {
                lprintf(1, "citserver: Can't listen: %s\n", strerror(errno));
                return(-1);
        }
@@ -362,7 +371,11 @@ struct CitContext *MyContext(void) {
 
 
 /*
- * Initialize a new context and place it in the list.
+ * Initialize a new context and place it in the list.  The session number
+ * used to be the PID (which is why it's called cs_pid), but that was when we
+ * had one process per session.  Now we just assign them sequentially, starting
+ * at 1 (don't change it to 0 because masterCC uses 0) and re-using them when
+ * sessions terminate.
  */
 struct CitContext *CreateNewContext(void) {
        struct CitContext *me, *ptr;
@@ -448,7 +461,7 @@ void client_write(char *buf, int nbytes)
  */
 void cprintf(const char *format, ...) {   
         va_list arg_ptr;   
-        char buf[256];   
+        char buf[SIZ];   
    
         va_start(arg_ptr, format);   
         if (vsnprintf(buf, sizeof buf, format, arg_ptr) == -1)
@@ -555,8 +568,15 @@ void sysdep_master_cleanup(void) {
         */
        for (serviceptr = ServiceHookTable; serviceptr != NULL;
            serviceptr = serviceptr->next ) {
-               lprintf(3, "Closing listener on port %d\n",
-                       serviceptr->tcp_port);
+
+               if (serviceptr->tcp_port > 0)
+                       lprintf(3, "Closing listener on port %d\n",
+                               serviceptr->tcp_port);
+
+               if (serviceptr->sockpath != NULL)
+                       lprintf(3, "Closing listener on '%s'\n",
+                               serviceptr->sockpath);
+
                close(serviceptr->msock);
 
                /* If it's a Unix domain socket, remove the file. */
@@ -616,7 +636,7 @@ void cmd_nset(char *cmdbuf)
        FILE *netsetup;
        int ch;
        int a, b;
-       char netsetup_args[3][256];
+       char netsetup_args[3][SIZ];
 
        if (CC->usersupp.axlevel < 6) {
                cprintf("%d Higher access required.\n", 
@@ -784,6 +804,7 @@ void CtdlRedirectOutput(FILE *fp, int sock) {
 void InitializeMasterCC(void) {
        memset(&masterCC, 0, sizeof(struct CitContext));
        masterCC.internal_pgm = 1;
+       masterCC.cs_pid = 0;
 }
 
 
@@ -803,6 +824,7 @@ void init_master_fdset(void) {
 
        FD_ZERO(&masterfds);
        masterhighest = 0;
+
        lprintf(9, "Will listen on rescan pipe %d\n", rescan[0]);
        FD_SET(rescan[0], &masterfds);
        if (rescan[0] > masterhighest) masterhighest = rescan[0];
@@ -826,7 +848,7 @@ void init_master_fdset(void) {
  */
 int main(int argc, char **argv)
 {
-       pthread_t HousekeepingThread;   /* Thread descriptor */
+       pthread_t WorkerThread; /* Thread descriptor */
         pthread_attr_t attr;           /* Thread attributes */
        char tracefile[128];            /* Name of file to log traces to */
        int a, i;                       /* General-purpose variables */
@@ -905,19 +927,24 @@ int main(int argc, char **argv)
        lprintf(7, "Loading citadel.config\n");
        get_config();
 
+
        /*
         * Do non system dependent startup functions.
         */
        master_startup();
 
        /*
-        * Bind the server to our favorite ports.
+        * Bind the server to a Unix-domain socket.
         */
-       CtdlRegisterServiceHook(0,                              /* Unix */
+       CtdlRegisterServiceHook(0,
                                "citadel.socket",
                                citproto_begin_session,
                                do_command_loop);
-       CtdlRegisterServiceHook(config.c_port_number,           /* TCP */
+
+       /*
+        * Bind the server to our favorite TCP port (usually 504).
+        */
+       CtdlRegisterServiceHook(config.c_port_number,
                                NULL,
                                citproto_begin_session,
                                do_command_loop);
@@ -966,33 +993,26 @@ int main(int argc, char **argv)
                }
        }
 
-       /*
-        * Create the housekeeper thread
-        */
-       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));
-       }
-
-
+       /* We want to check for idle sessions once per minute */
+       CtdlRegisterSessionHook(terminate_idle_sessions, EVT_TIMER);
+       
        /*
         * Now create a bunch of worker threads.
         */
        for (i=0; i<(config.c_min_workers-1); ++i) {
+               lprintf(9, "Creating worker thread %d\n", i);
                pthread_attr_init(&attr);
                        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-               if (pthread_create(&HousekeepingThread, &attr,
+               if (pthread_create(&WorkerThread, &attr,
                   (void* (*)(void*)) worker_thread, NULL) != 0) {
                        lprintf(1, "Can't create worker thead: %s\n",
                        strerror(errno));
                }
        }
 
+
        /* Now this thread can become a worker as well. */
+       lprintf(9, "Original thread entering worker loop\n");
        worker_thread();
 
        return(0);
@@ -1041,7 +1061,7 @@ void worker_thread(void) {
                 */
 
                begin_critical_section(S_I_WANNA_SELECT);
-SETUP_FD:      memcpy(&readfds, &masterfds, sizeof(fd_set) );
+SETUP_FD:      memcpy(&readfds, &masterfds, sizeof masterfds);
                highest = masterhighest;
                begin_critical_section(S_SESSION_TABLE);
                for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
@@ -1169,6 +1189,8 @@ SETUP_FD: memcpy(&readfds, &masterfds, sizeof(fd_set) );
                        last_timer = time(NULL);
                        PerformSessionHooks(EVT_TIMER);
                }
+
+               check_sched_shutdown();
        }
 
        /* If control reaches this point, the server is shutting down */