3333
3434#[ allow( dead_code) ] ;
3535
36+ use std:: cast;
3637use std:: rt:: local:: Local ;
3738use std:: rt:: rtio:: LocalIo ;
3839use std:: rt:: task:: { Task , BlockedTask } ;
@@ -70,6 +71,17 @@ impl Clone for HomeHandle {
7071 }
7172}
7273
74+ pub fn local_id ( ) -> uint {
75+ let mut io = match LocalIo :: borrow ( ) {
76+ Some ( io) => io, None => return 0 ,
77+ } ;
78+ let io = io. get ( ) ;
79+ unsafe {
80+ let ( _vtable, ptr) : ( uint , uint ) = cast:: transmute ( io) ;
81+ return ptr;
82+ }
83+ }
84+
7385pub trait HomingIO {
7486 fn home < ' r > ( & ' r mut self ) -> & ' r mut HomeHandle ;
7587
@@ -79,35 +91,26 @@ pub trait HomingIO {
7991 fn go_to_IO_home ( & mut self ) -> uint {
8092 let _f = ForbidUnwind :: new ( "going home" ) ;
8193
82- let mut cur_task: ~Task = Local :: take ( ) ;
83- let cur_loop_id = {
84- let mut io = cur_task. local_io ( ) . expect ( "libuv must have I/O" ) ;
85- io. get ( ) . id ( )
86- } ;
94+ let cur_loop_id = local_id ( ) ;
95+ let destination = self . home ( ) . id ;
8796
8897 // Try at all costs to avoid the homing operation because it is quite
8998 // expensive. Hence, we only deschedule/send if we're not on the correct
9099 // event loop. If we're already on the home event loop, then we're good
91100 // to go (remember we have no preemption, so we're guaranteed to stay on
92101 // this event loop as long as we avoid the scheduler).
93- if cur_loop_id != self . home ( ) . id {
102+ if cur_loop_id != destination {
103+ let cur_task: ~Task = Local :: take ( ) ;
94104 cur_task. deschedule ( 1 , |task| {
95105 self . home ( ) . send ( task) ;
96106 Ok ( ( ) )
97107 } ) ;
98108
99109 // Once we wake up, assert that we're in the right location
100- let cur_loop_id = {
101- let mut io = LocalIo :: borrow ( ) . expect ( "libuv must have I/O" ) ;
102- io. get ( ) . id ( )
103- } ;
104- assert_eq ! ( cur_loop_id, self . home( ) . id) ;
105-
106- cur_loop_id
107- } else {
108- Local :: put ( cur_task) ;
109- cur_loop_id
110+ assert_eq ! ( local_id( ) , destination) ;
110111 }
112+
113+ return destination;
111114 }
112115
113116 /// Fires a single homing missile, returning another missile targeted back
@@ -130,8 +133,7 @@ impl HomingMissile {
130133 /// Check at runtime that the task has *not* transplanted itself to a
131134 /// different I/O loop while executing.
132135 pub fn check ( & self , msg : & ' static str ) {
133- let mut io = LocalIo :: borrow ( ) . expect ( "libuv must have I/O" ) ;
134- assert ! ( io. get( ) . id( ) == self . io_home, "{}" , msg) ;
136+ assert ! ( local_id( ) == self . io_home, "{}" , msg) ;
135137 }
136138}
137139
0 commit comments