X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-background-processor%2Fsrc%2Flib.rs;h=541813c7e42c72f68568ec1c397fc531156d158c;hb=7ca37097274d5d2ed66e5f42e9948f71a344681f;hp=e15458d54b22c101c63d5961d11cd6182515e398;hpb=54a51f8554c9e6c47285eabcfe5a8115d0e3dc98;p=rust-lightning diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index e15458d5..541813c7 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -7,7 +7,7 @@ #![deny(private_intra_doc_links)] #![deny(missing_docs)] -#![deny(unsafe_code)] +#![cfg_attr(not(feature = "futures"), deny(unsafe_code))] #![cfg_attr(docsrs, feature(doc_auto_cfg))] @@ -52,8 +52,6 @@ use std::thread::{self, JoinHandle}; #[cfg(feature = "std")] use std::time::Instant; -#[cfg(feature = "futures")] -use futures_util::task; #[cfg(not(feature = "std"))] use alloc::vec::Vec; @@ -385,38 +383,48 @@ macro_rules! define_run_body { } #[cfg(feature = "futures")] -use core::future::Future; -#[cfg(feature = "futures")] -use core::task::Poll; -#[cfg(feature = "futures")] -use core::pin::Pin; -#[cfg(feature = "futures")] -use core::marker::Unpin; -#[cfg(feature = "futures")] -struct Selector + Unpin, B: Future + Unpin> { - a: A, - b: B, -} -#[cfg(feature = "futures")] -enum SelectorOutput { - A, B(bool), -} +pub(crate) mod futures_util { + use core::future::Future; + use core::task::{Poll, Waker, RawWaker, RawWakerVTable}; + use core::pin::Pin; + use core::marker::Unpin; + pub(crate) struct Selector + Unpin, B: Future + Unpin> { + pub a: A, + pub b: B, + } + pub(crate) enum SelectorOutput { + A, B(bool), + } -#[cfg(feature = "futures")] -impl + Unpin, B: Future + Unpin> Future for Selector { - type Output = SelectorOutput; - fn poll(mut self: Pin<&mut Self>, ctx: &mut core::task::Context<'_>) -> Poll { - match Pin::new(&mut self.a).poll(ctx) { - Poll::Ready(()) => { return Poll::Ready(SelectorOutput::A); }, - Poll::Pending => {}, - } - match Pin::new(&mut self.b).poll(ctx) { - Poll::Ready(res) => { return Poll::Ready(SelectorOutput::B(res)); }, - Poll::Pending => {}, + impl + Unpin, B: Future + Unpin> Future for Selector { + type Output = SelectorOutput; + fn poll(mut self: Pin<&mut Self>, ctx: &mut core::task::Context<'_>) -> Poll { + match Pin::new(&mut self.a).poll(ctx) { + Poll::Ready(()) => { return Poll::Ready(SelectorOutput::A); }, + Poll::Pending => {}, + } + match Pin::new(&mut self.b).poll(ctx) { + Poll::Ready(res) => { return Poll::Ready(SelectorOutput::B(res)); }, + Poll::Pending => {}, + } + Poll::Pending } - Poll::Pending } + + // If we want to poll a future without an async context to figure out if it has completed or + // not without awaiting, we need a Waker, which needs a vtable...we fill it with dummy values + // but sadly there's a good bit of boilerplate here. + fn dummy_waker_clone(_: *const ()) -> RawWaker { RawWaker::new(core::ptr::null(), &DUMMY_WAKER_VTABLE) } + fn dummy_waker_action(_: *const ()) { } + + const DUMMY_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new( + dummy_waker_clone, dummy_waker_action, dummy_waker_action, dummy_waker_action); + pub(crate) fn dummy_waker() -> Waker { unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &DUMMY_WAKER_VTABLE)) } } } +#[cfg(feature = "futures")] +use futures_util::{Selector, SelectorOutput, dummy_waker}; +#[cfg(feature = "futures")] +use core::task; /// Processes background events in a future. /// @@ -517,7 +525,7 @@ where } }, |t| sleeper(Duration::from_secs(t)), |fut: &mut SleepFuture, _| { - let mut waker = task::noop_waker(); + let mut waker = dummy_waker(); let mut ctx = task::Context::from_waker(&mut waker); core::pin::Pin::new(fut).poll(&mut ctx).is_ready() }) @@ -702,7 +710,7 @@ mod tests { use lightning::chain::keysinterface::{InMemorySigner, KeysManager}; use lightning::chain::transaction::OutPoint; use lightning::events::{Event, PathFailure, MessageSendEventsProvider, MessageSendEvent}; - use lightning::get_event_msg; + use lightning::{get_event_msg, get_event}; use lightning::ln::PaymentHash; use lightning::ln::channelmanager; use lightning::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChainParameters, MIN_CLTV_EXPIRY_DELTA, PaymentId}; @@ -1050,7 +1058,10 @@ mod tests { ($node_a: expr, $node_b: expr, $temporary_channel_id: expr, $tx: expr) => {{ $node_a.node.funding_transaction_generated(&$temporary_channel_id, &$node_b.node.get_our_node_id(), $tx.clone()).unwrap(); $node_b.node.handle_funding_created(&$node_a.node.get_our_node_id(), &get_event_msg!($node_a, MessageSendEvent::SendFundingCreated, $node_b.node.get_our_node_id())); + get_event!($node_b, Event::ChannelPending); + $node_a.node.handle_funding_signed(&$node_b.node.get_our_node_id(), &get_event_msg!($node_b, MessageSendEvent::SendFundingSigned, $node_a.node.get_our_node_id())); + get_event!($node_a, Event::ChannelPending); }} }