fn optimistic_check(&mut self) -> bool {
// The optimistic check is never necessary for correctness. For testing
// purposes, making it randomly return false simulates a racing sender.
- use rand::{Rand, rng};
- let mut rng = rng();
- let actually_check = Rand::rand(&mut rng);
+ use rand::{Rand};
+ let actually_check = do Local::borrow::<Scheduler, bool> |sched| {
+ Rand::rand(&mut sched.rng)
+ };
if actually_check {
unsafe { (*self.packet()).state.load(Acquire) == STATE_ONE }
} else {
}
}
-impl<T> Select for Port<T> {
+// XXX: Kind of gross. A Port<T> should be selectable so you can make an array
+// of them, but a &Port<T> should also be selectable so you can select2 on it
+// alongside a PortOne<U> without passing the port by value in recv_ready.
+
+impl<'self, T> Select for &'self Port<T> {
#[inline]
fn optimistic_check(&mut self) -> bool {
do self.next.with_mut_ref |pone| { pone.optimistic_check() }
}
}
-impl<T> SelectPort<(T, Port<T>)> for Port<T> {
- fn recv_ready(self) -> Option<(T, Port<T>)> {
+impl<T> Select for Port<T> {
+ #[inline]
+ fn optimistic_check(&mut self) -> bool {
+ (&*self).optimistic_check()
+ }
+
+ #[inline]
+ fn block_on(&mut self, sched: &mut Scheduler, task: BlockedTask) -> bool {
+ (&*self).block_on(sched, task)
+ }
+
+ #[inline]
+ fn unblock_from(&mut self) -> bool {
+ (&*self).unblock_from()
+ }
+}
+
+impl<'self, T> SelectPort<T> for &'self Port<T> {
+ fn recv_ready(self) -> Option<T> {
match self.next.take().recv_ready() {
Some(StreamPayload { val, next }) => {
self.next.put_back(next);
- Some((val, self))
+ Some(val)
}
None => None
}
fn select_stream() {
use util;
use comm::GenericChan;
+ use iter::Times;
// Sends 10 buffered packets, and uses select to retrieve them all.
// Puts the port in a different spot in the vector each time.
// get it back out
util::swap(port.get_mut_ref(), &mut ports[index]);
// NB. Not recv(), because optimistic_check randomly fails.
- let (data, new_port) = port.take_unwrap().recv_ready().unwrap();
- assert!(data == 31337);
- port = Some(new_port);
+ assert!(port.get_ref().recv_ready().unwrap() == 31337);
}
}
}
fn select_racing_senders_helper(killable: bool, send_on_chans: ~[uint]) {
use rt::test::spawntask_random;
+ use iter::Times;
do run_in_newsched_task {
// A bit of stress, since ordinarily this is just smoke and mirrors.