| Index: runtime/bin/eventhandler_macos.cc
|
| diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
|
| index 4fb47a8258a4aaa22527df93999aadcfbb3a1501..4b0566351be3a2a5faba11a09c1404a7a01c9baf 100644
|
| --- a/runtime/bin/eventhandler_macos.cc
|
| +++ b/runtime/bin/eventhandler_macos.cc
|
| @@ -78,11 +78,19 @@ static void UpdateKqueue(intptr_t kqueue_fd_, SocketData* sd) {
|
| static const intptr_t kMaxChanges = 2;
|
| intptr_t changes = 0;
|
| struct kevent events[kMaxChanges];
|
| + // Only report events once and wait for them to be re-enabled after the
|
| + // event has been handled by the Dart code. This is done by using EV_ONESHOT.
|
| if (sd->port() != 0) {
|
| // Register or unregister READ filter if needed.
|
| if (sd->HasReadEvent()) {
|
| if (!sd->read_tracked_by_kqueue()) {
|
| - EV_SET(events + changes, sd->fd(), EVFILT_READ, EV_ADD, 0, 0, sd);
|
| + EV_SET(events + changes,
|
| + sd->fd(),
|
| + EVFILT_READ,
|
| + EV_ADD | EV_ONESHOT,
|
| + 0,
|
| + 0,
|
| + sd);
|
| ++changes;
|
| sd->set_read_tracked_by_kqueue(true);
|
| }
|
| @@ -94,7 +102,13 @@ static void UpdateKqueue(intptr_t kqueue_fd_, SocketData* sd) {
|
| // Register or unregister WRITE filter if needed.
|
| if (sd->HasWriteEvent()) {
|
| if (!sd->write_tracked_by_kqueue()) {
|
| - EV_SET(events + changes, sd->fd(), EVFILT_WRITE, EV_ADD, 0, 0, sd);
|
| + EV_SET(events + changes,
|
| + sd->fd(),
|
| + EVFILT_WRITE,
|
| + EV_ADD | EV_ONESHOT,
|
| + 0,
|
| + 0,
|
| + sd);
|
| ++changes;
|
| sd->set_write_tracked_by_kqueue(true);
|
| }
|
| @@ -342,12 +356,10 @@ void EventHandlerImplementation::HandleEvents(struct kevent* events,
|
| interrupt_seen = true;
|
| } else {
|
| SocketData* sd = reinterpret_cast<SocketData*>(events[i].udata);
|
| + sd->set_read_tracked_by_kqueue(false);
|
| + sd->set_write_tracked_by_kqueue(false);
|
| intptr_t event_mask = GetEvents(events + i, sd);
|
| if (event_mask != 0) {
|
| - // Unregister events for the file descriptor. Events will be
|
| - // registered again when the current event has been handled in
|
| - // Dart code.
|
| - RemoveFromKqueue(kqueue_fd_, sd);
|
| Dart_Port port = sd->port();
|
| ASSERT(port != 0);
|
| DartUtils::PostInt32(port, event_mask);
|
|
|