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 |