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::{SharedChan, Port};
17 use option::{Option, Some, None};
19 use result::{Result, Ok, Err};
23 use ai = io::net::addrinfo;
26 use io::net::ip::{IpAddr, SocketAddr};
27 use io::process::{ProcessConfig, ProcessExit};
28 use io::signal::Signum;
29 use io::{FileMode, FileAccess, FileStat, FilePermission};
38 fn callback(&mut self, proc());
39 fn pausable_idle_callback(&mut self, ~Callback) -> ~PausableIdleCallback;
40 fn remote_callback(&mut self, ~Callback) -> ~RemoteCallback;
42 /// The asynchronous I/O services. Not all event loops may provide one.
43 fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory>;
46 pub trait RemoteCallback {
47 /// Trigger the remote callback. Note that the number of times the
48 /// callback is run is not guaranteed. All that is guaranteed is
49 /// that, after calling 'fire', the callback will be called at
50 /// least once, but multiple callbacks may be coalesced and
51 /// callbacks may be called more often requested. Destruction also
52 /// triggers the callback.
56 /// Data needed to make a successful open(2) call
57 /// Using unix flag conventions for now, which happens to also be what's supported
58 /// libuv (it does translation to windows under the hood).
59 pub struct FileOpenConfig {
60 /// Path to file to be opened
62 /// Flags for file access mode (as per open(2))
64 /// File creation mode, ignored unless O_CREAT is passed as part of flags
68 /// Description of what to do when a file handle is closed
69 pub enum CloseBehavior {
70 /// Do not close this handle when the object is destroyed
72 /// Synchronously close the handle, meaning that the task will block when
73 /// the handle is destroyed until it has been fully closed.
75 /// Asynchronously closes a handle, meaning that the task will *not* block
76 /// when the handle is destroyed, but the handle will still get deallocated
77 /// and cleaned up (but this will happen asynchronously on the local event
82 pub struct LocalIo<'a> {
83 priv factory: &'a mut IoFactory,
87 impl<'a> Drop for LocalIo<'a> {
89 // XXX(pcwalton): Do nothing here for now, but eventually we may want
90 // something. For now this serves to make `LocalIo` noncopyable.
94 impl<'a> LocalIo<'a> {
95 /// Returns the local I/O: either the local scheduler's I/O services or
96 /// the native I/O services.
97 pub fn borrow() -> Option<LocalIo> {
100 // This is currently very unsafely implemented. We don't actually
101 // *take* the local I/O so there's a very real possibility that we
102 // can have two borrows at once. Currently there is not a clear way
103 // to actually borrow the local I/O factory safely because even if
104 // ownership were transferred down to the functions that the I/O
105 // factory implements it's just too much of a pain to know when to
106 // relinquish ownership back into the local task (but that would be
107 // the safe way of implementing this function).
109 // In order to get around this, we just transmute a copy out of the task
110 // in order to have what is likely a static lifetime (bad).
111 let mut t: ~Task = Local::take();
112 let ret = t.local_io().map(|t| {
113 unsafe { cast::transmute_copy(&t) }
119 pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> Result<T, IoError>)
122 match LocalIo::borrow() {
124 io::io_error::cond.raise(io::standard_error(io::IoUnavailable));
131 io::io_error::cond.raise(ioerr);
139 pub fn new<'a>(io: &'a mut IoFactory) -> LocalIo<'a> {
140 LocalIo { factory: io }
143 /// Returns the underlying I/O factory as a trait reference.
145 pub fn get<'a>(&'a mut self) -> &'a mut IoFactory {
146 // XXX(pcwalton): I think this is actually sound? Could borrow check
147 // allow this safely?
149 cast::transmute_copy(&self.factory)
154 pub trait IoFactory {
156 fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStream, IoError>;
157 fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListener, IoError>;
158 fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocket, IoError>;
159 fn unix_bind(&mut self, path: &CString) ->
160 Result<~RtioUnixListener, IoError>;
161 fn unix_connect(&mut self, path: &CString) -> Result<~RtioPipe, IoError>;
162 fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
163 hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError>;
165 // filesystem operations
166 fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior) -> ~RtioFileStream;
167 fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
168 -> Result<~RtioFileStream, IoError>;
169 fn fs_unlink(&mut self, path: &CString) -> Result<(), IoError>;
170 fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError>;
171 fn fs_mkdir(&mut self, path: &CString,
172 mode: FilePermission) -> Result<(), IoError>;
173 fn fs_chmod(&mut self, path: &CString,
174 mode: FilePermission) -> Result<(), IoError>;
175 fn fs_rmdir(&mut self, path: &CString) -> Result<(), IoError>;
176 fn fs_rename(&mut self, path: &CString, to: &CString) -> Result<(), IoError>;
177 fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
178 Result<~[Path], IoError>;
179 fn fs_lstat(&mut self, path: &CString) -> Result<FileStat, IoError>;
180 fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
182 fn fs_readlink(&mut self, path: &CString) -> Result<Path, IoError>;
183 fn fs_symlink(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
184 fn fs_link(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
185 fn fs_utime(&mut self, src: &CString, atime: u64, mtime: u64) ->
189 fn timer_init(&mut self) -> Result<~RtioTimer, IoError>;
190 fn spawn(&mut self, config: ProcessConfig)
191 -> Result<(~RtioProcess, ~[Option<~RtioPipe>]), IoError>;
192 fn pipe_open(&mut self, fd: c_int) -> Result<~RtioPipe, IoError>;
193 fn tty_open(&mut self, fd: c_int, readable: bool)
194 -> Result<~RtioTTY, IoError>;
195 fn signal(&mut self, signal: Signum, channel: SharedChan<Signum>)
196 -> Result<~RtioSignal, IoError>;
199 pub trait RtioTcpListener : RtioSocket {
200 fn listen(~self) -> Result<~RtioTcpAcceptor, IoError>;
203 pub trait RtioTcpAcceptor : RtioSocket {
204 fn accept(&mut self) -> Result<~RtioTcpStream, IoError>;
205 fn accept_simultaneously(&mut self) -> Result<(), IoError>;
206 fn dont_accept_simultaneously(&mut self) -> Result<(), IoError>;
209 pub trait RtioTcpStream : RtioSocket {
210 fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
211 fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
212 fn peer_name(&mut self) -> Result<SocketAddr, IoError>;
213 fn control_congestion(&mut self) -> Result<(), IoError>;
214 fn nodelay(&mut self) -> Result<(), IoError>;
215 fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError>;
216 fn letdie(&mut self) -> Result<(), IoError>;
219 pub trait RtioSocket {
220 fn socket_name(&mut self) -> Result<SocketAddr, IoError>;
223 pub trait RtioUdpSocket : RtioSocket {
224 fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError>;
225 fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError>;
227 fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
228 fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
230 fn loop_multicast_locally(&mut self) -> Result<(), IoError>;
231 fn dont_loop_multicast_locally(&mut self) -> Result<(), IoError>;
233 fn multicast_time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
234 fn time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
236 fn hear_broadcasts(&mut self) -> Result<(), IoError>;
237 fn ignore_broadcasts(&mut self) -> Result<(), IoError>;
240 pub trait RtioTimer {
241 fn sleep(&mut self, msecs: u64);
242 fn oneshot(&mut self, msecs: u64) -> Port<()>;
243 fn period(&mut self, msecs: u64) -> Port<()>;
246 pub trait RtioFileStream {
247 fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError>;
248 fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
249 fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError>;
250 fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError>;
251 fn seek(&mut self, pos: i64, whence: SeekStyle) -> Result<u64, IoError>;
252 fn tell(&self) -> Result<u64, IoError>;
253 fn fsync(&mut self) -> Result<(), IoError>;
254 fn datasync(&mut self) -> Result<(), IoError>;
255 fn truncate(&mut self, offset: i64) -> Result<(), IoError>;
258 pub trait RtioProcess {
259 fn id(&self) -> libc::pid_t;
260 fn kill(&mut self, signal: int) -> Result<(), IoError>;
261 fn wait(&mut self) -> ProcessExit;
265 fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
266 fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
269 pub trait RtioUnixListener {
270 fn listen(~self) -> Result<~RtioUnixAcceptor, IoError>;
273 pub trait RtioUnixAcceptor {
274 fn accept(&mut self) -> Result<~RtioPipe, IoError>;
278 fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
279 fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
280 fn set_raw(&mut self, raw: bool) -> Result<(), IoError>;
281 fn get_winsize(&mut self) -> Result<(int, int), IoError>;
282 fn isatty(&self) -> bool;
285 pub trait PausableIdleCallback {
287 fn resume(&mut self);
290 pub trait RtioSignal {}