Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

ServerMain_T.hh

Go to the documentation of this file.
00001 /*
00002  * ServerMain_T.hh
00003  *
00004  * Copyright (c) 2003 The University of Utah and the Flux Group.
00005  * All rights reserved.
00006  *
00007  * This file is licensed under the terms of the GNU Public License.  
00008  * See the file "license.terms" for restrictions on redistribution 
00009  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00010  */
00011 
00012 /**
00013  * @file ServerMain_T.hh
00014  *
00015  * Contains a function template for setting up and running a single object
00016  * server.
00017  */
00018 
00019 #ifndef _server_main_t_hh
00020 #define _server_main_t_hh
00021 
00022 #include "config.h"
00023 
00024 #include <unistd.h>
00025 
00026 #include <iostream>
00027 #include <fstream>
00028 
00029 #include <assert_pp.h>
00030 
00031 #include <BrokerC.h>
00032 
00033 #include "NamingHelper_T.h"
00034 
00035 #if defined(HAVE_LIBRK)
00036 #include <rk.h>
00037 #include <rk/rk_error.h>
00038 #endif
00039 
00040 /*
00041  * The ServerMainDefaults structure is used to specify the default values for
00042  * any command line arguments recognized by the server.
00043  *
00044  * smd_Name - The name of the object in the NamingService.
00045  * smd_IOR - The name of the file that the IOR should be stored in or NULL if
00046  *           no file should be written.
00047  */
00048 struct ServerMainDefaults {
00049     const char *smd_Name;
00050     const char *smd_IOR;
00051 };
00052 
00053 /*
00054  * The ServerMainData structure holds any global data for the program.
00055  */
00056 struct ServerMainData {
00057 #if defined(HAVE_LIBRK)
00058     rk_resource_set_t smd_ResourceSet;
00059 #endif
00060 } server_main_data;
00061 
00062 /**
00063  * Handler for SIGINT/SIGTERM signals.
00064  *
00065  * @param sig The actual signal received.
00066  */
00067 void sigexit_handler(int sig)
00068 {
00069     require((sig == SIGINT) || (sig == SIGTERM));
00070     
00071 #if defined(HAVE_LIBRK)
00072     if( server_main_data.smd_ResourceSet != NULL )
00073     {
00074         rk_resource_set_destroy(server_main_data.smd_ResourceSet);
00075     }
00076 #endif
00077     exit(EXIT_SUCCESS);
00078 }
00079 
00080 /**
00081  * Output the usage message for this program to standard error.
00082  *
00083  * @param prog_name The program name, as given on the command line.
00084  * @param smd The default values for this program.
00085  */
00086 void server_main_usage(char *prog_name, struct ServerMainDefaults &smd)
00087 {
00088     require(prog_name != NULL);
00089     
00090     cerr << "Usage: " << prog_name << " [options]" << endl
00091 
00092          << endl
00093 
00094          << smd.smd_Name << " object server." << endl
00095 
00096          << endl
00097 
00098          << "Options:" << endl
00099 
00100          << "\t-h\t\tThis help message." << endl
00101          << "\t-V\t\tShow the version number." << endl
00102 
00103          << "\t-n <name>"
00104          << "\tThe name for the object in the NamingService. "
00105          << "(default: " << smd.smd_Name << ")" << endl
00106         
00107          << "\t-o <ior file>"
00108          << "\tThe IOR output file. "
00109          << "(default: "
00110          << (smd.smd_IOR == NULL ? "<none>" : smd.smd_IOR)
00111          << ")" << endl
00112         
00113          << endl
00114         
00115          << "Package: " PACKAGE_STRING << endl
00116          << "Contact: " PACKAGE_BUGREPORT << endl
00117 
00118         ;
00119 }
00120 
00121 /**
00122  * Template function for a server that exports a single object.
00123  *
00124  * @param T The object implementation class.  The constructor is expected to
00125  *          take a 'const char *' argument that contains the object name.
00126  * @param U The object's _var smart pointer class.
00127  * @param smd The defaults for the command line parameters.
00128  * @param argc The argc passed to the real main.
00129  * @param argv The argv passed to the real main.
00130  * @return EXIT_FAILURE or runs for forever.
00131  */
00132 template <class T, class U> int server_main(struct ServerMainDefaults &smd,
00133                                             int argc,
00134                                             char *argv[])
00135 {
00136     int retval = EXIT_FAILURE;
00137 
00138     require(smd.smd_Name != NULL);
00139     require(smd.smd_IOR != NULL);
00140     require(argc >= 1);
00141     require(argv != NULL);
00142 
00143     signal(SIGINT, sigexit_handler);
00144     signal(SIGTERM, sigexit_handler);
00145     try
00146     {
00147         /* ORB setup */
00148         CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
00149         
00150         CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
00151         
00152         PortableServer::POA_var root_poa =
00153             PortableServer::POA::_narrow(obj.in());
00154         PortableServer::POAManager_var mgr = root_poa->the_POAManager();
00155         mgr->activate();
00156 
00157         PortableServer::ThreadPolicy_var thread = root_poa->
00158             create_thread_policy(PortableServer::SINGLE_THREAD_MODEL);
00159 
00160         CORBA::PolicyList policy_list;
00161         policy_list.length(1);
00162         policy_list[0] = PortableServer::ThreadPolicy::_duplicate(thread.in());
00163         
00164         PortableServer::POA_var st_poa = root_poa->
00165             create_POA("SingleThread",
00166                        PortableServer::POAManager::_nil(),
00167                        policy_list);
00168 
00169         thread->destroy();
00170 
00171         {
00172             const char *obj_name = smd.smd_Name;
00173             const char *obj_ior = smd.smd_IOR;
00174             int ch;
00175 
00176             retval = EXIT_SUCCESS;
00177             while( ((ch = getopt(argc, argv, "hVn:o:")) != -1) &&
00178                    (retval == EXIT_SUCCESS) )
00179             {
00180                 switch( ch )
00181                 {
00182                 case 'V':
00183                     cerr << PACKAGE_VERSION << endl;
00184                     retval = EXIT_FAILURE;
00185                     break;
00186                 case 'n':
00187                     obj_name = optarg;
00188                     break;
00189                 case 'o':
00190                     obj_ior = optarg;
00191                     break;
00192                 case 'h':
00193                 case '?':
00194                 default:
00195                     server_main_usage(argv[0], smd);
00196                     retval = EXIT_FAILURE;
00197                     break;
00198                 }
00199             }
00200 
00201             if( retval == EXIT_SUCCESS )
00202             {
00203 #if defined(HAVE_LIBRK)
00204                 {
00205                     rk_resource_set_t rs;
00206                 
00207                     if( (rs = rk_resource_set_create(obj_name)) != NULL )
00208                     {
00209                         struct cpu_reserve_attr cra;
00210                         rk_reserve_t cr;
00211                         
00212                         memset(&cra, 0, sizeof(cra));
00213                         cra.compute_time.tv_sec = 0;
00214                         cra.compute_time.tv_nsec = 10000000;
00215                         cra.period.tv_sec = 1;
00216                         cra.period.tv_nsec = 0;
00217                         cra.deadline = cra.period;
00218                         cra.reserve_type.sch_mode = RSV_SOFT;
00219                         cra.reserve_type.enf_mode = RSV_SOFT;
00220                         cra.reserve_type.rep_mode = RSV_SOFT;
00221                         cra.processor = RK_ANY_CPU;
00222                         if( (rk_cpu_reserve_create(rs, &cr, &cra) ==
00223                              RK_SUCCESS) &&
00224                             (rk_resource_set_attach_process(rs, getpid()) ==
00225                              RK_SUCCESS) )
00226                         {
00227                             server_main_data.smd_ResourceSet = rs;
00228                         }
00229                         else
00230                         {
00231                             rk_resource_set_destroy(rs);
00232                         }
00233                     }
00234                     else
00235                     {
00236                         perror("rk_resource_set_create");
00237                     }
00238                 }
00239 #endif
00240                 
00241                 /* Create our object. */
00242                 T *spi = new T(obj_name);
00243                 U sobj;
00244                 
00245                 PortableServer::ObjectId_var oid = st_poa->
00246                     activate_object(spi);
00247                 
00248                 sobj = spi->_this();
00249                 
00250                 /* Write out the IOR, if they so desire. */
00251                 if( obj_ior[0] != '\0' )
00252                 {
00253                     ofstream ostr(obj_ior);
00254                     ostr << orb->object_to_string(sobj.in()) << endl;
00255                     ostr.close();
00256                 }
00257 
00258                 if( obj_name[0] != '\0' )
00259                 {
00260                     /* Get the NamingService. */
00261                     CosNaming::NamingContext_var nc;
00262                     
00263                     nc = NamingHelper<CosNaming::NamingContext>::
00264 			resolve_init(orb.in(), "NameService");
00265                     
00266                     if( !CORBA::is_nil(nc.in()) )
00267                     {
00268                         /* Register with the NamingService. */
00269                         CosNaming::Name name;
00270                         
00271                         name.length(1);
00272                         name[0].id = CORBA::string_dup(obj_name);
00273                         name[0].kind = CORBA::string_dup("");
00274                         
00275                         nc->rebind(name, sobj.in());
00276                     }
00277                     else
00278                     {
00279                         cerr << "Could not find name service!" << endl;
00280                     }
00281                 }
00282                 
00283                 /* Light the candle! */
00284                 orb->run();
00285                     
00286                 /* Candle in the wind... */
00287                 orb->shutdown();
00288                 
00289 #if defined(HAVE_LIBRK)
00290                 if( server_main_data.smd_ResourceSet != NULL )
00291                 {
00292                     rk_resource_set_destroy(server_main_data.smd_ResourceSet);
00293                 }
00294 #endif
00295             }
00296         }
00297     }
00298     catch(const CORBA::SystemException &e)
00299     {
00300         cerr << "Caught Exception: " << e << endl;
00301     }
00302     catch(...)
00303     {
00304         cerr << "Caught an unhandled exception" << endl;
00305     }
00306 
00307     return( retval );
00308 }
00309 
00310 #endif

Generated on Mon Dec 1 16:29:07 2003 for CPU Broker by doxygen 1.3.4