8000
We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
1 parent ae9bd89 commit a3a4d2cCopy full SHA for a3a4d2c
node.gyp
@@ -638,6 +638,7 @@
638
'src/string_decoder.cc',
639
'src/tcp_wrap.cc',
640
'src/timers.cc',
641
+ 'src/timer_wrap.cc',
642
'src/tracing/agent.cc',
643
'src/tracing/node_trace_buffer.cc',
644
'src/tracing/node_trace_writer.cc',
@@ -742,6 +743,7 @@
742
743
'src/tracing/trace_event.h',
744
'src/tracing/trace_event_common.h',
745
'src/tracing/traced_value.h',
746
+ 'src/timer_wrap.h',
747
'src/tty_wrap.h',
748
'src/udp_wrap.h',
749
'src/util.h',
src/timer_wrap.cc
@@ -0,0 +1,94 @@
1
+#include "env-inl.h"
2
+#include "memory_tracker-inl.h"
3
+#include "timer_wrap.h"
4
+#include "uv.h"
5
+
6
+namespace node {
7
8
+TimerWrap::TimerWrap(Environment* env, TimerCb fn, void* user_data)
9
+ : env_(env),
10
+ fn_(fn),
11
+ user_data_(user_data) {
12
+ uv_timer_init(env->event_loop(), &timer_);
13
+ timer_.data = this;
14
+}
15
16
+void TimerWrap::Stop(bool close) {
17
+ if (timer_.data == nullptr) return;
18
+ uv_timer_stop(&timer_);
19
+ if (LIKELY(close)) {
20
+ timer_.data = nullptr;
21
+ env_->CloseHandle(reinterpret_cast<uv_handle_t*>(&timer_), TimerClosedCb);
22
+ }
23
24
25
+void TimerWrap::TimerClosedCb(uv_handle_t* handle) {
26
+ std::unique_ptr<TimerWrap> ptr(
27
+ ContainerOf(&TimerWrap::timer_,
28
+ reinterpret_cast<uv_timer_t*>(handle)));
29
30
31
+void TimerWrap::Update(uint64_t interval, uint64_t repeat) {
32
33
+ uv_timer_start(&timer_, OnTimeout, interval, repeat);
34
35
36
+void TimerWrap::Ref() {
37
38
+ uv_ref(reinterpret_cast<uv_handle_t*>(&timer_));
39
40
41
+void TimerWrap::Unref() {
42
43
+ uv_unref(reinterpret_cast<uv_handle_t*>(&timer_));
44
45
46
+void TimerWrap::OnTimeout(uv_timer_t* timer) {
47
+ TimerWrap* t = ContainerOf(&TimerWrap::timer_, timer);
48
+ t->fn_(t->user_data_);
49
50
51
+TimerWrapHandle::TimerWrapHandle(
52
+ Environment* env,
53
+ TimerWrap::TimerCb fn,
54
+ void* user_data) {
55
+ timer_ = new TimerWrap(env, fn, user_data);
56
+ env->AddCleanupHook(CleanupHook, this);
57
58
59
+void TimerWrapHandle::Stop(bool close) {
60
+ if (UNLIKELY(!close))
61
+ return timer_->Stop(close);
62
63
+ if (timer_ != nullptr) {
64
+ timer_->env()->RemoveCleanupHook(CleanupHook, this);
65
+ timer_->Stop();
66
67
+ timer_ = nullptr;
68
69
70
+void TimerWrapHandle::Ref() {
71
+ if (timer_ != nullptr)
72
+ timer_->Ref();
73
74
75
+void TimerWrapHandle::Unref() {
76
77
+ timer_->Unref();
78
79
80
+void TimerWrapHandle::Update(uint64_t interval, uint64_t repeat) {
81
82
+ timer_->Update(interval, repeat);
83
84
85
+void TimerWrapHandle::CleanupHook(void* data) {
86
+ static_cast<TimerWrapHandle*>(data)->Stop();
87
88
89
+void TimerWrapHandle::MemoryInfo(node::MemoryTracker* tracker) const {
90
91
+ tracker->TrackField("timer", *timer_);
92
93
94
+} // namespace node
src/timer_wrap.h
@@ -0,0 +1,84 @@
+#ifndef SRC_TIMER_WRAP_H_
+#define SRC_TIMER_WRAP_H_
+#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
+#include "memory_tracker.h"
+#include "env.h"
+#include <functional>
+// Utility class that makes working with libuv timers a bit easier.
+class TimerWrap final : public MemoryRetainer {
+ public:
+ using TimerCb = std::function<void(void*)>;
+ TimerWrap(Environment* env, TimerCb fn, void* user_data);
+ TimerWrap(const TimerWrap&) = delete;
+ inline Environment* env() const { return env_; }
+ // Completely stops the timer, making it no longer usable.
+ void Stop(bool close = true);
+ // Starts / Restarts the Timer
+ void Update(uint64_t interval, uint64_t repeat = 0);
+ void Ref();
+ void Unref();
+ SET_NO_MEMORY_INFO();
+ SET_MEMORY_INFO_NAME(TimerWrap)
+ SET_SELF_SIZE(TimerWrap)
+ private:
+ static void TimerClosedCb(uv_handle_t* handle);
+ static void OnTimeout(uv_timer_t* timer);
+ ~TimerWrap() = default;
+ Environment* env_;
+ TimerCb fn_;
+ uv_timer_t timer_;
+ void* user_data_ = nullptr;
+ friend std::unique_ptr<TimerWrap>::deleter_type;
+};
+class TimerWrapHandle : public MemoryRetainer {
+ TimerWrapHandle(
+ void* user_data = nullptr);
+ TimerWrapHandle(const TimerWrapHandle&) = delete;
+ ~TimerWrapHandle() { Stop(); }
+ void MemoryInfo(node::MemoryTracker* tracker) const override;
+ SET_MEMORY_INFO_NAME(TimerWrapHandle)
+ SET_SELF_SIZE(TimerWrapHandle)
+ static void CleanupHook(void* data);
+ TimerWrap* timer_;
+#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
+#endif // SRC_TIMER_WRAP_H_