Wait for eventhandler to shut down before exiting
R=sgjesse@google.com Review URL: https://codereview.chromium.org//875403006 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@43504 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
@@ -4,7 +4,9 @@
|
||||
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/eventhandler.h"
|
||||
#include "bin/lockers.h"
|
||||
#include "bin/socket.h"
|
||||
#include "bin/thread.h"
|
||||
|
||||
#include "include/dart_api.h"
|
||||
|
||||
@@ -57,19 +59,40 @@ void TimeoutQueue::UpdateTimeout(Dart_Port port, int64_t timeout) {
|
||||
|
||||
|
||||
static EventHandler* event_handler = NULL;
|
||||
static Monitor *shutdown_monitor = NULL;
|
||||
|
||||
|
||||
void EventHandler::Start() {
|
||||
ASSERT(event_handler == NULL);
|
||||
shutdown_monitor = new Monitor();
|
||||
event_handler = new EventHandler();
|
||||
event_handler->delegate_.Start(event_handler);
|
||||
}
|
||||
|
||||
|
||||
void EventHandler::NotifyShutdownDone() {
|
||||
MonitorLocker ml(shutdown_monitor);
|
||||
ml.Notify();
|
||||
}
|
||||
|
||||
|
||||
void EventHandler::Stop() {
|
||||
if (event_handler == NULL) return;
|
||||
event_handler->delegate_.Shutdown();
|
||||
|
||||
// Wait until it has stopped.
|
||||
{
|
||||
MonitorLocker ml(shutdown_monitor);
|
||||
|
||||
// Signal to event handler that we want it to stop.
|
||||
event_handler->delegate_.Shutdown();
|
||||
ml.Wait(Monitor::kNoTimeout);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
delete event_handler;
|
||||
event_handler = NULL;
|
||||
delete shutdown_monitor;
|
||||
shutdown_monitor = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -119,6 +119,11 @@ class EventHandler {
|
||||
delegate_.SendData(id, dart_port, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal to main thread that event handler is done.
|
||||
*/
|
||||
void NotifyShutdownDone();
|
||||
|
||||
/**
|
||||
* Start the event-handler.
|
||||
*/
|
||||
|
||||
@@ -299,25 +299,27 @@ void EventHandlerImplementation::Poll(uword args) {
|
||||
ThreadSignalBlocker signal_blocker(SIGPROF);
|
||||
static const intptr_t kMaxEvents = 16;
|
||||
struct epoll_event events[kMaxEvents];
|
||||
EventHandlerImplementation* handler =
|
||||
reinterpret_cast<EventHandlerImplementation*>(args);
|
||||
ASSERT(handler != NULL);
|
||||
while (!handler->shutdown_) {
|
||||
int64_t millis = handler->GetTimeout();
|
||||
EventHandler* handler = reinterpret_cast<EventHandler*>(args);
|
||||
EventHandlerImplementation* handler_impl = &handler->delegate_;
|
||||
ASSERT(handler_impl != NULL);
|
||||
|
||||
while (!handler_impl->shutdown_) {
|
||||
int64_t millis = handler_impl->GetTimeout();
|
||||
ASSERT(millis == kInfinityTimeout || millis >= 0);
|
||||
if (millis > kMaxInt32) millis = kMaxInt32;
|
||||
intptr_t result = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
|
||||
epoll_wait(handler->epoll_fd_, events, kMaxEvents, millis));
|
||||
epoll_wait(handler_impl->epoll_fd_, events, kMaxEvents, millis));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if (result == -1) {
|
||||
if (errno != EWOULDBLOCK) {
|
||||
perror("Poll failed");
|
||||
}
|
||||
} else {
|
||||
handler->HandleTimeout();
|
||||
handler->HandleEvents(events, result);
|
||||
handler_impl->HandleTimeout();
|
||||
handler_impl->HandleEvents(events, result);
|
||||
}
|
||||
}
|
||||
handler->NotifyShutdownDone();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -315,6 +315,7 @@ void EventHandlerImplementation::Poll(uword args) {
|
||||
EventHandler* handler = reinterpret_cast<EventHandler*>(args);
|
||||
EventHandlerImplementation* handler_impl = &handler->delegate_;
|
||||
ASSERT(handler_impl != NULL);
|
||||
|
||||
while (!handler_impl->shutdown_) {
|
||||
intptr_t result = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
|
||||
epoll_wait(handler_impl->epoll_fd_, events, kMaxEvents, -1));
|
||||
@@ -327,13 +328,13 @@ void EventHandlerImplementation::Poll(uword args) {
|
||||
handler_impl->HandleEvents(events, result);
|
||||
}
|
||||
}
|
||||
delete handler;
|
||||
handler->NotifyShutdownDone();
|
||||
}
|
||||
|
||||
|
||||
void EventHandlerImplementation::Start(EventHandler* handler) {
|
||||
int result = Thread::Start(&EventHandlerImplementation::Poll,
|
||||
reinterpret_cast<uword>(handler));
|
||||
reinterpret_cast<uword>(handler));
|
||||
if (result != 0) {
|
||||
FATAL1("Failed to start event handler thread %d", result);
|
||||
}
|
||||
|
||||
@@ -358,6 +358,7 @@ void EventHandlerImplementation::EventHandlerEntry(uword args) {
|
||||
EventHandler* handler = reinterpret_cast<EventHandler*>(args);
|
||||
EventHandlerImplementation* handler_impl = &handler->delegate_;
|
||||
ASSERT(handler_impl != NULL);
|
||||
|
||||
while (!handler_impl->shutdown_) {
|
||||
int64_t millis = handler_impl->GetTimeout();
|
||||
ASSERT(millis == kInfinityTimeout || millis >= 0);
|
||||
@@ -387,14 +388,14 @@ void EventHandlerImplementation::EventHandlerEntry(uword args) {
|
||||
handler_impl->HandleEvents(events, result);
|
||||
}
|
||||
}
|
||||
delete handler;
|
||||
handler->NotifyShutdownDone();
|
||||
}
|
||||
|
||||
|
||||
void EventHandlerImplementation::Start(EventHandler* handler) {
|
||||
int result =
|
||||
Thread::Start(&EventHandlerImplementation::EventHandlerEntry,
|
||||
reinterpret_cast<uword>(handler));
|
||||
reinterpret_cast<uword>(handler));
|
||||
if (result != 0) {
|
||||
FATAL1("Failed to start event handler thread %d", result);
|
||||
}
|
||||
|
||||
@@ -1295,6 +1295,7 @@ void EventHandlerImplementation::EventHandlerEntry(uword args) {
|
||||
EventHandler* handler = reinterpret_cast<EventHandler*>(args);
|
||||
EventHandlerImplementation* handler_impl = &handler->delegate_;
|
||||
ASSERT(handler_impl != NULL);
|
||||
|
||||
while (!handler_impl->shutdown_) {
|
||||
DWORD bytes;
|
||||
ULONG_PTR key;
|
||||
@@ -1344,13 +1345,13 @@ void EventHandlerImplementation::EventHandlerEntry(uword args) {
|
||||
handler_impl->HandleIOCompletion(bytes, key, overlapped);
|
||||
}
|
||||
}
|
||||
delete handler;
|
||||
handler->NotifyShutdownDone();
|
||||
}
|
||||
|
||||
|
||||
void EventHandlerImplementation::Start(EventHandler* handler) {
|
||||
int result = Thread::Start(EventHandlerEntry,
|
||||
reinterpret_cast<uword>(handler));
|
||||
reinterpret_cast<uword>(handler));
|
||||
if (result != 0) {
|
||||
FATAL1("Failed to start event handler thread %d", result);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user