Skip to content

Commit 83f4b56

Browse files
committed
[WIP]
1 parent 35a5dca commit 83f4b56

26 files changed

Lines changed: 272 additions & 344 deletions

.vscode/settings.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
"cSpell.words": [
33
"combinators",
44
"isoprenoid",
5+
"oneshot",
56
"pinnable",
67
"Reborrows",
78
"restabilised",
89
"RPITIT",
910
"scopeguard",
10-
"sptr"
11+
"sptr",
12+
"uninit"
1113
],
1214
"rust-analyzer.cargo.features": [
1315
"_test"

Cargo.lock

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flourish-bound/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ _test = ["global_signals_runtime", "_doc"] # Internal testing feature.
2525
_doc = ["global_signals_runtime"] # Internal documentation feature.
2626

2727
[dependencies]
28+
futures-channel = { version = "0.3.31", default-features = false, features = ["alloc"] }
2829
futures-lite = { version = "2.3.0", default-features = false, features = ["alloc"] }
2930
isoprenoid-bound = { version = "0.1.2", path = "../isoprenoid-bound" }
3031
pin-project = "1.1.5"

flourish-bound/src/conversions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116

117117
use std::{borrow::Borrow, ops::Deref};
118118

119-
use isoprenoid::runtime::SignalsRuntimeRef;
119+
use isoprenoid_bound::runtime::SignalsRuntimeRef;
120120

121121
use crate::{
122122
signal_arc::SignalArcDynCell, traits::UnmanagedSignalCell, unmanaged::UnmanagedSignal, Effect,

flourish-bound/src/effect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{marker::PhantomData, pin::Pin};
22

3-
use isoprenoid::runtime::SignalsRuntimeRef;
3+
use isoprenoid_bound::runtime::SignalsRuntimeRef;
44

55
use crate::unmanaged::new_raw_unsubscribed_effect;
66

flourish-bound/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub use effect::Effect;
4040
mod traits;
4141
pub use traits::Guard;
4242

43-
pub use isoprenoid::runtime::{GlobalSignalsRuntime, Propagation, SignalsRuntimeRef};
43+
pub use isoprenoid_bound::runtime::{GlobalSignalsRuntime, Propagation, SignalsRuntimeRef};
4444

4545
pub mod prelude {
4646
//! Unmanaged signal accessors and [`SignalsRuntimeRef`].

flourish-bound/src/opaque.rs

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{
77
task::{Context, Poll},
88
};
99

10-
use isoprenoid::runtime::SignalsRuntimeRef;
10+
use isoprenoid_bound::runtime::{Propagation, SignalsRuntimeRef};
1111

1212
use crate::traits::{Guard, UnmanagedSignal, UnmanagedSignalCell};
1313

@@ -77,20 +77,16 @@ impl<T: ?Sized, SR: ?Sized + SignalsRuntimeRef> UnmanagedSignalCell<T, SR> for O
7777
match *self {}
7878
}
7979

80-
fn update(
81-
self: Pin<&Self>,
82-
_: impl 'static + FnOnce(&mut T) -> isoprenoid::runtime::Propagation,
83-
) where
80+
fn update(self: Pin<&Self>, _: impl 'static + FnOnce(&mut T) -> Propagation)
81+
where
8482
Self: Sized,
8583
T: 'static,
8684
{
8785
match *self {}
8886
}
8987

90-
fn update_dyn(
91-
self: Pin<&Self>,
92-
_: Box<dyn 'static + FnOnce(&mut T) -> isoprenoid::runtime::Propagation>,
93-
) where
88+
fn update_dyn(self: Pin<&Self>, _: Box<dyn 'static + FnOnce(&mut T) -> Propagation>)
89+
where
9490
T: 'static,
9591
{
9692
match *self {}
@@ -124,7 +120,7 @@ impl<T: ?Sized, SR: ?Sized + SignalsRuntimeRef> UnmanagedSignalCell<T, SR> for O
124120
Self: 'f + Sized,
125121
T: 'f + Sized;
126122

127-
fn update_eager<'f, U: 'f, F: 'f + FnOnce(&mut T) -> (isoprenoid::runtime::Propagation, U)>(
123+
fn update_eager<'f, U: 'f, F: 'f + FnOnce(&mut T) -> (Propagation, U)>(
128124
self: Pin<&Self>,
129125
_: F,
130126
) -> OpaqueFuture<Result<U, F>>
@@ -158,16 +154,8 @@ impl<T: ?Sized, SR: ?Sized + SignalsRuntimeRef> UnmanagedSignalCell<T, SR> for O
158154

159155
fn update_eager_dyn<'f>(
160156
self: Pin<&Self>,
161-
_: Box<dyn 'f + FnOnce(&mut T) -> isoprenoid::runtime::Propagation>,
162-
) -> Box<
163-
dyn 'f
164-
+ Future<
165-
Output = Result<
166-
(),
167-
Box<dyn 'f + FnOnce(&mut T) -> isoprenoid::runtime::Propagation>,
168-
>,
169-
>,
170-
>
157+
_: Box<dyn 'f + FnOnce(&mut T) -> Propagation>,
158+
) -> Box<dyn 'f + Future<Output = Result<(), Box<dyn 'f + FnOnce(&mut T) -> Propagation>>>>
171159
where
172160
T: 'f,
173161
{
@@ -188,20 +176,14 @@ impl<T: ?Sized, SR: ?Sized + SignalsRuntimeRef> UnmanagedSignalCell<T, SR> for O
188176
match *self {}
189177
}
190178

191-
fn update_blocking<U>(
192-
&self,
193-
_: impl FnOnce(&mut T) -> (isoprenoid::runtime::Propagation, U),
194-
) -> U
179+
fn update_blocking<U>(&self, _: impl FnOnce(&mut T) -> (Propagation, U)) -> U
195180
where
196181
Self: Sized,
197182
{
198183
match *self {}
199184
}
200185

201-
fn update_blocking_dyn(
202-
&self,
203-
_: Box<dyn '_ + FnOnce(&mut T) -> isoprenoid::runtime::Propagation>,
204-
) {
186+
fn update_blocking_dyn(&self, _: Box<dyn '_ + FnOnce(&mut T) -> Propagation>) {
205187
match *self {}
206188
}
207189
}

flourish-bound/src/signal.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::{
1313
};
1414

1515
use futures_lite::FutureExt as _;
16-
use isoprenoid::runtime::{CallbackTableTypes, Propagation, SignalsRuntimeRef};
16+
use isoprenoid_bound::runtime::{CallbackTableTypes, Propagation, SignalsRuntimeRef};
1717
use tap::Conv;
1818

1919
use crate::{
@@ -1480,7 +1480,7 @@ impl<T: ?Sized, S: ?Sized + UnmanagedSignalCell<T, SR>, SR: ?Sized + SignalsRunt
14801480
Box::pin(async move {
14811481
if let Some(this) = this.upgrade() {
14821482
//FIXME: Likely <https://github.com/rust-lang/rust/issues/100013>.
1483-
this.change_eager(new_value).boxed().await
1483+
this.change_eager(new_value).boxed_local().await
14841484
} else {
14851485
Err(new_value)
14861486
}
@@ -1502,7 +1502,7 @@ impl<T: ?Sized, S: ?Sized + UnmanagedSignalCell<T, SR>, SR: ?Sized + SignalsRunt
15021502
Box::pin(async move {
15031503
if let Some(this) = this.upgrade() {
15041504
//FIXME: Likely <https://github.com/rust-lang/rust/issues/100013>.
1505-
this.replace_eager(new_value).boxed().await
1505+
this.replace_eager(new_value).boxed_local().await
15061506
} else {
15071507
Err(new_value)
15081508
}
@@ -1527,7 +1527,7 @@ impl<T: ?Sized, S: ?Sized + UnmanagedSignalCell<T, SR>, SR: ?Sized + SignalsRunt
15271527
Box::pin(async move {
15281528
if let Some(this) = this.upgrade() {
15291529
//FIXME: Likely <https://github.com/rust-lang/rust/issues/100013>.
1530-
this.update_eager(update).boxed().await
1530+
this.update_eager(update).boxed_local().await
15311531
} else {
15321532
Err(update)
15331533
}

flourish-bound/src/signal_arc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55
ops::Deref,
66
};
77

8-
use isoprenoid::runtime::SignalsRuntimeRef;
8+
use isoprenoid_bound::runtime::SignalsRuntimeRef;
99

1010
use crate::{
1111
signal::{Signal, Strong, Weak},

flourish-bound/src/subscription.rs

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use std::{
55
mem::{ManuallyDrop, MaybeUninit},
66
ops::Deref,
77
pin::Pin,
8-
sync::Arc,
98
};
109

11-
use isoprenoid::runtime::{Propagation, SignalsRuntimeRef};
10+
use futures_channel::oneshot;
11+
use isoprenoid_bound::runtime::{Propagation, SignalsRuntimeRef};
1212
use pin_project::pin_project;
1313

1414
use crate::{
@@ -510,19 +510,19 @@ impl<T: ?Sized, SR: ?Sized + SignalsRuntimeRef> Subscription<T, Opaque, SR> {
510510
async {
511511
let sub = Subscription::computed_with_runtime(select_fn_pin, runtime.clone());
512512
{
513-
let once = async_lock::Mutex::new(());
514-
let mut lock = Some(once.try_lock().expect("unreachable"));
513+
let (notify_ready, ready) = oneshot::channel();
514+
let mut notify = Some(notify_ready);
515515
signals_helper! {
516516
let effect = effect_with_runtime!({
517517
let sub = &sub;
518518
move || {
519519
if !predicate_fn_pin(&**sub.read_dyn()) {
520-
drop(lock.take());
520+
notify.take().expect("Reached only once.").send(());
521521
}
522522
}
523523
}, drop, runtime);
524524
}
525-
once.lock().await;
525+
ready.await;
526526
}
527527
sub
528528
}
@@ -597,24 +597,21 @@ impl<T: ?Sized, SR: ?Sized + SignalsRuntimeRef> Subscription<T, Opaque, SR> {
597597
SR: 'a,
598598
{
599599
async {
600-
// It's actually possible to avoid the `Arc` here, with a tri-state atomic or another `Once`,
601-
// since the closure is guaranteed to run when the subscription is created.
602-
// However, that would be considerably trickier code.
603-
let once = Arc::new(async_lock::Mutex::<()>::new(()));
604-
let mut lock = Some(once.try_lock_arc().expect("unreachable"));
600+
let (notify_initialized, initialized) = oneshot::channel();
601+
let mut notify_initialized = Some(notify_initialized);
605602
let sub = Subscription::folded_with_runtime(
606603
MaybeUninit::uninit(),
607604
{
608605
move |value| {
609606
let next = fn_pin();
610607
if predicate_fn_pin(&next) {
611-
match lock.take() {
608+
match notify_initialized.take() {
612609
None => {
613610
*unsafe { value.assume_init_mut() } = next;
614611
}
615-
Some(lock) => {
612+
Some(notify_initialized) => {
616613
value.write(next);
617-
drop(lock);
614+
notify_initialized.send(());
618615
}
619616
}
620617
Propagation::Propagate
@@ -625,7 +622,7 @@ impl<T: ?Sized, SR: ?Sized + SignalsRuntimeRef> Subscription<T, Opaque, SR> {
625622
},
626623
runtime,
627624
);
628-
once.lock().await;
625+
initialized.await;
629626

630627
unsafe { assume_init_subscription(sub) }
631628
}
@@ -689,23 +686,20 @@ impl<T: ?Sized, SR: ?Sized + SignalsRuntimeRef> Subscription<T, Opaque, SR> {
689686
SR: 'a,
690687
{
691688
async {
692-
// It's actually possible to avoid the `Arc` here, with a tri-state atomic or another `Once`,
693-
// since the closure is guaranteed to run when the subscription is created.
694-
// However, that would be considerably trickier code.
695-
let once = Arc::new(async_lock::Mutex::new(()));
696-
let mut lock = Some(once.try_lock_arc().expect("unreachable"));
689+
let (notify_initialized, initialized) = oneshot::channel();
690+
let mut notify_initialized = Some(notify_initialized);
697691
let sub = Subscription::folded_with_runtime(
698692
MaybeUninit::uninit(),
699693
{
700694
move |value| {
701695
if let Some(next) = fn_pin() {
702-
match lock.take() {
696+
match notify_initialized.take() {
703697
None => {
704698
*unsafe { value.assume_init_mut() } = next;
705699
}
706-
Some(lock) => {
700+
Some(notify_initialized) => {
707701
value.write(next);
708-
drop(lock);
702+
notify_initialized.send(());
709703
}
710704
}
711705
Propagation::Propagate
@@ -716,7 +710,7 @@ impl<T: ?Sized, SR: ?Sized + SignalsRuntimeRef> Subscription<T, Opaque, SR> {
716710
},
717711
runtime,
718712
);
719-
once.lock().await;
713+
initialized.await;
720714

721715
unsafe { assume_init_subscription(sub) }
722716
}

0 commit comments

Comments
 (0)