]> git.lizzy.rs Git - rust.git/blob - src/libstd/rt/rtio.rs
auto merge of #13711 : alexcrichton/rust/snapshots, r=brson
[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::{Sender, Receiver};
14 use libc::c_int;
15 use libc;
16 use kinds::Send;
17 use ops::Drop;
18 use option::{Option, Some, None};
19 use path::Path;
20 use result::Err;
21 use rt::local::Local;
22 use rt::task::Task;
23 use vec::Vec;
24
25 use ai = io::net::addrinfo;
26 use io;
27 use io::IoResult;
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};
32 use io::{SeekStyle};
33
34 pub trait Callback {
35     fn call(&mut self);
36 }
37
38 pub trait EventLoop {
39     fn run(&mut self);
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;
44
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;
48 }
49
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.
57     fn fire(&mut self);
58 }
59
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
65     pub path: Path,
66     /// Flags for file access mode (as per open(2))
67     pub flags: int,
68     /// File creation mode, ignored unless O_CREAT is passed as part of flags
69     pub mode: int
70 }
71
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
75     DontClose,
76     /// Synchronously close the handle, meaning that the task will block when
77     /// the handle is destroyed until it has been fully closed.
78     CloseSynchronously,
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
82     /// loop).
83     CloseAsynchronously,
84 }
85
86 pub struct LocalIo<'a> {
87     factory: &'a mut IoFactory,
88 }
89
90 #[unsafe_destructor]
91 impl<'a> Drop for LocalIo<'a> {
92     fn drop(&mut self) {
93         // FIXME(pcwalton): Do nothing here for now, but eventually we may want
94         // something. For now this serves to make `LocalIo` noncopyable.
95     }
96 }
97
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
103         //
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).
112         //
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) }
118         });
119         Local::put(t);
120         return ret;
121     }
122
123     pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> IoResult<T>)
124         -> IoResult<T>
125     {
126         match LocalIo::borrow() {
127             None => Err(io::standard_error(io::IoUnavailable)),
128             Some(mut io) => f(io.get()),
129         }
130     }
131
132     pub fn new<'a>(io: &'a mut IoFactory) -> LocalIo<'a> {
133         LocalIo { factory: io }
134     }
135
136     /// Returns the underlying I/O factory as a trait reference.
137     #[inline]
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?
141         unsafe {
142             cast::transmute_copy(&self.factory)
143         }
144     }
145 }
146
147 pub trait IoFactory {
148     // networking
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]>;
158
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) ->
173         IoResult<Vec<Path>>;
174     fn fs_lstat(&mut self, path: &CString) -> IoResult<FileStat>;
175     fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
176         IoResult<()>;
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) ->
181         IoResult<()>;
182
183     // misc
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>;
193 }
194
195 pub trait RtioTcpListener : RtioSocket {
196     fn listen(~self) -> IoResult<~RtioTcpAcceptor:Send>;
197 }
198
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<()>;
203     fn set_timeout(&mut self, timeout: Option<u64>);
204 }
205
206 pub trait RtioTcpStream : RtioSocket {
207     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
208     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
209     fn peer_name(&mut self) -> IoResult<SocketAddr>;
210     fn control_congestion(&mut self) -> IoResult<()>;
211     fn nodelay(&mut self) -> IoResult<()>;
212     fn keepalive(&mut self, delay_in_seconds: uint) -> IoResult<()>;
213     fn letdie(&mut self) -> IoResult<()>;
214     fn clone(&self) -> ~RtioTcpStream:Send;
215     fn close_write(&mut self) -> IoResult<()>;
216 }
217
218 pub trait RtioSocket {
219     fn socket_name(&mut self) -> IoResult<SocketAddr>;
220 }
221
222 pub trait RtioUdpSocket : RtioSocket {
223     fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)>;
224     fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()>;
225
226     fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
227     fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
228
229     fn loop_multicast_locally(&mut self) -> IoResult<()>;
230     fn dont_loop_multicast_locally(&mut self) -> IoResult<()>;
231
232     fn multicast_time_to_live(&mut self, ttl: int) -> IoResult<()>;
233     fn time_to_live(&mut self, ttl: int) -> IoResult<()>;
234
235     fn hear_broadcasts(&mut self) -> IoResult<()>;
236     fn ignore_broadcasts(&mut self) -> IoResult<()>;
237
238     fn clone(&self) -> ~RtioUdpSocket:Send;
239 }
240
241 pub trait RtioTimer {
242     fn sleep(&mut self, msecs: u64);
243     fn oneshot(&mut self, msecs: u64) -> Receiver<()>;
244     fn period(&mut self, msecs: u64) -> Receiver<()>;
245 }
246
247 pub trait RtioFileStream {
248     fn read(&mut self, buf: &mut [u8]) -> IoResult<int>;
249     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
250     fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int>;
251     fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()>;
252     fn seek(&mut self, pos: i64, whence: SeekStyle) -> IoResult<u64>;
253     fn tell(&self) -> IoResult<u64>;
254     fn fsync(&mut self) -> IoResult<()>;
255     fn datasync(&mut self) -> IoResult<()>;
256     fn truncate(&mut self, offset: i64) -> IoResult<()>;
257 }
258
259 pub trait RtioProcess {
260     fn id(&self) -> libc::pid_t;
261     fn kill(&mut self, signal: int) -> IoResult<()>;
262     fn wait(&mut self) -> ProcessExit;
263 }
264
265 pub trait RtioPipe {
266     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
267     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
268     fn clone(&self) -> ~RtioPipe:Send;
269 }
270
271 pub trait RtioUnixListener {
272     fn listen(~self) -> IoResult<~RtioUnixAcceptor:Send>;
273 }
274
275 pub trait RtioUnixAcceptor {
276     fn accept(&mut self) -> IoResult<~RtioPipe:Send>;
277 }
278
279 pub trait RtioTTY {
280     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
281     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
282     fn set_raw(&mut self, raw: bool) -> IoResult<()>;
283     fn get_winsize(&mut self) -> IoResult<(int, int)>;
284     fn isatty(&self) -> bool;
285 }
286
287 pub trait PausableIdleCallback {
288     fn pause(&mut self);
289     fn resume(&mut self);
290 }
291
292 pub trait RtioSignal {}