pthread_mutex_unlock(&this_thread->ThreadMutex);
return -1;
}
- else if(this_thread->state < CTDL_THREAD_STOP_REQ)
+ else if((this_thread->state < CTDL_THREAD_STOP_REQ) && (this_thread->state > CTDL_THREAD_CREATE))
{
pthread_mutex_unlock(&this_thread->ThreadMutex);
return -1;
/* Sanity check number of worker threads */
if (workers != num_workers)
{
- CtdlLogPrintf(CTDL_WARNING,
- "Thread system WARNING, discrepancy in number of worker threads. Counted %d, should be %d.\n",
+ CtdlLogPrintf(CTDL_EMERG,
+ "Thread system PANIC, discrepancy in number of worker threads. Counted %d, should be %d.\n",
workers, num_workers
);
abort();
- return;
}
}
* can continue its execution.
*/
begin_critical_section(S_THREAD_LIST);
+ // Register the cleanup function to take care of when we exit.
+ pthread_cleanup_push(ctdl_internal_thread_cleanup, NULL);
// Get our thread data structure
this_thread = (struct CtdlThreadNode *) arg;
- this_thread->state = CTDL_THREAD_RUNNING;
+ /* Only change to running state if we weren't asked to stop during the create cycle
+ * Other wise there is a window to allow this threads creation to continue to full grown and
+ * therby prevent a shutdown of the server.
+ */
+ if (!CtdlThreadCheckStop(this_thread))
+ this_thread->state = CTDL_THREAD_RUNNING;
+
this_thread->pid = getpid();
gettimeofday(&this_thread->start_time, NULL); /* Time this thread started */
memcpy(&this_thread->last_state_change, &this_thread->start_time, sizeof (struct timeval)); /* Changed state so mark it. */
// Tell the world we are here
CtdlLogPrintf(CTDL_NOTICE, "Created a new thread \"%s\" (%ld). \n", this_thread->name, this_thread->tid);
- // Register the cleanup function to take care of when we exit.
- pthread_cleanup_push(ctdl_internal_thread_cleanup, NULL);
/*
- * run the thread to do the work
+ * run the thread to do the work but only if we haven't been asked to stop
*/
- ret = (this_thread->thread_func)(this_thread->user_args);
+ if (!CtdlThreadCheckStop(this_thread))
+ ret = (this_thread->thread_func)(this_thread->user_args);
/*
* Our thread is exiting either because it wanted to end or because the server is stopping
struct CitContext *ptr, *ptr2; /* general-purpose utility pointer */
struct CitContext *rem = NULL; /* list of sessions to be destroyed */
- CtdlThreadPushName("dead_session_purge");
-
if (force == 0) {
if ( (time(NULL) - last_purge) < 5 ) {
- CtdlThreadPopName();
return; /* Too soon, go away */
}
}
time(&last_purge);
- begin_critical_section(S_SESSION_TABLE);
+ if (try_critical_section(S_SESSION_TABLE))
+ return;
+
ptr = ContextList;
while (ptr) {
ptr2 = ptr;
}
--num_sessions;
-
/* And put it on our to-be-destroyed list */
ptr2->next = rem;
rem = ptr2;
-
}
}
end_critical_section(S_SESSION_TABLE);
rem = rem->next;
free(ptr);
}
-
- /* Raise the size of the worker thread pool if necessary. */
- begin_critical_section(S_THREAD_LIST);
- if ( (num_sessions > num_workers)
- && (num_workers < config.c_max_workers) ) {
- ctdl_internal_create_thread("Worker Thread", CTDLTHREAD_BIGSTACK + CTDLTHREAD_WORKER, worker_thread, NULL);
- }
- end_critical_section(S_THREAD_LIST);
- // FIXME: reduce the number of worker threads too
-
- CtdlThreadPopName();
-
}
tv.tv_sec = 1; /* wake up every second if no input */
tv.tv_usec = 0;
retval = CtdlThreadSelect(highest + 1, &readfds, NULL, NULL, &tv, CT);
-// retval = select(highest + 1, &readfds, NULL, NULL, &tv);
}
if (CtdlThreadCheckStop(CT)) return(NULL);
goto do_select;
}
}
- else if(retval == 0) {
- goto SKIP_SELECT;
- }
+// else if(retval == 0) {
+// goto SKIP_SELECT;
+// }
/* Next, check to see if it's a new client connecting
* on a master socket.
*/
dead_session_purge(force_purge);
do_housekeeping();
- check_sched_shutdown();
}
/* If control reaches this point, the server is shutting down */
return(NULL);