1 module geario.net.channel.posix.AbstractListener;
2 
3 // dfmt off
4 version(Posix):
5 // dfmt on
6 
7 import geario.event.selector.Selector;
8 import geario.net.channel.AbstractSocketChannel;
9 import geario.net.channel.Types;
10 import geario.logging;
11 
12 import std.conv;
13 import std.socket;
14 
15 import core.sys.posix.sys.socket;
16 
17 
18 
19 /**
20  *  TCP Server
21  */
22 abstract class AbstractListener : AbstractSocketChannel {
23     this(Selector loop, AddressFamily family = AddressFamily.INET) {
24         super(loop, ChannelType.Accept);
25         setFlag(ChannelFlag.Read, true);
26         this.socket = new TcpSocket(family);
27     }
28 
29     protected bool OnAccept(scope AcceptHandler handler) {
30         version (GEAR_DEBUG)
31             Trace("new connection coming...");
32         this.ClearError();
33 
34         // http://man7.org/linux/man-pages/man2/accept.2.html
35         version(HAVE_EPOLL) {
36             socket_t clientFd = cast(socket_t)(accept4(this.handle, null, null, SOCK_NONBLOCK | SOCK_CLOEXEC));
37             //socket_t clientFd = cast(socket_t)(accept(this.handle, null, null));
38 
39         } else {
40             socket_t clientFd = cast(socket_t)(accept(this.handle, null, null));
41         }
42         if (clientFd == socket_t.init)
43             return false;
44 
45         version (GEAR_DEBUG)
46             log.trace("Listener fd=%d, sslClient fd=%d", this.handle, clientFd);
47 
48         if (handler !is null)
49             handler(new Socket(clientFd, this.LocalAddress.addressFamily));
50         return true;
51     }
52 
53     override void OnWriteDone() {
54         version (GEAR_DEBUG)
55             log.trace("a new connection created");
56     }
57 }
58 
59 
60 extern (C) nothrow @nogc {
61     int     accept4(int, sockaddr*, socklen_t*, int);
62 }
63 
64 enum int SOCK_CLOEXEC = std.conv.octal!(2000000); /* Atomically set close-on-exec flag for the
65                    new descriptor(s).  */
66 enum int SOCK_NONBLOCK = std.conv.octal!4000; /* Atomically mark descriptor(s) as
67                    non-blocking.  */