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_ANDROID) | 8 #if defined(HOST_OS_ANDROID) |
9 | 9 |
10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
11 #include "bin/eventhandler_android.h" | 11 #include "bin/eventhandler_android.h" |
12 | 12 |
13 #include <errno.h> // NOLINT | 13 #include <errno.h> // NOLINT |
14 #include <fcntl.h> // NOLINT | 14 #include <fcntl.h> // NOLINT |
15 #include <pthread.h> // NOLINT | 15 #include <pthread.h> // NOLINT |
16 #include <stdio.h> // NOLINT | 16 #include <stdio.h> // NOLINT |
17 #include <string.h> // NOLINT | 17 #include <string.h> // NOLINT |
18 #include <sys/epoll.h> // NOLINT | 18 #include <sys/epoll.h> // NOLINT |
19 #include <sys/stat.h> // NOLINT | 19 #include <sys/stat.h> // NOLINT |
20 #include <unistd.h> // NOLINT | 20 #include <unistd.h> // NOLINT |
21 | 21 |
22 #include "bin/dartutils.h" | 22 #include "bin/dartutils.h" |
23 #include "bin/fdutils.h" | 23 #include "bin/fdutils.h" |
| 24 #include "bin/lockers.h" |
24 #include "bin/log.h" | 25 #include "bin/log.h" |
25 #include "bin/lockers.h" | |
26 #include "bin/socket.h" | 26 #include "bin/socket.h" |
27 #include "bin/thread.h" | 27 #include "bin/thread.h" |
28 #include "bin/utils.h" | 28 #include "bin/utils.h" |
29 #include "platform/hashmap.h" | 29 #include "platform/hashmap.h" |
30 #include "platform/utils.h" | 30 #include "platform/utils.h" |
31 | 31 |
32 // Android doesn't define EPOLLRDHUP. | 32 // Android doesn't define EPOLLRDHUP. |
33 #if !defined(EPOLLRDHUP) | 33 #if !defined(EPOLLRDHUP) |
34 #define EPOLLRDHUP 0x2000 | 34 #define EPOLLRDHUP 0x2000 |
35 #endif // !defined(EPOLLRDHUP) | 35 #endif // !defined(EPOLLRDHUP) |
36 | 36 |
37 namespace dart { | 37 namespace dart { |
38 namespace bin { | 38 namespace bin { |
39 | 39 |
40 intptr_t DescriptorInfo::GetPollEvents() { | 40 intptr_t DescriptorInfo::GetPollEvents() { |
41 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are | 41 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are |
42 // triggered anyway. | 42 // triggered anyway. |
43 intptr_t events = 0; | 43 intptr_t events = 0; |
44 if ((Mask() & (1 << kInEvent)) != 0) { | 44 if ((Mask() & (1 << kInEvent)) != 0) { |
45 events |= EPOLLIN; | 45 events |= EPOLLIN; |
46 } | 46 } |
47 if ((Mask() & (1 << kOutEvent)) != 0) { | 47 if ((Mask() & (1 << kOutEvent)) != 0) { |
48 events |= EPOLLOUT; | 48 events |= EPOLLOUT; |
49 } | 49 } |
50 return events; | 50 return events; |
51 } | 51 } |
52 | 52 |
53 | |
54 // Unregister the file descriptor for a DescriptorInfo structure with | 53 // Unregister the file descriptor for a DescriptorInfo structure with |
55 // epoll. | 54 // epoll. |
56 static void RemoveFromEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { | 55 static void RemoveFromEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { |
57 VOID_NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, di->fd(), NULL)); | 56 VOID_NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, di->fd(), NULL)); |
58 } | 57 } |
59 | 58 |
60 | |
61 static void AddToEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { | 59 static void AddToEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { |
62 struct epoll_event event; | 60 struct epoll_event event; |
63 event.events = EPOLLRDHUP | di->GetPollEvents(); | 61 event.events = EPOLLRDHUP | di->GetPollEvents(); |
64 if (!di->IsListeningSocket()) { | 62 if (!di->IsListeningSocket()) { |
65 event.events |= EPOLLET; | 63 event.events |= EPOLLET; |
66 } | 64 } |
67 event.data.ptr = di; | 65 event.data.ptr = di; |
68 int status = | 66 int status = |
69 NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, di->fd(), &event)); | 67 NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, di->fd(), &event)); |
70 if (status == -1) { | 68 if (status == -1) { |
71 // TODO(dart:io): Verify that the dart end is handling this correctly. | 69 // TODO(dart:io): Verify that the dart end is handling this correctly. |
72 | 70 |
73 // Epoll does not accept the file descriptor. It could be due to | 71 // Epoll does not accept the file descriptor. It could be due to |
74 // already closed file descriptor, or unuspported devices, such | 72 // already closed file descriptor, or unuspported devices, such |
75 // as /dev/null. In such case, mark the file descriptor as closed, | 73 // as /dev/null. In such case, mark the file descriptor as closed, |
76 // so dart will handle it accordingly. | 74 // so dart will handle it accordingly. |
77 di->NotifyAllDartPorts(1 << kCloseEvent); | 75 di->NotifyAllDartPorts(1 << kCloseEvent); |
78 } | 76 } |
79 } | 77 } |
80 | 78 |
81 | |
82 EventHandlerImplementation::EventHandlerImplementation() | 79 EventHandlerImplementation::EventHandlerImplementation() |
83 : socket_map_(&HashMap::SamePointerValue, 16) { | 80 : socket_map_(&HashMap::SamePointerValue, 16) { |
84 intptr_t result; | 81 intptr_t result; |
85 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); | 82 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); |
86 if (result != 0) { | 83 if (result != 0) { |
87 FATAL("Pipe creation failed"); | 84 FATAL("Pipe creation failed"); |
88 } | 85 } |
89 if (!FDUtils::SetNonBlocking(interrupt_fds_[0])) { | 86 if (!FDUtils::SetNonBlocking(interrupt_fds_[0])) { |
90 FATAL("Failed to set pipe fd non blocking\n"); | 87 FATAL("Failed to set pipe fd non blocking\n"); |
91 } | 88 } |
(...skipping 18 matching lines...) Expand all Loading... |
110 struct epoll_event event; | 107 struct epoll_event event; |
111 event.events = EPOLLIN; | 108 event.events = EPOLLIN; |
112 event.data.ptr = NULL; | 109 event.data.ptr = NULL; |
113 int status = NO_RETRY_EXPECTED( | 110 int status = NO_RETRY_EXPECTED( |
114 epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupt_fds_[0], &event)); | 111 epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupt_fds_[0], &event)); |
115 if (status == -1) { | 112 if (status == -1) { |
116 FATAL("Failed adding interrupt fd to epoll instance"); | 113 FATAL("Failed adding interrupt fd to epoll instance"); |
117 } | 114 } |
118 } | 115 } |
119 | 116 |
120 | |
121 static void DeleteDescriptorInfo(void* info) { | 117 static void DeleteDescriptorInfo(void* info) { |
122 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); | 118 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); |
123 di->Close(); | 119 di->Close(); |
124 delete di; | 120 delete di; |
125 } | 121 } |
126 | 122 |
127 | |
128 EventHandlerImplementation::~EventHandlerImplementation() { | 123 EventHandlerImplementation::~EventHandlerImplementation() { |
129 socket_map_.Clear(DeleteDescriptorInfo); | 124 socket_map_.Clear(DeleteDescriptorInfo); |
130 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_)); | 125 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_)); |
131 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 126 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
132 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 127 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
133 } | 128 } |
134 | 129 |
135 | |
136 void EventHandlerImplementation::UpdateEpollInstance(intptr_t old_mask, | 130 void EventHandlerImplementation::UpdateEpollInstance(intptr_t old_mask, |
137 DescriptorInfo* di) { | 131 DescriptorInfo* di) { |
138 intptr_t new_mask = di->Mask(); | 132 intptr_t new_mask = di->Mask(); |
139 if ((old_mask != 0) && (new_mask == 0)) { | 133 if ((old_mask != 0) && (new_mask == 0)) { |
140 RemoveFromEpollInstance(epoll_fd_, di); | 134 RemoveFromEpollInstance(epoll_fd_, di); |
141 } else if ((old_mask == 0) && (new_mask != 0)) { | 135 } else if ((old_mask == 0) && (new_mask != 0)) { |
142 AddToEpollInstance(epoll_fd_, di); | 136 AddToEpollInstance(epoll_fd_, di); |
143 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) { | 137 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) { |
144 ASSERT(!di->IsListeningSocket()); | 138 ASSERT(!di->IsListeningSocket()); |
145 RemoveFromEpollInstance(epoll_fd_, di); | 139 RemoveFromEpollInstance(epoll_fd_, di); |
146 AddToEpollInstance(epoll_fd_, di); | 140 AddToEpollInstance(epoll_fd_, di); |
147 } | 141 } |
148 } | 142 } |
149 | 143 |
150 | |
151 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( | 144 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( |
152 intptr_t fd, | 145 intptr_t fd, |
153 bool is_listening) { | 146 bool is_listening) { |
154 ASSERT(fd >= 0); | 147 ASSERT(fd >= 0); |
155 HashMap::Entry* entry = socket_map_.Lookup(GetHashmapKeyFromFd(fd), | 148 HashMap::Entry* entry = socket_map_.Lookup(GetHashmapKeyFromFd(fd), |
156 GetHashmapHashFromFd(fd), true); | 149 GetHashmapHashFromFd(fd), true); |
157 ASSERT(entry != NULL); | 150 ASSERT(entry != NULL); |
158 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); | 151 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); |
159 if (di == NULL) { | 152 if (di == NULL) { |
160 // If there is no data in the hash map for this file descriptor a | 153 // If there is no data in the hash map for this file descriptor a |
161 // new DescriptorInfo for the file descriptor is inserted. | 154 // new DescriptorInfo for the file descriptor is inserted. |
162 if (is_listening) { | 155 if (is_listening) { |
163 di = new DescriptorInfoMultiple(fd); | 156 di = new DescriptorInfoMultiple(fd); |
164 } else { | 157 } else { |
165 di = new DescriptorInfoSingle(fd); | 158 di = new DescriptorInfoSingle(fd); |
166 } | 159 } |
167 entry->value = di; | 160 entry->value = di; |
168 } | 161 } |
169 ASSERT(fd == di->fd()); | 162 ASSERT(fd == di->fd()); |
170 return di; | 163 return di; |
171 } | 164 } |
172 | 165 |
173 | |
174 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 166 void EventHandlerImplementation::WakeupHandler(intptr_t id, |
175 Dart_Port dart_port, | 167 Dart_Port dart_port, |
176 int64_t data) { | 168 int64_t data) { |
177 InterruptMessage msg; | 169 InterruptMessage msg; |
178 msg.id = id; | 170 msg.id = id; |
179 msg.dart_port = dart_port; | 171 msg.dart_port = dart_port; |
180 msg.data = data; | 172 msg.data = data; |
181 // WriteToBlocking will write up to 512 bytes atomically, and since our msg | 173 // WriteToBlocking will write up to 512 bytes atomically, and since our msg |
182 // is smaller than 512, we don't need a thread lock. | 174 // is smaller than 512, we don't need a thread lock. |
183 // See: http://linux.die.net/man/7/pipe, section 'Pipe_buf'. | 175 // See: http://linux.die.net/man/7/pipe, section 'Pipe_buf'. |
184 ASSERT(kInterruptMessageSize < PIPE_BUF); | 176 ASSERT(kInterruptMessageSize < PIPE_BUF); |
185 intptr_t result = | 177 intptr_t result = |
186 FDUtils::WriteToBlocking(interrupt_fds_[1], &msg, kInterruptMessageSize); | 178 FDUtils::WriteToBlocking(interrupt_fds_[1], &msg, kInterruptMessageSize); |
187 if (result != kInterruptMessageSize) { | 179 if (result != kInterruptMessageSize) { |
188 if (result == -1) { | 180 if (result == -1) { |
189 perror("Interrupt message failure:"); | 181 perror("Interrupt message failure:"); |
190 } | 182 } |
191 FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result); | 183 FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result); |
192 } | 184 } |
193 } | 185 } |
194 | 186 |
195 | |
196 void EventHandlerImplementation::HandleInterruptFd() { | 187 void EventHandlerImplementation::HandleInterruptFd() { |
197 const intptr_t MAX_MESSAGES = kInterruptMessageSize; | 188 const intptr_t MAX_MESSAGES = kInterruptMessageSize; |
198 InterruptMessage msg[MAX_MESSAGES]; | 189 InterruptMessage msg[MAX_MESSAGES]; |
199 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( | 190 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( |
200 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); | 191 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); |
201 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { | 192 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { |
202 if (msg[i].id == kTimerId) { | 193 if (msg[i].id == kTimerId) { |
203 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); | 194 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); |
204 } else if (msg[i].id == kShutdownId) { | 195 } else if (msg[i].id == kShutdownId) { |
205 shutdown_ = true; | 196 shutdown_ = true; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 intptr_t old_mask = di->Mask(); | 260 intptr_t old_mask = di->Mask(); |
270 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); | 261 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); |
271 UpdateEpollInstance(old_mask, di); | 262 UpdateEpollInstance(old_mask, di); |
272 } else { | 263 } else { |
273 UNREACHABLE(); | 264 UNREACHABLE(); |
274 } | 265 } |
275 } | 266 } |
276 } | 267 } |
277 } | 268 } |
278 | 269 |
279 | |
280 #ifdef DEBUG_POLL | 270 #ifdef DEBUG_POLL |
281 static void PrintEventMask(intptr_t fd, intptr_t events) { | 271 static void PrintEventMask(intptr_t fd, intptr_t events) { |
282 Log::Print("%d ", fd); | 272 Log::Print("%d ", fd); |
283 if ((events & EPOLLIN) != 0) { | 273 if ((events & EPOLLIN) != 0) { |
284 Log::Print("EPOLLIN "); | 274 Log::Print("EPOLLIN "); |
285 } | 275 } |
286 if ((events & EPOLLPRI) != 0) { | 276 if ((events & EPOLLPRI) != 0) { |
287 Log::Print("EPOLLPRI "); | 277 Log::Print("EPOLLPRI "); |
288 } | 278 } |
289 if ((events & EPOLLOUT) != 0) { | 279 if ((events & EPOLLOUT) != 0) { |
(...skipping 12 matching lines...) Expand all Loading... |
302 EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDHUP; | 292 EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDHUP; |
303 if ((events & ~all_events) != 0) { | 293 if ((events & ~all_events) != 0) { |
304 Log::Print("(and %08x) ", events & ~all_events); | 294 Log::Print("(and %08x) ", events & ~all_events); |
305 } | 295 } |
306 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd)); | 296 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd)); |
307 | 297 |
308 Log::Print("\n"); | 298 Log::Print("\n"); |
309 } | 299 } |
310 #endif | 300 #endif |
311 | 301 |
312 | |
313 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events, | 302 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events, |
314 DescriptorInfo* di) { | 303 DescriptorInfo* di) { |
315 #ifdef DEBUG_POLL | 304 #ifdef DEBUG_POLL |
316 PrintEventMask(di->fd(), events); | 305 PrintEventMask(di->fd(), events); |
317 #endif | 306 #endif |
318 if ((events & EPOLLERR) != 0) { | 307 if ((events & EPOLLERR) != 0) { |
319 // Return error only if EPOLLIN is present. | 308 // Return error only if EPOLLIN is present. |
320 return ((events & EPOLLIN) != 0) ? (1 << kErrorEvent) : 0; | 309 return ((events & EPOLLIN) != 0) ? (1 << kErrorEvent) : 0; |
321 } | 310 } |
322 intptr_t event_mask = 0; | 311 intptr_t event_mask = 0; |
323 if ((events & EPOLLIN) != 0) { | 312 if ((events & EPOLLIN) != 0) { |
324 event_mask |= (1 << kInEvent); | 313 event_mask |= (1 << kInEvent); |
325 } | 314 } |
326 if ((events & EPOLLOUT) != 0) { | 315 if ((events & EPOLLOUT) != 0) { |
327 event_mask |= (1 << kOutEvent); | 316 event_mask |= (1 << kOutEvent); |
328 } | 317 } |
329 if ((events & (EPOLLHUP | EPOLLRDHUP)) != 0) { | 318 if ((events & (EPOLLHUP | EPOLLRDHUP)) != 0) { |
330 event_mask |= (1 << kCloseEvent); | 319 event_mask |= (1 << kCloseEvent); |
331 } | 320 } |
332 return event_mask; | 321 return event_mask; |
333 } | 322 } |
334 | 323 |
335 | |
336 void EventHandlerImplementation::HandleEvents(struct epoll_event* events, | 324 void EventHandlerImplementation::HandleEvents(struct epoll_event* events, |
337 int size) { | 325 int size) { |
338 bool interrupt_seen = false; | 326 bool interrupt_seen = false; |
339 for (int i = 0; i < size; i++) { | 327 for (int i = 0; i < size; i++) { |
340 if (events[i].data.ptr == NULL) { | 328 if (events[i].data.ptr == NULL) { |
341 interrupt_seen = true; | 329 interrupt_seen = true; |
342 } else { | 330 } else { |
343 DescriptorInfo* di = | 331 DescriptorInfo* di = |
344 reinterpret_cast<DescriptorInfo*>(events[i].data.ptr); | 332 reinterpret_cast<DescriptorInfo*>(events[i].data.ptr); |
345 const intptr_t old_mask = di->Mask(); | 333 const intptr_t old_mask = di->Mask(); |
346 const intptr_t event_mask = GetPollEvents(events[i].events, di); | 334 const intptr_t event_mask = GetPollEvents(events[i].events, di); |
347 if ((event_mask & (1 << kErrorEvent)) != 0) { | 335 if ((event_mask & (1 << kErrorEvent)) != 0) { |
348 di->NotifyAllDartPorts(event_mask); | 336 di->NotifyAllDartPorts(event_mask); |
349 UpdateEpollInstance(old_mask, di); | 337 UpdateEpollInstance(old_mask, di); |
350 } else if (event_mask != 0) { | 338 } else if (event_mask != 0) { |
351 Dart_Port port = di->NextNotifyDartPort(event_mask); | 339 Dart_Port port = di->NextNotifyDartPort(event_mask); |
352 ASSERT(port != 0); | 340 ASSERT(port != 0); |
353 UpdateEpollInstance(old_mask, di); | 341 UpdateEpollInstance(old_mask, di); |
354 DartUtils::PostInt32(port, event_mask); | 342 DartUtils::PostInt32(port, event_mask); |
355 } | 343 } |
356 } | 344 } |
357 } | 345 } |
358 if (interrupt_seen) { | 346 if (interrupt_seen) { |
359 // Handle after socket events, so we avoid closing a socket before we handle | 347 // Handle after socket events, so we avoid closing a socket before we handle |
360 // the current events. | 348 // the current events. |
361 HandleInterruptFd(); | 349 HandleInterruptFd(); |
362 } | 350 } |
363 } | 351 } |
364 | 352 |
365 | |
366 int64_t EventHandlerImplementation::GetTimeout() { | 353 int64_t EventHandlerImplementation::GetTimeout() { |
367 if (!timeout_queue_.HasTimeout()) { | 354 if (!timeout_queue_.HasTimeout()) { |
368 return kInfinityTimeout; | 355 return kInfinityTimeout; |
369 } | 356 } |
370 int64_t millis = | 357 int64_t millis = |
371 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); | 358 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); |
372 return (millis < 0) ? 0 : millis; | 359 return (millis < 0) ? 0 : millis; |
373 } | 360 } |
374 | 361 |
375 | |
376 void EventHandlerImplementation::HandleTimeout() { | 362 void EventHandlerImplementation::HandleTimeout() { |
377 if (timeout_queue_.HasTimeout()) { | 363 if (timeout_queue_.HasTimeout()) { |
378 int64_t millis = timeout_queue_.CurrentTimeout() - | 364 int64_t millis = timeout_queue_.CurrentTimeout() - |
379 TimerUtils::GetCurrentMonotonicMillis(); | 365 TimerUtils::GetCurrentMonotonicMillis(); |
380 if (millis <= 0) { | 366 if (millis <= 0) { |
381 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 367 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
382 timeout_queue_.RemoveCurrent(); | 368 timeout_queue_.RemoveCurrent(); |
383 } | 369 } |
384 } | 370 } |
385 } | 371 } |
386 | 372 |
387 | |
388 void EventHandlerImplementation::Poll(uword args) { | 373 void EventHandlerImplementation::Poll(uword args) { |
389 ThreadSignalBlocker signal_blocker(SIGPROF); | 374 ThreadSignalBlocker signal_blocker(SIGPROF); |
390 static const intptr_t kMaxEvents = 16; | 375 static const intptr_t kMaxEvents = 16; |
391 struct epoll_event events[kMaxEvents]; | 376 struct epoll_event events[kMaxEvents]; |
392 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 377 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
393 EventHandlerImplementation* handler_impl = &handler->delegate_; | 378 EventHandlerImplementation* handler_impl = &handler->delegate_; |
394 ASSERT(handler_impl != NULL); | 379 ASSERT(handler_impl != NULL); |
395 | 380 |
396 while (!handler_impl->shutdown_) { | 381 while (!handler_impl->shutdown_) { |
397 int64_t millis = handler_impl->GetTimeout(); | 382 int64_t millis = handler_impl->GetTimeout(); |
(...skipping 10 matching lines...) Expand all Loading... |
408 } | 393 } |
409 } else { | 394 } else { |
410 handler_impl->HandleTimeout(); | 395 handler_impl->HandleTimeout(); |
411 handler_impl->HandleEvents(events, result); | 396 handler_impl->HandleEvents(events, result); |
412 } | 397 } |
413 } | 398 } |
414 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); | 399 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); |
415 handler->NotifyShutdownDone(); | 400 handler->NotifyShutdownDone(); |
416 } | 401 } |
417 | 402 |
418 | |
419 void EventHandlerImplementation::Start(EventHandler* handler) { | 403 void EventHandlerImplementation::Start(EventHandler* handler) { |
420 int result = Thread::Start(&EventHandlerImplementation::Poll, | 404 int result = Thread::Start(&EventHandlerImplementation::Poll, |
421 reinterpret_cast<uword>(handler)); | 405 reinterpret_cast<uword>(handler)); |
422 if (result != 0) { | 406 if (result != 0) { |
423 FATAL1("Failed to start event handler thread %d", result); | 407 FATAL1("Failed to start event handler thread %d", result); |
424 } | 408 } |
425 } | 409 } |
426 | 410 |
427 | |
428 void EventHandlerImplementation::Shutdown() { | 411 void EventHandlerImplementation::Shutdown() { |
429 SendData(kShutdownId, 0, 0); | 412 SendData(kShutdownId, 0, 0); |
430 } | 413 } |
431 | 414 |
432 | |
433 void EventHandlerImplementation::SendData(intptr_t id, | 415 void EventHandlerImplementation::SendData(intptr_t id, |
434 Dart_Port dart_port, | 416 Dart_Port dart_port, |
435 int64_t data) { | 417 int64_t data) { |
436 WakeupHandler(id, dart_port, data); | 418 WakeupHandler(id, dart_port, data); |
437 } | 419 } |
438 | 420 |
439 | |
440 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { | 421 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { |
441 // The hashmap does not support keys with value 0. | 422 // The hashmap does not support keys with value 0. |
442 return reinterpret_cast<void*>(fd + 1); | 423 return reinterpret_cast<void*>(fd + 1); |
443 } | 424 } |
444 | 425 |
445 | |
446 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 426 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
447 // The hashmap does not support keys with value 0. | 427 // The hashmap does not support keys with value 0. |
448 return dart::Utils::WordHash(fd + 1); | 428 return dart::Utils::WordHash(fd + 1); |
449 } | 429 } |
450 | 430 |
451 } // namespace bin | 431 } // namespace bin |
452 } // namespace dart | 432 } // namespace dart |
453 | 433 |
454 #endif // defined(HOST_OS_ANDROID) | 434 #endif // defined(HOST_OS_ANDROID) |
455 | 435 |
456 #endif // !defined(DART_IO_DISABLED) | 436 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |