| // 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_ |