Skip to content

Commit 8d9d07a

Browse files
committed
Removed Option<ExitStatus> member from fuchsia Process struct. Destroy launchpads and close handles in Drop impls rather than manually
1 parent 5c1c485 commit 8d9d07a

File tree

2 files changed

+45
-32
lines changed

2 files changed

+45
-32
lines changed

src/libstd/sys/unix/magenta.rs

+26
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,30 @@ pub const MX_INFO_PROCESS : mx_object_info_topic_t = 3;
4242

4343
pub const MX_HND_TYPE_JOB: u32 = 6;
4444

45+
// Safe wrapper around mx_handle_t
46+
pub struct Handle {
47+
raw: mx_handle_t,
48+
}
49+
50+
impl Handle {
51+
pub fn new(raw: mx_handle_t) -> Handle {
52+
Handle {
53+
raw: raw,
54+
}
55+
}
56+
57+
pub fn raw(&self) -> mx_handle_t {
58+
self.raw
59+
}
60+
}
61+
62+
impl Drop for Handle {
63+
fn drop(&mut self) {
64+
use sys::mx_cvt;
65+
unsafe { mx_cvt(mx_handle_close(self.raw)).expect("Failed to close mx_handle_t"); }
66+
}
67+
}
68+
4569
// Common MX_INFO header
4670
#[derive(Default)]
4771
#[repr(C)]
@@ -68,6 +92,8 @@ pub struct mx_info_process_t {
6892
}
6993

7094
extern {
95+
pub fn mx_task_kill(handle: mx_handle_t) -> mx_status_t;
96+
7197
pub fn mx_handle_close(handle: mx_handle_t) -> mx_status_t;
7298

7399
pub fn mx_handle_duplicate(handle: mx_handle_t, rights: mx_rights_t,

src/libstd/sys/unix/process/process_fuchsia.rs

+19-32
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use mem;
1414
use ptr;
1515

1616
use sys::mx_cvt;
17-
use sys::magenta::{launchpad_t, mx_handle_t};
17+
use sys::magenta::{Handle, launchpad_t, mx_handle_t};
1818
use sys::process::process_common::*;
1919

2020
////////////////////////////////////////////////////////////////////////////////
@@ -33,7 +33,7 @@ impl Command {
3333

3434
let (launchpad, process_handle) = unsafe { self.do_exec(theirs)? };
3535

36-
Ok((Process { launchpad: launchpad, handle: process_handle, status: None }, ours))
36+
Ok((Process { launchpad: launchpad, handle: Handle::new(process_handle) }, ours))
3737
}
3838

3939
pub fn exec(&mut self, default: Stdio) -> io::Error {
@@ -116,7 +116,7 @@ impl Command {
116116

117117
let process_handle = mx_cvt(launchpad_start(launchpad))?;
118118

119-
// Successfully started the launchpad, so launchpad_destroy shouldn't get called
119+
// Successfully started the launchpad
120120
mem::forget(launchpad_destructor);
121121

122122
Ok((launchpad, process_handle))
@@ -129,62 +129,49 @@ impl Command {
129129

130130
pub struct Process {
131131
launchpad: *mut launchpad_t,
132-
handle: mx_handle_t,
133-
status: Option<ExitStatus>,
132+
handle: Handle,
134133
}
135134

136135
impl Process {
137136
pub fn id(&self) -> u32 {
138-
self.handle as u32
137+
self.handle.raw() as u32
139138
}
140139

141140
pub fn kill(&mut self) -> io::Result<()> {
142141
use sys::magenta::*;
143142

144-
// If we've already waited on this process then the pid can be recycled
145-
// and used for another process, and we probably shouldn't be killing
146-
// random processes, so just return an error.
147-
if self.status.is_some() {
148-
Err(io::Error::new(io::ErrorKind::InvalidInput,
149-
"invalid argument: can't kill an exited process"))
150-
} else {
151-
unsafe {
152-
mx_cvt(mx_handle_close(self.handle))?;
153-
launchpad_destroy(self.launchpad);
154-
}
155-
Ok(())
156-
}
143+
unsafe { mx_cvt(mx_task_kill(self.handle.raw()))?; }
144+
145+
Ok(())
157146
}
158147

159148
pub fn wait(&mut self) -> io::Result<ExitStatus> {
160149
use default::Default;
161150
use sys::magenta::*;
162151

163-
if let Some(status) = self.status {
164-
return Ok(status)
165-
}
166-
167152
let mut proc_info: mx_info_process_t = Default::default();
168153
let mut actual: mx_size_t = 0;
169154
let mut avail: mx_size_t = 0;
170155

171156
unsafe {
172-
mx_cvt(mx_handle_wait_one(self.handle, MX_TASK_TERMINATED,
157+
mx_cvt(mx_handle_wait_one(self.handle.raw(), MX_TASK_TERMINATED,
173158
MX_TIME_INFINITE, ptr::null_mut()))?;
174-
mx_cvt(mx_object_get_info(self.handle, MX_INFO_PROCESS,
159+
mx_cvt(mx_object_get_info(self.handle.raw(), MX_INFO_PROCESS,
175160
&mut proc_info as *mut _ as *mut libc::c_void,
176161
mem::size_of::<mx_info_process_t>(), &mut actual,
177162
&mut avail))?;
178163
}
179164
if actual != 1 {
180-
return Err(io::Error::new(io::ErrorKind::InvalidInput,
181-
"Failed to get exit status of process"));
182-
}
183-
self.status = Some(ExitStatus::new(proc_info.rec.return_code));
184-
unsafe {
185-
mx_cvt(mx_handle_close(self.handle))?;
186-
launchpad_destroy(self.launchpad);
165+
return Err(io::Error::new(io::ErrorKind::InvalidData,
166+
"Failed to get exit status of process"));
187167
}
188168
Ok(ExitStatus::new(proc_info.rec.return_code))
189169
}
190170
}
171+
172+
impl Drop for Process {
173+
fn drop(&mut self) {
174+
use sys::magenta::launchpad_destroy;
175+
unsafe { launchpad_destroy(self.launchpad); }
176+
}
177+
}

0 commit comments

Comments
 (0)