windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/upssvc/apcsmart/apcsemnt.cxx
2020-09-26 16:20:57 +08:00

148 lines
3.8 KiB
C++

/*
*
* NOTES:
*
* REVISIONS:
* jwa 09FEB92 creation
* pcy21Apr93: OS2 FE merge
* pcy08Apr94: Trim size, use static iterators, dead code removal
* srt21Jun96: Added named shared event type semaphores
* mwh27Jan97: add this pointer to semaphore name in default ctor, needed
* to help with semaphores being used in a DLL and a client
* to a DLL. The DLL and the client each get their own copy
* of SemKey, but the memory addresses will be unique
*/
#include "cdefine.h"
#if (C_OS & C_NT)
#include <windows.h>
#include <stdio.h>
#endif
#include "err.h"
#include "apcsemnt.h"
INT SemKey = 0;
//-------------------------------------------------------------------------
// The semaphore is created as unnamed and shared
//
ApcSemaphore::ApcSemaphore(VOID) :
Semaphore()
{
SetObjectStatus(ErrNO_ERROR);
// unnamed semaphore, shared and
TCHAR cBuffer[128];
// add use of this pointer in the name - the memory address will be
// unique throughout this process, including any DLL's that are mapped
// in. This ocurred because if a DLL uses ApcSemaphore, and a client
// of the DLL also uses ApcSemaphore they each have their own copy of
// SemKey, meaning it is possible, and likely that when the DLL makes
// use of this CTOR, and the client makes use of this CTOR that they
// will map to the same name, therefore you will get two ApcSemaphore
// objects that both reference the same event. By adding the this
// pointer each event should be unique
_stprintf(cBuffer,_TEXT("%ld%ld_%d_%ld"),GetCurrentProcessId(),GetCurrentThreadId(),
SemKey,this);
SemKey++;
SemHand=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,
TRUE, // Manual Reset
FALSE, // Initial State
cBuffer);
if(!SemHand){
SetObjectStatus(ErrSEM_CREATE_FAILED);
}
}
//-------------------------------------------------------------------------
//
ApcSemaphore::ApcSemaphore(TCHAR * cBuffer) //named shared event
{
SemHand=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,
FALSE, // Manual Reset
FALSE, // Initial State
cBuffer);
if(!SemHand){
SetObjectStatus(ErrSEM_CREATE_FAILED);
}
}
//-------------------------------------------------------------------------
//
ApcSemaphore::~ApcSemaphore()
{
CloseHandle(SemHand);
}
//-------------------------------------------------------------------------
//
INT ApcSemaphore::Post(VOID)
{
INT err = ErrNO_ERROR;
if(!SetEvent(SemHand))
err= ErrSEM_GENERAL_ERROR;
return err;
}
//-------------------------------------------------------------------------
//
INT ApcSemaphore::Clear(VOID)
{
INT err = ErrNO_ERROR;
if(!ResetEvent(SemHand))
err = ErrSEM_GENERAL_ERROR;
return err;
}
//-------------------------------------------------------------------------
//
INT ApcSemaphore::IsPosted(VOID)
{
// Could also call TimedWait(0)
//
INT ret = ErrSEM_BLOCK_NG;
DWORD waitresult = WaitForSingleObject(SemHand,(DWORD)0);
if(waitresult == WAIT_TIMEOUT)
ret = ErrNO_ERROR;
return ret;
}
//-------------------------------------------------------------------------
// Wait for sem to be posted
//
// ulTimeout: 0 - Don't wait at all
// <0 - Wait forever (same as Wait())
// >0 - Wait for ulTimeout milliseconds
//
INT ApcSemaphore::TimedWait(LONG ulTimeout)
{
INT err;
DWORD time_out = (ulTimeout < 0) ? INFINITE : ulTimeout;
DWORD waitresult=WaitForSingleObject(SemHand,time_out);
if(waitresult == 0){
err = ErrNO_ERROR;
}
else if (waitresult == WAIT_TIMEOUT) {
err = ErrSEM_TIMED_OUT;
}
else {
err = ErrSEM_GENERAL_ERROR;
}
return err;
}