| Index: runtime/bin/eventhandler_macos.cc
|
| diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
|
| index b7d4fde975e809c72cb93d7844d5ad59f4d36e99..8024e1c406cf53a0637710a4c7eca52f81dfddb4 100644
|
| --- a/runtime/bin/eventhandler_macos.cc
|
| +++ b/runtime/bin/eventhandler_macos.cc
|
| @@ -47,26 +47,11 @@ bool SocketData::HasWriteEvent() {
|
| static void RemoveFromKqueue(intptr_t kqueue_fd_, SocketData* sd) {
|
| if (!sd->tracked_by_kqueue()) return;
|
| static const intptr_t kMaxChanges = 2;
|
| - intptr_t changes = 0;
|
| struct kevent events[kMaxChanges];
|
| - if (sd->HasReadEvent()) {
|
| - EV_SET(events + changes, sd->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL);
|
| - ++changes;
|
| - }
|
| - if (sd->HasWriteEvent()) {
|
| - EV_SET(events + changes, sd->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
|
| - ++changes;
|
| - }
|
| - ASSERT(changes > 0);
|
| - ASSERT(changes <= kMaxChanges);
|
| - int status =
|
| - TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL));
|
| - if (status == -1) {
|
| - const int kBufferSize = 1024;
|
| - char error_message[kBufferSize];
|
| - strerror_r(errno, error_message, kBufferSize);
|
| - FATAL1("Failed deleting events from kqueue: %s\n", error_message);
|
| - }
|
| + EV_SET(events, sd->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL);
|
| + VOID_TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, 1, NULL, 0, NULL));
|
| + EV_SET(events, sd->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
|
| + VOID_TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, 1, NULL, 0, NULL));
|
| sd->set_tracked_by_kqueue(false);
|
| }
|
|
|
| @@ -74,6 +59,7 @@ static void RemoveFromKqueue(intptr_t kqueue_fd_, SocketData* sd) {
|
| // Update the kqueue registration for SocketData structure to reflect
|
| // the events currently of interest.
|
| static void AddToKqueue(intptr_t kqueue_fd_, SocketData* sd) {
|
| + ASSERT(!sd->tracked_by_kqueue());
|
| static const intptr_t kMaxChanges = 2;
|
| intptr_t changes = 0;
|
| struct kevent events[kMaxChanges];
|
| @@ -102,7 +88,7 @@ static void AddToKqueue(intptr_t kqueue_fd_, SocketData* sd) {
|
| ASSERT(changes > 0);
|
| ASSERT(changes <= kMaxChanges);
|
| int status =
|
| - TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL));
|
| + TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL));
|
| if (status == -1) {
|
| // kQueue does not accept the file descriptor. It could be due to
|
| // already closed file descriptor, or unuspported devices, such
|
| @@ -152,8 +138,7 @@ EventHandlerImplementation::~EventHandlerImplementation() {
|
| }
|
|
|
|
|
| -SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd,
|
| - bool* is_new) {
|
| +SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) {
|
| ASSERT(fd >= 0);
|
| HashMap::Entry* entry = socket_map_.Lookup(
|
| GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true);
|
| @@ -164,7 +149,6 @@ SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd,
|
| // new SocketData for the file descriptor is inserted.
|
| sd = new SocketData(fd);
|
| entry->value = sd;
|
| - *is_new = true;
|
| }
|
| ASSERT(fd == sd->fd());
|
| return sd;
|
| @@ -203,19 +187,15 @@ void EventHandlerImplementation::HandleInterruptFd() {
|
| } else if (msg[i].id == kShutdownId) {
|
| shutdown_ = true;
|
| } else {
|
| - bool is_new = false;
|
| - SocketData* sd = GetSocketData(msg[i].id, &is_new);
|
| - if (is_new) {
|
| - sd->SetPortAndMask(msg[i].dart_port, msg[i].data);
|
| - }
|
| + SocketData* sd = GetSocketData(msg[i].id);
|
| if ((msg[i].data & (1 << kShutdownReadCommand)) != 0) {
|
| ASSERT(msg[i].data == (1 << kShutdownReadCommand));
|
| // Close the socket for reading.
|
| - sd->ShutdownRead();
|
| + shutdown(sd->fd(), SHUT_RD);
|
| } else if ((msg[i].data & (1 << kShutdownWriteCommand)) != 0) {
|
| ASSERT(msg[i].data == (1 << kShutdownWriteCommand));
|
| // Close the socket for writing.
|
| - sd->ShutdownWrite();
|
| + shutdown(sd->fd(), SHUT_WR);
|
| } else if ((msg[i].data & (1 << kCloseCommand)) != 0) {
|
| ASSERT(msg[i].data == (1 << kCloseCommand));
|
| // Close the socket and free system resources.
|
| @@ -225,10 +205,17 @@ void EventHandlerImplementation::HandleInterruptFd() {
|
| socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
|
| delete sd;
|
| DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent);
|
| - } else {
|
| - if (is_new) {
|
| + } else if ((msg[i].data & (1 << kReturnTokenCommand)) != 0) {
|
| + if (sd->ReturnToken()) {
|
| AddToKqueue(kqueue_fd_, sd);
|
| }
|
| + } else {
|
| + // Setup events to wait for.
|
| + ASSERT((msg[i].data > 0) && (msg[i].data < kIntptrMax));
|
| + ASSERT(sd->port() == 0);
|
| + sd->SetPortAndMask(msg[i].dart_port,
|
| + static_cast<intptr_t>(msg[i].data));
|
| + AddToKqueue(kqueue_fd_, sd);
|
| }
|
| }
|
| }
|
| @@ -320,6 +307,10 @@ void EventHandlerImplementation::HandleEvents(struct kevent* events,
|
| SocketData* sd = reinterpret_cast<SocketData*>(events[i].udata);
|
| intptr_t event_mask = GetEvents(events + i, sd);
|
| if (event_mask != 0) {
|
| + if (sd->TakeToken()) {
|
| + // Took last token, remove from epoll.
|
| + RemoveFromKqueue(kqueue_fd_, sd);
|
| + }
|
| Dart_Port port = sd->port();
|
| ASSERT(port != 0);
|
| DartUtils::PostInt32(port, event_mask);
|
| @@ -408,13 +399,13 @@ void EventHandlerImplementation::Start(EventHandler* handler) {
|
|
|
|
|
| void EventHandlerImplementation::Shutdown() {
|
| - Notify(kShutdownId, 0, 0);
|
| + SendData(kShutdownId, 0, 0);
|
| }
|
|
|
|
|
| -void EventHandlerImplementation::Notify(intptr_t id,
|
| - Dart_Port dart_port,
|
| - int64_t data) {
|
| +void EventHandlerImplementation::SendData(intptr_t id,
|
| + Dart_Port dart_port,
|
| + int64_t data) {
|
| WakeupHandler(id, dart_port, data);
|
| }
|
|
|
|
|