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.

127 lines
3.1 KiB

  1. // Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
  2. // CUnknown.cpp
  3. #include "precomp.h"
  4. #include <objidl.h>
  5. #include <cominit.h>
  6. #include <objbase.h>
  7. #include <comdef.h>
  8. #include "CUnknown.h"
  9. #include "factory.h"
  10. extern const char g_szTypeLibName[];
  11. long CUnknown::s_cActiveComponents = 0L;
  12. /*****************************************************************************/
  13. // Constructor
  14. /*****************************************************************************/
  15. CUnknown::CUnknown()
  16. : m_cRef(1),
  17. m_hEventThread(NULL),
  18. m_eStatus(Pending)
  19. {
  20. InterlockedIncrement(&s_cActiveComponents);
  21. }
  22. /*****************************************************************************/
  23. // Destructor
  24. /*****************************************************************************/
  25. CUnknown::~CUnknown()
  26. {
  27. InterlockedDecrement(&s_cActiveComponents);
  28. if(m_hEventThread)
  29. {
  30. ::CloseHandle(m_hEventThread);
  31. }
  32. }
  33. /*****************************************************************************/
  34. // FinalRelease - called by Release before it deletes the component
  35. /*****************************************************************************/
  36. void CUnknown::FinalRelease()
  37. {
  38. // If we have an event thread...
  39. if(m_eStatus != Pending)
  40. {
  41. // Let the event thread know that it can stop...
  42. m_eStatus = PendingStop;
  43. // Hold here until the event thread has stopped...
  44. DWORD dwWait = ::WaitForSingleObject(
  45. m_hEventThread,
  46. 1000 * 60 * 20);
  47. if(dwWait == WAIT_TIMEOUT)
  48. {
  49. // Something is most likely wrong....
  50. // If it takes 20 minutes, we will terminate
  51. // the thread, even though it is understood
  52. // that TerminateThread will leak some
  53. // resources, as that is better than
  54. // leaving the thread running infinitely.
  55. ::TerminateThread(
  56. m_hEventThread,
  57. -1L);
  58. }
  59. }
  60. }
  61. /*****************************************************************************/
  62. // CUnknown default initialization
  63. /*****************************************************************************/
  64. STDMETHODIMP CUnknown::Init()
  65. {
  66. HRESULT hr = S_OK;
  67. return S_OK ;
  68. }
  69. /*****************************************************************************/
  70. // IUnknown implementation
  71. /*****************************************************************************/
  72. STDMETHODIMP CUnknown::QueryInterface(const IID& iid, void** ppv)
  73. {
  74. HRESULT hr = S_OK;
  75. if(iid == IID_IUnknown)
  76. {
  77. *ppv = static_cast<IUnknown*>(this);
  78. }
  79. else
  80. {
  81. *ppv = NULL;
  82. hr = E_NOINTERFACE;
  83. }
  84. if(SUCCEEDED(hr))
  85. {
  86. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  87. }
  88. return hr;
  89. }
  90. STDMETHODIMP_(ULONG) CUnknown::AddRef()
  91. {
  92. return InterlockedIncrement(&m_cRef);
  93. }
  94. STDMETHODIMP_(ULONG) CUnknown::Release()
  95. {
  96. ULONG ulRet = 0L;
  97. InterlockedDecrement(&m_cRef);
  98. if (m_cRef == 0)
  99. {
  100. FinalRelease();
  101. delete this;
  102. }
  103. else
  104. {
  105. ulRet = m_cRef;
  106. }
  107. return ulRet;
  108. }