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_pool_unittest.cpp
|
||||
ulib/system/timer_unittest.cpp
|
||||
ulib/utils/defer_unittest.cpp
|
||||
)
|
||||
target_link_libraries(ulib_test PRIVATE
|
||||
ulib
|
||||
|
@ -7,30 +7,34 @@
|
||||
class TimerTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override { latch_ = nullptr; }
|
||||
|
||||
void TearDown() override { delete latch_; }
|
||||
|
||||
protected:
|
||||
ulib::CountDownLatch *latch_;
|
||||
};
|
||||
|
||||
TEST_F(TimerTest, OnceTrigger) {
|
||||
TEST_F(TimerTest, OnceTrigger)
|
||||
{
|
||||
latch_ = new ulib::CountDownLatch(1);
|
||||
ulib::TimerId timer_id = ulib::TimerManager::AddTimer([&]{
|
||||
latch_->CountDown();
|
||||
}, 1000);
|
||||
ulib::TimerId timer_id =
|
||||
ulib::TimerManager::AddTimer([&] { latch_->CountDown(); }, 1000);
|
||||
latch_->Await();
|
||||
ulib::TimerManager::CancelTimer(timer_id);
|
||||
}
|
||||
|
||||
TEST_F(TimerTest, PeriodTrigger) {
|
||||
TEST_F(TimerTest, PeriodTrigger)
|
||||
{
|
||||
latch_ = new ulib::CountDownLatch(3);
|
||||
std::atomic_int cnt(3);
|
||||
ulib::TimerId timer_id = ulib::TimerManager::AddTimer([&]{
|
||||
if (cnt.fetch_sub(1) > 0) {
|
||||
ULOG_INFO("timer.unittest", "start count down: {}", cnt);
|
||||
latch_->CountDown();
|
||||
}
|
||||
}, 1000, 3000);
|
||||
ulib::TimerId timer_id = ulib::TimerManager::AddTimer(
|
||||
[&] {
|
||||
if (cnt.fetch_sub(1) > 0) {
|
||||
ULOG_INFO("timer.unittest", "start count down: {}", cnt);
|
||||
latch_->CountDown();
|
||||
}
|
||||
},
|
||||
1000, 1000);
|
||||
latch_->Await();
|
||||
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