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.

135 lines
4.1 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000 - 2000
  6. //
  7. // File: eventlock.cpp
  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. #include "stdafx.h"
  14. #include <comdef.h>
  15. #include <vector>
  16. #include <queue>
  17. #include "eventlock.h"
  18. #include "mmcobj.h"
  19. // since the templates will be used from outside the library
  20. // we need to instantiale them explicitly in order to get them exported
  21. template class CEventLock<AppEvents>;
  22. /***************************************************************************\
  23. *
  24. * METHOD: CEventBuffer::ScEmitOrPostpone
  25. *
  26. * PURPOSE: The method will add methods to the queue. If interface is not locked
  27. * it will emit it immediately, else it will postpone it till appropriate
  28. * call to Unlock()
  29. *
  30. * PARAMETERS:
  31. * IDispatch *pDispatch - sink interface to receive the event
  32. * DISPID dispid - method's disp id
  33. * CComVariant *pVar - array of arguments to method call
  34. * int count - count of arguments in the array
  35. *
  36. * RETURNS:
  37. * SC - result code
  38. *
  39. \***************************************************************************/
  40. SC CEventBuffer::ScEmitOrPostpone(IDispatch *pDispatch, DISPID dispid, CComVariant *pVar, int count)
  41. {
  42. DECLARE_SC(sc, TEXT("CEventBuffer::ScEmitOrPostpone"));
  43. // construct the postponed data
  44. DispCallStr call_data;
  45. call_data.spDispatch = pDispatch;
  46. call_data.dispid = dispid;
  47. call_data.vars.insert(call_data.vars.begin(), pVar, pVar + count);
  48. // store the data for future use
  49. m_postponed.push(call_data);
  50. // emit rigt away if not locked
  51. if (!IsLocked())
  52. sc = ScFlushPostponed();
  53. return sc;
  54. }
  55. /***************************************************************************\
  56. *
  57. * METHOD: CEventBuffer::ScFlushPostponed
  58. *
  59. * PURPOSE: method will invoke all events currently in it's queue
  60. *
  61. * PARAMETERS:
  62. *
  63. * RETURNS:
  64. * SC - result code
  65. *
  66. \***************************************************************************/
  67. SC CEventBuffer::ScFlushPostponed()
  68. {
  69. DECLARE_SC(sc, TEXT("CEventBuffer::ScFlushPostponed"));
  70. SC sc_last_error;
  71. // for each event in queue
  72. while (m_postponed.size())
  73. {
  74. // ectract event from the queue
  75. DispCallStr call_data = m_postponed.front();
  76. m_postponed.pop();
  77. // check the dispatch pointer
  78. sc = ScCheckPointers(call_data.spDispatch, E_POINTER);
  79. if (sc)
  80. {
  81. sc_last_error = sc; // continue even if some calls failed
  82. sc.TraceAndClear();
  83. continue;
  84. }
  85. // construct parameter structure
  86. CComVariant varResult;
  87. DISPPARAMS disp = { call_data.vars.begin(), NULL, call_data.vars.size(), 0 };
  88. // invoke the method on event sink
  89. sc = call_data.spDispatch->Invoke(call_data.dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
  90. if (sc)
  91. {
  92. sc_last_error = sc; // continue even if some calls failed
  93. sc.TraceAndClear();
  94. continue;
  95. }
  96. // event methods should not return any values.
  97. // but even if the do (thru varResult) - we do not care, just ignore that.
  98. }
  99. // will return sc_last_error (not sc - we already traced it)
  100. return sc_last_error;
  101. }
  102. /***************************************************************************\
  103. *
  104. * FUNCTION: GetEventBuffer
  105. *
  106. * PURPOSE: This function provides access to static object created in it's body
  107. * Having it as template allows us to define as many static objects as
  108. * interfaces we have.
  109. *
  110. * PARAMETERS:
  111. *
  112. * RETURNS:
  113. * CEventBuffer& - reference to the static object created inside
  114. *
  115. \***************************************************************************/
  116. MMCBASE_API CEventBuffer& GetEventBuffer()
  117. {
  118. static CEventBuffer buffer;
  119. return buffer;
  120. }