I've narrowed this as much as I can. I have a vector of references to Senders
and want to process them after receive()
has completed running. However I'm running into a lifetime management issue. The inner struct is Mutex
protected and contains the Senders
that I'm trying to reference. I use the Mutex to gain mutability of the data, I'm open to alternatives. Any suggestions on how to work around this? I'd prefer not to change the signature of receive().
use std::sync::Mutex;
use std::sync::mpsc;
#[derive(Default)]
struct SaveForLater<'a> {
queue: Vec<(&'a mpsc::Sender<usize>, usize)>,
}
impl<'a> SaveForLater<'a> {
fn send(&mut self, channel: &'a mpsc::Sender<usize>, value: usize) {
self.queue.push((channel, value));
}
}
#[derive(Default)]
struct Forwarder {
data: Mutex<ForwarderData>,
}
#[derive(Default)]
struct ForwarderData {
senders: Vec<mpsc::Sender<usize>>,
}
impl Forwarder {
fn with_capacity(capacity: usize) -> Self {
let mut senders = Vec::new();
for _ in 0..capacity {
let (s,r) = mpsc::channel();
senders.push(s);
}
let data = ForwarderData { senders };
let data = Mutex::new(data);
Self { data }
}
fn receive<'a>(&'a self, value: usize, sender: &mut SaveForLater<'a>) {
match value {
0 => { self.data.lock().unwrap().senders.drain(..); },
_ => {
let data = self.data.lock().unwrap();
sender.send(&data.senders[0], value); },
/*
error[E0597]: `data` does not live long enough
--> src/main.rs:40:30
|
35 | fn receive<'a>(&'a self, value: usize, sender: &mut SaveForLater<'a>) {
| -- lifetime `'a` defined here
...
40 | sender.send(&data.senders[0], value); },
| -------------^^^^------------------- - `data` dropped here while still borrowed
| | |
| | borrowed value does not live long enough
| argument requires that `data` is borrowed for `'a`
*/
}
}
}
fn main() {
let fwd = Forwarder::with_capacity(3);
{
let mut sender = SaveForLater::default();
let value: usize = 42;
fwd.receive(value, &mut sender);
for (s,v) in sender.queue {
s.send(v);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_main() {
main();
}
}
see error in playground