00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _GENERIC_PORT_HXX_
00031 #define _GENERIC_PORT_HXX_
00032
00033 #include "CorbaTypeManipulator.hxx"
00034
00035 #include "Superv_Component_i.hxx"
00036
00037 #include "Utils_CorbaException.hxx"
00038
00039 #include "Utils_SALOME_Exception.hxx"
00040 #include "DSC_Exception.hxx"
00041 #include "utilities.h"
00042
00043 #include <iostream>
00044 #include <map>
00045
00046
00047 #include <algorithm>
00048 #include <iterator>
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 template < typename DataManipulator, class COUPLING_POLICY >
00062 class GenericPort : public COUPLING_POLICY {
00063 public:
00064
00065 typedef typename DataManipulator::Type DataType;
00066 typedef typename DataManipulator::CorbaInType CorbaInDataType;
00067
00068 GenericPort();
00069 virtual ~GenericPort();
00070
00071 template <typename TimeType,typename TagType> void put(CorbaInDataType data, TimeType time, TagType tag);
00072 template <typename TimeType,typename TagType> DataType get(TimeType time, TagType tag);
00073 template <typename TimeType,typename TagType> DataType get(TimeType& ti, TimeType tf, TagType tag = 0);
00074 template <typename TimeType,typename TagType> DataType next(TimeType &t, TagType &tag );
00075 void close (PortableServer::POA_var poa, PortableServer::ObjectId_var id);
00076 void wakeupWaiting();
00077 template <typename TimeType,typename TagType> void erase(TimeType time, TagType tag, bool before );
00078
00079 private:
00080
00081
00082 typedef typename COUPLING_POLICY::DataId DataId;
00083 typedef std::map< DataId, DataType> DataTable;
00084
00085
00086 DataTable storedDatas ;
00087
00088
00089 bool waitingForConvenientDataId;
00090
00091 bool waitingForAnyDataId;
00092
00093
00094 DataId expectedDataId ;
00095
00096 DataId lastDataId;
00097 bool lastDataIdSet;
00098
00099 omni_mutex storedDatas_mutex;
00100
00101 omni_condition cond_instance;
00102
00103 };
00104
00105 template < typename DataManipulator, typename COUPLING_POLICY >
00106 GenericPort<DataManipulator, COUPLING_POLICY >::GenericPort() :
00107 cond_instance(& this->storedDatas_mutex),waitingForConvenientDataId(false),
00108 waitingForAnyDataId(false),lastDataIdSet(false) {}
00109
00110 template < typename DataManipulator, typename COUPLING_POLICY>
00111 GenericPort<DataManipulator, COUPLING_POLICY>::~GenericPort() {
00112 typename DataTable::iterator it;
00113 for (it=storedDatas.begin(); it!=storedDatas.end(); ++it) {
00114 #ifdef MYDEBUG
00115 std::cerr << "~GenericPort() : destruction de la donnnée associée au DataId :"<< (*it).first << std::endl;
00116 #endif
00117 DataManipulator::delete_data( (*it).second );
00118 }
00119 }
00120
00121 template < typename DataManipulator, typename COUPLING_POLICY> void
00122 GenericPort<DataManipulator, COUPLING_POLICY>::close (PortableServer::POA_var poa,
00123 PortableServer::ObjectId_var id) {
00124
00125
00126 poa->deactivate_object (id);
00127 }
00128
00129 template < typename DataManipulator, typename COUPLING_POLICY> void
00130 GenericPort<DataManipulator, COUPLING_POLICY>::wakeupWaiting()
00131 {
00132 #ifdef MYDEBUG
00133 std::cout << "-------- wakeupWaiting ------------------" << std::endl;
00134 #endif
00135 storedDatas_mutex.lock();
00136 if (waitingForAnyDataId || waitingForConvenientDataId) {
00137 #ifdef MYDEBUG
00138 std::cout << "-------- wakeupWaiting:signal --------" << std::endl;
00139 std::cout << std::flush;
00140 #endif
00141 cond_instance.signal();
00142 }
00143 storedDatas_mutex.unlock();
00144
00145 }
00146
00147
00148
00149
00150
00151
00152 template < typename DataManipulator, typename COUPLING_POLICY>
00153 template < typename TimeType,typename TagType>
00154 void GenericPort<DataManipulator, COUPLING_POLICY>::put(CorbaInDataType dataParam,
00155 TimeType time,
00156 TagType tag) {
00157 fflush(stdout);
00158 fflush(stderr);
00159 try {
00160 #ifdef MYDEBUG
00161
00162 std::cerr << "parametres emis: " << time << ", " << tag << std::endl;
00163 DataManipulator::dump(dataParam);
00164 #endif
00165
00166
00167
00168
00169
00170 typedef typename COUPLING_POLICY::DataIdContainer DataIdContainer;
00171 typedef typename COUPLING_POLICY::DataId DataId;
00172
00173 DataId dataId(time,tag);
00174
00175
00176
00177 DataIdContainer dataIds(dataId, *this);
00178
00179 typename DataIdContainer::iterator dataIdIt = dataIds.begin();
00180
00181 bool expectedDataReceived = false;
00182
00183 #ifdef MYDEBUG
00184 std::cout << "-------- Put : MARK 1 ------------------" << std::endl;
00185 #endif
00186 if ( dataIds.empty() ) return;
00187 #ifdef MYDEBUG
00188 std::cout << "-------- Put : MARK 1bis ------------------" << std::endl;
00189 #endif
00190
00191
00192
00193 DataType data = DataManipulator::get_data(dataParam);
00194
00195
00196 int nbOfIter = 0;
00197
00198 #ifdef MYDEBUG
00199 std::cout << "-------- Put : MARK 2 ------ "<< (dataIdIt == dataIds.end()) << "------------" << std::endl;
00200 std::cout << "-------- Put : MARK 2bis "<< (*dataIdIt) <<"------------------" << std::endl;
00201 #endif
00202 storedDatas_mutex.lock();
00203
00204 for (;dataIdIt != dataIds.end();++dataIdIt) {
00205
00206 #ifdef MYDEBUG
00207 std::cout << "-------- Put : MARK 3 ------------------" << std::endl;
00208 #endif
00209
00210 if (nbOfIter > 0) data = DataManipulator::clone(data);
00211 #ifdef MYDEBUG
00212 std::cout << "-------- Put : MARK 3bis -----"<< dataIdIt.operator*() <<"------------" << std::endl;
00213 #endif
00214
00215 DataId currentDataId=*dataIdIt;
00216
00217 #ifdef MYDEBUG
00218 std::cerr << "processing dataId : "<< currentDataId << std::endl;
00219
00220 std::cout << "-------- Put : MARK 4 ------------------" << std::endl;
00221 #endif
00222
00223
00224
00225
00226
00227
00228
00229
00230 typename DataTable::iterator wDataIt = storedDatas.lower_bound(currentDataId);
00231 #ifdef MYDEBUG
00232 std::cout << "-------- Put : MARK 5 ------------------" << std::endl;
00233 #endif
00234
00235
00236
00237 if (wDataIt == storedDatas.end() || storedDatas.key_comp()(currentDataId,(*wDataIt).first) ) {
00238 #ifdef MYDEBUG
00239 std::cout << "-------- Put : MARK 6 ------------------" << std::endl;
00240 #endif
00241
00242 wDataIt = storedDatas.insert(wDataIt, make_pair (currentDataId, data));
00243 } else {
00244
00245
00246 #ifdef MYDEBUG
00247 std::cout << "-------- Put : MARK 7 ------------------" << std::endl;
00248 #endif
00249
00250
00251 DataType old_data = (*wDataIt).second;
00252 (*wDataIt).second = data;
00253
00254 DataManipulator::delete_data (old_data);
00255 }
00256
00257 #ifdef MYDEBUG
00258 std::cout << "-------- Put : MARK 8 ------------------" << std::endl;
00259 #endif
00260
00261 ++nbOfIter;
00262
00263 #ifdef MYDEBUG
00264 std::cout << "-------- Put : waitingForConvenientDataId : " << waitingForConvenientDataId <<"---" << std::endl;
00265 std::cout << "-------- Put : waitingForAnyDataId : " << waitingForAnyDataId <<"---" << std::endl;
00266 std::cout << "-------- Put : currentDataId : " << currentDataId <<"---" << std::endl;
00267 std::cout << "-------- Put : expectedDataId : " << expectedDataId <<"---" << std::endl;
00268 std::cout << "-------- Put : MARK 9 ------------------" << std::endl;
00269 #endif
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 bool dummy1,dummy2; typename DataTable::iterator dummy3;
00280
00281
00282
00283
00284 if ( waitingForAnyDataId ||
00285 ( waitingForConvenientDataId &&
00286 isDataIdConveniant(storedDatas, expectedDataId, dummy1, dummy2, dummy3) )
00287 ) {
00288 #ifdef MYDEBUG
00289 std::cout << "-------- Put : MARK 10 ------------------" << std::endl;
00290 #endif
00291
00292 expectedDataReceived = true;
00293 }
00294 }
00295
00296 if (expectedDataReceived) {
00297 #ifdef MYDEBUG
00298 std::cout << "-------- Put : MARK 11 ------------------" << std::endl;
00299 #endif
00300
00301
00302 if (waitingForAnyDataId)
00303 waitingForAnyDataId = false;
00304 else
00305 waitingForConvenientDataId = false;
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 #ifdef MYDEBUG
00316 std::cerr << "-------- Put : new datas available ------------------" << std::endl;
00317 #endif
00318 fflush(stdout);fflush(stderr);
00319 cond_instance.signal();
00320 }
00321 #ifdef MYDEBUG
00322 std::cout << "-------- Put : MARK 12 ------------------" << std::endl;
00323 #endif
00324
00325
00326 storedDatas_mutex.unlock();
00327
00328 #ifdef MYDEBUG
00329 std::cout << "-------- Put : MARK 13 ------------------" << std::endl;
00330 #endif
00331 fflush(stdout);
00332 fflush(stderr);
00333
00334 }
00335 catch ( const SALOME_Exception & ex ) {
00336
00337 storedDatas_mutex.unlock();
00338 THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR);
00339 }
00340
00341 }
00342
00343
00344 template < typename DataManipulator, typename COUPLING_POLICY >
00345 template <typename TimeType,typename TagType>
00346 void
00347 GenericPort<DataManipulator, COUPLING_POLICY>::erase(TimeType time, TagType tag, bool before)
00348 {
00349 typename COUPLING_POLICY::template EraseDataIdBeforeOrAfterTagProcessor<DataManipulator> processEraseDataId(*this);
00350 processEraseDataId.apply(storedDatas,time,tag,before);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360 template < typename DataManipulator, typename COUPLING_POLICY >
00361 template < typename TimeType,typename TagType>
00362 typename DataManipulator::Type
00363 GenericPort<DataManipulator, COUPLING_POLICY>::get(TimeType time,
00364 TagType tag)
00365
00366
00367
00368
00369 {
00370 typedef typename COUPLING_POLICY::DataId DataId;
00371
00372 DataType dataToTransmit ;
00373 bool isEqual, isBounded;
00374 typedef typename DataManipulator::InnerType InnerType;
00375
00376 #ifdef MYDEBUG
00377 std::cout << "-------- Get : MARK 1 ------------------" << std::endl;
00378 #endif
00379 expectedDataId = DataId(time,tag);
00380 #ifdef MYDEBUG
00381 std::cout << "-------- Get : MARK 2 ------------------" << std::endl;
00382 #endif
00383
00384 typename DataTable::iterator wDataIt1;
00385
00386 try {
00387 storedDatas_mutex.lock();
00388
00389 while ( true ) {
00390
00391
00392
00393
00394
00395
00396
00397 isDataIdConveniant(storedDatas,expectedDataId,isEqual,isBounded,wDataIt1);
00398 #ifdef MYDEBUG
00399 std::cout << "-------- Get : MARK 3 ------------------" << std::endl;
00400 #endif
00401
00402
00403 if ( isEqual ) {
00404
00405 #ifdef MYDEBUG
00406 std::cout << "-------- Get : MARK 4 ------------------" << std::endl;
00407 #endif
00408
00409
00410
00411
00412 dataToTransmit = (*wDataIt1).second;
00413
00414 #ifdef MYDEBUG
00415 std::cout << "-------- Get : MARK 5 ------------------" << std::endl;
00416 std::cout << "-------- Get : Données trouvées à t : " << std::endl;
00417 typename DataManipulator::InnerType const * const InIt1 = DataManipulator::getPointer(dataToTransmit);
00418 size_t N = DataManipulator::size(dataToTransmit);
00419 std::copy(InIt1, InIt1 + N,
00420 std::ostream_iterator< InnerType > (std::cout," "));
00421 std::cout << std::endl;
00422 #endif
00423
00424
00425
00426
00427 typename COUPLING_POLICY::template EraseDataIdProcessor<DataManipulator> processEraseDataId(*this);
00428 processEraseDataId.apply(storedDatas,wDataIt1);
00429 #ifdef MYDEBUG
00430 std::cout << "-------- Get : MARK 6 ------------------" << std::endl;
00431 #endif
00432 break;
00433
00434 }
00435 #ifdef MYDEBUG
00436 std::cout << "-------- Get : MARK 7 ------------------" << std::endl;
00437 #endif
00438
00439
00440
00441
00442 if ( isBounded ) {
00443
00444
00445
00446
00447
00448
00449 #ifdef MYDEBUG
00450 std::cout << "-------- Get : MARK 8 ------------------" << std::endl;
00451 #endif
00452
00453 typedef typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> BDI;
00454 BDI processBoundedDataId(*this);
00455
00456
00457
00458
00459 processBoundedDataId.apply(dataToTransmit,expectedDataId,wDataIt1);
00460
00461
00462
00463
00464
00465 storedDatas[expectedDataId]=dataToTransmit;
00466
00467 #ifdef MYDEBUG
00468 std::cout << "-------- Get : Données calculées à t : " << std::endl;
00469 typename DataManipulator::InnerType const * const InIt1 = DataManipulator::getPointer(dataToTransmit);
00470 size_t N = DataManipulator::size(dataToTransmit);
00471
00472 std::copy(InIt1, InIt1 + N,
00473 std::ostream_iterator< InnerType > (std::cout," "));
00474 std::cout << std::endl;
00475 std::cout << "-------- Get : MARK 9 ------------------" << std::endl;
00476 #endif
00477
00478 typename COUPLING_POLICY::template EraseDataIdProcessor<DataManipulator> processEraseDataId(*this);
00479 processEraseDataId.apply(storedDatas,wDataIt1);
00480
00481 break;
00482 }
00483
00484
00485
00486 typename COUPLING_POLICY::template DisconnectProcessor<DataManipulator> processDisconnect(*this);
00487 if ( processDisconnect.apply(storedDatas, expectedDataId, wDataIt1) ) continue;
00488
00489
00490
00491 #ifdef MYDEBUG
00492 std::cout << "-------- Get : MARK 10 ------------------" << std::endl;
00493 #endif
00494
00495 waitingForConvenientDataId = true;
00496 #ifdef MYDEBUG
00497 std::cout << "-------- Get : MARK 11 ------------------" << std::endl;
00498
00499
00500 std::cout << "-------- Get : waiting datas ------------------" << std::endl;
00501 #endif
00502 fflush(stdout);fflush(stderr);
00503 unsigned long ts, tns,rs=Superv_Component_i::dscTimeOut;
00504 if(rs==0)
00505 cond_instance.wait();
00506 else
00507 {
00508
00509 omni_thread::get_time(&ts,&tns, rs,0);
00510 int success=cond_instance.timedwait(ts,tns);
00511 if(!success)
00512 {
00513
00514 std::stringstream msg;
00515 msg<<"Timeout ("<<rs<<" s) exceeded";
00516 Engines_DSC_interface::writeEvent("BLOCKING","","","","Probably blocking",msg.str().c_str());
00517 throw DSC_Exception(msg.str());
00518 }
00519 }
00520
00521
00522 #ifdef MYDEBUG
00523 std::cout << "-------- Get : MARK 12 ------------------" << std::endl;
00524 #endif
00525 }
00526
00527 } catch (...) {
00528 waitingForConvenientDataId = true;
00529 storedDatas_mutex.unlock();
00530 throw;
00531 }
00532
00533
00534 storedDatas_mutex.unlock();
00535 #ifdef MYDEBUG
00536 std::cout << "-------- Get : MARK 13 ------------------" << std::endl;
00537 #endif
00538
00539
00540
00541
00542
00543 return dataToTransmit;
00544
00545 }
00546
00547 template < typename DataManipulator, typename COUPLING_POLICY >
00548 template < typename TimeType,typename TagType>
00549 typename DataManipulator::Type
00550 GenericPort<DataManipulator, COUPLING_POLICY>::get(TimeType& ti,
00551 TimeType tf,
00552 TagType tag ) {
00553 ti = COUPLING_POLICY::getEffectiveTime(ti,tf);
00554 return get(ti,tag);
00555 }
00556
00557
00558
00559
00560 template < typename DataManipulator, typename COUPLING_POLICY >
00561 template < typename TimeType,typename TagType>
00562 typename DataManipulator::Type
00563 GenericPort<DataManipulator, COUPLING_POLICY>::next(TimeType &t,
00564 TagType &tag ) {
00565
00566 typedef typename COUPLING_POLICY::DataId DataId;
00567
00568 DataType dataToTransmit;
00569 DataId dataId;
00570
00571 try {
00572 storedDatas_mutex.lock();
00573
00574 #ifdef MYDEBUG
00575 std::cout << "-------- Next : MARK 1 ---lastDataIdSet ("<<lastDataIdSet<<")---------------" << std::endl;
00576 #endif
00577
00578 typename DataTable::iterator wDataIt1;
00579 wDataIt1 = storedDatas.end();
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 if (lastDataIdSet)
00591 wDataIt1 = storedDatas.upper_bound(lastDataId);
00592 else if ( !storedDatas.empty() ) {
00593 lastDataIdSet = true;
00594 wDataIt1 = storedDatas.begin();
00595 }
00596
00597 typename COUPLING_POLICY::template DisconnectProcessor<DataManipulator> processDisconnect(*this);
00598
00599 while ( storedDatas.empty() || wDataIt1 == storedDatas.end() ) {
00600
00601
00602
00603 if ( processDisconnect.apply(storedDatas, lastDataId, wDataIt1) ) {
00604 waitingForAnyDataId = false; break;
00605 }
00606
00607 #ifdef MYDEBUG
00608 std::cout << "-------- Next : MARK 2 ------------------" << std::endl;
00609 #endif
00610
00611 waitingForAnyDataId = true;
00612 #ifdef MYDEBUG
00613 std::cout << "-------- Next : MARK 3 ------------------" << std::endl;
00614
00615 std::cout << "-------- Next : waiting datas ------------------" << std::endl;
00616 #endif
00617 fflush(stdout);fflush(stderr);
00618 unsigned long ts, tns,rs=Superv_Component_i::dscTimeOut;
00619 if(rs==0)
00620 cond_instance.wait();
00621 else
00622 {
00623
00624 omni_thread::get_time(&ts,&tns, rs,0);
00625 int success=cond_instance.timedwait(ts,tns);
00626 if(!success)
00627 {
00628
00629 std::stringstream msg;
00630 msg<<"Timeout ("<<rs<<" s) exceeded";
00631 Engines_DSC_interface::writeEvent("BLOCKING","","","","Probably blocking",msg.str().c_str());
00632 throw DSC_Exception(msg.str());
00633 }
00634 }
00635
00636 if (lastDataIdSet) {
00637 #ifdef MYDEBUG
00638 std::cout << "-------- Next : MARK 4 ------------------" << std::endl;
00639 #endif
00640 wDataIt1 = storedDatas.upper_bound(lastDataId);
00641 } else {
00642 #ifdef MYDEBUG
00643 std::cout << "-------- Next : MARK 5 ------------------" << std::endl;
00644 #endif
00645 lastDataIdSet = true;
00646 wDataIt1 = storedDatas.begin();
00647 }
00648 }
00649
00650 #ifdef MYDEBUG
00651 std::cout << "-------- Next : MARK 6 ------------------" << std::endl;
00652 #endif
00653
00654 t = getTime( (*wDataIt1).first );
00655 tag = getTag ( (*wDataIt1).first );
00656 dataToTransmit = (*wDataIt1).second;
00657
00658 #ifdef MYDEBUG
00659 std::cout << "-------- Next : MARK 7 ------------------" << std::endl;
00660 #endif
00661 lastDataId = (*wDataIt1).first;
00662
00663 typename COUPLING_POLICY::template EraseDataIdProcessor<DataManipulator> processEraseDataId(*this);
00664 processEraseDataId.apply(storedDatas, wDataIt1);
00665
00666 #ifdef MYDEBUG
00667 std::cout << "-------- Next : MARK 8 ------------------" << std::endl;
00668 #endif
00669 } catch (...) {
00670 #ifdef MYDEBUG
00671 std::cout << "-------- Next : MARK 8bis ------------------" << std::endl;
00672 #endif
00673 waitingForAnyDataId = false;
00674 storedDatas_mutex.unlock();
00675 throw;
00676 }
00677 storedDatas_mutex.unlock();
00678
00679 #ifdef MYDEBUG
00680 std::cout << "-------- Next : MARK 9 ------------------" << std::endl;
00681 #endif
00682
00683
00684
00685
00686
00687 return dataToTransmit;
00688
00689 };
00690
00691 #endif