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 |