Skip to content

Commit

Permalink
exmdb: emit notifications only after SQL transactions are complete
Browse files Browse the repository at this point in the history
The notification that a new mail object has come into existence was
sent out before the sqlite transaction was finished, leading midb to
not find the mail. This occurred since gromox-2.30 because that is
when we made mailboxes concurrently readable.

References: GXL-519, GXL-537, DESK-2301, DESK-2311
References: DESK-2402, DESK-2421, DESK-2436, DESK-2449
  • Loading branch information
jengelh committed Oct 5, 2024
1 parent 8f3f0dc commit 464b7b5
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 177 deletions.
147 changes: 79 additions & 68 deletions exch/exmdb/db_engine.cpp

Large diffs are not rendered by default.

31 changes: 17 additions & 14 deletions exch/exmdb/db_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ struct db_conn {
}
};
using ID_ARRAYS = std::map<const char *, std::vector<uint32_t>, xless>;
/* As long as any NOTIFQ object is alive, dbase should be held at least read-locked. */
using NOTIFQ = std::vector<std::pair<DB_NOTIFY_DATAGRAM, ID_ARRAYS>>;

db_conn(db_base &);
~db_conn();
Expand All @@ -179,20 +181,20 @@ struct db_conn {
db_base_wr_ptr lock_base_wr();
void update_dynamic(uint64_t folder_id, uint32_t search_flags, const RESTRICTION *prestriction, const LONGLONG_ARRAY *pfolder_ids, db_base &);
void delete_dynamic(uint64_t folder_id, db_base *);
void proc_dynamic_event(cpid_t, enum dynamic_event, uint64_t id1, uint64_t id2, uint64_t id3, db_base &);
void notify_new_mail(uint64_t folder_id, uint64_t msg_id, db_base &);
void notify_message_creation(uint64_t folder_id, uint64_t msg_id, db_base &);
void notify_link_creation(uint64_t parent_id, uint64_t msg_id, db_base &);
void notify_folder_creation(uint64_t parent_id, uint64_t folder_id, const db_base &);
void notify_message_deletion(uint64_t folder_id, uint64_t msg_id, db_base &);
void notify_link_deletion(uint64_t parent_id, uint64_t msg_id, db_base &);
void notify_folder_deletion(uint64_t parent_id, uint64_t folder_id, const db_base &);
void notify_message_modification(uint64_t folder_id, uint64_t msg_id, db_base &);
void notify_folder_modification(uint64_t parent_id, uint64_t folder_id, const db_base &);
void notify_message_movecopy(BOOL b_copy, uint64_t folder_id, uint64_t msg_id, uint64_t old_fid, uint64_t old_mid, db_base &);
void notify_folder_movecopy(BOOL b_copy, uint64_t parent_id, uint64_t folder_id, uint64_t old_pid, uint64_t old_fid, const db_base &);
void notify_cttbl_reload(uint32_t table_id, const db_base &);
void transport_new_mail(uint64_t folder_id, uint64_t msg_id, uint32_t msg_flags, const char *klass, const db_base &);
void proc_dynamic_event(cpid_t, enum dynamic_event, uint64_t id1, uint64_t id2, uint64_t id3, db_base &, NOTIFQ &);
void notify_new_mail(uint64_t folder_id, uint64_t msg_id, db_base &, NOTIFQ &);
void notify_message_creation(uint64_t folder_id, uint64_t msg_id, db_base &, NOTIFQ &);
void notify_link_creation(uint64_t parent_id, uint64_t msg_id, db_base &, NOTIFQ &);
void notify_folder_creation(uint64_t parent_id, uint64_t folder_id, const db_base &, NOTIFQ &);
void notify_message_deletion(uint64_t folder_id, uint64_t msg_id, db_base &, NOTIFQ &);
void notify_link_deletion(uint64_t parent_id, uint64_t msg_id, db_base &, NOTIFQ &);
void notify_folder_deletion(uint64_t parent_id, uint64_t folder_id, const db_base &, NOTIFQ &);
void notify_message_modification(uint64_t folder_id, uint64_t msg_id, db_base &, NOTIFQ &);
void notify_folder_modification(uint64_t parent_id, uint64_t folder_id, const db_base &, NOTIFQ &);
void notify_message_movecopy(BOOL b_copy, uint64_t folder_id, uint64_t msg_id, uint64_t old_fid, uint64_t old_mid, db_base &, NOTIFQ &);
void notify_folder_movecopy(BOOL b_copy, uint64_t parent_id, uint64_t folder_id, uint64_t old_pid, uint64_t old_fid, const db_base &, NOTIFQ &);
void notify_cttbl_reload(uint32_t table_id, const db_base &, NOTIFQ &);
void transport_new_mail(uint64_t folder_id, uint64_t msg_id, uint32_t msg_flags, const char *klass, const db_base &, NOTIFQ &);
void begin_batch_mode(db_base &);
/* pdb will also be put */
static void commit_batch_mode_release(std::optional<db_conn> &&pdb, db_base_wr_ptr &&base);
Expand Down Expand Up @@ -221,6 +223,7 @@ extern BOOL db_engine_vacuum(const char *path);
BOOL db_engine_unload_db(const char *path);
extern BOOL db_engine_enqueue_populating_criteria(const char *dir, cpid_t, uint64_t folder_id, BOOL recursive, const RESTRICTION *, const LONGLONG_ARRAY *folder_ids);
extern bool db_engine_check_populating(const char *dir, uint64_t folder_id);
extern void dg_notify(db_conn::NOTIFQ &&);

extern unsigned int g_exmdb_schema_upgrades, g_exmdb_search_pacing;
extern unsigned long long g_exmdb_search_pacing_time, g_exmdb_lock_timeout;
Expand Down
Loading

0 comments on commit 464b7b5

Please sign in to comment.