]> git.lizzy.rs Git - rust.git/blob - src/libstd/rt/rtio.rs
auto merge of #11386 : rcatolino/rust/ice-10955, r=pcwalton
[rust.git] / src / libstd / rt / rtio.rs
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.
4 //
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.
10
11 use c_str::CString;
12 use cast;
13 use comm::{SharedChan, Port};
14 use libc::c_int;
15 use libc;
16 use ops::Drop;
17 use option::{Option, Some, None};
18 use path::Path;
19 use result::{Result, Ok, Err};
20 use rt::task::Task;
21 use rt::local::Local;
22
23 use ai = io::net::addrinfo;
24 use io;
25 use io::IoError;
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};
30 use io::{SeekStyle};
31
32 pub trait Callback {
33     fn call(&mut self);
34 }
35
36 pub trait EventLoop {
37     fn run(&mut self);
38     fn callback(&mut self, proc());
39     fn pausable_idle_callback(&mut self, ~Callback) -> ~PausableIdleCallback;
40     fn remote_callback(&mut self, ~Callback) -> ~RemoteCallback;
41
42     /// The asynchronous I/O services. Not all event loops may provide one.
43     fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory>;
44 }
45
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.
53     fn fire(&mut self);
54 }
55
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
61     path: Path,
62     /// Flags for file access mode (as per open(2))
63     flags: int,
64     /// File creation mode, ignored unless O_CREAT is passed as part of flags
65     priv mode: int
66 }
67
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
71     DontClose,
72     /// Synchronously close the handle, meaning that the task will block when
73     /// the handle is destroyed until it has been fully closed.
74     CloseSynchronously,
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
78     /// loop).
79     CloseAsynchronously,
80 }
81
82 pub struct LocalIo<'a> {
83     priv factory: &'a mut IoFactory,
84 }
85
86 #[unsafe_destructor]
87 impl<'a> Drop for LocalIo<'a> {
88     fn drop(&mut self) {
89         // XXX(pcwalton): Do nothing here for now, but eventually we may want
90         // something. For now this serves to make `LocalIo` noncopyable.
91     }
92 }
93
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> {
98         // FIXME(#11053): bad
99         //
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).
108         //
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) }
114         });
115         Local::put(t);
116         return ret;
117     }
118
119     pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> Result<T, IoError>)
120         -> Option<T>
121     {
122         match LocalIo::borrow() {
123             None => {
124                 io::io_error::cond.raise(io::standard_error(io::IoUnavailable));
125                 None
126             }
127             Some(mut io) => {
128                 match f(io.get()) {
129                     Ok(t) => Some(t),
130                     Err(ioerr) => {
131                         io::io_error::cond.raise(ioerr);
132                         None
133                     }
134                 }
135             }
136         }
137     }
138
139     pub fn new<'a>(io: &'a mut IoFactory) -> LocalIo<'a> {
140         LocalIo { factory: io }
141     }
142
143     /// Returns the underlying I/O factory as a trait reference.
144     #[inline]
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?
148         unsafe {
149             cast::transmute_copy(&self.factory)
150         }
151     }
152 }
153
154 pub trait IoFactory {
155     // networking
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>;
164
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) ->
181         Result<(), IoError>;
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) ->
186         Result<(), IoError>;
187
188     // misc
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>;
197 }
198
199 pub trait RtioTcpListener : RtioSocket {
200     fn listen(~self) -> Result<~RtioTcpAcceptor, IoError>;
201 }
202
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>;
207 }
208
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>;
217 }
218
219 pub trait RtioSocket {
220     fn socket_name(&mut self) -> Result<SocketAddr, IoError>;
221 }
222
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>;
226
227     fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
228     fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
229
230     fn loop_multicast_locally(&mut self) -> Result<(), IoError>;
231     fn dont_loop_multicast_locally(&mut self) -> Result<(), IoError>;
232
233     fn multicast_time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
234     fn time_to_live(&mut self, ttl: int) -> Result<(), IoError>;
235
236     fn hear_broadcasts(&mut self) -> Result<(), IoError>;
237     fn ignore_broadcasts(&mut self) -> Result<(), IoError>;
238 }
239
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<()>;
244 }
245
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>;
256 }
257
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;
262 }
263
264 pub trait RtioPipe {
265     fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
266     fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
267 }
268
269 pub trait RtioUnixListener {
270     fn listen(~self) -> Result<~RtioUnixAcceptor, IoError>;
271 }
272
273 pub trait RtioUnixAcceptor {
274     fn accept(&mut self) -> Result<~RtioPipe, IoError>;
275 }
276
277 pub trait RtioTTY {
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;
283 }
284
285 pub trait PausableIdleCallback {
286     fn pause(&mut self);
287     fn resume(&mut self);
288 }
289
290 pub trait RtioSignal {}