]> code.citadel.org Git - citadel.git/commitdiff
* When a session kills itself (for example, due to a broken socket),
authorArt Cancro <ajc@citadel.org>
Fri, 14 May 2004 03:09:54 +0000 (03:09 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 14 May 2004 03:09:54 +0000 (03:09 +0000)
  force the dead_session_purge() to run immediately.  This avoids
  thousands of error messages for up to the next five seconds while it
  waits for the next purge.
* For the main select() loop, we can now recover from EBADF by jumping
  back to the code that scans for valid descriptors.  (Yeah, I used a
  goto.  It's more readable that way, so STFU if you have a problem with
  it.)

citadel/ChangeLog
citadel/sysdep.c

index a6165622450a5532f35fa51faa3eea443bc59336..c74b3cb7e1e221e8ceb4d637797872df58956658 100644 (file)
@@ -1,4 +1,14 @@
  $Log$
+ Revision 620.33  2004/05/14 03:09:54  ajc
+ * When a session kills itself (for example, due to a broken socket),
+   force the dead_session_purge() to run immediately.  This avoids
+   thousands of error messages for up to the next five seconds while it
+   waits for the next purge.
+ * For the main select() loop, we can now recover from EBADF by jumping
+   back to the code that scans for valid descriptors.  (Yeah, I used a
+   goto.  It's more readable that way, so STFU if you have a problem with
+   it.)
+
  Revision 620.32  2004/05/11 15:21:45  nbryant
  * configure.ac: check for <sys/prctl.h>
  * server_main.c: call prctl(PR_SET_DUMPABLE, 1) if we are dropping root
@@ -5762,4 +5772,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
-
index d59464dae87e23304465b3084e7f132be536de1d..b9e6079fc58f6a8cecdd431217eb8511fc51498c 100644 (file)
@@ -777,15 +777,21 @@ void create_worker(void) {
  * Purge all sessions which have the 'kill_me' flag set.
  * This function has code to prevent it from running more than once every
  * few seconds, because running it after every single unbind would waste a lot
- * of CPU time and keep the context list locked too much.
+ * of CPU time and keep the context list locked too much.  To force it to run
+ * anyway, set "force" to nonzero.
  *
- * After that's done, we raise or lower the size of the worker thread pool
+ *
+ * After that's done, we raise the size of the worker thread pool
  * if such an action is appropriate.
  */
-void dead_session_purge(void) {
+void dead_session_purge(int force) {
        struct CitContext *ptr, *rem;
 
-       if ( (time(NULL) - last_purge) < 5 ) return;    /* Too soon, go away */
+       if (force == 0) {
+               if ( (time(NULL) - last_purge) < 5 ) {
+                       return; /* Too soon, go away */
+               }
+       }
        time(&last_purge);
 
        do {
@@ -909,6 +915,7 @@ void *worker_thread(void *arg) {
        struct ServiceFunctionHook *serviceptr;
        int ssock;                      /* Descriptor for client socket */
        struct timeval tv;
+       int force_purge = 0;
 
        num_threads++;
 
@@ -932,6 +939,7 @@ void *worker_thread(void *arg) {
                 * which might cause a deadlock.
                 */
                cdb_check_handles();
+               force_purge = 0;
 
                begin_critical_section(S_I_WANNA_SELECT);
 SETUP_FD:      memcpy(&readfds, &masterfds, sizeof masterfds);
@@ -961,6 +969,11 @@ SETUP_FD:  memcpy(&readfds, &masterfds, sizeof masterfds);
                 * First, check for an error or exit condition.
                 */
                if (retval < 0) {
+                       if (errno == EBADF) {
+                               lprintf(CTDL_NOTICE, "select() failed: (%s)\n",
+                                       strerror(errno));
+                               goto SETUP_FD;
+                       }
                        if (errno != EINTR) {
                                lprintf(CTDL_EMERG, "Exiting (%s)\n", strerror(errno));
                                time_to_die = 1;
@@ -1074,13 +1087,14 @@ find_session:           if (next_session == NULL)
                        if (bind_me != NULL) {
                                become_session(bind_me);
                                CC->h_command_function();
+                               force_purge = CC->kill_me;
                                become_session(NULL);
                                bind_me->state = CON_IDLE;
                                write(rescan[1], &junk, 1);
                        }
 
                }
-               dead_session_purge();
+               dead_session_purge(force_purge);
                do_housekeeping();
                check_sched_shutdown();
        }