diff --git a/src/Definitions.h b/src/Definitions.h index 8921f34..a7590c2 100644 --- a/src/Definitions.h +++ b/src/Definitions.h @@ -100,13 +100,11 @@ namespace ts { UNKNOWN = 0xFF }; - enum ConnectionState { + enum ClientState { UNKNWON, - INIT_LOW, //Web -> WS Handschake - INIT_HIGH, //Web -> Auth + + INITIALIZING, CONNECTED, - DISCONNECTING, - DISCONNECTING_FLUSHING, DISCONNECTED }; } @@ -164,7 +162,7 @@ namespace ts { DEFINE_CONVERTER_ENUM(a, b); \ DEFINE_VARIABLE_TRANSFORM_ENUM(a, b); -DEFINE_TRANSFORMS(ts::server::ConnectionState, uint8_t); +DEFINE_TRANSFORMS(ts::server::ClientState, uint8_t); DEFINE_TRANSFORMS(ts::server::ClientType, uint8_t); DEFINE_TRANSFORMS(ts::LicenseType, uint8_t); DEFINE_TRANSFORMS(ts::PluginTargetMode, uint8_t); diff --git a/src/lock/rw_mutex.h b/src/lock/rw_mutex.h index 1eed292..01eda7f 100644 --- a/src/lock/rw_mutex.h +++ b/src/lock/rw_mutex.h @@ -27,171 +27,174 @@ namespace ts { constexpr static auto write_preferred{write_preferred_}; }; - struct mutex_action_validator { - public: - inline void try_exclusive_lock_acquire(); - inline void try_shared_lock_acquire(); - inline void exclusive_lock_acquire(); - inline void shared_lock_acquire(); + namespace impl { + struct mutex_action_validator { + public: + inline void try_exclusive_lock_acquire(); + inline void try_shared_lock_acquire(); + + inline void exclusive_lock_acquire(); + inline void shared_lock_acquire(); - inline void try_exclusive_lock_release(); - inline void try_shared_lock_release(); + inline void try_exclusive_lock_release(); + inline void try_shared_lock_release(); - inline void exclusive_lock_release(); - inline void shared_lock_release(); + inline void exclusive_lock_release(); + inline void shared_lock_release(); - inline void try_shared_lock_upgrade(); - inline void try_exclusive_lock_downgrade(); + inline void try_shared_lock_upgrade(); + inline void try_exclusive_lock_downgrade(); - inline void shared_lock_upgrade(); - inline void exclusive_lock_downgrade(); + inline void shared_lock_upgrade(); + inline void exclusive_lock_downgrade(); - private: - std::thread::id exclusive_lock{}; - bool exclusive_lock_upgraded{false}; - std::vector shared_lockers{}; - }; + private: + std::thread::id exclusive_lock{}; + bool exclusive_lock_upgraded{false}; + std::vector shared_lockers{}; + }; - struct dummy_action_validator { - inline void try_exclusive_lock_acquire() {} - inline void try_shared_lock_acquire() {} + struct dummy_action_validator { + inline void try_exclusive_lock_acquire() {} + inline void try_shared_lock_acquire() {} - inline void exclusive_lock_acquire() {} - inline void shared_lock_acquire() {} + inline void exclusive_lock_acquire() {} + inline void shared_lock_acquire() {} - inline void try_exclusive_lock_release() {} - inline void try_shared_lock_release() {} + inline void try_exclusive_lock_release() {} + inline void try_shared_lock_release() {} - inline void exclusive_lock_release() {} - inline void shared_lock_release() {} + inline void exclusive_lock_release() {} + inline void shared_lock_release() {} - inline void try_shared_lock_upgrade() {} - inline void try_exclusive_lock_downgrade() {} + inline void try_shared_lock_upgrade() {} + inline void try_exclusive_lock_downgrade() {} - inline void shared_lock_upgrade() {} - inline void exclusive_lock_downgrade() {} - }; + inline void shared_lock_upgrade() {} + inline void exclusive_lock_downgrade() {} + }; - template - class rw_mutex_impl { - public: - rw_mutex_impl() = default; - ~rw_mutex_impl(); + template + class rw_mutex_impl { + public: + rw_mutex_impl() = default; + ~rw_mutex_impl(); - template - rw_mutex_impl(const rw_mutex_impl&) = delete; + template + rw_mutex_impl(const rw_mutex_impl&) = delete; - template - rw_mutex_impl&operator=(const rw_mutex_impl&) = delete; + template + rw_mutex_impl&operator=(const rw_mutex_impl&) = delete; - /** - * Acquire the write lock - */ - inline void lock(); + /** + * Acquire the write lock + */ + inline void lock(); - /** - * Acquire the write lock with a timeout - */ - [[nodiscard]] inline std::cv_status lock_until(const std::chrono::system_clock::time_point& timeout); + /** + * Acquire the write lock with a timeout + */ + [[nodiscard]] inline std::cv_status lock_until(const std::chrono::system_clock::time_point& timeout); - /** - * Acquire the write lock with a timeout - */ - template - [[nodiscard]] inline std::cv_status lock_for(const duration_t& duration) { - auto now = std::chrono::system_clock::now(); - now += duration; - return this->lock_until(now); - } + /** + * Acquire the write lock with a timeout + */ + template + [[nodiscard]] inline std::cv_status lock_for(const duration_t& duration) { + auto now = std::chrono::system_clock::now(); + now += duration; + return this->lock_until(now); + } - /** - * Acquire the read lock - */ - inline void lock_shared(); + /** + * Acquire the read lock + */ + inline void lock_shared(); - /** - * Acquire the read lock with a timeout - */ - [[nodiscard]] inline std::cv_status lock_shared_until(const std::chrono::system_clock::time_point& timeout); + /** + * Acquire the read lock with a timeout + */ + [[nodiscard]] inline std::cv_status lock_shared_until(const std::chrono::system_clock::time_point& timeout); - /** - * Acquire the read lock with a timeout - */ - template - [[nodiscard]] inline std::cv_status lock_shared_for(const duration_t& duration) { - auto now = std::chrono::system_clock::now(); - now += duration; - return this->lock_shared_until(now); - } + /** + * Acquire the read lock with a timeout + */ + template + [[nodiscard]] inline std::cv_status lock_shared_for(const duration_t& duration) { + auto now = std::chrono::system_clock::now(); + now += duration; + return this->lock_shared_until(now); + } - /** - * Release the write lock - */ - inline void unlock(); + /** + * Release the write lock + */ + inline void unlock(); - /** - * Release the read lock - */ - inline void unlock_shared(); + /** + * Release the read lock + */ + inline void unlock_shared(); - /** - * Upgrade from a shared lock to an exclusive lock. - * Could fail due to the following reasons: - * would_deadlock: Another thread already tried to upgrade the lock and we're not supposed to release the shared lock - * resource_error: Another thread already claimed the write lock while we're waiting - * - * Note: This will cause a deadlock if the lock has been locked shared twice - */ - [[nodiscard]] inline rw_action_result upgrade_lock(); + /** + * Upgrade from a shared lock to an exclusive lock. + * Could fail due to the following reasons: + * would_deadlock: Another thread already tried to upgrade the lock and we're not supposed to release the shared lock + * resource_error: Another thread already claimed the write lock while we're waiting + * + * Note: This will cause a deadlock if the lock has been locked shared twice + */ + [[nodiscard]] inline rw_action_result upgrade_lock(); - /** - * Upgrade from a shared lock to an exclusive lock. - * Could fail due to the following reasons: - * would_deadlock: Another thread already tried to upgrade the lock and we're not supposed to release the shared lock - * resource_error: Another thread already claimed the write lock while we're waiting - * timeout: If the action could not be performed within the given time frame - * Note: This will cause a deadlock if the lock has been locked shared twice - */ - [[nodiscard]] inline rw_action_result upgrade_lock_until(const std::chrono::system_clock::time_point& timeout); + /** + * Upgrade from a shared lock to an exclusive lock. + * Could fail due to the following reasons: + * would_deadlock: Another thread already tried to upgrade the lock and we're not supposed to release the shared lock + * resource_error: Another thread already claimed the write lock while we're waiting + * timeout: If the action could not be performed within the given time frame + * Note: This will cause a deadlock if the lock has been locked shared twice + */ + [[nodiscard]] inline rw_action_result upgrade_lock_until(const std::chrono::system_clock::time_point& timeout); - /** - * Upgrade from a shared lock to an exclusive lock with an timeout. - * For return codes see upgrade_lock_until. - */ - template - [[nodiscard]] inline rw_action_result upgrade_lock_for(const duration_t& duration) { - auto now = std::chrono::system_clock::now(); - now += duration; - return this->upgrade_lock_until(now); - } + /** + * Upgrade from a shared lock to an exclusive lock with an timeout. + * For return codes see upgrade_lock_until. + */ + template + [[nodiscard]] inline rw_action_result upgrade_lock_for(const duration_t& duration) { + auto now = std::chrono::system_clock::now(); + now += duration; + return this->upgrade_lock_until(now); + } - /** - * Downgrade from an exclusive lock to a shared lock. - * No other thread could lock the lock exclusive until unlock_shared() has been called. - */ - inline void downgrade_lock(); - private: - action_validator_t action_validator_{}; + /** + * Downgrade from an exclusive lock to a shared lock. + * No other thread could lock the lock exclusive until unlock_shared() has been called. + */ + inline void downgrade_lock(); + private: + action_validator_t action_validator_{}; - std::mutex status_lock_{}; - std::condition_variable upgrade_update_{}; - std::condition_variable write_update_{}; - std::condition_variable read_update_{}; + std::mutex status_lock_{}; + std::condition_variable upgrade_update_{}; + std::condition_variable write_update_{}; + std::condition_variable read_update_{}; - bool write_locked{false}; - bool upgrade_pending{false}, write_lock_upgraded{false}; - uint32_t write_lock_pending{0}; - uint32_t read_lock_pending{0}; - uint32_t read_lock_count{0}; - }; + bool write_locked{false}; + bool upgrade_pending{false}, write_lock_upgraded{false}; + uint32_t write_lock_pending{0}; + uint32_t read_lock_pending{0}; + uint32_t read_lock_count{0}; + }; + } - typedef rw_mutex_impl, mutex_action_validator> rw_safe_mutex; - typedef rw_mutex_impl, mutex_action_validator> rw_unsafe_mutex; + typedef impl::rw_mutex_impl, impl::mutex_action_validator> rw_safe_mutex; + typedef impl::rw_mutex_impl, impl::mutex_action_validator> rw_unsafe_mutex; typedef rw_safe_mutex rw_mutex; struct rw_lock_defered_t {}; @@ -205,32 +208,37 @@ namespace ts { template struct rwshared_lock { public: + explicit rwshared_lock() { + this->lock_type_ = unlocked; + this->lock_ = nullptr; + } explicit rwshared_lock(lock_t& lock) : rwshared_lock{lock, rw_lock_shared} {} - explicit rwshared_lock(lock_t& lock, const rw_lock_defered_t&) : lock_{lock} { + explicit rwshared_lock(lock_t& lock, const rw_lock_defered_t&) : lock_{&lock} { this->lock_type_ = unlocked; } - explicit rwshared_lock(lock_t& lock, const rw_lock_shared_t&) : lock_{lock} { - this->lock_.lock_shared(); + explicit rwshared_lock(lock_t& lock, const rw_lock_shared_t&) : lock_{&lock} { + this->lock_->lock_shared(); this->lock_type_ = locked_shared; } - explicit rwshared_lock(lock_t& lock, const rw_lock_exclusive_t&) : lock_{lock} { - this->lock_.lock(); + explicit rwshared_lock(lock_t& lock, const rw_lock_exclusive_t&) : lock_{&lock} { + this->lock_->lock(); this->lock_type_ = locked_exclusive; } ~rwshared_lock() { if(this->lock_type_ == locked_shared) { - this->lock_.unlock_shared(); + this->lock_->unlock_shared(); } else if(this->lock_type_ == locked_exclusive) { - this->lock_.unlock(); + this->lock_->unlock(); } } rwshared_lock(const rwshared_lock&) = delete; rwshared_lock&operator=(const rwshared_lock&) = delete; + rwshared_lock&operator=(rwshared_lock&&) noexcept = default; /* state testers */ [[nodiscard]] inline bool exclusive_locked() const { @@ -244,13 +252,13 @@ namespace ts { /* basic lock functions */ inline void lock_shared() { rw_mutex_assert(this->lock_type_ == unlocked); - this->lock_.lock_shared(); + this->lock_->lock_shared(); this->lock_type_ = locked_shared; } [[nodiscard]] inline std::cv_status lock_shared_until(const std::chrono::system_clock::time_point& timeout) { rw_mutex_assert(this->lock_type_ == unlocked); - if(auto error = this->lock_.lock_shared_until(timeout); error == std::cv_status::timeout) + if(auto error = this->lock_->lock_shared_until(timeout); error == std::cv_status::timeout) return error; this->lock_type_ = locked_shared; return std::cv_status::no_timeout; @@ -258,19 +266,19 @@ namespace ts { inline void unlock_shared() { rw_mutex_assert(this->lock_type_ == locked_shared); - this->lock_.unlock_shared(); + this->lock_->unlock_shared(); this->lock_type_ = unlocked; } inline void lock_exclusive() { rw_mutex_assert(this->lock_type_ == unlocked); - this->lock_.lock(); + this->lock_->lock(); this->lock_type_ = locked_exclusive; } [[nodiscard]] inline std::cv_status lock_exclusive_until(const std::chrono::system_clock::time_point& timeout) { rw_mutex_assert(this->lock_type_ == unlocked); - if(auto error = this->lock_.lock_until(timeout); error == std::cv_status::timeout) + if(auto error = this->lock_->lock_until(timeout); error == std::cv_status::timeout) return error; this->lock_type_ = locked_exclusive; return std::cv_status::no_timeout; @@ -278,14 +286,14 @@ namespace ts { inline void unlock_exclusive() { rw_mutex_assert(this->lock_type_ == locked_exclusive); - this->lock_.unlock(); + this->lock_->unlock(); this->lock_type_ = unlocked; } /* upgrade/downgrade functions */ [[nodiscard]] inline rw_action_result upgrade_lock() { rw_mutex_assert(this->lock_type_ == locked_shared); - auto err = this->lock_.upgrade_lock(); + auto err = this->lock_->upgrade_lock(); if(err != rw_action_result::success) return err; this->lock_type_ = locked_exclusive; @@ -294,7 +302,7 @@ namespace ts { [[nodiscard]] inline rw_action_result upgrade_lock_until(const std::chrono::system_clock::time_point& timeout) { rw_mutex_assert(this->lock_type_ == locked_shared); - auto err = this->lock_.upgrade_lock_until(timeout); + auto err = this->lock_->upgrade_lock_until(timeout); if(err != rw_action_result::success) return err; this->lock_type_ = locked_exclusive; @@ -303,7 +311,7 @@ namespace ts { inline void downgrade_lock() { rw_mutex_assert(this->lock_type_ == locked_exclusive); - this->lock_.downgrade_lock(); + this->lock_->downgrade_lock(); this->lock_type_ = locked_shared; } @@ -345,6 +353,8 @@ namespace ts { else if(this->lock_type_ == locked_exclusive) this->unlock_exclusive(); } + + [[nodiscard]] inline auto mutex() { return this->lock_; } private: enum { unlocked, @@ -352,7 +362,7 @@ namespace ts { locked_exclusive } lock_type_; - lock_t& lock_; + lock_t* lock_; }; } @@ -366,9 +376,9 @@ namespace ts { template #ifndef DEBUG_RW_MUTEX - rw_mutex_impl::~rw_mutex_impl() = default; + impl::rw_mutex_impl::~rw_mutex_impl() = default; #else - rw_mutex_impl::~rw_mutex_impl() { + impl::rw_mutex_impl::~rw_mutex_impl() { rw_mutex_assert(!this->write_locked); rw_mutex_assert(!this->upgrade_pending); rw_mutex_assert(this->write_lock_pending == 0); @@ -378,7 +388,7 @@ namespace ts { #endif template - void rw_mutex_impl::lock() { + void impl::rw_mutex_impl::lock() { std::unique_lock slock{this->status_lock_}; this->action_validator_.try_exclusive_lock_acquire(); @@ -404,7 +414,7 @@ namespace ts { } template - std::cv_status rw_mutex_impl::lock_until(const std::chrono::system_clock::time_point& timeout) { + std::cv_status impl::rw_mutex_impl::lock_until(const std::chrono::system_clock::time_point& timeout) { std::unique_lock slock{this->status_lock_}; this->action_validator_.try_exclusive_lock_acquire(); this->write_lock_pending++; @@ -437,7 +447,7 @@ namespace ts { } template - void rw_mutex_impl::lock_shared() { + void impl::rw_mutex_impl::lock_shared() { std::unique_lock slock{this->status_lock_}; this->action_validator_.try_shared_lock_acquire(); this->read_lock_pending++; @@ -450,7 +460,7 @@ namespace ts { } template - std::cv_status rw_mutex_impl::lock_shared_until(const std::chrono::system_clock::time_point& timeout) { + std::cv_status impl::rw_mutex_impl::lock_shared_until(const std::chrono::system_clock::time_point& timeout) { std::unique_lock slock{this->status_lock_}; this->action_validator_.try_shared_lock_acquire(); this->read_lock_pending++; @@ -467,7 +477,7 @@ namespace ts { } template - void rw_mutex_impl::unlock() { + void impl::rw_mutex_impl::unlock() { std::lock_guard slock{this->status_lock_}; this->action_validator_.try_exclusive_lock_release(); rw_mutex_assert(this->write_locked); @@ -496,7 +506,7 @@ namespace ts { } template - void rw_mutex_impl::unlock_shared() { + void impl::rw_mutex_impl::unlock_shared() { std::lock_guard slock{this->status_lock_}; this->action_validator_.try_shared_lock_release(); rw_mutex_assert(!this->write_locked); @@ -520,7 +530,7 @@ namespace ts { } template - rw_action_result rw_mutex_impl::upgrade_lock() { + rw_action_result impl::rw_mutex_impl::upgrade_lock() { std::unique_lock slock{this->status_lock_}; this->action_validator_.try_shared_lock_upgrade(); rw_mutex_assert(!this->write_locked); @@ -549,7 +559,7 @@ namespace ts { } template - rw_action_result rw_mutex_impl::upgrade_lock_until(const std::chrono::system_clock::time_point& timeout) { + rw_action_result impl::rw_mutex_impl::upgrade_lock_until(const std::chrono::system_clock::time_point& timeout) { std::unique_lock slock{this->status_lock_}; this->action_validator_.try_shared_lock_upgrade(); rw_mutex_assert(!this->write_locked); @@ -581,7 +591,7 @@ namespace ts { } template - void rw_mutex_impl::downgrade_lock() { + void impl::rw_mutex_impl::downgrade_lock() { std::unique_lock slock{this->status_lock_}; this->action_validator_.try_exclusive_lock_downgrade(); rw_mutex_assert(this->write_locked); @@ -600,16 +610,16 @@ namespace ts { /* action validator */ /* shared lock part */ - void mutex_action_validator::try_shared_lock_acquire() { + void impl::mutex_action_validator::try_shared_lock_acquire() { if(this->exclusive_lock == std::this_thread::get_id()) throw std::logic_error{"mutex has been locked in exclusive lock by current thread"}; } - void mutex_action_validator::shared_lock_acquire() { + void impl::mutex_action_validator::shared_lock_acquire() { this->shared_lockers.push_back(std::this_thread::get_id()); } - void mutex_action_validator::try_shared_lock_upgrade() { + void impl::mutex_action_validator::try_shared_lock_upgrade() { if(this->exclusive_lock == std::this_thread::get_id()) throw std::logic_error{"mutex has been upgraded by current thread"}; @@ -624,12 +634,12 @@ namespace ts { throw std::logic_error{"upgrade not possible because shared mutex is locked more than once by current thread"}; } - void mutex_action_validator::shared_lock_upgrade() { + void impl::mutex_action_validator::shared_lock_upgrade() { this->exclusive_lock_upgraded = true; this->exclusive_lock = std::this_thread::get_id(); } - void mutex_action_validator::try_shared_lock_release() { + void impl::mutex_action_validator::try_shared_lock_release() { if(this->exclusive_lock == std::this_thread::get_id()) throw std::logic_error{this->exclusive_lock_upgraded ? "mutex has been upgraded" : "mutex has been locked in exclusive mode, not in shared mode"}; @@ -638,29 +648,29 @@ namespace ts { throw std::logic_error{"mutex not locked by current thread"}; } - void mutex_action_validator::shared_lock_release() { + void impl::mutex_action_validator::shared_lock_release() { auto it = std::find(this->shared_lockers.begin(), this->shared_lockers.end(), std::this_thread::get_id()); rw_mutex_assert(it != this->shared_lockers.end()); /* this should never happen (try_shared_lock_release has been called before) */ this->shared_lockers.erase(it); } /* exclusive lock part */ - void mutex_action_validator::try_exclusive_lock_acquire() { + void impl::mutex_action_validator::try_exclusive_lock_acquire() { if(this->exclusive_lock == std::this_thread::get_id()) throw std::logic_error{"mutex has been exclusive locked by current thread"}; } - void mutex_action_validator::exclusive_lock_acquire() { + void impl::mutex_action_validator::exclusive_lock_acquire() { this->exclusive_lock = std::this_thread::get_id(); this->exclusive_lock_upgraded = false; } - void mutex_action_validator::try_exclusive_lock_downgrade() { + void impl::mutex_action_validator::try_exclusive_lock_downgrade() { if(this->exclusive_lock != std::this_thread::get_id()) throw std::logic_error{"mutex hasn't been locked in exclusive mode by this thread"}; } - void mutex_action_validator::exclusive_lock_downgrade() { + void impl::mutex_action_validator::exclusive_lock_downgrade() { if(!this->exclusive_lock_upgraded) { this->shared_lockers.push_back(std::this_thread::get_id()); } else { @@ -672,12 +682,12 @@ namespace ts { this->exclusive_lock = std::thread::id{}; } - void mutex_action_validator::try_exclusive_lock_release() { + void impl::mutex_action_validator::try_exclusive_lock_release() { if(this->exclusive_lock != std::this_thread::get_id()) throw std::logic_error{"mutex hasn't been locked in exclusive mode by this thread"}; } - void mutex_action_validator::exclusive_lock_release() { + void impl::mutex_action_validator::exclusive_lock_release() { if(this->exclusive_lock_upgraded) { auto it = std::find(this->shared_lockers.begin(), this->shared_lockers.end(), std::this_thread::get_id()); assert(it != this->shared_lockers.end()); diff --git a/src/protocol/CryptHandler.cpp b/src/protocol/CryptHandler.cpp index 98b4d66..485b9f4 100644 --- a/src/protocol/CryptHandler.cpp +++ b/src/protocol/CryptHandler.cpp @@ -77,7 +77,7 @@ bool CryptHandler::setupSharedSecret(const std::string& alpha, const std::string return true; } -void _fe_neg(fe h, const fe f) { +inline void _fe_neg(fe h, const fe f) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2];