feat update tsa
This commit is contained in:
parent
a81eb0f8de
commit
03a62901f2
@ -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
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#ifndef SLED_FILESYSTEM_PATH_H
|
||||
#define SLED_FILESYSTEM_PATH_H
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#ifndef SLED_FILESYSTEM_TEMPORARY_FILE_H
|
||||
#define SLED_FILESYSTEM_TEMPORARY_FILE_H
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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__)
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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_; }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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"
|
||||
|
||||
|
52
include/sled/synchronization/sequence_checker.h
Normal file
52
include/sled/synchronization/sequence_checker.h
Normal 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
|
@ -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
|
@ -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,45 +47,34 @@ 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,
|
||||
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_,
|
||||
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_,
|
||||
detail::ThreadLocalManager::Instance().Set(detail::ThreadLocalManager::CurrentThreadId(), key_,
|
||||
(char *) 0 + value);
|
||||
}
|
||||
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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,
|
||||
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(); }
|
||||
|
||||
|
56
src/synchronization/sequence_checker.cc
Normal file
56
src/synchronization/sequence_checker.cc
Normal 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
|
@ -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
|
68
src/synchronization/sequence_checker_test.cc
Normal file
68
src/synchronization/sequence_checker_test.cc
Normal 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();
|
||||
}
|
Loading…
Reference in New Issue
Block a user