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 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) |
6 | 6 |
7 #include "platform/globals.h" | 7 #include "platform/globals.h" |
8 #if defined(HOST_OS_MACOS) | 8 #if defined(HOST_OS_MACOS) |
9 | 9 |
10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "platform/hashmap.h" | 28 #include "platform/hashmap.h" |
29 #include "platform/utils.h" | 29 #include "platform/utils.h" |
30 | 30 |
31 namespace dart { | 31 namespace dart { |
32 namespace bin { | 32 namespace bin { |
33 | 33 |
34 bool DescriptorInfo::HasReadEvent() { | 34 bool DescriptorInfo::HasReadEvent() { |
35 return (Mask() & (1 << kInEvent)) != 0; | 35 return (Mask() & (1 << kInEvent)) != 0; |
36 } | 36 } |
37 | 37 |
38 | |
39 bool DescriptorInfo::HasWriteEvent() { | 38 bool DescriptorInfo::HasWriteEvent() { |
40 return (Mask() & (1 << kOutEvent)) != 0; | 39 return (Mask() & (1 << kOutEvent)) != 0; |
41 } | 40 } |
42 | 41 |
43 | |
44 // Unregister the file descriptor for a SocketData structure with kqueue. | 42 // Unregister the file descriptor for a SocketData structure with kqueue. |
45 static void RemoveFromKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { | 43 static void RemoveFromKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { |
46 if (!di->tracked_by_kqueue()) { | 44 if (!di->tracked_by_kqueue()) { |
47 return; | 45 return; |
48 } | 46 } |
49 static const intptr_t kMaxChanges = 2; | 47 static const intptr_t kMaxChanges = 2; |
50 struct kevent events[kMaxChanges]; | 48 struct kevent events[kMaxChanges]; |
51 EV_SET(events, di->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); | 49 EV_SET(events, di->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); |
52 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)); |
53 EV_SET(events, di->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); | 51 EV_SET(events, di->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); |
54 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)); |
55 di->set_tracked_by_kqueue(false); | 53 di->set_tracked_by_kqueue(false); |
56 } | 54 } |
57 | 55 |
58 | |
59 // Update the kqueue registration for SocketData structure to reflect | 56 // Update the kqueue registration for SocketData structure to reflect |
60 // the events currently of interest. | 57 // the events currently of interest. |
61 static void AddToKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { | 58 static void AddToKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { |
62 ASSERT(!di->tracked_by_kqueue()); | 59 ASSERT(!di->tracked_by_kqueue()); |
63 static const intptr_t kMaxChanges = 2; | 60 static const intptr_t kMaxChanges = 2; |
64 intptr_t changes = 0; | 61 intptr_t changes = 0; |
65 struct kevent events[kMaxChanges]; | 62 struct kevent events[kMaxChanges]; |
66 int flags = EV_ADD; | 63 int flags = EV_ADD; |
67 if (!di->IsListeningSocket()) { | 64 if (!di->IsListeningSocket()) { |
68 flags |= EV_CLEAR; | 65 flags |= EV_CLEAR; |
(...skipping 21 matching lines...) Expand all Loading... |
90 // kQueue does not accept the file descriptor. It could be due to | 87 // kQueue does not accept the file descriptor. It could be due to |
91 // already closed file descriptor, or unuspported devices, such | 88 // already closed file descriptor, or unuspported devices, such |
92 // as /dev/null. In such case, mark the file descriptor as closed, | 89 // as /dev/null. In such case, mark the file descriptor as closed, |
93 // so dart will handle it accordingly. | 90 // so dart will handle it accordingly. |
94 di->NotifyAllDartPorts(1 << kCloseEvent); | 91 di->NotifyAllDartPorts(1 << kCloseEvent); |
95 } else { | 92 } else { |
96 di->set_tracked_by_kqueue(true); | 93 di->set_tracked_by_kqueue(true); |
97 } | 94 } |
98 } | 95 } |
99 | 96 |
100 | |
101 EventHandlerImplementation::EventHandlerImplementation() | 97 EventHandlerImplementation::EventHandlerImplementation() |
102 : socket_map_(&HashMap::SamePointerValue, 16) { | 98 : socket_map_(&HashMap::SamePointerValue, 16) { |
103 intptr_t result; | 99 intptr_t result; |
104 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); | 100 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); |
105 if (result != 0) { | 101 if (result != 0) { |
106 FATAL("Pipe creation failed"); | 102 FATAL("Pipe creation failed"); |
107 } | 103 } |
108 if (!FDUtils::SetNonBlocking(interrupt_fds_[0])) { | 104 if (!FDUtils::SetNonBlocking(interrupt_fds_[0])) { |
109 FATAL("Failed to set pipe fd non-blocking\n"); | 105 FATAL("Failed to set pipe fd non-blocking\n"); |
110 } | 106 } |
(...skipping 17 matching lines...) Expand all Loading... |
128 EV_SET(&event, interrupt_fds_[0], EVFILT_READ, EV_ADD, 0, 0, NULL); | 124 EV_SET(&event, interrupt_fds_[0], EVFILT_READ, EV_ADD, 0, 0, NULL); |
129 int status = NO_RETRY_EXPECTED(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL)); | 125 int status = NO_RETRY_EXPECTED(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL)); |
130 if (status == -1) { | 126 if (status == -1) { |
131 const int kBufferSize = 1024; | 127 const int kBufferSize = 1024; |
132 char error_message[kBufferSize]; | 128 char error_message[kBufferSize]; |
133 Utils::StrError(errno, error_message, kBufferSize); | 129 Utils::StrError(errno, error_message, kBufferSize); |
134 FATAL1("Failed adding interrupt fd to kqueue: %s\n", error_message); | 130 FATAL1("Failed adding interrupt fd to kqueue: %s\n", error_message); |
135 } | 131 } |
136 } | 132 } |
137 | 133 |
138 | |
139 static void DeleteDescriptorInfo(void* info) { | 134 static void DeleteDescriptorInfo(void* info) { |
140 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); | 135 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); |
141 di->Close(); | 136 di->Close(); |
142 delete di; | 137 delete di; |
143 } | 138 } |
144 | 139 |
145 | |
146 EventHandlerImplementation::~EventHandlerImplementation() { | 140 EventHandlerImplementation::~EventHandlerImplementation() { |
147 socket_map_.Clear(DeleteDescriptorInfo); | 141 socket_map_.Clear(DeleteDescriptorInfo); |
148 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); | 142 VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_)); |
149 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 143 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
150 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 144 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
151 } | 145 } |
152 | 146 |
153 | |
154 void EventHandlerImplementation::UpdateKQueueInstance(intptr_t old_mask, | 147 void EventHandlerImplementation::UpdateKQueueInstance(intptr_t old_mask, |
155 DescriptorInfo* di) { | 148 DescriptorInfo* di) { |
156 intptr_t new_mask = di->Mask(); | 149 intptr_t new_mask = di->Mask(); |
157 if (old_mask != 0 && new_mask == 0) { | 150 if (old_mask != 0 && new_mask == 0) { |
158 RemoveFromKqueue(kqueue_fd_, di); | 151 RemoveFromKqueue(kqueue_fd_, di); |
159 } else if ((old_mask == 0) && (new_mask != 0)) { | 152 } else if ((old_mask == 0) && (new_mask != 0)) { |
160 AddToKqueue(kqueue_fd_, di); | 153 AddToKqueue(kqueue_fd_, di); |
161 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) { | 154 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) { |
162 ASSERT(!di->IsListeningSocket()); | 155 ASSERT(!di->IsListeningSocket()); |
163 RemoveFromKqueue(kqueue_fd_, di); | 156 RemoveFromKqueue(kqueue_fd_, di); |
164 AddToKqueue(kqueue_fd_, di); | 157 AddToKqueue(kqueue_fd_, di); |
165 } | 158 } |
166 } | 159 } |
167 | 160 |
168 | |
169 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( | 161 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( |
170 intptr_t fd, | 162 intptr_t fd, |
171 bool is_listening) { | 163 bool is_listening) { |
172 ASSERT(fd >= 0); | 164 ASSERT(fd >= 0); |
173 HashMap::Entry* entry = socket_map_.Lookup(GetHashmapKeyFromFd(fd), | 165 HashMap::Entry* entry = socket_map_.Lookup(GetHashmapKeyFromFd(fd), |
174 GetHashmapHashFromFd(fd), true); | 166 GetHashmapHashFromFd(fd), true); |
175 ASSERT(entry != NULL); | 167 ASSERT(entry != NULL); |
176 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); | 168 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); |
177 if (di == NULL) { | 169 if (di == NULL) { |
178 // If there is no data in the hash map for this file descriptor a | 170 // If there is no data in the hash map for this file descriptor a |
179 // new DescriptorInfo for the file descriptor is inserted. | 171 // new DescriptorInfo for the file descriptor is inserted. |
180 if (is_listening) { | 172 if (is_listening) { |
181 di = new DescriptorInfoMultiple(fd); | 173 di = new DescriptorInfoMultiple(fd); |
182 } else { | 174 } else { |
183 di = new DescriptorInfoSingle(fd); | 175 di = new DescriptorInfoSingle(fd); |
184 } | 176 } |
185 entry->value = di; | 177 entry->value = di; |
186 } | 178 } |
187 ASSERT(fd == di->fd()); | 179 ASSERT(fd == di->fd()); |
188 return di; | 180 return di; |
189 } | 181 } |
190 | 182 |
191 | |
192 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 183 void EventHandlerImplementation::WakeupHandler(intptr_t id, |
193 Dart_Port dart_port, | 184 Dart_Port dart_port, |
194 int64_t data) { | 185 int64_t data) { |
195 InterruptMessage msg; | 186 InterruptMessage msg; |
196 msg.id = id; | 187 msg.id = id; |
197 msg.dart_port = dart_port; | 188 msg.dart_port = dart_port; |
198 msg.data = data; | 189 msg.data = data; |
199 // WriteToBlocking will write up to 512 bytes atomically, and since our msg | 190 // WriteToBlocking will write up to 512 bytes atomically, and since our msg |
200 // is smaller than 512, we don't need a thread lock. | 191 // is smaller than 512, we don't need a thread lock. |
201 ASSERT(kInterruptMessageSize < PIPE_BUF); | 192 ASSERT(kInterruptMessageSize < PIPE_BUF); |
202 intptr_t result = | 193 intptr_t result = |
203 FDUtils::WriteToBlocking(interrupt_fds_[1], &msg, kInterruptMessageSize); | 194 FDUtils::WriteToBlocking(interrupt_fds_[1], &msg, kInterruptMessageSize); |
204 if (result != kInterruptMessageSize) { | 195 if (result != kInterruptMessageSize) { |
205 if (result == -1) { | 196 if (result == -1) { |
206 perror("Interrupt message failure:"); | 197 perror("Interrupt message failure:"); |
207 } | 198 } |
208 FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result); | 199 FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result); |
209 } | 200 } |
210 } | 201 } |
211 | 202 |
212 | |
213 void EventHandlerImplementation::HandleInterruptFd() { | 203 void EventHandlerImplementation::HandleInterruptFd() { |
214 const intptr_t MAX_MESSAGES = kInterruptMessageSize; | 204 const intptr_t MAX_MESSAGES = kInterruptMessageSize; |
215 InterruptMessage msg[MAX_MESSAGES]; | 205 InterruptMessage msg[MAX_MESSAGES]; |
216 ssize_t bytes = TEMP_FAILURE_RETRY( | 206 ssize_t bytes = TEMP_FAILURE_RETRY( |
217 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); | 207 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); |
218 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { | 208 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { |
219 if (msg[i].id == kTimerId) { | 209 if (msg[i].id == kTimerId) { |
220 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); | 210 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); |
221 } else if (msg[i].id == kShutdownId) { | 211 } else if (msg[i].id == kShutdownId) { |
222 shutdown_ = true; | 212 shutdown_ = true; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 intptr_t old_mask = di->Mask(); | 275 intptr_t old_mask = di->Mask(); |
286 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); | 276 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); |
287 UpdateKQueueInstance(old_mask, di); | 277 UpdateKQueueInstance(old_mask, di); |
288 } else { | 278 } else { |
289 UNREACHABLE(); | 279 UNREACHABLE(); |
290 } | 280 } |
291 } | 281 } |
292 } | 282 } |
293 } | 283 } |
294 | 284 |
295 | |
296 #ifdef DEBUG_KQUEUE | 285 #ifdef DEBUG_KQUEUE |
297 static void PrintEventMask(intptr_t fd, struct kevent* event) { | 286 static void PrintEventMask(intptr_t fd, struct kevent* event) { |
298 Log::Print("%d ", static_cast<int>(fd)); | 287 Log::Print("%d ", static_cast<int>(fd)); |
299 | 288 |
300 Log::Print("filter=0x%x:", event->filter); | 289 Log::Print("filter=0x%x:", event->filter); |
301 if (event->filter == EVFILT_READ) { | 290 if (event->filter == EVFILT_READ) { |
302 Log::Print("EVFILT_READ "); | 291 Log::Print("EVFILT_READ "); |
303 } | 292 } |
304 if (event->filter == EVFILT_WRITE) { | 293 if (event->filter == EVFILT_WRITE) { |
305 Log::Print("EVFILT_WRITE "); | 294 Log::Print("EVFILT_WRITE "); |
(...skipping 16 matching lines...) Expand all Loading... |
322 Log::Print("EV_DELETE "); | 311 Log::Print("EV_DELETE "); |
323 } | 312 } |
324 | 313 |
325 Log::Print("- fflags: %d ", event->fflags); | 314 Log::Print("- fflags: %d ", event->fflags); |
326 Log::Print("- data: %ld ", event->data); | 315 Log::Print("- data: %ld ", event->data); |
327 Log::Print("(available %d) ", static_cast<int>(FDUtils::AvailableBytes(fd))); | 316 Log::Print("(available %d) ", static_cast<int>(FDUtils::AvailableBytes(fd))); |
328 Log::Print("\n"); | 317 Log::Print("\n"); |
329 } | 318 } |
330 #endif | 319 #endif |
331 | 320 |
332 | |
333 intptr_t EventHandlerImplementation::GetEvents(struct kevent* event, | 321 intptr_t EventHandlerImplementation::GetEvents(struct kevent* event, |
334 DescriptorInfo* di) { | 322 DescriptorInfo* di) { |
335 #ifdef DEBUG_KQUEUE | 323 #ifdef DEBUG_KQUEUE |
336 PrintEventMask(di->fd(), event); | 324 PrintEventMask(di->fd(), event); |
337 #endif | 325 #endif |
338 intptr_t event_mask = 0; | 326 intptr_t event_mask = 0; |
339 if (di->IsListeningSocket()) { | 327 if (di->IsListeningSocket()) { |
340 // On a listening socket the READ event means that there are | 328 // On a listening socket the READ event means that there are |
341 // connections ready to be accepted. | 329 // connections ready to be accepted. |
342 if (event->filter == EVFILT_READ) { | 330 if (event->filter == EVFILT_READ) { |
(...skipping 29 matching lines...) Expand all Loading... |
372 } | 360 } |
373 } | 361 } |
374 } else { | 362 } else { |
375 UNREACHABLE(); | 363 UNREACHABLE(); |
376 } | 364 } |
377 } | 365 } |
378 | 366 |
379 return event_mask; | 367 return event_mask; |
380 } | 368 } |
381 | 369 |
382 | |
383 void EventHandlerImplementation::HandleEvents(struct kevent* events, int size) { | 370 void EventHandlerImplementation::HandleEvents(struct kevent* events, int size) { |
384 bool interrupt_seen = false; | 371 bool interrupt_seen = false; |
385 for (int i = 0; i < size; i++) { | 372 for (int i = 0; i < size; i++) { |
386 // If flag EV_ERROR is set it indicates an error in kevent processing. | 373 // If flag EV_ERROR is set it indicates an error in kevent processing. |
387 if ((events[i].flags & EV_ERROR) != 0) { | 374 if ((events[i].flags & EV_ERROR) != 0) { |
388 const int kBufferSize = 1024; | 375 const int kBufferSize = 1024; |
389 char error_message[kBufferSize]; | 376 char error_message[kBufferSize]; |
390 Utils::StrError(events[i].data, error_message, kBufferSize); | 377 Utils::StrError(events[i].data, error_message, kBufferSize); |
391 FATAL1("kevent failed %s\n", error_message); | 378 FATAL1("kevent failed %s\n", error_message); |
392 } | 379 } |
(...skipping 14 matching lines...) Expand all Loading... |
407 } | 394 } |
408 } | 395 } |
409 } | 396 } |
410 if (interrupt_seen) { | 397 if (interrupt_seen) { |
411 // Handle after socket events, so we avoid closing a socket before we handle | 398 // Handle after socket events, so we avoid closing a socket before we handle |
412 // the current events. | 399 // the current events. |
413 HandleInterruptFd(); | 400 HandleInterruptFd(); |
414 } | 401 } |
415 } | 402 } |
416 | 403 |
417 | |
418 int64_t EventHandlerImplementation::GetTimeout() { | 404 int64_t EventHandlerImplementation::GetTimeout() { |
419 if (!timeout_queue_.HasTimeout()) { | 405 if (!timeout_queue_.HasTimeout()) { |
420 return kInfinityTimeout; | 406 return kInfinityTimeout; |
421 } | 407 } |
422 int64_t millis = | 408 int64_t millis = |
423 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); | 409 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); |
424 return (millis < 0) ? 0 : millis; | 410 return (millis < 0) ? 0 : millis; |
425 } | 411 } |
426 | 412 |
427 | |
428 void EventHandlerImplementation::HandleTimeout() { | 413 void EventHandlerImplementation::HandleTimeout() { |
429 if (timeout_queue_.HasTimeout()) { | 414 if (timeout_queue_.HasTimeout()) { |
430 int64_t millis = timeout_queue_.CurrentTimeout() - | 415 int64_t millis = timeout_queue_.CurrentTimeout() - |
431 TimerUtils::GetCurrentMonotonicMillis(); | 416 TimerUtils::GetCurrentMonotonicMillis(); |
432 if (millis <= 0) { | 417 if (millis <= 0) { |
433 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 418 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
434 timeout_queue_.RemoveCurrent(); | 419 timeout_queue_.RemoveCurrent(); |
435 } | 420 } |
436 } | 421 } |
437 } | 422 } |
438 | 423 |
439 | |
440 void EventHandlerImplementation::EventHandlerEntry(uword args) { | 424 void EventHandlerImplementation::EventHandlerEntry(uword args) { |
441 static const intptr_t kMaxEvents = 16; | 425 static const intptr_t kMaxEvents = 16; |
442 struct kevent events[kMaxEvents]; | 426 struct kevent events[kMaxEvents]; |
443 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 427 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
444 EventHandlerImplementation* handler_impl = &handler->delegate_; | 428 EventHandlerImplementation* handler_impl = &handler->delegate_; |
445 ASSERT(handler_impl != NULL); | 429 ASSERT(handler_impl != NULL); |
446 | 430 |
447 while (!handler_impl->shutdown_) { | 431 while (!handler_impl->shutdown_) { |
448 int64_t millis = handler_impl->GetTimeout(); | 432 int64_t millis = handler_impl->GetTimeout(); |
449 ASSERT(millis == kInfinityTimeout || millis >= 0); | 433 ASSERT(millis == kInfinityTimeout || millis >= 0); |
(...skipping 22 matching lines...) Expand all Loading... |
472 FATAL1("kevent failed %s\n", error_message); | 456 FATAL1("kevent failed %s\n", error_message); |
473 } else { | 457 } else { |
474 handler_impl->HandleTimeout(); | 458 handler_impl->HandleTimeout(); |
475 handler_impl->HandleEvents(events, result); | 459 handler_impl->HandleEvents(events, result); |
476 } | 460 } |
477 } | 461 } |
478 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); | 462 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); |
479 handler->NotifyShutdownDone(); | 463 handler->NotifyShutdownDone(); |
480 } | 464 } |
481 | 465 |
482 | |
483 void EventHandlerImplementation::Start(EventHandler* handler) { | 466 void EventHandlerImplementation::Start(EventHandler* handler) { |
484 int result = Thread::Start(&EventHandlerImplementation::EventHandlerEntry, | 467 int result = Thread::Start(&EventHandlerImplementation::EventHandlerEntry, |
485 reinterpret_cast<uword>(handler)); | 468 reinterpret_cast<uword>(handler)); |
486 if (result != 0) { | 469 if (result != 0) { |
487 FATAL1("Failed to start event handler thread %d", result); | 470 FATAL1("Failed to start event handler thread %d", result); |
488 } | 471 } |
489 } | 472 } |
490 | 473 |
491 | |
492 void EventHandlerImplementation::Shutdown() { | 474 void EventHandlerImplementation::Shutdown() { |
493 SendData(kShutdownId, 0, 0); | 475 SendData(kShutdownId, 0, 0); |
494 } | 476 } |
495 | 477 |
496 | |
497 void EventHandlerImplementation::SendData(intptr_t id, | 478 void EventHandlerImplementation::SendData(intptr_t id, |
498 Dart_Port dart_port, | 479 Dart_Port dart_port, |
499 int64_t data) { | 480 int64_t data) { |
500 WakeupHandler(id, dart_port, data); | 481 WakeupHandler(id, dart_port, data); |
501 } | 482 } |
502 | 483 |
503 | |
504 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { | 484 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { |
505 // The hashmap does not support keys with value 0. | 485 // The hashmap does not support keys with value 0. |
506 return reinterpret_cast<void*>(fd + 1); | 486 return reinterpret_cast<void*>(fd + 1); |
507 } | 487 } |
508 | 488 |
509 | |
510 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 489 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
511 // The hashmap does not support keys with value 0. | 490 // The hashmap does not support keys with value 0. |
512 return dart::Utils::WordHash(fd + 1); | 491 return dart::Utils::WordHash(fd + 1); |
513 } | 492 } |
514 | 493 |
515 } // namespace bin | 494 } // namespace bin |
516 } // namespace dart | 495 } // namespace dart |
517 | 496 |
518 #endif // defined(HOST_OS_MACOS) | 497 #endif // defined(HOST_OS_MACOS) |
519 | 498 |
520 #endif // !defined(DART_IO_DISABLED) | 499 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |