Assert recycler is given last reference to data

This patch likely fixes the sporadic failures in the following tests:

```
test server::tests::validator_exit ... FAILED
test streamer::test::streamer_send_test ... FAILED
test thin_client::tests::test_bad_sig ... FAILED
test drone::tests::test_send_airdrop ... FAILED
test thin_client::tests::test_thin_client ... FAILED
```
This commit is contained in:
Greg Fitzgerald
2018-06-25 17:13:26 -06:00
committed by Greg Fitzgerald
parent a5ce578c72
commit 1691060a22
3 changed files with 13 additions and 15 deletions

View File

@ -64,10 +64,7 @@ mod tests {
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
#[test] #[test]
#[ignore]
// test that stage will exit when flag is set // test that stage will exit when flag is set
// TODO: Troubleshoot Docker-based coverage build and re-enabled
// this test. It is probably failing due to too many threads.
fn test_exit() { fn test_exit() {
let exit = Arc::new(AtomicBool::new(false)); let exit = Arc::new(AtomicBool::new(false));
let tn = TestNode::new(); let tn = TestNode::new();

View File

@ -166,6 +166,7 @@ impl<T: Default> Recycler<T> {
.unwrap_or_else(|| Arc::new(RwLock::new(Default::default()))) .unwrap_or_else(|| Arc::new(RwLock::new(Default::default())))
} }
pub fn recycle(&self, msgs: Arc<RwLock<T>>) { pub fn recycle(&self, msgs: Arc<RwLock<T>>) {
assert_eq!(Arc::strong_count(&msgs), 1); // Ensure this function holds that last reference.
let mut gc = self.gc.lock().expect("recycler lock in pub fn recycle"); let mut gc = self.gc.lock().expect("recycler lock in pub fn recycle");
gc.push(msgs); gc.push(msgs);
} }

View File

@ -29,19 +29,18 @@ fn recv_loop(
) -> Result<()> { ) -> Result<()> {
loop { loop {
let msgs = re.allocate(); let msgs = re.allocate();
let msgs_ = msgs.clone();
loop { loop {
match msgs.write() let result = msgs.write()
.expect("write lock in fn recv_loop") .expect("write lock in fn recv_loop")
.recv_from(sock) .recv_from(sock);
{ match result {
Ok(()) => { Ok(()) => {
channel.send(msgs_)?; channel.send(msgs)?;
break; break;
} }
Err(_) => { Err(_) => {
if exit.load(Ordering::Relaxed) { if exit.load(Ordering::Relaxed) {
re.recycle(msgs_); re.recycle(msgs);
return Ok(()); return Ok(());
} }
} }
@ -760,12 +759,13 @@ mod test {
let mut msgs = VecDeque::new(); let mut msgs = VecDeque::new();
for i in 0..10 { for i in 0..10 {
let b = resp_recycler.allocate(); let b = resp_recycler.allocate();
let b_ = b.clone(); {
let mut w = b.write().unwrap(); let mut w = b.write().unwrap();
w.data[0] = i as u8; w.data[0] = i as u8;
w.meta.size = PACKET_DATA_SIZE; w.meta.size = PACKET_DATA_SIZE;
w.meta.set_addr(&addr); w.meta.set_addr(&addr);
msgs.push_back(b_); }
msgs.push_back(b);
} }
s_responder.send(msgs).expect("send"); s_responder.send(msgs).expect("send");
let mut num = 0; let mut num = 0;