#include <stdarg.h>
#include <grp.h>
#include <pwd.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#endif
#include "server.h"
#include "serv_extensions.h"
#include "sysdep_decls.h"
+#include "threads.h"
#include "citserver.h"
#include "support.h"
#include "config.h"
const char *CitadelServiceUDS="citadel-UDS";
const char *CitadelServiceTCP="citadel-TCP";
+
+void go_threading(void);
+
+
/*
* Here's where it all begins.
*/
int main(int argc, char **argv)
{
char facility[32];
- int a, i; /* General-purpose variables */
+ int a; /* General-purpose variables */
struct passwd pw, *pwp = NULL;
char pwbuf[SIZ];
int drop_root_perms = 1;
// eCrashSymbolTable symbol_table;
#endif
/* initialise semaphores here. Patch by Matt and davew
- * its called here as they are needed by lprintf for thread safety
+ * its called here as they are needed by CtdlLogPrintf for thread safety
*/
CtdlInitBase64Table();
InitialiseSemaphores();
/* any other parameter makes it crash and burn */
else {
- lprintf(CTDL_EMERG, "citserver: usage: "
+ CtdlLogPrintf(CTDL_EMERG, "citserver: usage: "
"citserver "
"[-lLogFacility] "
"[-d] [-f] [-D] "
}
/* Tell 'em who's in da house */
- lprintf(CTDL_NOTICE, "\n");
- lprintf(CTDL_NOTICE, "\n");
- lprintf(CTDL_NOTICE,
+ CtdlLogPrintf(CTDL_NOTICE, "\n");
+ CtdlLogPrintf(CTDL_NOTICE, "\n");
+ CtdlLogPrintf(CTDL_NOTICE,
"*** Citadel server engine v%d.%02d ***\n",
(REV_LEVEL/100), (REV_LEVEL%100));
- lprintf(CTDL_NOTICE,
+ CtdlLogPrintf(CTDL_NOTICE,
"Copyright (C) 1987-2007 by the Citadel development team.\n");
- lprintf(CTDL_NOTICE,
+ CtdlLogPrintf(CTDL_NOTICE,
"This program is distributed under the terms of the GNU "
"General Public License.\n");
- lprintf(CTDL_NOTICE, "\n");
- lprintf(CTDL_DEBUG, "Called as: %s\n", argv[0]);
- lprintf(CTDL_INFO, "%s\n", libcitadel_version_string());
+ CtdlLogPrintf(CTDL_NOTICE, "\n");
+ CtdlLogPrintf(CTDL_DEBUG, "Called as: %s\n", argv[0]);
+ CtdlLogPrintf(CTDL_INFO, "%s\n", libcitadel_version_string());
/* Load site-specific parameters, and set the ipgm secret */
- lprintf(CTDL_INFO, "Loading citadel.config\n");
+ CtdlLogPrintf(CTDL_INFO, "Loading citadel.config\n");
get_config();
config.c_ipgm_secret = rand();
put_config();
*/
master_startup();
- lprintf(CTDL_INFO, "Acquiring control record\n");
+ CtdlLogPrintf(CTDL_INFO, "Acquiring control record\n");
get_control();
/*
do_async_loop,
CitadelServiceTCP);
+
+ /*
+ * Run any upgrade entry points
+ */
+ CtdlLogPrintf(CTDL_INFO, "Upgrading modules.\n");
+ upgrade_modules();
+
+
/*
* Load any server-side extensions available here.
*/
- lprintf(CTDL_INFO, "Initializing server extensions\n");
+ CtdlLogPrintf(CTDL_INFO, "Initializing server extensions\n");
size = strlen(ctdl_home_directory) + 9;
initialise_modules(0);
getpwuid_r(config.c_ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp);
#endif
if (pwp == NULL)
- lprintf(CTDL_CRIT, "WARNING: getpwuid(%ld): %s\n"
+ CtdlLogPrintf(CTDL_CRIT, "WARNING: getpwuid(%ld): %s\n"
"Group IDs will be incorrect.\n", (long)CTDLUID,
strerror(errno));
else {
initgroups(pw.pw_name, pw.pw_gid);
if (setgid(pw.pw_gid))
- lprintf(CTDL_CRIT, "setgid(%ld): %s\n", (long)pw.pw_gid,
+ CtdlLogPrintf(CTDL_CRIT, "setgid(%ld): %s\n", (long)pw.pw_gid,
strerror(errno));
}
- lprintf(CTDL_INFO, "Changing uid to %ld\n", (long)CTDLUID);
+ CtdlLogPrintf(CTDL_INFO, "Changing uid to %ld\n", (long)CTDLUID);
if (setuid(CTDLUID) != 0) {
- lprintf(CTDL_CRIT, "setuid() failed: %s\n", strerror(errno));
+ CtdlLogPrintf(CTDL_CRIT, "setuid() failed: %s\n", strerror(errno));
}
#if defined (HAVE_SYS_PRCTL_H) && defined (PR_SET_DUMPABLE)
prctl(PR_SET_DUMPABLE, 1);
/* We want to check for idle sessions once per minute */
CtdlRegisterSessionHook(terminate_idle_sessions, EVT_TIMER);
- /*
- * Initialise the thread system
- */
- ctdl_thread_internal_init();
+ go_threading();
- /*
- * Now create a bunch of worker threads.
- */
- CtdlLogPrintf(CTDL_DEBUG, "Starting %d worker threads\n",
- config.c_min_workers-1);
- begin_critical_section(S_THREAD_LIST);
- for (i=0; i<(config.c_min_workers-1); ++i) {
- ctdl_internal_create_thread("Worker Thread", CTDLTHREAD_BIGSTACK + CTDLTHREAD_WORKER, worker_thread, NULL);
- }
- end_critical_section(S_THREAD_LIST);
-
- /* Second call to module init functions now that threading is up */
- initialise_modules(1);
-
- /*
- * This thread is now used for garbage collection of other threads in the thread list
- */
- CtdlLogPrintf(CTDL_INFO, "Startup thread %d becoming garbage collector,\n", pthread_self());
-
- /* Sleep 10 seconds before first garbage collection */
- CtdlThreadSleep(10);
-
- while (CtdlThreadGetCount())
- {
- if (exit_signal)
- CtdlThreadStopAll();
- begin_critical_section(S_THREAD_LIST);
- ctdl_thread_internal_calc_loadavg();
- end_critical_section(S_THREAD_LIST);
- CtdlThreadSleep(1);
- begin_critical_section(S_THREAD_LIST);
- ctdl_internal_thread_gc();
- end_critical_section(S_THREAD_LIST);
- if (CtdlThreadGetCount() <= 1) // Shutting down clean up the garbage collector
- {
- begin_critical_section(S_THREAD_LIST);
- ctdl_internal_thread_gc();
- end_critical_section(S_THREAD_LIST);
- }
- }
- /*
- * If the above loop exits we must be shutting down since we obviously have no threads
- */
- ctdl_thread_internal_cleanup();
master_cleanup(exit_signal);
return(0);