Created
October 15, 2019 21:31
-
-
Save deepal/6f2e2529aabe24018e5a38e822c7916b to your computer and use it in GitHub Desktop.
Worker::Run() Run worker thread
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| void Worker::Run() { | |
| std::string name = "WorkerThread "; | |
| name += std::to_string(thread_id_); | |
| TRACE_EVENT_METADATA1( | |
| "__metadata", "thread_name", "name", | |
| TRACE_STR_COPY(name.c_str())); | |
| CHECK_NOT_NULL(platform_); | |
| std::cout << "node_worker.cc[Worker::Run()] Creating WorkerThreadData for worker with id " << thread_id_ << "\n"; | |
| Debug(this, "Creating isolate for worker with id %llu", thread_id_); | |
| // Construction of WorkerThreadData instance will create a new isolate and will assign it as | |
| // the isolate of the worker which was passed as the constructor argument | |
| WorkerThreadData data(this); | |
| Debug(this, "Starting worker with id %llu", thread_id_); | |
| { | |
| Locker locker(isolate_); | |
| Isolate::Scope isolate_scope(isolate_); | |
| SealHandleScope outer_seal(isolate_); | |
| #if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR | |
| bool inspector_started = false; | |
| #endif | |
| DeleteFnPtr<Environment, FreeEnvironment> env_; | |
| OnScopeLeave cleanup_env([&]() { | |
| if (!env_) return; | |
| env_->set_can_call_into_js(false); | |
| Isolate::DisallowJavascriptExecutionScope disallow_js(isolate_, | |
| Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE); | |
| // Grab the parent-to-child channel and render is unusable. | |
| MessagePort* child_port; | |
| { | |
| Mutex::ScopedLock lock(mutex_); | |
| child_port = child_port_; | |
| child_port_ = nullptr; | |
| } | |
| { | |
| Context::Scope context_scope(env_->context()); | |
| if (child_port != nullptr) | |
| child_port->Close(); | |
| { | |
| Mutex::ScopedLock lock(mutex_); | |
| stopped_ = true; | |
| this->env_ = nullptr; | |
| } | |
| env_->thread_stopper()->set_stopped(true); | |
| env_->stop_sub_worker_contexts(); | |
| env_->RunCleanup(); | |
| RunAtExit(env_.get()); | |
| #if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR | |
| if (inspector_started) | |
| WaitForWorkerInspectorToStop(env_.get()); | |
| #endif | |
| // This call needs to be made while the `Environment` is still alive | |
| // because we assume that it is available for async tracking in the | |
| // NodePlatform implementation. | |
| platform_->DrainTasks(isolate_); | |
| } | |
| }); | |
| if (is_stopped()) return; | |
| { | |
| HandleScope handle_scope(isolate_); | |
| Local<Context> context = NewContext(isolate_); | |
| if (is_stopped()) return; | |
| CHECK(!context.IsEmpty()); | |
| Context::Scope context_scope(context); | |
| { | |
| // TODO(addaleax): Use CreateEnvironment(), or generally another | |
| // public API. | |
| std::cout << "node_worker.cc[Worker::Run()] Resetting worker environment\n"; | |
| env_.reset(new Environment(data.isolate_data_.get(), | |
| context, | |
| std::move(argv_), | |
| std::move(exec_argv_), | |
| Environment::kNoFlags, | |
| thread_id_)); | |
| CHECK_NOT_NULL(env_); | |
| env_->set_env_vars(std::move(env_vars_)); | |
| env_->set_abort_on_uncaught_exception(false); | |
| env_->set_worker_context(this); | |
| std::cout<<"node_worker.cc[Worker::Run()] Initializing libuv for thread " << thread_id_ << "\n"; | |
| env_->InitializeLibuv(start_profiler_idle_notifier_); | |
| } | |
| { | |
| Mutex::ScopedLock lock(mutex_); | |
| if (stopped_) return; | |
| this->env_ = env_.get(); | |
| } | |
| Debug(this, "Created Environment for worker with id %llu", thread_id_); | |
| if (is_stopped()) return; | |
| { | |
| env_->InitializeDiagnostics(); | |
| #if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR | |
| env_->InitializeInspector(inspector_parent_handle_.release()); | |
| inspector_started = true; | |
| #endif | |
| HandleScope handle_scope(isolate_); | |
| AsyncCallbackScope callback_scope(env_.get()); | |
| env_->async_hooks()->push_async_ids(1, 0); | |
| if (!env_->RunBootstrapping().IsEmpty()) { | |
| CreateEnvMessagePort(env_.get()); | |
| if (is_stopped()) return; | |
| std::cout<<"node_worker.cc[Worker::Run()] Created message port for worker " << thread_id_ << "\n"; | |
| Debug(this, "Created message port for worker %llu", thread_id_); | |
| std::cout<<"node_worker.cc[Worker::Run()] Running script internal/main/worker_thread \n"; | |
| USE(StartExecution(env_.get(), "internal/main/worker_thread")); | |
| } | |
| env_->async_hooks()->pop_async_id(1); | |
| Debug(this, "Loaded environment for worker %llu", thread_id_); | |
| } | |
| if (is_stopped()) return; | |
| { | |
| SealHandleScope seal(isolate_); | |
| bool more; | |
| env_->performance_state()->Mark( | |
| node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START); | |
| std::cout<<"node_worker.cc[Worker::Run()] Starting event loop on worker thread " << thread_id_ << "\n"; | |
| do { | |
| if (is_stopped()) break; | |
| uv_run(&data.loop_, UV_RUN_DEFAULT); | |
| if (is_stopped()) break; | |
| platform_->DrainTasks(isolate_); | |
| more = uv_loop_alive(&data.loop_); | |
| if (more && !is_stopped()) continue; | |
| std::cout<<"node_worker.cc[Worker::Run()] Emitting 'beforeExit' on worker thread " << thread_id_ << "\n"; | |
| EmitBeforeExit(env_.get()); | |
| // Emit `beforeExit` if the loop became alive either after emitting | |
| // event, or after running some callbacks. | |
| more = uv_loop_alive(&data.loop_); | |
| } while (more == true && !is_stopped()); | |
| env_->performance_state()->Mark( | |
| node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT); | |
| } | |
| } | |
| { | |
| int exit_code; | |
| bool stopped = is_stopped(); | |
| if (!stopped) | |
| std::cout<<"node_worker.cc[Worker::Run()] Emitting 'exit' on worker thread " << thread_id_ << "\n"; | |
| exit_code = EmitExit(env_.get()); | |
| Mutex::ScopedLock lock(mutex_); | |
| if (exit_code_ == 0 && !stopped) | |
| exit_code_ = exit_code; | |
| #if HAVE_INSPECTOR | |
| profiler::EndStartedProfilers(env_.get()); | |
| #endif | |
| std::cout << "node_worker.cc[Worker::Run()] Exiting thread for worker " << thread_id_ << " with exit code " << exit_code_ << " \n"; | |
| Debug(this, "Exiting thread for worker %llu with exit code %d", | |
| thread_id_, exit_code_); | |
| } | |
| } | |
| Debug(this, "Worker %llu thread stops", thread_id_); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment