Back to index

salome-kernel  6.5.0
Public Types | Public Member Functions | Private Types | Private Attributes
GenericPort< DataManipulator, COUPLING_POLICY > Class Template Reference

#include <GenericPort.hxx>

Inheritance diagram for GenericPort< DataManipulator, COUPLING_POLICY >:
Inheritance graph
[legend]
Collaboration diagram for GenericPort< DataManipulator, COUPLING_POLICY >:
Collaboration graph
[legend]

List of all members.

Public Types

typedef DataManipulator::Type DataType
typedef
DataManipulator::CorbaInType 
CorbaInDataType

Public Member Functions

 GenericPort ()
virtual ~GenericPort ()
template<typename TimeType , typename TagType >
void put (CorbaInDataType data, TimeType time, TagType tag)
template<typename TimeType , typename TagType >
DataType get (TimeType time, TagType tag)
template<typename TimeType , typename TagType >
DataType get (TimeType &ti, TimeType tf, TagType tag=0)
template<typename TimeType , typename TagType >
DataType next (TimeType &t, TagType &tag)
void close (PortableServer::POA_var poa, PortableServer::ObjectId_var id)
void wakeupWaiting ()
template<typename TimeType , typename TagType >
void erase (TimeType time, TagType tag, bool before)

Private Types

typedef COUPLING_POLICY::DataId DataId
typedef std::map< DataId,
DataType
DataTable

Private Attributes

DataTable storedDatas
bool waitingForConvenientDataId
bool waitingForAnyDataId
DataId expectedDataId
DataId lastDataId
bool lastDataIdSet
omni_mutex storedDatas_mutex
omni_condition cond_instance

Detailed Description

template<typename DataManipulator, class COUPLING_POLICY>
class GenericPort< DataManipulator, COUPLING_POLICY >

Definition at line 62 of file GenericPort.hxx.


Member Typedef Documentation

template<typename DataManipulator, class COUPLING_POLICY>
typedef DataManipulator::CorbaInType GenericPort< DataManipulator, COUPLING_POLICY >::CorbaInDataType
template<typename DataManipulator, class COUPLING_POLICY>
typedef COUPLING_POLICY::DataId GenericPort< DataManipulator, COUPLING_POLICY >::DataId [private]

Definition at line 82 of file GenericPort.hxx.

template<typename DataManipulator, class COUPLING_POLICY>
typedef std::map< DataId, DataType> GenericPort< DataManipulator, COUPLING_POLICY >::DataTable [private]

Definition at line 83 of file GenericPort.hxx.

template<typename DataManipulator, class COUPLING_POLICY>
typedef DataManipulator::Type GenericPort< DataManipulator, COUPLING_POLICY >::DataType

Constructor & Destructor Documentation

template<typename DataManipulator , typename COUPLING_POLICY >
GenericPort< DataManipulator, COUPLING_POLICY >::GenericPort ( )

Definition at line 106 of file GenericPort.hxx.

template<typename DataManipulator , typename COUPLING_POLICY >
GenericPort< DataManipulator, COUPLING_POLICY >::~GenericPort ( ) [virtual]

Definition at line 111 of file GenericPort.hxx.

                                                            {
  typename DataTable::iterator it;
  for (it=storedDatas.begin(); it!=storedDatas.end(); ++it) {
#ifdef MYDEBUG
    std::cerr << "~GenericPort() : destruction de la donnnée associée au DataId :"<<  (*it).first << std::endl;
#endif
    DataManipulator::delete_data( (*it).second );
  }
}

Member Function Documentation

template<typename DataManipulator , typename COUPLING_POLICY >
void GenericPort< DataManipulator, COUPLING_POLICY >::close ( PortableServer::POA_var  poa,
PortableServer::ObjectId_var  id 
)

Definition at line 122 of file GenericPort.hxx.

                                                                                     {
  // Ferme le port en supprimant le servant
  // La desactivation du servant du POA provoque sa suppression
  poa->deactivate_object (id);
}
template<typename DataManipulator , typename COUPLING_POLICY >
template<typename TimeType , typename TagType >
void GenericPort< DataManipulator, COUPLING_POLICY >::erase ( TimeType  time,
TagType  tag,
bool  before 
)

Definition at line 347 of file GenericPort.hxx.

{
  typename COUPLING_POLICY::template EraseDataIdBeforeOrAfterTagProcessor<DataManipulator> processEraseDataId(*this);
  processEraseDataId.apply(storedDatas,time,tag,before);
}
template<typename DataManipulator , typename COUPLING_POLICY >
template<typename TimeType , typename TagType >
DataManipulator::Type GenericPort< DataManipulator, COUPLING_POLICY >::get ( TimeType  time,
TagType  tag 
)

Definition at line 363 of file GenericPort.hxx.

{
  typedef typename COUPLING_POLICY::DataId DataId;
  // (Pointeur sur séquence) ou valeur..
  DataType dataToTransmit ;
  bool     isEqual, isBounded;
  typedef typename DataManipulator::InnerType InnerType;

#ifdef MYDEBUG
  std::cout << "-------- Get : MARK 1 ------------------" << std::endl;
#endif
  expectedDataId   = DataId(time,tag);
#ifdef MYDEBUG
  std::cout << "-------- Get : MARK 2 ------------------" << std::endl;
#endif
 
  typename DataTable::iterator wDataIt1;

  try {
    storedDatas_mutex.lock(); // Gérer les Exceptions ds le corps de la méthode
  
    while ( true ) {
 
      // Renvoie isEqual si le dataId attendu est trouvé dans storedDatas :
      //   - l'itérateur wDataIt1 pointe alors sur ce dataId
      // Renvoie isBounded si le dataId attendu n'est pas trouvé mais encadrable et 
      // que la politique  gére ce cas de figure 
      //   - l'itérateur wDataIt1 est tel que wDataIt1->first < wdataId < (wDataIt1+1)->first
      // Méthode provenant de la COUPLING_POLICY
      isDataIdConveniant(storedDatas,expectedDataId,isEqual,isBounded,wDataIt1);
#ifdef MYDEBUG
      std::cout << "-------- Get : MARK 3 ------------------" << std::endl;
#endif

      // L'ordre des différents tests est important
      if ( isEqual ) {
 
#ifdef MYDEBUG
        std::cout << "-------- Get : MARK 4 ------------------" << std::endl;
#endif
        // La propriété de la données N'EST PAS transmise à l'utilisateur en mode CALCIUM.
        // Si l'utilisateur supprime la donnée, storedDataIds devient incohérent
        // C'est EraseDataId qui choisi ou non de supprimer la donnée
        // Du coup interaction potentielle entre le 0 copy et gestion de l'historique
        dataToTransmit = (*wDataIt1).second; 

#ifdef MYDEBUG
        std::cout << "-------- Get : MARK 5 ------------------" << std::endl;
        std::cout << "-------- Get : Données trouvées à t : " << std::endl;
        typename DataManipulator::InnerType const * const InIt1 = DataManipulator::getPointer(dataToTransmit);
        size_t   N = DataManipulator::size(dataToTransmit);
        std::copy(InIt1,        InIt1 + N,
                  std::ostream_iterator< InnerType > (std::cout," "));
        std::cout << std::endl;
#endif

        // Décide de la suppression de certaines  instances de données 
        // La donnée contenu dans la structure CORBA et son dataId sont désallouées
        // Méthode provenant de la COUPLING_POLICY 
        typename COUPLING_POLICY::template EraseDataIdProcessor<DataManipulator> processEraseDataId(*this);
        processEraseDataId.apply(storedDatas,wDataIt1);
#ifdef MYDEBUG
        std::cout << "-------- Get : MARK 6 ------------------" << std::endl;
#endif
        break;

      }
#ifdef MYDEBUG
      std::cout << "-------- Get : MARK 7 ------------------" << std::endl;
#endif

      //if (  isBounded() && COUPLING_POLICY::template needToProcessBoundedDataId() ) {
      // Le DataId demandé n'est pas trouvé mais est encadré ET la politique de couplage
      // implémente une méthode processBoundedDataId capable de générer les données à retourner
      if (  isBounded ) {
        // Pour être cohérent avec la politique du bloc précédent
        // on stocke la paire (dataId,données interpolées ).
        // CALCIUM ne stockait pas les données interpolées. 
        // Cependant  comme les données sont censées être produites
        // par ordre croissant de DataId, de nouvelles données ne devrait pas améliorer
        // l'interpolation.
#ifdef MYDEBUG
        std::cout << "-------- Get : MARK 8 ------------------" << std::endl;
#endif

        typedef typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> BDI;
        BDI processBoundedDataId(*this);
        //        typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> processBoundedDataId(*this);
        //si static BDIP::apply(dataToTransmit,expectedDataId,wDataIt1);
        //ancienne version template processBoundedDataId<DataManipulator>(dataToTransmit,expectedDataId,wDataIt1);
        //BDIP processBoundedDataId;
        processBoundedDataId.apply(dataToTransmit,expectedDataId,wDataIt1);
  
        // Il ne peut pas y avoir déjà une clé expectedDataId dans storedDatas (utilisation de la notation [] )
        // La nouvelle donnée produite est stockée, ce n'était pas le cas dans CALCIUM
        // Cette opération n'a peut être pas un caractère générique.
        // A déplacer en paramètre de la méthode précédente ? ou déléguer ce choix au mode de couplage ?
        storedDatas[expectedDataId]=dataToTransmit;

#ifdef MYDEBUG
        std::cout << "-------- Get : Données calculées à t : " << std::endl;
        typename DataManipulator::InnerType const * const InIt1 = DataManipulator::getPointer(dataToTransmit);
        size_t   N = DataManipulator::size(dataToTransmit);
 
        std::copy(InIt1,        InIt1 + N,
                  std::ostream_iterator< InnerType > (std::cout," "));
        std::cout << std::endl;
        std::cout << "-------- Get : MARK 9 ------------------" << std::endl;
#endif

        typename COUPLING_POLICY::template EraseDataIdProcessor<DataManipulator> processEraseDataId(*this);
        processEraseDataId.apply(storedDatas,wDataIt1);
   
        break;
      }
  
      // Délègue au mode de couplage la gestion d'une demande de donnée non disponible 
      // si le port est deconnecté
      typename COUPLING_POLICY::template DisconnectProcessor<DataManipulator> processDisconnect(*this);
      if ( processDisconnect.apply(storedDatas, expectedDataId, wDataIt1) ) continue;
    
      // Réception bloquante sur le dataId demandé
      // Si l'instance de donnée n'est pas trouvee
#ifdef MYDEBUG
      std::cout << "-------- Get : MARK 10 ------------------" << std::endl;
#endif
      //Positionné à faux dans la méthode put
      waitingForConvenientDataId = true; 
#ifdef MYDEBUG
      std::cout << "-------- Get : MARK 11 ------------------" << std::endl;
     
      // Ici on attend que la méthode put recoive la donnée 
      std::cout << "-------- Get : waiting datas ------------------" << std::endl;
#endif
      fflush(stdout);fflush(stderr);
      unsigned long ts, tns,rs=Superv_Component_i::dscTimeOut;
      if(rs==0)
        cond_instance.wait();
      else
        {
          //Timed wait on omni condition
          omni_thread::get_time(&ts,&tns, rs,0);
          int success=cond_instance.timedwait(ts,tns);
          if(!success)
            {
              // Waiting too long probably blocking
              std::stringstream msg;
              msg<<"Timeout ("<<rs<<" s) exceeded";
              Engines_DSC_interface::writeEvent("BLOCKING","","","","Probably blocking",msg.str().c_str());
              throw DSC_Exception(msg.str());
            }
        }


#ifdef MYDEBUG
      std::cout << "-------- Get : MARK 12 ------------------" << std::endl;
#endif
    }

  } catch (...) {
    waitingForConvenientDataId = true;
    storedDatas_mutex.unlock();
    throw;
  }

  // Deverouille l'acces a la table
  storedDatas_mutex.unlock();
#ifdef MYDEBUG
  std::cout << "-------- Get : MARK 13 ------------------" << std::endl;
#endif

  // La propriété de la données N'EST PAS transmise à l'utilisateur en mode CALCIUM
  // Si l'utilisateur supprime la donnée, storedDataIds devient incohérent
  // c'est eraseDataId qui choisi ou non de supprimer la donnée
  // Du coup interaction potentielle entre le 0 copy et gestion des niveaux 
  return dataToTransmit; 

}

Here is the call graph for this function:

Here is the caller graph for this function:

template<typename DataManipulator , typename COUPLING_POLICY >
template<typename TimeType , typename TagType >
DataManipulator::Type GenericPort< DataManipulator, COUPLING_POLICY >::get ( TimeType &  ti,
TimeType  tf,
TagType  tag = 0 
)

Definition at line 550 of file GenericPort.hxx.

                                                                  {
  ti = COUPLING_POLICY::getEffectiveTime(ti,tf);
  return get(ti,tag);
}

Here is the caller graph for this function:

template<typename DataManipulator , typename COUPLING_POLICY >
template<typename TimeType , typename TagType >
DataManipulator::Type GenericPort< DataManipulator, COUPLING_POLICY >::next ( TimeType &  t,
TagType &  tag 
)

Definition at line 563 of file GenericPort.hxx.

                                                                    {
 
  typedef  typename COUPLING_POLICY::DataId DataId;

  DataType dataToTransmit;
  DataId   dataId;

  try {
    storedDatas_mutex.lock();// Gérer les Exceptions ds le corps de la méthode

#ifdef MYDEBUG
    std::cout << "-------- Next : MARK 1 ---lastDataIdSet ("<<lastDataIdSet<<")---------------" << std::endl;
#endif

    typename DataTable::iterator wDataIt1;
    wDataIt1 = storedDatas.end();

    //Recherche le prochain dataId à renvoyer
    // - lastDataIdset == true indique que lastDataId
    // contient le dernier DataId renvoyé
    // - lastDataIdset == false indique que l'on renverra
    //   le premier dataId trouvé
    // - upper_bound(lastDataId) situe le prochain DataId
    // à renvoyer
    // Rem : les données renvoyées ne sont effacées par eraseDataIds
    //       si necessaire
    if (lastDataIdSet) 
      wDataIt1 = storedDatas.upper_bound(lastDataId);
    else if ( !storedDatas.empty() ) {
      lastDataIdSet = true;
      wDataIt1      = storedDatas.begin();
    }

    typename COUPLING_POLICY::template DisconnectProcessor<DataManipulator> processDisconnect(*this);

    while ( storedDatas.empty() || wDataIt1 == storedDatas.end() ) {

      // Délègue au mode de couplage la gestion d'une demande de donnée non disponible 
      // si le port est deconnecté
      if ( processDisconnect.apply(storedDatas, lastDataId, wDataIt1) )  {
        waitingForAnyDataId = false; break;
      }
  
#ifdef MYDEBUG
      std::cout << "-------- Next : MARK 2 ------------------" << std::endl;
#endif
      //Positionné à faux dans la méthode put
      waitingForAnyDataId   = true;
#ifdef MYDEBUG
      std::cout << "-------- Next : MARK 3 ------------------" << std::endl;
      // Ici on attend que la méthode put recoive la donnée 
      std::cout << "-------- Next : waiting datas ------------------" << std::endl;
#endif
      fflush(stdout);fflush(stderr);
      unsigned long ts, tns,rs=Superv_Component_i::dscTimeOut;
      if(rs==0)
        cond_instance.wait();
      else
        {
          //Timed wait on omni condition
          omni_thread::get_time(&ts,&tns, rs,0);
          int success=cond_instance.timedwait(ts,tns);
          if(!success)
            {
              // Waiting too long probably blocking
              std::stringstream msg;
              msg<<"Timeout ("<<rs<<" s) exceeded";
              Engines_DSC_interface::writeEvent("BLOCKING","","","","Probably blocking",msg.str().c_str());
              throw DSC_Exception(msg.str());
            }
        }

      if (lastDataIdSet) {
#ifdef MYDEBUG
        std::cout << "-------- Next : MARK 4 ------------------" << std::endl;
#endif
        wDataIt1 = storedDatas.upper_bound(lastDataId);
      } else  {
#ifdef MYDEBUG
        std::cout << "-------- Next : MARK 5 ------------------" << std::endl;
#endif
        lastDataIdSet = true;
        wDataIt1      = storedDatas.begin();
      }
    }

#ifdef MYDEBUG
    std::cout << "-------- Next : MARK 6 ------------------" << std::endl;
#endif

    t   = getTime( (*wDataIt1).first );
    tag = getTag ( (*wDataIt1).first );
    dataToTransmit = (*wDataIt1).second;
 
#ifdef MYDEBUG
    std::cout << "-------- Next : MARK 7 ------------------" << std::endl;
#endif
    lastDataId    = (*wDataIt1).first;

    typename COUPLING_POLICY::template EraseDataIdProcessor<DataManipulator> processEraseDataId(*this);
    processEraseDataId.apply(storedDatas, wDataIt1);

#ifdef MYDEBUG
    std::cout << "-------- Next : MARK 8 ------------------" << std::endl;   
#endif
  } catch (...) {
#ifdef MYDEBUG
    std::cout << "-------- Next : MARK 8bis ------------------" << std::endl;
#endif
    waitingForAnyDataId = false;
    storedDatas_mutex.unlock();
    throw;
  }
  storedDatas_mutex.unlock();
  
#ifdef MYDEBUG
  std::cout << "-------- Next : MARK 9 ------------------" << std::endl;
#endif

  // La propriété de la données N'EST PAS transmise à l'utilisateur en mode CALCIUM
  // Si l'utilisateur supprime la donnée, storedDataIds devient incohérent
  // c'est eraseDataId qui choisi ou non de supprimer la donnée
  // Du coup interaction potentielle entre le 0 copy et gestion des niveaux 
  return dataToTransmit; 

};

Here is the call graph for this function:

template<typename DataManipulator , typename COUPLING_POLICY >
template<typename TimeType , typename TagType >
void GenericPort< DataManipulator, COUPLING_POLICY >::put ( CorbaInDataType  data,
TimeType  time,
TagType  tag 
)

Reimplemented in palm_data_seq_short_port_provides, and palm_data_short_port_provides.

Definition at line 154 of file GenericPort.hxx.

                                                                      {
  fflush(stdout);
  fflush(stderr);
  try {
#ifdef MYDEBUG
    // Affichage des donnees pour DEBUGging
    std::cerr << "parametres emis: " << time << ", " << tag << std::endl;
    DataManipulator::dump(dataParam);
#endif
  
    // L'intérêt des paramètres time et tag pour ce port est décidé dans la politique de couplage
    // Il est possible de filtrer en prenant en compte uniquement un paramètre time/tag ou les deux
    // Il est également possible de convertir les données recues ou bien de les dupliquer
    // pour plusieurs  valeurs de time et/ou tag (d'où la notion de container dans la politique de couplage)
    typedef typename COUPLING_POLICY::DataIdContainer DataIdContainer;  
    typedef typename COUPLING_POLICY::DataId          DataId;

    DataId          dataId(time,tag);
    // Effectue les traitements spécifiques à la politique de couplage 
    // pour construire une liste d'ids (par filtrage, conversion ...)
    // DataIdContainer dataIds(dataId,*(static_cast<const COUPLING_POLICY *>(this)));   
    DataIdContainer dataIds(dataId, *this);   

    typename DataIdContainer::iterator dataIdIt = dataIds.begin();

    bool expectedDataReceived = false;

#ifdef MYDEBUG
    std::cout << "-------- Put : MARK 1 ------------------" << std::endl;
#endif
    if ( dataIds.empty() ) return;
#ifdef MYDEBUG
    std::cout << "-------- Put : MARK 1bis ------------------" << std::endl;
#endif

    // Recupere les donnees venant de l'ORB et relâche les structures CORBA 
    // qui n'auraient plus cours en sortie de méthode put
    DataType data = DataManipulator::get_data(dataParam);


    int nbOfIter = 0;

#ifdef MYDEBUG
    std::cout << "-------- Put : MARK 2 ------ "<< (dataIdIt == dataIds.end()) << "------------" << std::endl;
    std::cout << "-------- Put : MARK 2bis "<< (*dataIdIt) <<"------------------" << std::endl;
#endif
    storedDatas_mutex.lock();

    for (;dataIdIt != dataIds.end();++dataIdIt) {

#ifdef MYDEBUG
      std::cout << "-------- Put : MARK 3 ------------------" << std::endl;
#endif
      // Duplique l'instance de donnée pour les autres dataIds 
      if (nbOfIter > 0) data = DataManipulator::clone(data);
#ifdef MYDEBUG
      std::cout << "-------- Put : MARK 3bis -----"<< dataIdIt.operator*() <<"------------" << std::endl;
#endif
    
      DataId currentDataId=*dataIdIt;

#ifdef MYDEBUG
      std::cerr << "processing dataId : "<< currentDataId << std::endl;

      std::cout << "-------- Put : MARK 4 ------------------" << std::endl;
#endif
 
      // Ajoute l'instance de la donnee a sa place dans la table de données
      // ou remplace une instance précédente si elle existe
    
      // Recherche la première clé telle quelle ne soit pas <  currentDataId
      // pour celà l'opérateur de comparaison storedDatas.key_comp() est utilisé
      // <=> premier emplacement où l'on pourrait insérer notre DataId
      // <=> en général équivaux à (*wDataIt).first >= currentDataId
      typename DataTable::iterator wDataIt = storedDatas.lower_bound(currentDataId);
#ifdef MYDEBUG
      std::cout << "-------- Put : MARK 5 ------------------" << std::endl;
#endif

      // On n'a pas trouvé de dataId supérieur au notre ou 
      // on a trouvé une clé >  à cet Id          
      if (wDataIt == storedDatas.end() || storedDatas.key_comp()(currentDataId,(*wDataIt).first) ) {
#ifdef MYDEBUG
        std::cout << "-------- Put : MARK 6 ------------------" << std::endl;
#endif
        // Ajoute la donnee dans la table
        wDataIt = storedDatas.insert(wDataIt, make_pair (currentDataId, data));
      } else  {
        // Si on n'est pas en fin de liste et qu'il n'y a pas de relation d'ordre strict
        // entre notre dataId et le DataId pointé c'est qu'ils sont identiques
#ifdef MYDEBUG
        std::cout << "-------- Put : MARK 7 ------------------" << std::endl;
#endif
        // Les données sont remplacées par les nouvelles valeurs
        // lorsque que le dataId existe déjà
        DataType old_data = (*wDataIt).second;
        (*wDataIt).second = data;
        // Detruit la vieille donnee
        DataManipulator::delete_data (old_data);
      }
  
#ifdef MYDEBUG
      std::cout << "-------- Put : MARK 8 ------------------" << std::endl;
#endif
      // Compte le nombre de dataIds à traiter
      ++nbOfIter;

#ifdef MYDEBUG
      std::cout << "-------- Put : waitingForConvenientDataId : " << waitingForConvenientDataId <<"---" << std::endl;
      std::cout << "-------- Put : waitingForAnyDataId : " << waitingForAnyDataId <<"---" << std::endl;
      std::cout << "-------- Put : currentDataId  : " << currentDataId <<"---" << std::endl;
      std::cout << "-------- Put : expectedDataId : " << expectedDataId <<"---" << std::endl;
      std::cout << "-------- Put : MARK 9 ------------------" << std::endl;
#endif

      // A simplifier mais :
      // - pas possible de mettre des arguments optionnels à cause
      //   du type itérator qui n'est pas connu (pas de possibilité de déclarer un static )
      // - compliquer de créer une méthode sans les paramètres inutiles tout en réutilisant
      //   la méthode initiale car cette dernière ne peut pas être déclarée virtuelle 
      //   à cause de ses paramètres templates. Du coup, il faudrait aussi redéfinir la
      //   méthode simplifiée dans les classes définissant une politique 
      //   de couplage particulière ...
      bool dummy1,dummy2; typename DataTable::iterator dummy3;
      // Par construction, les valeurs de waitingForAnyDataId, waitingForConvenientDataId et de 
      // expectedDataId ne peuvent pas être modifiées pendant le traitement de la boucle
      // sur les dataIds (à cause du lock utilisé dans la méthode put et les méthodes get )
      // rem : Utilisation de l'évaluation gauche droite du logical C or
      if ( waitingForAnyDataId || 
           ( waitingForConvenientDataId && 
             isDataIdConveniant(storedDatas, expectedDataId, dummy1, dummy2, dummy3) ) 
           ) {
#ifdef MYDEBUG
        std::cout << "-------- Put : MARK 10 ------------------" << std::endl;
#endif
        //Doit pouvoir réveiller le get ici (a vérifier)
        expectedDataReceived = true;
      }
    }
   
    if (expectedDataReceived) {
#ifdef MYDEBUG
      std::cout << "-------- Put : MARK 11 ------------------" << std::endl;
#endif
      // si waitingForAnyDataId était positionné, c'est forcément lui qui a activer
      // expectedDataReceived à true
      if (waitingForAnyDataId) 
        waitingForAnyDataId        = false;
      else 
        waitingForConvenientDataId = false;
      // Reveille le thread du destinataire (stoppe son attente)
      // Ne faudrait-il pas réveiller plutôt tous les threads ?
      // Celui  réveillé ne correspond pas forcément à celui qui demande
      // cet expectedDataReceived.
      // Pb1 : cas d'un un get séquentiel et d'un get sur un dataId que l'on vient de recevoir.
      // Si l'on reveille le mauvais thread, l'autre va attendre indéfiniment ! (sauf timeout)
      // Pb2 : également si deux attentes de DataIds même différents car on n'en stocke qu'un !
      // Conclusion : Pour l'instant on ne gère pas un service multithreadé qui effectue
      // des lectures simultanées sur le même port !
#ifdef MYDEBUG
      std::cerr << "-------- Put : new datas available ------------------" << std::endl;
#endif
      fflush(stdout);fflush(stderr);
      cond_instance.signal();
    }
#ifdef MYDEBUG
    std::cout << "-------- Put : MARK 12 ------------------" << std::endl;
#endif

    // Deverouille l'acces a la table : On peut remonter l'appel au dessus de expected...
    storedDatas_mutex.unlock();

#ifdef MYDEBUG
    std::cout << "-------- Put : MARK 13 ------------------" << std::endl;
#endif
    fflush(stdout);
    fflush(stderr);

  } // Catch les exceptions SALOME//C++ pour la transformer en une exception SALOME//CORBA  
  catch ( const SALOME_Exception & ex ) {
    // On évite de laisser un  mutex
    storedDatas_mutex.unlock();
    THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
  }

}

Here is the caller graph for this function:

template<typename DataManipulator , typename COUPLING_POLICY >
void GenericPort< DataManipulator, COUPLING_POLICY >::wakeupWaiting ( )

Definition at line 130 of file GenericPort.hxx.

{
#ifdef MYDEBUG
  std::cout << "-------- wakeupWaiting ------------------" << std::endl;
#endif
  storedDatas_mutex.lock();
  if (waitingForAnyDataId || waitingForConvenientDataId) {
#ifdef MYDEBUG
    std::cout << "-------- wakeupWaiting:signal --------" << std::endl;
    std::cout << std::flush;
#endif
    cond_instance.signal();
   }
  storedDatas_mutex.unlock();

}

Member Data Documentation

template<typename DataManipulator, class COUPLING_POLICY>
omni_condition GenericPort< DataManipulator, COUPLING_POLICY >::cond_instance [private]

Definition at line 101 of file GenericPort.hxx.

template<typename DataManipulator, class COUPLING_POLICY>
DataId GenericPort< DataManipulator, COUPLING_POLICY >::expectedDataId [private]

Definition at line 94 of file GenericPort.hxx.

template<typename DataManipulator, class COUPLING_POLICY>
DataId GenericPort< DataManipulator, COUPLING_POLICY >::lastDataId [private]

Definition at line 96 of file GenericPort.hxx.

template<typename DataManipulator, class COUPLING_POLICY>
bool GenericPort< DataManipulator, COUPLING_POLICY >::lastDataIdSet [private]

Definition at line 97 of file GenericPort.hxx.

template<typename DataManipulator, class COUPLING_POLICY>
DataTable GenericPort< DataManipulator, COUPLING_POLICY >::storedDatas [private]

Definition at line 86 of file GenericPort.hxx.

template<typename DataManipulator, class COUPLING_POLICY>
omni_mutex GenericPort< DataManipulator, COUPLING_POLICY >::storedDatas_mutex [private]

Definition at line 99 of file GenericPort.hxx.

template<typename DataManipulator, class COUPLING_POLICY>
bool GenericPort< DataManipulator, COUPLING_POLICY >::waitingForAnyDataId [private]

Definition at line 91 of file GenericPort.hxx.

template<typename DataManipulator, class COUPLING_POLICY>
bool GenericPort< DataManipulator, COUPLING_POLICY >::waitingForConvenientDataId [private]

Definition at line 89 of file GenericPort.hxx.


The documentation for this class was generated from the following file: