wasmrs_runtime/runtime/native/
mod.rs1#![allow(missing_docs)]
3use std::future::Future;
4use std::sync::Arc;
5
6use dashmap::DashMap;
7use parking_lot::Mutex;
8use tokio::task::JoinHandle;
9
10pub type TaskHandle = JoinHandle<()>;
11
12pub type BoxFuture<Output> = std::pin::Pin<Box<dyn Future<Output = Output> + Send + Sync + 'static>>;
13
14pub fn spawn<F>(id: &'static str, task: F) -> TaskHandle
15where
16 F: Future<Output = ()> + ConditionallySend,
17{
18 tracing::trace!("native:runtime:task:start:{}", id);
19 tokio::spawn(async move {
20 task.await;
21 tracing::trace!("native:runtime:task:end:{}", id);
22 })
23}
24
25pub fn exhaust_pool() {
26 unimplemented!("Not implemented in non-wasm hosts")
27}
28
29#[allow(missing_debug_implementations)]
30pub struct SafeMap<K, V>(DashMap<K, V>)
31where
32 K: std::hash::Hash,
33 K: Eq;
34
35impl<K, V> SafeMap<K, V>
36where
37 K: std::hash::Hash,
38 K: Eq,
39{
40 pub fn remove(&self, key: &K) -> Option<V> {
41 self.0.remove(key).map(|v| v.1)
42 }
43
44 pub fn insert(&self, key: K, value: V) {
45 self.0.insert(key, value);
46 }
47
48 #[must_use]
49 pub fn len(&self) -> usize {
50 self.0.len()
51 }
52
53 #[must_use]
54 pub fn is_empty(&self) -> bool {
55 self.0.is_empty()
56 }
57
58 pub fn cloned(&self, key: &K) -> Option<V>
59 where
60 V: Clone,
61 {
62 self.0.get(key).map(|v| v.clone())
63 }
64
65 pub fn entry(&self, key: K) -> Entry<'_, K, V> {
66 match self.0.entry(key) {
67 dashmap::mapref::entry::Entry::Occupied(v) => Entry::Occupied::<K, V>(OccupiedEntry(v)),
68 dashmap::mapref::entry::Entry::Vacant(v) => Entry::Vacant::<K, V>(VacantEntry(v)),
69 }
70 }
71}
72
73#[must_use]
74#[allow(missing_debug_implementations)]
75pub enum Entry<'a, K, V> {
76 Occupied(OccupiedEntry<'a, K, V>),
77 Vacant(VacantEntry<'a, K, V>),
78}
79
80#[allow(missing_debug_implementations)]
81pub struct OccupiedEntry<'a, K, V>(dashmap::mapref::entry::OccupiedEntry<'a, K, V>);
82
83impl<'a, K, V> OccupiedEntry<'a, K, V>
84where
85 K: Eq,
86 K: std::hash::Hash,
87{
88 pub fn get(&self) -> &V {
89 self.0.get()
90 }
91 pub fn remove(self) -> V {
92 self.0.remove()
93 }
94}
95
96#[allow(missing_debug_implementations)]
97pub struct VacantEntry<'a, K, V>(dashmap::mapref::entry::VacantEntry<'a, K, V>);
98
99impl<K, V> Default for SafeMap<K, V>
100where
101 K: std::hash::Hash,
102 K: Eq,
103{
104 fn default() -> Self {
105 Self(Default::default())
106 }
107}
108
109#[allow(missing_debug_implementations)]
110pub struct OptionalMut<T>(Arc<Mutex<Option<T>>>);
111
112impl<T> OptionalMut<T>
113where
114 T: Send,
115{
116 pub fn new(item: T) -> Self {
117 Self(Arc::new(Mutex::new(Some(item))))
118 }
119
120 #[must_use]
121 pub fn none() -> Self {
122 Self(Arc::new(Mutex::new(None)))
123 }
124
125 #[must_use]
126 pub fn take(&self) -> Option<T> {
127 self.0.lock().take()
128 }
129
130 pub fn insert(&self, item: T) {
131 let _ = self.0.lock().insert(item);
132 }
133
134 #[must_use]
135 pub fn is_some(&self) -> bool {
136 self.0.lock().is_some()
137 }
138
139 #[must_use]
140 pub fn is_none(&self) -> bool {
141 self.0.lock().is_none()
142 }
143}
144
145impl<T> Clone for OptionalMut<T> {
146 fn clone(&self) -> Self {
147 Self(self.0.clone())
148 }
149}
150
151#[allow(missing_debug_implementations)]
152pub struct MutRc<T>(pub(super) Arc<Mutex<T>>);
153
154impl<T> MutRc<T>
155where
156 T: ConditionallySendSync,
157{
158 pub fn new(item: T) -> Self {
159 Self(Arc::new(Mutex::new(item)))
160 }
161
162 pub fn lock(&self) -> parking_lot::lock_api::MutexGuard<'_, parking_lot::RawMutex, T> {
163 self.0.lock()
164 }
165}
166
167pub type RtRc<T> = Arc<T>;
168
169pub trait ConditionallySendSync: Send + Sync + 'static {}
170
171impl<S> ConditionallySendSync for S where S: Send + Sync + 'static {}
172
173pub trait ConditionallySend: Send + 'static {}
174
175impl<S> ConditionallySend for S where S: Send + 'static {}