mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:17:14 +00:00
868cb26a2d
Right now each isolate can have one port registered at the eventhandler. When the timer expires the isolate will be notified. The isolate can also cancel it's timer. The timer implementation in the eventhandler is implemented as a linked list, sorted by expiration date. Removing an entry for a given port will perform a linear search. This O(N) search can be very problematic as the number of isolates scales, effectively leading to O(N^2) behavior if N isolates register/cancel N timers. The priority_heap.h/priority_heap_test.cc was imported from the implementation in "github.com/dartino/sdk". Issue https://github.com/dart-lang/sdk/issues/44457 TEST=runtime/bin/priority_heap_test.cc Change-Id: I657c1c1ac0c68ade5295b2569e3fb1a3478325ec Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175729 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
112 lines
3 KiB
C++
112 lines
3 KiB
C++
// 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/lockers.h"
|
|
#include "bin/socket.h"
|
|
#include "bin/thread.h"
|
|
|
|
#include "include/dart_api.h"
|
|
|
|
namespace dart {
|
|
namespace bin {
|
|
|
|
static EventHandler* event_handler = NULL;
|
|
static Monitor* shutdown_monitor = NULL;
|
|
|
|
void EventHandler::Start() {
|
|
// Initialize global socket registry.
|
|
ListeningSocketRegistry::Initialize();
|
|
|
|
ASSERT(event_handler == NULL);
|
|
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 == NULL) {
|
|
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 = NULL;
|
|
delete shutdown_monitor;
|
|
shutdown_monitor = NULL;
|
|
|
|
// Destroy the global socket registry.
|
|
ListeningSocketRegistry::Cleanup();
|
|
}
|
|
|
|
EventHandlerImplementation* EventHandler::delegate() {
|
|
if (event_handler == NULL) {
|
|
return NULL;
|
|
}
|
|
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
|