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

Side by Side Diff: runtime/bin/eventhandler_linux.cc

Issue 10693039: Terminate event handler thread on isolate shutdown. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Adding new file to gyp file Created 8 years, 5 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 | « runtime/bin/eventhandler_linux.h ('k') | runtime/bin/eventhandler_macos.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 "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
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
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
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
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 }
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_linux.h ('k') | runtime/bin/eventhandler_macos.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698