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.
|
|
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999-2001 Microsoft Corporation
//
// Module Name:
// CActionList.cpp
//
// Description:
// Contains the definition of the CActionList class.
//
// Maintained By:
// David Potter (DavidP) 14-JUN-2001
// Vij Vasu (Vvasu) 08-MAR-2000
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Include Files
//////////////////////////////////////////////////////////////////////////////
// The precompiled header.
#include "Pch.h"
// For the CActionList class
#include "CActionList.h"
//////////////////////////////////////////////////////////////////////////////
//++
//
// CActionList::CActionList
//
// Description:
// Default constructor of the CActionList class
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any exceptions thrown by CList::CList()
//
//--
//////////////////////////////////////////////////////////////////////////////
CActionList::CActionList( void ) { TraceFunc( "" );
SetRollbackPossible( true );
TraceFuncExit();
} //*** CActionList::CActionList
//////////////////////////////////////////////////////////////////////////////
//++
//
// CActionList::~CActionList
//
// Description:
// Default destructor of the CActionList class. Deletes all the pointers
// in the list.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any exceptions thrown by CList::CList()
//
//--
//////////////////////////////////////////////////////////////////////////////
CActionList::~CActionList( void ) { TraceFunc( "" );
ActionPtrList::CIterator apliFirst = m_aplPendingActions.CiBegin(); ActionPtrList::CIterator apliCurrent = m_aplPendingActions.CiEnd();
while ( apliCurrent != apliFirst ) { --apliCurrent;
// Delete this action.
delete (*apliCurrent); }
TraceFuncExit();
} //*** CActionList::~CActionList
//////////////////////////////////////////////////////////////////////////////
//++
//
// CActionList::Commit
//
// Description:
// Commit this action list. This method iterates through the list
// sequentially and commits each action in the list in turn.
//
// If the commits of any of the actions throws an exeption, then all the
// previously committed actions are rolled back. This exception is then
// thrown back up.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any that are thrown by the contained actions.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CActionList::Commit( void ) { TraceFunc( "" );
// Iterator positioned at the first uncommitted action just past the last committed action.
ActionPtrList::CIterator apliFirstUncommitted = m_aplPendingActions.CiBegin();
// Call the base class commit method.
BaseClass::Commit();
try { // Walk the list of pending actions and commit them.
CommitList( apliFirstUncommitted );
} // try:
catch( ... ) { // If we are here, then something went wrong with one of the actions.
LogMsg( "[BC] Caught an exception during commit. The performed actions will be rolled back." );
//
// Rollback all committed actions in the reverse order. apliFirstUncommitted
// is at the first uncommitted action.
// Catch any exceptions thrown during rollback to make sure that there
// is no collided unwind.
//
try { RollbackCommitted( apliFirstUncommitted ); } catch( ... ) { //
// The rollback of the committed actions has failed.
// There is nothing that we can do, is there?
// We certainly cannot rethrow this exception, since
// the exception that caused the rollback is more important.
//
HRESULT_FROM_WIN32( TW32( ERROR_CLUSCFG_ROLLBACK_FAILED ) );
LogMsg( "[BC] THIS COMPUTER MAY BE IN AN INVALID STATE. Caught an exception during rollback. Rollback will be aborted." );
} // catch: all
// Rethrow the exception thrown by commit.
throw;
} // catch: all
// If we are here, then everything went well.
SetCommitCompleted();
TraceFuncExit();
} //*** CActionList::Commit
//////////////////////////////////////////////////////////////////////////////
//++
//
// CActionList::Rollback
//
// Description:
// Rollback this action list. If this list was successfully committed, then
// this method iterates through the list in the reverse order and rolls
// back action in turn.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any that are thrown by the contained actions.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CActionList::Rollback( void ) { TraceFunc( "[IUnknown]" );
// Call the base class rollback method.
BaseClass::Rollback();
LogMsg( "[BC] Attempting to rollback action list." );
// Rollback all actions starting from the last one.
RollbackCommitted( m_aplPendingActions.CiEnd() );
SetCommitCompleted( false );
TraceFuncExit();
} //*** CActionList::Rollback
//////////////////////////////////////////////////////////////////////////////
//++
//
// CActionList::AppendAction
//
// Description:
// Add an action to the end of the list of actions to be performed.
//
// Arguments:
// paNewActionIn
// Pointer to the action that is to be added to the end of the
// action list. This pointer cannot be NULL. The object pointed to by
// this pointer is deleted when this list is deleted.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CAssert
// If paNewActionIn is NULL.
//
// Any that are thrown by the underlying list.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CActionList::AppendAction( CAction * paNewActionIn ) { TraceFunc( "" );
// Temporarily assign pointer to smart pointer to make sure that it is
// deleted if it is not added to the list.
CSmartGenericPtr< CPtrTrait< CAction > > sapTempSmartPtr( paNewActionIn );
if ( paNewActionIn == NULL ) { LogMsg( "[BC] Cannot append NULL action pointer to list. Throwing an exception." ); THROW_ASSERT( E_INVALIDARG , "CActionList::AppendAction() => Cannot append NULL action pointer to list" );
} // if: the pointer to the action to be appended is NULL
//
LogMsg( "[BC] Appending action (paNewActionIn = %p) to list.", paNewActionIn );
// Add action to the end of the list.
m_aplPendingActions.Append( paNewActionIn );
// The pointer has been added to the list. Give up ownership of the memory.
sapTempSmartPtr.PRelease();
// The rollback capability of the list is the AND of the corresponding property of its member actions.
SetRollbackPossible( FIsRollbackPossible() && paNewActionIn->FIsRollbackPossible() );
// Since a new action has been added, set commit completed to false.
SetCommitCompleted( false );
TraceFuncExit();
} //*** CActionList::AppendAction
//////////////////////////////////////////////////////////////////////////////
//++
//
// CActionList::CommitList
//
// Description:
// Commit the action list of this object. This function is called by
// commit to avoid having loops in a try block.
//
// Arguments:
// rapliFirstUncommittedOut
// An iterator that points to the first uncommitted action.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any that are thrown by the contained actions.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CActionList::CommitList( ActionPtrList::CIterator & rapliFirstUncommittedOut ) { TraceFunc( "" );
ActionPtrList::CIterator apliCurrent = m_aplPendingActions.CiBegin(); ActionPtrList::CIterator apliLast = m_aplPendingActions.CiEnd();
rapliFirstUncommittedOut = apliCurrent;
while( apliCurrent != apliLast ) { LogMsg( "[BC] About to commit action (pointer = %#p)", *apliCurrent );
// Commit the current action.
(*apliCurrent)->Commit();
// Move to the next action.
++apliCurrent;
// This is now the first uncommitted action.
rapliFirstUncommittedOut = apliCurrent;
} // while: there still are actions to be committed.
TraceFuncExit();
} //*** CActionList::CommitList
//////////////////////////////////////////////////////////////////////////////
//++
//
// CActionList::RollbackCommitted
//
// Description:
// Rollback all actions that have been committed.
//
// Arguments:
// rapliFirstUncommittedIn
// An iterator that points to the first uncommitted action.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any that are thrown by the contained actions.
//
//--
//////////////////////////////////////////////////////////////////////////////
void CActionList::RollbackCommitted( const ActionPtrList::CIterator & rapliFirstUncommittedIn ) { TraceFunc( "" );
ActionPtrList::CIterator apliFirst = m_aplPendingActions.CiBegin(); ActionPtrList::CIterator apliCurrent = rapliFirstUncommittedIn;
while ( apliCurrent != apliFirst ) { --apliCurrent; // apliCurrent is now at the last committed action.
LogMsg( "[BC] About to rollback action (pointer = %#p)", *apliCurrent );
// Rollback the last un-rolledback, committed action.
if ( (*apliCurrent)->FIsRollbackPossible() ) { (*apliCurrent)->Rollback(); } // if: this action can be rolled back
else { LogMsg( "[BC] THIS COMPUTER MAY BE IN AN INVALID STATE. Action cannot be rolled back. Rollback was aborted." ); } // else: this action cannot be rolled back
} // while: more actions
TraceFuncExit();
} //*** CActionList::RollbackCommitted
//////////////////////////////////////////////////////////////////////////////
//++
//
// CActionList::UiGetMaxProgressTicks
//
// Description:
// Returns the number of progress messages that this action will send.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
UINT CActionList::UiGetMaxProgressTicks( void ) const throw() { TraceFunc( "" );
UINT uiRetVal = 0;
ActionPtrList::CIterator apliCurrent = m_aplPendingActions.CiBegin(); ActionPtrList::CIterator apliLast = m_aplPendingActions.CiEnd();
while ( apliCurrent != apliLast ) { uiRetVal += (*apliCurrent)->UiGetMaxProgressTicks(); ++apliCurrent; }
RETURN( uiRetVal );
} //*** CActionList::UiGetMaxProgressTicks
|