windows-nt/Source/XPSP1/NT/inetsrv/query/h/psavtrak.hxx
2020-09-26 16:20:57 +08:00

201 lines
5.1 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1997.
//
// File: psavtrak.hxx
//
// Contents: A pure virtual class to indicate progress in a save content-index
// operation. The save consists of two parts:
//
// 1. Merge Operation
// 2. Copying the index data
//
// This class also permits communicating an aout
// Classes: PSaveProgressTracker
//
// History: 3-18-97 srikants Created
//
//----------------------------------------------------------------------------
#pragma once
//+---------------------------------------------------------------------------
//
// Class: PSaveProgressTracker
//
// Purpose: A pure virtual class for indicating progress and communicating
// abort of a long operation.
//
// History: 3-18-97 srikants Created
//
//----------------------------------------------------------------------------
class PSaveProgressTracker
{
public:
virtual void UpdateMergeProgress( ULONG ulNumerator, ULONG ulDenominator ) = 0;
virtual void UpdateCopyProgress( ULONG ulNumerator, ULONG ulDenominator ) = 0;
virtual void GetProgress( ULONG & ulNumerator, ULONG & ulDenominator ) = 0;
virtual void SetAbort() = 0;
virtual BOOL IsAbort() = 0;
};
//+---------------------------------------------------------------------------
//
// Class: CProgressTracker
//
// Purpose: An implementation of the PSaveProgressTracker using the
// IProgressNotify interface.
//
// History: 3-20-97 srikants Created
//
//----------------------------------------------------------------------------
class CProgressTracker : public PSaveProgressTracker
{
public:
CProgressTracker()
: _fAbort(FALSE),
_fTracking(FALSE),
_ulNumerator(0),
_ulDenominator(1),
_pfClientAbort(0),
_pProgressNotify(0)
{
_evt.Set();
}
~CProgressTracker()
{
Win4Assert( 0 == _pfClientAbort );
Win4Assert( 0 == _pProgressNotify );
Win4Assert( !_fTracking );
}
//
// Assuming that it will be called from within an outer lock.
//
void LokStartTracking( IProgressNotify * pNotify = 0,
BOOL const * pfClientAbort = 0 )
{
_pProgressNotify = pNotify;
if ( 0 == pfClientAbort )
_pfClientAbort = &_fAbort;
else _pfClientAbort = pfClientAbort;
_ulNumerator = 0;
_ulDenominator = 1;
_fAbort = FALSE;
_fTracking = TRUE;
_evt.Reset();
}
//
// Assuming that it will be called from within an outer lock.
//
void LokStopTracking()
{
_pProgressNotify = 0;
_pfClientAbort = 0;
_fTracking = FALSE;
_fAbort = FALSE;
_evt.Set();
}
BOOL LokIsTracking() const
{
return _fTracking;
}
void WaitForCompletion()
{
_evt.Wait();
}
//
// I have assumed that merge and copy are 50% each. If we see that
// Merge is a much bigger portion, we have to adjust these numbers.
//
virtual void UpdateMergeProgress( ULONG ulNumerator, ULONG ulDenominator )
{
//
// Assume that Merge is half the work.
//
_UpdateProgress( ulNumerator, ulDenominator * 2 );
}
virtual void UpdateCopyProgress( ULONG ulNumerator, ULONG ulDenominator )
{
//
// Progress = num/(2*denom) + 1/2
// = (num + denom)/2*denom
_UpdateProgress( (ulNumerator+ulDenominator) , 2*ulDenominator );
}
virtual void GetProgress( ULONG & ulNumerator, ULONG & ulDenominator )
{
ulNumerator = _ulNumerator;
ulDenominator = _ulDenominator;
}
virtual void SetAbort()
{
_fAbort = TRUE;
}
virtual BOOL IsAbort()
{
return _fAbort || (*_pfClientAbort);
}
private:
BOOL _fAbort; // Abort controlled by us.
BOOL _fTracking; // Is there an active tracking
ULONG _ulNumerator;
ULONG _ulDenominator;
CEventSem _evt;
BOOL const * _pfClientAbort; // Abort controlled by the client
IProgressNotify * _pProgressNotify;
void _UpdateProgress( ULONG ulNumerator, ULONG ulDenominator )
{
Win4Assert( _fTracking );
Win4Assert( 0 != ulDenominator );
_ulNumerator = ulNumerator;
_ulDenominator = ulDenominator;
ciDebugOut(( DEB_ERROR,
"Save Progress = %d percent\n",
(_ulNumerator*100)/_ulDenominator ));
if ( _pProgressNotify )
{
_pProgressNotify->OnProgress(
(DWORD) _ulNumerator,
(DWORD) _ulDenominator,
FALSE, // Not accurate
FALSE // Ownership of Blocking Behavior
);
}
}
};