mirror of https://github.com/tongzx/nt5src
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.
205 lines
4.3 KiB
205 lines
4.3 KiB
/*++
|
|
|
|
Copyright (c) 1999, Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sample\utils.c
|
|
|
|
Abstract:
|
|
|
|
The file contains miscellaneous utilities.
|
|
|
|
--*/
|
|
|
|
|
|
#include "pchsample.h"
|
|
#pragma hdrstop
|
|
|
|
DWORD
|
|
QueueSampleWorker(
|
|
IN WORKERFUNCTION pfnFunction,
|
|
IN PVOID pvContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
This function is called to queue a worker function in a safe fashion;
|
|
if cleanup is in progress or if SAMPLE has stopped, this function
|
|
discards the work-item.
|
|
|
|
Locks
|
|
Acquires exclusively g_ce.rwlLock
|
|
Releases g_ce.rwlLock
|
|
|
|
Arguments
|
|
pfnFunction function to be called
|
|
pvContext opaque ptr used in callback
|
|
|
|
Return Value
|
|
NO_ERROR if success
|
|
Failure code o/w
|
|
|
|
--*/
|
|
{
|
|
DWORD dwErr = NO_ERROR;
|
|
BOOL bSuccess = FALSE;
|
|
|
|
ACQUIRE_WRITE_LOCK(&(g_ce.rwlLock));
|
|
|
|
do // breakout loop
|
|
{
|
|
// cannot queue a work function when SAMPLE has quit or is quitting
|
|
if (g_ce.iscStatus != IPSAMPLE_STATUS_RUNNING)
|
|
{
|
|
dwErr = ERROR_CAN_NOT_COMPLETE;
|
|
break;
|
|
}
|
|
|
|
bSuccess = QueueUserWorkItem((LPTHREAD_START_ROUTINE)pfnFunction,
|
|
pvContext,
|
|
0); // no flags
|
|
if (bSuccess)
|
|
g_ce.ulActivityCount++;
|
|
else
|
|
dwErr = GetLastError();
|
|
} while (FALSE);
|
|
|
|
RELEASE_WRITE_LOCK(&(g_ce.rwlLock));
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
EnterSampleAPI(
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
This function is called when entering a SAMPLE api, as well as when
|
|
entering the input thread and timer thread. It checks to see if SAMPLE
|
|
has stopped, and if so it quits; otherwise it increments the count of
|
|
active threads.
|
|
|
|
Locks
|
|
Acquires exclusively g_ce.rwlLock
|
|
Releases g_ce.rwlLock
|
|
|
|
Arguments
|
|
None
|
|
|
|
Return Value
|
|
TRUE if entered successfully
|
|
FALSE o/w
|
|
|
|
--*/
|
|
{
|
|
BOOL bEntered = FALSE;
|
|
|
|
ACQUIRE_WRITE_LOCK(&(g_ce.rwlLock));
|
|
|
|
if (g_ce.iscStatus is IPSAMPLE_STATUS_RUNNING)
|
|
{
|
|
// SAMPLE is running, so continue
|
|
g_ce.ulActivityCount++;
|
|
bEntered = TRUE;
|
|
}
|
|
|
|
RELEASE_WRITE_LOCK(&(g_ce.rwlLock));
|
|
|
|
return bEntered;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
EnterSampleWorker(
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
This function is called when entering a SAMPLE worker-function. Since
|
|
there is a lapse between the time a worker-function is queued and the
|
|
time the function is actually invoked by a worker thread, this function
|
|
must check to see if SAMPLE has stopped or is stopping; if this is the
|
|
case, then it decrements the activity count, releases the activity
|
|
semaphore, and quits.
|
|
|
|
Locks
|
|
Acquires exclusively g_ce.rwlLock
|
|
Releases g_ce.rwlLock
|
|
|
|
Arguments
|
|
None
|
|
|
|
Return Value
|
|
TRUE if entered successfully
|
|
FALSE o/w
|
|
|
|
--*/
|
|
{
|
|
BOOL bEntered = FALSE;
|
|
|
|
ACQUIRE_WRITE_LOCK(&(g_ce.rwlLock));
|
|
|
|
do // breakout loop
|
|
{
|
|
// SAMPLE is running, so the function may continue
|
|
if (g_ce.iscStatus is IPSAMPLE_STATUS_RUNNING)
|
|
{
|
|
bEntered = TRUE;
|
|
break;
|
|
}
|
|
|
|
// SAMPLE is not running, but it was, so the function must stop
|
|
if (g_ce.iscStatus is IPSAMPLE_STATUS_STOPPING)
|
|
{
|
|
g_ce.ulActivityCount--;
|
|
ReleaseSemaphore(g_ce.hActivitySemaphore, 1, NULL);
|
|
break;
|
|
}
|
|
|
|
// SAMPLE probably never started. quit
|
|
} while (FALSE);
|
|
|
|
RELEASE_WRITE_LOCK(&(g_ce.rwlLock));
|
|
|
|
return bEntered;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
LeaveSampleWorker(
|
|
)
|
|
/*++
|
|
|
|
Routine Description
|
|
This function is called when leaving a SAMPLE api or worker function.
|
|
It decrements the activity count, and if it detects that SAMPLE has
|
|
stopped or is stopping, it releases the activity semaphore.
|
|
|
|
Locks
|
|
Acquires exclusively g_ce.rwlLock
|
|
Releases g_ce.rwlLock
|
|
|
|
Arguments
|
|
None
|
|
|
|
Return Value
|
|
TRUE if entered successfully
|
|
FALSE o/w
|
|
|
|
--*/
|
|
{
|
|
ACQUIRE_WRITE_LOCK(&(g_ce.rwlLock));
|
|
|
|
g_ce.ulActivityCount--;
|
|
|
|
if (g_ce.iscStatus is IPSAMPLE_STATUS_STOPPING)
|
|
ReleaseSemaphore(g_ce.hActivitySemaphore, 1, NULL);
|
|
|
|
RELEASE_WRITE_LOCK(&(g_ce.rwlLock));
|
|
}
|