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. */