Leaked source code of windows server 2003
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.
|
|
/*****************************************************************/ /** Microsoft Windows for Workgroups **/ /** Copyright (C) Microsoft Corp., 1993-1994 **/ /*****************************************************************/
/* npcrit.c -- Implementation of critical section classes.
* * History: * 11/01/93 gregj Created */
#include "npcommon.h"
#include <npcrit.h>
#include <npassert.h>
/*
* Very simple interlock routines, used to stop race conditions when * initializing and de-initializing critical sections. Do NOT use * these for anything other than infrequent extremely short-term locks, * since WaitForInterlock contains a spin loop with a millisecond delay! */ BYTE InterlockedSet(volatile BYTE *pByte) { BYTE bRet; _asm { mov edi, pByte mov al, 1 xchg [edi], al /* store non-zero value, get what was there before */ mov bRet, al } return bRet; }
void WaitForInterlock(volatile BYTE *pByte) { for (;;) { BYTE bAlreadyOwned = InterlockedSet(pByte); /* attempt to grab the interlock */ if (!bAlreadyOwned) /* is someone else in there? */ break; /* nope, we now own it */ Sleep(1); /* yield to whomever owns it, then try again */ } }
void ReleaseInterlock(volatile BYTE *pByte) { *pByte = 0; /* clear the interlock to release others */ }
#if 0
// Remove CRITSEC code but keep for a while before deleting.
/*******************************************************************
NAME: CRITSEC::Init
SYNOPSIS: Initializes a global critical section object
ENTRY: pszName - name for the critical section
EXIT: No return value
NOTES: Currently pszName is not used; it will be used for named mutexes later.
HISTORY: gregj 11/01/93 Created
********************************************************************/
void CRITSEC::Init(char *pszName) { WaitForInterlock(&_bInterlock); if (!_fInitialized) { ::InitializeCriticalSection(&_critsec); #ifdef DEBUG
_wClaimCount = 0; #endif
_fInitialized = 1; } ReleaseInterlock(&_bInterlock); _cClients++; }
/*******************************************************************
NAME: CRITSEC::Term
SYNOPSIS: Cleans up resources allocated for a critical section
ENTRY: No parameters
EXIT: No return value
NOTES: This function should be callled at process attach. It will take care of making sure it only deletes the critical section when the last process using it calls Term().
HISTORY: gregj 11/01/93 Created
********************************************************************/
void CRITSEC::Term() { WaitForInterlock(&_bInterlock); BOOL fShouldCleanUp = (--_cClients == 0); if (fShouldCleanUp) { ::DeleteCriticalSection(&_critsec); _fInitialized = 0; } ReleaseInterlock(&_bInterlock); }
#ifdef DEBUG /* in retail, these are inline */
/*******************************************************************
NAME: CRITSEC::Enter
SYNOPSIS: Enters a critical section
ENTRY: No parameters
EXIT: No return value; critical section is owned by the calling thread
NOTES: This function is private, and is invoked indirectly by the friend class TAKE_CRITSEC.
HISTORY: gregj 11/01/93 Created
********************************************************************/
void CRITSEC::Enter() { #ifdef DEBUG
UIASSERT(_fInitialized != 0); #endif
::EnterCriticalSection(&_critsec);
#ifdef DEBUG
_wClaimCount++; #endif
}
/*******************************************************************
NAME: CRITSEC::Leave
SYNOPSIS: Leaves a critical section
ENTRY: No parameters
EXIT: No return value; critical section is released
NOTES: This function is private, and is invoked indirectly by the friend class TAKE_CRITSEC.
HISTORY: gregj 11/01/93 Created
********************************************************************/
void CRITSEC::Leave() { #ifdef DEBUG
UIASSERT(_fInitialized != 0); UIASSERT(_wClaimCount > 0); _wClaimCount--; #endif
::LeaveCriticalSection(&_critsec); } #endif /* DEBUG */
#endif /* 0 */
|