| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #include "bin/eventhandler.h" | |
| #include "bin/builtin.h" | |
| #include "bin/dartutils.h" | |
| #include "bin/file_system_watcher.h" | |
| #include "bin/lockers.h" | |
| #include "bin/socket.h" | |
| #include "bin/thread.h" | |
| #include "include/dart_api.h" | |
| namespace dart { | |
| namespace bin { | |
| static EventHandler* event_handler = nullptr; | |
| static Monitor* shutdown_monitor = nullptr; | |
| void EventHandler::Start() { | |
| FileSystemWatcher::InitOnce(); | |
| // Initialize global socket registry. | |
| ListeningSocketRegistry::Initialize(); | |
| ASSERT(event_handler == nullptr); | |
| shutdown_monitor = new Monitor(); | |
| event_handler = new EventHandler(); | |
| event_handler->delegate_.Start(event_handler); | |
| if (!SocketBase::Initialize()) { | |
| FATAL("Failed to initialize sockets"); | |
| } | |
| } | |
| void EventHandler::NotifyShutdownDone() { | |
| MonitorLocker ml(shutdown_monitor); | |
| ml.Notify(); | |
| } | |
| void EventHandler::Stop() { | |
| if (event_handler == nullptr) { | |
| return; | |
| } | |
| // 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 = nullptr; | |
| delete shutdown_monitor; | |
| shutdown_monitor = nullptr; | |
| // Destroy the global socket registry. | |
| ListeningSocketRegistry::Cleanup(); | |
| FileSystemWatcher::Cleanup(); | |
| } | |
| EventHandlerImplementation* EventHandler::delegate() { | |
| if (event_handler == nullptr) { | |
| return nullptr; | |
| } | |
| return &event_handler->delegate_; | |
| } | |
| void EventHandler::SendFromNative(intptr_t id, Dart_Port port, int64_t data) { | |
| event_handler->SendData(id, port, data); | |
| } | |
| /* | |
| * Send data to the EventHandler thread to register for a given instance | |
| * args[0] a ReceivePort args[1] with a notification event args[2]. | |
| */ | |
| void FUNCTION_NAME(EventHandler_SendData)(Dart_NativeArguments args) { | |
| // Get the id out of the send port. If the handle is not a send port | |
| // we will get an error and propagate that out. | |
| Dart_Handle handle = Dart_GetNativeArgument(args, 1); | |
| Dart_Port dart_port; | |
| handle = Dart_SendPortGetId(handle, &dart_port); | |
| if (Dart_IsError(handle)) { | |
| Dart_PropagateError(handle); | |
| UNREACHABLE(); | |
| } | |
| Dart_Handle sender = Dart_GetNativeArgument(args, 0); | |
| intptr_t id; | |
| if (Dart_IsNull(sender)) { | |
| id = kTimerId; | |
| } else { | |
| Socket* socket = Socket::GetSocketIdNativeField(sender); | |
| ASSERT(dart_port != ILLEGAL_PORT); | |
| socket->set_port(dart_port); | |
| socket->Retain(); // inc refcount before sending to the eventhandler. | |
| id = reinterpret_cast<intptr_t>(socket); | |
| } | |
| int64_t data = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2)); | |
| event_handler->SendData(id, dart_port, data); | |
| } | |
| void FUNCTION_NAME(EventHandler_TimerMillisecondClock)( | |
| Dart_NativeArguments args) { | |
| int64_t now = TimerUtils::GetCurrentMonotonicMillis(); | |
| Dart_SetReturnValue(args, Dart_NewInteger(now)); | |
| } | |
| } // namespace bin | |
| } // namespace dart |