| Index: runtime/vm/port.cc
|
| ===================================================================
|
| --- runtime/vm/port.cc (revision 3743)
|
| +++ runtime/vm/port.cc (working copy)
|
| @@ -7,7 +7,7 @@
|
| #include "platform/utils.h"
|
| #include "vm/dart_api_impl.h"
|
| #include "vm/isolate.h"
|
| -#include "vm/message_queue.h"
|
| +#include "vm/message.h"
|
| #include "vm/thread.h"
|
|
|
| namespace dart {
|
| @@ -15,13 +15,11 @@
|
| DECLARE_FLAG(bool, trace_isolates);
|
|
|
| Mutex* PortMap::mutex_ = NULL;
|
| -
|
| PortMap::Entry* PortMap::map_ = NULL;
|
| -Isolate* PortMap::deleted_entry_ = reinterpret_cast<Isolate*>(1);
|
| +MessageHandler* PortMap::deleted_entry_ = reinterpret_cast<MessageHandler*>(1);
|
| intptr_t PortMap::capacity_ = 0;
|
| intptr_t PortMap::used_ = 0;
|
| intptr_t PortMap::deleted_ = 0;
|
| -
|
| Dart_Port PortMap::next_port_ = 7111;
|
|
|
|
|
| @@ -29,7 +27,7 @@
|
| intptr_t index = port % capacity_;
|
| intptr_t start_index = index;
|
| Entry entry = map_[index];
|
| - while (entry.isolate != NULL) {
|
| + while (entry.handler != NULL) {
|
| if (entry.port == port) {
|
| return index;
|
| }
|
| @@ -83,7 +81,7 @@
|
| intptr_t index = FindPort(port);
|
| ASSERT(index >= 0);
|
| map_[index].live = true;
|
| - map_[index].isolate->increment_live_ports();
|
| + map_[index].handler->increment_live_ports();
|
| }
|
|
|
|
|
| @@ -100,13 +98,16 @@
|
| }
|
|
|
|
|
| -Dart_Port PortMap::CreatePort() {
|
| - Isolate* isolate = Isolate::Current();
|
| +Dart_Port PortMap::CreatePort(MessageHandler* handler) {
|
| + ASSERT(handler != NULL);
|
| MutexLocker ml(mutex_);
|
| +#if defined(DEBUG)
|
| + handler->CheckAccess();
|
| +#endif
|
|
|
| Entry entry;
|
| entry.port = AllocatePort();
|
| - entry.isolate = isolate;
|
| + entry.handler = handler;
|
| entry.live = false;
|
|
|
| // Search for the first unused slot. Make use of the knowledge that here is
|
| @@ -124,14 +125,13 @@
|
| ASSERT(index >= 0);
|
| ASSERT(index < capacity_);
|
| ASSERT(map_[index].port == 0);
|
| - ASSERT((map_[index].isolate == NULL) ||
|
| - (map_[index].isolate == deleted_entry_));
|
| - if (map_[index].isolate == deleted_entry_) {
|
| + ASSERT((map_[index].handler == NULL) ||
|
| + (map_[index].handler == deleted_entry_));
|
| + if (map_[index].handler == deleted_entry_) {
|
| // Consuming a deleted entry.
|
| deleted_--;
|
| }
|
| map_[index] = entry;
|
| - isolate->increment_num_ports();
|
|
|
| // Increment number of used slots and grow if necessary.
|
| used_++;
|
| @@ -141,74 +141,78 @@
|
| }
|
|
|
|
|
| -void PortMap::ClosePort(Dart_Port port) {
|
| - Isolate* isolate = Isolate::Current();
|
| +bool PortMap::ClosePort(Dart_Port port) {
|
| + MessageHandler* handler = NULL;
|
| {
|
| MutexLocker ml(mutex_);
|
| intptr_t index = FindPort(port);
|
| if (index < 0) {
|
| - return;
|
| + return false;
|
| }
|
| ASSERT(index < capacity_);
|
| ASSERT(map_[index].port != 0);
|
| - ASSERT(map_[index].isolate == isolate);
|
| + ASSERT(map_[index].handler != deleted_entry_);
|
| + ASSERT(map_[index].handler != NULL);
|
| +
|
| + handler = map_[index].handler;
|
| +#if defined(DEBUG)
|
| + handler->CheckAccess();
|
| +#endif
|
| // Before releasing the lock mark the slot in the map as deleted. This makes
|
| // it possible to release the port map lock before flushing all of its
|
| // pending messages below.
|
| map_[index].port = 0;
|
| - map_[index].isolate = deleted_entry_;
|
| - isolate->decrement_num_ports();
|
| + map_[index].handler = deleted_entry_;
|
| if (map_[index].live) {
|
| - isolate->decrement_live_ports();
|
| + handler->decrement_live_ports();
|
| }
|
|
|
| used_--;
|
| deleted_++;
|
| MaintainInvariants();
|
| }
|
| - isolate->ClosePort(port);
|
| + handler->ClosePort(port);
|
| + if (!handler->HasLivePorts() && handler->OwnedByPortMap()) {
|
| + delete handler;
|
| + }
|
| + return true;
|
| }
|
|
|
|
|
| -void PortMap::ClosePorts() {
|
| - Isolate* isolate = Isolate::Current();
|
| +void PortMap::ClosePorts(MessageHandler* handler) {
|
| {
|
| MutexLocker ml(mutex_);
|
| for (intptr_t i = 0; i < capacity_; i++) {
|
| - if (map_[i].isolate == isolate) {
|
| + if (map_[i].handler == handler) {
|
| // Mark the slot as deleted.
|
| map_[i].port = 0;
|
| - map_[i].isolate = deleted_entry_;
|
| - isolate->decrement_num_ports();
|
| -
|
| + map_[i].handler = deleted_entry_;
|
| + if (map_[i].live) {
|
| + handler->decrement_live_ports();
|
| + }
|
| used_--;
|
| deleted_++;
|
| }
|
| }
|
| MaintainInvariants();
|
| }
|
| - isolate->CloseAllPorts();
|
| + handler->CloseAllPorts();
|
| }
|
|
|
|
|
| bool PortMap::PostMessage(Message* message) {
|
| - // TODO(turnidge): Add a scoped locker for mutexes which is not a
|
| - // stack resource. This would probably be useful in the platform
|
| - // headers.
|
| - mutex_->Lock();
|
| + MutexLocker ml(mutex_);
|
| intptr_t index = FindPort(message->dest_port());
|
| if (index < 0) {
|
| free(message);
|
| - mutex_->Unlock();
|
| return false;
|
| }
|
| ASSERT(index >= 0);
|
| ASSERT(index < capacity_);
|
| - Isolate* isolate = map_[index].isolate;
|
| + MessageHandler* handler = map_[index].handler;
|
| ASSERT(map_[index].port != 0);
|
| - ASSERT((isolate != NULL) && (isolate != deleted_entry_));
|
| - isolate->PostMessage(message);
|
| - mutex_->Unlock();
|
| + ASSERT((handler != NULL) && (handler != deleted_entry_));
|
| + handler->PostMessage(message);
|
| return true;
|
| }
|
|
|
| @@ -226,5 +230,4 @@
|
| deleted_ = 0;
|
| }
|
|
|
| -
|
| } // namespace dart
|
|
|