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:
Sönke Ludwig 2017-09-02 00:11:34 +02:00
parent eb595ef858
commit fc5df2f949
No known key found for this signature in database
GPG key ID: D95E8DB493EE314C
5 changed files with 20 additions and 17 deletions

View file

@ -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;
}