Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/port.h" | 5 #include "vm/port.h" |
| 6 | 6 |
| 7 #include "vm/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/message_queue.h" | |
| 9 #include "vm/thread.h" | 10 #include "vm/thread.h" |
| 10 #include "vm/utils.h" | 11 #include "vm/utils.h" |
| 11 | 12 |
| 12 namespace dart { | 13 namespace dart { |
| 13 | 14 |
| 14 | 15 |
| 15 Mutex* PortMap::mutex_ = NULL; | 16 Mutex* PortMap::mutex_ = NULL; |
| 16 | 17 |
| 17 PortMap::Entry* PortMap::map_ = NULL; | 18 PortMap::Entry* PortMap::map_ = NULL; |
| 18 Isolate* PortMap::deleted_entry_ = reinterpret_cast<Isolate*>(1); | 19 Isolate* PortMap::deleted_entry_ = reinterpret_cast<Isolate*>(1); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 map_[index].isolate = deleted_entry_; | 158 map_[index].isolate = deleted_entry_; |
| 158 isolate->decrement_num_ports(); | 159 isolate->decrement_num_ports(); |
| 159 if (map_[index].live) { | 160 if (map_[index].live) { |
| 160 isolate->decrement_live_ports(); | 161 isolate->decrement_live_ports(); |
| 161 } | 162 } |
| 162 | 163 |
| 163 used_--; | 164 used_--; |
| 164 deleted_++; | 165 deleted_++; |
| 165 MaintainInvariants(); | 166 MaintainInvariants(); |
| 166 } | 167 } |
| 167 | 168 isolate->ClosePort(port); |
| 168 // Notify the embedder that this port is closed. | |
| 169 Dart_ClosePortCallback callback = isolate->close_port_callback(); | |
| 170 ASSERT(callback); | |
| 171 ASSERT(port != kCloseAllPorts); | |
| 172 (*callback)(Api::CastIsolate(isolate), port); | |
| 173 } | 169 } |
| 174 | 170 |
| 175 | 171 |
| 176 void PortMap::ClosePorts() { | 172 void PortMap::ClosePorts() { |
| 177 Isolate* isolate = Isolate::Current(); | 173 Isolate* isolate = Isolate::Current(); |
| 178 { | 174 { |
| 179 MutexLocker ml(mutex_); | 175 MutexLocker ml(mutex_); |
| 180 for (intptr_t i = 0; i < capacity_; i++) { | 176 for (intptr_t i = 0; i < capacity_; i++) { |
| 181 if (map_[i].isolate == isolate) { | 177 if (map_[i].isolate == isolate) { |
| 182 // Mark the slot as deleted. | 178 // Mark the slot as deleted. |
| 183 map_[i].port = 0; | 179 map_[i].port = 0; |
| 184 map_[i].isolate = deleted_entry_; | 180 map_[i].isolate = deleted_entry_; |
| 185 isolate->decrement_num_ports(); | 181 isolate->decrement_num_ports(); |
| 186 | 182 |
| 187 used_--; | 183 used_--; |
| 188 deleted_++; | 184 deleted_++; |
| 189 } | 185 } |
| 190 } | 186 } |
| 191 MaintainInvariants(); | 187 MaintainInvariants(); |
| 192 } | 188 } |
| 193 | 189 isolate->CloseAllPorts(); |
| 194 // Notify the embedder that all ports are closed. | |
| 195 Dart_ClosePortCallback callback = isolate->close_port_callback(); | |
| 196 ASSERT(callback); | |
| 197 (*callback)(Api::CastIsolate(isolate), kCloseAllPorts); | |
| 198 } | 190 } |
| 199 | 191 |
| 200 | 192 |
| 201 bool PortMap::PostMessage(Dart_Port dest_port, | 193 bool PortMap::PostMessage(Message* message) { |
| 202 Dart_Port reply_port, | |
| 203 Dart_Message message) { | |
| 204 mutex_->Lock(); | 194 mutex_->Lock(); |
|
Ivan Posva
2012/01/23 22:00:43
MutexLocker ml(mutex_);
turnidge
2012/01/23 22:32:52
We can post from a non-isolate via Dart_PostIntArr
| |
| 205 intptr_t index = FindPort(dest_port); | 195 intptr_t index = FindPort(message->dest_port()); |
| 206 if (index < 0) { | 196 if (index < 0) { |
| 207 free(message); | 197 free(message); |
| 208 mutex_->Unlock(); | 198 mutex_->Unlock(); |
| 209 return false; | 199 return false; |
| 210 } | 200 } |
| 211 ASSERT(index >= 0); | 201 ASSERT(index >= 0); |
| 212 ASSERT(index < capacity_); | 202 ASSERT(index < capacity_); |
| 213 Isolate* isolate = map_[index].isolate; | 203 Isolate* isolate = map_[index].isolate; |
| 214 ASSERT(map_[index].port != 0); | 204 ASSERT(map_[index].port != 0); |
| 215 ASSERT((isolate != NULL) && (isolate != deleted_entry_)); | 205 ASSERT((isolate != NULL) && (isolate != deleted_entry_)); |
| 216 | 206 isolate->PostMessage(message); |
| 217 // Delegate message delivery to the embedder. | |
| 218 Dart_PostMessageCallback callback = isolate->post_message_callback(); | |
| 219 ASSERT(callback); | |
| 220 bool result = | |
| 221 (*callback)(Api::CastIsolate(isolate), dest_port, reply_port, message); | |
| 222 | |
| 223 mutex_->Unlock(); | 207 mutex_->Unlock(); |
| 224 return result; | 208 return true; |
| 225 } | 209 } |
| 226 | 210 |
| 227 | 211 |
| 228 void PortMap::InitOnce() { | 212 void PortMap::InitOnce() { |
| 229 mutex_ = new Mutex(); | 213 mutex_ = new Mutex(); |
| 230 | 214 |
| 231 static const intptr_t kInitialCapacity = 8; | 215 static const intptr_t kInitialCapacity = 8; |
| 232 // TODO(iposva): Verify whether we want to keep exponentially growing. | 216 // TODO(iposva): Verify whether we want to keep exponentially growing. |
| 233 ASSERT(Utils::IsPowerOfTwo(kInitialCapacity)); | 217 ASSERT(Utils::IsPowerOfTwo(kInitialCapacity)); |
| 234 map_ = new Entry[kInitialCapacity]; | 218 map_ = new Entry[kInitialCapacity]; |
| 235 memset(map_, 0, kInitialCapacity * sizeof(Entry)); | 219 memset(map_, 0, kInitialCapacity * sizeof(Entry)); |
| 236 capacity_ = kInitialCapacity; | 220 capacity_ = kInitialCapacity; |
| 237 used_ = 0; | 221 used_ = 0; |
| 238 deleted_ = 0; | 222 deleted_ = 0; |
| 239 } | 223 } |
| 240 | 224 |
| 241 | 225 |
| 242 } // namespace dart | 226 } // namespace dart |
| OLD | NEW |