Logo Search packages:      
Sourcecode: tango version File versions  Download package

Starter.cpp

/*----- PROTECTED REGION ID(Starter.cpp) ENABLED START -----*/
static const char *RcsId = "$Id: Starter.cpp 16099 2011-03-17 12:46:03Z pascal_verdier $";
//=============================================================================
//
// file :        Starter.cpp
//
// description : C++ source for the Starter and its commands.
//               The class is derived from Device. It represents the
//               CORBA servant object which will be accessed from the
//               network. All commands which can be executed on the
//               Starter are implemented in this file.
//
// project :     Starter for Tango Administration.
//
// $Author: pascal_verdier $
//
// Copyright (C) :      2004,2005,2006,2007,2008,2009,2010
//                                  European Synchrotron Radiation Facility
//                      BP 220, Grenoble 38043
//                      FRANCE
//
// This file is part of Tango.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with Tango.  If not, see <http://www.gnu.org/licenses/>.
//
// $Revision: 16099 $
// $Date: 2011-03-17 13:46:03 +0100 (Thu, 17 Mar 2011) $
//
// SVN only:
// $HeadURL:  $
//
// CVS only:
// $Source$
// $Log$
// Revision 3.48  2011/01/10 13:02:57  pascal_verdier
// StartServersAtStartup  class property added.
// TAC is not managed any more.
//
// Revision 3.47  2010/10/18 12:58:52  pascal_verdier
// Pogo-7 compatibility
//
//
//=============================================================================
//                This file is generated by POGO
//        (Program Obviously used to Generate tango Object)
//=============================================================================


#include <tango.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <StarterUtil.h>
#include <Starter.h>
#include <StarterClass.h>

/*----- PROTECTED REGION END -----*/


/**
 *    Starter class description:
 *    This device server is able to control <b>Tango</b> components (database, device servers, clients...).
 *    It is able to start or stop and to report the status of these components.
 */

//================================================================
//
//  The following table gives the correspondence
//  between command and method names.
//
//  Command name          |  Method name
//----------------------------------------------------------------
//  State                 |  dev_state
//  Status                |  Inherited (no method)
//  DevStart              |  dev_start
//  DevStop               |  dev_stop
//  DevStartAll           |  dev_start_all
//  DevStopAll            |  dev_stop_all
//  DevGetRunningServers  |  dev_get_running_servers
//  DevGetStopServers     |  dev_get_stop_servers
//  DevReadLog            |  dev_read_log
//  HardKillServer        |  hard_kill_server
//  NotifyDaemonState     |  notify_daemon_state
//  UpdateServersInfo     |  update_servers_info
//================================================================

namespace Starter_ns
{
      /*----- PROTECTED REGION ID(Starter::namespace_starting) ENABLED START -----*/

      //    static initializations

      /*----- PROTECTED REGION END -----*/      //    Starter::namespace_starting



//--------------------------------------------------------
/**
 *    Method      : Starter::Starter()
 *    Description : Constructors for a Tango device
 *                  implementing the class Starter
 */
//--------------------------------------------------------
00118 Starter::Starter(Tango::DeviceClass *cl, string &s)
      : Tango::Device_4Impl(cl, s.c_str())
{
      /*----- PROTECTED REGION ID(Starter::constructor_1) ENABLED START -----*/

      starting = true;
      init_device();

      /*----- PROTECTED REGION END -----*/      //    Starter::constructor_1
}
//--------------------------------------------------------
00129 Starter::Starter(Tango::DeviceClass *cl, const char *s)
      : Tango::Device_4Impl(cl, s)
{
      /*----- PROTECTED REGION ID(Starter::constructor_2) ENABLED START -----*/

      starting = true;
      init_device();

      /*----- PROTECTED REGION END -----*/      //    Starter::constructor_2
}
//--------------------------------------------------------
00140 Starter::Starter(Tango::DeviceClass *cl, const char *s, const char *d)
      : Tango::Device_4Impl(cl, s, d)
{
      /*----- PROTECTED REGION ID(Starter::constructor_3) ENABLED START -----*/

      starting = true;
      init_device();

      /*----- PROTECTED REGION END -----*/      //    Starter::constructor_3
}


//--------------------------------------------------------
/**
 *    Method      : Starter::delete_device()()
 *    Description : will be called at device destruction or at init command
 */
//--------------------------------------------------------
00158 void Starter::delete_device()
{
      /*----- PROTECTED REGION ID(Starter::delete_device) ENABLED START -----*/

      util->log_starter_info("Starter shutdown");

      /* Do not not stop threads and free objects 

      //    Stop ping threads
      vector<ControledServer>::iterator it;
      for (it=servers.begin() ; it<servers.end() ; it++)
      {
            it->thread_data->set_stop_thread();
      }
      util->proc_util->stop_it();
      ms_sleep(1000);
      //    Delete device allocated objects
      delete dbase;
      delete util;
      delete attr_HostState_read;
      delete attr_NotifdState_read;
      delete start_proc_data;

      */
      
      //    But do not recreate at init
      starting = false;
      /*----- PROTECTED REGION END -----*/      //    Starter::delete_device
      
}


//--------------------------------------------------------
/**
 *    Method      : Starter::init_device()
 *    Description : //  will be called at device initialization.
 */
//--------------------------------------------------------
00196 void Starter::init_device()
{
      DEBUG_STREAM << "Starter::init_device() create device " << device_name << endl;

      /*----- PROTECTED REGION ID(Starter::init_device_before) ENABLED START -----*/

      //    Initialization before get_device_property() call
      cout << "Starter::Starter() init device " << device_name << endl;

      /*----- PROTECTED REGION END -----*/      //    Starter::init_device_before
      
      //    Get the device properties (if any) from database
      get_device_property();
      
      
      /*----- PROTECTED REGION ID(Starter::init_device) ENABLED START -----*/
      
      debug = false;
      char  *dbg = (char *)getenv("DEBUG");
      if (dbg!=NULL)
            if (strcmp(dbg, "true")==0)
            {
                  debug = true;
                  cout << "!!! Debug mode is set !!!" << endl;
            }
      if (serverStartupTimeout<SERVER_TIMEOUT)
            serverStartupTimeout = SERVER_TIMEOUT;

      //    First time, check if instance and host name are coherent
      if (!debug)
            check_host();

      //    Do it only at startup and not at Init command
      //----------------------------------------------------
      if (starting==true)
      {
            //    Get database server name
            //--------------------------------------
            Tango::Util *tg = Tango::Util::instance();
            string      dbname = tg->get_database()->get_dbase()->name();
            //    And connect database as DeviceProxy
            //--------------------------------------
            dbase = new Tango::DeviceProxy(dbname);
//          dbase->set_timeout_millis(500);

            //    Build a shared data for StartProcessShared
            start_proc_data = new StartProcessShared();

            //    Get hostname (In case of cluster host could be multiple)
            //-------------------------------------------------------------
            vector<string>    hosts_list;
            char  *env = (char *)getenv("TANGO_CLUSTER");
            if (env==NULL)
                  hosts_list.push_back(tg->get_host_name());
            else
            if (strlen(env)==0)
                  hosts_list.push_back(tg->get_host_name());
            else
            {
                  //    If MULTI_HOST is defined, parse host names
                  //--------------------------------------------------
                  string      str_list(env);
                  cout << "hosts_list = " << str_list << endl;
                  int   start = 0;
                  int   end = 0;
                  while ((end=str_list.find_first_of(":", start))>0)
                  {
                        string      s = str_list.substr(start, end-start);
                        hosts_list.push_back(s);
                        start = end+1;
                  }
                  string      s = str_list.substr(start, str_list.length()-start);
                  hosts_list.push_back(s);
                  for (unsigned int i=0 ; i<hosts_list.size() ; i++)
                        cout << hosts_list[i] << endl;
            }
            //    Create a StarterUtil instance
            //--------------------------------------
            util = new StarterUtil(dbase, hosts_list, logFileHome);
            util->log_starter_info("Starter startup");

            //    Initialize Attribute data member
            attr_HostState_read   = new Tango::DevShort[1];
            attr_NotifdState_read = new Tango::DevState[1];
            attr_NotifdState_read[0] = notifyd_state = Tango::UNKNOWN;

            //    Do not want exception during startup
            throwable = false;

            //    Wait a bit if necessary
            if (waitForDriverStartup>0)
            {
                  cout << "Waiting " << waitForDriverStartup <<
                              " seconds before starting (wait for drivers)." << endl;
                  ms_sleep(1000*waitForDriverStartup);
            }

            //    Start notify daemon if not desabled and not already running
            if (useEvents)
            {
                  try
                  {
                        cout << "Checking " << util->notifyd_name << endl;
                        if (util->is_notifyd_alive()!=Tango::ON)
                        {
                              string      name(NOTIFY_DAEMON_SCRIPT);
                              name += "/";
                              name += tg->get_host_name();
                              cout << "Starting " << name << endl;
                              dev_start((char*)name.c_str());
                        }
                  }
                  catch (...) {}
            }

            //    query database for controled objects
            //    Wait for Database device is  OK
            bool  done = false;
            while (!done)
            {
                  try {
                        util->build_server_ctrl_object(&servers);
                        do_update_from_db = false;
                        done = true;
                  }
                  catch(Tango::DevFailed &e) {
                        Tango::Except::print_exception(e);
                  }
#                 ifdef _TG_WINDOWS_
                        _sleep(1000);
#                 else
                        sleep(1);
#                 endif
            }
            
//    A a wait for first ping timeout !!!!
#     ifdef _TG_WINDOWS_
            _sleep(3000);
#     else
            sleep(3);
#     endif

            //    And Start servers for all startup levels.
            //    The interStartupLevelWait value will be managed
            //          by the start process thread.
            //---------------------------------------------------
            int nb_levels =
                  ((static_cast<StarterClass *>(get_device_class()))->nbStartupLevels);

            if (startServersAtStartup==true)
            {
                  //    Update state before
                  for (unsigned int i=0 ; i<servers.size() ; i++)
                  {
                        ControledServer   *server = &servers[i];
                        server->state = server->thread_data->get_state();
                  }
                  //    And then start levels
                  for (int level=1 ; level<=nb_levels ; level++)
                  {
                        dev_start_all(level);
                        ms_sleep(50);
                  }
            }

            //    Want exception during normal run
            throwable = true;

            //    Set the default state
            //-------------------------------
            set_state(Tango::MOVING);
            //set_status("Tango::MOVING");
            *attr_HostState_read = get_state();

            //    Update Loggs
            WARN_STREAM << "Starter Server Started !" << endl;
            cout << "Starter Server Started !" << endl;

            //    Start a thread to start polling
            PollingState      *poller = new PollingState(get_name());
            poller->start();
      }

      /*----- PROTECTED REGION END -----*/      //    Starter::init_device
}



//--------------------------------------------------------
/**
 *    Method      : Starter::get_device_property()
 *    Description : //  Add your own code to initialize
 */
//--------------------------------------------------------
00390 void Starter::get_device_property()
{
      /*----- PROTECTED REGION ID(Starter::get_device_property_before) ENABLED START -----*/

      //    Initialize property data members
      fireFromDbase = true;

      /*----- PROTECTED REGION END -----*/      //    Starter::get_device_property_before


      //    Read device properties from database.
      Tango::DbData     dev_prop;
      dev_prop.push_back(Tango::DbDatum("InterStartupLevelWait"));
      dev_prop.push_back(Tango::DbDatum("KeepLogFiles"));
      dev_prop.push_back(Tango::DbDatum("LogFileHome"));
      dev_prop.push_back(Tango::DbDatum("ServerStartupTimeout"));
      dev_prop.push_back(Tango::DbDatum("StartDsPath"));
      dev_prop.push_back(Tango::DbDatum("StartServersAtStartup"));
      dev_prop.push_back(Tango::DbDatum("UseEvents"));
      dev_prop.push_back(Tango::DbDatum("WaitForDriverStartup"));

      //    is there at least one property to be read ?
      if (dev_prop.size()>0)
      {
            //    Call database and extract values
            if (Tango::Util::instance()->_UseDb==true)
                  get_db_device()->get_property(dev_prop);
      
            //    get instance on StarterClass to get class property
            Tango::DbDatum    def_prop, cl_prop;
            StarterClass      *ds_class =
                  (static_cast<StarterClass *>(get_device_class()));
            int   i = -1;

            //    Try to initialize InterStartupLevelWait from class property
            cl_prop = ds_class->get_class_property(dev_prop[++i].name);
            if (cl_prop.is_empty()==false)      cl_prop  >>  interStartupLevelWait;
            else {
                  //    Try to initialize InterStartupLevelWait from default device value
                  def_prop = ds_class->get_default_device_property(dev_prop[i].name);
                  if (def_prop.is_empty()==false)     def_prop  >>  interStartupLevelWait;
            }
            //    And try to extract InterStartupLevelWait value from database
            if (dev_prop[i].is_empty()==false)  dev_prop[i]  >>  interStartupLevelWait;

            //    Try to initialize KeepLogFiles from class property
            cl_prop = ds_class->get_class_property(dev_prop[++i].name);
            if (cl_prop.is_empty()==false)      cl_prop  >>  keepLogFiles;
            else {
                  //    Try to initialize KeepLogFiles from default device value
                  def_prop = ds_class->get_default_device_property(dev_prop[i].name);
                  if (def_prop.is_empty()==false)     def_prop  >>  keepLogFiles;
            }
            //    And try to extract KeepLogFiles value from database
            if (dev_prop[i].is_empty()==false)  dev_prop[i]  >>  keepLogFiles;

            //    Try to initialize LogFileHome from class property
            cl_prop = ds_class->get_class_property(dev_prop[++i].name);
            if (cl_prop.is_empty()==false)      cl_prop  >>  logFileHome;
            else {
                  //    Try to initialize LogFileHome from default device value
                  def_prop = ds_class->get_default_device_property(dev_prop[i].name);
                  if (def_prop.is_empty()==false)     def_prop  >>  logFileHome;
            }
            //    And try to extract LogFileHome value from database
            if (dev_prop[i].is_empty()==false)  dev_prop[i]  >>  logFileHome;

            //    Try to initialize ServerStartupTimeout from class property
            cl_prop = ds_class->get_class_property(dev_prop[++i].name);
            if (cl_prop.is_empty()==false)      cl_prop  >>  serverStartupTimeout;
            else {
                  //    Try to initialize ServerStartupTimeout from default device value
                  def_prop = ds_class->get_default_device_property(dev_prop[i].name);
                  if (def_prop.is_empty()==false)     def_prop  >>  serverStartupTimeout;
            }
            //    And try to extract ServerStartupTimeout value from database
            if (dev_prop[i].is_empty()==false)  dev_prop[i]  >>  serverStartupTimeout;

            //    Try to initialize StartDsPath from class property
            cl_prop = ds_class->get_class_property(dev_prop[++i].name);
            if (cl_prop.is_empty()==false)      cl_prop  >>  startDsPath;
            else {
                  //    Try to initialize StartDsPath from default device value
                  def_prop = ds_class->get_default_device_property(dev_prop[i].name);
                  if (def_prop.is_empty()==false)     def_prop  >>  startDsPath;
            }
            //    And try to extract StartDsPath value from database
            if (dev_prop[i].is_empty()==false)  dev_prop[i]  >>  startDsPath;

            //    Try to initialize StartServersAtStartup from class property
            cl_prop = ds_class->get_class_property(dev_prop[++i].name);
            if (cl_prop.is_empty()==false)      cl_prop  >>  startServersAtStartup;
            else {
                  //    Try to initialize StartServersAtStartup from default device value
                  def_prop = ds_class->get_default_device_property(dev_prop[i].name);
                  if (def_prop.is_empty()==false)     def_prop  >>  startServersAtStartup;
            }
            //    And try to extract StartServersAtStartup value from database
            if (dev_prop[i].is_empty()==false)  dev_prop[i]  >>  startServersAtStartup;

            //    Try to initialize UseEvents from class property
            cl_prop = ds_class->get_class_property(dev_prop[++i].name);
            if (cl_prop.is_empty()==false)      cl_prop  >>  useEvents;
            else {
                  //    Try to initialize UseEvents from default device value
                  def_prop = ds_class->get_default_device_property(dev_prop[i].name);
                  if (def_prop.is_empty()==false)     def_prop  >>  useEvents;
            }
            //    And try to extract UseEvents value from database
            if (dev_prop[i].is_empty()==false)  dev_prop[i]  >>  useEvents;

            //    Try to initialize WaitForDriverStartup from class property
            cl_prop = ds_class->get_class_property(dev_prop[++i].name);
            if (cl_prop.is_empty()==false)      cl_prop  >>  waitForDriverStartup;
            else {
                  //    Try to initialize WaitForDriverStartup from default device value
                  def_prop = ds_class->get_default_device_property(dev_prop[i].name);
                  if (def_prop.is_empty()==false)     def_prop  >>  waitForDriverStartup;
            }
            //    And try to extract WaitForDriverStartup value from database
            if (dev_prop[i].is_empty()==false)  dev_prop[i]  >>  waitForDriverStartup;


      }
      /*----- PROTECTED REGION ID(Starter::get_device_property_after) ENABLED START -----*/

      //    Check device property data members init
      if (dev_prop[0].is_empty())
            cout << "WARNING : startDsPath NOT defined !!!!" << endl;
      if (startDsPath.size()==0)
            startDsPath.push_back(".");
      else
      for (unsigned int i=0 ; i<startDsPath.size() ; i++)
            INFO_STREAM << "startDsPath[" << i << "] = " << startDsPath[i] << endl;
      INFO_STREAM << "WaitForDriverStartup = " << waitForDriverStartup << " seconds" << endl;
      cout << "UseEvents  = " << ((useEvents==false)? "False": "True") << endl;
      cout << "interStartupLevelWait  = " << interStartupLevelWait << endl;
      cout << "serverStartupTimeout   = " << serverStartupTimeout << endl;



      //    Get the fireFromDbase value from Default object
      Tango::DbData     data;
      data.push_back(Tango::DbDatum("FireToStarter"));
      Tango::Util *tg = Tango::Util::instance();
      tg->get_database()->get_property("Default", data);
      string      tmp;
      if (data[0].is_empty()==false)
            data[0]  >>  tmp;
      transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
      if (tmp=="false")
            fireFromDbase = false;
      cout << "fireFromDbase  = " << fireFromDbase << endl;
      cout << "logFileHome    = " << logFileHome   << endl;
      cout << "StartServersAtStartup = " << startServersAtStartup  << endl;

      /*----- PROTECTED REGION END -----*/      //    Starter::get_device_property_after

}

//--------------------------------------------------------
/**
 *    Method      : Starter::always_executed_hook()
 *    Description : method always executed before any command is executed
 */
//--------------------------------------------------------
00556 void Starter::always_executed_hook()
{
      INFO_STREAM << "Starter::always_executed_hook()  " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::always_executed_hook) ENABLED START -----*/

      //    code always executed before all requests
      

      /*----- PROTECTED REGION END -----*/      //    Starter::always_executed_hook
}



//--------------------------------------------------------
/**
 *    Method      : Starter::read_attr_hardware()
 *    Description : Hardware acquisition for attributes.
 */
//--------------------------------------------------------
00575 void Starter::read_attr_hardware(vector<long> &attr_list)
{
      DEBUG_STREAM << "Starter::read_attr_hardware(vector<long> &attr_list) entering... " << endl;
      /*----- PROTECTED REGION ID(Starter::read_attr_hardware) ENABLED START -----*/

      //    Add your own code
      //    Update servers state
      for (unsigned int i=0 ; i < attr_list.size() ; i++)
      {
            Tango::WAttribute &att = dev_attr->get_w_attr_by_ind(attr_list[i]);
            string attr_name = att.get_name();
            if (attr_name == "Servers")
                  for (unsigned int j=0 ; j<servers.size() ; j++)
                  {
                        servers[j].state = servers[j].thread_data->get_state();
                        //if (servers[j].name=="")
                        //    cout << "read_attr_hardware:[" << servers[j].name << "]     " <<
                        //                      Tango::DevStateName[servers[j].state]  << endl;
                  }
      }

      /*----- PROTECTED REGION END -----*/      //    Starter::read_attr_hardware

}


//--------------------------------------------------------
/**
 *    Read NotifdState attribute
 *    Description: return ON or FAULT if notify daemon is running or not.
 *
 *    Data type:  Tango::DevState
 *    Attr type:  Scalar 
 */
//--------------------------------------------------------
00610 void Starter::read_NotifdState(Tango::Attribute &attr)
{
      DEBUG_STREAM << "Starter::read_NotifdState(Tango::Attribute &attr) entering... " << endl;
      /*----- PROTECTED REGION ID(Starter::read_NotifdState) ENABLED START -----*/

      //    Set the attribute value
      attr_NotifdState_read[0] = notifyd_state;
      attr.set_value(attr_NotifdState_read);

      /*----- PROTECTED REGION END -----*/      //    Starter::read_NotifdState
}
//--------------------------------------------------------
/**
 *    Read HostState attribute
 *    Description: 
 *
 *    Data type:  Tango::DevShort
 *    Attr type:  Scalar 
 */
//--------------------------------------------------------
00630 void Starter::read_HostState(Tango::Attribute &attr)
{
      DEBUG_STREAM << "Starter::read_HostState(Tango::Attribute &attr) entering... " << endl;
      /*----- PROTECTED REGION ID(Starter::read_HostState) ENABLED START -----*/

      //    Set the attribute value
      *attr_HostState_read = (short) get_state();
      DEBUG_STREAM << "HostState = " << attr_HostState_read[0] << endl;
      attr.set_value(attr_HostState_read);

      /*----- PROTECTED REGION END -----*/      //    Starter::read_HostState
}
//--------------------------------------------------------
/**
 *    Read RunningServers attribute
 *    Description: 
 *
 *    Data type:  Tango::DevString
 *    Attr type:  Spectrum  max = 200
 */
//--------------------------------------------------------
00651 void Starter::read_RunningServers(Tango::Attribute &attr)
{
      DEBUG_STREAM << "Starter::read_RunningServers(Tango::Attribute &attr) entering... " << endl;
      /*----- PROTECTED REGION ID(Starter::read_RunningServers) ENABLED START -----*/

      //    Check running ones
      vector<string>    runnings;
      for (unsigned int i=0 ; i<servers.size() ; i++)
            if (servers[i].state==Tango::ON)
                  runnings.push_back(servers[i].name);
      //    And fill attribute
      stringArrayRunning << runnings;     
      attr.set_value(stringArrayRunning.get_buffer(), stringArrayRunning.length());

      /*----- PROTECTED REGION END -----*/      //    Starter::read_RunningServers
}
//--------------------------------------------------------
/**
 *    Read StoppedServers attribute
 *    Description: Return all the Stopped servers.\n
 *
 *    Data type:  Tango::DevString
 *    Attr type:  Spectrum  max = 200
 */
//--------------------------------------------------------
00676 void Starter::read_StoppedServers(Tango::Attribute &attr)
{
      DEBUG_STREAM << "Starter::read_StoppedServers(Tango::Attribute &attr) entering... " << endl;
      /*----- PROTECTED REGION ID(Starter::read_StoppedServers) ENABLED START -----*/

      //    Check stopped ones
      vector<string>    stopped;
      for (unsigned int i=0 ; i<servers.size() ; i++)
            if (servers[i].state!=Tango::ON)
                  stopped.push_back(servers[i].name);
      //    And fill attribute
      stringArrayStopped << stopped;      
      attr.set_value(stringArrayStopped.get_buffer(), stringArrayStopped.length());

      /*----- PROTECTED REGION END -----*/      //    Starter::read_StoppedServers
}
//--------------------------------------------------------
/**
 *    Read Servers attribute
 *    Description: Return all registred servers for this host.\nServer names are followed by their states and controls
 *
 *    Data type:  Tango::DevString
 *    Attr type:  Spectrum  max = 1024
 */
//--------------------------------------------------------
00701 void Starter::read_Servers(Tango::Attribute &attr)
{
      DEBUG_STREAM << "Starter::read_Servers(Tango::Attribute &attr) entering... " << endl;
      /*----- PROTECTED REGION ID(Starter::read_Servers) ENABLED START -----*/

      //    Check starting ones
      vector<string>    vs;
      for (unsigned int i=0 ; i<servers.size() ; i++)
      {
            TangoSys_OMemStream tms;
            tms << servers[i].name << "\t" << 
                              Tango::DevStateName[servers[i].state] << "\t" <<
                              servers[i].controled  << "\t" << servers[i].startup_level;
            string      s = tms.str();
            vs.push_back(s);
            
      }
      //    And fill attribute
      stringArrayServers << vs;     
      attr.set_value(stringArrayServers.get_buffer(), stringArrayServers.length());

      /*----- PROTECTED REGION END -----*/      //    Starter::read_Servers
}

//--------------------------------------------------------
/**
 *    Method      : Starter::StarterClass::add_dynamic_attributes()
 *    Description : Create the dynamic attributes if any
 *                  for specified device.
 */
//--------------------------------------------------------
00732 void Starter::add_dynamic_attributes()
{
      /*----- PROTECTED REGION ID(Starter::Class::add_dynamic_attributes) ENABLED START -----*/

      //    Add your own code to create and add dynamic attributes if any

      /*----- PROTECTED REGION END -----*/      //    Starter::Class::add_dynamic_attributes

}



//========================================================
//    Command execution methods
//========================================================

//--------------------------------------------------------
/**
 *    Execute the State command:
 *    Description: This command gets the device state (stored in its <i>device_state</i> data member) and returns it to the caller.
 *
 *    @param argin none.
 *    @returns State Code
 */
//--------------------------------------------------------
00757 Tango::DevState Starter::dev_state()
{
      DEBUG_STREAM << "Starter::State()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::dev_state) ENABLED START -----*/

      Tango::DevState   argout = DeviceImpl::dev_state();
            //    Add your own state management
      //    Check if last command is more than readInfoDbPeriod class property
      int   period =
            ((static_cast<StarterClass *>(get_device_class()))->readInfoDbPeriod);

      //    If not fired -> do it myself by polling
      //---------------------------------------------
      if (fireFromDbase==false)
      {
            static time_t     t0 = 0;
               time_t   t1 = time(NULL);        
            //    If less -> no update
            if (t1-t0 >= period)
            {
                  t0 = t1;

                  //    Update control obj from database (could have been modified)
                  INFO_STREAM << "Updating from data base" << endl;
                  util->build_server_ctrl_object(&servers);
            }
      }
      else
      if (do_update_from_db)
      {
            //    Has been fired from Dbase
            util->build_server_ctrl_object(&servers);
            do_update_from_db = false;
      }
      //    Check for notify daemon state if requested
      //---------------------------------------------
      if (useEvents)
            notifyd_state = util->is_notifyd_alive();
      else
            notifyd_state = Tango::ON;

      //    Check if servers object initilized
      //---------------------------------------
      if (servers.size()==0)
      {
            INFO_STREAM << "Exiting dev_state() with servers.size() null" << endl;
            if (notifyd_state==Tango::ON)
                  set_state(Tango::ON);
            else
                  set_state(Tango::ALARM);
            return DeviceImpl::dev_state();
      }

      //    Check hown many servers are running
      //-----------------------------------------------------------
      ControledServer         *p_serv;
      int         nb_running   = 0;
      int         nb_controled = 0;
      int         nb_starting  = 0;
      for (unsigned int i=0 ; i<servers.size() ; i++)
      {
            p_serv = &servers[i];
            //    Count how many are controlled
            if (p_serv->controled)
            {
                  nb_controled++;

                  //    Fixe witch one is running and count how many controlled are running
                  if ((p_serv->state==Tango::ON))
                        nb_running ++;
                  else
                  if (p_serv->state==Tango::MOVING)
                        nb_starting ++;
            }
      }

      //    compare nb running with nb_controlled controled to set state
      if (nb_starting>0 || start_proc_data->get_starting_processes()>0)
            set_state(Tango::MOVING);
      else
      if (nb_running==nb_controled && notifyd_state==Tango::ON)
            set_state(Tango::ON);
      else
            set_state(Tango::ALARM);

      //cout << DeviceImpl::dev_state() << endl;
//time_t    t2 = time(NULL);
//cout << "------------------------------------> " << (t2-t1) << " seconds" << endl;

      return DeviceImpl::dev_state();

      /*----- PROTECTED REGION END -----*/      //    Starter::dev_state

      set_state(argout);               // Give the state to Tango.
      return DeviceImpl::dev_state();  // Return it after Tango management.

}

//--------------------------------------------------------
/**
 *    Execute the DevStart command:
 *    Description: Start the specified server.
 *
 *    @param argin Server to be started.
 *    @returns 
 */
//--------------------------------------------------------
00864 void Starter::dev_start(Tango::DevString argin)
{
      DEBUG_STREAM << "Starter::DevStart()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::dev_start) ENABLED START -----*/

      //    Add your own code
      //INFO_STREAM 
      cout << "Starter::dev_start(\""<< argin << "\"): entering... !" << endl;

      NewProcess  *np = processCouldStart(argin);
      if (np==NULL)
            return;

      //    Build a vector to start process
      vector<NewProcess *>    processes;
      processes.push_back(np);
      startProcesses(processes, 0);

      /*----- PROTECTED REGION END -----*/      //    Starter::dev_start

}

//--------------------------------------------------------
/**
 *    Execute the DevStop command:
 *    Description: Stop the specified server.
 *
 *    @param argin Servero be stopped.
 *    @returns 
 */
//--------------------------------------------------------
00895 void Starter::dev_stop(Tango::DevString argin)
{
      DEBUG_STREAM << "Starter::DevStop()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::dev_stop) ENABLED START -----*/

      //    Add your own code
      //    Check if servers object initilized
      //---------------------------------------
      if (servers.size()==0)
      {
            TangoSys_OMemStream out_stream;
            out_stream << argin << ": Server  not controlled !" << ends;
            Tango::Except::throw_exception(out_stream.str(),
                        out_stream.str(),
                        (const char *)"Starter::dev_stop()");
            return;
      }

      //    Check Argin as server name
      //----------------------------------
      string      name(argin);
      ControledServer   *server = util->get_server_by_name(name, servers);
      if (server==NULL)
      {
            TangoSys_OMemStream out_stream;
            out_stream << argin << ": Unkown Server !" << ends;
            Tango::Except::throw_exception(out_stream.str(),
                        out_stream.str(),
                        (const char *)"Starter::dev_stop()");
            return;
      }

      //    Make shure that it's  running.
      //---------------------------------------
      if (server->state==Tango::ON)
      {
            //    And Kill it with kill signal
            if (server->dev==NULL)
                  server->dev =  new Tango::DeviceProxy(server->admin_name);
            server->dev->command_inout("Kill");

            TangoSys_OMemStream out_stream;
            out_stream << argin << " stopped";
            WARN_STREAM << out_stream.str() << endl;
            cout << out_stream.str() << endl;
            util->log_starter_info(out_stream.str());
      }
      else
      if (server->state==Tango::MOVING)
      {
            TangoSys_OMemStream out_stream;
            out_stream << argin << " is running but not responding !" << ends;
            Tango::Except::throw_exception(
                        (const char *)"SERVER_NOT_RESPONDING",
                        out_stream.str(),
                        (const char *)"Starter::dev_stop()");
            return;
      }
      else
      {
            TangoSys_OMemStream out_stream;
            out_stream << argin << " is NOT running !" << ends;
            Tango::Except::throw_exception(
                        (const char *)"SERVER_NOT_RUNNING",
                        out_stream.str(),
                        (const char *)"Starter::dev_stop()");
            return;
      }

      /*----- PROTECTED REGION END -----*/      //    Starter::dev_stop

}

//--------------------------------------------------------
/**
 *    Execute the DevStartAll command:
 *    Description: Start all device servers controled on the host for the argin level.
 *
 *    @param argin Startup level.
 *    @returns 
 */
//--------------------------------------------------------
00977 void Starter::dev_start_all(Tango::DevShort argin)
{
      DEBUG_STREAM << "Starter::DevStartAll()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::dev_start_all) ENABLED START -----*/

      //    Add your own code
      Tango::DevShort  level = argin;
      cout << "Starter::dev_start_all(): entering for level "<< level <<"... !" << endl;

      Tango::DevBoolean throw_it = false;
      //    Check if servers object initilized
      //---------------------------------------
      if (servers.size()==0)
            if (throwable)
                  throw_it = true;
            else
                  return;
      if (throw_it)
      {
                  TangoSys_OMemStream out_stream;
                  out_stream << "NO Server  controlled !" << ends;
                  Tango::Except::throw_exception(out_stream.str(),
                  out_stream.str(),
                        (const char *)"Starter::dev_start_all()");
      }

      //    Do not want exception during startup
      throwable = false;

      //    And start the stopped ones
      //---------------------------------------------------
      vector<NewProcess *>    processes;
      for (unsigned int i=0 ; i<servers.size() ; i++)
      {
            ControledServer   *server = &servers[i];
            //    server->running could not be initialized
            if (server->controled  &&  server->startup_level==level)
            {
                  cout << "Check startup for " << server->name << endl;
                  if (server->state==Tango::FAULT)
                  {
                        NewProcess  *np = processCouldStart((char*)server->name.c_str());
                        if (np!=NULL)
                        {
                              processes.push_back(np);
                              cout << "Try to start " << np->servname << endl;
                        }
                        else
                              cout << "np is null (?)" << endl;
                  }
                  else
                        cout << "   Alread running...."<< endl;
            }
      }
      if (processes.size()>0)
            startProcesses(processes, level);

      //    Want exception during normal run
      throwable = true;

      /*----- PROTECTED REGION END -----*/      //    Starter::dev_start_all

}

//--------------------------------------------------------
/**
 *    Execute the DevStopAll command:
 *    Description: Stop all device servers controled on the host for the argin level.
 *
 *    @param argin Startup Level.
 *    @returns 
 */
//--------------------------------------------------------
01050 void Starter::dev_stop_all(Tango::DevShort argin)
{
      DEBUG_STREAM << "Starter::DevStopAll()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::dev_stop_all) ENABLED START -----*/

      //    Add your own code
      Tango::DevShort  level = argin;
      //    Check if servers object initilized
      //---------------------------------------
      if (servers.size()==0)
      {
            TangoSys_OMemStream out_stream;
            out_stream << "NO Server  controlled !" << ends;
            Tango::Except::throw_exception(out_stream.str(),
                        out_stream.str(),
                        (const char *)"Starter::dev_stop_all()");
            return;
      }
      //    And stop the running ones
      //---------------------------------------------------
      for (unsigned int i=0 ; i<servers.size() ; i++)
      {
            ControledServer   *server = &servers[i];
            if (server->controled             &&
                  server->startup_level==level  &&
                  server->state==Tango::ON)
                        dev_stop((char*)server->name.c_str());
      }

      /*----- PROTECTED REGION END -----*/      //    Starter::dev_stop_all

}

//--------------------------------------------------------
/**
 *    Execute the DevGetRunningServers command:
 *    Description: Control the running process from property list.
 *                 And return the list of the processes which are really running.
 *
 *    @param argin True for all servers. False for controled servers only.
 *    @returns List of the processes which are running.
 */
//--------------------------------------------------------
01093 Tango::DevVarStringArray *Starter::dev_get_running_servers(Tango::DevBoolean argin)
{
      Tango::DevVarStringArray *argout;
      DEBUG_STREAM << "Starter::DevGetRunningServers()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::dev_get_running_servers) ENABLED START -----*/

      //    Add your own code
      Tango::DevBoolean  all_serv = argin;
      argout = new Tango::DevVarStringArray;
      INFO_STREAM << "Starter::dev_get_running_server(): entering... !" << endl;

      //    Check if servers object initilized
      //---------------------------------------
      if (servers.size()==0)
      {
            return argout;
      }

      //    prepeare the argout for running servers list
      //-----------------------------------------------------------
      int         nb = 0;
      int         x;
      unsigned int      i;
      for (i=0 ; i<servers.size() ; i++)
            if (all_serv || servers[i].controled)
                  if (servers[i].state==Tango::ON)
                        nb ++;

      //    And fill it
      //-----------------------------------------------------------
      argout->length(nb);
      for (i=0, x=0 ; i<servers.size() && x<nb ; i++)
            if (all_serv || servers[i].controled)
                  if (servers[i].state==Tango::ON)
                  {
                        INFO_STREAM << "RUNNING: " << servers[i].name << endl;
                        (*argout)[x++] = CORBA::string_dup(servers[i].name.c_str());
                  }

      /*----- PROTECTED REGION END -----*/      //    Starter::dev_get_running_servers

      return argout;
}

//--------------------------------------------------------
/**
 *    Execute the DevGetStopServers command:
 *    Description: Control the running process from property list.
 *                 And return the list of the processes which are not running.
 *
 *    @param argin True for all servers. False for controled servers only.
 *    @returns List of the processes which are not running.
 */
//--------------------------------------------------------
01147 Tango::DevVarStringArray *Starter::dev_get_stop_servers(Tango::DevBoolean argin)
{
      Tango::DevVarStringArray *argout;
      DEBUG_STREAM << "Starter::DevGetStopServers()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::dev_get_stop_servers) ENABLED START -----*/

      //    Add your own code
      Tango::DevBoolean  all_serv = argin;
      argout = new Tango::DevVarStringArray();
      INFO_STREAM << "Starter::dev_get_stop_servers(): entering... !" << endl;

      //    Check if servers object initilized
      //---------------------------------------
      if (servers.size()==0)
      {
            argout->length(0);
            return argout;
      }

      //    prepeare the argout for NOT running servers list
      //-----------------------------------------------------------
      int         nb = 0;
      int         x;
      unsigned int      i;
      for (i=0 ; i<servers.size() ; i++)
            if (all_serv || servers[i].controled)
                  if (servers[i].state!=Tango::ON)
                        nb ++;

      //    And fill it
      //-----------------------------------------------------------
      argout->length(nb);
      for (i=0, x=0  ; i<servers.size() && x<nb; i++)
            if (all_serv || servers[i].controled)
                  if (servers[i].state!=Tango::ON)
                  {
                        INFO_STREAM << "STOPPED: " << servers[i].name << endl;
                        (*argout)[x++] = CORBA::string_dup(servers[i].name.c_str());
                  }

      /*----- PROTECTED REGION END -----*/      //    Starter::dev_get_stop_servers

      return argout;
}

//--------------------------------------------------------
/**
 *    Execute the DevReadLog command:
 *    Description: At server startup, its standard error is redirected to a log file.
 *                 This command will read this file and return the read string from the file.
 *
 *    @param argin server name and domain
 *    @returns ig Starter/corvus)
 */
//--------------------------------------------------------
01202 Tango::ConstDevString Starter::dev_read_log(Tango::DevString argin)
{
      Tango::ConstDevString argout;
      DEBUG_STREAM << "Starter::DevReadLog()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::dev_read_log) ENABLED START -----*/

      //    Add your own code
      string      filename;
      bool  on_starter;
      //    Check if for Starter itself
      if (strcmp(argin, "Starter")==0)
      {
            on_starter = true;
            filename = util->starter_log_file;
      }
      else
      {
            on_starter = false;
            filename = util->build_log_file_name(argin);
      }

      //    Try to open log file
      ifstream    ifs((char *)filename.c_str());
      if (!ifs)
      {
            //    Open log file failed -> Throw exception
            //----------------------------------------------
            TangoSys_OMemStream reason;
            TangoSys_OMemStream description;
            reason << "Cannot open " << filename << ends;
            description << strerror(errno);
            Tango::Except::throw_exception(reason.str(),
                                    description.str(),
                                    (const char *)"Starter::dev_read_log");
      }

      //    Read and close log file, and return string read from it.
      //-------------------------------------------------------------
      stringstream      strlog;
      if (!on_starter)
      {
            strlog << filename << endl;
            strlog << util->get_file_date((char *)filename.c_str()) << endl << endl;
      }
      strlog << ifs.rdbuf() << ends;
      ifs.close();
      returned_str = strlog.str();
      return returned_str.c_str();

      /*----- PROTECTED REGION END -----*/      //    Starter::dev_read_log

      return argout;
}

//--------------------------------------------------------
/**
 *    Execute the HardKillServer command:
 *    Description: Hard kill a server (kill -9)
 *
 *    @param argin Server name
 *    @returns 
 */
//--------------------------------------------------------
01265 void Starter::hard_kill_server(Tango::DevString argin)
{
      DEBUG_STREAM << "Starter::HardKillServer()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::hard_kill_server) ENABLED START -----*/

      //    Add your own code
      string      servname(argin);
      int   pid = util->proc_util->get_server_pid(servname);
      if (pid<0)
      {
            TangoSys_OMemStream tms;
            tms << "Server " << argin << " is not running !";
            Tango::Except::throw_exception(
                              (const char *)"SERVER_NOT_RUNNING",
                              tms.str().c_str(),
                              (const char *)"Starter::hard_kill_server()");
      }
#ifdef _TG_WINDOWS_

      HANDLE      handle = NULL;                      //- process addr (in the heap)
      if( (handle=OpenProcess(PROCESS_TERMINATE, false, pid)) == NULL)
      {
            TangoSys_OMemStream tms;
            tms << "Open handle on server " << argin << " failed !";
            Tango::Except::throw_exception(
                              (const char *)"KILL_DERVER_FAILED",
                              tms.str().c_str(),
                              (const char *)"Starter::hard_kill_server()");
      }
      
      TerminateProcess(handle, 0);
      CloseHandle(handle);
      if (GetLastError()!= ERROR_SUCCESS)
      {
            TangoSys_OMemStream tms;
            tms << "Kill server " << argin << " failed !";
            Tango::Except::throw_exception(
                              (const char *)"KILL_DERVER_FAILED",
                              tms.str().c_str(),
                              (const char *)"Starter::hard_kill_server()");
      }

#else

      TangoSys_OMemStream cmd;
      cmd << "kill -9 " << pid;
      if (system(cmd.str().c_str())<0)
      {
            TangoSys_OMemStream tms;
            tms << "Kill server " << argin << " failed !";
            Tango::Except::throw_exception(
                              (const char *)"KILL_DERVER_FAILED",
                              tms.str().c_str(),
                              (const char *)"Starter::hard_kill_server()");
      }
#endif

      /*----- PROTECTED REGION END -----*/      //    Starter::hard_kill_server

}

//--------------------------------------------------------
/**
 *    Execute the NotifyDaemonState command:
 *    Description: Returns the Notify Daemon state.
 *
 *    @param argin 
 *    @returns Tango::ON if Notify daemon is running else Tango::FAULT.
 */
//--------------------------------------------------------
01335 Tango::DevState Starter::notify_daemon_state()
{
      Tango::DevState argout;
      DEBUG_STREAM << "Starter::NotifyDaemonState()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::notify_daemon_state) ENABLED START -----*/

      //    Add your own code
      if (useEvents==false)
            Tango::Except::throw_exception(
                              (const char *)"NOTIFY_NOT_AVAILABLE",
                              (const char *)"Notify Daemon control is disabled",
                              (const char *)"Starter::notify_daemon_state()");
      argout = notifyd_state;

      /*----- PROTECTED REGION END -----*/      //    Starter::notify_daemon_state

      return argout;
}

//--------------------------------------------------------
/**
 *    Execute the UpdateServersInfo command:
 *    Description: Indicate to the device server than the information about servers to be controlled has been modified.
 *                 The device server must read the database to update the servers info list.
 *                 If the default case, this command is sent by Database server itself.
 *
 *    @param argin 
 *    @returns 
 */
//--------------------------------------------------------
01365 void Starter::update_servers_info()
{
      DEBUG_STREAM << "Starter::UpdateServersInfo()  - " << device_name << endl;
      /*----- PROTECTED REGION ID(Starter::update_servers_info) ENABLED START -----*/

      //    Add your own code
      do_update_from_db = true;

      /*----- PROTECTED REGION END -----*/      //    Starter::update_servers_info

}


      /*----- PROTECTED REGION ID(Starter::namespace_ending) ENABLED START -----*/

      //    Additional Methods
//+------------------------------------------------------------------
/**
 *    Class Destructor
 */
//+------------------------------------------------------------------
/*
Starter::~Starter()
{
      util->log_starter_info("Starter shutdown");
      //    Stop ping threads
      vector<ControledServer>::iterator it;
      for (it=servers.begin() ; it<servers.end() ; it++)
      {
            it->thread_data->set_stop_thread();
      }
      util->proc_util->stop_it();
      ms_sleep(1000);
      delete dbase;
      delete util;
      delete attr_HostState_read;
      delete attr_NotifdState_read;
      delete start_proc_data;
}
*/
//+------------------------------------------------------------------
/**
 *    Check if a process could be started (file exists, is not running, ...)
 */
//+------------------------------------------------------------------
01410 NewProcess *Starter::processCouldStart(char *argin)
{
      INFO_STREAM << "Starter::processCouldStart(\""<< argin << "\"): entering... !" << endl;
      
      //    Make sure that it's not running.
      //---------------------------------------
      if (servers.size()>0)
      {
            string      name(argin);
            ControledServer   *server = util->get_server_by_name(name, servers);
            if (server!=NULL)
                  if (server->state!=Tango::FAULT)
                  {
                        INFO_STREAM << argin << " is already running !" <<endl;
                        TangoSys_OMemStream tms;
                        tms << argin << " is already running !" << ends;
                        if (throwable)
                              Tango::Except::throw_exception(
                                                (const char *)"ALREADY_RUNNING",
                                                tms.str(),
                                                (const char *)"Starter::dev_start()");
                        return NULL;
                  }
      }

      //    Separate server name and instancename.
      //-------------------------------------
      char  *servname     = util->get_server_name(argin) ;
      char  *instancename = util->get_instance_name(argin);
      char  *adminname = new char[strlen(servname)+ strlen(instancename)+10];
      sprintf(adminname, "dserver/%s/%s", servname, instancename);
      char  *filename;
      try {
            filename = util->check_exe_file(servname, startDsPath);
      }
      catch(Tango::DevFailed &e)
      {
            free(servname);
            if (throwable)
                  throw e;
            else
            {
                  cout << e.errors[0].desc << endl;
                  return NULL;
            }
      }
      free(servname);

      //    Check if log dir already exists.
      //-------------------------------------
      string      log_file = util->build_log_file_name(argin);
      
      string      logpath;
      LogPath(logpath,logFileHome);
      INFO_STREAM << "LOG file : " << log_file << endl;
      if (chdir(logpath.c_str())==-1)
      {
            if (errno==ENOENT)
            {
                  //    Create directory
                  //-------------------------
                  cerr << "ENOENT" << endl;
                  cerr << errno << "  " << strerror(errno) << endl;
#ifdef _TG_WINDOWS_
                  mkdir(TmpRoot);
                  int r = mkdir(logpath.c_str());
#else
#     ifdef linux
                  int r = mkdir(logpath.c_str(), (mode_t)(0775) );
#     else
                  int r = mkdir(logpath.c_str(), (mode_t)(O_RDWR | O_CREAT, 0775) );
#     endif
#endif
                  if (r<0)
                  {
                        TangoSys_OMemStream     message;
                        message << "Cannot create error log directory:\n";
                        message << logpath;
                        message << "\n" << strerror(errno) << endl;
                        cerr << message.str() << endl;;
                        set_status(message.str());
                        Tango::Except::throw_exception(
                                                      (const char *)"CANNOT_CREATE_LOG_FILE",
                                                      message.str(),
                                                      (const char *)"Starter::dev_start");
                  }
                  else
                  {
                        TangoSys_OMemStream     tms;
                        tms << logpath << " Created !" << endl;
                        INFO_STREAM << tms.str() << endl;
                        set_status(tms.str());
                  }
            }
            else
            {
                  TangoSys_OMemStream     tms;
                  tms << "Cannot change to log directory:\n";
                  tms << logpath;
                  tms << "\n" << strerror(errno) << endl;
                  cerr << tms.str() << endl;;
                  set_status(tms.str());
            }
      }
      
      NewProcess  *np  = new NewProcess;
      np->servname     = filename;
      np->instancename = instancename;
      np->adminname    = adminname;
      np->logfile      = new char[log_file.length()+1];
      np->logfile      = strcpy(np->logfile, log_file.c_str());
      
      return np;
}
//+------------------------------------------------------------------
//+------------------------------------------------------------------
01526 void Starter::startProcesses(vector<NewProcess *> v_np, int level)
{
      //    Start process to start processes
      //-------------------------------------
      start_proc_data->push_back_level(level);
      StartProcessThread      *pt =
            new StartProcessThread(v_np, level, this);
      pt->start();
}
//+------------------------------------------------------------------
/**
 *    Return how many servers to start for specified level.
 */
//+------------------------------------------------------------------
01540 int   Starter::nb_servers_to_start(int level)
{
      int   cnt = 0;
      for (unsigned int i=0 ; i<servers.size() ; i++)
      {
            ControledServer   *server = &servers[i];
            //    server->running could not be initialized
            if (server->controled  &&  server->startup_level==level)
                  if (server->state!=Tango::ON)
                        cnt++;
      }
      return cnt;
}
//=================================================================
//=================================================================
01555 void Starter::check_host()
{
      string      hostname = Tango::Util::instance()->get_host_name();
      transform(hostname.begin(), hostname.end(), hostname.begin(), ::tolower);
      //    remove FQDN
      string::size_type pos = hostname.find('.');
      if (pos!=string::npos)
            hostname = hostname.substr(0, pos);

      string      devname = device_name;
      transform(devname.begin(), devname.end(), devname.begin(), ::tolower);

      //    Get only member
      pos = devname.find('/');
      if (pos!=string::npos)
      {
            pos = devname.find('/', pos+1);
            if (pos!=string::npos)
                  devname = devname.substr(pos+1);
      }
      //cout << hostname << " == " << devname << endl;
      
      if (devname != hostname)
      {
            TangoSys_OMemStream     tms;
            tms << "This server must run on " << devname << " and not on "  << hostname;
            string      descr(tms.str());
            
            Tango::Except::throw_exception(
                        (const char *)"BAD_PARAM",
                        (const char *) descr.c_str(),
                        (const char *)"Starter::check_host()");
      }
}


      /*----- PROTECTED REGION END -----*/      //    Starter::namespace_ending
} //  namespace

Generated by  Doxygen 1.6.0   Back to index