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 | 10 |
10 #include <errno.h> // NOLINT | 11 #include <errno.h> // NOLINT |
11 #include <pthread.h> // NOLINT | 12 #include <pthread.h> // NOLINT |
12 #include <stdio.h> // NOLINT | 13 #include <stdio.h> // NOLINT |
13 #include <string.h> // NOLINT | 14 #include <string.h> // NOLINT |
14 #include <sys/event.h> // NOLINT | 15 #include <sys/event.h> // NOLINT |
15 #include <unistd.h> // NOLINT | 16 #include <unistd.h> // NOLINT |
16 #include <fcntl.h> // NOLINT | 17 #include <fcntl.h> // NOLINT |
17 | 18 |
18 #include "bin/dartutils.h" | 19 #include "bin/dartutils.h" |
19 #include "bin/fdutils.h" | 20 #include "bin/fdutils.h" |
| 21 #include "bin/lockers.h" |
20 #include "bin/log.h" | 22 #include "bin/log.h" |
| 23 #include "bin/socket.h" |
21 #include "bin/thread.h" | 24 #include "bin/thread.h" |
22 #include "bin/utils.h" | 25 #include "bin/utils.h" |
23 #include "platform/hashmap.h" | 26 #include "platform/hashmap.h" |
24 #include "platform/utils.h" | 27 #include "platform/utils.h" |
25 | 28 |
26 | 29 |
27 namespace dart { | 30 namespace dart { |
28 namespace bin { | 31 namespace bin { |
29 | 32 |
30 bool SocketData::HasReadEvent() { | 33 |
31 return (mask_ & (1 << kInEvent)) != 0; | 34 bool DescriptorInfo::HasReadEvent() { |
| 35 return (Mask() & (1 << kInEvent)) != 0; |
32 } | 36 } |
33 | 37 |
34 | 38 |
35 bool SocketData::HasWriteEvent() { | 39 bool DescriptorInfo::HasWriteEvent() { |
36 return (mask_ & (1 << kOutEvent)) != 0; | 40 return (Mask() & (1 << kOutEvent)) != 0; |
37 } | 41 } |
38 | 42 |
39 | 43 |
40 // Unregister the file descriptor for a SocketData structure with kqueue. | 44 // Unregister the file descriptor for a SocketData structure with kqueue. |
41 static void RemoveFromKqueue(intptr_t kqueue_fd_, SocketData* sd) { | 45 static void RemoveFromKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { |
42 if (!sd->tracked_by_kqueue()) return; | 46 if (!di->tracked_by_kqueue()) return; |
43 static const intptr_t kMaxChanges = 2; | 47 static const intptr_t kMaxChanges = 2; |
44 struct kevent events[kMaxChanges]; | 48 struct kevent events[kMaxChanges]; |
45 EV_SET(events, sd->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); | 49 EV_SET(events, di->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); |
46 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)); |
47 EV_SET(events, sd->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); | 51 EV_SET(events, di->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); |
48 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)); |
49 sd->set_tracked_by_kqueue(false); | 53 di->set_tracked_by_kqueue(false); |
50 } | 54 } |
51 | 55 |
52 | 56 |
53 // Update the kqueue registration for SocketData structure to reflect | 57 // Update the kqueue registration for SocketData structure to reflect |
54 // the events currently of interest. | 58 // the events currently of interest. |
55 static void AddToKqueue(intptr_t kqueue_fd_, SocketData* sd) { | 59 static void AddToKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { |
56 ASSERT(!sd->tracked_by_kqueue()); | 60 ASSERT(!di->tracked_by_kqueue()); |
57 static const intptr_t kMaxChanges = 2; | 61 static const intptr_t kMaxChanges = 2; |
58 intptr_t changes = 0; | 62 intptr_t changes = 0; |
59 struct kevent events[kMaxChanges]; | 63 struct kevent events[kMaxChanges]; |
60 int flags = EV_ADD; | 64 int flags = EV_ADD; |
61 if (!sd->IsListeningSocket()) { | 65 if (!di->IsListeningSocket()) { |
62 flags |= EV_CLEAR; | 66 flags |= EV_CLEAR; |
63 } | 67 } |
| 68 |
| 69 ASSERT(di->HasReadEvent() || di->HasWriteEvent()); |
| 70 |
64 // Register or unregister READ filter if needed. | 71 // Register or unregister READ filter if needed. |
65 if (sd->HasReadEvent()) { | 72 if (di->HasReadEvent()) { |
66 EV_SET(events + changes, | 73 EV_SET(events + changes, |
67 sd->fd(), | 74 di->fd(), |
68 EVFILT_READ, | 75 EVFILT_READ, |
69 flags, | 76 flags, |
70 0, | 77 0, |
71 0, | 78 0, |
72 sd); | 79 di); |
73 ++changes; | 80 ++changes; |
74 } | 81 } |
75 // Register or unregister WRITE filter if needed. | 82 // Register or unregister WRITE filter if needed. |
76 if (sd->HasWriteEvent()) { | 83 if (di->HasWriteEvent()) { |
77 EV_SET(events + changes, | 84 EV_SET(events + changes, |
78 sd->fd(), | 85 di->fd(), |
79 EVFILT_WRITE, | 86 EVFILT_WRITE, |
80 flags, | 87 flags, |
81 0, | 88 0, |
82 0, | 89 0, |
83 sd); | 90 di); |
84 ++changes; | 91 ++changes; |
85 } | 92 } |
86 ASSERT(changes > 0); | 93 ASSERT(changes > 0); |
87 ASSERT(changes <= kMaxChanges); | 94 ASSERT(changes <= kMaxChanges); |
88 int status = | 95 int status = |
89 NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); | 96 NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); |
90 if (status == -1) { | 97 if (status == -1) { |
| 98 // TODO(dart:io): Verify that the dart end is handling this correctly. |
| 99 |
91 // kQueue does not accept the file descriptor. It could be due to | 100 // kQueue does not accept the file descriptor. It could be due to |
92 // already closed file descriptor, or unuspported devices, such | 101 // already closed file descriptor, or unuspported devices, such |
93 // as /dev/null. In such case, mark the file descriptor as closed, | 102 // as /dev/null. In such case, mark the file descriptor as closed, |
94 // so dart will handle it accordingly. | 103 // so dart will handle it accordingly. |
95 DartUtils::PostInt32(sd->port(), 1 << kCloseEvent); | 104 di->NotifyAllDartPorts(1 << kCloseEvent); |
96 } else { | 105 } else { |
97 sd->set_tracked_by_kqueue(true); | 106 di->set_tracked_by_kqueue(true); |
98 } | 107 } |
99 } | 108 } |
100 | 109 |
101 | 110 |
102 EventHandlerImplementation::EventHandlerImplementation() | 111 EventHandlerImplementation::EventHandlerImplementation() |
103 : socket_map_(&HashMap::SamePointerValue, 16) { | 112 : socket_map_(&HashMap::SamePointerValue, 16) { |
104 intptr_t result; | 113 intptr_t result; |
105 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); | 114 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); |
106 if (result != 0) { | 115 if (result != 0) { |
107 FATAL("Pipe creation failed"); | 116 FATAL("Pipe creation failed"); |
(...skipping 21 matching lines...) Expand all Loading... |
129 } | 138 } |
130 | 139 |
131 | 140 |
132 EventHandlerImplementation::~EventHandlerImplementation() { | 141 EventHandlerImplementation::~EventHandlerImplementation() { |
133 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); | 142 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); |
134 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 143 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
135 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 144 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
136 } | 145 } |
137 | 146 |
138 | 147 |
139 SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd, | 148 void EventHandlerImplementation::UpdateKQueueInstance(intptr_t old_mask, |
140 bool is_listening) { | 149 DescriptorInfo *di) { |
| 150 intptr_t new_mask = di->Mask(); |
| 151 if (old_mask != 0 && new_mask == 0) { |
| 152 RemoveFromKqueue(kqueue_fd_, di); |
| 153 } else if (old_mask == 0 && new_mask != 0) { |
| 154 AddToKqueue(kqueue_fd_, di); |
| 155 } else if (old_mask != 0 && new_mask != 0 && old_mask != new_mask) { |
| 156 ASSERT(!di->IsListeningSocket()); |
| 157 RemoveFromKqueue(kqueue_fd_, di); |
| 158 AddToKqueue(kqueue_fd_, di); |
| 159 } |
| 160 } |
| 161 |
| 162 |
| 163 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( |
| 164 intptr_t fd, bool is_listening) { |
141 ASSERT(fd >= 0); | 165 ASSERT(fd >= 0); |
142 HashMap::Entry* entry = socket_map_.Lookup( | 166 HashMap::Entry* entry = socket_map_.Lookup( |
143 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); | 167 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); |
144 ASSERT(entry != NULL); | 168 ASSERT(entry != NULL); |
145 SocketData* sd = reinterpret_cast<SocketData*>(entry->value); | 169 DescriptorInfo* di = |
146 if (sd == NULL) { | 170 reinterpret_cast<DescriptorInfo*>(entry->value); |
| 171 if (di == NULL) { |
147 // If there is no data in the hash map for this file descriptor a | 172 // If there is no data in the hash map for this file descriptor a |
148 // new SocketData for the file descriptor is inserted. | 173 // new DescriptorInfo for the file descriptor is inserted. |
149 sd = new SocketData(fd, is_listening); | 174 if (is_listening) { |
150 entry->value = sd; | 175 di = new DescriptorInfoMultiple(fd); |
| 176 } else { |
| 177 di = new DescriptorInfoSingle(fd); |
| 178 } |
| 179 entry->value = di; |
151 } | 180 } |
152 ASSERT(fd == sd->fd()); | 181 ASSERT(fd == di->fd()); |
153 return sd; | 182 return di; |
154 } | 183 } |
155 | 184 |
156 | 185 |
157 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 186 void EventHandlerImplementation::WakeupHandler(intptr_t id, |
158 Dart_Port dart_port, | 187 Dart_Port dart_port, |
159 int64_t data) { | 188 int64_t data) { |
160 InterruptMessage msg; | 189 InterruptMessage msg; |
161 msg.id = id; | 190 msg.id = id; |
162 msg.dart_port = dart_port; | 191 msg.dart_port = dart_port; |
163 msg.data = data; | 192 msg.data = data; |
(...skipping 17 matching lines...) Expand all Loading... |
181 ssize_t bytes = TEMP_FAILURE_RETRY( | 210 ssize_t bytes = TEMP_FAILURE_RETRY( |
182 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); | 211 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); |
183 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { | 212 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { |
184 if (msg[i].id == kTimerId) { | 213 if (msg[i].id == kTimerId) { |
185 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); | 214 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); |
186 } else if (msg[i].id == kShutdownId) { | 215 } else if (msg[i].id == kShutdownId) { |
187 shutdown_ = true; | 216 shutdown_ = true; |
188 } else { | 217 } else { |
189 ASSERT((msg[i].data & COMMAND_MASK) != 0); | 218 ASSERT((msg[i].data & COMMAND_MASK) != 0); |
190 | 219 |
191 SocketData* sd = GetSocketData( | 220 DescriptorInfo* di = GetDescriptorInfo( |
192 msg[i].id, IS_LISTENING_SOCKET(msg[i].data)); | 221 msg[i].id, IS_LISTENING_SOCKET(msg[i].data)); |
193 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { | 222 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { |
| 223 ASSERT(!di->IsListeningSocket()); |
194 // Close the socket for reading. | 224 // Close the socket for reading. |
195 shutdown(sd->fd(), SHUT_RD); | 225 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_RD)); |
196 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { | 226 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { |
| 227 ASSERT(!di->IsListeningSocket()); |
197 // Close the socket for writing. | 228 // Close the socket for writing. |
198 shutdown(sd->fd(), SHUT_WR); | 229 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_WR)); |
199 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { | 230 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { |
200 // Close the socket and free system resources. | 231 // Close the socket and free system resources and move on to next |
201 RemoveFromKqueue(kqueue_fd_, sd); | 232 // message. |
202 intptr_t fd = sd->fd(); | 233 intptr_t old_mask = di->Mask(); |
203 VOID_TEMP_FAILURE_RETRY(close(fd)); | 234 Dart_Port port = msg[i].dart_port; |
204 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); | 235 di->RemovePort(port); |
205 delete sd; | 236 intptr_t new_mask = di->Mask(); |
206 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); | 237 UpdateKQueueInstance(old_mask, di); |
| 238 |
| 239 intptr_t fd = di->fd(); |
| 240 if (di->IsListeningSocket()) { |
| 241 // We only close the socket file descriptor from the operating |
| 242 // system if there are no other dart socket objects which |
| 243 // are listening on the same (address, port) combination. |
| 244 |
| 245 // TODO(dart:io): This assumes that all sockets listen before we |
| 246 // close. |
| 247 // This needs to be synchronized with a global datastructure. |
| 248 if (new_mask == 0) { |
| 249 socket_map_.Remove( |
| 250 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
| 251 di->Close(); |
| 252 delete di; |
| 253 } |
| 254 |
| 255 |
| 256 } else { |
| 257 ASSERT(new_mask == 0); |
| 258 socket_map_.Remove( |
| 259 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
| 260 di->Close(); |
| 261 delete di; |
| 262 } |
| 263 |
| 264 DartUtils::PostInt32(port, 1 << kDestroyedEvent); |
207 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { | 265 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { |
208 int count = TOKEN_COUNT(msg[i].data); | 266 intptr_t old_mask = di->Mask(); |
209 for (int i = 0; i < count; i++) { | 267 di->ReturnTokens(msg[i].dart_port, TOKEN_COUNT(msg[i].data)); |
210 if (sd->ReturnToken()) { | 268 UpdateKQueueInstance(old_mask, di); |
211 AddToKqueue(kqueue_fd_, sd); | |
212 } | |
213 } | |
214 } else if (IS_COMMAND(msg[i].data, kSetEventMaskCommand)) { | 269 } else if (IS_COMMAND(msg[i].data, kSetEventMaskCommand)) { |
215 // `events` can only have kInEvent/kOutEvent flags set. | 270 // `events` can only have kInEvent/kOutEvent flags set. |
216 intptr_t events = msg[i].data & EVENT_MASK; | 271 intptr_t events = msg[i].data & EVENT_MASK; |
217 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent))); | 272 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent))); |
218 | 273 |
219 // Setup events to wait for. | 274 intptr_t old_mask = di->Mask(); |
220 ASSERT(sd->port() == 0); | 275 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); |
221 sd->SetPortAndMask(msg[i].dart_port, events); | 276 UpdateKQueueInstance(old_mask, di); |
222 AddToKqueue(kqueue_fd_, sd); | |
223 } else { | 277 } else { |
224 UNREACHABLE(); | 278 UNREACHABLE(); |
225 } | 279 } |
226 } | 280 } |
227 } | 281 } |
228 } | 282 } |
229 | 283 |
230 #ifdef DEBUG_KQUEUE | 284 #ifdef DEBUG_KQUEUE |
231 static void PrintEventMask(intptr_t fd, struct kevent* event) { | 285 static void PrintEventMask(intptr_t fd, struct kevent* event) { |
232 Log::Print("%d ", static_cast<int>(fd)); | 286 Log::Print("%d ", static_cast<int>(fd)); |
233 Log::Print("filter=0x%x:", event->filter); | 287 Log::Print("filter=0x%x:", event->filter); |
234 if (event->filter == EVFILT_READ) Log::Print("EVFILT_READ "); | 288 if (event->filter == EVFILT_READ) Log::Print("EVFILT_READ "); |
235 if (event->filter == EVFILT_WRITE) Log::Print("EVFILT_WRITE "); | 289 if (event->filter == EVFILT_WRITE) Log::Print("EVFILT_WRITE "); |
236 Log::Print("flags: %x: ", event->flags); | 290 Log::Print("flags: %x: ", event->flags); |
237 if ((event->flags & EV_EOF) != 0) Log::Print("EV_EOF "); | 291 if ((event->flags & EV_EOF) != 0) Log::Print("EV_EOF "); |
238 if ((event->flags & EV_ERROR) != 0) Log::Print("EV_ERROR "); | 292 if ((event->flags & EV_ERROR) != 0) Log::Print("EV_ERROR "); |
239 if ((event->flags & EV_CLEAR) != 0) Log::Print("EV_CLEAR "); | 293 if ((event->flags & EV_CLEAR) != 0) Log::Print("EV_CLEAR "); |
240 if ((event->flags & EV_ADD) != 0) Log::Print("EV_ADD "); | 294 if ((event->flags & EV_ADD) != 0) Log::Print("EV_ADD "); |
241 if ((event->flags & EV_DELETE) != 0) Log::Print("EV_DELETE "); | 295 if ((event->flags & EV_DELETE) != 0) Log::Print("EV_DELETE "); |
242 Log::Print("- fflags: %d ", event->fflags); | 296 Log::Print("- fflags: %d ", event->fflags); |
243 Log::Print("- data: %ld ", event->data); | 297 Log::Print("- data: %ld ", event->data); |
244 Log::Print("(available %d) ", | 298 Log::Print("(available %d) ", |
245 static_cast<int>(FDUtils::AvailableBytes(fd))); | 299 static_cast<int>(FDUtils::AvailableBytes(fd))); |
246 Log::Print("\n"); | 300 Log::Print("\n"); |
247 } | 301 } |
248 #endif | 302 #endif |
249 | 303 |
250 | 304 |
251 intptr_t EventHandlerImplementation::GetEvents(struct kevent* event, | 305 intptr_t EventHandlerImplementation::GetEvents(struct kevent* event, |
252 SocketData* sd) { | 306 DescriptorInfo* di) { |
253 #ifdef DEBUG_KQUEUE | 307 #ifdef DEBUG_KQUEUE |
254 PrintEventMask(sd->fd(), event); | 308 PrintEventMask(di->fd(), event); |
255 #endif | 309 #endif |
256 intptr_t event_mask = 0; | 310 intptr_t event_mask = 0; |
257 if (sd->IsListeningSocket()) { | 311 if (di->IsListeningSocket()) { |
258 // On a listening socket the READ event means that there are | 312 // On a listening socket the READ event means that there are |
259 // connections ready to be accepted. | 313 // connections ready to be accepted. |
260 if (event->filter == EVFILT_READ) { | 314 if (event->filter == EVFILT_READ) { |
261 if ((event->flags & EV_EOF) != 0) { | 315 if ((event->flags & EV_EOF) != 0) { |
262 if (event->fflags != 0) { | 316 if (event->fflags != 0) { |
263 event_mask |= (1 << kErrorEvent); | 317 event_mask |= (1 << kErrorEvent); |
264 } else { | 318 } else { |
265 event_mask |= (1 << kCloseEvent); | 319 event_mask |= (1 << kCloseEvent); |
266 } | 320 } |
267 } | 321 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 // If flag EV_ERROR is set it indicates an error in kevent processing. | 357 // If flag EV_ERROR is set it indicates an error in kevent processing. |
304 if ((events[i].flags & EV_ERROR) != 0) { | 358 if ((events[i].flags & EV_ERROR) != 0) { |
305 const int kBufferSize = 1024; | 359 const int kBufferSize = 1024; |
306 char error_message[kBufferSize]; | 360 char error_message[kBufferSize]; |
307 strerror_r(events[i].data, error_message, kBufferSize); | 361 strerror_r(events[i].data, error_message, kBufferSize); |
308 FATAL1("kevent failed %s\n", error_message); | 362 FATAL1("kevent failed %s\n", error_message); |
309 } | 363 } |
310 if (events[i].udata == NULL) { | 364 if (events[i].udata == NULL) { |
311 interrupt_seen = true; | 365 interrupt_seen = true; |
312 } else { | 366 } else { |
313 SocketData* sd = reinterpret_cast<SocketData*>(events[i].udata); | 367 DescriptorInfo* di = |
314 intptr_t event_mask = GetEvents(events + i, sd); | 368 reinterpret_cast<DescriptorInfo*>(events[i].udata); |
| 369 intptr_t event_mask = GetEvents(events + i, di); |
| 370 if ((event_mask & (1 << kErrorEvent)) != 0) { |
| 371 di->NotifyAllDartPorts(event_mask); |
| 372 } |
| 373 event_mask &= ~(1 << kErrorEvent); |
| 374 |
315 if (event_mask != 0) { | 375 if (event_mask != 0) { |
316 if (sd->TakeToken()) { | 376 intptr_t old_mask = di->Mask(); |
317 // Took last token, remove from epoll. | 377 Dart_Port port = di->NextNotifyDartPort(event_mask); |
318 RemoveFromKqueue(kqueue_fd_, sd); | |
319 } | |
320 Dart_Port port = sd->port(); | |
321 ASSERT(port != 0); | 378 ASSERT(port != 0); |
| 379 UpdateKQueueInstance(old_mask, di); |
322 DartUtils::PostInt32(port, event_mask); | 380 DartUtils::PostInt32(port, event_mask); |
323 } | 381 } |
324 } | 382 } |
325 } | 383 } |
326 if (interrupt_seen) { | 384 if (interrupt_seen) { |
327 // Handle after socket events, so we avoid closing a socket before we handle | 385 // Handle after socket events, so we avoid closing a socket before we handle |
328 // the current events. | 386 // the current events. |
329 HandleInterruptFd(); | 387 HandleInterruptFd(); |
330 } | 388 } |
331 } | 389 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 | 481 |
424 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 482 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
425 // The hashmap does not support keys with value 0. | 483 // The hashmap does not support keys with value 0. |
426 return dart::Utils::WordHash(fd + 1); | 484 return dart::Utils::WordHash(fd + 1); |
427 } | 485 } |
428 | 486 |
429 } // namespace bin | 487 } // namespace bin |
430 } // namespace dart | 488 } // namespace dart |
431 | 489 |
432 #endif // defined(TARGET_OS_MACOS) | 490 #endif // defined(TARGET_OS_MACOS) |
OLD | NEW |