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

Side by Side Diff: dart/runtime/bin/eventhandler_android.cc

Issue 896213002: Revert "Introduce optional 'bool shared' parameter to ServerSocket.bind() ..." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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 | « dart/runtime/bin/eventhandler_android.h ('k') | dart/runtime/bin/eventhandler_linux.h » ('j') | 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_ANDROID) 6 #if defined(TARGET_OS_ANDROID)
7 7
8 #include "bin/eventhandler.h" 8 #include "bin/eventhandler.h"
9 #include "bin/eventhandler_android.h"
10 9
11 #include <errno.h> // NOLINT 10 #include <errno.h> // NOLINT
12 #include <pthread.h> // NOLINT 11 #include <pthread.h> // NOLINT
13 #include <stdio.h> // NOLINT 12 #include <stdio.h> // NOLINT
14 #include <string.h> // NOLINT 13 #include <string.h> // NOLINT
15 #include <sys/epoll.h> // NOLINT 14 #include <sys/epoll.h> // NOLINT
16 #include <sys/stat.h> // NOLINT 15 #include <sys/stat.h> // NOLINT
17 #include <unistd.h> // NOLINT 16 #include <unistd.h> // NOLINT
18 #include <fcntl.h> // NOLINT 17 #include <fcntl.h> // NOLINT
19 18
20 #include "bin/dartutils.h" 19 #include "bin/dartutils.h"
21 #include "bin/fdutils.h" 20 #include "bin/fdutils.h"
22 #include "bin/log.h" 21 #include "bin/log.h"
23 #include "bin/lockers.h"
24 #include "bin/socket.h"
25 #include "bin/thread.h" 22 #include "bin/thread.h"
26 #include "bin/utils.h" 23 #include "bin/utils.h"
27 #include "platform/hashmap.h" 24 #include "platform/hashmap.h"
28 #include "platform/utils.h" 25 #include "platform/utils.h"
29 26
30 27
31 // Android doesn't define EPOLLRDHUP. 28 // Android doesn't define EPOLLRDHUP.
32 #if !defined(EPOLLRDHUP) 29 #if !defined(EPOLLRDHUP)
33 #define EPOLLRDHUP 0x2000 30 #define EPOLLRDHUP 0x2000
34 #endif // !defined(EPOLLRDHUP) 31 #endif // !defined(EPOLLRDHUP)
35 32
36 33
37 namespace dart { 34 namespace dart {
38 namespace bin { 35 namespace bin {
39 36
37 static const int kInterruptMessageSize = sizeof(InterruptMessage);
38 static const int kInfinityTimeout = -1;
39 static const int kTimerId = -1;
40 static const int kShutdownId = -2;
40 41
41 intptr_t DescriptorInfo::GetPollEvents() { 42
43 intptr_t SocketData::GetPollEvents() {
42 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are 44 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are
43 // triggered anyway. 45 // triggered anyway.
44 intptr_t events = 0; 46 intptr_t events = 0;
45 if ((Mask() & (1 << kInEvent)) != 0) { 47 if ((mask_ & (1 << kInEvent)) != 0) {
46 events |= EPOLLIN; 48 events |= EPOLLIN;
47 } 49 }
48 if ((Mask() & (1 << kOutEvent)) != 0) { 50 if ((mask_ & (1 << kOutEvent)) != 0) {
49 events |= EPOLLOUT; 51 events |= EPOLLOUT;
50 } 52 }
51 return events; 53 return events;
52 } 54 }
53 55
54 56
55 // Unregister the file descriptor for a DescriptorInfo structure with 57 // Unregister the file descriptor for a SocketData structure with epoll.
56 // epoll. 58 static void RemoveFromEpollInstance(intptr_t epoll_fd_, SocketData* sd) {
57 static void RemoveFromEpollInstance(intptr_t epoll_fd_,
58 DescriptorInfo* di) {
59 VOID_NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, 59 VOID_NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_,
60 EPOLL_CTL_DEL, 60 EPOLL_CTL_DEL,
61 di->fd(), 61 sd->fd(),
62 NULL)); 62 NULL));
63 } 63 }
64 64
65 65
66 static void AddToEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { 66 static void AddToEpollInstance(intptr_t epoll_fd_, SocketData* sd) {
67 struct epoll_event event; 67 struct epoll_event event;
68 event.events = EPOLLRDHUP | di->GetPollEvents(); 68 event.events = EPOLLRDHUP | sd->GetPollEvents();
69 if (!di->IsListeningSocket()) { 69 if (!sd->IsListeningSocket()) {
70 event.events |= EPOLLET; 70 event.events |= EPOLLET;
71 } 71 }
72 event.data.ptr = di; 72 event.data.ptr = sd;
73 int status = NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, 73 int status = NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_,
74 EPOLL_CTL_ADD, 74 EPOLL_CTL_ADD,
75 di->fd(), 75 sd->fd(),
76 &event)); 76 &event));
77 if (status == -1) { 77 if (status == -1) {
78 // TODO(kustermann): Verify that the dart end is handling this correctly &
79 // adapt this code to work for multiple listening sockets.
80
81 // Epoll does not accept the file descriptor. It could be due to 78 // Epoll does not accept the file descriptor. It could be due to
82 // already closed file descriptor, or unuspported devices, such 79 // already closed file descriptor, or unuspported devices, such
83 // as /dev/null. In such case, mark the file descriptor as closed, 80 // as /dev/null. In such case, mark the file descriptor as closed,
84 // so dart will handle it accordingly. 81 // so dart will handle it accordingly.
85 DartUtils::PostInt32(di->NextPort(), 1 << kCloseEvent); 82 DartUtils::PostInt32(sd->port(), 1 << kCloseEvent);
86 } 83 }
87 } 84 }
88 85
89 86
90 EventHandlerImplementation::EventHandlerImplementation() 87 EventHandlerImplementation::EventHandlerImplementation()
91 : socket_map_(&HashMap::SamePointerValue, 16) { 88 : socket_map_(&HashMap::SamePointerValue, 16) {
92 intptr_t result; 89 intptr_t result;
93 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); 90 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_));
94 if (result != 0) { 91 if (result != 0) {
95 FATAL("Pipe creation failed"); 92 FATAL("Pipe creation failed");
96 } 93 }
97 FDUtils::SetNonBlocking(interrupt_fds_[0]); 94 FDUtils::SetNonBlocking(interrupt_fds_[0]);
98 FDUtils::SetCloseOnExec(interrupt_fds_[0]); 95 FDUtils::SetCloseOnExec(interrupt_fds_[0]);
99 FDUtils::SetCloseOnExec(interrupt_fds_[1]); 96 FDUtils::SetCloseOnExec(interrupt_fds_[1]);
100 shutdown_ = false; 97 shutdown_ = false;
101 // The initial size passed to epoll_create is ignore on newer (>= 98 // The initial size passed to epoll_create is ignore on newer (>=
102 // 2.6.8) Linux versions 99 // 2.6.8) Linux versions
103 static const int kEpollInitialSize = 64; 100 static const int kEpollInitialSize = 64;
104 epoll_fd_ = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize)); 101 epoll_fd_ = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize));
105 if (epoll_fd_ == -1) { 102 if (epoll_fd_ == -1) {
106 FATAL1("Failed creating epoll file descriptor: %i", errno); 103 FATAL("Failed creating epoll file descriptor");
107 } 104 }
108 FDUtils::SetCloseOnExec(epoll_fd_); 105 FDUtils::SetCloseOnExec(epoll_fd_);
109 // Register the interrupt_fd with the epoll instance. 106 // Register the interrupt_fd with the epoll instance.
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(epoll_ctl(epoll_fd_, 110 int status = NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_,
114 EPOLL_CTL_ADD, 111 EPOLL_CTL_ADD,
115 interrupt_fds_[0], 112 interrupt_fds_[0],
116 &event)); 113 &event));
117 if (status == -1) { 114 if (status == -1) {
118 FATAL("Failed adding interrupt fd to epoll instance"); 115 FATAL("Failed adding interrupt fd to epoll instance");
119 } 116 }
120 } 117 }
121 118
122 119
123 EventHandlerImplementation::~EventHandlerImplementation() { 120 EventHandlerImplementation::~EventHandlerImplementation() {
124 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_));
125 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); 121 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
126 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); 122 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
127 } 123 }
128 124
129 125
130 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( 126 SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) {
131 intptr_t fd, bool is_listening) {
132 ASSERT(fd >= 0); 127 ASSERT(fd >= 0);
133 HashMap::Entry* entry = socket_map_.Lookup( 128 HashMap::Entry* entry = socket_map_.Lookup(
134 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); 129 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true);
135 ASSERT(entry != NULL); 130 ASSERT(entry != NULL);
136 DescriptorInfo* di = 131 SocketData* sd = reinterpret_cast<SocketData*>(entry->value);
137 reinterpret_cast<DescriptorInfo*>(entry->value); 132 if (sd == NULL) {
138 if (di == NULL) {
139 // If there is no data in the hash map for this file descriptor a 133 // If there is no data in the hash map for this file descriptor a
140 // new DescriptorInfo for the file descriptor is inserted. 134 // new SocketData for the file descriptor is inserted.
141 if (is_listening) { 135 sd = new SocketData(fd);
142 di = new DescriptorInfoMultiple(fd); 136 entry->value = sd;
143 } else {
144 di = new DescriptorInfoSingle(fd);
145 }
146 entry->value = di;
147 } 137 }
148 ASSERT(fd == di->fd()); 138 ASSERT(fd == sd->fd());
149 return di; 139 return sd;
150 } 140 }
151 141
152 142
153 void EventHandlerImplementation::WakeupHandler(intptr_t id, 143 void EventHandlerImplementation::WakeupHandler(intptr_t id,
154 Dart_Port dart_port, 144 Dart_Port dart_port,
155 int64_t data) { 145 int64_t data) {
156 InterruptMessage msg; 146 InterruptMessage msg;
157 msg.id = id; 147 msg.id = id;
158 msg.dart_port = dart_port; 148 msg.dart_port = dart_port;
159 msg.data = data; 149 msg.data = data;
160 // WriteToBlocking will write up to 512 bytes atomically, and since our msg 150 // WriteToBlocking will write up to 512 bytes atomically, and since our msg
161 // is smaller than 512, we don't need a thread lock. 151 // is smaller than 512, we don't need a thread lock.
162 // See: http://linux.die.net/man/7/pipe, section 'Pipe_buf'. 152 // See: http://linux.die.net/man/7/pipe, section 'Pipe_buf'.
163 ASSERT(kInterruptMessageSize < PIPE_BUF); 153 ASSERT(kInterruptMessageSize < PIPE_BUF);
164 intptr_t result = 154 intptr_t result =
165 FDUtils::WriteToBlocking(interrupt_fds_[1], &msg, kInterruptMessageSize); 155 FDUtils::WriteToBlocking(interrupt_fds_[1], &msg, kInterruptMessageSize);
166 if (result != kInterruptMessageSize) { 156 if (result != kInterruptMessageSize) {
167 if (result == -1) { 157 if (result == -1) {
168 perror("Interrupt message failure:"); 158 perror("Interrupt message failure:");
169 } 159 }
170 FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result); 160 FATAL1("Interrupt message failure. Wrote %d bytes.", result);
171 } 161 }
172 } 162 }
173 163
174 164
175 void EventHandlerImplementation::HandleInterruptFd() { 165 void EventHandlerImplementation::HandleInterruptFd() {
176 const intptr_t MAX_MESSAGES = kInterruptMessageSize; 166 const intptr_t MAX_MESSAGES = kInterruptMessageSize;
177 InterruptMessage msg[MAX_MESSAGES]; 167 InterruptMessage msg[MAX_MESSAGES];
178 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( 168 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
179 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); 169 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize));
180 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { 170 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) {
181 if (msg[i].id == kTimerId) { 171 if (msg[i].id == kTimerId) {
182 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); 172 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data);
183 } else if (msg[i].id == kShutdownId) { 173 } else if (msg[i].id == kShutdownId) {
184 shutdown_ = true; 174 shutdown_ = true;
185 } else { 175 } else {
186 DescriptorInfo* di = GetDescriptorInfo( 176 SocketData* sd = GetSocketData(msg[i].id);
187 msg[i].id, (msg[i].data & (1 << kListeningSocket)) != 0); 177
188 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { 178 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) {
189 ASSERT(!di->IsListeningSocket());
190 // Close the socket for reading. 179 // Close the socket for reading.
191 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_RD)); 180 shutdown(sd->fd(), SHUT_RD);
192 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { 181 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) {
193 ASSERT(!di->IsListeningSocket());
194 // Close the socket for writing. 182 // Close the socket for writing.
195 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_WR)); 183 shutdown(sd->fd(), SHUT_WR);
196 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { 184 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) {
197 // Close the socket and free system resources and move on to next 185 // Close the socket and free system resources and move on to
198 // message. 186 // next message.
199 bool no_more_listeners = di->RemovePort(msg[i].dart_port); 187 RemoveFromEpollInstance(epoll_fd_, sd);
200 if (no_more_listeners) { 188 intptr_t fd = sd->fd();
201 RemoveFromEpollInstance(epoll_fd_, di); 189 sd->Close();
202 } 190 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
203 191 delete sd;
204 intptr_t fd = di->fd();
205 if (di->IsListeningSocket()) {
206 // We only close the socket file descriptor from the operating
207 // system if there are no other dart socket objects which
208 // are listening on the same (address, port) combination.
209 {
210 MutexLocker ml(globalTcpListeningSocketRegistry.mutex());
211 if (globalTcpListeningSocketRegistry.CloseSafe(fd)) {
212 socket_map_.Remove(
213 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
214 di->Close();
215 delete di;
216 }
217 }
218 } else {
219 ASSERT(no_more_listeners);
220 socket_map_.Remove(
221 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
222 di->Close();
223 delete di;
224 }
225 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); 192 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent);
226 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { 193 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) {
227 int count = TOKEN_COUNT(msg[i].data); 194 int count = TOKEN_COUNT(msg[i].data);
228 if (di->ReturnTokens(msg[i].dart_port, count)) { 195
229 AddToEpollInstance(epoll_fd_, di); 196 for (int i = 0; i < count; i++) {
197 if (sd->ReturnToken()) {
198 AddToEpollInstance(epoll_fd_, sd);
199 }
230 } 200 }
231 } else { 201 } else {
232 ASSERT_NO_COMMAND(msg[i].data); 202 ASSERT_NO_COMMAND(msg[i].data);
233 bool had_listeners = di->HasNextPort(); 203 // Setup events to wait for.
234 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); 204 sd->SetPortAndMask(msg[i].dart_port, msg[i].data);
235 bool has_listeners = di->HasNextPort(); 205 AddToEpollInstance(epoll_fd_, sd);
236
237 // Add/Remove from epoll set depending on previous and current state.
238 if (!had_listeners && has_listeners) {
239 AddToEpollInstance(epoll_fd_, di);
240 } else if (had_listeners && !has_listeners) {
241 RemoveFromEpollInstance(epoll_fd_, di);
242 }
243 } 206 }
244 } 207 }
245 } 208 }
246 } 209 }
247 210
248 #ifdef DEBUG_POLL 211 #ifdef DEBUG_POLL
249 static void PrintEventMask(intptr_t fd, intptr_t events) { 212 static void PrintEventMask(intptr_t fd, intptr_t events) {
250 Log::Print("%d ", fd); 213 Log::Print("%d ", fd);
251 if ((events & EPOLLIN) != 0) Log::Print("EPOLLIN "); 214 if ((events & EPOLLIN) != 0) Log::Print("EPOLLIN ");
252 if ((events & EPOLLPRI) != 0) Log::Print("EPOLLPRI "); 215 if ((events & EPOLLPRI) != 0) Log::Print("EPOLLPRI ");
253 if ((events & EPOLLOUT) != 0) Log::Print("EPOLLOUT "); 216 if ((events & EPOLLOUT) != 0) Log::Print("EPOLLOUT ");
254 if ((events & EPOLLERR) != 0) Log::Print("EPOLLERR "); 217 if ((events & EPOLLERR) != 0) Log::Print("EPOLLERR ");
255 if ((events & EPOLLHUP) != 0) Log::Print("EPOLLHUP "); 218 if ((events & EPOLLHUP) != 0) Log::Print("EPOLLHUP ");
256 if ((events & EPOLLRDHUP) != 0) Log::Print("EPOLLRDHUP "); 219 if ((events & EPOLLRDHUP) != 0) Log::Print("EPOLLRDHUP ");
257 int all_events = EPOLLIN | EPOLLPRI | EPOLLOUT | 220 int all_events = EPOLLIN | EPOLLPRI | EPOLLOUT |
258 EPOLLERR | EPOLLHUP | EPOLLRDHUP; 221 EPOLLERR | EPOLLHUP | EPOLLRDHUP;
259 if ((events & ~all_events) != 0) { 222 if ((events & ~all_events) != 0) {
260 Log::Print("(and %08x) ", events & ~all_events); 223 Log::Print("(and %08x) ", events & ~all_events);
261 } 224 }
262 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd)); 225 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd));
263 226
264 Log::Print("\n"); 227 Log::Print("\n");
265 } 228 }
266 #endif 229 #endif
267 230
268 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events, 231 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events,
269 DescriptorInfo* di) { 232 SocketData* sd) {
270 #ifdef DEBUG_POLL 233 #ifdef DEBUG_POLL
271 PrintEventMask(di->fd(), events); 234 PrintEventMask(sd->fd(), events);
272 #endif 235 #endif
273 if (events & EPOLLERR) { 236 if (events & EPOLLERR) {
274 // Return error only if EPOLLIN is present. 237 // Return error only if EPOLLIN is present.
275 return (events & EPOLLIN) ? (1 << kErrorEvent) : 0; 238 return (events & EPOLLIN) ? (1 << kErrorEvent) : 0;
276 } 239 }
277 intptr_t event_mask = 0; 240 intptr_t event_mask = 0;
278 if (events & EPOLLIN) event_mask |= (1 << kInEvent); 241 if (events & EPOLLIN) event_mask |= (1 << kInEvent);
279 if (events & EPOLLOUT) event_mask |= (1 << kOutEvent); 242 if (events & EPOLLOUT) event_mask |= (1 << kOutEvent);
280 if (events & (EPOLLHUP | EPOLLRDHUP)) event_mask |= (1 << kCloseEvent); 243 if (events & (EPOLLHUP | EPOLLRDHUP)) event_mask |= (1 << kCloseEvent);
281 return event_mask; 244 return event_mask;
282 } 245 }
283 246
284 247
285 void EventHandlerImplementation::HandleEvents(struct epoll_event* events, 248 void EventHandlerImplementation::HandleEvents(struct epoll_event* events,
286 int size) { 249 int size) {
287 bool interrupt_seen = false; 250 bool interrupt_seen = false;
288 for (int i = 0; i < size; i++) { 251 for (int i = 0; i < size; i++) {
289 if (events[i].data.ptr == NULL) { 252 if (events[i].data.ptr == NULL) {
290 interrupt_seen = true; 253 interrupt_seen = true;
291 } else { 254 } else {
292 DescriptorInfo* di = 255 SocketData* sd = reinterpret_cast<SocketData*>(events[i].data.ptr);
293 reinterpret_cast<DescriptorInfo*>(events[i].data.ptr); 256 intptr_t event_mask = GetPollEvents(events[i].events, sd);
294 intptr_t event_mask = GetPollEvents(events[i].events, di);
295 if (event_mask != 0) { 257 if (event_mask != 0) {
296 Dart_Port port = di->NextPort(); 258 if (sd->TakeToken()) {
259 // Took last token, remove from epoll.
260 RemoveFromEpollInstance(epoll_fd_, sd);
261 }
262 Dart_Port port = sd->port();
297 ASSERT(port != 0); 263 ASSERT(port != 0);
298 if (di->TakeToken()) {
299 // Took last token, remove from epoll.
300 RemoveFromEpollInstance(epoll_fd_, di);
301 }
302 DartUtils::PostInt32(port, event_mask); 264 DartUtils::PostInt32(port, event_mask);
303 } 265 }
304 } 266 }
305 } 267 }
306 if (interrupt_seen) { 268 if (interrupt_seen) {
307 // Handle after socket events, so we avoid closing a socket before we handle 269 // Handle after socket events, so we avoid closing a socket before we handle
308 // the current events. 270 // the current events.
309 HandleInterruptFd(); 271 HandleInterruptFd();
310 } 272 }
311 } 273 }
(...skipping 18 matching lines...) Expand all
330 timeout_queue_.RemoveCurrent(); 292 timeout_queue_.RemoveCurrent();
331 } 293 }
332 } 294 }
333 } 295 }
334 296
335 297
336 void EventHandlerImplementation::Poll(uword args) { 298 void EventHandlerImplementation::Poll(uword args) {
337 ThreadSignalBlocker signal_blocker(SIGPROF); 299 ThreadSignalBlocker signal_blocker(SIGPROF);
338 static const intptr_t kMaxEvents = 16; 300 static const intptr_t kMaxEvents = 16;
339 struct epoll_event events[kMaxEvents]; 301 struct epoll_event events[kMaxEvents];
340 EventHandler* handler = reinterpret_cast<EventHandler*>(args); 302 EventHandlerImplementation* handler =
341 EventHandlerImplementation* handler_impl = &handler->delegate_; 303 reinterpret_cast<EventHandlerImplementation*>(args);
342 ASSERT(handler_impl != NULL); 304 ASSERT(handler != NULL);
343 while (!handler_impl->shutdown_) { 305 while (!handler->shutdown_) {
344 int64_t millis = handler_impl->GetTimeout(); 306 int64_t millis = handler->GetTimeout();
345 ASSERT(millis == kInfinityTimeout || millis >= 0); 307 ASSERT(millis == kInfinityTimeout || millis >= 0);
346 if (millis > kMaxInt32) millis = kMaxInt32; 308 if (millis > kMaxInt32) millis = kMaxInt32;
347 intptr_t result = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( 309 intptr_t result = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
348 epoll_wait(handler_impl->epoll_fd_, events, kMaxEvents, millis)); 310 epoll_wait(handler->epoll_fd_, events, kMaxEvents, millis));
349 ASSERT(EAGAIN == EWOULDBLOCK); 311 ASSERT(EAGAIN == EWOULDBLOCK);
350 if (result == -1) { 312 if (result == -1) {
351 if (errno != EWOULDBLOCK) { 313 if (errno != EWOULDBLOCK) {
352 perror("Poll failed"); 314 perror("Poll failed");
353 } 315 }
354 } else { 316 } else {
355 handler_impl->HandleTimeout(); 317 handler->HandleTimeout();
356 handler_impl->HandleEvents(events, result); 318 handler->HandleEvents(events, result);
357 } 319 }
358 } 320 }
359 delete handler;
360 } 321 }
361 322
362 323
363 void EventHandlerImplementation::Start(EventHandler* handler) { 324 void EventHandlerImplementation::Start(EventHandler* handler) {
364 int result = Thread::Start(&EventHandlerImplementation::Poll, 325 int result = Thread::Start(&EventHandlerImplementation::Poll,
365 reinterpret_cast<uword>(handler)); 326 reinterpret_cast<uword>(handler));
366 if (result != 0) { 327 if (result != 0) {
367 FATAL1("Failed to start event handler thread %d", result); 328 FATAL1("Failed to start event handler thread %d", result);
368 } 329 }
369 } 330 }
370 331
371 332
372 void EventHandlerImplementation::Shutdown() { 333 void EventHandlerImplementation::Shutdown() {
373 SendData(kShutdownId, 0, 0); 334 SendData(kShutdownId, 0, 0);
374 } 335 }
375 336
376 337
377 void EventHandlerImplementation::SendData(intptr_t id, 338 void EventHandlerImplementation::SendData(intptr_t id,
378 Dart_Port dart_port, 339 Dart_Port dart_port,
379 int64_t data) { 340 intptr_t data) {
380 WakeupHandler(id, dart_port, data); 341 WakeupHandler(id, dart_port, data);
381 } 342 }
382 343
383 344
384 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { 345 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) {
385 // The hashmap does not support keys with value 0. 346 // The hashmap does not support keys with value 0.
386 return reinterpret_cast<void*>(fd + 1); 347 return reinterpret_cast<void*>(fd + 1);
387 } 348 }
388 349
389 350
390 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { 351 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) {
391 // The hashmap does not support keys with value 0. 352 // The hashmap does not support keys with value 0.
392 return dart::Utils::WordHash(fd + 1); 353 return dart::Utils::WordHash(fd + 1);
393 } 354 }
394 355
395 } // namespace bin 356 } // namespace bin
396 } // namespace dart 357 } // namespace dart
397 358
398 #endif // defined(TARGET_OS_ANDROID) 359 #endif // defined(TARGET_OS_ANDROID)
OLDNEW
« no previous file with comments | « dart/runtime/bin/eventhandler_android.h ('k') | dart/runtime/bin/eventhandler_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698