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

FactoryLibrary_ltdl.cc

Go to the documentation of this file.
00001 /*
00002  * FactoryLibrary_ltdl.cc
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 FactoryLibrary_ltdl.cc
00014  *
00015  * Implementation file for the FactoryLibrary_ltdl class.
00016  */
00017 
00018 #include "config.h"
00019 
00020 #include <assert_pp.h>
00021 #include <factory_library.h>
00022 
00023 #include <strstream>
00024 
00025 #include "FactoryLibrary_ltdl.hh"
00026 
00027 #ifndef __XSTRING
00028 /**
00029  * Convert a macro argument to a string.
00030  *
00031  * @param x The macro to expand to a string.
00032  */
00033 #define __XSTRING(x) __STRING(x)
00034 #endif
00035 
00036 map<string, FactoryLibrary_ltdl *> FactoryLibrary_ltdl::open_libraries;
00037 
00038 CORBA::ORB_var FactoryLibrary_ltdl::orb;
00039 
00040 FactoryLibrary_ltdl::FactoryLibrary_ltdl(const char *name,
00041                                          lt_dlhandle dlh,
00042                                          factory_method_t fm)
00043 {
00044     require(name != NULL);
00045     require(dlh != NULL);
00046     require(fm != NULL);
00047 
00048     this->fl_Name = name;
00049     this->fl_OpenCount = 1;
00050     this->fl_Library = dlh;
00051     this->fl_Method = fm;
00052 }
00053 
00054 FactoryLibrary_ltdl::~FactoryLibrary_ltdl(void)
00055 {
00056     require(this->fl_OpenCount == 0);
00057     
00058     lt_dlclose(this->fl_Library);
00059     this->fl_Library = NULL;
00060     this->fl_Method = NULL;
00061 }
00062 
00063 char *FactoryLibrary_ltdl::Name(void)
00064     throw (CORBA::SystemException)
00065 {
00066     CORBA::String_var retval;
00067 
00068     retval = this->fl_Name;
00069     return( retval._retn() );
00070 }
00071 
00072 CORBA::Long FactoryLibrary_ltdl::Hey(const edu::utah::pces::ArgV &args,
00073                                      CORBA::String_out o,
00074                                      CORBA::String_out e)
00075     throw (CORBA::SystemException)
00076 {
00077     HeyParser hp(args.length(), args.get_buffer());
00078     CORBA::Long retval = EINVAL;
00079 
00080     /* String streams for stdout and stderr */
00081     strstream out, err;
00082 
00083     try
00084     {
00085         /* Pass the request to the library. */
00086         retval = flFactoryMethod(this->fl_Method, FLO_HEY,
00087                                  FMA_ORB, FactoryLibrary_ltdl::orb.in(),
00088                                  FMA_HeyParser, &hp,
00089                                  FMA_StandardOut, &out,
00090                                  FMA_StandardError, &err,
00091                                  FMA_TAG_DONE);
00092     }
00093     catch(const HeyParserException &e)
00094     {
00095         err << e << endl;
00096     }
00097 
00098     /* Terminate the stdio strings. */
00099     out << ends;
00100     err << ends;
00101 
00102     /* Pass them back out. */
00103     o = out.str();
00104     e = err.str();
00105     return( retval );
00106 }
00107 
00108 edu::utah::pces::FactoryLibrary_ptr
00109 FactoryLibrary_ltdl::OpenLibrary(const char *name)
00110     throw (edu::utah::pces::NoSuchLibrary,
00111            CORBA::SystemException)
00112 {
00113     edu::utah::pces::FactoryLibrary_var retval;
00114     lt_dlhandle dlh;
00115 
00116     require(name != NULL);
00117 
00118     /* Do some initialization... */
00119     {
00120         static bool init_done = false;
00121 
00122         if( !init_done )
00123         {
00124             int argc = 0;
00125             
00126             if( lt_dlinit() != 0 )
00127             {
00128                 /* XXX Use a more appropriate exception. */
00129                 throw CORBA::NO_MEMORY();
00130             }
00131             orb = CORBA::ORB_init(argc, NULL);
00132             init_done = true;
00133         }
00134     }
00135 
00136     /* Check if it is already open, */
00137     if( FactoryLibrary_ltdl::open_libraries.count(name) )
00138     {
00139         FactoryLibrary_ltdl *fl;
00140 
00141         fl = FactoryLibrary_ltdl::open_libraries[name];
00142         fl->fl_OpenCount += 1;
00143         retval = fl->_this();
00144     }
00145     /* ... or is a valid path to a library. */
00146     else if( (dlh = lt_dlopenext(name)) != NULL )
00147     {
00148         FactoryLibrary_ltdl *fl;
00149         factory_method_t fm;
00150 
00151         /* Check if it is a real factory library then */
00152         if( (fm = (factory_method_t)
00153              lt_dlsym(dlh, __XSTRING(FACTORY_METHOD_SYMBOL))) == NULL )
00154         {
00155             lt_dlclose(dlh);
00156             throw edu::utah::pces::NoSuchLibrary(name, "No factory_method_t");
00157         }
00158 
00159         /* ... create the object and */
00160         fl = new FactoryLibrary_ltdl(name, dlh, fm);
00161         /* ... add it to the map. */
00162         FactoryLibrary_ltdl::open_libraries[name] = fl;
00163         retval = fl->_this();
00164     }
00165     else
00166     {
00167         throw edu::utah::pces::NoSuchLibrary(name, lt_dlerror());
00168     }
00169     return( retval._retn() );
00170 }

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