cprintf(Reply, CIT_OK + SERVER_SHUTTING_DOWN);
}
CC->kill_me = KILLME_SERVER_SHUTTING_DOWN;
- CtdlThreadStopAll();
+ server_shutting_down = 1;
}
if (CtdlAccessCheck(ac_aide)) return;
cprintf("%d Halting server. Goodbye.\n", CIT_OK);
- CtdlThreadStopAll();
+ server_shutting_down = 1;
shutdown_and_halt = 1;
}
void check_sched_shutdown(void) {
if ((ScheduledShutdown == 1) && (ContextList == NULL)) {
syslog(LOG_NOTICE, "Scheduled shutdown initiating.\n");
- CtdlThreadStopAll();
+ server_shutting_down = 1;
}
}
/* Make our DNS query. */
answer = fixedans;
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
{
if (txtbuf != NULL) {
snprintf(txtbuf, txtbufsize, "System shutting down");
return(1);
}
}
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
{
if (txtbuf != NULL)
snprintf(txtbuf, txtbufsize, "System shutting down");
* nameserver we're using.
*/
len = res_query(domain, C_IN, T_TXT, answer, PACKETSZ);
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
{
if (txtbuf != NULL) {
snprintf(txtbuf, txtbufsize, "System shutting down");
syslog(LOG_INFO, "Auto-purger: starting.\n");
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
{
retval = PurgeUsers();
syslog(LOG_NOTICE, "Purged %d users.\n", retval);
}
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
{
PurgeMessages();
syslog(LOG_NOTICE, "Expired %d messages.\n", messages_purged);
}
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
{
retval = PurgeRooms();
syslog(LOG_NOTICE, "Expired %d rooms.\n", retval);
}
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
{
retval = PurgeVisits();
syslog(LOG_NOTICE, "Purged %d visits.\n", retval);
}
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
{
retval = PurgeUseTable();
syslog(LOG_NOTICE, "Purged %d entries from the use table.\n", retval);
}
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
{
retval = PurgeEuidIndexTable();
syslog(LOG_NOTICE, "Purged %d entries from the EUID index.\n", retval);
}
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
{
retval = PurgeStaleOpenIDassociations();
syslog(LOG_NOTICE, "Purged %d stale OpenID associations.\n", retval);
}
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
{
retval = TDAP_ProcessAdjRefCountQueue();
syslog(LOG_NOTICE, "Processed %d message reference count adjustments.\n", retval);
}
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
{
syslog(LOG_INFO, "Auto-purger: finished.\n");
last_purge = now; /* So we don't do it again soon */
*/
void ft_index_room(struct ctdlroom *qrbuf, void *data)
{
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
return;
CtdlGetRoom(&CC->room, qrbuf->QRname);
ft_index_message(ft_newmsgs[i], 1);
/* Check to see if we need to quit early */
- if (CtdlThreadCheckStop()) {
+ if (server_shutting_down) {
syslog(LOG_DEBUG, "Indexer quitting early\n");
ft_newhighest = ft_newmsgs[i];
break;
}
end_time = time(NULL);
- if (CtdlThreadCheckStop()) {
+ if (server_shutting_down) {
is_running = 0;
return;
}
msglist = NULL;
msglist_alloc = 0;
syslog(LOG_DEBUG, "Imported %d messages.\n", msgcount);
- if (CtdlThreadCheckStop()) {
+ if (server_shutting_down) {
return;
}
}
linelen = strlen(buf);
strcpy(&buf[linelen++], "\n");
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
break; // Should we break or return?
if (buf[0] == '\0')
* If shutting down we can exit here and unlink the temp file.
* this shouldn't loose us any messages.
*/
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
{
fclose(fp);
unlink(tempfilename);
fclose(fp);
/* Last chance for shutdown exit */
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
{
unlink(tempfilename);
return;
bytes_to_write = plen;
while (bytes_to_write > 0L) {
/* Exit if shutting down */
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
{
close(fd);
return;
close(fd);
/* Last chance for shutdown exit */
- if(CtdlThreadCheckStop())
+ if(server_shutting_down)
return;
if (sock_puts(sock, "UCLS 1") < 0) return;
}
/* At this point we are authenticated. */
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
receive_spool(&sock, node);
- if (!CtdlThreadCheckStop())
+ if (!server_shutting_down)
transmit_spool(&sock, node);
}
/* Use the string tokenizer to grab one line at a time */
for (i=0; i<num_tokens(working_ignetcfg, '\n'); ++i) {
- if(CtdlThreadCheckStop())
+ if(server_shutting_down)
return;
extract_token(linebuf, working_ignetcfg, i, '\n', sizeof linebuf);
extract_token(node, linebuf, 0, '|', sizeof node);
/*
* Go ahead and run the queue
*/
- if (full_processing && !CtdlThreadCheckStop()) {
+ if (full_processing && !server_shutting_down) {
syslog(LOG_DEBUG, "network: loading outbound queue\n");
CtdlForEachRoom(network_queue_room, NULL);
}
if (rplist != NULL) {
syslog(LOG_DEBUG, "network: running outbound queue\n");
- while (rplist != NULL && !CtdlThreadCheckStop()) {
+ while (rplist != NULL && !server_shutting_down) {
char spoolroomname[ROOMNAMELEN];
safestrncpy(spoolroomname, rplist->name, sizeof spoolroomname);
begin_critical_section(S_RPLIST);
}
/* If there is anything in the inbound queue, process it */
- if (!CtdlThreadCheckStop()) {
+ if (!server_shutting_down) {
network_do_spoolin();
}
syslog(LOG_DEBUG, "POP3: %s %s %s <password>\n", roomname, pop3host, pop3user);
syslog(LOG_NOTICE, "Connecting to <%s>\n", pop3host);
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
return;
sock = sock_connect(pop3host, "110");
return;
}
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto bail;
syslog(LOG_DEBUG, "Connected!\n");
syslog(LOG_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto bail;
/* Identify ourselves. NOTE: we have to append a CR to each command. The LF will
syslog(LOG_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto bail;
/* Password */
syslog(LOG_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto bail;
/* Get the list of messages */
syslog(LOG_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto bail;
do {
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto bail;
if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
snprintf(utmsgid, sizeof utmsgid, "pop3/%s/%s@%s", roomname, this_uidl, pop3host);
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto bail;
cdbut = cdb_fetch(CDB_USETABLE, utmsgid, strlen(utmsgid));
syslog(LOG_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto bail;
/* If we get to this point, the message is on its way. Read it. */
FILE *fp;
struct pop3aggr *pptr;
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
return;
assoc_file_name(filename, sizeof filename, qrbuf, ctdl_netcfg_dir);
syslog(LOG_DEBUG, "pop3client started\n");
CtdlForEachRoom(pop3client_scan_room, NULL);
- while (palist != NULL && !CtdlThreadCheckStop()) {
+ while (palist != NULL && !server_shutting_down) {
if ((palist->interval && time(NULL) > (last_run + palist->interval))
|| (time(NULL) > last_run + config.c_pop3_fetch))
pop3_do_fetching(palist->roomname, palist->pop3host,
curl_easy_setopt(curl, CURLOPT_INTERFACE, config.c_ip_addr);
}
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto shutdown ;
rc = curl_easy_perform(curl);
curl_easy_setopt(curl, CURLOPT_INTERFACE, config.c_ip_addr);
}
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
{
curl_easy_cleanup(curl);
return;
}
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto shutdown ;
res = curl_easy_perform(curl);
syslog(LOG_ALERT, "libcurl error %d: %s\n", res, errmsg);
}
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
goto shutdown ;
assoc_file_name(filename, sizeof filename, qrbuf, ctdl_netcfg_dir);
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
return;
/* Only do net processing for rooms that have netconfigs */
return;
}
- while (fgets(buf, sizeof buf, fp) != NULL && !CtdlThreadCheckStop()) {
+ while (fgets(buf, sizeof buf, fp) != NULL && !server_shutting_down) {
buf[strlen(buf)-1] = 0;
extract_token(instr, buf, 0, '|', sizeof instr);
syslog(LOG_DEBUG, "rssclient started\n");
CtdlForEachRoom(rssclient_scan_room, NULL);
- while (rnclist != NULL && !CtdlThreadCheckStop()) {
+ while (rnclist != NULL && !server_shutting_down) {
rss_do_fetching(rnclist);
rptr = rnclist;
rnclist = rnclist->next;
*/
if ( (config.c_rbl_at_greeting) && (sSMTP->is_msa == 0) ) {
if (rbl_check(message_to_spammer)) {
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
cprintf("421 %s\r\n", message_to_spammer);
else
cprintf("550 %s\r\n", message_to_spammer);
&& (!sSMTP->is_lmtp) ) { /* Don't RBL LMTP clients */
if (config.c_rbl_at_greeting == 0) { /* Don't RBL again if we already did it */
if (rbl_check(message_to_spammer)) {
- if (CtdlThreadCheckStop())
+ if (server_shutting_down)
cprintf("421 %s\r\n", message_to_spammer);
else
cprintf("550 %s\r\n", message_to_spammer);
static RETSIGTYPE signal_cleanup(int signum) {
syslog(LOG_DEBUG, "Caught signal %d; shutting down.", signum);
exit_signal = signum;
+ server_shutting_down = 1;
}
static RETSIGTYPE signal_exit(int signum) {
syslog(LOG_DEBUG, "client_write(%d bytes) select() interrupted.",
nbytes-bytes_written
);
- if (CtdlThreadCheckStop()) {
+ if (server_shutting_down) {
CC->kill_me = KILLME_SELECT_INTERRUPTED;
return (-1);
} else {
++num_workers;
- while (!CtdlThreadCheckStop()) {
+ while (!server_shutting_down) {
/* make doubly sure we're not holding any stale db handles
* which might cause a deadlock.
* ahead and get ready to select().
*/
- if (!CtdlThreadCheckStop()) {
+ if (!server_shutting_down) {
tv.tv_sec = 1; /* wake up every second if no input */
tv.tv_usec = 0;
retval = select(highest + 1, &readfds, NULL, NULL, &tv);
}
if (errno != EINTR) {
syslog(LOG_EMERG, "Exiting (%s)\n", strerror(errno));
- CtdlThreadStopAll();
+ server_shutting_down = 1;
continue;
} else {
syslog(LOG_DEBUG, "Interrupted select()\n");
- if (CtdlThreadCheckStop()) return(NULL);
+ if (server_shutting_down) return(NULL);
goto do_select;
}
}
else if (retval == 0) {
- if (CtdlThreadCheckStop()) return(NULL);
+ if (server_shutting_down) return(NULL);
}
/* It must be a client socket. Find a context that has data
do_housekeeping();
--active_workers;
}
- /* If control reaches this point, the server is shutting down */
+
+ /* If control reaches this point, the server is shutting down */
+ --num_workers;
return(NULL);
}
CtdlFillSystemContext(&select_on_master_CC, "select_on_master");
pthread_setspecific(MyConKey, (void *)&select_on_master_CC);
- while (!CtdlThreadCheckStop()) {
+ while (!server_shutting_down) {
/* Initialize the fdset. */
FD_ZERO(&master_fds);
highest = 0;
}
}
- if (!CtdlThreadCheckStop()) {
+ if (!server_shutting_down) {
tv.tv_sec = 60; /* wake up every second if no input */
tv.tv_usec = 0;
retval = select(highest + 1, &master_fds, NULL, NULL, &tv);
}
if (errno != EINTR) {
syslog(LOG_EMERG, "Exiting (%s)\n", strerror(errno));
- CtdlThreadStopAll();
+ server_shutting_down = 1;
} else {
syslog(LOG_DEBUG, "Interrupted CtdlThreadSelect.\n");
- if (CtdlThreadCheckStop()) return(NULL);
+ if (server_shutting_down) return(NULL);
continue;
}
}
else if(retval == 0) {
- if (CtdlThreadCheckStop()) return(NULL);
+ if (server_shutting_down) return(NULL);
continue;
}
/* Next, check to see if it's a new client connecting
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 */
}
-/*
- * 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;
-}
/*
/* 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(!CtdlThreadCheckStop()) {
+ while (!server_shutting_down) {
if ((active_workers == num_workers) && (num_workers < 256)) {
- syslog(LOG_DEBUG, "worker threads: %d, active: %d\n", num_workers, active_workers);
CtdlThreadCreate(worker_thread);
- syslog(LOG_DEBUG, "worker threads: %d, active: %d\n", num_workers, active_workers);
}
sleep(1);
}
- /* Shut down */
- CtdlThreadStopAll();
- exit(0);
+ /* 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 */
+
+ int countdown = 10;
+ while ( (num_workers > 0) && (countdown-- > 0)) {
+ syslog(LOG_DEBUG, "Waiting for %d worker threads to exit", num_workers);
+ sleep(1);
+ }
}
extern int num_workers;
extern int active_workers;
+extern int server_shutting_down;
struct thread_tsd *MyThread(void);
int try_critical_section (int which_one);
void begin_critical_section (int which_one);
void end_critical_section (int which_one);
void go_threading(void);
-int CtdlThreadCheckStop(void);
-void CtdlThreadStopAll(void);
void InitializeMasterTSD(void);
#endif // THREADS_H