serv_network.c and msgbase.c: preliminary work for making
authorArt Cancro <ajc@citadel.org>
Thu, 21 Sep 2006 04:03:08 +0000 (04:03 +0000)
committerArt Cancro <ajc@citadel.org>
Thu, 21 Sep 2006 04:03:08 +0000 (04:03 +0000)
the networker more quickly aware of which rooms have recently
posted messages.  This still runs at a one minute granularity, which
is still too slow.  Need to reduce it to seconds in order to submit
rooms for Sieve processing using the networker.

citadel/msgbase.c
citadel/serv_network.c
citadel/serv_network.h
citadel/serv_sieve.c
citadel/server.h
citadel/sysdep.c

index cefc3edb87ec1df406609cd934dcae82cd3ff80d..978b19e9d1499bc169cfa0d3725b9acc71bc994f 100644 (file)
@@ -52,6 +52,7 @@
 #include "euidindex.h"
 #include "journaling.h"
 #include "citadel_dirs.h"
+#include "serv_network.h"
 
 long config_msgnum;
 struct addresses_to_be_filed *atbf = NULL;
@@ -2032,6 +2033,9 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms
                lprintf(CTDL_DEBUG, "CtdlSaveMsgPointerInRoom() skips repl checks\n");
        }
 
+       /* Submit this room for net processing */
+       network_queue_room(&CC->room, NULL);
+
        /* Go back to the room we were in before we wandered here... */
        getroom(&CC->room, hold_rm);
 
index a769aab3e3c20a4cba7c88abb75881f82f322836..a3b98a4f83b02d7dbbaa90b37ef0aa924852ed43 100644 (file)
@@ -77,8 +77,7 @@ 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
- * is global; this process *only* runs as part of the housekeeping loop and
- * therefore only one will run at a time.
+ * is global; we have a mutex that keeps it safe.
  */
 struct RoomProcList *rplist = NULL;
 
@@ -890,6 +889,11 @@ void network_spoolout_room(char *room_to_spool) {
        int skipthisline = 0;
        int i;
 
+       /*
+        * If the room doesn't exist, don't try to perform its networking tasks.
+        * Normally this should never happen, but once in a while maybe a room gets
+        * queued for networking and then deleted before it can happen.
+        */
        if (getroom(&CC->room, room_to_spool) != 0) {
                lprintf(CTDL_CRIT, "ERROR: cannot load <%s>\n", room_to_spool);
                return;
@@ -900,6 +904,7 @@ void network_spoolout_room(char *room_to_spool) {
 
        begin_critical_section(S_NETCONFIGS);
 
+       /* Only do net processing for rooms that have netconfigs */
        fp = fopen(filename, "r");
        if (fp == NULL) {
                end_critical_section(S_NETCONFIGS);
@@ -1171,8 +1176,10 @@ void network_queue_room(struct ctdlroom *qrbuf, void *data) {
        if (ptr == NULL) return;
 
        safestrncpy(ptr->name, qrbuf->QRname, sizeof ptr->name);
+       begin_critical_section(S_RPLIST);
        ptr->next = rplist;
        rplist = ptr;
+       end_critical_section(S_RPLIST);
 }
 
 
@@ -1949,13 +1956,31 @@ void network_do_queue(void) {
        if (full_processing) {
                lprintf(CTDL_DEBUG, "network: loading outbound queue\n");
                ForEachRoom(network_queue_room, NULL);
+       }
 
+       if (rplist != NULL) {
                lprintf(CTDL_DEBUG, "network: running outbound queue\n");
                while (rplist != NULL) {
-                       network_spoolout_room(rplist->name);
+                       char spoolroomname[ROOMNAMELEN];
+                       safestrncpy(spoolroomname, rplist->name, sizeof spoolroomname);
+                       begin_critical_section(S_RPLIST);
+
+                       /* pop this record off the list */
                        ptr = rplist;
                        rplist = rplist->next;
                        free(ptr);
+
+                       /* invalidate any duplicate entries to prevent double processing */
+                       for (ptr=rplist; ptr!=NULL; ptr=ptr->next) {
+                               if (!strcasecmp(ptr->name, spoolroomname)) {
+                                       ptr->name[0] = 0;
+                               }
+                       }
+
+                       end_critical_section(S_RPLIST);
+                       if (spoolroomname[0] != 0) {
+                               network_spoolout_room(spoolroomname);
+                       }
                }
        }
 
index 5c48b8d28d753e66c384b3ac0d1a3f2f0f3ceff6..39e04b9d7f011b5f6c453b33ba382829849b0c37 100644 (file)
@@ -41,3 +41,5 @@ struct FilterList {
 };
 
 extern struct FilterList *filterlist;
+
+void network_queue_room(struct ctdlroom *, void *);
index 430f35970299b5789ad3a44d2c7bf516e4e8a29b..e9fca4f50be01397f3f2a68a9c4e00d56b8eb245 100644 (file)
@@ -53,7 +53,6 @@
  */
 void log_the_sieve2_credits(void) {
        char *cred = NULL;
-       char *ptr;
 
        cred = strdup(sieve2_credits());
        if (cred == NULL) return;
index c45b081c332f6d7bb5b6a794cd3c02e435e5b33e..3e59e13f5fa49e79089c1b3619df4c37b45fa557 100644 (file)
@@ -221,6 +221,7 @@ enum {
        S_DEBUGMEMLEAKS,
        S_ATBF,
        S_JOURNAL_QUEUE,
+       S_RPLIST,
        MAX_SEMAPHORES
 };
 
index 7d65e6c8a646f605b643f4a215b36033a91f5df6..3e3e2cff6419d554f64dfbdda8c0caae4fd7c1ac 100644 (file)
@@ -248,6 +248,7 @@ void begin_critical_section(int which_one)
 #ifdef DEBUG_MEMORY_LEAKS
                && (which_one != S_DEBUGMEMLEAKS)
 #endif
+               && (which_one != S_RPLIST)
        ) {
                cdb_check_handles();
        }