blob: 8e94e3586bdca5293688afa73d778625d7dbf1a7 [file] [log] [blame] [edit]
// 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;
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 owning Isolate for port 'id'.
static Isolate* GetIsolate(Dart_Port id);
// Returns the origin id for port 'id'.
static Dart_Port GetOriginId(Dart_Port id);
#if defined(TESTING)
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);
static void DebugDumpForMessageHandler(MessageHandler* handler);
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();
// 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_