| 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 #include "bin/eventhandler_macos.h" | 9 #include "bin/eventhandler_macos.h" |
| 10 | 10 |
| 11 #include <errno.h> // NOLINT | 11 #include <errno.h> // NOLINT |
| 12 #include <fcntl.h> // NOLINT |
| 12 #include <pthread.h> // NOLINT | 13 #include <pthread.h> // NOLINT |
| 13 #include <stdio.h> // NOLINT | 14 #include <stdio.h> // NOLINT |
| 14 #include <string.h> // NOLINT | 15 #include <string.h> // NOLINT |
| 15 #include <sys/event.h> // NOLINT | 16 #include <sys/event.h> // NOLINT |
| 16 #include <unistd.h> // NOLINT | 17 #include <unistd.h> // NOLINT |
| 17 #include <fcntl.h> // NOLINT | |
| 18 | 18 |
| 19 #include "bin/dartutils.h" | 19 #include "bin/dartutils.h" |
| 20 #include "bin/fdutils.h" | 20 #include "bin/fdutils.h" |
| 21 #include "bin/lockers.h" | 21 #include "bin/lockers.h" |
| 22 #include "bin/log.h" | 22 #include "bin/log.h" |
| 23 #include "bin/socket.h" | 23 #include "bin/socket.h" |
| 24 #include "bin/thread.h" | 24 #include "bin/thread.h" |
| 25 #include "bin/utils.h" | 25 #include "bin/utils.h" |
| 26 #include "platform/hashmap.h" | 26 #include "platform/hashmap.h" |
| 27 #include "platform/utils.h" | 27 #include "platform/utils.h" |
| 28 | 28 |
| 29 | |
| 30 namespace dart { | 29 namespace dart { |
| 31 namespace bin { | 30 namespace bin { |
| 32 | 31 |
| 33 | |
| 34 bool DescriptorInfo::HasReadEvent() { | 32 bool DescriptorInfo::HasReadEvent() { |
| 35 return (Mask() & (1 << kInEvent)) != 0; | 33 return (Mask() & (1 << kInEvent)) != 0; |
| 36 } | 34 } |
| 37 | 35 |
| 38 | 36 |
| 39 bool DescriptorInfo::HasWriteEvent() { | 37 bool DescriptorInfo::HasWriteEvent() { |
| 40 return (Mask() & (1 << kOutEvent)) != 0; | 38 return (Mask() & (1 << kOutEvent)) != 0; |
| 41 } | 39 } |
| 42 | 40 |
| 43 | 41 |
| 44 // Unregister the file descriptor for a SocketData structure with kqueue. | 42 // Unregister the file descriptor for a SocketData structure with kqueue. |
| 45 static void RemoveFromKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { | 43 static void RemoveFromKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { |
| 46 if (!di->tracked_by_kqueue()) return; | 44 if (!di->tracked_by_kqueue()) { |
| 45 return; |
| 46 } |
| 47 static const intptr_t kMaxChanges = 2; | 47 static const intptr_t kMaxChanges = 2; |
| 48 struct kevent events[kMaxChanges]; | 48 struct kevent events[kMaxChanges]; |
| 49 EV_SET(events, di->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); | 49 EV_SET(events, di->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); |
| 50 VOID_NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, 1, NULL, 0, NULL)); | 50 VOID_NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, 1, NULL, 0, NULL)); |
| 51 EV_SET(events, di->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); | 51 EV_SET(events, di->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); |
| 52 VOID_NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, 1, NULL, 0, NULL)); | 52 VOID_NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, 1, NULL, 0, NULL)); |
| 53 di->set_tracked_by_kqueue(false); | 53 di->set_tracked_by_kqueue(false); |
| 54 } | 54 } |
| 55 | 55 |
| 56 | 56 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 143 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
| 144 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 144 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
| 145 } | 145 } |
| 146 | 146 |
| 147 | 147 |
| 148 void EventHandlerImplementation::UpdateKQueueInstance(intptr_t old_mask, | 148 void EventHandlerImplementation::UpdateKQueueInstance(intptr_t old_mask, |
| 149 DescriptorInfo *di) { | 149 DescriptorInfo *di) { |
| 150 intptr_t new_mask = di->Mask(); | 150 intptr_t new_mask = di->Mask(); |
| 151 if (old_mask != 0 && new_mask == 0) { | 151 if (old_mask != 0 && new_mask == 0) { |
| 152 RemoveFromKqueue(kqueue_fd_, di); | 152 RemoveFromKqueue(kqueue_fd_, di); |
| 153 } else if (old_mask == 0 && new_mask != 0) { | 153 } else if ((old_mask == 0) && (new_mask != 0)) { |
| 154 AddToKqueue(kqueue_fd_, di); | 154 AddToKqueue(kqueue_fd_, di); |
| 155 } else if (old_mask != 0 && new_mask != 0 && old_mask != new_mask) { | 155 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) { |
| 156 ASSERT(!di->IsListeningSocket()); | 156 ASSERT(!di->IsListeningSocket()); |
| 157 RemoveFromKqueue(kqueue_fd_, di); | 157 RemoveFromKqueue(kqueue_fd_, di); |
| 158 AddToKqueue(kqueue_fd_, di); | 158 AddToKqueue(kqueue_fd_, di); |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 | 161 |
| 162 | 162 |
| 163 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( | 163 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( |
| 164 intptr_t fd, bool is_listening) { | 164 intptr_t fd, bool is_listening) { |
| 165 ASSERT(fd >= 0); | 165 ASSERT(fd >= 0); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 intptr_t old_mask = di->Mask(); | 274 intptr_t old_mask = di->Mask(); |
| 275 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); | 275 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); |
| 276 UpdateKQueueInstance(old_mask, di); | 276 UpdateKQueueInstance(old_mask, di); |
| 277 } else { | 277 } else { |
| 278 UNREACHABLE(); | 278 UNREACHABLE(); |
| 279 } | 279 } |
| 280 } | 280 } |
| 281 } | 281 } |
| 282 } | 282 } |
| 283 | 283 |
| 284 |
| 284 #ifdef DEBUG_KQUEUE | 285 #ifdef DEBUG_KQUEUE |
| 285 static void PrintEventMask(intptr_t fd, struct kevent* event) { | 286 static void PrintEventMask(intptr_t fd, struct kevent* event) { |
| 286 Log::Print("%d ", static_cast<int>(fd)); | 287 Log::Print("%d ", static_cast<int>(fd)); |
| 288 |
| 287 Log::Print("filter=0x%x:", event->filter); | 289 Log::Print("filter=0x%x:", event->filter); |
| 288 if (event->filter == EVFILT_READ) Log::Print("EVFILT_READ "); | 290 if (event->filter == EVFILT_READ) { |
| 289 if (event->filter == EVFILT_WRITE) Log::Print("EVFILT_WRITE "); | 291 Log::Print("EVFILT_READ "); |
| 292 } |
| 293 if (event->filter == EVFILT_WRITE) { |
| 294 Log::Print("EVFILT_WRITE "); |
| 295 } |
| 296 |
| 290 Log::Print("flags: %x: ", event->flags); | 297 Log::Print("flags: %x: ", event->flags); |
| 291 if ((event->flags & EV_EOF) != 0) Log::Print("EV_EOF "); | 298 if ((event->flags & EV_EOF) != 0) { |
| 292 if ((event->flags & EV_ERROR) != 0) Log::Print("EV_ERROR "); | 299 Log::Print("EV_EOF "); |
| 293 if ((event->flags & EV_CLEAR) != 0) Log::Print("EV_CLEAR "); | 300 } |
| 294 if ((event->flags & EV_ADD) != 0) Log::Print("EV_ADD "); | 301 if ((event->flags & EV_ERROR) != 0) { |
| 295 if ((event->flags & EV_DELETE) != 0) Log::Print("EV_DELETE "); | 302 Log::Print("EV_ERROR "); |
| 303 } |
| 304 if ((event->flags & EV_CLEAR) != 0) { |
| 305 Log::Print("EV_CLEAR "); |
| 306 } |
| 307 if ((event->flags & EV_ADD) != 0) { |
| 308 Log::Print("EV_ADD "); |
| 309 } |
| 310 if ((event->flags & EV_DELETE) != 0) { |
| 311 Log::Print("EV_DELETE "); |
| 312 } |
| 313 |
| 296 Log::Print("- fflags: %d ", event->fflags); | 314 Log::Print("- fflags: %d ", event->fflags); |
| 297 Log::Print("- data: %ld ", event->data); | 315 Log::Print("- data: %ld ", event->data); |
| 298 Log::Print("(available %d) ", | 316 Log::Print("(available %d) ", static_cast<int>(FDUtils::AvailableBytes(fd))); |
| 299 static_cast<int>(FDUtils::AvailableBytes(fd))); | |
| 300 Log::Print("\n"); | 317 Log::Print("\n"); |
| 301 } | 318 } |
| 302 #endif | 319 #endif |
| 303 | 320 |
| 304 | 321 |
| 305 intptr_t EventHandlerImplementation::GetEvents(struct kevent* event, | 322 intptr_t EventHandlerImplementation::GetEvents(struct kevent* event, |
| 306 DescriptorInfo* di) { | 323 DescriptorInfo* di) { |
| 307 #ifdef DEBUG_KQUEUE | 324 #ifdef DEBUG_KQUEUE |
| 308 PrintEventMask(di->fd(), event); | 325 PrintEventMask(di->fd(), event); |
| 309 #endif | 326 #endif |
| 310 intptr_t event_mask = 0; | 327 intptr_t event_mask = 0; |
| 311 if (di->IsListeningSocket()) { | 328 if (di->IsListeningSocket()) { |
| 312 // On a listening socket the READ event means that there are | 329 // On a listening socket the READ event means that there are |
| 313 // connections ready to be accepted. | 330 // connections ready to be accepted. |
| 314 if (event->filter == EVFILT_READ) { | 331 if (event->filter == EVFILT_READ) { |
| 315 if ((event->flags & EV_EOF) != 0) { | 332 if ((event->flags & EV_EOF) != 0) { |
| 316 if (event->fflags != 0) { | 333 if (event->fflags != 0) { |
| 317 event_mask |= (1 << kErrorEvent); | 334 event_mask |= (1 << kErrorEvent); |
| 318 } else { | 335 } else { |
| 319 event_mask |= (1 << kCloseEvent); | 336 event_mask |= (1 << kCloseEvent); |
| 320 } | 337 } |
| 321 } | 338 } |
| 322 if (event_mask == 0) event_mask |= (1 << kInEvent); | 339 if (event_mask == 0) { |
| 340 event_mask |= (1 << kInEvent); |
| 341 } |
| 323 } else { | 342 } else { |
| 324 UNREACHABLE(); | 343 UNREACHABLE(); |
| 325 } | 344 } |
| 326 } else { | 345 } else { |
| 327 // Prioritize data events over close and error events. | 346 // Prioritize data events over close and error events. |
| 328 if (event->filter == EVFILT_READ) { | 347 if (event->filter == EVFILT_READ) { |
| 329 event_mask = (1 << kInEvent); | 348 event_mask = (1 << kInEvent); |
| 330 if ((event->flags & EV_EOF) != 0) { | 349 if ((event->flags & EV_EOF) != 0) { |
| 331 if (event->fflags != 0) { | 350 if (event->fflags != 0) { |
| 332 event_mask = (1 << kErrorEvent); | 351 event_mask = (1 << kErrorEvent); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 void EventHandlerImplementation::EventHandlerEntry(uword args) { | 433 void EventHandlerImplementation::EventHandlerEntry(uword args) { |
| 415 static const intptr_t kMaxEvents = 16; | 434 static const intptr_t kMaxEvents = 16; |
| 416 struct kevent events[kMaxEvents]; | 435 struct kevent events[kMaxEvents]; |
| 417 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 436 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
| 418 EventHandlerImplementation* handler_impl = &handler->delegate_; | 437 EventHandlerImplementation* handler_impl = &handler->delegate_; |
| 419 ASSERT(handler_impl != NULL); | 438 ASSERT(handler_impl != NULL); |
| 420 | 439 |
| 421 while (!handler_impl->shutdown_) { | 440 while (!handler_impl->shutdown_) { |
| 422 int64_t millis = handler_impl->GetTimeout(); | 441 int64_t millis = handler_impl->GetTimeout(); |
| 423 ASSERT(millis == kInfinityTimeout || millis >= 0); | 442 ASSERT(millis == kInfinityTimeout || millis >= 0); |
| 424 if (millis > kMaxInt32) millis = kMaxInt32; | 443 if (millis > kMaxInt32) { |
| 444 millis = kMaxInt32; |
| 445 } |
| 425 // NULL pointer timespec for infinite timeout. | 446 // NULL pointer timespec for infinite timeout. |
| 426 ASSERT(kInfinityTimeout < 0); | 447 ASSERT(kInfinityTimeout < 0); |
| 427 struct timespec* timeout = NULL; | 448 struct timespec* timeout = NULL; |
| 428 struct timespec ts; | 449 struct timespec ts; |
| 429 if (millis >= 0) { | 450 if (millis >= 0) { |
| 430 int32_t millis32 = static_cast<int32_t>(millis); | 451 int32_t millis32 = static_cast<int32_t>(millis); |
| 431 int32_t secs = millis32 / 1000; | 452 int32_t secs = millis32 / 1000; |
| 432 ts.tv_sec = secs; | 453 ts.tv_sec = secs; |
| 433 ts.tv_nsec = (millis32 - (secs * 1000)) * 1000000; | 454 ts.tv_nsec = (millis32 - (secs * 1000)) * 1000000; |
| 434 timeout = &ts; | 455 timeout = &ts; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 | 502 |
| 482 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 503 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
| 483 // The hashmap does not support keys with value 0. | 504 // The hashmap does not support keys with value 0. |
| 484 return dart::Utils::WordHash(fd + 1); | 505 return dart::Utils::WordHash(fd + 1); |
| 485 } | 506 } |
| 486 | 507 |
| 487 } // namespace bin | 508 } // namespace bin |
| 488 } // namespace dart | 509 } // namespace dart |
| 489 | 510 |
| 490 #endif // defined(TARGET_OS_MACOS) | 511 #endif // defined(TARGET_OS_MACOS) |
| OLD | NEW |