GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_watchdog.h Lines: 4 8 50.0 %
Date: 2022-08-28 04:20:35 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
2390
  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
5184
  static SigintWatchdogHelper* GetInstance() { return &instance; }
113
2397
  static Mutex& GetInstanceActionMutex() { return instance_action_mutex_; }
114
  void Register(SigintWatchdogBase* watchdog);
115
  void Unregister(SigintWatchdogBase* watchdog);
116
  bool HasPendingSignal();
117
118
  int Start();
119
  bool Stop();
120
121
 private:
122
  SigintWatchdogHelper();
123
  ~SigintWatchdogHelper();
124
125
  static bool InformWatchdogsAboutSignal();
126
  static SigintWatchdogHelper instance;
127
  static Mutex instance_action_mutex_;
128
129
  int start_stop_count_;
130
131
  Mutex mutex_;
132
  Mutex list_mutex_;
133
  std::vector<SigintWatchdogBase*> watchdogs_;
134
  bool has_pending_signal_;
135
136
#ifdef __POSIX__
137
  pthread_t thread_;
138
  uv_sem_t sem_;
139
  bool has_running_thread_;
140
  bool stopping_;
141
142
  static void* RunSigintWatchdog(void* arg);
143
  static void HandleSignal(int signum, siginfo_t* info, void* ucontext);
144
#else
145
  bool watchdog_disabled_;
146
  static BOOL WINAPI WinCtrlCHandlerRoutine(DWORD dwCtrlType);
147
#endif
148
};
149
150
}  // namespace node
151
152
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
153
154
#endif  // SRC_NODE_WATCHDOG_H_