Skip to content

Commit 4977113

Browse files
olsonjefferybrson
authored andcommitted
---
yaml --- r: 14523 b: refs/heads/try c: 974c23c h: refs/heads/master i: 14521: 8d0382e 14519: 34588c0 v: v3
1 parent f0b00da commit 4977113

File tree

3 files changed

+155
-43
lines changed

3 files changed

+155
-43
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: ffad8d7f0cc4917f46757f5a431f6207238bf59b
5+
refs/heads/try: 974c23cbeb4c0183723bac89aa50bf58e0bf7f6c
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/libstd/uvtmp.rs

Lines changed: 117 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,25 @@
22

33
// UV2
44
enum uv_operation {
5-
op_hw()
5+
op_async_init([u8])
66
}
77

8+
type uv_async = {
9+
id: [u8],
10+
loop: uv_loop
11+
};
12+
813
enum uv_msg {
914
// requests from library users
1015
msg_run(comm::chan<bool>),
1116
msg_run_in_bg(),
1217
msg_loop_delete(),
13-
msg_async_init([u8], fn~()),
18+
msg_async_init(fn~(uv_async), fn~(uv_async)),
1419
msg_async_send([u8]),
15-
msg_hw(),
1620

1721
// dispatches from libuv
18-
uv_hw()
22+
uv_async_init([u8], *ctypes::void),
23+
uv_async_send([u8])
1924
}
2025

2126
type uv_loop_data = {
@@ -25,10 +30,6 @@ type uv_loop_data = {
2530

2631
type uv_loop = comm::chan<uv_msg>;
2732

28-
enum uv_handle {
29-
handle([u8], *ctypes::void)
30-
}
31-
3233
#[nolink]
3334
native mod rustrt {
3435
fn rust_uvtmp_create_thread() -> thread;
@@ -66,10 +67,14 @@ native mod rustrt {
6667
fn rust_uvtmp_uv_bind_op_cb(loop: *ctypes::void, cb: *u8) -> *ctypes::void;
6768
fn rust_uvtmp_uv_run(loop_handle: *ctypes::void);
6869
fn rust_uvtmp_uv_async_send(handle: *ctypes::void);
70+
fn rust_uvtmp_uv_async_init(
71+
loop_handle: *ctypes::void,
72+
cb: *u8,
73+
id: *u8) -> *ctypes::void;
6974
}
7075

7176
mod uv {
72-
export loop_new, run, run_in_bg, hw;
77+
export loop_new, run, run_in_bg, async_init, async_send;
7378

7479
// public functions
7580
fn loop_new() -> uv_loop unsafe {
@@ -78,7 +83,9 @@ mod uv {
7883
let ret_recv_chan: comm::chan<uv_loop> =
7984
comm::chan(ret_recv_port);
8085

81-
task::spawn_sched(3u) {||
86+
let num_threads = 4u; // would be cool to tie this to
87+
// the number of logical procs
88+
task::spawn_sched(num_threads) {||
8289
// our beloved uv_loop_t ptr
8390
let loop_handle = rustrt::
8491
rust_uvtmp_uv_loop_new();
@@ -115,12 +122,17 @@ mod uv {
115122
// to libuv, this will be
116123
// in the process_operation
117124
// crust fn
118-
let async_handle = rustrt::rust_uvtmp_uv_bind_op_cb(
125+
let op_handle = rustrt::rust_uvtmp_uv_bind_op_cb(
119126
loop_handle,
120127
process_operation);
121128

122129
// all state goes here
123-
let handles: map::map<[u8], uv_handle> =
130+
let handles: map::map<[u8], *ctypes::void> =
131+
map::new_bytes_hash();
132+
let async_cbs: map::map<[u8], fn~(uv_async)> =
133+
map::new_bytes_hash();
134+
let async_init_after_cbs: map::map<[u8],
135+
fn~(uv_async)> =
124136
map::new_bytes_hash();
125137

126138
// the main loop that this task blocks on.
@@ -143,36 +155,51 @@ mod uv {
143155
comm::send(end_chan, true);
144156
};
145157
}
158+
146159
msg_run_in_bg {
147160
task::spawn_sched(1u) {||
148161
// this call blocks
149162
rustrt::rust_uvtmp_uv_run(loop_handle);
150163
};
151164
}
152-
msg_hw() {
153-
comm::send(operation_chan, op_hw);
154-
io::println("CALLING ASYNC_SEND FOR HW");
155-
rustrt::rust_uvtmp_uv_async_send(async_handle);
156-
}
157-
uv_hw() {
158-
io::println("HELLO WORLD!!!");
159-
}
160-
161-
////// STUBS ///////
162-
msg_loop_delete {
163-
// delete the event loop's c ptr
164-
// this will of course stop any
165-
// further processing
166-
}
167-
msg_async_init(id, callback) {
165+
166+
msg_async_init(callback, after_cb) {
168167
// create a new async handle
169168
// with the id as the handle's
170169
// data and save the callback for
171170
// invocation on msg_async_send
171+
let id = gen_handle_id();
172+
async_cbs.insert(id, callback);
173+
async_init_after_cbs.insert(id, after_cb);
174+
let op = op_async_init(id);
175+
comm::send(operation_chan, op);
176+
rustrt::rust_uvtmp_uv_async_send(op_handle);
177+
io::println("MSG_ASYNC_INIT");
172178
}
179+
uv_async_init(id, async_handle) {
180+
// libuv created a handle, which is
181+
// passed back to us. save it and
182+
// then invoke the supplied callback
183+
// for after completion
184+
handles.insert(id, async_handle);
185+
let after_cb = async_init_after_cbs.get(id);
186+
async_init_after_cbs.remove(id);
187+
task::spawn {||
188+
let async: uv_async = {
189+
id: id,
190+
loop: rust_loop_chan
191+
};
192+
after_cb(async);
193+
};
194+
}
195+
173196
msg_async_send(id) {
174-
// get the callback matching the
175-
// supplied id and invoke it
197+
let async_handle = handles.get(id);
198+
rustrt::rust_uvtmp_uv_async_send(async_handle);
199+
}
200+
uv_async_send(id) {
201+
let async_cb = async_cbs.get(id);
202+
async_cb({id: id, loop: rust_loop_chan});
176203
}
177204

178205
_ { fail "unknown form of uv_msg received"; }
@@ -193,37 +220,88 @@ mod uv {
193220
comm::send(loop, msg_run_in_bg);
194221
}
195222

196-
fn hw(loop: uv_loop) {
197-
comm::send(loop, msg_hw);
223+
fn async_init (
224+
loop: uv_loop,
225+
async_cb: fn~(uv_async),
226+
after_cb: fn~(uv_async)) {
227+
let msg = msg_async_init(async_cb, after_cb);
228+
comm::send(loop, msg);
229+
}
230+
231+
fn async_send(async: uv_async) {
232+
comm::send(async.loop, msg_async_send(async.id));
198233
}
199234

200235
// internal functions
236+
fn gen_handle_id() -> [u8] {
237+
ret rand::mk_rng().gen_bytes(16u);
238+
}
239+
fn get_handle_id_from(buf: *u8) -> [u8] unsafe {
240+
ret vec::unsafe::from_buf(buf, 16u);
241+
}
242+
243+
fn get_loop_chan_from(data: *uv_loop_data)
244+
-> comm::chan<uv_msg> unsafe {
245+
ret (*data).rust_loop_chan;
246+
}
201247

202248
// crust
203-
crust fn process_operation(data: *uv_loop_data) unsafe {
249+
crust fn process_operation(
250+
loop: *ctypes::void,
251+
data: *uv_loop_data) unsafe {
204252
io::println("IN PROCESS_OPERATION");
205253
let op_port = (*data).operation_port;
206-
let loop_chan = (*data).rust_loop_chan;
254+
let loop_chan = get_loop_chan_from(data);
207255
let op_pending = comm::peek(op_port);
208256
while(op_pending) {
209257
io::println("OPERATION PENDING!");
210258
alt comm::recv(op_port) {
211-
op_hw() {
212-
io::println("GOT OP_HW IN CRUST");
213-
comm::send(loop_chan, uv_hw);
259+
op_async_init(id) {
260+
io::println("OP_ASYNC_INIT");
261+
let id_ptr = vec::unsafe::to_ptr(id);
262+
let async_handle = rustrt::rust_uvtmp_uv_async_init(
263+
loop,
264+
process_async_send,
265+
id_ptr);
266+
comm::send(loop_chan, uv_async_init(
267+
id,
268+
async_handle));
214269
}
270+
215271
_ { fail "unknown form of uv_operation received"; }
216272
}
217273
op_pending = comm::peek(op_port);
218274
}
219275
io::println("NO MORE OPERATIONS PENDING!");
220276
}
277+
278+
crust fn process_async_send(id_buf: *u8, data: *uv_loop_data)
279+
unsafe {
280+
let handle_id = get_handle_id_from(id_buf);
281+
let loop_chan = get_loop_chan_from(data);
282+
comm::send(loop_chan, uv_async_send(handle_id));
283+
}
284+
285+
286+
}
287+
288+
#[test]
289+
fn test_uvtmp_uv_new_loop_no_handles() {
290+
let test_loop = uv::loop_new();
291+
uv::run(test_loop); // this should return immediately
292+
// since there aren't any handles..
221293
}
222294

223295
#[test]
224-
fn uvtmp_uv_test_hello_world() {
296+
fn test_uvtmp_uv_simple_async() {
225297
let test_loop = uv::loop_new();
226-
uv::hw(test_loop);
298+
let cb: fn~(uv_async) = fn~(h: uv_async) {
299+
io::println("HELLO FROM ASYNC CALLBACK!");
300+
};
301+
uv::async_init(test_loop, cb) {|new_async|
302+
io::println("NEW_ASYNC CREATED!");
303+
uv::async_send(new_async);
304+
};
227305
uv::run(test_loop);
228306
}
229307

branches/try/src/rt/rust_uvtmp.cpp

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ struct timer_start_data {
5757

5858
// UVTMP REWORK
5959

60+
typedef void (*async_op_cb)(uv_loop_t* loop, void* data);
61+
typedef void (*rust_async_cb)(uint8_t* id_buf, void* loop_data);
62+
6063
static void*
6164
current_kernel_malloc(size_t size, const char* tag) {
6265
return rust_task_thread::get_task()->malloc(size, tag);
@@ -68,6 +71,11 @@ current_kernel_free(void* ptr) {
6871
rust_task_thread::get_task()->free(ptr);
6972
}
7073
*/
74+
#define RUST_UV_HANDLE_LEN 16
75+
struct async_data {
76+
uint8_t id_buf[RUST_UV_HANDLE_LEN];
77+
rust_async_cb cb;
78+
};
7179

7280
extern "C" void*
7381
rust_uvtmp_uv_loop_new() {
@@ -79,11 +87,11 @@ rust_uvtmp_uv_loop_set_data(uv_loop_t* loop, void* data) {
7987
loop->data = data;
8088
}
8189

82-
typedef void (*async_op_cb)(void* data);
83-
void native_async_op_cb(uv_async_t* handle, int status) {
90+
static void
91+
native_async_op_cb(uv_async_t* handle, int status) {
8492
async_op_cb cb = (async_op_cb)handle->data;
8593
void* loop_data = handle->loop->data;
86-
cb(loop_data);
94+
cb(handle->loop, loop_data);
8795
}
8896

8997
extern "C" void*
@@ -92,6 +100,8 @@ rust_uvtmp_uv_bind_op_cb(uv_loop_t* loop, async_op_cb cb) {
92100
sizeof(uv_async_t),
93101
"uv_async_t");
94102
uv_async_init(loop, async, native_async_op_cb);
103+
// decrement the ref count, so that our async bind
104+
// does count towards keeping the loop alive
95105
async->data = (void*)cb;
96106
return async;
97107
}
@@ -105,6 +115,30 @@ rust_uvtmp_uv_async_send(uv_async_t* handle) {
105115
uv_async_send(handle);
106116
}
107117

118+
static void
119+
native_async_cb(uv_async_t* handle, int status) {
120+
async_data* handle_data = (async_data*)handle->data;
121+
void* loop_data = handle->loop->data;
122+
handle_data->cb(handle_data->id_buf, loop_data);
123+
}
124+
125+
extern "C" void*
126+
rust_uvtmp_uv_async_init(uv_loop_t* loop, rust_async_cb cb,
127+
uint8_t* buf) {
128+
uv_async_t* async = (uv_async_t*)current_kernel_malloc(
129+
sizeof(uv_async_t),
130+
"uv_async_t");
131+
uv_async_init(loop, async, native_async_cb);
132+
async_data* data = (async_data*)current_kernel_malloc(
133+
sizeof(async_data),
134+
"async_data");
135+
memcpy(data->id_buf, buf, RUST_UV_HANDLE_LEN);
136+
data->cb = cb;
137+
async->data = data;
138+
139+
return async;
140+
}
141+
108142
// UVTMP REWORK
109143

110144
// FIXME: Copied from rust_builtins.cpp. Could bitrot easily

0 commit comments

Comments
 (0)