summaryrefslogtreecommitdiff
path: root/src/node_watchdog.h
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2016-05-08 03:28:47 +0200
committerAnna Henningsen <anna@addaleax.net>2016-06-18 20:44:16 +0200
commit0815b9401d087202cd64458b6906a5225929fc5d (patch)
tree78fb84a7b6887091cd392e5d9feff11bae6edf96 /src/node_watchdog.h
parentde9a84186e6da9e4e6ee9434aa89715bf3eb9172 (diff)
downloadandroid-node-v8-0815b9401d087202cd64458b6906a5225929fc5d.tar.gz
android-node-v8-0815b9401d087202cd64458b6906a5225929fc5d.tar.bz2
android-node-v8-0815b9401d087202cd64458b6906a5225929fc5d.zip
vm: add ability to break on sigint/ctrl+c
- Adds the `breakEvalOnSigint` option to `vm.runIn(This)Context`. This uses a watchdog thread to wait for SIGINT and generally works just like the existing `timeout` option. - Adds a method to the existing timer-based watchdog to check if it stopped regularly or by running into the timeout. This is used to tell a SIGINT abort from a timer-based one. - Adds (internal) `process._{start,stop}SigintWatchdog` methods to start/stop the watchdog thread used by the above option manually. This will be used in the REPL to set up SIGINT handling before entering terminal raw mode, so that there is no time window in which Ctrl+C fully aborts the process. PR-URL: https://github.com/nodejs/node/pull/6635 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'src/node_watchdog.h')
-rw-r--r--src/node_watchdog.h59
1 files changed, 58 insertions, 1 deletions
diff --git a/src/node_watchdog.h b/src/node_watchdog.h
index 36125ac0e1..65815e2bcd 100644
--- a/src/node_watchdog.h
+++ b/src/node_watchdog.h
@@ -5,6 +5,11 @@
#include "v8.h"
#include "uv.h"
+#include <vector>
+
+#ifdef __POSIX__
+#include <pthread.h>
+#endif
namespace node {
@@ -16,7 +21,7 @@ class Watchdog {
void Dispose();
v8::Isolate* isolate() { return isolate_; }
-
+ bool HasTimedOut() { return timed_out_; }
private:
void Destroy();
@@ -29,9 +34,61 @@ class Watchdog {
uv_loop_t* loop_;
uv_async_t async_;
uv_timer_t timer_;
+ bool timed_out_;
bool destroyed_;
};
+class SigintWatchdog {
+ public:
+ explicit SigintWatchdog(v8::Isolate* isolate);
+ ~SigintWatchdog();
+
+ void Dispose();
+
+ v8::Isolate* isolate() { return isolate_; }
+ void HandleSigint();
+ private:
+ void Destroy();
+
+ v8::Isolate* isolate_;
+ bool destroyed_;
+};
+
+class SigintWatchdogHelper {
+ public:
+ static SigintWatchdogHelper* GetInstance() { return &instance; }
+ void Register(SigintWatchdog* watchdog);
+ void Unregister(SigintWatchdog* watchdog);
+
+ int Start();
+ bool Stop();
+ private:
+ SigintWatchdogHelper();
+ ~SigintWatchdogHelper();
+
+ static bool InformWatchdogsAboutSignal();
+ static SigintWatchdogHelper instance;
+
+ int start_stop_count_;
+
+ uv_mutex_t mutex_;
+ uv_mutex_t list_mutex_;
+ std::vector<SigintWatchdog*> watchdogs_;
+ bool has_pending_signal_;
+
+#ifdef __POSIX__
+ pthread_t thread_;
+ uv_sem_t sem_;
+ bool has_running_thread_;
+ bool stopping_;
+
+ static void* RunSigintWatchdog(void* arg);
+ static void HandleSignal(int signum);
+#else
+ static BOOL WINAPI WinCtrlCHandlerRoutine(DWORD dwCtrlType);
+#endif
+};
+
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS