Skip to content

Commit b47ff23

Browse files
committed
green: Move a scheduler test inside libgreen
This test also had a race condition in using the cvar/lock, so I fixed that up as well. The race originated from one half trying to destroy the lock when another half was using it.
1 parent 7f48345 commit b47ff23

File tree

2 files changed

+72
-61
lines changed

2 files changed

+72
-61
lines changed

src/libgreen/sched.rs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ mod test {
957957
use std::rt::local::Local;
958958

959959
use basic;
960-
use sched::TaskFromFriend;
960+
use sched::{TaskFromFriend, PinnedTask};
961961
use task::{GreenTask, HomeSched};
962962
use PoolConfig;
963963
use SchedPool;
@@ -1406,4 +1406,75 @@ mod test {
14061406
5.times(deschedule);
14071407
}
14081408
}
1409+
1410+
#[test]
1411+
fn test_spawn_sched_blocking() {
1412+
use std::unstable::mutex::Mutex;
1413+
1414+
// Testing that a task in one scheduler can block in foreign code
1415+
// without affecting other schedulers
1416+
for _ in range(0, 20) {
1417+
let mut pool = pool();
1418+
let (start_po, start_ch) = Chan::new();
1419+
let (fin_po, fin_ch) = Chan::new();
1420+
1421+
let lock = unsafe { Mutex::new() };
1422+
let lock2 = unsafe { lock.clone() };
1423+
1424+
let mut handle = pool.spawn_sched();
1425+
handle.send(PinnedTask(pool.task(TaskOpts::new(), proc() {
1426+
let mut lock = lock2;
1427+
unsafe {
1428+
lock.lock();
1429+
1430+
start_ch.send(());
1431+
lock.wait(); // block the scheduler thread
1432+
lock.signal(); // let them know we have the lock
1433+
lock.unlock();
1434+
}
1435+
1436+
fin_ch.send(());
1437+
})));
1438+
drop(handle);
1439+
1440+
let mut handle = pool.spawn_sched();
1441+
handle.send(TaskFromFriend(pool.task(TaskOpts::new(), proc() {
1442+
// Wait until the other task has its lock
1443+
start_po.recv();
1444+
1445+
fn pingpong(po: &Port<int>, ch: &Chan<int>) {
1446+
let mut val = 20;
1447+
while val > 0 {
1448+
val = po.recv();
1449+
ch.try_send(val - 1);
1450+
}
1451+
}
1452+
1453+
let (setup_po, setup_ch) = Chan::new();
1454+
let (parent_po, parent_ch) = Chan::new();
1455+
do spawn {
1456+
let (child_po, child_ch) = Chan::new();
1457+
setup_ch.send(child_ch);
1458+
pingpong(&child_po, &parent_ch);
1459+
};
1460+
1461+
let child_ch = setup_po.recv();
1462+
child_ch.send(20);
1463+
pingpong(&parent_po, &child_ch);
1464+
unsafe {
1465+
let mut lock = lock;
1466+
lock.lock();
1467+
lock.signal(); // wakeup waiting scheduler
1468+
lock.wait(); // wait for them to grab the lock
1469+
lock.unlock();
1470+
lock.destroy(); // now we're guaranteed they have no locks
1471+
}
1472+
})));
1473+
drop(handle);
1474+
1475+
fin_po.recv();
1476+
pool.shutdown();
1477+
}
1478+
1479+
}
14091480
}

src/libstd/task.rs

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -529,66 +529,6 @@ fn test_spawn_sched_childs_on_default_sched() {
529529
po.recv();
530530
}
531531
532-
#[test]
533-
fn test_spawn_sched_blocking() {
534-
use unstable::mutex::Mutex;
535-
use num::Times;
536-
537-
unsafe {
538-
539-
// Testing that a task in one scheduler can block in foreign code
540-
// without affecting other schedulers
541-
20u.times(|| {
542-
let (start_po, start_ch) = Chan::new();
543-
let (fin_po, fin_ch) = Chan::new();
544-
545-
let mut lock = Mutex::new();
546-
let lock2 = lock.clone();
547-
548-
do spawn {
549-
let mut lock = lock2;
550-
lock.lock();
551-
552-
start_ch.send(());
553-
554-
// Block the scheduler thread
555-
lock.wait();
556-
lock.unlock();
557-
558-
fin_ch.send(());
559-
};
560-
561-
// Wait until the other task has its lock
562-
start_po.recv();
563-
564-
fn pingpong(po: &Port<int>, ch: &Chan<int>) {
565-
let mut val = 20;
566-
while val > 0 {
567-
val = po.recv();
568-
ch.try_send(val - 1);
569-
}
570-
}
571-
572-
let (setup_po, setup_ch) = Chan::new();
573-
let (parent_po, parent_ch) = Chan::new();
574-
do spawn {
575-
let (child_po, child_ch) = Chan::new();
576-
setup_ch.send(child_ch);
577-
pingpong(&child_po, &parent_ch);
578-
};
579-
580-
let child_ch = setup_po.recv();
581-
child_ch.send(20);
582-
pingpong(&parent_po, &child_ch);
583-
lock.lock();
584-
lock.signal();
585-
lock.unlock();
586-
fin_po.recv();
587-
lock.destroy();
588-
})
589-
}
590-
}
591-
592532
#[cfg(test)]
593533
fn avoid_copying_the_body(spawnfn: |v: proc()|) {
594534
let (p, ch) = Chan::<uint>::new();

0 commit comments

Comments
 (0)