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 15 matching lines...) Expand all Loading... |
26 UNREACHABLE(); | 26 UNREACHABLE(); |
27 return 0; | 27 return 0; |
28 } | 28 } |
29 return ((static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec) / 1000; | 29 return ((static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec) / 1000; |
30 } | 30 } |
31 | 31 |
32 | 32 |
33 static const int kInterruptMessageSize = sizeof(InterruptMessage); | 33 static const int kInterruptMessageSize = sizeof(InterruptMessage); |
34 static const int kInfinityTimeout = -1; | 34 static const int kInfinityTimeout = -1; |
35 static const int kTimerId = -1; | 35 static const int kTimerId = -1; |
| 36 static const int kShutdownId = -2; |
36 | 37 |
37 | 38 |
38 intptr_t SocketData::GetPollEvents() { | 39 intptr_t SocketData::GetPollEvents() { |
39 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are | 40 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are |
40 // triggered anyway. | 41 // triggered anyway. |
41 intptr_t events = 0; | 42 intptr_t events = 0; |
42 if (!IsClosedRead()) { | 43 if (!IsClosedRead()) { |
43 if ((mask_ & (1 << kInEvent)) != 0) { | 44 if ((mask_ & (1 << kInEvent)) != 0) { |
44 events |= EPOLLIN; | 45 events |= EPOLLIN; |
45 } | 46 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 EventHandlerImplementation::EventHandlerImplementation() | 99 EventHandlerImplementation::EventHandlerImplementation() |
99 : socket_map_(&HashMap::SamePointerValue, 16) { | 100 : socket_map_(&HashMap::SamePointerValue, 16) { |
100 intptr_t result; | 101 intptr_t result; |
101 result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_)); | 102 result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_)); |
102 if (result != 0) { | 103 if (result != 0) { |
103 FATAL("Pipe creation failed"); | 104 FATAL("Pipe creation failed"); |
104 } | 105 } |
105 FDUtils::SetNonBlocking(interrupt_fds_[0]); | 106 FDUtils::SetNonBlocking(interrupt_fds_[0]); |
106 timeout_ = kInfinityTimeout; | 107 timeout_ = kInfinityTimeout; |
107 timeout_port_ = 0; | 108 timeout_port_ = 0; |
| 109 shutdown_ = false; |
108 // The initial size passed to epoll_create is ignore on newer (>= | 110 // The initial size passed to epoll_create is ignore on newer (>= |
109 // 2.6.8) Linux versions | 111 // 2.6.8) Linux versions |
110 static const int kEpollInitialSize = 64; | 112 static const int kEpollInitialSize = 64; |
111 epoll_fd_ = TEMP_FAILURE_RETRY(epoll_create(kEpollInitialSize)); | 113 epoll_fd_ = TEMP_FAILURE_RETRY(epoll_create(kEpollInitialSize)); |
112 if (epoll_fd_ == -1) { | 114 if (epoll_fd_ == -1) { |
113 FATAL("Failed creating epoll file descriptor"); | 115 FATAL("Failed creating epoll file descriptor"); |
114 } | 116 } |
115 // Register the interrupt_fd with the epoll instance. | 117 // Register the interrupt_fd with the epoll instance. |
116 struct epoll_event event; | 118 struct epoll_event event; |
117 event.events = EPOLLIN; | 119 event.events = EPOLLIN; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 } | 188 } |
187 return (total_read == kInterruptMessageSize) ? true : false; | 189 return (total_read == kInterruptMessageSize) ? true : false; |
188 } | 190 } |
189 | 191 |
190 void EventHandlerImplementation::HandleInterruptFd() { | 192 void EventHandlerImplementation::HandleInterruptFd() { |
191 InterruptMessage msg; | 193 InterruptMessage msg; |
192 while (GetInterruptMessage(&msg)) { | 194 while (GetInterruptMessage(&msg)) { |
193 if (msg.id == kTimerId) { | 195 if (msg.id == kTimerId) { |
194 timeout_ = msg.data; | 196 timeout_ = msg.data; |
195 timeout_port_ = msg.dart_port; | 197 timeout_port_ = msg.dart_port; |
| 198 } else if (msg.id == kShutdownId) { |
| 199 shutdown_ = true; |
196 } else { | 200 } else { |
197 SocketData* sd = GetSocketData(msg.id); | 201 SocketData* sd = GetSocketData(msg.id); |
198 if ((msg.data & (1 << kShutdownReadCommand)) != 0) { | 202 if ((msg.data & (1 << kShutdownReadCommand)) != 0) { |
199 ASSERT(msg.data == (1 << kShutdownReadCommand)); | 203 ASSERT(msg.data == (1 << kShutdownReadCommand)); |
200 // Close the socket for reading. | 204 // Close the socket for reading. |
201 sd->ShutdownRead(); | 205 sd->ShutdownRead(); |
202 UpdateEpollInstance(epoll_fd_, sd); | 206 UpdateEpollInstance(epoll_fd_, sd); |
203 } else if ((msg.data & (1 << kShutdownWriteCommand)) != 0) { | 207 } else if ((msg.data & (1 << kShutdownWriteCommand)) != 0) { |
204 ASSERT(msg.data == (1 << kShutdownWriteCommand)); | 208 ASSERT(msg.data == (1 << kShutdownWriteCommand)); |
205 // Close the socket for writing. | 209 // Close the socket for writing. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 } | 370 } |
367 } | 371 } |
368 | 372 |
369 | 373 |
370 void EventHandlerImplementation::Poll(uword args) { | 374 void EventHandlerImplementation::Poll(uword args) { |
371 static const intptr_t kMaxEvents = 16; | 375 static const intptr_t kMaxEvents = 16; |
372 struct epoll_event events[kMaxEvents]; | 376 struct epoll_event events[kMaxEvents]; |
373 EventHandlerImplementation* handler = | 377 EventHandlerImplementation* handler = |
374 reinterpret_cast<EventHandlerImplementation*>(args); | 378 reinterpret_cast<EventHandlerImplementation*>(args); |
375 ASSERT(handler != NULL); | 379 ASSERT(handler != NULL); |
376 while (1) { | 380 while (!handler->shutdown_) { |
377 intptr_t millis = handler->GetTimeout(); | 381 intptr_t millis = handler->GetTimeout(); |
378 intptr_t result = TEMP_FAILURE_RETRY(epoll_wait(handler->epoll_fd_, | 382 intptr_t result = TEMP_FAILURE_RETRY(epoll_wait(handler->epoll_fd_, |
379 events, | 383 events, |
380 kMaxEvents, | 384 kMaxEvents, |
381 millis)); | 385 millis)); |
382 ASSERT(EAGAIN == EWOULDBLOCK); | 386 ASSERT(EAGAIN == EWOULDBLOCK); |
383 if (result == -1) { | 387 if (result == -1) { |
384 if (errno != EWOULDBLOCK) { | 388 if (errno != EWOULDBLOCK) { |
385 perror("Poll failed"); | 389 perror("Poll failed"); |
386 } | 390 } |
387 } else { | 391 } else { |
388 handler->HandleTimeout(); | 392 handler->HandleTimeout(); |
389 handler->HandleEvents(events, result); | 393 handler->HandleEvents(events, result); |
390 } | 394 } |
391 } | 395 } |
392 } | 396 } |
393 | 397 |
394 | 398 |
395 void EventHandlerImplementation::StartEventHandler() { | 399 void EventHandlerImplementation::Start() { |
396 int result = dart::Thread::Start(&EventHandlerImplementation::Poll, | 400 int result = dart::Thread::Start(&EventHandlerImplementation::Poll, |
397 reinterpret_cast<uword>(this)); | 401 reinterpret_cast<uword>(this)); |
398 if (result != 0) { | 402 if (result != 0) { |
399 FATAL1("Failed to start event handler thread %d", result); | 403 FATAL1("Failed to start event handler thread %d", result); |
400 } | 404 } |
401 } | 405 } |
402 | 406 |
403 | 407 |
| 408 void EventHandlerImplementation::Shutdown() { |
| 409 SendData(kShutdownId, 0, 0); |
| 410 } |
| 411 |
| 412 |
404 void EventHandlerImplementation::SendData(intptr_t id, | 413 void EventHandlerImplementation::SendData(intptr_t id, |
405 Dart_Port dart_port, | 414 Dart_Port dart_port, |
406 intptr_t data) { | 415 intptr_t data) { |
407 WakeupHandler(id, dart_port, data); | 416 WakeupHandler(id, dart_port, data); |
408 } | 417 } |
409 | 418 |
410 | 419 |
411 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { | 420 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { |
412 // The hashmap does not support keys with value 0. | 421 // The hashmap does not support keys with value 0. |
413 return reinterpret_cast<void*>(fd + 1); | 422 return reinterpret_cast<void*>(fd + 1); |
414 } | 423 } |
415 | 424 |
416 | 425 |
417 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 426 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
418 // The hashmap does not support keys with value 0. | 427 // The hashmap does not support keys with value 0. |
419 return dart::Utils::WordHash(fd + 1); | 428 return dart::Utils::WordHash(fd + 1); |
420 } | 429 } |
OLD | NEW |