/home/fwph/code/wurde/rde/mcp/util.cpp

Go to the documentation of this file.
00001 #include <mcp.H>
00002 #include <WURDEConfiguration.H>
00003 
00004 using namespace WURDE;
00005 using namespace std;
00006 
00007 namespace MCP{
00008 
00009        
00010        Module::Module(string name):
00011               m_lastTimestamp()
00012        {
00013               m_moduleName=name;
00014               //set slow TTL until we've got some info
00015               m_TTL.tv_sec=1;
00016               m_TTL.tv_usec=0;
00017               g_logdebug << "new module with name " << name << endl;
00018               //indicate we don't know anything about it yet
00019               m_state=STATE_NULL;
00020               m_locale=LOCALE_NULL;
00021               m_managedType=PROC_NULL;
00022               m_attemptedStarts=0;
00023               m_maxAttempts=3;
00024        }
00025        
00026        Module::Module() {
00027               m_lastTimestamp.zero();
00028               m_moduleName="unknown";
00029               m_TTL.tv_sec=1;
00030               m_TTL.tv_usec=0;
00031               m_state=STATE_NULL;
00032               m_locale=LOCALE_NULL;
00033               m_managedType=PROC_NULL;
00034               m_attemptedStarts=0;
00035               m_maxAttempts=3;
00036        }
00037        
00038        Module::Module(HeartbeatInfoStruct &info){
00039               setModuleName(info.source);
00040               refresh(info);
00041               m_attemptedStarts=0;
00042               m_maxAttempts=3;
00043        }
00044        
00045        Module::Module(HeartbeatDataStruct &data){
00046               setModuleName(data.source);
00047               beat(data);
00048               m_attemptedStarts=0;
00049               m_maxAttempts=3;
00050        }
00051        
00052        bool Module::stale(){
00053               Time temp(m_TTL), current;
00054               current.now();
00055               temp=temp+temp+temp+m_lastTimestamp;
00056               
00057               if(current>=temp){
00058                      return true;
00059               }
00060               
00061               return false;
00062        }
00063        
00064        void Module::setTTL(double seconds){
00065               int count=0;
00066               while(seconds>0){
00067                      seconds--;
00068                      count++;
00069               }
00070               
00071               m_TTL.tv_sec=count;
00072               m_TTL.tv_usec=(unsigned long)(1000000.0*seconds);
00073        }
00074        
00075        bool Module::beat(HeartbeatDataStruct beat){
00076               string buffer="New beat for " + m_moduleName;
00077               if(beat.source!=m_moduleName){
00078                      g_error("Beat called with wrong module heartbeat");
00079                      return false;
00080               }
00081               
00082               m_lastTimestamp=beat.timestamp;
00083               setTTL(beat.TTL);
00084               
00085               //              g_debug(buffer);
00086               
00087               return true;
00088        }
00089        
00090        bool Module::refresh(HeartbeatInfoStruct info){
00091               if(info.source!=m_moduleName){
00092                      g_error("Refresh called with wrong module info");
00093                      return false;
00094               }
00095               
00096               //the interface array currently only contains useful information
00097               //in the STATE_INFO state.
00098               if(info.state.getValue()==STATE_INFO){
00099                      //clear the interface list
00100                      m_interfaces.clear();
00101                      //set all the available interfaces
00102                      m_interfaces=info.interfaces.getValue();
00103                      vector<InterfaceStream>::iterator m_iter;
00104 #ifdef FULL_DEBUG
00105                      /*              for(m_iter=m_interfaces.begin();m_iter!=m_interfaces.end();m_iter++){
00106                             cout << "some stream: " << m_iter->type << " ::  " << m_iter->streamname << endl;
00107                             }*/
00108 #endif
00109                      setState(STATE_INACTIVE);
00110                      g_logdebug << "Got stream information from " << m_moduleName << endl;
00111               }else if(info.state.getValue()==STATE_QUIT){
00112                      setState(STATE_INACTIVE);
00113                      g_debug("Got a quit");
00114               }else{
00115                      g_debug("Some other info");
00116                      setState(info.state.getValue());
00117                      setType(info.managedType.getValue());
00118                      setLocale(info.locale.getValue());
00119               }
00120               return true;
00121        }
00122        
00126        string Module::findObjectMapping(string object, string interface, ConnectionStrategy strat){
00127               vector<Mapping>::iterator iter;
00128               string retval;
00129               bool found=false;
00130               char logbuf[1024];
00131               
00132               sprintf(logbuf, "Looking for a module that can fulfill %s for %s",interface.c_str(),object.c_str());
00133               g_debug(logbuf);
00134 
00135               if(strat==STRAT_ASSIGNED){
00136                      g_debug("looking for assigned...");
00137                      /* if we're looking for a specific mapping */
00138                      for(iter=m_mappings.begin();iter!=m_mappings.end();iter++){
00139                             if(iter->object==object&&iter->interface==interface){
00140                                    
00141                                    //the following is a relic of stupidity, and will be removed as sure as I'm certain
00142                                    //of that fact
00143                                //&&
00144                                //    !(m_state==STATE_FAIL||m_state==STATE_NULL)){
00145                                    /*                              if(start&&!(m_state==STATE_RUN||m_state==STATE_IDLE||
00146                                                m_state==STATE_RESET||m_state==STATE_RESTART)){
00147                                           m_state=STATE_REQUEST;
00148                                           }*/
00149                                    retval=iter->source;
00150                                    found=true;
00151                                    break;
00152                             }else{
00153                                    g_logdebug << "Found " << iter->object << " for " << iter->interface << " , but it's not what we want. " << endl;
00154                             }
00155                      }
00156                      if(found){
00157                             sprintf(logbuf, "Found %s", retval.c_str());
00158                             g_debug(logbuf);
00159                             return retval;
00160                      }else{
00161                             g_debug("Found nothing");
00162                             return "";
00163                      }
00164               }else if(strat==STRAT_NORMAL){
00165                      /* if we are just looking for an interface mapping */
00166                      for(iter=m_mappings.begin();iter!=m_mappings.end();iter++){
00167 
00168                             if(iter->interface==interface){
00169                                    //&&
00170                                    // !(m_state==STATE_FAIL||m_state==STATE_NULL)){
00171                                    //if(start&&!(m_state==STATE_RUN||m_state==STATE_IDLE||
00172                                    //          m_state==STATE_RESET||m_state==STATE_RESTART)){
00173                                    //     m_state=STATE_REQUEST;
00174                                    //}
00175                                    retval=iter->source;
00176                                    //cout << iter->source << endl;
00177                                    found=true;
00178                                    //cout << "!!! target: "<< interface << " found: " << iter->interface << endl;
00179                                    break;
00180                             }else{
00181                                    // cout << "target: "<< interface << " found: " << iter->interface << endl;
00182                             }
00183                      }
00184                      
00185                      if(found){
00186                             sprintf(logbuf,"Found %s",retval.c_str());
00187                             g_debug(logbuf);
00188                             return retval;
00189                      }else{
00190                             g_debug("Found nothing");
00191                             return "";
00192                      }
00193               }else{
00194                      /* then we're looking for the module which uses this stream name, and not using mappings at all */
00195                      /* actually, then we shouldn't be here */
00196 
00197               }
00198               return "";
00199        }
00200 
00201 
00202        void Module::addInterface(string interface, string name){
00203               InterfaceStream someinterface;
00204               
00205               someinterface.type=interface;
00206               someinterface.streamname=name;
00207               m_interfaces.push_back(someinterface);
00208        }
00209 
00210        bool Module::hasSupplier(string streamname,string type){
00211               vector<InterfaceStream>::iterator iter;
00212               char logbuf[1024];
00213               sprintf(logbuf,"Looking for %s of type %s in module %s",streamname.c_str(),type.c_str(),m_moduleName.c_str());
00214               g_debug(logbuf);
00215               for(iter=m_interfaces.begin();iter!=m_interfaces.end();iter++){
00216                      if((iter->type==type)&&(iter->streamname==streamname)){
00217                             return true;
00218                      }else{
00219                             // cout << iter->streamname << " " << iter->type << endl;
00220                      }
00221               }
00222               g_debug("Didn't find the supplier we were looking for");
00223               return false;
00224        }
00225  
00226        bool Module::startUp(CommsManager &myManager, string someArgs){
00227               FILE *testhandle=NULL;
00228               string fullbinary;
00229               if(m_binary=="empty"){
00230                       g_logdebug << "No binary for module " << m_moduleName << ". Continuing on." << endl;
00231                       return true;
00232               }
00233               if(m_binary[0]!='/'){
00234                      fullbinary=g_globalConfiguration.getBinDirectory()+"/"+m_binary;
00235               }else{
00236                      fullbinary=m_binary;
00237               }
00238               //              char buffer[512],temp[m_options.length()+1],temp2[someArgs.length()+1],nametmp[fullbinary.length()+1];
00239               char buffer[512];
00240                      //,nametmp[fullbinary.length()+1];
00241               
00242               /*              strncpy(temp,m_options.c_str(),m_options.length());
00243               strncpy(temp2,someArgs.c_str(),someArgs.length());
00244               strncpy(nametmp,fullbinary.c_str(),fullbinary.length());
00245               temp[m_options.length()]='\0';
00246               temp2[someArgs.length()]='\0';
00247               nametmp[fullbinary.length()]='\0';
00248               */
00249 
00250               g_logdebug << "Using binary " << fullbinary << endl;
00251 
00252               //              char * const options[4]={nametmp,temp,temp2,NULL};
00253               const char *options[m_options.size()+3];
00254               options[0]=fullbinary.c_str();
00255               for(unsigned int i=0;i<m_options.size();i++){
00256                      options[i+1]=m_options[i].c_str();
00257               }
00258               options[m_options.size()+1]=someArgs.c_str();
00259               options[m_options.size()+2]=NULL;
00260 
00261               std::string logdir=g_globalConfiguration.getLogDirectory();
00262               /* if it's already running, we're fine, but if it's marked
00263                  as failed, we can't do anything. */
00264               switch(m_state){
00265               case STATE_RUN:
00266               case STATE_RESTART:
00267               case STATE_RESET:
00268               case STATE_STARTUP:
00269                      return true;
00270               case STATE_FAIL:
00271                      return false;
00272               default:
00273                      break;
00274               }
00275 
00276               testhandle=fopen(fullbinary.c_str(),"r");
00277               
00278               if(testhandle){
00279                      fclose(testhandle);
00280                      m_lastTimestamp.now();
00281                      m_state=STATE_STARTUP;
00282                      
00283                      m_process=fork();
00284                      if(m_process==0){
00285                              myManager.closeConnections();
00286                              
00287                              setsid();
00288                              sprintf(buffer,"%s/%s-stdout",logdir.c_str(),m_moduleName.c_str());
00289                              freopen(buffer,"w",stdout);
00290                              sprintf(buffer,"%s/%s-stderr",logdir.c_str(),m_moduleName.c_str());
00291                              freopen(buffer,"w",stderr);
00292                              cout << "Invoking #" << fullbinary << "# with options:";
00293                              for(int i=0;i<m_options.size();i++){
00294                                     cout << " " << m_options[i];
00295                              }
00296                              cout << endl;
00297                              
00298                              //if(execlp(fullbinary.c_str(),nametmp,temp,temp2,(char *) NULL)){
00299                              //if this ever returns, something went wrong
00300                              execvp(fullbinary.c_str(),(char * const *)options);
00301                              cout << "Something went wrong starting up the binary: " << fullbinary << ". it was : " << strerror(errno) << endl;                         
00302                              exit(-1);
00303 
00304                      }
00305                      return true;
00306               }else{
00307                       //binary path is incorrect
00308                       g_logerror << "Binary location for module " << m_moduleName << " is incorrect: " << fullbinary << " shortname: " << m_binary << endl;
00309                       return false;
00310               }
00311               return false;
00312        }
00313         
00314 }

Generated on Thu Feb 1 15:31:54 2007 for WURDE by  doxygen 1.5.1