Source code of Windows XP (NT5)
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.

138 lines
3.9 KiB

  1. //
  2. // MODULE: Stateless.CPP
  3. //
  4. // PURPOSE: CStateless is the base for a hierarchy of classes intended for stateless operation
  5. // in a multithreaded environment. The idea is that each public method in any class inheriting
  6. // from CStateless should be atomic. Typically, a public method will begin with Lock() and
  7. // end with Unlock(). It should represent a complete process.
  8. // In general, public methods should fall into two categories.
  9. // 1. Determine certain irreversible statuses (e.g. whether certain things are initialized).
  10. // 2. Perform atomic operations. For example, it is appropriate to write a method that
  11. // will take a complete set of node states and return a vector of recommendations.
  12. //
  13. // It is NOT appropriate to write methods to
  14. // - associate a a single node and state, this method to be called repeatedly
  15. // - get a vector of recommendations based on previousl established node/state associations.
  16. // This relies on a state to be maintained across calls, but that state may be lost due to
  17. // other threads using the same object.
  18. //
  19. // It is legitimate, but not recommended to write the following methods:
  20. // - associate a uniquely identified query, a node, and a state
  21. // - get a vector of recommendations for a uniquely identified query, based on node/state
  22. // associations.
  23. // This last approach is not truly stateless, but at least provides sufficient information to
  24. // allow appropriate preservation of state without denying other threads the use of the
  25. // CStateless object.
  26. //
  27. //
  28. // COMPANY: Saltmine Creative, Inc. (206)-284-7511 [email protected]
  29. //
  30. // AUTHOR: Joe Mabel
  31. //
  32. // ORIGINAL DATE: 9-9-98
  33. //
  34. // NOTES:
  35. // 1. Lock() and Unlock() are const methods so that (for example) a simple "get" in a
  36. // class which inherits from this can be const. E.g.:
  37. //
  38. // class CFoo : public CStateless
  39. // {
  40. // int i;
  41. // public:
  42. // int GetI() const
  43. // {
  44. // Lock();
  45. // int ret = i;
  46. // Unlock();
  47. // retrn ret;
  48. // }
  49. // ...
  50. // };
  51. //
  52. // Version Date By Comments
  53. //--------------------------------------------------------------------
  54. // V3.0 9-9-98 JM
  55. //
  56. #include "stdafx.h"
  57. #include "Stateless.h"
  58. #include "APIWraps.h"
  59. #include "Event.h"
  60. #include "BaseException.h"
  61. #include <algorithm>
  62. using namespace std;
  63. ////////////////////////////////////////////////////////////////////////////////////
  64. // CStateless
  65. /////////////////////////////////////////////////////////////////////////////////////
  66. CStateless::CStateless(DWORD TimeOutVal /*= 60000 */)
  67. {
  68. m_TimeOutVal = TimeOutVal;
  69. m_hMutex = ::CreateMutex(NULL, FALSE, NULL);
  70. if (!m_hMutex)
  71. {
  72. CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
  73. CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
  74. SrcLoc.GetSrcFileLineStr(),
  75. _T("Hourly"),
  76. _T(""),
  77. EV_GTS_ERROR_MUTEX );
  78. throw bad_alloc();
  79. }
  80. }
  81. CStateless::~CStateless()
  82. {
  83. ::CloseHandle(m_hMutex);
  84. }
  85. void CStateless::Lock(
  86. LPCSTR srcFile, // Calling source file (__FILE__), used for logging.
  87. // LPCSTR, not LPCTSTR, because __FILE__ is a char*, not a TCHAR*
  88. int srcLine // Calling source line (__LINE__), used for logging.
  89. ) const
  90. {
  91. APIwraps::WaitAndLogIfSlow(m_hMutex, srcFile, srcLine, m_TimeOutVal);
  92. }
  93. void CStateless::Unlock() const
  94. {
  95. ::ReleaseMutex(m_hMutex);
  96. }
  97. // this function is needed to support multi-mutex locking.
  98. HANDLE CStateless::GetMutexHandle() const
  99. {
  100. return m_hMutex;
  101. }
  102. ////////////////////////////////////////////////////////////////////////////////////
  103. // CNameStateless
  104. /////////////////////////////////////////////////////////////////////////////////////
  105. CNameStateless::CNameStateless()
  106. : CStateless()
  107. {
  108. }
  109. CNameStateless::CNameStateless(const CString& str)
  110. : CStateless()
  111. {
  112. LOCKOBJECT();
  113. m_strName = str;
  114. UNLOCKOBJECT();
  115. }
  116. void CNameStateless::Set(const CString& str)
  117. {
  118. LOCKOBJECT();
  119. m_strName = str;
  120. UNLOCKOBJECT();
  121. }
  122. CString CNameStateless::Get() const
  123. {
  124. LOCKOBJECT();
  125. CString ret = m_strName;
  126. UNLOCKOBJECT();
  127. return ret;
  128. }