195 lines
4.2 KiB
C
195 lines
4.2 KiB
C
//============================================================================
|
|
// Copyright (c) 1996, Microsoft Corporation
|
|
//
|
|
// File: sync.c
|
|
//
|
|
// History:
|
|
// Abolade Gbadegesin Jan-12-1996 Created.
|
|
//
|
|
// Synchronization routines used by IPBOOTP.
|
|
//============================================================================
|
|
|
|
|
|
#include "pchbootp.h"
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: QueueBootpWorker
|
|
//
|
|
// This function is called to queue a BOOTP function in a safe fashion;
|
|
// if cleanup is in progress or if RIP has stopped, this function
|
|
// discards the work-item.
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD
|
|
QueueBootpWorker(
|
|
WORKERFUNCTION pFunction,
|
|
PVOID pContext
|
|
) {
|
|
|
|
DWORD dwErr = NO_ERROR;
|
|
|
|
EnterCriticalSection(&ig.IG_CS);
|
|
|
|
if (ig.IG_Status != IPBOOTP_STATUS_RUNNING) {
|
|
|
|
//
|
|
// cannot queue a work function when RIP has quit or is quitting
|
|
//
|
|
|
|
dwErr = ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
else {
|
|
|
|
BOOL bSuccess;
|
|
|
|
++ig.IG_ActivityCount;
|
|
|
|
bSuccess = QueueUserWorkItem(
|
|
(LPTHREAD_START_ROUTINE)pFunction,
|
|
pContext, 0
|
|
);
|
|
|
|
if (!bSuccess) {
|
|
dwErr = GetLastError();
|
|
--ig.IG_ActivityCount;
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&ig.IG_CS);
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: EnterBootpAPI
|
|
//
|
|
// This function is called to when entering a BOOTP api, as well as
|
|
// when entering the input thread and timer thread.
|
|
// It checks to see if BOOTP has stopped, and if so it quits; otherwise
|
|
// it increments the count of active threads.
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
EnterBootpAPI(
|
|
) {
|
|
|
|
BOOL bEntered;
|
|
|
|
EnterCriticalSection(&ig.IG_CS);
|
|
|
|
if (ig.IG_Status == IPBOOTP_STATUS_RUNNING) {
|
|
|
|
//
|
|
// BOOTP is running, so the API may continue
|
|
//
|
|
|
|
++ig.IG_ActivityCount;
|
|
|
|
bEntered = TRUE;
|
|
}
|
|
else {
|
|
|
|
//
|
|
// BOOTP is not running, so the API exits quietly
|
|
//
|
|
|
|
bEntered = FALSE;
|
|
}
|
|
|
|
LeaveCriticalSection(&ig.IG_CS);
|
|
|
|
return bEntered;
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: EnterBootpWorker
|
|
//
|
|
// This function is called when entering a BOOTP 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 BOOTP has stopped or is stopping;
|
|
// if this is the case, then it decrements the activity count,
|
|
// releases the activity semaphore, and quits.
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
EnterBootpWorker(
|
|
) {
|
|
|
|
BOOL bEntered;
|
|
|
|
EnterCriticalSection(&ig.IG_CS);
|
|
|
|
if (ig.IG_Status == IPBOOTP_STATUS_RUNNING) {
|
|
|
|
//
|
|
// BOOTP is running, so the function may continue
|
|
//
|
|
|
|
bEntered = TRUE;
|
|
}
|
|
else
|
|
if (ig.IG_Status == IPBOOTP_STATUS_STOPPING) {
|
|
|
|
//
|
|
// BOOTP is not running, but it was, so the function must stop.
|
|
//
|
|
|
|
--ig.IG_ActivityCount;
|
|
|
|
ReleaseSemaphore(ig.IG_ActivitySemaphore, 1, NULL);
|
|
|
|
bEntered = FALSE;
|
|
}
|
|
else {
|
|
|
|
//
|
|
// BOOTP probably never started. quit quietly
|
|
//
|
|
|
|
bEntered = FALSE;
|
|
}
|
|
|
|
LeaveCriticalSection(&ig.IG_CS);
|
|
|
|
return bEntered;
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: LeaveBootpWorker
|
|
//
|
|
// This function is called when leaving a BOOTP API or worker function.
|
|
// It decrements the activity count, and if it detects that BOOTP has stopped
|
|
// or is stopping, it releases the activity semaphore.
|
|
//----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
LeaveBootpWorker(
|
|
) {
|
|
|
|
EnterCriticalSection(&ig.IG_CS);
|
|
|
|
--ig.IG_ActivityCount;
|
|
|
|
if (ig.IG_Status == IPBOOTP_STATUS_STOPPING) {
|
|
|
|
ReleaseSemaphore(ig.IG_ActivitySemaphore, 1, NULL);
|
|
}
|
|
|
|
LeaveCriticalSection(&ig.IG_CS);
|
|
|
|
}
|
|
|
|
|