| 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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 EventHandlerImplementation::~EventHandlerImplementation() { | 132 EventHandlerImplementation::~EventHandlerImplementation() { |
| 133 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); | 133 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); |
| 134 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 134 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
| 135 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 135 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
| 136 } | 136 } |
| 137 | 137 |
| 138 | 138 |
| 139 SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) { | 139 SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd, |
| 140 bool is_listening) { |
| 140 ASSERT(fd >= 0); | 141 ASSERT(fd >= 0); |
| 141 HashMap::Entry* entry = socket_map_.Lookup( | 142 HashMap::Entry* entry = socket_map_.Lookup( |
| 142 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); | 143 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); |
| 143 ASSERT(entry != NULL); | 144 ASSERT(entry != NULL); |
| 144 SocketData* sd = reinterpret_cast<SocketData*>(entry->value); | 145 SocketData* sd = reinterpret_cast<SocketData*>(entry->value); |
| 145 if (sd == NULL) { | 146 if (sd == NULL) { |
| 146 // If there is no data in the hash map for this file descriptor a | 147 // If there is no data in the hash map for this file descriptor a |
| 147 // new SocketData for the file descriptor is inserted. | 148 // new SocketData for the file descriptor is inserted. |
| 148 sd = new SocketData(fd); | 149 sd = new SocketData(fd, is_listening); |
| 149 entry->value = sd; | 150 entry->value = sd; |
| 150 } | 151 } |
| 151 ASSERT(fd == sd->fd()); | 152 ASSERT(fd == sd->fd()); |
| 152 return sd; | 153 return sd; |
| 153 } | 154 } |
| 154 | 155 |
| 155 | 156 |
| 156 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 157 void EventHandlerImplementation::WakeupHandler(intptr_t id, |
| 157 Dart_Port dart_port, | 158 Dart_Port dart_port, |
| 158 int64_t data) { | 159 int64_t data) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 178 const intptr_t MAX_MESSAGES = kInterruptMessageSize; | 179 const intptr_t MAX_MESSAGES = kInterruptMessageSize; |
| 179 InterruptMessage msg[MAX_MESSAGES]; | 180 InterruptMessage msg[MAX_MESSAGES]; |
| 180 ssize_t bytes = TEMP_FAILURE_RETRY( | 181 ssize_t bytes = TEMP_FAILURE_RETRY( |
| 181 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); | 182 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); |
| 182 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { | 183 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { |
| 183 if (msg[i].id == kTimerId) { | 184 if (msg[i].id == kTimerId) { |
| 184 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); | 185 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); |
| 185 } else if (msg[i].id == kShutdownId) { | 186 } else if (msg[i].id == kShutdownId) { |
| 186 shutdown_ = true; | 187 shutdown_ = true; |
| 187 } else { | 188 } else { |
| 188 SocketData* sd = GetSocketData(msg[i].id); | 189 ASSERT((msg[i].data & COMMAND_MASK) != 0); |
| 190 |
| 191 SocketData* sd = GetSocketData( |
| 192 msg[i].id, IS_LISTENING_SOCKET(msg[i].data)); |
| 189 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { | 193 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { |
| 190 // Close the socket for reading. | 194 // Close the socket for reading. |
| 191 shutdown(sd->fd(), SHUT_RD); | 195 shutdown(sd->fd(), SHUT_RD); |
| 192 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { | 196 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { |
| 193 // Close the socket for writing. | 197 // Close the socket for writing. |
| 194 shutdown(sd->fd(), SHUT_WR); | 198 shutdown(sd->fd(), SHUT_WR); |
| 195 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { | 199 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { |
| 196 // Close the socket and free system resources. | 200 // Close the socket and free system resources. |
| 197 RemoveFromKqueue(kqueue_fd_, sd); | 201 RemoveFromKqueue(kqueue_fd_, sd); |
| 198 intptr_t fd = sd->fd(); | 202 intptr_t fd = sd->fd(); |
| 199 VOID_TEMP_FAILURE_RETRY(close(fd)); | 203 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 200 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); | 204 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
| 201 delete sd; | 205 delete sd; |
| 202 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); | 206 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); |
| 203 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { | 207 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { |
| 204 int count = TOKEN_COUNT(msg[i].data); | 208 int count = TOKEN_COUNT(msg[i].data); |
| 205 for (int i = 0; i < count; i++) { | 209 for (int i = 0; i < count; i++) { |
| 206 if (sd->ReturnToken()) { | 210 if (sd->ReturnToken()) { |
| 207 AddToKqueue(kqueue_fd_, sd); | 211 AddToKqueue(kqueue_fd_, sd); |
| 208 } | 212 } |
| 209 } | 213 } |
| 214 } else if (IS_COMMAND(msg[i].data, kSetEventMaskCommand)) { |
| 215 // `events` can only have kInEvent/kOutEvent flags set. |
| 216 intptr_t events = msg[i].data & EVENT_MASK; |
| 217 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent))); |
| 218 |
| 219 // Setup events to wait for. |
| 220 ASSERT(sd->port() == 0); |
| 221 sd->SetPortAndMask(msg[i].dart_port, events); |
| 222 AddToKqueue(kqueue_fd_, sd); |
| 210 } else { | 223 } else { |
| 211 ASSERT_NO_COMMAND(msg[i].data); | 224 UNREACHABLE(); |
| 212 // Setup events to wait for. | |
| 213 ASSERT((msg[i].data > 0) && (msg[i].data < kIntptrMax)); | |
| 214 ASSERT(sd->port() == 0); | |
| 215 sd->SetPortAndMask(msg[i].dart_port, | |
| 216 static_cast<intptr_t>(msg[i].data)); | |
| 217 AddToKqueue(kqueue_fd_, sd); | |
| 218 } | 225 } |
| 219 } | 226 } |
| 220 } | 227 } |
| 221 } | 228 } |
| 222 | 229 |
| 223 #ifdef DEBUG_KQUEUE | 230 #ifdef DEBUG_KQUEUE |
| 224 static void PrintEventMask(intptr_t fd, struct kevent* event) { | 231 static void PrintEventMask(intptr_t fd, struct kevent* event) { |
| 225 Log::Print("%d ", static_cast<int>(fd)); | 232 Log::Print("%d ", static_cast<int>(fd)); |
| 226 Log::Print("filter=0x%x:", event->filter); | 233 Log::Print("filter=0x%x:", event->filter); |
| 227 if (event->filter == EVFILT_READ) Log::Print("EVFILT_READ "); | 234 if (event->filter == EVFILT_READ) Log::Print("EVFILT_READ "); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 | 423 |
| 417 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 424 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
| 418 // The hashmap does not support keys with value 0. | 425 // The hashmap does not support keys with value 0. |
| 419 return dart::Utils::WordHash(fd + 1); | 426 return dart::Utils::WordHash(fd + 1); |
| 420 } | 427 } |
| 421 | 428 |
| 422 } // namespace bin | 429 } // namespace bin |
| 423 } // namespace dart | 430 } // namespace dart |
| 424 | 431 |
| 425 #endif // defined(TARGET_OS_MACOS) | 432 #endif // defined(TARGET_OS_MACOS) |
| OLD | NEW |