Commit graph

28 commits

Author SHA1 Message Date
Matt Corallo
8157c01eab Never store more than one StdWaker per live Future
When an `std::future::Future` is `poll()`ed, we're only supposed to
use the latest `Waker` provided. However, we currently push an
`StdWaker` onto our callback list every time `poll` is called,
waking every `Waker` but also using more and more memory until the
`Future` itself is woken.

Here we fix this by removing any `StdWaker`s stored for a given
`Future` when it is `drop`ped or prior to pushing a new `StdWaker`
onto the list when `poll`ed.

Sadly, the introduction of a `Drop` impl for `Future` means we
can't trivially destructure the struct any longer, causing a few
methods to need to take `Future`s by reference rather than
ownership and `clone` a few `Arc`s.

Fixes #2874
2024-02-15 21:52:06 +00:00
Matt Corallo
5f404b9d0a Give Futures for a FutureState an idx and track StdWaker idxn
When an `std::future::Future` is `poll()`ed, we're only supposed to
use the latest `Waker` provided. However, we currently push an
`StdWaker` onto our callback list every time `poll` is called,
waking every `Waker` but also using more and more memory until the
`Future` itself is woken.

Here we take a step towards fixing this by giving each `Future` a
unique index and storing which `Future` an `StdWaker` came from in
the callback list. This sets us up to deduplicate `StdWaker`s by
`Future`s in the next commit.
2024-02-15 21:52:06 +00:00
Matt Corallo
2c987209f9 Split lists of Waker and directly-registered Future callbacks
In the next commit we'll fix a memory leak due to keeping too many
`std::task::Waker` callbacks in `FutureState` from redundant `poll`
calls, but first we need to split handling of `StdWaker`-based
future wake callbacks from normal ones, which we do here.
2024-02-15 21:52:06 +00:00
shuoer86
fff6616b7c
Fix typo lightning/src/util/wakers.rs 2024-01-12 20:46:47 +08:00
Matt Corallo
7caa584051 Fix a leak in FutureState when a Notifier is dropped un-woken
If a `Notifier` has an internal `FutureState` which gathers some
sleeper callbacks, but is never actaully woken, those callbacks
will leak due to a circular `Arc` reference when the `Notifier` is
`drop`'d.

Because `Notifier`s are rarely `drop`'d in production this isn't a
huge deal, but shows up materially in bindings tests as they spawn
many nodes over the course of a short test.

Fixes #2232
2023-04-26 05:43:23 +00:00
Matt Corallo
3873afcb75 Hold a reference to the Arc<FutureState> when completing futures
This will allow us to pass in that state to the callbacks in the
next commit.
2023-04-26 05:39:25 +00:00
Matt Corallo
3acf7e2c9d 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.
2023-04-03 16:49:54 +00:00
Matt Corallo
efcb5e02dc Move the pub wait methods from ChannelManager to Future
Rather than having three ways to await a `ChannelManager` being
persistable, this moves to just exposing the awaitable `Future` and
having sleep functions on that.
2023-04-03 16:49:54 +00:00
Matt Corallo
b455fb5e77 Implement the ability to block on multiple futures at once
In the next commits we'll be adding a second notify pipeline - from
the `ChainMonitor` back to the background processor. This will
cause the `background-processor` to need to await multiple wakers
at once, which we cannot do in the current scheme without taking on
a full async runtime.

Building a multi-future waiter isn't so bad, and notably will allow
us to remove the existing sleep pipeline entirely, reducing the
complexity of our wakers implementation by only having one notify
path to consider.
2023-04-03 16:49:54 +00:00
Matt Corallo
328407351c Do not bound callbacks by Send when building for no-std
`Send` is rather useless on a `no-std` target - we don't have
threads and are just needlessly restricting ourselves, so here we
skip it for the wakers callback.
2023-04-03 16:49:54 +00:00
munjesi
b0bf50fa24 Replacing (C-not exported) in the docs 2023-03-22 14:30:36 +03:00
Matt Corallo
cd03cb6477 Make waking after a future completes propagates to the next future
In our `wakers`, if we first `notify` a future, which is then
`poll`ed complete, and then `notify` the same waker again before a
new future is fetched, that new future will be marked as
non-complete initially and wait for a third `notify`.

The fix is luckily rather trivial, when we `notify` a future, if it
is completed immediately, simply wipe the future state so that we
look at the pending-notify flag when we generate the next future.
2023-03-02 07:50:16 +00:00
Matt Corallo
0a1e48f9c7 Await Future::poll Completed before unsetting notify-required
When we mark a future as complete, if the user is using the
`std::future::Future` impl to get notified, we shouldn't just
assume we have completed the `Future` when we call the `Waker`. A
`Future` may have been `drop`'d at that point (or may not be
`poll`'d again) even though we wake the `Waker`.

Because we now have a `callbacks_made` flag, we can fix this rather
trivially, simply not setting the flag until the `Future` is
`poll`'d `Complete`.
2022-11-16 00:21:43 +00:00
Matt Corallo
5f053e43af Wipe Notifier FutureState when returning from a waiter.
When we return from one of the wait functions in `Notifier`, we
should also ensure that the next `Future` doesn't start in the
`complete` state, as we have already notified the user, as far as
we're concerned.

This is technically a regression from the previous commit, but as
it is a logically separate change it is in its own commit.
2022-11-16 00:21:43 +00:00
Matt Corallo
7527e4b7df Unset the needs-notify bit in a Notifier when a Future is fetched
If a `Notifier` gets `notify()`ed and the a `Future` is fetched,
even though the `Future` is marked completed from the start and
the user may pass callbacks which are called, we'll never wipe the
needs-notify bit in the `Notifier`.

The solution is to keep track of the `FutureState` in the returned
`Future` even though its `complete` from the start, adding a new
flag in the `FutureState` which indicates callbacks have been made
and checking that flag when waiting or returning a second `Future`.
2022-11-16 00:21:43 +00:00
Matt Corallo
bcf8687301 Remove excess module
This appears to have been added with the intent of having a sealed
trait, which was never committed.
2022-11-16 00:21:41 +00:00
Matt Corallo
f382f56cbb Fix persistence-required futures always completing instantly
After the first persistence-required `Future` wakeup, we'll always
complete additional futures instantly as we don't clear the
"need wake" bit. Instead, we need to just assume that if a future
was generated (and not immediately drop'd) that its sufficient to
notify the user.
2022-11-11 02:03:52 +00:00
Wilmer Paulino
f4f1093edc
Bump workspace to rust edition 2018
Mostly motivated by the need of async/await.
2022-10-21 14:47:34 -07:00
Matt Corallo
cf3471f8ad Fix (and test) Future creation after a Notifier was notified
After a `Notifier` has been `notify`'d, attempts to `get_future`
should return a `Future` which is pre-completed, however this was
not the case.

This commit simply fixes the behavior, adding a test to demonstrate
the issue.
2022-10-06 23:54:52 +00:00
Matt Corallo
1beb3bb421 Add a bindings-only version of Future::register_callback
While we could, in theory, add support to the bindings logic to map
`Box<dyn Trait>`, there isn't a whole lot of use doing so when its
incredibly trivial to do directly.

This adds a trivial wrapper around `Future::register_callback` that
is only built in bindings and which is linked in the
`register_callback` docs for visibility.
2022-09-23 21:12:04 +00:00
Matt Corallo
0cc3572719 Fix several compile warnings when testing in no-std mode 2022-09-10 00:18:32 +00:00
Matt Corallo
610511ced6 Fix (really dumb) warning rustc introduced in latest beta 2022-09-09 21:49:05 +00:00
Matt Corallo
f14ea3dd18 Fix several compile warnings added in some of my recent commits 2022-09-09 21:49:05 +00:00
Matt Corallo
2a5bac22bf Add a background processing function that is async.
Adds a method which operates like BackgroundProcessor::start but
instead of functioning by spawning a background thread it is async.
2022-09-06 17:42:24 +00:00
Matt Corallo
c6890cfc33 Add a Future which can receive manager persistence events
This allows users who don't wish to block a full thread to receive
persistence events.

The `Future` added here is really just a trivial list of callbacks,
but from that we can build a (somewhat ineffecient)
std::future::Future implementation and can (at least once a mapping
for Box<dyn Trait> is added) include the future in no-std bindings
as well.

Fixes #1595
2022-09-06 17:42:21 +00:00
Matt Corallo
2035cebe8a Remove internal references to persistence in waker.rs 2022-09-06 16:22:58 +00:00
Matt Corallo
47e9ca15b2 Rename PersistenceNotifier to simply Notifier
... as it is no longer persistence-specific (though still only used
for persistence).
2022-08-12 23:55:28 +00:00
Matt Corallo
68b3d2e453 Move PersistenceNotifier to a new util module
It was always somewhat strange to have a bunch of notification
logic in `channelmanager`, and with the next commit adding a bunch
more, its moved here first.
2022-08-09 06:06:18 +00:00