Skip to content

Commit

Permalink
Auto merge of #95 - asajeffrey:master, r=pcwalton
Browse files Browse the repository at this point in the history
Added unit test for reentrancy.

IPC channels are reentrant, in that if we call `c.send(a)` and serializing `a` calls `c.send(b)`, then the channel contents are `b` then `a`. (This comes up in the case of logging over channels, since serialization may include logging.)

This PR adds a unit test to make sure we don't break reentrancy.

Discussion with @nox on IRC.
  • Loading branch information
bors-servo authored Sep 5, 2016
2 parents 65d8404 + 3a06775 commit ca63fdb
Showing 1 changed file with 40 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use ipc::{self, IpcReceiver, IpcReceiverSet, IpcSender, IpcSharedMemory};
use ipc::{OpaqueIpcSender};
use router::ROUTER;
use libc;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::cell::RefCell;
use std::iter;
use std::ptr;
use std::sync::Arc;
Expand All @@ -19,6 +21,7 @@ use std::thread;

#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
use ipc::IpcOneShotServer;

#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
use std::io::Error;

Expand Down Expand Up @@ -386,3 +389,40 @@ fn test_so_linger() {
};
assert_eq!(val, 42);
}

#[derive(Clone, Debug, Eq, PartialEq)]
struct HasWeirdSerializer (Option<String>);

thread_local! { static WEIRD_CHANNEL: RefCell<Option<IpcSender<HasWeirdSerializer>>> = RefCell::new(None) }

impl Serialize for HasWeirdSerializer {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer
{
if self.0.is_some() {
WEIRD_CHANNEL.with(|chan| { chan.borrow().as_ref().unwrap().send(HasWeirdSerializer(None)).unwrap(); });
}
self.0.serialize(serializer)
}
}

impl Deserialize for HasWeirdSerializer {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer
{
Ok(HasWeirdSerializer(try!(Deserialize::deserialize(deserializer))))
}
}

#[test]
fn test_reentrant() {
let null = HasWeirdSerializer(None);
let hello = HasWeirdSerializer(Some(String::from("hello")));
let (sender, receiver) = ipc::channel().unwrap();
WEIRD_CHANNEL.with(|chan| { *chan.borrow_mut() = Some(sender.clone()); });
sender.send(hello.clone()).unwrap();
assert_eq!(null, receiver.recv().unwrap());
assert_eq!(hello, receiver.recv().unwrap());
sender.send(null.clone()).unwrap();
assert_eq!(null, receiver.recv().unwrap());
}

0 comments on commit ca63fdb

Please sign in to comment.