* Any "delete message" operation which is synchronous to a client is now
authorArt Cancro <ajc@citadel.org>
Fri, 5 Aug 2005 21:31:01 +0000 (21:31 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 5 Aug 2005 21:31:01 +0000 (21:31 +0000)
  deferred.  This is accomplished by copying the message pointer to
  the __CitadelDeletedMessages__ room, which keeps the reference count at
  least 1.  THE DREADED AUTO-PURGER can sweep it up later.

13 files changed:
citadel/ChangeLog
citadel/citserver.c
citadel/msgbase.c
citadel/msgbase.h
citadel/room_ops.c
citadel/serv_calendar.c
citadel/serv_expire.c
citadel/serv_imap.c
citadel/serv_network.c
citadel/serv_pop3.c
citadel/serv_smtp.c
citadel/serv_vcard.c
citadel/sysconfig.h

index 11ac511172ae8fbea7ee00f7260e8a148ca58304..fb8919d9a1ebb69b3708978aa27bafb6dca2e682 100644 (file)
@@ -1,4 +1,10 @@
 $Log$
+Revision 654.1  2005/08/05 21:31:01  ajc
+* Any "delete message" operation which is synchronous to a client is now
+  deferred.  This is accomplished by copying the message pointer to
+  the __CitadelDeletedMessages__ room, which keeps the reference count at
+  least 1.  THE DREADED AUTO-PURGER can sweep it up later.
+
 Revision 654.0  2005/08/05 16:22:38  ajc
 * THIS IS 6.54
 
@@ -6988,4 +6994,3 @@ 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 0946ed54883313a388520114bb82911a69628ad1..868f2daab498b6d80e50f4e13317a9bdbeae3cfd 100644 (file)
@@ -112,6 +112,27 @@ void master_startup(void) {
                 lputroom(&qrbuf);
         }
 
+       /*
+        * Create a room in which we can deposit "deleted" messages for
+        * deferred deletion.  This will silently fail if the room already
+        * exists, and that's perfectly ok, because we want it to exist.
+        */
+       create_room(DELETED_MSGS_ROOM, 3, "", 0, 1, 0, VIEW_MAILBOX);
+
+       /*
+        * Make sure it's set to be a "system room" so it doesn't show up
+        * in the <K>nown rooms list for Aides.  Also set the message expire
+        * policy to "by count, 1 message" so everything gets deleted all
+        * the time (we can't set it to 0 because that's invalid, so we keep
+        * a single message around).
+        */
+       if (lgetroom(&qrbuf, DELETED_MSGS_ROOM) == 0) {
+               qrbuf.QRflags2 |= QR2_SYSTEM;
+               qrbuf.QRep.expire_mode = EXPIRE_NUMMSGS;
+               qrbuf.QRep.expire_value = 1;
+               lputroom(&qrbuf);
+       }
+
        lprintf(CTDL_INFO, "Seeding the pseudo-random number generator...\n");
        urandom = fopen("/dev/urandom", "r");
        if (urandom != NULL) {
index 42b738a22df147e74924168c23341d1951d8265e..e70269533c6a578374d681cab2320ba931628616 100644 (file)
@@ -1958,7 +1958,7 @@ void serialize_message(struct ser_ret *ret,               /* return values */
  */
 void check_repl(long msgnum, void *userdata) {
        lprintf(CTDL_DEBUG, "check_repl() replacing message %ld\n", msgnum);
-       CtdlDeleteMessages(CC->room.QRname, msgnum, "");
+       CtdlDeleteMessages(CC->room.QRname, msgnum, "", 0);
 }
 
 
@@ -2941,8 +2941,9 @@ void cmd_ent0(char *entargs)
  * (returns the actual number of messages deleted)
  */
 int CtdlDeleteMessages(char *room_name,                /* which room */
-                      long dmsgnum,            /* or "0" for any */
-                      char *content_type       /* or "" for any */
+                       long dmsgnum,           /* or "0" for any */
+                       char *content_type,     /* or "" for any */
+                       int deferred            /* let TDAP sweep it later */
 )
 {
 
@@ -2956,8 +2957,8 @@ int CtdlDeleteMessages(char *room_name,           /* which room */
        int delete_this;
        struct MetaData smi;
 
-       lprintf(CTDL_DEBUG, "CtdlDeleteMessages(%s, %ld, %s)\n",
-               room_name, dmsgnum, content_type);
+       lprintf(CTDL_DEBUG, "CtdlDeleteMessages(%s, %ld, %s, %d)\n",
+               room_name, dmsgnum, content_type, deferred);
 
        /* get room record, obtaining a lock... */
        if (lgetroom(&qrbuf, room_name) != 0) {
@@ -3008,6 +3009,20 @@ int CtdlDeleteMessages(char *room_name,          /* which room */
        }
        lputroom(&qrbuf);
 
+       /*
+        * If the delete operation is "deferred" (and technically, any delete
+        * operation not performed by THE DREADED AUTO-PURGER ought to be
+        * a deferred delete) then we save a pointer to the message in the
+        * DELETED_MSGS_ROOM.  This will cause the reference count to remain
+        * at least 1, which will save the user from having to synchronously
+        * wait for various disk-intensive operations to complete.
+        */
+       if ( (deferred) && (num_deleted) ) {
+               for (i=0; i<num_deleted; ++i) {
+                       CtdlCopyMsgToRoom(dellist[i], DELETED_MSGS_ROOM);
+               }
+       }
+
        /* Go through the messages we pulled out of the index, and decrement
         * their reference counts by 1.  If this is the only room the message
         * was in, the reference count will reach zero and the message will
@@ -3062,7 +3077,7 @@ void cmd_dele(char *delstr)
        }
        delnum = extract_long(delstr, 0);
 
-       num_deleted = CtdlDeleteMessages(CC->room.QRname, delnum, "");
+       num_deleted = CtdlDeleteMessages(CC->room.QRname, delnum, "", 1);
 
        if (num_deleted) {
                cprintf("%d %d message%s deleted.\n", CIT_OK,
@@ -3155,7 +3170,7 @@ void cmd_move(char *args)
         * if this is a 'move' rather than a 'copy' operation.
         */
        if (is_copy == 0) {
-               CtdlDeleteMessages(CC->room.QRname, num, "");
+               CtdlDeleteMessages(CC->room.QRname, num, "", 0);
        }
 
        cprintf("%d Message %s.\n", CIT_OK, (is_copy ? "copied" : "moved") );
@@ -3366,7 +3381,8 @@ void CtdlWriteObject(char *req_room,              /* Room to stuff it in */
         */
        if (is_unique) {
                lprintf(CTDL_DEBUG, "Deleted %d other msgs of this type\n",
-                       CtdlDeleteMessages(roomname, 0L, content_type));
+                       CtdlDeleteMessages(roomname, 0L, content_type, 0)
+               );
        }
        /* Now write the data */
        CtdlSubmitMsg(msg, NULL, roomname);
index dd069ac5515c266b5f8aee7b65abb349e97c8435..50d8b72f04a3af7537a28b3eaa05558d29d43607 100644 (file)
@@ -99,7 +99,7 @@ int CtdlForEachMessage(int mode, long ref,
                        struct CtdlMessage *compare,
                         void (*CallBack) (long, void *),
                        void *userdata);
-int CtdlDeleteMessages(char *, long, char *);
+int CtdlDeleteMessages(char *, long, char *, int);
 void CtdlWriteObject(char *, char *, char *, struct ctdluser *,
                        int, int, unsigned int);
 struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body);
index 57d42b5522fcf8006f65eb59428a0f9894e5b261..682adddaba5afbe61d88076a8b3d246b809f3a9d 100644 (file)
@@ -1599,7 +1599,7 @@ void delete_room(struct ctdlroom *qrbuf)
        /* Delete the messages in the room
         * (Careful: this opens an S_ROOMS critical section!)
         */
-       CtdlDeleteMessages(qrbuf->QRname, 0L, "");
+       CtdlDeleteMessages(qrbuf->QRname, 0L, "", 0);
 
        /* Flag the room record as not in use */
        lgetroom(qrbuf, qrbuf->QRname);
index 64a44d1ea05e39faadd57f5b1952cd64c579acea..fbc5ec510279dcf2ef599ed0516831c7b0fcaa8f 100644 (file)
@@ -428,7 +428,7 @@ void ical_respond(long msgnum, char *partnum, char *action) {
                /* Now that we've processed this message, we don't need it
                 * anymore.  So delete it.
                 */
-               CtdlDeleteMessages(CC->room.QRname, msgnum, "");
+               CtdlDeleteMessages(CC->room.QRname, msgnum, "", 1);
 
                /* Free the memory we allocated and return a response. */
                icalcomponent_free(ird.cal);
@@ -779,7 +779,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) {
                /* Now that we've processed this message, we don't need it
                 * anymore.  So delete it.  (Maybe make this optional?)
                 */
-               CtdlDeleteMessages(CC->room.QRname, msgnum, "");
+               CtdlDeleteMessages(CC->room.QRname, msgnum, "", 1);
 
                /* Free the memory we allocated and return a response. */
                icalcomponent_free(ird.cal);
index 5995d80edd6749545e96f08f04a4f2c0e9ab56f4..0da8e381c4ac5a0ce4068dfaa66e3c4f538e076d 100644 (file)
@@ -206,7 +206,7 @@ void DoPurgeMessages(FILE *purgelist) {
                if (!strncasecmp(buf, "m=", 2)) {
                        msgnum = atol(&buf[2]);
                        if (msgnum > 0L) {
-                               CtdlDeleteMessages(roomname, msgnum, "");
+                               CtdlDeleteMessages(roomname, msgnum, "", 0);
                        }
                }
        }
index cc442ca8d3f198dad1f87e3b1ad0cf48503e6fec..ff340b007909fe5f669d87e608e4030758f76772 100644 (file)
@@ -704,7 +704,7 @@ int imap_do_expunge(void)
                for (i = 0; i < IMAP->num_msgs; ++i) {
                        if (IMAP->flags[i] & IMAP_DELETED) {
                                CtdlDeleteMessages(CC->room.QRname,
-                                                  IMAP->msgids[i], "");
+                                                  IMAP->msgids[i], "", 1);
                                ++num_expunged;
                        }
                }
index 055ef0f36f47172f589e426be9e5d33b84f0b8f3..05c86f74507c6e824fd63e50fe70d511bc969e90 100644 (file)
@@ -755,7 +755,7 @@ void network_spool_msg(long msgnum, void *userdata) {
 
        /* Delete this message if delete-after-send is set */
        if (delete_after_send) {
-               CtdlDeleteMessages(CC->room.QRname, msgnum, "");
+               CtdlDeleteMessages(CC->room.QRname, msgnum, "", 0);
        }
 
 }
index 5fb7328d4b3e1c99e934dd0dabeb0e31f171145a..b79b3771fe2e9bf3ec70a627795c712c1661b73c 100644 (file)
@@ -471,7 +471,7 @@ void pop3_update(void) {
        if (POP3->num_msgs > 0) for (i=0; i<POP3->num_msgs; ++i) {
                if (POP3->msgs[i].deleted) {
                        CtdlDeleteMessages(MAILROOM,
-                               POP3->msgs[i].msgnum, "");
+                               POP3->msgs[i].msgnum, "", 1);
                }
        }
 
index 0f0c7dbfec89ba67157e05f406b524fd8c7c0648..91e8ed50ad9b1083aeba9bec33b493884dbd0caf 100644 (file)
@@ -1527,8 +1527,8 @@ void smtp_do_procmsg(long msgnum, void *userdata) {
         * message and the message message.
         */
        if (incomplete_deliveries_remaining <= 0) {
-               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "");
-               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, text_msgid, "");
+               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "", 0);
+               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, text_msgid, "", 0);
        }
 
 
@@ -1537,7 +1537,7 @@ void smtp_do_procmsg(long msgnum, void *userdata) {
         * instructions and replace with the updated ones.
         */
        if (incomplete_deliveries_remaining > 0) {
-               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "");
+               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "", 0);
                msg = malloc(sizeof(struct CtdlMessage));
                memset(msg, 0, sizeof(struct CtdlMessage));
                msg->cm_magic = CTDLMESSAGE_MAGIC;
index 59fea7718e633e2003d19a48cb40b074a4589f65..1365d07b3b44ecd352760a9ae14f42242a230ceb 100644 (file)
@@ -323,7 +323,7 @@ int vcard_upload_beforesave(struct CtdlMessage *msg) {
                                 * vCard in the user's config room at all times.
                                 */
                                CtdlDeleteMessages(CC->room.QRname,
-                                               0L, "text/x-vcard");
+                                               0L, "text/x-vcard", 1);
 
                                /* Make the author of the message the name of the user.
                                 */
index 9c233555cf8e16fe16889667d6d8076c4f2c0173..822575f713d4ecc6aa4993f9a8ea2bc107be44f8 100644 (file)
 #define PAGELOGROOM            "Sent/Received Pages"
 #define SYSCONFIGROOM          "Local System Configuration"
 #define SMTP_SPOOLOUT_ROOM     "__CitadelSMTPspoolout__"
+#define DELETED_MSGS_ROOM      "__CitadelDeletedMessages__"
 
 /*
  * How long (in seconds) to retain message entries in the use table