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

Generated on Mon Dec 1 16:21:56 2003 for CPUBroker by doxygen 1.3.4