From: Art Cancro Date: Fri, 18 Mar 2011 16:47:10 +0000 (-0400) Subject: Moved all of the background tasks back to the old EVT_TIMER style X-Git-Tag: v8.11~815 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=7716f155f4145d83b6acfe6157599e6a9ee04608 Moved all of the background tasks back to the old EVT_TIMER style in order to prepare for the forthcoming simplification of the server thread architecture --- diff --git a/citadel/configure.ac b/citadel/configure.ac index 1beae85af..e29bbea0c 100644 --- a/citadel/configure.ac +++ b/citadel/configure.ac @@ -788,22 +788,6 @@ fi -dnl Checks for the Boehm-Demers-Weiser garbage collection library. -if test "x$with_gc" != xno ; then - AC_CHECK_HEADERS(gc/gc_local_alloc.h, - [AC_CHECK_LIB(gc, GC_init, - [ok_gc=yes],, - )]) -fi - -if test "x$ok_gc" = xyes ; then - SERVER_LIBS="-lgc $SERVER_LIBS" - AC_DEFINE(HAVE_GC, [], [define this if you have Boehm-Demers-Weiser available]) -fi - - - - dnl Checks for the libdspam mail spam scanning library. dnl if test "x$with_libdspam" != xno ; then diff --git a/citadel/context.c b/citadel/context.c index 2a522066a..f49d645dd 100644 --- a/citadel/context.c +++ b/citadel/context.c @@ -313,7 +313,8 @@ void terminate_idle_sessions(void) void terminate_stuck_sessions(void) { - return; + abort(); + /* FIXME this function has been disabled because it is somehow being * called at times other than server shutdown, which is throwing all * the users off. EPIC FAIL!!! diff --git a/citadel/housekeeping.c b/citadel/housekeeping.c index 9cce88447..5773925dd 100644 --- a/citadel/housekeeping.c +++ b/citadel/housekeeping.c @@ -123,7 +123,6 @@ void do_housekeeping(void) { int do_housekeeping_now = 0; int do_perminute_housekeeping_now = 0; time_t now; - const char *old_name; /* * We do it this way instead of wrapping the whole loop in an @@ -152,16 +151,12 @@ void do_housekeeping(void) { */ /* First, do the "as often as needed" stuff... */ - old_name = CtdlThreadName("House Keeping - Journal"); JournalRunQueue(); - - CtdlThreadName("House Keeping - EVT_HOUSE"); - PerformSessionHooks(EVT_HOUSE); /* perform as needed housekeeping */ + PerformSessionHooks(EVT_HOUSE); /* Then, do the "once per minute" stuff... */ if (do_perminute_housekeeping_now) { cdb_check_handles(); /* suggested by Justin Case */ - CtdlThreadName("House Keeping - EVT_TIMER"); PerformSessionHooks(EVT_TIMER); /* Run any timer hooks */ } @@ -169,5 +164,4 @@ void do_housekeeping(void) { * All done. */ housekeeping_in_progress = 0; - CtdlThreadName(old_name); } diff --git a/citadel/modules/checkpoint/serv_checkpoint.c b/citadel/modules/checkpoint/serv_checkpoint.c index 061f980a7..83ac887f4 100644 --- a/citadel/modules/checkpoint/serv_checkpoint.c +++ b/citadel/modules/checkpoint/serv_checkpoint.c @@ -1,21 +1,21 @@ /* * checkpointing module for the database * - * Copyright (c) 1987-2009 by the citadel.org team + * Copyright (c) 1987-2011 by the citadel.org team * - * This program is free 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. + * 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. * - * 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. + * 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 + * 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 "sysdep.h" @@ -56,32 +56,12 @@ #include "ctdl_module.h" #include "context.h" -/* - * Main loop for the checkpoint thread. - */ -void *checkpoint_thread(void *arg) { - struct CitContext checkpointCC; - - - CtdlFillSystemContext(&checkpointCC, "checkpoint"); - citthread_setspecific(MyConKey, (void *)&checkpointCC ); - - syslog(LOG_DEBUG, "checkpoint_thread() initializing\n"); - while (!CtdlThreadCheckStop()) { - cdb_checkpoint(); - CtdlThreadSleep(60); - } - - syslog(LOG_DEBUG, "checkpoint_thread() exiting\n"); - CtdlClearSystemContext(); - return NULL; -} CTDL_MODULE_INIT(checkpoint) { if (threading) { - CtdlThreadCreate ("checkpoint", CTDLTHREAD_BIGSTACK, checkpoint_thread, NULL); + CtdlRegisterSessionHook(cdb_checkpoint, EVT_TIMER); } /* return our Subversion id for the Log */ return "checkpoint"; diff --git a/citadel/modules/expire/serv_expire.c b/citadel/modules/expire/serv_expire.c index bf1097381..70ddb316c 100644 --- a/citadel/modules/expire/serv_expire.c +++ b/citadel/modules/expire/serv_expire.c @@ -3,21 +3,21 @@ * * You might also see this module affectionately referred to as the DAP (the Dreaded Auto-Purger). * - * Copyright (c) 1988-2009 by citadel.org (Art Cancro, Wilifried Goesgens, and others) + * Copyright (c) 1988-2011 by citadel.org (Art Cancro, Wilifried Goesgens, and others) * - * This program is free 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. + * 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. * - * 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. + * 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 + * 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 * * * A brief technical discussion: @@ -148,7 +148,7 @@ void GatherPurgeMessages(struct ctdlroom *qrbuf, void *data) { time_t xtime, now; struct CtdlMessage *msg = NULL; int a; - struct cdbdata *cdbfr; + struct cdbdata *cdbfr; long *msglist = NULL; int num_msgs = 0; FILE *purgelist; @@ -167,13 +167,13 @@ void GatherPurgeMessages(struct ctdlroom *qrbuf, void *data) { if (!strcasecmp(qrbuf->QRname, SYSCONFIGROOM)) return; /* Ok, we got this far ... now let's see what's in the room */ - cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf->QRnumber, sizeof(long)); + cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf->QRnumber, sizeof(long)); - if (cdbfr != NULL) { - msglist = malloc(cdbfr->len); - memcpy(msglist, cdbfr->ptr, cdbfr->len); - num_msgs = cdbfr->len / sizeof(long); - cdb_free(cdbfr); + if (cdbfr != NULL) { + msglist = malloc(cdbfr->len); + memcpy(msglist, cdbfr->ptr, cdbfr->len); + num_msgs = cdbfr->len / sizeof(long); + cdb_free(cdbfr); } /* Nothing to do if there aren't any messages */ @@ -717,10 +717,10 @@ int PurgeUseTable(void) { * this will release this file from the serv_network.h * Maybe it could be a macro that extracts and casts the reult */ - memcpy(&ut, cdbut->ptr, - ((cdbut->len > sizeof(struct UseTable)) ? - sizeof(struct UseTable) : cdbut->len)); - cdb_free(cdbut); + memcpy(&ut, cdbut->ptr, + ((cdbut->len > sizeof(struct UseTable)) ? + sizeof(struct UseTable) : cdbut->len)); + cdb_free(cdbut); if ( (time(NULL) - ut.ut_timestamp) > USETABLE_RETAIN ) { uptr = (struct UPurgeList *) malloc(sizeof(struct UPurgeList)); @@ -784,7 +784,7 @@ int PurgeEuidIndexTable(void) { ++purged; } - cdb_free(cdbei); + cdb_free(cdbei); } @@ -854,183 +854,89 @@ int PurgeStaleOpenIDassociations(void) { -void *purge_databases(void *args) +void purge_databases(void) { - int retval; - static time_t last_purge = 0; - time_t now; - struct tm tm; - struct CitContext purgerCC; - - CtdlFillSystemContext(&purgerCC, "purger"); - citthread_setspecific(MyConKey, (void *)&purgerCC ); - syslog(LOG_DEBUG, "Auto-purger_thread() initializing\n"); - - while (!CtdlThreadCheckStop()) { - /* Do the auto-purge if the current hour equals the purge hour, - * but not if the operation has already been performed in the - * last twelve hours. This is usually enough granularity. - */ - now = time(NULL); - localtime_r(&now, &tm); - if ( - ((tm.tm_hour != config.c_purge_hour) || ((now - last_purge) < 43200)) - && (force_purge_now == 0) - ) { - CtdlThreadSleep(60); - continue; - } - - - syslog(LOG_INFO, "Auto-purger: starting.\n"); - - if (!CtdlThreadCheckStop()) - { - retval = PurgeUsers(); - syslog(LOG_NOTICE, "Purged %d users.\n", retval); - } - - if (!CtdlThreadCheckStop()) - { - PurgeMessages(); - syslog(LOG_NOTICE, "Expired %d messages.\n", messages_purged); - } - - if (!CtdlThreadCheckStop()) - { - retval = PurgeRooms(); - syslog(LOG_NOTICE, "Expired %d rooms.\n", retval); - } - - if (!CtdlThreadCheckStop()) - { - retval = PurgeVisits(); - syslog(LOG_NOTICE, "Purged %d visits.\n", retval); - } - - if (!CtdlThreadCheckStop()) - { - retval = PurgeUseTable(); - syslog(LOG_NOTICE, "Purged %d entries from the use table.\n", retval); - } - - if (!CtdlThreadCheckStop()) - { - retval = PurgeEuidIndexTable(); - syslog(LOG_NOTICE, "Purged %d entries from the EUID index.\n", retval); - } - - if (!CtdlThreadCheckStop()) - { - retval = PurgeStaleOpenIDassociations(); - syslog(LOG_NOTICE, "Purged %d stale OpenID associations.\n", retval); - } - - if (!CtdlThreadCheckStop()) - { - retval = TDAP_ProcessAdjRefCountQueue(); - syslog(LOG_NOTICE, "Processed %d message reference count adjustments.\n", retval); - } - - if (!CtdlThreadCheckStop()) - { - syslog(LOG_INFO, "Auto-purger: finished.\n"); - last_purge = now; /* So we don't do it again soon */ - force_purge_now = 0; - } - else - syslog(LOG_INFO, "Auto-purger: STOPPED.\n"); - - } - CtdlClearSystemContext(); - return NULL; -} -/*****************************************************************************/ - - -/* The FSCK command has been removed because people were misusing it */ - -#if 0 - -void do_fsck_msg(long msgnum, void *userdata) { - struct ctdlroomref *ptr; - - ptr = (struct ctdlroomref *)malloc(sizeof(struct ctdlroomref)); - ptr->next = rr; - ptr->msgnum = msgnum; - rr = ptr; -} - -void do_fsck_room(struct ctdlroom *qrbuf, void *data) -{ - CtdlGetRoom(&CC->room, qrbuf->QRname); - CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, do_fsck_msg, NULL); -} - -/* - * Check message reference counts - */ -void cmd_fsck(char *argbuf) { - long msgnum; - struct cdbdata *cdbmsg; - struct MetaData smi; - struct ctdlroomref *ptr; - int realcount; - - if (CtdlAccessCheck(ac_aide)) return; + int retval; + static time_t last_purge = 0; + time_t now; + struct tm tm; - /* Lame way of checking whether anyone else is doing this now */ - if (rr != NULL) { - cprintf("%d Another FSCK is already running.\n", ERROR + RESOURCE_BUSY); - return; + /* Do the auto-purge if the current hour equals the purge hour, + * but not if the operation has already been performed in the + * last twelve hours. This is usually enough granularity. + */ + now = time(NULL); + localtime_r(&now, &tm); + if ( + ((tm.tm_hour != config.c_purge_hour) || ((now - last_purge) < 43200)) + && (force_purge_now == 0) + ) { + return; } - cprintf("%d Checking message reference counts\n", LISTING_FOLLOWS); + syslog(LOG_INFO, "Auto-purger: starting.\n"); - cprintf("\nThis could take a while. Please be patient!\n\n"); - cprintf("Gathering pointers...\n"); - CtdlForEachRoom(do_fsck_room, NULL); - - get_control(); - cprintf("Checking message base...\n"); - for (msgnum = 0L; msgnum <= CitControl.MMhighest; ++msgnum) { - - cdbmsg = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long)); - if (cdbmsg != NULL) { - cdb_free(cdbmsg); - cprintf("Message %7ld ", msgnum); + if (!CtdlThreadCheckStop()) + { + retval = PurgeUsers(); + syslog(LOG_NOTICE, "Purged %d users.\n", retval); + } + + if (!CtdlThreadCheckStop()) + { + PurgeMessages(); + syslog(LOG_NOTICE, "Expired %d messages.\n", messages_purged); + } - GetMetaData(&smi, msgnum); - cprintf("refcount=%-2d ", smi.meta_refcount); + if (!CtdlThreadCheckStop()) + { + retval = PurgeRooms(); + syslog(LOG_NOTICE, "Expired %d rooms.\n", retval); + } - realcount = 0; - for (ptr = rr; ptr != NULL; ptr = ptr->next) { - if (ptr->msgnum == msgnum) ++realcount; - } - cprintf("realcount=%-2d\n", realcount); + if (!CtdlThreadCheckStop()) + { + retval = PurgeVisits(); + syslog(LOG_NOTICE, "Purged %d visits.\n", retval); + } - if ( (smi.meta_refcount != realcount) - || (realcount == 0) ) { - AdjRefCount(msgnum, (smi.meta_refcount - realcount)); - } + if (!CtdlThreadCheckStop()) + { + retval = PurgeUseTable(); + syslog(LOG_NOTICE, "Purged %d entries from the use table.\n", retval); + } - } + if (!CtdlThreadCheckStop()) + { + retval = PurgeEuidIndexTable(); + syslog(LOG_NOTICE, "Purged %d entries from the EUID index.\n", retval); + } + if (!CtdlThreadCheckStop()) + { + retval = PurgeStaleOpenIDassociations(); + syslog(LOG_NOTICE, "Purged %d stale OpenID associations.\n", retval); } - cprintf("Freeing memory...\n"); - while (rr != NULL) { - ptr = rr->next; - free(rr); - rr = ptr; + if (!CtdlThreadCheckStop()) + { + retval = TDAP_ProcessAdjRefCountQueue(); + syslog(LOG_NOTICE, "Processed %d message reference count adjustments.\n", retval); } - cprintf("Done!\n"); - cprintf("000\n"); + if (!CtdlThreadCheckStop()) + { + syslog(LOG_INFO, "Auto-purger: finished.\n"); + last_purge = now; /* So we don't do it again soon */ + force_purge_now = 0; + } + else { + syslog(LOG_INFO, "Auto-purger: STOPPED.\n"); + } + CtdlClearSystemContext(); } -#endif /* end of commented-out fsck cmd */ /* * Manually initiate a run of The Dreaded Auto-Purger (tm) @@ -1042,20 +948,17 @@ void cmd_tdap(char *argbuf) { } -/*****************************************************************************/ CTDL_MODULE_INIT(expire) { if (!threading) { - /* CtdlRegisterProtoHook(cmd_fsck, "FSCK", "Check message ref counts"); */ CtdlRegisterProtoHook(cmd_tdap, "TDAP", "Manually initiate auto-purger"); - CtdlRegisterProtoHook(cmd_gpex, "GPEX", "Get expire policy"); CtdlRegisterProtoHook(cmd_spex, "SPEX", "Set expire policy"); + CtdlRegisterSessionHook(purge_databases, EVT_TIMER); } - else - CtdlThreadCreate("Auto Purger", CTDLTHREAD_BIGSTACK, purge_databases, NULL); + /* return our Subversion id for the Log */ return "expire"; } diff --git a/citadel/modules/fulltext/serv_fulltext.c b/citadel/modules/fulltext/serv_fulltext.c index f7861ad03..bac3e90b9 100644 --- a/citadel/modules/fulltext/serv_fulltext.c +++ b/citadel/modules/fulltext/serv_fulltext.c @@ -1,8 +1,8 @@ /* * This module handles fulltext indexing of the message base. - * Copyright (c) 2005-2009 by the citadel.org team + * Copyright (c) 2005-2011 by the citadel.org team * - * This program is free software; you can redistribute it and/or modify + * 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. @@ -14,7 +14,7 @@ * * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -58,14 +58,11 @@ #include "ctdl_module.h" - - long ft_newhighest = 0L; long *ft_newmsgs = NULL; int ft_num_msgs = 0; int ft_num_alloc = 0; - int ftc_num_msgs[65536]; long *ftc_msgs[65536]; @@ -248,6 +245,9 @@ void do_fulltext_indexing(void) { static time_t last_progress = 0L; time_t run_time = 0L; time_t end_time = 0L; + static int is_running = 0; + if (is_running) return; /* Concurrency check - only one can run */ + is_running = 1; /* * Don't do this if the site doesn't have it enabled. @@ -260,13 +260,10 @@ void do_fulltext_indexing(void) { * Make sure we don't run the indexer too frequently. * FIXME move the setting into config */ -/* - * The thread sleeps for 300 seconds so we don't need this here any more if ( (time(NULL) - last_index) < 300L) { return; } -*/ /* * Check to see whether the fulltext index is up to date; if there @@ -346,8 +343,10 @@ void do_fulltext_indexing(void) { } end_time = time(NULL); - if (CtdlThreadCheckStop()) + if (CtdlThreadCheckStop()) { + is_running = 0; return; + } syslog(LOG_DEBUG, "do_fulltext_indexing() duration (%ld)\n", end_time - run_time); @@ -361,30 +360,10 @@ void do_fulltext_indexing(void) { last_index = time(NULL); syslog(LOG_DEBUG, "do_fulltext_indexing() finished\n"); + is_running = 0; return; } -/* - * Main loop for the indexer thread. - */ -void *indexer_thread(void *arg) { - struct CitContext indexerCC; - - - CtdlFillSystemContext(&indexerCC, "indexer"); - citthread_setspecific(MyConKey, (void *)&indexerCC ); - syslog(LOG_DEBUG, "indexer_thread() initializing\n"); - - while (!CtdlThreadCheckStop()) { - do_fulltext_indexing(); - CtdlThreadSleep(300); - } - - syslog(LOG_DEBUG, "indexer_thread() exiting\n"); - CtdlClearSystemContext(); - return NULL; -} - /* @@ -526,10 +505,7 @@ CTDL_MODULE_INIT(fulltext) CtdlRegisterDeleteHook(ft_delete_remove); CtdlRegisterSearchFuncHook(ft_search, "fulltext"); CtdlRegisterCleanupHook(noise_word_cleanup); - } - else - { - CtdlThreadCreate("Indexer", CTDLTHREAD_BIGSTACK, indexer_thread, NULL); + CtdlRegisterSessionHook(do_fulltext_indexing, EVT_TIMER); } /* return our Subversion id for the Log */ return "fulltext"; diff --git a/citadel/modules/network/serv_network.c b/citadel/modules/network/serv_network.c index eae59f394..99d7f6a28 100644 --- a/citadel/modules/network/serv_network.c +++ b/citadel/modules/network/serv_network.c @@ -2,9 +2,9 @@ * This module handles shared rooms, inter-Citadel mail, and outbound * mailing list processing. * - * Copyright (c) 2000-2010 by the citadel.org team + * Copyright (c) 2000-2011 by the citadel.org team * - * This program is free software; you can redistribute it and/or modify + * 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. @@ -92,9 +92,6 @@ -/* Nonzero while we are doing network processing */ -static int doing_queue = 0; - /* * When we do network processing, it's accomplished in two passes; one to * gather a list of rooms and one to actually do them. It's ok that rplist @@ -2311,6 +2308,7 @@ void create_spool_dirs(void) { * Run through the rooms doing various types of network stuff. */ void network_do_queue(void) { + static int doing_queue = 0; static time_t last_run = 0L; struct RoomProcList *ptr; int full_processing = 1; @@ -2476,24 +2474,6 @@ int network_room_handler (struct ctdlroom *room) return 0; } -void *ignet_thread(void *arg) { - struct CitContext ignet_thread_CC; - - syslog(LOG_DEBUG, "ignet_thread() initializing\n"); - CtdlFillSystemContext(&ignet_thread_CC, "IGnet Queue"); - citthread_setspecific(MyConKey, (void *)&ignet_thread_CC); - - while (!CtdlThreadCheckStop()) { - network_do_queue(); - CtdlThreadSleep(60); - } - - CtdlClearSystemContext(); - return(NULL); -} - - - /* * Module entry point @@ -2509,7 +2489,7 @@ CTDL_MODULE_INIT(network) CtdlRegisterProtoHook(cmd_nsyn, "NSYN", "Synchronize room to node"); CtdlRegisterRoomHook(network_room_handler); CtdlRegisterCleanupHook(destroy_network_queue_room); - CtdlThreadCreate("SMTP Send", CTDLTHREAD_BIGSTACK, ignet_thread, NULL); + CtdlRegisterSessionHook(network_do_queue, EVT_TIMER); } return "network"; } diff --git a/citadel/modules/smtp/serv_smtpclient.c b/citadel/modules/smtp/serv_smtpclient.c index 9782d3e42..d4ca65264 100644 --- a/citadel/modules/smtp/serv_smtpclient.c +++ b/citadel/modules/smtp/serv_smtpclient.c @@ -20,9 +20,9 @@ * The VRFY and EXPN commands have been removed from this implementation * because nobody uses these commands anymore, except for spammers. * - * Copyright (c) 1998-2009 by the citadel.org team + * Copyright (c) 1998-2011 by the citadel.org team * - * This program is free software; you can redistribute it and/or modify + * 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. @@ -937,30 +937,23 @@ void cmd_smtp(char *argbuf) { * * Run through the queue sending out messages. */ -void *smtp_queue_thread(void *arg) { +void smtp_do_queue(void) { + static int is_running = 0; int num_processed = 0; - struct CitContext smtp_queue_CC; - CtdlFillSystemContext(&smtp_queue_CC, "SMTP Send"); - citthread_setspecific(MyConKey, (void *)&smtp_queue_CC); - syslog(LOG_DEBUG, "smtp_queue_thread() initializing\n"); + if (is_running) return; /* Concurrency check - only one can run */ + is_running = 1; - while (!CtdlThreadCheckStop()) { - - syslog(LOG_INFO, "SMTP client: processing outbound queue\n"); + syslog(LOG_INFO, "SMTP client: processing outbound queue\n"); - if (CtdlGetRoom(&CC->room, SMTP_SPOOLOUT_ROOM) != 0) { - syslog(LOG_ERR, "Cannot find room <%s>\n", SMTP_SPOOLOUT_ROOM); - } - else { - num_processed = CtdlForEachMessage(MSGS_ALL, 0L, NULL, SPOOLMIME, NULL, smtp_do_procmsg, NULL); - } - syslog(LOG_INFO, "SMTP client: queue run completed; %d messages processed\n", num_processed); - CtdlThreadSleep(60); + if (CtdlGetRoom(&CC->room, SMTP_SPOOLOUT_ROOM) != 0) { + syslog(LOG_ERR, "Cannot find room <%s>\n", SMTP_SPOOLOUT_ROOM); } - - CtdlClearSystemContext(); - return(NULL); + else { + num_processed = CtdlForEachMessage(MSGS_ALL, 0L, NULL, SPOOLMIME, NULL, smtp_do_procmsg, NULL); + } + syslog(LOG_INFO, "SMTP client: queue run completed; %d messages processed\n", num_processed); + is_running = 0; } @@ -995,7 +988,7 @@ CTDL_MODULE_INIT(smtp_client) if (!threading) { smtp_init_spoolout(); - CtdlThreadCreate("SMTP Send", CTDLTHREAD_BIGSTACK, smtp_queue_thread, NULL); + CtdlRegisterSessionHook(smtp_do_queue, EVT_TIMER); CtdlRegisterProtoHook(cmd_smtp, "SMTP", "SMTP utility commands"); } diff --git a/citadel/server_main.c b/citadel/server_main.c index 86cf5b0b0..cc4570466 100644 --- a/citadel/server_main.c +++ b/citadel/server_main.c @@ -116,12 +116,6 @@ int main(int argc, char **argv) // eCrashSymbolTable symbol_table; #endif -#ifdef HAVE_GC - GC_INIT(); - GC_find_leak = 1; -#endif - - /* initialise semaphores here. Patch by Matt and davew * its called here as they are needed by syslog for thread safety */ @@ -143,11 +137,6 @@ int main(int argc, char **argv) running_as_daemon = 1; } - /* run a few stats if -s was specified */ - else if (!strncmp(argv[a], "-s", 2)) { - statcount = atoi(&argv[a][2]); - } - else if (!strncmp(argv[a], "-h", 2)) { relh=argv[a][2]!='/'; if (!relh) safestrncpy(ctdl_home_directory, &argv[a][2], @@ -397,7 +386,6 @@ int main(int argc, char **argv) go_threading(); - master_cleanup(exit_signal); return(0); } diff --git a/citadel/sysdep.c b/citadel/sysdep.c index 9809cddbb..4c19d2933 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -168,22 +168,14 @@ void init_sysdep(void) { */ sigemptyset(&set); sigaddset(&set, SIGINT); // intr = shutdown - // sigaddset(&set, SIGQUIT); // quit = force quit sigaddset(&set, SIGHUP); sigaddset(&set, SIGTERM); - // sigaddset(&set, SIGSEGV); // we want core dumps - // sigaddset(&set, SIGILL); // we want core dumps - // sigaddset(&set, SIGBUS); sigprocmask(SIG_UNBLOCK, &set, NULL); signal(SIGINT, signal_cleanup); // intr = shutdown - // signal(SIGQUIT, signal_cleanup); // quit = force quit signal(SIGHUP, signal_cleanup); signal(SIGTERM, signal_cleanup); signal(SIGUSR2, signal_exit); - // signal(SIGSEGV, signal_cleanup); // we want coredumps - // signal(SIGILL, signal_cleanup); // we want core dumps - // signal(SIGBUS, signal_cleanup); /* * Do not shut down the server on broken pipe signals, otherwise the @@ -1166,31 +1158,6 @@ int convert_login(char NameToConvert[]) { /* * This loop just keeps going and going and going... */ -/* - * FIXME: - * This current implimentation of worker_thread creates a bottle neck in several situations - * The first thing to remember is that a single thread can handle more than one connection at a time. - * More threads mean less memory for the system to run in. - * So for efficiency we want every thread to be doing something useful or waiting in the main loop for - * something to happen anywhere. - * This current implimentation requires worker threads to wait in other locations, after it has - * been committed to a single connection which is very wasteful. - * As an extreme case consider this: - * A slow client connects and this slow client sends only one character each second. - * With this current implimentation a single worker thread is dispatched to handle that connection - * until such times as the client timeout expires, an error occurs on the socket or the client - * completes its transmission. - * THIS IS VERY BAD since that thread could have handled a read from many more clients in each one - * second interval between chars. - * - * It is my intention to re-write this code and the associated client_getln, client_read functions - * to allow any thread to read data on behalf of any connection (context). - * To do this I intend to have this main loop read chars into a buffer stored in the context. - * Once the correct criteria for a full buffer is met then we will dispatch a thread to - * process it. - * This worker thread loop also needs to be able to handle binary data. - */ - void *worker_thread(void *arg) { int highest; CitContext *ptr; diff --git a/citadel/threads.c b/citadel/threads.c index 68ec83ca9..e87ac935d 100644 --- a/citadel/threads.c +++ b/citadel/threads.c @@ -81,8 +81,6 @@ static int num_threads = 0; /* Current number of threads */ static int num_workers = 0; /* Current number of worker threads */ -long statcount = 0; /* are we doing a stats check? */ -static long stats_done = 0; CtdlThreadNode *CtdlThreadList = NULL; CtdlThreadNode *CtdlThreadSchedList = NULL; @@ -1210,32 +1208,6 @@ void *new_worker_thread(void *arg); extern void close_masters (void); -void *simulation_worker (void*arg) { - struct CitContext *this; - - this = CreateNewContext(); - CtdlThreadSleep(1); - this->kill_me = KILLME_SIMULATION_WORKER; - this->state = CON_IDLE; - dead_session_purge(1); - begin_critical_section(S_SESSION_TABLE); - stats_done++; - end_critical_section(S_SESSION_TABLE); - return NULL; -} - - -void *simulation_thread (void *arg) -{ - long stats = statcount; - - while(stats && !CtdlThreadCheckStop()) { - CtdlThreadCreate("Connection simulation worker", CTDLTHREAD_BIGSTACK, simulation_worker, NULL); - stats--; - } - CtdlThreadStopAll(); - return NULL; -} void go_threading(void) { @@ -1250,16 +1222,8 @@ void go_threading(void) ctdl_thread_internal_init(); /* Second call to module init functions now that threading is up */ - if (!statcount) { - initialise_modules(1); - CtdlThreadCreate("select_on_master", CTDLTHREAD_BIGSTACK, select_on_master, NULL); - } - else { - syslog(LOG_EMERG, "Running connection simulation stats\n"); - gettimeofday(&start, NULL); - CtdlThreadCreate("Connection simulation master", CTDLTHREAD_BIGSTACK, simulation_thread, NULL); - } - + initialise_modules(1); + CtdlThreadCreate("select_on_master", CTDLTHREAD_BIGSTACK, select_on_master, NULL); /* * This thread is now used for garbage collection of other threads in the thread list @@ -1328,8 +1292,11 @@ void go_threading(void) /* FIXME: come up with a better way to dynamically alter the number of threads * based on the system load */ - if (!statcount) { - if ((((CtdlThreadGetWorkers() < config.c_max_workers) && (CtdlThreadGetWorkerAvg() > 60)) || CtdlThreadGetWorkers() < config.c_min_workers) && (CT->state > CTDL_THREAD_STOP_REQ)) + if ( (((CtdlThreadGetWorkers() < config.c_max_workers) + && (CtdlThreadGetWorkerAvg() > 60)) + || CtdlThreadGetWorkers() < config.c_min_workers) + && (CT->state > CTDL_THREAD_STOP_REQ) + ) { /* Only start new threads if we are not going to overload the machine */ /* Temporarily set to 10 should be enough to make sure we don't stranglew the server @@ -1346,7 +1313,6 @@ void go_threading(void) else syslog(LOG_WARNING, "Server strangled due to machine load average too high.\n"); } - } CtdlThreadGC(); @@ -1366,13 +1332,6 @@ void go_threading(void) * If the above loop exits we must be shutting down since we obviously have no threads */ ctdl_thread_internal_cleanup(); - - if (statcount) { - gettimeofday(&now, NULL); - timersub(&now, &start, &result); - last_duration = (double)result.tv_sec + ((double)result.tv_usec / (double) 1000000); - syslog(LOG_EMERG, "Simulated %ld connections in %f seconds\n", stats_done, last_duration); - } }