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

Side by Side Diff: runtime/bin/eventhandler_macos.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_macos.h ('k') | runtime/bin/eventhandler_win.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 14 matching lines...) Expand all
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
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
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
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 }
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_macos.h ('k') | runtime/bin/eventhandler_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698