feat update tsa
Some checks failed
linux-x64-gcc / linux-gcc (Debug) (push) Failing after 1m26s
linux-x64-gcc / linux-gcc (Release) (push) Failing after 58s

This commit is contained in:
tqcq 2024-03-23 08:53:11 +08:00
parent a81eb0f8de
commit 03a62901f2
29 changed files with 338 additions and 315 deletions

View File

@ -56,7 +56,7 @@ target_sources(
src/strings/utils.cc
src/synchronization/event.cc
src/synchronization/mutex.cc
src/synchronization/sequence_checker_internal.cc
src/synchronization/sequence_checker.cc
src/synchronization/thread_local.cc
src/system/location.cc
src/system/pid.cc
@ -126,6 +126,7 @@ if(SLED_BUILD_TESTS)
src/futures/future_test.cc
# src/profiling/profiling_test.cc
src/strings/base64_test.cc
src/synchronization/sequence_checker_test.cc
src/cleanup_test.cc
src/status_or_test.cc
src/system/fiber/fiber_test.cc

View File

@ -1,6 +1,6 @@
#pragma once
#ifndef SLED_FILESYSTEM_PATH_H
#define SLED_FILESYSTEM_PATH_H
#pragma once
#include <string>

View File

@ -1,6 +1,6 @@
#pragma once
#ifndef SLED_FILESYSTEM_TEMPORARY_FILE_H
#define SLED_FILESYSTEM_TEMPORARY_FILE_H
#pragma once
#include <string>

View File

@ -1,39 +1,59 @@
#pragma once
#ifndef SLED_LANG_ATTRIBUTES_H
#define SLED_LANG_ATTRIBUTES_H
#pragma once
#include <marl/tsa.h>
#define SLED_DEPRECATED __attribute__((deprecated))
#define SLED_DEPRECATED() __attribute__((deprecated))
#ifndef THREAD_ANNOTATION_ATTRIBUTE__
#if defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__) && !defined(SWIG)
#define THREAD_ANNOTATION_ATTRIBUTE__(x)
#elif defined(__clang__)
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#if defined(__clang__) && (!defined(SWIG))
#define SLED_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x)
#endif
#endif// THREAD_ANNOTATION_ATTRIBUTE__
#ifndef GUARDED_BY
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define SLED_THREAD_ANNOTATION_ATTRIBUTE__(x)// no-op
#endif
#if defined(__clang__)
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
#define SLED_CAPABILITY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
#define EXCLUSIVE_LOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
#define SLED_SCOPED_CAPABILITY SLED_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
#define SLED_LOCKABLE SLED_THREAD_ANNOTATION_ATTRIBUTE__(lockable)
#define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
#define SLED_GUARDED_BY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
// #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#define SLED_PT_GUARDED_BY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#else// defined(__clang__)
#define SLED_ACQUIRED_BEFORE(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
#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
#define SLED_ACQUIRED_AFTER(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
#define SLED_REQUIRES(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
#define SLED_REQUIRES_SHARED(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
#define SLED_ACQUIRE(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
#define SLED_ACQUIRE_SHARED(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
#define SLED_RELEASE(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
#define SLED_RELEASE_SHARED(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
#define SLED_TRY_ACQUIRE(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
#define SLED_TRY_ACQUIRE_SHARED(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
#define SLED_EXCLUDES(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#define SLED_ASSERT_CAPABILITY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
#define SLED_ASSERT_SHARED_CAPABILITY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
#define SLED_RETURN_CAPABILITY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
#define SLED_NO_THREAD_SAFETY_ANALYSIS SLED_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
#define SLED_EXCLUSIVE_LOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
#define SLED_SHARED_LOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
#define SLED_EXCLUSIVE_TRYLOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
#define SLED_SHARED_TRYLOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
#define SLED_UNLOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
#define SLED_ASSERT_EXCLUSIVE_LOCK(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
#endif// SLED_LANG_ATTRIBUTES_H

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_LOG_LOG_H
#define SLED_LOG_LOG_H
#pragma once
#include "sled/system/location.h"
#include <assert.h>
#include <fmt/format.h>
@ -69,6 +69,9 @@ void Log(LogLevel level, const char *tag, const char *fmt, const char *file_name
#define LOGE_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kError, tag, fmt, __VA_ARGS__)
#define LOGF_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kFatal, tag, fmt, __VA_ARGS__)
#define CHECK(cond, fmt, ...) SLOG_ASSERT(cond, "DCHECK", fmt, ##__VA_ARGS__)
#define DCHECK(cond, fmt, ...) SLOG_ASSERT(cond, "DCHECK", fmt, ##__VA_ARGS__)
#define LOGV(tag, fmt, ...) SLOG(sled::LogLevel::kTrace, tag, fmt, ##__VA_ARGS__)
#define LOGD(tag, fmt, ...) SLOG(sled::LogLevel::kDebug, tag, fmt, ##__VA_ARGS__)
#define LOGI(tag, fmt, ...) SLOG(sled::LogLevel::kInfo, tag, fmt, ##__VA_ARGS__)

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_NETWORK_ASYNC_RESOLVER_H
#define SLED_NETWORK_ASYNC_RESOLVER_H
#pragma once
#include "sled/network/async_resolver_interface.h"
#include "sled/scoped_refptr.h"
@ -34,8 +34,7 @@ private:
SocketAddress addr_;
std::vector<IPAddress> addresses_;
int error_;
bool recursion_check_ =
false;// Protects against SignalDone calling into Destroy.
bool recursion_check_ = false;// Protects against SignalDone calling into Destroy.
bool destroy_called_ = false;
scoped_refptr<State> state_;
};

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_NETWORK_ASYNC_RESOLVER_INTERFACE_H
#define SLED_NETWORK_ASYNC_RESOLVER_INTERFACE_H
#pragma once
#include "sled/network/socket_address.h"
#include "sled/sigslot.h"

View File

@ -4,10 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_NETWORK_IP_ADDRESS_H
#define SLED_NETWORK_IP_ADDRESS_H
#pragma once
#include "sled/byte_order.h"
#include <arpa/inet.h>
@ -29,10 +28,7 @@ public:
u_.ip4 = ip4;
}
explicit IPAddress(const in6_addr &ip6) : family_(AF_INET6)
{
u_.ip6 = ip6;
}
explicit IPAddress(const in6_addr &ip6) : family_(AF_INET6) { u_.ip6 = ip6; }
explicit IPAddress(uint32_t ip_in_host_byte_order) : family_(AF_INET)
{
@ -40,10 +36,7 @@ public:
u_.ip4.s_addr = HostToNetwork32(ip_in_host_byte_order);
}
IPAddress(const IPAddress &other) : family_(other.family_)
{
::memcpy(&u_, &other.u_, sizeof(u_));
}
IPAddress(const IPAddress &other) : family_(other.family_) { ::memcpy(&u_, &other.u_, sizeof(u_)); }
virtual ~IPAddress() = default;

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_NETWORK_NULL_SOCKET_SERVER_H
#define SLED_NETWORK_NULL_SOCKET_SERVER_H
#pragma once
#include "sled/network/socket_server.h"
#include "sled/synchronization/event.h"
@ -21,6 +21,7 @@ public:
void WakeUp() override;
Socket *CreateSocket(int family, int type) override;
private:
Event event_;
};

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_NETWORK_PHYSICAL_SOCKET_SERVER_H
#define SLED_NETWORK_PHYSICAL_SOCKET_SERVER_H
#pragma once
#include "sled/network/async_resolver.h"
#include "sled/sigslot.h"

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_NETWORK_SOCKET_H
#define SLED_NETWORK_SOCKET_H
#pragma once
#include "sled/network/socket_address.h"
#include "sled/sigslot.h"
@ -36,11 +36,9 @@ public:
virtual int Bind(const SocketAddress &addr) = 0;
virtual int Connect(const SocketAddress &addr) = 0;
virtual int Send(const void *pv, size_t cb) = 0;
virtual int
SendTo(const void *pv, size_t cb, const SocketAddress &addr) = 0;
virtual int SendTo(const void *pv, size_t cb, const SocketAddress &addr) = 0;
virtual int Recv(void *pv, size_t cb, int64_t *timestamp) = 0;
virtual int
RecvFrom(void *pv, size_t cb, SocketAddress *paddr, int64_t *timestamp) = 0;
virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr, int64_t *timestamp) = 0;
virtual int Listen(int backlog) = 0;
virtual Socket *Accept(SocketAddress *paddr) = 0;
virtual int Close() = 0;

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_NETWORK_SOCKET_ADDRESS_H
#define SLED_NETWORK_SOCKET_ADDRESS_H
#pragma once
#include "sled/network/ip_address.h"
@ -65,8 +65,7 @@ private:
bool literal_;
};
bool SocketAddressFromSockAddrStorage(const sockaddr_storage &saddr,
SocketAddress *out);
bool SocketAddressFromSockAddrStorage(const sockaddr_storage &saddr, SocketAddress *out);
}// namespace sled
#endif// SLED_NETWORK_SOCKET_ADDRESS_H

View File

@ -4,10 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_NETWORK_SOCKET_FACTORY_H
#define SLED_NETWORK_SOCKET_FACTORY_H
#pragma once
#include "sled/network/socket.h"

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma
#ifndef SLED_NETWORK_SOCKET_SERVER_H
#define SLED_NETWORK_SOCKET_SERVER_H
#pragma once
#include "sled/network/socket_factory.h"
#include "sled/units/time_delta.h"

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_NUMERICS_DIVIDE_ROUND_H
#define SLED_NUMERICS_DIVIDE_ROUND_H
#pragma once
#include <type_traits>

View File

@ -22,9 +22,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#ifndef FIXED_POINT_H_
#define FIXED_POINT_H_
#pragma once
#include <Eigen/Eigen>
#include <cmath>
#include <cstdint>
@ -186,8 +186,7 @@ template<int shift, typename T>
constexpr T
signed_rsh(T x)
{
return shifter<shift, (shift >= 0), (abs_helper(shift) >= sizeof(T) * 8),
T>::op(x);
return shifter<shift, (shift >= 0), (abs_helper(shift) >= sizeof(T) * 8), T>::op(x);
}
/*Signed right shift, run time version.*/
@ -195,9 +194,7 @@ template<typename T>
T
signed_rsh(T x, int shift)
{
return std::abs(shift) < sizeof(T) * 8
? (shift < 0 ? x << -shift : x >> shift)
: 0;
return std::abs(shift) < sizeof(T) * 8 ? (shift < 0 ? x << -shift : x >> shift) : 0;
}
/*Signed left shift, compile-time version*/
@ -213,9 +210,7 @@ template<typename T>
T
signed_lsh(T x, int shift)
{
return std::abs(shift) < sizeof(T) * 8
? (shift < 0 ? x >> -shift : x << shift)
: 0;
return std::abs(shift) < sizeof(T) * 8 ? (shift < 0 ? x >> -shift : x << shift) : 0;
}
/*Multiplies and simultaneously right-shifts the argument values,
@ -381,8 +376,7 @@ template<unsigned fb>
fp::q<f, I>
fp::q<f, I>::operator/(q<fb, I> b) const
{
static const I msb = (I) 1
<< (sizeof(I) * 8 - 1);//Most significant bit for the type
static const I msb = (I) 1 << (sizeof(I) * 8 - 1);//Most significant bit for the type
//Make b positive so that leading zeroes can be properly computed
I abs_b = b.i < 0 ? -b.i : b.i;
unsigned lz = fp_internal::clz(abs_b);//Amount of leading zeroes
@ -398,9 +392,7 @@ fp::q<f, I>::operator/(q<fb, I> b) const
}
q<f, I> t;
t.i = (I) fp_internal::mul_rsh(//adjust the radix point of (this*r)
r.i,
(typename std::make_unsigned<I>::type)(this->i < 0 ? -this->i
: this->i),
r.i, (typename std::make_unsigned<I>::type)(this->i < 0 ? -this->i : this->i),
sizeof(i) * 16 - fb - lz - (d == msb) - 1);
t.i = (b.i < 0) ^ (this->i < 0) ? -t.i : t.i;//set correct sign
return t;
@ -552,10 +544,8 @@ fp::q<f, I>::operator>=(q<fb, I> b) const
I mb = fp_internal::signed_rsh<fb>(b.i);
return (ma > mb)
|| ((ma == mb)
&& ((typename std::make_unsigned<I>::type)
fp_internal::signed_lsh<bits - f>(i)
>= (typename std::make_unsigned<I>::type)
fp_internal::signed_lsh<bits - fb>(b.i)));
&& ((typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - f>(i)
>= (typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - fb>(b.i)));
}
template<unsigned f, typename I>
@ -568,10 +558,8 @@ fp::q<f, I>::operator>(q<fb, I> b) const
I mb = fp_internal::signed_rsh<fb>(b.i);
return (ma > mb)
|| ((ma == mb)
&& ((typename std::make_unsigned<I>::type)
fp_internal::signed_lsh<bits - f>(i)
> (typename std::make_unsigned<I>::type)
fp_internal::signed_lsh<bits - fb>(b.i)));
&& ((typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - f>(i)
> (typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - fb>(b.i)));
}
template<unsigned f, typename I>
@ -584,10 +572,8 @@ fp::q<f, I>::operator<=(q<fb, I> b) const
I mb = fp_internal::signed_rsh<fb>(b.i);
return (ma < mb)
|| ((ma == mb)
&& ((typename std::make_unsigned<I>::type)
fp_internal::signed_lsh<bits - f>(i)
<= (typename std::make_unsigned<I>::type)
fp_internal::signed_lsh<bits - fb>(b.i)));
&& ((typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - f>(i)
<= (typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - fb>(b.i)));
}
template<unsigned f, typename I>
@ -600,10 +586,8 @@ fp::q<f, I>::operator<(q<fb, I> b) const
I mb = fp_internal::signed_rsh<fb>(b.i);
return (ma < mb)
|| ((ma == mb)
&& ((typename std::make_unsigned<I>::type)
fp_internal::signed_lsh<bits - f>(i)
< (typename std::make_unsigned<I>::type)
fp_internal::signed_lsh<bits - fb>(b.i)));
&& ((typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - f>(i)
< (typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - fb>(b.i)));
}
template<unsigned f, typename I>
@ -611,8 +595,7 @@ template<unsigned fb>
bool
fp::q<f, I>::operator==(q<fb, I> b) const
{
return fp_internal::signed_rsh<f - fb>(i) == b.i
&& fp_internal::signed_rsh<fb - f>(b.i) == i;
return fp_internal::signed_rsh<f - fb>(i) == b.i && fp_internal::signed_rsh<fb - f>(b.i) == i;
}
template<unsigned f, typename I>
@ -620,8 +603,7 @@ template<unsigned fb>
bool
fp::q<f, I>::operator!=(q<fb, I> b) const
{
return fp_internal::signed_rsh<f - fb>(i) != b.i
|| fp_internal::signed_rsh<fb - f>(b.i) != i;
return fp_internal::signed_rsh<f - fb>(i) != b.i || fp_internal::signed_rsh<fb - f>(b.i) != i;
}
template<unsigned f, typename I>

View File

@ -1,6 +1,6 @@
#pragma once
#ifndef SLED_PROFILING_PROFILING_H
#define SLED_PROFILING_PROFILING_H
#pragma once
#include "sled/system/location.h"
#include <fmt/format.h>

View File

@ -6,6 +6,7 @@
#ifndef SLED_QUEUE_CIRCLE_QUEUE_H
#define SLED_QUEUE_CIRCLE_QUEUE_H
#pragma once
#include "sled/log/log.h"
#include <array>
@ -49,10 +50,7 @@ public:
head_ = (head_ + 1) % (LEN + 1);
}
size_t size() const
{
return tail_ >= head_ ? tail_ - head_ : (LEN + 1) - (head_ - tail_);
}
size_t size() const { return tail_ >= head_ ? tail_ - head_ : (LEN + 1) - (head_ - tail_); }
bool empty() const { return (tail_ + 1) % (LEN + 1) == head_; }

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_SYNCHRONIZATION_EVENT_H
#define SLED_SYNCHRONIZATION_EVENT_H
#pragma once
#include "sled/synchronization/mutex.h"
#include "sled/units/time_delta.h"
@ -28,15 +28,13 @@ public:
bool Wait(TimeDelta give_up_after)
{
return Wait(give_up_after,
give_up_after.IsPlusInfinity() ? TimeDelta::Seconds(3)
: kForever);
return Wait(give_up_after, give_up_after.IsPlusInfinity() ? TimeDelta::Seconds(3) : kForever);
}
Mutex mutex_;
ConditionVariable cv_;
const bool is_manual_reset_;
bool event_status_ GUARDED_BY(mutex_);
bool event_status_ SLED_GUARDED_BY(mutex_);
};
}// namespace sled

View File

@ -4,17 +4,17 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_SYNCHRONIZATION_MUTEX_H
#define SLED_SYNCHRONIZATION_MUTEX_H
#pragma once
#include "marl/conditionvariable.h"
#include "sled/lang/attributes.h"
#include "sled/units/time_delta.h"
#include <chrono>
#include <condition_variable>
#include <marl/conditionvariable.h>
#include <marl/mutex.h>
#include <mutex>
// #include <condition_variable>
// #include <mutex>
#include <type_traits>
namespace sled {
@ -60,36 +60,52 @@ public:
RecursiveMutex(const RecursiveMutex &) = delete;
RecursiveMutex &operator=(const RecursiveMutex &) = delete;
inline void Lock() EXCLUSIVE_LOCK_FUNCTION() { impl_.lock(); }
inline void Lock() SLED_SHARED_LOCK_FUNCTION() { impl_.lock(); }
inline bool TryLock() { return impl_.try_lock(); }
inline bool TryLock() SLED_SHARED_TRYLOCK_FUNCTION(true) { return impl_.try_lock(); }
inline void AssertHeld() {}
inline void Unlock() UNLOCK_FUNCTION() { impl_.unlock(); }
inline void Unlock() SLED_UNLOCK_FUNCTION() { impl_.unlock(); }
private:
std::recursive_mutex impl_;
};
template<typename TLock, typename std::enable_if<internal::HasLockAndUnlock<TLock>::value, TLock>::type * = nullptr>
class LockGuard final {
class RecursiveMutexLock final {
public:
LockGuard(const LockGuard &) = delete;
LockGuard &operator=(const LockGuard &) = delete;
RecursiveMutexLock(const RecursiveMutexLock &) = delete;
RecursiveMutexLock &operator=(const RecursiveMutexLock &) = delete;
explicit LockGuard(TLock *lock) EXCLUSIVE_LOCK_FUNCTION() : mutex_(lock) { mutex_->Lock(); };
explicit RecursiveMutexLock(RecursiveMutex *mutex) SLED_EXCLUSIVE_LOCK_FUNCTION(mutex) : mutex_(mutex)
{
mutex->Lock();
}
~LockGuard() UNLOCK_FUNCTION() { mutex_->Unlock(); };
~RecursiveMutexLock() SLED_UNLOCK_FUNCTION() { mutex_->Unlock(); }
private:
TLock *mutex_;
friend class ConditionVariable;
RecursiveMutex *mutex_;
};
// public:
// LockGuard(const LockGuard &) = delete;
// LockGuard &operator=(const LockGuard &) = delete;
//
// explicit LockGuard(TLock *lock) SLED_EXCLUSIVE_LOCK_FUNCTION(lock) : mutex_(lock) { mutex_->Lock(); };
//
// ~LockGuard() SLED_UNLOCK_FUNCTION() { mutex_->Unlock(); };
//
// private:
// TLock *mutex_;
// friend class ConditionVariable;
// };
//
class MutexLock final {
public:
MutexLock(Mutex *mutex) : lock_(*mutex) {}
MutexLock(Mutex *mutex) SLED_EXCLUSIVE_LOCK_FUNCTION(mutex) : lock_(*mutex) {}
~MutexLock() SLED_UNLOCK_FUNCTION() = default;
MutexLock(const MutexLock &) = delete;
MutexLock &operator=(const MutexLock &) = delete;
@ -99,41 +115,6 @@ private:
marl::lock lock_;
};
using MutexGuard SLED_DEPRECATED() = MutexLock;
// using MutexGuard = marl::lock;
// using MutexLock = LockGuard<Mutex>;
// using MutexGuard = LockGuard<Mutex>;
using RecursiveMutexLock SLED_DEPRECATED() = LockGuard<RecursiveMutex>;
// class MutexLock final {
// public:
// MutexLock(const MutexLock &) = delete;
// MutexLock &operator=(const MutexLock &) = delete;
//
// explicit MutexLock(Mutex *mutex) : mutex_(mutex) { mutex->Lock(); }
//
// ~MutexLock() { mutex_->Unlock(); }
//
// private:
// Mutex *mutex_;
// };
//
// class RecursiveMutexLock final {
// public:
// RecursiveMutexLock(const RecursiveMutexLock &) = delete;
// RecursiveMutexLock &operator=(const RecursiveMutexLock &) = delete;
//
// explicit RecursiveMutexLock(RecursiveMutex *mutex) : mutex_(mutex)
// {
// mutex->Lock();
// }
//
// ~RecursiveMutexLock() { mutex_->Unlock(); }
//
// private:
// RecursiveMutex *mutex_;
// };
class ConditionVariable final {
public:
static constexpr TimeDelta kForever = TimeDelta::PlusInfinity();

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_SYNCHRONIZATION_ONE_TIME_EVENT_H
#define SLED_SYNCHRONIZATION_ONE_TIME_EVENT_H
#pragma once
#include "sled/synchronization/mutex.h"

View File

@ -0,0 +1,52 @@
/**
* @file : sequence_checker_internal
* @created : Saturday Feb 03, 2024 13:34:40 CST
* @license : MIT
**/
#ifndef SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
#define SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
#pragma once
#include "sled/log/log.h"
#include "sled/synchronization/mutex.h"
#include "sled/task_queue/task_queue_base.h"
namespace sled {
class SLED_LOCKABLE SequenceChecker {
public:
enum InitialState { kDetached = false, kAttached = true };
explicit SequenceChecker(InitialState initial_state = kAttached);
~SequenceChecker() = default;
bool IsCurrent() const;
void Detach();
// only use by macro RUN_ON
std::string ExpectationToString() const;
private:
mutable Mutex mutex_;
mutable bool attached_ GUARDED_BY(mutex_);
mutable pthread_t valid_thread_ GUARDED_BY(mutex_);
mutable const TaskQueueBase *valid_queue_ GUARDED_BY(mutex_);
};
class SequenceCheckerDoNothing {
public:
explicit SequenceCheckerDoNothing(bool attach_to_current_thread) {}
bool IsCurrent() const { return true; }
void Detach() {}
};
#define SLED_RUN_ON(x) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x))
#define SLED_DCHECK_RUN_ON(x) DCHECK((x)->IsCurrent(), (x)->ExpectationToString())
}// namespace sled
#endif// SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H

View File

@ -1,57 +0,0 @@
/**
* @file : sequence_checker_internal
* @created : Saturday Feb 03, 2024 13:34:40 CST
* @license : MIT
**/
#pragma once
#ifndef SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
#define SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
#include "sled/synchronization/mutex.h"
#include <string>
namespace sled {
class SequenceCheckerImpl {
public:
explicit SequenceCheckerImpl(bool attach_to_current_thread);
~SequenceCheckerImpl() = default;
bool IsCurrent() const;
void Detach();
std::string ExpectationToString() const;
private:
mutable Mutex lock_;
mutable bool attached_;
};
class SequenceCheckerDoNothing {
public:
explicit SequenceCheckerDoNothing(bool attach_to_current_thread) {}
bool IsCurrent() const { return true; }
void Detach() {}
};
template<typename ThreadLikeObject>
typename std::enable_if<std::is_base_of<SequenceCheckerImpl, ThreadLikeObject>::value,
std::string>::type
ExpectationToString(const ThreadLikeObject *checker)
{
return checker->ExpectationToString();
}
template<typename ThreadLikeObject>
typename std::enable_if<!std::is_base_of<SequenceCheckerImpl, ThreadLikeObject>::value,
std::string>::type
ExpectationToString(const ThreadLikeObject *checker)
{
return std::string();
}
}// namespace sled
#endif// SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H

View File

@ -4,9 +4,9 @@
* @license : MIT
**/
#pragma once
#ifndef SLED_SYNCHRONIZATION_THREAD_LOCAL_H
#define SLED_SYNCHRONIZATION_THREAD_LOCAL_H
#pragma once
#include <cstddef>
#include <thread>
#include <type_traits>
@ -47,46 +47,35 @@ public:
}
template<typename PointerT = T>
typename std::enable_if<std::is_pointer<PointerT>::value, PointerT>::type
Get() const
typename std::enable_if<std::is_pointer<PointerT>::value, PointerT>::type Get() const
{
auto ptr = detail::ThreadLocalManager::Instance().Get(
detail::ThreadLocalManager::CurrentThreadId(), key_);
auto ptr = detail::ThreadLocalManager::Instance().Get(detail::ThreadLocalManager::CurrentThreadId(), key_);
return static_cast<PointerT>(ptr);
}
template<typename IntT = T>
typename std::enable_if<std::is_integral<IntT>::value, IntT>::type
Get() const
typename std::enable_if<std::is_integral<IntT>::value, IntT>::type Get() const
{
static_assert(sizeof(IntT) <= sizeof(void *), "");
auto ptr = detail::ThreadLocalManager::Instance().Get(
detail::ThreadLocalManager::CurrentThreadId(), key_);
return static_cast<IntT>(static_cast<char *>(ptr)
- static_cast<char *>(0));
auto ptr = detail::ThreadLocalManager::Instance().Get(detail::ThreadLocalManager::CurrentThreadId(), key_);
return static_cast<IntT>(static_cast<char *>(ptr) - static_cast<char *>(0));
}
template<typename PointerT = T,
typename std::enable_if<
std::is_pointer<PointerT>::value
|| std::is_same<std::nullptr_t, PointerT>::value,
PointerT>::type = nullptr>
typename std::enable_if<std::is_pointer<PointerT>::value || std::is_same<std::nullptr_t, PointerT>::value,
PointerT>::type = nullptr>
void Set(PointerT value)
{
detail::ThreadLocalManager::Instance().Set(
detail::ThreadLocalManager::CurrentThreadId(), key_,
static_cast<void *>(value));
detail::ThreadLocalManager::Instance().Set(detail::ThreadLocalManager::CurrentThreadId(), key_,
static_cast<void *>(value));
}
template<typename IntT = T,
typename std::enable_if<std::is_integral<IntT>::value, IntT>::type
* = nullptr>
template<typename IntT = T, typename std::enable_if<std::is_integral<IntT>::value, IntT>::type * = nullptr>
void Set(IntT value)
{
static_assert(sizeof(IntT) <= sizeof(void *), "");
detail::ThreadLocalManager::Instance().Set(
detail::ThreadLocalManager::CurrentThreadId(), key_,
(char *) 0 + value);
detail::ThreadLocalManager::Instance().Set(detail::ThreadLocalManager::CurrentThreadId(), key_,
(char *) 0 + value);
}
private:

View File

@ -1,5 +1,4 @@
#include "sled/network/async_resolver.h"
#include "sled/network/async_resolver_interface.h"
#include "sled/ref_counted_base.h"
#include "sled/synchronization/mutex.h"
#include "sled/task_queue/task_queue_base.h"
@ -15,9 +14,7 @@ struct AsyncResolver::State : public RefCountedBase {
};
int
ResolveHostname(const std::string &hostname,
int family,
std::vector<IPAddress> *addresses)
ResolveHostname(const std::string &hostname, int family, std::vector<IPAddress> *addresses)
{
if (!addresses) { return -1; }

View File

@ -85,10 +85,7 @@ private:
bool &flag_to_clear_;
};
PhysicalSocketServer::PhysicalSocketServer() : fWait_(false)
{
signal_wakeup_ = new Signaler(this, fWait_);
}
PhysicalSocketServer::PhysicalSocketServer() : fWait_(false) { signal_wakeup_ = new Signaler(this, fWait_); }
PhysicalSocketServer::~PhysicalSocketServer() { delete signal_wakeup_; }
@ -158,9 +155,7 @@ PhysicalSocketServer::Update(Dispatcher *pdispatcher)
int
PhysicalSocketServer::ToCusWait(TimeDelta max_wait_duration)
{
return max_wait_duration == Event::kForever
? kForeverMs
: max_wait_duration.RoundUpTo(TimeDelta::Micros(1)).us();
return max_wait_duration == Event::kForever ? kForeverMs : max_wait_duration.RoundUpTo(TimeDelta::Micros(1)).us();
}
bool
@ -174,17 +169,12 @@ PhysicalSocketServer::Wait(TimeDelta max_wait_duration, bool process_io)
}
static void
ProcessEvents(Dispatcher *pdispatcher,
bool readable,
bool writable,
bool error_event,
bool check_error)
ProcessEvents(Dispatcher *pdispatcher, bool readable, bool writable, bool error_event, bool check_error)
{
int errcode = 0;
if (check_error) {
socklen_t len = sizeof(errcode);
int res = ::getsockopt(pdispatcher->GetDescriptor(), SOL_SOCKET,
SO_ERROR, &errcode, &len);
int res = ::getsockopt(pdispatcher->GetDescriptor(), SOL_SOCKET, SO_ERROR, &errcode, &len);
if (res < 0) {
if (error_event || errno != ENOTSOCK) { errcode = EBADF; }
}
@ -243,9 +233,7 @@ PhysicalSocketServer::WaitSelect(int64_t cusWait, bool process_io)
for (auto const &kv : dispatcher_by_key_) {
uint64_t key = kv.first;
Dispatcher *pdispatcher = kv.second;
if (!process_io && (pdispatcher != signal_wakeup_)) {
continue;
}
if (!process_io && (pdispatcher != signal_wakeup_)) { continue; }
current_dispatcher_keys_.push_back(key);
int fd = pdispatcher->GetDescriptor();
if (fd > fdmax) { fdmax = fd; }
@ -278,8 +266,7 @@ PhysicalSocketServer::WaitSelect(int64_t cusWait, bool process_io)
bool writable = FD_ISSET(fd, &fdsWrite);
if (writable) { FD_CLR(fd, &fdsWrite); }
ProcessEvents(pdispatcher, readable, writable, false,
readable || writable);
ProcessEvents(pdispatcher, readable, writable, false, readable || writable);
}
}
@ -309,8 +296,7 @@ PhysicalSocket::PhysicalSocket(PhysicalSocketServer *ss, SOCKET s)
SetEnabledEvents(DE_READ | DE_WRITE);
int type = SOCK_STREAM;
socklen_t len = sizeof(type);
const int res =
getsockopt(s_, SOL_SOCKET, SO_TYPE, (void *) &type, &len);
const int res = getsockopt(s_, SOL_SOCKET, SO_TYPE, (void *) &type, &len);
udp_ = (SOCK_DGRAM == type);
}
}
@ -399,8 +385,7 @@ void
PhysicalSocket::SetError(int error)
{
// MutexLock lock(&mutex_);
MutexGuard lock(&mutex_);
MutexLock lock(&mutex_);
error_ = error;
}
@ -431,31 +416,24 @@ PhysicalSocket::SetOption(Option opt, int value)
int
PhysicalSocket::Send(const void *pv, size_t cb)
{
int sent = DoSend(s_, reinterpret_cast<const char *>(pv),
static_cast<int>(cb), MSG_NOSIGNAL);
int sent = DoSend(s_, reinterpret_cast<const char *>(pv), static_cast<int>(cb), MSG_NOSIGNAL);
UpdateLastError();
if ((sent > 0 && sent < static_cast<int>(cb))
|| (sent < 0 && IsBlockingError(GetError()))) {
if ((sent > 0 && sent < static_cast<int>(cb)) || (sent < 0 && IsBlockingError(GetError()))) {
EnableEvents(DE_WRITE);
}
return sent;
}
int
PhysicalSocket::SendTo(const void *buffer,
size_t length,
const SocketAddress &addr)
PhysicalSocket::SendTo(const void *buffer, size_t length, const SocketAddress &addr)
{
sockaddr_storage saddr;
size_t len = addr.ToSockAddrStorage(&saddr);
int sent =
DoSendTo(s_, static_cast<const char *>(buffer),
static_cast<int>(length), MSG_NOSIGNAL,
reinterpret_cast<sockaddr *>(&saddr), static_cast<int>(len));
int sent = DoSendTo(s_, static_cast<const char *>(buffer), static_cast<int>(length), MSG_NOSIGNAL,
reinterpret_cast<sockaddr *>(&saddr), static_cast<int>(len));
UpdateLastError();
if ((sent > 0 && sent < static_cast<int>(length))
|| (sent < 0 && IsBlockingError(GetError()))) {
if ((sent > 0 && sent < static_cast<int>(length)) || (sent < 0 && IsBlockingError(GetError()))) {
EnableEvents(DE_WRITE);
}
return sent;
@ -483,10 +461,7 @@ PhysicalSocket::Recv(void *buffer, size_t length, int64_t *timestamp)
}
int
PhysicalSocket::RecvFrom(void *buffer,
size_t length,
SocketAddress *out_addr,
int64_t *timestamp)
PhysicalSocket::RecvFrom(void *buffer, size_t length, SocketAddress *out_addr, int64_t *timestamp)
{
int received = DoReadFromSocket(buffer, length, out_addr, timestamp);
UpdateLastError();
@ -516,17 +491,12 @@ GetSocketRecvTimestamp(int socket)
if (ret != 0) { return -1; }
int64_t timestamp =
static_cast<int64_t>(tv_ioctl.tv_sec) * kNumMicrosecsPerSec
+ tv_ioctl.tv_usec;
int64_t timestamp = static_cast<int64_t>(tv_ioctl.tv_sec) * kNumMicrosecsPerSec + tv_ioctl.tv_usec;
return timestamp;
}
int
PhysicalSocket::DoReadFromSocket(void *buffer,
size_t length,
SocketAddress *out_addr,
int64_t *timestamp)
PhysicalSocket::DoReadFromSocket(void *buffer, size_t length, SocketAddress *out_addr, int64_t *timestamp)
{
sockaddr_storage addr_storage;
socklen_t addr_len = sizeof(addr_storage);
@ -534,12 +504,10 @@ PhysicalSocket::DoReadFromSocket(void *buffer,
int received = 0;
if (out_addr) {
received = ::recvfrom(s_, static_cast<char *>(buffer),
static_cast<int>(length), 0, addr, &addr_len);
received = ::recvfrom(s_, static_cast<char *>(buffer), static_cast<int>(length), 0, addr, &addr_len);
SocketAddressFromSockAddrStorage(addr_storage, out_addr);
} else {
received = ::recv(s_, static_cast<char *>(buffer),
static_cast<int>(length), 0);
received = ::recv(s_, static_cast<char *>(buffer), static_cast<int>(length), 0);
}
if (timestamp) { *timestamp = GetSocketRecvTimestamp(s_); }
@ -592,10 +560,7 @@ PhysicalSocket::Close()
}
SOCKET
PhysicalSocket::DoAccept(SOCKET socket, sockaddr *addr, socklen_t *addrlen)
{
return ::accept(socket, addr, addrlen);
}
PhysicalSocket::DoAccept(SOCKET socket, sockaddr *addr, socklen_t *addrlen) { return ::accept(socket, addr, addrlen); }
int
PhysicalSocket::DoSend(SOCKET socket, const char *buf, int len, int flags)
@ -617,9 +582,7 @@ PhysicalSocket::DoSendTo(SOCKET socket,
int
PhysicalSocket::DoConnect(const SocketAddress &connect_addr)
{
if ((s_ == INVALID_SOCKET) && !Create(connect_addr.family(), SOCK_STREAM)) {
return SOCKET_ERROR;
}
if ((s_ == INVALID_SOCKET) && !Create(connect_addr.family(), SOCK_STREAM)) { return SOCKET_ERROR; }
sockaddr_storage addr_storage;
size_t len = connect_addr.ToSockAddrStorage(&addr_storage);
@ -702,13 +665,9 @@ PhysicalSocket::TranslateOption(Option opt, int *slevel, int *sopt)
return 0;
}
SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss)
: PhysicalSocket(ss)
{}
SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss) : PhysicalSocket(ss) {}
SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss)
: PhysicalSocket(ss, s)
{}
SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss) : PhysicalSocket(ss, s) {}
SocketDispatcher::~SocketDispatcher() { Close(); }

View File

@ -0,0 +1,56 @@
#include "sled/synchronization/sequence_checker.h"
namespace sled {
SequenceChecker::SequenceChecker(InitialState initial_state)
: attached_(initial_state),
valid_thread_(pthread_self()),
valid_queue_(TaskQueueBase::Current())
{}
bool
SequenceChecker::IsCurrent() const
{
const TaskQueueBase *const current_queue = TaskQueueBase::Current();
const pthread_t current_thread = pthread_self();
MutexLock lock(&mutex_);
if (!attached_) {
attached_ = true;
valid_thread_ = current_thread;
valid_queue_ = current_queue;
return true;
}
if (valid_queue_) { return valid_queue_ == current_queue; }
return pthread_equal(valid_thread_, current_thread);
}
void
SequenceChecker::Detach()
{
MutexLock lock(&mutex_);
attached_ = false;
}
std::string
SequenceChecker::ExpectationToString() const
{
const TaskQueueBase *const current_queue = TaskQueueBase::Current();
const pthread_t current_thread = pthread_self();
MutexLock lock(&mutex_);
if (!attached_) { return "Checker currently not attached."; }
std::stringstream ss;
ss << "# Expected: TQ: " << valid_queue_ << " Thread: " << reinterpret_cast<const void *>(valid_thread_)
<< std::endl;
ss << "# Current: TQ: " << current_queue << " Thread: " << reinterpret_cast<const void *>(current_thread)
<< std::endl;
if ((valid_queue_ || current_queue) && valid_queue_ != current_queue) {
ss << "# Mismatched TaskQueue" << std::endl;
} else if (valid_thread_ != current_thread) {
ss << "# Mismatched Thread" << std::endl;
}
return ss.str();
}
}// namespace sled

View File

@ -1,13 +0,0 @@
#include "sled/synchronization/sequence_checker_internal.h"
namespace sled {
SequenceCheckerImpl::SequenceCheckerImpl(bool attach_to_current_thread)
: attached_(attach_to_current_thread)
{}
bool
SequenceCheckerImpl::IsCurrent() const
{
return false;
}
}// namespace sled

View File

@ -0,0 +1,68 @@
#include <gtest/gtest.h>
#include <sled/log/log.h>
#include <sled/synchronization/event.h>
#include <sled/synchronization/sequence_checker.h>
#include <sled/system/thread.h>
void
RunOnDifferentThread(std::function<void()> func)
{
sled::Event thread_has_run_event;
std::thread thread([&] {
func();
thread_has_run_event.Set();
});
thread.detach();
EXPECT_TRUE(thread_has_run_event.Wait(sled::TimeDelta::Seconds(1)));
}
TEST(SequenceChecker, CallsAllowedOnSameThread)
{
sled::SequenceChecker sequence_checker;
EXPECT_TRUE(sequence_checker.IsCurrent());
}
TEST(SequenceChecker, DestructorAllowedOnDifferentThread)
{
auto sequence_checker = std::make_unique<sled::SequenceChecker>();
RunOnDifferentThread([&] { sequence_checker.reset(); });
}
TEST(SequenceChecker, Detach)
{
sled::SequenceChecker sequence_checker;
sequence_checker.Detach();
RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
}
TEST(SequenceChecker, OnlyCurrentOnOneThread)
{
sled::SequenceChecker sequence_checker(sled::SequenceChecker::kDetached);
RunOnDifferentThread([&] {
EXPECT_TRUE(sequence_checker.IsCurrent());
RunOnDifferentThread([&] { EXPECT_FALSE(sequence_checker.IsCurrent()); });
EXPECT_TRUE(sequence_checker.IsCurrent());
});
}
TEST(SequenceChecker, DeatchFromThreadAndUseOnTaskQueue)
{
auto queue = sled::Thread::Create();
ASSERT_TRUE(queue->Start());
sled::SequenceChecker sequence_checker;
sequence_checker.Detach();
queue->BlockingCall([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
}
TEST(SequenceChecker, DetachFromTaskQueueAndUseOnThread)
{
auto queue = sled::Thread::Create();
ASSERT_TRUE(queue->Start());
queue->BlockingCall([&] {
sled::SequenceChecker sequence_checker;
sequence_checker.Detach();
RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
});
queue->Stop();
}