windows-nt/Source/XPSP1/NT/admin/activec/inc/eventlock.h
2020-09-26 16:20:57 +08:00

122 lines
4 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 2000 - 2000
//
// File: eventlock.h
//
// This file contains code needed to fire script event in a safer way
// Locks made on stack will postpone firing the event on particular interface
// as long as the last lock is released.
//--------------------------------------------------------------------------
#pragma once
#if !defined(EVENTLOCK_H_INCLUDED)
#define EVENTLOCK_H_INCLUDED
/***************************************************************************\
*
* CLASS: CEventBuffer
*
* PURPOSE: objects this class maintains the interface locks by exposing
* methods Lock(), Unlock() and IsLocked(); It also implements queue
* of script events accessible thru ScEmitOrPostpone(); Events in the queue
* will be automatically emited when the last lock is removed by
* calling Unlock() method.
*
* USAGE: Object of this class are constucted as global or static variables
* per each monitored interface.
* Currently it is used (as static variable) by GetEventBuffer template
* function and is accessed by CEventLock object put on the stack by
* LockComEventInterface macro
*
\***************************************************************************/
class MMCBASE_API CEventBuffer
{
// structure containing postponed script event
// since it is a dipinterface call, data consists of pointer to
// IDispatch interface , disp_id and the array of parameters
struct DispCallStr
{
IDispatchPtr spDispatch;
DISPID dispid;
std::vector<CComVariant> vars;
};
// queue of postponed events
std::queue<DispCallStr> m_postponed;
// lock count
int m_locks;
public:
// constructor. No locks initially
CEventBuffer() : m_locks(0) {}
// locking methods
void Lock() { m_locks++; }
void Unlock() { ASSERT(m_locks > 0); if (--m_locks == 0) ScFlushPostponed(); }
bool IsLocked() { return m_locks != 0; }
// event emitting / postponing
SC ScEmitOrPostpone(IDispatch *pDispatch, DISPID dispid, CComVariant *pVar, int count);
private:
// helper emiting postponed events
SC ScFlushPostponed();
};
/***************************************************************************\
*
* FUNCTION: GetEventBuffer
*
* PURPOSE: This function provides access to static object created in it's body
* Having it as template allows us to define as many static objects as
* interfaces we have.
*
* PARAMETERS:
*
* RETURNS:
* CEventBuffer& - reference to the static object created inside
*
\***************************************************************************/
MMCBASE_API CEventBuffer& GetEventBuffer();
/***************************************************************************\
*
* CLASS: CEventLock
*
* PURPOSE: Template class to allow simple Lock()/Unlock() functionality
* by placing instances of this class on the stack.
* Constructor will put a lock on the event interface, destructor
* will release it.
*
* USAGE: You can place the lock on stack by constructing object directly
* or by using LockComEventInterface macro (which does the same)
*
\***************************************************************************/
template <typename _dispinterface>
class MMCBASE_API CEventLock
{
public:
CEventLock() { GetEventBuffer().Lock(); }
~CEventLock() { GetEventBuffer().Unlock(); }
};
/***************************************************************************\
*
* MACRO: LockComEventInterface
*
* PURPOSE: Constructs the object on stack which holds a lock on event interface
*
\***************************************************************************/
#define LockComEventInterface(_dispinterface) \
CEventLock<_dispinterface> _LocalEventInterfaceLock;
#endif // !defined(EVENTLOCK_H_INCLUDED)