Skip to content

Commit 329630c

Browse files
Remove parking_lot dependency (#20630)
# Objective Spend less time compiling what is already in the standard library. Remove `parking_lot` from first party crate dependencies. Contribute to #18978. Supercedes #18996. ## Solution Use `bevy_platform::sync` types wherever possible. `BevyManifest::shared` directly returned a mapped guard, but that could be circumvented by just using a scope-like API instead. The crate is still in the dependency tree, transitively, through `wgpu`, but is now no longer required for any non-rendering crates. ## Testing Ran tests locally. Co-Authored-By: Zac Harrold <[email protected]>
1 parent 8272c41 commit 329630c

File tree

23 files changed

+289
-181
lines changed

23 files changed

+289
-181
lines changed

crates/bevy_animation/macros/src/animation_event.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ use syn::{parse_macro_input, DeriveInput};
55

66
pub fn derive_animation_event(input: TokenStream) -> TokenStream {
77
let ast = parse_macro_input!(input as DeriveInput);
8-
let manifest = BevyManifest::shared();
9-
let bevy_ecs = manifest.get_path("bevy_ecs");
10-
let bevy_animation = manifest.get_path("bevy_animation");
8+
let (bevy_ecs, bevy_animation) = BevyManifest::shared(|manifest| {
9+
let bevy_ecs = manifest.get_path("bevy_ecs");
10+
let bevy_animation = manifest.get_path("bevy_animation");
11+
(bevy_ecs, bevy_animation)
12+
});
1113

1214
let generics = ast.generics;
1315
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();

crates/bevy_asset/Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ either = { version = "1.13", default-features = false }
5353
futures-io = { version = "0.3", default-features = false }
5454
futures-lite = { version = "2.0.1", default-features = false }
5555
blake3 = { version = "1.5", default-features = false }
56-
parking_lot = { version = "0.12", default-features = false, features = [
57-
"arc_lock",
58-
"send_guard",
59-
] }
6056
ron = { version = "0.10", default-features = false }
6157
serde = { version = "1", default-features = false, features = ["derive"] }
6258
thiserror = { version = "2", default-features = false }

crates/bevy_asset/macros/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use quote::{format_ident, quote};
88
use syn::{parse_macro_input, Data, DeriveInput, Path};
99

1010
pub(crate) fn bevy_asset_path() -> Path {
11-
BevyManifest::shared().get_path("bevy_asset")
11+
BevyManifest::shared(|manifest| manifest.get_path("bevy_asset"))
1212
}
1313

1414
const DEPENDENCY_ATTRIBUTE: &str = "dependency";

crates/bevy_asset/src/assets.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ impl<A: Asset> Assets<A> {
572572
// that `asset_server.load` calls that occur during it block, which ensures that
573573
// re-loads are kicked off appropriately. This function must be "transactional" relative
574574
// to other asset info operations
575-
let mut infos = asset_server.data.infos.write();
575+
let mut infos = asset_server.write_infos();
576576
while let Ok(drop_event) = assets.handle_provider.drop_receiver.try_recv() {
577577
let id = drop_event.id.typed();
578578

crates/bevy_asset/src/io/embedded/embedded_watcher.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use crate::io::{
55
};
66
use alloc::{boxed::Box, sync::Arc, vec::Vec};
77
use bevy_platform::collections::HashMap;
8+
use bevy_platform::sync::{PoisonError, RwLock};
89
use core::time::Duration;
910
use notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, RecommendedCache};
10-
use parking_lot::RwLock;
1111
use std::{
1212
fs::File,
1313
io::{BufReader, Read},
@@ -64,7 +64,12 @@ impl FilesystemEventHandler for EmbeddedEventHandler {
6464

6565
fn get_path(&self, absolute_path: &Path) -> Option<(PathBuf, bool)> {
6666
let (local_path, is_meta) = get_asset_path(&self.root, absolute_path);
67-
let final_path = self.root_paths.read().get(local_path.as_path())?.clone();
67+
let final_path = self
68+
.root_paths
69+
.read()
70+
.unwrap_or_else(PoisonError::into_inner)
71+
.get(local_path.as_path())?
72+
.clone();
6873
if is_meta {
6974
warn!("Meta file asset hot-reloading is not supported yet: {final_path:?}");
7075
}

crates/bevy_asset/src/io/embedded/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use crate::AssetServer;
1212
use alloc::boxed::Box;
1313
use bevy_app::App;
1414
use bevy_ecs::{resource::Resource, world::World};
15+
#[cfg(feature = "embedded_watcher")]
16+
use bevy_platform::sync::{Arc, PoisonError, RwLock};
1517
use std::path::{Path, PathBuf};
1618

1719
#[cfg(feature = "embedded_watcher")]
@@ -30,9 +32,7 @@ pub const EMBEDDED: &str = "embedded";
3032
pub struct EmbeddedAssetRegistry {
3133
dir: Dir,
3234
#[cfg(feature = "embedded_watcher")]
33-
root_paths: alloc::sync::Arc<
34-
parking_lot::RwLock<bevy_platform::collections::HashMap<Box<Path>, PathBuf>>,
35-
>,
35+
root_paths: Arc<RwLock<bevy_platform::collections::HashMap<Box<Path>, PathBuf>>>,
3636
}
3737

3838
impl EmbeddedAssetRegistry {
@@ -51,6 +51,7 @@ impl EmbeddedAssetRegistry {
5151
#[cfg(feature = "embedded_watcher")]
5252
self.root_paths
5353
.write()
54+
.unwrap_or_else(PoisonError::into_inner)
5455
.insert(full_path.into(), asset_path.to_owned());
5556
self.dir.insert_asset(asset_path, value);
5657
}
@@ -70,6 +71,7 @@ impl EmbeddedAssetRegistry {
7071
#[cfg(feature = "embedded_watcher")]
7172
self.root_paths
7273
.write()
74+
.unwrap_or_else(PoisonError::into_inner)
7375
.insert(full_path.into(), asset_path.to_owned());
7476
self.dir.insert_meta(asset_path, value);
7577
}

crates/bevy_asset/src/io/gated.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use crate::io::{AssetReader, AssetReaderError, PathStream, Reader};
22
use alloc::{boxed::Box, sync::Arc};
33
use async_channel::{Receiver, Sender};
4-
use bevy_platform::collections::HashMap;
5-
use parking_lot::RwLock;
6-
use std::path::Path;
4+
use bevy_platform::{collections::HashMap, sync::RwLock};
5+
use std::{path::Path, sync::PoisonError};
76

87
/// A "gated" reader that will prevent asset reads from returning until
98
/// a given path has been "opened" using [`GateOpener`].
@@ -32,7 +31,7 @@ impl GateOpener {
3231
/// Opens the `path` "gate", allowing a _single_ [`AssetReader`] operation to return for that path.
3332
/// If multiple operations are expected, call `open` the expected number of calls.
3433
pub fn open<P: AsRef<Path>>(&self, path: P) {
35-
let mut gates = self.gates.write();
34+
let mut gates = self.gates.write().unwrap_or_else(PoisonError::into_inner);
3635
let gates = gates
3736
.entry_ref(path.as_ref())
3837
.or_insert_with(async_channel::unbounded);
@@ -58,7 +57,7 @@ impl<R: AssetReader> GatedReader<R> {
5857
impl<R: AssetReader> AssetReader for GatedReader<R> {
5958
async fn read<'a>(&'a self, path: &'a Path) -> Result<impl Reader + 'a, AssetReaderError> {
6059
let receiver = {
61-
let mut gates = self.gates.write();
60+
let mut gates = self.gates.write().unwrap_or_else(PoisonError::into_inner);
6261
let gates = gates
6362
.entry_ref(path.as_ref())
6463
.or_insert_with(async_channel::unbounded);

crates/bevy_asset/src/io/memory.rs

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use crate::io::{AssetReader, AssetReaderError, PathStream, Reader};
22
use alloc::{borrow::ToOwned, boxed::Box, sync::Arc, vec::Vec};
3-
use bevy_platform::collections::HashMap;
3+
use bevy_platform::{
4+
collections::HashMap,
5+
sync::{PoisonError, RwLock},
6+
};
47
use core::{pin::Pin, task::Poll};
58
use futures_io::AsyncRead;
69
use futures_lite::{ready, Stream};
7-
use parking_lot::RwLock;
810
use std::path::{Path, PathBuf};
911

1012
use super::AsyncSeekForward;
@@ -44,13 +46,17 @@ impl Dir {
4446
if let Some(parent) = path.parent() {
4547
dir = self.get_or_insert_dir(parent);
4648
}
47-
dir.0.write().assets.insert(
48-
path.file_name().unwrap().to_string_lossy().into(),
49-
Data {
50-
value: value.into(),
51-
path: path.to_owned(),
52-
},
53-
);
49+
dir.0
50+
.write()
51+
.unwrap_or_else(PoisonError::into_inner)
52+
.assets
53+
.insert(
54+
path.file_name().unwrap().to_string_lossy().into(),
55+
Data {
56+
value: value.into(),
57+
path: path.to_owned(),
58+
},
59+
);
5460
}
5561

5662
/// Removes the stored asset at `path` and returns the `Data` stored if found and otherwise `None`.
@@ -60,21 +66,29 @@ impl Dir {
6066
dir = self.get_or_insert_dir(parent);
6167
}
6268
let key: Box<str> = path.file_name().unwrap().to_string_lossy().into();
63-
dir.0.write().assets.remove(&key)
69+
dir.0
70+
.write()
71+
.unwrap_or_else(PoisonError::into_inner)
72+
.assets
73+
.remove(&key)
6474
}
6575

6676
pub fn insert_meta(&self, path: &Path, value: impl Into<Value>) {
6777
let mut dir = self.clone();
6878
if let Some(parent) = path.parent() {
6979
dir = self.get_or_insert_dir(parent);
7080
}
71-
dir.0.write().metadata.insert(
72-
path.file_name().unwrap().to_string_lossy().into(),
73-
Data {
74-
value: value.into(),
75-
path: path.to_owned(),
76-
},
77-
);
81+
dir.0
82+
.write()
83+
.unwrap_or_else(PoisonError::into_inner)
84+
.metadata
85+
.insert(
86+
path.file_name().unwrap().to_string_lossy().into(),
87+
Data {
88+
value: value.into(),
89+
path: path.to_owned(),
90+
},
91+
);
7892
}
7993

8094
pub fn get_or_insert_dir(&self, path: &Path) -> Dir {
@@ -84,7 +98,7 @@ impl Dir {
8498
full_path.push(c);
8599
let name = c.as_os_str().to_string_lossy().into();
86100
dir = {
87-
let dirs = &mut dir.0.write().dirs;
101+
let dirs = &mut dir.0.write().unwrap_or_else(PoisonError::into_inner).dirs;
88102
dirs.entry(name)
89103
.or_insert_with(|| Dir::new(full_path.clone()))
90104
.clone()
@@ -98,7 +112,13 @@ impl Dir {
98112
let mut dir = self.clone();
99113
for p in path.components() {
100114
let component = p.as_os_str().to_str().unwrap();
101-
let next_dir = dir.0.read().dirs.get(component)?.clone();
115+
let next_dir = dir
116+
.0
117+
.read()
118+
.unwrap_or_else(PoisonError::into_inner)
119+
.dirs
120+
.get(component)?
121+
.clone();
102122
dir = next_dir;
103123
}
104124
Some(dir)
@@ -110,8 +130,14 @@ impl Dir {
110130
dir = dir.get_dir(parent)?;
111131
}
112132

113-
path.file_name()
114-
.and_then(|f| dir.0.read().assets.get(f.to_str().unwrap()).cloned())
133+
path.file_name().and_then(|f| {
134+
dir.0
135+
.read()
136+
.unwrap_or_else(PoisonError::into_inner)
137+
.assets
138+
.get(f.to_str().unwrap())
139+
.cloned()
140+
})
115141
}
116142

117143
pub fn get_metadata(&self, path: &Path) -> Option<Data> {
@@ -120,12 +146,22 @@ impl Dir {
120146
dir = dir.get_dir(parent)?;
121147
}
122148

123-
path.file_name()
124-
.and_then(|f| dir.0.read().metadata.get(f.to_str().unwrap()).cloned())
149+
path.file_name().and_then(|f| {
150+
dir.0
151+
.read()
152+
.unwrap_or_else(PoisonError::into_inner)
153+
.metadata
154+
.get(f.to_str().unwrap())
155+
.cloned()
156+
})
125157
}
126158

127159
pub fn path(&self) -> PathBuf {
128-
self.0.read().path.to_owned()
160+
self.0
161+
.read()
162+
.unwrap_or_else(PoisonError::into_inner)
163+
.path
164+
.to_owned()
129165
}
130166
}
131167

@@ -153,7 +189,7 @@ impl Stream for DirStream {
153189
_cx: &mut core::task::Context<'_>,
154190
) -> Poll<Option<Self::Item>> {
155191
let this = self.get_mut();
156-
let dir = this.dir.0.read();
192+
let dir = this.dir.0.read().unwrap_or_else(PoisonError::into_inner);
157193

158194
let dir_index = this.dir_index;
159195
if let Some(dir_path) = dir

crates/bevy_asset/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,10 @@ mod tests {
728728
prelude::*,
729729
schedule::{LogLevel, ScheduleBuildSettings},
730730
};
731-
use bevy_platform::collections::{HashMap, HashSet};
731+
use bevy_platform::{
732+
collections::{HashMap, HashSet},
733+
sync::Mutex,
734+
};
732735
use bevy_reflect::TypePath;
733736
use core::time::Duration;
734737
use crossbeam_channel::Sender;
@@ -825,7 +828,7 @@ mod tests {
825828
/// A dummy [`CoolText`] asset reader that only succeeds after `failure_count` times it's read from for each asset.
826829
#[derive(Default, Clone)]
827830
pub struct UnstableMemoryAssetReader {
828-
pub attempt_counters: Arc<std::sync::Mutex<HashMap<Box<Path>, usize>>>,
831+
pub attempt_counters: Arc<Mutex<HashMap<Box<Path>, usize>>>,
829832
pub load_delay: Duration,
830833
memory_reader: MemoryAssetReader,
831834
failure_count: usize,

crates/bevy_asset/src/processor/mod.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@ use crate::{
5858
};
5959
use alloc::{borrow::ToOwned, boxed::Box, collections::VecDeque, sync::Arc, vec, vec::Vec};
6060
use bevy_ecs::prelude::*;
61-
use bevy_platform::collections::{HashMap, HashSet};
61+
use bevy_platform::{
62+
collections::{HashMap, HashSet},
63+
sync::{PoisonError, RwLock},
64+
};
6265
use bevy_tasks::IoTaskPool;
6366
use futures_io::ErrorKind;
6467
use futures_lite::{AsyncReadExt, AsyncWriteExt, StreamExt};
65-
use parking_lot::RwLock;
6668
use std::path::{Path, PathBuf};
6769
use thiserror::Error;
6870
use tracing::{debug, error, trace, warn};
@@ -533,7 +535,7 @@ impl AssetProcessor {
533535
async fn finish_processing_assets(&self) {
534536
self.try_reprocessing_queued().await;
535537
// clean up metadata in asset server
536-
self.server.data.infos.write().consume_handle_drop_events();
538+
self.server.write_infos().consume_handle_drop_events();
537539
self.set_state(ProcessorState::Finished).await;
538540
}
539541

@@ -581,28 +583,49 @@ impl AssetProcessor {
581583

582584
/// Register a new asset processor.
583585
pub fn register_processor<P: Process>(&self, processor: P) {
584-
let mut process_plans = self.data.processors.write();
586+
let mut process_plans = self
587+
.data
588+
.processors
589+
.write()
590+
.unwrap_or_else(PoisonError::into_inner);
585591
#[cfg(feature = "trace")]
586592
let processor = InstrumentedAssetProcessor(processor);
587593
process_plans.insert(core::any::type_name::<P>(), Arc::new(processor));
588594
}
589595

590596
/// Set the default processor for the given `extension`. Make sure `P` is registered with [`AssetProcessor::register_processor`].
591597
pub fn set_default_processor<P: Process>(&self, extension: &str) {
592-
let mut default_processors = self.data.default_processors.write();
598+
let mut default_processors = self
599+
.data
600+
.default_processors
601+
.write()
602+
.unwrap_or_else(PoisonError::into_inner);
593603
default_processors.insert(extension.into(), core::any::type_name::<P>());
594604
}
595605

596606
/// Returns the default processor for the given `extension`, if it exists.
597607
pub fn get_default_processor(&self, extension: &str) -> Option<Arc<dyn ErasedProcessor>> {
598-
let default_processors = self.data.default_processors.read();
608+
let default_processors = self
609+
.data
610+
.default_processors
611+
.read()
612+
.unwrap_or_else(PoisonError::into_inner);
599613
let key = default_processors.get(extension)?;
600-
self.data.processors.read().get(key).cloned()
614+
self.data
615+
.processors
616+
.read()
617+
.unwrap_or_else(PoisonError::into_inner)
618+
.get(key)
619+
.cloned()
601620
}
602621

603622
/// Returns the processor with the given `processor_type_name`, if it exists.
604623
pub fn get_processor(&self, processor_type_name: &str) -> Option<Arc<dyn ErasedProcessor>> {
605-
let processors = self.data.processors.read();
624+
let processors = self
625+
.data
626+
.processors
627+
.read()
628+
.unwrap_or_else(PoisonError::into_inner);
606629
processors.get(processor_type_name).cloned()
607630
}
608631

0 commit comments

Comments
 (0)