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.
|
|
//+-------------------------------------------------------------------------
//
// 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)
|