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.

149 lines
3.3 KiB

  1. //+------------------------------------------------------------
  2. //
  3. // Copyright (C) 1999, Microsoft Corporation
  4. //
  5. // File: cleanback.h
  6. //
  7. // Contents: Implements Cleanup callback interface
  8. //
  9. // Classes: CCleanBack
  10. //
  11. // Description: The intention is this object will be used as a part of
  12. // other objects (member variable or inheritence).
  13. // Therefore, the IUnknown passed in is NOT referenced.
  14. //
  15. // History:
  16. // jstamerj 1999/09/27 17:58:50: Created.
  17. //
  18. //-------------------------------------------------------------
  19. #include "mailmsg.h"
  20. #include "spinlock.h"
  21. class CCleanBack :
  22. public IMailMsgRegisterCleanupCallback
  23. {
  24. public:
  25. CCleanBack(IUnknown *pUnknown)
  26. {
  27. m_pListHead = NULL;
  28. m_pIUnknown = pUnknown;
  29. InitializeSpinLock(&m_spinlock);
  30. }
  31. ~CCleanBack()
  32. {
  33. CallCallBacks();
  34. }
  35. VOID CallCallBacks()
  36. {
  37. //
  38. // Call all registered callbacks while destroying the list
  39. //
  40. CCallBack *pCallback;
  41. while(m_pListHead) {
  42. //
  43. // Dequeue from head of list
  44. //
  45. AcquireSpinLock(&m_spinlock);
  46. pCallback = m_pListHead;
  47. if(pCallback)
  48. m_pListHead = pCallback->GetNext();
  49. ReleaseSpinLock(&m_spinlock);
  50. //
  51. // Make the call
  52. //
  53. if(pCallback) {
  54. pCallback->Call(m_pIUnknown);
  55. delete pCallback;
  56. }
  57. }
  58. }
  59. STDMETHOD (RegisterCleanupCallback) (
  60. IMailMsgCleanupCallback *pICallBack,
  61. PVOID pvContext)
  62. {
  63. CCallBack *pCCallBack;
  64. if(pICallBack == NULL)
  65. return E_POINTER;
  66. pCCallBack = new CCallBack(
  67. pICallBack,
  68. pvContext);
  69. if(pCCallBack == NULL)
  70. return E_OUTOFMEMORY;
  71. //
  72. // Insert object into list
  73. //
  74. AcquireSpinLock(&m_spinlock);
  75. pCCallBack->SetNext(m_pListHead);
  76. m_pListHead = pCCallBack;
  77. ReleaseSpinLock(&m_spinlock);
  78. return S_OK;
  79. }
  80. class CCallBack {
  81. public:
  82. CCallBack(IMailMsgCleanupCallback *pICallBack, PVOID pvContext)
  83. {
  84. m_pICallBack = pICallBack;
  85. m_pICallBack->AddRef();
  86. m_pvContext = pvContext;
  87. m_pNext = NULL;
  88. }
  89. ~CCallBack()
  90. {
  91. m_pICallBack->Release();
  92. }
  93. VOID Call(IUnknown *pIUnknown)
  94. {
  95. m_pICallBack->CleanupCallback(
  96. pIUnknown,
  97. m_pvContext);
  98. }
  99. VOID SetNext(CCallBack *pCCallBack)
  100. {
  101. m_pNext = pCCallBack;
  102. }
  103. CCallBack * GetNext()
  104. {
  105. return m_pNext;
  106. }
  107. private:
  108. IMailMsgCleanupCallback *m_pICallBack;
  109. PVOID m_pvContext;
  110. CCallBack *m_pNext;
  111. };
  112. public:
  113. //IUnknown
  114. STDMETHOD (QueryInterface) (
  115. REFIID iid,
  116. PVOID *ppv)
  117. {
  118. return m_pIUnknown->QueryInterface(
  119. iid,
  120. ppv);
  121. }
  122. STDMETHOD_ (ULONG, AddRef) ()
  123. {
  124. return m_pIUnknown->AddRef();
  125. }
  126. STDMETHOD_ (ULONG, Release) ()
  127. {
  128. return m_pIUnknown->Release();
  129. }
  130. private:
  131. SPIN_LOCK m_spinlock;
  132. CCallBack *m_pListHead;
  133. IUnknown *m_pIUnknown;
  134. };