GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_worker.h Lines: 6 8 75.0 %
Date: 2022-05-16 04:15:04 Branches: 1 2 50.0 %

Line Branch Exec Source
1
#ifndef SRC_NODE_WORKER_H_
2
#define SRC_NODE_WORKER_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include <optional>
7
#include <unordered_map>
8
#include "node_messaging.h"
9
#include "uv.h"
10
11
namespace node {
12
13
struct SnapshotData;
14
namespace worker {
15
16
class WorkerThreadData;
17
18
enum ResourceLimits {
19
  kMaxYoungGenerationSizeMb,
20
  kMaxOldGenerationSizeMb,
21
  kCodeRangeSizeMb,
22
  kStackSizeMb,
23
  kTotalResourceLimitCount
24
};
25
26
// A worker thread, as represented in its parent thread.
27
class Worker : public AsyncWrap {
28
 public:
29
  Worker(Environment* env,
30
         v8::Local<v8::Object> wrap,
31
         const std::string& url,
32
         std::shared_ptr<PerIsolateOptions> per_isolate_opts,
33
         std::vector<std::string>&& exec_argv,
34
         std::shared_ptr<KVStore> env_vars,
35
         const SnapshotData* snapshot_data);
36
  ~Worker() override;
37
38
  // Run the worker. This is only called from the worker thread.
39
  void Run();
40
41
  // Forcibly exit the thread with a specified exit code. This may be called
42
  // from any thread. `error_code` and `error_message` can be used to create
43
  // a custom `'error'` event before emitting `'exit'`.
44
  void Exit(int code,
45
            const char* error_code = nullptr,
46
            const char* error_message = nullptr);
47
48
  // Wait for the worker thread to stop (in a blocking manner).
49
  void JoinThread();
50
51
  template <typename Fn>
52
  inline bool RequestInterrupt(Fn&& cb);
53
54
  void MemoryInfo(MemoryTracker* tracker) const override;
55
  SET_MEMORY_INFO_NAME(Worker)
56
  SET_SELF_SIZE(Worker)
57
  bool IsNotIndicativeOfMemoryLeakAtExit() const override;
58
59
  bool is_stopped() const;
60
1619
  const SnapshotData* snapshot_data() const { return snapshot_data_; }
61
62
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
63
  static void CloneParentEnvVars(
64
      const v8::FunctionCallbackInfo<v8::Value>& args);
65
  static void SetEnvVars(const v8::FunctionCallbackInfo<v8::Value>& args);
66
  static void StartThread(const v8::FunctionCallbackInfo<v8::Value>& args);
67
  static void StopThread(const v8::FunctionCallbackInfo<v8::Value>& args);
68
  static void HasRef(const v8::FunctionCallbackInfo<v8::Value>& args);
69
  static void Ref(const v8::FunctionCallbackInfo<v8::Value>& args);
70
  static void Unref(const v8::FunctionCallbackInfo<v8::Value>& args);
71
  static void GetResourceLimits(
72
      const v8::FunctionCallbackInfo<v8::Value>& args);
73
  v8::Local<v8::Float64Array> GetResourceLimits(v8::Isolate* isolate) const;
74
  static void TakeHeapSnapshot(const v8::FunctionCallbackInfo<v8::Value>& args);
75
  static void LoopIdleTime(const v8::FunctionCallbackInfo<v8::Value>& args);
76
  static void LoopStartTime(const v8::FunctionCallbackInfo<v8::Value>& args);
77
78
 private:
79
  bool CreateEnvMessagePort(Environment* env);
80
  static size_t NearHeapLimit(void* data, size_t current_heap_limit,
81
                              size_t initial_heap_limit);
82
83
  std::shared_ptr<PerIsolateOptions> per_isolate_opts_;
84
  std::vector<std::string> exec_argv_;
85
  std::vector<std::string> argv_;
86
87
  MultiIsolatePlatform* platform_;
88
  v8::Isolate* isolate_ = nullptr;
89
  std::optional<uv_thread_t> tid_;  // Set while the thread is running
90
91
  std::unique_ptr<InspectorParentHandle> inspector_parent_handle_;
92
93
  // This mutex protects access to all variables listed below it.
94
  mutable Mutex mutex_;
95
96
  const char* custom_error_ = nullptr;
97
  std::string custom_error_str_;
98
  int exit_code_ = 0;
99
  ThreadId thread_id_;
100
  uintptr_t stack_base_ = 0;
101
102
  // Custom resource constraints:
103
  double resource_limits_[kTotalResourceLimitCount];
104
  void UpdateResourceConstraints(v8::ResourceConstraints* constraints);
105
106
  // Full size of the thread's stack.
107
  size_t stack_size_ = 4 * 1024 * 1024;
108
  // Stack buffer size that is not available to the JS engine.
109
  static constexpr size_t kStackBufferSize = 192 * 1024;
110
111
  std::unique_ptr<MessagePortData> child_port_data_;
112
  std::shared_ptr<KVStore> env_vars_;
113
114
  // This is always kept alive because the JS object associated with the Worker
115
  // instance refers to it via its [kPort] property.
116
  MessagePort* parent_port_ = nullptr;
117
118
  // A raw flag that is used by creator and worker threads to
119
  // sync up on pre-mature termination of worker  - while in the
120
  // warmup phase.  Once the worker is fully warmed up, use the
121
  // async handle of the worker's Environment for the same purpose.
122
  bool stopped_ = true;
123
124
  bool has_ref_ = true;
125
  uint64_t environment_flags_ = EnvironmentFlags::kNoFlags;
126
127
  // The real Environment of the worker object. It has a lesser
128
  // lifespan than the worker object itself - comes to life
129
  // when the worker thread creates a new Environment, and gets
130
  // destroyed alongwith the worker thread.
131
  Environment* env_ = nullptr;
132
133
  const SnapshotData* snapshot_data_ = nullptr;
134
  friend class WorkerThreadData;
135
};
136
137
template <typename Fn>
138
3
bool Worker::RequestInterrupt(Fn&& cb) {
139
6
  Mutex::ScopedLock lock(mutex_);
140
3
  if (env_ == nullptr) return false;
141
3
  env_->RequestInterrupt(std::move(cb));
142
3
  return true;
143
}
144
145
}  // namespace worker
146
}  // namespace node
147
148
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
149
150
151
#endif  // SRC_NODE_WORKER_H_