GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_watchdog.h Lines: 3 7 42.9 %
Date: 2022-06-06 04:15:48 Branches: 0 0 - %

Line Branch Exec Source
1
// Copyright Joyent, Inc. and other Node contributors.
2
//
3
// Permission is hereby granted, free of charge, to any person obtaining a
4
// copy of this software and associated documentation files (the
5
// "Software"), to deal in the Software without restriction, including
6
// without limitation the rights to use, copy, modify, merge, publish,
7
// distribute, sublicense, and/or sell copies of the Software, and to permit
8
// persons to whom the Software is furnished to do so, subject to the
9
// following conditions:
10
//
11
// The above copyright notice and this permission notice shall be included
12
// in all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
#ifndef SRC_NODE_WATCHDOG_H_
23
#define SRC_NODE_WATCHDOG_H_
24
25
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26
27
#include <vector>
28
#include "handle_wrap.h"
29
#include "memory_tracker-inl.h"
30
#include "node_mutex.h"
31
#include "uv.h"
32
#include "v8.h"
33
34
#ifdef __POSIX__
35
#include <pthread.h>
36
#endif
37
38
namespace node {
39
40
enum class SignalPropagation {
41
  kContinuePropagation,
42
  kStopPropagation,
43
};
44
45
class Watchdog {
46
 public:
47
  explicit Watchdog(v8::Isolate* isolate,
48
                    uint64_t ms,
49
                    bool* timed_out = nullptr);
50
  ~Watchdog();
51
13
  v8::Isolate* isolate() { return isolate_; }
52
53
 private:
54
  static void Run(void* arg);
55
  static void Timer(uv_timer_t* timer);
56
57
  v8::Isolate* isolate_;
58
  uv_thread_t thread_;
59
  uv_loop_t loop_;
60
  uv_async_t async_;
61
  uv_timer_t timer_;
62
  bool* timed_out_;
63
};
64
65
class SigintWatchdogBase {
66
 public:
67
378
  virtual ~SigintWatchdogBase() = default;
68
  virtual SignalPropagation HandleSigint() = 0;
69
};
70
71
class SigintWatchdog : public SigintWatchdogBase {
72
 public:
73
  explicit SigintWatchdog(v8::Isolate* isolate,
74
                          bool* received_signal = nullptr);
75
  ~SigintWatchdog();
76
  v8::Isolate* isolate() { return isolate_; }
77
  SignalPropagation HandleSigint() override;
78
79
 private:
80
  v8::Isolate* isolate_;
81
  bool* received_signal_;
82
};
83
84
class TraceSigintWatchdog : public HandleWrap, public SigintWatchdogBase {
85
 public:
86
  static void Init(Environment* env, v8::Local<v8::Object> target);
87
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
88
  static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
89
  static void Stop(const v8::FunctionCallbackInfo<v8::Value>& args);
90
91
  SignalPropagation HandleSigint() override;
92
93
  inline void MemoryInfo(node::MemoryTracker* tracker) const override {
94
    tracker->TrackInlineField("handle_", handle_);
95
  }
96
  SET_MEMORY_INFO_NAME(TraceSigintWatchdog)
97
  SET_SELF_SIZE(TraceSigintWatchdog)
98
99
 private:
100
  enum class SignalFlags { None, FromIdle, FromInterrupt };
101
102
  TraceSigintWatchdog(Environment* env, v8::Local<v8::Object> object);
103
  void HandleInterrupt();
104
105
  bool interrupting = false;
106
  uv_async_t handle_;
107
  SignalFlags signal_flag_ = SignalFlags::None;
108
};
109
110
class SigintWatchdogHelper {
111
 public:
112
1148
  static SigintWatchdogHelper* GetInstance() { return &instance; }
113
  void Register(SigintWatchdogBase* watchdog);
114
  void Unregister(SigintWatchdogBase* watchdog);
115
  bool HasPendingSignal();
116
117
  int Start();
118
  bool Stop();
119
120
 private:
121
  SigintWatchdogHelper();
122
  ~SigintWatchdogHelper();
123
124
  static bool InformWatchdogsAboutSignal();
125
  static SigintWatchdogHelper instance;
126
127
  int start_stop_count_;
128
129
  Mutex mutex_;
130
  Mutex list_mutex_;
131
  std::vector<SigintWatchdogBase*> watchdogs_;
132
  bool has_pending_signal_;
133
134
#ifdef __POSIX__
135
  pthread_t thread_;
136
  uv_sem_t sem_;
137
  bool has_running_thread_;
138
  bool stopping_;
139
140
  static void* RunSigintWatchdog(void* arg);
141
  static void HandleSignal(int signum, siginfo_t* info, void* ucontext);
142
#else
143
  bool watchdog_disabled_;
144
  static BOOL WINAPI WinCtrlCHandlerRoutine(DWORD dwCtrlType);
145
#endif
146
};
147
148
}  // namespace node
149
150
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
151
152
#endif  // SRC_NODE_WATCHDOG_H_