Mutex.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /* -*- C++ -*- */
  2. /****************************************************************************
  3. ** Copyright (c) 2001-2014
  4. **
  5. ** This file is part of the QuickFIX FIX Engine
  6. **
  7. ** This file may be distributed under the terms of the quickfixengine.org
  8. ** license as defined by quickfixengine.org and appearing in the file
  9. ** LICENSE included in the packaging of this file.
  10. **
  11. ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  12. ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  13. **
  14. ** See http://www.quickfixengine.org/LICENSE for licensing information.
  15. **
  16. ** Contact ask@quickfixengine.org if any conditions of this licensing are
  17. ** not clear to you.
  18. **
  19. ****************************************************************************/
  20. #ifndef FIX_MUTEX_H
  21. #define FIX_MUTEX_H
  22. #include "Utility.h"
  23. namespace FIX
  24. {
  25. /// Portable implementation of a mutex.
  26. class Mutex
  27. {
  28. public:
  29. Mutex()
  30. {
  31. #ifdef _MSC_VER
  32. InitializeCriticalSection( &m_mutex );
  33. #else
  34. m_count = 0;
  35. m_threadID = 0;
  36. //pthread_mutexattr_t attr;
  37. //pthread_mutexattr_init(&attr);
  38. //pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  39. //pthread_mutex_init(&m_mutex, &attr);
  40. pthread_mutex_init( &m_mutex, 0 );
  41. #endif
  42. }
  43. ~Mutex()
  44. {
  45. #ifdef _MSC_VER
  46. DeleteCriticalSection( &m_mutex );
  47. #else
  48. pthread_mutex_destroy( &m_mutex );
  49. #endif
  50. }
  51. void lock()
  52. {
  53. #ifdef _MSC_VER
  54. EnterCriticalSection( &m_mutex );
  55. #else
  56. if ( m_count && m_threadID == pthread_self() )
  57. { ++m_count; return ; }
  58. pthread_mutex_lock( &m_mutex );
  59. ++m_count;
  60. m_threadID = pthread_self();
  61. #endif
  62. }
  63. void unlock()
  64. {
  65. #ifdef _MSC_VER
  66. LeaveCriticalSection( &m_mutex );
  67. #else
  68. if ( m_count > 1 )
  69. { m_count--; return ; }
  70. --m_count;
  71. m_threadID = 0;
  72. pthread_mutex_unlock( &m_mutex );
  73. #endif
  74. }
  75. private:
  76. #ifdef _MSC_VER
  77. CRITICAL_SECTION m_mutex;
  78. #else
  79. pthread_mutex_t m_mutex;
  80. pthread_t m_threadID;
  81. int m_count;
  82. #endif
  83. };
  84. /// Locks/Unlocks a mutex using RAII.
  85. class Locker
  86. {
  87. public:
  88. Locker( Mutex& mutex )
  89. : m_mutex( mutex )
  90. {
  91. m_mutex.lock();
  92. }
  93. ~Locker()
  94. {
  95. m_mutex.unlock();
  96. }
  97. private:
  98. Mutex& m_mutex;
  99. };
  100. /// Does the opposite of the Locker to ensure mutex ends up in a locked state.
  101. class ReverseLocker
  102. {
  103. public:
  104. ReverseLocker( Mutex& mutex )
  105. : m_mutex( mutex )
  106. {
  107. m_mutex.unlock();
  108. }
  109. ~ReverseLocker()
  110. {
  111. m_mutex.lock();
  112. }
  113. private:
  114. Mutex& m_mutex;
  115. };
  116. }
  117. #endif