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

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

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