1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// SPDX-License-Identifier: MIT OR Apache-2.0
//! A suite of WebAssembly-safe synchronization primitives that paper over platform-specific locking constraints.
//!
//! 
//!
//! # The Core Problem
//!
//! **WebAssembly's main thread cannot use blocking locks** - attempting to do so will panic
//! with "cannot block on the main thread". This is a fundamental limitation of the browser
//! environment where blocking the main thread would freeze the entire UI.
//!
//! However, blocking locks ARE allowed in:
//! - **WebAssembly worker threads** (where `Atomics.wait` is available)
//! - **Native platforms** (both main and worker threads)
//! - **Most non-WASM contexts** (traditional OS threads have no such restrictions)
//!
//! # The Solution
//!
//! This crate provides synchronization primitives that automatically adapt their
//! locking strategy based on the runtime environment:
//!
//! - **Native**: Uses efficient thread parking (`thread::park`)
//! - **WASM with `Atomics.wait`**: Uses `Atomics.wait` for proper blocking
//! - **WASM without `Atomics.wait`**: Falls back to spinning (e.g., browser main thread)
//!
//! This means you can write code once and have it work correctly across all platforms,
//! without worrying about whether you're on the main thread, a worker thread, native or WASM.
//!
//! # Primitives
//!
//! This crate provides the following primitives, all of which support the adaptive behavior:
//!
//! - **[`Mutex`]**: A mutual exclusion primitive for protecting shared data.
//! - **[`RwLock`](rwlock::RwLock)**: A reader-writer lock that allows multiple concurrent readers or one exclusive writer.
//! - **[`Condvar`](condvar::Condvar)**: A condition variable for blocking a thread while waiting for an event.
//! - **[`Spinlock`](spinlock::Spinlock)**: A spinlock for short-lived critical sections (primarily for internal use).
//! - **[`mpsc`]**: A multi-producer, single-consumer channel for message passing between threads.
//!
//! # Features
//!
//! - **Transparent adaptation**: Automatically detects and uses the best available locking mechanism
//! - **Main thread safe**: Won't panic on WASM main thread (uses spinning instead)
//! - **Worker thread optimized**: Uses proper blocking when available for efficiency
//! - **Native performance**: Full thread parking on native platforms
//! - **Async support**: Non-blocking async methods that work everywhere
//! - **Multiple strategies**: Try-lock, spin-lock, blocking lock, and async lock
//!
//! # Examples
//!
//! ## Mutex
//!
//! ```
//! use wasm_safe_mutex::Mutex;
//!
//! let mutex = Mutex::new(42);
//! let mut guard = mutex.lock_sync();
//! *guard = 100;
//! drop(guard);
//!
//! assert_eq!(*mutex.lock_sync(), 100);
//! ```
//!
//! ## RwLock
//!
//! ```
//! use wasm_safe_mutex::rwlock::RwLock;
//!
//! let rwlock = RwLock::new(vec![1, 2, 3]);
//!
//! // Multiple readers
//! let r1 = rwlock.lock_sync_read();
//! let r2 = rwlock.lock_sync_read();
//! assert_eq!(r1.len(), 3);
//! assert_eq!(r2.len(), 3);
//! drop(r1);
//! drop(r2);
//!
//! // Exclusive writer
//! let mut w = rwlock.lock_sync_write();
//! w.push(4);
//! ```
//!
//! ## Channel (mpsc)
//!
//! The [`channel()`](mpsc::channel) function creates a [`Sender`](mpsc::Sender) and [`Receiver`](mpsc::Receiver) pair.
//! The `Sender` can be cloned to create multiple producers, while the `Receiver` can be used directly
//! or consumed as an iterator via [`IntoIter`](mpsc::IntoIter).
//!
//! ```
//! use wasm_safe_mutex::mpsc::channel;
//!
//! let (tx, rx) = channel();
//!
//! // Send values from multiple producers
//! tx.send_sync(1).unwrap();
//! tx.send_sync(2).unwrap();
//!
//! // Receive values
//! assert_eq!(rx.recv_sync().unwrap(), 1);
//! assert_eq!(rx.recv_sync().unwrap(), 2);
//! ```
//!
//! The receiver can also be used as an iterator:
//!
//! ```
//! # // std::thread::spawn panics on wasm32
//! # if cfg!(target_arch = "wasm32") { return; }
//! # use wasm_safe_mutex::mpsc::channel;
//! # use std::thread;
//! let (tx, rx) = channel();
//!
//! // Spawn a thread to send values
//! thread::spawn(move || {
//! for i in 0..5 {
//! tx.send_sync(i).unwrap();
//! }
//! // tx is dropped here, closing the channel
//! });
//!
//! // Iterate over received values until channel closes
//! for value in rx {
//! println!("Received: {}", value);
//! }
//! ```
//!
//! ## Async Usage
//!
//! ```
//! # test_executors::spin_on(async {
//! use wasm_safe_mutex::Mutex;
//!
//! let mutex = Mutex::new(0);
//!
//! // Async lock works everywhere, including WASM main thread
//! let mut guard = mutex.lock_async().await;
//! *guard += 1;
//! # });
//! ```
pub use crateGuard;
pub use ;