1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
extern crate nix;
extern crate slab;
extern crate num_cpus;
extern crate pad;
extern crate time;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate error_chain;
#[macro_use] extern crate log;
#[macro_export]
macro_rules! eintr {
($syscall:expr, $name:expr, $($arg:expr),*) => {{
let res;
loop {
match $syscall($($arg),*) {
Ok(m) => {
res = Ok(Some(m));
break;
},
Err(::nix::Error::Sys(::nix::errno::EAGAIN)) => {
trace!("{}: EAGAIN: socket not ready", $name);
res = Ok(None);
break;
},
Err(::nix::Error::Sys(::nix::errno::EINTR)) => {
debug!("{}: EINTR: re-submitting syscall", $name);
continue;
},
Err(err) => {
res = Err(err);
break;
}
}
}
res
}}
}
#[macro_export]
macro_rules! report_err {
($name:expr, $err:expr) => {{
let e: Error = $err;
error!("{}: {}\n{:?}", $name, e, e.backtrace());
for e in e.iter().skip(1) {
error!("caused_by: {}", e);
}
}}
}
#[macro_export]
macro_rules! perrorr {
($name:expr, $res:expr) => {{
match $res {
Ok(s) => s,
Err(err) => {
let err: Error = err.into();
report_err!($name, err);
return;
}
}
}}
}
#[macro_export]
macro_rules! perror {
($name:expr, $res:expr) => {{
match $res {
Ok(s) => s,
Err(e) => {
report_err!($name, e.into());
},
}
}}
}
mod constants;
pub mod protocol;
pub mod poll;
pub mod buf;
pub mod handler;
pub mod server;
pub mod logging;
pub mod error;
use std::os::unix::io::{AsRawFd, RawFd};
pub use poll::{Epoll, EpollFd, EpollEvent};
pub use handler::Handler;
pub use handler::sync::SyncHandler;
pub use server::{Server, ServerImpl};
pub use logging::{LoggingBackend, SimpleLogging};
pub use error::Result;
pub use protocol::{IOProtocol, Action};
pub use nix::unistd;
pub use nix::unistd::close;
pub use nix::sys::socket::{shutdown, Shutdown};
pub use nix::fcntl;
pub use nix::sys::stat;
pub fn write(fd: RawFd, buf: &[u8]) -> Result<Option<usize>> {
let b = try!(eintr!(unistd::write, "unistd::write", fd, buf));
Ok(b)
}
pub fn read(fd: RawFd, buf: &mut [u8]) -> Result<Option<usize>> {
let b = try!(eintr!(unistd::read, "unistd::read", fd, buf));
trace!("unistd::read {:?} bytes", b);
Ok(b)
}