Chromium Code Reviews| 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(TARGET_OS_MACOS) | 8 #if defined(TARGET_OS_MACOS) |
| 9 | 9 |
| 10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 } | 36 } |
| 37 | 37 |
| 38 | 38 |
| 39 bool DescriptorInfo::HasWriteEvent() { | 39 bool DescriptorInfo::HasWriteEvent() { |
| 40 return (Mask() & (1 << kOutEvent)) != 0; | 40 return (Mask() & (1 << kOutEvent)) != 0; |
| 41 } | 41 } |
| 42 | 42 |
| 43 | 43 |
| 44 // Unregister the file descriptor for a SocketData structure with kqueue. | 44 // Unregister the file descriptor for a SocketData structure with kqueue. |
| 45 static void RemoveFromKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { | 45 static void RemoveFromKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { |
| 46 if (!di->tracked_by_kqueue()) { | |
| 47 return; | |
| 48 } | |
| 49 static const intptr_t kMaxChanges = 2; | 46 static const intptr_t kMaxChanges = 2; |
| 50 struct kevent events[kMaxChanges]; | 47 struct kevent events[kMaxChanges]; |
|
kustermann
2017/01/20 12:22:49
Unrelated side note:
Seems like legacy code: We o
zra
2017/01/20 17:16:32
Maybe in another CL. We should try the bug fix in
| |
| 51 EV_SET(events, di->fd(), EVFILT_READ, EV_DELETE, 0, 0, NULL); | 48 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)); | 49 VOID_NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, 1, NULL, 0, NULL)); |
|
kustermann
2017/01/20 12:22:49
Unrelated side note:
We should probably check th
zra
2017/01/20 17:16:32
ditto
| |
| 53 EV_SET(events, di->fd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL); | 50 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)); | 51 VOID_NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, 1, NULL, 0, NULL)); |
|
kustermann
2017/01/20 12:22:49
Unrelated side note:
As opposed to the adding co
zra
2017/01/20 17:16:32
ditto
| |
| 55 di->set_tracked_by_kqueue(false); | |
| 56 } | 52 } |
| 57 | 53 |
| 58 | 54 |
| 59 // Update the kqueue registration for SocketData structure to reflect | 55 // Update the kqueue registration for SocketData structure to reflect |
| 60 // the events currently of interest. | 56 // the events currently of interest. |
| 61 static void AddToKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { | 57 static void AddToKqueue(intptr_t kqueue_fd_, DescriptorInfo* di) { |
| 62 ASSERT(!di->tracked_by_kqueue()); | |
|
kustermann
2017/01/20 12:22:49
I cannot think of a case where this ASSERT should
| |
| 63 static const intptr_t kMaxChanges = 2; | 58 static const intptr_t kMaxChanges = 2; |
| 64 intptr_t changes = 0; | 59 intptr_t changes = 0; |
| 65 struct kevent events[kMaxChanges]; | 60 struct kevent events[kMaxChanges]; |
| 66 int flags = EV_ADD; | 61 int flags = EV_ADD; |
| 67 if (!di->IsListeningSocket()) { | 62 if (!di->IsListeningSocket()) { |
| 68 flags |= EV_CLEAR; | 63 flags |= EV_CLEAR; |
| 69 } | 64 } |
| 70 | 65 |
| 71 ASSERT(di->HasReadEvent() || di->HasWriteEvent()); | 66 ASSERT(di->HasReadEvent() || di->HasWriteEvent()); |
| 72 | 67 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 85 int status = | 80 int status = |
| 86 NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); | 81 NO_RETRY_EXPECTED(kevent(kqueue_fd_, events, changes, NULL, 0, NULL)); |
| 87 if (status == -1) { | 82 if (status == -1) { |
| 88 // TODO(dart:io): Verify that the dart end is handling this correctly. | 83 // TODO(dart:io): Verify that the dart end is handling this correctly. |
| 89 | 84 |
| 90 // kQueue does not accept the file descriptor. It could be due to | 85 // kQueue does not accept the file descriptor. It could be due to |
| 91 // already closed file descriptor, or unuspported devices, such | 86 // already closed file descriptor, or unuspported devices, such |
| 92 // as /dev/null. In such case, mark the file descriptor as closed, | 87 // as /dev/null. In such case, mark the file descriptor as closed, |
| 93 // so dart will handle it accordingly. | 88 // so dart will handle it accordingly. |
| 94 di->NotifyAllDartPorts(1 << kCloseEvent); | 89 di->NotifyAllDartPorts(1 << kCloseEvent); |
| 95 } else { | |
| 96 di->set_tracked_by_kqueue(true); | |
| 97 } | 90 } |
| 98 } | 91 } |
| 99 | 92 |
| 100 | 93 |
| 101 EventHandlerImplementation::EventHandlerImplementation() | 94 EventHandlerImplementation::EventHandlerImplementation() |
| 102 : socket_map_(&HashMap::SamePointerValue, 16) { | 95 : socket_map_(&HashMap::SamePointerValue, 16) { |
| 103 intptr_t result; | 96 intptr_t result; |
| 104 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); | 97 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); |
| 105 if (result != 0) { | 98 if (result != 0) { |
| 106 FATAL("Pipe creation failed"); | 99 FATAL("Pipe creation failed"); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 | 146 |
| 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 // kevent() will automatically replace the old filter for an existing fd. |
| 157 // There is no need to remove it first. | |
| 164 AddToKqueue(kqueue_fd_, di); | 158 AddToKqueue(kqueue_fd_, di); |
|
kustermann
2017/01/20 12:22:49
This is an incorrect change if I understand it pro
zra
2017/01/20 17:16:32
Acknowledged.
| |
| 165 } | 159 } |
| 166 } | 160 } |
| 167 | 161 |
| 168 | 162 |
| 169 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( | 163 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( |
| 170 intptr_t fd, | 164 intptr_t fd, |
| 171 bool is_listening) { | 165 bool is_listening) { |
| 172 ASSERT(fd >= 0); | 166 ASSERT(fd >= 0); |
| 173 HashMap::Entry* entry = socket_map_.Lookup(GetHashmapKeyFromFd(fd), | 167 HashMap::Entry* entry = socket_map_.Lookup(GetHashmapKeyFromFd(fd), |
| 174 GetHashmapHashFromFd(fd), true); | 168 GetHashmapHashFromFd(fd), true); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 381 if ((events[i].flags & EV_ERROR) != 0) { | 375 if ((events[i].flags & EV_ERROR) != 0) { |
| 382 const int kBufferSize = 1024; | 376 const int kBufferSize = 1024; |
| 383 char error_message[kBufferSize]; | 377 char error_message[kBufferSize]; |
| 384 Utils::StrError(events[i].data, error_message, kBufferSize); | 378 Utils::StrError(events[i].data, error_message, kBufferSize); |
| 385 FATAL1("kevent failed %s\n", error_message); | 379 FATAL1("kevent failed %s\n", error_message); |
| 386 } | 380 } |
| 387 if (events[i].udata == NULL) { | 381 if (events[i].udata == NULL) { |
| 388 interrupt_seen = true; | 382 interrupt_seen = true; |
| 389 } else { | 383 } else { |
| 390 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(events[i].udata); | 384 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(events[i].udata); |
| 391 intptr_t event_mask = GetEvents(events + i, di); | 385 intptr_t event_mask = GetEvents(events + i, di); |
|
kustermann
2017/01/20 12:22:49
Unrelated side note:
Suggestion: We could traver
| |
| 392 if ((event_mask & (1 << kErrorEvent)) != 0) { | 386 if ((event_mask & (1 << kErrorEvent)) != 0) { |
| 393 di->NotifyAllDartPorts(event_mask); | 387 di->NotifyAllDartPorts(event_mask); |
| 394 } | 388 } |
| 395 event_mask &= ~(1 << kErrorEvent); | 389 event_mask &= ~(1 << kErrorEvent); |
| 396 | 390 |
| 397 if (event_mask != 0) { | 391 if (event_mask != 0) { |
| 398 intptr_t old_mask = di->Mask(); | 392 intptr_t old_mask = di->Mask(); |
|
zra
2017/01/20 15:54:30
I'm pretty sure the problem is here.
If the event
kustermann
2017/01/23 11:49:34
Very good point.
| |
| 399 Dart_Port port = di->NextNotifyDartPort(event_mask); | 393 Dart_Port port = di->NextNotifyDartPort(event_mask); |
| 400 ASSERT(port != 0); | 394 ASSERT(port != 0); |
| 401 UpdateKQueueInstance(old_mask, di); | 395 UpdateKQueueInstance(old_mask, di); |
| 402 DartUtils::PostInt32(port, event_mask); | 396 DartUtils::PostInt32(port, event_mask); |
| 403 } | 397 } |
| 404 } | 398 } |
| 405 } | 399 } |
| 406 if (interrupt_seen) { | 400 if (interrupt_seen) { |
| 407 // Handle after socket events, so we avoid closing a socket before we handle | 401 // Handle after socket events, so we avoid closing a socket before we handle |
| 408 // the current events. | 402 // the current events. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 // The hashmap does not support keys with value 0. | 500 // The hashmap does not support keys with value 0. |
| 507 return dart::Utils::WordHash(fd + 1); | 501 return dart::Utils::WordHash(fd + 1); |
| 508 } | 502 } |
| 509 | 503 |
| 510 } // namespace bin | 504 } // namespace bin |
| 511 } // namespace dart | 505 } // namespace dart |
| 512 | 506 |
| 513 #endif // defined(TARGET_OS_MACOS) | 507 #endif // defined(TARGET_OS_MACOS) |
| 514 | 508 |
| 515 #endif // !defined(DART_IO_DISABLED) | 509 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |