mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
auto merge of #13050 : alexcrichton/rust/no-send-default, r=huonw
See #10296 for the rationale, and commits for the implementation.
This commit is contained in:
commit
13dafa09f1
@ -2430,23 +2430,25 @@ select the method to call at runtime.
|
||||
|
||||
This usage of traits is similar to Java interfaces.
|
||||
|
||||
By default, each of the three storage classes for traits enforce a
|
||||
particular set of built-in kinds that their contents must fulfill in
|
||||
order to be packaged up in a trait object of that storage class.
|
||||
There are some built-in bounds, such as `Send` and `Share`, which are properties
|
||||
of the components of types. By design, trait objects don't know the exact type
|
||||
of their contents and so the compiler cannot reason about those properties.
|
||||
|
||||
* The contents of owned traits (`~Trait`) must fulfill the `Send` bound.
|
||||
* The contents of reference traits (`&Trait`) are not constrained by any bound.
|
||||
You can instruct the compiler, however, that the contents of a trait object must
|
||||
acribe to a particular bound with a trailing colon (`:`). These are examples of
|
||||
valid types:
|
||||
|
||||
Consequently, the trait objects themselves automatically fulfill their
|
||||
respective kind bounds. However, this default behavior can be overridden by
|
||||
specifying a list of bounds on the trait type, for example, by writing `~Trait:`
|
||||
(which indicates that the contents of the owned trait need not fulfill any
|
||||
bounds), or by writing `~Trait:Send+Share`, which indicates that in addition
|
||||
to fulfilling `Send`, contents must also fulfill `Share`, and as a consequence,
|
||||
the trait itself fulfills `Share`.
|
||||
~~~rust
|
||||
trait Foo {}
|
||||
trait Bar<T> {}
|
||||
|
||||
* `~Trait:Send` is equivalent to `~Trait`.
|
||||
* `&Trait:` is equivalent to `&Trait`.
|
||||
fn sendable_foo(f: ~Foo:Send) { /* ... */ }
|
||||
fn shareable_bar<T: Share>(b: &Bar<T>: Share) { /* ... */ }
|
||||
~~~
|
||||
|
||||
When no colon is specified (such as the type `~Foo`), it is inferred that the
|
||||
value ascribes to no bounds. They must be added manually if any bounds are
|
||||
necessary for usage.
|
||||
|
||||
Builtin kind bounds can also be specified on closure types in the same way (for
|
||||
example, by writing `fn:Send()`), and the default behaviours are the same as
|
||||
|
@ -22,14 +22,14 @@ use std::rt::rtio::{EventLoop, IoFactory, RemoteCallback, PausableIdleCallback,
|
||||
use std::unstable::sync::Exclusive;
|
||||
|
||||
/// This is the only exported function from this module.
|
||||
pub fn event_loop() -> ~EventLoop {
|
||||
~BasicLoop::new() as ~EventLoop
|
||||
pub fn event_loop() -> ~EventLoop:Send {
|
||||
~BasicLoop::new() as ~EventLoop:Send
|
||||
}
|
||||
|
||||
struct BasicLoop {
|
||||
work: ~[proc()], // pending work
|
||||
work: ~[proc:Send()], // pending work
|
||||
idle: Option<*mut BasicPausable>, // only one is allowed
|
||||
remotes: ~[(uint, ~Callback)],
|
||||
remotes: ~[(uint, ~Callback:Send)],
|
||||
next_remote: uint,
|
||||
messages: Exclusive<~[Message]>,
|
||||
}
|
||||
@ -135,26 +135,28 @@ impl EventLoop for BasicLoop {
|
||||
}
|
||||
}
|
||||
|
||||
fn callback(&mut self, f: proc()) {
|
||||
fn callback(&mut self, f: proc:Send()) {
|
||||
self.work.push(f);
|
||||
}
|
||||
|
||||
// FIXME: Seems like a really weird requirement to have an event loop provide.
|
||||
fn pausable_idle_callback(&mut self, cb: ~Callback) -> ~PausableIdleCallback {
|
||||
fn pausable_idle_callback(&mut self, cb: ~Callback:Send)
|
||||
-> ~PausableIdleCallback:Send
|
||||
{
|
||||
let callback = ~BasicPausable::new(self, cb);
|
||||
rtassert!(self.idle.is_none());
|
||||
unsafe {
|
||||
let cb_ptr: &*mut BasicPausable = cast::transmute(&callback);
|
||||
self.idle = Some(*cb_ptr);
|
||||
}
|
||||
return callback as ~PausableIdleCallback;
|
||||
callback as ~PausableIdleCallback:Send
|
||||
}
|
||||
|
||||
fn remote_callback(&mut self, f: ~Callback) -> ~RemoteCallback {
|
||||
fn remote_callback(&mut self, f: ~Callback:Send) -> ~RemoteCallback:Send {
|
||||
let id = self.next_remote;
|
||||
self.next_remote += 1;
|
||||
self.remotes.push((id, f));
|
||||
~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback
|
||||
~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback:Send
|
||||
}
|
||||
|
||||
fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory> { None }
|
||||
@ -195,12 +197,12 @@ impl Drop for BasicRemote {
|
||||
|
||||
struct BasicPausable {
|
||||
eloop: *mut BasicLoop,
|
||||
work: ~Callback,
|
||||
work: ~Callback:Send,
|
||||
active: bool,
|
||||
}
|
||||
|
||||
impl BasicPausable {
|
||||
fn new(eloop: &mut BasicLoop, cb: ~Callback) -> BasicPausable {
|
||||
fn new(eloop: &mut BasicLoop, cb: ~Callback:Send) -> BasicPausable {
|
||||
BasicPausable {
|
||||
active: false,
|
||||
work: cb,
|
||||
|
@ -247,7 +247,7 @@ pub mod task;
|
||||
/// The return value is used as the process return code. 0 on success, 101 on
|
||||
/// error.
|
||||
pub fn start(argc: int, argv: **u8,
|
||||
event_loop_factory: fn() -> ~rtio::EventLoop,
|
||||
event_loop_factory: fn() -> ~rtio::EventLoop:Send,
|
||||
main: proc()) -> int {
|
||||
rt::init(argc, argv);
|
||||
let mut main = Some(main);
|
||||
@ -268,7 +268,8 @@ pub fn start(argc: int, argv: **u8,
|
||||
///
|
||||
/// This function will not return until all schedulers in the associated pool
|
||||
/// have returned.
|
||||
pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop, main: proc()) -> int {
|
||||
pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop:Send,
|
||||
main: proc()) -> int {
|
||||
// Create a scheduler pool and spawn the main task into this pool. We will
|
||||
// get notified over a channel when the main task exits.
|
||||
let mut cfg = PoolConfig::new();
|
||||
@ -298,7 +299,7 @@ pub struct PoolConfig {
|
||||
threads: uint,
|
||||
/// A factory function used to create new event loops. If this is not
|
||||
/// specified then the default event loop factory is used.
|
||||
event_loop_factory: fn() -> ~rtio::EventLoop,
|
||||
event_loop_factory: fn() -> ~rtio::EventLoop:Send,
|
||||
}
|
||||
|
||||
impl PoolConfig {
|
||||
@ -323,7 +324,7 @@ pub struct SchedPool {
|
||||
priv stack_pool: StackPool,
|
||||
priv deque_pool: deque::BufferPool<~task::GreenTask>,
|
||||
priv sleepers: SleeperList,
|
||||
priv factory: fn() -> ~rtio::EventLoop,
|
||||
priv factory: fn() -> ~rtio::EventLoop:Send,
|
||||
priv task_state: TaskState,
|
||||
priv tasks_done: Receiver<()>,
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ pub struct Scheduler {
|
||||
/// A fast XorShift rng for scheduler use
|
||||
rng: XorShiftRng,
|
||||
/// A togglable idle callback
|
||||
idle_callback: Option<~PausableIdleCallback>,
|
||||
idle_callback: Option<~PausableIdleCallback:Send>,
|
||||
/// A countdown that starts at a random value and is decremented
|
||||
/// every time a yield check is performed. When it hits 0 a task
|
||||
/// will yield.
|
||||
@ -99,7 +99,7 @@ pub struct Scheduler {
|
||||
// destroyed before it's actually destroyed.
|
||||
|
||||
/// The event loop used to drive the scheduler and perform I/O
|
||||
event_loop: ~EventLoop,
|
||||
event_loop: ~EventLoop:Send,
|
||||
}
|
||||
|
||||
/// An indication of how hard to work on a given operation, the difference
|
||||
@ -122,7 +122,7 @@ impl Scheduler {
|
||||
// * Initialization Functions
|
||||
|
||||
pub fn new(pool_id: uint,
|
||||
event_loop: ~EventLoop,
|
||||
event_loop: ~EventLoop:Send,
|
||||
work_queue: deque::Worker<~GreenTask>,
|
||||
work_queues: ~[deque::Stealer<~GreenTask>],
|
||||
sleeper_list: SleeperList,
|
||||
@ -135,7 +135,7 @@ impl Scheduler {
|
||||
}
|
||||
|
||||
pub fn new_special(pool_id: uint,
|
||||
event_loop: ~EventLoop,
|
||||
event_loop: ~EventLoop:Send,
|
||||
work_queue: deque::Worker<~GreenTask>,
|
||||
work_queues: ~[deque::Stealer<~GreenTask>],
|
||||
sleeper_list: SleeperList,
|
||||
@ -182,7 +182,7 @@ impl Scheduler {
|
||||
pub fn bootstrap(mut ~self) {
|
||||
|
||||
// Build an Idle callback.
|
||||
let cb = ~SchedRunner as ~Callback;
|
||||
let cb = ~SchedRunner as ~Callback:Send;
|
||||
self.idle_callback = Some(self.event_loop.pausable_idle_callback(cb));
|
||||
|
||||
// Create a task for the scheduler with an empty context.
|
||||
@ -230,7 +230,7 @@ impl Scheduler {
|
||||
// mutable reference to the event_loop to give it the "run"
|
||||
// command.
|
||||
unsafe {
|
||||
let event_loop: *mut ~EventLoop = &mut self.event_loop;
|
||||
let event_loop: *mut ~EventLoop:Send = &mut self.event_loop;
|
||||
// Our scheduler must be in the task before the event loop
|
||||
// is started.
|
||||
stask.put_with_sched(self);
|
||||
@ -868,7 +868,7 @@ impl Scheduler {
|
||||
}
|
||||
|
||||
pub fn make_handle(&mut self) -> SchedHandle {
|
||||
let remote = self.event_loop.remote_callback(~SchedRunner as ~Callback);
|
||||
let remote = self.event_loop.remote_callback(~SchedRunner);
|
||||
|
||||
return SchedHandle {
|
||||
remote: remote,
|
||||
@ -893,7 +893,7 @@ pub enum SchedMessage {
|
||||
}
|
||||
|
||||
pub struct SchedHandle {
|
||||
priv remote: ~RemoteCallback,
|
||||
priv remote: ~RemoteCallback:Send,
|
||||
priv queue: msgq::Producer<SchedMessage>,
|
||||
sched_id: uint
|
||||
}
|
||||
@ -1007,7 +1007,6 @@ mod test {
|
||||
|
||||
use std::comm;
|
||||
use std::task::TaskOpts;
|
||||
use std::rt::Runtime;
|
||||
use std::rt::task::Task;
|
||||
use std::rt::local::Local;
|
||||
|
||||
@ -1034,7 +1033,7 @@ mod test {
|
||||
match task.get().maybe_take_runtime::<GreenTask>() {
|
||||
Some(green) => {
|
||||
let ret = green.sched.get_ref().sched_id();
|
||||
task.get().put_runtime(green as ~Runtime);
|
||||
task.get().put_runtime(green);
|
||||
return ret;
|
||||
}
|
||||
None => fail!()
|
||||
|
@ -34,7 +34,7 @@ impl Runtime for SimpleTask {
|
||||
|
||||
let me = &mut *self as *mut SimpleTask;
|
||||
let cur_dupe = &*cur_task as *Task;
|
||||
cur_task.put_runtime(self as ~Runtime);
|
||||
cur_task.put_runtime(self);
|
||||
let task = BlockedTask::block(cur_task);
|
||||
|
||||
// See libnative/task.rs for what's going on here with the `awoken`
|
||||
@ -57,7 +57,7 @@ impl Runtime for SimpleTask {
|
||||
}
|
||||
fn reawaken(mut ~self, mut to_wake: ~Task) {
|
||||
let me = &mut *self as *mut SimpleTask;
|
||||
to_wake.put_runtime(self as ~Runtime);
|
||||
to_wake.put_runtime(self);
|
||||
unsafe {
|
||||
cast::forget(to_wake);
|
||||
let guard = (*me).lock.lock();
|
||||
@ -86,6 +86,6 @@ pub fn task() -> ~Task {
|
||||
task.put_runtime(~SimpleTask {
|
||||
lock: unsafe {NativeMutex::new()},
|
||||
awoken: false,
|
||||
} as ~Runtime);
|
||||
});
|
||||
return task;
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ impl GreenTask {
|
||||
|
||||
pub fn swap(mut ~self) -> ~Task {
|
||||
let mut task = self.task.take_unwrap();
|
||||
task.put_runtime(self as ~Runtime);
|
||||
task.put_runtime(self);
|
||||
return task;
|
||||
}
|
||||
|
||||
@ -482,7 +482,6 @@ impl Runtime for GreenTask {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::rt::Runtime;
|
||||
use std::rt::local::Local;
|
||||
use std::rt::task::Task;
|
||||
use std::task;
|
||||
@ -576,7 +575,7 @@ mod tests {
|
||||
let mut task: ~Task = Local::take();
|
||||
match task.maybe_take_runtime::<GreenTask>() {
|
||||
Some(ops) => {
|
||||
task.put_runtime(ops as ~Runtime);
|
||||
task.put_runtime(ops);
|
||||
}
|
||||
None => fail!(),
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ pub static WARN: u32 = 2;
|
||||
/// Error log level
|
||||
pub static ERROR: u32 = 1;
|
||||
|
||||
local_data_key!(local_logger: ~Logger)
|
||||
local_data_key!(local_logger: ~Logger:Send)
|
||||
|
||||
/// A trait used to represent an interface to a task-local logger. Each task
|
||||
/// can have its own custom logger which can respond to logging messages
|
||||
@ -203,7 +203,7 @@ pub fn log(level: u32, args: &fmt::Arguments) {
|
||||
// frob the slot while we're doing the logging. This will destroy any logger
|
||||
// set during logging.
|
||||
let mut logger = local_data::pop(local_logger).unwrap_or_else(|| {
|
||||
~DefaultLogger { handle: io::stderr() } as ~Logger
|
||||
~DefaultLogger { handle: io::stderr() } as ~Logger:Send
|
||||
});
|
||||
logger.log(level, args);
|
||||
local_data::set(local_logger, logger);
|
||||
@ -217,7 +217,7 @@ pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }
|
||||
|
||||
/// Replaces the task-local logger with the specified logger, returning the old
|
||||
/// logger.
|
||||
pub fn set_logger(logger: ~Logger) -> Option<~Logger> {
|
||||
pub fn set_logger(logger: ~Logger:Send) -> Option<~Logger:Send> {
|
||||
let prev = local_data::pop(local_logger);
|
||||
local_data::set(local_logger, logger);
|
||||
return prev;
|
||||
|
@ -176,8 +176,8 @@ impl rtio::RtioPipe for FileDesc {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
self.inner_write(buf)
|
||||
}
|
||||
fn clone(&self) -> ~rtio::RtioPipe {
|
||||
~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe
|
||||
fn clone(&self) -> ~rtio::RtioPipe:Send {
|
||||
~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe:Send
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,8 +206,8 @@ impl rtio::RtioPipe for FileDesc {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
self.inner_write(buf)
|
||||
}
|
||||
fn clone(&self) -> ~rtio::RtioPipe {
|
||||
~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe
|
||||
fn clone(&self) -> ~rtio::RtioPipe:Send {
|
||||
~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe:Send
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,20 +227,20 @@ impl IoFactory {
|
||||
|
||||
impl rtio::IoFactory for IoFactory {
|
||||
// networking
|
||||
fn tcp_connect(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpStream> {
|
||||
net::TcpStream::connect(addr).map(|s| ~s as ~RtioTcpStream)
|
||||
fn tcp_connect(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpStream:Send> {
|
||||
net::TcpStream::connect(addr).map(|s| ~s as ~RtioTcpStream:Send)
|
||||
}
|
||||
fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener> {
|
||||
net::TcpListener::bind(addr).map(|s| ~s as ~RtioTcpListener)
|
||||
fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener:Send> {
|
||||
net::TcpListener::bind(addr).map(|s| ~s as ~RtioTcpListener:Send)
|
||||
}
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioUdpSocket> {
|
||||
net::UdpSocket::bind(addr).map(|u| ~u as ~RtioUdpSocket)
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioUdpSocket:Send> {
|
||||
net::UdpSocket::bind(addr).map(|u| ~u as ~RtioUdpSocket:Send)
|
||||
}
|
||||
fn unix_bind(&mut self, path: &CString) -> IoResult<~RtioUnixListener> {
|
||||
pipe::UnixListener::bind(path).map(|s| ~s as ~RtioUnixListener)
|
||||
fn unix_bind(&mut self, path: &CString) -> IoResult<~RtioUnixListener:Send> {
|
||||
pipe::UnixListener::bind(path).map(|s| ~s as ~RtioUnixListener:Send)
|
||||
}
|
||||
fn unix_connect(&mut self, path: &CString) -> IoResult<~RtioPipe> {
|
||||
pipe::UnixStream::connect(path).map(|s| ~s as ~RtioPipe)
|
||||
fn unix_connect(&mut self, path: &CString) -> IoResult<~RtioPipe:Send> {
|
||||
pipe::UnixStream::connect(path).map(|s| ~s as ~RtioPipe:Send)
|
||||
}
|
||||
fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
|
||||
hint: Option<ai::Hint>) -> IoResult<~[ai::Info]> {
|
||||
@ -249,16 +249,16 @@ impl rtio::IoFactory for IoFactory {
|
||||
|
||||
// filesystem operations
|
||||
fn fs_from_raw_fd(&mut self, fd: c_int,
|
||||
close: CloseBehavior) -> ~RtioFileStream {
|
||||
close: CloseBehavior) -> ~RtioFileStream:Send {
|
||||
let close = match close {
|
||||
rtio::CloseSynchronously | rtio::CloseAsynchronously => true,
|
||||
rtio::DontClose => false
|
||||
};
|
||||
~file::FileDesc::new(fd, close) as ~RtioFileStream
|
||||
~file::FileDesc::new(fd, close) as ~RtioFileStream:Send
|
||||
}
|
||||
fn fs_open(&mut self, path: &CString, fm: io::FileMode, fa: io::FileAccess)
|
||||
-> IoResult<~RtioFileStream> {
|
||||
file::open(path, fm, fa).map(|fd| ~fd as ~RtioFileStream)
|
||||
-> IoResult<~RtioFileStream:Send> {
|
||||
file::open(path, fm, fa).map(|fd| ~fd as ~RtioFileStream:Send)
|
||||
}
|
||||
fn fs_unlink(&mut self, path: &CString) -> IoResult<()> {
|
||||
file::unlink(path)
|
||||
@ -304,25 +304,27 @@ impl rtio::IoFactory for IoFactory {
|
||||
}
|
||||
|
||||
// misc
|
||||
fn timer_init(&mut self) -> IoResult<~RtioTimer> {
|
||||
timer::Timer::new().map(|t| ~t as ~RtioTimer)
|
||||
fn timer_init(&mut self) -> IoResult<~RtioTimer:Send> {
|
||||
timer::Timer::new().map(|t| ~t as ~RtioTimer:Send)
|
||||
}
|
||||
fn spawn(&mut self, config: ProcessConfig)
|
||||
-> IoResult<(~RtioProcess, ~[Option<~RtioPipe>])> {
|
||||
-> IoResult<(~RtioProcess:Send, ~[Option<~RtioPipe:Send>])> {
|
||||
process::Process::spawn(config).map(|(p, io)| {
|
||||
(~p as ~RtioProcess,
|
||||
io.move_iter().map(|p| p.map(|p| ~p as ~RtioPipe)).collect())
|
||||
(~p as ~RtioProcess:Send,
|
||||
io.move_iter().map(|p| p.map(|p| ~p as ~RtioPipe:Send)).collect())
|
||||
})
|
||||
}
|
||||
fn kill(&mut self, pid: libc::pid_t, signum: int) -> IoResult<()> {
|
||||
process::Process::kill(pid, signum)
|
||||
}
|
||||
fn pipe_open(&mut self, fd: c_int) -> IoResult<~RtioPipe> {
|
||||
Ok(~file::FileDesc::new(fd, true) as ~RtioPipe)
|
||||
fn pipe_open(&mut self, fd: c_int) -> IoResult<~RtioPipe:Send> {
|
||||
Ok(~file::FileDesc::new(fd, true) as ~RtioPipe:Send)
|
||||
}
|
||||
fn tty_open(&mut self, fd: c_int, _readable: bool) -> IoResult<~RtioTTY> {
|
||||
fn tty_open(&mut self, fd: c_int, _readable: bool)
|
||||
-> IoResult<~RtioTTY:Send>
|
||||
{
|
||||
if unsafe { libc::isatty(fd) } != 0 {
|
||||
Ok(~file::FileDesc::new(fd, true) as ~RtioTTY)
|
||||
Ok(~file::FileDesc::new(fd, true) as ~RtioTTY:Send)
|
||||
} else {
|
||||
Err(IoError {
|
||||
kind: io::MismatchedFileTypeForOperation,
|
||||
@ -332,7 +334,7 @@ impl rtio::IoFactory for IoFactory {
|
||||
}
|
||||
}
|
||||
fn signal(&mut self, _signal: Signum, _channel: Sender<Signum>)
|
||||
-> IoResult<~RtioSignal> {
|
||||
-> IoResult<~RtioSignal:Send> {
|
||||
Err(unimpl())
|
||||
}
|
||||
}
|
||||
|
@ -348,8 +348,8 @@ impl rtio::RtioTcpStream for TcpStream {
|
||||
self.set_keepalive(None)
|
||||
}
|
||||
|
||||
fn clone(&self) -> ~rtio::RtioTcpStream {
|
||||
~TcpStream { inner: self.inner.clone() } as ~rtio::RtioTcpStream
|
||||
fn clone(&self) -> ~rtio::RtioTcpStream:Send {
|
||||
~TcpStream { inner: self.inner.clone() } as ~rtio::RtioTcpStream:Send
|
||||
}
|
||||
fn close_write(&mut self) -> IoResult<()> {
|
||||
super::mkerr_libc(unsafe {
|
||||
@ -418,8 +418,8 @@ impl TcpListener {
|
||||
}
|
||||
|
||||
impl rtio::RtioTcpListener for TcpListener {
|
||||
fn listen(~self) -> IoResult<~rtio::RtioTcpAcceptor> {
|
||||
self.native_listen(128).map(|a| ~a as ~rtio::RtioTcpAcceptor)
|
||||
fn listen(~self) -> IoResult<~rtio::RtioTcpAcceptor:Send> {
|
||||
self.native_listen(128).map(|a| ~a as ~rtio::RtioTcpAcceptor:Send)
|
||||
}
|
||||
}
|
||||
|
||||
@ -461,8 +461,8 @@ impl rtio::RtioSocket for TcpAcceptor {
|
||||
}
|
||||
|
||||
impl rtio::RtioTcpAcceptor for TcpAcceptor {
|
||||
fn accept(&mut self) -> IoResult<~rtio::RtioTcpStream> {
|
||||
self.native_accept().map(|s| ~s as ~rtio::RtioTcpStream)
|
||||
fn accept(&mut self) -> IoResult<~rtio::RtioTcpStream:Send> {
|
||||
self.native_accept().map(|s| ~s as ~rtio::RtioTcpStream:Send)
|
||||
}
|
||||
|
||||
fn accept_simultaneously(&mut self) -> IoResult<()> { Ok(()) }
|
||||
@ -630,7 +630,7 @@ impl rtio::RtioUdpSocket for UdpSocket {
|
||||
self.set_broadcast(false)
|
||||
}
|
||||
|
||||
fn clone(&self) -> ~rtio::RtioUdpSocket {
|
||||
~UdpSocket { inner: self.inner.clone() } as ~rtio::RtioUdpSocket
|
||||
fn clone(&self) -> ~rtio::RtioUdpSocket:Send {
|
||||
~UdpSocket { inner: self.inner.clone() } as ~rtio::RtioUdpSocket:Send
|
||||
}
|
||||
}
|
||||
|
@ -150,8 +150,8 @@ impl rtio::RtioPipe for UnixStream {
|
||||
}
|
||||
}
|
||||
|
||||
fn clone(&self) -> ~rtio::RtioPipe {
|
||||
~UnixStream { inner: self.inner.clone() } as ~rtio::RtioPipe
|
||||
fn clone(&self) -> ~rtio::RtioPipe:Send {
|
||||
~UnixStream { inner: self.inner.clone() } as ~rtio::RtioPipe:Send
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,8 +250,8 @@ impl UnixListener {
|
||||
}
|
||||
|
||||
impl rtio::RtioUnixListener for UnixListener {
|
||||
fn listen(~self) -> IoResult<~rtio::RtioUnixAcceptor> {
|
||||
self.native_listen(128).map(|a| ~a as ~rtio::RtioUnixAcceptor)
|
||||
fn listen(~self) -> IoResult<~rtio::RtioUnixAcceptor:Send> {
|
||||
self.native_listen(128).map(|a| ~a as ~rtio::RtioUnixAcceptor:Send)
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,7 +279,7 @@ impl UnixAcceptor {
|
||||
}
|
||||
|
||||
impl rtio::RtioUnixAcceptor for UnixAcceptor {
|
||||
fn accept(&mut self) -> IoResult<~rtio::RtioPipe> {
|
||||
self.native_accept().map(|s| ~s as ~rtio::RtioPipe)
|
||||
fn accept(&mut self) -> IoResult<~rtio::RtioPipe:Send> {
|
||||
self.native_accept().map(|s| ~s as ~rtio::RtioPipe:Send)
|
||||
}
|
||||
}
|
||||
|
@ -335,12 +335,12 @@ impl rtio::RtioPipe for UnixStream {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn clone(&self) -> ~rtio::RtioPipe {
|
||||
fn clone(&self) -> ~rtio::RtioPipe:Send {
|
||||
~UnixStream {
|
||||
inner: self.inner.clone(),
|
||||
read: None,
|
||||
write: None,
|
||||
} as ~rtio::RtioPipe
|
||||
} as ~rtio::RtioPipe:Send
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,8 +383,8 @@ impl Drop for UnixListener {
|
||||
}
|
||||
|
||||
impl rtio::RtioUnixListener for UnixListener {
|
||||
fn listen(~self) -> IoResult<~rtio::RtioUnixAcceptor> {
|
||||
self.native_listen().map(|a| ~a as ~rtio::RtioUnixAcceptor)
|
||||
fn listen(~self) -> IoResult<~rtio::RtioUnixAcceptor:Send> {
|
||||
self.native_listen().map(|a| ~a as ~rtio::RtioUnixAcceptor:Send)
|
||||
}
|
||||
}
|
||||
|
||||
@ -485,8 +485,8 @@ impl UnixAcceptor {
|
||||
}
|
||||
|
||||
impl rtio::RtioUnixAcceptor for UnixAcceptor {
|
||||
fn accept(&mut self) -> IoResult<~rtio::RtioPipe> {
|
||||
self.native_accept().map(|s| ~s as ~rtio::RtioPipe)
|
||||
fn accept(&mut self) -> IoResult<~rtio::RtioPipe:Send> {
|
||||
self.native_accept().map(|s| ~s as ~rtio::RtioPipe:Send)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ pub fn new(stack_bounds: (uint, uint)) -> ~Task {
|
||||
let mut task = ~Task::new();
|
||||
let mut ops = ops();
|
||||
ops.stack_bounds = stack_bounds;
|
||||
task.put_runtime(ops as ~rt::Runtime);
|
||||
task.put_runtime(ops);
|
||||
return task;
|
||||
}
|
||||
|
||||
@ -50,13 +50,13 @@ fn ops() -> ~Ops {
|
||||
}
|
||||
|
||||
/// Spawns a function with the default configuration
|
||||
pub fn spawn(f: proc()) {
|
||||
pub fn spawn(f: proc:Send()) {
|
||||
spawn_opts(TaskOpts::new(), f)
|
||||
}
|
||||
|
||||
/// Spawns a new task given the configuration options and a procedure to run
|
||||
/// inside the task.
|
||||
pub fn spawn_opts(opts: TaskOpts, f: proc()) {
|
||||
pub fn spawn_opts(opts: TaskOpts, f: proc:Send()) {
|
||||
let TaskOpts {
|
||||
notify_chan, name, stack_size,
|
||||
stderr, stdout,
|
||||
@ -98,7 +98,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
|
||||
|
||||
let mut f = Some(f);
|
||||
let mut task = task;
|
||||
task.put_runtime(ops as ~rt::Runtime);
|
||||
task.put_runtime(ops);
|
||||
let t = task.run(|| { f.take_unwrap()() });
|
||||
drop(t);
|
||||
bookkeeping::decrement();
|
||||
@ -121,7 +121,7 @@ struct Ops {
|
||||
impl rt::Runtime for Ops {
|
||||
fn yield_now(~self, mut cur_task: ~Task) {
|
||||
// put the task back in TLS and then invoke the OS thread yield
|
||||
cur_task.put_runtime(self as ~rt::Runtime);
|
||||
cur_task.put_runtime(self);
|
||||
Local::put(cur_task);
|
||||
Thread::yield_now();
|
||||
}
|
||||
@ -129,7 +129,7 @@ impl rt::Runtime for Ops {
|
||||
fn maybe_yield(~self, mut cur_task: ~Task) {
|
||||
// just put the task back in TLS, on OS threads we never need to
|
||||
// opportunistically yield b/c the OS will do that for us (preemption)
|
||||
cur_task.put_runtime(self as ~rt::Runtime);
|
||||
cur_task.put_runtime(self);
|
||||
Local::put(cur_task);
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ impl rt::Runtime for Ops {
|
||||
fn deschedule(mut ~self, times: uint, mut cur_task: ~Task,
|
||||
f: |BlockedTask| -> Result<(), BlockedTask>) {
|
||||
let me = &mut *self as *mut Ops;
|
||||
cur_task.put_runtime(self as ~rt::Runtime);
|
||||
cur_task.put_runtime(self);
|
||||
|
||||
unsafe {
|
||||
let cur_task_dupe = &*cur_task as *Task;
|
||||
@ -230,7 +230,7 @@ impl rt::Runtime for Ops {
|
||||
fn reawaken(mut ~self, mut to_wake: ~Task) {
|
||||
unsafe {
|
||||
let me = &mut *self as *mut Ops;
|
||||
to_wake.put_runtime(self as ~rt::Runtime);
|
||||
to_wake.put_runtime(self);
|
||||
cast::forget(to_wake);
|
||||
let guard = (*me).lock.lock();
|
||||
(*me).awoken = true;
|
||||
@ -238,8 +238,8 @@ impl rt::Runtime for Ops {
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_sibling(~self, mut cur_task: ~Task, opts: TaskOpts, f: proc()) {
|
||||
cur_task.put_runtime(self as ~rt::Runtime);
|
||||
fn spawn_sibling(~self, mut cur_task: ~Task, opts: TaskOpts, f: proc:Send()) {
|
||||
cur_task.put_runtime(self);
|
||||
Local::put(cur_task);
|
||||
|
||||
task::spawn_opts(opts, f);
|
||||
@ -252,7 +252,6 @@ impl rt::Runtime for Ops {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::rt::Runtime;
|
||||
use std::rt::local::Local;
|
||||
use std::rt::task::Task;
|
||||
use std::task;
|
||||
@ -335,7 +334,7 @@ mod tests {
|
||||
let mut task: ~Task = Local::take();
|
||||
match task.maybe_take_runtime::<Ops>() {
|
||||
Some(ops) => {
|
||||
task.put_runtime(ops as ~Runtime);
|
||||
task.put_runtime(ops);
|
||||
}
|
||||
None => fail!(),
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ fn parse_crate_attrs(sess: &session::Session, input: &d::Input) ->
|
||||
///
|
||||
/// The diagnostic emitter yielded to the procedure should be used for reporting
|
||||
/// errors of the compiler.
|
||||
pub fn monitor(f: proc()) {
|
||||
pub fn monitor(f: proc:Send()) {
|
||||
// FIXME: This is a hack for newsched since it doesn't support split stacks.
|
||||
// rustc needs a lot of stack! When optimizations are disabled, it needs
|
||||
// even *more* stack than usual as well.
|
||||
@ -387,7 +387,7 @@ pub fn monitor(f: proc()) {
|
||||
let mut r = io::ChanReader::new(rx);
|
||||
|
||||
match task_builder.try(proc() {
|
||||
io::stdio::set_stderr(~w as ~io::Writer);
|
||||
io::stdio::set_stderr(~w);
|
||||
f()
|
||||
}) {
|
||||
Ok(()) => { /* fallthrough */ }
|
||||
@ -425,7 +425,7 @@ pub fn monitor(f: proc()) {
|
||||
// Fail so the process returns a failure code, but don't pollute the
|
||||
// output with some unnecessary failure messages, we've already
|
||||
// printed everything that we needed to.
|
||||
io::stdio::set_stderr(~io::util::NullWriter as ~io::Writer);
|
||||
io::stdio::set_stderr(~io::util::NullWriter);
|
||||
fail!();
|
||||
}
|
||||
}
|
||||
|
@ -850,15 +850,12 @@ fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyPar
|
||||
}
|
||||
builtin_bounds
|
||||
},
|
||||
// ~Trait is sugar for ~Trait:Send.
|
||||
(&None, ty::UniqTraitStore) => {
|
||||
let mut set = ty::EmptyBuiltinBounds(); set.add(ty::BoundSend); set
|
||||
}
|
||||
// &'static Trait is sugar for &'static Trait:'static.
|
||||
(&None, ty::RegionTraitStore(ty::ReStatic)) => {
|
||||
let mut set = ty::EmptyBuiltinBounds(); set.add(ty::BoundStatic); set
|
||||
}
|
||||
// &'r Trait is sugar for &'r Trait:<no-bounds>.
|
||||
(&None, ty::RegionTraitStore(..)) => ty::EmptyBuiltinBounds(),
|
||||
// No bounds are automatically applied for &'r Trait or ~Trait
|
||||
(&None, ty::RegionTraitStore(..)) |
|
||||
(&None, ty::UniqTraitStore) => ty::EmptyBuiltinBounds(),
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
|
||||
let old = io::stdio::set_stderr(~w1);
|
||||
spawn(proc() {
|
||||
let mut p = io::ChanReader::new(rx);
|
||||
let mut err = old.unwrap_or(~io::stderr() as ~Writer);
|
||||
let mut err = old.unwrap_or(~io::stderr() as ~Writer:Send);
|
||||
io::util::copy(&mut p, &mut err).unwrap();
|
||||
});
|
||||
let emitter = diagnostic::EmitterWriter::new(~w2);
|
||||
|
@ -27,12 +27,12 @@ pub struct AsyncWatcher {
|
||||
}
|
||||
|
||||
struct Payload {
|
||||
callback: ~Callback,
|
||||
callback: ~Callback:Send,
|
||||
exit_flag: Exclusive<bool>,
|
||||
}
|
||||
|
||||
impl AsyncWatcher {
|
||||
pub fn new(loop_: &mut Loop, cb: ~Callback) -> AsyncWatcher {
|
||||
pub fn new(loop_: &mut Loop, cb: ~Callback:Send) -> AsyncWatcher {
|
||||
let handle = UvHandle::alloc(None::<AsyncWatcher>, uvll::UV_ASYNC);
|
||||
assert_eq!(unsafe {
|
||||
uvll::uv_async_init(loop_.handle, handle, async_cb)
|
||||
@ -149,8 +149,7 @@ mod test_remote {
|
||||
|
||||
let (tx, rx) = channel();
|
||||
let cb = ~MyCallback(Some(tx));
|
||||
let watcher = AsyncWatcher::new(&mut local_loop().loop_,
|
||||
cb as ~Callback);
|
||||
let watcher = AsyncWatcher::new(&mut local_loop().loop_, cb);
|
||||
|
||||
let thread = Thread::start(proc() {
|
||||
let mut watcher = watcher;
|
||||
|
@ -19,11 +19,11 @@ pub struct IdleWatcher {
|
||||
handle: *uvll::uv_idle_t,
|
||||
idle_flag: bool,
|
||||
closed: bool,
|
||||
callback: ~Callback,
|
||||
callback: ~Callback:Send,
|
||||
}
|
||||
|
||||
impl IdleWatcher {
|
||||
pub fn new(loop_: &mut Loop, cb: ~Callback) -> ~IdleWatcher {
|
||||
pub fn new(loop_: &mut Loop, cb: ~Callback:Send) -> ~IdleWatcher {
|
||||
let handle = UvHandle::alloc(None::<IdleWatcher>, uvll::UV_IDLE);
|
||||
assert_eq!(unsafe {
|
||||
uvll::uv_idle_init(loop_.handle, handle)
|
||||
|
@ -126,8 +126,8 @@ pub mod stream;
|
||||
/// // this code is running inside of a green task powered by libuv
|
||||
/// }
|
||||
/// ```
|
||||
pub fn event_loop() -> ~rtio::EventLoop {
|
||||
~uvio::UvEventLoop::new() as ~rtio::EventLoop
|
||||
pub fn event_loop() -> ~rtio::EventLoop:Send {
|
||||
~uvio::UvEventLoop::new() as ~rtio::EventLoop:Send
|
||||
}
|
||||
|
||||
/// A type that wraps a uv handle
|
||||
|
@ -167,8 +167,8 @@ pub struct TcpListener {
|
||||
home: HomeHandle,
|
||||
handle: *uvll::uv_pipe_t,
|
||||
priv closing_task: Option<BlockedTask>,
|
||||
priv outgoing: Sender<Result<~rtio::RtioTcpStream, IoError>>,
|
||||
priv incoming: Receiver<Result<~rtio::RtioTcpStream, IoError>>,
|
||||
priv outgoing: Sender<Result<~rtio::RtioTcpStream:Send, IoError>>,
|
||||
priv incoming: Receiver<Result<~rtio::RtioTcpStream:Send, IoError>>,
|
||||
}
|
||||
|
||||
pub struct TcpAcceptor {
|
||||
@ -295,7 +295,7 @@ impl rtio::RtioTcpStream for TcpWatcher {
|
||||
})
|
||||
}
|
||||
|
||||
fn clone(&self) -> ~rtio::RtioTcpStream {
|
||||
fn clone(&self) -> ~rtio::RtioTcpStream:Send {
|
||||
~TcpWatcher {
|
||||
handle: self.handle,
|
||||
stream: StreamWatcher::new(self.handle),
|
||||
@ -303,7 +303,7 @@ impl rtio::RtioTcpStream for TcpWatcher {
|
||||
refcount: self.refcount.clone(),
|
||||
write_access: self.write_access.clone(),
|
||||
read_access: self.read_access.clone(),
|
||||
} as ~rtio::RtioTcpStream
|
||||
} as ~rtio::RtioTcpStream:Send
|
||||
}
|
||||
|
||||
fn close_write(&mut self) -> Result<(), IoError> {
|
||||
@ -397,14 +397,14 @@ impl rtio::RtioSocket for TcpListener {
|
||||
}
|
||||
|
||||
impl rtio::RtioTcpListener for TcpListener {
|
||||
fn listen(~self) -> Result<~rtio::RtioTcpAcceptor, IoError> {
|
||||
fn listen(~self) -> Result<~rtio::RtioTcpAcceptor:Send, IoError> {
|
||||
// create the acceptor object from ourselves
|
||||
let mut acceptor = ~TcpAcceptor { listener: self };
|
||||
|
||||
let _m = acceptor.fire_homing_missile();
|
||||
// FIXME: the 128 backlog should be configurable
|
||||
match unsafe { uvll::uv_listen(acceptor.listener.handle, 128, listen_cb) } {
|
||||
0 => Ok(acceptor as ~rtio::RtioTcpAcceptor),
|
||||
0 => Ok(acceptor as ~rtio::RtioTcpAcceptor:Send),
|
||||
n => Err(uv_error_to_io_error(UvError(n))),
|
||||
}
|
||||
}
|
||||
@ -420,7 +420,7 @@ extern fn listen_cb(server: *uvll::uv_stream_t, status: c_int) {
|
||||
});
|
||||
let client = TcpWatcher::new_home(&loop_, tcp.home().clone());
|
||||
assert_eq!(unsafe { uvll::uv_accept(server, client.handle) }, 0);
|
||||
Ok(~client as ~rtio::RtioTcpStream)
|
||||
Ok(~client as ~rtio::RtioTcpStream:Send)
|
||||
}
|
||||
n => Err(uv_error_to_io_error(UvError(n)))
|
||||
};
|
||||
@ -448,7 +448,7 @@ impl rtio::RtioSocket for TcpAcceptor {
|
||||
}
|
||||
|
||||
impl rtio::RtioTcpAcceptor for TcpAcceptor {
|
||||
fn accept(&mut self) -> Result<~rtio::RtioTcpStream, IoError> {
|
||||
fn accept(&mut self) -> Result<~rtio::RtioTcpStream:Send, IoError> {
|
||||
self.listener.incoming.recv()
|
||||
}
|
||||
|
||||
@ -709,14 +709,14 @@ impl rtio::RtioUdpSocket for UdpWatcher {
|
||||
})
|
||||
}
|
||||
|
||||
fn clone(&self) -> ~rtio::RtioUdpSocket {
|
||||
fn clone(&self) -> ~rtio::RtioUdpSocket:Send {
|
||||
~UdpWatcher {
|
||||
handle: self.handle,
|
||||
home: self.home.clone(),
|
||||
refcount: self.refcount.clone(),
|
||||
write_access: self.write_access.clone(),
|
||||
read_access: self.read_access.clone(),
|
||||
} as ~rtio::RtioUdpSocket
|
||||
} as ~rtio::RtioUdpSocket:Send
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,8 @@ pub struct PipeWatcher {
|
||||
pub struct PipeListener {
|
||||
home: HomeHandle,
|
||||
pipe: *uvll::uv_pipe_t,
|
||||
priv outgoing: Sender<Result<~RtioPipe, IoError>>,
|
||||
priv incoming: Receiver<Result<~RtioPipe, IoError>>,
|
||||
priv outgoing: Sender<Result<~RtioPipe:Send, IoError>>,
|
||||
priv incoming: Receiver<Result<~RtioPipe:Send, IoError>>,
|
||||
}
|
||||
|
||||
pub struct PipeAcceptor {
|
||||
@ -139,7 +139,7 @@ impl RtioPipe for PipeWatcher {
|
||||
self.stream.write(buf).map_err(uv_error_to_io_error)
|
||||
}
|
||||
|
||||
fn clone(&self) -> ~RtioPipe {
|
||||
fn clone(&self) -> ~RtioPipe:Send {
|
||||
~PipeWatcher {
|
||||
stream: StreamWatcher::new(self.stream.handle),
|
||||
defused: false,
|
||||
@ -147,7 +147,7 @@ impl RtioPipe for PipeWatcher {
|
||||
refcount: self.refcount.clone(),
|
||||
read_access: self.read_access.clone(),
|
||||
write_access: self.write_access.clone(),
|
||||
} as ~RtioPipe
|
||||
} as ~RtioPipe:Send
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,14 +197,14 @@ impl PipeListener {
|
||||
}
|
||||
|
||||
impl RtioUnixListener for PipeListener {
|
||||
fn listen(~self) -> Result<~RtioUnixAcceptor, IoError> {
|
||||
fn listen(~self) -> Result<~RtioUnixAcceptor:Send, IoError> {
|
||||
// create the acceptor object from ourselves
|
||||
let mut acceptor = ~PipeAcceptor { listener: self };
|
||||
|
||||
let _m = acceptor.fire_homing_missile();
|
||||
// FIXME: the 128 backlog should be configurable
|
||||
match unsafe { uvll::uv_listen(acceptor.listener.pipe, 128, listen_cb) } {
|
||||
0 => Ok(acceptor as ~RtioUnixAcceptor),
|
||||
0 => Ok(acceptor as ~RtioUnixAcceptor:Send),
|
||||
n => Err(uv_error_to_io_error(UvError(n))),
|
||||
}
|
||||
}
|
||||
@ -229,7 +229,7 @@ extern fn listen_cb(server: *uvll::uv_stream_t, status: libc::c_int) {
|
||||
});
|
||||
let client = PipeWatcher::new_home(&loop_, pipe.home().clone(), false);
|
||||
assert_eq!(unsafe { uvll::uv_accept(server, client.handle()) }, 0);
|
||||
Ok(~client as ~RtioPipe)
|
||||
Ok(~client as ~RtioPipe:Send)
|
||||
}
|
||||
n => Err(uv_error_to_io_error(UvError(n)))
|
||||
};
|
||||
@ -246,7 +246,7 @@ impl Drop for PipeListener {
|
||||
// PipeAcceptor implementation and traits
|
||||
|
||||
impl RtioUnixAcceptor for PipeAcceptor {
|
||||
fn accept(&mut self) -> Result<~RtioPipe, IoError> {
|
||||
fn accept(&mut self) -> Result<~RtioPipe:Send, IoError> {
|
||||
self.listener.incoming.recv()
|
||||
}
|
||||
}
|
||||
|
@ -85,14 +85,17 @@ impl rtio::EventLoop for UvEventLoop {
|
||||
IdleWatcher::onetime(&mut self.uvio.loop_, f);
|
||||
}
|
||||
|
||||
fn pausable_idle_callback(&mut self, cb: ~rtio::Callback)
|
||||
-> ~rtio::PausableIdleCallback
|
||||
fn pausable_idle_callback(&mut self, cb: ~rtio::Callback:Send)
|
||||
-> ~rtio::PausableIdleCallback:Send
|
||||
{
|
||||
IdleWatcher::new(&mut self.uvio.loop_, cb) as ~rtio::PausableIdleCallback
|
||||
IdleWatcher::new(&mut self.uvio.loop_,
|
||||
cb) as ~rtio::PausableIdleCallback:Send
|
||||
}
|
||||
|
||||
fn remote_callback(&mut self, f: ~rtio::Callback) -> ~rtio::RemoteCallback {
|
||||
~AsyncWatcher::new(&mut self.uvio.loop_, f) as ~rtio::RemoteCallback
|
||||
fn remote_callback(&mut self, f: ~rtio::Callback:Send)
|
||||
-> ~rtio::RemoteCallback:Send
|
||||
{
|
||||
~AsyncWatcher::new(&mut self.uvio.loop_, f) as ~rtio::RemoteCallback:Send
|
||||
}
|
||||
|
||||
fn io<'a>(&'a mut self) -> Option<&'a mut rtio::IoFactory> {
|
||||
@ -141,30 +144,30 @@ impl IoFactory for UvIoFactory {
|
||||
// NB: This blocks the task waiting on the connection.
|
||||
// It would probably be better to return a future
|
||||
fn tcp_connect(&mut self, addr: SocketAddr)
|
||||
-> Result<~rtio::RtioTcpStream, IoError>
|
||||
-> Result<~rtio::RtioTcpStream:Send, IoError>
|
||||
{
|
||||
match TcpWatcher::connect(self, addr) {
|
||||
Ok(t) => Ok(~t as ~rtio::RtioTcpStream),
|
||||
Ok(t) => Ok(~t as ~rtio::RtioTcpStream:Send),
|
||||
Err(e) => Err(uv_error_to_io_error(e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~rtio::RtioTcpListener, IoError> {
|
||||
fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~rtio::RtioTcpListener:Send, IoError> {
|
||||
match TcpListener::bind(self, addr) {
|
||||
Ok(t) => Ok(t as ~rtio::RtioTcpListener),
|
||||
Ok(t) => Ok(t as ~rtio::RtioTcpListener:Send),
|
||||
Err(e) => Err(uv_error_to_io_error(e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> Result<~rtio::RtioUdpSocket, IoError> {
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> Result<~rtio::RtioUdpSocket:Send, IoError> {
|
||||
match UdpWatcher::bind(self, addr) {
|
||||
Ok(u) => Ok(~u as ~rtio::RtioUdpSocket),
|
||||
Ok(u) => Ok(~u as ~rtio::RtioUdpSocket:Send),
|
||||
Err(e) => Err(uv_error_to_io_error(e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn timer_init(&mut self) -> Result<~rtio::RtioTimer, IoError> {
|
||||
Ok(TimerWatcher::new(self) as ~rtio::RtioTimer)
|
||||
fn timer_init(&mut self) -> Result<~rtio::RtioTimer:Send, IoError> {
|
||||
Ok(TimerWatcher::new(self) as ~rtio::RtioTimer:Send)
|
||||
}
|
||||
|
||||
fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
|
||||
@ -174,12 +177,12 @@ impl IoFactory for UvIoFactory {
|
||||
}
|
||||
|
||||
fn fs_from_raw_fd(&mut self, fd: c_int,
|
||||
close: rtio::CloseBehavior) -> ~rtio::RtioFileStream {
|
||||
~FileWatcher::new(self, fd, close) as ~rtio::RtioFileStream
|
||||
close: rtio::CloseBehavior) -> ~rtio::RtioFileStream:Send {
|
||||
~FileWatcher::new(self, fd, close) as ~rtio::RtioFileStream:Send
|
||||
}
|
||||
|
||||
fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
|
||||
-> Result<~rtio::RtioFileStream, IoError> {
|
||||
-> Result<~rtio::RtioFileStream:Send, IoError> {
|
||||
let flags = match fm {
|
||||
io::Open => 0,
|
||||
io::Append => libc::O_APPEND,
|
||||
@ -195,7 +198,7 @@ impl IoFactory for UvIoFactory {
|
||||
};
|
||||
|
||||
match FsRequest::open(self, path, flags as int, mode as int) {
|
||||
Ok(fs) => Ok(~fs as ~rtio::RtioFileStream),
|
||||
Ok(fs) => Ok(~fs as ~rtio::RtioFileStream:Send),
|
||||
Err(e) => Err(uv_error_to_io_error(e))
|
||||
}
|
||||
}
|
||||
@ -260,12 +263,12 @@ impl IoFactory for UvIoFactory {
|
||||
}
|
||||
|
||||
fn spawn(&mut self, config: ProcessConfig)
|
||||
-> Result<(~rtio::RtioProcess, ~[Option<~rtio::RtioPipe>]), IoError>
|
||||
-> Result<(~rtio::RtioProcess:Send, ~[Option<~rtio::RtioPipe:Send>]), IoError>
|
||||
{
|
||||
match Process::spawn(self, config) {
|
||||
Ok((p, io)) => {
|
||||
Ok((p as ~rtio::RtioProcess,
|
||||
io.move_iter().map(|i| i.map(|p| ~p as ~rtio::RtioPipe)).collect()))
|
||||
Ok((p as ~rtio::RtioProcess:Send,
|
||||
io.move_iter().map(|i| i.map(|p| ~p as ~rtio::RtioPipe:Send)).collect()))
|
||||
}
|
||||
Err(e) => Err(uv_error_to_io_error(e)),
|
||||
}
|
||||
@ -275,40 +278,40 @@ impl IoFactory for UvIoFactory {
|
||||
Process::kill(pid, signum).map_err(uv_error_to_io_error)
|
||||
}
|
||||
|
||||
fn unix_bind(&mut self, path: &CString) -> Result<~rtio::RtioUnixListener, IoError>
|
||||
fn unix_bind(&mut self, path: &CString) -> Result<~rtio::RtioUnixListener:Send, IoError>
|
||||
{
|
||||
match PipeListener::bind(self, path) {
|
||||
Ok(p) => Ok(p as ~rtio::RtioUnixListener),
|
||||
Ok(p) => Ok(p as ~rtio::RtioUnixListener:Send),
|
||||
Err(e) => Err(uv_error_to_io_error(e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn unix_connect(&mut self, path: &CString) -> Result<~rtio::RtioPipe, IoError> {
|
||||
fn unix_connect(&mut self, path: &CString) -> Result<~rtio::RtioPipe:Send, IoError> {
|
||||
match PipeWatcher::connect(self, path) {
|
||||
Ok(p) => Ok(~p as ~rtio::RtioPipe),
|
||||
Ok(p) => Ok(~p as ~rtio::RtioPipe:Send),
|
||||
Err(e) => Err(uv_error_to_io_error(e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn tty_open(&mut self, fd: c_int, readable: bool)
|
||||
-> Result<~rtio::RtioTTY, IoError> {
|
||||
-> Result<~rtio::RtioTTY:Send, IoError> {
|
||||
match TtyWatcher::new(self, fd, readable) {
|
||||
Ok(tty) => Ok(~tty as ~rtio::RtioTTY),
|
||||
Ok(tty) => Ok(~tty as ~rtio::RtioTTY:Send),
|
||||
Err(e) => Err(uv_error_to_io_error(e))
|
||||
}
|
||||
}
|
||||
|
||||
fn pipe_open(&mut self, fd: c_int) -> Result<~rtio::RtioPipe, IoError> {
|
||||
fn pipe_open(&mut self, fd: c_int) -> Result<~rtio::RtioPipe:Send, IoError> {
|
||||
match PipeWatcher::open(self, fd) {
|
||||
Ok(s) => Ok(~s as ~rtio::RtioPipe),
|
||||
Ok(s) => Ok(~s as ~rtio::RtioPipe:Send),
|
||||
Err(e) => Err(uv_error_to_io_error(e))
|
||||
}
|
||||
}
|
||||
|
||||
fn signal(&mut self, signum: Signum, channel: Sender<Signum>)
|
||||
-> Result<~rtio::RtioSignal, IoError> {
|
||||
-> Result<~rtio::RtioSignal:Send, IoError> {
|
||||
match SignalWatcher::new(self, signum, channel) {
|
||||
Ok(s) => Ok(s as ~rtio::RtioSignal),
|
||||
Ok(s) => Ok(s as ~rtio::RtioSignal:Send),
|
||||
Err(e) => Err(uv_error_to_io_error(e)),
|
||||
}
|
||||
}
|
||||
|
@ -2600,6 +2600,6 @@ mod tests {
|
||||
Ok(o) => o
|
||||
};
|
||||
let mut decoder = Decoder::new(json_obj);
|
||||
let hm: HashMap<uint, bool> = Decodable::decode(&mut decoder);
|
||||
let _hm: HashMap<uint, bool> = Decodable::decode(&mut decoder);
|
||||
}
|
||||
}
|
||||
|
@ -35,17 +35,18 @@
|
||||
|
||||
use cast;
|
||||
use container::Container;
|
||||
use ptr;
|
||||
use ptr::RawPtr;
|
||||
use raw;
|
||||
use option::{Option, Some, None};
|
||||
use kinds::Send;
|
||||
use ops::Drop;
|
||||
use option::{Option, Some, None};
|
||||
use ptr::RawPtr;
|
||||
use ptr;
|
||||
use raw;
|
||||
|
||||
/// The type representing a foreign chunk of memory
|
||||
pub struct CVec<T> {
|
||||
priv base: *mut T,
|
||||
priv len: uint,
|
||||
priv dtor: Option<proc()>,
|
||||
priv dtor: Option<proc:Send()>,
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
@ -89,7 +90,7 @@ impl<T> CVec<T> {
|
||||
/// * dtor - A proc to run when the value is destructed, useful
|
||||
/// for freeing the buffer, etc.
|
||||
pub unsafe fn new_with_dtor(base: *mut T, len: uint,
|
||||
dtor: proc()) -> CVec<T> {
|
||||
dtor: proc:Send()) -> CVec<T> {
|
||||
assert!(base != ptr::mut_null());
|
||||
CVec {
|
||||
base: base,
|
||||
|
@ -53,6 +53,7 @@ use c_str::ToCStr;
|
||||
use clone::Clone;
|
||||
use container::Container;
|
||||
use iter::Iterator;
|
||||
use kinds::Send;
|
||||
use super::{Reader, Writer, Seek};
|
||||
use super::{SeekStyle, Read, Write, Open, IoError, Truncate,
|
||||
FileMode, FileAccess, FileStat, IoResult, FilePermission};
|
||||
@ -77,7 +78,7 @@ use vec::Vec;
|
||||
/// configured at creation time, via the `FileAccess` parameter to
|
||||
/// `File::open_mode()`.
|
||||
pub struct File {
|
||||
priv fd: ~RtioFileStream,
|
||||
priv fd: ~RtioFileStream:Send,
|
||||
priv path: Path,
|
||||
priv last_nread: int,
|
||||
}
|
||||
|
@ -20,9 +20,10 @@
|
||||
#[deny(missing_doc)];
|
||||
|
||||
use clone::Clone;
|
||||
use io::IoResult;
|
||||
use io::net::ip::SocketAddr;
|
||||
use io::{Reader, Writer, Listener, Acceptor};
|
||||
use io::IoResult;
|
||||
use kinds::Send;
|
||||
use rt::rtio::{IoFactory, LocalIo, RtioSocket, RtioTcpListener};
|
||||
use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
|
||||
|
||||
@ -45,11 +46,11 @@ use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
|
||||
/// drop(stream); // close the connection
|
||||
/// ```
|
||||
pub struct TcpStream {
|
||||
priv obj: ~RtioTcpStream
|
||||
priv obj: ~RtioTcpStream:Send
|
||||
}
|
||||
|
||||
impl TcpStream {
|
||||
fn new(s: ~RtioTcpStream) -> TcpStream {
|
||||
fn new(s: ~RtioTcpStream:Send) -> TcpStream {
|
||||
TcpStream { obj: s }
|
||||
}
|
||||
|
||||
@ -127,7 +128,7 @@ impl Writer for TcpStream {
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct TcpListener {
|
||||
priv obj: ~RtioTcpListener
|
||||
priv obj: ~RtioTcpListener:Send
|
||||
}
|
||||
|
||||
impl TcpListener {
|
||||
@ -160,7 +161,7 @@ impl Listener<TcpStream, TcpAcceptor> for TcpListener {
|
||||
/// a `TcpListener`'s `listen` method, and this object can be used to accept new
|
||||
/// `TcpStream` instances.
|
||||
pub struct TcpAcceptor {
|
||||
priv obj: ~RtioTcpAcceptor
|
||||
priv obj: ~RtioTcpAcceptor:Send
|
||||
}
|
||||
|
||||
impl Acceptor<TcpStream> for TcpAcceptor {
|
||||
|
@ -16,9 +16,10 @@
|
||||
//! datagram protocol.
|
||||
|
||||
use clone::Clone;
|
||||
use result::{Ok, Err};
|
||||
use io::net::ip::SocketAddr;
|
||||
use io::{Reader, Writer, IoResult};
|
||||
use kinds::Send;
|
||||
use result::{Ok, Err};
|
||||
use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
|
||||
|
||||
/// A User Datagram Protocol socket.
|
||||
@ -53,7 +54,7 @@ use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
|
||||
/// drop(socket); // close the socket
|
||||
/// ```
|
||||
pub struct UdpSocket {
|
||||
priv obj: ~RtioUdpSocket
|
||||
priv obj: ~RtioUdpSocket:Send
|
||||
}
|
||||
|
||||
impl UdpSocket {
|
||||
|
@ -28,10 +28,11 @@ use prelude::*;
|
||||
|
||||
use c_str::ToCStr;
|
||||
use clone::Clone;
|
||||
use rt::rtio::{IoFactory, LocalIo, RtioUnixListener};
|
||||
use rt::rtio::{RtioUnixAcceptor, RtioPipe};
|
||||
use io::pipe::PipeStream;
|
||||
use io::{Listener, Acceptor, Reader, Writer, IoResult};
|
||||
use kinds::Send;
|
||||
use rt::rtio::{IoFactory, LocalIo, RtioUnixListener};
|
||||
use rt::rtio::{RtioUnixAcceptor, RtioPipe};
|
||||
|
||||
/// A stream which communicates over a named pipe.
|
||||
pub struct UnixStream {
|
||||
@ -39,7 +40,7 @@ pub struct UnixStream {
|
||||
}
|
||||
|
||||
impl UnixStream {
|
||||
fn new(obj: ~RtioPipe) -> UnixStream {
|
||||
fn new(obj: ~RtioPipe:Send) -> UnixStream {
|
||||
UnixStream { obj: PipeStream::new(obj) }
|
||||
}
|
||||
|
||||
@ -82,7 +83,7 @@ impl Writer for UnixStream {
|
||||
/// A value that can listen for incoming named pipe connection requests.
|
||||
pub struct UnixListener {
|
||||
/// The internal, opaque runtime Unix listener.
|
||||
priv obj: ~RtioUnixListener,
|
||||
priv obj: ~RtioUnixListener:Send,
|
||||
}
|
||||
|
||||
impl UnixListener {
|
||||
@ -124,7 +125,7 @@ impl Listener<UnixStream, UnixAcceptor> for UnixListener {
|
||||
/// A value that can accept named pipe connections, returned from `listen()`.
|
||||
pub struct UnixAcceptor {
|
||||
/// The internal, opaque runtime Unix acceptor.
|
||||
priv obj: ~RtioUnixAcceptor,
|
||||
priv obj: ~RtioUnixAcceptor:Send,
|
||||
}
|
||||
|
||||
impl Acceptor<UnixStream> for UnixAcceptor {
|
||||
@ -140,7 +141,7 @@ mod tests {
|
||||
use io::*;
|
||||
use io::test::*;
|
||||
|
||||
pub fn smalltest(server: proc(UnixStream), client: proc(UnixStream)) {
|
||||
pub fn smalltest(server: proc:Send(UnixStream), client: proc:Send(UnixStream)) {
|
||||
let path1 = next_test_unix();
|
||||
let path2 = path1.clone();
|
||||
|
||||
|
@ -23,7 +23,7 @@ use rt::rtio::{RtioPipe, LocalIo};
|
||||
/// A synchronous, in-memory pipe.
|
||||
pub struct PipeStream {
|
||||
/// The internal, opaque runtime pipe object.
|
||||
priv obj: ~RtioPipe,
|
||||
priv obj: ~RtioPipe:Send,
|
||||
}
|
||||
|
||||
impl PipeStream {
|
||||
@ -51,7 +51,7 @@ impl PipeStream {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn new(inner: ~RtioPipe) -> PipeStream {
|
||||
pub fn new(inner: ~RtioPipe:Send) -> PipeStream {
|
||||
PipeStream { obj: inner }
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ use rt::rtio::{RtioProcess, IoFactory, LocalIo};
|
||||
/// assert!(child.wait().success());
|
||||
/// ```
|
||||
pub struct Process {
|
||||
priv handle: ~RtioProcess,
|
||||
priv handle: ~RtioProcess:Send,
|
||||
|
||||
/// Handle to the child's stdin, if the `stdin` field of this process's
|
||||
/// `ProcessConfig` was `CreatePipe`. By default, this handle is `Some`.
|
||||
|
@ -32,6 +32,7 @@ use fmt;
|
||||
use io::{Reader, Writer, IoResult, IoError, OtherIoError,
|
||||
standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
|
||||
use libc;
|
||||
use kinds::Send;
|
||||
use mem::replace;
|
||||
use option::{Option, Some, None};
|
||||
use prelude::drop;
|
||||
@ -71,8 +72,8 @@ use slice::ImmutableVector;
|
||||
// tl;dr; TTY works on everything but when windows stdout is redirected, in that
|
||||
// case pipe also doesn't work, but magically file does!
|
||||
enum StdSource {
|
||||
TTY(~RtioTTY),
|
||||
File(~RtioFileStream),
|
||||
TTY(~RtioTTY:Send),
|
||||
File(~RtioFileStream:Send),
|
||||
}
|
||||
|
||||
fn src<T>(fd: libc::c_int, readable: bool, f: |StdSource| -> T) -> T {
|
||||
@ -145,8 +146,10 @@ pub fn stderr_raw() -> StdWriter {
|
||||
src(libc::STDERR_FILENO, false, |src| StdWriter { inner: src })
|
||||
}
|
||||
|
||||
fn reset_helper(w: ~Writer,
|
||||
f: |&mut Task, ~Writer| -> Option<~Writer>) -> Option<~Writer> {
|
||||
fn reset_helper(w: ~Writer:Send,
|
||||
f: |&mut Task, ~Writer:Send| -> Option<~Writer:Send>)
|
||||
-> Option<~Writer:Send>
|
||||
{
|
||||
let mut t = Local::borrow(None::<Task>);
|
||||
// Be sure to flush any pending output from the writer
|
||||
match f(t.get(), w) {
|
||||
@ -168,7 +171,7 @@ fn reset_helper(w: ~Writer,
|
||||
///
|
||||
/// Note that this does not need to be called for all new tasks; the default
|
||||
/// output handle is to the process's stdout stream.
|
||||
pub fn set_stdout(stdout: ~Writer) -> Option<~Writer> {
|
||||
pub fn set_stdout(stdout: ~Writer:Send) -> Option<~Writer:Send> {
|
||||
reset_helper(stdout, |t, w| replace(&mut t.stdout, Some(w)))
|
||||
}
|
||||
|
||||
@ -180,7 +183,7 @@ pub fn set_stdout(stdout: ~Writer) -> Option<~Writer> {
|
||||
///
|
||||
/// Note that this does not need to be called for all new tasks; the default
|
||||
/// output handle is to the process's stderr stream.
|
||||
pub fn set_stderr(stderr: ~Writer) -> Option<~Writer> {
|
||||
pub fn set_stderr(stderr: ~Writer:Send) -> Option<~Writer:Send> {
|
||||
reset_helper(stderr, |t, w| replace(&mut t.stderr, Some(w)))
|
||||
}
|
||||
|
||||
@ -206,7 +209,7 @@ fn with_task_stdout(f: |&mut Writer| -> IoResult<()> ) {
|
||||
Local::put(task);
|
||||
|
||||
if my_stdout.is_none() {
|
||||
my_stdout = Some(~stdout() as ~Writer);
|
||||
my_stdout = Some(~stdout() as ~Writer:Send);
|
||||
}
|
||||
let ret = f(*my_stdout.get_mut_ref());
|
||||
|
||||
@ -399,7 +402,7 @@ mod tests {
|
||||
let (tx, rx) = channel();
|
||||
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
|
||||
spawn(proc() {
|
||||
set_stdout(~w as ~Writer);
|
||||
set_stdout(~w);
|
||||
println!("hello!");
|
||||
});
|
||||
assert_eq!(r.read_to_str().unwrap(), ~"hello!\n");
|
||||
@ -411,7 +414,7 @@ mod tests {
|
||||
let (tx, rx) = channel();
|
||||
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
|
||||
spawn(proc() {
|
||||
set_stderr(~w as ~Writer);
|
||||
set_stderr(~w);
|
||||
fail!("my special message");
|
||||
});
|
||||
let s = r.read_to_str().unwrap();
|
||||
|
@ -18,8 +18,9 @@ and create receivers which will receive notifications after a period of time.
|
||||
*/
|
||||
|
||||
use comm::Receiver;
|
||||
use rt::rtio::{IoFactory, LocalIo, RtioTimer};
|
||||
use io::IoResult;
|
||||
use kinds::Send;
|
||||
use rt::rtio::{IoFactory, LocalIo, RtioTimer};
|
||||
|
||||
/// A synchronous timer object
|
||||
///
|
||||
@ -62,7 +63,7 @@ use io::IoResult;
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct Timer {
|
||||
priv obj: ~RtioTimer
|
||||
priv obj: ~RtioTimer:Send,
|
||||
}
|
||||
|
||||
/// Sleep the current task for `msecs` milliseconds.
|
||||
|
@ -41,11 +41,12 @@ local_data::get(key_vector, |opt| assert_eq!(*opt.unwrap(), ~[4]));
|
||||
// magic.
|
||||
|
||||
use cast;
|
||||
use option::{None, Option, Some};
|
||||
use slice::{ImmutableVector, MutableVector, OwnedVector};
|
||||
use iter::{Iterator};
|
||||
use rt::task::{Task, LocalStorage};
|
||||
use kinds::Send;
|
||||
use mem::replace;
|
||||
use option::{None, Option, Some};
|
||||
use rt::task::{Task, LocalStorage};
|
||||
use slice::{ImmutableVector, MutableVector, OwnedVector};
|
||||
|
||||
/**
|
||||
* Indexes a task-local data slot. This pointer is used for comparison to
|
||||
@ -89,7 +90,7 @@ impl<T: 'static> LocalData for T {}
|
||||
// a proper map.
|
||||
#[doc(hidden)]
|
||||
pub type Map = ~[Option<(*u8, TLSValue, LoanState)>];
|
||||
type TLSValue = ~LocalData;
|
||||
type TLSValue = ~LocalData:Send;
|
||||
|
||||
// Gets the map from the runtime. Lazily initialises if not done so already.
|
||||
unsafe fn get_local_map() -> &mut Map {
|
||||
@ -328,7 +329,7 @@ pub fn set<T: 'static>(key: Key<T>, data: T) {
|
||||
// transmute here to add the Send bound back on. This doesn't actually
|
||||
// matter because TLS will always own the data (until its moved out) and
|
||||
// we're not actually sending it to other schedulers or anything.
|
||||
let data: ~LocalData = unsafe { cast::transmute(data) };
|
||||
let data: ~LocalData:Send = unsafe { cast::transmute(data) };
|
||||
match insertion_position(map, keyval) {
|
||||
Some(i) => { map[i] = Some((keyval, data, NoLoan)); }
|
||||
None => { map.push(Some((keyval, data, NoLoan))); }
|
||||
|
@ -686,7 +686,7 @@ fn test_repr() {
|
||||
exact_test(&println, "fn(&str)");
|
||||
exact_test(&swap::<int>, "fn(&mut int, &mut int)");
|
||||
exact_test(&is_alphabetic, "fn(char) -> bool");
|
||||
exact_test(&(~5 as ~ToStr), "~to_str::ToStr:Send");
|
||||
exact_test(&(~5 as ~ToStr), "~to_str::ToStr<no-bounds>");
|
||||
|
||||
struct Foo;
|
||||
exact_test(&(~[Foo, Foo]), "~[repr::test_repr::Foo, repr::test_repr::Foo]");
|
||||
|
@ -14,13 +14,14 @@
|
||||
|
||||
use cast;
|
||||
use iter::Iterator;
|
||||
use kinds::Send;
|
||||
use mem;
|
||||
use option::{Some, None};
|
||||
use ptr::RawPtr;
|
||||
use unstable::sync::Exclusive;
|
||||
use slice::OwnedVector;
|
||||
|
||||
type Queue = Exclusive<~[proc()]>;
|
||||
type Queue = Exclusive<~[proc:Send()]>;
|
||||
|
||||
// You'll note that these variables are *not* atomic, and this is done on
|
||||
// purpose. This module is designed to have init() called *once* in a
|
||||
@ -39,7 +40,7 @@ pub fn init() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(f: proc()) {
|
||||
pub fn push(f: proc:Send()) {
|
||||
unsafe {
|
||||
rtassert!(!RUNNING);
|
||||
rtassert!(!QUEUE.is_null());
|
||||
|
@ -55,6 +55,7 @@ Several modules in `core` are clients of `rt`:
|
||||
#[allow(missing_doc)];
|
||||
|
||||
use any::Any;
|
||||
use kinds::Send;
|
||||
use option::Option;
|
||||
use result::Result;
|
||||
use task::TaskOpts;
|
||||
@ -156,7 +157,7 @@ pub trait Runtime {
|
||||
|
||||
// Miscellaneous calls which are very different depending on what context
|
||||
// you're in.
|
||||
fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc());
|
||||
fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc:Send());
|
||||
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>>;
|
||||
/// The (low, high) edges of the current stack.
|
||||
fn stack_bounds(&self) -> (uint, uint); // (lo, hi)
|
||||
@ -195,7 +196,7 @@ pub fn init(argc: int, argv: **u8) {
|
||||
///
|
||||
/// It is forbidden for procedures to register more `at_exit` handlers when they
|
||||
/// are running, and doing so will lead to a process abort.
|
||||
pub fn at_exit(f: proc()) {
|
||||
pub fn at_exit(f: proc:Send()) {
|
||||
at_exit_imp::push(f);
|
||||
}
|
||||
|
||||
|
@ -13,16 +13,17 @@ use cast;
|
||||
use comm::{Sender, Receiver};
|
||||
use libc::c_int;
|
||||
use libc;
|
||||
use kinds::Send;
|
||||
use ops::Drop;
|
||||
use option::{Option, Some, None};
|
||||
use path::Path;
|
||||
use result::{Result, Err};
|
||||
use rt::task::Task;
|
||||
use result::Err;
|
||||
use rt::local::Local;
|
||||
use rt::task::Task;
|
||||
|
||||
use ai = io::net::addrinfo;
|
||||
use io;
|
||||
use io::{IoError, IoResult};
|
||||
use io::IoResult;
|
||||
use io::net::ip::{IpAddr, SocketAddr};
|
||||
use io::process::{ProcessConfig, ProcessExit};
|
||||
use io::signal::Signum;
|
||||
@ -35,9 +36,10 @@ pub trait Callback {
|
||||
|
||||
pub trait EventLoop {
|
||||
fn run(&mut self);
|
||||
fn callback(&mut self, proc());
|
||||
fn pausable_idle_callback(&mut self, ~Callback) -> ~PausableIdleCallback;
|
||||
fn remote_callback(&mut self, ~Callback) -> ~RemoteCallback;
|
||||
fn callback(&mut self, arg: proc:Send());
|
||||
fn pausable_idle_callback(&mut self,
|
||||
~Callback:Send) -> ~PausableIdleCallback:Send;
|
||||
fn remote_callback(&mut self, ~Callback:Send) -> ~RemoteCallback:Send;
|
||||
|
||||
/// The asynchronous I/O services. Not all event loops may provide one.
|
||||
fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory>;
|
||||
@ -143,93 +145,94 @@ impl<'a> LocalIo<'a> {
|
||||
|
||||
pub trait IoFactory {
|
||||
// networking
|
||||
fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStream, IoError>;
|
||||
fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListener, IoError>;
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocket, IoError>;
|
||||
fn unix_bind(&mut self, path: &CString) ->
|
||||
Result<~RtioUnixListener, IoError>;
|
||||
fn unix_connect(&mut self, path: &CString) -> Result<~RtioPipe, IoError>;
|
||||
fn tcp_connect(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpStream:Send>;
|
||||
fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener:Send>;
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioUdpSocket:Send>;
|
||||
fn unix_bind(&mut self, path: &CString)
|
||||
-> IoResult<~RtioUnixListener:Send>;
|
||||
fn unix_connect(&mut self, path: &CString) -> IoResult<~RtioPipe:Send>;
|
||||
fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
|
||||
hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError>;
|
||||
hint: Option<ai::Hint>) -> IoResult<~[ai::Info]>;
|
||||
|
||||
// filesystem operations
|
||||
fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) -> ~RtioFileStream;
|
||||
fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior)
|
||||
-> ~RtioFileStream:Send;
|
||||
fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
|
||||
-> Result<~RtioFileStream, IoError>;
|
||||
fn fs_unlink(&mut self, path: &CString) -> Result<(), IoError>;
|
||||
fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError>;
|
||||
-> IoResult<~RtioFileStream:Send>;
|
||||
fn fs_unlink(&mut self, path: &CString) -> IoResult<()>;
|
||||
fn fs_stat(&mut self, path: &CString) -> IoResult<FileStat>;
|
||||
fn fs_mkdir(&mut self, path: &CString,
|
||||
mode: FilePermission) -> Result<(), IoError>;
|
||||
mode: FilePermission) -> IoResult<()>;
|
||||
fn fs_chmod(&mut self, path: &CString,
|
||||
mode: FilePermission) -> Result<(), IoError>;
|
||||
fn fs_rmdir(&mut self, path: &CString) -> Result<(), IoError>;
|
||||
fn fs_rename(&mut self, path: &CString, to: &CString) -> Result<(), IoError>;
|
||||
mode: FilePermission) -> IoResult<()>;
|
||||
fn fs_rmdir(&mut self, path: &CString) -> IoResult<()>;
|
||||
fn fs_rename(&mut self, path: &CString, to: &CString) -> IoResult<()>;
|
||||
fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
|
||||
Result<~[Path], IoError>;
|
||||
fn fs_lstat(&mut self, path: &CString) -> Result<FileStat, IoError>;
|
||||
IoResult<~[Path]>;
|
||||
fn fs_lstat(&mut self, path: &CString) -> IoResult<FileStat>;
|
||||
fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
|
||||
Result<(), IoError>;
|
||||
fn fs_readlink(&mut self, path: &CString) -> Result<Path, IoError>;
|
||||
fn fs_symlink(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
|
||||
fn fs_link(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
|
||||
IoResult<()>;
|
||||
fn fs_readlink(&mut self, path: &CString) -> IoResult<Path>;
|
||||
fn fs_symlink(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
|
||||
fn fs_link(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
|
||||
fn fs_utime(&mut self, src: &CString, atime: u64, mtime: u64) ->
|
||||
Result<(), IoError>;
|
||||
IoResult<()>;
|
||||
|
||||
// misc
|
||||
fn timer_init(&mut self) -> Result<~RtioTimer, IoError>;
|
||||
fn timer_init(&mut self) -> IoResult<~RtioTimer:Send>;
|
||||
fn spawn(&mut self, config: ProcessConfig)
|
||||
-> Result<(~RtioProcess, ~[Option<~RtioPipe>]), IoError>;
|
||||
fn kill(&mut self, pid: libc::pid_t, signal: int) -> Result<(), IoError>;
|
||||
fn pipe_open(&mut self, fd: c_int) -> Result<~RtioPipe, IoError>;
|
||||
-> IoResult<(~RtioProcess:Send, ~[Option<~RtioPipe:Send>])>;
|
||||
fn kill(&mut self, pid: libc::pid_t, signal: int) -> IoResult<()>;
|
||||
fn pipe_open(&mut self, fd: c_int) -> IoResult<~RtioPipe:Send>;
|
||||
fn tty_open(&mut self, fd: c_int, readable: bool)
|
||||
-> Result<~RtioTTY, IoError>;
|
||||
-> IoResult<~RtioTTY:Send>;
|
||||
fn signal(&mut self, signal: Signum, channel: Sender<Signum>)
|
||||
-> Result<~RtioSignal, IoError>;
|
||||
-> IoResult<~RtioSignal:Send>;
|
||||
}
|
||||
|
||||
pub trait RtioTcpListener : RtioSocket {
|
||||
fn listen(~self) -> Result<~RtioTcpAcceptor, IoError>;
|
||||
fn listen(~self) -> IoResult<~RtioTcpAcceptor:Send>;
|
||||
}
|
||||
|
||||
pub trait RtioTcpAcceptor : RtioSocket {
|
||||
fn accept(&mut self) -> Result<~RtioTcpStream, IoError>;
|
||||
fn accept_simultaneously(&mut self) -> Result<(), IoError>;
|
||||
fn dont_accept_simultaneously(&mut self) -> Result<(), IoError>;
|
||||
fn accept(&mut self) -> IoResult<~RtioTcpStream:Send>;
|
||||
fn accept_simultaneously(&mut self) -> IoResult<()>;
|
||||
fn dont_accept_simultaneously(&mut self) -> IoResult<()>;
|
||||
}
|
||||
|
||||
pub trait RtioTcpStream : RtioSocket {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
|
||||
fn peer_name(&mut self) -> Result<SocketAddr, IoError>;
|
||||
fn control_congestion(&mut self) -> Result<(), IoError>;
|
||||
fn nodelay(&mut self) -> Result<(), IoError>;
|
||||
fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError>;
|
||||
fn letdie(&mut self) -> Result<(), IoError>;
|
||||
fn clone(&self) -> ~RtioTcpStream;
|
||||
fn close_write(&mut self) -> Result<(), IoError>;
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()>;
|
||||
fn peer_name(&mut self) -> IoResult<SocketAddr>;
|
||||
fn control_congestion(&mut self) -> IoResult<()>;
|
||||
fn nodelay(&mut self) -> IoResult<()>;
|
||||
fn keepalive(&mut self, delay_in_seconds: uint) -> IoResult<()>;
|
||||
fn letdie(&mut self) -> IoResult<()>;
|
||||
fn clone(&self) -> ~RtioTcpStream:Send;
|
||||
fn close_write(&mut self) -> IoResult<()>;
|
||||
}
|
||||
|
||||
pub trait RtioSocket {
|
||||
fn socket_name(&mut self) -> Result<SocketAddr, IoError>;
|
||||
fn socket_name(&mut self) -> IoResult<SocketAddr>;
|
||||
}
|
||||
|
||||
pub trait RtioUdpSocket : RtioSocket {
|
||||
fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError>;
|
||||
fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError>;
|
||||
fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)>;
|
||||
fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()>;
|
||||
|
||||
fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
|
||||
fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
|
||||
fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
|
||||
fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
|
||||
|
||||
fn loop_multicast_locally(&mut self) -> Result<(), IoError>;
|
||||
fn dont_loop_multicast_locally(&mut self) -> Result<(), IoError>;
|
||||
fn loop_multicast_locally(&mut self) -> IoResult<()>;
|
||||
fn dont_loop_multicast_locally(&mut self) -> IoResult<()>;
|
||||
|
||||
fn multicast_time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
|
||||
fn time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
|
||||
fn multicast_time_to_live(&mut self, ttl: int) -> IoResult<()>;
|
||||
fn time_to_live(&mut self, ttl: int) -> IoResult<()>;
|
||||
|
||||
fn hear_broadcasts(&mut self) -> Result<(), IoError>;
|
||||
fn ignore_broadcasts(&mut self) -> Result<(), IoError>;
|
||||
fn hear_broadcasts(&mut self) -> IoResult<()>;
|
||||
fn ignore_broadcasts(&mut self) -> IoResult<()>;
|
||||
|
||||
fn clone(&self) -> ~RtioUdpSocket;
|
||||
fn clone(&self) -> ~RtioUdpSocket:Send;
|
||||
}
|
||||
|
||||
pub trait RtioTimer {
|
||||
@ -239,42 +242,42 @@ pub trait RtioTimer {
|
||||
}
|
||||
|
||||
pub trait RtioFileStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError>;
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
|
||||
fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError>;
|
||||
fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError>;
|
||||
fn seek(&mut self, pos: i64, whence: SeekStyle) -> Result<u64, IoError>;
|
||||
fn tell(&self) -> Result<u64, IoError>;
|
||||
fn fsync(&mut self) -> Result<(), IoError>;
|
||||
fn datasync(&mut self) -> Result<(), IoError>;
|
||||
fn truncate(&mut self, offset: i64) -> Result<(), IoError>;
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<int>;
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()>;
|
||||
fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int>;
|
||||
fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()>;
|
||||
fn seek(&mut self, pos: i64, whence: SeekStyle) -> IoResult<u64>;
|
||||
fn tell(&self) -> IoResult<u64>;
|
||||
fn fsync(&mut self) -> IoResult<()>;
|
||||
fn datasync(&mut self) -> IoResult<()>;
|
||||
fn truncate(&mut self, offset: i64) -> IoResult<()>;
|
||||
}
|
||||
|
||||
pub trait RtioProcess {
|
||||
fn id(&self) -> libc::pid_t;
|
||||
fn kill(&mut self, signal: int) -> Result<(), IoError>;
|
||||
fn kill(&mut self, signal: int) -> IoResult<()>;
|
||||
fn wait(&mut self) -> ProcessExit;
|
||||
}
|
||||
|
||||
pub trait RtioPipe {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
|
||||
fn clone(&self) -> ~RtioPipe;
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()>;
|
||||
fn clone(&self) -> ~RtioPipe:Send;
|
||||
}
|
||||
|
||||
pub trait RtioUnixListener {
|
||||
fn listen(~self) -> Result<~RtioUnixAcceptor, IoError>;
|
||||
fn listen(~self) -> IoResult<~RtioUnixAcceptor:Send>;
|
||||
}
|
||||
|
||||
pub trait RtioUnixAcceptor {
|
||||
fn accept(&mut self) -> Result<~RtioPipe, IoError>;
|
||||
fn accept(&mut self) -> IoResult<~RtioPipe:Send>;
|
||||
}
|
||||
|
||||
pub trait RtioTTY {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
|
||||
fn set_raw(&mut self, raw: bool) -> Result<(), IoError>;
|
||||
fn get_winsize(&mut self) -> Result<(int, int), IoError>;
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()>;
|
||||
fn set_raw(&mut self, raw: bool) -> IoResult<()>;
|
||||
fn get_winsize(&mut self) -> IoResult<(int, int)>;
|
||||
fn isatty(&self) -> bool;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ use clone::Clone;
|
||||
use comm::Sender;
|
||||
use io::Writer;
|
||||
use iter::{Iterator, Take};
|
||||
use kinds::Send;
|
||||
use local_data;
|
||||
use ops::Drop;
|
||||
use option::{Option, Some, None};
|
||||
@ -50,10 +51,10 @@ pub struct Task {
|
||||
destroyed: bool,
|
||||
name: Option<SendStr>,
|
||||
|
||||
stdout: Option<~Writer>,
|
||||
stderr: Option<~Writer>,
|
||||
stdout: Option<~Writer:Send>,
|
||||
stderr: Option<~Writer:Send>,
|
||||
|
||||
priv imp: Option<~Runtime>,
|
||||
priv imp: Option<~Runtime:Send>,
|
||||
}
|
||||
|
||||
pub struct GarbageCollector;
|
||||
@ -69,7 +70,7 @@ pub enum BlockedTask {
|
||||
pub enum DeathAction {
|
||||
/// Action to be done with the exit code. If set, also makes the task wait
|
||||
/// until all its watched children exit before collecting the status.
|
||||
Execute(proc(TaskResult)),
|
||||
Execute(proc:Send(TaskResult)),
|
||||
/// A channel to send the result of the task on when the task exits
|
||||
SendMessage(Sender<TaskResult>),
|
||||
}
|
||||
@ -195,7 +196,7 @@ impl Task {
|
||||
/// Inserts a runtime object into this task, transferring ownership to the
|
||||
/// task. It is illegal to replace a previous runtime object in this task
|
||||
/// with this argument.
|
||||
pub fn put_runtime(&mut self, ops: ~Runtime) {
|
||||
pub fn put_runtime(&mut self, ops: ~Runtime:Send) {
|
||||
assert!(self.imp.is_none());
|
||||
self.imp = Some(ops);
|
||||
}
|
||||
@ -225,7 +226,7 @@ impl Task {
|
||||
Ok(t) => Some(t),
|
||||
Err(t) => {
|
||||
let (_, obj): (uint, uint) = cast::transmute(t);
|
||||
let obj: ~Runtime = cast::transmute((vtable, obj));
|
||||
let obj: ~Runtime:Send = cast::transmute((vtable, obj));
|
||||
self.put_runtime(obj);
|
||||
None
|
||||
}
|
||||
@ -235,7 +236,7 @@ impl Task {
|
||||
|
||||
/// Spawns a sibling to this task. The newly spawned task is configured with
|
||||
/// the `opts` structure and will run `f` as the body of its code.
|
||||
pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc()) {
|
||||
pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc:Send()) {
|
||||
let ops = self.imp.take_unwrap();
|
||||
ops.spawn_sibling(self, opts, f)
|
||||
}
|
||||
|
@ -68,13 +68,13 @@ impl Thread<()> {
|
||||
/// to finish executing. This means that even if `join` is not explicitly
|
||||
/// called, when the `Thread` falls out of scope its destructor will block
|
||||
/// waiting for the OS thread.
|
||||
pub fn start<T: Send>(main: proc() -> T) -> Thread<T> {
|
||||
pub fn start<T: Send>(main: proc:Send() -> T) -> Thread<T> {
|
||||
Thread::start_stack(DEFAULT_STACK_SIZE, main)
|
||||
}
|
||||
|
||||
/// Performs the same functionality as `start`, but specifies an explicit
|
||||
/// stack size for the new thread.
|
||||
pub fn start_stack<T: Send>(stack: uint, main: proc() -> T) -> Thread<T> {
|
||||
pub fn start_stack<T: Send>(stack: uint, main: proc:Send() -> T) -> Thread<T> {
|
||||
|
||||
// We need the address of the packet to fill in to be stable so when
|
||||
// `main` fills it in it's still valid, so allocate an extra ~ box to do
|
||||
@ -83,7 +83,7 @@ impl Thread<()> {
|
||||
let packet2: *mut Option<T> = unsafe {
|
||||
*cast::transmute::<&~Option<T>, **mut Option<T>>(&packet)
|
||||
};
|
||||
let main: proc() = proc() unsafe { *packet2 = Some(main()); };
|
||||
let main = proc() unsafe { *packet2 = Some(main()); };
|
||||
let native = unsafe { imp::create(stack, ~main) };
|
||||
|
||||
Thread {
|
||||
@ -99,13 +99,13 @@ impl Thread<()> {
|
||||
/// This corresponds to creating threads in the 'detached' state on unix
|
||||
/// systems. Note that platforms may not keep the main program alive even if
|
||||
/// there are detached thread still running around.
|
||||
pub fn spawn(main: proc()) {
|
||||
pub fn spawn(main: proc:Send()) {
|
||||
Thread::spawn_stack(DEFAULT_STACK_SIZE, main)
|
||||
}
|
||||
|
||||
/// Performs the same functionality as `spawn`, but explicitly specifies a
|
||||
/// stack size for the new thread.
|
||||
pub fn spawn_stack(stack: uint, main: proc()) {
|
||||
pub fn spawn_stack(stack: uint, main: proc:Send()) {
|
||||
unsafe {
|
||||
let handle = imp::create(stack, ~main);
|
||||
imp::detach(handle);
|
||||
@ -146,6 +146,7 @@ impl<T: Send> Drop for Thread<T> {
|
||||
mod imp {
|
||||
use cast;
|
||||
use cmp;
|
||||
use kinds::Send;
|
||||
use libc;
|
||||
use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T, BOOL,
|
||||
LPVOID, DWORD, LPDWORD, HANDLE};
|
||||
@ -155,7 +156,7 @@ mod imp {
|
||||
pub type rust_thread = HANDLE;
|
||||
pub type rust_thread_return = DWORD;
|
||||
|
||||
pub unsafe fn create(stack: uint, p: ~proc()) -> rust_thread {
|
||||
pub unsafe fn create(stack: uint, p: ~proc:Send()) -> rust_thread {
|
||||
let arg: *mut libc::c_void = cast::transmute(p);
|
||||
// FIXME On UNIX, we guard against stack sizes that are too small but
|
||||
// that's because pthreads enforces that stacks are at least
|
||||
@ -203,6 +204,7 @@ mod imp {
|
||||
mod imp {
|
||||
use cast;
|
||||
use cmp;
|
||||
use kinds::Send;
|
||||
use libc::consts::os::posix01::{PTHREAD_CREATE_JOINABLE, PTHREAD_STACK_MIN};
|
||||
use libc;
|
||||
use mem;
|
||||
@ -213,7 +215,7 @@ mod imp {
|
||||
pub type rust_thread = libc::pthread_t;
|
||||
pub type rust_thread_return = *u8;
|
||||
|
||||
pub unsafe fn create(stack: uint, p: ~proc()) -> rust_thread {
|
||||
pub unsafe fn create(stack: uint, p: ~proc:Send()) -> rust_thread {
|
||||
let mut native: libc::pthread_t = mem::uninit();
|
||||
let mut attr: libc::pthread_attr_t = mem::uninit();
|
||||
assert_eq!(pthread_attr_init(&mut attr), 0);
|
||||
|
@ -76,7 +76,7 @@ use uw = rt::libunwind;
|
||||
|
||||
pub struct Unwinder {
|
||||
priv unwinding: bool,
|
||||
priv cause: Option<~Any>
|
||||
priv cause: Option<~Any:Send>
|
||||
}
|
||||
|
||||
impl Unwinder {
|
||||
@ -126,7 +126,7 @@ impl Unwinder {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn begin_unwind(&mut self, cause: ~Any) -> ! {
|
||||
pub fn begin_unwind(&mut self, cause: ~Any:Send) -> ! {
|
||||
rtdebug!("begin_unwind()");
|
||||
|
||||
self.unwinding = true;
|
||||
@ -372,7 +372,7 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> !
|
||||
/// Do this split took the LLVM IR line counts of `fn main() { fail!()
|
||||
/// }` from ~1900/3700 (-O/no opts) to 180/590.
|
||||
#[inline(never)] #[cold] // this is the slow path, please never inline this
|
||||
fn begin_unwind_inner(msg: ~Any, file: &'static str, line: uint) -> ! {
|
||||
fn begin_unwind_inner(msg: ~Any:Send, file: &'static str, line: uint) -> ! {
|
||||
let mut task;
|
||||
{
|
||||
let msg_s = match msg.as_ref::<&'static str>() {
|
||||
|
@ -55,7 +55,7 @@ use str::{Str, SendStr, IntoMaybeOwned};
|
||||
///
|
||||
/// If you wish for this result's delivery to block until all
|
||||
/// children tasks complete, recommend using a result future.
|
||||
pub type TaskResult = Result<(), ~Any>;
|
||||
pub type TaskResult = Result<(), ~Any:Send>;
|
||||
|
||||
/// Task configuration options
|
||||
pub struct TaskOpts {
|
||||
@ -66,9 +66,9 @@ pub struct TaskOpts {
|
||||
/// The size of the stack for the spawned task
|
||||
stack_size: Option<uint>,
|
||||
/// Task-local stdout
|
||||
stdout: Option<~Writer>,
|
||||
stdout: Option<~Writer:Send>,
|
||||
/// Task-local stderr
|
||||
stderr: Option<~Writer>,
|
||||
stderr: Option<~Writer:Send>,
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,7 +86,7 @@ pub struct TaskOpts {
|
||||
pub struct TaskBuilder {
|
||||
/// Options to spawn the new task with
|
||||
opts: TaskOpts,
|
||||
priv gen_body: Option<proc(v: proc()) -> proc()>,
|
||||
priv gen_body: Option<proc:Send(v: proc:Send()) -> proc:Send()>,
|
||||
priv nopod: Option<marker::NoPod>,
|
||||
}
|
||||
|
||||
@ -150,22 +150,14 @@ impl TaskBuilder {
|
||||
* generator by applying the task body which results from the
|
||||
* existing body generator to the new body generator.
|
||||
*/
|
||||
pub fn with_wrapper(mut self, wrapper: proc(v: proc()) -> proc()) -> TaskBuilder {
|
||||
let prev_gen_body = self.gen_body.take();
|
||||
let prev_gen_body = match prev_gen_body {
|
||||
Some(gen) => gen,
|
||||
None => {
|
||||
let f: proc(proc()) -> proc() = proc(body) body;
|
||||
f
|
||||
}
|
||||
pub fn with_wrapper(mut self,
|
||||
wrapper: proc:Send(v: proc:Send()) -> proc:Send())
|
||||
-> TaskBuilder
|
||||
{
|
||||
self.gen_body = match self.gen_body.take() {
|
||||
Some(prev) => Some(proc(body) { wrapper(prev(body)) }),
|
||||
None => Some(wrapper)
|
||||
};
|
||||
let next_gen_body = {
|
||||
let f: proc(proc()) -> proc() = proc(body) {
|
||||
wrapper(prev_gen_body(body))
|
||||
};
|
||||
f
|
||||
};
|
||||
self.gen_body = Some(next_gen_body);
|
||||
self
|
||||
}
|
||||
|
||||
@ -176,7 +168,7 @@ impl TaskBuilder {
|
||||
* the provided unique closure. The task has the properties and behavior
|
||||
* specified by the task_builder.
|
||||
*/
|
||||
pub fn spawn(mut self, f: proc()) {
|
||||
pub fn spawn(mut self, f: proc:Send()) {
|
||||
let gen_body = self.gen_body.take();
|
||||
let f = match gen_body {
|
||||
Some(gen) => gen(f),
|
||||
@ -199,7 +191,7 @@ impl TaskBuilder {
|
||||
* # Failure
|
||||
* Fails if a future_result was already set for this task.
|
||||
*/
|
||||
pub fn try<T:Send>(mut self, f: proc() -> T) -> Result<T, ~Any> {
|
||||
pub fn try<T:Send>(mut self, f: proc:Send() -> T) -> Result<T, ~Any:Send> {
|
||||
let (tx, rx) = channel();
|
||||
|
||||
let result = self.future_result();
|
||||
@ -241,12 +233,12 @@ impl TaskOpts {
|
||||
/// the provided unique closure.
|
||||
///
|
||||
/// This function is equivalent to `task().spawn(f)`.
|
||||
pub fn spawn(f: proc()) {
|
||||
pub fn spawn(f: proc:Send()) {
|
||||
let task = task();
|
||||
task.spawn(f)
|
||||
}
|
||||
|
||||
pub fn try<T:Send>(f: proc() -> T) -> Result<T, ~Any> {
|
||||
pub fn try<T:Send>(f: proc:Send() -> T) -> Result<T, ~Any:Send> {
|
||||
/*!
|
||||
* Execute a function in another task and return either the return value
|
||||
* of the function or result::err.
|
||||
@ -346,7 +338,7 @@ fn test_run_basic() {
|
||||
fn test_with_wrapper() {
|
||||
let (tx, rx) = channel();
|
||||
task().with_wrapper(proc(body) {
|
||||
let result: proc() = proc() {
|
||||
let result: proc:Send() = proc() {
|
||||
body();
|
||||
tx.send(());
|
||||
};
|
||||
@ -432,7 +424,7 @@ fn test_spawn_sched_childs_on_default_sched() {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn avoid_copying_the_body(spawnfn: |v: proc()|) {
|
||||
fn avoid_copying_the_body(spawnfn: |v: proc:Send()|) {
|
||||
let (tx, rx) = channel::<uint>();
|
||||
|
||||
let x = ~1;
|
||||
@ -478,7 +470,7 @@ fn test_child_doesnt_ref_parent() {
|
||||
// (well, it would if the constant were 8000+ - I lowered it to be more
|
||||
// valgrind-friendly. try this at home, instead..!)
|
||||
static generations: uint = 16;
|
||||
fn child_no(x: uint) -> proc() {
|
||||
fn child_no(x: uint) -> proc:Send() {
|
||||
return proc() {
|
||||
if x < generations {
|
||||
task().spawn(child_no(x+1));
|
||||
@ -524,10 +516,10 @@ fn test_try_fail_message_owned_str() {
|
||||
#[test]
|
||||
fn test_try_fail_message_any() {
|
||||
match try(proc() {
|
||||
fail!(~413u16 as ~Any);
|
||||
fail!(~413u16 as ~Any:Send);
|
||||
}) {
|
||||
Err(e) => {
|
||||
type T = ~Any;
|
||||
type T = ~Any:Send;
|
||||
assert!(e.is::<T>());
|
||||
let any = e.move::<T>().unwrap();
|
||||
assert!(any.is::<u16>());
|
||||
|
@ -28,7 +28,7 @@ for it to terminate.
|
||||
The executing thread has no access to a task pointer and will be using
|
||||
a normal large stack.
|
||||
*/
|
||||
pub fn run_in_bare_thread(f: proc()) {
|
||||
pub fn run_in_bare_thread(f: proc:Send()) {
|
||||
use rt::thread::Thread;
|
||||
Thread::start(f).join()
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub struct Future<A> {
|
||||
}
|
||||
|
||||
enum FutureState<A> {
|
||||
Pending(proc() -> A),
|
||||
Pending(proc:Send() -> A),
|
||||
Evaluating,
|
||||
Forced(A)
|
||||
}
|
||||
@ -90,7 +90,7 @@ impl<A> Future<A> {
|
||||
Future {state: Forced(val)}
|
||||
}
|
||||
|
||||
pub fn from_fn(f: proc() -> A) -> Future<A> {
|
||||
pub fn from_fn(f: proc:Send() -> A) -> Future<A> {
|
||||
/*!
|
||||
* Create a future from a function.
|
||||
*
|
||||
@ -117,7 +117,7 @@ impl<A:Send> Future<A> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn spawn(blk: proc() -> A) -> Future<A> {
|
||||
pub fn spawn(blk: proc:Send() -> A) -> Future<A> {
|
||||
/*!
|
||||
* Create a future from a unique closure.
|
||||
*
|
||||
|
@ -836,7 +836,7 @@ mod tests {
|
||||
let m = Arc::new(Mutex::new());
|
||||
let m2 = m.clone();
|
||||
|
||||
let result: result::Result<(), ~Any> = task::try(proc() {
|
||||
let result: result::Result<(), ~Any:Send> = task::try(proc() {
|
||||
let _lock = m2.lock();
|
||||
fail!();
|
||||
});
|
||||
@ -1076,7 +1076,7 @@ mod tests {
|
||||
let x = Arc::new(RWLock::new());
|
||||
let x2 = x.clone();
|
||||
|
||||
let result: result::Result<(), ~Any> = task::try(proc() {
|
||||
let result: result::Result<(), ~Any:Send> = task::try(proc() {
|
||||
lock_rwlock_in_mode(&x2, mode1, || {
|
||||
fail!();
|
||||
})
|
||||
|
@ -16,7 +16,7 @@
|
||||
use std::task;
|
||||
|
||||
enum Msg<T> {
|
||||
Execute(proc(&T)),
|
||||
Execute(proc:Send(&T)),
|
||||
Quit
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ impl<T> TaskPool<T> {
|
||||
/// returns a function which, given the index of the task, should return
|
||||
/// local data to be kept around in that task.
|
||||
pub fn new(n_tasks: uint,
|
||||
init_fn_factory: || -> proc(uint) -> T)
|
||||
init_fn_factory: || -> proc:Send(uint) -> T)
|
||||
-> TaskPool<T> {
|
||||
assert!(n_tasks >= 1);
|
||||
|
||||
@ -49,7 +49,7 @@ impl<T> TaskPool<T> {
|
||||
let (tx, rx) = channel::<Msg<T>>();
|
||||
let init_fn = init_fn_factory();
|
||||
|
||||
let task_body: proc() = proc() {
|
||||
let task_body = proc() {
|
||||
let local_data = init_fn(i);
|
||||
loop {
|
||||
match rx.recv() {
|
||||
@ -73,7 +73,7 @@ impl<T> TaskPool<T> {
|
||||
|
||||
/// Executes the function `f` on a task in the pool. The function
|
||||
/// receives a reference to the local data returned by the `init_fn`.
|
||||
pub fn execute(&mut self, f: proc(&T)) {
|
||||
pub fn execute(&mut self, f: proc:Send(&T)) {
|
||||
self.channels.get(self.next_index).send(Execute(f));
|
||||
self.next_index += 1;
|
||||
if self.next_index == self.channels.len() { self.next_index = 0; }
|
||||
@ -82,8 +82,8 @@ impl<T> TaskPool<T> {
|
||||
|
||||
#[test]
|
||||
fn test_task_pool() {
|
||||
let f: || -> proc(uint) -> uint = || {
|
||||
let g: proc(uint) -> uint = proc(i) i;
|
||||
let f: || -> proc:Send(uint) -> uint = || {
|
||||
let g: proc:Send(uint) -> uint = proc(i) i;
|
||||
g
|
||||
};
|
||||
let mut pool = TaskPool::new(4, f);
|
||||
|
@ -79,7 +79,7 @@ impl SpanHandler {
|
||||
// others log errors for later reporting.
|
||||
pub struct Handler {
|
||||
err_count: Cell<uint>,
|
||||
emit: RefCell<~Emitter>,
|
||||
emit: RefCell<~Emitter:Send>,
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
@ -148,7 +148,7 @@ pub fn default_handler() -> Handler {
|
||||
mk_handler(~EmitterWriter::stderr())
|
||||
}
|
||||
|
||||
pub fn mk_handler(e: ~Emitter) -> Handler {
|
||||
pub fn mk_handler(e: ~Emitter:Send) -> Handler {
|
||||
Handler {
|
||||
err_count: Cell::new(0),
|
||||
emit: RefCell::new(e),
|
||||
@ -221,7 +221,7 @@ pub struct EmitterWriter {
|
||||
|
||||
enum Destination {
|
||||
Terminal(term::Terminal<io::stdio::StdWriter>),
|
||||
Raw(~Writer),
|
||||
Raw(~Writer:Send),
|
||||
}
|
||||
|
||||
impl EmitterWriter {
|
||||
@ -238,7 +238,7 @@ impl EmitterWriter {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(dst: ~Writer) -> EmitterWriter {
|
||||
pub fn new(dst: ~Writer:Send) -> EmitterWriter {
|
||||
EmitterWriter { dst: Raw(dst) }
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ pub enum TestFn {
|
||||
StaticTestFn(fn()),
|
||||
StaticBenchFn(fn(&mut BenchHarness)),
|
||||
StaticMetricFn(proc(&mut MetricMap)),
|
||||
DynTestFn(proc()),
|
||||
DynTestFn(proc:Send()),
|
||||
DynMetricFn(proc(&mut MetricMap)),
|
||||
DynBenchFn(~TDynBenchFn)
|
||||
}
|
||||
@ -948,7 +948,7 @@ pub fn run_test(force_ignore: bool,
|
||||
#[allow(deprecated_owned_vector)]
|
||||
fn run_test_inner(desc: TestDesc,
|
||||
monitor_ch: Sender<MonitorMsg>,
|
||||
testfn: proc()) {
|
||||
testfn: proc:Send()) {
|
||||
spawn(proc() {
|
||||
let (tx, rx) = channel();
|
||||
let mut reader = ChanReader::new(rx);
|
||||
@ -958,8 +958,8 @@ pub fn run_test(force_ignore: bool,
|
||||
DynTestName(ref name) => name.clone().into_maybe_owned(),
|
||||
StaticTestName(name) => name.into_maybe_owned(),
|
||||
});
|
||||
task.opts.stdout = Some(~stdout as ~Writer);
|
||||
task.opts.stderr = Some(~stderr as ~Writer);
|
||||
task.opts.stdout = Some(~stdout as ~Writer:Send);
|
||||
task.opts.stderr = Some(~stderr as ~Writer:Send);
|
||||
let result_future = task.future_result();
|
||||
task.spawn(testfn);
|
||||
|
||||
|
@ -394,14 +394,14 @@ impl<'a> Prep<'a> {
|
||||
pub fn exec<'a, T:Send +
|
||||
Encodable<json::Encoder<'a>> +
|
||||
Decodable<json::Decoder>>(
|
||||
&'a self, blk: proc(&mut Exec) -> T) -> T {
|
||||
&'a self, blk: proc:Send(&mut Exec) -> T) -> T {
|
||||
self.exec_work(blk).unwrap()
|
||||
}
|
||||
|
||||
fn exec_work<'a, T:Send +
|
||||
Encodable<json::Encoder<'a>> +
|
||||
Decodable<json::Decoder>>( // FIXME(#5121)
|
||||
&'a self, blk: proc(&mut Exec) -> T) -> Work<'a, T> {
|
||||
&'a self, blk: proc:Send(&mut Exec) -> T) -> Work<'a, T> {
|
||||
let mut bo = Some(blk);
|
||||
|
||||
debug!("exec_work: looking up {} and {:?}", self.fn_name,
|
||||
|
@ -29,7 +29,7 @@ impl Drop for Foo {
|
||||
|
||||
#[macro_registrar]
|
||||
pub fn registrar(_: |Name, SyntaxExtension|) {
|
||||
local_data_key!(foo: ~Any);
|
||||
local_data::set(foo, ~Foo { foo: 10 } as ~Any);
|
||||
local_data_key!(foo: ~Any:Send);
|
||||
local_data::set(foo, ~Foo { foo: 10 } as ~Any:Send);
|
||||
}
|
||||
|
||||
|
@ -31,12 +31,12 @@ impl Foo for B
|
||||
|
||||
struct A
|
||||
{
|
||||
v: ~Foo,
|
||||
v: ~Foo:Send,
|
||||
}
|
||||
|
||||
fn main()
|
||||
{
|
||||
let a = A {v: ~B{v: None} as ~Foo};
|
||||
let a = A {v: ~B{v: None} as ~Foo:Send};
|
||||
//~^ ERROR cannot pack type `~B`, which does not fulfill `Send`
|
||||
let v = Rc::new(RefCell::new(a));
|
||||
let w = v.clone();
|
||||
|
@ -14,7 +14,8 @@ fn foo(_x: @uint) {}
|
||||
|
||||
fn main() {
|
||||
let x = @3u;
|
||||
let _: proc() = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc() = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc() = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc() = proc() foo(x);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
trait Foo {}
|
||||
|
||||
fn a(_x: ~Foo) { // should be same as ~Foo:Send
|
||||
fn a(_x: ~Foo:Send) {
|
||||
}
|
||||
|
||||
fn b(_x: &'static Foo) { // should be same as &'static Foo:'static
|
||||
|
@ -11,5 +11,5 @@
|
||||
// error-pattern:failed at '~Any'
|
||||
|
||||
fn main() {
|
||||
fail!(~413 as ~::std::any::Any);
|
||||
fail!(~413 as ~::std::any::Any:Send);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ fn failfn() {
|
||||
|
||||
fn main() {
|
||||
let y = ~0;
|
||||
let x: @proc() = @(proc() {
|
||||
let x: @proc:Send() = @(proc() {
|
||||
println!("{:?}", y.clone());
|
||||
});
|
||||
failfn();
|
||||
|
@ -42,7 +42,7 @@ fn main() {
|
||||
let (tx, rx) = channel();
|
||||
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
|
||||
spawn(proc() {
|
||||
set_logger(~MyWriter(w) as ~Logger);
|
||||
set_logger(~MyWriter(w) as ~Logger:Send);
|
||||
debug!("debug");
|
||||
info!("info");
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ struct Pair {
|
||||
pub fn main() {
|
||||
let z = ~Pair { a : 10, b : 12};
|
||||
|
||||
let f: proc() = proc() {
|
||||
let f: proc:Send() = proc() {
|
||||
assert_eq!(z.a, 10);
|
||||
assert_eq!(z.b, 12);
|
||||
};
|
||||
|
@ -12,13 +12,13 @@ use std::task;
|
||||
|
||||
static generations: uint = 1024+256+128+49;
|
||||
|
||||
fn spawn(f: proc()) {
|
||||
fn spawn(f: proc:Send()) {
|
||||
let mut t = task::task();
|
||||
t.opts.stack_size = Some(32 * 1024);
|
||||
t.spawn(f);
|
||||
}
|
||||
|
||||
fn child_no(x: uint) -> proc() {
|
||||
fn child_no(x: uint) -> proc:Send() {
|
||||
proc() {
|
||||
if x < generations {
|
||||
spawn(child_no(x+1));
|
||||
|
@ -11,7 +11,7 @@
|
||||
use std::task;
|
||||
|
||||
type RingBuffer = Vec<f64> ;
|
||||
type SamplesFn = proc(samples: &RingBuffer);
|
||||
type SamplesFn = proc:Send(samples: &RingBuffer);
|
||||
|
||||
enum Msg
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ fn test05_start(f: proc(int)) {
|
||||
|
||||
fn test05() {
|
||||
let three = ~3;
|
||||
let fn_to_send: proc(int) = proc(n) {
|
||||
let fn_to_send: proc:Send(int) = proc(n) {
|
||||
println!("{}", *three + n); // will copy x into the closure
|
||||
assert_eq!(*three, 3);
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ fn test_tempdir() {
|
||||
|
||||
fn test_rm_tempdir() {
|
||||
let (tx, rx) = channel();
|
||||
let f: proc() = proc() {
|
||||
let f: proc:Send() = proc() {
|
||||
let tmp = TempDir::new("test_rm_tempdir").unwrap();
|
||||
tx.send(tmp.path().clone());
|
||||
fail!("fail to unwind past `tmp`");
|
||||
@ -47,7 +47,7 @@ fn test_rm_tempdir() {
|
||||
|
||||
let tmp = TempDir::new("test_rm_tempdir").unwrap();
|
||||
let path = tmp.path().clone();
|
||||
let f: proc() = proc() {
|
||||
let f: proc:Send() = proc() {
|
||||
let _tmp = tmp;
|
||||
fail!("fail to unwind past `tmp`");
|
||||
};
|
||||
@ -56,7 +56,7 @@ fn test_rm_tempdir() {
|
||||
|
||||
let path;
|
||||
{
|
||||
let f: proc() -> TempDir = proc() {
|
||||
let f = proc() {
|
||||
TempDir::new("test_rm_tempdir").unwrap()
|
||||
};
|
||||
let tmp = task::try(f).ok().expect("test_rm_tmdir");
|
||||
|
@ -26,7 +26,7 @@ fn d(x: ~Foo:Send) {
|
||||
}
|
||||
|
||||
fn e(x: ~Foo) { // sugar for ~Foo:Owned
|
||||
b(x);
|
||||
a(x);
|
||||
}
|
||||
|
||||
pub fn main() { }
|
||||
|
@ -18,7 +18,7 @@ struct Tree(@RefCell<TreeR>);
|
||||
struct TreeR {
|
||||
left: Option<Tree>,
|
||||
right: Option<Tree>,
|
||||
val: ~to_str
|
||||
val: ~to_str:Send
|
||||
}
|
||||
|
||||
trait to_str {
|
||||
@ -53,10 +53,10 @@ fn foo<T:to_str>(x: T) -> ~str { x.to_str_() }
|
||||
pub fn main() {
|
||||
let t1 = Tree(@RefCell::new(TreeR{left: None,
|
||||
right: None,
|
||||
val: ~1 as ~to_str}));
|
||||
val: ~1 as ~to_str:Send}));
|
||||
let t2 = Tree(@RefCell::new(TreeR{left: Some(t1),
|
||||
right: Some(t1),
|
||||
val: ~2 as ~to_str}));
|
||||
val: ~2 as ~to_str:Send}));
|
||||
let expected = ~"[2, some([1, none, none]), some([1, none, none])]";
|
||||
assert!(t2.to_str_() == expected);
|
||||
assert!(foo(t2) == expected);
|
||||
|
@ -19,12 +19,11 @@ enum maybe_pointy {
|
||||
|
||||
struct Pointy {
|
||||
a : maybe_pointy,
|
||||
d : proc() -> uint,
|
||||
d : proc:Send() -> uint,
|
||||
}
|
||||
|
||||
fn make_uniq_closure<A:Send>(a: A) -> proc() -> uint {
|
||||
let result: proc() -> uint = proc() &a as *A as uint;
|
||||
result
|
||||
fn make_uniq_closure<A:Send>(a: A) -> proc:Send() -> uint {
|
||||
proc() { &a as *A as uint }
|
||||
}
|
||||
|
||||
fn empty_pointy() -> @RefCell<Pointy> {
|
||||
|
@ -20,7 +20,7 @@ enum maybe_pointy {
|
||||
struct Pointy {
|
||||
a : maybe_pointy,
|
||||
c : ~int,
|
||||
d : proc()->(),
|
||||
d : proc:Send()->(),
|
||||
}
|
||||
|
||||
fn empty_pointy() -> @RefCell<Pointy> {
|
||||
|
Loading…
Reference in New Issue
Block a user