1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 use comm::{Sender, Receiver};
18 use option::{Option, Some, None};
25 use ai = io::net::addrinfo;
28 use io::net::ip::{IpAddr, SocketAddr};
29 use io::process::{ProcessConfig, ProcessExit};
30 use io::signal::Signum;
31 use io::{FileMode, FileAccess, FileStat, FilePermission};
40 fn callback(&mut self, arg: proc():Send);
41 fn pausable_idle_callback(&mut self,
42 ~Callback:Send) -> ~PausableIdleCallback:Send;
43 fn remote_callback(&mut self, ~Callback:Send) -> ~RemoteCallback:Send;
45 /// The asynchronous I/O services. Not all event loops may provide one.
46 fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory>;
47 fn has_active_io(&self) -> bool;
50 pub trait RemoteCallback {
51 /// Trigger the remote callback. Note that the number of times the
52 /// callback is run is not guaranteed. All that is guaranteed is
53 /// that, after calling 'fire', the callback will be called at
54 /// least once, but multiple callbacks may be coalesced and
55 /// callbacks may be called more often requested. Destruction also
56 /// triggers the callback.
60 /// Data needed to make a successful open(2) call
61 /// Using unix flag conventions for now, which happens to also be what's supported
62 /// libuv (it does translation to windows under the hood).
63 pub struct FileOpenConfig {
64 /// Path to file to be opened
66 /// Flags for file access mode (as per open(2))
68 /// File creation mode, ignored unless O_CREAT is passed as part of flags
72 /// Description of what to do when a file handle is closed
73 pub enum CloseBehavior {
74 /// Do not close this handle when the object is destroyed
76 /// Synchronously close the handle, meaning that the task will block when
77 /// the handle is destroyed until it has been fully closed.
79 /// Asynchronously closes a handle, meaning that the task will *not* block
80 /// when the handle is destroyed, but the handle will still get deallocated
81 /// and cleaned up (but this will happen asynchronously on the local event
86 pub struct LocalIo<'a> {
87 factory: &'a mut IoFactory,
91 impl<'a> Drop for LocalIo<'a> {
93 // FIXME(pcwalton): Do nothing here for now, but eventually we may want
94 // something. For now this serves to make `LocalIo` noncopyable.
98 impl<'a> LocalIo<'a> {
99 /// Returns the local I/O: either the local scheduler's I/O services or
100 /// the native I/O services.
101 pub fn borrow() -> Option<LocalIo> {
102 // FIXME(#11053): bad
104 // This is currently very unsafely implemented. We don't actually
105 // *take* the local I/O so there's a very real possibility that we
106 // can have two borrows at once. Currently there is not a clear way
107 // to actually borrow the local I/O factory safely because even if
108 // ownership were transferred down to the functions that the I/O
109 // factory implements it's just too much of a pain to know when to
110 // relinquish ownership back into the local task (but that would be
111 // the safe way of implementing this function).
113 // In order to get around this, we just transmute a copy out of the task
114 // in order to have what is likely a static lifetime (bad).
115 let mut t: ~Task = Local::take();
116 let ret = t.local_io().map(|t| {
117 unsafe { cast::transmute_copy(&t) }
123 pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> IoResult<T>)
126 match LocalIo::borrow() {
127 None => Err(io::standard_error(io::IoUnavailable)),
128 Some(mut io) => f(io.get()),
132 pub fn new<'a>(io: &'a mut IoFactory) -> LocalIo<'a> {
133 LocalIo { factory: io }
136 /// Returns the underlying I/O factory as a trait reference.
138 pub fn get<'a>(&'a mut self) -> &'a mut IoFactory {
139 // FIXME(pcwalton): I think this is actually sound? Could borrow check
140 // allow this safely?
142 cast::transmute_copy(&self.factory)
147 pub trait IoFactory {
149 fn tcp_connect(&mut self, addr: SocketAddr,
150 timeout: Option<u64>) -> IoResult<~RtioTcpStream:Send>;
151 fn tcp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioTcpListener:Send>;
152 fn udp_bind(&mut self, addr: SocketAddr) -> IoResult<~RtioUdpSocket:Send>;
153 fn unix_bind(&mut self, path: &CString)
154 -> IoResult<~RtioUnixListener:Send>;
155 fn unix_connect(&mut self, path: &CString) -> IoResult<~RtioPipe:Send>;
156 fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
157 hint: Option<ai::Hint>) -> IoResult<~[ai::Info]>;
159 // filesystem operations
160 fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior)
161 -> ~RtioFileStream:Send;
162 fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
163 -> IoResult<~RtioFileStream:Send>;
164 fn fs_unlink(&mut self, path: &CString) -> IoResult<()>;
165 fn fs_stat(&mut self, path: &CString) -> IoResult<FileStat>;
166 fn fs_mkdir(&mut self, path: &CString,
167 mode: FilePermission) -> IoResult<()>;
168 fn fs_chmod(&mut self, path: &CString,
169 mode: FilePermission) -> IoResult<()>;
170 fn fs_rmdir(&mut self, path: &CString) -> IoResult<()>;
171 fn fs_rename(&mut self, path: &CString, to: &CString) -> IoResult<()>;
172 fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
174 fn fs_lstat(&mut self, path: &CString) -> IoResult<FileStat>;
175 fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
177 fn fs_readlink(&mut self, path: &CString) -> IoResult<Path>;
178 fn fs_symlink(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
179 fn fs_link(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
180 fn fs_utime(&mut self, src: &CString, atime: u64, mtime: u64) ->
184 fn timer_init(&mut self) -> IoResult<~RtioTimer:Send>;
185 fn spawn(&mut self, config: ProcessConfig)
186 -> IoResult<(~RtioProcess:Send, ~[Option<~RtioPipe:Send>])>;
187 fn kill(&mut self, pid: libc::pid_t, signal: int) -> IoResult<()>;
188 fn pipe_open(&mut self, fd: c_int) -> IoResult<~RtioPipe:Send>;
189 fn tty_open(&mut self, fd: c_int, readable: bool)
190 -> IoResult<~RtioTTY:Send>;
191 fn signal(&mut self, signal: Signum, channel: Sender<Signum>)
192 -> IoResult<~RtioSignal:Send>;
195 pub trait RtioTcpListener : RtioSocket {
196 fn listen(~self) -> IoResult<~RtioTcpAcceptor:Send>;
199 pub trait RtioTcpAcceptor : RtioSocket {
200 fn accept(&mut self) -> IoResult<~RtioTcpStream:Send>;
201 fn accept_simultaneously(&mut self) -> IoResult<()>;
202 fn dont_accept_simultaneously(&mut self) -> IoResult<()>;
205 pub trait RtioTcpStream : RtioSocket {
206 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
207 fn write(&mut self, buf: &[u8]) -> IoResult<()>;
208 fn peer_name(&mut self) -> IoResult<SocketAddr>;
209 fn control_congestion(&mut self) -> IoResult<()>;
210 fn nodelay(&mut self) -> IoResult<()>;
211 fn keepalive(&mut self, delay_in_seconds: uint) -> IoResult<()>;
212 fn letdie(&mut self) -> IoResult<()>;
213 fn clone(&self) -> ~RtioTcpStream:Send;
214 fn close_write(&mut self) -> IoResult<()>;
217 pub trait RtioSocket {
218 fn socket_name(&mut self) -> IoResult<SocketAddr>;
221 pub trait RtioUdpSocket : RtioSocket {
222 fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)>;
223 fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()>;
225 fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
226 fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
228 fn loop_multicast_locally(&mut self) -> IoResult<()>;
229 fn dont_loop_multicast_locally(&mut self) -> IoResult<()>;
231 fn multicast_time_to_live(&mut self, ttl: int) -> IoResult<()>;
232 fn time_to_live(&mut self, ttl: int) -> IoResult<()>;
234 fn hear_broadcasts(&mut self) -> IoResult<()>;
235 fn ignore_broadcasts(&mut self) -> IoResult<()>;
237 fn clone(&self) -> ~RtioUdpSocket:Send;
240 pub trait RtioTimer {
241 fn sleep(&mut self, msecs: u64);
242 fn oneshot(&mut self, msecs: u64) -> Receiver<()>;
243 fn period(&mut self, msecs: u64) -> Receiver<()>;
246 pub trait RtioFileStream {
247 fn read(&mut self, buf: &mut [u8]) -> IoResult<int>;
248 fn write(&mut self, buf: &[u8]) -> IoResult<()>;
249 fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int>;
250 fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()>;
251 fn seek(&mut self, pos: i64, whence: SeekStyle) -> IoResult<u64>;
252 fn tell(&self) -> IoResult<u64>;
253 fn fsync(&mut self) -> IoResult<()>;
254 fn datasync(&mut self) -> IoResult<()>;
255 fn truncate(&mut self, offset: i64) -> IoResult<()>;
258 pub trait RtioProcess {
259 fn id(&self) -> libc::pid_t;
260 fn kill(&mut self, signal: int) -> IoResult<()>;
261 fn wait(&mut self) -> ProcessExit;
265 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
266 fn write(&mut self, buf: &[u8]) -> IoResult<()>;
267 fn clone(&self) -> ~RtioPipe:Send;
270 pub trait RtioUnixListener {
271 fn listen(~self) -> IoResult<~RtioUnixAcceptor:Send>;
274 pub trait RtioUnixAcceptor {
275 fn accept(&mut self) -> IoResult<~RtioPipe:Send>;
279 fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
280 fn write(&mut self, buf: &[u8]) -> IoResult<()>;
281 fn set_raw(&mut self, raw: bool) -> IoResult<()>;
282 fn get_winsize(&mut self) -> IoResult<(int, int)>;
283 fn isatty(&self) -> bool;
286 pub trait PausableIdleCallback {
288 fn resume(&mut self);
291 pub trait RtioSignal {}