OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "platform/utils.h" | 7 #include "platform/utils.h" |
8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/message_queue.h" |
10 #include "vm/thread.h" | 11 #include "vm/thread.h" |
11 | 12 |
12 namespace dart { | 13 namespace dart { |
13 | 14 |
14 DECLARE_FLAG(bool, trace_isolates); | 15 DECLARE_FLAG(bool, trace_isolates); |
15 | 16 |
16 Mutex* PortMap::mutex_ = NULL; | 17 Mutex* PortMap::mutex_ = NULL; |
17 | 18 |
18 PortMap::Entry* PortMap::map_ = NULL; | 19 PortMap::Entry* PortMap::map_ = NULL; |
19 Isolate* PortMap::deleted_entry_ = reinterpret_cast<Isolate*>(1); | 20 Isolate* PortMap::deleted_entry_ = reinterpret_cast<Isolate*>(1); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 map_[index].isolate = deleted_entry_; | 159 map_[index].isolate = deleted_entry_; |
159 isolate->decrement_num_ports(); | 160 isolate->decrement_num_ports(); |
160 if (map_[index].live) { | 161 if (map_[index].live) { |
161 isolate->decrement_live_ports(); | 162 isolate->decrement_live_ports(); |
162 } | 163 } |
163 | 164 |
164 used_--; | 165 used_--; |
165 deleted_++; | 166 deleted_++; |
166 MaintainInvariants(); | 167 MaintainInvariants(); |
167 } | 168 } |
168 | 169 isolate->ClosePort(port); |
169 // Notify the embedder that this port is closed. | |
170 Dart_ClosePortCallback callback = isolate->close_port_callback(); | |
171 ASSERT(callback); | |
172 ASSERT(port != kCloseAllPorts); | |
173 (*callback)(Api::CastIsolate(isolate), port); | |
174 } | 170 } |
175 | 171 |
176 | 172 |
177 void PortMap::ClosePorts() { | 173 void PortMap::ClosePorts() { |
178 Isolate* isolate = Isolate::Current(); | 174 Isolate* isolate = Isolate::Current(); |
179 { | 175 { |
180 MutexLocker ml(mutex_); | 176 MutexLocker ml(mutex_); |
181 for (intptr_t i = 0; i < capacity_; i++) { | 177 for (intptr_t i = 0; i < capacity_; i++) { |
182 if (map_[i].isolate == isolate) { | 178 if (map_[i].isolate == isolate) { |
183 // Mark the slot as deleted. | 179 // Mark the slot as deleted. |
184 map_[i].port = 0; | 180 map_[i].port = 0; |
185 map_[i].isolate = deleted_entry_; | 181 map_[i].isolate = deleted_entry_; |
186 isolate->decrement_num_ports(); | 182 isolate->decrement_num_ports(); |
187 | 183 |
188 used_--; | 184 used_--; |
189 deleted_++; | 185 deleted_++; |
190 } | 186 } |
191 } | 187 } |
192 MaintainInvariants(); | 188 MaintainInvariants(); |
193 } | 189 } |
194 | 190 isolate->CloseAllPorts(); |
195 // Notify the embedder that all ports are closed. | |
196 Dart_ClosePortCallback callback = isolate->close_port_callback(); | |
197 ASSERT(callback); | |
198 (*callback)(Api::CastIsolate(isolate), kCloseAllPorts); | |
199 } | 191 } |
200 | 192 |
201 | 193 |
202 bool PortMap::PostMessage(Dart_Port dest_port, | 194 bool PortMap::PostMessage(Message* message) { |
203 Dart_Port reply_port, | 195 // TODO(turnidge): Add a scoped locker for mutexes which is not a |
204 Dart_Message message) { | 196 // stack resource. This would probably be useful in the platform |
| 197 // headers. |
205 mutex_->Lock(); | 198 mutex_->Lock(); |
206 intptr_t index = FindPort(dest_port); | 199 intptr_t index = FindPort(message->dest_port()); |
207 if (index < 0) { | 200 if (index < 0) { |
208 free(message); | 201 free(message); |
209 mutex_->Unlock(); | 202 mutex_->Unlock(); |
210 return false; | 203 return false; |
211 } | 204 } |
212 ASSERT(index >= 0); | 205 ASSERT(index >= 0); |
213 ASSERT(index < capacity_); | 206 ASSERT(index < capacity_); |
214 Isolate* isolate = map_[index].isolate; | 207 Isolate* isolate = map_[index].isolate; |
215 ASSERT(map_[index].port != 0); | 208 ASSERT(map_[index].port != 0); |
216 ASSERT((isolate != NULL) && (isolate != deleted_entry_)); | 209 ASSERT((isolate != NULL) && (isolate != deleted_entry_)); |
217 | 210 isolate->PostMessage(message); |
218 // Delegate message delivery to the embedder. | |
219 Dart_PostMessageCallback callback = isolate->post_message_callback(); | |
220 ASSERT(callback); | |
221 bool result = | |
222 (*callback)(Api::CastIsolate(isolate), dest_port, reply_port, message); | |
223 if (FLAG_trace_isolates) { | |
224 const char* source_name = "<native code>"; | |
225 Isolate* source_isolate = Isolate::Current(); | |
226 if (source_isolate) { | |
227 source_name = source_isolate->name(); | |
228 } | |
229 OS::Print("[>] Posting message:\n" | |
230 "\tsource: %s\n" | |
231 "\treply_port: %lld\n" | |
232 "\tdest: %s\n" | |
233 "\tdest_port: %lld\n", | |
234 source_name, reply_port, isolate->name(), dest_port); | |
235 } | |
236 mutex_->Unlock(); | 211 mutex_->Unlock(); |
237 return result; | 212 return true; |
238 } | 213 } |
239 | 214 |
240 | 215 |
241 void PortMap::InitOnce() { | 216 void PortMap::InitOnce() { |
242 mutex_ = new Mutex(); | 217 mutex_ = new Mutex(); |
243 | 218 |
244 static const intptr_t kInitialCapacity = 8; | 219 static const intptr_t kInitialCapacity = 8; |
245 // TODO(iposva): Verify whether we want to keep exponentially growing. | 220 // TODO(iposva): Verify whether we want to keep exponentially growing. |
246 ASSERT(Utils::IsPowerOfTwo(kInitialCapacity)); | 221 ASSERT(Utils::IsPowerOfTwo(kInitialCapacity)); |
247 map_ = new Entry[kInitialCapacity]; | 222 map_ = new Entry[kInitialCapacity]; |
248 memset(map_, 0, kInitialCapacity * sizeof(Entry)); | 223 memset(map_, 0, kInitialCapacity * sizeof(Entry)); |
249 capacity_ = kInitialCapacity; | 224 capacity_ = kInitialCapacity; |
250 used_ = 0; | 225 used_ = 0; |
251 deleted_ = 0; | 226 deleted_ = 0; |
252 } | 227 } |
253 | 228 |
254 | 229 |
255 } // namespace dart | 230 } // namespace dart |
OLD | NEW |