feat add defer
Some checks failed
rpcrypto-build / build (Debug, himix200.toolchain.cmake) (push) Successful in 57s
rpcrypto-build / build (Debug, hisiv510.toolchain.cmake) (push) Failing after 14m46s
rpcrypto-build / build (Release, himix200.toolchain.cmake) (push) Failing after 14m48s
rpcrypto-build / build (Release, hisiv510.toolchain.cmake) (push) Failing after 14m51s
linux-hisiv500-gcc / linux-gcc-hisiv500 (push) Failing after 14m54s
linux-mips64-gcc / linux-gcc-mips64el (push) Failing after 14m57s
linux-x64-gcc / linux-gcc (push) Failing after 15m1s
Some checks failed
rpcrypto-build / build (Debug, himix200.toolchain.cmake) (push) Successful in 57s
rpcrypto-build / build (Debug, hisiv510.toolchain.cmake) (push) Failing after 14m46s
rpcrypto-build / build (Release, himix200.toolchain.cmake) (push) Failing after 14m48s
rpcrypto-build / build (Release, hisiv510.toolchain.cmake) (push) Failing after 14m51s
linux-hisiv500-gcc / linux-gcc-hisiv500 (push) Failing after 14m54s
linux-mips64-gcc / linux-gcc-mips64el (push) Failing after 14m57s
linux-x64-gcc / linux-gcc (push) Failing after 15m1s
This commit is contained in:
parent
51f923757d
commit
ce98a59397
51
src/ulib/utils/defer.h
Normal file
51
src/ulib/utils/defer.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef ULIB_SRC_ULIB_UTILS_DEFER_H_
|
||||||
|
#define ULIB_SRC_ULIB_UTILS_DEFER_H_
|
||||||
|
#include "ulib/base/noncopyable.h"
|
||||||
|
#include "ulib/base/stringize_macros.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace ulib {
|
||||||
|
class Defer : NonCopyable {
|
||||||
|
public:
|
||||||
|
using DeferFunc = std::function<void()>;
|
||||||
|
|
||||||
|
Defer() = default;
|
||||||
|
|
||||||
|
Defer(const DeferFunc &defer_func) { Add(defer_func); }
|
||||||
|
|
||||||
|
Defer(DeferFunc &&defer_func) { Add(std::move(defer_func)); }
|
||||||
|
|
||||||
|
Defer(Defer &&other) noexcept : defer_funcs_(std::move(other.defer_funcs_))
|
||||||
|
{}
|
||||||
|
|
||||||
|
~Defer()
|
||||||
|
{
|
||||||
|
std::for_each(defer_funcs_.rbegin(), defer_funcs_.rend(),
|
||||||
|
[](const DeferFunc &defer_func) { defer_func(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F, typename... Args>
|
||||||
|
void Add(F &&func, Args &&...args)
|
||||||
|
{
|
||||||
|
defer_funcs_.push_back(
|
||||||
|
std::bind(std::forward<F>(func), std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear() { defer_funcs_.clear(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<DeferFunc> defer_funcs_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define _ULIB_DEFER_CONCAT(a, b) a##b
|
||||||
|
#define ULIB_DEFER_CONCAT(a, b) _ULIB_DEFER_CONCAT(a, b)
|
||||||
|
|
||||||
|
#define defer(x) \
|
||||||
|
::ulib::Defer ULIB_DEFER_CONCAT(__ulib_defer__, __LINE__) = \
|
||||||
|
::ulib::Defer(x);
|
||||||
|
|
||||||
|
}// namespace ulib
|
||||||
|
#endif// ULIB_SRC_ULIB_UTILS_DEFER_H_
|
@ -10,6 +10,7 @@ add_executable(ulib_test
|
|||||||
ulib/system/thread_unittest.cpp
|
ulib/system/thread_unittest.cpp
|
||||||
ulib/system/thread_pool_unittest.cpp
|
ulib/system/thread_pool_unittest.cpp
|
||||||
ulib/system/timer_unittest.cpp
|
ulib/system/timer_unittest.cpp
|
||||||
|
ulib/utils/defer_unittest.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(ulib_test PRIVATE
|
target_link_libraries(ulib_test PRIVATE
|
||||||
ulib
|
ulib
|
||||||
|
@ -7,30 +7,34 @@
|
|||||||
class TimerTest : public ::testing::Test {
|
class TimerTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override { latch_ = nullptr; }
|
void SetUp() override { latch_ = nullptr; }
|
||||||
|
|
||||||
void TearDown() override { delete latch_; }
|
void TearDown() override { delete latch_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ulib::CountDownLatch *latch_;
|
ulib::CountDownLatch *latch_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(TimerTest, OnceTrigger) {
|
TEST_F(TimerTest, OnceTrigger)
|
||||||
|
{
|
||||||
latch_ = new ulib::CountDownLatch(1);
|
latch_ = new ulib::CountDownLatch(1);
|
||||||
ulib::TimerId timer_id = ulib::TimerManager::AddTimer([&]{
|
ulib::TimerId timer_id =
|
||||||
latch_->CountDown();
|
ulib::TimerManager::AddTimer([&] { latch_->CountDown(); }, 1000);
|
||||||
}, 1000);
|
|
||||||
latch_->Await();
|
latch_->Await();
|
||||||
ulib::TimerManager::CancelTimer(timer_id);
|
ulib::TimerManager::CancelTimer(timer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, PeriodTrigger) {
|
TEST_F(TimerTest, PeriodTrigger)
|
||||||
|
{
|
||||||
latch_ = new ulib::CountDownLatch(3);
|
latch_ = new ulib::CountDownLatch(3);
|
||||||
std::atomic_int cnt(3);
|
std::atomic_int cnt(3);
|
||||||
ulib::TimerId timer_id = ulib::TimerManager::AddTimer([&]{
|
ulib::TimerId timer_id = ulib::TimerManager::AddTimer(
|
||||||
|
[&] {
|
||||||
if (cnt.fetch_sub(1) > 0) {
|
if (cnt.fetch_sub(1) > 0) {
|
||||||
ULOG_INFO("timer.unittest", "start count down: {}", cnt);
|
ULOG_INFO("timer.unittest", "start count down: {}", cnt);
|
||||||
latch_->CountDown();
|
latch_->CountDown();
|
||||||
}
|
}
|
||||||
}, 1000, 3000);
|
},
|
||||||
|
1000, 1000);
|
||||||
latch_->Await();
|
latch_->Await();
|
||||||
ulib::TimerManager::CancelTimer(timer_id);
|
ulib::TimerManager::CancelTimer(timer_id);
|
||||||
}
|
}
|
60
tests/ulib/utils/defer_unittest.cpp
Normal file
60
tests/ulib/utils/defer_unittest.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ulib/utils/defer.h>
|
||||||
|
|
||||||
|
TEST(Defer, Defer)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
{
|
||||||
|
defer([&i]() { i++; });
|
||||||
|
EXPECT_EQ(i, 0);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Defer, DeferFunc)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
{
|
||||||
|
defer([&i]() { i++; });
|
||||||
|
EXPECT_EQ(i, 0);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Defer, DeferMove)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
{
|
||||||
|
defer([&i]() { i++; });
|
||||||
|
EXPECT_EQ(i, 0);
|
||||||
|
defer([&i]() { i++; });
|
||||||
|
EXPECT_EQ(i, 0);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(i, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Defer, Add)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
{
|
||||||
|
ulib::Defer defer;
|
||||||
|
defer.Add([&i]() { i++; });
|
||||||
|
EXPECT_EQ(i, 0);
|
||||||
|
defer.Add([&i]() { i++; });
|
||||||
|
EXPECT_EQ(i, 0);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(i, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Defer, Clear)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
{
|
||||||
|
ulib::Defer defer;
|
||||||
|
defer.Add([&i]() { i++; });
|
||||||
|
EXPECT_EQ(i, 0);
|
||||||
|
defer.Clear();
|
||||||
|
EXPECT_EQ(i, 0);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(i, 0);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user