]> git.lizzy.rs Git - rust.git/blob - src/libstd/rt/rtio.rs
auto merge of #13967 : richo/rust/features/ICE-fails, r=alexcrichton
[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 //! The EventLoop and internal synchronous I/O interface.
12
13 use c_str::CString;
14 use cast;
15 use comm::{Sender, Receiver};
16 use libc::c_int;
17 use libc;
18 use kinds::Send;
19 use ops::Drop;
20 use option::{Option, Some, None};
21 use owned::Box;
22 use path::Path;
23 use result::Err;
24 use rt::local::Local;
25 use rt::task::Task;
26 use vec::Vec;
27
28 use ai = io::net::addrinfo;
29 use io;
30 use io::IoResult;
31 use io::net::ip::{IpAddr, SocketAddr};
32 use io::process::{ProcessConfig, ProcessExit};
33 use io::signal::Signum;
34 use io::{FileMode, FileAccess, FileStat, FilePermission};
35 use io::{SeekStyle};
36
37 pub trait Callback {
38     fn call(&mut self);
39 }
40
41 pub trait EventLoop {
42     fn run(&mut self);
43     fn callback(&mut self, arg: proc():Send);
44     fn pausable_idle_callback(&mut self, Box<Callback:Send>)
45                               -> Box<PausableIdleCallback:Send>;
46     fn remote_callback(&mut self, Box<Callback:Send>)
47                        -> Box<RemoteCallback:Send>;
48
49     /// The asynchronous I/O services. Not all event loops may provide one.
50     fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory>;
51     fn has_active_io(&self) -> bool;
52 }
53
54 pub trait RemoteCallback {
55     /// Trigger the remote callback. Note that the number of times the
56     /// callback is run is not guaranteed. All that is guaranteed is
57     /// that, after calling 'fire', the callback will be called at
58     /// least once, but multiple callbacks may be coalesced and
59     /// callbacks may be called more often requested. Destruction also
60     /// triggers the callback.
61     fn fire(&mut self);
62 }
63
64 /// Data needed to make a successful open(2) call
65 /// Using unix flag conventions for now, which happens to also be what's supported
66 /// libuv (it does translation to windows under the hood).
67 pub struct FileOpenConfig {
68     /// Path to file to be opened
69     pub path: Path,
70     /// Flags for file access mode (as per open(2))
71     pub flags: int,
72     /// File creation mode, ignored unless O_CREAT is passed as part of flags
73     pub mode: int
74 }
75
76 /// Description of what to do when a file handle is closed
77 pub enum CloseBehavior {
78     /// Do not close this handle when the object is destroyed
79     DontClose,
80     /// Synchronously close the handle, meaning that the task will block when
81     /// the handle is destroyed until it has been fully closed.
82     CloseSynchronously,
83     /// Asynchronously closes a handle, meaning that the task will *not* block
84     /// when the handle is destroyed, but the handle will still get deallocated
85     /// and cleaned up (but this will happen asynchronously on the local event
86     /// loop).
87     CloseAsynchronously,
88 }
89
90 pub struct LocalIo<'a> {
91     factory: &'a mut IoFactory,
92 }
93
94 #[unsafe_destructor]
95 impl<'a> Drop for LocalIo<'a> {
96     fn drop(&mut self) {
97         // FIXME(pcwalton): Do nothing here for now, but eventually we may want
98         // something. For now this serves to make `LocalIo` noncopyable.
99     }
100 }
101
102 impl<'a> LocalIo<'a> {
103     /// Returns the local I/O: either the local scheduler's I/O services or
104     /// the native I/O services.
105     pub fn borrow() -> Option<LocalIo> {
106         // FIXME(#11053): bad
107         //
108         // This is currently very unsafely implemented. We don't actually
109         // *take* the local I/O so there's a very real possibility that we
110         // can have two borrows at once. Currently there is not a clear way
111         // to actually borrow the local I/O factory safely because even if
112         // ownership were transferred down to the functions that the I/O
113         // factory implements it's just too much of a pain to know when to
114         // relinquish ownership back into the local task (but that would be
115         // the safe way of implementing this function).
116         //
117         // In order to get around this, we just transmute a copy out of the task
118         // in order to have what is likely a static lifetime (bad).
119         let mut t: Box<Task> = Local::take();
120         let ret = t.local_io().map(|t| {
121             unsafe { cast::transmute_copy(&t) }
122         });
123         Local::put(t);
124         return ret;
125     }
126
127     pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> IoResult<T>)
128         -> IoResult<T>
129     {
130         match LocalIo::borrow() {
131             None => Err(io::standard_error(io::IoUnavailable)),
132             Some(mut io) => f(io.get()),
133         }
134     }
135
136     pub fn new<'a>(io: &'a mut IoFactory) -> LocalIo<'a> {
137         LocalIo { factory: io }
138     }
139
140     /// Returns the underlying I/O factory as a trait reference.
141     #[inline]
142     pub fn get<'a>(&'a mut self) -> &'a mut IoFactory {
143         // FIXME(pcwalton): I think this is actually sound? Could borrow check
144         // allow this safely?
145         unsafe {
146             cast::transmute_copy(&self.factory)
147         }
148     }
149 }
150
151 pub trait IoFactory {
152     // networking
153     fn tcp_connect(&mut self, addr: SocketAddr,
154                    timeout: Option<u64>) -> IoResult<Box<RtioTcpStream:Send>>;
155     fn tcp_bind(&mut self, addr: SocketAddr)
156                 -> IoResult<Box<RtioTcpListener:Send>>;
157     fn udp_bind(&mut self, addr: SocketAddr)
158                 -> IoResult<Box<RtioUdpSocket:Send>>;
159     fn unix_bind(&mut self, path: &CString)
160                  -> IoResult<Box<RtioUnixListener:Send>>;
161     fn unix_connect(&mut self, path: &CString,
162                     timeout: Option<u64>) -> IoResult<Box<RtioPipe:Send>>;
163     fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
164                           hint: Option<ai::Hint>) -> IoResult<~[ai::Info]>;
165
166     // filesystem operations
167     fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior)
168                       -> Box<RtioFileStream:Send>;
169     fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
170                -> IoResult<Box<RtioFileStream:Send>>;
171     fn fs_unlink(&mut self, path: &CString) -> IoResult<()>;
172     fn fs_stat(&mut self, path: &CString) -> IoResult<FileStat>;
173     fn fs_mkdir(&mut self, path: &CString,
174                 mode: FilePermission) -> IoResult<()>;
175     fn fs_chmod(&mut self, path: &CString,
176                 mode: FilePermission) -> IoResult<()>;
177     fn fs_rmdir(&mut self, path: &CString) -> IoResult<()>;
178     fn fs_rename(&mut self, path: &CString, to: &CString) -> IoResult<()>;
179     fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
180         IoResult<Vec<Path>>;
181     fn fs_lstat(&mut self, path: &CString) -> IoResult<FileStat>;
182     fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
183         IoResult<()>;
184     fn fs_readlink(&mut self, path: &CString) -> IoResult<Path>;
185     fn fs_symlink(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
186     fn fs_link(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
187     fn fs_utime(&mut self, src: &CString, atime: u64, mtime: u64) ->
188         IoResult<()>;
189
190     // misc
191     fn timer_init(&mut self) -> IoResult<Box<RtioTimer:Send>>;
192     fn spawn(&mut self, config: ProcessConfig)
193             -> IoResult<(Box<RtioProcess:Send>,
194                          ~[Option<Box<RtioPipe:Send>>])>;
195     fn kill(&mut self, pid: libc::pid_t, signal: int) -> IoResult<()>;
196     fn pipe_open(&mut self, fd: c_int) -> IoResult<Box<RtioPipe:Send>>;
197     fn tty_open(&mut self, fd: c_int, readable: bool)
198             -> IoResult<Box<RtioTTY:Send>>;
199     fn signal(&mut self, signal: Signum, channel: Sender<Signum>)
200         -> IoResult<Box<RtioSignal:Send>>;
201 }
202
203 pub trait RtioTcpListener : RtioSocket {
204     fn listen(~self) -> IoResult<Box<RtioTcpAcceptor:Send>>;
205 }
206
207 pub trait RtioTcpAcceptor : RtioSocket {
208     fn accept(&mut self) -> IoResult<Box<RtioTcpStream:Send>>;
209     fn accept_simultaneously(&mut self) -> IoResult<()>;
210     fn dont_accept_simultaneously(&mut self) -> IoResult<()>;
211     fn set_timeout(&mut self, timeout: Option<u64>);
212 }
213
214 pub trait RtioTcpStream : RtioSocket {
215     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
216     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
217     fn peer_name(&mut self) -> IoResult<SocketAddr>;
218     fn control_congestion(&mut self) -> IoResult<()>;
219     fn nodelay(&mut self) -> IoResult<()>;
220     fn keepalive(&mut self, delay_in_seconds: uint) -> IoResult<()>;
221     fn letdie(&mut self) -> IoResult<()>;
222     fn clone(&self) -> Box<RtioTcpStream:Send>;
223     fn close_write(&mut self) -> IoResult<()>;
224 }
225
226 pub trait RtioSocket {
227     fn socket_name(&mut self) -> IoResult<SocketAddr>;
228 }
229
230 pub trait RtioUdpSocket : RtioSocket {
231     fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)>;
232     fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()>;
233
234     fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
235     fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
236
237     fn loop_multicast_locally(&mut self) -> IoResult<()>;
238     fn dont_loop_multicast_locally(&mut self) -> IoResult<()>;
239
240     fn multicast_time_to_live(&mut self, ttl: int) -> IoResult<()>;
241     fn time_to_live(&mut self, ttl: int) -> IoResult<()>;
242
243     fn hear_broadcasts(&mut self) -> IoResult<()>;
244     fn ignore_broadcasts(&mut self) -> IoResult<()>;
245
246     fn clone(&self) -> Box<RtioUdpSocket:Send>;
247 }
248
249 pub trait RtioTimer {
250     fn sleep(&mut self, msecs: u64);
251     fn oneshot(&mut self, msecs: u64) -> Receiver<()>;
252     fn period(&mut self, msecs: u64) -> Receiver<()>;
253 }
254
255 pub trait RtioFileStream {
256     fn read(&mut self, buf: &mut [u8]) -> IoResult<int>;
257     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
258     fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int>;
259     fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()>;
260     fn seek(&mut self, pos: i64, whence: SeekStyle) -> IoResult<u64>;
261     fn tell(&self) -> IoResult<u64>;
262     fn fsync(&mut self) -> IoResult<()>;
263     fn datasync(&mut self) -> IoResult<()>;
264     fn truncate(&mut self, offset: i64) -> IoResult<()>;
265 }
266
267 pub trait RtioProcess {
268     fn id(&self) -> libc::pid_t;
269     fn kill(&mut self, signal: int) -> IoResult<()>;
270     fn wait(&mut self) -> ProcessExit;
271 }
272
273 pub trait RtioPipe {
274     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
275     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
276     fn clone(&self) -> Box<RtioPipe:Send>;
277 }
278
279 pub trait RtioUnixListener {
280     fn listen(~self) -> IoResult<Box<RtioUnixAcceptor:Send>>;
281 }
282
283 pub trait RtioUnixAcceptor {
284     fn accept(&mut self) -> IoResult<Box<RtioPipe:Send>>;
285     fn set_timeout(&mut self, timeout: Option<u64>);
286 }
287
288 pub trait RtioTTY {
289     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
290     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
291     fn set_raw(&mut self, raw: bool) -> IoResult<()>;
292     fn get_winsize(&mut self) -> IoResult<(int, int)>;
293     fn isatty(&self) -> bool;
294 }
295
296 pub trait PausableIdleCallback {
297     fn pause(&mut self);
298     fn resume(&mut self);
299 }
300
301 pub trait RtioSignal {}