jccl::ConfigElementHandler Class Reference

Abstract base class for all classes that can handle ConfigElement objects. More...

#include <jccl/RTRC/ConfigElementHandler.h>

List of all members.

Public Member Functions

virtual ~ConfigElementHandler ()
virtual bool configCanHandle (ConfigElementPtr element)=0
 Checks if this handler can process the given config element.
virtual int configProcessPending ()
 Processes any pending reconfiguration requests that we know how to deal with.
virtual bool configAdd (ConfigElementPtr element)=0
 Adds the pending element to the configuration.
virtual bool configRemove (ConfigElementPtr element)=0
 Removes the pending element from the current configuration.


Detailed Description

Abstract base class for all classes that can handle ConfigElement objects.

Any class supporting this interface can be dynamically reconfigured by the JCCL Configuration Manager.

The idea is that a subclass overrides configCanHandle() to recognize those elements types that the derived class cares about. Then override configAdd() and configRemove() to process instances of those elements.

The actual work of checking the list of pending add and remove requests and passing them to the methods of this interface is done by configProcessPending(). This can also be overriden to provide special behavior, but this is strongly discouraged. The default implementation should be sufficient for almost any conceivable dynamic reconfiguration need.

See also:
ConfigManager

Definition at line 61 of file ConfigElementHandler.h.


Constructor & Destructor Documentation

virtual jccl::ConfigElementHandler::~ConfigElementHandler (  )  [inline, virtual]

Definition at line 65 of file ConfigElementHandler.h.

00066    {
00067       /* Do nothing. */ ;
00068    }


Member Function Documentation

virtual bool jccl::ConfigElementHandler::configCanHandle ( ConfigElementPtr  element  )  [pure virtual]

Checks if this handler can process the given config element.

Typically, an implementation of this method will check the element's definition ID to decide if it knows how to deal with it.

Parameters:
element The current config element that is ready to be processed.
Returns:
true iff this handler can process element.

int jccl::ConfigElementHandler::configProcessPending (  )  [virtual]

Processes any pending reconfiguration requests that we know how to deal with.

The default implementation does the following for each item in the pending list:

for each pending item p in the pending list do if this->configCanHandle(p) AND p's dependencies are met retval = configAdd or configRemove (p) if retval == true remove request from pending add or remove p.element from active

ConfigManager's pending list MUST be locked before this function is called. Typically, configProcessPending() will be called by jccl::ConfigManager::attemptReconfiguration(), which takes care of this automatically.

See also:
ConfigManager

Definition at line 56 of file ConfigElementHandler.cpp.

References jccl::ConfigManager::PendingElement::ADD, jccl::ConfigManager::addActive(), configRemove(), jccl::DependencyManager::debugOutDependencies(), jccl::FAILED, jccl::ConfigManager::getNumPending(), jccl::ConfigManager::getPendingBegin(), jccl::ConfigManager::getPendingEnd(), jccl::DependencyManager::isSatisfied(), jccl::NEED_DEPS, jccl::outputPendingItemState(), jccl::ConfigManager::PendingElement::REMOVE, jccl::ConfigManager::removeActive(), jccl::ConfigManager::removePending(), jccl::ConfigManager::scanForLostDependencies(), and jccl::SUCCESS.

00057 {
00058    ConfigManager*     cfg_mgr = ConfigManager::instance();
00059    DependencyManager* dep_mgr = DependencyManager::instance();
00060 
00061    bool scan_for_lost_dependants(false);       // Do we need to scan for un-filled dependencies
00062 
00063    // We need to track the number vefore and after to know if we changed anything
00064    std::list<ConfigManager::PendingElement>::size_type num_pending_before =
00065       cfg_mgr->getNumPending();
00066    std::list<ConfigManager::PendingElement>::size_type num_pending_after(0);
00067 
00068    vprDEBUG_BEGIN(vprDBG_ALL,vprDBG_STATE_LVL)
00069       << typeid(*this).name() << "::configProcessPending: Entering: "
00070       << num_pending_before << " items pending.\n" << vprDEBUG_FLUSH;
00071 
00072    // Perform the work of processing pending config elements.
00073    {
00074       std::list<ConfigManager::PendingElement>::iterator current, end, remove_me;
00075       current = cfg_mgr->getPendingBegin();
00076       end = cfg_mgr->getPendingEnd();
00077 
00078       // --- For each item in pending list --- //
00079       while(current != end)
00080       {
00081          // Get information about the current element
00082          ConfigElementPtr cur_element = (*current).mElement;
00083          vprASSERT(cur_element.get() != NULL && "Trying to use an invalid element");
00084          std::string element_name = cur_element->getName();
00085          std::string element_type = cur_element->getID();
00086 
00087          vprDEBUG_BEGIN(vprDBG_ALL,vprDBG_VERB_LVL)
00088             << "Item: name:" << element_name << " type:" << element_type
00089             << std::endl << vprDEBUG_FLUSH;
00090 
00091          // If the current handler (this) knows about the element
00092          if(this->configCanHandle(cur_element))
00093          {
00094             // ---- HANDLE THE ELEMENT ---- //
00095             switch ((*current).mType)
00096             {
00097             case ConfigManager::PendingElement::ADD:         // -- CONFIG ADD -- //
00098                if(dep_mgr->isSatisfied(cur_element))         // Are all the dependencies satisfied
00099                {
00100                   bool added = this->configAdd(cur_element);
00101                   if(added)                                 // SUCCESS adding
00102                   {
00103                      remove_me = current;
00104                      current++;                          // Goto next item
00105                      cfg_mgr->removePending(remove_me);  // Delete previous item
00106                      cfg_mgr->addActive(cur_element);    // Add it to the current config
00107 
00108                      outputPendingItemState(vprDBG_CONFIG_STATUS_LVL,
00109                                             element_name, element_type,
00110                                             SUCCESS);
00111                   }
00112                   else  // FAILED adding
00113                   {
00114                      outputPendingItemState(vprDBG_CRITICAL_LVL, element_name,
00115                                             element_type, FAILED);
00116                      current++;
00117                   }
00118                }
00119                else     // Dependency failed
00120                {
00121                   outputPendingItemState(vprDBG_CONFIG_LVL, element_name,
00122                                          element_type, NEED_DEPS);
00123                   vprDEBUG_CONT(vprDBG_ALL,vprDBG_CONFIG_LVL)
00124                      << std::endl << vprDEBUG_FLUSH;
00125                   dep_mgr->debugOutDependencies(cur_element,vprDBG_CONFIG_LVL);
00126                   current++;
00127                }
00128                break;
00129 
00130             case ConfigManager::PendingElement::REMOVE:      // Config remove
00131                {
00132                   bool removed = this->configRemove(cur_element);
00133                   if(removed)      // Was there success adding
00134                   {
00135                      remove_me = current;
00136                      current++;                          // Goto next item
00137                      cfg_mgr->removePending(remove_me);  // Delete previous item
00138                      cfg_mgr->removeActive(cur_element->getName());     // Add it to the current config
00139                      scan_for_lost_dependants = true;    // We have to scan to see if somebody depended on that element
00140                   }
00141                   else // Failed to remove
00142                   {
00143                      current++;
00144                   }
00145                }
00146                break;
00147 
00148             default:
00149                current++;  // Goto next entry
00150                break;
00151             }
00152          }
00153          // ---- CAN'T HANDLE THE ELEMENT --- //
00154          else           // if(can_handle)
00155          {
00156             vprDEBUG_NEXT(vprDBG_ALL,vprDBG_STATE_LVL)
00157                << "Pending item: " << cur_element->getName()
00158                << " type: " << cur_element->getID()
00159                << " --> Not handled by this handler.\n" << vprDEBUG_FLUSH;
00160             current++;
00161          }
00162 
00163          vprDEBUG_END(vprDBG_ALL,vprDBG_VERB_LVL) << "==== End item =====\n"
00164                                                   << vprDEBUG_FLUSH;
00165       }        // END: while(current != end)
00166    }
00167 
00168    num_pending_after = cfg_mgr->getNumPending();
00169 
00170    vprDEBUG_END(vprDBG_ALL,vprDBG_STATE_LVL)
00171       << "              Exiting: "
00172       << num_pending_after << " items now pending ==> We processed "
00173       << (num_pending_before-num_pending_after) << " items.\n"
00174       << vprDEBUG_FLUSH;
00175 
00176    // Check for items that have lost their dependencies dues to a remove item being processed
00177    if(scan_for_lost_dependants)
00178    {
00179       cfg_mgr->scanForLostDependencies();
00180    }
00181 
00182    return (num_pending_before-num_pending_after);
00183 }

virtual bool jccl::ConfigElementHandler::configAdd ( ConfigElementPtr  element  )  [pure virtual]

Adds the pending element to the configuration.

Precondition:
configCanHandle(element) == true.
Parameters:
element A newly added config element to be processed.
Returns:
true is returned if and only if the given element was processed successfully.

virtual bool jccl::ConfigElementHandler::configRemove ( ConfigElementPtr  element  )  [pure virtual]

Removes the pending element from the current configuration.

Precondition:
configCanHandle(element) == true.
Parameters:
element A newly removed config element to be processed.
Returns:
true is returned if and only if the given element was processed successfully.

Referenced by configProcessPending().


The documentation for this class was generated from the following files:
Generated on Thu Jan 4 10:49:54 2007 for JCCL: Juggler Configuration and Control Library by  doxygen 1.5.1