GeezerVison is showing github.com — src: add TimerWrap utility · nodejs/node@a3a4d2c
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: node.gyp +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 638 | 638 | 'src/string_decoder.cc', | 639 | 639 | 'src/tcp_wrap.cc', | 640 | 640 | 'src/timers.cc', | | 641 | + 'src/timer_wrap.cc', | 641 | 642 | 'src/tracing/agent.cc', | 642 | 643 | 'src/tracing/node_trace_buffer.cc', | 643 | 644 | 'src/tracing/node_trace_writer.cc', | | 742 | 743 | 'src/tracing/trace_event.h', | 743 | 744 | 'src/tracing/trace_event_common.h', | 744 | 745 | 'src/tracing/traced_value.h', | | 746 | + 'src/timer_wrap.h', | 745 | 747 | 'src/tty_wrap.h', | 746 | 748 | 'src/udp_wrap.h', | 747 | 749 | 'src/util.h', | |
Collapse file Copy file name to clipboard +94Lines changed: 94 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 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 | + if (timer_.data == nullptr) return; | | 33 | + uv_timer_start(&timer_, OnTimeout, interval, repeat); | | 34 | +} | | 35 | + | | 36 | +void TimerWrap::Ref() { | | 37 | + if (timer_.data == nullptr) return; | | 38 | + uv_ref(reinterpret_cast<uv_handle_t*>(&timer_)); | | 39 | +} | | 40 | + | | 41 | +void TimerWrap::Unref() { | | 42 | + if (timer_.data == nullptr) return; | | 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 | + if (timer_ != nullptr) | | 77 | + timer_->Unref(); | | 78 | +} | | 79 | + | | 80 | +void TimerWrapHandle::Update(uint64_t interval, uint64_t repeat) { | | 81 | + if (timer_ != nullptr) | | 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 | + if (timer_ != nullptr) | | 91 | + tracker->TrackField("timer", *timer_); | | 92 | +} | | 93 | + | | 94 | +} // namespace node |
Collapse file Copy file name to clipboard +84Lines changed: 84 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +#ifndef SRC_TIMER_WRAP_H_ | | 2 | +#define SRC_TIMER_WRAP_H_ | | 3 | + | | 4 | +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | | 5 | + | | 6 | +#include "memory_tracker.h" | | 7 | +#include "env.h" | | 8 | +#include "uv.h" | | 9 | + | | 10 | +#include <functional> | | 11 | + | | 12 | +namespace node { | | 13 | + | | 14 | +// Utility class that makes working with libuv timers a bit easier. | | 15 | +class TimerWrap final : public MemoryRetainer { | | 16 | + public: | | 17 | + using TimerCb = std::function<void(void*)>; | | 18 | + | | 19 | + TimerWrap(Environment* env, TimerCb fn, void* user_data); | | 20 | + TimerWrap(const TimerWrap&) = delete; | | 21 | + | | 22 | + inline Environment* env() const { return env_; } | | 23 | + | | 24 | + // Completely stops the timer, making it no longer usable. | | 25 | + void Stop(bool close = true); | | 26 | + | | 27 | + // Starts / Restarts the Timer | | 28 | + void Update(uint64_t interval, uint64_t repeat = 0); | | 29 | + | | 30 | + void Ref(); | | 31 | + | | 32 | + void Unref(); | | 33 | + | | 34 | + SET_NO_MEMORY_INFO(); | | 35 | + SET_MEMORY_INFO_NAME(TimerWrap) | | 36 | + SET_SELF_SIZE(TimerWrap) | | 37 | + | | 38 | + private: | | 39 | + static void TimerClosedCb(uv_handle_t* handle); | | 40 | + static void OnTimeout(uv_timer_t* timer); | | 41 | + ~TimerWrap() = default; | | 42 | + | | 43 | + Environment* env_; | | 44 | + TimerCb fn_; | | 45 | + uv_timer_t timer_; | | 46 | + void* user_data_ = nullptr; | | 47 | + | | 48 | + friend std::unique_ptr<TimerWrap>::deleter_type; | | 49 | +}; | | 50 | + | | 51 | +class TimerWrapHandle : public MemoryRetainer { | | 52 | + public: | | 53 | + TimerWrapHandle( | | 54 | + Environment* env, | | 55 | + TimerWrap::TimerCb fn, | | 56 | + void* user_data = nullptr); | | 57 | + | | 58 | + TimerWrapHandle(const TimerWrapHandle&) = delete; | | 59 | + | | 60 | + ~TimerWrapHandle() { Stop(); } | | 61 | + | | 62 | + void Update(uint64_t interval, uint64_t repeat = 0); | | 63 | + | | 64 | + void Ref(); | | 65 | + | | 66 | + void Unref(); | | 67 | + | | 68 | + void Stop(bool close = true); | | 69 | + | | 70 | + void MemoryInfo(node::MemoryTracker* tracker) const override; | | 71 | + | | 72 | + SET_MEMORY_INFO_NAME(TimerWrapHandle) | | 73 | + SET_SELF_SIZE(TimerWrapHandle) | | 74 | + | | 75 | + private: | | 76 | + static void CleanupHook(void* data); | | 77 | + TimerWrap* timer_; | | 78 | +}; | | 79 | + | | 80 | +} // namespace node | | 81 | + | | 82 | +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | | 83 | + | | 84 | +#endif // SRC_TIMER_WRAP_H_ |
|