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