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.

145 lines
4.4 KiB

  1. //-----------------------------------------------------------------------------
  2. //
  3. //
  4. // File: shutdown.cpp
  5. //
  6. // Description: Implementation of CSyncShutdown.
  7. //
  8. // Author: mikeswa
  9. //
  10. // Copyright (C) 1998 Microsoft Corporation
  11. //
  12. //-----------------------------------------------------------------------------
  13. #include "aqprecmp.h"
  14. #include "shutdown.h"
  15. #include "aqutil.h"
  16. //---[ CSyncShutdown::~CSyncShutdown ]-----------------------------------------
  17. //
  18. //
  19. // Description:
  20. // CSyncShutdown Destructor
  21. // Parameters:
  22. // -
  23. // Returns:
  24. // -
  25. //
  26. //-----------------------------------------------------------------------------
  27. CSyncShutdown::~CSyncShutdown()
  28. {
  29. //There should not be any outstanding locks
  30. m_dwSignature = CSyncShutdown_SigFree;
  31. _ASSERT(0 == (m_cReadLocks & ~SYNC_SHUTDOWN_SIGNALED));
  32. }
  33. //---[ CSyncShutdown::fTryShutdownLock ]---------------------------------------
  34. //
  35. //
  36. // Description:
  37. // Trys to aquire Shared lock to guard against shutdown happening. This
  38. // call will *not* block, but may cause the thread calling SignalShutdown
  39. // to block.
  40. // Parameters:
  41. // -
  42. // Returns:
  43. // TRUE if shutdown lock can be aquired and shutdown has not started.
  44. // FALSE if lock cannot be aquired (thread in SignalShutdown) or if
  45. // SYNC_SHUTDOWN_SIGNALED has already been set.
  46. //
  47. //-----------------------------------------------------------------------------
  48. BOOL CSyncShutdown::fTryShutdownLock()
  49. {
  50. if (m_cReadLocks & SYNC_SHUTDOWN_SIGNALED)
  51. return FALSE;
  52. else if (!m_slShutdownLock.TryShareLock()) //Never block for the lock..
  53. return FALSE;
  54. //Check bit again... now that we have sharelock
  55. if (m_cReadLocks & SYNC_SHUTDOWN_SIGNALED)
  56. {
  57. m_slShutdownLock.ShareUnlock();
  58. return FALSE;
  59. }
  60. //In retail, m_cReadLocks is only used for the SYNC_SHUTDOWN_SIGNALED flag
  61. DEBUG_DO_IT(InterlockedIncrement((PLONG) &m_cReadLocks));
  62. return TRUE;
  63. }
  64. //---[ CSyncShutdown::ShutdownUnlock ]-----------------------------------------
  65. //
  66. //
  67. // Description:
  68. // Releases a perviously aquired share lock. Must be matched with a
  69. // *succeeding* call to fTryShutdownLock().
  70. // Parameters:
  71. // -
  72. // Returns:
  73. // -
  74. //
  75. // Will assert if called more times than there are outstanding share locks
  76. //
  77. //-----------------------------------------------------------------------------
  78. void CSyncShutdown::ShutdownUnlock()
  79. {
  80. _ASSERT(0 < (m_cReadLocks & ~SYNC_SHUTDOWN_SIGNALED));
  81. //In retail, m_cReadLocks is only used for the SYNC_SHUTDOWN_SIGNALED flag
  82. DEBUG_DO_IT(InterlockedDecrement((PLONG) &m_cReadLocks));
  83. m_slShutdownLock.ShareUnlock();
  84. }
  85. //---[ CSyncShutdown::SignalShutdown ]-----------------------------------------
  86. //
  87. //
  88. // Description:
  89. // Aquires the Exclusive lock & sets the shutdown flag, which will prevent
  90. // Any further shared locks from being aquired.
  91. //
  92. // This call *may* block, and should not be called by a thread that
  93. // already owns a shared shutdown lock. This is unlikely to happen, since
  94. // This should only be called by a thread that stopping the server
  95. // instance.
  96. // Parameters:
  97. // -
  98. // Returns:
  99. // -
  100. //
  101. //-----------------------------------------------------------------------------
  102. void CSyncShutdown::SignalShutdown()
  103. {
  104. //Let everyone know that we are shutting down... once this is called, no
  105. //one will be able to grab the lock shared.
  106. SetShutdownHint();
  107. //Wait until all threads that have acquired the lock are done
  108. m_slShutdownLock.ExclusiveLock();
  109. m_slShutdownLock.ExclusiveUnlock();
  110. //Now all calls to fTryShutdownLock should fail
  111. _ASSERT(!fTryShutdownLock());
  112. }
  113. //---[ CSyncShutdown::SetShutdownHint ]----------------------------------------
  114. //
  115. //
  116. // Description:
  117. // Sets the shutdown hint so that further calls to fTryShutdownLock
  118. // will fail.
  119. // Parameters:
  120. // -
  121. // Returns:
  122. // -
  123. // History:
  124. // 7/7/99 - MikeSwa Created
  125. //
  126. //-----------------------------------------------------------------------------
  127. void CSyncShutdown::SetShutdownHint()
  128. {
  129. dwInterlockedSetBits(&m_cReadLocks, SYNC_SHUTDOWN_SIGNALED);
  130. //Now all calls to fTryShutdownLock should fail
  131. _ASSERT(!fTryShutdownLock());
  132. }