summaryrefslogtreecommitdiffstats
path: root/src/lib-storage/mail-duplicate.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib-storage/mail-duplicate.h51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/lib-storage/mail-duplicate.h b/src/lib-storage/mail-duplicate.h
new file mode 100644
index 0000000..c414893
--- /dev/null
+++ b/src/lib-storage/mail-duplicate.h
@@ -0,0 +1,51 @@
+#ifndef MAIL_DUPLICATE_H
+#define MAIL_DUPLICATE_H
+
+struct mail_duplicate_db;
+
+enum mail_duplicate_check_result {
+ /* The ID exists. The ID is not locked. */
+ MAIL_DUPLICATE_CHECK_RESULT_EXISTS,
+ /* The ID doesn't exist yet. The ID gets locked. */
+ MAIL_DUPLICATE_CHECK_RESULT_NOT_FOUND,
+ /* Internal I/O error (e.g. permission error) */
+ MAIL_DUPLICATE_CHECK_RESULT_IO_ERROR,
+ /* Locking timed out. */
+ MAIL_DUPLICATE_CHECK_RESULT_LOCK_TIMEOUT,
+ /* Too many locks held. */
+ MAIL_DUPLICATE_CHECK_RESULT_TOO_MANY_LOCKS,
+ /* Locking detected a deadlock. The caller should rollback the
+ transaction to release all locks, do a short random sleep, retry
+ and hope that the next attempt succeeds. */
+ MAIL_DUPLICATE_CHECK_RESULT_DEADLOCK,
+};
+
+#define MAIL_DUPLICATE_DEFAULT_KEEP (3600 * 24)
+
+struct mail_duplicate_transaction *
+mail_duplicate_transaction_begin(struct mail_duplicate_db *db);
+void mail_duplicate_transaction_rollback(
+ struct mail_duplicate_transaction **_trans);
+void mail_duplicate_transaction_commit(
+ struct mail_duplicate_transaction **_trans);
+
+/* Check if id exists in the duplicate database. If not, lock the id. Any
+ further checks for the same id in other processes will block until the first
+ one's transaction is finished. Because checks can be done in different order
+ by different processes, this can result in a deadlock. The caller should
+ handle it by rolling back the transaction and retrying. */
+enum mail_duplicate_check_result
+mail_duplicate_check(struct mail_duplicate_transaction *trans,
+ const void *id, size_t id_size, const char *user);
+/* Add id to the duplicate database. The writing isn't done until transaction
+ is committed. There's no locking done by this call. If locking is needed,
+ mail_duplicate_check() should be called first. */
+void mail_duplicate_mark(struct mail_duplicate_transaction *trans,
+ const void *id, size_t id_size,
+ const char *user, time_t timestamp);
+
+struct mail_duplicate_db *
+mail_duplicate_db_init(struct mail_user *user, const char *name);
+void mail_duplicate_db_deinit(struct mail_duplicate_db **db);
+
+#endif