Skip to content

Commit ca63fdb

Browse files
author
bors-servo
authored
Auto merge of #95 - asajeffrey:master, r=pcwalton
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.
2 parents 65d8404 + 3a06775 commit ca63fdb

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/test.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use ipc::{self, IpcReceiver, IpcReceiverSet, IpcSender, IpcSharedMemory};
1111
use ipc::{OpaqueIpcSender};
1212
use router::ROUTER;
1313
use libc;
14+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
15+
use std::cell::RefCell;
1416
use std::iter;
1517
use std::ptr;
1618
use std::sync::Arc;
@@ -19,6 +21,7 @@ use std::thread;
1921

2022
#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
2123
use ipc::IpcOneShotServer;
24+
2225
#[cfg(not(any(feature = "force-inprocess", target_os = "windows", target_os = "android")))]
2326
use std::io::Error;
2427

@@ -386,3 +389,40 @@ fn test_so_linger() {
386389
};
387390
assert_eq!(val, 42);
388391
}
392+
393+
#[derive(Clone, Debug, Eq, PartialEq)]
394+
struct HasWeirdSerializer (Option<String>);
395+
396+
thread_local! { static WEIRD_CHANNEL: RefCell<Option<IpcSender<HasWeirdSerializer>>> = RefCell::new(None) }
397+
398+
impl Serialize for HasWeirdSerializer {
399+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
400+
where S: Serializer
401+
{
402+
if self.0.is_some() {
403+
WEIRD_CHANNEL.with(|chan| { chan.borrow().as_ref().unwrap().send(HasWeirdSerializer(None)).unwrap(); });
404+
}
405+
self.0.serialize(serializer)
406+
}
407+
}
408+
409+
impl Deserialize for HasWeirdSerializer {
410+
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
411+
where D: Deserializer
412+
{
413+
Ok(HasWeirdSerializer(try!(Deserialize::deserialize(deserializer))))
414+
}
415+
}
416+
417+
#[test]
418+
fn test_reentrant() {
419+
let null = HasWeirdSerializer(None);
420+
let hello = HasWeirdSerializer(Some(String::from("hello")));
421+
let (sender, receiver) = ipc::channel().unwrap();
422+
WEIRD_CHANNEL.with(|chan| { *chan.borrow_mut() = Some(sender.clone()); });
423+
sender.send(hello.clone()).unwrap();
424+
assert_eq!(null, receiver.recv().unwrap());
425+
assert_eq!(hello, receiver.recv().unwrap());
426+
sender.send(null.clone()).unwrap();
427+
assert_eq!(null, receiver.recv().unwrap());
428+
}

0 commit comments

Comments
 (0)