mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 13:36:30 +03:00
fix: add mutex around wal_checkpoint()
Documentation comment explains how it prevents the deadlock.
This commit is contained in:
@@ -71,6 +71,24 @@ struct InnerPool {
|
||||
/// This mutex is locked when write connection
|
||||
/// is outside the pool.
|
||||
pub(crate) write_mutex: Arc<Mutex<()>>,
|
||||
|
||||
/// WAL checkpointing mutex.
|
||||
///
|
||||
/// This mutex ensures that no more than one thread
|
||||
/// runs WAL checkpointing at the same time.
|
||||
///
|
||||
/// Normal procedures acquire either one read connection
|
||||
/// or one write connection with a write mutex,
|
||||
/// and return the resources without trying to acquire
|
||||
/// more connections or trying to acquire write mutex
|
||||
/// without returning the read connection first.
|
||||
/// WAL checkpointing is special, it tries to acquire all
|
||||
/// connections and the write mutex,
|
||||
/// so two threads doing this at the same time
|
||||
/// may result in a deadlock with one thread
|
||||
/// waiting for a write lock and the other thread
|
||||
/// waiting for a connection.
|
||||
wal_checkpoint_mutex: Mutex<()>,
|
||||
}
|
||||
|
||||
impl InnerPool {
|
||||
@@ -191,6 +209,7 @@ impl Pool {
|
||||
connections: parking_lot::Mutex::new(connections),
|
||||
semaphore,
|
||||
write_mutex: Default::default(),
|
||||
wal_checkpoint_mutex: Default::default(),
|
||||
});
|
||||
Pool { inner }
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ pub(crate) struct WalCheckpointStats {
|
||||
|
||||
/// Runs a checkpoint operation in TRUNCATE mode, so the WAL file is truncated to 0 bytes.
|
||||
pub(super) async fn wal_checkpoint(pool: &Pool) -> Result<WalCheckpointStats> {
|
||||
let _guard = pool.inner.wal_checkpoint_mutex.lock().await;
|
||||
let t_start = Time::now();
|
||||
|
||||
// Do as much work as possible without blocking anybody.
|
||||
|
||||
Reference in New Issue
Block a user