From: Art Cancro Date: Fri, 5 Aug 2005 21:31:01 +0000 (+0000) Subject: * Any "delete message" operation which is synchronous to a client is now X-Git-Tag: v7.86~4748 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=014b286fd533d8ee38eea35287ee953f6a5c7a4e * 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. --- diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 11ac51117..fb8919d9a 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -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 Fri Jul 10 1998 Art Cancro * Initial CVS import - diff --git a/citadel/citserver.c b/citadel/citserver.c index 0946ed548..868f2daab 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -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 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) { diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 42b738a22..e70269533 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -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; iroom.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); diff --git a/citadel/msgbase.h b/citadel/msgbase.h index dd069ac55..50d8b72f0 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -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); diff --git a/citadel/room_ops.c b/citadel/room_ops.c index 57d42b552..682adddab 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -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); diff --git a/citadel/serv_calendar.c b/citadel/serv_calendar.c index 64a44d1ea..fbc5ec510 100644 --- a/citadel/serv_calendar.c +++ b/citadel/serv_calendar.c @@ -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); diff --git a/citadel/serv_expire.c b/citadel/serv_expire.c index 5995d80ed..0da8e381c 100644 --- a/citadel/serv_expire.c +++ b/citadel/serv_expire.c @@ -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); } } } diff --git a/citadel/serv_imap.c b/citadel/serv_imap.c index cc442ca8d..ff340b007 100644 --- a/citadel/serv_imap.c +++ b/citadel/serv_imap.c @@ -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; } } diff --git a/citadel/serv_network.c b/citadel/serv_network.c index 055ef0f36..05c86f745 100644 --- a/citadel/serv_network.c +++ b/citadel/serv_network.c @@ -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); } } diff --git a/citadel/serv_pop3.c b/citadel/serv_pop3.c index 5fb7328d4..b79b3771f 100644 --- a/citadel/serv_pop3.c +++ b/citadel/serv_pop3.c @@ -471,7 +471,7 @@ void pop3_update(void) { if (POP3->num_msgs > 0) for (i=0; inum_msgs; ++i) { if (POP3->msgs[i].deleted) { CtdlDeleteMessages(MAILROOM, - POP3->msgs[i].msgnum, ""); + POP3->msgs[i].msgnum, "", 1); } } diff --git a/citadel/serv_smtp.c b/citadel/serv_smtp.c index 0f0c7dbfe..91e8ed50a 100644 --- a/citadel/serv_smtp.c +++ b/citadel/serv_smtp.c @@ -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; diff --git a/citadel/serv_vcard.c b/citadel/serv_vcard.c index 59fea7718..1365d07b3 100644 --- a/citadel/serv_vcard.c +++ b/citadel/serv_vcard.c @@ -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. */ diff --git a/citadel/sysconfig.h b/citadel/sysconfig.h index 9c233555c..822575f71 100644 --- a/citadel/sysconfig.h +++ b/citadel/sysconfig.h @@ -111,6 +111,7 @@ #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