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.

121 lines
4.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000 - 2000
  6. //
  7. // File: eventlock.h
  8. //
  9. // This file contains code needed to fire script event in a safer way
  10. // Locks made on stack will postpone firing the event on particular interface
  11. // as long as the last lock is released.
  12. //--------------------------------------------------------------------------
  13. #pragma once
  14. #if !defined(EVENTLOCK_H_INCLUDED)
  15. #define EVENTLOCK_H_INCLUDED
  16. /***************************************************************************\
  17. *
  18. * CLASS: CEventBuffer
  19. *
  20. * PURPOSE: objects this class maintains the interface locks by exposing
  21. * methods Lock(), Unlock() and IsLocked(); It also implements queue
  22. * of script events accessible thru ScEmitOrPostpone(); Events in the queue
  23. * will be automatically emited when the last lock is removed by
  24. * calling Unlock() method.
  25. *
  26. * USAGE: Object of this class are constucted as global or static variables
  27. * per each monitored interface.
  28. * Currently it is used (as static variable) by GetEventBuffer template
  29. * function and is accessed by CEventLock object put on the stack by
  30. * LockComEventInterface macro
  31. *
  32. \***************************************************************************/
  33. class MMCBASE_API CEventBuffer
  34. {
  35. // structure containing postponed script event
  36. // since it is a dipinterface call, data consists of pointer to
  37. // IDispatch interface , disp_id and the array of parameters
  38. struct DispCallStr
  39. {
  40. IDispatchPtr spDispatch;
  41. DISPID dispid;
  42. std::vector<CComVariant> vars;
  43. };
  44. // queue of postponed events
  45. std::queue<DispCallStr> m_postponed;
  46. // lock count
  47. int m_locks;
  48. public:
  49. // constructor. No locks initially
  50. CEventBuffer() : m_locks(0) {}
  51. // locking methods
  52. void Lock() { m_locks++; }
  53. void Unlock() { ASSERT(m_locks > 0); if (--m_locks == 0) ScFlushPostponed(); }
  54. bool IsLocked() { return m_locks != 0; }
  55. // event emitting / postponing
  56. SC ScEmitOrPostpone(IDispatch *pDispatch, DISPID dispid, CComVariant *pVar, int count);
  57. private:
  58. // helper emiting postponed events
  59. SC ScFlushPostponed();
  60. };
  61. /***************************************************************************\
  62. *
  63. * FUNCTION: GetEventBuffer
  64. *
  65. * PURPOSE: This function provides access to static object created in it's body
  66. * Having it as template allows us to define as many static objects as
  67. * interfaces we have.
  68. *
  69. * PARAMETERS:
  70. *
  71. * RETURNS:
  72. * CEventBuffer& - reference to the static object created inside
  73. *
  74. \***************************************************************************/
  75. MMCBASE_API CEventBuffer& GetEventBuffer();
  76. /***************************************************************************\
  77. *
  78. * CLASS: CEventLock
  79. *
  80. * PURPOSE: Template class to allow simple Lock()/Unlock() functionality
  81. * by placing instances of this class on the stack.
  82. * Constructor will put a lock on the event interface, destructor
  83. * will release it.
  84. *
  85. * USAGE: You can place the lock on stack by constructing object directly
  86. * or by using LockComEventInterface macro (which does the same)
  87. *
  88. \***************************************************************************/
  89. template <typename _dispinterface>
  90. class MMCBASE_API CEventLock
  91. {
  92. public:
  93. CEventLock() { GetEventBuffer().Lock(); }
  94. ~CEventLock() { GetEventBuffer().Unlock(); }
  95. };
  96. /***************************************************************************\
  97. *
  98. * MACRO: LockComEventInterface
  99. *
  100. * PURPOSE: Constructs the object on stack which holds a lock on event interface
  101. *
  102. \***************************************************************************/
  103. #define LockComEventInterface(_dispinterface) \
  104. CEventLock<_dispinterface> _LocalEventInterfaceLock;
  105. #endif // !defined(EVENTLOCK_H_INCLUDED)