Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
2.4 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. // atomics.cpp
  3. //
  4. #ifndef _WIN32_WINNT
  5. #define _WIN32_WINNT 0x0500
  6. #endif
  7. #include <atlbase.h>
  8. #include "atomics.h"
  9. CComCriticalSection g_critInc;
  10. void AtomicInit()
  11. {
  12. g_critInc.Init();
  13. }
  14. void AtomicTerm()
  15. {
  16. g_critInc.Term();
  17. }
  18. bool AtomicSeizeToken( long &lVal )
  19. {
  20. bool bRet = false;
  21. g_critInc.Lock();
  22. if ( !lVal )
  23. {
  24. lVal++;
  25. bRet = true;
  26. }
  27. g_critInc.Unlock();
  28. return bRet;
  29. }
  30. bool AtomicReleaseToken( long &lVal )
  31. {
  32. bool bRet = false;
  33. g_critInc.Lock();
  34. if ( lVal == 1 )
  35. {
  36. lVal--;
  37. bRet = true;
  38. }
  39. g_critInc.Unlock();
  40. return bRet;
  41. }
  42. ///////////////////////////////////////////////////////////////////////////
  43. // class CAtomicList
  44. //
  45. CAtomicList::CAtomicList()
  46. {
  47. m_dwThreadID = 0;
  48. m_lCount = 0;
  49. m_hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  50. InitializeCriticalSection( &m_crit );
  51. }
  52. CAtomicList::~CAtomicList()
  53. {
  54. _ASSERT( m_lCount == 0 ); // don't want to destroy object with outstanding ref's
  55. CloseHandle( m_hEvent );
  56. DeleteCriticalSection( &m_crit );
  57. }
  58. bool CAtomicList::Lock( short nType, DWORD dwTimeOut /*= INFINITE*/)
  59. {
  60. switch ( nType )
  61. {
  62. case LIST_READ:
  63. if ( dwTimeOut == INFINITE )
  64. {
  65. EnterCriticalSection( &m_crit );
  66. m_lCount++;
  67. LeaveCriticalSection( &m_crit );
  68. }
  69. else
  70. {
  71. while ( dwTimeOut )
  72. {
  73. if ( TryEnterCriticalSection(&m_crit) )
  74. {
  75. m_lCount++;
  76. LeaveCriticalSection(&m_crit);
  77. break;
  78. }
  79. else
  80. {
  81. // Sleep for a while
  82. if ( dwTimeOut > 50 )
  83. {
  84. dwTimeOut -= 50;
  85. Sleep( 50 );
  86. }
  87. else
  88. {
  89. return false;
  90. }
  91. }
  92. }
  93. }
  94. break;
  95. case LIST_WRITE:
  96. for ( ;; )
  97. {
  98. EnterCriticalSection( &m_crit );
  99. if ( (GetCurrentThreadId() != m_dwThreadID) && (m_lCount > 0) )
  100. {
  101. LeaveCriticalSection( &m_crit );
  102. WaitForSingleObject( m_hEvent, INFINITE );
  103. }
  104. else
  105. {
  106. m_dwThreadID = GetCurrentThreadId();
  107. m_lCount++;
  108. break;
  109. }
  110. };
  111. break;
  112. }
  113. // Success!
  114. return true;
  115. }
  116. void CAtomicList::Unlock( short nType )
  117. {
  118. EnterCriticalSection( &m_crit );
  119. _ASSERT( m_lCount > 0 );
  120. m_lCount--;
  121. if ( nType == LIST_WRITE )
  122. {
  123. if ( !m_lCount ) m_dwThreadID = 0;
  124. LeaveCriticalSection( &m_crit );
  125. }
  126. LeaveCriticalSection( &m_crit );
  127. PulseEvent( m_hEvent );
  128. }