diff options
author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 21:25:21 +0200 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 22:40:26 +0300 |
commit | e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch) | |
tree | 1bb897489ce524986f6196201c10ac0d8861aa5f /indra/llcommon/llmutex.h | |
parent | 069ea06848f766466f1a281144c82a0f2bd79f3a (diff) |
Fix line endlings
Diffstat (limited to 'indra/llcommon/llmutex.h')
-rw-r--r-- | indra/llcommon/llmutex.h | 542 |
1 files changed, 271 insertions, 271 deletions
diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index 898ddab284..6e8cf9643b 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -1,271 +1,271 @@ -/**
- * @file llmutex.h
- * @brief Base classes for mutex and condition handling.
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLMUTEX_H
-#define LL_LLMUTEX_H
-
-#include "stdtypes.h"
-#include "llthread.h"
-#include <boost/noncopyable.hpp>
-
-#include "mutex.h"
-#include <shared_mutex>
-#include <unordered_map>
-#include <condition_variable>
-
-//============================================================================
-
-//#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
-#define MUTEX_DEBUG 0 //disable mutex debugging as it's interfering with profiles
-
-#if MUTEX_DEBUG
-#include <map>
-#endif
-
-class LL_COMMON_API LLMutex
-{
-public:
- LLMutex();
- virtual ~LLMutex();
-
- void lock(); // blocks
- bool trylock(); // non-blocking, returns true if lock held.
- void unlock(); // undefined behavior when called on mutex not being held
- bool isLocked(); // non-blocking, but does do a lock/unlock so not free
- bool isSelfLocked(); //return true if locked in a same thread
- LLThread::id_t lockingThread() const; //get ID of locking thread
-
-protected:
- std::mutex mMutex;
- mutable U32 mCount;
- mutable LLThread::id_t mLockingThread;
-
-#if MUTEX_DEBUG
- std::unordered_map<LLThread::id_t, bool> mIsLocked;
-#endif
-};
-
-//============================================================================
-
-class LL_COMMON_API LLSharedMutex
-{
-public:
- LLSharedMutex();
-
- bool isLocked() const;
- bool isThreadLocked() const;
- bool isShared() const { return mIsShared; }
-
- void lockShared();
- void lockExclusive();
- template<bool SHARED> void lock();
-
- bool trylockShared();
- bool trylockExclusive();
- template<bool SHARED> bool trylock();
-
- void unlockShared();
- void unlockExclusive();
- template<bool SHARED> void unlock();
-
-private:
- std::shared_mutex mSharedMutex;
- mutable std::mutex mLockMutex;
- std::unordered_map<LLThread::id_t, U32> mLockingThreads;
- bool mIsShared;
-
- using iterator = std::unordered_map<LLThread::id_t, U32>::iterator;
- using const_iterator = std::unordered_map<LLThread::id_t, U32>::const_iterator;
-};
-
-template<>
-inline void LLSharedMutex::lock<true>()
-{
- lockShared();
-}
-
-template<>
-inline void LLSharedMutex::lock<false>()
-{
- lockExclusive();
-}
-
-template<>
-inline bool LLSharedMutex::trylock<true>()
-{
- return trylockShared();
-}
-
-template<>
-inline bool LLSharedMutex::trylock<false>()
-{
- return trylockExclusive();
-}
-
-template<>
-inline void LLSharedMutex::unlock<true>()
-{
- unlockShared();
-}
-
-template<>
-inline void LLSharedMutex::unlock<false>()
-{
- unlockExclusive();
-}
-
-// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
-class LL_COMMON_API LLCondition : public LLMutex
-{
-public:
- LLCondition();
- ~LLCondition();
-
- void wait(); // blocks
- void signal();
- void broadcast();
-
-protected:
- std::condition_variable mCond;
-};
-
-//============================================================================
-
-class LLMutexLock
-{
-public:
- LLMutexLock(LLMutex* mutex)
- {
- mMutex = mutex;
-
- if (mMutex)
- mMutex->lock();
- }
-
- ~LLMutexLock()
- {
- if (mMutex)
- mMutex->unlock();
- }
-
-private:
- LLMutex* mMutex;
-};
-
-//============================================================================
-
-template<bool SHARED>
-class LLSharedMutexLockTemplate
-{
-public:
- LLSharedMutexLockTemplate(LLSharedMutex* mutex)
- : mSharedMutex(mutex)
- {
- if (mSharedMutex)
- mSharedMutex->lock<SHARED>();
- }
-
- ~LLSharedMutexLockTemplate()
- {
- if (mSharedMutex)
- mSharedMutex->unlock<SHARED>();
- }
-
-private:
- LLSharedMutex* mSharedMutex;
-};
-
-using LLSharedMutexLock = LLSharedMutexLockTemplate<true>;
-using LLExclusiveMutexLock = LLSharedMutexLockTemplate<false>;
-
-//============================================================================
-
-// Scoped locking class similar in function to LLMutexLock but uses
-// the trylock() method to conditionally acquire lock without
-// blocking. Caller resolves the resulting condition by calling
-// the isLocked() method and either punts or continues as indicated.
-//
-// Mostly of interest to callers needing to avoid stalls who can
-// guarantee another attempt at a later time.
-
-class LLMutexTrylock
-{
-public:
- LLMutexTrylock(LLMutex* mutex);
- LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms = 10);
- ~LLMutexTrylock();
-
- bool isLocked() const
- {
- return mLocked;
- }
-
-private:
- LLMutex* mMutex;
- bool mLocked;
-};
-
-//============================================================================
-
-/**
-* @class LLScopedLock
-* @brief Small class to help lock and unlock mutexes.
-*
-* The constructor handles the lock, and the destructor handles
-* the unlock. Instances of this class are <b>not</b> thread safe.
-*/
-class LL_COMMON_API LLScopedLock : private boost::noncopyable
-{
-public:
- /**
- * @brief Constructor which accepts a mutex, and locks it.
- *
- * @param mutex An allocated mutex. If you pass in NULL,
- * this wrapper will not lock.
- */
- LLScopedLock(std::mutex* mutex);
-
- /**
- * @brief Destructor which unlocks the mutex if still locked.
- */
- ~LLScopedLock();
-
- /**
- * @brief Check lock.
- */
- bool isLocked() const { return mLocked; }
-
- /**
- * @brief This method unlocks the mutex.
- */
- void unlock();
-
-protected:
- bool mLocked;
- std::mutex* mMutex;
-};
-
-#endif // LL_LLMUTEX_H
+/** + * @file llmutex.h + * @brief Base classes for mutex and condition handling. + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLMUTEX_H +#define LL_LLMUTEX_H + +#include "stdtypes.h" +#include "llthread.h" +#include <boost/noncopyable.hpp> + +#include "mutex.h" +#include <shared_mutex> +#include <unordered_map> +#include <condition_variable> + +//============================================================================ + +//#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) +#define MUTEX_DEBUG 0 //disable mutex debugging as it's interfering with profiles + +#if MUTEX_DEBUG +#include <map> +#endif + +class LL_COMMON_API LLMutex +{ +public: + LLMutex(); + virtual ~LLMutex(); + + void lock(); // blocks + bool trylock(); // non-blocking, returns true if lock held. + void unlock(); // undefined behavior when called on mutex not being held + bool isLocked(); // non-blocking, but does do a lock/unlock so not free + bool isSelfLocked(); //return true if locked in a same thread + LLThread::id_t lockingThread() const; //get ID of locking thread + +protected: + std::mutex mMutex; + mutable U32 mCount; + mutable LLThread::id_t mLockingThread; + +#if MUTEX_DEBUG + std::unordered_map<LLThread::id_t, bool> mIsLocked; +#endif +}; + +//============================================================================ + +class LL_COMMON_API LLSharedMutex +{ +public: + LLSharedMutex(); + + bool isLocked() const; + bool isThreadLocked() const; + bool isShared() const { return mIsShared; } + + void lockShared(); + void lockExclusive(); + template<bool SHARED> void lock(); + + bool trylockShared(); + bool trylockExclusive(); + template<bool SHARED> bool trylock(); + + void unlockShared(); + void unlockExclusive(); + template<bool SHARED> void unlock(); + +private: + std::shared_mutex mSharedMutex; + mutable std::mutex mLockMutex; + std::unordered_map<LLThread::id_t, U32> mLockingThreads; + bool mIsShared; + + using iterator = std::unordered_map<LLThread::id_t, U32>::iterator; + using const_iterator = std::unordered_map<LLThread::id_t, U32>::const_iterator; +}; + +template<> +inline void LLSharedMutex::lock<true>() +{ + lockShared(); +} + +template<> +inline void LLSharedMutex::lock<false>() +{ + lockExclusive(); +} + +template<> +inline bool LLSharedMutex::trylock<true>() +{ + return trylockShared(); +} + +template<> +inline bool LLSharedMutex::trylock<false>() +{ + return trylockExclusive(); +} + +template<> +inline void LLSharedMutex::unlock<true>() +{ + unlockShared(); +} + +template<> +inline void LLSharedMutex::unlock<false>() +{ + unlockExclusive(); +} + +// Actually a condition/mutex pair (since each condition needs to be associated with a mutex). +class LL_COMMON_API LLCondition : public LLMutex +{ +public: + LLCondition(); + ~LLCondition(); + + void wait(); // blocks + void signal(); + void broadcast(); + +protected: + std::condition_variable mCond; +}; + +//============================================================================ + +class LLMutexLock +{ +public: + LLMutexLock(LLMutex* mutex) + { + mMutex = mutex; + + if (mMutex) + mMutex->lock(); + } + + ~LLMutexLock() + { + if (mMutex) + mMutex->unlock(); + } + +private: + LLMutex* mMutex; +}; + +//============================================================================ + +template<bool SHARED> +class LLSharedMutexLockTemplate +{ +public: + LLSharedMutexLockTemplate(LLSharedMutex* mutex) + : mSharedMutex(mutex) + { + if (mSharedMutex) + mSharedMutex->lock<SHARED>(); + } + + ~LLSharedMutexLockTemplate() + { + if (mSharedMutex) + mSharedMutex->unlock<SHARED>(); + } + +private: + LLSharedMutex* mSharedMutex; +}; + +using LLSharedMutexLock = LLSharedMutexLockTemplate<true>; +using LLExclusiveMutexLock = LLSharedMutexLockTemplate<false>; + +//============================================================================ + +// Scoped locking class similar in function to LLMutexLock but uses +// the trylock() method to conditionally acquire lock without +// blocking. Caller resolves the resulting condition by calling +// the isLocked() method and either punts or continues as indicated. +// +// Mostly of interest to callers needing to avoid stalls who can +// guarantee another attempt at a later time. + +class LLMutexTrylock +{ +public: + LLMutexTrylock(LLMutex* mutex); + LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms = 10); + ~LLMutexTrylock(); + + bool isLocked() const + { + return mLocked; + } + +private: + LLMutex* mMutex; + bool mLocked; +}; + +//============================================================================ + +/** +* @class LLScopedLock +* @brief Small class to help lock and unlock mutexes. +* +* The constructor handles the lock, and the destructor handles +* the unlock. Instances of this class are <b>not</b> thread safe. +*/ +class LL_COMMON_API LLScopedLock : private boost::noncopyable +{ +public: + /** + * @brief Constructor which accepts a mutex, and locks it. + * + * @param mutex An allocated mutex. If you pass in NULL, + * this wrapper will not lock. + */ + LLScopedLock(std::mutex* mutex); + + /** + * @brief Destructor which unlocks the mutex if still locked. + */ + ~LLScopedLock(); + + /** + * @brief Check lock. + */ + bool isLocked() const { return mLocked; } + + /** + * @brief This method unlocks the mutex. + */ + void unlock(); + +protected: + bool mLocked; + std::mutex* mMutex; +}; + +#endif // LL_LLMUTEX_H |