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 "include/dart_native_api.h" | 5 #include "include/dart_native_api.h" |
6 #include "platform/assert.h" | 6 #include "platform/assert.h" |
7 #include "vm/bootstrap_natives.h" | 7 #include "vm/bootstrap_natives.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/dart.h" | 9 #include "vm/dart.h" |
10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 | 136 |
137 class SpawnIsolateTask : public ThreadPool::Task { | 137 class SpawnIsolateTask : public ThreadPool::Task { |
138 public: | 138 public: |
139 explicit SpawnIsolateTask(IsolateSpawnState* state) : state_(state) {} | 139 explicit SpawnIsolateTask(IsolateSpawnState* state) : state_(state) {} |
140 | 140 |
141 virtual void Run() { | 141 virtual void Run() { |
142 // Create a new isolate. | 142 // Create a new isolate. |
143 char* error = NULL; | 143 char* error = NULL; |
144 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); | 144 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); |
145 if (callback == NULL) { | 145 if (callback == NULL) { |
| 146 state_->DecrementSpawnCount(); |
146 ReportError( | 147 ReportError( |
147 "Isolate spawn is not supported by this Dart implementation\n"); | 148 "Isolate spawn is not supported by this Dart implementation\n"); |
148 delete state_; | 149 delete state_; |
149 state_ = NULL; | 150 state_ = NULL; |
150 return; | 151 return; |
151 } | 152 } |
152 | 153 |
153 Dart_IsolateFlags api_flags; | 154 Dart_IsolateFlags api_flags; |
154 state_->isolate_flags()->CopyTo(&api_flags); | 155 state_->isolate_flags()->CopyTo(&api_flags); |
155 | 156 |
156 Isolate* isolate = reinterpret_cast<Isolate*>( | 157 Isolate* isolate = reinterpret_cast<Isolate*>( |
157 (callback)(state_->script_url(), | 158 (callback)(state_->script_url(), |
158 state_->function_name(), | 159 state_->function_name(), |
159 state_->package_root(), | 160 state_->package_root(), |
160 state_->package_map(), | 161 state_->package_map(), |
161 &api_flags, | 162 &api_flags, |
162 state_->init_data(), | 163 state_->init_data(), |
163 &error)); | 164 &error)); |
| 165 state_->DecrementSpawnCount(); |
164 if (isolate == NULL) { | 166 if (isolate == NULL) { |
165 ReportError(error); | 167 ReportError(error); |
166 delete state_; | 168 delete state_; |
167 state_ = NULL; | 169 state_ = NULL; |
168 free(error); | 170 free(error); |
169 return; | 171 return; |
170 } | 172 } |
171 | 173 |
172 if (state_->origin_id() != ILLEGAL_PORT) { | 174 if (state_->origin_id() != ILLEGAL_PORT) { |
173 // For isolates spawned using spawnFunction we set the origin_id | 175 // For isolates spawned using spawnFunction we set the origin_id |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 ctx = Closure::context(closure); | 220 ctx = Closure::context(closure); |
219 ASSERT(ctx.num_variables() == 0); | 221 ASSERT(ctx.num_variables() == 0); |
220 #endif | 222 #endif |
221 // Get the parent function so that we get the right function name. | 223 // Get the parent function so that we get the right function name. |
222 func = func.parent_function(); | 224 func = func.parent_function(); |
223 | 225 |
224 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); | 226 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); |
225 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); | 227 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); |
226 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); | 228 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); |
227 | 229 |
228 ThreadPool::Task* spawn_task = | 230 IsolateSpawnState* state = |
229 new SpawnIsolateTask( | 231 new IsolateSpawnState(port.Id(), |
230 new IsolateSpawnState(port.Id(), | 232 isolate->origin_id(), |
231 isolate->origin_id(), | 233 isolate->init_callback_data(), |
232 isolate->init_callback_data(), | 234 func, |
233 func, | 235 message, |
234 message, | 236 isolate->spawn_count_monitor(), |
235 paused.value(), | 237 isolate->spawn_count(), |
236 fatal_errors, | 238 paused.value(), |
237 on_exit_port, | 239 fatal_errors, |
238 on_error_port)); | 240 on_exit_port, |
| 241 on_error_port); |
| 242 ThreadPool::Task* spawn_task = new SpawnIsolateTask(state); |
| 243 |
| 244 isolate->IncrementSpawnCount(); |
239 if (FLAG_i_like_slow_isolate_spawn) { | 245 if (FLAG_i_like_slow_isolate_spawn) { |
240 // We block the parent isolate while the child isolate loads. | 246 // We block the parent isolate while the child isolate loads. |
241 Isolate* saved = Isolate::Current(); | 247 Isolate* saved = Isolate::Current(); |
242 Thread::ExitIsolate(); | 248 Thread::ExitIsolate(); |
243 spawn_task->Run(); | 249 spawn_task->Run(); |
244 delete spawn_task; | 250 delete spawn_task; |
245 spawn_task = NULL; | 251 spawn_task = NULL; |
246 Thread::EnterIsolate(saved); | 252 Thread::EnterIsolate(saved); |
247 } else { | 253 } else if (!Dart::thread_pool()->Run(spawn_task)) { |
248 Dart::thread_pool()->Run(spawn_task); | 254 // Running on the thread pool failed. Clean up everything. |
| 255 state->DecrementSpawnCount(); |
| 256 delete state; |
| 257 state = NULL; |
| 258 delete spawn_task; |
| 259 spawn_task = NULL; |
249 } | 260 } |
250 return Object::null(); | 261 return Object::null(); |
251 } | 262 } |
252 } | 263 } |
253 const String& msg = String::Handle(String::New( | 264 const String& msg = String::Handle(String::New( |
254 "Isolate.spawn expects to be passed a static or top-level function")); | 265 "Isolate.spawn expects to be passed a static or top-level function")); |
255 Exceptions::ThrowArgumentError(msg); | 266 Exceptions::ThrowArgumentError(msg); |
256 return Object::null(); | 267 return Object::null(); |
257 } | 268 } |
258 | 269 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 | 379 |
369 IsolateSpawnState* state = | 380 IsolateSpawnState* state = |
370 new IsolateSpawnState( | 381 new IsolateSpawnState( |
371 port.Id(), | 382 port.Id(), |
372 isolate->init_callback_data(), | 383 isolate->init_callback_data(), |
373 canonical_uri, | 384 canonical_uri, |
374 utf8_package_root, | 385 utf8_package_root, |
375 utf8_package_map, | 386 utf8_package_map, |
376 args, | 387 args, |
377 message, | 388 message, |
| 389 isolate->spawn_count_monitor(), |
| 390 isolate->spawn_count(), |
378 paused.value(), | 391 paused.value(), |
379 fatal_errors, | 392 fatal_errors, |
380 on_exit_port, | 393 on_exit_port, |
381 on_error_port); | 394 on_error_port); |
382 | 395 |
383 // If we were passed a value then override the default flags state for | 396 // If we were passed a value then override the default flags state for |
384 // checked mode. | 397 // checked mode. |
385 if (!checked.IsNull()) { | 398 if (!checked.IsNull()) { |
386 state->isolate_flags()->set_checked(checked.value()); | 399 state->isolate_flags()->set_checked(checked.value()); |
387 } | 400 } |
388 | 401 |
389 ThreadPool::Task* spawn_task = new SpawnIsolateTask(state); | 402 ThreadPool::Task* spawn_task = new SpawnIsolateTask(state); |
| 403 |
| 404 isolate->IncrementSpawnCount(); |
390 if (FLAG_i_like_slow_isolate_spawn) { | 405 if (FLAG_i_like_slow_isolate_spawn) { |
391 // We block the parent isolate while the child isolate loads. | 406 // We block the parent isolate while the child isolate loads. |
392 Isolate* saved = Isolate::Current(); | 407 Isolate* saved = Isolate::Current(); |
393 Thread::ExitIsolate(); | 408 Thread::ExitIsolate(); |
394 spawn_task->Run(); | 409 spawn_task->Run(); |
395 delete spawn_task; | 410 delete spawn_task; |
396 spawn_task = NULL; | 411 spawn_task = NULL; |
397 Thread::EnterIsolate(saved); | 412 Thread::EnterIsolate(saved); |
398 } else { | 413 } else if (!Dart::thread_pool()->Run(spawn_task)) { |
399 Dart::thread_pool()->Run(spawn_task); | 414 // Running on the thread pool failed. Clean up everything. |
| 415 state->DecrementSpawnCount(); |
| 416 delete state; |
| 417 state = NULL; |
| 418 delete spawn_task; |
| 419 spawn_task = NULL; |
400 } | 420 } |
401 return Object::null(); | 421 return Object::null(); |
402 } | 422 } |
403 | 423 |
404 | 424 |
405 DEFINE_NATIVE_ENTRY(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) { | 425 DEFINE_NATIVE_ENTRY(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) { |
406 const Array& result = Array::Handle(Array::New(3)); | 426 const Array& result = Array::Handle(Array::New(3)); |
407 result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port()))); | 427 result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port()))); |
408 result.SetAt(1, Capability::Handle( | 428 result.SetAt(1, Capability::Handle( |
409 Capability::New(isolate->pause_capability()))); | 429 Capability::New(isolate->pause_capability()))); |
(...skipping 14 matching lines...) Expand all Loading... |
424 MessageWriter writer(&data, &allocator, false); | 444 MessageWriter writer(&data, &allocator, false); |
425 writer.WriteMessage(msg); | 445 writer.WriteMessage(msg); |
426 | 446 |
427 PortMap::PostMessage(new Message(port.Id(), | 447 PortMap::PostMessage(new Message(port.Id(), |
428 data, writer.BytesWritten(), | 448 data, writer.BytesWritten(), |
429 Message::kOOBPriority)); | 449 Message::kOOBPriority)); |
430 return Object::null(); | 450 return Object::null(); |
431 } | 451 } |
432 | 452 |
433 } // namespace dart | 453 } // namespace dart |
OLD | NEW |