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:
bors 2014-03-27 14:32:02 -07:00
commit 13dafa09f1
65 changed files with 406 additions and 393 deletions

View File

@ -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

View File

@ -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,

View File

@ -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<()>,
}

View File

@ -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!()

View File

@ -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;
}

View File

@ -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!(),
}

View File

@ -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;

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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())
}
}

View File

@ -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
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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!(),
}

View File

@ -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!();
}
}

View File

@ -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(),
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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
}
}

View File

@ -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()
}
}

View File

@ -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)),
}
}

View File

@ -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);
}
}

View File

@ -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,

View File

@ -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,
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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();

View File

@ -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 }
}
}

View File

@ -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`.

View File

@ -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();

View File

@ -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.

View File

@ -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))); }

View File

@ -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]");

View File

@ -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());

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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)
}

View File

@ -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);

View File

@ -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>() {

View File

@ -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>());

View File

@ -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()
}

View File

@ -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.
*

View File

@ -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!();
})

View File

@ -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);

View File

@ -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) }
}
}

View File

@ -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);

View File

@ -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,

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -11,5 +11,5 @@
// error-pattern:failed at '~Any'
fn main() {
fail!(~413 as ~::std::any::Any);
fail!(~413 as ~::std::any::Any:Send);
}

View File

@ -18,7 +18,7 @@ fn failfn() {
fn main() {
let y = ~0;
let x: @proc() = @(proc() {
let x: @proc:Send() = @(proc() {
println!("{:?}", y.clone());
});
failfn();

View File

@ -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");
});

View File

@ -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);
};

View File

@ -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));

View File

@ -11,7 +11,7 @@
use std::task;
type RingBuffer = Vec<f64> ;
type SamplesFn = proc(samples: &RingBuffer);
type SamplesFn = proc:Send(samples: &RingBuffer);
enum Msg
{

View File

@ -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);
};

View File

@ -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");

View File

@ -26,7 +26,7 @@ fn d(x: ~Foo:Send) {
}
fn e(x: ~Foo) { // sugar for ~Foo:Owned
b(x);
a(x);
}
pub fn main() { }

View File

@ -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);

View File

@ -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> {

View File

@ -20,7 +20,7 @@ enum maybe_pointy {
struct Pointy {
a : maybe_pointy,
c : ~int,
d : proc()->(),
d : proc:Send()->(),
}
fn empty_pointy() -> @RefCell<Pointy> {