OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "bin/eventhandler.h" | 5 #include "bin/eventhandler.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <pthread.h> | 8 #include <pthread.h> |
9 #include <stdio.h> | 9 #include <stdio.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 14 matching lines...) Expand all Loading... |
25 UNREACHABLE(); | 25 UNREACHABLE(); |
26 return 0; | 26 return 0; |
27 } | 27 } |
28 return ((static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec) / 1000; | 28 return ((static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec) / 1000; |
29 } | 29 } |
30 | 30 |
31 | 31 |
32 static const int kInterruptMessageSize = sizeof(InterruptMessage); | 32 static const int kInterruptMessageSize = sizeof(InterruptMessage); |
33 static const int kInfinityTimeout = -1; | 33 static const int kInfinityTimeout = -1; |
34 static const int kTimerId = -1; | 34 static const int kTimerId = -1; |
| 35 static const int kShutdownId = -2; |
35 | 36 |
36 | 37 |
37 bool SocketData::HasReadEvent() { | 38 bool SocketData::HasReadEvent() { |
38 return !IsClosedRead() && ((mask_ & (1 << kInEvent)) != 0); | 39 return !IsClosedRead() && ((mask_ & (1 << kInEvent)) != 0); |
39 } | 40 } |
40 | 41 |
41 | 42 |
42 bool SocketData::HasWriteEvent() { | 43 bool SocketData::HasWriteEvent() { |
43 return !IsClosedWrite() && ((mask_ & (1 << kOutEvent)) != 0); | 44 return !IsClosedWrite() && ((mask_ & (1 << kOutEvent)) != 0); |
44 } | 45 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 EventHandlerImplementation::EventHandlerImplementation() | 117 EventHandlerImplementation::EventHandlerImplementation() |
117 : socket_map_(&HashMap::SamePointerValue, 16) { | 118 : socket_map_(&HashMap::SamePointerValue, 16) { |
118 intptr_t result; | 119 intptr_t result; |
119 result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_)); | 120 result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_)); |
120 if (result != 0) { | 121 if (result != 0) { |
121 FATAL("Pipe creation failed"); | 122 FATAL("Pipe creation failed"); |
122 } | 123 } |
123 FDUtils::SetNonBlocking(interrupt_fds_[0]); | 124 FDUtils::SetNonBlocking(interrupt_fds_[0]); |
124 timeout_ = kInfinityTimeout; | 125 timeout_ = kInfinityTimeout; |
125 timeout_port_ = 0; | 126 timeout_port_ = 0; |
| 127 shutdown_ = false; |
126 | 128 |
127 kqueue_fd_ = TEMP_FAILURE_RETRY(kqueue()); | 129 kqueue_fd_ = TEMP_FAILURE_RETRY(kqueue()); |
128 if (kqueue_fd_ == -1) { | 130 if (kqueue_fd_ == -1) { |
129 FATAL("Failed creating kqueue"); | 131 FATAL("Failed creating kqueue"); |
130 } | 132 } |
131 // Register the interrupt_fd with the kqueue. | 133 // Register the interrupt_fd with the kqueue. |
132 struct kevent event; | 134 struct kevent event; |
133 EV_SET(&event, interrupt_fds_[0], EVFILT_READ, EV_ADD, 0, 0, NULL); | 135 EV_SET(&event, interrupt_fds_[0], EVFILT_READ, EV_ADD, 0, 0, NULL); |
134 int status = TEMP_FAILURE_RETRY(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL)); | 136 int status = TEMP_FAILURE_RETRY(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL)); |
135 if (status == -1) { | 137 if (status == -1) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 } | 200 } |
199 return (total_read == kInterruptMessageSize) ? true : false; | 201 return (total_read == kInterruptMessageSize) ? true : false; |
200 } | 202 } |
201 | 203 |
202 void EventHandlerImplementation::HandleInterruptFd() { | 204 void EventHandlerImplementation::HandleInterruptFd() { |
203 InterruptMessage msg; | 205 InterruptMessage msg; |
204 while (GetInterruptMessage(&msg)) { | 206 while (GetInterruptMessage(&msg)) { |
205 if (msg.id == kTimerId) { | 207 if (msg.id == kTimerId) { |
206 timeout_ = msg.data; | 208 timeout_ = msg.data; |
207 timeout_port_ = msg.dart_port; | 209 timeout_port_ = msg.dart_port; |
| 210 } else if (msg.id == kShutdownId) { |
| 211 shutdown_ = true; |
208 } else { | 212 } else { |
209 SocketData* sd = GetSocketData(msg.id); | 213 SocketData* sd = GetSocketData(msg.id); |
210 if ((msg.data & (1 << kShutdownReadCommand)) != 0) { | 214 if ((msg.data & (1 << kShutdownReadCommand)) != 0) { |
211 ASSERT(msg.data == (1 << kShutdownReadCommand)); | 215 ASSERT(msg.data == (1 << kShutdownReadCommand)); |
212 // Close the socket for reading. | 216 // Close the socket for reading. |
213 sd->ShutdownRead(); | 217 sd->ShutdownRead(); |
214 UpdateKqueue(kqueue_fd_, sd); | 218 UpdateKqueue(kqueue_fd_, sd); |
215 } else if ((msg.data & (1 << kShutdownWriteCommand)) != 0) { | 219 } else if ((msg.data & (1 << kShutdownWriteCommand)) != 0) { |
216 ASSERT(msg.data == (1 << kShutdownWriteCommand)); | 220 ASSERT(msg.data == (1 << kShutdownWriteCommand)); |
217 // Close the socket for writing. | 221 // Close the socket for writing. |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 } | 354 } |
351 } | 355 } |
352 | 356 |
353 | 357 |
354 void EventHandlerImplementation::EventHandlerEntry(uword args) { | 358 void EventHandlerImplementation::EventHandlerEntry(uword args) { |
355 static const intptr_t kMaxEvents = 16; | 359 static const intptr_t kMaxEvents = 16; |
356 struct kevent events[kMaxEvents]; | 360 struct kevent events[kMaxEvents]; |
357 EventHandlerImplementation* handler = | 361 EventHandlerImplementation* handler = |
358 reinterpret_cast<EventHandlerImplementation*>(args); | 362 reinterpret_cast<EventHandlerImplementation*>(args); |
359 ASSERT(handler != NULL); | 363 ASSERT(handler != NULL); |
360 while (1) { | 364 while (!handler->shutdown_) { |
361 intptr_t millis = handler->GetTimeout(); | 365 intptr_t millis = handler->GetTimeout(); |
362 // NULL pointer timespec for infinite timeout. | 366 // NULL pointer timespec for infinite timeout. |
363 ASSERT(kInfinityTimeout < 0); | 367 ASSERT(kInfinityTimeout < 0); |
364 struct timespec* timeout = NULL; | 368 struct timespec* timeout = NULL; |
365 struct timespec ts; | 369 struct timespec ts; |
366 if (millis >= 0) { | 370 if (millis >= 0) { |
367 ts.tv_sec = millis / 1000; | 371 ts.tv_sec = millis / 1000; |
368 ts.tv_nsec = (millis - (ts.tv_sec * 1000)) * 1000000; | 372 ts.tv_nsec = (millis - (ts.tv_sec * 1000)) * 1000000; |
369 timeout = &ts; | 373 timeout = &ts; |
370 } | 374 } |
371 intptr_t result = TEMP_FAILURE_RETRY(kevent(handler->kqueue_fd_, | 375 intptr_t result = TEMP_FAILURE_RETRY(kevent(handler->kqueue_fd_, |
372 NULL, | 376 NULL, |
373 0, | 377 0, |
374 events, | 378 events, |
375 kMaxEvents, | 379 kMaxEvents, |
376 timeout)); | 380 timeout)); |
377 if (result == -1) { | 381 if (result == -1) { |
378 FATAL1("kevent failed %s\n", strerror(errno)); | 382 FATAL1("kevent failed %s\n", strerror(errno)); |
379 } else { | 383 } else { |
380 handler->HandleTimeout(); | 384 handler->HandleTimeout(); |
381 handler->HandleEvents(events, result); | 385 handler->HandleEvents(events, result); |
382 } | 386 } |
383 } | 387 } |
384 } | 388 } |
385 | 389 |
386 | 390 |
387 void EventHandlerImplementation::StartEventHandler() { | 391 void EventHandlerImplementation::Start() { |
388 int result = | 392 int result = |
389 dart::Thread::Start(&EventHandlerImplementation::EventHandlerEntry, | 393 dart::Thread::Start(&EventHandlerImplementation::EventHandlerEntry, |
390 reinterpret_cast<uword>(this)); | 394 reinterpret_cast<uword>(this)); |
391 if (result != 0) { | 395 if (result != 0) { |
392 FATAL1("Failed to start event handler thread %d", result); | 396 FATAL1("Failed to start event handler thread %d", result); |
393 } | 397 } |
394 } | 398 } |
395 | 399 |
396 | 400 |
| 401 void EventHandlerImplementation::Shutdown() { |
| 402 SendData(kShutdownId, 0, 0); |
| 403 } |
| 404 |
| 405 |
397 void EventHandlerImplementation::SendData(intptr_t id, | 406 void EventHandlerImplementation::SendData(intptr_t id, |
398 Dart_Port dart_port, | 407 Dart_Port dart_port, |
399 intptr_t data) { | 408 intptr_t data) { |
400 WakeupHandler(id, dart_port, data); | 409 WakeupHandler(id, dart_port, data); |
401 } | 410 } |
402 | 411 |
403 | 412 |
404 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { | 413 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { |
405 // The hashmap does not support keys with value 0. | 414 // The hashmap does not support keys with value 0. |
406 return reinterpret_cast<void*>(fd + 1); | 415 return reinterpret_cast<void*>(fd + 1); |
407 } | 416 } |
408 | 417 |
409 | 418 |
410 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 419 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
411 // The hashmap does not support keys with value 0. | 420 // The hashmap does not support keys with value 0. |
412 return dart::Utils::WordHash(fd + 1); | 421 return dart::Utils::WordHash(fd + 1); |
413 } | 422 } |
OLD | NEW |