mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-07-27 10:18:30 +00:00
refactor: Replace std Mutex with parking_lot
This commit is contained in:
parent
0631094350
commit
30a8c06fd9
12 changed files with 44 additions and 59 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -967,6 +967,7 @@ dependencies = [
|
||||||
"maplit",
|
"maplit",
|
||||||
"nix",
|
"nix",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"parking_lot",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
|
|
@ -515,6 +515,13 @@ version = "1.0"
|
||||||
[workspace.dependencies.proc-macro2]
|
[workspace.dependencies.proc-macro2]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
|
|
||||||
|
[workspace.dependencies.parking_lot]
|
||||||
|
version = "0.12.4"
|
||||||
|
|
||||||
|
# Use this when extending with_lock::WithLock to parking_lot
|
||||||
|
# [workspace.dependencies.lock_api]
|
||||||
|
# version = "0.4.13"
|
||||||
|
|
||||||
[workspace.dependencies.bytesize]
|
[workspace.dependencies.bytesize]
|
||||||
version = "2.0"
|
version = "2.0"
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
use std::{
|
use std::{fmt::Write, mem::take, panic::AssertUnwindSafe, sync::Arc, time::SystemTime};
|
||||||
fmt::Write,
|
|
||||||
mem::take,
|
|
||||||
panic::AssertUnwindSafe,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
time::SystemTime,
|
|
||||||
};
|
|
||||||
|
|
||||||
use clap::{CommandFactory, Parser};
|
use clap::{CommandFactory, Parser};
|
||||||
use conduwuit::{
|
use conduwuit::{
|
||||||
Error, Result, debug, error,
|
Error, Result, SyncMutex, debug, error,
|
||||||
log::{
|
log::{
|
||||||
capture,
|
capture,
|
||||||
capture::Capture,
|
capture::Capture,
|
||||||
|
@ -123,7 +117,7 @@ async fn process(
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
|
||||||
// Prepend the logs only if any were captured
|
// Prepend the logs only if any were captured
|
||||||
let logs = logs.lock().expect("locked");
|
let logs = logs.lock();
|
||||||
if logs.lines().count() > 2 {
|
if logs.lines().count() > 2 {
|
||||||
writeln!(&mut output, "{logs}").expect("failed to format logs to command output");
|
writeln!(&mut output, "{logs}").expect("failed to format logs to command output");
|
||||||
}
|
}
|
||||||
|
@ -132,7 +126,7 @@ async fn process(
|
||||||
(result, output)
|
(result, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn capture_create(context: &Context<'_>) -> (Arc<Capture>, Arc<Mutex<String>>) {
|
fn capture_create(context: &Context<'_>) -> (Arc<Capture>, Arc<SyncMutex<String>>) {
|
||||||
let env_config = &context.services.server.config.admin_log_capture;
|
let env_config = &context.services.server.config.admin_log_capture;
|
||||||
let env_filter = EnvFilter::try_new(env_config).unwrap_or_else(|e| {
|
let env_filter = EnvFilter::try_new(env_config).unwrap_or_else(|e| {
|
||||||
warn!("admin_log_capture filter invalid: {e:?}");
|
warn!("admin_log_capture filter invalid: {e:?}");
|
||||||
|
@ -152,7 +146,7 @@ fn capture_create(context: &Context<'_>) -> (Arc<Capture>, Arc<Mutex<String>>) {
|
||||||
data.level() <= log_level && data.our_modules() && data.scope.contains(&"admin")
|
data.level() <= log_level && data.our_modules() && data.scope.contains(&"admin")
|
||||||
};
|
};
|
||||||
|
|
||||||
let logs = Arc::new(Mutex::new(
|
let logs = Arc::new(SyncMutex::new(
|
||||||
collect_stream(|s| markdown_table_head(s)).expect("markdown table header"),
|
collect_stream(|s| markdown_table_head(s)).expect("markdown table header"),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,7 @@ tracing-core.workspace = true
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
url.workspace = true
|
url.workspace = true
|
||||||
|
parking_lot.workspace = true
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
nix.workspace = true
|
nix.workspace = true
|
||||||
|
|
|
@ -3,18 +3,15 @@
|
||||||
//! several crates, lower-level information is supplied from each crate during
|
//! several crates, lower-level information is supplied from each crate during
|
||||||
//! static initialization.
|
//! static initialization.
|
||||||
|
|
||||||
use std::{
|
use std::{collections::BTreeMap, sync::OnceLock};
|
||||||
collections::BTreeMap,
|
|
||||||
sync::{Mutex, OnceLock},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::utils::exchange;
|
use crate::{SyncMutex, utils::exchange};
|
||||||
|
|
||||||
/// Raw capture of rustc flags used to build each crate in the project. Informed
|
/// Raw capture of rustc flags used to build each crate in the project. Informed
|
||||||
/// by rustc_flags_capture macro (one in each crate's mod.rs). This is
|
/// by rustc_flags_capture macro (one in each crate's mod.rs). This is
|
||||||
/// done during static initialization which is why it's mutex-protected and pub.
|
/// done during static initialization which is why it's mutex-protected and pub.
|
||||||
/// Should not be written to by anything other than our macro.
|
/// Should not be written to by anything other than our macro.
|
||||||
pub static FLAGS: Mutex<BTreeMap<&str, &[&str]>> = Mutex::new(BTreeMap::new());
|
pub static FLAGS: SyncMutex<BTreeMap<&str, &[&str]>> = SyncMutex::new(BTreeMap::new());
|
||||||
|
|
||||||
/// Processed list of enabled features across all project crates. This is
|
/// Processed list of enabled features across all project crates. This is
|
||||||
/// generated from the data in FLAGS.
|
/// generated from the data in FLAGS.
|
||||||
|
@ -27,7 +24,6 @@ fn init_features() -> Vec<&'static str> {
|
||||||
let mut features = Vec::new();
|
let mut features = Vec::new();
|
||||||
FLAGS
|
FLAGS
|
||||||
.lock()
|
.lock()
|
||||||
.expect("locked")
|
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|(_, flags)| append_features(&mut features, flags));
|
.for_each(|(_, flags)| append_features(&mut features, flags));
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ where
|
||||||
let mut visitor = Visitor { values: Values::new() };
|
let mut visitor = Visitor { values: Values::new() };
|
||||||
event.record(&mut visitor);
|
event.record(&mut visitor);
|
||||||
|
|
||||||
let mut closure = capture.closure.lock().expect("exclusive lock");
|
let mut closure = capture.closure.lock();
|
||||||
closure(Data {
|
closure(Data {
|
||||||
layer,
|
layer,
|
||||||
event,
|
event,
|
||||||
|
|
|
@ -4,7 +4,7 @@ pub mod layer;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub use data::Data;
|
pub use data::Data;
|
||||||
use guard::Guard;
|
use guard::Guard;
|
||||||
|
@ -12,6 +12,8 @@ pub use layer::{Layer, Value};
|
||||||
pub use state::State;
|
pub use state::State;
|
||||||
pub use util::*;
|
pub use util::*;
|
||||||
|
|
||||||
|
use crate::SyncMutex;
|
||||||
|
|
||||||
pub type Filter = dyn Fn(Data<'_>) -> bool + Send + Sync + 'static;
|
pub type Filter = dyn Fn(Data<'_>) -> bool + Send + Sync + 'static;
|
||||||
pub type Closure = dyn FnMut(Data<'_>) + Send + Sync + 'static;
|
pub type Closure = dyn FnMut(Data<'_>) + Send + Sync + 'static;
|
||||||
|
|
||||||
|
@ -19,7 +21,7 @@ pub type Closure = dyn FnMut(Data<'_>) + Send + Sync + 'static;
|
||||||
pub struct Capture {
|
pub struct Capture {
|
||||||
state: Arc<State>,
|
state: Arc<State>,
|
||||||
filter: Option<Box<Filter>>,
|
filter: Option<Box<Filter>>,
|
||||||
closure: Mutex<Box<Closure>>,
|
closure: SyncMutex<Box<Closure>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Capture {
|
impl Capture {
|
||||||
|
@ -34,7 +36,7 @@ impl Capture {
|
||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
filter: filter.map(|p| -> Box<Filter> { Box::new(p) }),
|
filter: filter.map(|p| -> Box<Filter> { Box::new(p) }),
|
||||||
closure: Mutex::new(Box::new(closure)),
|
closure: SyncMutex::new(Box::new(closure)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
super::{Level, fmt},
|
super::{Level, fmt},
|
||||||
Closure, Data,
|
Closure, Data,
|
||||||
};
|
};
|
||||||
use crate::Result;
|
use crate::{Result, SyncMutex};
|
||||||
|
|
||||||
pub fn fmt_html<S>(out: Arc<Mutex<S>>) -> Box<Closure>
|
pub fn fmt_html<S>(out: Arc<SyncMutex<S>>) -> Box<Closure>
|
||||||
where
|
where
|
||||||
S: std::fmt::Write + Send + 'static,
|
S: std::fmt::Write + Send + 'static,
|
||||||
{
|
{
|
||||||
fmt(fmt::html, out)
|
fmt(fmt::html, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fmt_markdown<S>(out: Arc<Mutex<S>>) -> Box<Closure>
|
pub fn fmt_markdown<S>(out: Arc<SyncMutex<S>>) -> Box<Closure>
|
||||||
where
|
where
|
||||||
S: std::fmt::Write + Send + 'static,
|
S: std::fmt::Write + Send + 'static,
|
||||||
{
|
{
|
||||||
fmt(fmt::markdown, out)
|
fmt(fmt::markdown, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fmt<F, S>(fun: F, out: Arc<Mutex<S>>) -> Box<Closure>
|
pub fn fmt<F, S>(fun: F, out: Arc<SyncMutex<S>>) -> Box<Closure>
|
||||||
where
|
where
|
||||||
F: Fn(&mut S, &Level, &str, &str) -> Result<()> + Send + Sync + Copy + 'static,
|
F: Fn(&mut S, &Level, &str, &str) -> Result<()> + Send + Sync + Copy + 'static,
|
||||||
S: std::fmt::Write + Send + 'static,
|
S: std::fmt::Write + Send + 'static,
|
||||||
{
|
{
|
||||||
Box::new(move |data| call(fun, &mut *out.lock().expect("locked"), &data))
|
Box::new(move |data| call(fun, &mut *out.lock(), &data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call<F, S>(fun: F, out: &mut S, data: &Data<'_>)
|
fn call<F, S>(fun: F, out: &mut S, data: &Data<'_>)
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
use std::{
|
use std::{collections::HashMap, sync::Arc};
|
||||||
collections::HashMap,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
};
|
|
||||||
|
|
||||||
use tracing_subscriber::{EnvFilter, reload};
|
use tracing_subscriber::{EnvFilter, reload};
|
||||||
|
|
||||||
use crate::{Result, error};
|
use crate::{Result, SyncMutex, error};
|
||||||
|
|
||||||
/// We need to store a reload::Handle value, but can't name it's type explicitly
|
/// We need to store a reload::Handle value, but can't name it's type explicitly
|
||||||
/// because the S type parameter depends on the subscriber's previous layers. In
|
/// because the S type parameter depends on the subscriber's previous layers. In
|
||||||
|
@ -35,7 +32,7 @@ impl<L: Clone, S> ReloadHandle<L> for reload::Handle<L, S> {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct LogLevelReloadHandles {
|
pub struct LogLevelReloadHandles {
|
||||||
handles: Arc<Mutex<HandleMap>>,
|
handles: Arc<SyncMutex<HandleMap>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type HandleMap = HashMap<String, Handle>;
|
type HandleMap = HashMap<String, Handle>;
|
||||||
|
@ -43,16 +40,12 @@ type Handle = Box<dyn ReloadHandle<EnvFilter> + Send + Sync>;
|
||||||
|
|
||||||
impl LogLevelReloadHandles {
|
impl LogLevelReloadHandles {
|
||||||
pub fn add(&self, name: &str, handle: Handle) {
|
pub fn add(&self, name: &str, handle: Handle) {
|
||||||
self.handles
|
self.handles.lock().insert(name.into(), handle);
|
||||||
.lock()
|
|
||||||
.expect("locked")
|
|
||||||
.insert(name.into(), handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reload(&self, new_value: &EnvFilter, names: Option<&[&str]>) -> Result<()> {
|
pub fn reload(&self, new_value: &EnvFilter, names: Option<&[&str]>) -> Result<()> {
|
||||||
self.handles
|
self.handles
|
||||||
.lock()
|
.lock()
|
||||||
.expect("locked")
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(name, _)| names.is_some_and(|names| names.contains(&name.as_str())))
|
.filter(|(name, _)| names.is_some_and(|names| names.contains(&name.as_str())))
|
||||||
.for_each(|(_, handle)| {
|
.for_each(|(_, handle)| {
|
||||||
|
@ -66,7 +59,6 @@ impl LogLevelReloadHandles {
|
||||||
pub fn current(&self, name: &str) -> Option<EnvFilter> {
|
pub fn current(&self, name: &str) -> Option<EnvFilter> {
|
||||||
self.handles
|
self.handles
|
||||||
.lock()
|
.lock()
|
||||||
.expect("locked")
|
|
||||||
.get(name)
|
.get(name)
|
||||||
.map(|handle| handle.current())?
|
.map(|handle| handle.current())?
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ pub use info::{
|
||||||
pub use matrix::{
|
pub use matrix::{
|
||||||
Event, EventTypeExt, Pdu, PduCount, PduEvent, PduId, RoomVersion, pdu, state_res,
|
Event, EventTypeExt, Pdu, PduCount, PduEvent, PduId, RoomVersion, pdu, state_res,
|
||||||
};
|
};
|
||||||
|
pub use parking_lot::{Mutex as SyncMutex, RwLock as SyncRwLock};
|
||||||
pub use server::Server;
|
pub use server::Server;
|
||||||
pub use utils::{ctor, dtor, implement, result, result::Result};
|
pub use utils::{ctor, dtor, implement, result, result::Result};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
use std::{
|
use std::{fmt::Debug, hash::Hash, sync::Arc};
|
||||||
fmt::Debug,
|
|
||||||
hash::Hash,
|
|
||||||
sync::{Arc, TryLockError::WouldBlock},
|
|
||||||
};
|
|
||||||
|
|
||||||
use tokio::sync::OwnedMutexGuard as Omg;
|
use tokio::sync::OwnedMutexGuard as Omg;
|
||||||
|
|
||||||
use crate::{Result, err};
|
use crate::{Result, SyncMutex, err};
|
||||||
|
|
||||||
/// Map of Mutexes
|
/// Map of Mutexes
|
||||||
pub struct MutexMap<Key, Val> {
|
pub struct MutexMap<Key, Val> {
|
||||||
|
@ -19,7 +15,7 @@ pub struct Guard<Key, Val> {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Map<Key, Val> = Arc<MapMutex<Key, Val>>;
|
type Map<Key, Val> = Arc<MapMutex<Key, Val>>;
|
||||||
type MapMutex<Key, Val> = std::sync::Mutex<HashMap<Key, Val>>;
|
type MapMutex<Key, Val> = SyncMutex<HashMap<Key, Val>>;
|
||||||
type HashMap<Key, Val> = std::collections::HashMap<Key, Value<Val>>;
|
type HashMap<Key, Val> = std::collections::HashMap<Key, Value<Val>>;
|
||||||
type Value<Val> = Arc<tokio::sync::Mutex<Val>>;
|
type Value<Val> = Arc<tokio::sync::Mutex<Val>>;
|
||||||
|
|
||||||
|
@ -45,7 +41,6 @@ where
|
||||||
let val = self
|
let val = self
|
||||||
.map
|
.map
|
||||||
.lock()
|
.lock()
|
||||||
.expect("locked")
|
|
||||||
.entry(k.try_into().expect("failed to construct key"))
|
.entry(k.try_into().expect("failed to construct key"))
|
||||||
.or_default()
|
.or_default()
|
||||||
.clone();
|
.clone();
|
||||||
|
@ -66,7 +61,6 @@ where
|
||||||
let val = self
|
let val = self
|
||||||
.map
|
.map
|
||||||
.lock()
|
.lock()
|
||||||
.expect("locked")
|
|
||||||
.entry(k.try_into().expect("failed to construct key"))
|
.entry(k.try_into().expect("failed to construct key"))
|
||||||
.or_default()
|
.or_default()
|
||||||
.clone();
|
.clone();
|
||||||
|
@ -87,10 +81,7 @@ where
|
||||||
let val = self
|
let val = self
|
||||||
.map
|
.map
|
||||||
.try_lock()
|
.try_lock()
|
||||||
.map_err(|e| match e {
|
.ok_or_else(|| err!("would block"))?
|
||||||
| WouldBlock => err!("would block"),
|
|
||||||
| _ => panic!("{e:?}"),
|
|
||||||
})?
|
|
||||||
.entry(k.try_into().expect("failed to construct key"))
|
.entry(k.try_into().expect("failed to construct key"))
|
||||||
.or_default()
|
.or_default()
|
||||||
.clone();
|
.clone();
|
||||||
|
@ -102,13 +93,13 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn contains(&self, k: &Key) -> bool { self.map.lock().expect("locked").contains_key(k) }
|
pub fn contains(&self, k: &Key) -> bool { self.map.lock().contains_key(k) }
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_empty(&self) -> bool { self.map.lock().expect("locked").is_empty() }
|
pub fn is_empty(&self) -> bool { self.map.lock().is_empty() }
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn len(&self) -> usize { self.map.lock().expect("locked").len() }
|
pub fn len(&self) -> usize { self.map.lock().len() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Key, Val> Default for MutexMap<Key, Val>
|
impl<Key, Val> Default for MutexMap<Key, Val>
|
||||||
|
@ -123,7 +114,7 @@ impl<Key, Val> Drop for Guard<Key, Val> {
|
||||||
#[tracing::instrument(name = "unlock", level = "trace", skip_all)]
|
#[tracing::instrument(name = "unlock", level = "trace", skip_all)]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if Arc::strong_count(Omg::mutex(&self.val)) <= 2 {
|
if Arc::strong_count(Omg::mutex(&self.val)) <= 2 {
|
||||||
self.map.lock().expect("locked").retain(|_, val| {
|
self.map.lock().retain(|_, val| {
|
||||||
!Arc::ptr_eq(val, Omg::mutex(&self.val)) || Arc::strong_count(val) > 2
|
!Arc::ptr_eq(val, Omg::mutex(&self.val)) || Arc::strong_count(val) > 2
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,13 @@ pub(super) fn flags_capture(args: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
#[conduwuit_core::ctor]
|
#[conduwuit_core::ctor]
|
||||||
fn _set_rustc_flags() {
|
fn _set_rustc_flags() {
|
||||||
conduwuit_core::info::rustc::FLAGS.lock().expect("locked").insert(#crate_name, &RUSTC_FLAGS);
|
conduwuit_core::info::rustc::FLAGS.lock().insert(#crate_name, &RUSTC_FLAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static strings have to be yanked on module unload
|
// static strings have to be yanked on module unload
|
||||||
#[conduwuit_core::dtor]
|
#[conduwuit_core::dtor]
|
||||||
fn _unset_rustc_flags() {
|
fn _unset_rustc_flags() {
|
||||||
conduwuit_core::info::rustc::FLAGS.lock().expect("locked").remove(#crate_name);
|
conduwuit_core::info::rustc::FLAGS.lock().remove(#crate_name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue