#include "tao/Codeset_Descriptor_Base.h" #include "tao/Codeset_Manager_Factory_Base.h" #include "tao/Codeset_Manager.h" #include "tao/ORBInitializer_Registry_Adapter.h" #include "ace/ARGV.h" #include "ace/Dynamic_Service.h" #include "ace/Dynamic_Service_Dependency.h" #include "ace/Thread_Manager.h" #include "ace/Intrusive_Auto_Ptr.h" #include "Service_Configuration_Per_ORB.h" // Return the name of the service configuration file, based on the current ACE // support for wide characters and unicode /// Borrowing this from the $ACE_ROOT/test/Service_Config_Test /// The various config files have the same effect of loading 5 /// new service objects. const ACE_TCHAR* file_Service_Config_Test () { #if defined (ACE_USES_WCHAR) // When using full Unicode support, use the version of the Service // Configurator file appropriate to the platform. // For example, Windows Unicode uses UTF-16. // // iconv(1) found on Linux, for example, can // be used to convert between encodings. // // Byte ordering is also an issue, so we should be // generating this file on-the-fly from the UTF-8 encoded // file by using functions like iconv(1) or iconv(3). # if defined (ACE_WIN32) static const ACE_TCHAR svc_conf[] = ACE_TEXT ("Service_Config_Test.UTF-16") ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT); # else static const ACE_TCHAR svc_conf[] = ACE_TEXT ("Service_Config_Test.WCHAR_T") ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT); # endif /* ACE_WIN32 */ #else // ASCII (UTF-8) encoded Service Configurator file. static const ACE_TCHAR svc_conf[] = ACE_TEXT ("Service_Config_Test") ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT); #endif /* ACE_USES_WCHAR */ return svc_conf; } // @brief Loading dynamic services in a local repository int testOpenDynamicServices (int , ACE_TCHAR *[]) { ACE_TRACE ("testOpenDynamicServices"); ACE_ARGV new_argv; // Process the Service Configurator directives in this test's if (false == (new_argv.add (ACE_TEXT ("bogus")) != -1 && new_argv.add (ACE_TEXT ("-f")) != -1 && new_argv.add (file_Service_Config_Test ()) != -1)) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Error: Failed to build an argv\n"))); return -1; } // We need this scope to make sure that the destructor for the // gets called. ACE_Service_Gestalt_Test daemon(10); if (daemon.open (new_argv.argc (), new_argv.argv ()) == -1 && errno == ENOENT) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Error: Unable to open service config\n"))); return -1; } ACE_DEBUG ((LM_DEBUG, "\tdaemon.services_count () -> %d\n", daemon.services_count ())); if (5 != daemon.services_count ()) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Error: Expected %d service, but found %d instead\n"), 5, daemon.services_count ())); return -1; } // Since the loaded services start their own threads, wait until all // of them are done to avoid pulling the rug under their feet. ACE_Thread_Manager::instance ()->wait (); return 0; } // @brief Try loading the ORBInitializer_Registry locally int testORBInitializer_Registry (int , ACE_TCHAR *[]) { ACE_TRACE ("testORBInitializer_Registry"); // for global service registrations ACE_Intrusive_Auto_Ptr glob (new ACE_Service_Gestalt_Test ()); ACE_Intrusive_Auto_Ptr one (new ACE_Service_Gestalt_Test (10)); size_t glob_size = glob->services_count (); size_t loca_size = one->services_count (); // It is expected to be empty at this point since it is not using // the global repo if (loca_size != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Expected empty repository\n"))); return -1; } // Lookup it up. TAO::ORBInitializer_Registry_Adapter* oir = ACE_Dynamic_Service::instance (one.get (), "ORBInitializer_Registry"); #if defined (TAO_AS_STATIC_LIBS) if ((oir == 0)) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Expected to find staticaly linked ORBInitializer_Registry\n"))); return -1; } #else if (oir != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Not expected to find ORBInitializer_Registry\n"))); return -1; } #endif #if !defined (TAO_AS_STATIC_LIBS) // In case we build shared, try to load the PI Client library, in a // static build we just can't do this, so don't try it, lower layers // output an error then. if (oir == 0) { one->process_directive ( ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE("ORBInitializer_Registry", "TAO_PI", TAO_VERSION, "_make_ORBInitializer_Registry", "")); oir = ACE_Dynamic_Service::instance (one.get (), "ORBInitializer_Registry"); } if (oir == 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Expected to find ORBInitializer_Registry\n"))); return -1; } #endif if (glob_size != glob->services_count ()) { ACE_ERROR ((LM_ERROR, "Expected %d local static service registrations, found %d\n", glob_size, glob->services_count ())); return -1; } // The local repository must have asquired also the static services // registered within the dynamic service we just loaded. As of this // writing, loading ORBInitializer_Registry causes the registration of // four other (static) services. The PolicyFactory_Loader, // ClientRequestInterceptor_Adapter_Factory and PICurrent_Loader are // registred explicitely, while CodecFactory_Loader - indirectly. if (loca_size == one->services_count ()) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Expected to find additional services present\n"))); return -1; } ACE_DEBUG ((LM_DEBUG, "(%P|%t) try global dynamic service" " on ORBInitializer_Registry ...\n")); // Try to instantiate the dynamic service from the global repository ... TAO::ORBInitializer_Registry_Adapter* oir1 = ACE_Dynamic_Service::instance ("ORBInitializer_Registry"); // Right! It should not have been global. if (oir1 != 0) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("Unexpected to find ORBInitializer_Registry\n")), -1); ACE_DEBUG ((LM_DEBUG, "(%P|%t) try local dynamic service" " on ORBInitializer_Registry ...\n")); // Try to instantiate the dynamic service from the local repository ... TAO::ORBInitializer_Registry_Adapter* oir2 = ACE_Dynamic_Service::instance (one.get (), "ORBInitializer_Registry"); // Right! That's local. if (oir2 == 0) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("Expected to find ORBInitializer_Registry locally\n")), -1); ACE_DEBUG ((LM_DEBUG, "(%P|%t) Explicitely initialize ORBInitializer_Registry" " (although Dynamic_Service already did it) ...\n")); // ... initialize, but note that without the guard there is nothing to tell // the service which gestalt must be used. If init() does static service // registrations, those may end up in the wrong (global) gestalt and will // be in memory, which may not be mapped by finalization time! { ACE_Service_Config_Guard guard (one.get ()); oir2->init (0,0); } ACE_DEBUG ((LM_DEBUG, "(%P|%t) Try dynamic_service on a " "dependent static service (CodecFactory_Loader) ...\n")); // ... and also one of the dependent static services if (0 == ACE_Dynamic_Service ::instance (one.get (), "CodecFactory_Loader")) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("Error: Expected to find CodecFactory_Loader locally\n")), -1); ACE_DEBUG ((LM_DEBUG, "(%P|%t) Explicitely dynamic_service PolicyFactory_Loader" " (although ORBInitializer_Registry already did it) ...\n")); one->process_directive (ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE("PolicyFactory_Loader", "TAO_PI", TAO_VERSION, "_make_TAO_PolicyFactory_Loader", "")); if (0 == ACE_Dynamic_Service ::instance (one.get (), "PolicyFactory_Loader")) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("Error: Expected to find PolicyFactory_Loader locally\n")), -1); ACE_DEBUG ((LM_DEBUG, "(%P|%t) We're done testing.\n")); return 0; } // @brief ... int testServiceDependency (int , ACE_TCHAR *[]) { ACE_TRACE ("testServiceDependency"); ACE_DEBUG ((LM_DEBUG, "sizeof (ACE_DLL) == %d\n", sizeof (ACE_DLL))); ACE_DEBUG ((LM_DEBUG, "sizeof (ACE_Dynamic_Service_Dependency) == %d\n", sizeof (ACE_Dynamic_Service_Dependency))); TAO_Codeset_Manager *codeset_manager = 0; ACE_Dynamic_Service_Dependency *pdep = 0; { // Start a block to limit the lifespan of a gestalt ACE_Intrusive_Auto_Ptr one (new ACE_Service_Gestalt_Test (10)); int result = one->process_directive (ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE("TAO_Codeset", "TAO_Codeset", TAO_VERSION, "_make_TAO_Codeset_Manager_Factory", "")); if (result != 0) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("Expected to register TAO_Codeset successfuly\n")), -1); TAO_Codeset_Manager_Factory_Base *factory = ACE_Dynamic_Service::instance (one.get (), "TAO_Codeset"); if (factory == 0) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("Expected to obtain an instance successfuly\n")), -1); codeset_manager = factory->create (); if (codeset_manager == 0) ACE_DEBUG ((LM_DEBUG, "Creating dependency ...\n")); // [1] // // Stating that a thing depends on that dynamic service. Why? // Read on ... pdep = new ACE_Dynamic_Service_Dependency (one.get (), ACE_TEXT ("TAO_Codeset")); // This would ordinarily cause the dynamic services to get // unloaded and their DLL's unmapped ... } // ... therefore the following code would crash miserably because it // needs the ~TAO_Codeset_Manager()'s code, which is in the // (unlodaed) DLL's text segment ... delete codeset_manager; // ... unless of course we used the magic dependency statement, // above - [1] delete pdep; return 0; } int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { return testServiceDependency (argc, argv) && testOpenDynamicServices (argc, argv) && testORBInitializer_Registry(argc, argv); }