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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #include <config.h>
00062
00063
00064 #ifdef HAVE_UNISTD_H
00065 #include <unistd.h>
00066 #endif
00067
00068 #include <iostream>
00069
00070 #ifdef WIN32
00071 #include <windows.h>
00072 #include <time.h>
00073 #endif
00074
00075
00076 #include <omnithread.h>
00077
00078
00079
00080
00081 #include <debug.h>
00082
00083 #include <cmdlineprops.h>
00084
00085 #include <DefaultContextSwitch.h>
00086
00087
00088 #include "TemplateService.h"
00089
00090
00091 using namespace DWARF;
00092
00093
00094
00095
00096 TemplateService::TemplateService() :
00097 m_mutexShouldRun(),
00098 m_signalShouldRun(&m_mutexShouldRun),
00099 m_name("Unknown"),
00100 m_shouldRun(false)
00101 {
00102 DEBUGSTREAM(5, "Constructor");
00103 }
00104
00105 TemplateService::~TemplateService() {
00106 stopService( NULL );
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 char* TemplateService::getStatus() {
00123 DEBUGSTREAM(20, "getStatus");
00124 char status[512];
00125 sprintf(status, "Dummy message. Overwrite TemplateService::getStatus() to get useful results.");
00126 return CORBA::string_dup(status);
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 void TemplateService::startService(ActiveServiceDescription_ptr serviceDesc) {
00152
00153 DEBUGSTREAM(1, "startService");
00154
00155 try{
00156 m_name = serviceDesc->getName();
00157 m_serviceDesc = ActiveServiceDescription::_duplicate(serviceDesc);
00158 }
00159 catch(CORBA::Exception&) {
00160 DEBUGSTREAM(1, "Caught CORBA::Exception while getting service's name");
00161 }
00162 catch(...) {
00163 DEBUGSTREAM(1, "Caught unknown exception while getting service's name");
00164 }
00165
00166
00167 DEBUGSTREAM(15, m_name << ": Parsing abilities...");
00168 parseAbilities(serviceDesc);
00169 DEBUGSTREAM(15, m_name << ": Parsing needs...");
00170 parseNeeds(serviceDesc);
00171 DEBUGSTREAM(15, m_name << ": Looking for ContextSwitch need...");
00172 checkContextSwitch(serviceDesc);
00173
00174
00175 DEBUGSTREAM(15, m_name << ": Starting Control object in new thread");
00176 m_mutexShouldRun.lock();
00177 m_shouldRun = true;
00178 m_signalShouldRun.broadcast();
00179 (new omni_thread( &controlThreadStarter, this ))->start();
00180 DEBUGSTREAM(10, m_name << ": Thread created and start() called. Signaling it that is should run.");
00181 m_mutexShouldRun.unlock();
00182 DEBUGSTREAM(1, m_name << ": Control thread started, startService finished.");
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 void TemplateService::stopService(ActiveServiceDescription_ptr serviceDesc) {
00198 DEBUGSTREAM(1, m_name << ": stopService. Shutting down...");
00199
00200
00201
00202
00203
00204
00205 DEBUGSTREAM(1, m_name << ": Service Controller and all Needs and Abilities NOT destroyed -- find out how to correctly destroy CORBA objects!");
00206
00207 m_mutexShouldRun.lock();
00208 m_shouldRun = false;
00209 m_signalShouldRun.broadcast();
00210 m_mutexShouldRun.unlock();
00211 DEBUGSTREAM(10, "Signaled change of m_shouldRun");
00212 }
00213
00214
00215
00216
00217
00218 std::vector<std::string>* TemplateService::getAbilities(){
00219 std::vector<std::string> *retVal = new std::vector<std::string>;
00220 retVal->reserve( m_abilityMap.size() );
00221 typedef ObjectMap::iterator needAbilIterator;
00222 for( needAbilIterator abils = m_abilityMap.begin(); abils != m_abilityMap.end(); abils++ ) {
00223 retVal->push_back((std::string)abils->first);
00224 }
00225 return retVal;
00226 }
00227
00228
00229
00230
00231
00232 std::vector<std::string>* TemplateService::getNeeds(){
00233 std::vector<std::string> *retVal = new std::vector<std::string>;
00234 retVal->reserve( m_needMap.size() );
00235 typedef ObjectMap::iterator needAbilIterator;
00236 for( needAbilIterator needs = m_needMap.begin(); needs != m_needMap.end(); needs++ ) {
00237 retVal->push_back(needs->first);
00238 }
00239 return retVal;
00240 }
00241
00242
00243
00244
00245
00246 void TemplateService::addAbility(CORBA::String_var name, CORBA::Object_ptr object){
00247 m_abilityMap[(const char*)name] = CORBA::Object::_duplicate( object );
00248 return;
00249 }
00250
00251
00252
00253
00254 CORBA::Object_var TemplateService::getAbility(std::string name){
00255 if( m_abilityMap.find( name ) != m_abilityMap.end() )
00256 return m_abilityMap[name];
00257
00258 return CORBA::Object::_nil();
00259 }
00260
00261
00262
00263
00264 void TemplateService::addNeed(CORBA::String_var name, CORBA::Object_ptr object){
00265 m_needMap[(const char*)name] = CORBA::Object::_duplicate( object );
00266 return;
00267 }
00268
00269
00270
00271
00272 CORBA::Object_var TemplateService::getNeed(std::string name){
00273 if( m_needMap.find( name ) != m_needMap.end() )
00274 return m_needMap[name];
00275
00276 return CORBA::Object::_nil();
00277 }
00278
00279
00280
00281
00282
00283 ActiveServiceDescription_ptr TemplateService::getServiceDesc(){
00284 return ActiveServiceDescription::_duplicate(m_serviceDesc);
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 void TemplateService::parseAbilities(ActiveServiceDescription_ptr serviceDesc) {
00302
00303 StringSeq_var abilities;
00304 try {
00305 abilities = serviceDesc->getAbilities();
00306 DEBUGSTREAM(20, m_name << ": Found " << abilities->length() << " Abilities");
00307 }
00308 catch(CORBA::Exception&) {
00309 DEBUGSTREAM(1, m_name << ": Caught CORBA::Exception while getting abilities.");
00310 }
00311 catch(...) {
00312 DEBUGSTREAM(1, m_name << ": Caught unknown exception while getting abilities..");
00313 }
00314
00315 unsigned int num_abil=0;
00316 unsigned int reg_abil=0;
00317 for(num_abil=0; num_abil<abilities->length(); num_abil++) {
00318 try {
00319
00320 AbilityDescription_ptr abilityDescr = serviceDesc->getAbility(abilities[num_abil]);
00321
00322
00323 CORBA::Object_var abil = getAbility( abilityDescr->getName() );
00324 if ( CORBA::is_nil( abil ) || !checkAbilityObject( abil, abilityDescr ) )
00325
00326 abil = createAbilityObject( abilityDescr );
00327
00328
00329
00330 if( !CORBA::is_nil(abil) && checkAbilityObject(abil,abilityDescr) ) {
00331
00332
00333 DEBUGSTREAM(10, m_name << ": Registering " << abilityDescr->getType() << " Ability " <<
00334 abilityDescr->getName() << " at ServiceManager");
00335 serviceDesc->registerAbility( abilityDescr->getName(), abil );
00336 reg_abil++;
00337
00338
00339 addAbility( abilities[num_abil], abil );
00340 }
00341
00342 else {
00343
00344 m_abilityMap.erase(abilityDescr->getName());
00345
00346 DEBUGSTREAM(0, m_name << ": The object you specified for ability <" << abilityDescr->getName() <<
00347 "> either has no type that is understood by this service implementation or" <<
00348 " does not implement the interfaces necessary for its connectors." << std::endl <<
00349 " It will not be registered at the service manager.");
00350 serviceDesc->deleteAbility(abilityDescr->getName());
00351 }
00352 }
00353 catch(CORBA::Exception&) {
00354 DEBUGSTREAM(1, m_name << ": Caught CORBA::Exception while setting up ability " << num_abil);
00355 }
00356 catch(...) {
00357 DEBUGSTREAM(1, m_name << ": Caught unknown exception while setting up ability " << num_abil);
00358 }
00359 }
00360 DEBUGSTREAM(5, m_name << ": Done parsing abilities, found " << num_abil << " abilities and registered "
00361 << reg_abil << " of these." << std::endl);
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371 bool TemplateService::checkAbilityObject(CORBA::Object_ptr ability, AbilityDescription_ptr abilityDescr){
00372 bool validObject = true;
00373 try {
00374 StringSeq_var connectors = abilityDescr->getConnectors();
00375 for( unsigned int i=0; i<connectors->length(); i++) {
00376 const char *connProtocol = (const char*) abilityDescr->getConnector(connectors[i])->getProtocol();
00377 DEBUGSTREAM(20, m_name << ": Found Connector " << abilityDescr->getConnector(connectors[i])
00378 << " of protocol " << connProtocol);
00379 if(!strcmp(connProtocol, "PushSupplier")) {
00380
00381 if( !ability->_is_a("IDL:in.tum.de/DWARF/SvcProtPushSupplier:1.0") ) {
00382
00383 validObject = false;
00384 break;
00385 }
00386 }
00387 else if(!strcmp(connProtocol, "Shmem")) {
00388
00389 if( !ability->_is_a("IDL:in.tum.de/DWARF/SvcProtShmem:1.0") ) {
00390
00391 validObject = false;
00392 break;
00393 }
00394 }
00395 }
00396
00397
00398 if( ability->_is_a("IDL:in.tum.de/DWARF/SvcSession:1.0")) validObject = true;
00399 }
00400 catch(CORBA::Exception&) {
00401 DEBUGSTREAM(1, m_name << ": Caught CORBA::Exception while checking ability object.");
00402 return false;
00403 }
00404 catch(...) {
00405 DEBUGSTREAM(1, m_name << ": Caught unknown exception while checking ability object.");
00406 return false;
00407 }
00408 return validObject;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 void TemplateService::parseNeeds(ActiveServiceDescription_ptr serviceDesc) {
00424
00425 StringSeq_var needs;
00426 try {
00427 needs = serviceDesc->getNeeds();
00428 DEBUGSTREAM(20, m_name << ": Found " << needs->length() << " Needs");
00429 }
00430 catch(CORBA::Exception&) {
00431 DEBUGSTREAM(1, m_name << ": Caught CORBA::Exception while getting needs.");
00432 }
00433 catch(...) {
00434 DEBUGSTREAM(1, m_name << ": Caught unknown exception while getting needs.");
00435 }
00436
00437 unsigned int num_need=0;
00438 unsigned int reg_need=0;
00439 for(num_need=0; num_need<needs->length(); num_need++) {
00440 try {
00441
00442 NeedDescription_ptr needDescr = serviceDesc->getNeed(needs[num_need]);
00443
00444 if(!strcmp(needDescr->getType(), "ContextSwitch") ) continue;
00445
00446
00447 CORBA::Object_var need = getNeed( static_cast< const char* >( needs[num_need] ) );
00448 if ( CORBA::is_nil( need ) || !checkNeedObject( need, needDescr ) )
00449 need = createNeedObject( needDescr );
00450
00451
00452
00453 if( !CORBA::is_nil(need) && checkNeedObject(need,needDescr) ) {
00454
00455
00456 DEBUGSTREAM(10, m_name << ": Registering " << needDescr->getType() << " Need " <<
00457 needDescr->getName() << " at ServiceManager");
00458 serviceDesc->registerNeed( needDescr->getName(), need );
00459 reg_need++;
00460
00461
00462 addNeed( needs[num_need], need );
00463 }
00464
00465 else {
00466
00467 m_needMap.erase(needDescr->getName());
00468
00469 DEBUGSTREAM(0, m_name << ": The object you specified for need <" << needDescr->getName() <<
00470 "> either has no type that is understood by this service implementation or" <<
00471 " does not implement the interfaces necessary for its connectors." << std::endl <<
00472 " It will not be registered at the service manager.");
00473 serviceDesc->deleteNeed(needDescr->getName());
00474 }
00475 }
00476 catch(CORBA::Exception&) {
00477 DEBUGSTREAM(1, m_name << ": Caught CORBA::Exception while setting up need #" << num_need);
00478 }
00479 catch(...) {
00480 DEBUGSTREAM(1, m_name << ": Caught unknown exception while setting up need #" << num_need);
00481 }
00482 }
00483 DEBUGSTREAM(5, m_name << ": Done parsing needs, found " << num_need << " needs and registered "
00484 << reg_need << " of these.");
00485
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495 bool TemplateService::checkNeedObject(CORBA::Object_ptr need, NeedDescription_ptr needDescr){
00496 bool validObject = true;
00497 try {
00498 StringSeq_var connectors = needDescr->getConnectors();
00499 for( unsigned int i=0; i<connectors->length(); i++) {
00500 const char *connProtocol = (const char*) needDescr->getConnector(connectors[i])->getProtocol();
00501 DEBUGSTREAM(20, m_name << ": Found Connector " << needDescr->getConnector(connectors[i])
00502 << " of protocol " << connProtocol);
00503 if(!strcmp(connProtocol, "PushConsumer")) {
00504
00505 if( !need->_is_a("IDL:in.tum.de/DWARF/SvcProtPushConsumer:1.0") ) {
00506
00507 validObject = false;
00508 break;
00509 }
00510 }
00511 else if(!strcmp(connProtocol, "PullConsumer")) {
00512
00513 if( !need->_is_a("IDL:in.tum.de/DWARF/SvcProtPullConsumer:1.0") ) {
00514
00515 validObject = false;
00516 break;
00517 }
00518 }
00519 else if(!strcmp(connProtocol, "Shmem")) {
00520
00521 if( !need->_is_a("IDL:in.tum.de/DWARF/SvcProtShmem:1.0") ) {
00522
00523 validObject = false;
00524 break;
00525 }
00526 }
00527 else if(!strcmp(connProtocol, "ObjrefImporter")) {
00528
00529 if( !need->_is_a("IDL:in.tum.de/DWARF/SvcProtObjrefImporter:1.0") ) {
00530
00531 validObject = false;
00532 break;
00533 }
00534 }
00535 }
00536 if( validObject==false ) {
00537
00538
00539 if( need->_is_a("IDL:in.tum.de/DWARF/SvcSession:1.0") ) validObject = true;
00540 }
00541 }
00542 catch(CORBA::Exception&) {
00543 DEBUGSTREAM(1, m_name << ": Caught CORBA::Exception while checking need object.");
00544 return false;
00545 }
00546 catch(...) {
00547 DEBUGSTREAM(1, m_name << ": Caught unknown exception while checking need object.");
00548 return false;
00549 }
00550 return validObject;
00551 }
00552
00553 void TemplateService::checkContextSwitch(DWARF::ActiveServiceDescription_ptr serviceDesc) {
00554
00555 StringSeq_var needs;
00556 try {
00557 needs = serviceDesc->getNeeds();
00558 DEBUGSTREAM(20, m_name << ": Found " << needs->length() << " Needs");
00559 }
00560 catch(CORBA::Exception&) {
00561 DEBUGSTREAM(1, m_name << ": Caught CORBA::Exception while getting needs.");
00562 }
00563 catch(...) {
00564 DEBUGSTREAM(1, m_name << ": Caught unknown exception while getting needs.");
00565 }
00566
00567 unsigned int num_need=0;
00568 unsigned int reg_need=0;
00569 for(num_need=0; num_need<needs->length(); num_need++) {
00570 try {
00571
00572 NeedDescription_ptr needDescr = serviceDesc->getNeed(needs[num_need]);
00573
00574 if(strcmp(needDescr->getType(), "ContextSwitch")) continue;
00575
00576 CORBA::Object_ptr contextSwitch = createContextSwitchObject(needDescr, serviceDesc);
00577
00578
00579
00580 if( !CORBA::is_nil(contextSwitch) && checkNeedObject(contextSwitch,needDescr) ) {
00581
00582
00583 DEBUGSTREAM(10, m_name << ": Registering ContextSwitch Need " <<
00584 needDescr->getName() << " at ServiceManager");
00585 serviceDesc->registerNeed( needDescr->getName(), contextSwitch );
00586 reg_need++;
00587 }
00588
00589 else {
00590
00591 m_needMap.erase(needDescr->getName());
00592
00593 serviceDesc->deleteNeed(needDescr->getName());
00594 }
00595 }
00596 catch(CORBA::Exception&) {
00597 DEBUGSTREAM(1, m_name << ": Caught CORBA::Exception while setting up ContextSwitch need #" << num_need);
00598 }
00599 catch(...) {
00600 DEBUGSTREAM(1, m_name << ": Caught unknown exception while setting up ContextSwitch need #" << num_need);
00601 }
00602 }
00603 return;
00604 }
00605
00606
00607 CORBA::Object_ptr TemplateService::createContextSwitchObject( DWARF::NeedDescription_ptr needDescr,
00608 DWARF::ActiveServiceDescription_ptr serviceDesc ) {
00609
00610 POA_DWARF::ContextSwitch *object = new DefaultContextSwitch(needDescr, serviceDesc);
00611 CORBA::Object_ptr pCorbaObject = object->_this();
00612 addNeed( needDescr->getName(), pCorbaObject );
00613 return pCorbaObject;
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623 void* TemplateService::controlThreadStarter(void* data) {
00624 ((TemplateService*)data)->run();
00625 return 0;
00626 }
00627
00628
00629
00630
00631
00632 void TemplateService::run() {
00633 DEBUGSTREAM(1, m_name << ": Default run() method. Returning immediately");
00634 return;
00635 }
00636
00637 void TemplateService::blockUntilRunning() {
00638 m_mutexShouldRun.lock();
00639 while(!m_shouldRun) m_signalShouldRun.wait();
00640 m_mutexShouldRun.unlock();
00641 }
00642
00643 void TemplateService::blockUntilStopped() {
00644 m_mutexShouldRun.lock();
00645 while(m_shouldRun) m_signalShouldRun.wait();
00646 m_mutexShouldRun.unlock();
00647 }
00648 bool TemplateService::shouldRun() {
00649 bool retval;
00650 m_mutexShouldRun.lock();
00651 retval = m_shouldRun;
00652 m_mutexShouldRun.unlock();
00653 return retval;
00654 }