]> code.citadel.org Git - citadel.git/blobdiff - citadel/threads.c
Thread log was too verbose when writing to disk
[citadel.git] / citadel / threads.c
index fdbf5dced068a5fa3be3daeaf5a367709e078dd4..a1497d98c35907ce25c6198f95a1ec9e407cb146 100644 (file)
@@ -57,7 +57,7 @@ static int num_workers = 0;                   /* Current number of worker threads */
 CtdlThreadNode *CtdlThreadList = NULL;
 CtdlThreadNode *CtdlThreadSchedList = NULL;
 
-static citthread_t GC_thread;
+static CtdlThreadNode *GC_thread = NULL;
 static char *CtdlThreadStates[CTDL_THREAD_LAST_STATE];
 double CtdlThreadLoadAvg = 0;
 double CtdlThreadWorkerAvg = 0;
@@ -153,7 +153,7 @@ void ctdl_thread_internal_init_tsd(void)
        int ret;
        
        if ((ret = citthread_key_create(&ThreadKey, ctdl_thread_internal_dest_tsd))) {
-               lprintf(CTDL_EMERG, "citthread_key_create: %s\n", strerror(ret));
+               CtdlLogPrintf(CTDL_EMERG, "citthread_key_create: %s\n", strerror(ret));
                exit(CTDLEXIT_DB);
        }
 }
@@ -220,7 +220,6 @@ void ctdl_thread_internal_init(void)
        CtdlThreadNode *this_thread;
        int ret = 0;
        
-       GC_thread = citthread_self();
        CtdlThreadStates[CTDL_THREAD_INVALID] = strdup ("Invalid Thread");
        CtdlThreadStates[CTDL_THREAD_VALID] = strdup("Valid Thread");
        CtdlThreadStates[CTDL_THREAD_CREATE] = strdup("Thread being Created");
@@ -257,7 +256,8 @@ void ctdl_thread_internal_init(void)
 
        this_thread->name = "Garbage Collection Thread";
        
-       this_thread->tid = GC_thread;
+       this_thread->tid = citthread_self();
+       GC_thread = this_thread;
        CT = this_thread;
        
        num_threads++;  // Increase the count of threads in the system.
@@ -471,7 +471,7 @@ int CtdlThreadCheckStop(void)
        
        state = CT->state;
 
-#ifdef THREADS_USERSIGNALS
+#ifdef THREADS_USESIGNALS
        if (CT->signal)
                CtdlLogPrintf(CTDL_DEBUG, "Thread \"%s\" caught signal %d.\n", CT->name, CT->signal);
 #endif
@@ -641,10 +641,18 @@ void CtdlThreadGC (void)
                if ((that_thread->state == CTDL_THREAD_STOP_REQ || that_thread->state == CTDL_THREAD_STOPPING)
                        && (!citthread_equal(that_thread->tid, citthread_self())))
                                that_thread->stop_ticker++;
+               else
+               {
+                       /**
+                        * Catch the situation where a worker was asked to stop but couldn't and we are not
+                        * shutting down.
+                        */
+                       that_thread->stop_ticker = 0;
+               }
                
                if (that_thread->stop_ticker == 5)
                {
-                       CtdlLogPrintf(CTDL_DEBUG, "Thread System: The thread \"%s\" (0x%08lx) failed to self terminate withing 5 ticks. It would be cancelled now.\n", that_thread->name, that_thread->tid);
+                       CtdlLogPrintf(CTDL_DEBUG, "Thread System: The thread \"%s\" (0x%08lx) failed to self terminate within 5 ticks. It would be cancelled now.\n", that_thread->name, that_thread->tid);
                        if ((that_thread->flags & CTDLTHREAD_WORKER) == 0)
                                CtdlLogPrintf(CTDL_INFO, "Thread System: A non worker thread would have been canceled this may cause message loss.\n");
 //                     that_thread->state = CTDL_THREAD_CANCELLED;
@@ -1139,7 +1147,36 @@ int CtdlThreadSelect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds
        
        ctdl_thread_internal_change_state(CT, CTDL_THREAD_BLOCKED);
        ret = select(n, readfds, writefds, exceptfds, timeout);
-       ctdl_thread_internal_change_state(CT, CTDL_THREAD_RUNNING);
+       /**
+        * If the select returned <= 0 then it failed due to an error
+        * or timeout so this thread could stop if asked to do so.
+        * Anything else means it needs to continue unless the system is shutting down
+        */
+       if (ret <= 0)
+       {
+               /**
+                * select says nothing to do so we can change to running if we haven't been asked to stop.
+                */
+               ctdl_thread_internal_change_state(CT, CTDL_THREAD_RUNNING);
+       }
+       else
+       {
+               /**
+                * The select says this thread needs to do something useful.
+                * This thread was in an idle state so it may have been asked to stop
+                * but if the system isn't shutting down this thread is no longer
+                * idle and select has given it a task to do so it must not stop
+                * In this condition we need to force it into the running state.
+                * CtdlThreadGC will clear its ticker for us.
+                */
+               if (GC_thread->state > CTDL_THREAD_STOP_REQ)
+               {
+                       citthread_mutex_lock(&CT->ThreadMutex); /* To prevent race condition of a sleeping thread */
+                       CT->state = CTDL_THREAD_RUNNING;
+                       citthread_mutex_unlock(&CT->ThreadMutex);
+               }
+       }
+
        return ret;
 }