* The full text indexer now runs in its own dedicated thread instead of
authorArt Cancro <ajc@citadel.org>
Wed, 1 Jun 2005 05:23:26 +0000 (05:23 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 1 Jun 2005 05:23:26 +0000 (05:23 +0000)
  in the housekeeping thread.  The main indexer loop now also has the ability
  to save its place and bail out early when it discovers that the server is
  trying to shut down.  The main server loop will pthread_join() the indexer
  thread and patiently wait for it to complete before exiting.  These changes
  all put together mean that citserver will not hang when it is terminated
  during an indexing operation.

citadel/ChangeLog
citadel/citserver.c
citadel/serv_fulltext.c
citadel/serv_fulltext.h
citadel/server_main.c
citadel/sysconfig.h
citadel/sysdep.c
citadel/sysdep_decls.h

index 7d417c34f093506b65a101b5c1b713e28fb2cd46..3c075a6498beaf2fdf2d20d15a0eff90808577d6 100644 (file)
@@ -6764,3 +6764,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
+
index 473e256b30893675d882b05336a876c63e6e8d99..1e32ea54b5ceca67679346b84a3bd6d76b30c88b 100644 (file)
@@ -148,6 +148,10 @@ void master_cleanup(int exitcode) {
                (*fcn->h_function_pointer)();
        }
 
+       /* Shut down the indexer thread */
+       lprintf(CTDL_INFO, "Waiting for the indexer thread to shut down\n");
+       pthread_join(indexer_thread_tid, NULL);
+
        /* Close databases */
        lprintf(CTDL_INFO, "Closing databases\n");
        close_databases();
index d2384ab4f4f97521cb6f127e231ee7d74dcd216a..61e2085bda2cebaaeb13f02aa3692f44de970b65 100644 (file)
@@ -253,6 +253,14 @@ void do_fulltext_indexing(void) {
                                last_progress = time(NULL);
                        }
                        ft_index_message(ft_newmsgs[i], 1);
+
+                       /* Check to see if we need to quit early */
+                       if (time_to_die) {
+                               lprintf(CTDL_DEBUG, "Indexer quitting early\n");
+                               ft_newhighest = ft_newmsgs[i];
+                               break;
+                       }
+
                }
 
                free(ft_newmsgs);
@@ -271,6 +279,31 @@ void do_fulltext_indexing(void) {
        return;
 }
 
+/*
+ * Main loop for the indexer thread.
+ */
+void *indexer_thread(void *arg) {
+       struct CitContext indexerCC;
+
+       lprintf(CTDL_DEBUG, "indexer_thread() initializing\n");
+
+       memset(&indexerCC, 0, sizeof(struct CitContext));
+       indexerCC.internal_pgm = 1;
+       indexerCC.cs_pid = 0;
+       pthread_setspecific(MyConKey, (void *)&indexerCC );
+
+       cdb_allocate_tsd();
+
+       while (!time_to_die) {
+               do_fulltext_indexing();
+               sleep(1);
+       }
+
+       lprintf(CTDL_DEBUG, "indexer_thread() exiting\n");
+       pthread_exit(NULL);
+}
+
+
 
 /*
  * API call to perform searches.
@@ -378,7 +411,6 @@ void cmd_srch(char *argbuf) {
 
 char *serv_fulltext_init(void)
 {
-       CtdlRegisterSessionHook(do_fulltext_indexing, EVT_TIMER);
        CtdlRegisterProtoHook(cmd_srch, "SRCH", "Full text search");
        return "$Id$";
 }
index c083af261d853f111497ecdabb508aafefb92df3..5a106f7af44642636d40322b5cc11ab8016db716 100644 (file)
@@ -5,3 +5,4 @@
 
 void ft_index_message(long msgnum, int op);
 void ft_search(int *fts_num_msgs, long **fts_msgs, char *search_string);
+void *indexer_thread(void *arg);
index 75c6c713752a4139f5aa8f8c5c4eb5ba6fbe98d5..fdf8e15893fcfaa7f667fd5537cba72dfe701f3f 100644 (file)
@@ -241,6 +241,9 @@ int main(int argc, char **argv)
        }
        end_critical_section(S_WORKER_LIST);
 
+       /* Create the indexer thread. */
+       create_indexer_thread();
+
        /* Now this thread can become a worker as well. */
        worker_thread(NULL);
 
index bdb78502d763496e71a9d3a1677034342ef0fd49..9c233555cf8e16fe16889667d6d8076c4f2c0173 100644 (file)
 #define CTDL_KEY_PATH          CTDL_CRYPTO_DIR "/citadel.key"
 #define CTDL_CSR_PATH          CTDL_CRYPTO_DIR "/citadel.csr"
 #define CTDL_CER_PATH          CTDL_CRYPTO_DIR "/citadel.cer"
+
+#define THREADSTACKSIZE                1048576
index 30247b9618c0bd701f7cde4bf807d09d78a32dc2..b71c068a2819e4f359d47c1b64109f46bf346c90 100644 (file)
@@ -66,6 +66,7 @@
 #include "housekeeping.h"
 #include "tools.h"
 #include "serv_crypto.h"
+#include "serv_fulltext.h"
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
@@ -97,6 +98,7 @@ struct CitContext masterCC;
 time_t last_purge = 0;                         /* Last dead session purge */
 static int num_threads = 0;                    /* Current number of threads */
 int num_sessions = 0;                          /* Current number of sessions */
+pthread_t indexer_thread_tid;
 
 int syslog_facility = (-1);
 int enable_syslog = 0;
@@ -410,8 +412,7 @@ struct CitContext *MyContext(void) {
  * Initialize a new context and place it in the list.  The session number
  * used to be the PID (which is why it's called cs_pid), but that was when we
  * had one process per session.  Now we just assign them sequentially, starting
- * at 1 (don't change it to 0 because masterCC uses 0) and re-using them when
- * sessions terminate.
+ * at 1 (don't change it to 0 because masterCC uses 0).
  */
 struct CitContext *CreateNewContext(void) {
        struct CitContext *me;
@@ -787,12 +788,13 @@ void create_worker(void) {
                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.
+       /* 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, 1024 * 1024))) {
-               lprintf(CTDL_EMERG, "pthread_attr_setstacksize: %s\n", strerror(ret));
+       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;
@@ -811,6 +813,41 @@ void create_worker(void) {
 }
 
 
+/*
+ * Create the indexer thread and begin its operation.
+ */
+void create_indexer_thread(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;
+       }
+
+       if ((ret = pthread_create(&indexer_thread_tid, &attr, indexer_thread, NULL) != 0))
+       {
+               lprintf(CTDL_ALERT, "Can't create indexer thread: %s\n",
+                       strerror(ret));
+       }
+
+       pthread_attr_destroy(&attr);
+}
+
+
 
 /*
  * Purge all sessions which have the 'kill_me' flag set.
index a4d574435705e4a722e054132e31a1b457973664..99071ec3cc3b4c9fee1cb6ebae8981740d97dcfa 100644 (file)
@@ -41,6 +41,8 @@ void lprintf (enum LogLevel loglevel, const char *format, ...);
 void cprintf (const char *format, ...);
 #endif
 
+extern pthread_key_t MyConKey;                 /* TSD key for MyContext() */
+
 extern int enable_syslog;
 
 void init_sysdep (void);
@@ -95,3 +97,6 @@ void tracked_free(void *ptr);
 char *tracked_strdup(const char *s, char *file, int line);
 void dump_heap(void);
 #endif
+
+void create_indexer_thread(void);
+extern pthread_t indexer_thread_tid;