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.
 
 
 
 
 
 

299 lines
5.1 KiB

/*++
Copyright (C) Microsoft Corporation, 1994 - 1998
All rights reserved.
Module Name:
notify.hxx
Abstract:
Holds notify definitions
Author:
Albert Ting (AlbertT) 13-Dec-1994
Revision History:
Lazar Ivanov (LazarI) Nov-20-2000, major redesign
--*/
#ifndef _NOTIFY_HXX
#define _NOTIFY_HXX
class MNotifyWork;
/********************************************************************
TNotify
Generally a singleton class that handles all registration of
MNotifyWork.
********************************************************************/
class TNotify: public MRefCom
{
friend MNotifyWork;
SIGNATURE( 'ntfy' )
SAFE_NEW
public:
TNotify(
VOID
);
VOID
vDelete(
VOID
);
BOOL
bValid(
VOID
) const
{
return _shEventProcessed && VALID_BASE( MRefCom );
}
STATUS
sRegister(
MNotifyWork* pNotifyWork
);
STATUS
sUnregister(
MNotifyWork* pNotifyWork
);
BOOL
bSuspendCallbacks(
VOID
);
VOID
vResumeCallbacks(
VOID
);
VAR(CCSLock, csResumeSuspend);
private:
enum EOPERATION
{
kEopRegister = 1,
kEopUnregister = 2,
kEopModify = 3,
kEopSuspendRequest = 4,
kEopResumeRequest = 5,
kEopExitRequest = 6,
};
enum _CONSTANTS
{
//
// Minimum interval at which objects get signaled.
//
kSleepTime = 1000,
};
/********************************************************************
The TWait class handles waiting on the group of objects.
Since there are a maximum of 32 wait handles per thread
(in WaitForMultipleObjects), we must create multiple threads.
Each TWait handles one thread.
********************************************************************/
class TWait
{
public:
enum _CONSTANTS
{
kNotifyWorkMax = MAXIMUM_WAIT_OBJECTS-1
};
TWait(
TNotify* pNotify
);
~TWait(
VOID
);
//
// Accessed only by vRun thread. If we are modifying,
// then we are in the critical section.
//
DLINK( TWait, Wait );
VAR( TRefLock<TNotify>, pNotify );
COUNT _cNotifyWork;
HANDLE _ahNotifyArea[kNotifyWorkMax + 1];
MNotifyWork* _apNotifyWork[kNotifyWorkMax];
CAutoHandleNT _shThread;
PHANDLE
phNotifys(
VOID
)
{
return &_ahNotifyArea[1];
}
BOOL
bValid(
VOID
) const
{
return _ahNotifyArea[0] ? TRUE : FALSE;
}
BOOL
bFull(
VOID
) const
{
return _cNotifyWork == kNotifyWorkMax;
}
VOID
vProcessOperation(
VOID
);
static
VOID
vRun(
TWait* pWait
);
};
struct CS_GUARD
{
//
// protected by _CritSec, and _shEventProcessed
//
MNotifyWork* _pNotifyWork;
EOPERATION _eOperation;
DLINK_BASE( TWait, Wait, Wait );
BOOL _bSuspended;
} CSGuard;
DWORD _dwSleepTime;
CAutoHandleNT _shEventProcessed;
CCSLock _CritSec;
//
// Defined as private since clients must use vDelete().
//
~TNotify(
VOID
);
VOID
vSendRequest(
TWait* pWait
);
VOID
vExecuteOperation(
MNotifyWork* pNotifyWork,
TWait* pWait,
EOPERATION eOp
);
STATUS
sFindOrCreateWaitObject(
TWait **ppWait
);
//
// Virtual definition for MRefCom.
//
VOID
vRefZeroed(
VOID
);
friend TNotify::TWait;
};
/********************************************************************
MNotifyWork
This represents the work object that has a handle and needs
to be notified when the handle is signaled.
Clients should inherit from this class and override
hEvent() - returns event to be watched
vProcessNotifyWork() - quickly processes and resets event
********************************************************************/
class MNotifyWork
{
friend TNotify;
friend TNotify::TWait;
SIGNATURE( 'nfwk' )
ALWAYS_VALID
SAFE_NEW
public:
MNotifyWork(
VOID
) : _pWait( NULL )
{}
virtual
~MNotifyWork(
VOID
);
private:
//
// Indicates which TWait owns it. If NULL, not owned.
//
TNotify::TWait* _pWait;
//
// Retrieves the event handle associated with this object.
// This handle will be waited on and when it is signaled,
// vProcessNotifyWork will be called.
//
virtual
HANDLE
hEvent(
VOID
) const = 0;
//
// Called when hEvent() is signaled. This routine must
// return quickly.
//
virtual
VOID
vProcessNotifyWork(
TNotify* pNotify
) = 0;
};
#endif // ndef _NOTIFY_HXX