]> code.citadel.org Git - citadel.git/blobdiff - citadel/sysdep.c
Created a routine to get a copy of the context list so that it can be
[citadel.git] / citadel / sysdep.c
index 0cbfec52798229323476923ed2c23b9327a91964..bf77408ee4e80fbe305594be210ff93bc49f03cd 100644 (file)
@@ -234,9 +234,6 @@ void init_sysdep(void) {
        // sigaddset(&set, SIGILL);     we want core dumps
        // sigaddset(&set, SIGBUS);
        sigprocmask(SIG_UNBLOCK, &set, NULL);
-       sigemptyset(&set);
-       sigaddset(&set, SIGUSR1);
-       sigprocmask(SIG_BLOCK, &set, NULL);
 
        signal(SIGINT, signal_cleanup);
        signal(SIGQUIT, signal_cleanup);
@@ -457,13 +454,30 @@ struct CitContext *CreateNewContext(void) {
        if (me->next != NULL) {
                me->next->prev = me;
        }
-       me->client_expires_at.tv_sec = config.c_sleeping;
        ++num_sessions;
        end_critical_section(S_SESSION_TABLE);
        return (me);
 }
 
 
+struct CitContext *CtdlGetContextArray(int *count)
+{
+       int nContexts, i;
+       struct CitContext *nptr, *cptr;
+       
+       nContexts = num_sessions;
+       nptr = malloc(sizeof(struct CitContext) * nContexts);
+       if (!nptr)
+               return NULL;
+       begin_critical_section(S_SESSION_TABLE);
+       for (cptr = ContextList, i=0; cptr != NULL && i < nContexts; cptr = cptr->next, i++)
+               memcpy(&nptr[i], cptr, sizeof (struct CitContext));
+       end_critical_section (S_SESSION_TABLE);
+       
+       *count = i;
+       return nptr;
+}
+
 /*
  * The following functions implement output buffering. If the kernel supplies
  * native TCP buffering (Linux & *BSD), use that; otherwise, emulate it with
@@ -551,7 +565,9 @@ void client_write(char *buf, int nbytes)
 #ifndef HAVE_TCP_BUFFERING
        int old_buffer_len = 0;
 #endif
+       fd_set wset;
        t_context *Ctx;
+       int fdflags;
 
        Ctx = CC;
        if (Ctx->redirect_buffer != NULL) {
@@ -586,7 +602,23 @@ void client_write(char *buf, int nbytes)
        }
 #endif
 
+       fdflags = fcntl(Ctx->client_socket, F_GETFL);
+
        while (bytes_written < nbytes) {
+               if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
+                       FD_ZERO(&wset);
+                       FD_SET(Ctx->client_socket, &wset);
+                       if (select(1, NULL, &wset, NULL, NULL) == -1) {
+                               CtdlLogPrintf(CTDL_ERR,
+                                       "client_write(%d bytes) select failed: %s (%d)\n",
+                                       nbytes - bytes_written,
+                                       strerror(errno), errno);
+                               cit_backtrace();
+                               Ctx->kill_me = 1;
+                               return;
+                       }
+               }
+
                retval = write(Ctx->client_socket, &buf[bytes_written],
                        nbytes - bytes_written);
                if (retval < 1) {
@@ -1145,7 +1177,7 @@ do_select:        force_purge = 0;
                                CtdlLogPrintf(CTDL_EMERG, "Exiting (%s)\n", strerror(errno));
                                CtdlThreadStopAll();
                        } else if (!CtdlThreadCheckStop()) {
-                               CtdlLogPrintf(CTDL_DEBUG, "Un handled select failure.\n");
+                               CtdlLogPrintf(CTDL_DEBUG, "Interrupted select.\n");
                                goto do_select;
                        }
                }
@@ -1256,6 +1288,7 @@ SKIP_SELECT:
                }
 
                dead_session_purge(force_purge);
+               do_housekeeping();
        }
        /* If control reaches this point, the server is shutting down */        
        return(NULL);