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

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: 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
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: This assumes that all sockets listen before we close.
231 // This needs to be synchronized with a global datastructure.
232 if (new_mask == 0) {
233 socket_map_.Remove(
234 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
235 di->Close();
236 delete di;
237 }
238 } else {
239 ASSERT(new_mask == 0);
240 socket_map_.Remove(
241 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd));
242 di->Close();
243 delete di;
244 }
245
246 DartUtils::PostInt32(port, 1 << kDestroyedEvent);
192 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { 247 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) {
193 int count = TOKEN_COUNT(msg[i].data); 248 int count = TOKEN_COUNT(msg[i].data);
194 249 intptr_t old_mask = di->Mask();
195 for (int i = 0; i < count; i++) { 250 di->ReturnTokens(msg[i].dart_port, count);
196 if (sd->ReturnToken()) { 251 UpdateEpollInstance(old_mask, di);
197 AddToEpollInstance(epoll_fd_, sd);
198 }
199 }
200 } else if (IS_COMMAND(msg[i].data, kSetEventMaskCommand)) { 252 } else if (IS_COMMAND(msg[i].data, kSetEventMaskCommand)) {
201 // `events` can only have kInEvent/kOutEvent flags set. 253 // `events` can only have kInEvent/kOutEvent flags set.
202 intptr_t events = msg[i].data & EVENT_MASK; 254 intptr_t events = msg[i].data & EVENT_MASK;
203 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent))); 255 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent)));
204 256
205 // Setup events to wait for. 257 intptr_t old_mask = di->Mask();
206 sd->SetPortAndMask(msg[i].dart_port, events); 258 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK);
207 AddToEpollInstance(epoll_fd_, sd); 259 UpdateEpollInstance(old_mask, di);
208 } else { 260 } else {
209 UNREACHABLE(); 261 UNREACHABLE();
210 } 262 }
211 } 263 }
212 } 264 }
213 } 265 }
214 266
215 #ifdef DEBUG_POLL 267 #ifdef DEBUG_POLL
216 static void PrintEventMask(intptr_t fd, intptr_t events) { 268 static void PrintEventMask(intptr_t fd, intptr_t events) {
217 Log::Print("%d ", fd); 269 Log::Print("%d ", fd);
218 if ((events & EPOLLIN) != 0) Log::Print("EPOLLIN "); 270 if ((events & EPOLLIN) != 0) Log::Print("EPOLLIN ");
219 if ((events & EPOLLPRI) != 0) Log::Print("EPOLLPRI "); 271 if ((events & EPOLLPRI) != 0) Log::Print("EPOLLPRI ");
220 if ((events & EPOLLOUT) != 0) Log::Print("EPOLLOUT "); 272 if ((events & EPOLLOUT) != 0) Log::Print("EPOLLOUT ");
221 if ((events & EPOLLERR) != 0) Log::Print("EPOLLERR "); 273 if ((events & EPOLLERR) != 0) Log::Print("EPOLLERR ");
222 if ((events & EPOLLHUP) != 0) Log::Print("EPOLLHUP "); 274 if ((events & EPOLLHUP) != 0) Log::Print("EPOLLHUP ");
223 if ((events & EPOLLRDHUP) != 0) Log::Print("EPOLLRDHUP "); 275 if ((events & EPOLLRDHUP) != 0) Log::Print("EPOLLRDHUP ");
224 int all_events = EPOLLIN | EPOLLPRI | EPOLLOUT | 276 int all_events = EPOLLIN | EPOLLPRI | EPOLLOUT |
225 EPOLLERR | EPOLLHUP | EPOLLRDHUP; 277 EPOLLERR | EPOLLHUP | EPOLLRDHUP;
226 if ((events & ~all_events) != 0) { 278 if ((events & ~all_events) != 0) {
227 Log::Print("(and %08x) ", events & ~all_events); 279 Log::Print("(and %08x) ", events & ~all_events);
228 } 280 }
229 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd)); 281 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd));
230 282
231 Log::Print("\n"); 283 Log::Print("\n");
232 } 284 }
233 #endif 285 #endif
234 286
235 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events, 287 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events,
236 SocketData* sd) { 288 DescriptorInfo* di) {
237 #ifdef DEBUG_POLL 289 #ifdef DEBUG_POLL
238 PrintEventMask(sd->fd(), events); 290 PrintEventMask(di->fd(), events);
239 #endif 291 #endif
240 if (events & EPOLLERR) { 292 if (events & EPOLLERR) {
241 // Return error only if EPOLLIN is present. 293 // Return error only if EPOLLIN is present.
242 return (events & EPOLLIN) ? (1 << kErrorEvent) : 0; 294 return (events & EPOLLIN) ? (1 << kErrorEvent) : 0;
243 } 295 }
244 intptr_t event_mask = 0; 296 intptr_t event_mask = 0;
245 if (events & EPOLLIN) event_mask |= (1 << kInEvent); 297 if (events & EPOLLIN) event_mask |= (1 << kInEvent);
246 if (events & EPOLLOUT) event_mask |= (1 << kOutEvent); 298 if (events & EPOLLOUT) event_mask |= (1 << kOutEvent);
247 if (events & (EPOLLHUP | EPOLLRDHUP)) event_mask |= (1 << kCloseEvent); 299 if (events & (EPOLLHUP | EPOLLRDHUP)) event_mask |= (1 << kCloseEvent);
248 return event_mask; 300 return event_mask;
249 } 301 }
250 302
251 303
252 void EventHandlerImplementation::HandleEvents(struct epoll_event* events, 304 void EventHandlerImplementation::HandleEvents(struct epoll_event* events,
253 int size) { 305 int size) {
254 bool interrupt_seen = false; 306 bool interrupt_seen = false;
255 for (int i = 0; i < size; i++) { 307 for (int i = 0; i < size; i++) {
256 if (events[i].data.ptr == NULL) { 308 if (events[i].data.ptr == NULL) {
257 interrupt_seen = true; 309 interrupt_seen = true;
258 } else { 310 } else {
259 SocketData* sd = reinterpret_cast<SocketData*>(events[i].data.ptr); 311 DescriptorInfo* di =
260 intptr_t event_mask = GetPollEvents(events[i].events, sd); 312 reinterpret_cast<DescriptorInfo*>(events[i].data.ptr);
313 intptr_t event_mask = GetPollEvents(events[i].events, di);
261 if (event_mask != 0) { 314 if (event_mask != 0) {
262 if (sd->TakeToken()) { 315 intptr_t old_mask = di->Mask();
263 // Took last token, remove from epoll. 316 Dart_Port port = di->NextNotifyDartPort(event_mask);
264 RemoveFromEpollInstance(epoll_fd_, sd);
265 }
266 Dart_Port port = sd->port();
267 ASSERT(port != 0); 317 ASSERT(port != 0);
318 UpdateEpollInstance(old_mask, di);
268 DartUtils::PostInt32(port, event_mask); 319 DartUtils::PostInt32(port, event_mask);
269 } 320 }
270 } 321 }
271 } 322 }
272 if (interrupt_seen) { 323 if (interrupt_seen) {
273 // Handle after socket events, so we avoid closing a socket before we handle 324 // Handle after socket events, so we avoid closing a socket before we handle
274 // the current events. 325 // the current events.
275 HandleInterruptFd(); 326 HandleInterruptFd();
276 } 327 }
277 } 328 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 handler_impl->HandleTimeout(); 373 handler_impl->HandleTimeout();
323 handler_impl->HandleEvents(events, result); 374 handler_impl->HandleEvents(events, result);
324 } 375 }
325 } 376 }
326 handler->NotifyShutdownDone(); 377 handler->NotifyShutdownDone();
327 } 378 }
328 379
329 380
330 void EventHandlerImplementation::Start(EventHandler* handler) { 381 void EventHandlerImplementation::Start(EventHandler* handler) {
331 int result = Thread::Start(&EventHandlerImplementation::Poll, 382 int result = Thread::Start(&EventHandlerImplementation::Poll,
332 reinterpret_cast<uword>(handler)); 383 reinterpret_cast<uword>(handler));
333 if (result != 0) { 384 if (result != 0) {
334 FATAL1("Failed to start event handler thread %d", result); 385 FATAL1("Failed to start event handler thread %d", result);
335 } 386 }
336 } 387 }
337 388
338 389
339 void EventHandlerImplementation::Shutdown() { 390 void EventHandlerImplementation::Shutdown() {
340 SendData(kShutdownId, 0, 0); 391 SendData(kShutdownId, 0, 0);
341 } 392 }
342 393
343 394
344 void EventHandlerImplementation::SendData(intptr_t id, 395 void EventHandlerImplementation::SendData(intptr_t id,
345 Dart_Port dart_port, 396 Dart_Port dart_port,
346 intptr_t data) { 397 int64_t data) {
347 WakeupHandler(id, dart_port, data); 398 WakeupHandler(id, dart_port, data);
348 } 399 }
349 400
350 401
351 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { 402 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) {
352 // The hashmap does not support keys with value 0. 403 // The hashmap does not support keys with value 0.
353 return reinterpret_cast<void*>(fd + 1); 404 return reinterpret_cast<void*>(fd + 1);
354 } 405 }
355 406
356 407
357 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { 408 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) {
358 // The hashmap does not support keys with value 0. 409 // The hashmap does not support keys with value 0.
359 return dart::Utils::WordHash(fd + 1); 410 return dart::Utils::WordHash(fd + 1);
360 } 411 }
361 412
362 } // namespace bin 413 } // namespace bin
363 } // namespace dart 414 } // namespace dart
364 415
365 #endif // defined(TARGET_OS_ANDROID) 416 #endif // defined(TARGET_OS_ANDROID)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698