Skip to content

Commit 8e652c1

Browse files
committed
---
yaml --- r: 91595 b: refs/heads/auto c: ceab326 h: refs/heads/master i: 91593: aa7fa27 91591: 4044ea8 v: v3
1 parent 81214a3 commit 8e652c1

File tree

5 files changed

+116
-201
lines changed

5 files changed

+116
-201
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0
1313
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1414
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1515
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
16-
refs/heads/auto: 24b42234185427c5141b03103d8ce640538ba500
16+
refs/heads/auto: ceab326e82dfba2f3cd513926c023dea1af4b1c2
1717
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1818
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1919
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336

branches/auto/src/librustuv/lib.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ pub trait UvHandle<T> {
139139

140140
fn install(~self) -> ~Self {
141141
unsafe {
142-
let myptr = cast::transmute::<&~Self, *u8>(&self);
143-
uvll::set_data_for_uv_handle(self.uv_handle(), myptr);
142+
let myptr = cast::transmute::<&~Self, &*u8>(&self);
143+
uvll::set_data_for_uv_handle(self.uv_handle(), *myptr);
144144
}
145145
self
146146
}
@@ -188,9 +188,6 @@ pub type NullCallback = ~fn();
188188
pub type IdleCallback = ~fn(IdleWatcher, Option<UvError>);
189189
pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
190190
pub type FsCallback = ~fn(&mut FsRequest, Option<UvError>);
191-
// first int is exit_status, second is term_signal
192-
pub type ExitCallback = ~fn(Process, int, int, Option<UvError>);
193-
pub type TimerCallback = ~fn(TimerWatcher, Option<UvError>);
194191
pub type AsyncCallback = ~fn(AsyncWatcher, Option<UvError>);
195192
pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, SocketAddr, uint, Option<UvError>);
196193
pub type UdpSendCallback = ~fn(UdpWatcher, Option<UvError>);
@@ -206,11 +203,9 @@ struct WatcherData {
206203
close_cb: Option<NullCallback>,
207204
alloc_cb: Option<AllocCallback>,
208205
idle_cb: Option<IdleCallback>,
209-
timer_cb: Option<TimerCallback>,
210206
async_cb: Option<AsyncCallback>,
211207
udp_recv_cb: Option<UdpReceiveCallback>,
212208
udp_send_cb: Option<UdpSendCallback>,
213-
exit_cb: Option<ExitCallback>,
214209
signal_cb: Option<SignalCallback>,
215210
}
216211

@@ -242,11 +237,9 @@ impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
242237
close_cb: None,
243238
alloc_cb: None,
244239
idle_cb: None,
245-
timer_cb: None,
246240
async_cb: None,
247241
udp_recv_cb: None,
248242
udp_send_cb: None,
249-
exit_cb: None,
250243
signal_cb: None,
251244
};
252245
let data = transmute::<~WatcherData, *c_void>(data);

branches/auto/src/librustuv/process.rs

Lines changed: 105 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,58 +9,42 @@
99
// except according to those terms.
1010

1111
use std::cell::Cell;
12+
use std::libc::c_int;
1213
use std::libc;
1314
use std::ptr;
14-
use std::vec;
15+
use std::rt::BlockedTask;
16+
use std::rt::io::IoError;
1517
use std::rt::io::process::*;
18+
use std::rt::local::Local;
19+
use std::rt::rtio::RtioProcess;
20+
use std::rt::sched::{Scheduler, SchedHandle};
21+
use std::vec;
1622

17-
use super::{Watcher, Loop, NativeHandle, UvError};
18-
use super::{status_to_maybe_uv_error, ExitCallback};
19-
use uvio::{UvPipeStream, UvUnboundPipe};
23+
use super::{Loop, NativeHandle, UvHandle, UvError, uv_error_to_io_error};
24+
use uvio::{HomingIO, UvPipeStream, UvUnboundPipe};
2025
use uvll;
2126

22-
/// A process wraps the handle of the underlying uv_process_t.
23-
pub struct Process(*uvll::uv_process_t);
27+
pub struct Process {
28+
handle: *uvll::uv_process_t,
29+
home: SchedHandle,
2430

25-
impl Watcher for Process {}
31+
/// Task to wake up (may be null) for when the process exits
32+
to_wake: Option<BlockedTask>,
2633

27-
impl Process {
28-
/// Creates a new process, ready to spawn inside an event loop
29-
pub fn new() -> Process {
30-
let handle = unsafe { uvll::malloc_handle(uvll::UV_PROCESS) };
31-
assert!(handle.is_not_null());
32-
let mut ret: Process = NativeHandle::from_native_handle(handle);
33-
ret.install_watcher_data();
34-
return ret;
35-
}
34+
/// Collected from the exit_cb
35+
exit_status: Option<int>,
36+
term_signal: Option<int>,
37+
}
3638

39+
impl Process {
3740
/// Spawn a new process inside the specified event loop.
3841
///
39-
/// The `config` variable will be passed down to libuv, and the `exit_cb`
40-
/// will be run only once, when the process exits.
41-
///
4242
/// Returns either the corresponding process object or an error which
4343
/// occurred.
44-
pub fn spawn(&mut self, loop_: &Loop, config: ProcessConfig,
45-
exit_cb: ExitCallback)
46-
-> Result<~[Option<~UvPipeStream>], UvError>
44+
pub fn spawn(loop_: &Loop, config: ProcessConfig)
45+
-> Result<(~Process, ~[Option<~UvPipeStream>]), UvError>
4746
{
4847
let cwd = config.cwd.map(|s| s.to_c_str());
49-
50-
extern fn on_exit(p: *uvll::uv_process_t,
51-
exit_status: libc::c_int,
52-
term_signal: libc::c_int) {
53-
let mut p: Process = NativeHandle::from_native_handle(p);
54-
let err = match exit_status {
55-
0 => None,
56-
_ => status_to_maybe_uv_error(-1)
57-
};
58-
p.get_watcher_data().exit_cb.take_unwrap()(p,
59-
exit_status as int,
60-
term_signal as int,
61-
err);
62-
}
63-
6448
let io = config.io;
6549
let mut stdio = vec::with_capacity::<uvll::uv_stdio_container_t>(io.len());
6650
let mut ret_io = vec::with_capacity(io.len());
@@ -73,7 +57,6 @@ impl Process {
7357
}
7458
}
7559

76-
let exit_cb = Cell::new(exit_cb);
7760
let ret_io = Cell::new(ret_io);
7861
do with_argv(config.program, config.args) |argv| {
7962
do with_env(config.env) |envp| {
@@ -93,34 +76,47 @@ impl Process {
9376
gid: 0,
9477
};
9578

79+
let handle = UvHandle::alloc(None::<Process>, uvll::UV_PROCESS);
9680
match unsafe {
97-
uvll::uv_spawn(loop_.native_handle(), **self, options)
81+
uvll::uv_spawn(loop_.native_handle(), handle, options)
9882
} {
9983
0 => {
100-
(*self).get_watcher_data().exit_cb = Some(exit_cb.take());
101-
Ok(ret_io.take())
84+
let process = ~Process {
85+
handle: handle,
86+
home: get_handle_to_current_scheduler!(),
87+
to_wake: None,
88+
exit_status: None,
89+
term_signal: None,
90+
};
91+
Ok((process.install(), ret_io.take()))
92+
}
93+
err => {
94+
unsafe { uvll::free_handle(handle) }
95+
Err(UvError(err))
10296
}
103-
err => Err(UvError(err))
10497
}
10598
}
10699
}
107100
}
101+
}
108102

109-
/// Sends a signal to this process.
110-
///
111-
/// This is a wrapper around `uv_process_kill`
112-
pub fn kill(&self, signum: int) -> Result<(), UvError> {
113-
match unsafe {
114-
uvll::uv_process_kill(self.native_handle(), signum as libc::c_int)
115-
} {
116-
0 => Ok(()),
117-
err => Err(UvError(err))
103+
extern fn on_exit(handle: *uvll::uv_process_t,
104+
exit_status: libc::c_int,
105+
term_signal: libc::c_int) {
106+
let handle = handle as *uvll::uv_handle_t;
107+
let p: &mut Process = unsafe { UvHandle::from_uv_handle(&handle) };
108+
109+
assert!(p.exit_status.is_none());
110+
assert!(p.term_signal.is_none());
111+
p.exit_status = Some(exit_status as int);
112+
p.term_signal = Some(term_signal as int);
113+
114+
match p.to_wake.take() {
115+
Some(task) => {
116+
let scheduler: ~Scheduler = Local::take();
117+
scheduler.resume_blocked_task_immediately(task);
118118
}
119-
}
120-
121-
/// Returns the process id of a spawned process
122-
pub fn pid(&self) -> libc::pid_t {
123-
unsafe { uvll::process_pid(**self) as libc::pid_t }
119+
None => {}
124120
}
125121
}
126122

@@ -192,11 +188,59 @@ fn with_env<T>(env: Option<&[(~str, ~str)]>, f: &fn(**libc::c_char) -> T) -> T {
192188
c_envp.as_imm_buf(|buf, _| f(buf))
193189
}
194190

195-
impl NativeHandle<*uvll::uv_process_t> for Process {
196-
fn from_native_handle(handle: *uvll::uv_process_t) -> Process {
197-
Process(handle)
191+
impl HomingIO for Process {
192+
fn home<'r>(&'r mut self) -> &'r mut SchedHandle { &mut self.home }
193+
}
194+
195+
impl UvHandle<uvll::uv_process_t> for Process {
196+
fn uv_handle(&self) -> *uvll::uv_process_t { self.handle }
197+
}
198+
199+
impl RtioProcess for Process {
200+
fn id(&self) -> libc::pid_t {
201+
unsafe { uvll::process_pid(self.handle) as libc::pid_t }
202+
}
203+
204+
fn kill(&mut self, signal: int) -> Result<(), IoError> {
205+
do self.home_for_io |self_| {
206+
match unsafe {
207+
uvll::process_kill(self_.handle, signal as libc::c_int)
208+
} {
209+
0 => Ok(()),
210+
err => Err(uv_error_to_io_error(UvError(err)))
211+
}
212+
}
213+
}
214+
215+
fn wait(&mut self) -> int {
216+
// Make sure (on the home scheduler) that we have an exit status listed
217+
do self.home_for_io |self_| {
218+
match self_.exit_status {
219+
Some(*) => {}
220+
None => {
221+
// If there's no exit code previously listed, then the
222+
// process's exit callback has yet to be invoked. We just
223+
// need to deschedule ourselves and wait to be reawoken.
224+
let scheduler: ~Scheduler = Local::take();
225+
do scheduler.deschedule_running_task_and_then |_, task| {
226+
assert!(self_.to_wake.is_none());
227+
self_.to_wake = Some(task);
228+
}
229+
assert!(self_.exit_status.is_some());
230+
}
231+
}
232+
}
233+
234+
// FIXME(#10109): this is wrong
235+
self.exit_status.unwrap()
198236
}
199-
fn native_handle(&self) -> *uvll::uv_process_t {
200-
match self { &Process(ptr) => ptr }
237+
}
238+
239+
impl Drop for Process {
240+
fn drop(&mut self) {
241+
do self.home_for_io |self_| {
242+
assert!(self_.to_wake.is_none());
243+
self_.close_async_();
244+
}
201245
}
202246
}

branches/auto/src/librustuv/timer.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,17 @@ impl RtioTimer for TimerWatcher {
103103

104104
extern fn timer_cb(handle: *uvll::uv_timer_t, _status: c_int) {
105105
let handle = handle as *uvll::uv_handle_t;
106-
let foo: &mut TimerWatcher = unsafe { UvHandle::from_uv_handle(&handle) };
106+
let timer : &mut TimerWatcher = unsafe { UvHandle::from_uv_handle(&handle) };
107107

108-
match foo.action.take_unwrap() {
108+
match timer.action.take_unwrap() {
109109
WakeTask(task) => {
110110
let sched: ~Scheduler = Local::take();
111111
sched.resume_blocked_task_immediately(task);
112112
}
113113
SendOnce(chan) => chan.send(()),
114114
SendMany(chan) => {
115115
chan.send(());
116-
foo.action = Some(SendMany(chan));
116+
timer.action = Some(SendMany(chan));
117117
}
118118
}
119119
}

0 commit comments

Comments
 (0)