Add a C-bindings-compatible read lock type for NetworkGraph 2020-08-c-bindings-cleanups-3
authorMatt Corallo <git@bluematt.me>
Mon, 24 Aug 2020 18:14:05 +0000 (14:14 -0400)
committerMatt Corallo <git@bluematt.me>
Wed, 26 Aug 2020 01:26:51 +0000 (21:26 -0400)
In order to calculate a route, it is likely that users need to take
a read()-lock on NetGraphMsgHandler::network_graph. This is not
possible naively from C bindings, as Rust's native RwLock is not
exposed.

Thus, we provide a simple wrapper around the RwLockReadGuard and
expose simple accessor methods.

lightning/src/routing/network_graph.rs

index 44f2ed237bf9ef9730ed5c8a0ea9da7db133a1fc..c46781d11b5888b8e0f55114a525db4ea0908a75 100644 (file)
@@ -27,7 +27,7 @@ use util::ser::{Writeable, Readable, Writer};
 use util::logger::Logger;
 
 use std::{cmp, fmt};
-use std::sync::RwLock;
+use std::sync::{RwLock, RwLockReadGuard};
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::collections::BTreeMap;
 use std::collections::btree_map::Entry as BtreeEntry;
@@ -41,6 +41,11 @@ pub struct NetworkGraph {
        nodes: BTreeMap<PublicKey, NodeInfo>,
 }
 
+/// A simple newtype for RwLockReadGuard<'a, NetworkGraph>.
+/// This exists only to make accessing a RwLock<NetworkGraph> possible from
+/// the C bindings, as it can be done directly in Rust code.
+pub struct LockedNetworkGraph<'a>(pub RwLockReadGuard<'a, NetworkGraph>);
+
 /// Receives and validates network updates from peers,
 /// stores authentic and relevant data as a network graph.
 /// This network graph is then used for routing payments.
@@ -85,6 +90,21 @@ impl<C: Deref, L: Deref> NetGraphMsgHandler<C, L> where C::Target: ChainWatchInt
                        logger,
                }
        }
+
+       /// Take a read lock on the network_graph and return it in the C-bindings
+       /// newtype helper. This is likely only useful when called via the C
+       /// bindings as you can call `self.network_graph.read().unwrap()` in Rust
+       /// yourself.
+       pub fn read_locked_graph<'a>(&'a self) -> LockedNetworkGraph<'a> {
+               LockedNetworkGraph(self.network_graph.read().unwrap())
+       }
+}
+
+impl<'a> LockedNetworkGraph<'a> {
+       /// Get a reference to the NetworkGraph which this read-lock contains.
+       pub fn graph(&self) -> &NetworkGraph {
+               &*self.0
+       }
 }