Skip to content

Commit a439187

Browse files
olsonjefferybrson
authored andcommitted
---
yaml --- r: 11516 b: refs/heads/master c: ffad8d7 h: refs/heads/master v: v3
1 parent 0eb3afb commit a439187

File tree

3 files changed

+251
-1
lines changed

3 files changed

+251
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 418c6bcec35a5552f8732946819f792da75bf555
2+
refs/heads/master: ffad8d7f0cc4917f46757f5a431f6207238bf59b
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/libstd/uvtmp.rs

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
11
// Some temporary libuv hacks for servo
22

3+
// UV2
4+
enum uv_operation {
5+
op_hw()
6+
}
7+
8+
enum uv_msg {
9+
// requests from library users
10+
msg_run(comm::chan<bool>),
11+
msg_run_in_bg(),
12+
msg_loop_delete(),
13+
msg_async_init([u8], fn~()),
14+
msg_async_send([u8]),
15+
msg_hw(),
16+
17+
// dispatches from libuv
18+
uv_hw()
19+
}
20+
21+
type uv_loop_data = {
22+
operation_port: comm::port<uv_operation>,
23+
rust_loop_chan: comm::chan<uv_msg>
24+
};
25+
26+
type uv_loop = comm::chan<uv_msg>;
27+
28+
enum uv_handle {
29+
handle([u8], *ctypes::void)
30+
}
31+
332
#[nolink]
433
native mod rustrt {
534
fn rust_uvtmp_create_thread() -> thread;
@@ -29,8 +58,177 @@ native mod rustrt {
2958
chan: comm::chan<iomsg>);
3059
fn rust_uvtmp_delete_buf(buf: *u8);
3160
fn rust_uvtmp_get_req_id(cd: connect_data) -> u32;
61+
62+
fn rust_uvtmp_uv_loop_new() -> *ctypes::void;
63+
fn rust_uvtmp_uv_loop_set_data(
64+
loop: *ctypes::void,
65+
data: *uv_loop_data);
66+
fn rust_uvtmp_uv_bind_op_cb(loop: *ctypes::void, cb: *u8) -> *ctypes::void;
67+
fn rust_uvtmp_uv_run(loop_handle: *ctypes::void);
68+
fn rust_uvtmp_uv_async_send(handle: *ctypes::void);
3269
}
3370

71+
mod uv {
72+
export loop_new, run, run_in_bg, hw;
73+
74+
// public functions
75+
fn loop_new() -> uv_loop unsafe {
76+
let ret_recv_port: comm::port<uv_loop> =
77+
comm::port();
78+
let ret_recv_chan: comm::chan<uv_loop> =
79+
comm::chan(ret_recv_port);
80+
81+
task::spawn_sched(3u) {||
82+
// our beloved uv_loop_t ptr
83+
let loop_handle = rustrt::
84+
rust_uvtmp_uv_loop_new();
85+
86+
// this port/chan pair are used to send messages to
87+
// libuv. libuv processes any pending messages on the
88+
// port (via crust) after receiving an async "wakeup"
89+
// on a special uv_async_t handle created below
90+
let operation_port = comm::port::<uv_operation>();
91+
let operation_chan = comm::chan::<uv_operation>(
92+
operation_port);
93+
94+
// this port/chan pair as used in the while() loop
95+
// below. It takes dispatches, originating from libuv
96+
// callbacks, to invoke handles registered by the
97+
// user
98+
let rust_loop_port = comm::port::<uv_msg>();
99+
let rust_loop_chan =
100+
comm::chan::<uv_msg>(rust_loop_port);
101+
// let the task-spawner return
102+
comm::send(ret_recv_chan, copy(rust_loop_chan));
103+
104+
// create our "special" async handle that will
105+
// allow all operations against libuv to be
106+
// "buffered" in the operation_port, for processing
107+
// from the thread that libuv runs on
108+
let loop_data: uv_loop_data = {
109+
operation_port: operation_port,
110+
rust_loop_chan: rust_loop_chan
111+
};
112+
rustrt::rust_uvtmp_uv_loop_set_data(
113+
loop_handle,
114+
ptr::addr_of(loop_data)); // pass an opaque C-ptr
115+
// to libuv, this will be
116+
// in the process_operation
117+
// crust fn
118+
let async_handle = rustrt::rust_uvtmp_uv_bind_op_cb(
119+
loop_handle,
120+
process_operation);
121+
122+
// all state goes here
123+
let handles: map::map<[u8], uv_handle> =
124+
map::new_bytes_hash();
125+
126+
// the main loop that this task blocks on.
127+
// should have the same lifetime as the C libuv
128+
// event loop.
129+
let keep_going = true;
130+
while (keep_going) {
131+
alt comm::recv(rust_loop_port) {
132+
msg_run(end_chan) {
133+
// start the libuv event loop
134+
// we'll also do a uv_async_send with
135+
// the operation handle to have the
136+
// loop process any pending operations
137+
// once its up and running
138+
task::spawn_sched(1u) {||
139+
// this call blocks
140+
rustrt::rust_uvtmp_uv_run(loop_handle);
141+
// when we're done, msg the
142+
// end chan
143+
comm::send(end_chan, true);
144+
};
145+
}
146+
msg_run_in_bg {
147+
task::spawn_sched(1u) {||
148+
// this call blocks
149+
rustrt::rust_uvtmp_uv_run(loop_handle);
150+
};
151+
}
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) {
168+
// create a new async handle
169+
// with the id as the handle's
170+
// data and save the callback for
171+
// invocation on msg_async_send
172+
}
173+
msg_async_send(id) {
174+
// get the callback matching the
175+
// supplied id and invoke it
176+
}
177+
178+
_ { fail "unknown form of uv_msg received"; }
179+
}
180+
}
181+
};
182+
ret comm::recv(ret_recv_port);
183+
}
184+
185+
fn run(loop: uv_loop) {
186+
let end_port = comm::port::<bool>();
187+
let end_chan = comm::chan::<bool>(end_port);
188+
comm::send(loop, msg_run(end_chan));
189+
comm::recv(end_port);
190+
}
191+
192+
fn run_in_bg(loop: uv_loop) {
193+
comm::send(loop, msg_run_in_bg);
194+
}
195+
196+
fn hw(loop: uv_loop) {
197+
comm::send(loop, msg_hw);
198+
}
199+
200+
// internal functions
201+
202+
// crust
203+
crust fn process_operation(data: *uv_loop_data) unsafe {
204+
io::println("IN PROCESS_OPERATION");
205+
let op_port = (*data).operation_port;
206+
let loop_chan = (*data).rust_loop_chan;
207+
let op_pending = comm::peek(op_port);
208+
while(op_pending) {
209+
io::println("OPERATION PENDING!");
210+
alt comm::recv(op_port) {
211+
op_hw() {
212+
io::println("GOT OP_HW IN CRUST");
213+
comm::send(loop_chan, uv_hw);
214+
}
215+
_ { fail "unknown form of uv_operation received"; }
216+
}
217+
op_pending = comm::peek(op_port);
218+
}
219+
io::println("NO MORE OPERATIONS PENDING!");
220+
}
221+
}
222+
223+
#[test]
224+
fn uvtmp_uv_test_hello_world() {
225+
let test_loop = uv::loop_new();
226+
uv::hw(test_loop);
227+
uv::run(test_loop);
228+
}
229+
230+
// END OF UV2
231+
34232
type thread = *ctypes::void;
35233

36234
type connect_data = *ctypes::void;

trunk/src/rt/rust_uvtmp.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,58 @@ struct timer_start_data {
5555
chan_handle chan;
5656
};
5757

58+
// UVTMP REWORK
59+
60+
static void*
61+
current_kernel_malloc(size_t size, const char* tag) {
62+
return rust_task_thread::get_task()->malloc(size, tag);
63+
}
64+
65+
/*
66+
static void
67+
current_kernel_free(void* ptr) {
68+
rust_task_thread::get_task()->free(ptr);
69+
}
70+
*/
71+
72+
extern "C" void*
73+
rust_uvtmp_uv_loop_new() {
74+
return (void*)uv_loop_new();
75+
}
76+
77+
extern "C" void
78+
rust_uvtmp_uv_loop_set_data(uv_loop_t* loop, void* data) {
79+
loop->data = data;
80+
}
81+
82+
typedef void (*async_op_cb)(void* data);
83+
void native_async_op_cb(uv_async_t* handle, int status) {
84+
async_op_cb cb = (async_op_cb)handle->data;
85+
void* loop_data = handle->loop->data;
86+
cb(loop_data);
87+
}
88+
89+
extern "C" void*
90+
rust_uvtmp_uv_bind_op_cb(uv_loop_t* loop, async_op_cb cb) {
91+
uv_async_t* async = (uv_async_t*)current_kernel_malloc(
92+
sizeof(uv_async_t),
93+
"uv_async_t");
94+
uv_async_init(loop, async, native_async_op_cb);
95+
async->data = (void*)cb;
96+
return async;
97+
}
98+
99+
extern "C" void rust_uvtmp_uv_run(uv_loop_t* loop) {
100+
uv_run(loop);
101+
}
102+
103+
extern "C" void
104+
rust_uvtmp_uv_async_send(uv_async_t* handle) {
105+
uv_async_send(handle);
106+
}
107+
108+
// UVTMP REWORK
109+
58110
// FIXME: Copied from rust_builtins.cpp. Could bitrot easily
59111
static void
60112
send(rust_task *task, chan_handle chan, void *data) {

0 commit comments

Comments
 (0)