Back to index

citadel  8.12
Functions | Variables
threads.c File Reference
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <signal.h>
#include <syslog.h>
#include "sysdep.h"
#include <time.h>
#include <libcitadel.h>
#include "threads.h"
#include "ctdl_module.h"
#include "modules_init.h"
#include "housekeeping.h"
#include "config.h"
#include "citserver.h"
#include "sysdep_decls.h"
#include "context.h"
#include "event_client.h"

Go to the source code of this file.

Functions

void InitializeSemaphores (void)
int try_critical_section (int which_one)
void begin_critical_section (int which_one)
void end_critical_section (int which_one)
struct thread_tsdMyThread (void)
void * CTC_backend (void *supplied_start_routine)
void CtdlThreadCreate (void *(*start_routine)(void *))
void InitializeMasterTSD (void)
void ShutDownEventQueues (void)
void go_threading (void)

Variables

int num_workers = 0
int active_workers = 0
pthread_key_t ThreadKey
pthread_mutex_t Critters [MAX_SEMAPHORES]
int server_shutting_down = 0
int EventQShuttingDown = 0
int EVQShutDown = 0

Function Documentation

void begin_critical_section ( int  which_one)

Definition at line 109 of file threads.c.

{
       /* For all types of critical sections except those listed here,
        * ensure nobody ever tries to do a critical section within a
        * transaction; this could lead to deadlock.
        */
       if (   (which_one != S_FLOORCACHE)
              && (which_one != S_RPLIST)
       ) {
              cdb_check_handles();
       }
       pthread_mutex_lock(&Critters[which_one]);
}

Here is the call graph for this function:

void* CTC_backend ( void *  supplied_start_routine)

Definition at line 149 of file threads.c.

{
       struct thread_tsd *mytsd;
       void *(*start_routine)(void*) = supplied_start_routine;

       mytsd = (struct thread_tsd *) malloc(sizeof(struct thread_tsd));
       memset(mytsd, 0, sizeof(struct thread_tsd));
       pthread_setspecific(ThreadKey, (const void *) mytsd);

       start_routine(NULL);

       free(mytsd);
       return(NULL);
}

Here is the caller graph for this function:

void CtdlThreadCreate ( void *(*)(void *)  start_routine)

Definition at line 168 of file threads.c.

{
       pthread_t thread;
       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));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void end_critical_section ( int  which_one)

Definition at line 126 of file threads.c.

{
       pthread_mutex_unlock(&Critters[which_one]);
}
void go_threading ( void  )

Definition at line 193 of file threads.c.

{
       if (pthread_key_create(&ThreadKey, NULL) != 0) {
              syslog(LOG_EMERG, "pthread_key_create() : %s", strerror(errno));
              abort();
       }

       /* Second call to module init functions now that threading is up */
       initialise_modules(1);

       /* 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.
        */
       while (!server_shutting_down) {
              if ((active_workers == num_workers) && (num_workers < 256)) {
                     CtdlThreadCreate(worker_thread);
              }
              usleep(1000);
       }

       /* When we get to this point we are getting ready to shut down our Citadel server */
       if (!EventQShuttingDown)
       {
              EventQShuttingDown = 1;
              ShutDownEventQueues();
       }
       while (!EVQShutDown)
              usleep(1000);


       terminate_all_sessions();          /* close all client sockets */
       CtdlShutdownServiceHooks();        /* close all listener sockets to prevent new connections */
       PerformSessionHooks(EVT_SHUTDOWN); /* run any registered shutdown hooks */

       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(1000);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void InitializeMasterTSD ( void  )

Definition at line 182 of file threads.c.

                               {
       memset(&masterTSD, 0, sizeof(struct thread_tsd));
}

Here is the caller graph for this function:

void InitializeSemaphores ( void  )

Definition at line 74 of file threads.c.

{
       int i;

       /* Set up a bunch of semaphores to be used for critical sections */
       for (i=0; i<MAX_SEMAPHORES; ++i) {
              pthread_mutex_init(&Critters[i], NULL);
       }
}
struct thread_tsd* MyThread ( void  ) [read]

Definition at line 137 of file threads.c.

                                  {
        register struct thread_tsd *c;
        return ((c = (struct thread_tsd *) pthread_getspecific(ThreadKey), c == NULL) ? &masterTSD : c);
}
void ShutDownEventQueues ( void  )

Definition at line 838 of file serv_eventclient.c.

{
       EVQM_syslog(LOG_DEBUG, "EVENT Qs triggering exits.\n");

       pthread_mutex_lock(&DBEventQueueMutex);
       ev_async_send (event_db, &DBExitEventLoop);
       pthread_mutex_unlock(&DBEventQueueMutex);

       pthread_mutex_lock(&EventQueueMutex);
       ev_async_send (EV_DEFAULT_ &ExitEventLoop);
       pthread_mutex_unlock(&EventQueueMutex);
}

Here is the caller graph for this function:

int try_critical_section ( int  which_one)

Definition at line 91 of file threads.c.

{
       /* For all types of critical sections except those listed here,
        * ensure nobody ever tries to do a critical section within a
        * transaction; this could lead to deadlock.
        */
       if (   (which_one != S_FLOORCACHE)
              && (which_one != S_RPLIST)
       ) {
              cdb_check_handles();
       }
       return (pthread_mutex_trylock(&Critters[which_one]));
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

int active_workers = 0

Definition at line 66 of file threads.c.

pthread_mutex_t Critters[MAX_SEMAPHORES]

Definition at line 68 of file threads.c.

Definition at line 188 of file threads.c.

int EVQShutDown = 0

Definition at line 189 of file threads.c.

int num_workers = 0

Definition at line 65 of file threads.c.

Definition at line 70 of file threads.c.

pthread_key_t ThreadKey

Definition at line 67 of file threads.c.