OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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_FUCHSIA) | 8 #if defined(HOST_OS_FUCHSIA) |
9 | 9 |
10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 // real, and which are ignore-and-continue. | 90 // real, and which are ignore-and-continue. |
91 read_events_enabled_ = true; | 91 read_events_enabled_ = true; |
92 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { | 92 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { |
93 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); | 93 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); |
94 } | 94 } |
95 | 95 |
96 errno = err; | 96 errno = err; |
97 return read_bytes; | 97 return read_bytes; |
98 } | 98 } |
99 | 99 |
100 | |
101 intptr_t IOHandle::Write(const void* buffer, intptr_t num_bytes) { | 100 intptr_t IOHandle::Write(const void* buffer, intptr_t num_bytes) { |
102 MutexLocker ml(mutex_); | 101 MutexLocker ml(mutex_); |
103 const ssize_t written_bytes = | 102 const ssize_t written_bytes = |
104 NO_RETRY_EXPECTED(write(fd_, buffer, num_bytes)); | 103 NO_RETRY_EXPECTED(write(fd_, buffer, num_bytes)); |
105 const int err = errno; | 104 const int err = errno; |
106 LOG_INFO("IOHandle::Write: fd = %ld. wrote %ld bytes\n", fd_, written_bytes); | 105 LOG_INFO("IOHandle::Write: fd = %ld. wrote %ld bytes\n", fd_, written_bytes); |
107 | 106 |
108 // Resubscribe to write events. | 107 // Resubscribe to write events. |
109 write_events_enabled_ = true; | 108 write_events_enabled_ = true; |
110 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLOUT, wait_key_)) { | 109 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLOUT, wait_key_)) { |
111 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); | 110 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); |
112 } | 111 } |
113 | 112 |
114 errno = err; | 113 errno = err; |
115 return written_bytes; | 114 return written_bytes; |
116 } | 115 } |
117 | 116 |
118 | |
119 intptr_t IOHandle::Accept(struct sockaddr* addr, socklen_t* addrlen) { | 117 intptr_t IOHandle::Accept(struct sockaddr* addr, socklen_t* addrlen) { |
120 MutexLocker ml(mutex_); | 118 MutexLocker ml(mutex_); |
121 const intptr_t socket = NO_RETRY_EXPECTED(accept(fd_, addr, addrlen)); | 119 const intptr_t socket = NO_RETRY_EXPECTED(accept(fd_, addr, addrlen)); |
122 const int err = errno; | 120 const int err = errno; |
123 LOG_INFO("IOHandle::Accept: fd = %ld. socket = %ld\n", fd_, socket); | 121 LOG_INFO("IOHandle::Accept: fd = %ld. socket = %ld\n", fd_, socket); |
124 | 122 |
125 // Re-subscribe to read events. | 123 // Re-subscribe to read events. |
126 read_events_enabled_ = true; | 124 read_events_enabled_ = true; |
127 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { | 125 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { |
128 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); | 126 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); |
129 } | 127 } |
130 | 128 |
131 errno = err; | 129 errno = err; |
132 return socket; | 130 return socket; |
133 } | 131 } |
134 | 132 |
135 | |
136 void IOHandle::Close() { | 133 void IOHandle::Close() { |
137 MutexLocker ml(mutex_); | 134 MutexLocker ml(mutex_); |
138 VOID_NO_RETRY_EXPECTED(close(fd_)); | 135 VOID_NO_RETRY_EXPECTED(close(fd_)); |
139 } | 136 } |
140 | 137 |
141 | |
142 uint32_t IOHandle::MaskToEpollEvents(intptr_t mask) { | 138 uint32_t IOHandle::MaskToEpollEvents(intptr_t mask) { |
143 MutexLocker ml(mutex_); | 139 MutexLocker ml(mutex_); |
144 // Do not ask for POLLERR and POLLHUP explicitly as they are | 140 // Do not ask for POLLERR and POLLHUP explicitly as they are |
145 // triggered anyway. | 141 // triggered anyway. |
146 uint32_t events = POLLRDHUP; | 142 uint32_t events = POLLRDHUP; |
147 if (read_events_enabled_ && ((mask & (1 << kInEvent)) != 0)) { | 143 if (read_events_enabled_ && ((mask & (1 << kInEvent)) != 0)) { |
148 events |= POLLIN; | 144 events |= POLLIN; |
149 } | 145 } |
150 if (write_events_enabled_ && ((mask & (1 << kOutEvent)) != 0)) { | 146 if (write_events_enabled_ && ((mask & (1 << kOutEvent)) != 0)) { |
151 events |= POLLOUT; | 147 events |= POLLOUT; |
152 } | 148 } |
153 return events; | 149 return events; |
154 } | 150 } |
155 | 151 |
156 | |
157 intptr_t IOHandle::EpollEventsToMask(intptr_t events) { | 152 intptr_t IOHandle::EpollEventsToMask(intptr_t events) { |
158 if ((events & POLLERR) != 0) { | 153 if ((events & POLLERR) != 0) { |
159 // Return error only if POLLIN is present. | 154 // Return error only if POLLIN is present. |
160 return ((events & POLLIN) != 0) ? (1 << kErrorEvent) : 0; | 155 return ((events & POLLIN) != 0) ? (1 << kErrorEvent) : 0; |
161 } | 156 } |
162 intptr_t event_mask = 0; | 157 intptr_t event_mask = 0; |
163 if ((events & POLLIN) != 0) { | 158 if ((events & POLLIN) != 0) { |
164 event_mask |= (1 << kInEvent); | 159 event_mask |= (1 << kInEvent); |
165 } | 160 } |
166 if ((events & POLLOUT) != 0) { | 161 if ((events & POLLOUT) != 0) { |
167 event_mask |= (1 << kOutEvent); | 162 event_mask |= (1 << kOutEvent); |
168 } | 163 } |
169 if ((events & (POLLHUP | POLLRDHUP)) != 0) { | 164 if ((events & (POLLHUP | POLLRDHUP)) != 0) { |
170 event_mask |= (1 << kCloseEvent); | 165 event_mask |= (1 << kCloseEvent); |
171 } | 166 } |
172 return event_mask; | 167 return event_mask; |
173 } | 168 } |
174 | 169 |
175 | |
176 bool IOHandle::AsyncWaitLocked(mx_handle_t port, | 170 bool IOHandle::AsyncWaitLocked(mx_handle_t port, |
177 uint32_t events, | 171 uint32_t events, |
178 uint64_t key) { | 172 uint64_t key) { |
179 LOG_INFO("IOHandle::AsyncWait: fd = %ld\n", fd_); | 173 LOG_INFO("IOHandle::AsyncWait: fd = %ld\n", fd_); |
180 // The call to __mxio_fd_to_io() in the DescriptorInfo constructor may have | 174 // The call to __mxio_fd_to_io() in the DescriptorInfo constructor may have |
181 // returned NULL. If it did, propagate the problem up to Dart. | 175 // returned NULL. If it did, propagate the problem up to Dart. |
182 if (mxio_ == NULL) { | 176 if (mxio_ == NULL) { |
183 LOG_ERR("__mxio_fd_to_io(%d) returned NULL\n", fd_); | 177 LOG_ERR("__mxio_fd_to_io(%d) returned NULL\n", fd_); |
184 return false; | 178 return false; |
185 } | 179 } |
(...skipping 19 matching lines...) Expand all Loading... |
205 mx_status_t status = | 199 mx_status_t status = |
206 mx_object_wait_async(handle_, port_, key, signals, MX_WAIT_ASYNC_ONCE); | 200 mx_object_wait_async(handle_, port_, key, signals, MX_WAIT_ASYNC_ONCE); |
207 if (status != MX_OK) { | 201 if (status != MX_OK) { |
208 LOG_ERR("mx_object_wait_async failed: %s\n", mx_status_get_string(status)); | 202 LOG_ERR("mx_object_wait_async failed: %s\n", mx_status_get_string(status)); |
209 return false; | 203 return false; |
210 } | 204 } |
211 | 205 |
212 return true; | 206 return true; |
213 } | 207 } |
214 | 208 |
215 | |
216 bool IOHandle::AsyncWait(mx_handle_t port, uint32_t events, uint64_t key) { | 209 bool IOHandle::AsyncWait(mx_handle_t port, uint32_t events, uint64_t key) { |
217 MutexLocker ml(mutex_); | 210 MutexLocker ml(mutex_); |
218 return AsyncWaitLocked(port, events, key); | 211 return AsyncWaitLocked(port, events, key); |
219 } | 212 } |
220 | 213 |
221 | |
222 void IOHandle::CancelWait(mx_handle_t port, uint64_t key) { | 214 void IOHandle::CancelWait(mx_handle_t port, uint64_t key) { |
223 MutexLocker ml(mutex_); | 215 MutexLocker ml(mutex_); |
224 LOG_INFO("IOHandle::CancelWait: fd = %ld\n", fd_); | 216 LOG_INFO("IOHandle::CancelWait: fd = %ld\n", fd_); |
225 ASSERT(port != MX_HANDLE_INVALID); | 217 ASSERT(port != MX_HANDLE_INVALID); |
226 ASSERT(handle_ != MX_HANDLE_INVALID); | 218 ASSERT(handle_ != MX_HANDLE_INVALID); |
227 mx_status_t status = mx_port_cancel(port, handle_, key); | 219 mx_status_t status = mx_port_cancel(port, handle_, key); |
228 if ((status != MX_OK) && (status != MX_ERR_NOT_FOUND)) { | 220 if ((status != MX_OK) && (status != MX_ERR_NOT_FOUND)) { |
229 LOG_ERR("mx_port_cancel failed: %s\n", mx_status_get_string(status)); | 221 LOG_ERR("mx_port_cancel failed: %s\n", mx_status_get_string(status)); |
230 } | 222 } |
231 } | 223 } |
232 | 224 |
233 | |
234 uint32_t IOHandle::WaitEnd(mx_signals_t observed) { | 225 uint32_t IOHandle::WaitEnd(mx_signals_t observed) { |
235 MutexLocker ml(mutex_); | 226 MutexLocker ml(mutex_); |
236 uint32_t events = 0; | 227 uint32_t events = 0; |
237 __mxio_wait_end(mxio_, observed, &events); | 228 __mxio_wait_end(mxio_, observed, &events); |
238 return events; | 229 return events; |
239 } | 230 } |
240 | 231 |
241 | |
242 intptr_t IOHandle::ToggleEvents(intptr_t event_mask) { | 232 intptr_t IOHandle::ToggleEvents(intptr_t event_mask) { |
243 MutexLocker ml(mutex_); | 233 MutexLocker ml(mutex_); |
244 if (!write_events_enabled_) { | 234 if (!write_events_enabled_) { |
245 LOG_INFO("IOHandle::ToggleEvents: fd = %ld de-asserting write\n", fd_); | 235 LOG_INFO("IOHandle::ToggleEvents: fd = %ld de-asserting write\n", fd_); |
246 event_mask = event_mask & ~(1 << kOutEvent); | 236 event_mask = event_mask & ~(1 << kOutEvent); |
247 } | 237 } |
248 if ((event_mask & (1 << kOutEvent)) != 0) { | 238 if ((event_mask & (1 << kOutEvent)) != 0) { |
249 LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting write and disabling\n", | 239 LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting write and disabling\n", |
250 fd_); | 240 fd_); |
251 write_events_enabled_ = false; | 241 write_events_enabled_ = false; |
252 } | 242 } |
253 if (!read_events_enabled_) { | 243 if (!read_events_enabled_) { |
254 LOG_INFO("IOHandle::ToggleEvents: fd=%ld de-asserting read\n", fd_); | 244 LOG_INFO("IOHandle::ToggleEvents: fd=%ld de-asserting read\n", fd_); |
255 event_mask = event_mask & ~(1 << kInEvent); | 245 event_mask = event_mask & ~(1 << kInEvent); |
256 } | 246 } |
257 if ((event_mask & (1 << kInEvent)) != 0) { | 247 if ((event_mask & (1 << kInEvent)) != 0) { |
258 LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting read and disabling\n", | 248 LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting read and disabling\n", |
259 fd_); | 249 fd_); |
260 read_events_enabled_ = false; | 250 read_events_enabled_ = false; |
261 } | 251 } |
262 return event_mask; | 252 return event_mask; |
263 } | 253 } |
264 | 254 |
265 | |
266 void EventHandlerImplementation::AddToPort(mx_handle_t port_handle, | 255 void EventHandlerImplementation::AddToPort(mx_handle_t port_handle, |
267 DescriptorInfo* di) { | 256 DescriptorInfo* di) { |
268 const uint32_t events = di->io_handle()->MaskToEpollEvents(di->Mask()); | 257 const uint32_t events = di->io_handle()->MaskToEpollEvents(di->Mask()); |
269 const uint64_t key = reinterpret_cast<uint64_t>(di); | 258 const uint64_t key = reinterpret_cast<uint64_t>(di); |
270 if (!di->io_handle()->AsyncWait(port_handle, events, key)) { | 259 if (!di->io_handle()->AsyncWait(port_handle, events, key)) { |
271 di->NotifyAllDartPorts(1 << kCloseEvent); | 260 di->NotifyAllDartPorts(1 << kCloseEvent); |
272 } | 261 } |
273 } | 262 } |
274 | 263 |
275 | |
276 void EventHandlerImplementation::RemoveFromPort(mx_handle_t port_handle, | 264 void EventHandlerImplementation::RemoveFromPort(mx_handle_t port_handle, |
277 DescriptorInfo* di) { | 265 DescriptorInfo* di) { |
278 const uint64_t key = reinterpret_cast<uint64_t>(di); | 266 const uint64_t key = reinterpret_cast<uint64_t>(di); |
279 di->io_handle()->CancelWait(port_handle, key); | 267 di->io_handle()->CancelWait(port_handle, key); |
280 } | 268 } |
281 | 269 |
282 | |
283 EventHandlerImplementation::EventHandlerImplementation() | 270 EventHandlerImplementation::EventHandlerImplementation() |
284 : socket_map_(&HashMap::SamePointerValue, 16) { | 271 : socket_map_(&HashMap::SamePointerValue, 16) { |
285 shutdown_ = false; | 272 shutdown_ = false; |
286 // Create the port. | 273 // Create the port. |
287 port_handle_ = MX_HANDLE_INVALID; | 274 port_handle_ = MX_HANDLE_INVALID; |
288 mx_status_t status = mx_port_create(0, &port_handle_); | 275 mx_status_t status = mx_port_create(0, &port_handle_); |
289 if (status != MX_OK) { | 276 if (status != MX_OK) { |
290 // This is a FATAL because the VM won't work at all if we can't create this | 277 // This is a FATAL because the VM won't work at all if we can't create this |
291 // port. | 278 // port. |
292 FATAL1("mx_port_create failed: %s\n", mx_status_get_string(status)); | 279 FATAL1("mx_port_create failed: %s\n", mx_status_get_string(status)); |
293 } | 280 } |
294 ASSERT(port_handle_ != MX_HANDLE_INVALID); | 281 ASSERT(port_handle_ != MX_HANDLE_INVALID); |
295 } | 282 } |
296 | 283 |
297 | |
298 static void DeleteDescriptorInfo(void* info) { | 284 static void DeleteDescriptorInfo(void* info) { |
299 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); | 285 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); |
300 LOG_INFO("Closed %ld\n", di->io_handle()->fd()); | 286 LOG_INFO("Closed %ld\n", di->io_handle()->fd()); |
301 di->Close(); | 287 di->Close(); |
302 delete di; | 288 delete di; |
303 } | 289 } |
304 | 290 |
305 | |
306 EventHandlerImplementation::~EventHandlerImplementation() { | 291 EventHandlerImplementation::~EventHandlerImplementation() { |
307 socket_map_.Clear(DeleteDescriptorInfo); | 292 socket_map_.Clear(DeleteDescriptorInfo); |
308 mx_handle_close(port_handle_); | 293 mx_handle_close(port_handle_); |
309 port_handle_ = MX_HANDLE_INVALID; | 294 port_handle_ = MX_HANDLE_INVALID; |
310 } | 295 } |
311 | 296 |
312 | |
313 void EventHandlerImplementation::UpdatePort(intptr_t old_mask, | 297 void EventHandlerImplementation::UpdatePort(intptr_t old_mask, |
314 DescriptorInfo* di) { | 298 DescriptorInfo* di) { |
315 const intptr_t new_mask = di->Mask(); | 299 const intptr_t new_mask = di->Mask(); |
316 if ((old_mask != 0) && (new_mask == 0)) { | 300 if ((old_mask != 0) && (new_mask == 0)) { |
317 RemoveFromPort(port_handle_, di); | 301 RemoveFromPort(port_handle_, di); |
318 } else if ((old_mask == 0) && (new_mask != 0)) { | 302 } else if ((old_mask == 0) && (new_mask != 0)) { |
319 AddToPort(port_handle_, di); | 303 AddToPort(port_handle_, di); |
320 } else if ((old_mask != 0) && (new_mask != 0)) { | 304 } else if ((old_mask != 0) && (new_mask != 0)) { |
321 ASSERT(!di->IsListeningSocket()); | 305 ASSERT(!di->IsListeningSocket()); |
322 RemoveFromPort(port_handle_, di); | 306 RemoveFromPort(port_handle_, di); |
323 AddToPort(port_handle_, di); | 307 AddToPort(port_handle_, di); |
324 } | 308 } |
325 } | 309 } |
326 | 310 |
327 | |
328 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( | 311 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( |
329 intptr_t fd, | 312 intptr_t fd, |
330 bool is_listening) { | 313 bool is_listening) { |
331 IOHandle* handle = reinterpret_cast<IOHandle*>(fd); | 314 IOHandle* handle = reinterpret_cast<IOHandle*>(fd); |
332 ASSERT(handle->fd() >= 0); | 315 ASSERT(handle->fd() >= 0); |
333 HashMap::Entry* entry = | 316 HashMap::Entry* entry = |
334 socket_map_.Lookup(GetHashmapKeyFromFd(handle->fd()), | 317 socket_map_.Lookup(GetHashmapKeyFromFd(handle->fd()), |
335 GetHashmapHashFromFd(handle->fd()), true); | 318 GetHashmapHashFromFd(handle->fd()), true); |
336 ASSERT(entry != NULL); | 319 ASSERT(entry != NULL); |
337 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); | 320 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); |
338 if (di == NULL) { | 321 if (di == NULL) { |
339 // If there is no data in the hash map for this file descriptor a | 322 // If there is no data in the hash map for this file descriptor a |
340 // new DescriptorInfo for the file descriptor is inserted. | 323 // new DescriptorInfo for the file descriptor is inserted. |
341 if (is_listening) { | 324 if (is_listening) { |
342 di = new DescriptorInfoMultiple(fd); | 325 di = new DescriptorInfoMultiple(fd); |
343 } else { | 326 } else { |
344 di = new DescriptorInfoSingle(fd); | 327 di = new DescriptorInfoSingle(fd); |
345 } | 328 } |
346 entry->value = di; | 329 entry->value = di; |
347 } | 330 } |
348 ASSERT(fd == di->fd()); | 331 ASSERT(fd == di->fd()); |
349 return di; | 332 return di; |
350 } | 333 } |
351 | 334 |
352 | |
353 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 335 void EventHandlerImplementation::WakeupHandler(intptr_t id, |
354 Dart_Port dart_port, | 336 Dart_Port dart_port, |
355 int64_t data) { | 337 int64_t data) { |
356 COMPILE_ASSERT(sizeof(InterruptMessage) <= sizeof(mx_packet_user_t)); | 338 COMPILE_ASSERT(sizeof(InterruptMessage) <= sizeof(mx_packet_user_t)); |
357 mx_port_packet_t pkt; | 339 mx_port_packet_t pkt; |
358 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(&pkt.user); | 340 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(&pkt.user); |
359 pkt.key = kInterruptPacketKey; | 341 pkt.key = kInterruptPacketKey; |
360 msg->id = id; | 342 msg->id = id; |
361 msg->dart_port = dart_port; | 343 msg->dart_port = dart_port; |
362 msg->data = data; | 344 msg->data = data; |
363 mx_status_t status = | 345 mx_status_t status = |
364 mx_port_queue(port_handle_, reinterpret_cast<void*>(&pkt), 0); | 346 mx_port_queue(port_handle_, reinterpret_cast<void*>(&pkt), 0); |
365 if (status != MX_OK) { | 347 if (status != MX_OK) { |
366 // This is a FATAL because the VM won't work at all if we can't send any | 348 // This is a FATAL because the VM won't work at all if we can't send any |
367 // messages to the EventHandler thread. | 349 // messages to the EventHandler thread. |
368 FATAL1("mx_port_queue failed: %s\n", mx_status_get_string(status)); | 350 FATAL1("mx_port_queue failed: %s\n", mx_status_get_string(status)); |
369 } | 351 } |
370 } | 352 } |
371 | 353 |
372 | |
373 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { | 354 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { |
374 if (msg->id == kTimerId) { | 355 if (msg->id == kTimerId) { |
375 LOG_INFO("HandleInterrupt read timer update\n"); | 356 LOG_INFO("HandleInterrupt read timer update\n"); |
376 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); | 357 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); |
377 return; | 358 return; |
378 } else if (msg->id == kShutdownId) { | 359 } else if (msg->id == kShutdownId) { |
379 LOG_INFO("HandleInterrupt read shutdown\n"); | 360 LOG_INFO("HandleInterrupt read shutdown\n"); |
380 shutdown_ = true; | 361 shutdown_ = true; |
381 return; | 362 return; |
382 } | 363 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 const intptr_t old_mask = di->Mask(); | 435 const intptr_t old_mask = di->Mask(); |
455 LOG_INFO("\t Set Event Mask: %ld: %lx %lx\n", fd, old_mask, | 436 LOG_INFO("\t Set Event Mask: %ld: %lx %lx\n", fd, old_mask, |
456 msg->data & EVENT_MASK); | 437 msg->data & EVENT_MASK); |
457 di->SetPortAndMask(msg->dart_port, msg->data & EVENT_MASK); | 438 di->SetPortAndMask(msg->dart_port, msg->data & EVENT_MASK); |
458 UpdatePort(old_mask, di); | 439 UpdatePort(old_mask, di); |
459 } else { | 440 } else { |
460 UNREACHABLE(); | 441 UNREACHABLE(); |
461 } | 442 } |
462 } | 443 } |
463 | 444 |
464 | |
465 void EventHandlerImplementation::HandlePacket(mx_port_packet_t* pkt) { | 445 void EventHandlerImplementation::HandlePacket(mx_port_packet_t* pkt) { |
466 LOG_INFO("HandlePacket: Got event packet: key=%lx\n", pkt->key); | 446 LOG_INFO("HandlePacket: Got event packet: key=%lx\n", pkt->key); |
467 LOG_INFO("HandlePacket: Got event packet: type=%lx\n", pkt->type); | 447 LOG_INFO("HandlePacket: Got event packet: type=%lx\n", pkt->type); |
468 LOG_INFO("HandlePacket: Got event packet: status=%ld\n", pkt->status); | 448 LOG_INFO("HandlePacket: Got event packet: status=%ld\n", pkt->status); |
469 if (pkt->type == MX_PKT_TYPE_USER) { | 449 if (pkt->type == MX_PKT_TYPE_USER) { |
470 ASSERT(pkt->key == kInterruptPacketKey); | 450 ASSERT(pkt->key == kInterruptPacketKey); |
471 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(&pkt->user); | 451 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(&pkt->user); |
472 HandleInterrupt(msg); | 452 HandleInterrupt(msg); |
473 return; | 453 return; |
474 } | 454 } |
(...skipping 17 matching lines...) Expand all Loading... |
492 if (!success) { | 472 if (!success) { |
493 // This can happen if e.g. the isolate that owns the port has died | 473 // This can happen if e.g. the isolate that owns the port has died |
494 // for some reason. | 474 // for some reason. |
495 LOG_INFO("Failed to post event to port %ld\n", port); | 475 LOG_INFO("Failed to post event to port %ld\n", port); |
496 } | 476 } |
497 } | 477 } |
498 } | 478 } |
499 UpdatePort(old_mask, di); | 479 UpdatePort(old_mask, di); |
500 } | 480 } |
501 | 481 |
502 | |
503 int64_t EventHandlerImplementation::GetTimeout() const { | 482 int64_t EventHandlerImplementation::GetTimeout() const { |
504 if (!timeout_queue_.HasTimeout()) { | 483 if (!timeout_queue_.HasTimeout()) { |
505 return kInfinityTimeout; | 484 return kInfinityTimeout; |
506 } | 485 } |
507 int64_t millis = | 486 int64_t millis = |
508 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); | 487 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); |
509 return (millis < 0) ? 0 : millis; | 488 return (millis < 0) ? 0 : millis; |
510 } | 489 } |
511 | 490 |
512 | |
513 void EventHandlerImplementation::HandleTimeout() { | 491 void EventHandlerImplementation::HandleTimeout() { |
514 if (timeout_queue_.HasTimeout()) { | 492 if (timeout_queue_.HasTimeout()) { |
515 int64_t millis = timeout_queue_.CurrentTimeout() - | 493 int64_t millis = timeout_queue_.CurrentTimeout() - |
516 TimerUtils::GetCurrentMonotonicMillis(); | 494 TimerUtils::GetCurrentMonotonicMillis(); |
517 if (millis <= 0) { | 495 if (millis <= 0) { |
518 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 496 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
519 timeout_queue_.RemoveCurrent(); | 497 timeout_queue_.RemoveCurrent(); |
520 } | 498 } |
521 } | 499 } |
522 } | 500 } |
523 | 501 |
524 | |
525 void EventHandlerImplementation::Poll(uword args) { | 502 void EventHandlerImplementation::Poll(uword args) { |
526 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 503 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
527 EventHandlerImplementation* handler_impl = &handler->delegate_; | 504 EventHandlerImplementation* handler_impl = &handler->delegate_; |
528 ASSERT(handler_impl != NULL); | 505 ASSERT(handler_impl != NULL); |
529 | 506 |
530 mx_port_packet_t pkt; | 507 mx_port_packet_t pkt; |
531 while (!handler_impl->shutdown_) { | 508 while (!handler_impl->shutdown_) { |
532 int64_t millis = handler_impl->GetTimeout(); | 509 int64_t millis = handler_impl->GetTimeout(); |
533 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); | 510 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); |
534 | 511 |
535 LOG_INFO("mx_port_wait(millis = %ld)\n", millis); | 512 LOG_INFO("mx_port_wait(millis = %ld)\n", millis); |
536 mx_status_t status = mx_port_wait(handler_impl->port_handle_, | 513 mx_status_t status = mx_port_wait(handler_impl->port_handle_, |
537 millis == kInfinityTimeout | 514 millis == kInfinityTimeout |
538 ? MX_TIME_INFINITE | 515 ? MX_TIME_INFINITE |
539 : mx_deadline_after(MX_MSEC(millis)), | 516 : mx_deadline_after(MX_MSEC(millis)), |
540 reinterpret_cast<void*>(&pkt), 0); | 517 reinterpret_cast<void*>(&pkt), 0); |
541 if (status == MX_ERR_TIMED_OUT) { | 518 if (status == MX_ERR_TIMED_OUT) { |
542 handler_impl->HandleTimeout(); | 519 handler_impl->HandleTimeout(); |
543 } else if (status != MX_OK) { | 520 } else if (status != MX_OK) { |
544 FATAL1("mx_port_wait failed: %s\n", mx_status_get_string(status)); | 521 FATAL1("mx_port_wait failed: %s\n", mx_status_get_string(status)); |
545 } else { | 522 } else { |
546 handler_impl->HandleTimeout(); | 523 handler_impl->HandleTimeout(); |
547 handler_impl->HandlePacket(&pkt); | 524 handler_impl->HandlePacket(&pkt); |
548 } | 525 } |
549 } | 526 } |
550 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); | 527 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); |
551 handler->NotifyShutdownDone(); | 528 handler->NotifyShutdownDone(); |
552 } | 529 } |
553 | 530 |
554 | |
555 void EventHandlerImplementation::Start(EventHandler* handler) { | 531 void EventHandlerImplementation::Start(EventHandler* handler) { |
556 int result = Thread::Start(&EventHandlerImplementation::Poll, | 532 int result = Thread::Start(&EventHandlerImplementation::Poll, |
557 reinterpret_cast<uword>(handler)); | 533 reinterpret_cast<uword>(handler)); |
558 if (result != 0) { | 534 if (result != 0) { |
559 FATAL1("Failed to start event handler thread %d", result); | 535 FATAL1("Failed to start event handler thread %d", result); |
560 } | 536 } |
561 } | 537 } |
562 | 538 |
563 | |
564 void EventHandlerImplementation::Shutdown() { | 539 void EventHandlerImplementation::Shutdown() { |
565 SendData(kShutdownId, 0, 0); | 540 SendData(kShutdownId, 0, 0); |
566 } | 541 } |
567 | 542 |
568 | |
569 void EventHandlerImplementation::SendData(intptr_t id, | 543 void EventHandlerImplementation::SendData(intptr_t id, |
570 Dart_Port dart_port, | 544 Dart_Port dart_port, |
571 int64_t data) { | 545 int64_t data) { |
572 WakeupHandler(id, dart_port, data); | 546 WakeupHandler(id, dart_port, data); |
573 } | 547 } |
574 | 548 |
575 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { | 549 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { |
576 // The hashmap does not support keys with value 0. | 550 // The hashmap does not support keys with value 0. |
577 return reinterpret_cast<void*>(fd + 1); | 551 return reinterpret_cast<void*>(fd + 1); |
578 } | 552 } |
579 | 553 |
580 | |
581 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 554 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
582 // The hashmap does not support keys with value 0. | 555 // The hashmap does not support keys with value 0. |
583 return dart::Utils::WordHash(fd + 1); | 556 return dart::Utils::WordHash(fd + 1); |
584 } | 557 } |
585 | 558 |
586 } // namespace bin | 559 } // namespace bin |
587 } // namespace dart | 560 } // namespace dart |
588 | 561 |
589 #endif // defined(HOST_OS_FUCHSIA) | 562 #endif // defined(HOST_OS_FUCHSIA) |
590 | 563 |
591 #endif // !defined(DART_IO_DISABLED) | 564 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |