X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fthreads.c;h=aec41a7c4d92b57292f6fc99e04a5ada5b025626;hb=51b18018ff923284d76a36cbd421d62abf6afcf4;hp=0d3caed9f24043e5a46bef32238ad9b76e9c4494;hpb=2c9048572f22002cd287cd3137b5f7461d35455b;p=citadel.git diff --git a/citadel/threads.c b/citadel/threads.c index 0d3caed9f..aec41a7c4 100644 --- a/citadel/threads.c +++ b/citadel/threads.c @@ -1,74 +1,35 @@ /* * Thread handling stuff for Citadel server * - * Copyright (c) 1987-2011 by the citadel.org team + * Copyright (c) 1987-2021 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License, version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include #include -#include -#include -#include -#include +#include #include - -#include "sysdep.h" -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#ifdef HAVE_SYSCALL_H -# include -#else -# if HAVE_SYS_SYSCALL_H -# include -# endif -#endif - #include - -#include "threads.h" -#include "ctdl_module.h" #include "modules_init.h" -#include "housekeeping.h" +#include "serv_extensions.h" +#include "ctdl_module.h" #include "config.h" -#include "citserver.h" -#include "sysdep_decls.h" #include "context.h" -#include "event_client.h" - +#include "threads.h" int num_workers = 0; /* Current number of worker threads */ int active_workers = 0; /* Number of ACTIVE worker threads */ pthread_key_t ThreadKey; pthread_mutex_t Critters[MAX_SEMAPHORES]; /* Things needing locking */ struct thread_tsd masterTSD; - - +int server_shutting_down = 0; /* set to nonzero during shutdown */ +pthread_mutex_t ThreadCountMutex; void InitializeSemaphores(void) { @@ -81,8 +42,6 @@ void InitializeSemaphores(void) } - - /* * Obtain a semaphore lock to begin a critical section. * but only if no one else has one @@ -94,7 +53,7 @@ int try_critical_section(int which_one) * transaction; this could lead to deadlock. */ if ( (which_one != S_FLOORCACHE) - && (which_one != S_RPLIST) + && (which_one != S_NETCONFIGS) ) { cdb_check_handles(); } @@ -112,13 +71,14 @@ void begin_critical_section(int which_one) * transaction; this could lead to deadlock. */ if ( (which_one != S_FLOORCACHE) - && (which_one != S_RPLIST) + && (which_one != S_NETCONFIGS) ) { cdb_check_handles(); } pthread_mutex_lock(&Critters[which_one]); } + /* * Release a semaphore lock to end a critical section. */ @@ -128,39 +88,18 @@ void end_critical_section(int which_one) } -/* - * A function to tell all threads to exit - */ -void CtdlThreadStopAll(void) -{ - terminate_all_sessions(); /* close all client sockets */ - CtdlShutdownServiceHooks(); /* close all listener sockets to prevent new connections */ - PerformSessionHooks(EVT_SHUTDOWN); /* run any registered shutdown hooks */ -} - - -/* - * A function for a thread to check if it has been asked to stop - */ -int CtdlThreadCheckStop(void) -{ - - /* FIXME this needs to do something useful. moar code pls ! */ - - return 0; -} - - /* * Return a pointer to our thread-specific (not session-specific) data. */ struct thread_tsd *MyThread(void) { - register struct thread_tsd *c; - return ((c = (struct thread_tsd *) pthread_getspecific(ThreadKey), c == NULL) ? &masterTSD : c); + struct thread_tsd *c = (struct thread_tsd *) pthread_getspecific(ThreadKey) ; + if (!c) { + return &masterTSD; + } + return c; } - /* * Called by CtdlThreadCreate() * We have to pass through here before starting our thread in order to create a set of data @@ -176,7 +115,7 @@ void *CTC_backend(void *supplied_start_routine) pthread_setspecific(ThreadKey, (const void *) mytsd); start_routine(NULL); - + // free(mytsd); return(NULL); } @@ -190,11 +129,10 @@ void CtdlThreadCreate(void *(*start_routine)(void*)) pthread_attr_t attr; int ret = 0; - ret = pthread_attr_init(&attr); ret = pthread_attr_setstacksize(&attr, THREADSTACKSIZE); ret = pthread_create(&thread, &attr, CTC_backend, (void *)start_routine); - if (ret != 0) syslog(LOG_EMERG, "pthread_create() : %s", strerror(errno)); + if (ret != 0) syslog(LOG_ERR, "pthread_create() : %m"); } @@ -208,32 +146,40 @@ void InitializeMasterTSD(void) { */ void go_threading(void) { - if (pthread_key_create(&ThreadKey, NULL) != 0) { - syslog(LOG_EMERG, "pthread_key_create() : %s", strerror(errno)); - abort(); - } + pthread_mutex_init(&ThreadCountMutex, NULL); /* Second call to module init functions now that threading is up */ initialise_modules(1); - CtdlThreadCreate(select_on_master); - /* Begin with one worker thread. We will expand the pool if necessary */ CtdlThreadCreate(worker_thread); /* The supervisor thread monitors worker threads and spawns more of them if it finds that - * they are all in use. FIXME make the 256 max threads a configurable value. + * they are all in use. */ - while(!CtdlThreadCheckStop()) { - if ((active_workers == num_workers) && (num_workers < 256)) { - syslog(LOG_DEBUG, "worker threads: %d, active: %d\n", num_workers, active_workers); + while (!server_shutting_down) { + if ((active_workers == num_workers) && (num_workers < CtdlGetConfigInt("c_max_workers"))) { CtdlThreadCreate(worker_thread); - syslog(LOG_DEBUG, "worker threads: %d, active: %d\n", num_workers, active_workers); } - sleep(1); + usleep(1000000); + } + + /* When we get to this point we are getting ready to shut down our Citadel server */ + terminate_all_sessions(); /* close all client sockets */ + CtdlShutdownServiceHooks(); /* close all listener sockets to prevent new connections */ + PerformSessionHooks(EVT_SHUTDOWN); /* run any registered shutdown hooks */ + + /* We used to wait for all threads to exit. Fuck that. The only thing important is that the databases are + * cleanly unmounted. After that, exit the whole program. + */ +#if 0 + int countdown = 30; + while ( (num_workers > 0) && (countdown-- > 0)) { + syslog(LOG_DEBUG, "Waiting %d seconds for %d worker threads to exit", + countdown, num_workers + ); + usleep(1000000); } +#endif - /* Shut down */ - CtdlThreadStopAll(); - exit(0); }