diff --git a/src/lib/comm.rs b/src/lib/comm.rs index 17c766cda1a5..615686a49e04 100644 --- a/src/lib/comm.rs +++ b/src/lib/comm.rs @@ -6,7 +6,7 @@ import task::task_id; export _chan; export _port; - +export chan_handle; export mk_port; export send; export recv; @@ -32,10 +32,9 @@ native "rust-intrinsic" mod rusti { type port_id = int; -type chan<~T> = { - task : task_id, - port : port_id -}; +type chan_handle<~T> = { task : task_id, port : port_id}; + +tag chan<~T> { chan_t(chan_handle); } type _chan<~T> = chan; resource port_ptr(po: *rustrt::rust_port) { @@ -43,11 +42,11 @@ resource port_ptr(po: *rustrt::rust_port) { rustrt::del_port(po); } -type port<~T> = @port_ptr; +tag port<~T> { port_t(@port_ptr); } obj port_obj<~T>(raw_port : port) { - fn mk_chan() -> _chan { - chan::(raw_port) + fn mk_chan() -> chan { + chan(raw_port) } fn recv() -> T { @@ -60,21 +59,21 @@ fn mk_port<~T>() -> _port { ret port_obj::(port::()); } -fn send<~T>(ch : chan, data : -T) { +fn send<~T>(ch : &chan, data : -T) { rustrt::chan_id_send(ch.task, ch.port, data); } fn port<~T>() -> port { - @port_ptr(rustrt::new_port(sys::size_of::())) + port_t(@port_ptr(rustrt::new_port(sys::size_of::()))) } -fn recv<~T>(p : port) -> T { - ret rusti::recv(**p) +fn recv<~T>(p : &port) -> T { + ret rusti::recv(***p) } -fn chan<~T>(p : port) -> chan { - { +fn chan<~T>(p : &port) -> chan { + chan_t({ task: task::get_task_id(), - port: rustrt::get_port_id(**p) - } + port: rustrt::get_port_id(***p) + }) } diff --git a/src/lib/task.rs b/src/lib/task.rs index 4ad160df6037..9ed8e8ecdf04 100644 --- a/src/lib/task.rs +++ b/src/lib/task.rs @@ -1,6 +1,5 @@ import cast = unsafe::reinterpret_cast; import comm; -import comm::_chan; import option::some; import option::none; import option = option::t; @@ -33,7 +32,7 @@ native "rust" mod rustrt { type rust_task = { id : task, mutable notify_enabled : u8, - mutable notify_chan : _chan, + mutable notify_chan : comm::chan_handle, ctx : task_context, stack_ptr : *u8 }; @@ -76,14 +75,12 @@ tag task_notification { fn join(task_port : (task_id, comm::port)) -> task_result { let (id, port) = task_port; - while true { - alt comm::recv::(port) { - exit(_id, res) { - if _id == id { ret res } - } - } + alt comm::recv::(port) { + exit(_id, res) { + if _id == id { ret res } + else { fail #fmt("join received id %d, expected %d", _id, id) } + } } - fail } fn join_id(t : task_id) -> task_result { @@ -108,7 +105,7 @@ fn spawn(thunk : -fn() -> ()) -> task { spawn_inner(thunk, none) } -fn spawn_notify(thunk : -fn() -> (), notify : _chan) +fn spawn_notify(thunk : -fn() -> (), notify : comm::chan) -> task { spawn_inner(thunk, some(notify)) } @@ -121,7 +118,7 @@ fn spawn_joinable(thunk : -fn()) -> (task_id, comm::port) { // FIXME: make this a fn~ once those are supported. fn spawn_inner(thunk : -fn() -> (), - notify : option<_chan>) + notify : option>) -> task_id { let id = rustrt::new_task(); @@ -144,7 +141,7 @@ fn spawn_inner(thunk : -fn() -> (), alt notify { some(c) { (**task_ptr).notify_enabled = 1u8; - (**task_ptr).notify_chan = c; + (**task_ptr).notify_chan = *c; } none {} }; diff --git a/src/test/compiletest/procsrv.rs b/src/test/compiletest/procsrv.rs index 67628fc82dcb..68df59be5216 100644 --- a/src/test/compiletest/procsrv.rs +++ b/src/test/compiletest/procsrv.rs @@ -14,10 +14,10 @@ import std::os; import std::run; import std::io; import std::str; -import std::comm::_chan; -import std::comm::mk_port; -import std::comm::_port; +import std::comm::chan; +import std::comm::port; import std::comm::send; +import std::comm::recv; export handle; export mk; @@ -26,27 +26,27 @@ export run; export close; export reqchan; -type reqchan = _chan; +type reqchan = chan; type handle = {task: option::t, chan: reqchan}; tag request { - exec([u8], [u8], [[u8]], _chan); + exec([u8], [u8], [[u8]], chan); stop; } type response = {pid: int, infd: int, outfd: int, errfd: int}; fn mk() -> handle { - let setupport = mk_port(); - let task = task::_spawn(bind fn(setupchan: _chan<_chan>) { - let reqport = mk_port(); - let reqchan = reqport.mk_chan(); + let setupport = port(); + let task = task::spawn(bind fn(setupchan: chan>) { + let reqport = port(); + let reqchan = chan(reqport); send(setupchan, reqchan); worker(reqport); - } (setupport.mk_chan())); + } (chan(setupport))); ret {task: option::some(task), - chan: setupport.recv() + chan: recv(setupport) }; } @@ -60,13 +60,13 @@ fn close(handle: &handle) { fn run(handle: &handle, lib_path: &str, prog: &str, args: &[str], input: &option::t) -> {status: int, out: str, err: str} { - let p = mk_port::(); - let ch = p.mk_chan(); + let p = port(); + let ch = chan(p); send(handle.chan, exec(str::bytes(lib_path), str::bytes(prog), clone_ivecstr(args), ch)); - let resp = p.recv(); + let resp = recv(p); writeclose(resp.infd, input); let output = readclose(resp.outfd); @@ -99,18 +99,12 @@ fn readclose(fd: int) -> str { ret buf; } -fn worker(p: _port) { +fn worker(p: port) { // FIXME (787): If we declare this inside of the while loop and then // break out of it before it's ever initialized (i.e. we don't run - // any tests), then the cleanups will puke, so we're initializing it - // here with defaults. - let execparms = { - lib_path: "", - prog: "", - args: ~[], - respchan: p.mk_chan() - }; + // any tests), then the cleanups will puke. + let execparms; while true { // FIXME: Sending strings across channels seems to still @@ -124,7 +118,7 @@ fn worker(p: _port) { // put the entire alt in another block to make sure the exec // message goes out of scope. Seems like the scoping rules for // the alt discriminant are wrong. - alt p.recv() { + alt recv(p) { exec(lib_path, prog, args, respchan) { { lib_path: str::unsafe_from_bytes(lib_path), diff --git a/src/test/run-fail/port-type.rs b/src/test/run-fail/port-type.rs index a5c077d0f8fe..5954ba530658 100644 --- a/src/test/run-fail/port-type.rs +++ b/src/test/run-fail/port-type.rs @@ -4,7 +4,7 @@ import std::comm::_chan; import std::comm::mk_port; import std::comm::send; -fn echo<~T>(c: _chan, oc: _chan<_chan>) { +fn echo<~T>(c: &_chan, oc: &_chan<_chan>) { // Tests that the type argument in port gets // visited let p = mk_port::(); diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs index 919c45a55f42..cfc358a91066 100644 --- a/src/test/run-pass/send-type-inference.rs +++ b/src/test/run-pass/send-type-inference.rs @@ -1,13 +1,13 @@ use std; -import std::comm::_chan; +import std::comm::chan; import std::comm::send; -import std::comm::mk_port; +import std::comm::port; // tests that ctrl's type gets inferred properly -type command = {key: K, val: V}; +type command<~K, ~V> = {key: K, val: V}; -fn cache_server(c: _chan<_chan>>) { - let ctrl = mk_port::<_chan>>(); - send(c, ctrl.mk_chan()); +fn cache_server<~K, ~V>(c: &chan>>) { + let ctrl = port(); + send(c, chan(ctrl)); } fn main() { } diff --git a/src/test/stdtest/comm.rs b/src/test/stdtest/comm.rs index 17c3bc1e9291..7d20042e8664 100644 --- a/src/test/stdtest/comm.rs +++ b/src/test/stdtest/comm.rs @@ -25,3 +25,19 @@ fn send_recv_fn() { comm::send(c, 42); assert(comm::recv(p) == 42); } + +#[test] +fn send_recv_fn_infer() { + let p = comm::port(); + let c = comm::chan(p); + comm::send(c, 42); + assert(comm::recv(p) == 42); +} + +#[test] +fn chan_chan() { + let p = comm::port(), p2 = comm::port::(); + let c = comm::chan(p); + comm::send(c, comm::chan(p2)); + let c2 = comm::recv(p); +}