]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: mail-duplicate - Implement separate error code for deadlock.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 13 Jul 2021 02:15:14 +0000 (04:15 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 23 Sep 2021 07:03:28 +0000 (07:03 +0000)
src/lib-storage/mail-duplicate.c
src/lib-storage/mail-duplicate.h

index 7eb1123ee444a650d003e191bf327ffc34ec2e8b..6940ede19c0917d53463a5403da43e7742c0f240 100644 (file)
@@ -34,6 +34,7 @@ enum mail_duplicate_lock_result {
        MAIL_DUPLICATE_LOCK_IO_ERROR,
        MAIL_DUPLICATE_LOCK_TIMEOUT,
        MAIL_DUPLICATE_LOCK_TOO_MANY,
+       MAIL_DUPLICATE_LOCK_DEADLOCK,
 };
 
 struct mail_duplicate_lock {
@@ -131,7 +132,10 @@ duplicate_lock_failed(struct mail_duplicate_transaction *trans,
        i_assert(lock->fd == -1);
        i_assert(lock->lock == NULL);
 
-       if (errno != EAGAIN) {
+       if (errno == EDEADLK) {
+               /* deadlock */
+               result = MAIL_DUPLICATE_LOCK_DEADLOCK;
+       } else if (errno != EAGAIN) {
                /* not a lock timeout */
                result = MAIL_DUPLICATE_LOCK_IO_ERROR;
        } else {
@@ -541,6 +545,10 @@ mail_duplicate_check(struct mail_duplicate_transaction *trans,
                e_debug(trans->event,
                        "Check ID: too many IDs locked");
                return MAIL_DUPLICATE_CHECK_RESULT_TOO_MANY_LOCKS;
+       case MAIL_DUPLICATE_LOCK_DEADLOCK:
+               e_debug(trans->event,
+                       "Check ID: deadlock detected while locking");
+               return MAIL_DUPLICATE_CHECK_RESULT_DEADLOCK;
        }
 
        mail_duplicate_update(trans);
index 4bbeaaba287e67e83d654800d24b5602b26fb5c9..c41489338585254e605bc5f7ea3b94750c45ec16 100644 (file)
@@ -14,6 +14,10 @@ enum mail_duplicate_check_result {
        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)