Skip to content

Switch total_consistency_lock to a Send RwLock variant #2003

Closed
@tnull

Description

@tnull

When trying to switch to async background processing/event handling in LDK Node, I stumbled across the fact that tokio won't let me spawn a task for the process_events_async, as the we currently try to hold the total_consistency_lock over .await boundaries:

let _read_guard = self.total_consistency_lock.read().unwrap();
let mut result = NotifyOption::SkipPersist;
// TODO: This behavior should be documented. It's unintuitive that we query
// ChannelMonitors when clearing other events.
if self.process_pending_monitor_events() {
result = NotifyOption::DoPersist;
}
let pending_events = mem::replace(&mut *self.pending_events.lock().unwrap(), vec![]);
if !pending_events.is_empty() {
result = NotifyOption::DoPersist;
}
for event in pending_events {
handler(event).await;
}

This is an issue since RwLockReadGuard is not Send:

     = help: within `impl futures::Future<Output = ()>`, the trait `std::marker::Send` is not implemented for `std::sync::RwLockReadGuard<'_, ()>`
note: future is not `Send` as this value is used across an await
    --> /Users/ero/.cargo/git/checkouts/rust-lightning-da94c153801dff32/17eafed/lightning/src/ln/channelmanager.rs:5258:18
     |
5242 |         let _read_guard = self.total_consistency_lock.read().unwrap();
     |             ----------- has type `std::sync::RwLockReadGuard<'_, ()>` which is not `Send`
...
5258 |             handler(event).await;
     |                           ^^^^^^ await occurs here, with `_read_guard` maybe used later
...
5264 |     }
     |     - `_read_guard` is later dropped here
note: required by a bound in `tokio::runtime::Runtime::spawn`
    --> /Users/ero/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.23.0/src/runtime/runtime.rs:192:21
     |
192  |         F: Future + Send + 'static,
     |                     ^^^^ required by this bound in `tokio::runtime::Runtime::spawn`

In order to fix this, we need to explore options for replacing the RwLock of total_consistency_lock. One option might be taking a suitable dependency such as parking_lot, another approach would be to implement our own RwLock variant that meets the requirements.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions