11cb0ef41Sopenharmony_ci#include "main_thread_interface.h"
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci#include "env-inl.h"
41cb0ef41Sopenharmony_ci#include "simdutf.h"
51cb0ef41Sopenharmony_ci#include "v8-inspector.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <functional>
81cb0ef41Sopenharmony_ci#include <memory>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_cinamespace node {
111cb0ef41Sopenharmony_cinamespace inspector {
121cb0ef41Sopenharmony_cinamespace {
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciusing v8_inspector::StringBuffer;
151cb0ef41Sopenharmony_ciusing v8_inspector::StringView;
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_citemplate <typename T>
181cb0ef41Sopenharmony_ciclass DeletableWrapper : public Deletable {
191cb0ef41Sopenharmony_ci public:
201cb0ef41Sopenharmony_ci  explicit DeletableWrapper(std::unique_ptr<T> object)
211cb0ef41Sopenharmony_ci                        : object_(std::move(object)) {}
221cb0ef41Sopenharmony_ci  ~DeletableWrapper() override = default;
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci  static T* get(MainThreadInterface* thread, int id) {
251cb0ef41Sopenharmony_ci    return
261cb0ef41Sopenharmony_ci        static_cast<DeletableWrapper<T>*>(thread->GetObject(id))->object_.get();
271cb0ef41Sopenharmony_ci  }
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci private:
301cb0ef41Sopenharmony_ci  std::unique_ptr<T> object_;
311cb0ef41Sopenharmony_ci};
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_citemplate <typename T>
341cb0ef41Sopenharmony_cistd::unique_ptr<Deletable> WrapInDeletable(std::unique_ptr<T> object) {
351cb0ef41Sopenharmony_ci  return std::unique_ptr<DeletableWrapper<T>>(
361cb0ef41Sopenharmony_ci      new DeletableWrapper<T>(std::move(object)));
371cb0ef41Sopenharmony_ci}
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_citemplate <typename Factory>
401cb0ef41Sopenharmony_ciclass CreateObjectRequest : public Request {
411cb0ef41Sopenharmony_ci public:
421cb0ef41Sopenharmony_ci  CreateObjectRequest(int object_id, Factory factory)
431cb0ef41Sopenharmony_ci                      : object_id_(object_id), factory_(std::move(factory)) {}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  void Call(MainThreadInterface* thread) override {
461cb0ef41Sopenharmony_ci    thread->AddObject(object_id_, WrapInDeletable(factory_(thread)));
471cb0ef41Sopenharmony_ci  }
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci private:
501cb0ef41Sopenharmony_ci  int object_id_;
511cb0ef41Sopenharmony_ci  Factory factory_;
521cb0ef41Sopenharmony_ci};
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_citemplate <typename Factory>
551cb0ef41Sopenharmony_cistd::unique_ptr<Request> NewCreateRequest(int object_id, Factory factory) {
561cb0ef41Sopenharmony_ci  return std::unique_ptr<Request>(
571cb0ef41Sopenharmony_ci      new CreateObjectRequest<Factory>(object_id, std::move(factory)));
581cb0ef41Sopenharmony_ci}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ciclass DeleteRequest : public Request {
611cb0ef41Sopenharmony_ci public:
621cb0ef41Sopenharmony_ci  explicit DeleteRequest(int object_id) : object_id_(object_id) {}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  void Call(MainThreadInterface* thread) override {
651cb0ef41Sopenharmony_ci    thread->RemoveObject(object_id_);
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci private:
691cb0ef41Sopenharmony_ci  int object_id_;
701cb0ef41Sopenharmony_ci};
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_citemplate <typename Target, typename Fn>
731cb0ef41Sopenharmony_ciclass CallRequest : public Request {
741cb0ef41Sopenharmony_ci public:
751cb0ef41Sopenharmony_ci  CallRequest(int id, Fn fn) : id_(id), fn_(std::move(fn)) {}
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  void Call(MainThreadInterface* thread) override {
781cb0ef41Sopenharmony_ci    fn_(DeletableWrapper<Target>::get(thread, id_));
791cb0ef41Sopenharmony_ci  }
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci private:
821cb0ef41Sopenharmony_ci  int id_;
831cb0ef41Sopenharmony_ci  Fn fn_;
841cb0ef41Sopenharmony_ci};
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_citemplate <typename T>
871cb0ef41Sopenharmony_ciclass AnotherThreadObjectReference {
881cb0ef41Sopenharmony_ci public:
891cb0ef41Sopenharmony_ci  AnotherThreadObjectReference(
901cb0ef41Sopenharmony_ci      std::shared_ptr<MainThreadHandle> thread, int object_id)
911cb0ef41Sopenharmony_ci      : thread_(thread), object_id_(object_id) {}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  template <typename Factory>
941cb0ef41Sopenharmony_ci  AnotherThreadObjectReference(
951cb0ef41Sopenharmony_ci      std::shared_ptr<MainThreadHandle> thread, Factory factory)
961cb0ef41Sopenharmony_ci      : AnotherThreadObjectReference(thread, thread->newObjectId()) {
971cb0ef41Sopenharmony_ci    thread_->Post(NewCreateRequest(object_id_, std::move(factory)));
981cb0ef41Sopenharmony_ci  }
991cb0ef41Sopenharmony_ci  AnotherThreadObjectReference(AnotherThreadObjectReference&) = delete;
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  ~AnotherThreadObjectReference() {
1021cb0ef41Sopenharmony_ci    // Disappearing thread may cause a memory leak
1031cb0ef41Sopenharmony_ci    thread_->Post(std::make_unique<DeleteRequest>(object_id_));
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  template <typename Fn>
1071cb0ef41Sopenharmony_ci  void Call(Fn fn) const {
1081cb0ef41Sopenharmony_ci    using Request = CallRequest<T, Fn>;
1091cb0ef41Sopenharmony_ci    thread_->Post(std::unique_ptr<Request>(
1101cb0ef41Sopenharmony_ci        new Request(object_id_, std::move(fn))));
1111cb0ef41Sopenharmony_ci  }
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  template <typename Arg>
1141cb0ef41Sopenharmony_ci  void Call(void (T::*fn)(Arg), Arg argument) const {
1151cb0ef41Sopenharmony_ci    Call(std::bind(Apply<Arg>, std::placeholders::_1, fn, std::move(argument)));
1161cb0ef41Sopenharmony_ci  }
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci private:
1191cb0ef41Sopenharmony_ci  // This has to use non-const reference to support std::bind with non-copyable
1201cb0ef41Sopenharmony_ci  // types
1211cb0ef41Sopenharmony_ci  template <typename Argument>
1221cb0ef41Sopenharmony_ci  static void Apply(T* target, void (T::*fn)(Argument),
1231cb0ef41Sopenharmony_ci    /* NOLINT (runtime/references) */ Argument& argument) {
1241cb0ef41Sopenharmony_ci    (target->*fn)(std::move(argument));
1251cb0ef41Sopenharmony_ci  }
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  std::shared_ptr<MainThreadHandle> thread_;
1281cb0ef41Sopenharmony_ci  const int object_id_;
1291cb0ef41Sopenharmony_ci};
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ciclass MainThreadSessionState {
1321cb0ef41Sopenharmony_ci public:
1331cb0ef41Sopenharmony_ci  MainThreadSessionState(MainThreadInterface* thread, bool prevent_shutdown)
1341cb0ef41Sopenharmony_ci                         : thread_(thread),
1351cb0ef41Sopenharmony_ci                           prevent_shutdown_(prevent_shutdown) {}
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  static std::unique_ptr<MainThreadSessionState> Create(
1381cb0ef41Sopenharmony_ci      MainThreadInterface* thread, bool prevent_shutdown) {
1391cb0ef41Sopenharmony_ci    return std::make_unique<MainThreadSessionState>(thread, prevent_shutdown);
1401cb0ef41Sopenharmony_ci  }
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  void Connect(std::unique_ptr<InspectorSessionDelegate> delegate) {
1431cb0ef41Sopenharmony_ci    Agent* agent = thread_->inspector_agent();
1441cb0ef41Sopenharmony_ci    if (agent != nullptr)
1451cb0ef41Sopenharmony_ci      session_ = agent->Connect(std::move(delegate), prevent_shutdown_);
1461cb0ef41Sopenharmony_ci  }
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  void Dispatch(std::unique_ptr<StringBuffer> message) {
1491cb0ef41Sopenharmony_ci    session_->Dispatch(message->string());
1501cb0ef41Sopenharmony_ci  }
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci private:
1531cb0ef41Sopenharmony_ci  MainThreadInterface* thread_;
1541cb0ef41Sopenharmony_ci  bool prevent_shutdown_;
1551cb0ef41Sopenharmony_ci  std::unique_ptr<InspectorSession> session_;
1561cb0ef41Sopenharmony_ci};
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ciclass CrossThreadInspectorSession : public InspectorSession {
1591cb0ef41Sopenharmony_ci public:
1601cb0ef41Sopenharmony_ci  CrossThreadInspectorSession(
1611cb0ef41Sopenharmony_ci      int id,
1621cb0ef41Sopenharmony_ci      std::shared_ptr<MainThreadHandle> thread,
1631cb0ef41Sopenharmony_ci      std::unique_ptr<InspectorSessionDelegate> delegate,
1641cb0ef41Sopenharmony_ci      bool prevent_shutdown)
1651cb0ef41Sopenharmony_ci      : state_(thread, std::bind(MainThreadSessionState::Create,
1661cb0ef41Sopenharmony_ci                                 std::placeholders::_1,
1671cb0ef41Sopenharmony_ci                                 prevent_shutdown)) {
1681cb0ef41Sopenharmony_ci    state_.Call(&MainThreadSessionState::Connect, std::move(delegate));
1691cb0ef41Sopenharmony_ci  }
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  void Dispatch(const StringView& message) override {
1721cb0ef41Sopenharmony_ci    state_.Call(&MainThreadSessionState::Dispatch,
1731cb0ef41Sopenharmony_ci                StringBuffer::create(message));
1741cb0ef41Sopenharmony_ci  }
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci private:
1771cb0ef41Sopenharmony_ci  AnotherThreadObjectReference<MainThreadSessionState> state_;
1781cb0ef41Sopenharmony_ci};
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ciclass ThreadSafeDelegate : public InspectorSessionDelegate {
1811cb0ef41Sopenharmony_ci public:
1821cb0ef41Sopenharmony_ci  ThreadSafeDelegate(std::shared_ptr<MainThreadHandle> thread, int object_id)
1831cb0ef41Sopenharmony_ci                     : thread_(thread), delegate_(thread, object_id) {}
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  void SendMessageToFrontend(const v8_inspector::StringView& message) override {
1861cb0ef41Sopenharmony_ci    delegate_.Call(
1871cb0ef41Sopenharmony_ci        [m = StringBuffer::create(message)]
1881cb0ef41Sopenharmony_ci        (InspectorSessionDelegate* delegate) {
1891cb0ef41Sopenharmony_ci      delegate->SendMessageToFrontend(m->string());
1901cb0ef41Sopenharmony_ci    });
1911cb0ef41Sopenharmony_ci  }
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci private:
1941cb0ef41Sopenharmony_ci  std::shared_ptr<MainThreadHandle> thread_;
1951cb0ef41Sopenharmony_ci  AnotherThreadObjectReference<InspectorSessionDelegate> delegate_;
1961cb0ef41Sopenharmony_ci};
1971cb0ef41Sopenharmony_ci}  // namespace
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ciMainThreadInterface::MainThreadInterface(Agent* agent) : agent_(agent) {}
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ciMainThreadInterface::~MainThreadInterface() {
2031cb0ef41Sopenharmony_ci  if (handle_)
2041cb0ef41Sopenharmony_ci    handle_->Reset();
2051cb0ef41Sopenharmony_ci}
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_civoid MainThreadInterface::Post(std::unique_ptr<Request> request) {
2081cb0ef41Sopenharmony_ci  CHECK_NOT_NULL(agent_);
2091cb0ef41Sopenharmony_ci  Mutex::ScopedLock scoped_lock(requests_lock_);
2101cb0ef41Sopenharmony_ci  bool needs_notify = requests_.empty();
2111cb0ef41Sopenharmony_ci  requests_.push_back(std::move(request));
2121cb0ef41Sopenharmony_ci  if (needs_notify) {
2131cb0ef41Sopenharmony_ci    std::weak_ptr<MainThreadInterface> weak_self {shared_from_this()};
2141cb0ef41Sopenharmony_ci    agent_->env()->RequestInterrupt([weak_self](Environment*) {
2151cb0ef41Sopenharmony_ci      if (auto iface = weak_self.lock()) iface->DispatchMessages();
2161cb0ef41Sopenharmony_ci    });
2171cb0ef41Sopenharmony_ci  }
2181cb0ef41Sopenharmony_ci  incoming_message_cond_.Broadcast(scoped_lock);
2191cb0ef41Sopenharmony_ci}
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_cibool MainThreadInterface::WaitForFrontendEvent() {
2221cb0ef41Sopenharmony_ci  // We allow DispatchMessages reentry as we enter the pause. This is important
2231cb0ef41Sopenharmony_ci  // to support debugging the code invoked by an inspector call, such
2241cb0ef41Sopenharmony_ci  // as Runtime.evaluate
2251cb0ef41Sopenharmony_ci  dispatching_messages_ = false;
2261cb0ef41Sopenharmony_ci  if (dispatching_message_queue_.empty()) {
2271cb0ef41Sopenharmony_ci    Mutex::ScopedLock scoped_lock(requests_lock_);
2281cb0ef41Sopenharmony_ci    while (requests_.empty()) incoming_message_cond_.Wait(scoped_lock);
2291cb0ef41Sopenharmony_ci  }
2301cb0ef41Sopenharmony_ci  return true;
2311cb0ef41Sopenharmony_ci}
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_civoid MainThreadInterface::DispatchMessages() {
2341cb0ef41Sopenharmony_ci  if (dispatching_messages_)
2351cb0ef41Sopenharmony_ci    return;
2361cb0ef41Sopenharmony_ci  dispatching_messages_ = true;
2371cb0ef41Sopenharmony_ci  bool had_messages = false;
2381cb0ef41Sopenharmony_ci  do {
2391cb0ef41Sopenharmony_ci    if (dispatching_message_queue_.empty()) {
2401cb0ef41Sopenharmony_ci      Mutex::ScopedLock scoped_lock(requests_lock_);
2411cb0ef41Sopenharmony_ci      requests_.swap(dispatching_message_queue_);
2421cb0ef41Sopenharmony_ci    }
2431cb0ef41Sopenharmony_ci    had_messages = !dispatching_message_queue_.empty();
2441cb0ef41Sopenharmony_ci    while (!dispatching_message_queue_.empty()) {
2451cb0ef41Sopenharmony_ci      MessageQueue::value_type task;
2461cb0ef41Sopenharmony_ci      std::swap(dispatching_message_queue_.front(), task);
2471cb0ef41Sopenharmony_ci      dispatching_message_queue_.pop_front();
2481cb0ef41Sopenharmony_ci
2491cb0ef41Sopenharmony_ci      v8::SealHandleScope seal_handle_scope(agent_->env()->isolate());
2501cb0ef41Sopenharmony_ci      task->Call(this);
2511cb0ef41Sopenharmony_ci    }
2521cb0ef41Sopenharmony_ci  } while (had_messages);
2531cb0ef41Sopenharmony_ci  dispatching_messages_ = false;
2541cb0ef41Sopenharmony_ci}
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_cistd::shared_ptr<MainThreadHandle> MainThreadInterface::GetHandle() {
2571cb0ef41Sopenharmony_ci  if (handle_ == nullptr)
2581cb0ef41Sopenharmony_ci    handle_ = std::make_shared<MainThreadHandle>(this);
2591cb0ef41Sopenharmony_ci  return handle_;
2601cb0ef41Sopenharmony_ci}
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_civoid MainThreadInterface::AddObject(int id,
2631cb0ef41Sopenharmony_ci                                    std::unique_ptr<Deletable> object) {
2641cb0ef41Sopenharmony_ci  CHECK_NOT_NULL(object);
2651cb0ef41Sopenharmony_ci  managed_objects_[id] = std::move(object);
2661cb0ef41Sopenharmony_ci}
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_civoid MainThreadInterface::RemoveObject(int id) {
2691cb0ef41Sopenharmony_ci  CHECK_EQ(1, managed_objects_.erase(id));
2701cb0ef41Sopenharmony_ci}
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ciDeletable* MainThreadInterface::GetObject(int id) {
2731cb0ef41Sopenharmony_ci  Deletable* pointer = GetObjectIfExists(id);
2741cb0ef41Sopenharmony_ci  // This would mean the object is requested after it was disposed, which is
2751cb0ef41Sopenharmony_ci  // a coding error.
2761cb0ef41Sopenharmony_ci  CHECK_NOT_NULL(pointer);
2771cb0ef41Sopenharmony_ci  return pointer;
2781cb0ef41Sopenharmony_ci}
2791cb0ef41Sopenharmony_ci
2801cb0ef41Sopenharmony_ciDeletable* MainThreadInterface::GetObjectIfExists(int id) {
2811cb0ef41Sopenharmony_ci  auto iterator = managed_objects_.find(id);
2821cb0ef41Sopenharmony_ci  if (iterator == managed_objects_.end()) {
2831cb0ef41Sopenharmony_ci    return nullptr;
2841cb0ef41Sopenharmony_ci  }
2851cb0ef41Sopenharmony_ci  return iterator->second.get();
2861cb0ef41Sopenharmony_ci}
2871cb0ef41Sopenharmony_ci
2881cb0ef41Sopenharmony_cistd::unique_ptr<StringBuffer> Utf8ToStringView(const std::string_view message) {
2891cb0ef41Sopenharmony_ci  size_t expected_u16_length =
2901cb0ef41Sopenharmony_ci      simdutf::utf16_length_from_utf8(message.data(), message.length());
2911cb0ef41Sopenharmony_ci  MaybeStackBuffer<char16_t> buffer(expected_u16_length);
2921cb0ef41Sopenharmony_ci  size_t utf16_length = simdutf::convert_utf8_to_utf16(
2931cb0ef41Sopenharmony_ci      message.data(), message.length(), buffer.out());
2941cb0ef41Sopenharmony_ci  StringView view(reinterpret_cast<uint16_t*>(buffer.out()), utf16_length);
2951cb0ef41Sopenharmony_ci  return StringBuffer::create(view);
2961cb0ef41Sopenharmony_ci}
2971cb0ef41Sopenharmony_ci
2981cb0ef41Sopenharmony_cistd::unique_ptr<InspectorSession> MainThreadHandle::Connect(
2991cb0ef41Sopenharmony_ci    std::unique_ptr<InspectorSessionDelegate> delegate,
3001cb0ef41Sopenharmony_ci    bool prevent_shutdown) {
3011cb0ef41Sopenharmony_ci  return std::unique_ptr<InspectorSession>(
3021cb0ef41Sopenharmony_ci      new CrossThreadInspectorSession(++next_session_id_,
3031cb0ef41Sopenharmony_ci                                      shared_from_this(),
3041cb0ef41Sopenharmony_ci                                      std::move(delegate),
3051cb0ef41Sopenharmony_ci                                      prevent_shutdown));
3061cb0ef41Sopenharmony_ci}
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_cibool MainThreadHandle::Post(std::unique_ptr<Request> request) {
3091cb0ef41Sopenharmony_ci  Mutex::ScopedLock scoped_lock(block_lock_);
3101cb0ef41Sopenharmony_ci  if (!main_thread_)
3111cb0ef41Sopenharmony_ci    return false;
3121cb0ef41Sopenharmony_ci  main_thread_->Post(std::move(request));
3131cb0ef41Sopenharmony_ci  return true;
3141cb0ef41Sopenharmony_ci}
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_civoid MainThreadHandle::Reset() {
3171cb0ef41Sopenharmony_ci  Mutex::ScopedLock scoped_lock(block_lock_);
3181cb0ef41Sopenharmony_ci  main_thread_ = nullptr;
3191cb0ef41Sopenharmony_ci}
3201cb0ef41Sopenharmony_ci
3211cb0ef41Sopenharmony_cistd::unique_ptr<InspectorSessionDelegate>
3221cb0ef41Sopenharmony_ciMainThreadHandle::MakeDelegateThreadSafe(
3231cb0ef41Sopenharmony_ci    std::unique_ptr<InspectorSessionDelegate> delegate) {
3241cb0ef41Sopenharmony_ci  int id = newObjectId();
3251cb0ef41Sopenharmony_ci  main_thread_->AddObject(id, WrapInDeletable(std::move(delegate)));
3261cb0ef41Sopenharmony_ci  return std::unique_ptr<InspectorSessionDelegate>(
3271cb0ef41Sopenharmony_ci      new ThreadSafeDelegate(shared_from_this(), id));
3281cb0ef41Sopenharmony_ci}
3291cb0ef41Sopenharmony_ci
3301cb0ef41Sopenharmony_cibool MainThreadHandle::Expired() {
3311cb0ef41Sopenharmony_ci  Mutex::ScopedLock scoped_lock(block_lock_);
3321cb0ef41Sopenharmony_ci  return main_thread_ == nullptr;
3331cb0ef41Sopenharmony_ci}
3341cb0ef41Sopenharmony_ci}  // namespace inspector
3351cb0ef41Sopenharmony_ci}  // namespace node
336