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