div class="twikiTopBar">

Chair for Computer Aided Medical Procedures & Augmented Reality
Lehrstuhl für Informatikanwendungen in der Medizin & Augmented Reality

TemplateService.cpp

Go to the documentation of this file.
00001 /* ========================================================================
00002  * Copyright (C) 2000-2003  Technische Universit� Mnchen
00003  *
00004  * This framework is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This framework is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this framework; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  * For further information please contact the DWARF team at
00019  * <dwarf-gnu@augmentedreality.de>
00020  * ========================================================================
00021  * PROJECT: DWARF
00022  * ======================================================================== */
00023 
00024 /*
00025  * Base class for DWARF services
00026  * TemplateService.cpp
00027  * Martin Wagner, October 2003
00028  * Distributed Wearable Augmented Reality Framework - www.augmentedreality.de
00029  *
00030  * For documentation and instructions, see the DWARF documentation website at
00031  * http://wwwbruegge.in.tum.de/projects/dwarf/doc/
00032  *
00033  * For further questions about DWARF, please contact us at
00034  * dwarf@augmentedreality.de
00035  * For questions about this particular service, contact
00036  * Martin Wagner <martin@augmentedreality.de>
00037  *
00038  * $Id: TemplateService.cpp,v 1.8 2006/02/15 17:41:45 pustka Exp $
00039  */
00040 
00041 /**
00042  * @defgroup CPPServiceTemplate Base class for DWARF services
00043  * This is a sample implementation of a DWARF service written in C++.
00044  *
00045  * @author Martin Wagner <martin@augmentedreality.de>
00046  */
00047 
00048 /**
00049  * @file TemplateService.cpp
00050  * @brief The file containing the template service class implementation.
00051  *
00052  * This file contains the implementation of class TemplateService. We use only
00053  * the most simple interface, BasicService. BasicService implements the DWARF
00054  * Service interface and the DWARF SvcStartup interface.
00055  * See the DWARF Middleware Tutorial for details.
00056  *
00057  * @author Martin Wagner <martin@augmentedreality.de>
00058  * @ingroup CPPServiceTemplate
00059  */
00060 // cmake/autoconf generated file with configuration information
00061 #include <config.h>
00062 
00063 // standard c headers
00064 #ifdef HAVE_UNISTD_H
00065 #include <unistd.h>
00066 #endif
00067 // standard c++ headers
00068 #include <iostream>
00069 
00070 #ifdef WIN32
00071 #include <windows.h>
00072 #include <time.h>
00073 #endif
00074 
00075 // omniORB threading library header
00076 #include <omnithread.h>
00077 
00078 
00079 
00080 // DWARF debug library header, providing DEBUGSTREAM macro
00081 #include <debug.h>
00082 // DWARF command line parsing library header file
00083 #include <cmdlineprops.h>
00084 
00085 #include <DefaultContextSwitch.h>
00086 
00087 // The service header file
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  * This method stems from the DWARF Service interface. It is
00112  * not necessary to implement it, however, you can provide
00113  * more or less useful status information to the service manager
00114  * and other services interested in (e.g. DIVE)
00115  *
00116  * @warning called only from service manager.
00117  * Do not call these methods yourself!
00118  *
00119  * @return CORBA string that must be generated using string_dup
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  * This method is called by the service manager on startup. Use this
00132  * method as the core initialization routine, parsing the service's
00133  * description for needs and abilities and instantiating corresponding
00134  * objects.
00135  *
00136  * The sequence of action is as follows:
00137  *  -# Back up the service description to a private variable.
00138  *  -# Parse all Needs and Abilities (call createAbility/NeedObject for every need),
00139  *     here you can implement your own behavior by subclassing
00140  *  -# Check if a need of type ContextSwitch exists and set up a handler object
00141  *  -# Execute the run() method in a new thread. Implement your own behavior by
00142  *     subclassing, the default method returns immediately.
00143  *
00144  * @TODO Document how the ContextSwitch mechanism works
00145  * @param serviceDesc The description of this service. This is a service's only
00146  *                    opportunity to get hold of its own service description.
00147  *                    If it is needed later on, store a copy of it in a member
00148  *                    variable
00149  * @warning This method should only be called by the service manager.
00150  */
00151 void TemplateService::startService(ActiveServiceDescription_ptr serviceDesc) {
00152 
00153   DEBUGSTREAM(1, "startService");
00154   // set service's name and remember serviceDesc
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   // set up object structure
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   // set up control object and start new thread
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  * This method is called by the service manager on shutdown of the
00188  * service. We use this method to delete the Service Control object,
00189  * assuming that it takes all necessary means in its destructor to
00190  * stop the controller thread(s). In addition, we delete all objects
00191  * handling the service's needs and abilities
00192  *
00193  * @param serviceDesc The service's description given by the service
00194  *                    manager
00195  * @warning This method should only be called by the service manager.
00196  */
00197 void TemplateService::stopService(ActiveServiceDescription_ptr serviceDesc) {
00198   DEBUGSTREAM(1, m_name << ": stopService. Shutting down...");
00199   // clear all hashmap entries, thereby deleting
00200   // all Object_var's in the maps
00201 
00202   // This will not work. Have to rethink cleaning up CORBA objects -- Daniel
00203   //m_abilityMap.clear();
00204   //m_needMap.clear();
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 // Access to abilities, needs and service description
00215 /**
00216  * @brief returns a list with all abilities' names
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  * @brief returns a list with all needs' names
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  * @brief add a CORBA object registered for ability <name>
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  * @brief returns the CORBA object registered for ability <name>
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  * @brief add a CORBA object registered for need <name>
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  * @brief returns the CORBA object registered for need <name>
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  * @brief returns the service's description
00282  */
00283 ActiveServiceDescription_ptr TemplateService::getServiceDesc(){
00284         return ActiveServiceDescription::_duplicate(m_serviceDesc);
00285 }
00286 
00287 
00288 
00289 // Protected Methods
00290 
00291 /**
00292  *  Parse all Abilities, for each found do
00293  *    -# Check for its type and connector protocol.
00294  *    -# Based on type, instantiate an object from a specific class
00295  *       (this is dependent on the actual service).
00296  *    -# Check whether this object can handle the specified protocol.
00297  *    -# Store the Ability description in a private hashmap.
00298  *    .
00299  * @param serviceDesc The description of this service.
00300  */
00301 void TemplateService::parseAbilities(ActiveServiceDescription_ptr serviceDesc) {
00302         // get all abilities' names
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         // now parse all abilities one by one
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                         // Create an object
00320                         AbilityDescription_ptr abilityDescr = serviceDesc->getAbility(abilities[num_abil]);
00321 
00322          // check if we have an object in our map and it implements the specified connectors
00323          CORBA::Object_var abil = getAbility( abilityDescr->getName() );
00324          if ( CORBA::is_nil( abil ) || !checkAbilityObject( abil, abilityDescr ) )
00325             // call handler of derived object
00326                            abil = createAbilityObject( abilityDescr );
00327 
00328                         // check whether it exists and implements the specified connectors;
00329                         // if it does, proceed
00330                         if( !CORBA::is_nil(abil) && checkAbilityObject(abil,abilityDescr) ) {
00331                                 // ...and tell the service manager that we have a new
00332                                 // ability object
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             // add object to map
00339             addAbility( abilities[num_abil], abil );
00340                         }
00341                         // otherwise tell the user and the service manager
00342                         else {
00343                                 // delete the object from the map
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  * Parse all connectors of the given ability description. Test if the
00367  * given object implements the necessary interface using _is_a().
00368  *
00369  * @return <<true>> if the object matches all connectors, <<false>> otherwise
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                                 // check if the ability implements SvcProtPushSupplier
00381                                 if( !ability->_is_a("IDL:in.tum.de/DWARF/SvcProtPushSupplier:1.0") ) {
00382                                         // it doesn't, so the object cannot be registered
00383                                         validObject = false;
00384                                         break;
00385                                 }
00386                         }
00387                         else if(!strcmp(connProtocol, "Shmem")) {
00388                                 // check if the ability implements SvcProtShmem
00389                                 if( !ability->_is_a("IDL:in.tum.de/DWARF/SvcProtShmem:1.0") ) {
00390                                         // it doesn't, so the object cannot be registered
00391                                         validObject = false;
00392                                         break;
00393                                 }
00394                         }
00395                 }
00396                 // it may happen that someone implements the SvcSession
00397                 // interface and has separate objects for communication
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  *  Parse all Needs, for each found do
00415  *    -# Check for its type and connector protocol.
00416  *    -# Based on type, instantiate an object from a specific class
00417  *       (this is dependent on the actual service).
00418  *    -# Check whether this object can handle the specified protocol.
00419  *    -# Store the Need description in a private hashmap.
00420  *    .
00421  * @param serviceDesc The description of this service.
00422  */
00423 void TemplateService::parseNeeds(ActiveServiceDescription_ptr serviceDesc) {
00424         // get all needs' names
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         // now parse all needs one by one
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                         // get need, output its name and type
00442                         NeedDescription_ptr needDescr = serviceDesc->getNeed(needs[num_need]);
00443                         // if the need sis of type ContextSwitch, it gets handled later
00444                         if(!strcmp(needDescr->getType(), "ContextSwitch") ) continue;
00445 
00446          // check if we have an object in our map and it implements the specified connectors
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                         // check whether it implements the specified connectors
00452                         // if it does, proceed
00453                         if(  !CORBA::is_nil(need) && checkNeedObject(need,needDescr) ) {
00454                                 // ...and tell the service manager that we have a new
00455                                 // need object
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             // add object to map
00462             addNeed( needs[num_need], need );
00463                         }
00464                         // otherwise tell the user and the service manager
00465                         else {
00466                                 // delete the object from the map
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  * Parse all connectors of the given ability description. Test if the
00491  * given object implements the necessary interface using dynamic_cast.
00492  *
00493  * @return <<true>> if the object matches all connectors, <<false>> otherwise
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                                 // check if the ability implements SvcProtPushConsumer
00505                                 if( !need->_is_a("IDL:in.tum.de/DWARF/SvcProtPushConsumer:1.0") ) {
00506                                         // it doesn't, so the object cannot be registered
00507                                         validObject = false;
00508                                         break;
00509                                 }
00510                         }
00511                         else if(!strcmp(connProtocol, "PullConsumer")) {
00512                                 // check if the ability implements SvcProtPushConsumer
00513                                 if( !need->_is_a("IDL:in.tum.de/DWARF/SvcProtPullConsumer:1.0") ) {
00514                                         // it doesn't, so the object cannot be registered
00515                                         validObject = false;
00516                                         break;
00517                                 }
00518                         }
00519                         else if(!strcmp(connProtocol, "Shmem")) {
00520                                 // check if the ability implements SvcProtShmem
00521                                 if( !need->_is_a("IDL:in.tum.de/DWARF/SvcProtShmem:1.0") ) {
00522                                         // it doesn't, so the object cannot be registered
00523                                         validObject = false;
00524                                         break;
00525                                 }
00526                         }
00527                         else if(!strcmp(connProtocol, "ObjrefImporter")) {
00528                                 // check if the ability implements SvcProtObjRefImporter
00529                                 if( !need->_is_a("IDL:in.tum.de/DWARF/SvcProtObjrefImporter:1.0") ) {
00530                                         // it doesn't, so the object cannot be registered
00531                                         validObject = false;
00532                                         break;
00533                                 }
00534                         }
00535                 }
00536                 if( validObject==false ) {
00537                         // it may happen that someone implements the Session
00538                         // interface and has separate objects for communication
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         // get all needs' names
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         // now parse all needs one by one
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                         // get need, output its name and type
00572                         NeedDescription_ptr needDescr = serviceDesc->getNeed(needs[num_need]);
00573                         // if the need is _not_ of type ContextSwitch, it has been handled before
00574                         if(strcmp(needDescr->getType(), "ContextSwitch")) continue;
00575 
00576                         CORBA::Object_ptr contextSwitch = createContextSwitchObject(needDescr, serviceDesc);
00577 
00578                         // check whether it implements the specified connectors
00579                         // if it does, proceed
00580                         if(  !CORBA::is_nil(contextSwitch) && checkNeedObject(contextSwitch,needDescr) ) {
00581                                 // ...and tell the service manager that we have a new
00582                                 // need object
00583                                 DEBUGSTREAM(10, m_name << ": Registering ContextSwitch Need " <<
00584                                         needDescr->getName() << " at ServiceManager");
00585                                 serviceDesc->registerNeed( needDescr->getName(), contextSwitch );
00586                                 reg_need++;
00587                         }
00588                         // otherwise tell the user and the service manager
00589                         else {
00590                                 // delete the object from the map
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         // create an object of the default type ContextSwitch and return a _this CORBA pointer to it
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  * Does nothing except calling the run() method of the Service
00618  * object. Note that it is this object's responsibility to
00619  * terminate the thread by returning from the run() method
00620  *
00621  * @param data A pointer to a ServiceController object.
00622  */
00623 void* TemplateService::controlThreadStarter(void* data) {
00624   ((TemplateService*)data)->run();
00625   return 0;
00626 }
00627 
00628 /**
00629  * Returns immediately, thus stopping the just started new thread.
00630  * Implement your own behavior by subclassing.
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 }

TemplateService.cpp Source File | generated on Sun Apr 29 02:01:05 2007 by Doxygen 1.4.1 for DWARF