Use level-triggered events for listening stream sockets.
The limit of 20 accepted connections per event invocation can otherwise lead to no more connections being accepted when more that 20 connections are available at a time. This is an adaptation of @Boris-Barboris pull request #21 to restrict the level triggered behavior to listening sockets. See also #20.
This commit is contained in:
parent
eb595ef858
commit
fc5df2f949
|
@ -91,7 +91,7 @@ final class PosixEventDriver(Loop : PosixEventLoop) : EventDriver {
|
|||
{
|
||||
m_files.dispose();
|
||||
m_dns.dispose();
|
||||
m_loop.dispose();
|
||||
m_loop.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,11 +215,11 @@ package class PosixEventLoop {
|
|||
protected abstract bool doProcessEvents(Duration dur);
|
||||
|
||||
/// Registers the FD for general notification reception.
|
||||
protected abstract void registerFD(FD fd, EventMask mask);
|
||||
protected abstract void registerFD(FD fd, EventMask mask, bool edge_triggered = true);
|
||||
/// Unregisters the FD for general notification reception.
|
||||
protected abstract void unregisterFD(FD fd, EventMask mask);
|
||||
/// Updates the event mask to use for listening for notifications.
|
||||
protected abstract void updateFD(FD fd, EventMask old_mask, EventMask new_mask);
|
||||
protected abstract void updateFD(FD fd, EventMask old_mask, EventMask new_mask, bool edge_triggered = true);
|
||||
|
||||
final protected void notify(EventType evt)(FD fd)
|
||||
{
|
||||
|
|
|
@ -62,11 +62,11 @@ final class EpollEventLoop : PosixEventLoop {
|
|||
close(m_epoll);
|
||||
}
|
||||
|
||||
override void registerFD(FD fd, EventMask mask)
|
||||
override void registerFD(FD fd, EventMask mask, bool edge_triggered = true)
|
||||
{
|
||||
debug (EventCoreEpollDebug) print("Epoll register FD %s: %s", fd, mask);
|
||||
epoll_event ev;
|
||||
ev.events |= EPOLLET;
|
||||
if (edge_triggered) ev.events |= EPOLLET;
|
||||
if (mask & EventMask.read) ev.events |= EPOLLIN;
|
||||
if (mask & EventMask.write) ev.events |= EPOLLOUT;
|
||||
if (mask & EventMask.status) ev.events |= EPOLLERR|EPOLLHUP|EPOLLRDHUP;
|
||||
|
@ -80,11 +80,11 @@ final class EpollEventLoop : PosixEventLoop {
|
|||
() @trusted { epoll_ctl(m_epoll, EPOLL_CTL_DEL, cast(int)fd, null); } ();
|
||||
}
|
||||
|
||||
override void updateFD(FD fd, EventMask old_mask, EventMask mask)
|
||||
override void updateFD(FD fd, EventMask old_mask, EventMask mask, bool edge_triggered = true)
|
||||
{
|
||||
debug (EventCoreEpollDebug) print("Epoll update FD %s: %s", fd, mask);
|
||||
epoll_event ev;
|
||||
ev.events |= EPOLLET;
|
||||
if (edge_triggered) ev.events |= EPOLLET;
|
||||
//ev.events = EPOLLONESHOT;
|
||||
if (mask & EventMask.read) ev.events |= EPOLLIN;
|
||||
if (mask & EventMask.write) ev.events |= EPOLLOUT;
|
||||
|
|
|
@ -86,12 +86,13 @@ final class KqueueEventLoop : PosixEventLoop {
|
|||
close(m_queue);
|
||||
}
|
||||
|
||||
override void registerFD(FD fd, EventMask mask)
|
||||
override void registerFD(FD fd, EventMask mask, bool edge_triggered = true)
|
||||
{
|
||||
//print("register %s %s", fd, mask);
|
||||
kevent_t ev;
|
||||
ev.ident = fd;
|
||||
ev.flags = EV_ADD|EV_CLEAR|EV_ENABLE;
|
||||
ev.flags = EV_ADD|EV_ENABLE;
|
||||
if (edge_triggered) ev.flags |= EV_CLEAR;
|
||||
if (mask & EventMask.read) {
|
||||
ev.filter = EVFILT_READ;
|
||||
m_changes ~= ev;
|
||||
|
@ -111,21 +112,23 @@ final class KqueueEventLoop : PosixEventLoop {
|
|||
m_changes ~= ev;
|
||||
}
|
||||
|
||||
override void updateFD(FD fd, EventMask old_mask, EventMask new_mask)
|
||||
override void updateFD(FD fd, EventMask old_mask, EventMask new_mask, bool edge_triggered = true)
|
||||
{
|
||||
//print("update %s %s", fd, mask);
|
||||
kevent_t ev;
|
||||
auto changes = old_mask ^ new_mask;
|
||||
|
||||
|
||||
if (changes & EventMask.read) {
|
||||
ev.filter = EVFILT_READ;
|
||||
ev.flags = EV_CLEAR | (new_mask & EventMask.read ? EV_ADD : EV_DELETE);
|
||||
ev.flags = new_mask & EventMask.read ? EV_ADD : EV_DELETE;
|
||||
if (edge_triggered) ev.flags |= EV_CLEAR;
|
||||
m_changes ~= ev;
|
||||
}
|
||||
|
||||
|
||||
if (changes & EventMask.write) {
|
||||
ev.filter = EVFILT_WRITE;
|
||||
ev.flags = EV_CLEAR | (new_mask & EventMask.write ? EV_ADD : EV_DELETE);
|
||||
ev.flags = new_mask & EventMask.write ? EV_ADD : EV_DELETE;
|
||||
if (edge_triggered) ev.flags |= EV_CLEAR;
|
||||
m_changes ~= ev;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ final class SelectEventLoop : PosixEventLoop {
|
|||
{
|
||||
}
|
||||
|
||||
override void registerFD(FD fd, EventMask mask)
|
||||
override void registerFD(FD fd, EventMask mask, bool edge_triggered = true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ final class SelectEventLoop : PosixEventLoop {
|
|||
{
|
||||
}
|
||||
|
||||
override void updateFD(FD fd, EventMask old_mask, EventMask mask)
|
||||
override void updateFD(FD fd, EventMask old_mask, EventMask mask, bool edge_triggered = true)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ final class PosixEventDriverSockets(Loop : PosixEventLoop) : EventDriverSockets
|
|||
|
||||
final override void waitForConnections(StreamListenSocketFD sock, AcceptCallback on_accept)
|
||||
{
|
||||
m_loop.registerFD(sock, EventMask.read);
|
||||
m_loop.registerFD(sock, EventMask.read, false);
|
||||
m_loop.m_fds[sock].streamListen.acceptCallback = on_accept;
|
||||
m_loop.setNotifyCallback!(EventType.read)(sock, &onAccept);
|
||||
onAccept(sock);
|
||||
|
|
Loading…
Reference in a new issue