summaryrefslogtreecommitdiffstats
path: root/tokio/src/executor/tests/loom_oneshot.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tokio/src/executor/tests/loom_oneshot.rs')
-rw-r--r--tokio/src/executor/tests/loom_oneshot.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/tokio/src/executor/tests/loom_oneshot.rs b/tokio/src/executor/tests/loom_oneshot.rs
new file mode 100644
index 00000000..c126fe47
--- /dev/null
+++ b/tokio/src/executor/tests/loom_oneshot.rs
@@ -0,0 +1,49 @@
+use loom::sync::Notify;
+
+use std::sync::{Arc, Mutex};
+
+pub(crate) fn channel<T>() -> (Sender<T>, Receiver<T>) {
+ let inner = Arc::new(Inner {
+ notify: Notify::new(),
+ value: Mutex::new(None),
+ });
+
+ let tx = Sender {
+ inner: inner.clone(),
+ };
+ let rx = Receiver { inner };
+
+ (tx, rx)
+}
+
+pub(crate) struct Sender<T> {
+ inner: Arc<Inner<T>>,
+}
+
+pub(crate) struct Receiver<T> {
+ inner: Arc<Inner<T>>,
+}
+
+struct Inner<T> {
+ notify: Notify,
+ value: Mutex<Option<T>>,
+}
+
+impl<T> Sender<T> {
+ pub(crate) fn send(self, value: T) {
+ *self.inner.value.lock().unwrap() = Some(value);
+ self.inner.notify.notify();
+ }
+}
+
+impl<T> Receiver<T> {
+ pub(crate) fn recv(self) -> T {
+ loop {
+ if let Some(v) = self.inner.value.lock().unwrap().take() {
+ return v;
+ }
+
+ self.inner.notify.wait();
+ }
+ }
+}