| 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 perror("Interrupt message failure:"); | 172 perror("Interrupt message failure:"); |
| 173 } | 173 } |
| 174 FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result); | 174 FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result); |
| 175 } | 175 } |
| 176 } | 176 } |
| 177 | 177 |
| 178 | 178 |
| 179 void EventHandlerImplementation::HandleInterruptFd() { | 179 void EventHandlerImplementation::HandleInterruptFd() { |
| 180 const intptr_t MAX_MESSAGES = kInterruptMessageSize; | 180 const intptr_t MAX_MESSAGES = kInterruptMessageSize; |
| 181 InterruptMessage msg[MAX_MESSAGES]; | 181 InterruptMessage msg[MAX_MESSAGES]; |
| 182 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( | 182 ssize_t bytes = TEMP_FAILURE_RETRY( |
| 183 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); | 183 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); |
| 184 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { | 184 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { |
| 185 if (msg[i].id == kTimerId) { | 185 if (msg[i].id == kTimerId) { |
| 186 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); | 186 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); |
| 187 } else if (msg[i].id == kShutdownId) { | 187 } else if (msg[i].id == kShutdownId) { |
| 188 shutdown_ = true; | 188 shutdown_ = true; |
| 189 } else { | 189 } else { |
| 190 SocketData* sd = GetSocketData(msg[i].id); | 190 SocketData* sd = GetSocketData(msg[i].id); |
| 191 if ((msg[i].data & (1 << kShutdownReadCommand)) != 0) { | 191 if ((msg[i].data & (1 << kShutdownReadCommand)) != 0) { |
| 192 ASSERT(msg[i].data == (1 << kShutdownReadCommand)); | 192 ASSERT(msg[i].data == (1 << kShutdownReadCommand)); |
| 193 // Close the socket for reading. | 193 // Close the socket for reading. |
| 194 shutdown(sd->fd(), SHUT_RD); | 194 shutdown(sd->fd(), SHUT_RD); |
| 195 } else if ((msg[i].data & (1 << kShutdownWriteCommand)) != 0) { | 195 } else if ((msg[i].data & (1 << kShutdownWriteCommand)) != 0) { |
| 196 ASSERT(msg[i].data == (1 << kShutdownWriteCommand)); | 196 ASSERT(msg[i].data == (1 << kShutdownWriteCommand)); |
| 197 // Close the socket for writing. | 197 // Close the socket for writing. |
| 198 shutdown(sd->fd(), SHUT_WR); | 198 shutdown(sd->fd(), SHUT_WR); |
| 199 } else if ((msg[i].data & (1 << kCloseCommand)) != 0) { | 199 } else if ((msg[i].data & (1 << kCloseCommand)) != 0) { |
| 200 ASSERT(msg[i].data == (1 << kCloseCommand)); | 200 ASSERT(msg[i].data == (1 << kCloseCommand)); |
| 201 // Close the socket and free system resources. | 201 // Close the socket and free system resources. |
| 202 RemoveFromKqueue(kqueue_fd_, sd); | 202 RemoveFromKqueue(kqueue_fd_, sd); |
| 203 intptr_t fd = sd->fd(); | 203 intptr_t fd = sd->fd(); |
| 204 sd->Close(); | 204 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 205 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); | 205 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
| 206 delete sd; | 206 delete sd; |
| 207 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); | 207 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); |
| 208 } else if ((msg[i].data & (1 << kReturnTokenCommand)) != 0) { | 208 } else if ((msg[i].data & (1 << kReturnTokenCommand)) != 0) { |
| 209 int count = msg[i].data & ((1 << kReturnTokenCommand) - 1); | 209 int count = msg[i].data & ((1 << kReturnTokenCommand) - 1); |
| 210 for (int i = 0; i < count; i++) { | 210 for (int i = 0; i < count; i++) { |
| 211 if (sd->ReturnToken()) { | 211 if (sd->ReturnToken()) { |
| 212 AddToKqueue(kqueue_fd_, sd); | 212 AddToKqueue(kqueue_fd_, sd); |
| 213 } | 213 } |
| 214 } | 214 } |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 TimerUtils::GetCurrentTimeMilliseconds(); | 344 TimerUtils::GetCurrentTimeMilliseconds(); |
| 345 if (millis <= 0) { | 345 if (millis <= 0) { |
| 346 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 346 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
| 347 timeout_queue_.RemoveCurrent(); | 347 timeout_queue_.RemoveCurrent(); |
| 348 } | 348 } |
| 349 } | 349 } |
| 350 } | 350 } |
| 351 | 351 |
| 352 | 352 |
| 353 void EventHandlerImplementation::EventHandlerEntry(uword args) { | 353 void EventHandlerImplementation::EventHandlerEntry(uword args) { |
| 354 ThreadSignalBlocker signal_blocker(SIGPROF); | |
| 355 static const intptr_t kMaxEvents = 16; | 354 static const intptr_t kMaxEvents = 16; |
| 356 struct kevent events[kMaxEvents]; | 355 struct kevent events[kMaxEvents]; |
| 357 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 356 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
| 358 EventHandlerImplementation* handler_impl = &handler->delegate_; | 357 EventHandlerImplementation* handler_impl = &handler->delegate_; |
| 359 ASSERT(handler_impl != NULL); | 358 ASSERT(handler_impl != NULL); |
| 360 while (!handler_impl->shutdown_) { | 359 while (!handler_impl->shutdown_) { |
| 361 int64_t millis = handler_impl->GetTimeout(); | 360 int64_t millis = handler_impl->GetTimeout(); |
| 362 ASSERT(millis == kInfinityTimeout || millis >= 0); | 361 ASSERT(millis == kInfinityTimeout || millis >= 0); |
| 363 if (millis > kMaxInt32) millis = kMaxInt32; | 362 if (millis > kMaxInt32) millis = kMaxInt32; |
| 364 // NULL pointer timespec for infinite timeout. | 363 // NULL pointer timespec for infinite timeout. |
| 365 ASSERT(kInfinityTimeout < 0); | 364 ASSERT(kInfinityTimeout < 0); |
| 366 struct timespec* timeout = NULL; | 365 struct timespec* timeout = NULL; |
| 367 struct timespec ts; | 366 struct timespec ts; |
| 368 if (millis >= 0) { | 367 if (millis >= 0) { |
| 369 int32_t millis32 = static_cast<int32_t>(millis); | 368 int32_t millis32 = static_cast<int32_t>(millis); |
| 370 int32_t secs = millis32 / 1000; | 369 int32_t secs = millis32 / 1000; |
| 371 ts.tv_sec = secs; | 370 ts.tv_sec = secs; |
| 372 ts.tv_nsec = (millis32 - (secs * 1000)) * 1000000; | 371 ts.tv_nsec = (millis32 - (secs * 1000)) * 1000000; |
| 373 timeout = &ts; | 372 timeout = &ts; |
| 374 } | 373 } |
| 375 intptr_t result = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( | 374 // We have to use TEMP_FAILURE_RETRY for mac, as kevent can modify the |
| 375 // current sigmask. |
| 376 intptr_t result = TEMP_FAILURE_RETRY( |
| 376 kevent(handler_impl->kqueue_fd_, NULL, 0, events, kMaxEvents, timeout)); | 377 kevent(handler_impl->kqueue_fd_, NULL, 0, events, kMaxEvents, timeout)); |
| 377 if (result == -1) { | 378 if (result == -1) { |
| 378 const int kBufferSize = 1024; | 379 const int kBufferSize = 1024; |
| 379 char error_message[kBufferSize]; | 380 char error_message[kBufferSize]; |
| 380 strerror_r(errno, error_message, kBufferSize); | 381 strerror_r(errno, error_message, kBufferSize); |
| 381 FATAL1("kevent failed %s\n", error_message); | 382 FATAL1("kevent failed %s\n", error_message); |
| 382 } else { | 383 } else { |
| 383 handler_impl->HandleTimeout(); | 384 handler_impl->HandleTimeout(); |
| 384 handler_impl->HandleEvents(events, result); | 385 handler_impl->HandleEvents(events, result); |
| 385 } | 386 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 | 419 |
| 419 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 420 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
| 420 // The hashmap does not support keys with value 0. | 421 // The hashmap does not support keys with value 0. |
| 421 return dart::Utils::WordHash(fd + 1); | 422 return dart::Utils::WordHash(fd + 1); |
| 422 } | 423 } |
| 423 | 424 |
| 424 } // namespace bin | 425 } // namespace bin |
| 425 } // namespace dart | 426 } // namespace dart |
| 426 | 427 |
| 427 #endif // defined(TARGET_OS_MACOS) | 428 #endif // defined(TARGET_OS_MACOS) |
| OLD | NEW |