asyncio/
socket_listener.rs

1use prelude::{Protocol, IoControl, GetSocketOption, SetSocketOption};
2use ffi::{RawFd, AsRawFd, socket, bind, listen, ioctl, getsockopt, setsockopt,
3          getsockname};
4use core::{IoContext, AsIoContext, Socket, AsyncFd};
5use async::Handler;
6use reactive_io::{AsAsyncFd, getnonblock, setnonblock, accept, async_accept, cancel};
7use socket_base::MAX_CONNECTIONS;
8
9use std::io;
10use std::fmt;
11use std::marker::PhantomData;
12
13/// Provides an ability to accept new connections.
14pub struct SocketListener<P, S> {
15    pro: P,
16    fd: AsyncFd,
17    _marker: PhantomData<S>,
18}
19
20impl<P: Protocol, S: Socket<P>> SocketListener<P, S> {
21    pub fn new(ctx: &IoContext, pro: P) -> io::Result<SocketListener<P, S>> {
22        let fd = try!(socket(&pro));
23        Ok(unsafe { Self::from_raw_fd(ctx, pro, fd) })
24    }
25
26    pub fn accept(&self) -> io::Result<(S, P::Endpoint)> {
27        accept(self, &self.pro)
28    }
29
30    pub fn async_accept<F>(&self, handler: F) -> F::Output
31        where F: Handler<(S, P::Endpoint), io::Error>,
32    {
33        async_accept(self, self.protocol(), handler)
34    }
35
36    pub fn bind(&self, ep: &P::Endpoint) -> io::Result<()> {
37        bind(self, ep)
38    }
39
40    pub fn cancel(&self) -> &Self {
41        cancel(self);
42        self
43    }
44
45    pub fn listen(&self) -> io::Result<()> {
46        listen(self, MAX_CONNECTIONS)
47    }
48
49    pub fn local_endpoint(&self) -> io::Result<P::Endpoint> {
50        getsockname(self, &self.pro)
51    }
52
53    pub fn io_control<T>(&self, cmd: &mut T) -> io::Result<()>
54        where T: IoControl,
55    {
56        ioctl(self, cmd)
57    }
58
59    pub fn get_non_blocking(&self) -> io::Result<bool> {
60        getnonblock(self)
61    }
62
63    pub fn get_option<C>(&self) -> io::Result<C>
64        where C: GetSocketOption<P>,
65    {
66        getsockopt(self, &self.pro)
67    }
68
69    pub fn set_non_blocking(&self, on: bool) -> io::Result<()> {
70        setnonblock(self, on)
71    }
72
73    pub fn set_option<C>(&self, cmd: C) -> io::Result<()>
74        where C: SetSocketOption<P>,
75    {
76        setsockopt(self, &self.pro, cmd)
77    }
78}
79
80impl<P: Protocol, S> fmt::Debug for SocketListener<P, S> {
81    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82        write!(f, "SocketListener({:?})", self.pro)
83    }
84}
85
86impl<P, S> AsRawFd for SocketListener<P, S> {
87    fn as_raw_fd(&self) -> RawFd {
88        self.fd.as_raw_fd()
89    }
90}
91
92unsafe impl<P, S> Send for SocketListener<P, S> { }
93
94unsafe impl<P, S> AsIoContext for SocketListener<P, S> {
95    fn as_ctx(&self) -> &IoContext {
96        self.fd.as_ctx()
97    }
98}
99
100impl<P: Protocol, S: Socket<P>> Socket<P> for SocketListener<P, S> {
101    unsafe fn from_raw_fd(ctx: &IoContext, pro: P, fd: RawFd) -> SocketListener<P, S> {
102        SocketListener {
103            pro: pro,
104            fd: AsyncFd::new::<Self>(fd, ctx),
105            _marker: PhantomData,
106        }
107    }
108
109    fn protocol(&self) -> P {
110        self.pro.clone()
111    }
112}
113
114impl<P: Protocol, S: Socket<P>> AsAsyncFd for SocketListener<P, S> {
115    fn as_fd(&self) -> &AsyncFd {
116        &self.fd
117    }
118}