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(); |
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 |