feature add Mutex,ConditionVariable,Event,MutexGuard
Some checks failed
rpcrypto-build / build (Debug, hisiv510.toolchain.cmake) (push) Successful in 52s
linux-x64-gcc / linux-gcc (push) Failing after 56s
linux-mips64-gcc / linux-gcc-mips64el (push) Failing after 57s
rpcrypto-build / build (Debug, himix200.toolchain.cmake) (push) Successful in 1m18s
rpcrypto-build / build (Debug, mipsel-openwrt-linux-musl.toolchain.cmake) (push) Failing after 1m17s
rpcrypto-build / build (Release, mipsel-openwrt-linux.toolchain.cmake) (push) Failing after 1m15s
rpcrypto-build / build (Release, himix200.toolchain.cmake) (push) Successful in 1m25s
linux-hisiv500-gcc / linux-gcc-hisiv500 (push) Successful in 1m23s
rpcrypto-build / build (Release, hisiv510.toolchain.cmake) (push) Successful in 1m29s
rpcrypto-build / build (Debug, mipsel-openwrt-linux.toolchain.cmake) (push) Failing after 1m3s
rpcrypto-build / build (Release, mipsel-openwrt-linux-musl.toolchain.cmake) (push) Failing after 1m21s
Some checks failed
rpcrypto-build / build (Debug, hisiv510.toolchain.cmake) (push) Successful in 52s
linux-x64-gcc / linux-gcc (push) Failing after 56s
linux-mips64-gcc / linux-gcc-mips64el (push) Failing after 57s
rpcrypto-build / build (Debug, himix200.toolchain.cmake) (push) Successful in 1m18s
rpcrypto-build / build (Debug, mipsel-openwrt-linux-musl.toolchain.cmake) (push) Failing after 1m17s
rpcrypto-build / build (Release, mipsel-openwrt-linux.toolchain.cmake) (push) Failing after 1m15s
rpcrypto-build / build (Release, himix200.toolchain.cmake) (push) Successful in 1m25s
linux-hisiv500-gcc / linux-gcc-hisiv500 (push) Successful in 1m23s
rpcrypto-build / build (Release, hisiv510.toolchain.cmake) (push) Successful in 1m29s
rpcrypto-build / build (Debug, mipsel-openwrt-linux.toolchain.cmake) (push) Failing after 1m3s
rpcrypto-build / build (Release, mipsel-openwrt-linux-musl.toolchain.cmake) (push) Failing after 1m21s
This commit is contained in:
parent
2a8b1d873e
commit
91e96b17b2
@ -2,18 +2,18 @@ name: linux-x64-gcc
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- '.gitea/workflows/linux-x64-gcc.yml'
|
- ".gitea/workflows/linux-x64-gcc.yml"
|
||||||
- 'src/**'
|
- "src/**"
|
||||||
- 'tests/**'
|
- "tests/**"
|
||||||
- 'CMakeLists.txt'
|
- "CMakeLists.txt"
|
||||||
- 'cmake/**'
|
- "cmake/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '.gitea/workflows/linux-x64-gcc.yml'
|
- ".gitea/workflows/linux-x64-gcc.yml"
|
||||||
- 'src/**'
|
- "src/**"
|
||||||
- 'tests/**'
|
- "tests/**"
|
||||||
- 'CMakeLists.txt'
|
- "CMakeLists.txt"
|
||||||
- 'cmake/**'
|
- "cmake/**"
|
||||||
concurrency:
|
concurrency:
|
||||||
group: linux-x64-gcc-${{ github.ref }}
|
group: linux-x64-gcc-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
@ -50,4 +50,5 @@ jobs:
|
|||||||
cmake --build build-shared -j `nproc`
|
cmake --build build-shared -j `nproc`
|
||||||
- name: test-shared
|
- name: test-shared
|
||||||
run: |
|
run: |
|
||||||
cd build-shared && ctest --output-on-failure -j `nproc`
|
cd build-shared && ctest --output-on-failure -j `nproc`
|
||||||
|
|
||||||
|
@ -8,11 +8,21 @@ set(CMAKE_CXX_EXTENSIONS OFF)
|
|||||||
option(ULIB_BUILD_TESTS "Build tests" OFF)
|
option(ULIB_BUILD_TESTS "Build tests" OFF)
|
||||||
option(ULIB_SHARED_LIB "Build shared library" OFF)
|
option(ULIB_SHARED_LIB "Build shared library" OFF)
|
||||||
|
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
if (ULIB_SHARED_LIB)
|
if (ULIB_SHARED_LIB)
|
||||||
add_library(${PROJECT_NAME} SHARED "")
|
add_library(${PROJECT_NAME} SHARED "")
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
||||||
else()
|
else()
|
||||||
add_library(${PROJECT_NAME} STATIC "")
|
add_library(${PROJECT_NAME} STATIC ""
|
||||||
|
src/ulib/concorrency/mutex.cpp
|
||||||
|
src/ulib/concorrency/mutex.h
|
||||||
|
src/ulib/concorrency/condition_variable.cpp
|
||||||
|
src/ulib/concorrency/condition_variable.h
|
||||||
|
src/ulib/concorrency/internal/mutex_impl.cpp
|
||||||
|
src/ulib/concorrency/internal/mutex_impl.h
|
||||||
|
src/ulib/concorrency/internal/condition_variable_impl.cpp
|
||||||
|
src/ulib/concorrency/internal/condition_variable_impl.h
|
||||||
|
src/ulib/concorrency/event.cpp
|
||||||
|
src/ulib/concorrency/event.h)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
@ -31,7 +41,6 @@ set(FMT_TEST OFF CACHE BOOL "Build tests" FORCE)
|
|||||||
set(FMT_USE_CPP11 OFF CACHE BOOL "Use C++11" FORCE)
|
set(FMT_USE_CPP11 OFF CACHE BOOL "Use C++11" FORCE)
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3party/fmt)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3party/fmt)
|
||||||
|
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME} PRIVATE
|
target_sources(${PROJECT_NAME} PRIVATE
|
||||||
src/ulib/empty.cpp
|
src/ulib/empty.cpp
|
||||||
src/ulib/log/logger.cpp
|
src/ulib/log/logger.cpp
|
||||||
|
38
src/ulib/concorrency/condition_variable.cpp
Normal file
38
src/ulib/concorrency/condition_variable.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "condition_variable.h"
|
||||||
|
#include "internal/condition_variable_impl.h"
|
||||||
|
|
||||||
|
namespace ulib {
|
||||||
|
|
||||||
|
ConditionVariable::ConditionVariable() : impl_(new detail::ConditionVariableImpl) {}
|
||||||
|
|
||||||
|
ConditionVariable::~ConditionVariable() { delete impl_; }
|
||||||
|
|
||||||
|
void
|
||||||
|
ConditionVariable::NotifyOne()
|
||||||
|
{
|
||||||
|
impl_->NotifyOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ConditionVariable::NotifyAll()
|
||||||
|
{
|
||||||
|
impl_->NotifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ConditionVariable::Wait(MutexGuard &guard)
|
||||||
|
{
|
||||||
|
impl_->Wait(*guard.mutex_.impl_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ConditionVariable::WaitForMilliseconds(MutexGuard &guard, uint32_t wait_time)
|
||||||
|
{
|
||||||
|
return impl_->WaitForMilliseconds(*guard.mutex_.impl_, wait_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
src/ulib/concorrency/condition_variable.h
Normal file
47
src/ulib/concorrency/condition_variable.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ULIB_SRC_ULIB_CONCORRENCY_CONDITION_VARIABLE_H_
|
||||||
|
#define ULIB_SRC_ULIB_CONCORRENCY_CONDITION_VARIABLE_H_
|
||||||
|
|
||||||
|
#include "mutex.h"
|
||||||
|
#include "ulib/base/types.h"
|
||||||
|
|
||||||
|
namespace ulib {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
class ConditionVariableImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConditionVariable {
|
||||||
|
public:
|
||||||
|
ConditionVariable();
|
||||||
|
~ConditionVariable();
|
||||||
|
|
||||||
|
void NotifyOne();
|
||||||
|
void NotifyAll();
|
||||||
|
|
||||||
|
void Wait(MutexGuard &guard);
|
||||||
|
bool WaitForMilliseconds(MutexGuard &guard, uint32_t wait_time);
|
||||||
|
|
||||||
|
template<class Predicate>
|
||||||
|
void Wait(MutexGuard &guard, Predicate p)
|
||||||
|
{
|
||||||
|
while (!p()) { Wait(guard); }
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Predicate>
|
||||||
|
bool WaitForMilliseconds(MutexGuard &guard, uint32_t wait_time, Predicate p)
|
||||||
|
{
|
||||||
|
if (!p()) { WaitForMilliseconds(guard, wait_time); }
|
||||||
|
return p();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
detail::ConditionVariableImpl *impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}// namespace ulib
|
||||||
|
|
||||||
|
#endif//ULIB_SRC_ULIB_CONCORRENCY_CONDITION_VARIABLE_H_
|
64
src/ulib/concorrency/event.cpp
Normal file
64
src/ulib/concorrency/event.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/13.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
|
ulib::Event::Event() : manual_reset_(false), event_status_(false) {}
|
||||||
|
|
||||||
|
ulib::Event::Event(bool manual_reset, bool initially_signaled)
|
||||||
|
: manual_reset_(manual_reset),
|
||||||
|
event_status_(initially_signaled)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ulib::Event::~Event() {}
|
||||||
|
|
||||||
|
void
|
||||||
|
ulib::Event::Set()
|
||||||
|
{
|
||||||
|
MutexGuard guard(mutex_);
|
||||||
|
event_status_ = true;
|
||||||
|
cond_.NotifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ulib::Event::Reset()
|
||||||
|
{
|
||||||
|
MutexGuard guard(mutex_);
|
||||||
|
event_status_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ulib::Event::Wait(int give_up_after_ms)
|
||||||
|
{
|
||||||
|
MutexGuard guard(mutex_);
|
||||||
|
if (event_status_) { return true; }
|
||||||
|
|
||||||
|
IsEventSetChecker checker(*this);
|
||||||
|
if (give_up_after_ms <= 0) {
|
||||||
|
cond_.Wait(guard, checker);
|
||||||
|
} else {
|
||||||
|
cond_.WaitForMilliseconds(guard, give_up_after_ms, checker);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event_status_) {
|
||||||
|
if (manual_reset_) { event_status_ = false; }
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ulib::Event::operator()() const
|
||||||
|
{
|
||||||
|
return event_status_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulib::Event::IsEventSetChecker::IsEventSetChecker(const ulib::Event &event) : event_(event) {}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ulib::Event::IsEventSetChecker::operator()()
|
||||||
|
{
|
||||||
|
return event_.event_status_;
|
||||||
|
}
|
50
src/ulib/concorrency/event.h
Normal file
50
src/ulib/concorrency/event.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/13.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ULIB_SRC_ULIB_CONCORRENCY_EVENT_H_
|
||||||
|
#define ULIB_SRC_ULIB_CONCORRENCY_EVENT_H_
|
||||||
|
|
||||||
|
#include "mutex.h"
|
||||||
|
#include "condition_variable.h"
|
||||||
|
|
||||||
|
namespace ulib {
|
||||||
|
class Event {
|
||||||
|
public:
|
||||||
|
Event();
|
||||||
|
Event(bool manual_reset, bool initially_signaled);
|
||||||
|
~Event();
|
||||||
|
|
||||||
|
void Set();
|
||||||
|
void Reset();
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param give_up_after_ms -1, always wait, > 0 set timeout
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool Wait(int give_up_after_ms = -1);
|
||||||
|
bool operator()() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class IsEventSetChecker {
|
||||||
|
public:
|
||||||
|
IsEventSetChecker(const Event &);
|
||||||
|
bool operator()();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Event &event_;
|
||||||
|
};
|
||||||
|
|
||||||
|
Event(const Event &);
|
||||||
|
Event &operator=(const Event &);
|
||||||
|
|
||||||
|
const bool manual_reset_;
|
||||||
|
Mutex mutex_;
|
||||||
|
ConditionVariable cond_;
|
||||||
|
bool event_status_;
|
||||||
|
|
||||||
|
friend class IsEventSetChecker;
|
||||||
|
};
|
||||||
|
}// namespace ulib
|
||||||
|
|
||||||
|
#endif//ULIB_SRC_ULIB_CONCORRENCY_EVENT_H_
|
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "condition_variable_impl.h"
|
58
src/ulib/concorrency/internal/condition_variable_impl.h
Normal file
58
src/ulib/concorrency/internal/condition_variable_impl.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ULIB_SRC_ULIB_CONCORRENCY_INTERNAL_CONDITION_VARIABLE_IMPL_H_
|
||||||
|
#define ULIB_SRC_ULIB_CONCORRENCY_INTERNAL_CONDITION_VARIABLE_IMPL_H_
|
||||||
|
|
||||||
|
#include "ulib/base/types.h"
|
||||||
|
#include "mutex_impl.h"
|
||||||
|
#include "ulib/concorrency/mutex.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
namespace ulib {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
class ConditionVariableImpl {
|
||||||
|
public:
|
||||||
|
ConditionVariableImpl() { pthread_cond_init(&cond_, NULL); }
|
||||||
|
|
||||||
|
~ConditionVariableImpl() { pthread_cond_destroy(&cond_); }
|
||||||
|
|
||||||
|
void NotifyOne() { pthread_cond_signal(&cond_); }
|
||||||
|
|
||||||
|
void NotifyAll() { pthread_cond_broadcast(&cond_); }
|
||||||
|
|
||||||
|
void Wait(MutexImpl &mutex_impl) { pthread_cond_wait(&cond_, &mutex_impl.mutex_); }
|
||||||
|
|
||||||
|
template<class Predicate>
|
||||||
|
void Wait(MutexImpl &mutex_impl, Predicate p)
|
||||||
|
{
|
||||||
|
while (!p()) { Wait(mutex_impl); }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitForMilliseconds(MutexImpl &mutex_impl, uint32_t wait_time)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
ts.tv_sec = 0;
|
||||||
|
ts.tv_nsec = wait_time * 1000000;
|
||||||
|
return ETIMEDOUT != pthread_cond_timedwait(&cond_, &mutex_impl.mutex_, &ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Predicate>
|
||||||
|
bool WaitForMilliseconds(MutexImpl &mutex_impl, uint32_t wait_time, Predicate p)
|
||||||
|
{
|
||||||
|
if (!p()) { WaitForMilliseconds(mutex_impl, wait_time); }
|
||||||
|
return p();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_cond_t cond_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
}// namespace ulib
|
||||||
|
|
||||||
|
#endif//ULIB_SRC_ULIB_CONCORRENCY_INTERNAL_CONDITION_VARIABLE_IMPL_H_
|
5
src/ulib/concorrency/internal/mutex_impl.cpp
Normal file
5
src/ulib/concorrency/internal/mutex_impl.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "mutex_impl.h"
|
31
src/ulib/concorrency/internal/mutex_impl.h
Normal file
31
src/ulib/concorrency/internal/mutex_impl.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ULIB_SRC_ULIB_CONCORRENCY_INTERNAL_MUTEX_IMPL_H_
|
||||||
|
#define ULIB_SRC_ULIB_CONCORRENCY_INTERNAL_MUTEX_IMPL_H_
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace ulib {
|
||||||
|
namespace detail {
|
||||||
|
class MutexImpl {
|
||||||
|
public:
|
||||||
|
MutexImpl() { pthread_mutex_init(&mutex_, NULL); }
|
||||||
|
|
||||||
|
~MutexImpl() { pthread_mutex_destroy(&mutex_); }
|
||||||
|
|
||||||
|
void Lock() { pthread_mutex_lock(&mutex_); }
|
||||||
|
|
||||||
|
void Unlock() { pthread_mutex_unlock(&mutex_); }
|
||||||
|
|
||||||
|
bool TryLock() { return pthread_mutex_trylock(&mutex_) == 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class ConditionVariableImpl;
|
||||||
|
pthread_mutex_t mutex_;
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace ulib
|
||||||
|
|
||||||
|
#endif//ULIB_SRC_ULIB_CONCORRENCY_INTERNAL_MUTEX_IMPL_H_
|
36
src/ulib/concorrency/mutex.cpp
Normal file
36
src/ulib/concorrency/mutex.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "mutex.h"
|
||||||
|
#include "internal/mutex_impl.h"
|
||||||
|
|
||||||
|
namespace ulib {
|
||||||
|
|
||||||
|
Mutex::Mutex() : impl_(new detail::MutexImpl) {}
|
||||||
|
|
||||||
|
Mutex::~Mutex() { delete impl_; }
|
||||||
|
|
||||||
|
void
|
||||||
|
Mutex::Lock()
|
||||||
|
{
|
||||||
|
impl_->Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mutex::Unlock()
|
||||||
|
{
|
||||||
|
impl_->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Mutex::TryLock()
|
||||||
|
{
|
||||||
|
return impl_->TryLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexGuard::MutexGuard(Mutex &mutex) : mutex_(mutex) { mutex_.Lock(); }
|
||||||
|
|
||||||
|
MutexGuard::~MutexGuard() { mutex_.Unlock(); }
|
||||||
|
|
||||||
|
}// namespace ulib
|
43
src/ulib/concorrency/mutex.h
Normal file
43
src/ulib/concorrency/mutex.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// Created by Feng Zhang on 2023/12/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ULIB_SRC_ULIB_CONCORRENCY_MUTEX_H_
|
||||||
|
#define ULIB_SRC_ULIB_CONCORRENCY_MUTEX_H_
|
||||||
|
|
||||||
|
namespace ulib {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
class MutexImpl;
|
||||||
|
}
|
||||||
|
class Mutex {
|
||||||
|
public:
|
||||||
|
Mutex();
|
||||||
|
~Mutex();
|
||||||
|
void Lock();
|
||||||
|
void Unlock();
|
||||||
|
bool TryLock();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mutex(const Mutex &);
|
||||||
|
Mutex &operator=(const Mutex &);
|
||||||
|
|
||||||
|
friend class ConditionVariable;
|
||||||
|
detail::MutexImpl *impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MutexGuard {
|
||||||
|
public:
|
||||||
|
MutexGuard(Mutex& );
|
||||||
|
~MutexGuard();
|
||||||
|
private:
|
||||||
|
MutexGuard(const MutexGuard&);
|
||||||
|
MutexGuard& operator=(const MutexGuard&);
|
||||||
|
|
||||||
|
friend class ConditionVariable;
|
||||||
|
Mutex& mutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ulib
|
||||||
|
|
||||||
|
#endif//ULIB_SRC_ULIB_CONCORRENCY_MUTEX_H_
|
@ -4,6 +4,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||||||
add_executable(ulib_test
|
add_executable(ulib_test
|
||||||
ulib/base/types_test.cpp
|
ulib/base/types_test.cpp
|
||||||
ulib/log/log_test.cpp
|
ulib/log/log_test.cpp
|
||||||
|
ulib/concorrency/mutex_test.cpp
|
||||||
|
ulib/concorrency/event_test.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(ulib_test PRIVATE
|
target_link_libraries(ulib_test PRIVATE
|
||||||
ulib
|
ulib
|
||||||
|
62
tests/ulib/concorrency/event_test.cpp
Normal file
62
tests/ulib/concorrency/event_test.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include <ulib/concorrency/condition_variable.h>
|
||||||
|
#include <ulib/concorrency/mutex.h>
|
||||||
|
#include <ulib/log/log.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ulib/concorrency/event.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class EventTest : public ::testing::Test {
|
||||||
|
public:
|
||||||
|
void SetUp() override
|
||||||
|
{
|
||||||
|
EXPECT_FALSE(event_());
|
||||||
|
EXPECT_FALSE(event_.Wait(100));
|
||||||
|
|
||||||
|
consumer_count_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulib::Event event_;
|
||||||
|
ulib::Mutex mutex_;
|
||||||
|
ulib::ConditionVariable cond_;
|
||||||
|
|
||||||
|
int32_t consumer_count_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *
|
||||||
|
Consumer(void *args)
|
||||||
|
{
|
||||||
|
EventTest *test = (EventTest *) args;
|
||||||
|
{
|
||||||
|
ulib::MutexGuard guard(test->mutex_);
|
||||||
|
++test->consumer_count_;
|
||||||
|
test->cond_.NotifyAll();
|
||||||
|
}
|
||||||
|
EXPECT_TRUE(test != NULL);
|
||||||
|
test->event_.Wait();
|
||||||
|
{
|
||||||
|
ulib::MutexGuard guard(test->mutex_);
|
||||||
|
--test->consumer_count_;
|
||||||
|
test->cond_.NotifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(EventTest, multi_thread_wait_event)
|
||||||
|
{
|
||||||
|
std::vector<pthread_t> threads(10);
|
||||||
|
for (int i = 0; i < threads.size(); i++) { pthread_create(&threads[i], NULL, Consumer, this); }
|
||||||
|
|
||||||
|
ulib::MutexGuard guard(mutex_);
|
||||||
|
while (consumer_count_ < threads.size()) { cond_.Wait(guard); }
|
||||||
|
EXPECT_EQ(consumer_count_, threads.size());
|
||||||
|
|
||||||
|
{
|
||||||
|
event_.Set();
|
||||||
|
while (consumer_count_ > 0) { cond_.Wait(guard); }
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(consumer_count_, 0);
|
||||||
|
for (int i = 0; i < threads.size(); i++) { pthread_join(threads[i], NULL); }
|
||||||
|
}
|
10
tests/ulib/concorrency/mutex_test.cpp
Normal file
10
tests/ulib/concorrency/mutex_test.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ulib/concorrency/mutex.h>
|
||||||
|
|
||||||
|
TEST(MutexTest, MutexTest)
|
||||||
|
{
|
||||||
|
ulib::Mutex mutex;
|
||||||
|
EXPECT_TRUE(mutex.TryLock());
|
||||||
|
EXPECT_FALSE(mutex.TryLock());
|
||||||
|
mutex.Unlock();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user