Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Side by Side Diff: runtime/bin/eventhandler_macos.cc

Issue 908183002: Implement mac support for having multiple Dart_Port's registered on one OS socket (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/eventhandler_macos.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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)
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_macos.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698