eathread_mutex_cpp11.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Electronic Arts Inc. All rights reserved.
  3. ///////////////////////////////////////////////////////////////////////////////
  4. #include "eathread/eathread_mutex.h"
  5. EAMutexData::EAMutexData() : mnLockCount(0) {}
  6. EA::Thread::MutexParameters::MutexParameters(bool /*bIntraProcess*/, const char* pName)
  7. {
  8. if(pName)
  9. {
  10. strncpy(mName, pName, sizeof(mName)-1);
  11. mName[sizeof(mName)-1] = 0;
  12. }
  13. else
  14. {
  15. mName[0] = 0;
  16. }
  17. }
  18. EA::Thread::Mutex::Mutex(const MutexParameters* pMutexParameters, bool bDefaultParameters)
  19. {
  20. if(!pMutexParameters && bDefaultParameters)
  21. {
  22. MutexParameters parameters;
  23. Init(&parameters);
  24. }
  25. else
  26. {
  27. Init(pMutexParameters);
  28. }
  29. }
  30. EA::Thread::Mutex::~Mutex()
  31. {
  32. EAT_ASSERT(mMutexData.mnLockCount == 0);
  33. }
  34. bool EA::Thread::Mutex::Init(const MutexParameters* pMutexParameters)
  35. {
  36. if (pMutexParameters)
  37. {
  38. mMutexData.mnLockCount = 0;
  39. return true;
  40. }
  41. return false;
  42. }
  43. int EA::Thread::Mutex::Lock(const ThreadTime& timeoutAbsolute)
  44. {
  45. if (timeoutAbsolute == kTimeoutNone)
  46. {
  47. mMutexData.mMutex.lock();
  48. }
  49. else
  50. {
  51. std::chrono::milliseconds timeoutAbsoluteMs(timeoutAbsolute);
  52. std::chrono::time_point<std::chrono::system_clock> timeout_time(timeoutAbsoluteMs);
  53. if (!mMutexData.mMutex.try_lock_until(timeout_time))
  54. {
  55. return kResultTimeout;
  56. }
  57. }
  58. EAT_ASSERT((mMutexData.mThreadId = EA::Thread::GetThreadId()) != kThreadIdInvalid);
  59. EAT_ASSERT(mMutexData.mnLockCount >= 0);
  60. return ++mMutexData.mnLockCount; // This is safe to do because we have the lock.
  61. }
  62. int EA::Thread::Mutex::Unlock()
  63. {
  64. EAT_ASSERT(mMutexData.mThreadId == EA::Thread::GetThreadId());
  65. EAT_ASSERT(mMutexData.mnLockCount > 0);
  66. const int nReturnValue(--mMutexData.mnLockCount); // This is safe to do because we have the lock.
  67. mMutexData.mMutex.unlock();
  68. return nReturnValue;
  69. }
  70. int EA::Thread::Mutex::GetLockCount() const
  71. {
  72. return mMutexData.mnLockCount;
  73. }
  74. bool EA::Thread::Mutex::HasLock() const
  75. {
  76. #if EAT_ASSERT_ENABLED
  77. return (mMutexData.mnLockCount > 0) && (mMutexData.mThreadId == EA::Thread::GetThreadId());
  78. #else
  79. return (mMutexData.mnLockCount > 0); // This is the best we can do, though it is of limited use, since it doesn't tell you if you are the thread with the lock.
  80. #endif
  81. }