02b30d5275
TEST=threading_pinning_test Change-Id: I9a80543a06dbf51c070fed5c0e64eeba247497de Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497126 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Alexander Aprelev <aam@google.com>
164 lines
4.7 KiB
C++
164 lines
4.7 KiB
C++
// Copyright (c) 2011, 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.
|
|
|
|
#ifndef RUNTIME_VM_PORT_H_
|
|
#define RUNTIME_VM_PORT_H_
|
|
|
|
#include <memory>
|
|
|
|
#include "include/dart_api.h"
|
|
#include "vm/allocation.h"
|
|
#include "vm/globals.h"
|
|
#include "vm/json_stream.h"
|
|
#include "vm/lockers.h"
|
|
#include "vm/port_set.h"
|
|
#include "vm/random.h"
|
|
|
|
namespace dart {
|
|
|
|
class Isolate;
|
|
class Message;
|
|
class MessageHandler;
|
|
class Mutex;
|
|
class PortHandler;
|
|
|
|
enum class IsolateAcquireResult {
|
|
SUCCESS,
|
|
ISOLATE_NOT_AVAILABLE,
|
|
BUSY,
|
|
PINNED_TO_ANOTHER_THREAD,
|
|
};
|
|
|
|
class PortMap : public AllStatic {
|
|
public:
|
|
// Allocate a port for the provided handler and return its VM-global id.
|
|
static Dart_Port CreatePort(PortHandler* handler);
|
|
|
|
// Close the port with id. All pending messages will be dropped.
|
|
//
|
|
// Returns true if the port is successfully closed.
|
|
static bool ClosePort(Dart_Port id, PortHandler** port_handler = nullptr);
|
|
|
|
// Close all the ports for the provided handler.
|
|
static void ClosePorts(MessageHandler* handler);
|
|
|
|
// Enqueues the message in the port with id. Returns false if the port is not
|
|
// active any longer.
|
|
//
|
|
// Claims ownership of 'message'.
|
|
static bool PostMessage(std::unique_ptr<Message> message,
|
|
bool before_events = false);
|
|
|
|
// Returns the origin id for port 'id'.
|
|
static Dart_Port GetOriginId(Dart_Port id);
|
|
|
|
// Returns whether the isolate that owns the port is owned by the current
|
|
// thread.
|
|
static bool IsOwnedByCurrentThread(Dart_Port id,
|
|
bool require_permanent_pin = false);
|
|
|
|
// Returns true if the port is owned by somebody.
|
|
static bool IsOwned(Dart_Port id);
|
|
|
|
static bool HasEventLoopRunning(Dart_Port id);
|
|
|
|
static IsolateAcquireResult AcquireIsolateByControlPort(Dart_Port target_port,
|
|
Isolate** p_isolate);
|
|
|
|
#if defined(TESTING)
|
|
static Isolate* GetIsolate(Dart_Port id);
|
|
static bool PortExists(Dart_Port id);
|
|
static bool HasPorts(MessageHandler* handler);
|
|
#endif
|
|
|
|
// Whether the destination port's isolate is a member of [isolate_group].
|
|
static bool IsReceiverInThisIsolateGroupOrClosed(Dart_Port receiver,
|
|
IsolateGroup* group);
|
|
|
|
static void Init();
|
|
static void Shutdown();
|
|
static void Cleanup();
|
|
|
|
static void PrintPortsForMessageHandler(MessageHandler* handler,
|
|
JSONStream* stream);
|
|
|
|
class Locker : public MutexLocker {
|
|
public:
|
|
Locker() : MutexLocker(PortMap::mutex_) {}
|
|
};
|
|
|
|
private:
|
|
struct Entry : public PortSet<Entry>::Entry {
|
|
Entry() : handler(nullptr) {}
|
|
Entry(Dart_Port port, PortHandler* handler)
|
|
: PortSet<Entry>::Entry(port), handler(handler) {}
|
|
|
|
PortHandler* handler;
|
|
};
|
|
|
|
// Allocate a new unique port.
|
|
static Dart_Port AllocatePort();
|
|
|
|
static Isolate* GetIsolateLocked(const Locker& ml, Dart_Port id);
|
|
|
|
// Lock protecting access to the port map.
|
|
static Mutex* mutex_;
|
|
|
|
static PortSet<Entry>* ports_;
|
|
|
|
static Random* prng_;
|
|
};
|
|
|
|
// An object handling messages dispatched to one or more ports in the |PortMap|.
|
|
class PortHandler {
|
|
public:
|
|
virtual ~PortHandler();
|
|
|
|
virtual const char* name() const = 0;
|
|
|
|
// Notify the handler that a port previously associated with it is
|
|
// now closed.
|
|
virtual void OnPortClosed(Dart_Port port) = 0;
|
|
|
|
#if defined(DEBUG)
|
|
// Check that it is safe to access this port handler.
|
|
//
|
|
// For example, if this |PortHandler| is an isolate, then it is
|
|
// only safe to access it when it is the current isolate.
|
|
virtual void CheckAccess() const;
|
|
#endif
|
|
|
|
// Return Isolate to which this message handler corresponds to.
|
|
virtual Isolate* isolate() const = 0;
|
|
|
|
// Ask the handler to shutdown, e.g. stop associated thread pools if any.
|
|
virtual void Shutdown() = 0;
|
|
|
|
// Posts a message on this handler's message queue.
|
|
// If before_events is true, then the message is enqueued before any pending
|
|
// events, but after any pending isolate library events.
|
|
virtual void PostMessage(std::unique_ptr<Message> message,
|
|
bool before_events = false) = 0;
|
|
|
|
protected:
|
|
struct PortSetEntry : public PortSet<PortSetEntry>::Entry {
|
|
PortSetEntry() : Entry() {}
|
|
explicit PortSetEntry(Dart_Port port) : Entry(port) {}
|
|
};
|
|
|
|
private:
|
|
friend class PortMap;
|
|
|
|
// Returns set of ports associate with this handler if
|
|
// handler supports multiple ports or |nullptr| otherwise.
|
|
//
|
|
// Only |PortMap| is expected to call this method under locked
|
|
// PortMap::mutex_.
|
|
virtual PortSet<PortSetEntry>* ports(PortMap::Locker& locker) = 0;
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_PORT_H_
|