Other(refactor): Sort safe.Mutex types before locking to prevent deadlocks
This change implements safe.Mutex and safe.RWMutex, which wrap the sync.Mutex and sync.RWMutex types and are assigned a globally unique integer ID. The safe.Lock and safe.RLock methods sort the mutexes by this integer ID before locking to ensure that locks for a given set of mutexes are always performed in the same order, avoiding deadlocks.
This commit is contained in:
@ -88,7 +88,7 @@ func (conn *imapConnector) GetMailbox(ctx context.Context, mailboxID imap.Mailbo
|
||||
}
|
||||
|
||||
return toIMAPMailbox(mailbox, conn.flags, conn.permFlags, conn.attrs), nil
|
||||
}, &conn.apiLabelsLock)
|
||||
}, conn.apiLabelsLock)
|
||||
}
|
||||
|
||||
// CreateMailbox creates a label with the given name.
|
||||
@ -157,7 +157,7 @@ func (conn *imapConnector) createFolder(ctx context.Context, name []string) (ima
|
||||
}
|
||||
|
||||
return toIMAPMailbox(label, conn.flags, conn.permFlags, conn.attrs), nil
|
||||
}, &conn.apiLabelsLock)
|
||||
}, conn.apiLabelsLock)
|
||||
}
|
||||
|
||||
// UpdateMailboxName sets the name of the label with the given ID.
|
||||
@ -232,7 +232,7 @@ func (conn *imapConnector) updateFolder(ctx context.Context, labelID imap.Mailbo
|
||||
}
|
||||
|
||||
return nil
|
||||
}, &conn.apiLabelsLock)
|
||||
}, conn.apiLabelsLock)
|
||||
}
|
||||
|
||||
// DeleteMailbox deletes the label with the given ID.
|
||||
@ -350,7 +350,7 @@ func (conn *imapConnector) MarkMessagesFlagged(ctx context.Context, messageIDs [
|
||||
func (conn *imapConnector) GetUpdates() <-chan imap.Update {
|
||||
return safe.RLockRet(func() <-chan imap.Update {
|
||||
return conn.updateCh[conn.addrID].GetChannel()
|
||||
}, &conn.updateChLock)
|
||||
}, conn.updateChLock)
|
||||
}
|
||||
|
||||
// GetUIDValidity returns the default UID validity for this user.
|
||||
@ -407,7 +407,7 @@ func (conn *imapConnector) importMessage(
|
||||
|
||||
return nil
|
||||
})
|
||||
}, &conn.apiUserLock, &conn.apiAddrsLock); err != nil {
|
||||
}, conn.apiUserLock, conn.apiAddrsLock); err != nil {
|
||||
return imap.Message{}, nil, err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user