Merge branch 'master' of code.uocat.com:tqcq/sled
Some checks failed
linux-x64-gcc / linux-gcc (Release) (push) Failing after 1m1s
linux-x64-gcc / linux-gcc (Debug) (push) Failing after 48s

This commit is contained in:
tqcq 2024-03-14 20:51:49 +08:00
commit bd0f7bd208
9 changed files with 205 additions and 22 deletions

View File

@ -70,11 +70,6 @@ target_sources(
# set(BUILD_WITH_STATIC_RUNTIME_LIBS ON) set(BUILD_WITH_DOCUMENTATION OFF)
# add_subdirectory(3party/rttr EXCLUDE_FROM_ALL)
target_include_directories(
sled
PUBLIC include
PRIVATE src)
target_link_libraries(sled PUBLIC rpc_core fmt marl protobuf::libprotobuf)
if(SLED_BUILD_BENCHMARK)
@ -100,6 +95,7 @@ if(SLED_BUILD_TESTS)
)
FetchContent_MakeAvailable(googletest)
add_executable(sled_tests
src/any_test.cc
src/filesystem/path_test.cc
src/strings/base64_test.cc
src/cleanup_test.cc

View File

@ -332,6 +332,98 @@ any_cast(any &&operand)
return any_cast<ValueType>(operand);
}
class Any final {
public:
inline Any() {}
inline Any(const Any &other) : value_(other.value_) {}
inline Any(Any &&other) noexcept : value_(std::move(other.value_)) {}
template<typename ValueType>
inline Any(const ValueType &value) : value_(value)
{}
template<typename ValueType>
inline Any(
ValueType &&value,
typename std::enable_if<!std::is_same<Any &, ValueType>::value>::type
* = 0,
typename std::enable_if<!std::is_const<ValueType>::value>::type * = 0)
: value_(std::forward<ValueType &&>(value))
{}
// ~Any() noexcept {}
Any &operator=(const Any &rhs)
{
Any(rhs).swap(*this);
return *this;
}
Any &operator=(Any &&rhs) noexcept
{
rhs.swap(*this);
Any().swap(rhs);
return *this;
}
template<typename ValueType>
Any &operator=(ValueType &&rhs)
{
Any(static_cast<ValueType &&>(rhs)).swap(*this);
return *this;
}
template<typename ValueType>
inline auto Cast() const -> ValueType const
{
return any_cast<ValueType>(value_);
}
template<typename ValueType>
inline ValueType Cast() const &&
{
return any_cast<ValueType>(value_);
}
template<typename ValueType, typename U = ValueType>
inline auto CastOr(U &&default_value) const -> ValueType
{
try {
return any_cast<ValueType>(value_);
} catch (const bad_any_cast &e) {
return static_cast<ValueType>(default_value);
}
}
template<typename ValueType, typename U = ValueType>
inline auto CastOr(U &&default_value) -> ValueType
{
try {
return any_cast<ValueType>(value_);
} catch (const bad_any_cast &e) {
return static_cast<ValueType>(default_value);
}
}
void Reset() noexcept { Any().swap(*this); }
bool HasValue() const noexcept { return value_.has_value(); }
const std::type_info &Type() const noexcept { return value_.type(); }
Any &swap(Any &rhs) noexcept
{
std::swap(value_, rhs.value_);
return *this;
}
any value_;
private:
};
}// namespace sled
#endif /* SLED_ANY_H */

View File

@ -0,0 +1,41 @@
#pragma once
#ifndef SLED_LANG_ATTRIBUTES_H
#define SLED_LANG_ATTRIBUTES_H
#define SLED_DEPRECATED() __attribute__((deprecated))
#if defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__) && !defined(SWIG)
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#elif defined(__clang__)
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x)
#endif
#if defined(GUARDED_BY)
#undef GUARDED_BY
#endif
#define GUARDED_BY(x) __attribute__((guarded_by(x)))
#if defined(__clang__)
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
#define EXCLUSIVE_LOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
#define UNLOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#else
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock(__VA_ARGS__))
#define EXCLUSIVE_LOCK_FUNCTION(...) \
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock(__VA_ARGS__))
#define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock(__VA_ARGS__))
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x))
#endif
#endif// SLED_LANG_ATTRIBUTES_H

View File

@ -10,6 +10,7 @@
#include "sled/ref_count.h"
#include "sled/ref_counter.h"
#include <memory>
namespace sled {

View File

@ -36,7 +36,7 @@ public:
Mutex mutex_;
ConditionVariable cv_;
const bool is_manual_reset_;
bool event_status_;
bool event_status_ GUARDED_BY(mutex_);
};
}// namespace sled

View File

@ -5,10 +5,11 @@
**/
#pragma once
#include "marl/conditionvariable.h"
#ifndef SLED_SYNCHRONIZATION_MUTEX_H
#define SLED_SYNCHRONIZATION_MUTEX_H
#include "marl/conditionvariable.h"
#include "sled/lang/attributes.h"
#include "sled/units/time_delta.h"
#include <chrono>
#include <condition_variable>
@ -59,13 +60,13 @@ public:
RecursiveMutex(const RecursiveMutex &) = delete;
RecursiveMutex &operator=(const RecursiveMutex &) = delete;
inline void Lock() { impl_.lock(); }
inline void Lock() EXCLUSIVE_LOCK_FUNCTION() { impl_.lock(); }
inline bool TryLock() { return impl_.try_lock(); }
inline void AssertHeld() {}
inline void Unlock() { impl_.unlock(); }
inline void Unlock() UNLOCK_FUNCTION() { impl_.unlock(); }
private:
std::recursive_mutex impl_;
@ -77,32 +78,35 @@ public:
LockGuard(const LockGuard &) = delete;
LockGuard &operator=(const LockGuard &) = delete;
explicit LockGuard(TLock *lock) : mutex_(lock) { mutex_->Lock(); };
explicit LockGuard(TLock *lock) EXCLUSIVE_LOCK_FUNCTION() : mutex_(lock)
{
mutex_->Lock();
};
~LockGuard() { mutex_->Unlock(); };
~LockGuard() UNLOCK_FUNCTION() { mutex_->Unlock(); };
private:
TLock *mutex_;
friend class ConditionVariable;
};
class MutexGuard final {
class MutexLock final {
public:
MutexGuard(Mutex *mutex) : lock_(*mutex) {}
MutexLock(Mutex *mutex) : lock_(*mutex) {}
MutexGuard(const MutexGuard &) = delete;
MutexGuard &operator=(const MutexGuard &) = delete;
MutexLock(const MutexLock &) = delete;
MutexLock &operator=(const MutexLock &) = delete;
private:
friend class ConditionVariable;
marl::lock lock_;
};
using MutexLock = MutexGuard;
using MutexGuard SLED_DEPRECATED() = MutexLock;
// using MutexGuard = marl::lock;
// using MutexLock = LockGuard<Mutex>;
// using MutexGuard = LockGuard<Mutex>;
using RecursiveMutexLock = LockGuard<RecursiveMutex>;
using RecursiveMutexLock SLED_DEPRECATED() = LockGuard<RecursiveMutex>;
// class MutexLock final {
// public:

View File

@ -25,7 +25,7 @@ public:
}
private:
bool happended_ = false;
bool happended_ GUARDED_BY(mutex_) = false;
Mutex mutex_;
};

View File

@ -159,9 +159,9 @@ private:
void ClearCurrentTaskQueue();
mutable Mutex mutex_;
std::queue<std::function<void()>> messages_;
std::priority_queue<DelayedMessage> delayed_messages_;
uint32_t delayed_next_num_;
std::queue<std::function<void()>> messages_ GUARDED_BY(mutex_);
std::priority_queue<DelayedMessage> delayed_messages_ GUARDED_BY(mutex_);
uint32_t delayed_next_num_ GUARDED_BY(mutex_);
bool fInitialized_;
bool fDestroyed_;
std::atomic<int> stop_;
@ -183,8 +183,9 @@ public:
AutoSocketServerThread(const AutoSocketServerThread &) = delete;
AutoSocketServerThread &operator=(const AutoSocketServerThread &) = delete;
private:
Thread* old_thread_;
Thread *old_thread_;
};
}// namespace sled

48
src/any_test.cc Normal file
View File

@ -0,0 +1,48 @@
#include <gtest/gtest.h>
#include <sled/any.h>
#include <sled/log/log.h>
TEST(Any, Assign)
{
sled::Any any1;
sled::Any any2(any1);
sled::Any any3(1);
sled::Any any4(any3);
sled::Any any5 = 1;
EXPECT_FALSE(any1.HasValue());
EXPECT_FALSE(any2.HasValue());
EXPECT_TRUE(any3.HasValue());
EXPECT_TRUE(any4.HasValue());
EXPECT_TRUE(any5.HasValue());
EXPECT_EQ(any3.Cast<int>(), 1);
EXPECT_EQ(any4.Cast<int>(), 1);
EXPECT_EQ(any5.Cast<int>(), 1);
EXPECT_EQ(any3.CastOr<std::string>("def"), "def");
EXPECT_EQ(any4.CastOr<std::string>("def"), "def");
EXPECT_EQ(any5.CastOr<std::string>("def"), "def");
EXPECT_EQ(any3.CastOr<int>(11), 1);
}
TEST(Any, std_swap)
{
sled::Any a;
sled::Any b = 2;
EXPECT_FALSE(a.HasValue());
EXPECT_TRUE(b.HasValue());
std::swap(a, b);
EXPECT_TRUE(a.HasValue());
EXPECT_FALSE(b.HasValue());
EXPECT_EQ(a.Cast<int>(), 2);
}
TEST(Any, custom_swap)
{
sled::Any a;
sled::Any b = 2;
EXPECT_FALSE(a.HasValue());
EXPECT_TRUE(b.HasValue());
a.swap(b);
EXPECT_TRUE(a.HasValue());
EXPECT_FALSE(b.HasValue());
EXPECT_EQ(a.Cast<int>(), 2);
}