Skip to content

Commit 9d834c9

Browse files
committed
---
yaml --- r: 61306 b: refs/heads/try c: ee0ce64 h: refs/heads/master v: v3
1 parent 1f12d1b commit 9d834c9

File tree

4 files changed

+61
-25
lines changed

4 files changed

+61
-25
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: 204e3d82ccf5015e39f847aafea148d5180ab951
5+
refs/heads/try: ee0ce64d9db10aebc491454b6595d6edf69fe513
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use libc::c_int;
1212
use option::Some;
1313
use rt::uv::uvll;
14-
use rt::uv::{Watcher, Loop, NativeHandle, IdleCallback};
14+
use rt::uv::{Watcher, Loop, NativeHandle, IdleCallback, NullCallback};
1515
use rt::uv::status_to_maybe_uv_error;
1616

1717
pub struct IdleWatcher(*uvll::uv_idle_t);
@@ -57,12 +57,23 @@ pub impl IdleWatcher {
5757
}
5858
}
5959

60-
fn close(self) {
60+
fn close(self, cb: NullCallback) {
61+
{
62+
let mut this = self;
63+
let data = this.get_watcher_data();
64+
assert!(data.close_cb.is_none());
65+
data.close_cb = Some(cb);
66+
}
67+
6168
unsafe { uvll::close(self.native_handle(), close_cb) };
6269

6370
extern fn close_cb(handle: *uvll::uv_idle_t) {
6471
unsafe {
6572
let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
73+
{
74+
let mut data = idle_watcher.get_watcher_data();
75+
data.close_cb.swap_unwrap()();
76+
}
6677
idle_watcher.drop_watcher_data();
6778
uvll::idle_delete(handle);
6879
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ fn idle_new_then_close() {
356356
do run_in_bare_thread {
357357
let mut loop_ = Loop::new();
358358
let idle_watcher = { IdleWatcher::new(&mut loop_) };
359-
idle_watcher.close();
359+
idle_watcher.close(||());
360360
}
361361
}
362362

@@ -372,7 +372,7 @@ fn idle_smoke_test() {
372372
assert!(status.is_none());
373373
if unsafe { *count_ptr == 10 } {
374374
idle_watcher.stop();
375-
idle_watcher.close();
375+
idle_watcher.close(||());
376376
} else {
377377
unsafe { *count_ptr = *count_ptr + 1; }
378378
}
@@ -396,7 +396,7 @@ fn idle_start_stop_start() {
396396
assert!(status.is_none());
397397
let mut idle_watcher = idle_watcher;
398398
idle_watcher.stop();
399-
idle_watcher.close();
399+
idle_watcher.close(||());
400400
}
401401
}
402402
loop_.run();

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

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl EventLoop for UvEventLoop {
6666
assert!(status.is_none());
6767
let mut idle_watcher = idle_watcher;
6868
idle_watcher.stop();
69-
idle_watcher.close();
69+
idle_watcher.close(||());
7070
f();
7171
}
7272
}
@@ -124,22 +124,26 @@ impl IoFactory for UvIoFactory {
124124
// Wait for a connection
125125
do tcp_watcher.connect(addr) |stream_watcher, status| {
126126
rtdebug!("connect: in connect callback");
127-
let maybe_stream = if status.is_none() {
127+
if status.is_none() {
128128
rtdebug!("status is none");
129-
Ok(~UvTcpStream { watcher: stream_watcher })
129+
let res = Ok(~UvTcpStream { watcher: stream_watcher });
130+
131+
// Store the stream in the task's stack
132+
unsafe { (*result_cell_ptr).put_back(res); }
133+
134+
// Context switch
135+
let scheduler = local_sched::take();
136+
scheduler.resume_task_immediately(task_cell.take());
130137
} else {
131138
rtdebug!("status is some");
132-
// XXX: Wait for close
133-
stream_watcher.close(||());
134-
Err(uv_error_to_io_error(status.get()))
139+
let task_cell = Cell(task_cell.take());
140+
do stream_watcher.close {
141+
let res = Err(uv_error_to_io_error(status.get()));
142+
unsafe { (*result_cell_ptr).put_back(res); }
143+
let scheduler = local_sched::take();
144+
scheduler.resume_task_immediately(task_cell.take());
145+
}
135146
};
136-
137-
// Store the stream in the task's stack
138-
unsafe { (*result_cell_ptr).put_back(maybe_stream); }
139-
140-
// Context switch
141-
let scheduler = local_sched::take();
142-
scheduler.resume_task_immediately(task_cell.take());
143147
}
144148
}
145149

@@ -152,8 +156,14 @@ impl IoFactory for UvIoFactory {
152156
match watcher.bind(addr) {
153157
Ok(_) => Ok(~UvTcpListener::new(watcher)),
154158
Err(uverr) => {
155-
// XXX: Should we wait until close completes?
156-
watcher.as_stream().close(||());
159+
let scheduler = local_sched::take();
160+
do scheduler.deschedule_running_task_and_then |task| {
161+
let task_cell = Cell(task);
162+
do watcher.as_stream().close {
163+
let scheduler = local_sched::take();
164+
scheduler.resume_task_immediately(task_cell.take());
165+
}
166+
}
157167
Err(uv_error_to_io_error(uverr))
158168
}
159169
}
@@ -181,8 +191,15 @@ impl UvTcpListener {
181191

182192
impl Drop for UvTcpListener {
183193
fn finalize(&self) {
184-
// XXX: Need to wait until close finishes before returning
185-
self.watcher().as_stream().close(||());
194+
let watcher = self.watcher();
195+
let scheduler = local_sched::take();
196+
do scheduler.deschedule_running_task_and_then |task| {
197+
let task_cell = Cell(task);
198+
do watcher.as_stream().close {
199+
let scheduler = local_sched::take();
200+
scheduler.resume_task_immediately(task_cell.take());
201+
}
202+
}
186203
}
187204
}
188205

@@ -235,8 +252,16 @@ impl UvTcpStream {
235252

236253
impl Drop for UvTcpStream {
237254
fn finalize(&self) {
238-
rtdebug!("closing stream");
239-
self.watcher().close(||());
255+
rtdebug!("closing tcp stream");
256+
let watcher = self.watcher();
257+
let scheduler = local_sched::take();
258+
do scheduler.deschedule_running_task_and_then |task| {
259+
let task_cell = Cell(task);
260+
do watcher.close {
261+
let scheduler = local_sched::take();
262+
scheduler.resume_task_immediately(task_cell.take());
263+
}
264+
}
240265
}
241266
}
242267

0 commit comments

Comments
 (0)