| 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 16 matching lines...) Expand all Loading... |
| 27 namespace dart { | 27 namespace dart { |
| 28 namespace bin { | 28 namespace bin { |
| 29 | 29 |
| 30 static const int kInterruptMessageSize = sizeof(InterruptMessage); | 30 static const int kInterruptMessageSize = sizeof(InterruptMessage); |
| 31 static const int kInfinityTimeout = -1; | 31 static const int kInfinityTimeout = -1; |
| 32 static const int kTimerId = -1; | 32 static const int kTimerId = -1; |
| 33 static const int kShutdownId = -2; | 33 static const int kShutdownId = -2; |
| 34 | 34 |
| 35 | 35 |
| 36 bool SocketData::HasReadEvent() { | 36 bool SocketData::HasReadEvent() { |
| 37 return !IsClosedRead() && ((mask_ & (1 << kInEvent)) != 0); | 37 return (mask_ & (1 << kInEvent)) != 0; |
| 38 } | 38 } |
| 39 | 39 |
| 40 | 40 |
| 41 bool SocketData::HasWriteEvent() { | 41 bool SocketData::HasWriteEvent() { |
| 42 return !IsClosedWrite() && ((mask_ & (1 << kOutEvent)) != 0); | 42 return (mask_ & (1 << kOutEvent)) != 0; |
| 43 } | 43 } |
| 44 | 44 |
| 45 | 45 |
| 46 // Unregister the file descriptor for a SocketData structure with kqueue. | 46 // Unregister the file descriptor for a SocketData structure with kqueue. |
| 47 static void RemoveFromKqueue(intptr_t kqueue_fd_, SocketData* sd) { | 47 static void RemoveFromKqueue(intptr_t kqueue_fd_, SocketData* sd) { |
| 48 if (!sd->tracked_by_kqueue()) return; |
| 48 static const intptr_t kMaxChanges = 2; | 49 static const intptr_t kMaxChanges = 2; |
| 49 intptr_t changes = 0; | 50 intptr_t changes = 0; |
| 50 struct kevent events[kMaxChanges]; | 51 struct kevent events[kMaxChanges]; |
| 51 if (sd->read_tracked_by_kqueue()) { | 52 if (sd->HasReadEvent()) { |
| 52 EV_SET(events + changes, sd->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); | 53 EV_SET(events + changes, sd->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); |
| 53 ++changes; | 54 ++changes; |
| 54 sd->set_read_tracked_by_kqueue(false); | |
| 55 } | 55 } |
| 56 if (sd->write_tracked_by_kqueue()) { | 56 if (sd->HasWriteEvent()) { |
| 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, NULL); |
| 58 ++changes; | 58 ++changes; |
| 59 sd->set_write_tracked_by_kqueue(false); | |
| 60 } | 59 } |
| 61 if (changes > 0) { | 60 ASSERT(changes > 0); |
| 62 ASSERT(changes <= kMaxChanges); | 61 ASSERT(changes <= kMaxChanges); |
| 63 int status = | 62 int status = |
| 64 TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); | 63 TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); |
| 65 if (status == -1) { | 64 if (status == -1) { |
| 66 const int kBufferSize = 1024; | 65 const int kBufferSize = 1024; |
| 67 char error_message[kBufferSize]; | 66 char error_message[kBufferSize]; |
| 68 strerror_r(errno, error_message, kBufferSize); | 67 strerror_r(errno, error_message, kBufferSize); |
| 69 FATAL1("Failed deleting events from kqueue: %s\n", error_message); | 68 FATAL1("Failed deleting events from kqueue: %s\n", error_message); |
| 70 } | |
| 71 } | 69 } |
| 70 sd->set_tracked_by_kqueue(false); |
| 72 } | 71 } |
| 73 | 72 |
| 74 | 73 |
| 75 // Update the kqueue registration for SocketData structure to reflect | 74 // Update the kqueue registration for SocketData structure to reflect |
| 76 // the events currently of interest. | 75 // the events currently of interest. |
| 77 static void UpdateKqueue(intptr_t kqueue_fd_, SocketData* sd) { | 76 static void AddToKqueue(intptr_t kqueue_fd_, SocketData* sd) { |
| 78 static const intptr_t kMaxChanges = 2; | 77 static const intptr_t kMaxChanges = 2; |
| 79 intptr_t changes = 0; | 78 intptr_t changes = 0; |
| 80 struct kevent events[kMaxChanges]; | 79 struct kevent events[kMaxChanges]; |
| 81 // Only report events once and wait for them to be re-enabled after the | 80 // Register or unregister READ filter if needed. |
| 82 // event has been handled by the Dart code. This is done by using EV_ONESHOT. | 81 if (sd->HasReadEvent()) { |
| 83 if (sd->port() != 0) { | 82 EV_SET(events + changes, |
| 84 // Register or unregister READ filter if needed. | 83 sd->fd(), |
| 85 if (sd->HasReadEvent()) { | 84 EVFILT_READ, |
| 86 if (!sd->read_tracked_by_kqueue()) { | 85 EV_ADD | EV_CLEAR, |
| 87 EV_SET(events + changes, | 86 0, |
| 88 sd->fd(), | 87 0, |
| 89 EVFILT_READ, | 88 sd); |
| 90 EV_ADD | EV_ONESHOT, | 89 ++changes; |
| 91 0, | |
| 92 0, | |
| 93 sd); | |
| 94 ++changes; | |
| 95 sd->set_read_tracked_by_kqueue(true); | |
| 96 } | |
| 97 } else if (sd->read_tracked_by_kqueue()) { | |
| 98 EV_SET(events + changes, sd->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); | |
| 99 ++changes; | |
| 100 sd->set_read_tracked_by_kqueue(false); | |
| 101 } | |
| 102 // Register or unregister WRITE filter if needed. | |
| 103 if (sd->HasWriteEvent()) { | |
| 104 if (!sd->write_tracked_by_kqueue()) { | |
| 105 EV_SET(events + changes, | |
| 106 sd->fd(), | |
| 107 EVFILT_WRITE, | |
| 108 EV_ADD | EV_ONESHOT, | |
| 109 0, | |
| 110 0, | |
| 111 sd); | |
| 112 ++changes; | |
| 113 sd->set_write_tracked_by_kqueue(true); | |
| 114 } | |
| 115 } else if (sd->write_tracked_by_kqueue()) { | |
| 116 EV_SET(events + changes, sd->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); | |
| 117 ++changes; | |
| 118 sd->set_write_tracked_by_kqueue(false); | |
| 119 } | |
| 120 } | 90 } |
| 121 if (changes > 0) { | 91 // Register or unregister WRITE filter if needed. |
| 122 ASSERT(changes <= kMaxChanges); | 92 if (sd->HasWriteEvent()) { |
| 123 int status = | 93 EV_SET(events + changes, |
| 124 TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); | 94 sd->fd(), |
| 125 if (status == -1) { | 95 EVFILT_WRITE, |
| 126 // kQueue does not accept the file descriptor. It could be due to | 96 EV_ADD | EV_CLEAR, |
| 127 // already closed file descriptor, or unuspported devices, such | 97 0, |
| 128 // as /dev/null. In such case, mark the file descriptor as closed, | 98 0, |
| 129 // so dart will handle it accordingly. | 99 sd); |
| 130 sd->set_write_tracked_by_kqueue(false); | 100 ++changes; |
| 131 sd->set_read_tracked_by_kqueue(false); | 101 } |
| 132 sd->ShutdownRead(); | 102 ASSERT(changes > 0); |
| 133 sd->ShutdownWrite(); | 103 ASSERT(changes <= kMaxChanges); |
| 134 DartUtils::PostInt32(sd->port(), 1 << kCloseEvent); | 104 int status = |
| 135 } | 105 TEMP_FAILURE_RETRY(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); |
| 106 if (status == -1) { |
| 107 // kQueue does not accept the file descriptor. It could be due to |
| 108 // already closed file descriptor, or unuspported devices, such |
| 109 // as /dev/null. In such case, mark the file descriptor as closed, |
| 110 // so dart will handle it accordingly. |
| 111 DartUtils::PostInt32(sd->port(), 1 << kCloseEvent); |
| 112 } else { |
| 113 sd->set_tracked_by_kqueue(true); |
| 136 } | 114 } |
| 137 } | 115 } |
| 138 | 116 |
| 139 | 117 |
| 140 EventHandlerImplementation::EventHandlerImplementation() | 118 EventHandlerImplementation::EventHandlerImplementation() |
| 141 : socket_map_(&HashMap::SamePointerValue, 16) { | 119 : socket_map_(&HashMap::SamePointerValue, 16) { |
| 142 intptr_t result; | 120 intptr_t result; |
| 143 result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_)); | 121 result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_)); |
| 144 if (result != 0) { | 122 if (result != 0) { |
| 145 FATAL("Pipe creation failed"); | 123 FATAL("Pipe creation failed"); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 167 } | 145 } |
| 168 | 146 |
| 169 | 147 |
| 170 EventHandlerImplementation::~EventHandlerImplementation() { | 148 EventHandlerImplementation::~EventHandlerImplementation() { |
| 171 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); | 149 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); |
| 172 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 150 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
| 173 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 151 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
| 174 } | 152 } |
| 175 | 153 |
| 176 | 154 |
| 177 SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) { | 155 SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd, |
| 156 bool* is_new) { |
| 178 ASSERT(fd >= 0); | 157 ASSERT(fd >= 0); |
| 179 HashMap::Entry* entry = socket_map_.Lookup( | 158 HashMap::Entry* entry = socket_map_.Lookup( |
| 180 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); | 159 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); |
| 181 ASSERT(entry != NULL); | 160 ASSERT(entry != NULL); |
| 182 SocketData* sd = reinterpret_cast<SocketData*>(entry->value); | 161 SocketData* sd = reinterpret_cast<SocketData*>(entry->value); |
| 183 if (sd == NULL) { | 162 if (sd == NULL) { |
| 184 // If there is no data in the hash map for this file descriptor a | 163 // If there is no data in the hash map for this file descriptor a |
| 185 // new SocketData for the file descriptor is inserted. | 164 // new SocketData for the file descriptor is inserted. |
| 186 sd = new SocketData(fd); | 165 sd = new SocketData(fd); |
| 187 entry->value = sd; | 166 entry->value = sd; |
| 167 *is_new = true; |
| 188 } | 168 } |
| 189 ASSERT(fd == sd->fd()); | 169 ASSERT(fd == sd->fd()); |
| 190 return sd; | 170 return sd; |
| 191 } | 171 } |
| 192 | 172 |
| 193 | 173 |
| 194 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 174 void EventHandlerImplementation::WakeupHandler(intptr_t id, |
| 195 Dart_Port dart_port, | 175 Dart_Port dart_port, |
| 196 int64_t data) { | 176 int64_t data) { |
| 197 InterruptMessage msg; | 177 InterruptMessage msg; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 216 const intptr_t MAX_MESSAGES = kInterruptMessageSize; | 196 const intptr_t MAX_MESSAGES = kInterruptMessageSize; |
| 217 InterruptMessage msg[MAX_MESSAGES]; | 197 InterruptMessage msg[MAX_MESSAGES]; |
| 218 ssize_t bytes = TEMP_FAILURE_RETRY( | 198 ssize_t bytes = TEMP_FAILURE_RETRY( |
| 219 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); | 199 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); |
| 220 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { | 200 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { |
| 221 if (msg[i].id == kTimerId) { | 201 if (msg[i].id == kTimerId) { |
| 222 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); | 202 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); |
| 223 } else if (msg[i].id == kShutdownId) { | 203 } else if (msg[i].id == kShutdownId) { |
| 224 shutdown_ = true; | 204 shutdown_ = true; |
| 225 } else { | 205 } else { |
| 226 SocketData* sd = GetSocketData(msg[i].id); | 206 bool is_new = false; |
| 207 SocketData* sd = GetSocketData(msg[i].id, &is_new); |
| 208 if (is_new) { |
| 209 sd->SetPortAndMask(msg[i].dart_port, msg[i].data); |
| 210 } |
| 227 if ((msg[i].data & (1 << kShutdownReadCommand)) != 0) { | 211 if ((msg[i].data & (1 << kShutdownReadCommand)) != 0) { |
| 228 ASSERT(msg[i].data == (1 << kShutdownReadCommand)); | 212 ASSERT(msg[i].data == (1 << kShutdownReadCommand)); |
| 229 // Close the socket for reading. | 213 // Close the socket for reading. |
| 230 sd->ShutdownRead(); | 214 sd->ShutdownRead(); |
| 231 UpdateKqueue(kqueue_fd_, sd); | |
| 232 } else if ((msg[i].data & (1 << kShutdownWriteCommand)) != 0) { | 215 } else if ((msg[i].data & (1 << kShutdownWriteCommand)) != 0) { |
| 233 ASSERT(msg[i].data == (1 << kShutdownWriteCommand)); | 216 ASSERT(msg[i].data == (1 << kShutdownWriteCommand)); |
| 234 // Close the socket for writing. | 217 // Close the socket for writing. |
| 235 sd->ShutdownWrite(); | 218 sd->ShutdownWrite(); |
| 236 UpdateKqueue(kqueue_fd_, sd); | |
| 237 } else if ((msg[i].data & (1 << kCloseCommand)) != 0) { | 219 } else if ((msg[i].data & (1 << kCloseCommand)) != 0) { |
| 238 ASSERT(msg[i].data == (1 << kCloseCommand)); | 220 ASSERT(msg[i].data == (1 << kCloseCommand)); |
| 239 // Close the socket and free system resources. | 221 // Close the socket and free system resources. |
| 240 RemoveFromKqueue(kqueue_fd_, sd); | 222 RemoveFromKqueue(kqueue_fd_, sd); |
| 241 intptr_t fd = sd->fd(); | 223 intptr_t fd = sd->fd(); |
| 242 sd->Close(); | 224 sd->Close(); |
| 243 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); | 225 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
| 244 delete sd; | 226 delete sd; |
| 245 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); | 227 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); |
| 246 } else { | 228 } else { |
| 247 if ((msg[i].data & (1 << kInEvent)) != 0 && sd->IsClosedRead()) { | 229 if (is_new) { |
| 248 DartUtils::PostInt32(msg[i].dart_port, 1 << kCloseEvent); | 230 AddToKqueue(kqueue_fd_, sd); |
| 249 } else { | |
| 250 // Setup events to wait for. | |
| 251 ASSERT((msg[i].data > 0) && (msg[i].data < kIntptrMax)); | |
| 252 sd->SetPortAndMask(msg[i].dart_port, | |
| 253 static_cast<intptr_t>(msg[i].data)); | |
| 254 UpdateKqueue(kqueue_fd_, sd); | |
| 255 } | 231 } |
| 256 } | 232 } |
| 257 } | 233 } |
| 258 } | 234 } |
| 259 } | 235 } |
| 260 | 236 |
| 261 #ifdef DEBUG_KQUEUE | 237 #ifdef DEBUG_KQUEUE |
| 262 static void PrintEventMask(intptr_t fd, struct kevent* event) { | 238 static void PrintEventMask(intptr_t fd, struct kevent* event) { |
| 263 Log::Print("%d ", static_cast<int>(fd)); | 239 Log::Print("%d ", static_cast<int>(fd)); |
| 240 Log::Print("filter=0x%x:", event->filter); |
| 264 if (event->filter == EVFILT_READ) Log::Print("EVFILT_READ "); | 241 if (event->filter == EVFILT_READ) Log::Print("EVFILT_READ "); |
| 265 if (event->filter == EVFILT_WRITE) Log::Print("EVFILT_WRITE "); | 242 if (event->filter == EVFILT_WRITE) Log::Print("EVFILT_WRITE "); |
| 266 Log::Print("flags: %x: ", event->flags); | 243 Log::Print("flags: %x: ", event->flags); |
| 267 if ((event->flags & EV_EOF) != 0) Log::Print("EV_EOF "); | 244 if ((event->flags & EV_EOF) != 0) Log::Print("EV_EOF "); |
| 268 if ((event->flags & EV_ERROR) != 0) Log::Print("EV_ERROR "); | 245 if ((event->flags & EV_ERROR) != 0) Log::Print("EV_ERROR "); |
| 246 if ((event->flags & EV_CLEAR) != 0) Log::Print("EV_CLEAR "); |
| 247 if ((event->flags & EV_ADD) != 0) Log::Print("EV_ADD "); |
| 248 if ((event->flags & EV_DELETE) != 0) Log::Print("EV_DELETE "); |
| 269 Log::Print("- fflags: %d ", event->fflags); | 249 Log::Print("- fflags: %d ", event->fflags); |
| 250 Log::Print("- data: %ld ", event->data); |
| 270 Log::Print("(available %d) ", | 251 Log::Print("(available %d) ", |
| 271 static_cast<int>(FDUtils::AvailableBytes(fd))); | 252 static_cast<int>(FDUtils::AvailableBytes(fd))); |
| 272 Log::Print("\n"); | 253 Log::Print("\n"); |
| 273 } | 254 } |
| 274 #endif | 255 #endif |
| 275 | 256 |
| 276 | 257 |
| 277 intptr_t EventHandlerImplementation::GetEvents(struct kevent* event, | 258 intptr_t EventHandlerImplementation::GetEvents(struct kevent* event, |
| 278 SocketData* sd) { | 259 SocketData* sd) { |
| 279 #ifdef DEBUG_KQUEUE | 260 #ifdef DEBUG_KQUEUE |
| (...skipping 11 matching lines...) Expand all Loading... |
| 291 event_mask |= (1 << kCloseEvent); | 272 event_mask |= (1 << kCloseEvent); |
| 292 } | 273 } |
| 293 } | 274 } |
| 294 if (event_mask == 0) event_mask |= (1 << kInEvent); | 275 if (event_mask == 0) event_mask |= (1 << kInEvent); |
| 295 } else { | 276 } else { |
| 296 UNREACHABLE(); | 277 UNREACHABLE(); |
| 297 } | 278 } |
| 298 } else { | 279 } else { |
| 299 // Prioritize data events over close and error events. | 280 // Prioritize data events over close and error events. |
| 300 if (event->filter == EVFILT_READ) { | 281 if (event->filter == EVFILT_READ) { |
| 301 if (FDUtils::AvailableBytes(sd->fd()) != 0) { | 282 event_mask = (1 << kInEvent); |
| 302 event_mask = (1 << kInEvent); | 283 if ((event->flags & EV_EOF) != 0) { |
| 303 } else if ((event->flags & EV_EOF) != 0) { | |
| 304 if (event->fflags != 0) { | 284 if (event->fflags != 0) { |
| 305 event_mask |= (1 << kErrorEvent); | 285 event_mask = (1 << kErrorEvent); |
| 306 } else { | 286 } else { |
| 307 event_mask |= (1 << kCloseEvent); | 287 event_mask |= (1 << kCloseEvent); |
| 308 } | 288 } |
| 309 sd->MarkClosedRead(); | |
| 310 } | 289 } |
| 311 } else if (event->filter == EVFILT_WRITE) { | 290 } else if (event->filter == EVFILT_WRITE) { |
| 291 event_mask |= (1 << kOutEvent); |
| 312 if ((event->flags & EV_EOF) != 0) { | 292 if ((event->flags & EV_EOF) != 0) { |
| 313 if (event->fflags != 0) { | 293 if (event->fflags != 0) { |
| 314 event_mask |= (1 << kErrorEvent); | 294 event_mask = (1 << kErrorEvent); |
| 315 } else { | |
| 316 event_mask |= (1 << kCloseEvent); | |
| 317 } | 295 } |
| 318 // If the receiver closed for reading, close for writing, | |
| 319 // update the registration with kqueue, and do not report a | |
| 320 // write event. | |
| 321 sd->MarkClosedWrite(); | |
| 322 UpdateKqueue(kqueue_fd_, sd); | |
| 323 } else { | |
| 324 event_mask |= (1 << kOutEvent); | |
| 325 } | 296 } |
| 326 } else { | 297 } else { |
| 327 UNREACHABLE(); | 298 UNREACHABLE(); |
| 328 } | 299 } |
| 329 } | 300 } |
| 330 | 301 |
| 331 return event_mask; | 302 return event_mask; |
| 332 } | 303 } |
| 333 | 304 |
| 334 | 305 |
| 335 void EventHandlerImplementation::HandleEvents(struct kevent* events, | 306 void EventHandlerImplementation::HandleEvents(struct kevent* events, |
| 336 int size) { | 307 int size) { |
| 337 bool interrupt_seen = false; | 308 bool interrupt_seen = false; |
| 338 for (int i = 0; i < size; i++) { | 309 for (int i = 0; i < size; i++) { |
| 339 // If flag EV_ERROR is set it indicates an error in kevent processing. | 310 // If flag EV_ERROR is set it indicates an error in kevent processing. |
| 340 if ((events[i].flags & EV_ERROR) != 0) { | 311 if ((events[i].flags & EV_ERROR) != 0) { |
| 341 const int kBufferSize = 1024; | 312 const int kBufferSize = 1024; |
| 342 char error_message[kBufferSize]; | 313 char error_message[kBufferSize]; |
| 343 strerror_r(events[i].data, error_message, kBufferSize); | 314 strerror_r(events[i].data, error_message, kBufferSize); |
| 344 FATAL1("kevent failed %s\n", error_message); | 315 FATAL1("kevent failed %s\n", error_message); |
| 345 } | 316 } |
| 346 if (events[i].udata == NULL) { | 317 if (events[i].udata == NULL) { |
| 347 interrupt_seen = true; | 318 interrupt_seen = true; |
| 348 } else { | 319 } else { |
| 349 SocketData* sd = reinterpret_cast<SocketData*>(events[i].udata); | 320 SocketData* sd = reinterpret_cast<SocketData*>(events[i].udata); |
| 350 sd->set_write_tracked_by_kqueue(false); | |
| 351 sd->set_read_tracked_by_kqueue(false); | |
| 352 intptr_t event_mask = GetEvents(events + i, sd); | 321 intptr_t event_mask = GetEvents(events + i, sd); |
| 353 if (event_mask == 0) { | 322 if (event_mask != 0) { |
| 354 // Event not handled, re-add to kqueue. | |
| 355 UpdateKqueue(kqueue_fd_, sd); | |
| 356 } else { | |
| 357 Dart_Port port = sd->port(); | 323 Dart_Port port = sd->port(); |
| 358 ASSERT(port != 0); | 324 ASSERT(port != 0); |
| 359 DartUtils::PostInt32(port, event_mask); | 325 DartUtils::PostInt32(port, event_mask); |
| 360 } | 326 } |
| 361 } | 327 } |
| 362 } | 328 } |
| 363 if (interrupt_seen) { | 329 if (interrupt_seen) { |
| 364 // Handle after socket events, so we avoid closing a socket before we handle | 330 // Handle after socket events, so we avoid closing a socket before we handle |
| 365 // the current events. | 331 // the current events. |
| 366 HandleInterruptFd(); | 332 HandleInterruptFd(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 | 427 |
| 462 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 428 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
| 463 // The hashmap does not support keys with value 0. | 429 // The hashmap does not support keys with value 0. |
| 464 return dart::Utils::WordHash(fd + 1); | 430 return dart::Utils::WordHash(fd + 1); |
| 465 } | 431 } |
| 466 | 432 |
| 467 } // namespace bin | 433 } // namespace bin |
| 468 } // namespace dart | 434 } // namespace dart |
| 469 | 435 |
| 470 #endif // defined(TARGET_OS_MACOS) | 436 #endif // defined(TARGET_OS_MACOS) |
| OLD | NEW |