Skip to content

Commit ec2ea17

Browse files
committed
Drop the dummy no-std Condvar which never sleeps
In `no-std`, we exposed `wait` functions which rely on a dummy `Condvar` which never actually sleeps. This is somwhat nonsensical, not to mention confusing to users. Instead, we simply remove the `wait` methods in `no-std` builds.
1 parent 8ad5160 commit ec2ea17

File tree

3 files changed

+42
-54
lines changed

3 files changed

+42
-54
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7822,6 +7822,7 @@ mod tests {
78227822
use bitcoin::hashes::Hash;
78237823
use bitcoin::hashes::sha256::Hash as Sha256;
78247824
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
7825+
#[cfg(feature = "std")]
78257826
use core::time::Duration;
78267827
use core::sync::atomic::Ordering;
78277828
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
@@ -7847,9 +7848,9 @@ mod tests {
78477848

78487849
// All nodes start with a persistable update pending as `create_network` connects each node
78497850
// with all other nodes to make most tests simpler.
7850-
assert!(nodes[0].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7851-
assert!(nodes[1].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7852-
assert!(nodes[2].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7851+
assert!(nodes[0].node.get_persistable_update_future().poll_is_complete());
7852+
assert!(nodes[1].node.get_persistable_update_future().poll_is_complete());
7853+
assert!(nodes[2].node.get_persistable_update_future().poll_is_complete());
78537854

78547855
let mut chan = create_announced_chan_between_nodes(&nodes, 0, 1);
78557856

@@ -7863,28 +7864,28 @@ mod tests {
78637864
&nodes[0].node.get_our_node_id()).pop().unwrap();
78647865

78657866
// The first two nodes (which opened a channel) should now require fresh persistence
7866-
assert!(nodes[0].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7867-
assert!(nodes[1].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7867+
assert!(nodes[0].node.get_persistable_update_future().poll_is_complete());
7868+
assert!(nodes[1].node.get_persistable_update_future().poll_is_complete());
78687869
// ... but the last node should not.
7869-
assert!(!nodes[2].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7870+
assert!(!nodes[2].node.get_persistable_update_future().poll_is_complete());
78707871
// After persisting the first two nodes they should no longer need fresh persistence.
7871-
assert!(!nodes[0].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7872-
assert!(!nodes[1].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7872+
assert!(!nodes[0].node.get_persistable_update_future().poll_is_complete());
7873+
assert!(!nodes[1].node.get_persistable_update_future().poll_is_complete());
78737874

78747875
// Node 3, unrelated to the only channel, shouldn't care if it receives a channel_update
78757876
// about the channel.
78767877
nodes[2].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &chan.0);
78777878
nodes[2].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &chan.1);
7878-
assert!(!nodes[2].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7879+
assert!(!nodes[2].node.get_persistable_update_future().poll_is_complete());
78797880

78807881
// The nodes which are a party to the channel should also ignore messages from unrelated
78817882
// parties.
78827883
nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan.0);
78837884
nodes[0].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan.1);
78847885
nodes[1].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan.0);
78857886
nodes[1].node.handle_channel_update(&nodes[2].node.get_our_node_id(), &chan.1);
7886-
assert!(!nodes[0].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7887-
assert!(!nodes[1].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7887+
assert!(!nodes[0].node.get_persistable_update_future().poll_is_complete());
7888+
assert!(!nodes[1].node.get_persistable_update_future().poll_is_complete());
78887889

78897890
// At this point the channel info given by peers should still be the same.
78907891
assert_eq!(nodes[0].node.list_channels()[0], node_a_chan_info);
@@ -7901,17 +7902,17 @@ mod tests {
79017902
// persisted and that its channel info remains the same.
79027903
nodes[0].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &as_update);
79037904
nodes[1].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &bs_update);
7904-
assert!(!nodes[0].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7905-
assert!(!nodes[1].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7905+
assert!(!nodes[0].node.get_persistable_update_future().poll_is_complete());
7906+
assert!(!nodes[1].node.get_persistable_update_future().poll_is_complete());
79067907
assert_eq!(nodes[0].node.list_channels()[0], node_a_chan_info);
79077908
assert_eq!(nodes[1].node.list_channels()[0], node_b_chan_info);
79087909

79097910
// Finally, deliver the other peers' message, ensuring each node needs to be persisted and
79107911
// the channel info has updated.
79117912
nodes[0].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &bs_update);
79127913
nodes[1].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &as_update);
7913-
assert!(nodes[0].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7914-
assert!(nodes[1].node.get_persistable_update_future().wait_timeout(Duration::from_millis(1)));
7914+
assert!(nodes[0].node.get_persistable_update_future().poll_is_complete());
7915+
assert!(nodes[1].node.get_persistable_update_future().poll_is_complete());
79157916
assert_ne!(nodes[0].node.list_channels()[0], node_a_chan_info);
79167917
assert_ne!(nodes[1].node.list_channels()[0], node_b_chan_info);
79177918
}

lightning/src/sync/nostd_sync.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,10 @@
11
pub use ::alloc::sync::Arc;
22
use core::ops::{Deref, DerefMut};
3-
use core::time::Duration;
43
use core::cell::{RefCell, Ref, RefMut};
54
use super::{LockTestExt, LockHeldState};
65

76
pub type LockResult<Guard> = Result<Guard, ()>;
87

9-
pub struct Condvar {}
10-
11-
impl Condvar {
12-
pub fn new() -> Condvar {
13-
Condvar { }
14-
}
15-
16-
pub fn wait<'a, T>(&'a self, guard: MutexGuard<'a, T>) -> LockResult<MutexGuard<'a, T>> {
17-
Ok(guard)
18-
}
19-
20-
#[allow(unused)]
21-
pub fn wait_timeout<'a, T>(&'a self, guard: MutexGuard<'a, T>, _dur: Duration) -> LockResult<(MutexGuard<'a, T>, ())> {
22-
Ok((guard, ()))
23-
}
24-
25-
pub fn notify_all(&self) {}
26-
}
27-
288
pub struct Mutex<T: ?Sized> {
299
inner: RefCell<T>
3010
}

lightning/src/util/wakers.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
1616
use alloc::sync::Arc;
1717
use core::mem;
18-
use crate::sync::{Condvar, Mutex, MutexGuard};
18+
use crate::sync::Mutex;
1919

2020
use crate::prelude::*;
2121

22-
#[cfg(any(test, feature = "std"))]
22+
#[cfg(feature = "std")]
23+
use crate::sync::{Condvar, MutexGuard};
24+
#[cfg(feature = "std")]
2325
use std::time::{Duration, Instant};
2426

2527
use core::future::Future as StdFuture;
@@ -160,17 +162,27 @@ impl Future {
160162
}
161163

162164
/// Waits until this [`Future`] completes.
165+
#[cfg(feature = "std")]
163166
pub fn wait(self) {
164167
Sleeper::from_single_future(self).wait();
165168
}
166169

167170
/// Waits until this [`Future`] completes or the given amount of time has elapsed.
168171
///
169172
/// Returns true if the [`Future`] completed, false if the time elapsed.
170-
#[cfg(any(test, feature = "std"))]
173+
#[cfg(feature = "std")]
171174
pub fn wait_timeout(self, max_wait: Duration) -> bool {
172175
Sleeper::from_single_future(self).wait_timeout(max_wait)
173176
}
177+
178+
#[cfg(test)]
179+
pub fn poll_is_complete(&self) -> bool {
180+
let mut state = self.state.lock().unwrap();
181+
if state.complete {
182+
state.callbacks_made = true;
183+
true
184+
} else { false }
185+
}
174186
}
175187

176188
use core::task::Waker;
@@ -198,10 +210,12 @@ impl<'a> StdFuture for Future {
198210

199211
/// A struct which can be used to select across many [`Future`]s at once without relying on a full
200212
/// async context.
213+
#[cfg(feature = "std")]
201214
pub struct Sleeper {
202215
notifiers: Vec<Arc<Mutex<FutureState>>>,
203216
}
204217

218+
#[cfg(feature = "std")]
205219
impl Sleeper {
206220
/// Constructs a new sleeper from one future, allowing blocking on it.
207221
pub fn from_single_future(future: Future) -> Self {
@@ -244,32 +258,23 @@ impl Sleeper {
244258
/// Wait until one of the [`Future`]s registered with this [`Sleeper`] has completed.
245259
pub fn wait(&self) {
246260
let (cv, notified_fut_mtx) = self.setup_wait();
247-
let notified_fut = loop {
248-
let mut notified_fut_lck = cv.wait(notified_fut_mtx.lock().unwrap()).unwrap();
249-
if let Some(notified_fut) = notified_fut_lck.take() {
250-
break notified_fut;
251-
}
252-
};
261+
let notified_fut = cv.wait_while(notified_fut_mtx.lock().unwrap(), |fut_opt| fut_opt.is_none())
262+
.unwrap().take().expect("CV wait shouldn't have returned until the notifying future was set");
253263
notified_fut.lock().unwrap().callbacks_made = true;
254264
}
255265

256266
/// Wait until one of the [`Future`]s registered with this [`Sleeper`] has completed or the
257267
/// given amount of time has elapsed. Returns true if a [`Future`] completed, false if the time
258268
/// elapsed.
259-
#[cfg(any(test, feature = "std"))]
260269
pub fn wait_timeout(&self, max_wait: Duration) -> bool {
261-
let start_time = Instant::now();
262270
let (cv, notified_fut_mtx) = self.setup_wait();
263-
let notified_fut = loop {
264-
let wait_duration = max_wait.saturating_sub(start_time.elapsed());
265-
if wait_duration == Duration::from_secs(0) { return false; }
266-
match cv.wait_timeout(notified_fut_mtx.lock().unwrap(), wait_duration) {
267-
Ok((mut notified_fut, _)) if notified_fut.is_some() =>
268-
break notified_fut.take().unwrap(),
269-
Ok((notified_fut_lck, _)) => continue,
271+
let notified_fut =
272+
match cv.wait_timeout_while(notified_fut_mtx.lock().unwrap(), max_wait, |fut_opt| fut_opt.is_none()) {
273+
Ok((_, e)) if e.timed_out() => return false,
274+
Ok((mut notified_fut, _)) =>
275+
notified_fut.take().expect("CV wait shouldn't have returned until the notifying future was set"),
270276
Err(_) => panic!("Previous panic while a lock was held led to a lock panic"),
271277
};
272-
};
273278
notified_fut.lock().unwrap().callbacks_made = true;
274279
true
275280
}
@@ -486,6 +491,7 @@ mod tests {
486491
}
487492

488493
#[test]
494+
#[cfg(feature = "std")]
489495
fn test_dropped_future_doesnt_count() {
490496
// Tests that if a Future gets drop'd before it is poll()ed `Ready` it doesn't count as
491497
// having been woken, leaving the notify-required flag set.
@@ -577,6 +583,7 @@ mod tests {
577583
}
578584

579585
#[test]
586+
#[cfg(feature = "std")]
580587
fn test_multi_future_sleep() {
581588
// Tests the `Sleeper` with multiple futures.
582589
let notifier_a = Notifier::new();

0 commit comments

Comments
 (0)