Skip to content

Commit 53d29aa

Browse files
committed
---
yaml --- r: 61290 b: refs/heads/try c: 9138fea h: refs/heads/master v: v3
1 parent 56dc96a commit 53d29aa

File tree

2 files changed

+20
-51
lines changed

2 files changed

+20
-51
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2d28d645422c1617be58c8ca7ad9a457264ca850
5-
refs/heads/try: 91ca3a9b295404e6dc36677d415573935a9989db
5+
refs/heads/try: 9138feab1509e930a811d5b727e5cad61e369852
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libcore/rt/uv/mod.rs

Lines changed: 19 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -132,28 +132,38 @@ pub impl IdleWatcher {
132132
let handle = uvll::idle_new();
133133
assert!(handle.is_not_null());
134134
assert!(0 == uvll::idle_init(loop_.native_handle(), handle));
135-
uvll::set_data_for_uv_handle(handle, null::<()>());
136-
NativeHandle::from_native_handle(handle)
135+
let mut watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
136+
watcher.install_watcher_data();
137+
return watcher
137138
}
138139
}
139140

140141
fn start(&mut self, cb: IdleCallback) {
142+
{
143+
let data = self.get_watcher_data();
144+
data.idle_cb = Some(cb);
145+
}
141146

142-
self.set_callback(cb);
143147
unsafe {
144148
assert!(0 == uvll::idle_start(self.native_handle(), idle_cb))
145149
};
146150

147151
extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
148-
let idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
149-
let cb: &IdleCallback = idle_watcher.borrow_callback();
152+
let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
153+
let data = idle_watcher.get_watcher_data();
154+
let cb: &IdleCallback = data.idle_cb.get_ref();
150155
let status = status_to_maybe_uv_error(handle, status);
151156
(*cb)(idle_watcher, status);
152157
}
153158
}
154159

155160
fn stop(&mut self) {
156-
unsafe { assert!(0 == uvll::idle_stop(self.native_handle())); }
161+
// NB: Not resetting the Rust idl_cb to None here because `stop` is likely
162+
// called from *within* the idle callback, which would cause a use after free
163+
164+
unsafe {
165+
assert!(0 == uvll::idle_stop(self.native_handle()));
166+
}
157167
}
158168

159169
fn close(self) {
@@ -162,7 +172,7 @@ pub impl IdleWatcher {
162172
extern fn close_cb(handle: *uvll::uv_idle_t) {
163173
unsafe {
164174
let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
165-
idle_watcher.drop_callback::<IdleCallback>();
175+
idle_watcher.drop_watcher_data();
166176
uvll::idle_delete(handle);
167177
}
168178
}
@@ -185,13 +195,11 @@ struct WatcherData {
185195
connect_cb: Option<ConnectionCallback>,
186196
close_cb: Option<NullCallback>,
187197
alloc_cb: Option<AllocCallback>,
198+
idle_cb: Option<IdleCallback>
188199
}
189200

190201
pub trait WatcherInterop {
191202
fn event_loop(&self) -> Loop;
192-
fn set_callback<CB: Callback>(&mut self, cb: CB);
193-
fn drop_callback<CB: Callback>(&mut self);
194-
fn borrow_callback<CB: Callback>(&self) -> &CB;
195203
fn install_watcher_data(&mut self);
196204
fn get_watcher_data<'r>(&'r mut self) -> &'r mut WatcherData;
197205
fn drop_watcher_data(&mut self);
@@ -207,46 +215,6 @@ impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
207215
}
208216
}
209217

210-
/// Set the custom data on a handle to a callback Note: This is only
211-
/// suitable for watchers that make just one type of callback. For
212-
/// others use WatcherData
213-
pub fn set_callback<CB: Callback>(&mut self, cb: CB) {
214-
unsafe {
215-
self.drop_callback::<CB>();
216-
217-
// XXX: Boxing the callback so it fits into a
218-
// pointer. Unfortunate extra allocation
219-
let boxed_cb = ~cb;
220-
let data = transmute::<~CB, *c_void>(boxed_cb);
221-
uvll::set_data_for_uv_handle(self.native_handle(), data);
222-
}
223-
}
224-
225-
/// Delete a callback from a handle's custom data
226-
pub fn drop_callback<CB: Callback>(&mut self) {
227-
unsafe {
228-
let handle = self.native_handle();
229-
let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
230-
if handle_data.is_not_null() {
231-
// Take ownership of the callback and drop it
232-
let _cb = transmute::<*c_void, ~CB>(handle_data);
233-
// Make sure the pointer is zeroed
234-
uvll::set_data_for_uv_handle(self.native_handle(), null::<()>());
235-
}
236-
}
237-
}
238-
239-
/// Take a pointer to the callback installed as custom data
240-
pub fn borrow_callback<CB: Callback>(&self) -> &CB {
241-
unsafe {
242-
let handle = self.native_handle();
243-
let handle_data: *c_void = uvll::get_data_for_uv_handle(handle);
244-
assert!(handle_data.is_not_null());
245-
let cb = transmute::<&*c_void, &~CB>(&handle_data);
246-
return &**cb;
247-
}
248-
}
249-
250218
pub fn install_watcher_data(&mut self) {
251219
unsafe {
252220
let data = ~WatcherData {
@@ -255,6 +223,7 @@ impl<H, W: Watcher + NativeHandle<*H>> WatcherInterop for W {
255223
connect_cb: None,
256224
close_cb: None,
257225
alloc_cb: None,
226+
idle_cb: None
258227
};
259228
let data = transmute::<~WatcherData, *c_void>(data);
260229
uvll::set_data_for_uv_handle(self.native_handle(), data);

0 commit comments

Comments
 (0)