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.
 
 
 
 
 
 

273 lines
5.9 KiB

/* Copyright 1999 American Power Conversion, All Rights Reserved
*
* Description:
* Implementation of the RUNNING state machine.
*
* Revision History:
* dsmith 31Mar1999 Created
*
*/
#include <windows.h>
#include "states.h"
#include "events.h"
#include "run_states.h"
#include "statmach.h"
#include "running_statmach.h"
//////////////////////////////////////////
// Internal prototype definitions
//////////////////////////////////////////
BOOL isRunningEvent(DWORD aState, DWORD anEvent);
DWORD do_running_work(DWORD aCurrentState);
DWORD change_running_state(DWORD aCurrentState, DWORD anEvent);
void exit_running_state(DWORD aCurrentState, DWORD anEvent);
void enter_running_state(DWORD aCurrentState, DWORD anEvent);
//////////////////////////////////////////
// Running State internal variables
//////////////////////////////////////////
BOOL theLogPowerRestoredEvent = FALSE;
/**
* Running_Enter
*
* Description:
* Performs the actions necessary when transitioning into the RUNNING state.
*
* Parameters:
* anEvent The event that caused the transition into this state.
*
* Returns:
* None
*/
void Running_Enter(DWORD anEvent){
// Initialize internal variables and enter the RUNNING default sub-state
OnLine_Enter(anEvent, FALSE);
}
/**
* Running_DoWork
*
* Description:
* Change run states based upon events from the UPS. When an event occurs
* that cannot be handled in the run state, then this method exits.
*
* Parameters:
* None
*
* Returns:
* The event that caused the transition from the RUNNING state.
*/
DWORD Running_DoWork(){
DWORD event = NO_EVENT;
DWORD new_state = ON_LINE;
DWORD current_state = new_state;
// Perform work in sub-states until an event occurs that cannot be
// handled in the RUNNING state
while (isRunningEvent(current_state, event) && IsStateMachineActive()){
new_state = change_running_state(current_state, event);
current_state = new_state;
event = do_running_work(current_state);
}
return event;
}
/**
* Running_Exit
*
* Description:
* Performs the actions necessary when transitioning from the RUNNING state.
*
* Parameters:
* anEvent The event that caused the transition from the RUNNING state.
*
* Returns:
* None
*/
void Running_Exit(DWORD anEvent){
// No work to perform
}
/**
* do_running_work
*
* Description:
* Transfers control to one of the RUNNING sub-states.
*
* Parameters:
* aCurrentState The sub-state to perform the work in.
*
* Returns:
* The event that caused the transition from one of the sub-states
*/
DWORD do_running_work(DWORD aCurrentState){
DWORD event = NO_EVENT;
switch (aCurrentState){
case ON_LINE:
event = OnLine_DoWork();
break;
case ON_BATTERY:
event = OnBattery_DoWork();
break;
case NO_COMM:
event = NoComm_DoWork();
break;
default:
break;
}
return event;
}
/**
* isRunningEvent
*
* Description:
* Determines if the current event pertains to the RUNNING state.
*
* Parameters:
* aState The current RUNNING state
* anEvent The current event occuring within the RUNNING state.
*
* Returns:
* TRUE if the current event is applicable to the RUNNING state.
* FALSE for all other events.
*/
BOOL isRunningEvent(DWORD aState, DWORD anEvent){
BOOL running_event = FALSE;
// If the state machine has been commanded to exit, then return FALSE
// Otherwise, determine if the event is applicable to the Running state
if (IsStateMachineActive()){
switch (anEvent){
case LOST_COMM:
// If the UPS is on battery, then lost comm will translate into
// a non-RUNNING state event (since the service must now shutdown)
if (aState != ON_BATTERY){
running_event = TRUE;
}
break;
case NO_EVENT:
case POWER_FAILED:
case POWER_RESTORED:
running_event = TRUE;
break;
default:
break;
}
}
return running_event;
}
/**
* change_running_state
*
* Description:
* Changes the running state based upon the current state and an event.
*
* Parameters:
* anEvent The current event occuring within the RUNNING state.
* aCurrentState The current RUNNING sub-state.
*
* Returns:
* The new RUNNING state.
*/
DWORD change_running_state(DWORD aCurrentState, DWORD anEvent){
DWORD new_state;
// Determine new RUNNING sub-state
switch (anEvent){
case LOST_COMM:
new_state = NO_COMM;
break;
case POWER_FAILED:
new_state = ON_BATTERY;
break;
case POWER_RESTORED:
new_state = ON_LINE;
break;
case NO_EVENT:
default:
new_state = aCurrentState;
break;
}
// Close down the old sub-state and enter the new one.
if (new_state != aCurrentState){
exit_running_state(aCurrentState, anEvent);
enter_running_state(new_state, anEvent);
}
return new_state;
}
/**
* exit_running_state
*
* Description:
* Exits the currently executing sub-state.
*
* Parameters:
* anEvent The event that is causing the transition from a sub-state.
* aCurrentState The current RUNNING sub-state.
*
* Returns:
* None
*/
void exit_running_state(DWORD aCurrentState, DWORD anEvent){
switch (aCurrentState){
case ON_LINE:
OnLine_Exit(anEvent);
break;
case ON_BATTERY:
OnBattery_Exit(anEvent);
theLogPowerRestoredEvent = TRUE;
break;
case NO_COMM:
NoComm_Exit(anEvent);
break;
default:
break;
}
}
/**
* enter_running_state
*
* Description:
* Initializes the new RUNNING sub-state.
*
* Parameters:
* anEvent The event that is causing the transition to a sub-state.
* aCurrentState A RUNNING sub-state to enter.
*
* Returns:
* None
*/
void enter_running_state(DWORD aCurrentState, DWORD anEvent){
switch (aCurrentState){
case ON_LINE:
OnLine_Enter(anEvent, theLogPowerRestoredEvent);
theLogPowerRestoredEvent = FALSE;
break;
case ON_BATTERY:
OnBattery_Enter(anEvent);
break;
case NO_COMM:
NoComm_Enter(anEvent);
break;
default:
break;
}
}