+ pthread_attr_destroy(&attr);
+}
+
+void DestroyWorkerList(void)
+{
+ struct CitContext *ptr; /* general-purpose utility pointer */
+ struct CitContext *rem = NULL; /* list of sessions to be destroyed */
+
+ begin_critical_section(S_SESSION_TABLE);
+ ptr = ContextList;
+ while (ptr != NULL){
+ /* Remove the session from the active list */
+ rem = ptr->next;
+ --num_sessions;
+
+ lprintf(CTDL_DEBUG, "Purging session %d\n", rem->cs_pid);
+ end_critical_section(S_SESSION_TABLE);
+ RemoveContext(ptr);
+ begin_critical_section(S_SESSION_TABLE);
+ free (ptr);
+ ptr = rem;
+ }
+ end_critical_section(S_SESSION_TABLE);
+
+ struct worker_node *cur, *p;
+ cur = worker_list;
+ while (cur != NULL)
+ {
+ p = cur->next;
+ free (cur);
+ cur = p;
+ }
+ worker_list = NULL;
+}
+
+/*
+ * Create the maintenance threads and begin their operation.
+ */
+void create_maintenance_threads(void) {
+ int ret;
+ pthread_attr_t attr;
+
+ if ((ret = pthread_attr_init(&attr))) {
+ lprintf(CTDL_EMERG, "pthread_attr_init: %s\n", strerror(ret));
+ time_to_die = -1;
+ return;
+ }
+
+ /* Our per-thread stacks need to be bigger than the default size,
+ * otherwise the MIME parser crashes on FreeBSD, and the IMAP service
+ * crashes on 64-bit Linux.
+ */
+ if ((ret = pthread_attr_setstacksize(&attr, THREADSTACKSIZE))) {
+ lprintf(CTDL_EMERG, "pthread_attr_setstacksize: %s\n",
+ strerror(ret));
+ time_to_die = -1;
+ pthread_attr_destroy(&attr);
+ return;
+ }
+
+ struct MaintenanceThreadHook *fcn;
+
+ lprintf(CTDL_DEBUG, "Performing startup of maintenance thread hooks\n");
+
+ for (fcn = MaintenanceThreadHookTable; fcn != NULL; fcn = fcn->next) {
+ if ((ret = pthread_create(&(fcn->MaintenanceThread_tid), &attr, fcn->fcn_ptr, NULL) != 0)) {
+ lprintf(CTDL_ALERT, "Can't create thread: %s\n", strerror(ret));
+ }
+ else
+ {
+ lprintf(CTDL_NOTICE, "Spawned a new maintenance thread \"%s\" (%ld). \n", fcn->name,
+ fcn->MaintenanceThread_tid);
+ }
+ }
+
+
+ pthread_attr_destroy(&attr);