mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:22:12 +00:00
602aad28a1
- Allow isolate library messages to be enqueued at the beginning of the message queue. R=asiva@google.com Review URL: https://codereview.chromium.org//749373002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@42193 260f80e4-7a28-3924-810f-c04153c831b5
110 lines
2.5 KiB
C++
110 lines
2.5 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.
|
|
|
|
#include "vm/message.h"
|
|
|
|
#include "vm/port.h"
|
|
|
|
namespace dart {
|
|
|
|
bool Message::RedirectToDeliveryFailurePort() {
|
|
if (delivery_failure_port_ == kIllegalPort) {
|
|
return false;
|
|
}
|
|
dest_port_ = delivery_failure_port_;
|
|
delivery_failure_port_ = kIllegalPort;
|
|
return true;
|
|
}
|
|
|
|
|
|
MessageQueue::MessageQueue() {
|
|
head_ = NULL;
|
|
tail_ = NULL;
|
|
}
|
|
|
|
|
|
MessageQueue::~MessageQueue() {
|
|
// Ensure that all pending messages have been released.
|
|
Clear();
|
|
ASSERT(head_ == NULL);
|
|
}
|
|
|
|
|
|
void MessageQueue::Enqueue(Message* msg, bool before_events) {
|
|
// Make sure messages are not reused.
|
|
ASSERT(msg->next_ == NULL);
|
|
if (head_ == NULL) {
|
|
// Only element in the queue.
|
|
ASSERT(tail_ == NULL);
|
|
head_ = msg;
|
|
tail_ = msg;
|
|
} else {
|
|
ASSERT(tail_ != NULL);
|
|
if (!before_events) {
|
|
// Append at the tail.
|
|
tail_->next_ = msg;
|
|
tail_ = msg;
|
|
} else {
|
|
ASSERT(msg->dest_port() == Message::kIllegalPort);
|
|
if (head_->dest_port() != Message::kIllegalPort) {
|
|
msg->next_ = head_;
|
|
head_ = msg;
|
|
} else {
|
|
Message* cur = head_;
|
|
while (cur->next_ != NULL) {
|
|
if (cur->next_->dest_port() != Message::kIllegalPort) {
|
|
// Splice in the new message at the break.
|
|
msg->next_ = cur->next_;
|
|
cur->next_ = msg;
|
|
return;
|
|
}
|
|
cur = cur->next_;
|
|
}
|
|
// All pending messages are isolate library control messages. Append at
|
|
// the tail.
|
|
ASSERT(tail_ == cur);
|
|
ASSERT(tail_->dest_port() == Message::kIllegalPort);
|
|
tail_->next_ = msg;
|
|
tail_ = msg;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Message* MessageQueue::Dequeue() {
|
|
Message* result = head_;
|
|
if (result != NULL) {
|
|
head_ = result->next_;
|
|
// The following update to tail_ is not strictly needed.
|
|
if (head_ == NULL) {
|
|
tail_ = NULL;
|
|
}
|
|
#if defined(DEBUG)
|
|
result->next_ = result; // Make sure to trigger ASSERT in Enqueue.
|
|
#endif // DEBUG
|
|
return result;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void MessageQueue::Clear() {
|
|
Message* cur = head_;
|
|
head_ = NULL;
|
|
tail_ = NULL;
|
|
while (cur != NULL) {
|
|
Message* next = cur->next_;
|
|
if (cur->RedirectToDeliveryFailurePort()) {
|
|
PortMap::PostMessage(cur);
|
|
} else {
|
|
delete cur;
|
|
}
|
|
cur = next;
|
|
}
|
|
}
|
|
|
|
|
|
} // namespace dart
|