OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
6 #if defined(TARGET_OS_MACOS) | 6 #if defined(TARGET_OS_MACOS) |
7 | 7 |
8 #include "bin/eventhandler.h" | 8 #include "bin/eventhandler.h" |
9 | 9 |
10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 if (sd->write_tracked_by_kqueue()) { | 56 if (sd->write_tracked_by_kqueue()) { |
57 EV_SET(events + changes, sd->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, sd); | 57 EV_SET(events + changes, sd->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, sd); |
58 ++changes; | 58 ++changes; |
59 sd->set_write_tracked_by_kqueue(false); | 59 sd->set_write_tracked_by_kqueue(false); |
60 } | 60 } |
61 if (changes > 0) { | 61 if (changes > 0) { |
62 ASSERT(changes <= kMaxChanges); | 62 ASSERT(changes <= kMaxChanges); |
63 int status = | 63 int status = |
64 TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); | 64 TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); |
65 if (status == -1) { | 65 if (status == -1) { |
66 FATAL1("Failed deleting events from kqueue: %s\n", strerror(errno)); | 66 const int kBufferSize = 1024; |
| 67 char error_message[kBufferSize]; |
| 68 strerror_r(errno, error_message, kBufferSize); |
| 69 FATAL1("Failed deleting events from kqueue: %s\n", error_message); |
67 } | 70 } |
68 } | 71 } |
69 } | 72 } |
70 | 73 |
71 | 74 |
72 // Update the kqueue registration for SocketData structure to reflect | 75 // Update the kqueue registration for SocketData structure to reflect |
73 // the events currently of interest. | 76 // the events currently of interest. |
74 static void UpdateKqueue(intptr_t kqueue_fd_, SocketData* sd) { | 77 static void UpdateKqueue(intptr_t kqueue_fd_, SocketData* sd) { |
75 static const intptr_t kMaxChanges = 2; | 78 static const intptr_t kMaxChanges = 2; |
76 intptr_t changes = 0; | 79 intptr_t changes = 0; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 kqueue_fd_ = TEMP_FAILURE_RETRY(kqueue()); | 138 kqueue_fd_ = TEMP_FAILURE_RETRY(kqueue()); |
136 if (kqueue_fd_ == -1) { | 139 if (kqueue_fd_ == -1) { |
137 FATAL("Failed creating kqueue"); | 140 FATAL("Failed creating kqueue"); |
138 } | 141 } |
139 FDUtils::SetCloseOnExec(kqueue_fd_); | 142 FDUtils::SetCloseOnExec(kqueue_fd_); |
140 // Register the interrupt_fd with the kqueue. | 143 // Register the interrupt_fd with the kqueue. |
141 struct kevent event; | 144 struct kevent event; |
142 EV_SET(&event, interrupt_fds_[0], EVFILT_READ, EV_ADD, 0, 0, NULL); | 145 EV_SET(&event, interrupt_fds_[0], EVFILT_READ, EV_ADD, 0, 0, NULL); |
143 int status = TEMP_FAILURE_RETRY(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL)); | 146 int status = TEMP_FAILURE_RETRY(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL)); |
144 if (status == -1) { | 147 if (status == -1) { |
145 FATAL1("Failed adding interrupt fd to kqueue: %s\n", strerror(errno)); | 148 const int kBufferSize = 1024; |
| 149 char error_message[kBufferSize]; |
| 150 strerror_r(errno, error_message, kBufferSize); |
| 151 FATAL1("Failed adding interrupt fd to kqueue: %s\n", error_message); |
146 } | 152 } |
147 } | 153 } |
148 | 154 |
149 | 155 |
150 EventHandlerImplementation::~EventHandlerImplementation() { | 156 EventHandlerImplementation::~EventHandlerImplementation() { |
151 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); | 157 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); |
152 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 158 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
153 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 159 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
154 } | 160 } |
155 | 161 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 | 336 |
331 return event_mask; | 337 return event_mask; |
332 } | 338 } |
333 | 339 |
334 | 340 |
335 void EventHandlerImplementation::HandleEvents(struct kevent* events, | 341 void EventHandlerImplementation::HandleEvents(struct kevent* events, |
336 int size) { | 342 int size) { |
337 for (int i = 0; i < size; i++) { | 343 for (int i = 0; i < size; i++) { |
338 // If flag EV_ERROR is set it indicates an error in kevent processing. | 344 // If flag EV_ERROR is set it indicates an error in kevent processing. |
339 if ((events[i].flags & EV_ERROR) != 0) { | 345 if ((events[i].flags & EV_ERROR) != 0) { |
340 FATAL1("kevent failed %s\n", strerror(events[i].data)); | 346 const int kBufferSize = 1024; |
| 347 char error_message[kBufferSize]; |
| 348 strerror_r(events[i].data, error_message, kBufferSize); |
| 349 FATAL1("kevent failed %s\n", error_message); |
341 } | 350 } |
342 if (events[i].udata != NULL) { | 351 if (events[i].udata != NULL) { |
343 SocketData* sd = reinterpret_cast<SocketData*>(events[i].udata); | 352 SocketData* sd = reinterpret_cast<SocketData*>(events[i].udata); |
344 intptr_t event_mask = GetEvents(events + i, sd); | 353 intptr_t event_mask = GetEvents(events + i, sd); |
345 if (event_mask != 0) { | 354 if (event_mask != 0) { |
346 // Unregister events for the file descriptor. Events will be | 355 // Unregister events for the file descriptor. Events will be |
347 // registered again when the current event has been handled in | 356 // registered again when the current event has been handled in |
348 // Dart code. | 357 // Dart code. |
349 RemoveFromKqueue(kqueue_fd_, sd); | 358 RemoveFromKqueue(kqueue_fd_, sd); |
350 Dart_Port port = sd->port(); | 359 Dart_Port port = sd->port(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 ts.tv_nsec = (millis - (ts.tv_sec * 1000)) * 1000000; | 407 ts.tv_nsec = (millis - (ts.tv_sec * 1000)) * 1000000; |
399 timeout = &ts; | 408 timeout = &ts; |
400 } | 409 } |
401 intptr_t result = TEMP_FAILURE_RETRY(kevent(handler_impl->kqueue_fd_, | 410 intptr_t result = TEMP_FAILURE_RETRY(kevent(handler_impl->kqueue_fd_, |
402 NULL, | 411 NULL, |
403 0, | 412 0, |
404 events, | 413 events, |
405 kMaxEvents, | 414 kMaxEvents, |
406 timeout)); | 415 timeout)); |
407 if (result == -1) { | 416 if (result == -1) { |
408 FATAL1("kevent failed %s\n", strerror(errno)); | 417 const int kBufferSize = 1024; |
| 418 char error_message[kBufferSize]; |
| 419 strerror_r(errno, error_message, kBufferSize); |
| 420 FATAL1("kevent failed %s\n", error_message); |
409 } else { | 421 } else { |
410 handler_impl->HandleTimeout(); | 422 handler_impl->HandleTimeout(); |
411 handler_impl->HandleEvents(events, result); | 423 handler_impl->HandleEvents(events, result); |
412 } | 424 } |
413 } | 425 } |
414 delete handler; | 426 delete handler; |
415 } | 427 } |
416 | 428 |
417 | 429 |
418 void EventHandlerImplementation::Start(EventHandler* handler) { | 430 void EventHandlerImplementation::Start(EventHandler* handler) { |
(...skipping 26 matching lines...) Expand all Loading... |
445 | 457 |
446 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 458 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
447 // The hashmap does not support keys with value 0. | 459 // The hashmap does not support keys with value 0. |
448 return dart::Utils::WordHash(fd + 1); | 460 return dart::Utils::WordHash(fd + 1); |
449 } | 461 } |
450 | 462 |
451 } // namespace bin | 463 } // namespace bin |
452 } // namespace dart | 464 } // namespace dart |
453 | 465 |
454 #endif // defined(TARGET_OS_MACOS) | 466 #endif // defined(TARGET_OS_MACOS) |
OLD | NEW |