windows-nt/Source/XPSP1/NT/base/cluster/admin/cluadmin/barf.cpp
2020-09-26 16:20:57 +08:00

393 lines
8.5 KiB
C++

/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1996-1997 Microsoft Corporation
//
// Module Name:
// Barf.cpp
//
// Abstract:
// Implementation of the Basic Artifical Resource Failure classes.
//
// Author:
// David Potter (davidp) April 11, 1997
//
// Revision History:
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#define _NO_BARF_DEFINITIONS_
#include "Barf.h"
#include "TraceTag.h"
#include "ExcOper.h"
#ifdef _USING_BARF_
#error BARF failures should be disabled!
#endif
#ifdef _DEBUG // The entire file!
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
/////////////////////////////////////////////////////////////////////////////
// Global Variables
/////////////////////////////////////////////////////////////////////////////
BOOL g_bFailOnNextBarf = FALSE;
CTraceTag g_tagBarf(_T("Debug"), _T("BARF Failures"), CTraceTag::tfDebug);
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
// CBarf
/////////////////////////////////////////////////////////////////////////////
BOOL CBarf::s_bGlobalEnable = TRUE;
LONG CBarf::s_nSuspend = 0;
CBarf * CBarf::s_pbarfFirst = NULL;
PFNBARFPOSTUPDATE CBarf::s_pfnPostUpdate = NULL;
PVOID CBarf::s_pvSpecialMem = NULL;
/////////////////////////////////////////////////////////////////////////////
//++
//
// CBarf::CBarf
//
// Routine Description:
// Constructor.
//
// Arguments:
// pszName [IN] Name of the set of APIs to BARF.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CBarf::CBarf(IN LPCTSTR pszName)
{
ASSERT(pszName != NULL);
m_pszName = pszName;
m_bDisabled = FALSE;
m_bContinuous = FALSE;
m_nFail = 0;
m_nCurrent = 0;
m_pbarfNext = s_pbarfFirst;
s_pbarfFirst = this;
} //*** CBarf::CBarf()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CBarf::Init
//
// Routine Description:
// Initializes the BARF counters instance by giving it its name and
// giving it a startup value (from the registry if possible).
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CBarf::Init(void)
{
CString strSection;
CString strValue;
strSection.Format(BARF_REG_SECTION_FMT, m_pszName);
m_bDisabled = AfxGetApp()->GetProfileInt(strSection, _T("Disabled"), FALSE);
m_bContinuous = AfxGetApp()->GetProfileInt(strSection, _T("Continuous"), FALSE);
m_nFail = AfxGetApp()->GetProfileInt(strSection, _T("Fail"), 0);
} //*** CBarf::Init()
/////////////////////////////////////////////////////////////////////////////
//
// CBarf::BFail
//
// Routine Description:
// Determines if the next call should artificially fail.
// Typical usage of this method is:
// BOOL BARFFoo( void )
// {
// if (barfMyApi.BFail())
// return FALSE;
// else
// return Foo();
// }
//
// Return value:
// bFail TRUE indicates the call should be made to
// artificially fail.
//
/////////////////////////////////////////////////////////////////////////////
BOOL CBarf::BFail(void)
{
BOOL bFail = FALSE;
// If BARF is suspended, don't artificially fail.
// Otherwise, check the counters.
if (s_nSuspend == 0)
{
// Increment the call count.
m_nCurrent++;
// Call the post-update routine to allow UI to be updated.
if (PfnPostUpdate())
((*PfnPostUpdate())());
// If not disable and not globally disabled, keep checking.
if (!m_bDisabled && s_bGlobalEnable)
{
// If in continuous fail mode, check to see if the counters
// are above the specified range. Otherwise check to see if
// the counter is exactly the same as what was specified.
if (m_bContinuous)
{
if (m_nCurrent >= m_nFail)
bFail = TRUE;
} // if: in continuous fail mode
else
{
if (m_nCurrent == m_nFail)
bFail = TRUE;
} // else: not in continuous fail mode
// If this API set was marked to fail on the next (this) call,
// fail the call and reset the marker.
if (g_bFailOnNextBarf)
{
bFail = TRUE;
g_bFailOnNextBarf = FALSE;
} // if: counters marked to fail on next (this) call
} // if: not disabled and globally enabled
} // if: not suspended
return bFail;
} //*** CBarf::BFail()
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
// CBarfSuspend
/////////////////////////////////////////////////////////////////////////////
CRITICAL_SECTION CBarfSuspend::s_critsec;
BOOL CBarfSuspend::s_bCritSecValid = FALSE;
/////////////////////////////////////////////////////////////////////////////
//++
//
// CBarfSuspend::CBarfSuspend
//
// Routine Description:
// Constructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CBarfSuspend::CBarfSuspend(void)
{
if (BCritSecValid())
EnterCriticalSection(Pcritsec());
CBarf::s_nSuspend++;
if (BCritSecValid())
LeaveCriticalSection(Pcritsec());
} //*** CBarfSuspend::CBarfSuspend()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CBarfSuspend::~CBarfSuspend
//
// Routine Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CBarfSuspend::~CBarfSuspend(void)
{
if (BCritSecValid())
EnterCriticalSection(Pcritsec());
CBarf::s_nSuspend--;
ASSERT(CBarf::s_nSuspend >= 0);
if (BCritSecValid())
LeaveCriticalSection(Pcritsec());
} //*** CBarfSuspend::~CBarfSuspend()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CBarfSuspend::Init
//
// Routine Description:
// Initialize the class.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CBarfSuspend::Init(void)
{
InitializeCriticalSection(Pcritsec());
s_bCritSecValid = TRUE;
} //*** CBarfSuspend::Init()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CBarfSuspend::Cleanup
//
// Routine Description:
// Initialize the class.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CBarfSuspend::Cleanup(void)
{
if (BCritSecValid())
{
DeleteCriticalSection(Pcritsec());
s_bCritSecValid = FALSE;
} // if: critical section is valid
} //*** CBarfSuspend::Cleanup()
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
// Global Functions
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// InitBarf
//
// Routine Description:
// Initializes all BARF counters in the BARF list.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void InitBarf(void)
{
CBarf * pbarf;
// Loop through the BARF counter list.
for (pbarf = CBarf::s_pbarfFirst ; pbarf != NULL ; pbarf = pbarf->m_pbarfNext)
pbarf->Init();
CBarfSuspend::Init();
} //*** InitBarf()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CleanupBarf
//
// Routine Description:
// Cleanup after BARF.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CleanupBarf(void)
{
CBarfSuspend::Cleanup();
} //*** CleanupBarf()
/////////////////////////////////////////////////////////////////////////////
//++
//
// EnableBarf
//
// Routine Description:
// Allows user code to enable/disable BARF for sections of code.
//
// Arguments:
// bEnable [IN] TRUE = enable BARF, FALSE = disable BARF.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void EnableBarf(IN BOOL bEnable)
{
if (bEnable)
Trace(g_tagBarf, _T("Artificial Failures enabled"));
else
Trace(g_tagBarf, _T("Artificial Failures disabled"));
CBarf::s_bGlobalEnable = bEnable;
} //*** EnableBarf()
#endif // _DEBUG