| Index: runtime/bin/eventhandler_macos.cc
|
| diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
|
| index f93409235fbd3bdabd9326c70f732b150ed21c6a..83c86ea56c9b4310f819d33c834ae17858559212 100644
|
| --- a/runtime/bin/eventhandler_macos.cc
|
| +++ b/runtime/bin/eventhandler_macos.cc
|
| @@ -232,16 +232,16 @@ void EventHandlerImplementation::HandleInterruptFd() {
|
| }
|
| }
|
|
|
| -
|
| #ifdef DEBUG_KQUEUE
|
| static void PrintEventMask(intptr_t fd, struct kevent* event) {
|
| - printf("%d ", fd);
|
| + printf("%d ", static_cast<int>(fd));
|
| if (event->filter == EVFILT_READ) printf("EVFILT_READ ");
|
| if (event->filter == EVFILT_WRITE) printf("EVFILT_WRITE ");
|
| printf("flags: %x: ", event->flags);
|
| if ((event->flags & EV_EOF) != 0) printf("EV_EOF ");
|
| if ((event->flags & EV_ERROR) != 0) printf("EV_ERROR ");
|
| - printf("(available %d) ", FDUtils::AvailableBytes(fd));
|
| + printf("- fflags: %d ", event->fflags);
|
| + printf("(available %d) ", static_cast<int>(FDUtils::AvailableBytes(fd)));
|
| printf("\n");
|
| }
|
| #endif
|
| @@ -257,8 +257,13 @@ intptr_t EventHandlerImplementation::GetEvents(struct kevent* event,
|
| // On a listening socket the READ event means that there are
|
| // connections ready to be accepted.
|
| if (event->filter == EVFILT_READ) {
|
| - if ((event->flags & EV_EOF) != 0) event_mask |= (1 << kCloseEvent);
|
| - if ((event->flags & EV_ERROR) != 0) event_mask |= (1 << kErrorEvent);
|
| + if ((event->flags & EV_EOF) != 0) {
|
| + if (event->fflags != 0) {
|
| + event_mask |= (1 << kErrorEvent);
|
| + } else {
|
| + event_mask |= (1 << kCloseEvent);
|
| + }
|
| + }
|
| if (event_mask == 0) event_mask |= (1 << kInEvent);
|
| }
|
| } else {
|
| @@ -267,18 +272,22 @@ intptr_t EventHandlerImplementation::GetEvents(struct kevent* event,
|
| if (FDUtils::AvailableBytes(sd->fd()) != 0) {
|
| event_mask = (1 << kInEvent);
|
| } else if ((event->flags & EV_EOF) != 0) {
|
| - event_mask = (1 << kCloseEvent);
|
| + if (event->fflags != 0) {
|
| + event_mask |= (1 << kErrorEvent);
|
| + } else {
|
| + event_mask |= (1 << kCloseEvent);
|
| + }
|
| sd->MarkClosedRead();
|
| - } else if ((event->flags & EV_ERROR) != 0) {
|
| - event_mask = (1 << kErrorEvent);
|
| }
|
| }
|
|
|
| if (event->filter == EVFILT_WRITE) {
|
| - if ((event->flags & EV_ERROR) != 0) {
|
| - event_mask = (1 << kErrorEvent);
|
| - sd->MarkClosedWrite();
|
| - } else if ((event->flags & EV_EOF) != 0) {
|
| + if ((event->flags & EV_EOF) != 0) {
|
| + if (event->fflags != 0) {
|
| + event_mask |= (1 << kErrorEvent);
|
| + } else {
|
| + event_mask |= (1 << kCloseEvent);
|
| + }
|
| // If the receiver closed for reading, close for writing,
|
| // update the registration with kqueue, and do not report a
|
| // write event.
|
| @@ -297,6 +306,10 @@ intptr_t EventHandlerImplementation::GetEvents(struct kevent* event,
|
| void EventHandlerImplementation::HandleEvents(struct kevent* events,
|
| int size) {
|
| for (int i = 0; i < size; i++) {
|
| + // If flag EV_ERROR is set it indicates an error in kevent processing.
|
| + if ((events[i].flags & EV_ERROR) != 0) {
|
| + FATAL1("kevent failed %s\n", strerror(events[i].data));
|
| + }
|
| if (events[i].udata != NULL) {
|
| SocketData* sd = reinterpret_cast<SocketData*>(events[i].udata);
|
| intptr_t event_mask = GetEvents(events + i, sd);
|
| @@ -360,8 +373,7 @@ void EventHandlerImplementation::EventHandlerEntry(uword args) {
|
| kMaxEvents,
|
| timeout));
|
| if (result == -1) {
|
| - perror("kevent failed");
|
| - FATAL("kevent failed\n");
|
| + FATAL1("kevent failed %s\n", strerror(errno));
|
| } else {
|
| handler->HandleTimeout();
|
| handler->HandleEvents(events, result);
|
|
|