Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 15 additions & 44 deletions rust_crate/src/shutdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,13 @@ pub struct Event {
impl Event {
/// Creates a new `Event` with the initial flag state.
pub fn new() -> Self {
let inner = EventInner {
flag: false,
session: 0,
wakers: Vec::new(),
};
Event {
inner: Arc::new(Mutex::new(EventInner::new())),
inner: Arc::new(Mutex::new(inner)),
#[cfg(not(target_family = "wasm"))]
condvar: Arc::new(Condvar::new()),
}
Expand Down Expand Up @@ -91,54 +96,13 @@ impl Event {
/// If the flag is already set,
/// this method will return immediately.
/// Otherwise, it will block until `set` is called by another thread.
pub fn wait(&self) {
let blocking = EventBlocking::new(self.inner.clone(), self.condvar.clone());
blocking.wait();
}
}

/// Internal state for the `Event` synchronization primitive.
struct EventInner {
flag: bool, // Current flag state
session: usize, // Session count to detect changes
wakers: Vec<Waker>, // List of wakers to be notified
}

impl EventInner {
pub fn new() -> Self {
EventInner {
flag: false,
session: 0,
wakers: Vec::new(),
}
}
}

/// Struct to handle waiting with session tracking.
#[cfg(not(target_family = "wasm"))]
struct EventBlocking {
inner: Arc<Mutex<EventInner>>,
condvar: Arc<Condvar>,
started_session: usize,
}

#[cfg(not(target_family = "wasm"))]
impl EventBlocking {
pub fn new(inner: Arc<Mutex<EventInner>>, condvar: Arc<Condvar>) -> Self {
let guard = inner.lock().recover();
EventBlocking {
inner: inner.clone(),
condvar,
started_session: guard.session,
}
}

pub fn wait(&self) {
// Lock the inner state and wait on the condition variable
let mut guard = self.inner.lock().recover();
let started_session = guard.session;
loop {
// Check if the condition is met
if guard.flag || guard.session != self.started_session {
if guard.flag || guard.session != started_session {
break;
}
// Wait on the condition variable and reassign the guard
Expand All @@ -147,6 +111,13 @@ impl EventBlocking {
}
}

/// Internal state for the `Event` synchronization primitive.
struct EventInner {
flag: bool, // Current flag state
session: usize, // Session count to detect changes
wakers: Vec<Waker>, // List of wakers to be notified
}

/// Future that resolves when the `Event` flag is set to `true`.
pub struct EventFuture {
started_session: usize,
Expand Down