GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/api/embed_helpers.cc Lines: 80 90 88.9 %
Date: 2021-02-19 04:08:54 Branches: 24 52 46.2 %

Line Branch Exec Source
1
#include "node.h"
2
#include "env-inl.h"
3
#include "debug_utils-inl.h"
4
5
using v8::Context;
6
using v8::Global;
7
using v8::HandleScope;
8
using v8::Isolate;
9
using v8::Local;
10
using v8::Locker;
11
using v8::Maybe;
12
using v8::Nothing;
13
using v8::SealHandleScope;
14
15
namespace node {
16
17
106
Maybe<int> SpinEventLoop(Environment* env) {
18
106
  CHECK_NOT_NULL(env);
19
106
  MultiIsolatePlatform* platform = GetMultiIsolatePlatform(env);
20
106
  CHECK_NOT_NULL(platform);
21
22
210
  HandleScope handle_scope(env->isolate());
23
106
  Context::Scope context_scope(env->context());
24
210
  SealHandleScope seal(env->isolate());
25
26
106
  if (env->is_stopping()) return Nothing<int>();
27
28
106
  env->set_trace_sync_io(env->options()->trace_sync_io);
29
  {
30
    bool more;
31
106
    env->performance_state()->Mark(
32
106
        node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START);
33
104
    do {
34
106
      if (env->is_stopping()) break;
35
106
      uv_run(env->event_loop(), UV_RUN_DEFAULT);
36
104
      if (env->is_stopping()) break;
37
38
104
      platform->DrainTasks(env->isolate());
39
40
104
      more = uv_loop_alive(env->event_loop());
41

104
      if (more && !env->is_stopping()) continue;
42
43
208
      if (EmitProcessBeforeExit(env).IsNothing())
44
        break;
45
46
      // Emit `beforeExit` if the loop became alive either after emitting
47
      // event, or after running some callbacks.
48
104
      more = uv_loop_alive(env->event_loop());
49

104
    } while (more == true && !env->is_stopping());
50
104
    env->performance_state()->Mark(
51
104
        node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT);
52
  }
53
104
  if (env->is_stopping()) return Nothing<int>();
54
55
104
  env->set_trace_sync_io(false);
56
104
  env->VerifyNoStrongBaseObjects();
57
104
  return EmitProcessExit(env);
58
}
59
60
24
struct CommonEnvironmentSetup::Impl {
61
  MultiIsolatePlatform* platform = nullptr;
62
  uv_loop_t loop;
63
  std::shared_ptr<ArrayBufferAllocator> allocator;
64
  Isolate* isolate = nullptr;
65
  DeleteFnPtr<IsolateData, FreeIsolateData> isolate_data;
66
  DeleteFnPtr<Environment, FreeEnvironment> env;
67
  Global<Context> context;
68
};
69
70
7
CommonEnvironmentSetup::CommonEnvironmentSetup(
71
    MultiIsolatePlatform* platform,
72
    std::vector<std::string>* errors,
73
7
    std::function<Environment*(const CommonEnvironmentSetup*)> make_env)
74
7
  : impl_(new Impl()) {
75
7
  CHECK_NOT_NULL(platform);
76
7
  CHECK_NOT_NULL(errors);
77
78
7
  impl_->platform = platform;
79
7
  uv_loop_t* loop = &impl_->loop;
80
  // Use `data` to tell the destructor whether the loop was initialized or not.
81
7
  loop->data = nullptr;
82
7
  int ret = uv_loop_init(loop);
83
7
  if (ret != 0) {
84
    errors->push_back(
85
        SPrintF("Failed to initialize loop: %s", uv_err_name(ret)));
86
    return;
87
  }
88
7
  loop->data = this;
89
90
7
  impl_->allocator = ArrayBufferAllocator::Create();
91
7
  impl_->isolate = NewIsolate(impl_->allocator, &impl_->loop, platform);
92
7
  Isolate* isolate = impl_->isolate;
93
94
  {
95
7
    Locker locker(isolate);
96
14
    Isolate::Scope isolate_scope(isolate);
97
7
    impl_->isolate_data.reset(CreateIsolateData(
98
14
        isolate, loop, platform, impl_->allocator.get()));
99
100
14
    HandleScope handle_scope(isolate);
101
7
    Local<Context> context = NewContext(isolate);
102
7
    impl_->context.Reset(isolate, context);
103
7
    if (context.IsEmpty()) {
104
      errors->push_back("Failed to initialize V8 Context");
105
      return;
106
    }
107
108
    Context::Scope context_scope(context);
109
7
    impl_->env.reset(make_env(this));
110
  }
111
}
112
113
10
CommonEnvironmentSetup::~CommonEnvironmentSetup() {
114
5
  if (impl_->isolate != nullptr) {
115
5
    Isolate* isolate = impl_->isolate;
116
    {
117
5
      Locker locker(isolate);
118
10
      Isolate::Scope isolate_scope(isolate);
119
120
5
      impl_->context.Reset();
121
5
      impl_->env.reset();
122
5
      impl_->isolate_data.reset();
123
    }
124
125
5
    bool platform_finished = false;
126
30
    impl_->platform->AddIsolateFinishedCallback(isolate, [](void* data) {
127
5
      *static_cast<bool*>(data) = true;
128
25
    }, &platform_finished);
129
5
    impl_->platform->UnregisterIsolate(isolate);
130
5
    isolate->Dispose();
131
132
    // Wait until the platform has cleaned up all relevant resources.
133
15
    while (!platform_finished)
134
5
      uv_run(&impl_->loop, UV_RUN_ONCE);
135
  }
136
137

5
  if (impl_->isolate || impl_->loop.data != nullptr)
138
5
    CheckedUvLoopClose(&impl_->loop);
139
140
5
  delete impl_;
141
5
}
142
143
144
uv_loop_t* CommonEnvironmentSetup::event_loop() const {
145
  return &impl_->loop;
146
}
147
148
std::shared_ptr<ArrayBufferAllocator>
149
CommonEnvironmentSetup::array_buffer_allocator() const {
150
  return impl_->allocator;
151
}
152
153
7
Isolate* CommonEnvironmentSetup::isolate() const {
154
7
  return impl_->isolate;
155
}
156
157
7
IsolateData* CommonEnvironmentSetup::isolate_data() const {
158
7
  return impl_->isolate_data.get();
159
}
160
161
7
Environment* CommonEnvironmentSetup::env() const {
162
7
  return impl_->env.get();
163
}
164
165
14
v8::Local<v8::Context> CommonEnvironmentSetup::context() const {
166
28
  return impl_->context.Get(impl_->isolate);
167
}
168
169

366
}  // namespace node