Version: 9.16.0
GenericPort.hxx
Go to the documentation of this file.
1// Copyright (C) 2007-2026 CEA, EDF, OPEN CASCADE
2//
3// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5//
6// This library is free software; you can redistribute it and/or
7// modify it under the terms of the GNU Lesser General Public
8// License as published by the Free Software Foundation; either
9// version 2.1 of the License, or (at your option) any later version.
10//
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// Lesser General Public License for more details.
15//
16// You should have received a copy of the GNU Lesser General Public
17// License along with this library; if not, write to the Free Software
18// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19//
20// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21//
22
23// File : GenericPort.hxx
24// Author : Eric Fayolle (EDF)
25// Module : KERNEL
26// Modified by : $LastChangedBy$
27// Date : $LastChangedDate: 2007-02-28 15:26:32 +0100 (mer, 28 fév 2007) $
28// Id : $Id$
29//
30#ifndef _GENERIC_PORT_HXX_
31#define _GENERIC_PORT_HXX_
32
34
36// SALOME CORBA Exception
38// SALOME C++ Exception
39#include "Utils_SALOME_Exception.hxx"
40#include "DSC_Exception.hxx"
41#include "utilities.h"
42#include "DisplayPair.hxx"
43
44#include <iostream>
45#include <map>
46
47// Inclusions pour l'affichage
48#include <algorithm>
49#include <iterator>
50
51// Classe GenericPort
52// --------------------------------
53//
54// Definition: Implemente un port de type "data-stream"
55// Cette implémentation gère tous les types de données définies par DataManipulator::type
56// Ce port est soumis à une politique d'itération sur les identificateurs de données (DataId)
57// Un identificateur de données est construit à partir d'un ou plusieurs paramètres de la méthode put
58// tels que : une date, une itération, un pas de temps ou une combinaison de ces paramètres.
59
60template < typename DataManipulator, class COUPLING_POLICY >
62public:
63 // Type de données manipulés
64 typedef typename DataManipulator::Type DataType;
65 typedef typename DataManipulator::CorbaInType CorbaInDataType;
66
68 virtual ~GenericPort();
69
70 template <typename TimeType,typename TagType> void put(CorbaInDataType data, TimeType time, TagType tag);
71 template <typename TimeType,typename TagType> DataType get(TimeType time, TagType tag);
72 template <typename TimeType,typename TagType> DataType get(TimeType& ti, TimeType tf, TagType tag = 0);
73 template <typename TimeType,typename TagType> DataType next(TimeType &t, TagType &tag );
74 void close (PortableServer::POA_var poa, PortableServer::ObjectId_var id);
76 template <typename TimeType,typename TagType> void erase(TimeType time, TagType tag, bool before );
77
78private:
79
80 // Type identifiant une instance de donnee. Exemple (time,tag)
82 typedef std::map< DataId, DataType> DataTable;
83
84 // Stockage des donnees recues et non encore distribuées
86
87 // Indicateur que le destinataire attend une instance particuliere de données
89 // Indicateur que le destinataire attend n'importe qu'elle instance de données
91
92 // Identificateur de la donné que le destinataire (propriétaire du port) attend
94 // Sauvegarde du DataId courant pour la méthode next
97 // Exclusion mutuelle d'acces a la table des données reçues
99 // Condition d'attente d'une instance (Le processus du Get attend la condition declaree par le processus Put)
101
102};
103
104template < typename DataManipulator, typename COUPLING_POLICY >
106 waitingForConvenientDataId(false),waitingForAnyDataId(false),lastDataIdSet(false),
107 cond_instance(& this->storedDatas_mutex){}
108
109template < typename DataManipulator, typename COUPLING_POLICY>
111 typename DataTable::iterator it;
112 for (it=storedDatas.begin(); it!=storedDatas.end(); ++it) {
113 if (SALOME::VerbosityActivated())
114 std::cerr << "~GenericPort() : destruction de la donnnée associée au DataId :" << (*it).first << std::endl;
115
116 DataManipulator::delete_data( (*it).second );
117 }
118}
119
120template < typename DataManipulator, typename COUPLING_POLICY> void
122 PortableServer::ObjectId_var id) {
123 // Ferme le port en supprimant le servant
124 // La desactivation du servant du POA provoque sa suppression
125 poa->deactivate_object (id);
126}
127
128template < typename DataManipulator, typename COUPLING_POLICY> void
130{
131 if (SALOME::VerbosityActivated())
132 std::cout << "-------- wakeupWaiting ------------------" << std::endl;
133
134 storedDatas_mutex.lock();
135 if (waitingForAnyDataId || waitingForConvenientDataId) {
136 if (SALOME::VerbosityActivated())
137 {
138 std::cout << "-------- wakeupWaiting:signal --------" << std::endl;
139 std::cout << std::flush;
140 }
141
142 cond_instance.signal();
143 }
144
145 storedDatas_mutex.unlock();
146}
147
148/* Methode put_generique
149 *
150 * Stocke en memoire une instance de donnee (pointeur) que l'emetteur donne a l'intention du destinataire.
151 * Reveille le destinataire, si il y a lieu.
152 */
153template < typename DataManipulator, typename COUPLING_POLICY>
154template < typename TimeType,typename TagType>
156 TimeType time,
157 TagType tag) {
158 fflush(stdout);
159 fflush(stderr);
160 try {
161 if (SALOME::VerbosityActivated())
162 {
163 // Affichage des donnees pour DEBUGging
164 std::cerr << "parametres emis: " << time << ", " << tag << std::endl;
165 DataManipulator::dump(dataParam);
166 }
167
168 // L'intérêt des paramètres time et tag pour ce port est décidé dans la politique de couplage
169 // Il est possible de filtrer en prenant en compte uniquement un paramètre time/tag ou les deux
170 // Il est également possible de convertir les données recues ou bien de les dupliquer
171 // pour plusieurs valeurs de time et/ou tag (d'où la notion de container dans la politique de couplage)
172 typedef typename COUPLING_POLICY::DataIdContainer DataIdContainer;
173 typedef typename COUPLING_POLICY::DataId DataId;
174
175 DataId dataId(time,tag);
176 // Effectue les traitements spécifiques à la politique de couplage
177 // pour construire une liste d'ids (par filtrage, conversion ...)
178 // DataIdContainer dataIds(dataId,*(static_cast<const COUPLING_POLICY *>(this)));
179 DataIdContainer dataIds(dataId, *this);
180
181 typename DataIdContainer::iterator dataIdIt = dataIds.begin();
182
183 bool expectedDataReceived = false;
184
185 if (SALOME::VerbosityActivated())
186 std::cout << "-------- Put : MARK 1 ------------------" << std::endl;
187
188 if ( dataIds.empty() ) return;
189 if (SALOME::VerbosityActivated())
190 std::cout << "-------- Put : MARK 1bis ------------------" << std::endl;
191
192 // Recupere les donnees venant de l'ORB et relâche les structures CORBA
193 // qui n'auraient plus cours en sortie de méthode put
194 DataType data = DataManipulator::get_data(dataParam);
195
196 int nbOfIter = 0;
197
198 if (SALOME::VerbosityActivated())
199 {
200 std::cout << "-------- Put : MARK 2 ------ "<< (dataIdIt == dataIds.end()) << "------------" << std::endl;
201 std::cout << "-------- Put : MARK 2bis "<< (*dataIdIt) <<"------------------" << std::endl;
202 }
203 storedDatas_mutex.lock();
204
205 for (;dataIdIt != dataIds.end();++dataIdIt) {
206 if (SALOME::VerbosityActivated())
207 std::cout << "-------- Put : MARK 3 ------------------" << std::endl;
208
209 // Duplique l'instance de donnée pour les autres dataIds
210 if (nbOfIter > 0) data = DataManipulator::clone(data);
211 if (SALOME::VerbosityActivated())
212 std::cout << "-------- Put : MARK 3bis -----"<< dataIdIt.operator*() <<"------------" << std::endl;
213
214 DataId currentDataId=*dataIdIt;
215
216 if (SALOME::VerbosityActivated())
217 {
218 std::cerr << "processing dataId : "<< currentDataId << std::endl;
219 std::cout << "-------- Put : MARK 4 ------------------" << std::endl;
220 }
221
222 // Ajoute l'instance de la donnee a sa place dans la table de données
223 // ou remplace une instance précédente si elle existe
224
225 // Recherche la première clé telle quelle ne soit pas < currentDataId
226 // pour celà l'opérateur de comparaison storedDatas.key_comp() est utilisé
227 // <=> premier emplacement où l'on pourrait insérer notre DataId
228 // <=> en général équivaux à (*wDataIt).first >= currentDataId
229 typename DataTable::iterator wDataIt = storedDatas.lower_bound(currentDataId);
230 if (SALOME::VerbosityActivated())
231 std::cout << "-------- Put : MARK 5 ------------------" << std::endl;
232
233 // On n'a pas trouvé de dataId supérieur au notre ou
234 // on a trouvé une clé > à cet Id
235 if (wDataIt == storedDatas.end() || storedDatas.key_comp()(currentDataId,(*wDataIt).first) ) {
236 if (SALOME::VerbosityActivated())
237 std::cout << "-------- Put : MARK 6 ------------------" << std::endl;
238
239 // Ajoute la donnee dans la table
240 wDataIt = storedDatas.insert(wDataIt, make_pair (currentDataId, data));
241 } else {
242 // Si on n'est pas en fin de liste et qu'il n'y a pas de relation d'ordre strict
243 // entre notre dataId et le DataId pointé c'est qu'ils sont identiques
244 if (SALOME::VerbosityActivated())
245 std::cout << "-------- Put : MARK 7 ------------------" << std::endl;
246
247 // Les données sont remplacées par les nouvelles valeurs
248 // lorsque que le dataId existe déjà
249 DataType old_data = (*wDataIt).second;
250 (*wDataIt).second = data;
251 // Detruit la vieille donnee
252 DataManipulator::delete_data (old_data);
253 }
254
255 if (SALOME::VerbosityActivated())
256 std::cout << "-------- Put : MARK 8 ------------------" << std::endl;
257
258 // Compte le nombre de dataIds à traiter
259 ++nbOfIter;
260
261 if (SALOME::VerbosityActivated())
262 {
263 std::cout << "-------- Put : waitingForConvenientDataId : " << waitingForConvenientDataId << "---" << std::endl;
264 std::cout << "-------- Put : waitingForAnyDataId : " << waitingForAnyDataId << "---" << std::endl;
265 std::cout << "-------- Put : currentDataId : " << currentDataId << "---" << std::endl;
266 std::cout << "-------- Put : expectedDataId : " << expectedDataId << "---" << std::endl;
267 std::cout << "-------- Put : MARK 9 ------------------" << std::endl;
268 }
269
270 // A simplifier mais :
271 // - pas possible de mettre des arguments optionnels à cause
272 // du type itérator qui n'est pas connu (pas de possibilité de déclarer un static )
273 // - compliquer de créer une méthode sans les paramètres inutiles tout en réutilisant
274 // la méthode initiale car cette dernière ne peut pas être déclarée virtuelle
275 // à cause de ses paramètres templates. Du coup, il faudrait aussi redéfinir la
276 // méthode simplifiée dans les classes définissant une politique
277 // de couplage particulière ...
278 bool dummy1,dummy2; typename DataTable::iterator dummy3;
279 // Par construction, les valeurs de waitingForAnyDataId, waitingForConvenientDataId et de
280 // expectedDataId ne peuvent pas être modifiées pendant le traitement de la boucle
281 // sur les dataIds (à cause du lock utilisé dans la méthode put et les méthodes get )
282 // rem : Utilisation de l'évaluation gauche droite du logical C or
283 if ( waitingForAnyDataId ||
284 ( waitingForConvenientDataId &&
285 this->isDataIdConveniant(storedDatas, expectedDataId, dummy1, dummy2, dummy3) )
286 )
287 {
288 if (SALOME::VerbosityActivated())
289 std::cout << "-------- Put : MARK 10 ------------------" << std::endl;
290
291 //Doit pouvoir réveiller le get ici (a vérifier)
292 expectedDataReceived = true;
293 }
294 }
295
296 if (expectedDataReceived) {
297 if (SALOME::VerbosityActivated())
298 std::cout << "-------- Put : MARK 11 ------------------" << std::endl;
299
300 // si waitingForAnyDataId était positionné, c'est forcément lui qui a activer
301 // expectedDataReceived à true
302 if (waitingForAnyDataId)
303 waitingForAnyDataId = false;
304 else
305 waitingForConvenientDataId = false;
306 // Reveille le thread du destinataire (stoppe son attente)
307 // Ne faudrait-il pas réveiller plutôt tous les threads ?
308 // Celui réveillé ne correspond pas forcément à celui qui demande
309 // cet expectedDataReceived.
310 // Pb1 : cas d'un un get séquentiel et d'un get sur un dataId que l'on vient de recevoir.
311 // Si l'on reveille le mauvais thread, l'autre va attendre indéfiniment ! (sauf timeout)
312 // Pb2 : également si deux attentes de DataIds même différents car on n'en stocke qu'un !
313 // Conclusion : Pour l'instant on ne gère pas un service multithreadé qui effectue
314 // des lectures simultanées sur le même port !
315 if (SALOME::VerbosityActivated())
316 std::cerr << "-------- Put : new datas available ------------------" << std::endl;
317
318 fflush(stdout);fflush(stderr);
319 cond_instance.signal();
320 }
321
322 if (SALOME::VerbosityActivated())
323 std::cout << "-------- Put : MARK 12 ------------------" << std::endl;
324
325 // Deverouille l'acces a la table : On peut remonter l'appel au dessus de expected...
326 storedDatas_mutex.unlock();
327
328 if (SALOME::VerbosityActivated())
329 std::cout << "-------- Put : MARK 13 ------------------" << std::endl;
330
331 fflush(stdout);
332 fflush(stderr);
333
334 } // Catch les exceptions SALOME//C++ pour la transformer en une exception SALOME//CORBA
335 catch ( const SALOME_Exception & ex ) {
336 // On évite de laisser un mutex
337 storedDatas_mutex.unlock();
339 }
340
341}
342
343// erase data before time or tag
344template < typename DataManipulator, typename COUPLING_POLICY >
345template <typename TimeType,typename TagType>
346void
348{
349 typename COUPLING_POLICY::template EraseDataIdBeforeOrAfterTagProcessor<DataManipulator> processEraseDataId(*this);
350 processEraseDataId.apply(storedDatas,time,tag,before);
351}
352
353// Version du Get en 0 copy
354// ( n'effectue pas de recopie de la donnée trouvée dans storedDatas )
355// ( L'utilisateur devra être attentif à la politique de gestion de l'historique
356// spécifique au mode de couplage car il peut y avoir une suppression potentielle
357// d'une donnée utilisée directement dans le code utilisateur )
358// Le code doit prendre connaissance du transfert de propriété ou non des données
359// auprès du mode de couplage choisi.
360template < typename DataManipulator, typename COUPLING_POLICY >
361template < typename TimeType,typename TagType>
362typename DataManipulator::Type
364 TagType tag)
365// REM : Laisse passer toutes les exceptions
366// En particulier les SALOME_Exceptions qui viennent de la COUPLING_POLICY
367// Pour déclarer le throw avec l'exception spécifique il faut que je vérifie
368// qu'un setunexpeted est positionné sinon le C++ arrête tout par appel à terminate
369{
370 typedef typename COUPLING_POLICY::DataId DataId;
371 // (Pointeur sur séquence) ou valeur..
372 DataType dataToTransmit ;
373 bool isEqual, isBounded;
374 typedef typename DataManipulator::InnerType InnerType;
375
376 if (SALOME::VerbosityActivated())
377 std::cout << "-------- Get : MARK 1 ------------------" << std::endl;
378
379 expectedDataId = DataId(time,tag);
380 if (SALOME::VerbosityActivated())
381 std::cout << "-------- Get : MARK 2 ------------------" << std::endl;
382
383 typename DataTable::iterator wDataIt1;
384
385 try {
386 storedDatas_mutex.lock(); // Gérer les Exceptions ds le corps de la méthode
387
388 while ( true ) {
389
390 // Renvoie isEqual si le dataId attendu est trouvé dans storedDatas :
391 // - l'itérateur wDataIt1 pointe alors sur ce dataId
392 // Renvoie isBounded si le dataId attendu n'est pas trouvé mais encadrable et
393 // que la politique gére ce cas de figure
394 // - l'itérateur wDataIt1 est tel que wDataIt1->first < wdataId < (wDataIt1+1)->first
395 // Méthode provenant de la COUPLING_POLICY
396 this->isDataIdConveniant(storedDatas,expectedDataId,isEqual,isBounded,wDataIt1);
397 if (SALOME::VerbosityActivated())
398 std::cout << "-------- Get : MARK 3 ------------------" << std::endl;
399
400 // L'ordre des différents tests est important
401 if ( isEqual ) {
402 if (SALOME::VerbosityActivated())
403 std::cout << "-------- Get : MARK 4 ------------------" << std::endl;
404
405 // La propriété de la données N'EST PAS transmise à l'utilisateur en mode CALCIUM.
406 // Si l'utilisateur supprime la donnée, storedDataIds devient incohérent
407 // C'est EraseDataId qui choisi ou non de supprimer la donnée
408 // Du coup interaction potentielle entre le 0 copy et gestion de l'historique
409 dataToTransmit = (*wDataIt1).second;
410
411 if (SALOME::VerbosityActivated())
412 {
413 std::cout << "-------- Get : MARK 5 ------------------" << std::endl;
414 std::cout << "-------- Get : Données trouvées à t : " << std::endl;
415 typename DataManipulator::InnerType const * const InIt1 = DataManipulator::getPointer(dataToTransmit);
416 size_t N = DataManipulator::size(dataToTransmit);
417 std::copy(InIt1, InIt1 + N,
418 std::ostream_iterator< InnerType > (std::cout," "));
419 std::cout << std::endl;
420 }
421
422 // Décide de la suppression de certaines instances de données
423 // La donnée contenu dans la structure CORBA et son dataId sont désallouées
424 // Méthode provenant de la COUPLING_POLICY
425 typename COUPLING_POLICY::template EraseDataIdProcessor<DataManipulator> processEraseDataId(*this);
426 processEraseDataId.apply(storedDatas,wDataIt1);
427 if (SALOME::VerbosityActivated())
428 std::cout << "-------- Get : MARK 6 ------------------" << std::endl;
429
430 break;
431 }
432
433 if (SALOME::VerbosityActivated())
434 std::cout << "-------- Get : MARK 7 ------------------" << std::endl;
435
436 //if ( isBounded() && COUPLING_POLICY::template needToProcessBoundedDataId() ) {
437 // Le DataId demandé n'est pas trouvé mais est encadré ET la politique de couplage
438 // implémente une méthode processBoundedDataId capable de générer les données à retourner
439 if ( isBounded ) {
440 // Pour être cohérent avec la politique du bloc précédent
441 // on stocke la paire (dataId,données interpolées ).
442 // CALCIUM ne stockait pas les données interpolées.
443 // Cependant comme les données sont censées être produites
444 // par ordre croissant de DataId, de nouvelles données ne devrait pas améliorer
445 // l'interpolation.
446 if (SALOME::VerbosityActivated())
447 std::cout << "-------- Get : MARK 8 ------------------" << std::endl;
448
449 typedef typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> BDI;
450 BDI processBoundedDataId(*this);
451 // typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> processBoundedDataId(*this);
452 //si static BDIP::apply(dataToTransmit,expectedDataId,wDataIt1);
453 //ancienne version template processBoundedDataId<DataManipulator>(dataToTransmit,expectedDataId,wDataIt1);
454 //BDIP processBoundedDataId;
455 processBoundedDataId.apply(dataToTransmit,expectedDataId,wDataIt1);
456
457 // Il ne peut pas y avoir déjà une clé expectedDataId dans storedDatas (utilisation de la notation [] )
458 // La nouvelle donnée produite est stockée, ce n'était pas le cas dans CALCIUM
459 // Cette opération n'a peut être pas un caractère générique.
460 // A déplacer en paramètre de la méthode précédente ? ou déléguer ce choix au mode de couplage ?
461 storedDatas[expectedDataId]=dataToTransmit;
462
463 if (SALOME::VerbosityActivated())
464 {
465 std::cout << "-------- Get : Données calculées à t : " << std::endl;
466 typename DataManipulator::InnerType const * const InIt1 = DataManipulator::getPointer(dataToTransmit);
467 size_t N = DataManipulator::size(dataToTransmit);
468
469 std::copy(InIt1, InIt1 + N,
470 std::ostream_iterator< InnerType > (std::cout," "));
471 std::cout << std::endl;
472 std::cout << "-------- Get : MARK 9 ------------------" << std::endl;
473 }
474
475 typename COUPLING_POLICY::template EraseDataIdProcessor<DataManipulator> processEraseDataId(*this);
476 processEraseDataId.apply(storedDatas,wDataIt1);
477
478 break;
479 }
480
481 // Délègue au mode de couplage la gestion d'une demande de donnée non disponible
482 // si le port est deconnecté
483 typename COUPLING_POLICY::template DisconnectProcessor<DataManipulator> processDisconnect(*this);
484 if ( processDisconnect.apply(storedDatas, expectedDataId, wDataIt1) ) continue;
485
486 // Réception bloquante sur le dataId demandé
487 // Si l'instance de donnée n'est pas trouvee
488 if (SALOME::VerbosityActivated())
489 std::cout << "-------- Get : MARK 10 ------------------" << std::endl;
490
491 //Positionné à faux dans la méthode put
492 waitingForConvenientDataId = true;
493 if (SALOME::VerbosityActivated())
494 {
495 std::cout << "-------- Get : MARK 11 ------------------" << std::endl;
496
497 // Ici on attend que la méthode put recoive la donnée
498 std::cout << "-------- Get : waiting datas ------------------" << std::endl;
499 }
500
501 fflush(stdout);fflush(stderr);
502 unsigned long ts, tns,rs=Superv_Component_i::dscTimeOut;
503 if(rs==0)
504 cond_instance.wait();
505 else
506 {
507 //Timed wait on omni condition
508 omni_thread::get_time(&ts,&tns, rs,0);
509 int success=cond_instance.timedwait(ts,tns);
510 if(!success)
511 {
512 // Waiting too long probably blocking
513 std::stringstream msg;
514 msg<<"Timeout ("<<rs<<" s) exceeded";
515 Engines_DSC_interface::writeEvent("BLOCKING","","","","Probably blocking",msg.str().c_str());
516 throw DSC_Exception(msg.str());
517 }
518 }
519
520 if (SALOME::VerbosityActivated())
521 std::cout << "-------- Get : MARK 12 ------------------" << std::endl;
522 }
523 } catch (...) {
524 waitingForConvenientDataId = true;
525 storedDatas_mutex.unlock();
526 throw;
527 }
528
529 // Deverouille l'acces a la table
530 storedDatas_mutex.unlock();
531 if (SALOME::VerbosityActivated())
532 std::cout << "-------- Get : MARK 13 ------------------" << std::endl;
533
534 // La propriété de la données N'EST PAS transmise à l'utilisateur en mode CALCIUM
535 // Si l'utilisateur supprime la donnée, storedDataIds devient incohérent
536 // c'est eraseDataId qui choisi ou non de supprimer la donnée
537 // Du coup interaction potentielle entre le 0 copy et gestion des niveaux
538 return dataToTransmit;
539
540}
541
542template < typename DataManipulator, typename COUPLING_POLICY >
543template < typename TimeType,typename TagType>
544typename DataManipulator::Type
546 TimeType tf,
547 TagType tag ) {
548 ti = COUPLING_POLICY::getEffectiveTime(ti,tf);
549 return get(ti,tag);
550}
551
552
553// Version du next en 0 copy
554// ( n'effectue pas de recopie de la donnée trouvée dans storedDatas )
555template < typename DataManipulator, typename COUPLING_POLICY >
556template < typename TimeType,typename TagType>
557typename DataManipulator::Type
559 TagType &tag ) {
560
561 typedef typename COUPLING_POLICY::DataId DataId;
562
563 DataType dataToTransmit;
564 DataId dataId;
565
566 try {
567 storedDatas_mutex.lock();// Gérer les Exceptions ds le corps de la méthode
568
569 if (SALOME::VerbosityActivated())
570 std::cout << "-------- Next : MARK 1 ---lastDataIdSet ("<<lastDataIdSet<<")---------------" << std::endl;
571
572 typename DataTable::iterator wDataIt1;
573 wDataIt1 = storedDatas.end();
574
575 //Recherche le prochain dataId à renvoyer
576 // - lastDataIdset == true indique que lastDataId
577 // contient le dernier DataId renvoyé
578 // - lastDataIdset == false indique que l'on renverra
579 // le premier dataId trouvé
580 // - upper_bound(lastDataId) situe le prochain DataId
581 // à renvoyer
582 // Rem : les données renvoyées ne sont effacées par eraseDataIds
583 // si necessaire
584 if (lastDataIdSet)
585 wDataIt1 = storedDatas.upper_bound(lastDataId);
586 else if ( !storedDatas.empty() ) {
587 lastDataIdSet = true;
588 wDataIt1 = storedDatas.begin();
589 }
590
591 typename COUPLING_POLICY::template DisconnectProcessor<DataManipulator> processDisconnect(*this);
592
593 while ( storedDatas.empty() || wDataIt1 == storedDatas.end() ) {
594
595 // Délègue au mode de couplage la gestion d'une demande de donnée non disponible
596 // si le port est deconnecté
597 if ( processDisconnect.apply(storedDatas, lastDataId, wDataIt1) ) {
598 waitingForAnyDataId = false; break;
599 }
600
601 if (SALOME::VerbosityActivated())
602 std::cout << "-------- Next : MARK 2 ------------------" << std::endl;
603
604 //Positionné à faux dans la méthode put
605 waitingForAnyDataId = true;
606
607 if (SALOME::VerbosityActivated())
608 {
609 std::cout << "-------- Next : MARK 3 ------------------" << std::endl;
610 // Ici on attend que la méthode put recoive la donnée
611 std::cout << "-------- Next : waiting datas ------------------" << std::endl;
612 }
613
614 fflush(stdout);fflush(stderr);
615 unsigned long ts, tns,rs=Superv_Component_i::dscTimeOut;
616 if(rs==0)
617 cond_instance.wait();
618 else
619 {
620 //Timed wait on omni condition
621 omni_thread::get_time(&ts,&tns, rs,0);
622 int success=cond_instance.timedwait(ts,tns);
623 if(!success)
624 {
625 // Waiting too long probably blocking
626 std::stringstream msg;
627 msg<<"Timeout ("<<rs<<" s) exceeded";
628 Engines_DSC_interface::writeEvent("BLOCKING","","","","Probably blocking",msg.str().c_str());
629 throw DSC_Exception(msg.str());
630 }
631 }
632
633 if (lastDataIdSet) {
634 if (SALOME::VerbosityActivated())
635 std::cout << "-------- Next : MARK 4 ------------------" << std::endl;
636
637 wDataIt1 = storedDatas.upper_bound(lastDataId);
638 } else {
639 if (SALOME::VerbosityActivated())
640 std::cout << "-------- Next : MARK 5 ------------------" << std::endl;
641
642 lastDataIdSet = true;
643 wDataIt1 = storedDatas.begin();
644 }
645 }
646
647 if (SALOME::VerbosityActivated())
648 std::cout << "-------- Next : MARK 6 ------------------" << std::endl;
649
650 t = this->getTime( (*wDataIt1).first );
651 tag = this->getTag ( (*wDataIt1).first );
652 dataToTransmit = (*wDataIt1).second;
653
654 if (SALOME::VerbosityActivated())
655 std::cout << "-------- Next : MARK 7 ------------------" << std::endl;
656
657 lastDataId = (*wDataIt1).first;
658
659 typename COUPLING_POLICY::template EraseDataIdProcessor<DataManipulator> processEraseDataId(*this);
660 processEraseDataId.apply(storedDatas, wDataIt1);
661
662 if (SALOME::VerbosityActivated())
663 std::cout << "-------- Next : MARK 8 ------------------" << std::endl;
664 } catch (...) {
665 if (SALOME::VerbosityActivated())
666 std::cout << "-------- Next : MARK 8bis ------------------" << std::endl;
667
668 waitingForAnyDataId = false;
669 storedDatas_mutex.unlock();
670 throw;
671 }
672 storedDatas_mutex.unlock();
673
674 if (SALOME::VerbosityActivated())
675 std::cout << "-------- Next : MARK 9 ------------------" << std::endl;
676
677 // La propriété de la données N'EST PAS transmise à l'utilisateur en mode CALCIUM
678 // Si l'utilisateur supprime la donnée, storedDataIds devient incohérent
679 // c'est eraseDataId qui choisi ou non de supprimer la donnée
680 // Du coup interaction potentielle entre le 0 copy et gestion des niveaux
681 return dataToTransmit;
682
683}
684
685#endif
#define THROW_SALOME_CORBA_EXCEPTION(chain, typex)
To raise a CORBA exception from a CORBA servant.
Definition: Utils_CorbaException.hxx:40
static void writeEvent(const char *request, const std::string &containerName, const char *instance_name, const char *port_name, const char *error, const char *message)
Write a record in the trace file.
Definition: DSC_interface.cxx:478
Definition: GenericPort.hxx:61
DataId expectedDataId
Definition: GenericPort.hxx:93
void close(PortableServer::POA_var poa, PortableServer::ObjectId_var id)
Definition: GenericPort.hxx:121
omni_mutex storedDatas_mutex
Definition: GenericPort.hxx:98
GenericPort()
Definition: GenericPort.hxx:105
DataManipulator::CorbaInType CorbaInDataType
Definition: GenericPort.hxx:65
bool lastDataIdSet
Definition: GenericPort.hxx:96
omni_condition cond_instance
Definition: GenericPort.hxx:100
std::map< DataId, DataType > DataTable
Definition: GenericPort.hxx:82
bool waitingForConvenientDataId
Definition: GenericPort.hxx:88
void put(CorbaInDataType data, TimeType time, TagType tag)
Definition: GenericPort.hxx:155
void erase(TimeType time, TagType tag, bool before)
Definition: GenericPort.hxx:347
void wakeupWaiting()
Definition: GenericPort.hxx:129
DataType next(TimeType &t, TagType &tag)
DataType get(TimeType time, TagType tag)
COUPLING_POLICY::DataId DataId
Definition: GenericPort.hxx:81
DataManipulator::Type DataType
Definition: GenericPort.hxx:64
DataType get(TimeType &ti, TimeType tf, TagType tag=0)
bool waitingForAnyDataId
Definition: GenericPort.hxx:90
virtual ~GenericPort()
Definition: GenericPort.hxx:110
DataTable storedDatas
Definition: GenericPort.hxx:85
DataId lastDataId
Definition: GenericPort.hxx:95
static long dscTimeOut
Definition: Superv_Component_i.hxx:251
poa
Definition: SALOME_ContainerPy.py:377
stdout
Definition: SALOME_ContainerPy.py:373
@ INTERNAL_ERROR
Application level problem, irrecoverable.
Definition: SALOME_Exception.idl:52
string msg
Definition: TestMinimalExample.py:168
def dump(filename)
Definition: pythfilter.py:368
def copy(src, dst)
Definition: pythonpath_reduction.py:35
def flush()
Definition: testPerfLogManager1.py:35
Definition: DSC_Exception.hxx:94
double TagType
Definition: testAdjacentPredicate.cxx:53
std::pair< TimeType, TagType > DataId
Definition: testAdjacentPredicate.cxx:54
int TimeType
Definition: testAdjacentPredicate.cxx:52