Skip to content

Commit

Permalink
src: begin adding further support for weak_ptr
Browse files Browse the repository at this point in the history
  • Loading branch information
trevnorris committed Feb 23, 2024
1 parent 5bf0076 commit 39bb1ca
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 6 deletions.
37 changes: 37 additions & 0 deletions include/nsuv-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,21 @@ int ns_timer::start(void (*cb)(ns_timer*, void*),
return start(cb, timeout, repeat, NSUV_CAST_NULLPTR);
}

template <typename D_T>
int ns_timer::start(ns_timer_cb_wp<D_T> cb,
uint64_t timeout,
uint64_t repeat,
std::weak_ptr<D_T> data) {
timer_cb_ptr_ = reinterpret_cast<void (*)()>(cb);
timer_cb_wp_ = data;

return uv_timer_start(
uv_handle(),
&timer_proxy_wp_<decltype(cb), D_T>,
timeout,
repeat);
}

int ns_timer::stop() {
return uv_timer_stop(uv_handle());
}
Expand All @@ -1299,6 +1314,14 @@ void ns_timer::timer_proxy_(uv_timer_t* handle) {
cb_(wrap, static_cast<D_T*>(wrap->timer_cb_data_));
}

template <typename CB_T, typename D_T>
void ns_timer::timer_proxy_wp_(uv_timer_t* handle) {
ns_timer* wrap = ns_timer::cast(handle);
auto* cb_ = reinterpret_cast<CB_T>(wrap->timer_cb_ptr_);
auto data = wrap->timer_cb_wp_.lock();
cb_(wrap, std::static_pointer_cast<D_T>(data));
}


/* ns_check, ns_idle, ns_prepare */

Expand Down Expand Up @@ -1790,6 +1813,20 @@ int ns_thread::create_ex(const uv_thread_options_t* params,
return create_ex(params, cb, NSUV_CAST_NULLPTR);
}

template <typename D_T>
int ns_thread::create_ex(const uv_thread_options_t* params,
ns_thread_cb_wp<D_T> cb,
std::weak_ptr<D_T> data) {
thread_cb_ptr_ = reinterpret_cast<void (*)()>(cb);
thread_cb_wp_ = data;

return uv_thread_create_ex(
&thread_,
params,
&create_proxy_wp_<decltype(cb), D_T>,
this);
}

int ns_thread::join() {
return uv_thread_join(&thread_);
}
Expand Down
22 changes: 16 additions & 6 deletions include/nsuv.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@
template <typename CB_T> \
static NSUV_INLINE void name(__VA_ARGS__); \
template <typename CB_T, typename D_T> \
static NSUV_INLINE void name(__VA_ARGS__);
static NSUV_INLINE void name(__VA_ARGS__); \
template <typename CB_T, typename D_T> \
static NSUV_INLINE void name##wp_(__VA_ARGS__);

#define NSUV_CB_FNS(name, ...) \
using name = void (*)(__VA_ARGS__); \
template <typename D_T> \
using name##_d = void (*)(__VA_ARGS__, D_T*);
using name##_d = void (*)(__VA_ARGS__, D_T*); \
template <typename D_T> \
using name##_wp = void (*)(__VA_ARGS__, std::weak_ptr<D_T>);

namespace nsuv {

Expand Down Expand Up @@ -654,13 +658,19 @@ class ns_timer : public ns_handle<uv_timer_t, ns_timer> {
uint64_t timeout,
uint64_t repeat,
std::nullptr_t);
template <typename D_T>
NSUV_INLINE NSUV_WUR int start(ns_timer_cb_wp<D_T> cb,
uint64_t timeout,
uint64_t repeat,
std::weak_ptr<D_T> data);
NSUV_INLINE NSUV_WUR int stop();
NSUV_INLINE size_t get_repeat();

private:
NSUV_PROXY_FNS(timer_proxy_, uv_timer_t* handle)
void (*timer_cb_ptr_)() = nullptr;
void* timer_cb_data_ = nullptr;
std::weak_ptr<void> timer_cb_wp_;
};


Expand Down Expand Up @@ -877,8 +887,6 @@ class ns_rwlock {
class ns_thread {
public:
NSUV_CB_FNS(ns_thread_cb, ns_thread*)
template <typename D_T>
using ns_thread_cb_wp = void(ns_thread*, std::weak_ptr<D_T>);

NSUV_INLINE NSUV_WUR int create(ns_thread_cb cb);
template <typename D_T>
Expand All @@ -897,6 +905,10 @@ class ns_thread {
NSUV_INLINE NSUV_WUR int create_ex(const uv_thread_options_t* params,
void (*cb)(ns_thread*, void*),
std::nullptr_t);
template <typename D_T>
NSUV_INLINE NSUV_WUR int create_ex(const uv_thread_options_t* params,
ns_thread_cb_wp<D_T> cb,
std::weak_ptr<D_T> data);
NSUV_INLINE NSUV_WUR int join();
NSUV_INLINE uv_thread_t base();
NSUV_INLINE NSUV_WUR bool equal(uv_thread_t* t2);
Expand All @@ -909,8 +921,6 @@ class ns_thread {

private:
NSUV_PROXY_FNS(create_proxy_, void* arg)
template <typename CB_T, typename D_T>
static void create_proxy_wp_(void* arg);

uv_thread_t thread_;
void (*thread_cb_ptr_)() = nullptr;
Expand Down
52 changes: 52 additions & 0 deletions test/test-timer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ TEST_CASE("timer_order", "[timer]") {
ns_timer handle_a;
ns_timer handle_b;

order_cb_called = 0;

ASSERT_EQ(0, handle_a.init(uv_default_loop()));
ASSERT_EQ(0, handle_b.init(uv_default_loop()));

Expand All @@ -173,6 +175,56 @@ TEST_CASE("timer_order", "[timer]") {
}


static void order_cb_a_wp(ns_timer*, std::weak_ptr<size_t> check) {
auto val = check.lock();
ASSERT(val);
ASSERT_EQ(order_cb_called++, *val);
}


static void order_cb_b_wp(ns_timer*, std::weak_ptr<size_t> check) {
auto val = check.lock();
ASSERT(val);
ASSERT_EQ(order_cb_called++, *val);
}


TEST_CASE("timer_order_wp", "[timer]") {
std::shared_ptr<size_t> first = std::make_shared<size_t>(0);
std::shared_ptr<size_t> second = std::make_shared<size_t>(1);
std::weak_ptr<size_t> first_wp = first;
std::weak_ptr<size_t> second_wp = second;
ns_timer handle_a;
ns_timer handle_b;

order_cb_called = 0;

ASSERT_EQ(0, handle_a.init(uv_default_loop()));
ASSERT_EQ(0, handle_b.init(uv_default_loop()));

/* Test for starting handle_a then handle_b */
ASSERT_EQ(0, handle_a.start(order_cb_a_wp, 0, 0, first_wp));
ASSERT_EQ(0, handle_b.start(order_cb_b_wp, 0, 0, second_wp));
ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT));

ASSERT_EQ(order_cb_called, 2);

ASSERT_EQ(0, handle_a.stop());
ASSERT_EQ(0, handle_b.stop());

/* Test for starting handle_b then handle_a */
order_cb_called = 0;
ASSERT_EQ(0, handle_b.start(order_cb_b_wp, 0, 0, first_wp));

ASSERT_EQ(0, handle_a.start(order_cb_a_wp, 0, 0, second_wp));
ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT));

ASSERT_EQ(order_cb_called, 2);

make_valgrind_happy();
}


static void tiny_timer_cb(ns_timer* handle) {
ASSERT_EQ(handle, &tiny_timer);
tiny_timer.close();
Expand Down

0 comments on commit 39bb1ca

Please sign in to comment.