/* * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ use crate::{DavResources, HttpAuthCache, MailboxCache, MessageStoreCache, UpdateLock}; use std::sync::atomic::{AtomicU64, Ordering}; use tokio::sync::{Semaphore, SemaphorePermit}; use utils::cache::CacheItemWeight; pub mod directory; pub mod invalidate; pub mod principals; pub mod reload; impl MailboxCache { pub fn parent_id(&self) -> Option { if self.parent_id != u32::MAX { Some(self.parent_id) } else { None } } pub fn sort_order(&self) -> Option { if self.sort_order != u32::MAX { Some(self.sort_order) } else { None } } pub fn is_root(&self) -> bool { self.parent_id == u32::MAX } } pub enum LockResult<'x> { Acquired(SemaphorePermit<'x>), Stale(SemaphorePermit<'x>), } impl UpdateLock { pub fn new() -> Self { Self { semaphore: Semaphore::new(1), revision: AtomicU64::new(0), } } pub async fn acquire(&self, current_revision: u64) -> trc::Result> { let permit = self.semaphore.acquire().await.map_err(|err| { trc::EventType::Server(trc::ServerEvent::ThreadError) .reason(err) .caused_by(trc::location!()) .details("Failed to acquire semaphore permit") })?; if self.revision.load(Ordering::Acquire) == current_revision { Ok(LockResult::Acquired(permit)) } else { Ok(LockResult::Stale(permit)) } } pub fn set_revision(&self, revision: u64) { self.revision.store(revision, Ordering::Release); } } impl Default for UpdateLock { fn default() -> Self { Self::new() } } impl CacheItemWeight for MessageStoreCache { fn weight(&self) -> u64 { self.size } } impl CacheItemWeight for HttpAuthCache { fn weight(&self) -> u64 { std::mem::size_of::() as u64 } } impl CacheItemWeight for DavResources { fn weight(&self) -> u64 { self.size } }