* Scheduler fix ... added the rescan pipe back in
authorArt Cancro <ajc@citadel.org>
Wed, 16 Jun 2004 03:13:03 +0000 (03:13 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 16 Jun 2004 03:13:03 +0000 (03:13 +0000)
13 files changed:
citadel/ChangeLog
citadel/imap_fetch.c
citadel/imap_search.c
citadel/msgbase.c
citadel/msgbase.h
citadel/serv_calendar.c
citadel/serv_expire.c
citadel/serv_inetcfg.c
citadel/serv_network.c
citadel/serv_smtp.c
citadel/serv_vandelay.c
citadel/serv_vcard.c
citadel/sysdep.c

index d4215549dd5db298df955ce584d7d23f58bb63b7..5898423d994b7f788dd0cd71aae8fe4bf6cda74e 100644 (file)
@@ -1,4 +1,7 @@
  $Log$
+ Revision 621.15  2004/06/16 03:13:02  ajc
+ * Scheduler fix ... added the rescan pipe back in
+
  Revision 621.14  2004/06/15 20:42:42  ajc
  * Store the body of any large (>1K) message in a separate database.  This
    will allow fast headers-only retrieval later.
@@ -5847,3 +5850,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 88542173a7ee7ffbc6ea300fd836cf9278eb570b..b8b7c7cbc830693c99164db3da4cda3c0c79956e 100644 (file)
@@ -579,7 +579,7 @@ void imap_fetch_body(long msgnum, char *item, int is_peek) {
                        lprintf(CTDL_CRIT, "Cannot open temp file: %s\n", strerror(errno));
                        return;
                }
-               msg = CtdlFetchMessage(msgnum);
+               msg = CtdlFetchMessage(msgnum, 1);
        }
 
        /* Now figure out what the client wants, and get it */
@@ -930,16 +930,16 @@ void imap_do_fetch_msg(int seq,
                /* Otherwise, load the message into memory.
                 */
                else if (!strcasecmp(itemlist[i], "BODYSTRUCTURE")) {
-                       if (msg == NULL) msg = CtdlFetchMessage(IMAP->msgids[seq-1]);
+                       if (msg == NULL) msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        imap_fetch_bodystructure(IMAP->msgids[seq-1],
                                        itemlist[i], msg);
                }
                else if (!strcasecmp(itemlist[i], "ENVELOPE")) {
-                       if (msg == NULL) msg = CtdlFetchMessage(IMAP->msgids[seq-1]);
+                       if (msg == NULL) msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        imap_fetch_envelope(IMAP->msgids[seq-1], msg);
                }
                else if (!strcasecmp(itemlist[i], "INTERNALDATE")) {
-                       if (msg == NULL) msg = CtdlFetchMessage(IMAP->msgids[seq-1]);
+                       if (msg == NULL) msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        imap_fetch_internaldate(msg);
                }
 
index dce7e605dad2a1395615f2bdd3c6e5a351a13be9..f85c30da8d07c3e5c3a2edcc10e9a110be108cfe 100644 (file)
@@ -375,7 +375,7 @@ void imap_do_search(int num_items, char **itemlist, int is_uid) {
        if (IMAP->num_msgs > 0)
         for (i = 0; i < IMAP->num_msgs; ++i)
          if (IMAP->flags[i] && IMAP_SELECTED) {
-               msg = CtdlFetchMessage(IMAP->msgids[i]);
+               msg = CtdlFetchMessage(IMAP->msgids[i], 1);
                if (msg != NULL) {
                        if (imap_do_search_msg(i+1, msg, num_items,
                           itemlist, is_uid)) {
index 16b4267bbf3f2c4e429dfec870e28dbb42e4893f..a34dadd27d863d31787508f717c9cb01c1dda211 100644 (file)
@@ -472,7 +472,7 @@ int CtdlForEachMessage(int mode, long ref,
        if (num_msgs > 0) {
                if (compare != NULL) {
                        for (a = 0; a < num_msgs; ++a) {
-                               msg = CtdlFetchMessage(msglist[a]);
+                               msg = CtdlFetchMessage(msglist[a], 1);
                                if (msg != NULL) {
                                        if (CtdlMsgCmp(msg, compare)) {
                                                msglist[a] = 0L;
@@ -781,7 +781,7 @@ void mime_download(char *name, char *filename, char *partnum, char *disp,
  * NOTE: Caller is responsible for freeing the returned CtdlMessage struct
  *       using the CtdlMessageFree() function.
  */
-struct CtdlMessage *CtdlFetchMessage(long msgnum)
+struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
 {
        struct cdbdata *dmsgtext;
        struct cdbdata *dbigmsg;
@@ -1091,9 +1091,16 @@ int CtdlOutputMsg(long msg_num,          /* message number (local) to fetch */
         */
 
        /*
-        * Fetch the message from disk.
+        * Fetch the message from disk.  If we're in sooper-fast headers
+        * only mode, request that we don't even bother loading the body
+        * into memory.
         */
-       TheMessage = CtdlFetchMessage(msg_num);
+       if (headers_only == HEADERS_FAST) {
+               TheMessage = CtdlFetchMessage(msg_num, 0);
+       }
+       else {
+               TheMessage = CtdlFetchMessage(msg_num, 1);
+       }
 
        if (TheMessage == NULL) {
                if (do_proto) cprintf("%d Can't locate msg %ld on disk\n",
@@ -1541,7 +1548,7 @@ void cmd_msg3(char *cmdbuf)
        }
 
        msgnum = extract_long(cmdbuf, 0);
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n", 
                        ERROR + MESSAGE_NOT_FOUND, msgnum);
@@ -1627,7 +1634,7 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int flags) {
        if (  (flags & SM_VERIFY_GOODNESS)
           || (flags & SM_DO_REPL_CHECK)
           ) {
-               msg = CtdlFetchMessage(msgid);
+               msg = CtdlFetchMessage(msgid, 1);
                if (msg == NULL) return(ERROR + ILLEGAL_VALUE);
        }
 
@@ -1852,7 +1859,7 @@ void check_repl(long msgnum, void *userdata) {
        time_t timestamp = (-1L);
 
        lprintf(CTDL_DEBUG, "check_repl() found message %ld\n", msgnum);
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) return;
        if (msg->cm_fields['T'] != NULL) {
                timestamp = atol(msg->cm_fields['T']);
@@ -3264,7 +3271,7 @@ char *CtdlGetSysConfig(char *sysconfname) {
                conf = NULL;
        }
        else {
-               msg = CtdlFetchMessage(msgnum);
+               msg = CtdlFetchMessage(msgnum, 1);
                if (msg != NULL) {
                        conf = strdup(msg->cm_fields['M']);
                        CtdlFreeMessage(msg);
index f009909ff8116341e153d77878bba0170bcaea08..e201ac01366bb884d9af49bc657eda65421b5eb4 100644 (file)
@@ -102,7 +102,7 @@ int CtdlForEachMessage(int mode, long ref,
 int CtdlDeleteMessages(char *, long, char *);
 void CtdlWriteObject(char *, char *, char *, struct ctdluser *,
                        int, int, unsigned int);
-struct CtdlMessage *CtdlFetchMessage(long msgnum);
+struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body);
 void CtdlFreeMessage(struct CtdlMessage *msg);
 void serialize_message(struct ser_ret *, struct CtdlMessage *);
 int is_valid_message(struct CtdlMessage *);
index fb259f7d1783d6bdb99bf839b1b6e902b5bea263..f53719234883146c5964f7b3363df1e409f22a81 100644 (file)
@@ -387,7 +387,7 @@ void ical_respond(long msgnum, char *partnum, char *action) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -656,7 +656,7 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) {
         * us the ability to load the event into memory so we can diddle the
         * attendees.
         */
-       msg = CtdlFetchMessage(msgnum_being_replaced);
+       msg = CtdlFetchMessage(msgnum_being_replaced, 1);
        if (msg == NULL) {
                return(2);                      /* internal error */
        }
@@ -733,7 +733,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -896,7 +896,7 @@ void ical_hunt_for_conflicts_backend(long msgnum, void *data) {
        strcpy(conflict_event_uid, "");
        strcpy(conflict_event_summary, "");
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
@@ -1003,7 +1003,7 @@ void ical_conflicts(long msgnum, char *partnum) {
        struct CtdlMessage *msg;
        struct ical_respond_data ird;
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) {
                cprintf("%d Message %ld not found.\n",
                        ERROR + ILLEGAL_VALUE,
@@ -1145,7 +1145,7 @@ void ical_freebusy_backend(long msgnum, void *data) {
 
        cal = (icalcomponent *)data;
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) return;
        memset(&ird, 0, sizeof ird);
        strcpy(ird.desired_partnum, "_HUNT_");
index 083cb5d3c34f2dfced848bee8f41fa40d993ada4..cac821ff95d0ace4db68107ebf955c1d3458a55b 100644 (file)
@@ -167,7 +167,7 @@ void GatherPurgeMessages(struct ctdlroom *qrbuf, void *data) {
                for (a=0; a<num_msgs; ++a) {
                        delnum = msglist[a];
 
-                       msg = CtdlFetchMessage(delnum);
+                       msg = CtdlFetchMessage(delnum, 0); /* dont need body */
                        if (msg != NULL) {
                                xtime = atol(msg->cm_fields['T']);
                                CtdlFreeMessage(msg);
index af7f35dfbe4602e3e482623b51d30d611095af4a..93ff9990f590fd2c93fdca1e58546008dd95bbc8 100644 (file)
@@ -142,7 +142,7 @@ int inetcfg_aftersave(struct CtdlMessage *msg) {
 void inetcfg_init_backend(long msgnum, void *userdata) {
        struct CtdlMessage *msg;
 
-               msg = CtdlFetchMessage(msgnum);
+               msg = CtdlFetchMessage(msgnum, 1);
                if (msg != NULL) {
                inetcfg_setTo(msg);
                        CtdlFreeMessage(msg);
@@ -154,7 +154,7 @@ void inetcfg_init_backend(long msgnum, void *userdata) {
 void spamstrings_init_backend(long msgnum, void *userdata) {
        struct CtdlMessage *msg;
 
-               msg = CtdlFetchMessage(msgnum);
+               msg = CtdlFetchMessage(msgnum, 1);
                if (msg != NULL) {
                spamstrings_setTo(msg);
                        CtdlFreeMessage(msg);
index 53872ce3b2e26ee63598a75b54f9a4714de2a097..19942b8862939b74d5acc98a9de76c295d561001 100644 (file)
@@ -482,7 +482,7 @@ void network_spool_msg(long msgnum, void *userdata) {
         */
        if (sc->ignet_push_shares != NULL) {
        
-               msg = CtdlFetchMessage(msgnum);
+               msg = CtdlFetchMessage(msgnum, 1);
                if (msg != NULL) {
                        size_t newpath_len;
 
index 840cbf1b2304ce70c713dce0db7b672747c136fe..8111416d30e492571b02aab71f09a515aba0004b 100644 (file)
@@ -1345,7 +1345,7 @@ void smtp_do_procmsg(long msgnum, void *userdata) {
 
        lprintf(CTDL_DEBUG, "smtp_do_procmsg(%ld)\n", msgnum);
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) {
                lprintf(CTDL_ERR, "SMTP: tried %ld but no such message!\n", msgnum);
                return;
index 42df0f2529f8ea6ba4e3bfd39ac85070781dc4b0..9de4f0622504c7150007ba12a06af36fa8d234f2 100644 (file)
@@ -194,7 +194,7 @@ void artv_export_message(long msgnum) {
        char buf[SIZ];
        char tempfile[SIZ];
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) return;        /* fail silently */
 
        cprintf("message\n");
index 01caf020b46dfd4bb3664f733b6e83045c08973e..4ad02753de30878f52de4fbe470c4fe72c0c5ec2 100644 (file)
@@ -169,7 +169,7 @@ void vcard_directory_add_user(char *internet_addr, char *citadel_addr) {
 void vcard_add_to_directory(long msgnum, void *data) {
        struct CtdlMessage *msg;
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg != NULL) {
                vcard_extract_internet_addresses(msg, vcard_directory_add_user);
        }
@@ -479,7 +479,7 @@ struct vCard *vcard_get_user(struct ctdluser *u) {
 
        if (VC->msgnum < 0L) return vcard_new();
 
-       msg = CtdlFetchMessage(VC->msgnum);
+       msg = CtdlFetchMessage(VC->msgnum, 1);
        if (msg == NULL) return vcard_new();
 
        v = vcard_load(msg->cm_fields['M']);
@@ -825,7 +825,7 @@ void vcard_delete_remove(char *room, long msgnum) {
                return;
        }
 
-       msg = CtdlFetchMessage(msgnum);
+       msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) return;
 
        ptr = msg->cm_fields['M'];
index d463683eb69b9425cb1067c53d84b80012b93d45..cee6c1fd583be5e5ddf9eaee6340088d3625877f 100644 (file)
@@ -94,6 +94,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 */
+static int rescan[2];                          /* The rescan pipe */
 
 pthread_t initial_thread;              /* tid for main() thread */
 
@@ -236,6 +237,17 @@ void init_sysdep(void) {
         * socket breaks.
         */
        signal(SIGPIPE, SIG_IGN);
+
+       /*
+        * Set up the rescan pipe.  When a session goes idle, it writes a
+        * single byte to this pipe to wake up the thread calling select(),
+        * which tells it to rescan the list of session sockets.
+        */
+       if (pipe(rescan) != 0) {
+               lprintf(CTDL_EMERG, "Cannot create rescan pipe: %s\n",
+                       strerror(errno));
+               abort();
+       }
 }
 
 
@@ -894,9 +906,10 @@ void *worker_thread(void *arg) {
 do_select:     force_purge = 0;
                bind_me = NULL;         /* Which session shall we handle? */
 
-               /* Initialize the fdset. */
+               /* Initialize the fdset.  Start with the rescan pipe. */
                FD_ZERO(&readfds);
-               highest = 0;
+               FD_SET(rescan[0], &readfds);
+               highest = rescan[0] + 1;
 
                begin_critical_section(S_SESSION_TABLE);
                for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
@@ -1005,6 +1018,11 @@ do_select:       force_purge = 0;
                                        serviceptr->h_greeting_function();
                                        become_session(NULL);
                                        con->state = CON_IDLE;
+
+                                       /* Wake up the currently blocking select() by
+                                        * writing a dummy byte to the rescan pipe.
+                                        */
+                                       write(rescan[1], &i, 1);
                                        goto do_select;
                                }
                        }
@@ -1015,6 +1033,12 @@ do_select:       force_purge = 0;
                        break;
                }
 
+               /* If the rescan pipe went active, read a dummy byte from it */
+               if (FD_ISSET(rescan[0], &readfds)) {
+                       read(rescan[0], &i, 1);
+                       goto do_select;
+               }
+
                /* It must be a client socket.  Find a context that has data
                 * waiting on its socket *and* is in the CON_IDLE state.  Any
                 * active sockets other than our chosen one are marked as
@@ -1059,6 +1083,11 @@ SKIP_SELECT:
                        force_purge = CC->kill_me;
                        become_session(NULL);
                        bind_me->state = CON_IDLE;
+
+                       /* Wake up the currently blocking select() by writing
+                        * a dummy byte to the rescan pipe.
+                        */
+                       write(rescan[1], &i, 1);
                }
 
                dead_session_purge(force_purge);