Example #1
0
// ============================================================================
void IncidentSvc::removeListener
( IIncidentListener* lis  ,
  const std::string& type )
{

  boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);

  if( type == "") {
    // remove Listener from all the lists
    ListenerMap::iterator itmap;
    for ( itmap = m_listenerMap.begin(); itmap != m_listenerMap.end();)
    {
      // since the current entry may be eventually deleted
      // we need to keep a memory of the next index before
      // calling recursively this method
      ListenerMap::iterator itmap_old = itmap;
      itmap++;
      removeListener( lis, (*itmap_old).first );
    }
  }
  else {
    ListenerMap::iterator itmap = m_listenerMap.find( type );

    if( itmap == m_listenerMap.end() ) {
      // if not found the incident type then return
      return;
    }
    else {
      ListenerList* llist = (*itmap).second;
      ListenerList::iterator itlist;
      bool justScheduleForRemoval = ( 0!= m_currentIncidentType )
                                    && (type == *m_currentIncidentType);
      // loop over all the entries in the Listener list
      // to remove all of them than matches
      // the listener address. Remember the next index
      // before erasing the current one
      for( itlist = llist->begin(); itlist != llist->end(); ) {
        if( (*itlist).iListener == lis || lis == 0) {
          if (justScheduleForRemoval) {
            (itlist++)->singleShot = true; // remove it as soon as it is safe
          }
          else {
            DEBMSG << "Removing [" << type << "] listener '"
                   << getListenerName(lis) << "'" << endmsg;
            itlist = llist->erase(itlist); // remove from the list now
          }
        }
        else {
          itlist++;
        }
      }
      if( llist->size() == 0) {
        delete llist;
        m_listenerMap.erase(itmap);
      }
    }
  }
}
Example #2
0
// ============================================================================
void IncidentSvc::i_fireIncident
( const Incident&    incident     ,
  const std::string& listenerType )
{

  boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);

  // Special case: FailInputFile incident must set the application return code
  if (incident.type() == IncidentType::FailInputFile
      || incident.type() == IncidentType::CorruptedInputFile) {
    SmartIF<IProperty> appmgr(serviceLocator());
    if (incident.type() == IncidentType::FailInputFile)
      // Set the return code to Gaudi::ReturnCode::FailInput (2)
      Gaudi::setAppReturnCode(appmgr, Gaudi::ReturnCode::FailInput).ignore();
    else
      Gaudi::setAppReturnCode(appmgr, Gaudi::ReturnCode::CorruptedInput).ignore();
  }

  ListenerMap::iterator itmap = m_listenerMap.find( listenerType );
  if ( m_listenerMap.end() == itmap ) return;

  // setting this pointer will avoid that a call to removeListener() during
  // the loop triggers a segfault
  m_currentIncidentType = &(incident.type());

  ListenerList* llist = (*itmap).second;
  ListenerList::iterator itlist;
  bool weHaveToCleanUp = false;
  // loop over all registered Listeners

    for( itlist = llist->begin(); itlist != llist->end(); itlist++ )
  {

    VERMSG << "Calling '" << getListenerName((*itlist).iListener)
           << "' for incident [" << incident.type() << "]" << endmsg;

    // handle exceptions if they occur
    try {
      (*itlist).iListener->handle(incident);
    }
    catch( const GaudiException& exc ) {
      error() << "Exception with tag=" << exc.tag() << " is caught"
                 " handling incident" << m_currentIncidentType << endmsg;
      error() <<  exc  << endmsg;
      if ( (*itlist).rethrow ) { throw (exc); }
    }
    catch( const std::exception& exc ) {
     error() << "Standard std::exception is caught"
          " handling incident" << m_currentIncidentType << endmsg;
      error() << exc.what()  << endmsg;
      if ( (*itlist).rethrow ) { throw (exc); }
    }
    catch(...) {
      error() << "UNKNOWN Exception is caught"
          " handling incident" << m_currentIncidentType << endmsg;
      if ( (*itlist).rethrow ) { throw; }
    }
    // check if at least one of the listeners is a one-shot
    weHaveToCleanUp |= itlist->singleShot;
  }
  if (weHaveToCleanUp) {
    // remove all the listeners that need to be removed from the list
    llist->remove_if( listenerToBeRemoved() );
    // if the list is empty, we can remove it
    if( llist->size() == 0) {
      delete llist;
      m_listenerMap.erase(itmap);
    }
  }

  m_currentIncidentType = 0;
}