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

broker_allup.cc

Go to the documentation of this file.
00001 /*
00002  * broker_allup.cc
00003  *
00004  * Copyright (c) 2003, 2004 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 broker_allup.cc
00014  *
00015  * Main file for an edu::utah::pces::Allup server.
00016  */
00017 
00018 #include "config.h"
00019 
00020 #include <stdlib.h>
00021 #include <signal.h>
00022 #include <unistd.h>
00023 
00024 #include <sys/time.h>
00025 
00026 #include <assert.h>
00027 #include <assert_pp.h>
00028 #include <instrumentation.h>
00029 
00030 #include <ltdl.h>
00031 
00032 #if defined(HAVE_LIBRK)
00033 #include <rk/rk.h>
00034 #include <rk/rk_error.h>
00035 #endif
00036 
00037 #include <fstream>
00038 #include <iostream>
00039 
00040 #include <AllupImpl.hh>
00041 
00042 using namespace std;
00043 
00044 /**
00045  * Flag bit numbers for the executable as a whole.
00046  */
00047 enum {
00048     BAB_DAEMON, /**< Fork into the background. */
00049 };
00050 
00051 /**
00052  * Flags bits derived from the bit numbers above.
00053  */
00054 enum {
00055     BAF_DAEMON = (1L << BAB_DAEMON),
00056 };
00057 
00058 /**
00059  * Global data for the server.
00060  *
00061  * ba_ResourceSet - The resource set for this process.
00062  */
00063 static struct {
00064     CORBA::ORB_var ba_ORB;
00065     unsigned long ba_Flags;
00066     const char *ba_IORFileName;
00067     const char *ba_PIDFileName;
00068 #if defined(HAVE_LIBRK)
00069     rk_resource_set_t ba_ResourceSet;
00070 #endif
00071 } ba_data;
00072 
00073 /**
00074  * Signal handler for SIGINT/SIGTERM.
00075  *
00076  * @param sig The actual signal number received.
00077  */
00078 static void sig_exit_handler(int sig)
00079 {
00080     ba_data.ba_ORB->shutdown(0); /* Break out of orb->run(). */
00081 }
00082 
00083 /**
00084  * Print out the usage statement to standard error.
00085  *
00086  * @param prog_name The program name.
00087  */
00088 static void baUsage(const char *prog_name)
00089 {
00090     require(prog_name != NULL);
00091 
00092     cerr << "Server for CPU broker objects." << endl
00093          << "Usage: "
00094          << prog_name
00095          << " [options]\n"
00096          << endl
00097          << "Options:\n"
00098          << "  -h\t\tThis help message.\n"
00099          << "  -V\t\tShow the version number.\n"
00100 
00101          << "  -f\t\tFork into the background.\n"
00102          << "  -p <file>\tThe PID file name.\n"
00103          << "  -o <file>\tThe IOR file name. (Default: "
00104          << ba_data.ba_IORFileName << ")" << endl
00105 
00106          << endl
00107         
00108          << "Package: " << PACKAGE_STRING << endl
00109          << "Contact: " << PACKAGE_BUGREPORT << endl
00110 
00111         ;
00112 }
00113 
00114 /**
00115  * Process the command line options.
00116  *
00117  * @param argc_inout Reference to main's argc variable.  On return, the
00118  * variable will contain the number of arguments remaining after option
00119  * processing.
00120  * @param argv_inout Reference to main's argv variable.  On return, the
00121  * variable will contain the remaining argument values.
00122  * @return True if the options were processed correctly, false otherwise.
00123  */
00124 static int baProcessOptions(int &argc_inout, char **&argv_inout)
00125 {
00126     int ch, retval = 0;
00127     char *prog_name;
00128     char **argv;
00129     int argc;
00130     
00131     argc = argc_inout;
00132     argv = argv_inout;
00133     prog_name = argv[0];
00134     while( ((ch = getopt(argc, argv, "hVfp:o:")) != -1) && (retval == 0) )
00135     {
00136         switch( ch )
00137         {
00138         case 'f':
00139             ba_data.ba_Flags |= BAF_DAEMON;
00140             break;
00141         case 'p':
00142             if( strlen(optarg) == 0 )
00143             {
00144                 cerr << "Empty PID file name" << endl;
00145                 retval = 1;
00146             }
00147             else
00148             {
00149                 ba_data.ba_PIDFileName = optarg;
00150             }
00151             break;
00152         case 'o':
00153             if( strlen(optarg) == 0 )
00154             {
00155                 cerr << "Empty IOR file name" << endl;
00156                 retval = 1;
00157             }
00158             else
00159             {
00160                 ba_data.ba_IORFileName = optarg;
00161             }
00162             break;
00163         case 'V':
00164             cerr << PACKAGE_VERSION << endl;
00165             retval = -1;
00166             break;
00167         case 'h':
00168         case '?':
00169         default:
00170             retval = 1;
00171             break;
00172         }
00173     }
00174     argc_inout -= optind;
00175     argv_inout += optind;
00176     return( retval );
00177 }
00178 
00179 int main(int argc, char *argv[])
00180 {
00181     const char *prog_name = argv[0];
00182     int retval = EXIT_FAILURE;
00183 
00184     /* Default values. */
00185     ba_data.ba_IORFileName = "allup.ior";
00186 
00187     /* Do not let them kill us until we are ready. */
00188     signal(SIGINT, SIG_IGN);
00189     signal(SIGTERM, SIG_IGN);
00190 
00191     atexit(iPrintPointsAtExit);
00192     
00193 #if defined(HAVE_ACE)
00194     ACE_Log_Msg::instance()->priority_mask(0, ACE_Log_Msg::PROCESS);
00195 #endif
00196 
00197 #if defined(HAVE_LIBRK)
00198     {
00199         char set_name[RK_NAME_LEN];
00200         rk_resource_set_t rs;
00201 
00202         snprintf(set_name, sizeof(set_name), "allup.%d", getpid());
00203         if( rk_proc_get_rset(getpid()) != NULL_RESOURCE_SET )
00204         {
00205             /* Already have a resource set. */
00206         }
00207         else if( (rs = rk_resource_set_create(set_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 = 50000;
00215             cra.period.tv_sec = 0;
00216             cra.period.tv_nsec = 10000000;
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) == RK_SUCCESS) &&
00223                 (rk_resource_set_attach_process(rs, getpid()) == RK_SUCCESS) )
00224             {
00225                 ba_data.ba_ResourceSet = rs;
00226             }
00227             else
00228             {
00229                 rk_resource_set_destroy(rs);
00230             }
00231         }
00232         else
00233         {
00234             perror("rk_resource_set_create");
00235         }
00236     }
00237 #endif
00238     
00239     try
00240     {
00241         int rc;
00242         
00243         /* ORB/POA setup */
00244         ba_data.ba_ORB = CORBA::ORB_init(argc, argv);
00245 
00246         try
00247         {
00248             CORBA::Object_var obj = ba_data.ba_ORB->
00249                 resolve_initial_references("RootPOA");
00250             
00251             PortableServer::POA_var root_poa =
00252                 PortableServer::POA::_narrow(obj.in());
00253             PortableServer::POAManager_var mgr = root_poa->the_POAManager();
00254             
00255             PortableServer::ThreadPolicy_var thread = root_poa->
00256                 create_thread_policy(PortableServer::SINGLE_THREAD_MODEL);
00257             
00258             CORBA::PolicyList policy_list;
00259             policy_list.length(1);
00260             policy_list[0] =
00261                 PortableServer::ThreadPolicy::_duplicate(thread.in());
00262             
00263             PortableServer::POA_var st_poa = root_poa->
00264                 create_POA("SingleThread", mgr.in(), policy_list);
00265             
00266             thread->destroy();
00267             thread = PortableServer::ThreadPolicy::_nil();
00268             
00269             mgr->activate();
00270             
00271             rc = baProcessOptions(argc, argv);
00272             if( rc > 0 )
00273             {
00274                 baUsage(prog_name);
00275             }
00276             else if( rc == 0 )
00277             {
00278                 PortableServer::ObjectId_var allup_oid;
00279                 edu::utah::pces::Allup_var allup;
00280                 struct sigaction sa;
00281                 sigset_t sigmask;
00282                 AllupImpl *ai;
00283                 
00284                 ai = new AllupImpl(st_poa.in());
00285                 allup_oid = st_poa->activate_object(ai);
00286                 allup = edu::utah::pces::Allup::
00287                     _narrow(st_poa->id_to_reference(allup_oid.in()));
00288                 
00289                 {
00290                     ofstream ostr(ba_data.ba_IORFileName);
00291                     
00292                     ostr << ba_data.ba_ORB->object_to_string(allup.in())
00293                          << endl;
00294                     ostr.close();
00295                 }
00296 
00297                 /* Install our signal handlers, */
00298                 sigemptyset(&sigmask);
00299                 sigaddset(&sigmask, SIGINT);
00300                 sigaddset(&sigmask, SIGTERM);
00301 
00302                 sa.sa_mask = sigmask;
00303                 sa.sa_flags = 0;
00304 #if defined(SA_RESTART)
00305                 sa.sa_flags |= SA_RESTART;
00306 #endif
00307                 sa.sa_handler = sig_exit_handler;
00308                 sigaction(SIGINT, &sa, NULL);
00309                 sigaction(SIGTERM, &sa, NULL);
00310 
00311                 /* ... try to become a daemon, */
00312                 if( ba_data.ba_Flags & BAF_DAEMON )
00313                 {
00314                     daemon(1, 1);
00315                     /* Parent exits here. */
00316                 }
00317 
00318                 /* ... try to write out our pid, */
00319                 if( ba_data.ba_PIDFileName != NULL )
00320                 {
00321                     FILE *file;
00322 
00323                     if( (file = fopen(ba_data.ba_PIDFileName, "w")) != NULL )
00324                     {
00325                         fprintf(file, "%d", getpid());
00326                         fclose(file);
00327                         file = NULL;
00328                     }
00329                 }
00330                 
00331                 /* ... handle events, and then */
00332                 ba_data.ba_ORB->run();
00333 
00334                 /* ... uninstall our signal handlers. */
00335                 signal(SIGINT, SIG_IGN);
00336                 signal(SIGTERM, SIG_IGN);
00337             }
00338         }
00339         catch(const CORBA::SystemException &e)
00340         {
00341             cerr << "Caught CORBA exception: " << e << endl;
00342         }
00343         catch(...)
00344         {
00345             cerr << "Caught unknown exception..." << endl;
00346         }
00347         
00348         ba_data.ba_ORB->destroy();
00349         ba_data.ba_ORB = CORBA::ORB::_nil();
00350     }
00351     catch(const CORBA::SystemException &e)
00352     {
00353         cerr << "Caught CORBA exception: " << e << endl;
00354     }
00355     catch(...)
00356     {
00357         cerr << "Caught unknown exception..." << endl;
00358     }
00359     
00360 #if defined(HAVE_LIBRK)
00361     if( ba_data.ba_ResourceSet != NULL_RESOURCE_SET )
00362     {
00363         rk_resource_set_destroy(ba_data.ba_ResourceSet);
00364     }
00365 #endif
00366     
00367     return( retval );
00368 }

Generated on Tue Jun 22 14:50:08 2004 for CPU Broker by doxygen 1.3.6