From 657f3eb1f8877ebe94b603730cbe35885127feae Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 13 May 2002 04:35:50 +0000 Subject: [PATCH] * usergoto() can now be supplied a NULL room name to signify that the caller has already copied the quickroom record into CC->quickroom. Eliminates an extra database fetch. * NewMailCount() now uses a per-session counter, which is incremented by CtdlSubmitMsg() when the user receiving a message is logged in at the time the message is saved. This eliminates the need to load and scan the user's mailbox every time a oto operation is performed. * The old NewMailCount() function is now InitialMailCheck() and is used at session startup time. --- citadel/msgbase.c | 1 + citadel/room_ops.c | 43 ++++++++++++++------ citadel/serv_imap.c | 3 +- citadel/server.h | 1 + citadel/user_ops.c | 98 +++++++++++++++++++++++++++++++-------------- citadel/user_ops.h | 2 + 6 files changed, 104 insertions(+), 44 deletions(-) diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 7495257a3..20846b54b 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1906,6 +1906,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ if (getuser(&userbuf, recipient) == 0) { MailboxName(actual_rm, sizeof actual_rm, &userbuf, MAILROOM); CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 0); + BumpNewMailCounter(userbuf.usernum); } else { lprintf(9, "No user <%s>\n", recipient); diff --git a/citadel/room_ops.c b/citadel/room_ops.c index 0eb87ba0e..01c09d73b 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -688,7 +688,11 @@ void cmd_lzrm(char *argbuf) } - +/* + * Make the specified room the current room for this session. No validation + * or access control is done here -- the caller should make sure that the + * specified room exists and is ok to access. + */ void usergoto(char *where, int display_result, int *retmsgs, int *retnew) { int a; @@ -704,26 +708,35 @@ void usergoto(char *where, int display_result, int *retmsgs, int *retnew) long *msglist = NULL; int num_msgs = 0; - strcpy(CC->quickroom.QRname, where); - getroom(&CC->quickroom, where); + /* If the supplied room name is NULL, the caller wants us to know that + * it has already copied the quickroom record into CC->quickroom, so + * we can skip the extra database fetch. + */ + if (where != NULL) { + strcpy(CC->quickroom.QRname, where); + getroom(&CC->quickroom, where); + } + + /* Take care of all the formalities. */ - lgetuser(&CC->usersupp, CC->curr_user); + begin_critical_section(S_USERSUPP); CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom); /* Know the room ... but not if it's the page log room */ - if (strcasecmp(where, config.c_logpages)) { + if (strcasecmp(CC->quickroom.QRname, config.c_logpages)) { vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT; vbuf.v_flags = vbuf.v_flags | V_ACCESS; } CtdlSetRelationship(&vbuf, &CC->usersupp, &CC->quickroom); - lputuser(&CC->usersupp); + end_critical_section(S_USERSUPP); - /* check for new mail */ + /* Check for new mail */ newmailcount = NewMailCount(); /* set info to 1 if the user needs to read the room's info file */ - if (CC->quickroom.QRinfo > vbuf.v_lastseen) + if (CC->quickroom.QRinfo > vbuf.v_lastseen) { info = 1; + } get_mm(); cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->quickroom.QRnumber, sizeof(long)); @@ -826,9 +839,11 @@ void cmd_goto(char *gargs) /* And if the room was found... */ if (c == 0) { - /* let internal programs go directly to any room */ + /* Let internal programs go directly to any room. */ if (CC->internal_pgm) { - usergoto(towhere, 1, NULL, NULL); + memcpy(&CC->quickroom, &QRscratch, + sizeof(struct quickroom)); + usergoto(NULL, 1, NULL, NULL); return; } @@ -843,7 +858,9 @@ void cmd_goto(char *gargs) if (ok == 1) { if ((QRscratch.QRflags & QR_MAILBOX) && ((ra & UA_GOTOALLOWED))) { - usergoto(towhere, 1, NULL, NULL); + memcpy(&CC->quickroom, &QRscratch, + sizeof(struct quickroom)); + usergoto(NULL, 1, NULL, NULL); return; } else if ((QRscratch.QRflags & QR_PASSWORDED) && ((ra & UA_KNOWN) == 0) && @@ -862,7 +879,9 @@ void cmd_goto(char *gargs) lprintf(9, "Failed to acquire private room\n"); goto NOPE; } else { - usergoto(towhere, 1, NULL, NULL); + memcpy(&CC->quickroom, &QRscratch, + sizeof(struct quickroom)); + usergoto(NULL, 1, NULL, NULL); return; } } diff --git a/citadel/serv_imap.c b/citadel/serv_imap.c index 05acf5c0f..ec3c6609f 100644 --- a/citadel/serv_imap.c +++ b/citadel/serv_imap.c @@ -411,7 +411,8 @@ void imap_select(int num_parms, char *parms[]) { * usergoto() formally takes us to the desired room, happily returning * the number of messages and number of new messages. */ - usergoto(QRscratch.QRname, 0, &msgs, &new); + memcpy(&CC->quickroom, &QRscratch, sizeof(struct quickroom)); + usergoto(NULL, 0, &msgs, &new); IMAP->selected = 1; if (!strcasecmp(parms[1], "EXAMINE")) { diff --git a/citadel/server.h b/citadel/server.h index 30c190ec8..c8cb89254 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -137,6 +137,7 @@ struct CitContext { /* A linked list of all express messages sent to us. */ struct ExpressMessage *FirstExpressMessage; int disable_exp; /* Set to 1 to disable incoming pages */ + int newmail; /* Other sessions increment this */ /* Masquerade... */ char fake_username[USERNAME_SIZE]; /* Fake username */ diff --git a/citadel/user_ops.c b/citadel/user_ops.c index fa35581e5..c66219515 100644 --- a/citadel/user_ops.c +++ b/citadel/user_ops.c @@ -1254,7 +1254,7 @@ void cmd_chek(void) } /* check for mail */ - mail = NewMailCount(); + mail = InitialMailCheck(); cprintf("%d %d|%d|%d\n", CIT_OK, mail, regis, vali); } @@ -1360,48 +1360,84 @@ void cmd_asup(char *cmdbuf) } + +/* + * Check to see if the user who we just sent mail to is logged in. If yes, + * bump the 'new mail' counter for their session. That enables them to + * receive a new mail notification without having to hit the database. + */ +void BumpNewMailCounter(long which_user) { + struct CitContext *ptr; + + begin_critical_section(S_SESSION_TABLE); + + for (ptr = ContextList; ptr != NULL; ptr = ptr->next) { + if (ptr->usersupp.usernum == which_user) { + ptr->newmail += 1; + } + } + + end_critical_section(S_SESSION_TABLE); +} + + /* * Count the number of new mail messages the user has */ int NewMailCount() { int num_newmsgs = 0; - int a; - char mailboxname[ROOMNAMELEN]; - struct quickroom mailbox; - struct visit vbuf; - struct cdbdata *cdbfr; - long *msglist = NULL; - int num_msgs = 0; - MailboxName(mailboxname, sizeof mailboxname, &CC->usersupp, MAILROOM); - if (getroom(&mailbox, mailboxname) != 0) - return (0); - CtdlGetRelationship(&vbuf, &CC->usersupp, &mailbox); - - cdbfr = cdb_fetch(CDB_MSGLISTS, &mailbox.QRnumber, sizeof(long)); - - if (cdbfr != NULL) { - msglist = mallok(cdbfr->len); - memcpy(msglist, cdbfr->ptr, cdbfr->len); - num_msgs = cdbfr->len / sizeof(long); - cdb_free(cdbfr); - } - if (num_msgs > 0) - for (a = 0; a < num_msgs; ++a) { - if (msglist[a] > 0L) { - if (msglist[a] > vbuf.v_lastseen) { - ++num_newmsgs; - } - } - } - if (msglist != NULL) - phree(msglist); + num_newmsgs = CC->newmail; + CC->newmail = 0; return (num_newmsgs); } +/* + * Count the number of new mail messages the user has + */ +int InitialMailCheck() +{ + int num_newmsgs = 0; + int a; + char mailboxname[ROOMNAMELEN]; + struct quickroom mailbox; + struct visit vbuf; + struct cdbdata *cdbfr; + long *msglist = NULL; + int num_msgs = 0; + + MailboxName(mailboxname, sizeof mailboxname, &CC->usersupp, MAILROOM); + if (getroom(&mailbox, mailboxname) != 0) + return (0); + CtdlGetRelationship(&vbuf, &CC->usersupp, &mailbox); + + cdbfr = cdb_fetch(CDB_MSGLISTS, &mailbox.QRnumber, sizeof(long)); + + if (cdbfr != NULL) { + msglist = mallok(cdbfr->len); + memcpy(msglist, cdbfr->ptr, cdbfr->len); + num_msgs = cdbfr->len / sizeof(long); + cdb_free(cdbfr); + } + if (num_msgs > 0) + for (a = 0; a < num_msgs; ++a) { + if (msglist[a] > 0L) { + if (msglist[a] > vbuf.v_lastseen) { + ++num_newmsgs; + } + } + } + if (msglist != NULL) + phree(msglist); + + return (num_newmsgs); +} + + + /* * Set the preferred view for the current user/room combination */ diff --git a/citadel/user_ops.h b/citadel/user_ops.h index 13a7f5b9a..821732023 100644 --- a/citadel/user_ops.h +++ b/citadel/user_ops.h @@ -34,6 +34,7 @@ void cmd_agup (char *cmdbuf); void cmd_asup (char *cmdbuf); void cmd_view (char *cmdbuf); int NewMailCount(void); +int InitialMailCheck(void); void put_visit(struct visit *newvisit); void CtdlGetRelationship(struct visit *vbuf, struct usersupp *rel_user, @@ -79,3 +80,4 @@ enum { int CtdlForgetThisRoom(void); void cmd_seen(char *argbuf); +void BumpNewMailCounter(long); -- 2.39.2