1f5364cd3b
Dart_NewNativePort creates a port associated with a C handler function. When messages come in on this port, they are forwarded to the C function for processing. To support this, refactored PortMap so that it operates on a new MessageHandler type instead of directly on Isolates. For now, native ports have a dedicated single thread. Eventually we will back native ports (and possibly Isolates as well) by a shared thread pool. Review URL: https://chromiumcodereview.appspot.com//9169063 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@3804 260f80e4-7a28-3924-810f-c04153c831b5
153 lines
3.9 KiB
C++
153 lines
3.9 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 VM_MESSAGE_H_
|
|
#define VM_MESSAGE_H_
|
|
|
|
#include "vm/thread.h"
|
|
|
|
// Duplicated from dart_api.h to avoid including the whole header.
|
|
typedef int64_t Dart_Port;
|
|
|
|
namespace dart {
|
|
|
|
class Message {
|
|
public:
|
|
typedef enum {
|
|
kNormalPriority = 0, // Deliver message when idle.
|
|
kOOBPriority = 1, // Deliver message asap.
|
|
|
|
// Iteration.
|
|
kFirstPriority = 0,
|
|
kNumPriorities = 2,
|
|
} Priority;
|
|
|
|
// A port number which is never used.
|
|
static const Dart_Port kIllegalPort = 0;
|
|
|
|
// A new message to be sent between two isolates. The data handed to this
|
|
// message will be disposed by calling free() once the message object is
|
|
// being destructed (after delivery or when the receiving port is closed).
|
|
//
|
|
// If reply_port is kIllegalPort, then there is no reply port.
|
|
Message(Dart_Port dest_port, Dart_Port reply_port,
|
|
uint8_t* data, Priority priority)
|
|
: next_(NULL),
|
|
dest_port_(dest_port),
|
|
reply_port_(reply_port),
|
|
data_(data),
|
|
priority_(priority) {}
|
|
~Message() {
|
|
free(data_);
|
|
}
|
|
|
|
Dart_Port dest_port() const { return dest_port_; }
|
|
Dart_Port reply_port() const { return reply_port_; }
|
|
uint8_t* data() const { return data_; }
|
|
Priority priority() const { return priority_; }
|
|
|
|
private:
|
|
friend class MessageQueue;
|
|
|
|
Message* next_;
|
|
Dart_Port dest_port_;
|
|
Dart_Port reply_port_;
|
|
uint8_t* data_;
|
|
Priority priority_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(Message);
|
|
};
|
|
|
|
// There is a message queue per isolate.
|
|
class MessageQueue {
|
|
public:
|
|
MessageQueue();
|
|
~MessageQueue();
|
|
|
|
void Enqueue(Message* msg);
|
|
|
|
// Gets the next message from the message queue, possibly blocking
|
|
// if no message is available. 'millis' is a timeout in
|
|
// milliseconds. If 'millis' is 0, then this means to block
|
|
// indefinitely. May block if no message is available. May return
|
|
// NULL even if 'millis' is 0 due to spurious wakeups.
|
|
Message* Dequeue(int64_t millis);
|
|
|
|
// Gets the next message from the message queue if available. Will
|
|
// not block.
|
|
Message* DequeueNoWait();
|
|
|
|
void Flush(Dart_Port port);
|
|
void FlushAll();
|
|
|
|
private:
|
|
friend class MessageQueueTestPeer;
|
|
|
|
Message* DequeueNoWaitHoldsLock();
|
|
|
|
Monitor monitor_;
|
|
Message* head_[Message::kNumPriorities];
|
|
Message* tail_[Message::kNumPriorities];
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(MessageQueue);
|
|
};
|
|
|
|
// A MessageHandler is an entity capable of accepting messages.
|
|
class MessageHandler {
|
|
protected:
|
|
MessageHandler();
|
|
|
|
// Allows subclasses to provide custom message notification.
|
|
virtual void MessageNotify(Message::Priority priority);
|
|
|
|
public:
|
|
virtual ~MessageHandler();
|
|
|
|
// Allow subclasses to provide a handler name.
|
|
virtual const char* name() const;
|
|
|
|
#if defined(DEBUG)
|
|
// Check that it is safe to access this message handler.
|
|
//
|
|
// For example, if this MessageHandler is an isolate, then it is
|
|
// only safe to access it when the MessageHandler is the current
|
|
// isolate.
|
|
virtual void CheckAccess();
|
|
#endif
|
|
|
|
void PostMessage(Message* message);
|
|
void ClosePort(Dart_Port port);
|
|
void CloseAllPorts();
|
|
|
|
// A message handler tracks how many live ports it has.
|
|
bool HasLivePorts() const { return live_ports_ > 0; }
|
|
void increment_live_ports() {
|
|
#if defined(DEBUG)
|
|
CheckAccess();
|
|
#endif
|
|
live_ports_++;
|
|
}
|
|
void decrement_live_ports() {
|
|
#if defined(DEBUG)
|
|
CheckAccess();
|
|
#endif
|
|
live_ports_--;
|
|
}
|
|
|
|
// Returns true if the handler is owned by the PortMap.
|
|
//
|
|
// This is used to delete handlers when their last live port is closed.
|
|
virtual bool OwnedByPortMap() const { return false; }
|
|
|
|
MessageQueue* queue() const { return queue_; }
|
|
|
|
private:
|
|
intptr_t live_ports_;
|
|
MessageQueue* queue_;
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // VM_MESSAGE_H_
|