-
Notifications
You must be signed in to change notification settings - Fork 825
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Modified the store so that it can be Cloned
Added a Reactor that drives WebAssembly react pattern Fixed multithreading Added thread local storage Implemented the remaining functionality for the bus
- Loading branch information
1 parent
43138b5
commit af5663b
Showing
69 changed files
with
2,860 additions
and
3,657 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
use std::collections::VecDeque; | ||
use std::sync::Mutex; | ||
use std::sync::atomic::AtomicBool; | ||
use std::sync::atomic::Ordering; | ||
use std::sync::mpsc; | ||
use std::sync::Arc; | ||
use std::task::Waker; | ||
use std::time::Duration; | ||
|
||
/// Reactor pattern implementation that allows for web assembly | ||
/// processes to easily implement asynchronous IO | ||
#[derive(Debug, Clone)] | ||
pub struct Reactors | ||
{ | ||
waker: Waker, | ||
woken: Arc<AtomicBool>, | ||
waiting: Arc<Mutex<VecDeque<mpsc::Sender<()>>>>, | ||
} | ||
|
||
impl Default | ||
for Reactors { | ||
fn default() -> Self { | ||
let woken = Arc::new(AtomicBool::new(false)); | ||
let waiting: Arc<Mutex<VecDeque<mpsc::Sender<()>>>> = Default::default(); | ||
|
||
let waker = { | ||
let woken = woken.clone(); | ||
let waiting = Arc::downgrade(&waiting); | ||
waker_fn::waker_fn(move || { | ||
if let Some(waiting) = waiting.upgrade() { | ||
let mut guard = waiting.lock().unwrap(); | ||
woken.store(true, Ordering::Release); | ||
if let Some(reactor) = guard.pop_front() { | ||
let _ = reactor.send(()); | ||
} | ||
} | ||
}) | ||
}; | ||
|
||
Self { | ||
waker, | ||
woken, | ||
waiting, | ||
} | ||
} | ||
} | ||
|
||
impl Reactors | ||
{ | ||
/// Gets a reference to the waker that can be used for | ||
/// asynchronous calls | ||
pub fn get_waker(&self) -> Waker { | ||
self.waker.clone() | ||
} | ||
|
||
/// Wakes one of the reactors thats currently waiting | ||
pub fn wake(&self) { | ||
self.waker.wake_by_ref(); | ||
} | ||
|
||
/// Wakes all of the reactors thats currently waiting | ||
pub fn wake_all(&self) { | ||
let mut guard = self.waiting.lock().unwrap(); | ||
self.woken.store(true, Ordering::Release); | ||
guard.clear(); | ||
} | ||
|
||
/// Returns true if woken, otherwise false for timeout | ||
pub fn wait(&self, timeout: Duration) -> bool { | ||
let rx = { | ||
let mut guard = self.waiting.lock().unwrap(); | ||
if self.woken.compare_exchange(true, false, Ordering::AcqRel, Ordering::Acquire).is_ok() { | ||
return true; | ||
} | ||
if timeout.is_zero() { | ||
return false; | ||
} | ||
|
||
let (tx, rx) = mpsc::channel(); | ||
guard.push_back(tx); | ||
rx | ||
}; | ||
match rx.recv_timeout(timeout) { | ||
Ok(_) => true, | ||
Err(_) => false, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.