diff options
author | jeliazkov_i <jeliazkov_i@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2006-04-26 21:21:54 +0000 |
---|---|---|
committer | jeliazkov_i <jeliazkov_i@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2006-04-26 21:21:54 +0000 |
commit | b0cf9bd42665d557f4522c8fa45d5dca4d586442 (patch) | |
tree | a9b9968661496861e290f57b51d11264f75c299f | |
parent | d4a143a940ad9f1a81e1959e3fff7105509660ab (diff) | |
download | ATCD-b0cf9bd42665d557f4522c8fa45d5dca4d586442.tar.gz |
ChangeLogTag: Wed Apr 26 20:21:49 UTC 2006 Iliyan Jeliazkov <iliyan@ociweb.com>
104 files changed, 8104 insertions, 2540 deletions
diff --git a/ChangeLog b/ChangeLog index e70e1a75735..139a710e606 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,361 @@ +Wed Apr 26 20:21:49 UTC 2006 Iliyan Jeliazkov <iliyan@ociweb.com> + + The motivation for these changes was to enable support in ACE + for multiple instances of Service Configuration Repository, or + more appropriately - "Gestalt" (from the German word, meaning + something that's more than the sum of its parts). This is + feature is necessary to enable support for ORB-specific, or more + generally - service-specific sets of services, i.e. to be able + to have dynamicaly loaded services to use their own private set + of service objects. In the context of the implementation I will + use "gestalt" as a synonym for service configuration context or + service configuration repository. + + In order to accomplish this, the "instance"-related + functionality of the former ACE_Service_Config class has been + moved to another class - ACE_Service_Gestalt. The + ACE_Service_Config retains all static interfaces and those + members, pertaining to the concept of process-wide configuration + state. The service config, as known today has been retained as a + concept, but in its specialized semantics as holding a + process-wide configuration state. The primary concept expressing + an instance of configuration context is the gestalt. The + implementation actually uses a specialization of + ACE_Service_Gestalt in order to implement ACE_Service_Config as + a singleton, special case of configuration context. + + The static methods in ACE_Service_Config provide access to + process-wide gestalt (ubergestalt, anyone?) instance. + + For more details, here is the history of all included changes, + with their motivation and explanation. It is ordered + alphabetically, by the names of the changed files: + + * ace/ACE.cpp: + + Added to the condition evaluating ACE::debug() to include a + check if environmental variable ACE_DEBUG has been set. + + Updated the debug() function to call getenv() only once by using + a method-local static variable to hold the value from the + environment. + + * ace/DLL.h: + * ace/DLL.cpp: + + Implemented an operator=, needed in order to implement the + ACE_Service_Configuration_Guard class. + + * ace/DLL_Manager.cpp: + + Improved the error diagnostics so that a "file not found" would + not mask a "symbol not defined" error when loading a DLL. + + * ace/Dynamic_Service.h: + + "Privatized" copy ctor and operator= for ACE_Dynamic_Service + objects since it is not designed for such operations. + + * ace/Dynamic_Service.inl: + + Added overloaded method instance() for ACE_ANTI_TCHAR. + + * ace/Dynamic_Service.cpp: + + Changes to enable instantiation of a service, based on the + registration in a particular service repository. Adding a method + that takes ACE_Service_Gestalt* additional parameter. + + * ace/Dynamic_Service_Base.h: + * ace/Dynamic_Service_Base.cpp: + + Factored out a find_i() method to be used by the friend + ACE_Dynamic_Service_Dependency class. It implements the specific + lookup policy that extends the search to the global repository + if the named service object can not be found locally. + + Added instance method, allowing the caller to explicitly specify + the gestalt. + + * ace/Dynamic_Service_Dependency.h: + * ace/Dynamic_Service_Dependency.inl: + * ace/Dynamic_Service_Dependency.cpp: + + A newly introduced class, whose instances are designed to be + embedded inside instances of other classes, typically created by + DLL-based factories (service objects). This provides a way to + declare dependency on a specific service, thus avoiding order of + initialization issues with objects whose implementation code + resides in dynamically loaded services. + + It is disastrous to have dynamically loadable services create + and give away ownership of objects and then be unloaded before + all those instances have been deleted. Normally the code for + such objects classes resides within the TEXT segment of the DLL, + which implements the service. If a service gets removed, its DLL + may be unmapped from memory and then any attempt to invoke a + method on the said objects will cause SEGV. + + Such instances must contain a member of + ACE_Dynamic_Service_Dependency initialized with the service they + depend on. @code ACE_Dynamic_Service_Dependency's constructor + and destructor are "magical" - they work by maintaining the + underlying dynamic service's DLL reference count. + + The problem was not present before because the one Service + Repository outlived any other user objects. Now that an + un-loadable service can own its configuration, the sequence of + service finalization has been reversed. + + Updated the implementation of ACE_Dynamic_Service_Dependency + class to ease debugging. ACE_Dynamic_Service_Dependency gets + initialized whenever a dependent service gets loaded, to help us + keep our access to dependent instances after their DLL is gone + (by upping the ref count on the DLL). + + Updated usage of gestalt's instance() to current(). Removed + unnecessary comments. + + * ace/Global_Macros.h: + + Changed the ACE_STATIC_SVC_DEFINE to use the new + ACE_Service_Config::insert () method, which allows to streamline + the Service Configuration interface and promote hiding the + storage used for the static service descriptors. + + * ace/Parse_Node.h: + * ace/Parse_Node.cpp: + + Changes to aid in keeping track of the gestalt, while deep in + the guts of the svc.conf parser. + + Replaced the ACE_Service_Gestalt & in the method signatures with + ACE_Service_Gestalt * to unify the interfaces. + + Updated the static function node's logic to use only + ACE_Service_Gestalt public members and to no longer rely on + knowledge about the internal storage representation of service + repository. + + Removed a static_cast<> in ACE_Static_Function_Node::symbol() + that was causing problems on some platforms. It was not even + necessary as both sides were of the same type. + + * ace/Service_Config.{h,inl,cpp}: + + This separates the responsibilities between the service gestalt, + which represents an _instance_ of configuration information, and + the service config, which represents a special, process-wide, + global configuration repository. Since both these entities + represent the same concept - service configuration state, but + from different aspects, the ACE_Service_Config now inherits + (publicly) from ACE_Service_Gestalt. + + Lots of instance-related code moved to ACE_Service_Gestalt + Replaced the use of char with ACE_ANTI_TCHAR and the appropriate + ACE_TEXT_* macros. + + Moved the parsing of command-line options, pertaining to the + process as a whole, here - in the parse_args_i () (protected, + virtual). + + In order to resolve a problem caused by the inability of a + dependent static service to determine which gestalt they need to + register with, the concept of "current" was separated from the + "global" gestalt. The current gestalt is pointed to by a + pointer, stored in thread-specific storage (TSS) and manipulated + by the ACE_Service_Config_Guard class that implements the + "resource acquisition is initialization" idiom. + + Fixed an error in the separation of responsibilities between the + instance gestalt and the global (ubergestalt), during + initialization. The bug can cause infinite recursion, when + initializing an ORB, housed in a dynamic service. The singleton + gestalt (i.e. ACE_Service_Config) must be initialized through + open_i(), before open_i() can proceed initializing the specific + gestalt instance. The difficulty is in that some use cases + reverse the order of initialization by calling + ACE_Service_Config::open () first and then, at some point call + the instance gestalt open_i(). The solution is to use the + is_initialized_ member together with an explicit call to + ACE_Service_Config::global()->open_i(). To ease debugging of + the process of registering static service, I have changes the + ACE_Service_Config::static_svcs() to return + ACE_Service_Gestalt::instance (), instead. Thus all the + ACE_STATIC_SVC* macros are still working (no need to change + existing code), but now there is a convenient place to debug - + see the newly added ACE_Service_Gestalt::insert () method. The + header file no longer declares ACE_STATIC_SVCS, + ACE_STATIC_SVCS_ITERATOR, ACE_SVC_QUEUE and + ACE_SVC_QUEUE_ITERATOR. Those are now protected typedefs in + ACE_Service_Gestalt, where they are actually used. + + Added new insert () method to use instead of the sequence + static_svc ()->insert () which unnecessary exposes the internal + storage structure of Service Configurator. Made no_static_svcs_ + an instance member, instead of a class (static) member, thus + providing for ability to set it per instance, not globally. + + Added default values for open_i() and declared private copy ctor + and assignment operator for ACE_Service_Config_Guard, since it + is not intended to be copied. + + Similarly, moved the parts of the open_i() functionality that + did not belong in every instance of the gestalt. + ACE_Service_Config is again a process-wide Singleton,registered + with ACE_Object_Manager. + + Eliminated old #if 0-ed code in Service_Config.cpp. + + * ace/Service_Gestalt.h: + * ace/Service_Gestalt.inl: + * ace/Service_Gestalt.cpp: + + Encapsulates the idea of Service Configuration repository, or + configuration context. + + Changed open_i to be able to detect if it is working on the + special, process-wide instance (ubergestalt) or a "plain" + gestalt instance, since there are things that must only be done + once per process - like signal handler, logging key and + daemon-ization of the whole process. + + Added an ignore_static_svcs parameter to + ACE_Service_Gestalt::open_i in order to preserve the prior + behavior of the singleton ACE_Service_Gestalt instance. Even + though its no_static_svcs_ member was being initialized with 1, + some clients (TAO) needs to be able to override it. Since now a + call to open_i on an instance gestalt may precede in time the + call to open_i on the ubergestalt, we need a mechanism to allow + the no_static_svcs_ value to be overridden. + + Added the insert()'s implementation (described above). Added a + singleton() method to return the process-wide gestalt singleton + (or ubergestalt?:). Used in open_i() to account for the fact + that now a Service Gestalt may be called to open () prior to + open () on the singleton instance, which would typically contain + the bulk of the static service object descriptors. + + There was a problem with "hybrid" service objects, i.e. dynamic + SO which contains static SO (dependent services). The dependent + services are typically registered via static ctor or static + initializer at the point of loading of the dynamic SO's DLL. As + such, they end up registering before the dynamic SO. Upon + finalization of the service repository, the dynamic SO is + finalized first, thus unloading its DLL and unmapping the TEXT + segment, where the dependent static services code is. When + next, the static SO is to be finalized its memory is no longer + at valid address. The change ensures the dynamic service is + registered *before* its dependent static services and will + therefore be finalized last. The solution is based upon the + concept of forward declaring a dynamic service, named after the + configuration file being processed. Before processing a file, + we simply check for an existing service with the same name and + "pass" if we find one. + + Fixed the ACE_Service_Config_Guard's detection of the case where + the forward service declaration was not replaced by a proper + declaration as expected. It now properly removes the forward + decl, not the "good" instance. + + Cleared up the TSS management issue, causing executable to crash + on startup. The problem was due to an order-of-instantiation + issue, involving the TSS-based pointer to the current + gestalt. Used ACE_Object_Manager's shutting_down and starting_up + methods to determine if it is safe to use the static ACE_TSS + instance. + + Added const-ness for find(). Removed prototypes for initialize, + resume, suspend and remove that used plain char type and + conditionally compiled in only for WinCE and + ACE_USES_WCHAR. Service_Config still declares and defines these + (using ACE_ANTI_TCHAR). Updated to resolve problems when built + with ACE_USES_WCHAR. + + Declared private copy ctor and assignment operator for + ACE_Service_Gestalt and ACE_Service_Type_Factory, since their + instances are not intended to be copied. Added an + ACE_UNIMPLEMENTED_FUNC macro for the copy-ctor and assignment + operator of ACE_Service_Type_Factory. + + Reorganized to streamline the header file and remove unnecessary + declarations and to add a decl for find_static_svc_descriptor(). + + Changed the open() method's implementation to incorporate the + additional parameter for open_i(). + + Added the new find_static_svc_descriptor() member, which allows + ACE_Static_Function_Node to not need to know how the static + services are registered in the service repository. + + * ace/Service_Object.h: + * ace/Service_Object.inl: + * ace/Service_Object.cpp: + + Exposed the dll_ member through dll () const method because the + reference is needed by the new ACE_Dynamic_Service_Dependency + class. Fixed the dump () method. + + * ace/Service_Repository.h: + * ace/Service_Repository.cpp: + + Added const-ness for the find* () methods. Added debugging. The + remove method changes the order of services registrations in the + repository, which may break the Service Repository's invariant, + imposed by the need to correctly finalize dynamic services with + their own static services. + + For example, consider a case where a static service (S0) is + registered in the repository. Then a DLL-based service (D1) + registers its own static service (S1). So far the order is + "finalization-compatible": S0 < D1 < S1, i.e. services will be + finalized in reverse order and D1's DLL will still be available + when finalizing S1. Now let's remove (S0). Currently, after + this operation the repository end up in this order: S1 < D1, + which is trivially not finalization-compatible. + + Instead of replacing the pointer with the last ptr to a svc in + the array (repository) and then decrementing the current size of + the repo, the solution actually shifts left the rest of the + array. + + * ace/Service_Types.cpp: + * ace/Shared_Object.cpp: + + Removed some and updated existing debug statements. Eliminated + dead partial instantiation code. + + * ace/Svc_Conf.y: + * ace/Svc_Conf.h: + * ace/Svc_Conf_Tokens.h: + * ace/Svc_Conf_y.cpp: + + Changed to allow propagation of the knowledge about which + gestalt is currently being used for service registrations. + + Factored the ACE_Svc_Conf_Param class out in its own translation + unit. + + * ace/Svc_Conf_Param.h: + + Replaced the ACE_Service_Gestalt & in the method signatures with + ACE_Service_Gestalt * + + * ace/svcconf.mpb: + + Updated the svcconf.mpb rule to allow building with Bison 2.0 + and up. The change adds #ifdef/#endif around the generated + header file. A YYSTYPE_IS_DECLARED define is added in order to + make sure the token declarations from the Svc_Conf_Tokens.h are + used instead of those generated in the Svc_Conf_y.cpp file. + + Added the new Dynamic_Service_Dependency.* files. + + * bin/tao_orb_tests.lst: + + Adding the new tests to the automated test suite to run during + the nightly builds. + Wed Apr 26 17:13:57 UTC 2006 Phil Mesnier <mesnier_p@ociweb.com> * bin/tao_orb_tests.lst: diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 94594c03037..236fa0ba947 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,246 @@ +Wed Apr 26 20:21:49 UTC 2006 Iliyan Jeliazkov <iliyan@ociweb.com> + + The motivation for these changes was to enable support for + ORB-local Service Objects. This for instance, makes it possible + for differently configured ORBs to coexist within the same + proces. + + In order to accomplish this, each orb (core) owns a "Gestalt", + i.e. a service object repository instance. There is also a + process-wide, or "global" gestalt, which is the default + repository where service objects are registered. The latter + retains the interface and behavioral compatibility with any + existing code. As a consequence of this design choice, any + un-named orb(s) will default to using the ubergestalt, which is + consistent with the prior behavior. + + * NEWS + + Added an entry to the NEWS file. + + * tao/DLL_Parser.cpp: + + Fixed the parse_string() method to use the correct ORB gestalt + when looking up a dynamic service object. That resolves a + failure in TAO/tests/Object_Loader test. + + * tao/ORB.cpp: + + Relocated some aging comments about having first to instantiate + the singleton manager to the correct place (ORB_init). Added a + gestalt parameter to the call to open_services. Edited a few + lines to fit within the standard length requirement. + + * tao/ORB_Core.h: + * tao/ORB_Core.i: + * tao/ORB_Core.cpp: + + Added a member and an accessors for the private service gestalt, + owned by the core. Replaced the call to methods that use the + implicit ubergestalt with ones that specify the gestalt to use + for service objects. + + Added an ACE_Service_Config_Guard to make sure the ORB + initialization uses the correct repository. + + Updated more references to process_directive() and instance() to + use ACE_TCHAR. Updated references to process_directive() to use + ACE_TCHAR for consistency. + + Added #if !defined(TAO_AS_STATIC_LIBS)/#endif around code, which + is only meaningful when TAO is _not_ statically compiled; + Updated the service and DLL symbol names used to load the + CodecFactory_Loader, PolicyFactory_Loader and + TypeCodeFactory_Loader dynamic services, in the cases where + those services are not statically linked and TAO supports + dynamic linking. (Thanks Ossama, for pointing that out.) Added + code to try and explicitly load an IORInterceptor adapter and + Concrete_IORInterceptor_Adapter_Factory, if TAO supports (is + built with) dynamic linking; + + Updated the code that loads the IORTable adapter to be exception + safe; Edited a few lines to fit within the standard length + requirement. + + * tao/Parser_Registry.cpp: + + Updated to explicitly specify the correct gestalt for the ORB. + + * tao/TAO_Internal.h: + * tao/TAO_Internal.cpp: + + Refactored the initialization code to separate process-wide + aspects of initialization from those having to do with the ORB + instance. It is necessary to deal with global initialization + because of the large number of use cases, where the first thing + a process does is to call ORB_init, and consequently - + open_services. There are also cases where a process calls + Service_Config::open, initializing the process-wide + configuration and only then proceeds to call ORB_init - for + example when using Service Configurator to load a DLL that uses + an ORB. The close_service is now only responsible for calling + close in the ORB's own gestalt, the ACE Object Manager is the + one that is clobering the process-wide Service Configuration. + Updated to explicitly specify the correct gestalt to be used. + + * tao/default_resource.h: + * tao/default_resource.cpp: + + Added the ACE_Dynamic_Service_Dependency member to the default + resource factory to expressly maintain the factory's dependance + on TAO_Codeset library, because the order of destruction may be + reversed in some cases. The member help us keep our access to + TAO_Codeset_Manager instances by upping the ref count on + TAO_Codeset's DLL. This is far from elegant, but a complete + reference counting scheme for the ORB services is a more complex + undertaking than what the available resources currently permit. + + * tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp: + + Fixed an (unrelated) issue arising from a call to strcmp() with + two different character types - only visible when ACE_USES_WCHAR + is in effect. + + * tao/Codeset/Codeset_Manager_i.h: + * tao/Codeset/Codeset_Manager_i.cpp: + + (minor) Added void as argument to the ctor and dtor. + + * tao/PI/ORBInitializer_Registry_Impl.h: + * tao/PI/ORBInitializer_Registry_Impl.cpp: + + Implemented an init() method, which registers all the static + services, usually taken for granted with the loading of + TAO_PI. Previously, static initializers were used, however the + dependent static services were being registered only globally, + which broke the ORBs that needed ORB-local services. + + * tao/PI/PI.h: + * tao/PI/PI.cpp: + * tao/PI/PolicyFactory_Loader.h: + * tao/PI/PolicyFactory_Loader.cpp: + + Removed the static initializers code and made it part of the + dynamic service's init method. See the comment above. + + * tao/PortableServer/Root_POA.cpp: + + Explicitly specified the gestalt to be used for registering + dynamic services. + + * tests/DLL_ORB/Test_Client_Module.cpp: + * tests/DLL_ORB/Test_Server_Module.cpp: + + Provided an ID for the client and server's ORB. In the future, + an option may be devised so that the user can specify if they + want any ORB to use its own gestalt, even if it does not have an + ID. The reverse would be to force all ORBs to use the global SR, + even if they have an ID. Fixed a a SEGV upon process + termination. The first thing a client process does in its main() + is to load a dynamic service - Test_Client_Module, using a call + to ACE_Service_Config::process_directive(). The service does + call ORB_init(), which causes the population of the SR with a + number of static and dynamic SOs. At process termination now + however, any services registered following the ORB_init () call + are destroyed first and will be unavailable when the + Test_Client_Module is finalized. Like the Resource Factory, for + example. + + The solution is to provide and ORB id for any ORB, which will + loaded as part of a dynamic service. Since the service gestalt + is tied to the ORB id, this will cause the new ORBs to create + and manage the lifetime of their own Service Repositories. The + ORB_init() will be invoked in the context of each distinct SR + and any SO an ORB needs will go there. At process termination, + the Test_Client_Module will be finalized, which will clobber the + ORB's SR and any SO registered there. + + * tests/ORB_Local_Config/ORB_Local_Config.mwc: + * tests/ORB_Local_Config/README: + * tests/ORB_Local_Config/run_tests_all.pl: + + Added tests and examples of the functionality affected by the + introduction of the multiple private (per-ORB) service + configuration repositories. + + * tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.h: + * tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.cpp: + * tests/ORB_Local_Config/lib/lib.mpc: + + Common test code. + + * tests/ORB_Local_Config/Bunch/Bunch.mpc: + * tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf: + * tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf.xml: + * tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf: + * tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf.xml: + * tests/ORB_Local_Config/Bunch/Service_Config_Test.conf: + * tests/ORB_Local_Config/Bunch/Service_Config_Test.conf.xml: + * tests/ORB_Local_Config/Bunch/Test.cpp: + * tests/ORB_Local_Config/Bunch/run_test.pl: + + A collection of miscellaneous tests for compatibility of the new + interfaces with the old; Processing of the command-line + directives; Loading dynamic services in a local repository; + Loading the ORBInitializer_Registry locally; Test the helper + components used to implement the temporary substitution of the + repository currently used as "global" for the sake of + registering static services, which are dependent on a dynamic + service; + + * tests/ORB_Local_Config/Limits/Limits.mpc: + * tests/ORB_Local_Config/Limits/Test.cpp: + * tests/ORB_Local_Config/Limits/run_test.pl: + + Testing the size limits of a gestalt. + + * tests/ORB_Local_Config/Separation/Separation.mpc: + * tests/ORB_Local_Config/Separation/Test.cpp: + * tests/ORB_Local_Config/Separation/run_test.pl: + + Services registered with separate repositories must remain + separate and inaccessible through anyone but the gestalt they + were registered with. + + * tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.h: + * tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.cpp: + * tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL_Export.h: + * tests/ORB_Local_Config/Service_Dependency/Service_Dependency.mpc: + * tests/ORB_Local_Config/Service_Dependency/Test.cpp: + * tests/ORB_Local_Config/Service_Dependency/run_test.pl: + + Tests the working of the ACE_Dynamic_Service_Dependency class + + * tests/ORB_Local_Config/Shared/Shared.mpc: + * tests/ORB_Local_Config/Shared/Test.cpp: + * tests/ORB_Local_Config/Shared/run_test.pl: + + Test that the default repository is available through any + Service Gestalt, created with its default ctor. + + * tests/ORB_Local_Config/Simple/Simple.mpc: + * tests/ORB_Local_Config/Simple/Test.cpp: + * tests/ORB_Local_Config/Simple/run_test.pl: + + * tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.h: + * tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.cpp: + * tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL_Export.h: + * tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test.conf: + * tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test2.conf: + * tests/ORB_Local_Config/Two_DLL_ORB/Test.idl: + * tests/ORB_Local_Config/Two_DLL_ORB/Test.cpp: + * tests/ORB_Local_Config/Two_DLL_ORB/Test_i.h: + * tests/ORB_Local_Config/Two_DLL_ORB/Test_i.cpp: + * tests/ORB_Local_Config/Two_DLL_ORB/Two_DLL_ORB.mpc: + * tests/ORB_Local_Config/Two_DLL_ORB/client.cpp: + * tests/ORB_Local_Config/Two_DLL_ORB/run_test.pl: + * tests/ORB_Local_Config/Two_DLL_ORB/server.cpp: + + Testing the loading a dynamic service, which initializes its own + ORB. The test is a variant of the Hello test with the twist that + both the client and the server are service objects, loaded by + the Service Configuration mechanism. + Wed Apr 26 20:09:33 UTC 2006 Phil Mesnier <mesnier_p@ociweb.com> * tao/EndpointPolicy/EndpointPolicyC.h: diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp index 71aa9aa9b8c..9e87aaf73e6 100644 --- a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp @@ -86,7 +86,7 @@ TAO::CSD::TP_Strategy_Factory::init (int argc, arg_remainder.substr (pos + 1, arg.length () - pos); // Case-insensitive string comparison. - if (ACE_OS::strcasecmp (off_str.c_str(), + if (ACE_OS::strcasecmp (ACE_TEXT_CHAR_TO_TCHAR (off_str.c_str()), ACE_TEXT("OFF")) == 0) { serialize_servants = false; diff --git a/TAO/tao/Codeset/Codeset_Manager_i.cpp b/TAO/tao/Codeset/Codeset_Manager_i.cpp index 25f8d360848..98664b6f60e 100644 --- a/TAO/tao/Codeset/Codeset_Manager_i.cpp +++ b/TAO/tao/Codeset/Codeset_Manager_i.cpp @@ -62,7 +62,7 @@ TAO_Codeset_Manager_i::default_char_codeset = TAO_DEFAULT_CHAR_CODESET_ID; CONV_FRAME::CodeSetId TAO_Codeset_Manager_i::default_wchar_codeset = TAO_DEFAULT_WCHAR_CODESET_ID; -TAO_Codeset_Manager_i::TAO_Codeset_Manager_i () +TAO_Codeset_Manager_i::TAO_Codeset_Manager_i (void) : codeset_info_ (), char_descriptor_ (), wchar_descriptor_ () @@ -72,9 +72,10 @@ TAO_Codeset_Manager_i::TAO_Codeset_Manager_i () wchar_descriptor_.ncs(TAO_Codeset_Manager_i::default_wchar_codeset); wchar_descriptor_.add_translator (ACE_TEXT ("UTF16_BOM_Factory")); + } -TAO_Codeset_Manager_i::~TAO_Codeset_Manager_i () +TAO_Codeset_Manager_i::~TAO_Codeset_Manager_i (void) { } diff --git a/TAO/tao/Codeset/Codeset_Manager_i.h b/TAO/tao/Codeset/Codeset_Manager_i.h index f5ca8491ca3..a9167804b1c 100644 --- a/TAO/tao/Codeset/Codeset_Manager_i.h +++ b/TAO/tao/Codeset/Codeset_Manager_i.h @@ -19,15 +19,15 @@ #include "tao/CONV_FRAMEC.h" #include "tao/Codeset_Manager.h" +#include "tao/Codeset/codeset_export.h" +#include "tao/Codeset/Codeset_Descriptor.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Unbounded_Set.h" -#include "tao/Codeset/codeset_export.h" -#include "tao/Codeset/Codeset_Descriptor.h" - +#include "ace/Dynamic_Service_Dependency.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL @@ -70,8 +70,8 @@ public: /// to provide a non-compliant default wchar codeset may do so. static CONV_FRAME::CodeSetId default_wchar_codeset; - TAO_Codeset_Manager_i (); - ~TAO_Codeset_Manager_i (); + TAO_Codeset_Manager_i (void); + ~TAO_Codeset_Manager_i (void); /// Called by an object of TAO_Acceptor to set NCS and CCS values /// for Char/Wchar in to the Object Reference. diff --git a/TAO/tao/DLL_Parser.cpp b/TAO/tao/DLL_Parser.cpp index 753ae4496d7..87fb45d897f 100644 --- a/TAO/tao/DLL_Parser.cpp +++ b/TAO/tao/DLL_Parser.cpp @@ -6,6 +6,7 @@ #include "tao/Environment.h" #include "tao/ORB_Constants.h" #include "tao/SystemException.h" +#include "tao/ORB_Core.h" #include "ace/Dynamic_Service.h" #include "ace/Log_Msg.h" @@ -44,8 +45,11 @@ TAO_DLL_Parser::parse_string (const char *ior, const char *name = ior + sizeof (::dll_prefix) - 1; + TAO_ORB_Core *oc = orb->orb_core (); + TAO_Object_Loader *loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance (name); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (oc->configuration(), name); if (loader == 0) { diff --git a/TAO/tao/ORB.cpp b/TAO/tao/ORB.cpp index 85b04ebe58c..e25baaaa44a 100644 --- a/TAO/tao/ORB.cpp +++ b/TAO/tao/ORB.cpp @@ -36,6 +36,7 @@ ACE_RCSID (tao, #endif /* ! __ACE_INLINE__ */ #include "ace/Dynamic_Service.h" +#include "ace/Service_Config.h" #include "ace/Arg_Shifter.h" #include "ace/Reactor.h" #include "ace/Argv_Type_Converter.h" @@ -188,7 +189,7 @@ CORBA::ORB::destroy (ACE_ENV_SINGLE_ARG_DECL) if (TAO_debug_level > 2) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("CORBA::ORB::destroy() has been called on ORB <%s>.\n"), + ACE_TEXT ("CORBA::ORB::destroy() called on ORB <%s>.\n"), ACE_TEXT_CHAR_TO_TCHAR (this->orb_core ()->orbid ()))); } @@ -1074,7 +1075,8 @@ CORBA::ORB::resolve_initial_references (const char *name, } else if (ACE_OS::strcmp (name, TAO_OBJID_POACURRENT) == 0) { - result = this->orb_core ()->resolve_poa_current (ACE_ENV_SINGLE_ARG_PARAMETER); + result = this->orb_core ()->resolve_poa_current + (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (CORBA::Object::_nil ()); } else if (ACE_OS::strcmp (name, TAO_OBJID_POLICYMANAGER) == 0) @@ -1087,33 +1089,39 @@ CORBA::ORB::resolve_initial_references (const char *name, } else if (ACE_OS::strcmp (name, TAO_OBJID_IORMANIPULATION) == 0) { - result = this->orb_core ()->resolve_ior_manipulation (ACE_ENV_SINGLE_ARG_PARAMETER); + result = this->orb_core ()->resolve_ior_manipulation + (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (CORBA::Object::_nil ()); } else if (ACE_OS::strcmp (name, TAO_OBJID_IORTABLE) == 0) { - result = this->orb_core ()->resolve_ior_table (ACE_ENV_SINGLE_ARG_PARAMETER); + result = this->orb_core ()->resolve_ior_table + (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (CORBA::Object::_nil ()); } else if (ACE_OS::strcmp (name, TAO_OBJID_DYNANYFACTORY) == 0) { - result = this->orb_core ()->resolve_dynanyfactory (ACE_ENV_SINGLE_ARG_PARAMETER); + result = this->orb_core ()->resolve_dynanyfactory + (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (CORBA::Object::_nil ()); } else if (ACE_OS::strcmp (name, TAO_OBJID_TYPECODEFACTORY) == 0) { - result = this->orb_core ()->resolve_typecodefactory (ACE_ENV_SINGLE_ARG_PARAMETER); + result = this->orb_core ()->resolve_typecodefactory + (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (CORBA::Object::_nil ()); } else if (ACE_OS::strcmp (name, TAO_OBJID_CODECFACTORY) == 0) { - result = this->orb_core ()->resolve_codecfactory (ACE_ENV_SINGLE_ARG_PARAMETER); + result = this->orb_core ()->resolve_codecfactory + (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (CORBA::Object::_nil ()); } #if TAO_HAS_INTERCEPTORS == 1 else if (ACE_OS::strcmp (name, TAO_OBJID_PICurrent) == 0) { - result = this->orb_core ()->resolve_picurrent (ACE_ENV_SINGLE_ARG_PARAMETER); + result = this->orb_core ()->resolve_picurrent + (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (CORBA::Object::_nil ()); } #endif @@ -1151,7 +1159,7 @@ CORBA::ORB::resolve_initial_references (const char *name, // Look for an environment variable called "<name>IOR". // CORBA::String_var ior_env_var_name = - CORBA::string_alloc (static_cast <CORBA::ULong> (ACE_OS::strlen (name) + 3)); + CORBA::string_alloc (static_cast<CORBA::ULong> (ACE_OS::strlen (name) + 3)); ACE_OS::strcpy (ior_env_var_name.inout (), name); @@ -1327,15 +1335,6 @@ CORBA::ORB_init (int &argc, char *argv[], const char *orb_name) { - // Make sure TAO's singleton manager is initialized. - // - // We need to initialize before TAO_default_environment() is called - // since that call instantiates a TAO_TSS_Singleton. - if (TAO_Singleton_Manager::instance ()->init () == -1) - { - return CORBA::ORB::_nil (); - } - return CORBA::ORB_init (argc, argv, orb_name, @@ -1366,6 +1365,8 @@ CORBA::ORB_init (int &argc, CORBA::ORB::_nil ())); // Make sure TAO's singleton manager is initialized. + // We need to initialize before TAO_default_environment() is called + // since that call instantiates a TAO_TSS_Singleton. if (TAO_Singleton_Manager::instance ()->init () == -1) { return CORBA::ORB::_nil (); @@ -1401,6 +1402,8 @@ CORBA::ORB_init (int &argc, CORBA::ORB::_nil ()); } + + if (orbid_string.length () == 0) { ACE_Arg_Shifter arg_shifter (command_line.get_argc (), @@ -1469,10 +1472,33 @@ CORBA::ORB_init (int &argc, oc.reset (tmp); } + + // Having the ORB's default static services be shared among all ORBs + // is tempting from the point of view of reducing the dynamic + // footprint. However, if the ORB in a DLL and the rest of that + // application most likely neither cares, nor wishes to know about + // them. Furthermore, if the ORB DLL gets unloaded, the static + // services it had registered globaly will no longer be accesible, + // which will have disastrous consequences at the process + // shutdown. Hence, the ACE_Service_Config_Guard ensures that for + // the current thread, any references to the global + // ACE_Service_Config will be forwarded to the ORB's. + + // Making sure the initialization process in the current thread uses + // the correct service repository (ours), instead of the global one. + ACE_Service_Config_Guard scg (oc->configuration ()); + + /* + * Currently I choose to make the ORB an owner of its configuration, + * which in general is not quite correct because it is very common ORBs to + * need to share the same configuration. + */ + // Initialize the Service Configurator. This must occur before the // ORBInitializer::pre_init() method is invoked on each registered // ORB initializer. - int result = TAO::ORB::open_services (command_line.get_argc (), + int result = TAO::ORB::open_services (oc->configuration (), + command_line.get_argc (), command_line.get_TCHAR_argv ()); // Check for errors returned from <TAO_Internal::open_services>. diff --git a/TAO/tao/ORB_Core.cpp b/TAO/tao/ORB_Core.cpp index 652495aaa26..d65b89e9814 100644 --- a/TAO/tao/ORB_Core.cpp +++ b/TAO/tao/ORB_Core.cpp @@ -99,7 +99,8 @@ TAO_ORB_Core_Static_Resources* TAO_ORB_Core_Static_Resources::instance_ = 0; // Force an instance to be created at module initialization time, // since we do not want to worry about double checked locking and // the race condition to initialize the lock. -TAO_ORB_Core_Static_Resources* TAO_ORB_Core_Static_Resources::initialization_reference_ = +TAO_ORB_Core_Static_Resources* +TAO_ORB_Core_Static_Resources::initialization_reference_ = TAO_ORB_Core_Static_Resources::instance (); TAO_ORB_Core_Static_Resources* @@ -126,7 +127,9 @@ TAO_ORB_Core_Static_Resources::TAO_ORB_Core_Static_Resources (void) timeout_hook_ (0), connection_timeout_hook_ (0), endpoint_selector_factory_name_ ("Default_Endpoint_Selector_Factory"), - thread_lane_resources_manager_factory_name_ ("Default_Thread_Lane_Resources_Manager_Factory"), + thread_lane_resources_manager_factory_name_ + ("Default_Thread_Lane_Resources_Manager_Factory"), + collocation_resolver_name_ ("Default_Collocation_Resolver"), stub_factory_name_ ("Default_Stub_Factory"), resource_factory_name_ ("Resource_Factory"), @@ -136,7 +139,12 @@ TAO_ORB_Core_Static_Resources::TAO_ORB_Core_Static_Resources (void) iorinterceptor_adapter_factory_name_ ("IORInterceptor_Adapter_Factory"), valuetype_adapter_factory_name_ ("valuetype_Adapter_Factory"), poa_factory_name_ ("TAO_Object_Adapter_Factory"), - poa_factory_directive_ (ACE_TEXT_ALWAYS_CHAR (ACE_DYNAMIC_SERVICE_DIRECTIVE("TAO_Object_Adapter_Factory", "TAO_PortableServer", "_make_TAO_Object_Adapter_Factory", ""))), + poa_factory_directive_ + (ACE_TEXT_ALWAYS_CHAR + (ACE_DYNAMIC_SERVICE_DIRECTIVE("TAO_Object_Adapter_Factory", + "TAO_PortableServer", + "_make_TAO_Object_Adapter_Factory", + ""))), alt_connection_timeout_hook_ (0) { } @@ -253,6 +261,17 @@ TAO_ORB_Core::TAO_ORB_Core (const char *orbid) // Initialize the default request dispatcher. ACE_NEW (this->request_dispatcher_, TAO_Request_Dispatcher); + + /* + * @TODO: Get rid of the "magic number" for the Service repository size. + * Can this be dynamic container instead? + */ + if (ACE_OS::strnlen (this->orbid_, 1) == 0) + // (re)use the default/global getsalt + ACE_NEW (this->config_, ACE_Service_Gestalt); + else + ACE_NEW (this->config_, + ACE_Service_Gestalt (ACE_Service_Gestalt::MAX_SERVICES / 4)); } TAO_ORB_Core::~TAO_ORB_Core (void) @@ -289,6 +308,9 @@ TAO_ORB_Core::~TAO_ORB_Core (void) orbinitializer_registry_ = 0; ::CORBA::release (this->orb_); + + delete this->config_; + this->config_ = 0; } int @@ -687,7 +709,8 @@ TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL) (ACE_TEXT("-ORBDefaultInitRef")))) { // Set the list of prefixes from -ORBDefaultInitRef. - this->orb_params ()->default_init_ref (ACE_TEXT_ALWAYS_CHAR(current_arg)); + this->orb_params ()->default_init_ref + (ACE_TEXT_ALWAYS_CHAR(current_arg)); arg_shifter.consume_arg (); } @@ -746,7 +769,8 @@ TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL) CORBA::COMPLETED_NO)); ACE_CHECK_RETURN (-1); - output_stream->open (ACE_TEXT_ALWAYS_CHAR (file_name), ios::out | ios::app); + output_stream->open (ACE_TEXT_ALWAYS_CHAR (file_name), + ios::out | ios::app); if (!output_stream->bad ()) { @@ -893,10 +917,11 @@ TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL) ACE_CString lane (ACE_TEXT_ALWAYS_CHAR (current_arg)); arg_shifter.consume_arg (); - if(arg_shifter.is_option_next ()) + if (arg_shifter.is_option_next ()) return -1; - ACE_CString endpoints (ACE_TEXT_ALWAYS_CHAR (arg_shifter.get_current ())); + ACE_CString endpoints (ACE_TEXT_ALWAYS_CHAR + (arg_shifter.get_current ())); arg_shifter.consume_arg (); this->set_endpoint_helper (lane, @@ -991,7 +1016,8 @@ TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL) ACE_DEBUG ((LM_ERROR, ACE_TEXT ("ERROR: Unknown \"-ORB\" option ") ACE_TEXT ("<%s>.\n"), - ((current_arg == 0) ? ACE_TEXT("<NULL>") : current_arg))); + ((current_arg == 0) ? ACE_TEXT("<NULL>") + : current_arg))); } ACE_THROW_RETURN (CORBA::BAD_PARAM ( @@ -1025,7 +1051,8 @@ TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL) if (TAO_debug_level > 0) { ACE_ERROR ((LM_ERROR, - ACE_TEXT ("ERROR: Environment variable TAO_ORBENDPOINT set to invalid value ") + ACE_TEXT ("ERROR: Environment variable ") + ACE_TEXT ("TAO_ORBENDPOINT set to invalid value ") ACE_TEXT ("<%s>.\n"), env_endpoint)); } @@ -1051,6 +1078,7 @@ TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL) (void) ACE_OS::signal (SIGPIPE, (ACE_SignalHandler) SIG_IGN); #endif /* SIGPIPE */ + // Calling the open method here so that the svc.conf file is // opened and TAO_default_resource_factory::init () is called by the // time this method is called. @@ -1230,9 +1258,13 @@ TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL) this->flushing_strategy_ = trf->create_flushing_strategy (); // Look in the service repository for an instance of the Protocol Hooks. + const ACE_CString &protocols_hooks_name = + TAO_ORB_Core_Static_Resources::instance ()->protocols_hooks_name_; + this->protocols_hooks_ = ACE_Dynamic_Service<TAO_Protocols_Hooks>::instance - (TAO_ORB_Core_Static_Resources::instance ()->protocols_hooks_name_.c_str()); + (this->configuration (), + ACE_TEXT_CHAR_TO_TCHAR (protocols_hooks_name.c_str())); // Must have valid protocol hooks. if (this->protocols_hooks_ == 0) @@ -1317,7 +1349,7 @@ TAO_ORB_Core::fini (void) if (this->thread_lane_resources_manager_ != 0) this->thread_lane_resources_manager_->finalize (); - (void) TAO::ORB::close_services (); + (void) TAO::ORB::close_services (this->configuration ()); // Destroy the object_key table this->object_key_table_.destroy (); @@ -1439,9 +1471,13 @@ TAO_ORB_Core::resource_factory (void) } // Look in the service repository for an instance. + ACE_CString &resource_factory_name = + TAO_ORB_Core_Static_Resources::instance ()->resource_factory_name_; + this->resource_factory_ = ACE_Dynamic_Service<TAO_Resource_Factory>::instance - (TAO_ORB_Core_Static_Resources::instance ()->resource_factory_name_.c_str()); + (this->configuration (), + ACE_TEXT_CHAR_TO_TCHAR (resource_factory_name.c_str())); return this->resource_factory_; } @@ -1461,9 +1497,13 @@ TAO_ORB_Core::thread_lane_resources_manager (void) return *this->thread_lane_resources_manager_; // If not, lookup the corresponding factory and ask it to make one. + const ACE_CString &thread_lane_resources_manager_factory_name = + TAO_ORB_Core_Static_Resources::instance ()->thread_lane_resources_manager_factory_name_; + TAO_Thread_Lane_Resources_Manager_Factory *factory = ACE_Dynamic_Service<TAO_Thread_Lane_Resources_Manager_Factory>::instance - (TAO_ORB_Core_Static_Resources::instance ()->thread_lane_resources_manager_factory_name_.c_str()); + (this->configuration (), + ACE_TEXT_CHAR_TO_TCHAR (thread_lane_resources_manager_factory_name.c_str())); this->thread_lane_resources_manager_ = factory->create_thread_lane_resources_manager (*this); @@ -1479,9 +1519,13 @@ TAO_ORB_Core::collocation_resolver (void) return *this->collocation_resolver_; // If not, lookup it up. + const ACE_CString &collocation_resolver_name = + TAO_ORB_Core_Static_Resources::instance ()->collocation_resolver_name_; + this->collocation_resolver_ = ACE_Dynamic_Service<TAO_Collocation_Resolver>::instance - (TAO_ORB_Core_Static_Resources::instance ()->collocation_resolver_name_.c_str()); + (this->configuration (), + ACE_TEXT_CHAR_TO_TCHAR (collocation_resolver_name.c_str())); return *this->collocation_resolver_; } @@ -1491,18 +1535,21 @@ TAO_ORB_Core::policy_factory_registry_i (void) { TAO_PolicyFactory_Registry_Factory *loader = - ACE_Dynamic_Service<TAO_PolicyFactory_Registry_Factory>::instance ( - "PolicyFactory_Loader"); + ACE_Dynamic_Service<TAO_PolicyFactory_Registry_Factory>::instance + (this->configuration (), + ACE_TEXT ("PolicyFactory_Loader")); + if (loader == 0) { - ACE_Service_Config::process_directive ( + this->configuration ()->process_directive ( ACE_DYNAMIC_SERVICE_DIRECTIVE("PolicyFactory_Loader", "TAO_PI", - "_make_PolicyFactory_Loader", + "_make_TAO_PolicyFactory_Loader", "")); loader = - ACE_Dynamic_Service<TAO_PolicyFactory_Registry_Factory>::instance ( - "PolicyFactory_Loader"); + ACE_Dynamic_Service<TAO_PolicyFactory_Registry_Factory>::instance + (this->configuration (), + ACE_TEXT ("PolicyFactory_Loader")); } if (loader != 0) @@ -1520,7 +1567,8 @@ TAO_ORB_Core::orbinitializer_registry_i (void) // If not, lookup it up. this->orbinitializer_registry_ = ACE_Dynamic_Service<TAO::ORBInitializer_Registry_Adapter>::instance - ("ORBInitializer_Registry"); + (this->configuration (), + ACE_TEXT ("ORBInitializer_Registry")); #if !defined (TAO_AS_STATIC_LIBS) // In case we build shared, try to load the PI Client library, in a @@ -1528,14 +1576,15 @@ TAO_ORB_Core::orbinitializer_registry_i (void) // output an error then. if (orbinitializer_registry_ == 0) { - ACE_Service_Config::process_directive ( + this->configuration ()->process_directive ( ACE_DYNAMIC_SERVICE_DIRECTIVE("ORBInitializer_Registry", "TAO_PI", "_make_ORBInitializer_Registry", "")); orbinitializer_registry_ = ACE_Dynamic_Service<TAO::ORBInitializer_Registry_Adapter>::instance - ("ORBInitializer_Registry"); + (this->configuration (), + ACE_TEXT ("ORBInitializer_Registry")); } #endif /* !TAO_AS_STATIC_LIBS */ @@ -1550,9 +1599,13 @@ TAO_ORB_Core::stub_factory (void) return this->stub_factory_; // If not, look in the service repository for an instance. + const ACE_CString &stub_factory_name = + TAO_ORB_Core_Static_Resources::instance ()->stub_factory_name_; + this->stub_factory_ = ACE_Dynamic_Service<TAO_Stub_Factory>::instance - (TAO_ORB_Core_Static_Resources::instance ()->stub_factory_name_.c_str()); + (this->configuration (), + ACE_TEXT_CHAR_TO_TCHAR (stub_factory_name.c_str())); return this->stub_factory_; } @@ -1588,9 +1641,13 @@ TAO_ORB_Core::endpoint_selector_factory (void) return this->endpoint_selector_factory_; // If not, look in the service repository for an instance. + const ACE_CString &endpoint_selector_factory_name = + TAO_ORB_Core_Static_Resources::instance ()->endpoint_selector_factory_name_; + this->endpoint_selector_factory_ = ACE_Dynamic_Service<TAO_Endpoint_Selector_Factory>::instance - (TAO_ORB_Core_Static_Resources::instance ()->endpoint_selector_factory_name_.c_str()); + (this->configuration (), + ACE_TEXT_CHAR_TO_TCHAR (endpoint_selector_factory_name.c_str())); return this->endpoint_selector_factory_; } @@ -1676,7 +1733,9 @@ TAO_ORB_Core::client_factory (void) { // Look in the service repository for an instance. this->client_factory_ = - ACE_Dynamic_Service<TAO_Client_Strategy_Factory>::instance ("Client_Strategy_Factory"); + ACE_Dynamic_Service<TAO_Client_Strategy_Factory>::instance + (this->configuration (), + ACE_TEXT ("Client_Strategy_Factory")); } return this->client_factory_; @@ -1689,7 +1748,9 @@ TAO_ORB_Core::server_factory (void) { // Look in the service repository for an instance. this->server_factory_ = - ACE_Dynamic_Service<TAO_Server_Strategy_Factory>::instance ("Server_Strategy_Factory"); + ACE_Dynamic_Service<TAO_Server_Strategy_Factory>::instance + (this->configuration (), + ACE_TEXT ("Server_Strategy_Factory")); } return this->server_factory_; @@ -1701,20 +1762,29 @@ TAO_ORB_Core::root_poa (ACE_ENV_SINGLE_ARG_DECL) // DCL .. if (CORBA::is_nil (this->root_poa_.in ())) { + + // Making sure the initialization process in the current thread uses + // the correct service repository (ours), instead of the global one. + ACE_Service_Config_Guard scg (this->configuration ()); + + TAO_ORB_Core_Static_Resources* static_resources = TAO_ORB_Core_Static_Resources::instance (); TAO_Adapter_Factory *factory = - ACE_Dynamic_Service<TAO_Adapter_Factory>::instance ( + ACE_Dynamic_Service<TAO_Adapter_Factory>::instance + (this->configuration (), static_resources->poa_factory_name_.c_str()); if (factory == 0) { - ACE_Service_Config::process_directive ( + this->configuration()->process_directive ( ACE_TEXT_CHAR_TO_TCHAR ( static_resources->poa_factory_directive_.c_str())); + factory = - ACE_Dynamic_Service<TAO_Adapter_Factory>::instance ( + ACE_Dynamic_Service<TAO_Adapter_Factory>::instance + (this->configuration (), static_resources->poa_factory_name_.c_str()); } @@ -1833,7 +1903,8 @@ TAO_ORB_Core::load_policy_validators (TAO_Policy_Validator &validator if (this->bidir_adapter_ == 0) { this->bidir_adapter_ = - ACE_Dynamic_Service<TAO_BiDir_Adapter>::instance ("BiDirGIOP_Loader"); + ACE_Dynamic_Service<TAO_BiDir_Adapter>::instance + (this->configuration (), ACE_TEXT ("BiDirGIOP_Loader")); } // Call the BiDir library if it has been loaded @@ -2017,6 +2088,8 @@ TAO_ORB_Core::run (ACE_Time_Value *tv, int perform_work ACE_ENV_ARG_DECL_NOT_USED) { + ACE_Service_Config_Guard guard (this->configuration()); + if (TAO_debug_level > 2) { ACE_DEBUG ((LM_DEBUG, @@ -2101,6 +2174,7 @@ TAO_ORB_Core::run (ACE_Time_Value *tv, // A timeout, terminate the loop... break; } + if (perform_work) { // This is running on behalf of a perform_work() call, @@ -2205,8 +2279,7 @@ TAO_ORB_Core::destroy (ACE_ENV_SINGLE_ARG_DECL) // // Shutdown the ORB and block until the shutdown is complete. - this->shutdown (1 - ACE_ENV_ARG_PARAMETER); + this->shutdown (1 ACE_ENV_ARG_PARAMETER); ACE_CHECK; // Invoke Interceptor::destroy() on all registered interceptors. @@ -2235,7 +2308,6 @@ TAO_ORB_Core::check_shutdown (ACE_ENV_SINGLE_ARG_DECL) void TAO_ORB_Core::destroy_interceptors (ACE_ENV_SINGLE_ARG_DECL) { - ACE_TRY { ACE_GUARD (TAO_SYNCH_MUTEX, monitor, this->lock_); @@ -2298,19 +2370,28 @@ void TAO_ORB_Core::resolve_typecodefactory_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Object_Loader *loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("TypeCodeFactory_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("TypeCodeFactory_Loader")); + +#if !defined(TAO_AS_STATIC_LIBS) if (loader == 0) { - ACE_Service_Config::process_directive ( - ACE_DYNAMIC_SERVICE_DIRECTIVE("TypeCodeFactory_Loader", + this->configuration ()->process_directive ( + ACE_DYNAMIC_SERVICE_DIRECTIVE("TypeCodeFactory", "TAO_TypeCodeFactory", "_make_TAO_TypeCodeFactory_Loader", "")); loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("TypeCodeFactory_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("TypeCodeFactory_Loader")); + if (loader == 0) ACE_THROW (CORBA::ORB::InvalidName ()); } +#endif /* !defined (TAO_AS_STATIC_LIBS) */ + this->typecode_factory_ = loader->create_object (this->orb_, 0, 0 ACE_ENV_ARG_PARAMETER); } @@ -2319,17 +2400,26 @@ void TAO_ORB_Core::resolve_codecfactory_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Object_Loader *loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("CodecFactory_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("CodecFactory_Loader")); + +#if !defined(TAO_AS_STATIC_LIBS) if (loader == 0) { - ACE_Service_Config::process_directive ( - ACE_DYNAMIC_SERVICE_DIRECTIVE("CodecFactory_Loader", + this->configuration()->process_directive ( + ACE_DYNAMIC_SERVICE_DIRECTIVE("CodecFactory", "TAO_CodecFactory", "_make_TAO_CodecFactory_Loader", "")); loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("CodecFactory_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("CodecFactory_Loader")); + } +#endif /* !defined (TAO_AS_STATIC_LIBS) */ + if (loader != 0) { this->codec_factory_ = @@ -2342,17 +2432,29 @@ void TAO_ORB_Core::resolve_poa_current_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Object_Loader *loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("TAO_POA_Current_Factory"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration(), + ACE_TEXT ("TAO_POA_Current_Factory")); + +#if !defined(TAO_AS_STATIC_LIBS) if (loader == 0) { - ACE_Service_Config::process_directive ( + this->configuration()->process_directive ( ACE_DYNAMIC_SERVICE_DIRECTIVE("TAO_POA_Current_Factory", "TAO_PortableServer", "_make_TAO_POA_Current_Factory", "")); loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("TAO_POA_Current_Factory"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration(), + ACE_TEXT ("TAO_POA_Current_Factory")); } + + if (loader == 0) + ACE_THROW (CORBA::ORB::InvalidName ()); + +#endif /* !defined (TAO_AS_STATIC_LIBS) */ + if (loader != 0) { this->poa_current_ = @@ -2367,17 +2469,24 @@ void TAO_ORB_Core::resolve_picurrent_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Object_Loader *loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("PICurrent_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("PICurrent_Loader")); + +#if !defined(TAO_AS_STATIC_LIBS) if (loader == 0) { - ACE_Service_Config::process_directive ( + this->configuration ()->process_directive ( ACE_DYNAMIC_SERVICE_DIRECTIVE("PICurrent_Loader", "TAO_PI", "_make_TAO_PICurrent_Loader", "")); loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("PICurrent_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("PICurrent_Loader")); } +#endif /* !defined (TAO_AS_STATIC_LIBS) */ if (loader != 0) { @@ -2396,17 +2505,24 @@ void TAO_ORB_Core::resolve_dynanyfactory_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Object_Loader *loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("DynamicAny_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("DynamicAny_Loader")); + +#if !defined(TAO_AS_STATIC_LIBS) if (loader == 0) { - ACE_Service_Config::process_directive ( + this->configuration ()->process_directive ( ACE_DYNAMIC_SERVICE_DIRECTIVE("DynamicAny_Loader", "TAO_DynamicAny", "_make_TAO_DynamicAny_Loader", "")); loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("DynamicAny_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("DynamicAny_Loader")); } +#endif /* !defined (TAO_AS_STATIC_LIBS) */ if (loader != 0) { @@ -2420,18 +2536,25 @@ void TAO_ORB_Core::resolve_iormanipulation_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Object_Loader *loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("IORManip_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("IORManip_Loader")); +#if !defined(TAO_AS_STATIC_LIBS) if (loader == 0) { - ACE_Service_Config::process_directive ( + this->configuration()->process_directive ( ACE_DYNAMIC_SERVICE_DIRECTIVE("IORManip_Loader", "TAO_IORManip", "_make_TAO_IORManip_Loader", "")); loader = - ACE_Dynamic_Service<TAO_Object_Loader>::instance ("IORManip_Loader"); + ACE_Dynamic_Service<TAO_Object_Loader>::instance + (this->configuration (), + ACE_TEXT ("IORManip_Loader")); } +#endif /* !defined (TAO_AS_STATIC_LIBS) */ + if (loader != 0) { this->ior_manip_factory_ = @@ -2444,29 +2567,39 @@ void TAO_ORB_Core::resolve_ior_table_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Adapter_Factory *factory = - ACE_Dynamic_Service<TAO_Adapter_Factory>::instance ("TAO_IORTable"); + ACE_Dynamic_Service<TAO_Adapter_Factory>::instance + (this->configuration (), + ACE_TEXT ("TAO_IORTable")); + +#if !defined(TAO_AS_STATIC_LIBS) if (factory == 0) { - ACE_Service_Config::process_directive ( + this->configuration ()->process_directive ( ACE_DYNAMIC_SERVICE_DIRECTIVE("TAO_IORTable", "TAO_IORTable", "_make_TAO_Table_Adapter_Factory", "")); factory = - ACE_Dynamic_Service<TAO_Adapter_Factory>::instance ("TAO_IORTable"); + ACE_Dynamic_Service<TAO_Adapter_Factory>::instance + (this->configuration (), + ACE_TEXT ("TAO_IORTable")); } +#endif /* !defined (TAO_AS_STATIC_LIBS) */ if (factory != 0) { - // @@ Not exception safe - TAO_Adapter *iortable_adapter = factory->create (this); - this->adapter_registry_.insert (iortable_adapter ACE_ENV_ARG_PARAMETER); + ACE_Auto_Ptr <TAO_Adapter> iortable_adapter (factory->create (this)); + iortable_adapter->open (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - iortable_adapter->open (ACE_ENV_SINGLE_ARG_PARAMETER); + CORBA::Object_var tmp_root = iortable_adapter->root (); + + this->adapter_registry_.insert (iortable_adapter.get () ACE_ENV_ARG_PARAMETER); ACE_CHECK; - this->ior_table_ = iortable_adapter->root (); + // It is now (exception) safe to release ownership from the auto pointers + this->ior_table_= tmp_root._retn (); + iortable_adapter.release (); } } @@ -2743,7 +2876,8 @@ TAO_ORB_Core::implrepo_service (void) ACE_TRY_NEW_ENV { - CORBA::Object_var temp = this->orb_->resolve_initial_references ("ImplRepoService" ACE_ENV_ARG_PARAMETER); + CORBA::Object_var temp = + this->orb_->resolve_initial_references ("ImplRepoService" ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, CORBA::Object::_nil ()); @@ -2753,7 +2887,8 @@ TAO_ORB_Core::implrepo_service (void) } ACE_CATCHANY { - // Just make sure that we have a null pointer. Ignore the exception anyway. + // Just make sure that we have a null pointer. Ignore the exception + // anyway. this->implrepo_service_ = CORBA::Object::_nil (); } ACE_ENDTRY; @@ -3087,16 +3222,38 @@ TAO_ORB_Core::ior_interceptor_adapter (void) ACE_TRY { TAO_IORInterceptor_Adapter_Factory * ior_ap_factory = - ACE_Dynamic_Service<TAO_IORInterceptor_Adapter_Factory>::instance ( - TAO_ORB_Core::iorinterceptor_adapter_factory_name () - ); + ACE_Dynamic_Service<TAO_IORInterceptor_Adapter_Factory>::instance + (this->configuration (), + ACE_TEXT_CHAR_TO_TCHAR (TAO_ORB_Core::iorinterceptor_adapter_factory_name ())); + +#if !defined (TAO_AS_STATIC_LIBS) + // In case we build shared, try to load the IOR_Interceptor factory. In a + // static build we just can't do this, so don't try it + if (ior_ap_factory == 0) + { + this->configuration()->process_directive + (ACE_DYNAMIC_SERVICE_DIRECTIVE("Concrete_IORInterceptor_Adapter_Factory", + "TAO_IORInterceptor", + "_make_TAO_IORInterceptor_Adapter_Factory_Impl", + "")); + ior_ap_factory = + ACE_Dynamic_Service<TAO_IORInterceptor_Adapter_Factory>::instance + (this->configuration (), ACE_TEXT("Concrete_IORInterceptor_Adapter_Factory")); + } +#endif /* !TAO_AS_STATIC_LIBS */ - if (ior_ap_factory) + if (ior_ap_factory == 0) { - this->ior_interceptor_adapter_ = - ior_ap_factory->create (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_TRY_CHECK; + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Unable to get a IORInterceptor factory\n")), + 0); + ACE_THROW (CORBA::INTERNAL ()); } + + this->ior_interceptor_adapter_ = + ior_ap_factory->create (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } ACE_CATCHANY { @@ -3130,7 +3287,8 @@ TAO_ORB_Core::add_interceptor ( ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("ERROR: ORB Core unable to find the ") - ACE_TEXT ("Client Request Interceptor Adapter Factory instance"))); + ACE_TEXT ("Client Request Interceptor Adapter Factory ") + ACE_TEXT ("instance"))); ACE_THROW (CORBA::INTERNAL ()); } @@ -3149,9 +3307,9 @@ TAO_ORB_Core::clientrequestinterceptor_adapter_i (void) if (this->client_request_interceptor_adapter_ == 0) { TAO_ClientRequestInterceptor_Adapter_Factory *factory = - ACE_Dynamic_Service<TAO_ClientRequestInterceptor_Adapter_Factory>::instance ( - "ClientRequestInterceptor_Adapter_Factory" - ); + ACE_Dynamic_Service<TAO_ClientRequestInterceptor_Adapter_Factory>::instance + (this->configuration (), + ACE_TEXT ("ClientRequestInterceptor_Adapter_Factory")); if (factory) { @@ -3180,7 +3338,8 @@ TAO_ORB_Core::add_interceptor ( ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("ERROR: ORB Core unable to find the ") - ACE_TEXT ("Server Request Interceptor Adapter Factory instance"))); + ACE_TEXT ("Server Request Interceptor Adapter Factory ") + ACE_TEXT ("instance"))); ACE_THROW (CORBA::INTERNAL ()); } @@ -3206,7 +3365,8 @@ TAO_ORB_Core::add_interceptor ( ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("ERROR: ORB Core unable to find the ") - ACE_TEXT ("Client Request Interceptor Adapter Factory instance"))); + ACE_TEXT ("Client Request Interceptor Adapter Factory ") + ACE_TEXT ("instance"))); ACE_THROW (CORBA::INTERNAL ()); } @@ -3232,7 +3392,8 @@ TAO_ORB_Core::add_interceptor ( ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("ERROR: ORB Core unable to find the ") - ACE_TEXT ("Server Request Interceptor Adapter Factory instance"))); + ACE_TEXT ("Server Request Interceptor Adapter Factory ") + ACE_TEXT ("instance"))); ACE_THROW (CORBA::INTERNAL ()); } @@ -3251,9 +3412,9 @@ TAO_ORB_Core::serverrequestinterceptor_adapter_i (void) if (this->server_request_interceptor_adapter_ == 0) { TAO_ServerRequestInterceptor_Adapter_Factory *factory = - ACE_Dynamic_Service<TAO_ServerRequestInterceptor_Adapter_Factory>::instance ( - "ServerRequestInterceptor_Adapter_Factory" - ); + ACE_Dynamic_Service<TAO_ServerRequestInterceptor_Adapter_Factory>::instance + (this->configuration (), + ACE_TEXT ("ServerRequestInterceptor_Adapter_Factory")); if (factory) { @@ -3263,6 +3424,11 @@ TAO_ORB_Core::serverrequestinterceptor_adapter_i (void) } } + if (TAO_debug_level > 2) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Server request interceptor adapter list at %@\n"), + this->server_request_interceptor_adapter_)); + return this->server_request_interceptor_adapter_; } diff --git a/TAO/tao/ORB_Core.h b/TAO/tao/ORB_Core.h index 5b2a3b7a1ae..b9a0581bf39 100644 --- a/TAO/tao/ORB_Core.h +++ b/TAO/tao/ORB_Core.h @@ -316,7 +316,7 @@ public: * Sets the value of gui_resource_factory in TSS. ORB_Core is responsible * for releasing this factory if needed. */ - static void set_gui_resource_factory (TAO::GUIResource_Factory *gui_resource_factory); + static void set_gui_resource_factory (TAO::GUIResource_Factory *gui_factory); /// Sets the value of TAO_ORB_Core::protocols_hooks_ static void set_protocols_hooks (const char *protocols_hooks_name); @@ -917,6 +917,9 @@ public: (const CORBA::Object_ptr obj, const TAO_Service_Context &service_context); + /// Configuration accessor method + ACE_Service_Gestalt* configuration () const; + /// Get outgoing fragmentation strategy. auto_ptr<TAO_GIOP_Fragmentation_Strategy> fragmentation_strategy (TAO_Transport * transport); @@ -1259,6 +1262,8 @@ protected: /// Code Set Manager - points to service object in the service repo TAO_Codeset_Manager *codeset_manager_; + /// ORB's service configuration + ACE_Service_Gestalt *config_; }; // **************************************************************** diff --git a/TAO/tao/ORB_Core.i b/TAO/tao/ORB_Core.i index b78066a39eb..3f5f53cd423 100644 --- a/TAO/tao/ORB_Core.i +++ b/TAO/tao/ORB_Core.i @@ -7,6 +7,12 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL +ACE_INLINE ACE_Service_Gestalt* +TAO_ORB_Core::configuration (void) const +{ + return this->config_; +} + ACE_INLINE CORBA::ULong TAO_ORB_Core::_incr_refcnt (void) { @@ -250,23 +256,6 @@ TAO_ORB_Core::orb_params(void) return &(this->orb_params_); } -ACE_INLINE TAO_Codeset_Manager * -TAO_ORB_Core::codeset_manager() -{ - if (this->orb_params()->negotiate_codesets() == 0) - return 0; - if (this->codeset_manager_ == 0) - { - // This causes a factory to be loaded which will call - // the codeset_manager setter in this thread. - this->codeset_manager_ = - this->resource_factory()->codeset_manager(); - if (this->codeset_manager_ == 0) - this->orb_params()->negotiate_codesets(false); - } - return this->codeset_manager_; -} - #define TAO_OC_RETRIEVE(member) \ ((this->member##_ == 0) \ ? (this->member##_ = this->resource_factory ()->get_##member ()) \ @@ -447,6 +436,23 @@ TAO_ORB_Core::server_id (void) const return this->server_id_.c_str(); } +ACE_INLINE TAO_Codeset_Manager * +TAO_ORB_Core::codeset_manager() +{ + if (this->orb_params()->negotiate_codesets() == 0) + return 0; + if (this->codeset_manager_ == 0) + { + // This causes a factory to be loaded which will call + // the codeset_manager setter in this thread. + this->codeset_manager_ = + this->resource_factory()->codeset_manager(); + if (this->codeset_manager_ == 0) + this->orb_params()->negotiate_codesets(false); + } + return this->codeset_manager_; +} + ACE_INLINE TAO::ORBInitializer_Registry_Adapter * TAO_ORB_Core::orbinitializer_registry () { diff --git a/TAO/tao/PI/ORBInitializer_Registry_Impl.cpp b/TAO/tao/PI/ORBInitializer_Registry_Impl.cpp index 919abb2706e..57834a96e38 100644 --- a/TAO/tao/PI/ORBInitializer_Registry_Impl.cpp +++ b/TAO/tao/PI/ORBInitializer_Registry_Impl.cpp @@ -1,6 +1,7 @@ #include "tao/PI/ORBInitializer_Registry_Impl.h" #include "tao/PI/ORBInitInfo.h" #include "tao/PI/PICurrent.h" +#include "tao/PI/PI_ORBInitializer.h" #include "tao/ORB_Core.h" #include "tao/ORB_Constants.h" @@ -10,6 +11,10 @@ #include "ace/Recursive_Thread_Mutex.h" #include "ace/Log_Msg.h" +#include "tao/PI/ClientRequestInterceptor_Factory_Impl.h" +#include "tao/PI/PICurrent_Loader.h" +#include "tao/PI/PolicyFactory_Loader.h" + ACE_RCSID (PI, ORBInitializer_Registry, "$Id$") @@ -24,6 +29,66 @@ TAO::ORBInitializer_Registry::ORBInitializer_Registry (void) } int +TAO::ORBInitializer_Registry::init (int, ACE_TCHAR *[]) +{ + ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, + guard, + this->lock_, + -1); + +#if TAO_HAS_INTERCEPTORS == 1 + + ACE_Service_Config::process_directive + (ace_svc_desc_TAO_PolicyFactory_Loader); + + ACE_Service_Config::process_directive + (ace_svc_desc_TAO_ClientRequestInterceptor_Adapter_Factory_Impl); + + ACE_Service_Config::process_directive + (ace_svc_desc_TAO_PICurrent_Loader); + + PortableInterceptor::ORBInitializer_ptr temp_orb_initializer = + PortableInterceptor::ORBInitializer::_nil (); + + PortableInterceptor::ORBInitializer_var orb_initializer; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + /// Register the PI ORBInitializer. + + ACE_NEW_THROW_EX (temp_orb_initializer, + TAO_PI_ORBInitializer, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_TRY_CHECK; + + orb_initializer = temp_orb_initializer; + + this->register_orb_initializer (orb_initializer.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + if (TAO_debug_level > 0) + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "(%P | %t) Caught exception:"); + } + return -1; + } + ACE_ENDTRY; +#endif /* TAO_HAS_INTERCEPTORS == 1 */ + + return 0; +} + + +int TAO::ORBInitializer_Registry::fini (void) { ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, diff --git a/TAO/tao/PI/ORBInitializer_Registry_Impl.h b/TAO/tao/PI/ORBInitializer_Registry_Impl.h index edb5a2bfc26..1e4788a2602 100644 --- a/TAO/tao/PI/ORBInitializer_Registry_Impl.h +++ b/TAO/tao/PI/ORBInitializer_Registry_Impl.h @@ -76,6 +76,17 @@ namespace TAO PortableInterceptor::SlotId slotid ACE_ENV_ARG_DECL); + protected: + + // Added to provide registration for the several static service objects, + // brought in with this ORBInitializer_Registry implementation. Note that + // this is more reliable than using static initializers, since multiple + // copies of the dynamic service object will require their own (multiple) + // copies of the dependent static service objects. That is just impossible + // without registering those static services in the same repo, the dynamic + // SO is registered with. + virtual int init (int, ACE_TCHAR *[]); + private: // Prevent copying ORBInitializer_Registry (const ORBInitializer_Registry &); diff --git a/TAO/tao/PI/PI.cpp b/TAO/tao/PI/PI.cpp index 3e18928cf8c..ebec2effb3f 100644 --- a/TAO/tao/PI/PI.cpp +++ b/TAO/tao/PI/PI.cpp @@ -1,11 +1,4 @@ #include "tao/PI/PI.h" -#include "tao/PI/ORBInitializer_Registry_Impl.h" -#include "tao/PI/PolicyFactory_Loader.h" -#include "tao/PI/ClientRequestInterceptor_Factory_Impl.h" -#include "tao/PI/PICurrent_Loader.h" -#include "tao/PI/PI_ORBInitializer.h" -#include "tao/ORBInitializer_Registry.h" -#include "tao/ORB_Constants.h" ACE_RCSID (PI, PI, @@ -13,55 +6,4 @@ ACE_RCSID (PI, TAO_BEGIN_VERSIONED_NAMESPACE_DECL -int -TAO_PI_Init::Initializer (void) -{ -#if TAO_HAS_INTERCEPTORS == 1 - ACE_Service_Config::process_directive (ace_svc_desc_TAO_ClientRequestInterceptor_Adapter_Factory_Impl); - - ACE_Service_Config::process_directive (ace_svc_desc_TAO_PICurrent_Loader); -#endif /* TAO_HAS_INTERCEPTORS == 1 */ - - int status = ACE_Service_Config::process_directive ( - ace_svc_desc_ORBInitializer_Registry); -#if TAO_HAS_INTERCEPTORS == 1 - PortableInterceptor::ORBInitializer_ptr temp_orb_initializer = - PortableInterceptor::ORBInitializer::_nil (); - - PortableInterceptor::ORBInitializer_var orb_initializer; - - ACE_DECLARE_NEW_CORBA_ENV; - ACE_TRY - { - /// Register the PI ORBInitializer. - - ACE_NEW_THROW_EX (temp_orb_initializer, - TAO_PI_ORBInitializer, - CORBA::NO_MEMORY ( - CORBA::SystemException::_tao_minor_code ( - TAO::VMCID, - ENOMEM), - CORBA::COMPLETED_NO)); - ACE_TRY_CHECK; - - orb_initializer = temp_orb_initializer; - - PortableInterceptor::register_orb_initializer (orb_initializer.in () - ACE_ENV_ARG_PARAMETER); - ACE_TRY_CHECK; - } - ACE_CATCHANY - { - if (TAO_debug_level > 0) - { - ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, - "(%P | %t) Caught exception:"); - } - return -1; - } - ACE_ENDTRY; -#endif /* TAO_HAS_INTERCEPTORS == 1 */ - return status; -} - TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/PI/PI.h b/TAO/tao/PI/PI.h index da45315f182..6facdc7fc2d 100644 --- a/TAO/tao/PI/PI.h +++ b/TAO/tao/PI/PI.h @@ -25,22 +25,6 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL -/** - * @class TAO_PI_Init - * - */ -class TAO_PI_Export TAO_PI_Init -{ -public: - - /// Used to force the initialization of the ORB code. - static int Initializer (void); -}; - -static int -TAO_Requires_PI_Initializer = - TAO_PI_Init::Initializer (); - TAO_END_VERSIONED_NAMESPACE_DECL #include /**/ "ace/post.h" diff --git a/TAO/tao/PI/PolicyFactory_Loader.cpp b/TAO/tao/PI/PolicyFactory_Loader.cpp index 3b8e49f062c..1e4f6e44d5a 100644 --- a/TAO/tao/PI/PolicyFactory_Loader.cpp +++ b/TAO/tao/PI/PolicyFactory_Loader.cpp @@ -14,9 +14,6 @@ #include "tao/PI/PolicyFactory_Loader.h" #include "tao/PI/PolicyFactory_Registry.h" -#include "tao/ORB.h" -#include "tao/debug.h" - ACE_RCSID (PI, PolicyFactory_Loader, "$Id$") @@ -33,12 +30,6 @@ TAO_PolicyFactory_Loader::create (void) return obj; } -int -TAO_PolicyFactory_Loader::Initializer (void) -{ - return ACE_Service_Config::process_directive (ace_svc_desc_TAO_PolicyFactory_Loader); -} - TAO_END_VERSIONED_NAMESPACE_DECL ACE_STATIC_SVC_DEFINE (TAO_PolicyFactory_Loader, diff --git a/TAO/tao/PI/PolicyFactory_Loader.h b/TAO/tao/PI/PolicyFactory_Loader.h index a25c378676e..4ee3c5a2c56 100644 --- a/TAO/tao/PI/PolicyFactory_Loader.h +++ b/TAO/tao/PI/PolicyFactory_Loader.h @@ -34,14 +34,8 @@ class TAO_PI_Export TAO_PolicyFactory_Loader public: /// Creates a Codec factory and returns it. virtual TAO::PolicyFactory_Registry_Adapter* create (void); - - /// Used to force the initialization of the ORB code. - static int Initializer (void); }; -static int -TAO_Requires_PolicyFactory_Initializer = TAO_PolicyFactory_Loader::Initializer (); - TAO_END_VERSIONED_NAMESPACE_DECL ACE_STATIC_SVC_DECLARE (TAO_PolicyFactory_Loader) diff --git a/TAO/tao/Parser_Registry.cpp b/TAO/tao/Parser_Registry.cpp index 1d873b9ae12..7b21273679e 100644 --- a/TAO/tao/Parser_Registry.cpp +++ b/TAO/tao/Parser_Registry.cpp @@ -49,7 +49,8 @@ TAO_Parser_Registry::open (TAO_ORB_Core *orb_core) for (size_t i = 0; i != this->size_; ++i) { this->parsers_[i] = - ACE_Dynamic_Service<TAO_IOR_Parser>::instance (names [i]); + ACE_Dynamic_Service<TAO_IOR_Parser>::instance (orb_core->configuration (), + names [i]); if (this->parsers_[i] == 0) { diff --git a/TAO/tao/PortableServer/Root_POA.cpp b/TAO/tao/PortableServer/Root_POA.cpp index b476ae8bec6..686e4759d51 100644 --- a/TAO/tao/PortableServer/Root_POA.cpp +++ b/TAO/tao/PortableServer/Root_POA.cpp @@ -2515,7 +2515,8 @@ TAO_Root_POA::find_servant_priority ( TAO::ORT_Adapter_Factory * TAO_Root_POA::ORT_adapter_factory (void) { - return ACE_Dynamic_Service<TAO::ORT_Adapter_Factory>::instance ( + return ACE_Dynamic_Service<TAO::ORT_Adapter_Factory>::instance + (orb_core_.configuration (), TAO_Root_POA::ort_adapter_factory_name ()); } diff --git a/TAO/tao/TAO_Internal.cpp b/TAO/tao/TAO_Internal.cpp index 0839cc1f048..65393f2a33e 100644 --- a/TAO/tao/TAO_Internal.cpp +++ b/TAO/tao/TAO_Internal.cpp @@ -48,33 +48,71 @@ ACE_RCSID (tao, namespace { + + /** + * Parses the supplied command-line arguments to extract any that + * apply to the process (globally) + * + * @brief Modifies the argc to reflect any arguments it has + * "consumed" + */ + int + parse_global_args_i (int &argc, + char **argv, + CORBA::StringSeq &svc_config_argv); + /** - * Initialize the ACE Service Configurator. This is a one-shot - * method, i.e., it can be called multiple times but it will only do - * its work once. It does, however, track the number of times it's - * called (see @c open_services()). It is fully thread-safe. + * Initialize the ACE Service Configurator with the process-global + * services (available to any ORB). * * @return @c 0 if successful, @c -1 with @c errno set if failure. * * @note You can provide your program a set of default `svc.conf' * entries by setting @a ignore_default_svc_conf_file to * non-zero and use @c default_svc_conf_entries() before - * calling @c open_services(). In addition, you can @a + * calling @c open_global_services(). In addition, you can @a * skip_service_config_open altogether, which used to be * important when the ORB is linked in via the - * ACE_Service_Configurator, since the - * ACE_Service_Configurator was non-reentrant. However, the - * ACE_Service_Configurator is now reentrant meaning that it - * is really no longer necessary to do so. + * ACE_Service_Config, since the ACE_Service_Config was + * non-reentrant. However, the ACE_Service_Config is now + * reentrant meaning that it is really no longer necessary to + * do so. + */ + void register_global_services_i (ACE_Service_Gestalt * pcfg); + int open_global_services_i (ACE_Service_Gestalt* theone, + int & argc, + char ** argv, + bool skip_service_config_open); + + /** + * Parses the supplied command-line arguments to extract any + * instance-specific ones. + * + * @brief Modifies the argc to reflect any arguments it has + * "consumed" + */ + int + parse_private_args_i (int &argc, + char **argv, + CORBA::StringSeq & svc_config_argv, + bool & skip_service_config_open); + + /** + * Initialize ORB-local (private) ACE Service Configurator + * repository. + * + * @return @c 0 if successful, @c -1 with @c errno set if failure. + * */ - int open_services_i (int & argc, - char ** argv, - bool ignore_default_svc_conf_file = false, - bool skip_service_config_open = false); + int open_private_services_i (ACE_Service_Gestalt* pcfg, + int & argc, + char ** argv, + bool skip_service_config_open = false); - /// Number of times open_services() has been called. Incremented by - /// open_services(), and decremented by close_services(). /** + * Number of times open_services() has been called. Incremented by + * open_global_services_i(), and decremented by close_services(). + * * @note In/decrement operations are atomic. */ long service_open_count = 0; @@ -90,7 +128,9 @@ namespace TAO_BEGIN_VERSIONED_NAMESPACE_DECL int -TAO::ORB::open_services (int &argc, ACE_TCHAR **argv) +TAO::ORB::open_services (ACE_Service_Gestalt* pcfg, + int &argc, + ACE_TCHAR **argv) { // Construct an argument vector specific to the Service // Configurator. @@ -105,7 +145,6 @@ TAO::ORB::open_services (int &argc, ACE_TCHAR **argv) argv0 = ACE_TEXT_ALWAYS_CHAR (argv[0]); } - CORBA::ULong len = 0; svc_config_argv.length (1); svc_config_argv[0] = argv0.c_str (); @@ -117,157 +156,66 @@ TAO::ORB::open_services (int &argc, ACE_TCHAR **argv) // -Ossama bool skip_service_config_open = false; -#if defined (TAO_DEBUG) && !defined (ACE_HAS_WINCE) - // Make it a little easier to debug programs using this code. + // Extract any ORB options from the argument vector. + if (parse_private_args_i (argc, + argv, + svc_config_argv, + skip_service_config_open) == -1) + return -1; + else { - TAO_debug_level = ACE_Env_Value<u_int> ("TAO_ORB_DEBUG", 0); + ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, + guard, + *ACE_Static_Object_Lock::instance (), + -1)); - char * const value = ACE_OS::getenv ("TAO_ORB_DEBUG"); + service_open_count++; - if (value != 0) + ACE_Service_Gestalt * theone = ACE_Service_Config::global (); + if (pcfg != theone) + { + int status = open_global_services_i (theone, argc, argv, skip_service_config_open); + if (status == -1) { - TAO_debug_level = ACE_OS::atoi (value); - - if (TAO_debug_level <= 0) - { - TAO_debug_level = 1; - } - - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO_debug_level == %d\n"), - TAO_debug_level)); + if (TAO_debug_level > 0) + ACE_ERROR_RETURN ((LM_DEBUG, + ACE_LIB_TEXT ("TAO (%P|%t) Failed to ") + ACE_LIB_TEXT("open process-wide service configuration\n")), + -1); + return -1; } - } -#endif /* TAO_DEBUG && !ACE_HAS_WINCE */ - - // Extract the Service Configurator ORB options from the argument - // vector. - ACE_Arg_Shifter arg_shifter (argc, argv); + } - while (arg_shifter.is_anything_left ()) + int svc_config_argc = svc_config_argv.length (); + int status = + open_private_services_i (pcfg, + svc_config_argc, + svc_config_argv.get_buffer (), + skip_service_config_open); + if (status == -1) { - const ACE_TCHAR *current_arg = 0; - - // Start with the parameterless flags. - if (arg_shifter.cur_arg_strncasecmp - (ACE_TEXT ("-ORBSkipServiceConfigOpen")) == 0) - { - skip_service_config_open = true; - - arg_shifter.consume_arg (); - } - else if (arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBDebug")) == 0) - { - // later, replace all of these - // warning this turns on a daemon - ACE::debug (1); - arg_shifter.consume_arg (); - } - else if (0 != (current_arg = arg_shifter.get_the_parameter - (ACE_TEXT ("-ORBDebugLevel")))) - { - TAO_debug_level = - ACE_OS::atoi (current_arg); - - arg_shifter.consume_arg (); - } - else if (arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBDaemon")) == 0) - { - // Be a daemon - - len = svc_config_argv.length (); - svc_config_argv.length (len + 1); - - svc_config_argv[len] = CORBA::string_dup ("-b"); - - arg_shifter.consume_arg (); - } - // Continue with flags that accept parameters. - else if (0 != (current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBSvcConfDirective")))) - { - len = svc_config_argv.length (); - svc_config_argv.length (len + 2); // 2 arguments to add - - // This is used to pass arguments to the Service - // Configurator using the "command line" to provide - // configuration information rather than using a svc.conf - // file. Pass the "-S" to the service configurator. - svc_config_argv[len] = CORBA::string_dup ("-S"); - svc_config_argv[len + 1] = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(current_arg)); - - arg_shifter.consume_arg (); - } - else if (0 != (current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBSvcConf")))) - { - // Specify the name of the svc.conf file to be used. - - // Proceeds only if the configuration file exists. - FILE * const conf_file = ACE_OS::fopen (current_arg, ACE_TEXT ("r")); - - if (conf_file == 0) - { - // Assigning EINVAL to errno to make an exception - // thrown. calling code does not throw an exception if - // the errno is set to ENOENT for some reason. - errno = EINVAL; - - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("TAO (%P|%t) Service Configurator ") - ACE_TEXT ("unable to open file %s\n"), - current_arg), - -1); - - } - else - { - ACE_OS::fclose (conf_file); - } - - len = svc_config_argv.length (); - svc_config_argv.length (len + 2); // 2 arguments to add - - svc_config_argv[len] = CORBA::string_dup ("-f"); - svc_config_argv[len + 1] = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(current_arg)); - - arg_shifter.consume_arg(); - } - else if (0 != (current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBServiceConfigLoggerKey")))) - { - len = svc_config_argv.length (); - svc_config_argv.length (len + 2); // 2 arguments to add - - svc_config_argv[len] = CORBA::string_dup ("-k"); - svc_config_argv[len + 1] = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(current_arg)); - - arg_shifter.consume_arg (); - } - // Can't interpret this argument. Move on to the next argument. - else - { - // Any arguments that don't match are ignored so that the - // caller can still use them. - arg_shifter.ignore_arg (); - } + if (TAO_debug_level > 0) + ACE_ERROR_RETURN ((LM_DEBUG, + ACE_LIB_TEXT ("TAO (%P|%t) Failed to ") + ACE_LIB_TEXT("open orb service configuration\n")), + -1); + return -1; } - int svc_config_argc = svc_config_argv.length (); - return open_services_i (svc_config_argc, - svc_config_argv.get_buffer (), - 0, // @@ What about this argument? - skip_service_config_open); + return 0; + } } int -TAO::ORB::close_services (void) +TAO::ORB::close_services (ACE_Service_Gestalt* pcfg) { ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard, *ACE_Static_Object_Lock::instance (), -1)); + service_open_count--; - --service_open_count; - - return 0; + return pcfg->close (); } void @@ -285,32 +233,78 @@ TAO_END_VERSIONED_NAMESPACE_DECL // ----------------------------------------------------- namespace { + + /// + int - open_services_i (int & argc, - char ** argv, - bool ignore_default_svc_conf_file, - bool skip_service_config_open) + open_global_services_i (ACE_Service_Gestalt * theone, + int & argc, + ACE_TCHAR ** argv, + bool skip_service_config_open) + { + // Construct an argument vector specific to the process-wide + // (global) Service Configurator instance. + CORBA::StringSeq global_svc_config_argv; + + // Be certain to copy the program name so that service configurator + // has something to skip! + ACE_CString argv0 (""); + + if (argc > 0 && argv != 0) + { + argv0 = ACE_TEXT_ALWAYS_CHAR (argv[0]); + } + + global_svc_config_argv.length (1); + global_svc_config_argv[0] = argv0.c_str (); + + if (parse_global_args_i (argc, argv, global_svc_config_argv) == -1) + return -1; + + ACE_Service_Config_Guard guard (theone); + register_global_services_i (theone); + + int global_svc_config_argc = global_svc_config_argv.length (); + if (!skip_service_config_open) + { + return theone->open (global_svc_config_argc, + global_svc_config_argv.get_buffer ()); + } + return 0; + } + + + /// + + int + open_private_services_i (ACE_Service_Gestalt * pcfg, + int & argc, + ACE_TCHAR ** argv, + bool skip_service_config_open) { #if defined (TAO_PLATFORM_SVC_CONF_FILE_NOTSUP) - ignore_default_svc_conf_file = true; + bool ignore_default_svc_conf_file = true; +#else + bool ignore_default_svc_conf_file = false; #endif /* TAO_PLATFORM_SVC_CONF_FILE_NOTSUP */ - { - ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, - guard, - *ACE_Static_Object_Lock::instance (), - -1)); + if (skip_service_config_open) + return 0; - if (service_open_count++ != 0) // Atomic increment - return 0; - } + return pcfg->open (argc, + argv, + ACE_DEFAULT_LOGGER_KEY, + 0, // Don't ignore static services. + ignore_default_svc_conf_file); + } - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_Default_Resource_Factory); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_Default_Client_Strategy_Factory); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_Default_Server_Strategy_Factory); + /// @brief registers all process-wide (global) services, available to all ORBs + void + register_global_services_i (ACE_Service_Gestalt * pcfg) + { + pcfg->process_directive (ace_svc_desc_TAO_Default_Resource_Factory); + pcfg->process_directive (ace_svc_desc_TAO_Default_Client_Strategy_Factory); + pcfg->process_directive (ace_svc_desc_TAO_Default_Server_Strategy_Factory); // Configure the IIOP factory. You do *NOT* need modify this // code to add your own protocol, instead simply add the @@ -321,125 +315,273 @@ namespace // // where PN is the name of your protocol and LIB is the base // name of the shared library that implements the protocol. + #if defined (TAO_HAS_IIOP) && (TAO_HAS_IIOP != 0) - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_IIOP_Protocol_Factory); + pcfg->process_directive (ace_svc_desc_TAO_IIOP_Protocol_Factory); #endif /* TAO_HAS_IIOP && TAO_HAS_IIOP != 0 */ // add descriptor to list of static objects. - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_MCAST_Parser); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_CORBANAME_Parser); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_CORBALOC_Parser); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_FILE_Parser); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_DLL_Parser); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_Default_Stub_Factory); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_Default_Endpoint_Selector_Factory); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_Default_Protocols_Hooks); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_Default_Thread_Lane_Resources_Manager_Factory); - ACE_Service_Config::process_directive ( - ace_svc_desc_TAO_Default_Collocation_Resolver); - - int result = 0; - - if (!skip_service_config_open) - { - // Copy command line parameter not to use original. - ACE_Argv_Type_Converter command_line (argc, argv); - - result = - ACE_Service_Config::open (command_line.get_argc(), - command_line.get_TCHAR_argv(), - ACE_DEFAULT_LOGGER_KEY, - 0, // Don't ignore static services. - ignore_default_svc_conf_file); - } + pcfg->process_directive (ace_svc_desc_TAO_MCAST_Parser); + pcfg->process_directive (ace_svc_desc_TAO_CORBANAME_Parser); + pcfg->process_directive (ace_svc_desc_TAO_CORBALOC_Parser); + pcfg->process_directive (ace_svc_desc_TAO_FILE_Parser); + pcfg->process_directive (ace_svc_desc_TAO_DLL_Parser); + pcfg->process_directive (ace_svc_desc_TAO_Default_Stub_Factory); + pcfg->process_directive (ace_svc_desc_TAO_Default_Endpoint_Selector_Factory); + pcfg->process_directive (ace_svc_desc_TAO_Default_Protocols_Hooks); + pcfg->process_directive (ace_svc_desc_TAO_Default_Thread_Lane_Resources_Manager_Factory); + pcfg->process_directive (ace_svc_desc_TAO_Default_Collocation_Resolver); + + // @@ What the heck do these things do and do we need to avoid + // calling them if we're not invoking the svc.conf file? + // @@ They are needed for platforms that have no file system, + // like VxWorks. + if (resource_factory_args != 0) + { + pcfg->process_directive + (ACE_TEXT_CHAR_TO_TCHAR (resource_factory_args)); + } + + if (client_strategy_factory_args != 0) + { + pcfg->process_directive + (ACE_TEXT_CHAR_TO_TCHAR (client_strategy_factory_args)); + } + + if (server_strategy_factory_args != 0) + { + pcfg->process_directive + (ACE_TEXT_CHAR_TO_TCHAR (server_strategy_factory_args)); + } // If available, allow the Adapter Factory to setup. ACE_Service_Object *adapter_factory = - ACE_Dynamic_Service<TAO_Adapter_Factory>::instance ( - TAO_ORB_Core::poa_factory_name ().c_str()); + ACE_Dynamic_Service<ACE_Service_Object>::instance + (pcfg, TAO_ORB_Core::poa_factory_name ().c_str()); if (adapter_factory != 0) - { - adapter_factory->init (0, 0); - } + { + adapter_factory->init (0, 0); + } ACE_Service_Object * const pi_server_loader = - ACE_Dynamic_Service<ACE_Service_Object>::instance ("PI_Server_Loader"); + ACE_Dynamic_Service<ACE_Service_Object>::instance (pcfg, "PI_Server_Loader"); if (pi_server_loader != 0) - { - pi_server_loader->init (0, 0); - } + { + pi_server_loader->init (0, 0); + } ACE_Service_Object * const bidir_loader = - ACE_Dynamic_Service<ACE_Service_Object>::instance ("BiDirGIOP_Loader"); + ACE_Dynamic_Service<ACE_Service_Object>::instance (pcfg, "BiDirGIOP_Loader"); if (bidir_loader != 0) - { - bidir_loader->init (0, 0); - } + { + bidir_loader->init (0, 0); + } ACE_Service_Object * const messaging_loader = - ACE_Dynamic_Service<ACE_Service_Object>::instance ("Messaging_Loader"); + ACE_Dynamic_Service<ACE_Service_Object>::instance (pcfg, "Messaging_Loader"); if (messaging_loader != 0) - { - messaging_loader->init (0, 0); - } + { + messaging_loader->init (0, 0); + } // Handle RTCORBA library special case. Since RTCORBA needs // its init method call to register several hooks, call it // here if it hasn't already been called. ACE_Service_Object * const rt_loader = - ACE_Dynamic_Service<ACE_Service_Object>::instance ("RT_ORB_Loader"); + ACE_Dynamic_Service<ACE_Service_Object>::instance (pcfg, "RT_ORB_Loader"); if (rt_loader != 0) - { - rt_loader->init (0, 0); - } + { + rt_loader->init (0, 0); + } ACE_Service_Object * const rtscheduler_loader = - ACE_Dynamic_Service<ACE_Service_Object>::instance ("RTScheduler_Loader"); + ACE_Dynamic_Service<ACE_Service_Object>::instance (pcfg, "RTScheduler_Loader"); if (rtscheduler_loader != 0) + { + rtscheduler_loader->init (0, 0); + } + + } /* register_additional_services_i */ + + + int + parse_private_args_i (int &argc, + char **argv, + CORBA::StringSeq &svc_config_argv, + bool & skip_service_config_open) + { + // Extract the Service Configurator ORB options from the argument + // vector. + ACE_Arg_Shifter arg_shifter (argc, argv); + + CORBA::ULong len = 0; + while (arg_shifter.is_anything_left ()) + { + const ACE_TCHAR *current_arg = 0; + + // Start with the parameterless flags. + if (arg_shifter.cur_arg_strncasecmp + (ACE_TEXT ("-ORBSkipServiceConfigOpen")) == 0) { - rtscheduler_loader->init (0, 0); + skip_service_config_open = true; + + arg_shifter.consume_arg (); } + // Continue with flags that accept parameters. + else if (0 != (current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBSvcConfDirective")))) + { + len = svc_config_argv.length (); + svc_config_argv.length (len + 2); // 2 arguments to add - // @@ What the heck do these things do and do we need to avoid - // calling them if we're not invoking the svc.conf file? - // @@ They are needed for platforms that have no file system, - // like VxWorks. - if (resource_factory_args != 0) + // This is used to pass arguments to the Service + // Configurator using the "command line" to provide + // configuration information rather than using a svc.conf + // file. Pass the "-S" to the service configurator. + svc_config_argv[len] = CORBA::string_dup ("-S"); + svc_config_argv[len + 1] = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(current_arg)); + + arg_shifter.consume_arg (); + } + else if (0 != (current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBSvcConf")))) + { + // Specify the name of the svc.conf file to be used. + + // Proceeds only if the configuration file exists. + FILE * const conf_file = ACE_OS::fopen (current_arg, ACE_TEXT ("r")); + + if (conf_file == 0) + { + // Assigning EINVAL to errno to make an exception + // thrown. calling code does not throw an exception if + // the errno is set to ENOENT for some reason. + errno = EINVAL; + + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) Service Configurator ") + ACE_TEXT ("unable to open file %s\n"), + current_arg), + -1); + + } + else + { + ACE_OS::fclose (conf_file); + } + + len = svc_config_argv.length (); + svc_config_argv.length (len + 2); // 2 arguments to add + + svc_config_argv[len] = CORBA::string_dup ("-f"); + svc_config_argv[len + 1] = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(current_arg)); + + arg_shifter.consume_arg(); + } + else if (0 != (current_arg = arg_shifter.get_the_parameter (ACE_TEXT ("-ORBServiceConfigLoggerKey")))) + { + len = svc_config_argv.length (); + svc_config_argv.length (len + 2); // 2 arguments to add + + svc_config_argv[len] = CORBA::string_dup ("-k"); + svc_config_argv[len + 1] = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(current_arg)); + + arg_shifter.consume_arg (); + } + // Can't interpret this argument. Move on to the next argument. + else { - ACE_Service_Config::process_directive ( - ACE_TEXT_CHAR_TO_TCHAR (resource_factory_args)); + // Any arguments that don't match are ignored so that the + // caller can still use them. + arg_shifter.ignore_arg (); } + } - if (client_strategy_factory_args != 0) + return 0; + + } /* parse_private_args_i */ + + int + parse_global_args_i (int &argc, + char **argv, + CORBA::StringSeq &svc_config_argv) + { + +#if defined (TAO_DEBUG) && !defined (ACE_HAS_WINCE) + // Make it a little easier to debug programs using this code. + { + TAO_debug_level = ACE_Env_Value<u_int> ("TAO_ORB_DEBUG", 0); + + char * const value = ACE_OS::getenv ("TAO_ORB_DEBUG"); + + if (value != 0) { - ACE_Service_Config::process_directive ( - ACE_TEXT_CHAR_TO_TCHAR (client_strategy_factory_args)); + TAO_debug_level = ACE_OS::atoi (value); + + if (TAO_debug_level <= 0) + { + TAO_debug_level = 1; + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO_debug_level == %d\n"), + TAO_debug_level)); } + } +#endif /* TAO_DEBUG && !ACE_HAS_WINCE */ - if (server_strategy_factory_args != 0) + + // Extract the Service Configurator ORB options from the argument + // vector. + ACE_Arg_Shifter arg_shifter (argc, argv); + CORBA::ULong len = 0; + + while (arg_shifter.is_anything_left ()) + { + const ACE_TCHAR *current_arg = 0; + if (arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBDebug")) == 0) { - ACE_Service_Config::process_directive ( - ACE_TEXT_CHAR_TO_TCHAR (server_strategy_factory_args)); + // later, replace all of these + // warning this turns on a daemon + ACE::debug (1); + arg_shifter.consume_arg (); } + else if (0 != (current_arg = arg_shifter.get_the_parameter + (ACE_TEXT ("-ORBDebugLevel")))) + { + TAO_debug_level = + ACE_OS::atoi (current_arg); - return result; - } -} + arg_shifter.consume_arg (); + } + else if (arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBDaemon")) == 0) + { + // Be a daemon + + len = svc_config_argv.length (); + svc_config_argv.length (len + 1); + + svc_config_argv[len] = CORBA::string_dup ("-b"); + arg_shifter.consume_arg (); + } + // Can't interpret this argument. Move on to the next argument. + else + { + // Any arguments that don't match are ignored so that the + // caller can still use them. + arg_shifter.ignore_arg (); + } + } + + return 0; + + } /* parse_global_args_i */ + + +} // TAO_BEGIN_VERSIONED_NAMESPACE_DECL -- ended prior to anonymous namespace. diff --git a/TAO/tao/TAO_Internal.h b/TAO/tao/TAO_Internal.h index e528980821c..3a40ef07bd6 100644 --- a/TAO/tao/TAO_Internal.h +++ b/TAO/tao/TAO_Internal.h @@ -24,6 +24,11 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +/// Forward declaration +class ACE_Service_Gestalt; +ACE_END_VERSIONED_NAMESPACE_DECL + TAO_BEGIN_VERSIONED_NAMESPACE_DECL namespace TAO @@ -38,13 +43,14 @@ namespace TAO */ namespace ORB { - /// Extract ACE Service Configurator arguments from the given - /// argument vector, and initialize the ACE Service Configurator. /** + * Extract ACE Service Configurator arguments from the given + * argument vector, and initialize the ACE Service Configurator. + * * @note This method should be called before the ORB Core is * initialized, and before any ORBInitializers are invoked. */ - int open_services (int& argc, ACE_TCHAR** argv); + int open_services (ACE_Service_Gestalt* cfg, int& argc, ACE_TCHAR** argv); /** * The complement to @c open_services(), this will perform @@ -52,13 +58,16 @@ namespace TAO * should be called as many times as @c open_services(), and will * only actually close things down on the last call. It is fully * thread-safe. + * * @return @c 0 if successful, @c -1 with @c errno set if * failure. */ - int close_services (void); + int close_services (ACE_Service_Gestalt* pcfg); - /// Set default @c `svc.conf' content. This call has no effect if - /// This function must be called before first ORB initialization. + /** + * Set default @c `svc.conf' content. + * This function must be called before first ORB initialization. + */ void default_svc_conf_entries (char const * rf_args, char const * ssf_args, char const * csf_args); diff --git a/TAO/tao/default_resource.cpp b/TAO/tao/default_resource.cpp index b52665b7023..3de123a5310 100644 --- a/TAO/tao/default_resource.cpp +++ b/TAO/tao/default_resource.cpp @@ -62,11 +62,14 @@ TAO_Default_Resource_Factory::TAO_Default_Resource_Factory (void) , wchar_codeset_descriptor_ (0) , resource_usage_strategy_ (TAO_Resource_Factory::TAO_EAGER) , drop_replies_ (true) + , principal_(0) { #if TAO_USE_LAZY_RESOURCE_USAGE_STRATEGY == 1 this->resource_usage_strategy_ = TAO_Resource_Factory::TAO_LAZY; #endif /*TAO_USE_LAZY_RESOURCE_USAGE_STRATEGY*/ + + } TAO_Default_Resource_Factory::~TAO_Default_Resource_Factory (void) @@ -90,6 +93,8 @@ TAO_Default_Resource_Factory::~TAO_Default_Resource_Factory (void) delete codeset_manager_; codeset_manager_ = 0; + + delete principal_; } int @@ -102,7 +107,8 @@ TAO_Default_Resource_Factory::init (int argc, ACE_TCHAR *argv[]) // are useless if (this->factory_disabled_) { ACE_DEBUG ((LM_WARNING, - ACE_TEXT ("TAO (%P|%t) Warning: Resource_Factory options ignored\n") + ACE_TEXT ("TAO (%P|%t) Warning: Resource_Factory options ") + ACE_TEXT ("ignored\n") ACE_TEXT ("Default Resource Factory is disabled\n"))); return 0; } @@ -171,7 +177,8 @@ TAO_Default_Resource_Factory::init (int argc, ACE_TCHAR *argv[]) -1); if (pset->insert (item) == -1) ACE_ERROR ((LM_ERROR, - ACE_TEXT ("(%P|%t) Unable to add protocol factories for %s: %m\n"), + ACE_TEXT ("(%P|%t) Unable to add protocol factories ") + ACE_TEXT ("for %s: %m\n"), argv[curarg])); } } @@ -239,7 +246,8 @@ TAO_Default_Resource_Factory::init (int argc, ACE_TCHAR *argv[]) // note is being written during 1.2.3 timeframe. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) This option would be deprecated \n") - ACE_TEXT ("(%P|%t) Please use -ORBConnectionPurgingStrategy instead \n"))); + ACE_TEXT ("(%P|%t) Please use -ORBConnectionPurgingStrategy ") + ACE_TEXT ("instead \n"))); if (curarg < argc) { @@ -1184,6 +1192,9 @@ TAO_Default_Resource_Factory::codeset_manager(void) "")); factory = ACE_Dynamic_Service<TAO_Codeset_Manager_Factory_Base>::instance ("TAO_Codeset"); + + principal_ = new ACE_Dynamic_Service_Dependency (ACE_TEXT ("TAO_Codeset")); + #endif } if (factory == 0) diff --git a/TAO/tao/default_resource.h b/TAO/tao/default_resource.h index aef5e545fd7..8f022479fc5 100644 --- a/TAO/tao/default_resource.h +++ b/TAO/tao/default_resource.h @@ -17,6 +17,7 @@ #include /**/ "ace/pre.h" #include "ace/Service_Config.h" +#include "ace/Dynamic_Service_Dependency.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -257,6 +258,12 @@ private: /// Flag to indicate whether replies should be dropped during ORB /// shutdown. bool drop_replies_; + + // Makes a dependency on a specific dynamic service ("TAO_Codeset") explicit. + // It helps to keep the corresponding DLL around until the last instance + // is destroyed. Note that failure to delete the instances will "pin" the + // DLL in memory, preventing it from being unloaded on demand. + ACE_Dynamic_Service_Dependency *principal_; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tests/DLL_ORB/Test_Client_Module.cpp b/TAO/tests/DLL_ORB/Test_Client_Module.cpp index 1aa4db4d534..f6cd461b12e 100644 --- a/TAO/tests/DLL_ORB/Test_Client_Module.cpp +++ b/TAO/tests/DLL_ORB/Test_Client_Module.cpp @@ -89,7 +89,7 @@ Test_Client_Module::init (int argc, ACE_TCHAR *argv[]) // Initialize the ORB. this->orb_ = CORBA::ORB_init (new_argc, new_argv.get_buffer (), - "" + "CLIENT" ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; @@ -141,33 +141,8 @@ Test_Client_Module::init (int argc, ACE_TCHAR *argv[]) int Test_Client_Module::fini (void) { - ACE_DECLARE_NEW_CORBA_ENV; - ACE_TRY - { - // Make sure the ORB is destroyed. - if (!CORBA::is_nil (this->orb_.in ())) - { - this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_TRY_CHECK; - } - } - ACE_CATCHANY - { - ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, - ACE_TEXT ("Test_Client_Module::fini")); - return -1; - } - ACE_ENDTRY; - ACE_CHECK_RETURN (-1); - - // This is a bit of a hack. The ORB Core's lifetime is tied to the - // lifetime of an object reference. We need to wipe out all object - // references before we call fini() on the TAO_Singleton_Manager. - // - // Note that this is only necessary if the default resource factory - // is used, i.e. one isn't explicitly loaded prior to initializing - // the ORB. - (void) this->test_.out (); + ACE_DEBUG ((LM_INFO, + "Client is being finalized.\n")); // ------------------------------------------------------------ // Pre-Test_Client_Module termination steps. @@ -196,6 +171,31 @@ Test_Client_Module::svc (void) /// Shutdown the remote ORB. this->test_->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; + + // Make sure the ORB is destroyed here - before the thread + // exits, because it may be holding global resources, owned by + // the Object Manager (thru its core, which is in turn owned by + // the ORB table; which is owned by the Object Manager). + // Otherwise the Object Manager will have clobbered them by the + // time it gets to destroy the ORB Table, which calls our + // fini(). Had we destroyed the ORB in our fini(), its core + // fininalization would have required access to those already + // deleted resources. + if (!CORBA::is_nil (this->orb_.in ())) + { + this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + // This is a bit of a hack. The ORB Core's lifetime is tied to the + // lifetime of an object reference. We need to wipe out all object + // references before we call fini() on the TAO_Singleton_Manager. + // + // Note that this is only necessary if the default resource factory + // is used, i.e. one isn't explicitly loaded prior to initializing + // the ORB. + (void) this->test_.out (); + } ACE_CATCHANY { diff --git a/TAO/tests/DLL_ORB/Test_Server_Module.cpp b/TAO/tests/DLL_ORB/Test_Server_Module.cpp index b48c4c8704b..2bb64be76df 100644 --- a/TAO/tests/DLL_ORB/Test_Server_Module.cpp +++ b/TAO/tests/DLL_ORB/Test_Server_Module.cpp @@ -90,7 +90,7 @@ Test_Server_Module::init (int argc, ACE_TCHAR *argv[]) // Initialize the ORB. this->orb_ = CORBA::ORB_init (new_argc, new_argv.get_buffer (), - 0 + "SERVER" ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; @@ -168,24 +168,8 @@ Test_Server_Module::init (int argc, ACE_TCHAR *argv[]) int Test_Server_Module::fini (void) { - ACE_DECLARE_NEW_CORBA_ENV; - ACE_TRY - { - // Make sure the ORB is destroyed. - if (!CORBA::is_nil (this->orb_.in ())) - { - this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_TRY_CHECK; - } - } - ACE_CATCHANY - { - ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, - ACE_TEXT ("Test_Server_Module::fini")); - return -1; - } - ACE_ENDTRY; - ACE_CHECK_RETURN (-1); + ACE_DEBUG ((LM_INFO, + "Server is being finalized.\n")); // ------------------------------------------------------------ // Pre-Test_Server_Module termination steps. @@ -210,6 +194,24 @@ Test_Server_Module::svc (void) // Run the ORB event loop in its own thread. this->orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; + + ACE_DEBUG ((LM_INFO, + "Server is being destroyed.\n")); + + // Make sure the ORB is destroyed here - before the thread + // exits, because it may be holding global resources, owned by + // the Object Manager (thru its core, which is in turn owned by + // the ORB table; which is owned by the Object Manager). + // Otherwise the Object Manager will have clobbered them by the + // time it gets to destroy the ORB Table, which calls our + // fini(). Had we destroyed the ORB in our fini(), its core + // fininalization would have required access to those already + // deleted resources. + if (!CORBA::is_nil (this->orb_.in ())) + { + this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } } ACE_CATCHANY { diff --git a/TAO/tests/ORB_Local_Config/Bunch/Bunch.mpc b/TAO/tests/ORB_Local_Config/Bunch/Bunch.mpc new file mode 100644 index 00000000000..c71a117c14b --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Bunch/Bunch.mpc @@ -0,0 +1,15 @@ +// -*- MPC -*- +// $Id$ + + +project(*) : ../../../tests/acetest, taoserver { + after += lib + exename = Test + includes += ../lib + libpaths += ../lib + libs += lib + Source_Files { + Test.cpp + } +} + diff --git a/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf Binary files differnew file mode 100644 index 00000000000..e5d36fd215f --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf diff --git a/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf.xml b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf.xml Binary files differnew file mode 100644 index 00000000000..1d75d2763c0 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf.xml diff --git a/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf Binary files differnew file mode 100644 index 00000000000..a36db0600c9 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf diff --git a/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf.xml b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf.xml Binary files differnew file mode 100644 index 00000000000..88e7c26e8eb --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf.xml diff --git a/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.conf b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.conf new file mode 100644 index 00000000000..34d51068365 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.conf @@ -0,0 +1,19 @@ +# Dynamically loading each of the Service Objects below causes a +# number of threads to be spawned, each one invoking the Service +# Configurator (e.g. ACE_Service_Config::process_directive(). If the +# Service Configurator is thread safe and reentrant, then parsing of +# this `Service_Config_Test.conf' file should run to completion +# without error. +# +# Test_Object_1 will cause Test_Object_2 and Test_Object_3 to be +# dynamically loaded. Dynamic loading of each of object will occur in +# a separate thread. +dynamic Test_Object_1 Service_Object * Service_Config_DLL:_make_Service_Config_DLL() "2 3" + +# Test_Object_4 will cause Test_Object_5 and Test_Object_6 to be +# dynamically loaded. Dynamic loading of each of object will occur in +# a separate thread. +dynamic Test_Object_4 Service_Object * Service_Config_DLL:_make_Service_Config_DLL() "5 6" + +# Final_Object does nothing but print a completion message. +dynamic Final_Object Service_Object * Service_Config_DLL:_make_Service_Config_DLL() "FINAL" diff --git a/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.conf.xml b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.conf.xml new file mode 100644 index 00000000000..f3273f0cb93 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.conf.xml @@ -0,0 +1,27 @@ +<?xml version='1.0'?> +<!-- Converted from Service_Config_Test.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- Dynamically loading each of the Service Objects below causes a --> + <!-- number of threads to be spawned, each one invoking the Service --> + <!-- Configurator (e.g. ACE_Service_Config::process_directive(). If the --> + <!-- Service Configurator is thread safe and reentrant, then parsing of --> + <!-- this `Service_Config_Test.conf' file should run to completion --> + <!-- without error. --> + <!-- --> + <!-- Test_Object_1 will cause Test_Object_2 and Test_Object_3 to be --> + <!-- dynamically loaded. Dynamic loading of each of object will occur in --> + <!-- a separate thread. --> + <dynamic id="Test_Object_1" type="Service_Object"> + <initializer init="_make_Service_Config_DLL" path="Service_Config_DLL" params="2 3"/> + </dynamic> + <!-- Test_Object_4 will cause Test_Object_5 and Test_Object_6 to be --> + <!-- dynamically loaded. Dynamic loading of each of object will occur in --> + <!-- a separate thread. --> + <dynamic id="Test_Object_4" type="Service_Object"> + <initializer init="_make_Service_Config_DLL" path="Service_Config_DLL" params="5 6"/> + </dynamic> + <!-- Final_Object does nothing but print a completion message. --> + <dynamic id="Final_Object" type="Service_Object"> + <initializer init="_make_Service_Config_DLL" path="Service_Config_DLL" params="FINAL"/> + </dynamic> +</ACE_Svc_Conf> diff --git a/TAO/tests/ORB_Local_Config/Bunch/Test.cpp b/TAO/tests/ORB_Local_Config/Bunch/Test.cpp new file mode 100644 index 00000000000..1e4b802bf75 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Bunch/Test.cpp @@ -0,0 +1,315 @@ +// $Id$ + +#include "tao/CORBANAME_Parser.h" +#include "tao/CORBALOC_Parser.h" +#include "tao/IIOP_Factory.h" +#include "tao/ORBInitializer_Registry_Adapter.h" + +#include "ace/Thread_Manager.h" +#include "ace/ARGV.h" +#include "ace/Dynamic_Service.h" + +ACE_RCSID (tests, server, "$Id$") + + +#include "Service_Configuration_Per_ORB.h" + +// @brief The "new" interfaces must be compatible with the "old" ones + +int +testCompatibility (int , ACE_TCHAR *[]) +{ + ACE_TRACE ("testCompatibility"); + + // This uses the same default ACE_Service_Repository + ACE_Service_Gestalt_Test glob; + + // Use the "old" interface + ACE_ASSERT (0 == ACE_Service_Config::process_directive + (ace_svc_desc_TAO_CORBANAME_Parser)); + ACE_ASSERT (0 == ACE_Service_Config::process_directive + (ace_svc_desc_TAO_CORBALOC_Parser)); + + { + // This uses the same default ACE_Service_Repository + ACE_Service_Gestalt_Test one; + + TAO_CORBANAME_Parser* p20 = + ACE_Dynamic_Service<TAO_CORBANAME_Parser>::instance (&one, "CORBANAME_Parser"); + ACE_ASSERT ((p20 != 0)); + + TAO_CORBALOC_Parser* p21 = + ACE_Dynamic_Service<TAO_CORBALOC_Parser>::instance (&one, "CORBALOC_Parser"); + ACE_ASSERT ((p21 != 0)); + + ACE_DEBUG ((LM_DEBUG, "\tglobal.services_count () -> %d\n", + one.services_count ())); + ACE_ASSERT (32 == one.services_count ()); + + // Exiting this scope should fini all services ... + } + + TAO_CORBANAME_Parser* p20 = + ACE_Dynamic_Service<TAO_CORBANAME_Parser>::instance ("CORBANAME_Parser"); + ACE_ASSERT ((p20 == 0)); + + TAO_CORBALOC_Parser* p21 = + ACE_Dynamic_Service<TAO_CORBALOC_Parser>::instance ("CORBALOC_Parser"); + ACE_ASSERT ((p21 == 0)); + + + + p20 = ACE_Dynamic_Service<TAO_CORBANAME_Parser>::instance (&glob, "CORBANAME_Parser"); + ACE_ASSERT ((p20 == 0)); + + p21 =ACE_Dynamic_Service<TAO_CORBALOC_Parser>::instance (&glob, "CORBALOC_Parser"); + ACE_ASSERT ((p21 == 0)); + + return 0; +} + +// @brief Test commandline processing + + +int +testCommandLineDirectives (int , ACE_TCHAR *[]) +{ + ACE_TRACE ("testCommandLineDirectives"); + + ACE_ARGV new_argv; + ACE_ASSERT (new_argv.add (ACE_TEXT ("-f")) != -1 + && new_argv.add (ACE_TEXT ("-S")) != -1 + && new_argv.add (ACE_TEXT ("d1")) != -1 + && new_argv.add (ACE_TEXT ("-S")) != -1 + && new_argv.add (ACE_TEXT ("d2")) != -1); + + ACE_Service_Gestalt_Test g(5); + ACE_ASSERT (g.parse_args (new_argv.argc (), + new_argv.argv ()) != -1 + || errno == ENOENT); + + ACE_DEBUG ((LM_DEBUG, "\tg.command_line_directives_count () -> %d\n", + g.command_line_directives_count ())); + + ACE_ASSERT (2 == g.command_line_directives_count ()); + return 0; +} + + + +// @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 + ACE_ASSERT (new_argv.add (ACE_TEXT ("bogus")) != -1 + && new_argv.add (ACE_TEXT ("-f")) != -1 + && new_argv.add (file_Service_Config_Test ()) != -1); + + // We need this scope to make sure that the destructor for the + // <ACE_Service_Config> gets called. + ACE_Service_Gestalt_Test daemon(10); + + ACE_ASSERT (daemon.open (new_argv.argc (), + new_argv.argv ()) != -1 || errno == ENOENT); + + ACE_DEBUG ((LM_DEBUG, + "\tdaemon.services_count () -> %d\n", + daemon.services_count ())); + + ACE_ASSERT (5 == daemon.services_count ()); + + // 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"); + + ACE_Service_Gestalt_Test glob; // The global service registrations are here + ACE_Service_Gestalt_Test one (10); // Localized ones go here + + 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 + ACE_ASSERT (loca_size == 0); + + // Lookup it up. + TAO::ORBInitializer_Registry_Adapter* oir = + ACE_Dynamic_Service<TAO::ORBInitializer_Registry_Adapter>::instance + (&one, "ORBInitializer_Registry"); + +#if defined (TAO_AS_STATIC_LIBS) + ACE_ASSERT ((oir != 0)); +#else + ACE_ASSERT ((oir == 0)); +#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_SERVICE_DIRECTIVE("ORBInitializer_Registry", + "TAO_PI", + "_make_ORBInitializer_Registry", + "")); + oir = + ACE_Dynamic_Service<TAO::ORBInitializer_Registry_Adapter>::instance + (&one, "ORBInitializer_Registry"); + } + ACE_ASSERT ((oir != 0)); +#endif + + + ACE_DEBUG ((LM_DEBUG, + "Expected %d global static service registrations, found %d\n", + glob_size, + glob.services_count ())); + + ACE_ASSERT (glob_size == glob.services_count ()); + + ACE_DEBUG ((LM_DEBUG, + "Expected %d local static service registrations, found %d\n", + 5, + one.services_count ())); + + // 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. + // Hence the number 5. + + ACE_ASSERT (loca_size != one.services_count ()); + ACE_ASSERT (5 == one.services_count ()); + + 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<TAO::ORBInitializer_Registry_Adapter>::instance + ("ORBInitializer_Registry"); + + ACE_ASSERT ((oir1 == 0)); // Right! It should not have been global. + + 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<TAO::ORBInitializer_Registry_Adapter>::instance + (&one, "ORBInitializer_Registry"); + + ACE_ASSERT ((oir2 != 0)); // Right! That's local. + + 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); + 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 + ACE_ASSERT (0 != ACE_Dynamic_Service <ACE_Service_Object>::instance + (&one, "CodecFactory_Loader")); + + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Explicitely dynamic_service PolicyFactory_Loader" + " (although ORBInitializer_Registry already did it) ...\n")); + + one.process_directive + (ACE_DYNAMIC_SERVICE_DIRECTIVE("PolicyFactory_Loader", + "TAO_PI", + "_make_TAO_PolicyFactory_Loader", + "")); + + ACE_ASSERT (0 != ACE_Dynamic_Service <ACE_Service_Object>::instance + (&one, "PolicyFactory_Loader")); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) We're done testing.\n")); + return 0; +} + + +// @brief Test the helper components used to implement the temporary +// substitution of the repository currently used as "global" for the +// sake of registering static services, which are dependent on a dynamic +// service + +int +testTSSGestalt (int , ACE_TCHAR *[]) +{ + ACE_TRACE ("testTSSGestalt"); + + ACE_Service_Gestalt_Test one (10); // Localized ones go here + + ACE_Service_Gestalt *global_instance = ACE_Service_Config::instance (); + + ACE_ASSERT (global_instance == ACE_Service_Config::instance ()); + ACE_ASSERT (global_instance != &one); + + { + ACE_Service_Config_Guard temporary (&one); + + ACE_Service_Gestalt *global_instance2 = ACE_Service_Config::instance (); + + ACE_ASSERT (global_instance != global_instance2); + ACE_ASSERT (global_instance2 == &one); + } + + ACE_ASSERT (global_instance == ACE_Service_Config::instance ()); + ACE_ASSERT (global_instance != &one); + + return 0; +} + + + +// @brief the main driver + +int +run_main(int argc, ACE_TCHAR *argv[]) +{ + testCompatibility (argc, argv); + testCommandLineDirectives (argc, argv); + testOpenDynamicServices (argc, argv); + testORBInitializer_Registry(argc, argv); + testTSSGestalt(argc, argv); + return 0; +} + + + + diff --git a/TAO/tests/ORB_Local_Config/Bunch/run_test.pl b/TAO/tests/ORB_Local_Config/Bunch/run_test.pl new file mode 100755 index 00000000000..2b7f1395785 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Bunch/run_test.pl @@ -0,0 +1,49 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../bin'; +use PerlACE::Run_Test; + +sub add_path { + my($name) = shift; + my($value) = shift; + if (defined $ENV{$name}) { + $ENV{$name} .= ':' . $value + } + else { + $ENV{$name} = $value; + } +} + +# Set the library path for the client to be able to load +# the Time_Date library. +add_path('LD_LIBRARY_PATH', '../lib'); +add_path('LIBPATH', '../lib'); +add_path('SHLIB_PATH', '../lib'); + +sub test($) +{ + (my $executable, my $arguments) = @_; + my $t1 = new PerlACE::Process ($executable, ($arguments ? $arguments : "")); + my $status = $t1->SpawnWaitKill (10); + if ($status != 0) { + print STDERR "ERROR: test failed, status=$status\n"; + } + return $status; +} + +my $status = 0; +$status |= test("Test"); + +if ($status == 0) { + print STDERR "SUCCESS: All tests passed\n"; +} +else { + print STDERR "ERROR: Some test failed, status=$status\n"; +} +exit $status; + diff --git a/TAO/tests/ORB_Local_Config/Limits/Limits.mpc b/TAO/tests/ORB_Local_Config/Limits/Limits.mpc new file mode 100644 index 00000000000..c71a117c14b --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Limits/Limits.mpc @@ -0,0 +1,15 @@ +// -*- MPC -*- +// $Id$ + + +project(*) : ../../../tests/acetest, taoserver { + after += lib + exename = Test + includes += ../lib + libpaths += ../lib + libs += lib + Source_Files { + Test.cpp + } +} + diff --git a/TAO/tests/ORB_Local_Config/Limits/Test.cpp b/TAO/tests/ORB_Local_Config/Limits/Test.cpp new file mode 100644 index 00000000000..5f8e5da7d8a --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Limits/Test.cpp @@ -0,0 +1,21 @@ +// $Id$ + +#include "tao/CORBANAME_Parser.h" +#include "tao/CORBALOC_Parser.h" + +#include "Service_Configuration_Per_ORB.h" + +// @brief The size of a repository is pre-determined and can not be exceeded + +int +run_main (int , ACE_TCHAR *[]) +{ + ACE_TRACE ("testTooMany"); + + ACE_Service_Gestalt one(1); // Room for just one ... + ACE_ASSERT (0 == one.process_directive (ace_svc_desc_TAO_CORBANAME_Parser)); + ACE_ASSERT (-1 == one.process_directive (ace_svc_desc_TAO_CORBALOC_Parser)); + ACE_ASSERT (ENOSPC == errno); + ACE_DEBUG ((LM_DEBUG, "%p\n", "\tReporting an expected error: ")); + return 0; +} diff --git a/TAO/tests/ORB_Local_Config/Limits/run_test.pl b/TAO/tests/ORB_Local_Config/Limits/run_test.pl new file mode 100755 index 00000000000..2b7f1395785 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Limits/run_test.pl @@ -0,0 +1,49 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../bin'; +use PerlACE::Run_Test; + +sub add_path { + my($name) = shift; + my($value) = shift; + if (defined $ENV{$name}) { + $ENV{$name} .= ':' . $value + } + else { + $ENV{$name} = $value; + } +} + +# Set the library path for the client to be able to load +# the Time_Date library. +add_path('LD_LIBRARY_PATH', '../lib'); +add_path('LIBPATH', '../lib'); +add_path('SHLIB_PATH', '../lib'); + +sub test($) +{ + (my $executable, my $arguments) = @_; + my $t1 = new PerlACE::Process ($executable, ($arguments ? $arguments : "")); + my $status = $t1->SpawnWaitKill (10); + if ($status != 0) { + print STDERR "ERROR: test failed, status=$status\n"; + } + return $status; +} + +my $status = 0; +$status |= test("Test"); + +if ($status == 0) { + print STDERR "SUCCESS: All tests passed\n"; +} +else { + print STDERR "ERROR: Some test failed, status=$status\n"; +} +exit $status; + diff --git a/TAO/tests/ORB_Local_Config/ORB_Local_Config.mwc b/TAO/tests/ORB_Local_Config/ORB_Local_Config.mwc new file mode 100644 index 00000000000..9237c7d3541 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/ORB_Local_Config.mwc @@ -0,0 +1,14 @@ +// -*- MPC -*- +// $Id$ + +workspace { + lib + Bunch + Bug_1459 + Limits + Separation + Service_Dependency + Shared + Simple + Two_DLL_ORB +} diff --git a/TAO/tests/ORB_Local_Config/README b/TAO/tests/ORB_Local_Config/README new file mode 100644 index 00000000000..013590337f7 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/README @@ -0,0 +1,50 @@ +# $Id$ + +This is a collection of tests for the refactoring of the Service Configurator. +The following executables are self-sufficient test suites: + +These tests require ACE_wrappers/tests/Test_Output. + +test-bunch + + A collection of miscellaneous tests for + * (testCompatibility) Compatibility of the new interfaces with the old; + * (testCommandLineDirectives) Processing of the command-line directives; + * (testOpenDynamicServices) Loading dynamic services in a local repository; + * (testORBInitializer_Registry) Loading the ORBInitializer_Registry locally; + * (testTSSGestalt) Test the helper components used to implement the + temporary substitution of the repository currently used as "global" for the + sake of registering static services, which are dependent on a dynamic + service; + +test-dependency + + * Tests the working of the ACE_Dynamic_Service_Dependency class; + +test-new-cfg + + * + +test-orb-service + + * Loading a dynamic service, which initializes its own ORB; + +test-reusing-globals + + * If all default-constructor-created Service Config instances refer to the + The One Global Configuration; + +test-separation + + * Services registered with separate repositories must remain separate + and inaccessible through anyone but the one they were registered with + +test-simple + + * Dynamic services loading through the new interfaces; + +test-too-many + + * Testing the size limits of a gestalt + +The executables can be run independently, or together using the run_test.pl diff --git a/TAO/tests/ORB_Local_Config/Separation/Separation.mpc b/TAO/tests/ORB_Local_Config/Separation/Separation.mpc new file mode 100644 index 00000000000..02156762f83 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Separation/Separation.mpc @@ -0,0 +1,14 @@ +// -*- MPC -*- +// $Id$ + + +project(*) : ../../../tests/acetest, taoserver { + exename = Test + includes += ../lib + libpaths += ../lib + libs += lib + Source_Files { + Test.cpp + } +} + diff --git a/TAO/tests/ORB_Local_Config/Separation/Test.cpp b/TAO/tests/ORB_Local_Config/Separation/Test.cpp new file mode 100644 index 00000000000..876d43c55b8 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Separation/Test.cpp @@ -0,0 +1,55 @@ +// $Id$ + +#include "tao/CORBANAME_Parser.h" +#include "tao/CORBALOC_Parser.h" +#include "tao/IIOP_Factory.h" + +#include "ace/Dynamic_Service.h" + +#include "Service_Configuration_Per_ORB.h" + +// @brief Services registered with separate repositories must remain separate +// and inaccesible through anyone but the one they were gegistered with + +int +run_main(int , ACE_TCHAR *[]) +{ + ACE_TRACE ("testSeparation"); + + ACE_Service_Gestalt_Test one (10); + + one.process_directive (ace_svc_desc_TAO_CORBANAME_Parser); + + ACE_Service_Gestalt_Test two (10); + + two.process_directive (ace_svc_desc_TAO_CORBALOC_Parser); + + TAO_Protocol_Factory* p10 = + ACE_Dynamic_Service<TAO_Protocol_Factory>::instance (&one, "IIOP_Factory"); + ACE_ASSERT ((p10 == 0)); + + TAO_Protocol_Factory* p11 = + ACE_Dynamic_Service<TAO_Protocol_Factory>::instance (&two, "IIOP_Factory"); + ACE_ASSERT ((p11 == 0)); + + + TAO_CORBANAME_Parser* p20 = + ACE_Dynamic_Service<TAO_CORBANAME_Parser>::instance (&one, "CORBANAME_Parser"); + ACE_ASSERT ((p20 != 0)); + + TAO_CORBALOC_Parser* p21 = + ACE_Dynamic_Service<TAO_CORBALOC_Parser>::instance (&one, "CORBALOC_Parser"); + ACE_ASSERT ((p21 == 0)); + + + TAO_CORBALOC_Parser* p30 = + ACE_Dynamic_Service<TAO_CORBALOC_Parser>::instance (&two, "CORBALOC_Parser"); + ACE_ASSERT ((p30 != 0)); + + TAO_CORBANAME_Parser* p31 = + ACE_Dynamic_Service<TAO_CORBANAME_Parser>::instance (&two, "CORBANAME_Parser"); + ACE_ASSERT ((p31 == 0)); + + return 0; +} + diff --git a/TAO/tests/ORB_Local_Config/Separation/run_test.pl b/TAO/tests/ORB_Local_Config/Separation/run_test.pl new file mode 100755 index 00000000000..2b7f1395785 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Separation/run_test.pl @@ -0,0 +1,49 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../bin'; +use PerlACE::Run_Test; + +sub add_path { + my($name) = shift; + my($value) = shift; + if (defined $ENV{$name}) { + $ENV{$name} .= ':' . $value + } + else { + $ENV{$name} = $value; + } +} + +# Set the library path for the client to be able to load +# the Time_Date library. +add_path('LD_LIBRARY_PATH', '../lib'); +add_path('LIBPATH', '../lib'); +add_path('SHLIB_PATH', '../lib'); + +sub test($) +{ + (my $executable, my $arguments) = @_; + my $t1 = new PerlACE::Process ($executable, ($arguments ? $arguments : "")); + my $status = $t1->SpawnWaitKill (10); + if ($status != 0) { + print STDERR "ERROR: test failed, status=$status\n"; + } + return $status; +} + +my $status = 0; +$status |= test("Test"); + +if ($status == 0) { + print STDERR "SUCCESS: All tests passed\n"; +} +else { + print STDERR "ERROR: Some test failed, status=$status\n"; +} +exit $status; + diff --git a/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.cpp b/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.cpp new file mode 100644 index 00000000000..8e47b64f3a5 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.cpp @@ -0,0 +1,196 @@ +// -*- C++ -*- + +#include "Service_Config_DLL.h" +#include "ace/Service_Config.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID (tests, + Service_Config_DLL, + "$Id$") + +static ACE_THR_FUNC_RETURN +invoke_service_config (void *arg) +{ + const ACE_TCHAR *directive = reinterpret_cast<const ACE_TCHAR *> (arg); + + + // Process a Service Configurator directive in the current thread. + if (ACE_Service_Config::process_directive (directive) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Service_Config_DLL::svc() - ") + ACE_TEXT ("process_directive() failed for:\n") + ACE_TEXT ("\"%s\"\n"), + directive)); + + return 0; +} + +Service_Config_DLL::Service_Config_DLL (void) +{ + ACE_OS::memset (this->directive_[0], 0, BUFSIZ * sizeof (ACE_TCHAR)); + ACE_OS::memset (this->directive_[1], 0, BUFSIZ * sizeof (ACE_TCHAR)); +} + +int +Service_Config_DLL::init (int argc, ACE_TCHAR *argv[]) +{ + if (argc == 2) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Loading Test_Object_%s and Test_Object_%s\n"), + argv[0], + argv[1])); + + ACE_OS::sprintf (this->directive_[0], +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + ACE_TEXT ("dynamic Test_Object_%s Service_Object * Service_Config_DLL:_make_Service_Config_DLL() \"Test_Object_%s\""), +#else + ACE_TEXT ("<?xml version='1.0'?> <dynamic id='Test_Object_%s' type='service_object'> <initializer init='_make_Service_Config_DLL' path='Service_Config_DLL' params='Test_Object_%s'/> </dynamic>"), +#endif + argv[0], + argv[0]); + + ACE_OS::sprintf (this->directive_[1], +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + ACE_TEXT ("dynamic Test_Object_%s Service_Object * Service_Config_DLL:_make_Service_Config_DLL() \"Test_Object_%s\""), +#else + ACE_TEXT ("<?xml version='1.0'?> <dynamic id='Test_Object_%s' type='service_object'> <initializer init='_make_Service_Config_DLL' path='Service_Config_DLL' params='Test_Object_%s'/> </dynamic>"), +#endif + + argv[1], + argv[1]); + + if (ACE_Service_Config::process_directive (this->directive_[0]) != 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Service_Config_DLL::init() - ") + ACE_TEXT ("process_directive() failed for:\n") + ACE_TEXT ("\"%s\"\n"), + this->directive_[0])); + +#if defined (ACE_HAS_THREADS) + + // Become an Active Object if more than one argument passed. + // Two arguments indicate two "test objects" to be dynamically + // loaded. + return this->activate (); + +#endif /* ACE_HAS_THREADS */ + + } + else if (argc == 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Service_Config_DLL::init () - %s\n"), + argv[0])); + } + else + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Incorrect number of arguments ") + ACE_TEXT ("(%d) passed to Service_Config_DLL::init ()"), + argc), + -1); + } + + return 0; +} + +int +Service_Config_DLL::fini (void) +{ + return 0; +} + +int +Service_Config_DLL::svc (void) +{ + if (ACE_Thread_Manager::instance ()->spawn (invoke_service_config, + this->directive_[1]) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Unable to spawn thread to ") + ACE_TEXT ("invoke Service Configurator.\n")), + -1); + + return 0; +} + +// The same class (Service_Config_DLL) is used to implement each of the +// Service Objects whose service descriptors are defined below. + +// ----------------------------------------------------------------- + +ACE_STATIC_SVC_DEFINE (Test_Object_1, + ACE_TEXT ("Test_Object_1"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (Service_Config_DLL), + ACE_Service_Type::DELETE_THIS + | ACE_Service_Type::DELETE_OBJ, + 0) + +// ----------------------------------------------------------------- + +ACE_STATIC_SVC_DEFINE (Test_Object_2, + ACE_TEXT ("Test_Object_2"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (Service_Config_DLL), + ACE_Service_Type::DELETE_THIS + | ACE_Service_Type::DELETE_OBJ, + 0) + +// ----------------------------------------------------------------- + +ACE_STATIC_SVC_DEFINE (Test_Object_3, + ACE_TEXT ("Test_Object_3"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (Service_Config_DLL), + ACE_Service_Type::DELETE_THIS + | ACE_Service_Type::DELETE_OBJ, + 0) + +// ----------------------------------------------------------------- + +ACE_STATIC_SVC_DEFINE (Test_Object_4, + ACE_TEXT ("Test_Object_4"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (Service_Config_DLL), + ACE_Service_Type::DELETE_THIS + | ACE_Service_Type::DELETE_OBJ, + 0) + +// ----------------------------------------------------------------- + +ACE_STATIC_SVC_DEFINE (Test_Object_5, + ACE_TEXT ("Test_Object_5"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (Service_Config_DLL), + ACE_Service_Type::DELETE_THIS + | ACE_Service_Type::DELETE_OBJ, + 0) + +// ----------------------------------------------------------------- + +ACE_STATIC_SVC_DEFINE (Test_Object_6, + ACE_TEXT ("Test_Object_6"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (Service_Config_DLL), + ACE_Service_Type::DELETE_THIS + | ACE_Service_Type::DELETE_OBJ, + 0) + +// ----------------------------------------------------------------- + +ACE_STATIC_SVC_DEFINE (Final_Object, + ACE_TEXT ("Final_Object"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (Service_Config_DLL), + ACE_Service_Type::DELETE_THIS + | ACE_Service_Type::DELETE_OBJ, + 0) + +// ----------------------------------------------------------------- + +// Same factory is used for all service descriptors defined above. +ACE_FACTORY_DEFINE (Service_Config_DLL, Service_Config_DLL) + + diff --git a/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.h b/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.h new file mode 100644 index 00000000000..3875b70aef8 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.h @@ -0,0 +1,69 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Service_Config_DLL.h + * + * $Id$ + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + +#ifndef SERVICE_CONFIG_DLL_H +#define SERVICE_CONFIG_DLL_H + +#include /**/ "ace/pre.h" + +#include "Service_Config_DLL_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Task.h" + +/** + * @class Service_Config_DLL + * + * @brief The Service_Config_DLL that is instantiated when the + * client-side test module/library is dynamically loaded. + * + * This class is the implementation used for all service instances + * (i.e. those declared using the ACE_FACTORY_* macros). + */ +class Service_Config_DLL_Export Service_Config_DLL : public ACE_Task_Base +{ +public: + + /// Constructor. + Service_Config_DLL (void); + + /// Initializes object when dynamic linking occurs. + virtual int init (int argc, ACE_TCHAR *argv[]); + + /// Terminates object when dynamic unlinking occurs. + virtual int fini (void); + + /// Run by a daemon thread. + /** + * Each thread will invoke the Service Configurator via this + * method unless the object is the "FINAL" object. + */ + virtual int svc (void); + +private: + + /// Directives to be passed to be processed by the Service + /// Configurator in seperate threads. + ACE_TCHAR directive_[2][BUFSIZ]; + +}; + + +ACE_FACTORY_DECLARE (Service_Config_DLL, Service_Config_DLL) + + +#include /**/ "ace/post.h" + +#endif /* SERVICE_CONFIG_DLL_H */ diff --git a/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL_Export.h b/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL_Export.h new file mode 100644 index 00000000000..1688a745350 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL_Export.h @@ -0,0 +1,38 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl +// ------------------------------ +#ifndef SERVICE_CONFIG_DLL_EXPORT_H +#define SERVICE_CONFIG_DLL_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (SERVICE_CONFIG_DLL_HAS_DLL) +# define SERVICE_CONFIG_DLL_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && ! SERVICE_CONFIG_DLL_HAS_DLL */ + +#if !defined (SERVICE_CONFIG_DLL_HAS_DLL) +# define SERVICE_CONFIG_DLL_HAS_DLL 1 +#endif /* ! TEST_HAS_DLL */ + +#if defined (SERVICE_CONFIG_DLL_HAS_DLL) && (SERVICE_CONFIG_DLL_HAS_DLL == 1) +# if defined (SERVICE_CONFIG_DLL_BUILD_DLL) +# define Service_Config_DLL_Export ACE_Proper_Export_Flag +# define TEST_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* SERVICE_CONFIG_DLL_BUILD_DLL */ +# define Service_Config_DLL_Export ACE_Proper_Import_Flag +# define TEST_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* SERVICE_CONFIG_DLL_BUILD_DLL */ +#else /* SERVICE_CONFIG_DLL_HAS_DLL == 1 */ +# define Service_Config_DLL_Export +# define TEST_SINGLETON_DECLARATION(T) +# define TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* SERVICE_CONFIG_DLL_HAS_DLL == 1 */ + +#endif /* SERVICE_CONFIG_DLL_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Dependency.mpc b/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Dependency.mpc new file mode 100644 index 00000000000..76c9f08d074 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Service_Dependency/Service_Dependency.mpc @@ -0,0 +1,28 @@ +// -*- MPC -*- +// $Id$ + +project(*) : ../../../tests/acetest, taoserver { + after += lib Service_Config_DLL TAO + exename = Test + includes += ../lib + libpaths += ../lib + libs += lib + Source_Files { + Test.cpp + } +} + +project(Service Config DLL) : acelib { + sharedname = Service_Config_DLL + dynamicflags = SERVICE_CONFIG_DLL_BUILD_DLL + + Source_Files { + Service_Config_DLL.cpp + } + Header_Files { + Service_Config_DLL.h + Service_Config_DLL_Export.h + } +} + + diff --git a/TAO/tests/ORB_Local_Config/Service_Dependency/Test.cpp b/TAO/tests/ORB_Local_Config/Service_Dependency/Test.cpp new file mode 100644 index 00000000000..bb211a3b619 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Service_Dependency/Test.cpp @@ -0,0 +1,66 @@ +// $Id$ + +#include "tao/Codeset_Descriptor_Base.h" +#include "tao/Codeset_Manager_Factory_Base.h" +#include "tao/Codeset_Manager.h" + +#include "ace/Dynamic_Service.h" +#include "ace/Dynamic_Service_Dependency.h" + +#include "Service_Configuration_Per_ORB.h" + +// @brief ... + + +int +run_main(int , ACE_TCHAR *[]) +{ + ACE_TRACE ("testDependency"); + + 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_Service_Gestalt_Test one (10); + + int result = one.process_directive + (ACE_DYNAMIC_SERVICE_DIRECTIVE("TAO_Codeset", + "TAO_Codeset", + "_make_TAO_Codeset_Manager_Factory", + "")); + ACE_ASSERT (result == 0); + + TAO_Codeset_Manager_Factory_Base *factory = + ACE_Dynamic_Service<TAO_Codeset_Manager_Factory_Base>::instance (&one, "TAO_Codeset"); + ACE_ASSERT (factory != 0); + + codeset_manager = factory->create (); + ACE_ASSERT (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, "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; +} + diff --git a/TAO/tests/ORB_Local_Config/Service_Dependency/run_test.pl b/TAO/tests/ORB_Local_Config/Service_Dependency/run_test.pl new file mode 100755 index 00000000000..2b7f1395785 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Service_Dependency/run_test.pl @@ -0,0 +1,49 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../bin'; +use PerlACE::Run_Test; + +sub add_path { + my($name) = shift; + my($value) = shift; + if (defined $ENV{$name}) { + $ENV{$name} .= ':' . $value + } + else { + $ENV{$name} = $value; + } +} + +# Set the library path for the client to be able to load +# the Time_Date library. +add_path('LD_LIBRARY_PATH', '../lib'); +add_path('LIBPATH', '../lib'); +add_path('SHLIB_PATH', '../lib'); + +sub test($) +{ + (my $executable, my $arguments) = @_; + my $t1 = new PerlACE::Process ($executable, ($arguments ? $arguments : "")); + my $status = $t1->SpawnWaitKill (10); + if ($status != 0) { + print STDERR "ERROR: test failed, status=$status\n"; + } + return $status; +} + +my $status = 0; +$status |= test("Test"); + +if ($status == 0) { + print STDERR "SUCCESS: All tests passed\n"; +} +else { + print STDERR "ERROR: Some test failed, status=$status\n"; +} +exit $status; + diff --git a/TAO/tests/ORB_Local_Config/Shared/Shared.mpc b/TAO/tests/ORB_Local_Config/Shared/Shared.mpc new file mode 100644 index 00000000000..02156762f83 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Shared/Shared.mpc @@ -0,0 +1,14 @@ +// -*- MPC -*- +// $Id$ + + +project(*) : ../../../tests/acetest, taoserver { + exename = Test + includes += ../lib + libpaths += ../lib + libs += lib + Source_Files { + Test.cpp + } +} + diff --git a/TAO/tests/ORB_Local_Config/Shared/Test.cpp b/TAO/tests/ORB_Local_Config/Shared/Test.cpp new file mode 100644 index 00000000000..595c4aff3a5 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Shared/Test.cpp @@ -0,0 +1,50 @@ +// $Id$ + +#include "tao/CORBANAME_Parser.h" +#include "tao/CORBALOC_Parser.h" +#include "tao/Protocol_Factory.h" +#include "ace/Dynamic_Service.h" + +#include "Service_Configuration_Per_ORB.h" + +// @brief All default-constructor-created Service Config instabces referr to the +// The One Global Configuration + +int +run_main(int , ACE_TCHAR *[]) +{ + ACE_TRACE ("testReusingGlobals"); + + { + ACE_Service_Gestalt/*_Test*/ one; // The ACE_Service_Gestalt_Test will teardown all! + + one.process_directive (ace_svc_desc_TAO_CORBANAME_Parser); + one.process_directive (ace_svc_desc_TAO_CORBALOC_Parser); + + TAO_Protocol_Factory* p1 = + ACE_Dynamic_Service<TAO_Protocol_Factory>::instance (&one, "IIOP_Factory"); + + ACE_ASSERT ((p1 == 0)); + + TAO_CORBANAME_Parser* p2 = + ACE_Dynamic_Service<TAO_CORBANAME_Parser>::instance (&one, "CORBANAME_Parser"); + + ACE_ASSERT ((p2 != 0)); + + TAO_CORBALOC_Parser* p3 = + ACE_Dynamic_Service<TAO_CORBALOC_Parser>::instance (&one, "CORBALOC_Parser"); + + ACE_ASSERT ((p3 != 0)); + } + + + ACE_Service_Gestalt_Test two; // Use the ACE_Service_Repository::instance () + + TAO_CORBANAME_Parser* p2 = + ACE_Dynamic_Service<TAO_CORBANAME_Parser>::instance (&two, "CORBANAME_Parser"); + + ACE_ASSERT ((p2 != 0)); // You should be able to find the same stuff here, too + + return 0; +} + diff --git a/TAO/tests/ORB_Local_Config/Shared/run_test.pl b/TAO/tests/ORB_Local_Config/Shared/run_test.pl new file mode 100755 index 00000000000..2b7f1395785 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Shared/run_test.pl @@ -0,0 +1,49 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../bin'; +use PerlACE::Run_Test; + +sub add_path { + my($name) = shift; + my($value) = shift; + if (defined $ENV{$name}) { + $ENV{$name} .= ':' . $value + } + else { + $ENV{$name} = $value; + } +} + +# Set the library path for the client to be able to load +# the Time_Date library. +add_path('LD_LIBRARY_PATH', '../lib'); +add_path('LIBPATH', '../lib'); +add_path('SHLIB_PATH', '../lib'); + +sub test($) +{ + (my $executable, my $arguments) = @_; + my $t1 = new PerlACE::Process ($executable, ($arguments ? $arguments : "")); + my $status = $t1->SpawnWaitKill (10); + if ($status != 0) { + print STDERR "ERROR: test failed, status=$status\n"; + } + return $status; +} + +my $status = 0; +$status |= test("Test"); + +if ($status == 0) { + print STDERR "SUCCESS: All tests passed\n"; +} +else { + print STDERR "ERROR: Some test failed, status=$status\n"; +} +exit $status; + diff --git a/TAO/tests/ORB_Local_Config/Simple/Simple.mpc b/TAO/tests/ORB_Local_Config/Simple/Simple.mpc new file mode 100644 index 00000000000..c71a117c14b --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Simple/Simple.mpc @@ -0,0 +1,15 @@ +// -*- MPC -*- +// $Id$ + + +project(*) : ../../../tests/acetest, taoserver { + after += lib + exename = Test + includes += ../lib + libpaths += ../lib + libs += lib + Source_Files { + Test.cpp + } +} + diff --git a/TAO/tests/ORB_Local_Config/Simple/Test.cpp b/TAO/tests/ORB_Local_Config/Simple/Test.cpp new file mode 100644 index 00000000000..f0285549bac --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Simple/Test.cpp @@ -0,0 +1,39 @@ +// $Id$ + +#include "tao/CORBANAME_Parser.h" +#include "tao/CORBALOC_Parser.h" +#include "tao/Protocol_Factory.h" +#include "ace/Dynamic_Service.h" + +#include "Service_Configuration_Per_ORB.h" + + +// @brief Dynamic services loading + +int +run_main (int , ACE_TCHAR *[]) +{ + ACE_TRACE ("testSimple"); + + ACE_Service_Gestalt_Test one; // Use the ACE_Service_Repository::instance () + + one.process_directive (ace_svc_desc_TAO_CORBANAME_Parser); + one.process_directive (ace_svc_desc_TAO_CORBALOC_Parser); + + TAO_Protocol_Factory* p1 = + ACE_Dynamic_Service<TAO_Protocol_Factory>::instance (&one, "IIOP_Factory"); + + ACE_ASSERT ((p1 == 0)); + + TAO_CORBANAME_Parser* p2 = + ACE_Dynamic_Service<TAO_CORBANAME_Parser>::instance (&one, "CORBANAME_Parser"); + + ACE_ASSERT ((p2 != 0)); + + TAO_CORBALOC_Parser* p3 = + ACE_Dynamic_Service<TAO_CORBALOC_Parser>::instance (&one, "CORBALOC_Parser"); + + ACE_ASSERT ((p3 != 0)); + + return 0; +} diff --git a/TAO/tests/ORB_Local_Config/Simple/run_test.pl b/TAO/tests/ORB_Local_Config/Simple/run_test.pl new file mode 100755 index 00000000000..2b7f1395785 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Simple/run_test.pl @@ -0,0 +1,49 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../bin'; +use PerlACE::Run_Test; + +sub add_path { + my($name) = shift; + my($value) = shift; + if (defined $ENV{$name}) { + $ENV{$name} .= ':' . $value + } + else { + $ENV{$name} = $value; + } +} + +# Set the library path for the client to be able to load +# the Time_Date library. +add_path('LD_LIBRARY_PATH', '../lib'); +add_path('LIBPATH', '../lib'); +add_path('SHLIB_PATH', '../lib'); + +sub test($) +{ + (my $executable, my $arguments) = @_; + my $t1 = new PerlACE::Process ($executable, ($arguments ? $arguments : "")); + my $status = $t1->SpawnWaitKill (10); + if ($status != 0) { + print STDERR "ERROR: test failed, status=$status\n"; + } + return $status; +} + +my $status = 0; +$status |= test("Test"); + +if ($status == 0) { + print STDERR "SUCCESS: All tests passed\n"; +} +else { + print STDERR "ERROR: Some test failed, status=$status\n"; +} +exit $status; + diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.cpp b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.cpp new file mode 100644 index 00000000000..0ded5ce3258 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.cpp @@ -0,0 +1,134 @@ +// -*- C++ -*- + +#include "ORB_DLL.h" +#include "ace/Service_Config.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_strings.h" + +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" + +ACE_RCSID (tests, + ORB_DLL, + "$Id$") + + +// +Abstract_Worker::Abstract_Worker (const char* s) + : ior_file_ (s) +{ +} + +// +Abstract_Worker::~Abstract_Worker (void) +{ +} + + +// +Service_Config_ORB_DLL::Service_Config_ORB_DLL (void) + : is_server_ (-1) + , worker_ (0) + , argv_ (0) +{ +} + +// +Service_Config_ORB_DLL::~Service_Config_ORB_DLL (void) +{ +} + +// +int +Service_Config_ORB_DLL::init (int argc, ACE_TCHAR *argv[]) +{ + ACE_ARGV* tmp = 0; + ACE_NEW_RETURN (tmp, ACE_ARGV (argv), -1); + this->argv_.reset (tmp); + + ACE_Get_Opt get_opts (argc, argv, "cs"); + for (int c=0;((c = get_opts ()) != -1); ) + switch (c) + { + case 'c': + this->is_server_ = 0; + break; + + case 's': + this->is_server_ = 1; + break; + } + + if (this->is_server_ < 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) You must specify -c(lient) or -s(erver) argument. Aborting."), -1); + + Abstract_Worker* worker = 0; + if (this->is_server_) + { + ACE_NEW_RETURN (worker, Server_Worker, -1); + } + else + { + ACE_NEW_RETURN (worker, Client_Worker, -1); + } + this->worker_.reset (worker); + +#if defined (ACE_HAS_THREADS) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) About to activate %s, argv[%d]=\'%s\' ...\n"), + this->worker_->kind (), + this->argv_->argc (), + this->argv_->buf ())); + + // Become an Active Object if more than one argument passed. + // Two arguments indicate two "test objects" to be dynamically + // loaded. + return this->activate (); +#else + ACE_ERROR_RETURN (("(%P|%t) Threading support is required for this test. Aborting."), -1); +#endif /* ACE_HAS_THREADS */ +} + +int +Service_Config_ORB_DLL::svc (void) +{ + ACE_ASSERT (this->worker_.get () != 0); + ACE_ASSERT (this->argv_.get () != 0); + + ACE_DECLARE_NEW_ENV; + ACE_TRY + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) %@ %s is active, argv[%d]=\'%s\'\n"), + this, + this->worker_->kind (), + this->argv_->argc (), + this->argv_->buf ())); + + int ret = this->worker_->main (this->argv_->argc (), this->argv_->argv () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) %@ %s bowes out - so long, cruel world! (%d)\n"), + this, + this->worker_->kind (), + ret)); + return ret; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, ACE_TEXT("Failure:")); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) Aborting.\n")), + -1); + } + ACE_ENDTRY; + +} + + +// Define our service for using with the Service Configurator +ACE_FACTORY_DEFINE (Service_Config_ORB_DLL, Service_Config_ORB_DLL) + + + diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.h b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.h new file mode 100644 index 00000000000..061340149c1 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.h @@ -0,0 +1,112 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file ORB_DLL.h + * + * $Id$ + * + * @author Iliyan Jeliazkov <iliyan@ociweb.com> + */ +//============================================================================= + +#ifndef SERVICE_CONFIG_ORB_DLL_H +#define SERVICE_CONFIG_ORB_DLL_H + +#include /**/ "ace/pre.h" + +#include "ORB_DLL_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Task.h" +#include "ace/ARGV.h" +#include "ace/String_Base.h" +#include "tao/ORB.h" + +/// +class Abstract_Worker +{ +public: + Abstract_Worker (const char* ior); + virtual ~Abstract_Worker (void); + virtual int main (int argc, + ACE_TCHAR *argv[] ACE_ENV_ARG_DECL_WITH_DEFAULTS) = 0; + virtual const ACE_TCHAR * kind (void) const = 0; +protected: + ACE_TString ior_file_; +}; + +/** + * A server kind of test + */ +class Server_Worker : public Abstract_Worker +{ +public: + Server_Worker (); + ~Server_Worker (void); + int main (int argc, ACE_TCHAR *argv[] ACE_ENV_ARG_DECL_WITH_DEFAULTS); + const ACE_TCHAR * kind (void) const; + +private: + int parse_args (int argc, ACE_TCHAR *argv[]); +}; + +/** + * A client kind of test + */ +class Client_Worker : public Abstract_Worker +{ +public: + Client_Worker (); + ~Client_Worker (void); + int main (int argc, ACE_TCHAR *argv[] ACE_ENV_ARG_DECL_WITH_DEFAULTS); + const ACE_TCHAR * kind (void) const; + +private: + int parse_args (int argc, ACE_TCHAR *argv[]); +}; + + +/** + * @class Service_Config_ORB_DLL + * + * @brief The Service_Config_ORB_DLL that is instantiated when the + * client-side test module/library is dynamically loaded. + * + */ +class Service_Config_ORB_DLL_Export Service_Config_ORB_DLL + : public ACE_Task_Base +{ +public: + + /// Constructor. + Service_Config_ORB_DLL (void); + ~Service_Config_ORB_DLL (void); + + /// Initializes object when dynamic linking occurs. + virtual int init (int argc, ACE_TCHAR *argv[]); + + /// Run by a daemon thread. + /** + * Each thread will invoke the Service Configurator via this + * method unless the object is the "FINAL" object. + */ + virtual int svc (void); + +private: + signed char is_server_; + auto_ptr<Abstract_Worker> worker_; + auto_ptr<ACE_ARGV> argv_; +}; + + +ACE_FACTORY_DECLARE (Service_Config_ORB_DLL, Service_Config_ORB_DLL) + + + +#include /**/ "ace/post.h" + +#endif /* SERVICE_CONFIG_ORB_DLL_H */ diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL_Export.h b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL_Export.h new file mode 100644 index 00000000000..3812349efcd --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL_Export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl Service_Config_ORB_DLL +// ------------------------------ +#ifndef SERVICE_CONFIG_ORB_DLL_EXPORT_H +#define SERVICE_CONFIG_ORB_DLL_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (SERVICE_CONFIG_ORB_DLL_HAS_DLL) +# define SERVICE_CONFIG_ORB_DLL_HAS_DLL 1 +#endif /* ! SERVICE_CONFIG_ORB_DLL_HAS_DLL */ + +#if defined (SERVICE_CONFIG_ORB_DLL_HAS_DLL) && (SERVICE_CONFIG_ORB_DLL_HAS_DLL == 1) +# if defined (SERVICE_CONFIG_ORB_DLL_BUILD_DLL) +# define Service_Config_ORB_DLL_Export ACE_Proper_Export_Flag +# define SERVICE_CONFIG_ORB_DLL_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define SERVICE_CONFIG_ORB_DLL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* SERVICE_CONFIG_ORB_DLL_BUILD_DLL */ +# define Service_Config_ORB_DLL_Export ACE_Proper_Import_Flag +# define SERVICE_CONFIG_ORB_DLL_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define SERVICE_CONFIG_ORB_DLL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* SERVICE_CONFIG_ORB_DLL_BUILD_DLL */ +#else /* SERVICE_CONFIG_ORB_DLL_HAS_DLL == 1 */ +# define Service_Config_ORB_DLL_Export +# define SERVICE_CONFIG_ORB_DLL_SINGLETON_DECLARATION(T) +# define SERVICE_CONFIG_ORB_DLL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* SERVICE_CONFIG_ORB_DLL_HAS_DLL == 1 */ + +// Set SERVICE_CONFIG_ORB_DLL_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (SERVICE_CONFIG_ORB_DLL_NTRACE) +# if (ACE_NTRACE == 1) +# define SERVICE_CONFIG_ORB_DLL_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define SERVICE_CONFIG_ORB_DLL_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !SERVICE_CONFIG_ORB_DLL_NTRACE */ + +#if (SERVICE_CONFIG_ORB_DLL_NTRACE == 1) +# define SERVICE_CONFIG_ORB_DLL_TRACE(X) +#else /* (SERVICE_CONFIG_ORB_DLL_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define SERVICE_CONFIG_ORB_DLL_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (SERVICE_CONFIG_ORB_DLL_NTRACE == 1) */ + +#endif /* SERVICE_CONFIG_ORB_DLL_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test.conf b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test.conf new file mode 100644 index 00000000000..536102ed7cd --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test.conf @@ -0,0 +1,5 @@ +dynamic ORB_DLL_Server Service_Object * ORB_DLL_Server:_make_Service_Config_ORB_DLL() "dummy_server -s -ORBId SERVER" +dynamic ORB_DLL_Client Service_Object * ORB_DLL_Client:_make_Service_Config_ORB_DLL() "dummy_client -c -ORBId CLIENT" + +#dynamic ORB_DLL_Server Service_Object * ORB_DLL_Server:_make_Service_Config_ORB_DLL() "-s -ORBDebugLevel 10 -ORBId SERVER -ORBSvcConf Service_Config_ORB_Test2.conf" +#dynamic ORB_DLL_Client Service_Object * ORB_DLL_Client:_make_Service_Config_ORB_DLL() "-c -ORBDebugLevel 10 -ORBId CLIENT -ORBSvcConf Service_Config_ORB_Test2.conf" diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test2.conf b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test2.conf new file mode 100644 index 00000000000..477c4795007 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test2.conf @@ -0,0 +1 @@ +# Nothing so far diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test.cpp b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test.cpp new file mode 100644 index 00000000000..d39bea396c5 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test.cpp @@ -0,0 +1,34 @@ +// $Id$ + +#include "ace/ARGV.h" +#include "ace/Thread_Manager.h" + +#include "Service_Configuration_Per_ORB.h" + +// @brief Loading a dynamic services in a local repository, which +// initializes its own ORB + +int +run_main (int , ACE_TCHAR *argv[]) +{ + ACE_TRACE ("testORBBasedService"); + + ACE_ARGV new_argv; + + ACE_DEBUG ((LM_DEBUG, "Looking for conf file %s\n", file_Service_Config_ORB_Test ())); + + // Process the Service Configurator directives in this test's + ACE_ASSERT (new_argv.add (argv) != -1 + && new_argv.add (ACE_TEXT ("-f")) != -1 + && new_argv.add (file_Service_Config_ORB_Test ()) != -1); + + ACE_ASSERT (ACE_Service_Config::instance() ->open (new_argv.argc (), + new_argv.argv ()) != -1 || errno == ENOENT); + + + // 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; +} + diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test.idl b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test.idl new file mode 100644 index 00000000000..3c0976e106d --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test.idl @@ -0,0 +1,20 @@ +// +// $Id$ +// + +/// Put the interfaces in a module, to avoid global namespace pollution +module Test +{ + /// A very simple interface + interface Hello + { + /// Return a simple string + string get_string (); + + /// A method to shutdown the ORB + /** + * This method is used to simplify the test shutdown process + */ + oneway void shutdown (); + }; +}; diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test_i.cpp b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test_i.cpp new file mode 100644 index 00000000000..97c8347258a --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test_i.cpp @@ -0,0 +1,25 @@ +// +// $Id$ +// +#include "Test_i.h" + +ACE_RCSID(Hello, Hello, "$Id$") + +Hello::Hello (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)) +{ +} + +char * +Hello::get_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup ("Hello there!"); +} + +void +Hello::shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test_i.h b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test_i.h new file mode 100644 index 00000000000..1a404058944 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test_i.h @@ -0,0 +1,33 @@ +// +// $Id$ +// + +#ifndef HELLO_H +#define HELLO_H +#include /**/ "ace/pre.h" + +#include "TestS.h" + +/// Implement the Test::Hello interface +class Hello + : public virtual POA_Test::Hello +{ +public: + /// Constructor + Hello (CORBA::ORB_ptr orb); + + // = The skeleton methods + virtual char * get_string (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + /// Use an ORB reference to conver strings to objects and shutdown + /// the application. + CORBA::ORB_var orb_; +}; + +#include /**/ "ace/post.h" +#endif /* HELLO_H */ diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Two_DLL_ORB.mpc b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Two_DLL_ORB.mpc new file mode 100644 index 00000000000..636f83716aa --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Two_DLL_ORB.mpc @@ -0,0 +1,63 @@ +// -*- MPC -*- +// $Id$ + +project(ORB DLL Server) : taolib_with_idl { + sharedname = ORB_DLL_Server + dynamicflags = ORB_DLL_BUILD_DLL + + IDL_Files { + Test.idl + } + + Source_Files { + ORB_DLL.cpp + Test_i.cpp + TestC.cpp + TestS.cpp + server.cpp + client.cpp + } + Header_Files { + ORB_DLL.h + ORB_DLL_Export.h + } + Resource_Files { + } +} + +project(ORB DLL Client) : taolib_with_idl { + sharedname = ORB_DLL_Client + dynamicflags = ORB_DLL_BUILD_DLL + + IDL_Files { + Test.idl + } + + Source_Files { + ORB_DLL.cpp + TestC.cpp + client.cpp + server.cpp + } + Header_Files { + ORB_DLL.h + ORB_DLL_Export.h + } + Resource_Files { + } +} + + +project(*) : ../../../tests/acetest, taoserver { + after += lib ORB_DLL_Client ORB_DLL_Server + exename = Test + includes += ../lib + libpaths += ../lib + libs += lib + Source_Files { + Test.cpp + } +} + + + diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/client.cpp b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/client.cpp new file mode 100644 index 00000000000..41e6f5c43fe --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/client.cpp @@ -0,0 +1,110 @@ +// $Id$ + +#include "Test_i.h" +#include "ORB_DLL.h" + +//#include "TestC.h" +#include "ace/Get_Opt.h" +#include "ace/Argv_Type_Converter.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(Hello, client, "$Id$") + +Client_Worker::Client_Worker () + : Abstract_Worker ("file://test.ior") +{ + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) %@ Client::<ctor>\n", this)); +} + +const ACE_TCHAR * +Client_Worker::kind (void) const +{ + return ACE_TEXT ("Client"); +} + +Client_Worker::~Client_Worker (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) %@ Client::<dtor>\n", this)); +} + +int +Client_Worker::parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:"); + + for( int c = 0; ((c = get_opts ()) != -1); ) + switch (c) + { + case 'k': + this->ior_file_ = get_opts.opt_arg (); + break; + } + + // Indicates sucessful parsing of the command line + return 0; +} + +int +Client_Worker::main (int argc, ACE_TCHAR *argv[] ACE_ENV_ARG_DECL) +{ + + ACE_Argv_Type_Converter cvt (argc, argv); + CORBA::ORB_var orb = CORBA::ORB_init (cvt.get_argc (), cvt.get_ASCII_argv () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (cvt.get_argc (), cvt.get_ASCII_argv ()) != 0) + return 1; + + // Doing this dance to allow the server some time to come up. + CORBA::Object_ptr co = 0; + for (int attempts_left=5; co == 0 && attempts_left > 0; --attempts_left) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) Delaying the client to give the server a chance to start ...\n")); + ACE_OS::sleep (5); + + ACE_TRY + { + co = orb->string_to_object(ior_file_.c_str () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::TRANSIENT, ex) + { + if (!attempts_left) + ACE_RE_THROW; + } + ACE_ENDTRY; + } + + ACE_ASSERT (co != 0); + CORBA::Object_var tmp (co); + + Test::Hello_var hello = + Test::Hello::_narrow(tmp.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (hello.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "(%P|%t) Nil Test::Hello reference <%s>\n", + ior_file_.c_str ()), + 1); + } + + CORBA::String_var the_string = + hello->get_string (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) - string returned from the server <%s>\n", + the_string.in ())); + + hello->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->shutdown (0 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + return 0; +} diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/run_test.pl b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/run_test.pl new file mode 100755 index 00000000000..2b7f1395785 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/run_test.pl @@ -0,0 +1,49 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../bin'; +use PerlACE::Run_Test; + +sub add_path { + my($name) = shift; + my($value) = shift; + if (defined $ENV{$name}) { + $ENV{$name} .= ':' . $value + } + else { + $ENV{$name} = $value; + } +} + +# Set the library path for the client to be able to load +# the Time_Date library. +add_path('LD_LIBRARY_PATH', '../lib'); +add_path('LIBPATH', '../lib'); +add_path('SHLIB_PATH', '../lib'); + +sub test($) +{ + (my $executable, my $arguments) = @_; + my $t1 = new PerlACE::Process ($executable, ($arguments ? $arguments : "")); + my $status = $t1->SpawnWaitKill (10); + if ($status != 0) { + print STDERR "ERROR: test failed, status=$status\n"; + } + return $status; +} + +my $status = 0; +$status |= test("Test"); + +if ($status == 0) { + print STDERR "SUCCESS: All tests passed\n"; +} +else { + print STDERR "ERROR: Some test failed, status=$status\n"; +} +exit $status; + diff --git a/TAO/tests/ORB_Local_Config/Two_DLL_ORB/server.cpp b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/server.cpp new file mode 100644 index 00000000000..f9b53292977 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/server.cpp @@ -0,0 +1,129 @@ +// $Id$ + + +#include "Test_i.h" +#include "ORB_DLL.h" + +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" +#include "ace/Argv_Type_Converter.h" + + +ACE_RCSID (Hello, + server, + "$Id$") + +// +Server_Worker::Server_Worker () + : Abstract_Worker ("test.ior") +{ + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) %@ Server::<ctor>\n", this)); +} + +// +const ACE_TCHAR * +Server_Worker::kind (void) const +{ + return ACE_TEXT ("Server"); +} + +// +Server_Worker::~Server_Worker (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) %@ Server::<dtor>\n", this)); +} + +// +int +Server_Worker::parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:"); + + for( int c = 0; ((c = get_opts ()) != -1); ) + switch (c) + { + case 'o': + this->ior_file_ = get_opts.opt_arg (); + break; + } + + // Indicates sucessful parsing of the command line + return 0; +} + +// +int +Server_Worker::main (int argc, ACE_TCHAR *argv[] ACE_ENV_ARG_DECL) +{ + ACE_Argv_Type_Converter cvt (argc, argv); + CORBA::ORB_var orb = CORBA::ORB_init (cvt.get_argc (), cvt.get_ASCII_argv () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var poa_object = + orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (root_poa.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Panic: nil RootPOA\n"), + 1); + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (cvt.get_argc (), cvt.get_ASCII_argv ()) != 0) + return 1; + + Hello *hello_impl; + ACE_NEW_RETURN (hello_impl, + Hello (orb.in ()), + 1); + PortableServer::ServantBase_var owner_transfer(hello_impl); + + Test::Hello_var hello = + hello_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::String_var ior = + orb->object_to_string (hello.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Output the IOR to the <ior_output_file> + FILE *output_file= ACE_OS::fopen (ior_file_.c_str (), "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) Cannot open output file for writing IOR: %s", + ior_file_.c_str ()), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - entering event loop\n")); + + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop finished\n")); + + root_poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // During normal test execution the ORB would have been destroyed + // by a request from the client. + + // orb->shutdown (0 ACE_ENV_ARG_PARAMETER); + // ACE_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + return 0; +} diff --git a/TAO/tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.cpp b/TAO/tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.cpp new file mode 100644 index 00000000000..ef928a30df8 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.cpp @@ -0,0 +1,58 @@ +// $Id$ + +#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 and Solaris, 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; +} + +// Return the name of the service configuration file, for the ORB-based +// service object test + +const ACE_TCHAR* +file_Service_Config_ORB_Test () +{ + // ASCII (UTF-8) encoded Service Configurator file. + static const ACE_TCHAR svc_conf[] = + ACE_TEXT ("Service_Config_ORB_Test") + ACE_TEXT (ACE_DEFAULT_SVC_CONF_EXT); + + return svc_conf; +} + diff --git a/TAO/tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.h b/TAO/tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.h new file mode 100644 index 00000000000..a79b3e104a7 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.h @@ -0,0 +1,82 @@ +// $Id$ + +#ifndef SERVICE_CONFIGURATION_PER_ORB_H +# define SERVICE_CONFIGURATION_PER_ORB_H + + +#include "ace/Trace.h" +#include "ace/Service_Config.h" + +/// We need this wrapper to "break" the encapsulation and test +/// the internals of the class. The class also does a complete +/// teardown on the service repository used. So, do not expect +/// to find *any*, even static services in the global repo afer +/// this class desructor is done. + +class ACE_Service_Gestalt_Test : public ACE_Service_Gestalt +{ + public: + ACE_Service_Gestalt_Test (size_t n) + : ACE_Service_Gestalt (n) + , teardown_ (false) + { + }; + + ACE_Service_Gestalt_Test () + : ACE_Service_Gestalt () + , teardown_ (true) + { + }; + + ~ACE_Service_Gestalt_Test (void) + { + if (this->teardown_) + { + // Close and possibly delete all service instances in the Service + // Repository. + ACE_Service_Config::fini_svcs (); + + // Unlink all services in the Service Repository and close/delete + // all ACE library services and singletons. + ACE_Service_Config::close (); + } + }; + + size_t command_line_directives_count (void) const + { + return this->svc_queue_->size (); + }; + + size_t service_config_files_count (void) const + { + return this->svc_conf_file_queue_->size (); + }; + + size_t services_count (void) const + { + return this->repo_->current_size (); + }; + + bool has_same_service_repository ( ACE_Service_Gestalt_Test const * psg) + { + return (this->repo_ == psg->repo_); + } + +private: + bool teardown_; +}; + +// 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 (); + +// Return the name of the service configuration file, for the ORB-based +// service object test + +const ACE_TCHAR* file_Service_Config_ORB_Test (); + +#endif /* SERVICE_CONFIGURATION_PER_ORB_H */ diff --git a/TAO/tests/ORB_Local_Config/lib/lib.mpc b/TAO/tests/ORB_Local_Config/lib/lib.mpc new file mode 100644 index 00000000000..933fcbecedc --- /dev/null +++ b/TAO/tests/ORB_Local_Config/lib/lib.mpc @@ -0,0 +1,15 @@ +// -*- MPC -*- +// $Id$ + + +project(*) : { + + Source_Files { + Service_Configuration_Per_ORB.cpp + } + + Header_Files { + Service_Configuration_Per_ORB.h + } +} + diff --git a/TAO/tests/ORB_Local_Config/run_tests_all.pl b/TAO/tests/ORB_Local_Config/run_tests_all.pl new file mode 100755 index 00000000000..3aae9463dd5 --- /dev/null +++ b/TAO/tests/ORB_Local_Config/run_tests_all.pl @@ -0,0 +1,62 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; + +sub add_path { + my($name) = shift; + my($value) = shift; + if (defined $ENV{$name}) { + $ENV{$name} .= ':' . $value + } + else { + $ENV{$name} = $value; + } +} + +# Set the library path for the client to be able to load +# the Time_Date library. +add_path('LD_LIBRARY_PATH', '../lib'); +add_path('LIBPATH', '../lib'); +add_path('SHLIB_PATH', '../lib'); + +sub test($) +{ + (my $executable, my $arguments) = @_; + chdir ($executable); + my $t1 = new PerlACE::Process ("Test", ($arguments ? $arguments : "")); + print STDERR "\nTest $executable is running ...\n"; + my $status = $t1->SpawnWaitKill (10); + chdir (".."); + if ($status != 0) { + print STDERR "\nERROR: Test $executable failed, status=$status\n"; + return -1; + } + + print STDERR "Test $executable reported success.\n"; + return 0; +} + +my $status = 0; +$status += test("Bug_1459"); +$status += test("Bunch"); +$status += test("Limits"); +$status += test("Separation"); +$status += test("Service_Dependency"); +$status += test("Shared"); +$status += test("Simple"); +$status += test("Two_DLL_ORB"); + +if ($status == 0) { + print STDERR "SUCCESS: All tests passed\n"; +} +else { + print STDERR "ERROR: Some test failed, status=$status\n"; +} +exit $status; + diff --git a/ace/ACE.cpp b/ace/ACE.cpp index 3e900bc24ef..125ee429963 100644 --- a/ace/ACE.cpp +++ b/ace/ACE.cpp @@ -164,7 +164,8 @@ ACE::compiler_beta_version (void) char ACE::debug (void) { - return ACE::debug_; + static const char* debug = ACE_OS::getenv ("ACE_DEBUG"); + return ACE::debug_ != 0 ? ACE::debug_ : (debug != 0 ? (*debug - '0'): 0); } void diff --git a/ace/DLL.cpp b/ace/DLL.cpp index 00363d51bbf..62f85a19ebe 100644 --- a/ace/DLL.cpp +++ b/ace/DLL.cpp @@ -46,6 +46,33 @@ ACE_DLL::ACE_DLL (const ACE_DLL &rhs) this->error ())); } +// Assignment operator + +const ACE_DLL & +ACE_DLL::operator= (const ACE_DLL &rhs) +{ + ACE_TRACE ("ACE_DLL::operator= (const ACE_DLL &)"); + + open_mode_ = 0; + dll_name_ = 0; + close_handle_on_destruction_=0; + dll_handle_=0; + error_=0; + + if (rhs.dll_name_ + // This will automatically up the refcount and initialize *this + && this->open (rhs.dll_name_, + rhs.open_mode_, + rhs.close_handle_on_destruction_) != 0 + && ACE::debug ()) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("ACE_DLL::operator=: error: %s\n"), + this->error ())); + + return *this; +} + + // If the library name and the opening mode are specified than on // object creation the library is implicitly opened. diff --git a/ace/DLL.h b/ace/DLL.h index 022521ae6a7..ae1e882f01d 100644 --- a/ace/DLL.h +++ b/ace/DLL.h @@ -57,6 +57,10 @@ public: */ explicit ACE_DLL (int close_handle_on_destruction = 1); + /// Allow assignment + const ACE_DLL& operator= (const ACE_DLL &rhs); + + /** * This constructor performs the actions of open() during construction. * @param dll_name The name or path of the DLL to load. @@ -156,10 +160,8 @@ private: ACE_SHLIB_HANDLE handle = 0); - // Disallow assignment since we don't handle it. - void operator= (const ACE_DLL &); - -private: + //private: +public: /// Open mode. int open_mode_; diff --git a/ace/DLL_Manager.cpp b/ace/DLL_Manager.cpp index 783b524c5a2..ce2c3d9cf4d 100644 --- a/ace/DLL_Manager.cpp +++ b/ace/DLL_Manager.cpp @@ -54,10 +54,6 @@ ACE_DLL_Handle::open (const ACE_TCHAR *dll_name, ACE_TRACE ("ACE_DLL_Handle::open"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); - //ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("dll_name: %s; open_mode: %d \n"), - // dll_name, - // open_mode)); - if (this->dll_name_) { // Once dll_name_ has been set, it can't be changed.. @@ -65,7 +61,7 @@ ACE_DLL_Handle::open (const ACE_TCHAR *dll_name, { if (ACE::debug ()) ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("ACE_DLL_Handle::open: error, ") + ACE_LIB_TEXT ("(%P|%t) DLL_Handle::open: error, ") ACE_LIB_TEXT ("tried to reopen %s with name %s\n"), this->dll_name_, dll_name)); @@ -86,10 +82,6 @@ ACE_DLL_Handle::open (const ACE_TCHAR *dll_name, this->handle_ = handle; else { - if (ACE::debug ()) - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_DLL_Handle::open: calling dlopen on ") - ACE_LIB_TEXT ("\"%s\"\n"), dll_name)); - /* ** Get the set of names to try loading. We need to do this to ** properly support the ability for a user to specify a simple, @@ -129,18 +121,34 @@ ACE_DLL_Handle::open (const ACE_TCHAR *dll_name, ACE_TString *name = 0; while (name_iter.next (name)) { - if (ACE::debug ()) + if (ACE::debug () > 1) ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("ACE_DLL_Handle::open: Trying to open DLL %s with %s name\n"), - this->dll_name_, - name->c_str ())); + ACE_LIB_TEXT ("(%P|%t) ACE_DLL_Handle::open: ") + ACE_LIB_TEXT ("calling dlopen on ") + ACE_LIB_TEXT ("\"%s\"\n"), name->c_str ())); // The ACE_SHLIB_HANDLE object is obtained. this->handle_ = ACE_OS::dlopen (name->c_str (), open_mode); - if (this->handle_ != ACE_SHLIB_INVALID_HANDLE) // Good one + + if (this->handle_ != ACE_SHLIB_INVALID_HANDLE) // Good one? break; + // If errno is ENOENT we just skip over this one, + // anything else - like an undefined symbol, for + // instance must be flagged here or the next error will + // mask it. + // @TODO: If we've found our DLL _and_ it's + // broken, should we continue at all? + if (ACE::debug () && (errno != 0) && (errno != ENOENT)) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) ACE_DLL_Handle::open: ") + ACE_LIB_TEXT ("Attempt to open \'%s\' failed ") + ACE_LIB_TEXT ("(%d): %s\n"), + name->c_str (), + errno, + this->error ()->c_str ())); + #if defined (AIX) // AIX often puts the shared library file (most often named // shr.o) inside an archive library. If this is an archive @@ -154,11 +162,35 @@ ACE_DLL_Handle::open (const ACE_TCHAR *dll_name, aix_pathname[name->length ()] = '\0'; ACE_OS::strcat (aix_pathname, ACE_LIB_TEXT ("(shr.o)")); open_mode |= RTLD_MEMBER; + + if (ACE::debug () > 1) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) ACE_DLL_Handle::open: ") + ACE_LIB_TEXT ("calling dlopen on ") + ACE_LIB_TEXT ("\"%s\"\n"), aix_pathname)); + this->handle_ = ACE_OS::dlopen (aix_pathname, open_mode); if (this->handle_ != ACE_SHLIB_INVALID_HANDLE) break; + + // If errno is ENOENT we just skip over this one, anything + // else - like an undefined symbol, for instance + // must be flagged here or the next error will mask it. + // + // @TODO: If we've found our DLL _and_ it's broken, + // should we continue at all? + if (ACE::debug () && (errno != 0) && (errno != ENOENT)) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) ACE_DLL_Handle::open: ") + ACE_LIB_TEXT ("Attempt to open \'%s\' failed") + ACE_LIB_TEXT (" (%d): %s\n"), + name->c_str (), + errno, + this->error ()->c_str ())); + } #endif /* AIX */ + name_iter.advance (); } @@ -166,7 +198,9 @@ ACE_DLL_Handle::open (const ACE_TCHAR *dll_name, { if (ACE::debug ()) ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("ACE_DLL_Handle::open: Invalid handle when opening DLL %s: %s\n"), + ACE_LIB_TEXT ("(%P|%t) DLL_Handle::open: ") + ACE_LIB_TEXT ("Invalid handle while ") + ACE_LIB_TEXT ("opening DLL \"%s\": %s\n"), this->dll_name_, this->error ()->c_str ())); @@ -174,11 +208,6 @@ ACE_DLL_Handle::open (const ACE_TCHAR *dll_name, } } } - if (ACE::debug ()) - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("ACE_DLL_Handle::open: loading %s (%d)\n"), - this->dll_name_, - this->handle_)); ++this->refcount_; return 0; @@ -200,15 +229,25 @@ ACE_DLL_Handle::close (int unload) else this->refcount_ = 0; + if (ACE::debug () > 2) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) DLL_Handle::close: ") + ACE_LIB_TEXT ("closing %s (%d), refcount is down to %d\n"), + this->dll_name_, + this->handle_, + this->refcount_)); + if (this->refcount_ == 0 && this->handle_ != ACE_SHLIB_INVALID_HANDLE && unload == 1) { - if (ACE::debug ()) + if (ACE::debug () > 1) ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("ACE_DLL_Handle::close: unloading %s (%d)\n"), + ACE_LIB_TEXT ("(%P|%t) DLL_Handle::close: ") + ACE_LIB_TEXT ("Unloading %s (%d)\n"), this->dll_name_, this->handle_)); + // First remove any associated Framework Components. ACE_Framework_Repository * frPtr= ACE_Framework_Repository::instance (); @@ -221,9 +260,10 @@ ACE_DLL_Handle::close (int unload) this->handle_ = ACE_SHLIB_INVALID_HANDLE; } - if (retval != 0 && ACE::debug ()) + if (retval != 0) ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("ACE_DLL_Handle::close error: \"%s\".\n"), + ACE_LIB_TEXT ("(%P|%t) DLL_Handle::close: ") + ACE_LIB_TEXT ("failed with: \"%s\".\n"), this->error ()->c_str ())); return retval; @@ -256,7 +296,8 @@ ACE_DLL_Handle::symbol (const ACE_TCHAR *sym_name, int ignore_errors) { if (ACE::debug ()) ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("ACE_DLL_Handle::symbol (\"%s\") \"%s\".\n"), + ACE_LIB_TEXT ("(%P|%t) DLL_Handle::symbol (\"%s\") ") + ACE_LIB_TEXT (" failed with \"%s\".\n"), auto_name.get (), this->error ()->c_str ())); @@ -277,9 +318,9 @@ ACE_DLL_Handle::get_handle (int become_owner) if (this->refcount_ == 0 && become_owner != 0) { - if (ACE::debug ()) + if (ACE::debug () > 1) ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("ACE_DLL_Handle::get_handle: ") + ACE_LIB_TEXT ("(%P|%t) DLL_Handle::get_handle: ") ACE_LIB_TEXT ("cannot become owner, refcount == 0.\n"))); return ACE_SHLIB_INVALID_HANDLE; @@ -293,12 +334,13 @@ ACE_DLL_Handle::get_handle (int become_owner) this->handle_ = ACE_SHLIB_INVALID_HANDLE; } - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("ACE_DLL_Handle::get_handle: ") - ACE_LIB_TEXT ("post call: handle %s, refcount %d\n"), - this->handle_ == ACE_SHLIB_INVALID_HANDLE ? + if (ACE::debug () > 1) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("ACE_DLL_Handle::get_handle: ") + ACE_LIB_TEXT ("post call: handle %s, refcount %d\n"), + this->handle_ == ACE_SHLIB_INVALID_HANDLE ? ACE_LIB_TEXT ("invalid") : ACE_LIB_TEXT ("valid"), - this->refcount_)); + this->refcount_)); return handle; } diff --git a/ace/Dynamic_Service.cpp b/ace/Dynamic_Service.cpp index dd0d8d0c679..9af5fdf2c65 100644 --- a/ace/Dynamic_Service.cpp +++ b/ace/Dynamic_Service.cpp @@ -25,6 +25,18 @@ ACE_Dynamic_Service<TYPE>::instance (const ACE_TCHAR *name) return dynamic_cast<TYPE *> (svc_obj); } + +template <class TYPE> TYPE * +ACE_Dynamic_Service<TYPE>::instance (const ACE_Service_Gestalt* conf, + const ACE_TCHAR *name) +{ + ACE_Service_Object * svc_obj = + static_cast<ACE_Service_Object *> (ACE_Dynamic_Service_Base::instance (conf, name)); + return dynamic_cast<TYPE *> (svc_obj); +} + + + ACE_END_VERSIONED_NAMESPACE_DECL #endif /* ACE_DYNAMIC_SERVICE_CPP */ diff --git a/ace/Dynamic_Service.h b/ace/Dynamic_Service.h index d913f1a750d..5961e4cf8ab 100644 --- a/ace/Dynamic_Service.h +++ b/ace/Dynamic_Service.h @@ -17,6 +17,7 @@ #include /**/ "ace/pre.h" #include "ace/config-all.h" +#include "ace/Global_Macros.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -44,10 +45,27 @@ public: /// Return instance using @a name to search the Service_Repository. static TYPE* instance (const ACE_TCHAR *name); + static TYPE* instance (const ACE_Service_Gestalt* repo, + const ACE_TCHAR *name); + #if defined (ACE_USES_WCHAR) + /// Return instance using @a name to search the Service_Repository. static TYPE* instance (const ACE_ANTI_TCHAR *name); + + static TYPE* instance (const ACE_Service_Gestalt* repo, + const ACE_ANTI_TCHAR *name); #endif // ACE_USES_WCHAR + +private: + ACE_UNIMPLEMENTED_FUNC + (ACE_Dynamic_Service ()); + + ACE_UNIMPLEMENTED_FUNC + (ACE_Dynamic_Service (const ACE_Dynamic_Service&)); + + ACE_UNIMPLEMENTED_FUNC + (ACE_Dynamic_Service& operator= (const ACE_Dynamic_Service&)); }; ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/Dynamic_Service.inl b/ace/Dynamic_Service.inl index 50bce680a39..3980038ef3f 100644 --- a/ace/Dynamic_Service.inl +++ b/ace/Dynamic_Service.inl @@ -5,11 +5,21 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL #if defined (ACE_USES_WCHAR) + template <class TYPE> ACE_INLINE TYPE * ACE_Dynamic_Service<TYPE>::instance (const ACE_ANTI_TCHAR *name) { return instance (ACE_TEXT_CHAR_TO_TCHAR (name)); } + +template <class TYPE> ACE_INLINE TYPE * +ACE_Dynamic_Service<TYPE>::instance (const ACE_Service_Gestalt* repo, + const ACE_ANTI_TCHAR *name) +{ + return instance (repo, ACE_TEXT_CHAR_TO_TCHAR (name)); +} + + #endif // ACE_USES_WCHAR ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/Dynamic_Service_Base.cpp b/ace/Dynamic_Service_Base.cpp index bec17fb079f..8e55675c6ac 100644 --- a/ace/Dynamic_Service_Base.cpp +++ b/ace/Dynamic_Service_Base.cpp @@ -11,6 +11,7 @@ ACE_RCSID (ace, ACE_BEGIN_VERSIONED_NAMESPACE_DECL + void ACE_Dynamic_Service_Base::dump (void) const { @@ -23,24 +24,74 @@ ACE_Dynamic_Service_Base::dump (void) const #endif /* ACE_HAS_DUMP */ } -// Get the instance using <name>. +// Get the instance using <name> for the current global +// service configuration repository. void * ACE_Dynamic_Service_Base::instance (const ACE_TCHAR *name) { ACE_TRACE ("ACE_Dynamic_Service_Base::instance"); - const ACE_Service_Type *svc_rec; + return instance (ACE_Service_Config::current (), name); +} + + +// Find a service registration + +const ACE_Service_Type * +ACE_Dynamic_Service_Base::find_i (const ACE_Service_Gestalt* &repo, + const ACE_TCHAR *name) +{ + ACE_TRACE ("ACE_Dynamic_Service_Base::find_i"); + const ACE_Service_Type *svc_rec = 0; + + ACE_Service_Gestalt* global = ACE_Service_Config::global (); + + for ( ; repo->find (name, &svc_rec) == -1; repo = global) + { + // Check the static repo, too if different + if (repo == global) + break; + } + + return svc_rec; +} + + +// Get the instance using <name> for specific configuration repository. + +void * +ACE_Dynamic_Service_Base::instance (const ACE_Service_Gestalt* repo, + const ACE_TCHAR *name) +{ + ACE_TRACE ("ACE_Dynamic_Service_Base::instance"); + + void *obj = 0; + const ACE_Service_Type_Impl *type = 0; + + const ACE_Service_Gestalt* repo_found = repo; + + const ACE_Service_Type *svc_rec = find_i (repo_found, name); + if (svc_rec != 0) + { + type = svc_rec->type (); + if (type != 0) + obj = type->object (); + } - if (ACE_Service_Repository::instance ()->find (name, - &svc_rec) == -1) - return 0; + if (ACE::debug ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) DSB::instance, repo=%@, name=%s, type=%@ => %@"), + repo->repo_, name, type, obj)); - const ACE_Service_Type_Impl *type = svc_rec->type (); + if (repo->repo_ != repo_found->repo_) + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" [in repo=%@]\n"), + repo_found->repo_)); + else + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - if (type == 0) - return 0; + } - void * const obj = type->object (); return obj; } diff --git a/ace/Dynamic_Service_Base.h b/ace/Dynamic_Service_Base.h index 17b7c5dda2f..0db626a919f 100644 --- a/ace/Dynamic_Service_Base.h +++ b/ace/Dynamic_Service_Base.h @@ -24,6 +24,9 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL +class ACE_Service_Gestalt; +class ACE_Service_Type; + /** * @class ACE_Dynamic_Service_Base * @@ -34,13 +37,33 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL */ class ACE_Export ACE_Dynamic_Service_Base { + public: /// Dump the current static of the object void dump (void) const; protected: - /// Return instance using @a name to search the Service_Repository. + /// Return instance using @a name to search the (default) Service_Repository. static void* instance (const ACE_TCHAR *name); + + /// Return instance using @a name to search the specific @a repo instance. + static void* instance (const ACE_Service_Gestalt* repo, + const ACE_TCHAR *name); + + /// No need to create, or assign instances of this class + ACE_Dynamic_Service_Base (void); + ~ACE_Dynamic_Service_Base (void); + const ACE_Dynamic_Service_Base& operator= (const ACE_Dynamic_Service_Base&); + +private: + /// Implement the service search policy, i.e. "look for the service first + /// locally and then globally" + static const ACE_Service_Type *find_i (const ACE_Service_Gestalt* &repo, + const ACE_TCHAR *name); + + /// The dependency declaration class needs access to the service search + /// policy, implemented by find_i() + friend class ACE_Dynamic_Service_Dependency; }; ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/Dynamic_Service_Dependency.cpp b/ace/Dynamic_Service_Dependency.cpp new file mode 100644 index 00000000000..a22f02333fe --- /dev/null +++ b/ace/Dynamic_Service_Dependency.cpp @@ -0,0 +1,52 @@ +#include "ace/DLL_Manager.h" +#include "ace/Dynamic_Service_Dependency.h" +#include "ace/Service_Config.h" + +ACE_RCSID (ace, + Dynamic_Service_Dependency, + "$Id$") + + +#if !defined (__ACE_INLINE__) +# include "ace/Dynamic_Service_Dependency.inl" +#endif /* __ACE_INLINE__ */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + + +ACE_Dynamic_Service_Dependency::ACE_Dynamic_Service_Dependency (const ACE_TCHAR *principal) +{ + this->init (ACE_Service_Config::current (), principal); +} + +ACE_Dynamic_Service_Dependency::ACE_Dynamic_Service_Dependency (const ACE_Service_Gestalt *cfg, + const ACE_TCHAR *principal) +{ + this->init (cfg, principal); +} + + +ACE_Dynamic_Service_Dependency::~ACE_Dynamic_Service_Dependency (void) +{ + if (ACE::debug () > 1) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) DSD, this=%@ - destroying dependency\n"), + this)); +} + +void +ACE_Dynamic_Service_Dependency::init (const ACE_Service_Gestalt *cfg, + const ACE_TCHAR *principal) +{ + const ACE_Service_Type* st = ACE_Dynamic_Service_Base::find_i (cfg, principal); + if (ACE::debug () > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) DSD, this=%@ - creating dependency on "), this)); + st->dump (); + } + this->tracker_ = st->dll (); +} + + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/Dynamic_Service_Dependency.h b/ace/Dynamic_Service_Dependency.h new file mode 100644 index 00000000000..e021851d267 --- /dev/null +++ b/ace/Dynamic_Service_Dependency.h @@ -0,0 +1,73 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Dynamic_Service_Dependency.h + * + * $Id$ + * + * @author Iliyan Jeliazkov <iliyan@ociweb.com> + */ +//============================================================================= + +#ifndef ACE_DYNAMIC_SERVICE_DEPENDENCY_H +#define ACE_DYNAMIC_SERVICE_DEPENDENCY_H + +#include /**/ "ace/pre.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Dynamic_Service_Base.h" +#include "ace/Service_Object.h" +#include "ace/DLL.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Dynamic_Service_Dependency + * + * @brief Provides a way to declare dependency on specific service, + * thus helping to avoid order of initialization issues with instances + * of an objects whose implementation code resides in dynamically loaded + * services. + * + * It is disastrous to have dynamically loadable services create and give away + * ownership of objects and then ending up being unloaded before all those + * instances have been deleted. Normally the code for such objects classes + * resides within the TEXT segment of the DLL, which implements the service. + * If a service gets removed, its DLL may be unmapped from memory and then + * any attempt to invoke a method on the said objects will cause SEGV. + * + * Such instances must contain a member of @code ACE_Dynamic_Service_Dependency + * initialized with the service they depend on. + * @code ACE_Dynamic_Service_Dependency's constructor and destructor are + * "magical" - they work by maintaining the underlying dynamic service's + * DLL reference count. + */ +class ACE_Export ACE_Dynamic_Service_Dependency +{ +public: + ACE_Dynamic_Service_Dependency (const ACE_Service_Gestalt *cfg, + const ACE_TCHAR *principal); + ACE_Dynamic_Service_Dependency (const ACE_TCHAR *principal); + ~ACE_Dynamic_Service_Dependency (void); + +private: + void init (const ACE_Service_Gestalt *cfg, const ACE_TCHAR *principal); + +private: + ACE_DLL tracker_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Dynamic_Service_Dependency.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_DYNAMIC_SERVICE_DEPENDENCY_H */ diff --git a/ace/Dynamic_Service_Dependency.inl b/ace/Dynamic_Service_Dependency.inl new file mode 100644 index 00000000000..eed0b0e959a --- /dev/null +++ b/ace/Dynamic_Service_Dependency.inl @@ -0,0 +1,20 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Dynamic_Service_Dependency.inl + * + * $Id$ + * + * @author Iliyan Jeliazkov <iliyan@ociweb.com> + */ +//============================================================================= + +ACE_RCSID (ace, + Dynamic_Service_Dependency, + "$Id$") + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/Global_Macros.h b/ace/Global_Macros.h index b09aadfe072..0dce353fa83 100644 --- a/ace/Global_Macros.h +++ b/ace/Global_Macros.h @@ -570,7 +570,7 @@ ACE_Static_Svc_Descriptor ace_svc_desc_##SERVICE_CLASS = { NAME, TYPE, FN, FLAGS class ACE_Static_Svc_##SERVICE_CLASS {\ public:\ ACE_Static_Svc_##SERVICE_CLASS() { \ - ACE_Service_Config::static_svcs ()->insert (\ + ACE_Service_Config::insert (\ &ace_svc_desc_##SERVICE_CLASS); \ } \ }; @@ -583,7 +583,7 @@ ACE_Static_Svc_##SERVICE_CLASS ace_static_svc_##SERVICE_CLASS class ACE_Static_Svc_##SERVICE_CLASS {\ public:\ ACE_Static_Svc_##SERVICE_CLASS() { \ - ACE_Service_Config::static_svcs ()->insert (\ + ACE_Service_Config::insert (\ &ace_svc_desc_##SERVICE_CLASS); \ } \ };\ diff --git a/ace/Parse_Node.cpp b/ace/Parse_Node.cpp index e442c5e4b65..8e83a510bb5 100644 --- a/ace/Parse_Node.cpp +++ b/ace/Parse_Node.cpp @@ -31,19 +31,21 @@ ACE_Stream_Node::dump (void) const } void -ACE_Stream_Node::apply (int & yyerrno) +ACE_Stream_Node::apply (ACE_Service_Gestalt *config, int &yyerrno) { ACE_TRACE ("ACE_Stream_Node::apply"); - if (ACE_Service_Config::initialize (this->node_->record (), - this->node_->parameters ()) == -1) + if (config->initialize (this->node_->record (config), + this->node_->parameters ()) == -1) ++yyerrno; +#ifndef ACE_NLOGGING if (ACE::debug ()) ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("did stream on %s, error = %d\n"), + ACE_LIB_TEXT ("(%P|%t) Did stream on %s, error = %d\n"), this->node_->name (), yyerrno)); +#endif /* ACE_NLOGGING */ } ACE_ALLOC_HOOK_DEFINE (ACE_Parse_Node) @@ -178,32 +180,37 @@ ACE_Resume_Node::~ACE_Resume_Node (void) } void -ACE_Suspend_Node::apply (int & yyerrno) +ACE_Suspend_Node::apply (ACE_Service_Gestalt *config, int &yyerrno) { ACE_TRACE ("ACE_Suspend_Node::apply"); - if (ACE_Service_Config::suspend (this->name ()) == -1) + if (config->suspend (this->name ()) == -1) ++yyerrno; +#ifndef ACE_NLOGGING if (ACE::debug ()) ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("did suspend on %s, error = %d\n"), this->name (), yyerrno)); +#endif /* ACE_NLOGGING */ } void -ACE_Resume_Node::apply (int & yyerrno) +ACE_Resume_Node::apply (ACE_Service_Gestalt *config, int &yyerrno) { ACE_TRACE ("ACE_Resume_Node::apply"); - if (ACE_Service_Config::resume (this->name ()) == -1) + + if (config->resume (this->name ()) == -1) ++yyerrno; +#ifndef ACE_NLOGGING if (ACE::debug ()) ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("did resume on %s, error = %d\n"), this->name (), yyerrno)); +#endif /* ACE_NLOGGING */ } ACE_ALLOC_HOOK_DEFINE (ACE_Remove_Node) @@ -227,48 +234,49 @@ ACE_Remove_Node::~ACE_Remove_Node (void) } void -ACE_Remove_Node::apply (int & yyerrno) +ACE_Remove_Node::apply (ACE_Service_Gestalt *config, int &yyerrno) { ACE_TRACE ("ACE_Remove_Node::apply"); - if (ACE_Service_Config::remove (this->name ()) == -1) + + if (config->remove (this->name ()) == -1) ++yyerrno; +#ifndef ACE_NLOGGING if (ACE::debug ()) ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("did remove on %s, error = %d\n"), + ACE_LIB_TEXT ("(%P|%t) ACE_Remove_Node::apply") + ACE_LIB_TEXT (" - did remove on %s, error = %d\n"), this->name (), yyerrno)); +#endif /* ACE_NLOGGING */ } -ACE_Dynamic_Node::ACE_Dynamic_Node (const ACE_Service_Type *sr, + +ACE_Dynamic_Node::ACE_Dynamic_Node (ACE_Service_Type_Factory const *stf, ACE_TCHAR *parms) - : ACE_Static_Node (sr->name (), parms), - record_ (sr) + : ACE_Static_Node (stf->name (), parms) + , factory_ (stf) { ACE_TRACE ("ACE_Dynamic_Node::ACE_Dynamic_Node"); } -const ACE_Service_Type * -ACE_Dynamic_Node::record (void) const -{ - ACE_TRACE ("ACE_Dynamic_Node::record"); - return this->record_; -} - void -ACE_Dynamic_Node::apply (int & yyerrno) +ACE_Dynamic_Node::apply (ACE_Service_Gestalt *config, int &yyerrno) { ACE_TRACE ("ACE_Dynamic_Node::apply"); - if (ACE_Service_Config::initialize (this->record (), - this->parameters ()) == -1) + if (config->initialize (this->factory_.get (), + this->parameters ()) == -1) ++yyerrno; +#ifndef ACE_NLOGGING if (ACE::debug ()) ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("did dynamic on %s, error = %d\n"), + ACE_LIB_TEXT ("(%P|%t) ACE_Dynamic_Node::apply") + ACE_LIB_TEXT (" - did dynamic on %s, error = %d\n"), this->name (), yyerrno)); +#endif /* ACE_NLOGGING */ } ACE_ALLOC_HOOK_DEFINE (ACE_Dynamic_Node) @@ -305,17 +313,15 @@ ACE_Static_Node::ACE_Static_Node (const ACE_TCHAR *nm, } const ACE_Service_Type * -ACE_Static_Node::record (void) const +ACE_Static_Node::record (const ACE_Service_Gestalt *config) const { ACE_TRACE ("ACE_Static_Node::record"); ACE_Service_Type *sr = 0; - if (ACE_Service_Repository::instance()->find - (this->name (), - (const ACE_Service_Type **) &sr) == -1) + if (config->find (this->name (), (const ACE_Service_Type **) &sr) == -1) return 0; - else - return sr; + + return sr; } ACE_TCHAR * @@ -326,18 +332,20 @@ ACE_Static_Node::parameters (void) const } void -ACE_Static_Node::apply (int & yyerrno) +ACE_Static_Node::apply (ACE_Service_Gestalt *config, int &yyerrno) { ACE_TRACE ("ACE_Static_Node::apply"); - if (ACE_Service_Config::initialize (this->name (), + if (config->initialize (this->name (), this->parameters ()) == -1) ++yyerrno; +#ifndef ACE_NLOGGING if (ACE::debug ()) ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("did static on %s, error = %d\n"), this->name (), yyerrno)); +#endif /* ACE_NLOGGING */ } ACE_Static_Node::~ACE_Static_Node (void) @@ -346,6 +354,7 @@ ACE_Static_Node::~ACE_Static_Node (void) delete[] this->parameters_; } + ACE_ALLOC_HOOK_DEFINE (ACE_Location_Node) void @@ -389,13 +398,6 @@ ACE_Location_Node::pathname (const ACE_TCHAR *p) this->pathname_ = p; } -void -ACE_Location_Node::set_symbol (void *s) -{ - ACE_TRACE ("ACE_Location_Node::set_symbol"); - this->symbol_ = s; -} - int ACE_Location_Node::dispose (void) const { @@ -408,10 +410,25 @@ ACE_Location_Node::open_dll (int & yyerrno) { ACE_TRACE ("ACE_Location_Node::open_dll"); +#ifndef ACE_NLOGGING + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) LN::open_dll - path=%s\n"), + this->pathname ())); +#endif /* ACE_NLOGGING */ + if (-1 == this->dll_.open (this->pathname ())) { ++yyerrno; +#ifndef ACE_NLOGGING + ACE_TCHAR *errmsg = this->dll_.error (); + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) LN - DLL::open failed for %s: %s\n"), + this->pathname (), + errmsg ? errmsg : ACE_LIB_TEXT ("no error reported"))); +#endif /* ACE_NLOGGING */ + return -1; } @@ -419,6 +436,13 @@ ACE_Location_Node::open_dll (int & yyerrno) } +void +ACE_Location_Node::set_symbol (void *s) +{ + ACE_TRACE ("ACE_Location_Node::set_symbol"); + this->symbol_ = s; +} + ACE_ALLOC_HOOK_DEFINE (ACE_Object_Node) void @@ -439,7 +463,8 @@ ACE_Object_Node::ACE_Object_Node (const ACE_TCHAR *path, } void * -ACE_Object_Node::symbol (int & yyerrno, +ACE_Object_Node::symbol (ACE_Service_Gestalt *, + int &yyerrno, ACE_Service_Object_Exterminator *) { ACE_TRACE ("ACE_Object_Node::symbol"); @@ -455,7 +480,7 @@ ACE_Object_Node::symbol (int & yyerrno, #ifndef ACE_NLOGGING ACE_TCHAR *errmsg = this->dll_.error (); ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("ACE_DLL::symbol failed for object %s: %s\n"), + ACE_LIB_TEXT ("DLL::symbol failed for object %s: %s\n"), object_name, errmsg ? errmsg : ACE_LIB_TEXT ("no error reported"))); #endif /* ACE_NLOGGING */ @@ -555,7 +580,8 @@ ACE_Function_Node::make_func_name (ACE_TCHAR const * func_name) } void * -ACE_Function_Node::symbol (int & yyerrno, +ACE_Function_Node::symbol (ACE_Service_Gestalt *, + int &yyerrno, ACE_Service_Object_Exterminator *gobbler) { typedef ACE_Service_Object *(*ACE_Service_Factory_Ptr) @@ -582,7 +608,8 @@ ACE_Function_Node::symbol (int & yyerrno, #ifndef ACE_NLOGGING ACE_TCHAR *errmsg = this->dll_.error (); ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("ACE_DLL::symbol failed for function %s: %s\n"), + ACE_LIB_TEXT ("DLL::symbol failed for function %s: ") + ACE_LIB_TEXT ("%s\n"), function_name, errmsg ? errmsg : ACE_LIB_TEXT ("no error reported"))); @@ -635,7 +662,7 @@ ACE_Dummy_Node::ACE_Dummy_Node (const ACE_Static_Node *static_node, } void -ACE_Dummy_Node::apply (int & yyerrno) +ACE_Dummy_Node::apply (ACE_Service_Gestalt *, int &yyerrno) { ACE_TRACE ("ACE_Dummy_Node::apply"); @@ -645,8 +672,6 @@ ACE_Dummy_Node::apply (int & yyerrno) ACE_LIB_TEXT ("did operations on stream %s, error = %d\n"), this->name (), yyerrno)); -#else - ACE_UNUSED_ARG (yyerrno); #endif /* ACE_NLOGGING */ } @@ -677,32 +702,28 @@ ACE_Static_Function_Node::ACE_Static_Function_Node (const ACE_TCHAR *func_name) } void * -ACE_Static_Function_Node::symbol (int & yyerrno, +ACE_Static_Function_Node::symbol (ACE_Service_Gestalt *config, + int &yyerrno, ACE_Service_Object_Exterminator *gobbler) { ACE_TRACE ("ACE_Static_Function_Node::symbol"); - void *(*func)(ACE_Service_Object_Exterminator *) = 0; this->symbol_ = 0; // Locate the factory function <function_name> in the statically // linked svcs. - ACE_Static_Svc_Descriptor **ssdp = 0; - ACE_STATIC_SVCS &svcs = *ACE_Service_Config::static_svcs (); - ACE_TCHAR *function_name = const_cast<ACE_TCHAR *> (this->function_name_); - - for (ACE_STATIC_SVCS_ITERATOR iter (svcs); - iter.next (ssdp) != 0; - iter.advance ()) - { - ACE_Static_Svc_Descriptor *ssd = *ssdp; - if (ACE_OS::strcmp (ssd->name_, - function_name) == 0) - func = (void *(*)(ACE_Service_Object_Exterminator*)) ssd->alloc_; + ACE_Static_Svc_Descriptor *ssd = 0; + if (config->find_static_svc_descriptor (this->function_name_, &ssd) == -1) + { + yyerrno++; + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) No static service registered for function %s\n"), + this->function_name_), + 0); } - if (func == 0) + if (ssd->alloc_ == 0) { yyerrno++; @@ -711,14 +732,15 @@ ACE_Static_Function_Node::symbol (int & yyerrno, ++yyerrno; ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("no static service registered for function %s\n"), - function_name), + ACE_LIB_TEXT ("(%P|%t) No static service factory ") + ACE_LIB_TEXT ("function registered for function %s\n"), + this->function_name_), 0); } } // Invoke the factory function and record it's return value. - this->symbol_ = (*func) (gobbler); + this->symbol_ = (*ssd->alloc_) (gobbler); if (this->symbol_ == 0) { diff --git a/ace/Parse_Node.h b/ace/Parse_Node.h index acb07deadc8..bbec8e430ee 100644 --- a/ace/Parse_Node.h +++ b/ace/Parse_Node.h @@ -25,6 +25,7 @@ #if (ACE_USES_CLASSIC_SVC_CONF == 1) #include "ace/DLL.h" +#include "ace/Svc_Conf.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL @@ -51,7 +52,9 @@ public: ACE_Parse_Node *link (void) const; void link (ACE_Parse_Node *); - virtual void apply (int & yyerrno) = 0; + + /// Will update the yyereno member and/or the corresponding configuration + virtual void apply (ACE_Service_Gestalt *cfg, int &yyerrno) = 0; const ACE_TCHAR *name (void) const; void print (void) const; @@ -65,6 +68,10 @@ public: private: const ACE_TCHAR *name_; ACE_Parse_Node *next_; + +private: + ACE_UNIMPLEMENTED_FUNC (ACE_Parse_Node (const ACE_Parse_Node&)); + ACE_UNIMPLEMENTED_FUNC (ACE_Parse_Node& operator= (const ACE_Parse_Node&)); }; /** @@ -82,13 +89,20 @@ public: ACE_Suspend_Node (const ACE_TCHAR *name); ~ACE_Suspend_Node (void); - virtual void apply (int & yyerrno); + virtual void apply (ACE_Service_Gestalt *cfg, int &yyerrno); /// Dump the state of an object. void dump (void) const; /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; + +private: + ACE_UNIMPLEMENTED_FUNC + (ACE_Suspend_Node (const ACE_Suspend_Node&)); + + ACE_UNIMPLEMENTED_FUNC + (ACE_Suspend_Node& operator= (const ACE_Suspend_Node&)); }; /** @@ -106,13 +120,17 @@ public: ACE_Resume_Node (const ACE_TCHAR *name); ~ACE_Resume_Node (void); - virtual void apply (int & yyerrno); + virtual void apply (ACE_Service_Gestalt *cfg, int &yyerrno); /// Dump the state of an object. void dump (void) const; /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; + +private: + ACE_UNIMPLEMENTED_FUNC (ACE_Resume_Node (const ACE_Resume_Node&)); + ACE_UNIMPLEMENTED_FUNC (ACE_Resume_Node& operator= (const ACE_Resume_Node&)); }; /** @@ -130,13 +148,17 @@ public: ACE_Remove_Node (const ACE_TCHAR *name); ~ACE_Remove_Node (void); - virtual void apply (int & yyerrno); + virtual void apply (ACE_Service_Gestalt *cfg, int &yyerrno); /// Dump the state of an object. void dump (void) const; /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; + +private: + ACE_UNIMPLEMENTED_FUNC (ACE_Remove_Node (const ACE_Remove_Node&)); + ACE_UNIMPLEMENTED_FUNC (ACE_Remove_Node& operator= (const ACE_Remove_Node&)); }; /** @@ -154,8 +176,9 @@ public: ACE_Static_Node (const ACE_TCHAR *name, ACE_TCHAR *params = 0); virtual ~ACE_Static_Node (void); - virtual void apply (int & yyerrno); - virtual const ACE_Service_Type *record (void) const; + virtual void apply (ACE_Service_Gestalt *cfg, int &yyerrno); + virtual const ACE_Service_Type *record (const ACE_Service_Gestalt *g) const; + ACE_TCHAR *parameters (void) const; /// Dump the state of an object. @@ -167,8 +190,15 @@ public: private: /// "Command-line" parameters. ACE_TCHAR *parameters_; + +private: + ACE_UNIMPLEMENTED_FUNC (ACE_Static_Node (const ACE_Static_Node&)); + ACE_UNIMPLEMENTED_FUNC (ACE_Static_Node& operator= (const ACE_Static_Node&)); }; + +class ACE_Service_Type_Factory; + /** * @class ACE_Dynamic_Node * @@ -181,11 +211,13 @@ private: class ACE_Dynamic_Node : public ACE_Static_Node { public: - ACE_Dynamic_Node (const ACE_Service_Type *, ACE_TCHAR *params); + ACE_Dynamic_Node (ACE_Service_Type_Factory const *, ACE_TCHAR *params); + + // ACE_Dynamic_Node (const ACE_Service_Type *, ACE_TCHAR *params); virtual ~ACE_Dynamic_Node (void); - virtual const ACE_Service_Type *record (void) const; - virtual void apply (int & yyerrno); + // virtual const ACE_Service_Type *record (void) const; + virtual void apply (ACE_Service_Gestalt *cfg, int &yyerrno); /// Dump the state of an object. void dump (void) const; @@ -195,7 +227,14 @@ public: private: /// Pointer to a descriptor that describes this node. - const ACE_Service_Type *record_; + ACE_Auto_Ptr<const ACE_Service_Type_Factory> factory_; + +private: + ACE_UNIMPLEMENTED_FUNC + (ACE_Dynamic_Node (const ACE_Dynamic_Node&)); + + ACE_UNIMPLEMENTED_FUNC + (ACE_Dynamic_Node& operator= (const ACE_Dynamic_Node&)); }; /** @@ -213,7 +252,7 @@ public: ACE_Stream_Node (const ACE_Static_Node *, const ACE_Parse_Node *); virtual ~ACE_Stream_Node (void); - virtual void apply (int & yyerrno); + virtual void apply (ACE_Service_Gestalt *cfg, int &yyerrno); /// Dump the state of an object. void dump (void) const; @@ -225,6 +264,42 @@ private: /// Linked list of modules that are part of the stream. const ACE_Static_Node *node_; const ACE_Parse_Node *mods_; + +private: + ACE_UNIMPLEMENTED_FUNC (ACE_Stream_Node (const ACE_Stream_Node&)); + ACE_UNIMPLEMENTED_FUNC (ACE_Stream_Node& operator= (const ACE_Stream_Node&)); +}; + +/** + * @class ACE_Dummy_Node + * + * @brief I forget why this is here... ;-) + * @brief Used in a special case of static STREAM definintion + * + * @note This class is only meant for INTERNAL use by ACE. + */ +class ACE_Dummy_Node : public ACE_Parse_Node +{ +public: + ACE_Dummy_Node (const ACE_Static_Node *, const ACE_Parse_Node *); + ~ACE_Dummy_Node (void); + + virtual void apply (ACE_Service_Gestalt *cfg, int &yyerrno); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Linked list of modules that we're dealing with. + const ACE_Static_Node *node_; + const ACE_Parse_Node *mods_; + +private: + ACE_UNIMPLEMENTED_FUNC (ACE_Dummy_Node (const ACE_Dummy_Node&)); + ACE_UNIMPLEMENTED_FUNC (ACE_Dummy_Node& operator= (const ACE_Dummy_Node&)); }; /** @@ -240,15 +315,19 @@ class ACE_Location_Node { public: ACE_Location_Node (void); - virtual void *symbol (int & yyerrno, - ACE_Service_Object_Exterminator * = 0) = 0; - virtual void set_symbol (void *h); const ACE_DLL &dll (void); const ACE_TCHAR *pathname (void) const; void pathname (const ACE_TCHAR *h); int dispose (void) const; virtual ~ACE_Location_Node (void); + virtual void set_symbol (void *h); + + /// Will update the yyerrno member and/or corresponding configuration + /// repository + virtual void *symbol (ACE_Service_Gestalt *cfgptr, + int &yyerrno, + ACE_Service_Object_Exterminator * = 0) = 0; /// Dump the state of an object. void dump (void) const; @@ -274,6 +353,13 @@ protected: /// Symbol that we've obtained from the shared library. void *symbol_; + +private: + ACE_UNIMPLEMENTED_FUNC + (ACE_Location_Node (const ACE_Location_Node&)); + + ACE_UNIMPLEMENTED_FUNC + (ACE_Location_Node& operator= (const ACE_Location_Node&)); }; /** @@ -289,7 +375,8 @@ class ACE_Object_Node : public ACE_Location_Node { public: ACE_Object_Node (const ACE_TCHAR *pathname, const ACE_TCHAR *obj_name); - virtual void *symbol (int & yyerrno, + virtual void *symbol (ACE_Service_Gestalt *config, + int &yyerrno, ACE_Service_Object_Exterminator * = 0); virtual ~ACE_Object_Node (void); @@ -302,6 +389,10 @@ public: private: /// Name of the object that we're parsing. const ACE_TCHAR *object_name_; + +private: + ACE_UNIMPLEMENTED_FUNC (ACE_Object_Node (const ACE_Object_Node&)); + ACE_UNIMPLEMENTED_FUNC (ACE_Object_Node& operator= (const ACE_Object_Node&)); }; /** @@ -317,7 +408,8 @@ class ACE_Function_Node : public ACE_Location_Node { public: ACE_Function_Node (const ACE_TCHAR *pathname, const ACE_TCHAR *func_name); - virtual void *symbol (int & yyerrno, + virtual void *symbol (ACE_Service_Gestalt *config, + int &yyerrno, ACE_Service_Object_Exterminator *gobbler = 0); virtual ~ACE_Function_Node (void); @@ -352,34 +444,13 @@ private: /// Name of the function that we're parsing. const ACE_TCHAR *function_name_; -}; - -/** - * @class ACE_Dummy_Node - * - * @brief I forget why this is here... ;-) - * - * @note This class is only meant for INTERNAL use by ACE. - * - * @internal - */ -class ACE_Dummy_Node : public ACE_Parse_Node -{ -public: - ACE_Dummy_Node (const ACE_Static_Node *, const ACE_Parse_Node *); - ~ACE_Dummy_Node (void); - virtual void apply (int & yyerrno); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; private: - /// Linked list of modules that we're dealing with. - const ACE_Static_Node *node_; - const ACE_Parse_Node *mods_; + ACE_UNIMPLEMENTED_FUNC + (ACE_Function_Node (const ACE_Function_Node&)); + + ACE_UNIMPLEMENTED_FUNC + (ACE_Function_Node& operator= (const ACE_Function_Node&)); }; /** @@ -397,7 +468,8 @@ class ACE_Static_Function_Node : public ACE_Location_Node { public: explicit ACE_Static_Function_Node (const ACE_TCHAR *func_name); - virtual void *symbol (int & yyerrno, + virtual void *symbol (ACE_Service_Gestalt *config, + int &yyerrno, ACE_Service_Object_Exterminator * = 0); virtual ~ACE_Static_Function_Node (void); @@ -410,11 +482,14 @@ public: private: /// Name of the function that we're parsing. const ACE_TCHAR *function_name_; -}; -/// Global variable used to communicate between the parser and the main -/// program. -extern ACE_Service_Config *ace_this_svc; +private: + ACE_UNIMPLEMENTED_FUNC + (ACE_Static_Function_Node (const ACE_Static_Function_Node&)); + + ACE_UNIMPLEMENTED_FUNC + (ACE_Static_Function_Node& operator= (const ACE_Static_Function_Node&)); +}; ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/Service_Config.cpp b/ace/Service_Config.cpp index f69f3569cf9..f6f8e0b88ef 100644 --- a/ace/Service_Config.cpp +++ b/ace/Service_Config.cpp @@ -6,29 +6,13 @@ #include "ace/Service_Config.inl" #endif /* __ACE_INLINE__ */ -#include "ace/Svc_Conf.h" -#include "ace/Get_Opt.h" -#include "ace/ARGV.h" -#include "ace/Malloc.h" -#include "ace/Service_Manager.h" -#include "ace/Service_Repository.h" #include "ace/Service_Types.h" -#include "ace/Containers.h" -#include "ace/Auto_Ptr.h" #include "ace/Reactor.h" -#include "ace/Thread_Manager.h" -#include "ace/DLL.h" -#include "ace/XML_Svc_Conf.h" -#include "ace/SString.h" - -#ifndef ACE_LACKS_UNIX_SIGNALS -# include "ace/Signal.h" -#endif /* !ACE_LACKS_UNIX_SIGNALS */ - -#include "ace/OS_NS_stdio.h" +#include "ace/Signal.h" #include "ace/OS_NS_time.h" #include "ace/OS_NS_unistd.h" -#include "ace/OS_NS_sys_stat.h" +#include "ace/Get_Opt.h" +#include "ace/Service_Gestalt.h" ACE_RCSID (ace, Service_Config, @@ -36,17 +20,43 @@ ACE_RCSID (ace, ACE_BEGIN_VERSIONED_NAMESPACE_DECL -ACE_ALLOC_HOOK_DEFINE (ACE_Service_Config) -void -ACE_Service_Config::dump (void) const +/// +ACE_Service_Config_Guard::ACE_Service_Config_Guard (ACE_Service_Gestalt * psg) + : saved_ (ACE_Service_Config::current ()) { -#if defined (ACE_HAS_DUMP) - ACE_TRACE ("ACE_Service_Config::dump"); -#endif /* ACE_HAS_DUMP */ + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SCG::ctor, repo=%@ - guard with %@\n"), + this->saved_->repo_, + psg->repo_)); + + if (saved_ != psg) + { + // Modify the TSS - no locking needed + (void)ACE_Service_Config::current (psg); + } +} + +/// +ACE_Service_Config_Guard::~ACE_Service_Config_Guard (void) +{ + ACE_Service_Config::current (this->saved_); + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SCG::dtor, repo=%@ - un-guard\n"), + this->saved_->repo_)); } -// ---------------------------------------- + +ACE_ALLOC_HOOK_DEFINE (ACE_Service_Config) + + +// A thread-specific storage to keep a pointer to the (current) global +// configuration. +ACE_TSS_TYPE (ACE_TSS_Type_Adapter <ACE_Service_Gestalt*>) + ACE_Service_Config::current_ (0); // Set the signal handler to point to the handle_signal() function. ACE_Sig_Adapter *ACE_Service_Config::signal_handler_ = 0; @@ -54,40 +64,281 @@ ACE_Sig_Adapter *ACE_Service_Config::signal_handler_ = 0; // Trigger a reconfiguration. sig_atomic_t ACE_Service_Config::reconfig_occurred_ = 0; - // = Set by command-line options. +// = Set by command-line options. + +/// Pathname of file to write process id. +ACE_TCHAR *ACE_Service_Config::pid_file_name_ = 0; + +/// Shall we become a daemon process? int ACE_Service_Config::be_a_daemon_ = 0; -int ACE_Service_Config::no_static_svcs_ = 1; -ACE_TCHAR* ACE_Service_Config::pid_file_name_ = 0; // Number of the signal used to trigger reconfiguration. int ACE_Service_Config::signum_ = SIGHUP; -// Indicates where to write the logging output. This is typically -// either a STREAM pipe or a socket address. -const ACE_TCHAR *ACE_Service_Config::logger_key_ = ACE_DEFAULT_LOGGER_KEY; -// The ACE_Service_Manager static service object is now defined by the -// ACE_Object_Manager, in Object_Manager.cpp. +void +ACE_Service_Config::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Service_Config::dump"); +#endif /* ACE_HAS_DUMP */ +} + +int +ACE_Service_Config::parse_args_i (int argc, ACE_TCHAR *argv[]) +{ + ACE_TRACE ("ACE_Service_Config::parse_args_i"); + ACE_Get_Opt getopt (argc, + argv, + ACE_LIB_TEXT ("bs:p:"), + 1); // Start at argv[1]. + + for (int c; (c = getopt ()) != -1; ) + switch (c) + { + case 'p': + ACE_Service_Config::pid_file_name_ = getopt.opt_arg (); + break; + case 'b': + ACE_Service_Config::be_a_daemon_ = 1; + break; + case 's': + { + // There's no point in dealing with this on NT since it + // doesn't really support signals very well... +#if !defined (ACE_LACKS_UNIX_SIGNALS) + ACE_Service_Config::signum_ = + ACE_OS::atoi (getopt.opt_arg ()); + + if (ACE_Reactor::instance ()->register_handler + (ACE_Service_Config::signum_, + ACE_Service_Config::signal_handler_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("cannot obtain signal handler\n")), + -1); +#endif /* ACE_LACKS_UNIX_SIGNALS */ + break; + } + } + + return ACE_Service_Gestalt::parse_args_i (argc, argv); + +} /* parse_args_i () */ + + +int +ACE_Service_Config::open_i (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key, + bool ignore_static_svcs, + bool ignore_default_svc_conf_file, + bool ignore_debug_flag) +{ + int result = 0; + ACE_TRACE ("ACE_Service_Config::open_i"); + ACE_Log_Msg *log_msg = ACE_LOG_MSG; + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) SC::open_i - this=%@, opened=%d, ") + ACE_TEXT ("loadstatics=%d\n"), + this, this->is_opened_, this->no_static_svcs_)); + + // Guard against reentrant processing. For example, + // if the singleton gestalt (ubergestalt) was already open, + // do not open it again... + // The base class open_i increments this and we are + // forwarding to it, so we don't have to increment here. + if (this->is_opened_ != 0) + return 0; + + // Check for things we need to do on a per-process basis and which + // may not be safe, or wise to do an a per instance basis + + // Override any defaults, if required + this->no_static_svcs_ = ignore_static_svcs; + + // Become a daemon before doing anything else. + if (this->be_a_daemon_) + ACE::daemonize (); + + // Write process id to file. + if (this->pid_file_name_ != 0) + { + FILE* pidf = ACE_OS::fopen (this->pid_file_name_, + ACE_LIB_TEXT("w")); + + if (pidf != 0) + { + ACE_OS::fprintf (pidf, + "%ld\n", + static_cast<long> (ACE_OS::getpid())); + ACE_OS::fclose (pidf); + } + } + + u_long flags = log_msg->flags (); + + // Only use STDERR if the caller hasn't already set the flags. + if (flags == 0) + flags = (u_long) ACE_Log_Msg::STDERR; + + const ACE_TCHAR *key = logger_key; + + if (key == 0 || ACE_OS::strcmp (key, ACE_DEFAULT_LOGGER_KEY) == 0) + // Only use the static <logger_key_> if the caller doesn't + // override it in the parameter list or if the key supplied is + // equal to the default static logger key. + key = this->logger_key_; + else + ACE_SET_BITS (flags, ACE_Log_Msg::LOGGER); + + if (log_msg->open (program_name, + flags, + key) == -1) + result = -1; + else + { + if (ACE::debug ()) + ACE_DEBUG ((LM_STARTUP, + ACE_LIB_TEXT ("starting up daemon %n\n"))); + + // Initialize the Service Repository (this will still work if + // user forgets to define an object of type ACE_Service_Config). + ACE_Service_Repository::instance (ACE_Service_Config::MAX_SERVICES); + + // Initialize the ACE_Reactor (the ACE_Reactor should be the + // same size as the ACE_Service_Repository). + ACE_Reactor::instance (); + + // There's no point in dealing with this on NT since it doesn't + // really support signals very well... +#if !defined (ACE_LACKS_UNIX_SIGNALS) + // Only attempt to register a signal handler for positive + // signal numbers. + if (ACE_Service_Config::signum_ > 0) + { + ACE_Sig_Set ss; + ss.sig_add (ACE_Service_Config::signum_); + if (ACE_Reactor::instance ()->register_handler + (ss, ACE_Service_Config::signal_handler_) == -1) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("can't register signal handler\n"))); + } +#endif /* ACE_LACKS_UNIX_SIGNALS */ + } + + if (result == -1) + return -1; + + if (this->init_svc_conf_file_queue () == -1) + return -1; + + // Check if the default file exists before attempting to queue it + // for processing + if (!ignore_default_svc_conf_file) + { + FILE *fp = ACE_OS::fopen (ACE_DEFAULT_SVC_CONF, + ACE_LIB_TEXT ("r")); + ignore_default_svc_conf_file = (fp == 0); + if (fp != 0) + ACE_OS::fclose (fp); + } + + if (!ignore_default_svc_conf_file + && this->svc_conf_file_queue_->is_empty ()) + { + // Load the default "svc.conf" entry here if there weren't + // overriding -f arguments in <parse_args>. + if (this->svc_conf_file_queue_->enqueue_tail (ACE_TString (ACE_DEFAULT_SVC_CONF)) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("enqueuing ") + ACE_LIB_TEXT (ACE_DEFAULT_SVC_CONF) + ACE_LIB_TEXT(" file")), + -1); + } + } + + return ACE_Service_Gestalt::open_i (program_name, + logger_key, + ignore_static_svcs, + ignore_default_svc_conf_file, + ignore_debug_flag); + +} + +/// Return the global configuration instance. Allways returns the same +/// instance +ACE_Service_Gestalt * +ACE_Service_Config::global (void) +{ + return ACE_Singleton<ACE_Service_Config, ACE_SYNCH_MUTEX>::instance (); +} + +/// +ACE_Service_Gestalt * +ACE_Service_Config::instance (void) +{ + return ACE_Service_Config::current (); +} + +/// Return the configuration instance, considered "global" in +/// the current thread. This may be the same as instance(), but on some +/// occasions, it may be a different one. For example, ACE_Service_Config_Guard +/// provides a way of temporarily replacing the "current" configuration +/// instance in the context of a thread. +ACE_Service_Gestalt * +ACE_Service_Config::current (void) +{ + ACE_Service_Gestalt *tmp = ACE_Service_Config::global (); -// Are we initialized already? -int ACE_Service_Config::is_initialized_ = 0; + // If the Object_Manager is in transient state, the + // ACE_Service_Gestalt::current_ instance may not have been constructed + // yet (or may have been already destroyed). Either way there + // are no other threads. + if (ACE_Object_Manager::starting_up () || ACE_Object_Manager::shutting_down ()) + return tmp; -// List of statically configured services. + if (ACE_Service_Config::current_.ts_object () != 0) + return ACE_TSS_GET (current_, ACE_Service_Gestalt); -ACE_STATIC_SVCS *ACE_Service_Config::static_svcs_ = 0; -ACE_SVC_QUEUE *ACE_Service_Config::svc_queue_ = 0; -ACE_SVC_QUEUE *ACE_Service_Config::svc_conf_file_queue_ = 0; + // Stash a pointer to the global configuration, so it can be returned out + // of TSS the next time a thread asks for it + ACE_Service_Config::current (tmp); -ACE_STATIC_SVCS * + return tmp; +} + +/// A mutator to set the "current" (TSS) gestalt instance. +int +ACE_Service_Config::current (ACE_Service_Gestalt *newcurrent) +{ + *ACE_Service_Config::current_ = newcurrent; + return 0; +} + + +// Changed the interface of this method to return the gestalt instead of +// the container, underlying the service repository and defined +// ACE_Service_Gestalt::insert (ACE_Static_Svc_Descriptor*). This way the +// existing source code can keep using ACE_Service_Config::static_svcs(), +// however now it is not necessary to expose the repository storage *and* +// it is much easier to debug service registration problems. +ACE_Service_Gestalt * ACE_Service_Config::static_svcs (void) { - if (ACE_Service_Config::static_svcs_ == 0) - ACE_NEW_RETURN (ACE_Service_Config::static_svcs_, - ACE_STATIC_SVCS, - 0); - return ACE_Service_Config::static_svcs_; + return ACE_Service_Config::current (); } +/// +int +ACE_Service_Config::insert (ACE_Static_Svc_Descriptor* stsd) +{ + return ACE_Service_Config::current ()->insert (stsd); +} + + // Totally remove <svc_name> from the daemon by removing it from the // ACE_Reactor, and unlinking it if necessary. @@ -131,7 +382,9 @@ ACE_Service_Config::ACE_Service_Config (int ignore_static_svcs, int signum) { ACE_TRACE ("ACE_Service_Config::ACE_Service_Config"); - ACE_Service_Config::no_static_svcs_ = ignore_static_svcs; + + this->no_static_svcs_ = (ignore_static_svcs); + ACE_Service_Config::signum_ = signum; // Initialize the Service Repository. @@ -142,98 +395,6 @@ ACE_Service_Config::ACE_Service_Config (int ignore_static_svcs, ACE_Reactor::instance (); } -int -ACE_Service_Config::init_svc_conf_file_queue (void) -{ - if (ACE_Service_Config::svc_conf_file_queue_ == 0) - ACE_NEW_RETURN (ACE_Service_Config::svc_conf_file_queue_, - ACE_SVC_QUEUE, - -1); - return 0; -} - -// Handle the command-line options intended for the -// ACE_Service_Config. - -int -ACE_Service_Config::parse_args (int argc, ACE_TCHAR *argv[]) -{ - ACE_TRACE ("ACE_Service_Config::parse_args"); - ACE_Get_Opt getopt (argc, - argv, - ACE_LIB_TEXT ("bdf:k:nyp:s:S:"), - 1); // Start at argv[1]. - - if (ACE_Service_Config::init_svc_conf_file_queue () == -1) - return -1; - - for (int c; (c = getopt ()) != -1; ) - switch (c) - { - case 'b': - ACE_Service_Config::be_a_daemon_ = 1; - break; - case 'd': - ACE::debug (1); - break; - case 'f': - if (ACE_Service_Config::svc_conf_file_queue_->enqueue_tail - (ACE_TString (getopt.opt_arg ())) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("enqueue_tail")), - -1); - break; - case 'k': - ACE_Service_Config::logger_key_ = getopt.opt_arg (); - break; - case 'n': - ACE_Service_Config::no_static_svcs_ = 1; - break; - case 'y': - ACE_Service_Config::no_static_svcs_ = 0; - break; - case 'p': - ACE_Service_Config::pid_file_name_ = getopt.opt_arg (); - break; - case 's': - { - // There's no point in dealing with this on NT since it - // doesn't really support signals very well... -#if !defined (ACE_LACKS_UNIX_SIGNALS) - ACE_Service_Config::signum_ = - ACE_OS::atoi (getopt.opt_arg ()); - - if (ACE_Reactor::instance ()->register_handler - (ACE_Service_Config::signum_, - ACE_Service_Config::signal_handler_) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("cannot obtain signal handler\n")), - -1); -#endif /* ACE_LACKS_UNIX_SIGNALS */ - break; - } - case 'S': - if (ACE_Service_Config::svc_queue_ == 0) - ACE_NEW_RETURN (ACE_Service_Config::svc_queue_, - ACE_SVC_QUEUE, - -1); - if (ACE_Service_Config::svc_queue_->enqueue_tail - (ACE_TString (getopt.opt_arg ())) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("enqueue_tail")), - -1); - break; - default: - if (ACE::debug () > 0) - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("%c is not a ACE_Service_Config option\n"), - c)); - } - - return 0; -} #if (ACE_USES_CLASSIC_SVC_CONF == 0) ACE_Service_Type * @@ -291,492 +452,6 @@ ACE_Service_Config::create_service_type_impl (const ACE_TCHAR *name, } -// Initialize and activate a statically linked service. - -int -ACE_Service_Config::initialize (const ACE_TCHAR *svc_name, - const ACE_TCHAR *parameters) -{ - ACE_TRACE ("ACE_Service_Config::initialize"); - ACE_ARGV args (parameters); - ACE_Service_Type *srp = 0; - - if (ACE::debug ()) - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("opening static service %s\n"), - svc_name)); - - if (ACE_Service_Repository::instance ()->find - (svc_name, - (const ACE_Service_Type **) &srp) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("%s not found\n"), - svc_name), - -1); - else if (srp->type ()->init (args.argc (), - args.argv ()) == -1) - { - // Remove this entry. - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("static initialization failed, %p\n"), - svc_name)); - ACE_Service_Repository::instance ()->remove (svc_name); - return -1; - } - else - { - srp->active (1); - return 0; - } -} - -// Dynamically link the shared object file and retrieve a pointer to -// the designated shared object in this file. - -int -ACE_Service_Config::initialize (const ACE_Service_Type *sr, - const ACE_TCHAR *parameters) -{ - ACE_TRACE ("ACE_Service_Config::initialize"); - ACE_ARGV args (parameters); - - if (ACE::debug ()) - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("opening dynamic service %s\n"), - sr->name ())); - - ACE_Service_Type *srp = 0; - if (ACE_Service_Repository::instance ()->find - (sr->name (), - (const ACE_Service_Type **) &srp) >= 0) - ACE_ERROR_RETURN ((LM_DEBUG, - ACE_LIB_TEXT ("%s already installed, please remove first before reinstalling\n"), - sr->name ()), - 0); - - if (sr->type ()->init (args.argc (), - args.argv ()) == -1) - { - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("dynamic initialization failed for %s\n"), - sr->name ())); - ACE_Service_Type *ps = 0; - ACE_Service_Repository::instance ()->remove (sr->name (), &ps); - // We just get ps to avoid having remove() delete it. - return -1; - } - - if (ACE_Service_Repository::instance ()->insert (sr) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("insertion failed, %p\n"), - sr->name ()), - -1); - return 0; -} - -#if (ACE_USES_CLASSIC_SVC_CONF == 1) -int -ACE_Service_Config::process_directives_i (ACE_Svc_Conf_Param *param) -{ - // AC 970827 Skip the heap check because yacc allocates a buffer - // here which will be reported as a memory leak for some reason. - ACE_NO_HEAP_CHECK - - ::ace_yyparse (param); - - if (param->yyerrno > 0) - { - // This is a hack, better errors should be provided... - errno = EINVAL; - return param->yyerrno; - } - else - return 0; -} -#else -ACE_XML_Svc_Conf * -ACE_Service_Config::get_xml_svc_conf (ACE_DLL &xmldll) -{ - if (xmldll.open (ACE_LIB_TEXT ("ACEXML_XML_Svc_Conf_Parser")) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("Fail to open ACEXML_XML_Svc_Conf_Parser: %p\n"), - "ACE_Service_Config::get_xml_svc_conf"), - 0); - - void *foo; - foo = xmldll.symbol (ACE_LIB_TEXT ("_ACEXML_create_XML_Svc_Conf_Object")); - - // Cast the void* to long first. - long tmp = reinterpret_cast<long> (foo); - ACE_XML_Svc_Conf::Factory factory = - reinterpret_cast<ACE_XML_Svc_Conf::Factory> (tmp); - if (factory == 0) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("Unable to resolve factory: %p\n"), - xmldll.error ()), - 0); - - return factory (); -} -#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ - -int -ACE_Service_Config::process_file (const ACE_TCHAR file[]) -{ - ACE_TRACE ("ACE_Service_Config::process_file"); - -#if (ACE_USES_CLASSIC_SVC_CONF == 1) - int result = 0; - - FILE *fp = ACE_OS::fopen (file, - ACE_LIB_TEXT ("r")); - - if (fp == 0) - { - // Invalid svc.conf file. We'll report it here and break out of - // the method. - if (ACE::debug ()) - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("%p\n"), - file)); - - // Use stat to find out if the file exists. I didn't use access() - // because stat is better supported on most non-unix platforms. - ACE_stat exists; - if (ACE_OS::stat (file, &exists) == 0) - // If it exists, but we couldn't open it for reading then we - // must not have permission to read it. - errno = EPERM; - else - errno = ENOENT; - result = -1; - } - else - { - ACE_Svc_Conf_Param f (fp); - - // Keep track of the number of errors. - result = ACE_Service_Config::process_directives_i (&f); - - (void) ACE_OS::fclose (fp); - } - return result; -#else - ACE_DLL dll; - - auto_ptr<ACE_XML_Svc_Conf> - xml_svc_conf (ACE_Service_Config::get_xml_svc_conf (dll)); - - if (xml_svc_conf.get () == 0) - return -1; - - return xml_svc_conf->parse_file (file); -#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ -} - -int -ACE_Service_Config::process_directive (const ACE_TCHAR directive[]) -{ - ACE_TRACE ("ACE_Service_Config::process_directive"); - - if (ACE::debug ()) - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("Service_Config::process_directive - %s\n"), - directive)); - -#if (ACE_USES_CLASSIC_SVC_CONF == 1) - ACE_UNUSED_ARG (directive); - - ACE_Svc_Conf_Param d (directive); - - int result = ACE_Service_Config::process_directives_i (&d); - - return result; -#else - ACE_DLL dll; - - auto_ptr<ACE_XML_Svc_Conf> - xml_svc_conf (ACE_Service_Config::get_xml_svc_conf (dll)); - - if (xml_svc_conf.get () == 0) - return -1; - - return xml_svc_conf->parse_string (directive); -#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ -} - -// Process service configuration requests as indicated in the queue of -// svc.conf files. -int -ACE_Service_Config::process_directives (void) -{ - ACE_TRACE ("ACE_Service_Config::process_directives"); - - int result = 0; - - if (ACE_Service_Config::svc_conf_file_queue_ != 0) - { - ACE_TString *sptr = 0; - ACE_SVC_QUEUE &queue = *ACE_Service_Config::svc_conf_file_queue_; - - // Iterate through all the svc.conf files. - for (ACE_SVC_QUEUE_ITERATOR iter (queue); - iter.next (sptr) != 0; - iter.advance ()) - { - int r = ACE_Service_Config::process_file (sptr->fast_rep ()); - - if (r < 0) - { - result = r; - break; - } - - result += r; - } - } - - return result; -} - -int -ACE_Service_Config::process_commandline_directives (void) -{ - int result = 0; - - if (ACE_Service_Config::svc_queue_ != 0) - { - ACE_TString *sptr = 0; - ACE_SVC_QUEUE &queue = *ACE_Service_Config::svc_queue_; - - for (ACE_SVC_QUEUE_ITERATOR iter (queue); - iter.next (sptr) != 0; - iter.advance ()) - { - // Process just a single directive. - if (ACE_Service_Config::process_directive (sptr->fast_rep ()) != 0) - { - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("process_directive"))); - result = -1; - } - } - - delete ACE_Service_Config::svc_queue_; - ACE_Service_Config::svc_queue_ = 0; - } - - return result; -} - -int -ACE_Service_Config::process_directive (const ACE_Static_Svc_Descriptor &ssd, - int force_replace) -{ - if (!force_replace) - { - if (ACE_Service_Repository::instance ()->find (ssd.name_, - 0, 0) >= 0) - { - // The service is already there, just return - return 0; - } - } - - ACE_Service_Object_Exterminator gobbler; - void *sym = (ssd.alloc_)(&gobbler); - - ACE_Service_Type_Impl *stp = - ACE_Service_Config::create_service_type_impl (ssd.name_, - ssd.type_, - sym, - ssd.flags_, - gobbler); - if (stp == 0) - return 0; - - - ACE_Service_Type *service_type; - // This is just a temporary to force the compiler to use the right - // constructor in ACE_Service_Type - ACE_DLL tmp_dll; - - ACE_NEW_RETURN (service_type, - ACE_Service_Type (ssd.name_, - stp, - tmp_dll, - ssd.active_), - -1); - - return ACE_Service_Repository::instance ()->insert (service_type); -} - -// Add the default statically-linked services to the Service -// Repository. - -int -ACE_Service_Config::load_static_svcs (void) -{ - ACE_TRACE ("ACE_Service_Config::load_static_svcs"); - - ACE_Static_Svc_Descriptor **ssdp = 0; - ACE_STATIC_SVCS &svcs = *ACE_Service_Config::static_svcs (); - - for (ACE_STATIC_SVCS_ITERATOR iter (svcs); - iter.next (ssdp) != 0; - iter.advance ()) - { - ACE_Static_Svc_Descriptor *ssd = *ssdp; - - if (ACE_Service_Config::process_directive (*ssd, 1) == -1) - return -1; - } - return 0; -} - -// Performs an open without parsing command-line arguments. - -int -ACE_Service_Config::open_i (const ACE_TCHAR program_name[], - const ACE_TCHAR *logger_key, - int ignore_default_svc_conf_file, - int ignore_debug_flag) -{ - int result = 0; - ACE_TRACE ("ACE_Service_Config::open_i"); - ACE_Log_Msg *log_msg = ACE_LOG_MSG; - - // Record the current log setting upon entering this thread. - u_long old_process_mask = log_msg->priority_mask - (ACE_Log_Msg::PROCESS); - u_long old_thread_mask = log_msg->priority_mask - (ACE_Log_Msg::THREAD); - - if (ACE_Service_Config::is_initialized_ != 0) - // Guard against reentrant processing! - return 0; - else - ACE_Service_Config::is_initialized_++; - - if (ACE_Service_Config::init_svc_conf_file_queue () == -1) - return -1; - else if (!ignore_default_svc_conf_file - && ACE_Service_Config::svc_conf_file_queue_->is_empty () - // Load the default "svc.conf" entry here if there weren't - // overriding -f arguments in <parse_args>. - && ACE_Service_Config::svc_conf_file_queue_->enqueue_tail - (ACE_TString (ACE_DEFAULT_SVC_CONF)) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("enqueue_tail")), - -1); - - if (ignore_debug_flag == 0) - { - // If -d was included as a startup parameter, the user wants debug - // information printed during service initialization. - if (ACE::debug ()) - ACE_Log_Msg::enable_debug_messages (); - else - // The user has requested no debugging info. - ACE_Log_Msg::disable_debug_messages (); - } - - // Become a daemon before doing anything else. - if (ACE_Service_Config::be_a_daemon_) - ACE_Service_Config::start_daemon (); - - // Write process id to file. - if (ACE_Service_Config::pid_file_name_ != 0) - { - FILE* pidf = ACE_OS::fopen (ACE_Service_Config::pid_file_name_, - ACE_LIB_TEXT("w")); - - if (pidf != 0) - { - ACE_OS::fprintf (pidf, - "%ld\n", - static_cast<long> (ACE_OS::getpid())); - ACE_OS::fclose (pidf); - } - } - - u_long flags = log_msg->flags (); - - if (flags == 0) - // Only use STDERR if the caller hasn't already set the flags. - flags = (u_long) ACE_Log_Msg::STDERR; - - const ACE_TCHAR *key = logger_key; - - if (key == 0 || ACE_OS::strcmp (key, ACE_DEFAULT_LOGGER_KEY) == 0) - // Only use the static <logger_key_> if the caller doesn't - // override it in the parameter list or if the key supplied is - // equal to the default static logger key. - key = ACE_Service_Config::logger_key_; - else - ACE_SET_BITS (flags, ACE_Log_Msg::LOGGER); - - if (log_msg->open (program_name, - flags, - key) == -1) - result = -1; - else - { - if (ACE::debug ()) - ACE_DEBUG ((LM_STARTUP, - ACE_LIB_TEXT ("starting up daemon %n\n"))); - - // Initialize the Service Repository (this will still work if - // user forgets to define an object of type ACE_Service_Config). - ACE_Service_Repository::instance (ACE_Service_Config::MAX_SERVICES); - - // Initialize the ACE_Reactor (the ACE_Reactor should be the - // same size as the ACE_Service_Repository). - ACE_Reactor::instance (); - - // There's no point in dealing with this on NT since it doesn't - // really support signals very well... -#if !defined (ACE_LACKS_UNIX_SIGNALS) - // Only attempt to register a signal handler for positive - // signal numbers. - if (ACE_Service_Config::signum_ > 0) - if (ACE_Reactor::instance ()->register_handler - (ACE_Service_Config::signum_, - ACE_Service_Config::signal_handler_) == -1) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("can't register signal handler\n"))); -#endif /* ACE_LACKS_UNIX_SIGNALS */ - - // See if we need to load the static services. - if (ACE_Service_Config::no_static_svcs_ == 0 - && ACE_Service_Config::load_static_svcs () == -1) - result = -1; - else - { - if (ACE_Service_Config::process_commandline_directives () == -1) - result = -1; - else - result = ACE_Service_Config::process_directives (); - } - } - - { - // Make sure to save/restore errno properly. - ACE_Errno_Guard error (errno); - - if (ignore_debug_flag == 0) - { - // Reset debugging back to the way it was when we came into - // into <open_i>. - log_msg->priority_mask (old_process_mask, ACE_Log_Msg::PROCESS); - log_msg->priority_mask (old_thread_mask, ACE_Log_Msg::THREAD); - } - } - - return result; -} ACE_Service_Config::ACE_Service_Config (const ACE_TCHAR program_name[], const ACE_TCHAR *logger_key) @@ -838,25 +513,7 @@ ACE_Service_Config::reconfigure (void) int ACE_Service_Config::close (void) { - ACE_TRACE ("ACE_Service_Config::close"); - - ACE_Service_Config::is_initialized_--; - if (ACE_Service_Config::is_initialized_ > 0) - return 0; - - // Delete the service repository. All the objects inside the - // service repository should already have been finalized. - ACE_Service_Config::close_svcs (); - - // Delete the list fo svc.conf files - delete ACE_Service_Config::svc_conf_file_queue_; - ACE_Service_Config::svc_conf_file_queue_ = 0; - - // Delete the dynamically allocated static_svcs instance. - delete ACE_Service_Config::static_svcs_; - ACE_Service_Config::static_svcs_ = 0; - - return 0; + return ACE_Service_Config::current ()->close (); } int @@ -912,20 +569,6 @@ ACE_Service_Config::reconfig_occurred (int config_occurred) ACE_Service_Config::reconfig_occurred_ = config_occurred; } -// Become a daemon (i.e., run as a "background" process). - -int -ACE_Service_Config::start_daemon (void) -{ - ACE_TRACE ("ACE_Service_Config::start_daemon"); - return ACE::daemonize (); -} +// ************************************************************ ACE_END_VERSIONED_NAMESPACE_DECL - -// All the factory functions that allocate default statically linked -// services should be placed below. - -// Allocate a Service Manager. - -ACE_FACTORY_DEFINE (ACE, ACE_Service_Manager) diff --git a/ace/Service_Config.h b/ace/Service_Config.h index 40955ac8a9b..375ed1dd0a0 100644 --- a/ace/Service_Config.h +++ b/ace/Service_Config.h @@ -17,13 +17,12 @@ #include "ace/config-all.h" #include "ace/Default_Constants.h" +#include "ace/Service_Gestalt.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Unbounded_Queue.h" -#include "ace/Unbounded_Set.h" #include "ace/SString.h" #include "ace/OS_NS_signal.h" @@ -122,20 +121,8 @@ public: bool operator!= (ACE_Static_Svc_Descriptor &) const; }; -// Maintain a set of the statically linked service descriptors. -typedef ACE_Unbounded_Set<ACE_Static_Svc_Descriptor *> - ACE_STATIC_SVCS; -typedef ACE_Unbounded_Set_Iterator<ACE_Static_Svc_Descriptor *> - ACE_STATIC_SVCS_ITERATOR; - -// Maintain a queue of services to be configured from the -// command-line. -typedef ACE_Unbounded_Queue<ACE_TString> - ACE_SVC_QUEUE; -typedef ACE_Unbounded_Queue_Iterator<ACE_TString> - ACE_SVC_QUEUE_ITERATOR; - #define ACE_Component_Config ACE_Service_Config + /** * @class ACE_Service_Config * @@ -143,7 +130,22 @@ typedef ACE_Unbounded_Queue_Iterator<ACE_TString> * configuration of services. * * The ACE_Service_Config uses the Monostate pattern. Therefore, - * you can only have one of these instantiated per-process. + * you can only have one of these instantiated per-process. It + * represents the process-wide collection of services, which is + * typicaly shared among all other configurable entities. The only + * ACE_Service_Config instance is registered with and owned by the + * ACE_Object_Manager. + * + * By contrast, the ACE_Service_Gestalt represents the collection + * of services, pertaining to a configurable entity. Typicaly, a + * "configurable entity" is an instance, which owns an instance of + * ACE_Service_Gestalt in order to ensure full controll over the + * services it needs. + * + * Another facet of ACE_Service_Config is that for a given thread, + * it provides access to its current, process-global + * ACE_Service_Gestalt instance through its curent() method. + * * @note The signal_handler_ static member is allocated by the * ACE_Object_Manager. The ACE_Service_Config constructor * uses signal_handler_. Therefore, if the program has any @@ -152,13 +154,9 @@ typedef ACE_Unbounded_Queue_Iterator<ACE_TString> * not eliminated, by _not_ #defining * ACE_HAS_NONSTATIC_OBJECT_MANAGER. */ -class ACE_Export ACE_Service_Config +class ACE_Export ACE_Service_Config: public ACE_Service_Gestalt { public: - enum - { - MAX_SERVICES = ACE_DEFAULT_SERVICE_REPOSITORY_SIZE - }; // = Initialization and termination methods. @@ -168,7 +166,7 @@ public: * registered when the repository is opened. */ ACE_Service_Config (int ignore_static_svcs = 1, - size_t size = ACE_Service_Config::MAX_SERVICES, + size_t size = ACE_Service_Gestalt::MAX_SERVICES, int signum = SIGHUP); /** @@ -179,9 +177,19 @@ public: ACE_Service_Config (const ACE_TCHAR program_name[], const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY); + /// Perform user-specified close activities and remove dynamic + /// memory. + virtual ~ACE_Service_Config (void); + + +protected: + /** - * Performs an open without parsing command-line arguments. The - * @a logger_key indicates where to write the logging output, which + * Performs an open without parsing command-line arguments. + * Implements whats different in the opening sequence + * for this class, as opposed to the base class. + * + * The @a logger_key indicates where to write the logging output, which * is typically either a STREAM pipe or a socket address. If * @a ignore_default_svc_conf_file is non-0 then the "svc.conf" file * will be ignored. If @a ignore_debug_flag is non-0 then the @@ -189,12 +197,56 @@ public: * @c ACE_Log_Msg::priority_mask() appropriately. Returns number of * errors that occurred on failure and 0 otherwise. */ - static int open_i (const ACE_TCHAR program_name[], - const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, - int ignore_default_svc_conf_file = 0, - int ignore_debug_flag = 0); + virtual int open_i (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key, + bool ignore_static_svcs, + bool ignore_default_svc_conf_file, + bool ignore_debug_flag); /** + * Implements whats different in the command line parameter processing + * for this class, as opposed to the base class. + */ + virtual int parse_args_i (int argc, ACE_TCHAR *argv[]); + + + + /// = Static interfaces + + + +protected: + + /// Mutator to set the (TSS) global instance. Intended for use by helper + /// classes, like ACE_Service_Config_Guard which when instantiated on the + /// stack, can temporarily change which gestalt instance is viewed as + /// global from the point of view of the static initializers in DLLs. + static int current (ACE_Service_Gestalt*); + + +public: + + /// If not yet initialized, creates a process-wide instance + /// global instance, which is registered with the ACE_Object_Manager, + /// via ACE_Singleton. Note that this is allways the same instance, + /// in contrast with current (), which may be different instance at + /// different times, dependent on the context. + static ACE_Service_Gestalt* global (void); + + + /// Accessor for the "current" service repository through a pointer + /// held in TSS. + static ACE_Service_Gestalt* current (void); + + /// This is what the static service initializators are hard-wired + /// to use, so in order to keep interface changes to a minimum this + /// method merely forwards to current(). Thus it is possible to + /// temporarily replace what those initializers think is the global + /// service repository, for instance when dynamically loading a + /// service from a DLL, which in turn, contains its own static services. + static ACE_Service_Gestalt* instance (void); + + /** * Performs an open without parsing command-line arguments. The * @a logger_key indicates where to write the logging output, which * is typically either a STREAM pipe or a socket address. If @@ -271,10 +323,6 @@ public: int ignore_default_svc_conf_file = 0, int ignore_debug_flag = 0); - /// Perform user-specified close activities and remove dynamic - /// memory. - virtual ~ACE_Service_Config (void); - /// Tidy up and perform last rites when ACE_Service_Config is shut /// down. This method calls <close_svcs>. Returns 0. static int close (void); @@ -303,11 +351,31 @@ public: // semantics for the Reactor, Service_Repository, Thread_Manager, // and Acceptor/Connector Strategy factory. Other portions of the // system may need to access them at some point or another... + + // = This is not strictly needed, anymore since the service configurator + // has been refactored to allow multiple service configuration + // instances (called gestalts). The interfaces, however were retained in for + // the sake of maintaining source-code compatibility. + // = Accessors and mutators for process-wide Singletons. /// Returns a pointer to the list of statically linked services. - static ACE_STATIC_SVCS *static_svcs (void); + /// + /// @deprecated - Same as instance(), but still useful in legacy code, + /// (notably, one that can not be easily modified) which uses the following + /// idiom for registering static services: + /// + /// ACE_Service_Config::static_svcs ()->insert (...); + static ACE_Service_Gestalt *static_svcs (void); + + /// Insert a static service descriptor for processing on open_i(). The + /// corresponding ACE_STATIC_SVC_* macros were chaged to use this method + /// instead of obtaining a ptr to a container. See the note on static_svcs(). + /// Added to prevent exposing the internal storage representation of the + /// services repository and provide a better way of debugging service + /// loading and registration problems. + static int insert (ACE_Static_Svc_Descriptor *svc); // = Utility methods. /// Dynamically link the shared object file and retrieve a pointer to @@ -340,11 +408,11 @@ public: #if defined (ACE_HAS_WINCE) && defined (ACE_USES_WCHAR) // We must provide these function to bridge the Svc_Conf parser // with ACE. - static int initialize (const ACE_Service_Type *, char parameters[]); - static int initialize (const char svc_name[], char parameters[]); - static int resume (const char svc_name[]); - static int suspend (const char svc_name[]); - static int remove (const char svc_name[]); + static int initialize (const ACE_Service_Type *, ACE_ANTI_TCHAR []); + static int initialize (const char svc_name[], ACE_ANTI_TCHAR parameters[]); + static int resume (const ACE_ANTI_TCHAR svc_name[]); + static int suspend (const ACE_ANTI_TCHAR svc_name[]); + static int remove (const ACE_ANTI_TCHAR svc_name[]); #endif /* ACE_HAS_WINCE */ /// Dump the state of an object. @@ -414,12 +482,15 @@ public: int active); #endif /* ACE_USES_CLASSIC_SVC_CONF == 0 */ - static ACE_Service_Type_Impl *create_service_type_impl (const ACE_TCHAR *name, - int type, - void *symbol, - u_int flags, - ACE_Service_Object_Exterminator gobbler); + static ACE_Service_Type_Impl * + create_service_type_impl (const ACE_TCHAR *name, + int type, + void *symbol, + u_int flags, + ACE_Service_Object_Exterminator gobbler); + protected: + /// Process service configuration requests that were provided on the /// command-line. Returns the number of errors that occurred. static int process_commandline_directives (void); @@ -430,7 +501,8 @@ protected: /// that occurred. static int process_directives_i (ACE_Svc_Conf_Param *param); #else - /// Helper function to dynamically link in the XML Service Configurator parser. + /// Helper function to dynamically link in the XML Service Configurator + /// parser. static ACE_XML_Svc_Conf *get_xml_svc_conf (ACE_DLL &d); #endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ @@ -441,23 +513,8 @@ protected: /// ACE_Service_Repository. static int load_static_svcs (void); + private: - /// Indicates where to write the logging output. This is typically - /// either a STREAM pipe or a socket address. - static const ACE_TCHAR *logger_key_; - - /// Singleton repository of statically linked services. - static ACE_STATIC_SVCS *static_svcs_; - - /// Queue of services specified on the command-line. - static ACE_SVC_QUEUE *svc_queue_; - - /// Queue of svc.conf files specified on the command-line. - /// @@ This should probably be made to handle unicode filenames... - static ACE_SVC_QUEUE *svc_conf_file_queue_; - - /// Initialize the <svc_conf_file_queue_> if necessary. - static int init_svc_conf_file_queue (void); /// True if reconfiguration occurred. static sig_atomic_t reconfig_occurred_; @@ -469,25 +526,63 @@ private: /// Pathname of file to write process id. static ACE_TCHAR *pid_file_name_; - /// Should we avoid loading the static services? - static int no_static_svcs_; - /// Number of the signal used to trigger reconfiguration. static int signum_; /// Handles the reconfiguration signals. static ACE_Sig_Adapter *signal_handler_; - /** - * Keep track of whether the ACE_Service_Config is already - * initialized. If so, we can't allow <yyparse> to be called since - * it's not reentrant. This variable is incremented by the - * <ACE_Service_Config::open> method and decremented by the - * <ACE_Service_Config::close> method. - */ - static int is_initialized_; + /// Pointer to the Singleton (ACE_Cleanup) Gestalt instance. + /// There is thread-specific global instance pointer, which is used to + /// temporarily change which Gestalt instance is used for static service + /// registrations. + /// + /// A specific use case is a thread, which loads a _dynamic_ service from + /// a DLL. If the said DLL also contains additional _static_ services, + /// those *must* be registered with the same configuration repository as + /// the dynamic service. Otherwise, the DLL's static services would be + /// registered with the global Gestalt and may outlive the DLL that + /// contains their code and perhaps the memory in which they are in. + /// This is a problem because if the DLL gets unloaded (as it will, if + /// it was loaded in an instance of Gestalt), the DLL's memory will be + /// deallocated, but the global service repository will still "think" + /// it must finalize the (DLL's) static services - with disastrous + /// consequences, occurring in the post-main code (at_exit()). + static ACE_TSS< ACE_TSS_Type_Adapter <ACE_Service_Gestalt*> > current_; + + /// This class needs the intimate access to be able to swap the + /// current TSS pointer for the global Gestalt. + friend class ACE_Service_Config_Guard; + +}; + +/** + * @class ACE_Service_Config_Guard + * + * @brief A guard class, designed to be instantiated on the stack. + * + * Instantiating it with a specific configuration ensures any references to + * ACE_Service_Config::instance(), even when occuring in static constructors, + * will allways access the designated configuration instance. + * This comes very handy when a dynamic service also registers any static + * services of its own and their static factories. + */ +class ACE_Export ACE_Service_Config_Guard +{ +public: + ACE_Service_Config_Guard (ACE_Service_Gestalt * psg); + ~ACE_Service_Config_Guard (void); + +private: + // Private AND not implemented to disable copying + ACE_Service_Config_Guard(const ACE_Service_Config_Guard&); + ACE_Service_Config_Guard& operator= (const ACE_Service_Config_Guard&); + +private: + ACE_Service_Gestalt* saved_; }; + ACE_END_VERSIONED_NAMESPACE_DECL #if defined (__ACE_INLINE__) diff --git a/ace/Service_Config.inl b/ace/Service_Config.inl index 44df3f6742d..c93fc6a06f2 100644 --- a/ace/Service_Config.inl +++ b/ace/Service_Config.inl @@ -17,14 +17,14 @@ ACE_Service_Config::open (const ACE_TCHAR program_name[], int ignore_debug_flag) { ACE_TRACE ("ACE_Service_Config::open"); - ACE_Service_Config::no_static_svcs_ = ignore_static_svcs; - - return ACE_Service_Config::open_i (program_name, + return ACE_Service_Config::current()->open (program_name, logger_key, + ignore_static_svcs, ignore_default_svc_conf, ignore_debug_flag); } + ACE_INLINE int ACE_Service_Config::open (int argc, ACE_TCHAR *argv[], @@ -34,18 +34,23 @@ ACE_Service_Config::open (int argc, int ignore_debug_flag) { ACE_TRACE ("ACE_Service_Config::open"); - ACE_Service_Config::no_static_svcs_ = ignore_static_svcs; - - if (ACE_Service_Config::parse_args (argc, - argv) == -1) - return -1; - else - return ACE_Service_Config::open_i (argv[0], + return ACE_Service_Config::current()->open (argc, + argv, logger_key, + ignore_static_svcs, ignore_default_svc_conf, ignore_debug_flag); } +// Handle the command-line options intended for the +// ACE_Service_Config. + +ACE_INLINE int +ACE_Service_Config::parse_args (int argc, ACE_TCHAR *argv[]) +{ + return ACE_Service_Config::current ()->parse_args (argc, argv); +} + // Compare two service descriptors for equality. ACE_INLINE bool @@ -68,38 +73,85 @@ ACE_Service_Config::signal_handler (ACE_Sig_Adapter *signal_handler) signal_handler_ = signal_handler; } +// Initialize and activate a statically linked service. + +ACE_INLINE int +ACE_Service_Config::initialize (const ACE_TCHAR *svc_name, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Config::initialize"); + return ACE_Service_Config::current ()->initialize (svc_name, + parameters); +} + +// Dynamically link the shared object file and retrieve a pointer to +// the designated shared object in this file. + +ACE_INLINE int +ACE_Service_Config::initialize (const ACE_Service_Type *sr, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Config::initialize"); + return ACE_Service_Config::current ()->initialize (sr, + parameters); +} + + +ACE_INLINE int +ACE_Service_Config::process_directive (const ACE_TCHAR directive[]) +{ + return ACE_Service_Config::current ()->process_directive (directive); +} + +// Process service configuration requests as indicated in the queue of +// svc.conf files. +ACE_INLINE int +ACE_Service_Config::process_directives (void) +{ + return ACE_Service_Config::current ()->process_directives (); +} + +ACE_INLINE int +ACE_Service_Config::process_directive (const ACE_Static_Svc_Descriptor &ssd, + int force_replace) +{ + return ACE_Service_Config::current ()->process_directive (ssd, + force_replace); +} + + #if defined (ACE_HAS_WINCE) && defined (ACE_USES_WCHAR) // We must provide these function to bridge Svc_Conf parser with ACE. ACE_INLINE int -ACE_Service_Config::initialize (const ACE_Service_Type *sp, char parameters[]) +ACE_Service_Config::initialize (const ACE_Service_Type *sp, ACE_ANTI_TCHAR parameters[]) { - return ACE_Service_Config::initialize (sp, ACE_TEXT_CHAR_TO_TCHAR (parameters)); + return ACE_Service_Config::initialize (sp, ACE_TEXT_ANTI_TO_TCHAR (parameters)); } ACE_INLINE int -ACE_Service_Config::initialize (const char svc_name[], char parameters[]) +ACE_Service_Config::initialize (const ACE_ANTI_TCHAR svc_name[], ACE_ANTI_TCHAR parameters[]) { - return ACE_Service_Config::initialize (ACE_TEXT_CHAR_TO_TCHAR (svc_name), - ACE_TEXT_CHAR_TO_TCHAR (parameters)); + return ACE_Service_Config::initialize (ACE_TEXT_ANTI_TO_TCHAR (svc_name), + ACE_TEXT_ANTI_TO_TCHAR (parameters)); } ACE_INLINE int -ACE_Service_Config::resume (const char svc_name[]) +ACE_Service_Config::resume (const ACE_ANTI_TCHAR svc_name[]) { - return ACE_Service_Config::resume (ACE_TEXT_CHAR_TO_TCHAR (svc_name)); + return ACE_Service_Config::resume (ACE_TEXT_ANTI_TO_TCHAR (svc_name)); } ACE_INLINE int -ACE_Service_Config::suspend (const char svc_name[]) +ACE_Service_Config::suspend (const ACE_ANTI_TCHAR svc_name[]) { - return ACE_Service_Config::suspend (ACE_TEXT_CHAR_TO_TCHAR (svc_name)); + return ACE_Service_Config::suspend (ACE_TEXT_ANTI_TO_TCHAR (svc_name)); } ACE_INLINE int -ACE_Service_Config::remove (const char svc_name[]) +ACE_Service_Config::remove (const ACE_ANTI_TCHAR svc_name[]) { - return ACE_Service_Config::remove (ACE_TEXT_CHAR_TO_TCHAR (svc_name)); + return ACE_Service_Config::remove (ACE_TEXT_ANTI_TO_TCHAR (svc_name)); } #endif /* ACE_HAS_WINCE && !ACE_USES_WCHAR */ diff --git a/ace/Service_Gestalt.cpp b/ace/Service_Gestalt.cpp new file mode 100644 index 00000000000..28efeb2c21e --- /dev/null +++ b/ace/Service_Gestalt.cpp @@ -0,0 +1,1108 @@ +// $Id$ + +#include "ace/Svc_Conf.h" +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "ace/Malloc.h" +#include "ace/Service_Manager.h" +#include "ace/Service_Types.h" +#include "ace/Containers.h" +#include "ace/Auto_Ptr.h" +#include "ace/Reactor.h" +#include "ace/Thread_Manager.h" +#include "ace/DLL.h" +#include "ace/XML_Svc_Conf.h" +#include "ace/SString.h" + +#ifndef ACE_LACKS_UNIX_SIGNALS +# include "ace/Signal.h" +#endif /* !ACE_LACKS_UNIX_SIGNALS */ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_sys_stat.h" + +#include "ace/TSS_T.h" +#include "ace/Service_Gestalt.h" + +#include "ace/Svc_Conf_Param.h" + +ACE_RCSID (ace, + Service_Gestalt, + "$Id$") + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// This is here, in the implementation, because it depends on the ACE_DLL type, +// which would be unnecessary to introduuce all over the place, had we declared +// this in the header file. + +// A forward service declaration guard. Used to declare a Service Type with a +// specific name in a Service Repository, which may later be replaced by the +// "real" Service Type. The only application is in the implementation of +// ACE_Service_Gestalt::initialize (), hence the declaration scoping in +// this file. +class ACE_Service_Type_Forward_Declaration_Guard +{ +public: + ACE_Service_Type_Forward_Declaration_Guard (ACE_Service_Repository *r, + ACE_TCHAR const *name); + + ~ACE_Service_Type_Forward_Declaration_Guard (void); + +private: + const ACE_DLL dummy_dll_; + ACE_Service_Repository *repo_; + ACE_TCHAR const * const name_; + ACE_Service_Type const * dummy_; +}; + +ACE_Service_Type_Forward_Declaration_Guard::ACE_Service_Type_Forward_Declaration_Guard +(ACE_Service_Repository *r, const ACE_TCHAR *name) + : repo_ (r) + , name_ (name) +{ + ACE_ASSERT (this->repo_ != 0); // No repository specified? + ACE_ASSERT (this->name_ != 0); // No name? + + ACE_NEW_NORETURN (this->dummy_, // Allocate the forward declaration ... + ACE_Service_Type (this->name_, // ... use the same name + 0, // ... inactive + this->dummy_dll_, // ... bogus ACE_DLL + 0)); // ... no type_impl + + ACE_ASSERT (this->dummy_ != 0); // No memory? + + if(ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) FWDCL::start, repo=%@, \'%s\' ") + ACE_LIB_TEXT ("- type=%@ (impl=(nil))\n"), + this->repo_, + this->name_, + this->dummy_)); + + // Note that the dummy_'s memory can disaper between invoking + // the ctor and dtor, if the expected "real" dynamic service is + // inserted in the repository. + this->repo_->insert (this->dummy_); +} + +ACE_Service_Type_Forward_Declaration_Guard::~ACE_Service_Type_Forward_Declaration_Guard (void) +{ + const ACE_Service_Type *tmp = 0; + + // Lookup without ignoring suspended services. Making sure + // not to ignore any inactive services, since those may be forward + // declarations + int ret = this->repo_->find (this->name_, &tmp, 0); + + // We inserted it (as inactive), so we expect to find it, right? + ACE_ASSERT (ret = -2 || ret >= 0); + + if (tmp != 0 && tmp->type () != 0) + { + // Something has registered a proper (non-forward-decl) service with + // the same name as our dummy. The ACE_Service_Gestalt::insert() modifies + // the memory for the previous ACE_Service_Type instance. It has in fact + // taken ownership and deleted the instance when it replaced it with the + // actual implementation, so nothing is left to do. We are hereby giving + // up any ownership claims. + this->dummy_ = 0; + + if(ACE::debug ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) FWDCL::end, repo=%@ - ") + ACE_LIB_TEXT ("Found different decl - "), + this->repo_, + this->name_)); + tmp->dump (); + } + + } + else + { + if(ACE::debug ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) FWDCL::end, repo=%@ - ") + ACE_LIB_TEXT ("Removing incomplete decl - "), + this->repo_, + this->name_)); + this->dummy_->dump (); + } + + // The (dummy) forward declaration is still there and is + // the same, which means that no actual declaration was + // provided inside the guarded scope. Therefore, the forward + // declaration is no longer necessary. + if (this->repo_->remove (this->name_, + const_cast< ACE_Service_Type**> (&this->dummy_)) == 0) + { + delete this->dummy_; + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) FWDCL::end, repo=%@ - ") + ACE_LIB_TEXT ("Failed to remove incomplete decl"), + this->repo_, + this->name_)); + this->dummy_->dump (); + } + } + + + // Clean up + this->dummy_ = 0; + this->repo_ = 0; +} + + + +// ---------------------------------------- + +ACE_Service_Gestalt::~ACE_Service_Gestalt (void) +{ + ACE_ASSERT (this->repo_ != 0); + + if (this->repo_is_owned_) + delete this->repo_; +} + +ACE_Service_Gestalt::ACE_Service_Gestalt (size_t size) + : repo_ (new ACE_Service_Repository (size)) + , repo_is_owned_ (true) + , is_opened_ (0) + , svc_conf_file_queue_ (0) + , static_svcs_ (new ACE_STATIC_SVCS) + , svc_queue_ (0) + , logger_key_ (ACE_DEFAULT_LOGGER_KEY) + , no_static_svcs_ (1) +{ + ACE_ASSERT (this->repo_ != 0); +} + +ACE_Service_Gestalt::ACE_Service_Gestalt (void) + : repo_ (ACE_Service_Repository::instance ()) + , repo_is_owned_ (false) + , is_opened_ (0) + , svc_conf_file_queue_ (0) + , static_svcs_ (new ACE_STATIC_SVCS) + , svc_queue_ (0) + , logger_key_ (ACE_DEFAULT_LOGGER_KEY) + , no_static_svcs_ (1) +{ + ACE_ASSERT (this->repo_ != 0); +} + + + +// Add the default statically-linked services to the Service +// Repository. + +int +ACE_Service_Gestalt::load_static_svcs (void) +{ + ACE_TRACE ("ACE_Service_Gestalt::load_static_svcs"); + + if (this->static_svcs_ == 0) + return 0; // Nothing to do + + ACE_Static_Svc_Descriptor **ssdp = 0; + for (ACE_STATIC_SVCS_ITERATOR iter (*this->static_svcs_); + iter.next (ssdp) != 0; + iter.advance ()) + { + ACE_Static_Svc_Descriptor *ssd = *ssdp; + + if (this->process_directive (*ssd, 1) == -1) + return -1; + } + return 0; + +} /* load_static_svcs () */ + + + +/// Find a static service descriptor by name + +int +ACE_Service_Gestalt::find_static_svc_descriptor (const ACE_TCHAR* name, + ACE_Static_Svc_Descriptor **ssd) const +{ + ACE_TRACE ("ACE_Service_Gestalt::find_static_svc_descriptor"); + + if (this->static_svcs_ == 0) + return -1; + + ACE_Static_Svc_Descriptor **ssdp = 0; + for (ACE_STATIC_SVCS_ITERATOR iter ( *this->static_svcs_); + iter.next (ssdp) != 0; + iter.advance ()) + { + if (ACE_OS::strcmp ((*ssdp)->name_, name) == 0) + { + if (ssd != 0) + *ssd = *ssdp; + + return 0; + } + } + return -1; + +} /* find_static_svc_descriptor () */ + + +int +ACE_Service_Gestalt::insert (ACE_Static_Svc_Descriptor *stsd) +{ + if (ACE::debug () > 1) + { + // If called during static initialization ACE_Log_Msg may not have + // been initialized yet, so use printf intead. + ACE_OS::fprintf (stderr, + "// (%d|0) SG::insert" + " repo=%p, name=%s - Static_Svc_Descriptor: active=%d, opened=%d.\n", + ACE_OS::getpid (), + this->repo_, + stsd->name_, + stsd->active_, + this->is_opened_); + } + + // Inserting a service after teh Gestalt has been opened makes it + // impossible to activate it later. Perhaps open came too soon? + //ACE_ASSERT (this->is_opened_ == 0); + + return this->static_svcs_->insert (stsd); +} + + +ACE_ALLOC_HOOK_DEFINE (ACE_Service_Gestalt) + + +void +ACE_Service_Gestalt::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_TRACE ("ACE_Service_Gestalt::dump"); +#endif /* ACE_HAS_DUMP */ +} + + + +ACE_ALLOC_HOOK_DEFINE (ACE_Service_Type_Factory) + +ACE_Service_Type_Factory::ACE_Service_Type_Factory (ACE_TCHAR const *name, + int type, + ACE_Location_Node *location, + int active) + : name_ (name) + , type_ (type) + , location_ (location) + , is_active_ (active) +{ + ACE_TRACE ("ACE_Service_Type_Factory::ACE_Service_Type_Factory"); +}; + +ACE_Service_Type_Factory::~ACE_Service_Type_Factory (void) +{ + ACE_TRACE ("ACE_Service_Type_Factory::~ACE_Service_Type_Factory"); +} + + +ACE_Service_Type * +ACE_Service_Type_Factory::make_service_type (ACE_Service_Gestalt *cfg) const +{ + ACE_TRACE ("ACE_Service_Type_Factory::make_service_type"); + + u_int flags = ACE_Service_Type::DELETE_THIS + | (this->location_->dispose () == 0 ? 0 : ACE_Service_Type::DELETE_OBJ); + + ACE_Service_Object_Exterminator gobbler = 0; + + int yyerrno = 0; + void *sym = this->location_->symbol (cfg, yyerrno, &gobbler); + + if (sym != 0) + { + ACE_Service_Type_Impl *stp + = ACE_Service_Config::create_service_type_impl (this->name (), + this->type_, + sym, + flags, + gobbler); + if (stp == 0) + ++yyerrno; + + return new ACE_Service_Type (this->name (), + stp, + this->location_->dll (), + this->is_active_); + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("Unable to find service: %s\n"), + this->name ())); + ++yyerrno; + return 0; + } +} + +ACE_TCHAR const* +ACE_Service_Type_Factory::name (void) const +{ + return name_.c_str (); +} + + +/// + +int +ACE_Service_Gestalt::initialize (const ACE_TCHAR *svc_name, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Gestalt_Base::initialize (repo)"); + ACE_ARGV args (parameters); + + if (ACE::debug () > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SG::initialize - () repo=%@, looking up static ") + ACE_LIB_TEXT ("service \'%s\' to initialize\n"), + this->repo_, + svc_name)); + } + + const ACE_Service_Type *srp = 0; + if (this->repo_->find (svc_name, &srp) == -1) + { + // Since we're searching by name, the service may be in the + // process-wide repository, so check that before reporting + // failure. + if (this->repo_ == ACE_Service_Repository::instance () + || ACE_Service_Repository::instance ()->find (svc_name, &srp) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) SG::initialize - service \'%s\'") + ACE_LIB_TEXT (" was not located.\n"), + svc_name), + -1); + } + } + + /// If initialization fails ... + if (srp->type ()->init (args.argc (), + args.argv ()) == -1) + { + // ... report and remove this entry. + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) SG::initialize - static init of \'%s\'") + ACE_LIB_TEXT (" failed (%p)\n"), + svc_name)); + this->repo_->remove (svc_name); + return -1; + } + + // If everything is ok, activate it + const_cast<ACE_Service_Type *>(srp)->active (1); + return 0; +} + + +int +ACE_Service_Gestalt::initialize (const ACE_Service_Type_Factory *stf, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Gestalt::initialize"); + + if (ACE::debug () > 1) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SG::initialize - repo=%@, looking up dynamic ") + ACE_LIB_TEXT ("service \'%s\' to initialize\n"), + this->repo_, + stf->name ())); + + ACE_Service_Type *srp = 0; + int retv = this->repo_->find (stf->name (), + (const ACE_Service_Type **) &srp); + + // If there is an active service already, it must first be removed, + // before it could be re-installed. + if (retv >= 0) + ACE_ERROR_RETURN ((LM_WARNING, + ACE_LIB_TEXT ("(%P|%t) \'%s\' already installed.") + ACE_LIB_TEXT (" Must be removes before re-installing\n"), + stf->name ()), + 0); + + // There is an inactive service by that name, so it may have been + // either inactivated, or just a forward declaration for a service, + // that is in the process of being loaded. If the latter, then we + // have detected an attempt to initialize the same dynamic service + // while still processing previous attempt. This can lock up the + // process, because the ACE_DLL_Manager::open () is not re-entrant - + // it uses a Singleton lock to serialize concurent invocations. This + // use case must be handled here, because if the DLL_Manager was + // re-entrant we would have entered an infinite recursion here. + if (retv == -2 && srp->type () == 0) + ACE_ERROR_RETURN ((LM_WARNING, + ACE_LIB_TEXT ("(%P|%t) \'%s\' has not been ") + ACE_LIB_TEXT ("completely defined. Recursive ") + ACE_LIB_TEXT ("initialization request while ") + ACE_LIB_TEXT ("already performing one.\n"), + stf->name ()), + -1); + + // Reserve a spot for the dynamic service by inserting an incomplete + // service declaration, i.e. one that can not produce a service + // object if asked. Having this incomplete declaration works + // similar to C++'s forward declaration to allow, in this case + // proper partial ordering of the loaded services in respect to + // their finalization. I.e. dependent static services must be + // registered *after* the dynamic service that loads them, so that + // their finalization is complete *before* finalizing the dynamic + // service. + ACE_Service_Type_Forward_Declaration_Guard dummy (this->repo_, + stf->name ()); + + // make_service_type() is doing the dynamic loading and also runs + // any static initializers + ACE_Auto_Ptr<ACE_Service_Type> tmp (stf->make_service_type (this)); + + if (tmp.get () != 0 && + this->initialize_i (tmp.get (), parameters) == 0) + { + // All good the ACE_Service_Type instance is now owned by the repository + // and we should make sure it is not destroyed upon exit from this method. + (void)tmp.release (); + return 0; + } + + // Something went wrong ... + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) Error initializing \'%s\'\n"), + stf->name()), + -1); +} + + +// Dynamically link the shared object file and retrieve a pointer to +// the designated shared object in this file. +// @note This is obsolete (and error-prone) in the presense of dynamic +// services with their own static services. This method will allow those +// static services to register *before* the dynamic service that owns them. +// Upon finalization of the static services the process may crash, because +// the dynamic service's DLL may have been already released, together with +// the memory in which the static services reside. +// It may not crash, for instance, when the first static service to register +// is the same as the dynamic service being loaded. You should be so lucky! .. + +int +ACE_Service_Gestalt::initialize (const ACE_Service_Type *sr, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Gestalt::initialize"); + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SG::initialize - looking up dynamic ") + ACE_LIB_TEXT (" service \'%s\' to initialize\n"), + sr->name ())); + + ACE_Service_Type *srp = 0; + if (this->repo_->find (sr->name (), + (const ACE_Service_Type **) &srp) >= 0) + ACE_ERROR_RETURN ((LM_WARNING, + ACE_LIB_TEXT ("(%P|%t) SG::initialize - \'%s\' ") + ACE_LIB_TEXT ("has already been installed. ") + ACE_LIB_TEXT ("Remove before reinstalling\n"), + sr->name ()), + 0); + + return this->initialize_i (sr, parameters); + +} + +// Dynamically link the shared object file and retrieve a pointer to +// the designated shared object in this file. +int +ACE_Service_Gestalt::initialize_i (const ACE_Service_Type *sr, + const ACE_TCHAR *parameters) +{ + ACE_TRACE ("ACE_Service_Gestalt::initialize_i"); + ACE_ARGV args (parameters); + + if (sr->type ()->init (args.argc (), + args.argv ()) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) SG - dynamic initialization ") + ACE_LIB_TEXT ("failed for \'%s\'\n"), + sr->name ())); + + ACE_Service_Type *ps = 0; + this->repo_->remove (sr->name (), &ps); + + // We just get ps to avoid having remove() delete it. + return -1; + } + + if (this->repo_->insert (sr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("(%P|%t) SG - inserting service") + ACE_LIB_TEXT (" description failed, %p\n"), + sr->name ()), + -1); + return 0; +} + +// Totally remove <svc_name> from the daemon by removing it from the +// ACE_Reactor, and unlinking it if necessary. + +int +ACE_Service_Gestalt::remove (const ACE_TCHAR svc_name[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::remove"); + return this->repo_->remove (svc_name); +} + +// Suspend <svc_name>. Note that this will not unlink the service +// from the daemon if it was dynamically linked, it will mark it as +// being suspended in the Service Repository and call the <suspend> +// member function on the appropriate <ACE_Service_Object>. A service +// can be resumed later on by calling the <resume> method... + +int +ACE_Service_Gestalt::suspend (const ACE_TCHAR svc_name[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::suspend"); + return this->repo_->suspend (svc_name); +} + +// Resume a SVC_NAME that was previously suspended or has not yet +// been resumed (e.g., a static service). + +int +ACE_Service_Gestalt::resume (const ACE_TCHAR svc_name[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::resume"); + return this->repo_->resume (svc_name); +} + + +int +ACE_Service_Gestalt::process_directive (const ACE_Static_Svc_Descriptor &ssd, + int force_replace) +{ + if (ACE::debug () > 2) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SG::process_directive, ") + ACE_LIB_TEXT ("repo=%@, replace=%d - %s\n"), + this->repo_, + force_replace, + ssd.name_)); + + if (!force_replace) + { + if (this->repo_->find (ssd.name_, 0, 0) >= 0) + { + // The service is already there, just return + return 0; + } + } + + ACE_Service_Object_Exterminator gobbler; + void *sym = (ssd.alloc_)(&gobbler); + + ACE_Service_Type_Impl *stp = + ACE_Service_Config::create_service_type_impl (ssd.name_, + ssd.type_, + sym, + ssd.flags_, + gobbler); + if (stp == 0) + return 0; + + + ACE_Service_Type *service_type; + + // This is just a temporary to force the compiler to use the right + // constructor in ACE_Service_Type + ACE_DLL tmp_dll; + + ACE_NEW_RETURN (service_type, + ACE_Service_Type (ssd.name_, + stp, + tmp_dll, + ssd.active_), + -1); + + return this->repo_->insert (service_type); +} + + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + +int +ACE_Service_Gestalt::process_directives_i (ACE_Svc_Conf_Param *param) +{ + // AC 970827 Skip the heap check because yacc allocates a buffer + // here which will be reported as a memory leak for some reason. + ACE_NO_HEAP_CHECK + + // Were we called in the context of the current instance? + ACE_ASSERT (this == param->config); + + // Temporarily (for the duration of this call) make sure that *any* static + // service registrations will happen with this instance. Such registrations + // are possible as a side-effect of dynamically loading a DLL, which has + // other static services registered. Thus this instance will own both the + // DLL and those static services, which implies that their finalization + // will be performed in the correct order, i.e. prior to finalizing the DLL + ACE_Service_Config_Guard guard (this); + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SG::process_directives_i, ") + ACE_LIB_TEXT ("repo=%@ - %s\n"), + this->repo_, + (param->type == ACE_Svc_Conf_Param::SVC_CONF_FILE) + ? ACE_TEXT ("<from file>") + : param->source.directive)); + + + ::ace_yyparse (param); + + if (param->yyerrno > 0) + { + // This is a hack, better errors should be provided... + errno = EINVAL; + return param->yyerrno; + } + else + return 0; +} + +#else + +ACE_XML_Svc_Conf * +ACE_Service_Gestalt::get_xml_svc_conf (ACE_DLL &xmldll) +{ + if (xmldll.open (ACE_LIB_TEXT ("ACEXML_XML_Svc_Conf_Parser")) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("Fail to open ACEXML_XML_Svc_Conf_Parser: %p\n"), + "ACE_Service_Config::get_xml_svc_conf"), + 0); + + void *foo; + foo = xmldll.symbol (ACE_LIB_TEXT ("_ACEXML_create_XML_Svc_Conf_Object")); + + // Cast the void* to long first. + long tmp = reinterpret_cast<long> (foo); + ACE_XML_Svc_Conf::Factory factory = + reinterpret_cast<ACE_XML_Svc_Conf::Factory> (tmp); + if (factory == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("Unable to resolve factory: %p\n"), + xmldll.error ()), + 0); + + return factory (); +} +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + +int +ACE_Service_Gestalt::process_file (const ACE_TCHAR file[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::process_file"); + + // To avoid recursive processing of the same file and the same repository + // we maintain an implicit stack of dummy "services" named after the file + // being processed. Anytime we have to open a new file, we then can check + // to see if it is not already being processed by searching for a dummy + // service with a matching name. + if (this->repo_->find (file, 0, 0) >=0) + { + ACE_DEBUG ((LM_WARNING, + ACE_TEXT ("(%P|%t) Configuration file %s has not finished") + ACE_TEXT (" processing yet. Ignoring.\n"), + file)); + return 0; + } + + // Register a dummy service as a forward decl, using the file name as name. + // The entry will be automaticaly removed once the thread exits this block. + ACE_Service_Type_Forward_Declaration_Guard recursion_guard (this->repo_, file); + + /* + * @TODO: Test with ACE_USES_CLASSIC_SVC_CONF turned off! + */ +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + int result = 0; + + FILE *fp = ACE_OS::fopen (file, + ACE_LIB_TEXT ("r")); + + if (fp == 0) + { + // Invalid svc.conf file. We'll report it here and break out of + // the method. + if (ACE::debug ()) + ACE_DEBUG ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + file)); + + // Use stat to find out if the file exists. I didn't use access() + // because stat is better supported on most non-unix platforms. + ACE_stat exists; + if (ACE_OS::stat (file, &exists) == 0) + // If it exists, but we couldn't open it for reading then we + // must not have permission to read it. + errno = EPERM; + else + errno = ENOENT; + result = -1; + } + else + { + ACE_Svc_Conf_Param f (this, fp); + + // Keep track of the number of errors. + result = this->process_directives_i (&f); + + (void) ACE_OS::fclose (fp); + } + return result; +#else + ACE_DLL dll; + + auto_ptr<ACE_XML_Svc_Conf> + xml_svc_conf (ACE_Service_Config::get_xml_svc_conf (dll)); + + if (xml_svc_conf.get () == 0) + return -1; + + return xml_svc_conf->parse_file (file); +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ +} + +int +ACE_Service_Gestalt::process_directive (const ACE_TCHAR directive[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::process_directive"); + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SG::process_directive, repo=%@ - %s\n"), + this->repo_, + directive)); + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + ACE_UNUSED_ARG (directive); + + ACE_Svc_Conf_Param d (this, directive); + + int result = this->process_directives_i (&d); + + return result; +#else + ACE_DLL dll; + + auto_ptr<ACE_XML_Svc_Conf> + xml_svc_conf (this->get_xml_svc_conf (dll)); + + if (xml_svc_conf.get () == 0) + return -1; + + return xml_svc_conf->parse_string (directive); +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + +} /* process_directive () */ + + +int +ACE_Service_Gestalt::init_svc_conf_file_queue (void) +{ + if (this->svc_conf_file_queue_ == 0) + { + ACE_SVC_QUEUE *tmp = 0; + ACE_NEW_RETURN (tmp, + ACE_SVC_QUEUE, + -1); + delete this->svc_conf_file_queue_; + this->svc_conf_file_queue_ = tmp; + } + + if (ACE::debug () > 1) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SG::init_svc_conf_file_queue ") + ACE_LIB_TEXT ("- this=%@, repo=%@\n"), + this, this->repo_)); + return 0; + +} /* init_svc_conf_file_queue () */ + + +int +ACE_Service_Gestalt::open_i (const ACE_TCHAR /*program_name*/[], + const ACE_TCHAR* /*logger_key*/, + bool /*ignore_static_svcs*/, + bool /*ignore_default_svc_conf_file*/, + bool ignore_debug_flag) +{ + ACE_TRACE ("ACE_Service_Gestalt::open_i"); + int result = 0; + ACE_Log_Msg *log_msg = ACE_LOG_MSG; + + // Record the current log setting upon entering this thread. + u_long old_process_mask = log_msg->priority_mask + (ACE_Log_Msg::PROCESS); + u_long old_thread_mask = log_msg->priority_mask + (ACE_Log_Msg::THREAD); + + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) SG::open_i - this=%@, ") + ACE_TEXT ("opened=%d, loadstatics=%d\n"), + this, this->is_opened_, this->no_static_svcs_)); + + // Guard against reentrant processing. For example, + // if the singleton gestalt (ubergestalt) was already open, + // do not open it again... + if (this->is_opened_++ != 0) + return 0; + + if (ignore_debug_flag == 0) + { + // If -d was included as a startup parameter, the user wants debug + // information printed during service initialization. + if (ACE::debug ()) + ACE_Log_Msg::enable_debug_messages (); + else + // The user has requested no debugging info. + ACE_Log_Msg::disable_debug_messages (); + } + + // See if we need to load the static services. + if (this->no_static_svcs_ == 0 + && this->load_static_svcs () == -1) + result = -1; + else + { + if (this->process_commandline_directives () == -1) + result = -1; + else + result = this->process_directives (); + } + + + // Reset debugging back to the way it was when we came into + // into <open_i>. + { + // Make sure to save/restore errno properly. + ACE_Errno_Guard error (errno); + + if (ignore_debug_flag == 0) + { + log_msg->priority_mask (old_process_mask, ACE_Log_Msg::PROCESS); + log_msg->priority_mask (old_thread_mask, ACE_Log_Msg::THREAD); + } + } + + return result; +} /* open_i () */ + + +int +ACE_Service_Gestalt::is_opened (void) +{ + return this->is_opened_; +} + +int +ACE_Service_Gestalt::process_commandline_directives (void) +{ + int result = 0; + if (this->svc_queue_ != 0) + { + ACE_TString *sptr = 0; + for (ACE_SVC_QUEUE_ITERATOR iter (*this->svc_queue_); + iter.next (sptr) != 0; + iter.advance ()) + { + // Process just a single directive. + if (this->process_directive ((sptr->fast_rep ())) != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("process_directive"))); + result = -1; + } + } + + delete this->svc_queue_; + this->svc_queue_ = 0; + } + + return result; + +} /* process_commandline_directives () */ + + +int +ACE_Service_Gestalt::parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::parse_args"); + return parse_args_i (argc, argv); +} + +int +ACE_Service_Gestalt::parse_args_i (int argc, ACE_TCHAR *argv[]) +{ + ACE_TRACE ("ACE_Service_Gestalt::parse_args_i"); + ACE_Get_Opt getopt (argc, + argv, + ACE_LIB_TEXT ("df:k:nyp:s:S:"), + 1); // Start at argv[1]. + + if (this->init_svc_conf_file_queue () == -1) + return -1; + + for (int c; (c = getopt ()) != -1; ) + switch (c) + { + case 'd': + ACE::debug (1); + break; + case 'f': + if (this->svc_conf_file_queue_->enqueue_tail (ACE_TString (getopt.opt_arg ())) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("enqueue_tail")), + -1); + break; + case 'k': + /* + * @TODO: Is this always a static storage? Shouldn't we copy + * & gain ownership of the value? + */ + this->logger_key_ = getopt.opt_arg (); + break; + case 'n': + this->no_static_svcs_ = 1; + break; + case 'y': + this->no_static_svcs_ = 0; + break; + case 'S': + if (this->svc_queue_ == 0) + { + ACE_NEW_RETURN (this->svc_queue_, + ACE_SVC_QUEUE, + -1); + } + + if (this->svc_queue_->enqueue_tail (ACE_TString (getopt.opt_arg ())) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("enqueue_tail")), + -1); + break; + default: + if (ACE::debug () > 0) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("%c is not a ACE_Service_Config option\n"), + c)); + } + + return 0; +} /* parse_args_i () */ + + + +// Process service configuration requests as indicated in the queue of +// svc.conf files. +int +ACE_Service_Gestalt::process_directives (void) +{ + ACE_TRACE ("ACE_Service_Gestalt::process_directives"); + + int result = 0; + + if (this->svc_conf_file_queue_ != 0) + { + ACE_TString *sptr = 0; + + // Iterate through all the svc.conf files. + for (ACE_SVC_QUEUE_ITERATOR iter (*this->svc_conf_file_queue_); + iter.next (sptr) != 0; + iter.advance ()) + { + int r = this->process_file (sptr->fast_rep ()); + + if (r < 0) + { + result = r; + break; + } + + result += r; + } + } + + return result; + +} /* process_directives () */ + + + +// Tidy up and perform last rites on a terminating ACE_Service_Gestalt. +int +ACE_Service_Gestalt::close (void) +{ + ACE_TRACE ("ACE_Service_Gestalt::close"); + + if (ACE::debug () > 1) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SG::close - this=%@, repo=%@, is_opened=%d\n"), + this, this->repo_, this->is_opened_)); + + this->is_opened_--; + if (this->is_opened_ > 0) + return 0; + + // Delete the service repository. All the objects inside the + // service repository should already have been finalized. + // ACE_Service_Config::close_svcs (); + + // Delete the list fo svc.conf files + delete this->svc_conf_file_queue_; + this->svc_conf_file_queue_ = 0; + + // Delete the dynamically allocated static_svcs instance. + if (ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SG::close - this=%@, repo=%@\n"), + this, this->repo_)); + + delete this->static_svcs_; + this->static_svcs_ = 0; + + return 0; + +} /* close () */ + + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Gestalt.inl" +#endif /* __ACE_INLINE__ */ + + +// Allocate a Service Manager. +ACE_FACTORY_DEFINE (ACE, ACE_Service_Manager) diff --git a/ace/Service_Gestalt.h b/ace/Service_Gestalt.h new file mode 100644 index 00000000000..98c52abfca7 --- /dev/null +++ b/ace/Service_Gestalt.h @@ -0,0 +1,440 @@ +// -*- C++ -*- + +//==================================================================== +/** + * @file Service_Gestalt.h + * + * $Id$ + * + * @author Iliyan Jeliazkov <iliyan@ociweb.com> + */ +//==================================================================== + +#ifndef ACE_SERVICE_GESTALT_H +#define ACE_SERVICE_GESTALT_H + +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" +#include "ace/Default_Constants.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SString.h" +#include "ace/Unbounded_Queue.h" +#include "ace/Service_Repository.h" +#include "ace/Singleton.h" +#include "ace/OS_NS_signal.h" +#include "ace/Synch_Traits.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +class ACE_Service_Type_Factory; +class ACE_Static_Svc_Descriptor; +class ACE_Svc_Conf_Param; + +class ACE_Service_Gestalt; + +/** + * @class ACE_Service_Gestalt + * + * @brief Supplies common server operations for dynamic and static + * configuration of services. + */ +class ACE_Export ACE_Service_Gestalt +{ +private: + /** + * Not implemented to enforce no copying + */ + ACE_UNIMPLEMENTED_FUNC (ACE_Service_Gestalt(const ACE_Service_Gestalt&)); + + ACE_UNIMPLEMENTED_FUNC + (ACE_Service_Gestalt& operator=(const ACE_Service_Gestalt&)); + +public: + enum + { + MAX_SERVICES = ACE_DEFAULT_SERVICE_REPOSITORY_SIZE + }; + + /// Default constructor - associates the instance with the process-wide + /// singleton instance of ACE_Service_Repository. + ACE_Service_Gestalt (void); + + /// Creates an instance with a specified repository size. Takes ownership + /// of the repository. + ACE_Service_Gestalt (size_t size); + + /// Perform user-specified close activities and remove dynamic + /// memory. + virtual ~ACE_Service_Gestalt (void); + + /// Dump the state of an object. + void dump (void) const; + + /** + * Performs an open without parsing command-line arguments. The + * @a logger_key indicates where to write the logging output, which + * is typically either a STREAM pipe or a socket address. If + * @a ignore_static_svcs is 1 then static services are not loaded, + * otherwise, they are loaded. If @a ignore_default_svc_conf_file is + * non-0 then the <svc.conf> configuration file will be ignored. + * Returns zero upon success, -1 if the file is not found or cannot + * be opened (errno is set accordingly), otherwise returns the + * number of errors encountered loading the services in the + * specified svc.conf configuration file. If @a ignore_debug_flag is + * non-0 then the application is responsible for setting the + * <ACE_Log_Msg::priority_mask> appropriately. + */ + int open (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, + int ignore_static_svcs = 1, + int ignore_default_svc_conf_file = 0, + int ignore_debug_flag = 0); + + /** + * This is the primary entry point into the ACE_Service_Config (the + * constructor just handles simple initializations). It parses + * arguments passed in from @a argc and @a argv parameters. The + * arguments that are valid in a call to this method include: + * + * - '-b' Option to indicate that we should be a daemon. Note that when + * this option is used, the process will be daemonized before the + * service configuration file(s) are read. During daemonization, + * (on POSIX systems) the current directory will be changed to "/" + * so the caller should either fully specify the file names, or + * execute a @c chroot() to the appropriate directory. + * @sa ACE::daemonize(). + * - '-d' Turn on debugging mode + * - '-f' Specifies a configuration file name other than the default + * svc.conf. Can be specified multiple times to use multiple files. + * - '-k' Specifies the rendezvous point to use for the ACE distributed + * logger. + * - '-y' Explicitly enables the use of static services. This flag + * overrides the @a ignore_static_svcs parameter value. + * - '-n' Explicitly disables the use of static services. This flag + * overrides the @a ignore_static_svcs parameter value. + * - '-p' Specifies a pathname which is used to store the process id. + * - '-s' Specifies a signal number other than SIGHUP to trigger reprocessing + * of the configuration file(s). Ignored for platforms that do not + * have POSIX signals, such as Windows. + * - '-S' Specifies a service directive string. Enclose the string in quotes + * and escape any embedded quotes with a backslash. This option + * specifies service directives without the need for a configuration + * file. + * + * @param argc The number of commandline arguments. + * @param argv The array with commandline arguments + * @param logger_key Indicates where to write the logging output, + * which is typically either a STREAM pipe or a + * socket address. + * @param ignore_static_svcs If 1 then static services are not loaded, + * otherwise, they are loaded. + * @param ignore_default_svc_conf_file If non-0 then the @c svc.conf + * configuration file will be ignored. + * @param ignore_debug_flag If non-0 then the application is responsible + * for setting the @c ACE_Log_Msg::priority_mask + * appropriately. + * + * @retval -1 The configuration file is not found or cannot + * be opened (errno is set accordingly). + * @retval 0 Success. + * @retval >0 The number of errors encountered while processing + * the service configuration file(s). + */ + int open (int argc, + ACE_TCHAR *argv[], + const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, + int ignore_static_svcs = 1, + int ignore_default_svc_conf_file = 0, + int ignore_debug_flag = 0); + + /// Has it been opened? Returns the difference between the times + /// open and close have been called on this instance + int is_opened (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Process one service configuration @a directive, which is passed as + /// a string. Returns the number of errors that occurred. + int process_directive (const ACE_TCHAR directive[]); + + /// Process one static service definition. + /** + * Load a new static service. + * + * @param ssd Service descriptor, see the document of + * ACE_Static_Svc_Descriptor for more details. + * + * @param force_replace If set the new service descriptor replaces + * any previous instance in the repository. + * + * @return Returns -1 if the service cannot be 'loaded'. + */ + int process_directive (const ACE_Static_Svc_Descriptor &ssd, + int force_replace = 0); + + /// Process a file containing a list of service configuration + /// directives. + int process_file (const ACE_TCHAR file[]); + + /** + * Locate an entry with <name> in the table. If <ignore_suspended> + * is set then only consider services marked as resumed. If the + * caller wants the located entry, pass back a pointer to the + * located entry via <srp>. If <name> is not found, -1 is returned. + * If <name> is found, but it is suspended and the caller wants to + * ignore suspended services a -2 is returned. + */ + int find (const ACE_TCHAR name[], + const ACE_Service_Type **srp = 0, + int ignore_suspended = 1) const; + + /** + * Handle the command-line options intended for the + * <ACE_Service_Config>. Note that <argv[0]> is assumed to be the + * program name. + * The arguments that are valid in a call to this method are + * - '-b' Option to indicate that we should be a daemon + * - '-d' Turn on debugging mode + * - '-f' Option to read in the list of svc.conf file names + * - '-k' Option to read a wide string where in the logger output can + * be written + * - '-y' Turn on the flag for a repository of statically + * linked services + * - '-n' Need not have a repository of statically linked services + * - '-S' Option to read in the list of services on the command-line + * Please observe the difference between options '-f' that looks + * for a list of files and here a list of services. + */ + int parse_args (int, ACE_TCHAR *argv[]); + + /** + * Process (or re-process) service configuration requests that are + * provided in the svc.conf file(s). Returns the number of errors + * that occurred. + */ + int process_directives (void); + + /// Tidy up and perform last rites when ACE_Service_Config is shut + /// down. This method calls <close_svcs>. Returns 0. + int close (void); + + + // Registers a service descriptor for a static service object + int insert (ACE_Static_Svc_Descriptor *stsd); + + // = Utility methods. + /// Dynamically link the shared object file and retrieve a pointer to + /// the designated shared object in this file. Also account for the + /// possiblity to have static services registered when loading the DLL, by + /// ensuring that the dynamic sevice is registered before any of its + /// subordibnate static services. Thus avoiding any finalization order + /// problems. + int initialize (const ACE_Service_Type_Factory *, + const ACE_TCHAR *parameters); + + // Dynamically link the shared object file and retrieve a pointer to + // the designated shared object in this file. + // @obsolete + // @note This is error-prone in the presense of dynamic + // services with their own static services. This method will allow those + // static services to register *before* the dynamic service that owns them. + // Upon finalization of the static services the process may crash, because + // the dynamic service's DLL may have been already released, together with + // the memory in which the static services reside. + // It may not crash, for instance, when the first static service to register + // is the same as the dynamic service being loaded. You should be so lucky! + int initialize (const ACE_Service_Type *, + const ACE_TCHAR *parameters); + + /// Initialize and activate a statically @a svc_name service. + int initialize (const ACE_TCHAR *svc_name, + const ACE_TCHAR *parameters); + + /// Resume a @a svc_name that was previously suspended or has not yet + /// been resumed (e.g., a static service). + int resume (const ACE_TCHAR svc_name[]); + + /** + * Suspend @a svc_name. Note that this will not unlink the service + * from the daemon if it was dynamically linked, it will mark it as + * being suspended in the Service Repository and call the <suspend> + * member function on the appropriate <ACE_Service_Object>. A + * service can be resumed later on by calling the <RESUME> member + * function... + */ + int suspend (const ACE_TCHAR svc_name[]); + + /// Totally remove @a svc_name from the daemon by removing it + /// from the ACE_Reactor, and unlinking it if necessary. + int remove (const ACE_TCHAR svc_name[]); + + /** + * Using the supplied name, finds and (if needed) returns a pointer to a + * static service descriptor. Returns 0 for success and -1 for failure + */ + int find_static_svc_descriptor (const ACE_TCHAR* name, + ACE_Static_Svc_Descriptor **ssd = 0) const; + +protected: + + /** + * + */ + virtual int parse_args_i (int, ACE_TCHAR *argv[]); + + /** + * Performs an open without parsing command-line arguments. The + * @a logger_key indicates where to write the logging output, which + * is typically either a STREAM pipe or a socket address. If + * @a ignore_default_svc_conf_file is non-0 then the "svc.conf" file + * will be ignored. If @a ignore_debug_flag is non-0 then the + * application is responsible for setting the + * @c ACE_Log_Msg::priority_mask() appropriately. Returns number of + * errors that occurred on failure and 0 otherwise. + */ + virtual int open_i (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, + bool ignore_static_svcs = true, + bool ignore_default_svc_conf_file = false, + bool ignore_debug_flag = false); + + /// Initialize the <svc_conf_file_queue_> if necessary. + int init_svc_conf_file_queue (void); + + /// Add the default statically-linked services to the + /// ACE_Service_Repository. + int load_static_svcs (void); + + /// Process service configuration requests that were provided on the + /// command-line. Returns the number of errors that occurred. + int process_commandline_directives (void); + +#if (ACE_USES_CLASSIC_SVC_CONF == 1) + /// This is the implementation function that process_directives() + /// and process_directive() both call. Returns the number of errors + /// that occurred. + int process_directives_i (ACE_Svc_Conf_Param *param); +#else + /// Helper function to dynamically link in the XML Service Configurator + /// parser. + ACE_XML_Svc_Conf *get_xml_svc_conf (ACE_DLL &d); +#endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + + // Dynamically link the shared object file and retrieve a pointer to + // the designated shared object in this file. + int initialize_i (const ACE_Service_Type *sr, const ACE_TCHAR *parameters); + + +protected: + + // Maintain a queue of services to be configured from the + // command-line. + typedef ACE_Unbounded_Queue<ACE_TString> ACE_SVC_QUEUE; + typedef ACE_Unbounded_Queue_Iterator<ACE_TString> ACE_SVC_QUEUE_ITERATOR; + + // Maintain a set of the statically linked service descriptors. + typedef ACE_Unbounded_Set<ACE_Static_Svc_Descriptor *> + ACE_STATIC_SVCS; + + typedef ACE_Unbounded_Set_Iterator<ACE_Static_Svc_Descriptor *> + ACE_STATIC_SVCS_ITERATOR; + + friend class ACE_Dynamic_Service_Base; + friend class ACE_Service_Object; + friend class ACE_Service_Config_Guard; + +protected: + + /// The service repository to hold the services. + ACE_Service_Repository* const repo_; + + /// Do we own the service repository instance or have only been given a ptr + /// to the singleton one? + bool repo_is_owned_; + + /// Keep track of the number of times the instance has been + /// initialized (opened). "If so, we can't allow <yyparse> to be called since + /// it's not reentrant" is the original motivation, but that does not seem + /// to be the case anymore. This variable is incremented by the + /// <ACE_Service_Gestalt::open> method and decremented by the + /// <ACE_Service_Gestalt::close> method. + int is_opened_; + + /** Queue of svc.conf files specified on the command-line. + * @@ This should probably be made to handle unicode filenames... + */ + ACE_SVC_QUEUE* svc_conf_file_queue_; + + /// Repository of statically linked services. + ACE_STATIC_SVCS* static_svcs_; + + /// Queue of services specified on the command-line. + ACE_SVC_QUEUE* svc_queue_; + + /// Indicates where to write the logging output. This is typically + /// either a STREAM pipe or a socket + const ACE_TCHAR *logger_key_; + + /// Should we avoid loading the static services? + int no_static_svcs_; + +}; /* class ACE_Service_Gestalt */ + + +class ACE_Location_Node; + +// A helper class used to safely register dynamic services, which may contains +// subordinate static services. It is used to capture the necessary data during +// the parsing, but perform the actuall instantiation later. +class ACE_Service_Type_Factory +{ +public: + ACE_Service_Type_Factory (ACE_TCHAR const *name, + int type, + ACE_Location_Node *location, + int active); + + ~ACE_Service_Type_Factory (void); + + ACE_Service_Type *make_service_type (ACE_Service_Gestalt *pcfg) const; + + ACE_TCHAR const* name (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + /** + * Not implemented to enforce no copying + */ + ACE_UNIMPLEMENTED_FUNC + (ACE_Service_Type_Factory(const ACE_Service_Type_Factory&)); + + ACE_UNIMPLEMENTED_FUNC + (ACE_Service_Type_Factory& operator=(const ACE_Service_Type_Factory&)); + +private: + ACE_TString name_; + int type_; + ACE_Auto_Ptr<ACE_Location_Node> location_; + int is_active_; +}; + + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Service_Gestalt.inl" +#endif /* __ACE_INLINE__ */ + + +#include /**/ "ace/post.h" + +#endif /* ACE_SERVICE_GESTALT_H */ diff --git a/ace/Service_Gestalt.inl b/ace/Service_Gestalt.inl new file mode 100644 index 00000000000..9897b83c681 --- /dev/null +++ b/ace/Service_Gestalt.inl @@ -0,0 +1,64 @@ +// -*- C++ -*- +// +// $Id$ + + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + + +// This is the primary entry point into the ACE_Service_Config (the +// constructor just handles simple initializations). + +ACE_INLINE int +ACE_Service_Gestalt::open (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key, + int ignore_static_svcs, + int ignore_default_svc_conf, + int ignore_debug_flag) +{ + ACE_TRACE ("ACE_Service_Gestalt::open"); + this->no_static_svcs_ = ignore_static_svcs; + + return this->open_i (program_name, + logger_key, + ignore_static_svcs, + ignore_default_svc_conf, + ignore_debug_flag); +} + +ACE_INLINE int +ACE_Service_Gestalt::open (int argc, + ACE_TCHAR *argv[], + const ACE_TCHAR *logger_key, + int ignore_static_svcs, + int ignore_default_svc_conf, + int ignore_debug_flag) +{ + ACE_TRACE ("ACE_Service_Gestalt::open"); + this->no_static_svcs_ = ignore_static_svcs; + + if (this->parse_args_i (argc, + argv) == -1) + return -1; + else + return this->open_i (argv == 0 ? 0 : argv[0], + logger_key, + ignore_static_svcs, + ignore_default_svc_conf, + ignore_debug_flag); +} + +/// Searches for a service object declaration in the local repo, only + +ACE_INLINE int +ACE_Service_Gestalt::find (const ACE_TCHAR name[], + const ACE_Service_Type **srp, + int ignore_suspended) const +{ + ACE_ASSERT (this->repo_ != 0); + return this->repo_->find (name, srp, ignore_suspended); +} + + + +ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/Service_Object.cpp b/ace/Service_Object.cpp index 00de5f6e056..87d5b655151 100644 --- a/ace/Service_Object.cpp +++ b/ace/Service_Object.cpp @@ -26,6 +26,18 @@ ACE_Service_Type::dump (void) const #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_Service_Type::dump"); #endif /* ACE_HAS_DUMP */ + + + // Using printf, since the log facility may not have + // been initialized yet + ACE_OS::fprintf(stderr, + "// [ST] dump, this=%p, name=%s, type=%p, so=%p, active=%d\n", + this, + this->name_, + this->type_, + (this->type_ != 0) ? this->type_->object () : 0, + this->active_); + } ACE_Service_Type::ACE_Service_Type (const ACE_TCHAR *n, @@ -60,7 +72,6 @@ ACE_Service_Type::ACE_Service_Type (const ACE_TCHAR *n, ACE_Service_Type::~ACE_Service_Type (void) { ACE_TRACE ("ACE_Service_Type::~ACE_Service_Type"); - this->fini (); delete [] const_cast <ACE_TCHAR *> (this->name_); @@ -72,7 +83,15 @@ ACE_Service_Type::fini (void) if (!this->fini_already_called_) { this->fini_already_called_ = 1; + if (this->type_ != 0) return this->type_->fini (); + else + return 1; // No implementation was found. + // Currently only makes sense for dummy ST, used to "reserve" + // a spot (kind of like forward-declarations) for a dynamic + // service. This is necessary to help enforce the correct + // finalization order, when such service also has any + // (dependent) static services } return 0; } diff --git a/ace/Service_Object.h b/ace/Service_Object.h index 6101372c5f1..c206db17261 100644 --- a/ace/Service_Object.h +++ b/ace/Service_Object.h @@ -24,9 +24,12 @@ #include "ace/Event_Handler.h" #include "ace/DLL.h" +#include "ace/Service_Gestalt.h" + ACE_BEGIN_VERSIONED_NAMESPACE_DECL #define ACE_Component ACE_Service_Object + /** * @class ACE_Service_Object * @@ -38,7 +41,9 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL * ACE_Event_Handler, as well as being dynamically linked by * the ACE_Service_Config (due to the <ACE_Shared_Object>). */ -class ACE_Export ACE_Service_Object : public ACE_Event_Handler, public ACE_Shared_Object +class ACE_Export ACE_Service_Object + : public ACE_Event_Handler, + public ACE_Shared_Object { public: // = Initialization and termination methods. @@ -101,8 +106,10 @@ public: void name (const ACE_TCHAR *); const ACE_Service_Type_Impl *type (void) const; - void type (const ACE_Service_Type_Impl *, - int active = 1); + void type (const ACE_Service_Type_Impl *, int active = 1); + + // Is this just a stub for the real thing? + bool is_forward_declaration (void) const; int suspend (void) const; int resume (void) const; @@ -118,6 +125,9 @@ public: /// Dump the state of an object. void dump (void) const; + /// Get to the DLL's implentation + const ACE_DLL & dll () const; + /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; @@ -128,7 +138,8 @@ private: /// Pointer to C++ object that implements the svc. const ACE_Service_Type_Impl *type_; - /// ACE_DLL representing the shared object file (non-zero if dynamically linked). + /// ACE_DLL representing the shared object file (non-zero if + /// dynamically linked). mutable ACE_DLL dll_; /// 1 if svc is currently active, otherwise 0. diff --git a/ace/Service_Object.inl b/ace/Service_Object.inl index 23eb323085f..a675d4e942b 100644 --- a/ace/Service_Object.inl +++ b/ace/Service_Object.inl @@ -63,5 +63,10 @@ ACE_Service_Type::fini_called (void) const return this->fini_already_called_; } +ACE_INLINE const ACE_DLL & ACE_Service_Type::dll () const +{ + return this->dll_; +} + ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/Service_Repository.cpp b/ace/Service_Repository.cpp index 81feb3b233e..875dceb9842 100644 --- a/ace/Service_Repository.cpp +++ b/ace/Service_Repository.cpp @@ -10,6 +10,7 @@ #include "ace/Object_Manager.h" #include "ace/Log_Msg.h" #include "ace/ACE.h" +#include "ace/OS_NS_unistd.h" #include "ace/OS_NS_errno.h" #include "ace/OS_NS_string.h" @@ -67,6 +68,7 @@ ACE_Service_Repository::instance (int size /* = ACE_Service_Repository::DEFAULT_ } } + // ACE_ASSERT (ACE_Service_Repository::svc_rep_ != 0); return ACE_Service_Repository::svc_rep_; } @@ -149,16 +151,28 @@ ACE_Service_Repository::fini (void) // order. for (int i = this->current_size_ - 1; i >= 0; i--) + { + ACE_Service_Type *s = + const_cast<ACE_Service_Type *> (this->service_vector_[i]); + + if (ACE::debug ()) { - if (ACE::debug ()) - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("finalizing %s\n"), - this->service_vector_[i]->name ())); - ACE_Service_Type *s = - const_cast<ACE_Service_Type *> (this->service_vector_[i]); - // Collect errors. - retval += s->fini (); + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SR::fini, %@ [%d] (%d): "), + this, i, this->total_size_)); + s->dump(); } + + // Collect any errors. + int ret = s->fini (); + if (ACE::debug ()>1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SR::fini, returned %d\n"), + ret)); + } + retval += ret; + } } return (retval == 0) ? 0 : -1; @@ -180,8 +194,22 @@ ACE_Service_Repository::close (void) // compaction. However, the common case is not to remove // services, so typically they are deleted in reverse order. + if(ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SR::close, this=%@, size=%d\n"), + this, + this->current_size_)); + for (int i = this->current_size_ - 1; i >= 0; i--) { + if(ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SR::close, this=%@, delete so[%d]=%@ (%s)\n"), + this, + i, + this->service_vector_[i], + this->service_vector_[i]->name ())); + ACE_Service_Type *s = const_cast<ACE_Service_Type *> (this->service_vector_[i]); --this->current_size_; delete s; @@ -198,6 +226,8 @@ ACE_Service_Repository::close (void) ACE_Service_Repository::~ACE_Service_Repository (void) { ACE_TRACE ("ACE_Service_Repository::~ACE_Service_Repository"); + if(ACE::debug ()) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) SR::<dtor>, this=%@\n", this)); this->close (); } @@ -211,7 +241,7 @@ ACE_Service_Repository::~ACE_Service_Repository (void) int ACE_Service_Repository::find_i (const ACE_TCHAR name[], const ACE_Service_Type **srp, - int ignore_suspended) + int ignore_suspended) const { ACE_TRACE ("ACE_Service_Repository::find_i"); int i; @@ -244,7 +274,7 @@ ACE_Service_Repository::find_i (const ACE_TCHAR name[], int ACE_Service_Repository::find (const ACE_TCHAR name[], const ACE_Service_Type **srp, - int ignore_suspended) + int ignore_suspended) const { ACE_TRACE ("ACE_Service_Repository::find"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); @@ -254,16 +284,20 @@ ACE_Service_Repository::find (const ACE_TCHAR name[], // Insert the ACE_Service_Type SR into the repository. Note that -// services may be inserted either resumed or suspended. +// services may be inserted either resumed or suspended. Using same name +// as in an existing service causes the delete () to be called for the old one, +// i.e. make sure @code sr is allocated on the heap! int ACE_Service_Repository::insert (const ACE_Service_Type *sr) { ACE_TRACE ("ACE_Service_Repository::insert"); + int return_value = -1; ACE_Service_Type *s = 0; { + // @TODO: Do we need a recursive mutex here? ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); int i; @@ -275,38 +309,49 @@ ACE_Service_Repository::insert (const ACE_Service_Type *sr) // Replacing an existing entry if (i < this->current_size_) + { + return_value = 0; + // Check for self-assignment... + if (sr != this->service_vector_[i]) { - // Check for self-assignment... - if (sr == this->service_vector_[i]) - { - return_value = 0; - } - else - { - s = const_cast<ACE_Service_Type *> (this->service_vector_[i]); - this->service_vector_[i] = sr; - return_value = 0; - } + s = const_cast<ACE_Service_Type *> (this->service_vector_[i]); + this->service_vector_[i] = sr; } + } // Adding a new entry. else if (i < this->total_size_) - { - this->service_vector_[i] = sr; - this->current_size_++; - return_value = 0; - } + { + this->service_vector_[i] = sr; + this->current_size_++; + return_value = 0; + } + + if (ACE::debug ()) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) SR::insert, repo=%@ [%d] (size=%d): ", + this, + i, + this->total_size_)); + sr->dump(); + } } - // delete outside the lock + // Delete outside the lock if (s != 0) + { + if (ACE::debug () > 1) { - delete s; + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) SR::insert, repo=%@ - destroying : ", + this)); + s->dump(); } + delete s; + } if (return_value == -1) - { - ACE_OS::last_error (ENOSPC); - } + ACE_OS::last_error (ENOSPC); return return_value; } @@ -345,11 +390,21 @@ ACE_Service_Repository::suspend (const ACE_TCHAR name[], return this->service_vector_[i]->suspend (); } -// Completely remove a <name> entry from the Repository and -// dynamically unlink it if it was originally dynamically linked. -// Since the order of services in the Respository does not matter, we -// simply overwrite the entry being deleted with the final entry in -// the array and decrement the <current_size> by 1. + +/** + * @brief Completely remove a <name> entry from the Repository and + * dynamically unlink it if it was originally dynamically linked. + * + * Since the order of services in the Respository matters, we can't + * simply overwrite the entry being deleted with the last and + * decrement the <current_size> by 1 - we must "pack" the array. A + * good example of why the order matters is a dynamic service, in + * whose DLL there is at least one static service. In order to prevent + * SEGV during finalization, those static services must be finalized + * _before_the dynamic service that owns them. Otherwice the TEXT + * segment, containing the code for the static service's desructor may + * be unloaded with the DLL. + */ int ACE_Service_Repository::remove (const ACE_TCHAR name[], ACE_Service_Type **ps) @@ -360,16 +415,19 @@ ACE_Service_Repository::remove (const ACE_TCHAR name[], ACE_Service_Type **ps) ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); int i = this->find_i (name, 0, 0); + // Not found if (i == -1) return -1; + // We need the old ptr to be delete outside the lock s = const_cast<ACE_Service_Type *> (this->service_vector_[i]); - --this->current_size_; - if (this->current_size_ >= 1) - this->service_vector_[i] - = this->service_vector_[this->current_size_]; + // Pack the array + --this->current_size_; + for (int j = i; j < this->current_size_; j++) + this->service_vector_[j] = this->service_vector_[j+1]; } + if (ps != 0) *ps = s; else diff --git a/ace/Service_Repository.h b/ace/Service_Repository.h index 1bda4000913..a8c677e7599 100644 --- a/ace/Service_Repository.h +++ b/ace/Service_Repository.h @@ -77,7 +77,8 @@ public: int fini (void); /// Get pointer to a process-wide ACE_Service_Repository. - static ACE_Service_Repository *instance (int size = ACE_Service_Repository::DEFAULT_SIZE); + static ACE_Service_Repository * + instance (int size = ACE_Service_Repository::DEFAULT_SIZE); /// Set pointer to a process-wide ACE_Service_Repository and return /// existing pointer. @@ -88,8 +89,8 @@ public: // = Search structure operations (all acquire locks as necessary). - /// Insert a new service record. Returns -1 when the service repository is full - /// and 0 on success. + /// Insert a new service record. Returns -1 when the service repository + /// is full and 0 on success. int insert (const ACE_Service_Type *); /** @@ -102,7 +103,7 @@ public: */ int find (const ACE_TCHAR name[], const ACE_Service_Type **srp = 0, - int ignore_suspended = 1); + int ignore_suspended = 1) const; /// Remove an existing service record. If @a sr == 0, the service record /// is deleted before control is returned to the caller. If @a sr != 0, @@ -135,7 +136,7 @@ private: /// held... int find_i (const ACE_TCHAR service_name[], const ACE_Service_Type ** = 0, - int ignore_suspended = 1); + int ignore_suspended = 1) const; /// Contains all the configured services. const ACE_Service_Type **service_vector_; @@ -154,7 +155,7 @@ private: #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) /// Synchronization variable for the MT_SAFE Repository - ACE_Recursive_Thread_Mutex lock_; + mutable ACE_Recursive_Thread_Mutex lock_; #endif /* ACE_MT_SAFE */ }; diff --git a/ace/Service_Types.cpp b/ace/Service_Types.cpp index 35140d29d4e..fec79c53824 100644 --- a/ace/Service_Types.cpp +++ b/ace/Service_Types.cpp @@ -103,6 +103,15 @@ ACE_Service_Object_Type::init (int argc, ACE_TCHAR *argv[]) const ACE_Service_Object * const so = static_cast<ACE_Service_Object *> (obj); + if (ACE::debug () > 2) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SOT::init, this=%@, ") + ACE_LIB_TEXT ("name=%s, flags=%d, so=%@\n"), + this, + this->name_, + this->flags_, + obj)); + if (so == 0) return -1; else @@ -116,6 +125,15 @@ ACE_Service_Object_Type::fini (void) const void * const obj = this->object (); + if (ACE::debug () > 2) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("(%P|%t) SOT::fini - this=%@, ") + ACE_LIB_TEXT ("name=%s, flags=%d, so=%@\n"), + this, + this->name_, + this->flags_, + obj)); + ACE_Service_Object * const so = static_cast<ACE_Service_Object *> (obj); @@ -123,6 +141,7 @@ ACE_Service_Object_Type::fini (void) const { so->fini (); + // @TODO: Why is this disabled? #if 0 if (ACE_BIT_ENABLED (this->flags_, ACE_Service_Type::DELETE_OBJ)) @@ -455,5 +474,6 @@ ACE_Stream_Type::find (const ACE_TCHAR *mod_name) const return 0; } +// @@@ Eliminated ommented out explicit template instantiation code ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ace/Svc_Conf.h b/ace/Svc_Conf.h index 4c14981caa3..4a0794a9077 100644 --- a/ace/Svc_Conf.h +++ b/ace/Svc_Conf.h @@ -28,13 +28,12 @@ #include "ace/Service_Config.h" #include "ace/Parse_Node.h" +#include "ace/Svc_Conf_Param.h" + #if (ACE_USES_CLASSIC_SVC_CONF == 1) ACE_BEGIN_VERSIONED_NAMESPACE_DECL -// Forward declarations. -struct ace_yy_buffer_state; - // The following yylex() declarations require support for reentrant // parser generation (e.g. from GNU Bison). #if defined (DEBUGGING) @@ -46,98 +45,11 @@ struct ace_yy_buffer_state; #define ACE_YY_DECL extern "C" int ace_yylex (ACE_YYSTYPE *ace_yylval, void *ACE_YYLEX_PARAM) #endif /* DEBUGGING */ -extern void ace_yy_delete_buffer (ace_yy_buffer_state *buffer); - -/** - * @class ACE_Svc_Conf_Param - * - * @brief An instance of this object will be passed down to the - * yyparse() and yylex() functions. - * - * This class retains the state for a given parse/scan. It primarily - * makes it possible to hold the static object lock in the scanner - * for as short a period of time as possible. The resulting finer - * grained locking prevents deadlocks from occuring when scanning a - * `svc.conf' file and activating an ACE_Task, for example, as a - * result of processing the directives in that file. - */ -class ACE_Svc_Conf_Param -{ -public: - - enum SVC_CONF_PARAM_TYPE - { - /// The lexer will scan a file containing one or more directives. - SVC_CONF_FILE, - - /// The lexer will scan a string containing a directive. - SVC_CONF_DIRECTIVE - }; - - /// Constructor - ACE_Svc_Conf_Param (FILE *file) - : type (SVC_CONF_FILE), - yyerrno (0), - yylineno (1), - buffer (0), - obstack () - { - source.file = file; - } - - /// Constructor - ACE_Svc_Conf_Param (const ACE_TCHAR *directive) - : type (SVC_CONF_DIRECTIVE), - yyerrno (0), - yylineno (1), - buffer (0), - obstack () - { - source.directive = directive; - } - - ~ACE_Svc_Conf_Param (void) - { - ace_yy_delete_buffer (this->buffer); - } - -public: - - union - { - /// FILE stream from which directives will be scanned and parsed. - FILE *file; - - /// String containing directive that will be scanned and parsed. - const ACE_TCHAR *directive; - - } source; - - /// Discriminant use to determine which union member to use. - SVC_CONF_PARAM_TYPE type; - - /// Keeps track of the number of errors encountered so far. - int yyerrno; - - /// Keeps track of the current line number for error-handling routine. - int yylineno; - - /// Lexer buffer that corresponds to the current Service - /// Configurator file/direct scan. - ace_yy_buffer_state *buffer; - - /// Obstack used for efficient memory allocation when - /// parsing/scanning a service configurator directive. - ACE_Obstack_T<ACE_TCHAR> obstack; - -}; - -// Parameter that is passed down to the yyparse() function, and -// eventually to yylex(). -#define ACE_YYPARSE_PARAM ace_svc_conf_parameter -#define ACE_YYLEX_PARAM ACE_YYPARSE_PARAM - -#define ACE_SVC_CONF_PARAM (static_cast<ACE_Svc_Conf_Param *> (ACE_YYLEX_PARAM)) +// Forward declarations +class ACE_Location_Node; +class ACE_Parse_Node; +class ACE_Static_Node; +class ACE_Service_Type_Factory; // The following definition for the ACE_YYSTYPE must occur before // ACE_YY_DECL is declared since ACE_YY_DECL expands to function @@ -148,7 +60,7 @@ typedef union ACE_Location_Node *location_node_; ACE_Parse_Node *parse_node_; ACE_Static_Node *static_node_; - ACE_Service_Type *svc_record_; + ACE_Service_Type_Factory *svc_record_; ACE_TCHAR *ident_; } ACE_YYSTYPE; diff --git a/ace/Svc_Conf.y b/ace/Svc_Conf.y index cb159d68b2f..542a7a03e0b 100644 --- a/ace/Svc_Conf.y +++ b/ace/Svc_Conf.y @@ -12,6 +12,8 @@ #include "ace/OS_NS_string.h" +#include "ace/ace_wchar.h" + ACE_RCSID (ace, Svc_Conf_y, "$Id$") @@ -19,12 +21,14 @@ ACE_RCSID (ace, ACE_BEGIN_VERSIONED_NAMESPACE_DECL // Prototypes. -static ACE_Module_Type *ace_get_module (ACE_Static_Node *str_rec, - ACE_Static_Node *svc_type, - int & yyerrno); -static ACE_Module_Type *ace_get_module (ACE_Static_Node *str_rec, + +static ACE_Module_Type *ace_get_module (const ACE_Service_Type *sr, + const ACE_Service_Type *sv, + int & ace_yyerrno); + +static ACE_Module_Type *ace_get_module (const ACE_Service_Type *sr, const ACE_TCHAR *svc_name, - int & yyerrno); + int & ace_yyerrno); #define YYDEBUG_LEXER_TEXT (yytext[yyleng] = '\0', yytext) @@ -57,7 +61,8 @@ svc_config_entries { if ($2 != 0) { - $2->apply (ACE_SVC_CONF_PARAM->yyerrno); delete $2; + $2->apply (ACE_SVC_CONF_PARAM->config, ACE_SVC_CONF_PARAM->yyerrno); + delete $2; } ACE_SVC_CONF_PARAM->obstack.release (); } @@ -170,11 +175,11 @@ module ACE_Static_Node *module = $<static_node_>-1; ACE_ARGV args (svc_type->parameters ()); - ACE_Module_Type *mt = ace_get_module (module, - svc_type, + ACE_Module_Type *mt = ace_get_module (module->record (ACE_SVC_CONF_PARAM->config), + svc_type->record (ACE_SVC_CONF_PARAM->config), ACE_SVC_CONF_PARAM->yyerrno); ACE_Stream_Type *st = - dynamic_cast<ACE_Stream_Type *> (const_cast<ACE_Service_Type_Impl *> (module->record ()->type ())); + dynamic_cast<ACE_Stream_Type *> (const_cast<ACE_Service_Type_Impl *> (module->record (ACE_SVC_CONF_PARAM->config)->type ())); if (mt->init (args.argc (), args.argv ()) == -1 || st->push (mt) == -1) @@ -188,11 +193,12 @@ module } | static { - ACE_Module_Type *mt = ace_get_module ($<static_node_>-1, + ACE_Static_Node *sn = $<static_node_>-1; + ACE_Module_Type *mt = ace_get_module (sn->record (ACE_SVC_CONF_PARAM->config), $<static_node_>1->name (), ACE_SVC_CONF_PARAM->yyerrno); - if (((ACE_Stream_Type *) ($<static_node_>-1)->record ()->type ())->push (mt) == -1) + if (((ACE_Stream_Type *) sn->record (ACE_SVC_CONF_PARAM->config)->type ())->push (mt) == -1) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("Problem with static\n"))); @@ -201,15 +207,17 @@ module } | suspend { - ACE_Module_Type *mt = ace_get_module ($<static_node_>-1, - $<static_node_>1->name (), + ACE_Static_Node *sn = $<static_node_>-1; + ACE_Module_Type *mt = ace_get_module (sn->record (ACE_SVC_CONF_PARAM->config), + sn->name (), ACE_SVC_CONF_PARAM->yyerrno); if (mt != 0) mt->suspend (); } | resume { - ACE_Module_Type *mt = ace_get_module ($<static_node_>-1, + ACE_Static_Node *sn = $<static_node_>-1; + ACE_Module_Type *mt = ace_get_module (sn->record (ACE_SVC_CONF_PARAM->config), $<static_node_>1->name (), ACE_SVC_CONF_PARAM->yyerrno); if (mt != 0) @@ -219,12 +227,12 @@ module { ACE_Static_Node *stream = $<static_node_>-1; ACE_Static_Node *module = $<static_node_>1; - ACE_Module_Type *mt = ace_get_module (stream, + ACE_Module_Type *mt = ace_get_module (stream->record (ACE_SVC_CONF_PARAM->config), module->name (), ACE_SVC_CONF_PARAM->yyerrno); ACE_Stream_Type *st = - dynamic_cast<ACE_Stream_Type *> (const_cast<ACE_Service_Type_Impl *> (stream->record ()->type ())); + dynamic_cast<ACE_Stream_Type *> (const_cast<ACE_Service_Type_Impl *> (stream->record (ACE_SVC_CONF_PARAM->config)->type ())); if (mt != 0 && st->remove (mt) == -1) { ACE_ERROR ((LM_ERROR, @@ -239,37 +247,7 @@ module svc_location : ACE_IDENT type svc_initializer status { - u_int flags - = ACE_Service_Type::DELETE_THIS - | ($3->dispose () == 0 ? 0 : ACE_Service_Type::DELETE_OBJ); - ACE_Service_Object_Exterminator gobbler = 0; - void *sym = $3->symbol (ACE_SVC_CONF_PARAM->yyerrno, &gobbler); - - if (sym != 0) - { - ACE_Service_Type_Impl *stp - = ACE_Service_Config::create_service_type_impl ($1, - $2, - sym, - flags, - gobbler); - if (stp == 0) - ++ACE_SVC_CONF_PARAM->yyerrno; - - $$ = new ACE_Service_Type ($1, - stp, - $3->dll (), - $4); - } - else - { - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("Unable to find service: %s\n"), - $1)); - ++ACE_SVC_CONF_PARAM->yyerrno; - $$ = 0; - } - delete $3; + $$ = new ACE_Service_Type_Factory ($1, $2, $3, $4); } ; @@ -353,11 +331,10 @@ yyerror (int yyerrno, int yylineno, const char *s) // record. static ACE_Module_Type * -ace_get_module (ACE_Static_Node *str_rec, +ace_get_module (const ACE_Service_Type *sr, const ACE_TCHAR *svc_name, int & yyerrno) { - const ACE_Service_Type *sr = str_rec->record (); const ACE_Service_Type_Impl *type = sr->type (); ACE_Stream_Type *st = sr == 0 ? 0 @@ -369,7 +346,7 @@ ace_get_module (ACE_Static_Node *str_rec, ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("cannot locate Module_Type %s in STREAM_Type %s\n"), svc_name, - str_rec->name ())); + sr->name ())); yyerrno++; } @@ -377,24 +354,23 @@ ace_get_module (ACE_Static_Node *str_rec, } static ACE_Module_Type * -ace_get_module (ACE_Static_Node *str_rec, - ACE_Static_Node *svc_type, +ace_get_module (const ACE_Service_Type *sr, + const ACE_Service_Type *sv, int & yyerrno) { - const ACE_Service_Type *sr = str_rec->record (); const ACE_Service_Type_Impl *type = sr->type (); ACE_Stream_Type *st = sr == 0 ? 0 : (ACE_Stream_Type *) type; - const ACE_Service_Type *sv = svc_type->record (); + type = sv->type (); ACE_Module_Type *mt = (ACE_Module_Type *) type; - const ACE_TCHAR *module_type_name = svc_type->name (); + const ACE_TCHAR *module_type_name = sr->name (); if (sr == 0 || st == 0 || mt == 0) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("cannot locate Module_Type %s or STREAM_Type %s\n"), module_type_name, - str_rec->name ())); + sr->name ())); yyerrno++; } diff --git a/ace/Svc_Conf_Param.h b/ace/Svc_Conf_Param.h new file mode 100644 index 00000000000..898b3b5cd07 --- /dev/null +++ b/ace/Svc_Conf_Param.h @@ -0,0 +1,140 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Svc_Conf_Param.h + * + * $Id$ + * + * @author Iliyan Jeliazkov <iliyan@ociweb.com> + */ +//============================================================================= + + +#ifndef ACE_SVC_CONF_PARAM_H +#define ACE_SVC_CONF_PARAM_H + +#include /**/ "ace/pre.h" + +// Globally visible macros, type decls, and extern var decls for +// Service Configurator utility. + +#include "ace/Obstack.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward declarations. +struct ace_yy_buffer_state; +class ACE_Service_Gestalt; + +extern void ace_yy_delete_buffer (ace_yy_buffer_state *buffer); + +/** + * @class ACE_Svc_Conf_Param + * + * @brief An instance of this object will be passed down to the + * yyparse() and yylex() functions. + * + * This is intended for internal use within ACE service configuration + * framework only. + * + * This class retains the state for a given parse/scan. It primarily + * makes it possible to hold the static object lock in the scanner + * for as short a period of time as possible. The resulting finer + * grained locking prevents deadlocks from occuring when scanning a + * `svc.conf' file and activating an ACE_Task, for example, as a + * result of processing the directives in that file. + */ +class ACE_Svc_Conf_Param +{ +public: + + enum SVC_CONF_PARAM_TYPE + { + /// The lexer will scan a file containing one or more directives. + SVC_CONF_FILE, + + /// The lexer will scan a string containing a directive. + SVC_CONF_DIRECTIVE + }; + + /// Constructor + ACE_Svc_Conf_Param (ACE_Service_Gestalt* config, FILE *file) + : type (SVC_CONF_FILE), + yyerrno (0), + yylineno (1), + buffer (0), + obstack (), + config (config) + { + source.file = file; + } + + /// Constructor + ACE_Svc_Conf_Param (ACE_Service_Gestalt* config, const ACE_TCHAR *directive) + : type (SVC_CONF_DIRECTIVE), + yyerrno (0), + yylineno (1), + buffer (0), + obstack (), + config (config) + { + source.directive = directive; + } + + ~ACE_Svc_Conf_Param (void) + { + ace_yy_delete_buffer (this->buffer); + } + +public: + + union + { + /// FILE stream from which directives will be scanned and parsed. + FILE *file; + + /// String containing directive that will be scanned and parsed. + const ACE_TCHAR *directive; + + } source; + + /// Discriminant use to determine which union member to use. + SVC_CONF_PARAM_TYPE type; + + /// Keeps track of the number of errors encountered so far. + int yyerrno; + + /// Keeps track of the current line number for error-handling routine. + int yylineno; + + /// Lexer buffer that corresponds to the current Service + /// Configurator file/direct scan. + ace_yy_buffer_state *buffer; + + /// Obstack used for efficient memory allocation when + /// parsing/scanning a service configurator directive. + ACE_Obstack_T<ACE_TCHAR> obstack; + + /// A reference to the configuration + ACE_Service_Gestalt *config; +}; + + +// Parameter that is passed down to the yyparse() function, and +// eventually to yylex(). +#define ACE_YYPARSE_PARAM ace_svc_conf_parameter + +#define ACE_YYLEX_PARAM ACE_YYPARSE_PARAM + +#define ACE_SVC_CONF_PARAM (static_cast<ACE_Svc_Conf_Param *> (ACE_YYLEX_PARAM)) + +ACE_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* ACE_SVC_CONF_PARAM_H */ diff --git a/ace/Svc_Conf_Tokens.h b/ace/Svc_Conf_Tokens.h index 6fe46126fef..8c514a0a582 100644 --- a/ace/Svc_Conf_Tokens.h +++ b/ace/Svc_Conf_Tokens.h @@ -1,21 +1,81 @@ // $Id$ #ifndef BISON_SVC_CONF_TAB_H # define BISON_SVC_CONF_TAB_H +# define ACE_YYSTYPE_IS_DECLARED 1 +/* A Bison parser, made by GNU Bison 2.0. */ -# define ACE_DYNAMIC 257 -# define ACE_STATIC 258 -# define ACE_SUSPEND 259 -# define ACE_RESUME 260 -# define ACE_REMOVE 261 -# define ACE_USTREAM 262 -# define ACE_MODULE_T 263 -# define ACE_STREAM_T 264 -# define ACE_SVC_OBJ_T 265 -# define ACE_ACTIVE 266 -# define ACE_INACTIVE 267 -# define ACE_PATHNAME 268 -# define ACE_IDENT 269 -# define ACE_STRING 270 - - -#endif /* not BISON_SVC_CONF_TAB_H */ +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef ACE_YYTOKENTYPE +# define ACE_YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum ace_yytokentype { + ACE_DYNAMIC = 258, + ACE_STATIC = 259, + ACE_SUSPEND = 260, + ACE_RESUME = 261, + ACE_REMOVE = 262, + ACE_USTREAM = 263, + ACE_MODULE_T = 264, + ACE_STREAM_T = 265, + ACE_SVC_OBJ_T = 266, + ACE_ACTIVE = 267, + ACE_INACTIVE = 268, + ACE_PATHNAME = 269, + ACE_IDENT = 270, + ACE_STRING = 271 + }; +#endif +#define ACE_DYNAMIC 258 +#define ACE_STATIC 259 +#define ACE_SUSPEND 260 +#define ACE_RESUME 261 +#define ACE_REMOVE 262 +#define ACE_USTREAM 263 +#define ACE_MODULE_T 264 +#define ACE_STREAM_T 265 +#define ACE_SVC_OBJ_T 266 +#define ACE_ACTIVE 267 +#define ACE_INACTIVE 268 +#define ACE_PATHNAME 269 +#define ACE_IDENT 270 +#define ACE_STRING 271 + + + + +#if ! defined (ACE_YYSTYPE) && ! defined (ACE_YYSTYPE_IS_DECLARED) +typedef int ACE_YYSTYPE; +# define ace_yystype ACE_YYSTYPE /* obsolescent; will be withdrawn */ +# define ACE_YYSTYPE_IS_DECLARED 1 +# define ACE_YYSTYPE_IS_TRIVIAL 1 +#endif + + + + + +#endif /* ifndef BISON_SVC_CONF_TAB_H */ diff --git a/ace/Svc_Conf_y.cpp b/ace/Svc_Conf_y.cpp index d18774268d8..de8efe646c9 100644 --- a/ace/Svc_Conf_y.cpp +++ b/ace/Svc_Conf_y.cpp @@ -1,22 +1,93 @@ -/* A Bison parser, made from Svc_Conf.y - by GNU bison 1.35. */ - -#define ACE_YYBISON 1 /* Identify Bison output. */ - -# define ACE_DYNAMIC 257 -# define ACE_STATIC 258 -# define ACE_SUSPEND 259 -# define ACE_RESUME 260 -# define ACE_REMOVE 261 -# define ACE_USTREAM 262 -# define ACE_MODULE_T 263 -# define ACE_STREAM_T 264 -# define ACE_SVC_OBJ_T 265 -# define ACE_ACTIVE 266 -# define ACE_INACTIVE 267 -# define ACE_PATHNAME 268 -# define ACE_IDENT 269 -# define ACE_STRING 270 +/* A Bison parser, made by GNU Bison 2.0. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with ace_yy or ACE_YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define ACE_YYBISON 1 + +/* Skeleton name. */ +#define ACE_YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define ACE_YYPURE 1 + +/* Using locations. */ +#define ACE_YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef ACE_YYTOKENTYPE +# define ACE_YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum ace_yytokentype { + ACE_DYNAMIC = 258, + ACE_STATIC = 259, + ACE_SUSPEND = 260, + ACE_RESUME = 261, + ACE_REMOVE = 262, + ACE_USTREAM = 263, + ACE_MODULE_T = 264, + ACE_STREAM_T = 265, + ACE_SVC_OBJ_T = 266, + ACE_ACTIVE = 267, + ACE_INACTIVE = 268, + ACE_PATHNAME = 269, + ACE_IDENT = 270, + ACE_STRING = 271 + }; +#endif +#define ACE_DYNAMIC 258 +#define ACE_STATIC 259 +#define ACE_SUSPEND 260 +#define ACE_RESUME 261 +#define ACE_REMOVE 262 +#define ACE_USTREAM 263 +#define ACE_MODULE_T 264 +#define ACE_STREAM_T 265 +#define ACE_SVC_OBJ_T 266 +#define ACE_ACTIVE 267 +#define ACE_INACTIVE 268 +#define ACE_PATHNAME 269 +#define ACE_IDENT 270 +#define ACE_STRING 271 + + + + +/* Copy the first part of user declarations. */ // $Id$ @@ -32,41 +103,179 @@ #include "ace/OS_NS_string.h" +#include "ace/ace_wchar.h" + ACE_RCSID (ace, Svc_Conf_y, "$Id$") - ACE_BEGIN_VERSIONED_NAMESPACE_DECL // Prototypes. -static ACE_Module_Type *ace_get_module (ACE_Static_Node *str_rec, - ACE_Static_Node *svc_type, - int & ace_yyerrno); -static ACE_Module_Type *ace_get_module (ACE_Static_Node *str_rec, + +static ACE_Module_Type *ace_get_module (const ACE_Service_Type *sr, + const ACE_Service_Type *sv, + int & ace_ace_yyerrno); + +static ACE_Module_Type *ace_get_module (const ACE_Service_Type *sr, const ACE_TCHAR *svc_name, - int & ace_yyerrno); + int & ace_ace_yyerrno); #define ACE_YYDEBUG_LEXER_TEXT (ace_yytext[ace_yyleng] = '\0', ace_yytext) // Force the pretty debugging code to compile. // #define ACE_YYDEBUG 1 + + +/* Enabling traces. */ #ifndef ACE_YYDEBUG # define ACE_YYDEBUG 0 #endif +/* Enabling verbose error messages. */ +#ifdef ACE_YYERROR_VERBOSE +# undef ACE_YYERROR_VERBOSE +# define ACE_YYERROR_VERBOSE 1 +#else +# define ACE_YYERROR_VERBOSE 0 +#endif + +#if ! defined (ACE_YYSTYPE) && ! defined (ACE_YYSTYPE_IS_DECLARED) +typedef int ACE_YYSTYPE; +# define ace_yystype ACE_YYSTYPE /* obsolescent; will be withdrawn */ +# define ACE_YYSTYPE_IS_DECLARED 1 +# define ACE_YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + +/* Line 213 of yacc.c. */ -#define ACE_YYFINAL 66 -#define ACE_YYFLAG -32768 -#define ACE_YYNTBASE 23 -/* ACE_YYTRANSLATE(ACE_YYLEX) -- Bison token number corresponding to ACE_YYLEX. */ -#define ACE_YYTRANSLATE(x) ((unsigned)(x) <= 270 ? ace_yytranslate[x] : 43) +#if ! defined (ace_yyoverflow) || ACE_YYERROR_VERBOSE -/* ACE_YYTRANSLATE[ACE_YYLEX] -- Bison token number corresponding to ACE_YYLEX. */ -static const ACE_TCHAR ace_yytranslate[] = +# ifndef ACE_YYFREE +# define ACE_YYFREE free +# endif +# ifndef ACE_YYMALLOC +# define ACE_YYMALLOC malloc +# endif + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef ACE_YYSTACK_USE_ALLOCA +# if ACE_YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define ACE_YYSTACK_ALLOC __builtin_alloca +# else +# define ACE_YYSTACK_ALLOC alloca +# endif +# endif +# endif + +# ifdef ACE_YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define ACE_YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# define ACE_YYSIZE_T size_t +# endif +# define ACE_YYSTACK_ALLOC ACE_YYMALLOC +# define ACE_YYSTACK_FREE ACE_YYFREE +# endif +#endif /* ! defined (ace_yyoverflow) || ACE_YYERROR_VERBOSE */ + + +#if (! defined (ace_yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (ACE_YYSTYPE_IS_TRIVIAL) && ACE_YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union ace_yyalloc +{ + short int ace_yyss; + ACE_YYSTYPE ace_yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define ACE_YYSTACK_GAP_MAXIMUM (sizeof (union ace_yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define ACE_YYSTACK_BYTES(N) \ + ((N) * (sizeof (short int) + sizeof (ACE_YYSTYPE)) \ + + ACE_YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef ACE_YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define ACE_YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define ACE_YYCOPY(To, From, Count) \ + do \ + { \ + register ACE_YYSIZE_T ace_yyi; \ + for (ace_yyi = 0; ace_yyi < (Count); ace_yyi++) \ + (To)[ace_yyi] = (From)[ace_yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables ACE_YYSIZE and ACE_YYSTACKSIZE give the old and new number of + elements in the stack, and ACE_YYPTR gives the new location of the + stack. Advance ACE_YYPTR to a properly aligned location for the next + stack. */ +# define ACE_YYSTACK_RELOCATE(Stack) \ + do \ + { \ + ACE_YYSIZE_T ace_yynewbytes; \ + ACE_YYCOPY (&ace_yyptr->Stack, Stack, ace_yysize); \ + Stack = &ace_yyptr->Stack; \ + ace_yynewbytes = ace_yystacksize * sizeof (*Stack) + ACE_YYSTACK_GAP_MAXIMUM; \ + ace_yyptr += ace_yynewbytes / sizeof (*ace_yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char ace_yysigned_char; +#else + typedef short int ace_yysigned_char; +#endif + +/* ACE_YYFINAL -- State number of the termination state. */ +#define ACE_YYFINAL 2 +/* ACE_YYLAST -- Last index in ACE_YYTABLE. */ +#define ACE_YYLAST 62 + +/* ACE_YYNTOKENS -- Number of terminals. */ +#define ACE_YYNTOKENS 23 +/* ACE_YYNNTS -- Number of nonterminals. */ +#define ACE_YYNNTS 21 +/* ACE_YYNRULES -- Number of rules. */ +#define ACE_YYNRULES 45 +/* ACE_YYNRULES -- Number of states. */ +#define ACE_YYNSTATES 66 + +/* ACE_YYTRANSLATE(ACE_YYLEX) -- Bison symbol number corresponding to ACE_YYLEX. */ +#define ACE_YYUNDEFTOK 2 +#define ACE_YYMAXUTOK 271 + +#define ACE_YYTRANSLATE(ACE_YYX) \ + ((unsigned int) (ACE_YYX) <= ACE_YYMAXUTOK ? ace_yytranslate[ACE_YYX] : ACE_YYUNDEFTOK) + +/* ACE_YYTRANSLATE[ACE_YYLEX] -- Bison symbol number corresponding to ACE_YYLEX. */ +static const unsigned char ace_yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -93,290 +302,183 @@ static const ACE_TCHAR ace_yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16 + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16 }; #if ACE_YYDEBUG -static const short ace_yyprhs[] = +/* ACE_YYPRHS[ACE_YYN] -- Index of the first RHS symbol of rule number ACE_YYN in + ACE_YYRHS. */ +static const unsigned char ace_yyprhs[] = { - 0, 0, 3, 6, 7, 9, 11, 13, 15, 17, - 19, 23, 27, 30, 33, 36, 40, 41, 46, 48, - 50, 51, 56, 57, 60, 61, 63, 65, 67, 69, - 71, 76, 78, 80, 81, 85, 91, 96, 99, 102, - 105, 107, 108, 110, 112 + 0, 0, 3, 6, 9, 10, 12, 14, 16, 18, + 20, 22, 26, 30, 33, 36, 39, 43, 44, 49, + 51, 53, 54, 59, 60, 63, 64, 66, 68, 70, + 72, 74, 79, 81, 83, 84, 88, 94, 99, 102, + 105, 108, 110, 111, 113, 115 }; -static const short ace_yyrhs[] = + +/* ACE_YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const ace_yysigned_char ace_yyrhs[] = { - 23, 24, 0, 23, 1, 0, 0, 25, 0, 26, - 0, 27, 0, 28, 0, 29, 0, 30, 0, 3, - 37, 41, 0, 4, 15, 41, 0, 5, 15, 0, - 6, 15, 0, 7, 15, 0, 8, 32, 33, 0, - 0, 8, 15, 31, 33, 0, 25, 0, 26, 0, - 0, 17, 34, 35, 18, 0, 0, 35, 36, 0, - 0, 25, 0, 26, 0, 27, 0, 28, 0, 29, - 0, 15, 40, 39, 38, 0, 12, 0, 13, 0, - 0, 42, 19, 15, 0, 42, 19, 15, 20, 21, - 0, 19, 15, 20, 21, 0, 9, 22, 0, 11, - 22, 0, 10, 22, 0, 16, 0, 0, 14, 0, - 15, 0, 16, 0 + 24, 0, -1, 24, 25, -1, 24, 1, -1, -1, + 26, -1, 27, -1, 28, -1, 29, -1, 30, -1, + 31, -1, 3, 38, 42, -1, 4, 15, 42, -1, + 5, 15, -1, 6, 15, -1, 7, 15, -1, 8, + 33, 34, -1, -1, 8, 15, 32, 34, -1, 26, + -1, 27, -1, -1, 17, 35, 36, 18, -1, -1, + 36, 37, -1, -1, 26, -1, 27, -1, 28, -1, + 29, -1, 30, -1, 15, 41, 40, 39, -1, 12, + -1, 13, -1, -1, 43, 19, 15, -1, 43, 19, + 15, 20, 21, -1, 19, 15, 20, 21, -1, 9, + 22, -1, 11, 22, -1, 10, 22, -1, 16, -1, + -1, 14, -1, 15, -1, 16, -1 }; -#endif - -#if ACE_YYDEBUG -/* ACE_YYRLINE[ACE_YYN] -- source line where rule number ACE_YYN was defined. */ -static const short ace_yyrline[] = +/* ACE_YYRLINE[ACE_YYN] -- source line where rule number ACE_YYN was defined. */ +static const unsigned short int ace_yyrline[] = { - 0, 55, 63, 67, 71, 72, 73, 74, 75, 76, - 80, 90, 97, 104, 111, 118, 122, 122, 129, 132, - 138, 138, 147, 151, 159, 163, 188, 201, 209, 217, - 239, 276, 280, 284, 291, 295, 299, 306, 310, 314, - 321, 322, 326, 327, 328 + 0, 60, 60, 69, 73, 77, 78, 79, 80, 81, + 82, 86, 96, 103, 110, 117, 124, 128, 128, 135, + 138, 145, 144, 153, 157, 165, 169, 194, 208, 217, + 226, 248, 255, 259, 264, 270, 274, 278, 285, 289, + 293, 300, 301, 305, 306, 307 }; #endif - -#if (ACE_YYDEBUG) || defined ACE_YYERROR_VERBOSE - -/* ACE_YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */ -static const ACE_TCHAR *const ace_yytname[] = +#if ACE_YYDEBUG || ACE_YYERROR_VERBOSE +/* ACE_YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at ACE_YYNTOKENS, nonterminals. */ +static const char *const ace_yytname[] = { - "$", "error", "$undefined.", "ACE_DYNAMIC", "ACE_STATIC", "ACE_SUSPEND", - "ACE_RESUME", "ACE_REMOVE", "ACE_USTREAM", "ACE_MODULE_T", - "ACE_STREAM_T", "ACE_SVC_OBJ_T", "ACE_ACTIVE", "ACE_INACTIVE", - "ACE_PATHNAME", "ACE_IDENT", "ACE_STRING", "'{'", "'}'", "':'", "'('", - "')'", "'*'", "svc_config_entries", "svc_config_entry", "dynamic", - "static", "suspend", "resume", "remove", "stream", "@1", "stream_ops", - "stream_modules", "@2", "module_list", "module", "svc_location", - "status", "svc_initializer", "type", "parameters_opt", "pathname", 0 + "$end", "error", "$undefined", "ACE_DYNAMIC", "ACE_STATIC", + "ACE_SUSPEND", "ACE_RESUME", "ACE_REMOVE", "ACE_USTREAM", "ACE_MODULE_T", + "ACE_STREAM_T", "ACE_SVC_OBJ_T", "ACE_ACTIVE", "ACE_INACTIVE", + "ACE_PATHNAME", "ACE_IDENT", "ACE_STRING", "'{'", "'}'", "':'", "'('", + "')'", "'*'", "$accept", "svc_config_entries", "svc_config_entry", + "dynamic", "static", "suspend", "resume", "remove", "stream", "@1", + "stream_ops", "stream_modules", "@2", "module_list", "module", + "svc_location", "status", "svc_initializer", "type", "parameters_opt", + "pathname", 0 }; #endif -/* ACE_YYR1[ACE_YYN] -- Symbol number of symbol that rule ACE_YYN derives. */ -static const short ace_yyr1[] = +# ifdef ACE_YYPRINT +/* ACE_YYTOKNUM[ACE_YYLEX-NUM] -- Internal token number corresponding to + token ACE_YYLEX-NUM. */ +static const unsigned short int ace_yytoknum[] = { - 0, 23, 23, 23, 24, 24, 24, 24, 24, 24, - 25, 26, 27, 28, 29, 30, 31, 30, 32, 32, - 34, 33, 33, 35, 35, 36, 36, 36, 36, 36, - 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, - 41, 41, 42, 42, 42 + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 123, 125, 58, + 40, 41, 42 }; +# endif -/* ACE_YYR2[ACE_YYN] -- Number of symbols composing right hand side of rule ACE_YYN. */ -static const short ace_yyr2[] = +/* ACE_YYR1[ACE_YYN] -- Symbol number of symbol that rule ACE_YYN derives. */ +static const unsigned char ace_yyr1[] = { - 0, 2, 2, 0, 1, 1, 1, 1, 1, 1, - 3, 3, 2, 2, 2, 3, 0, 4, 1, 1, - 0, 4, 0, 2, 0, 1, 1, 1, 1, 1, - 4, 1, 1, 0, 3, 5, 4, 2, 2, 2, - 1, 0, 1, 1, 1 + 0, 23, 24, 24, 24, 25, 25, 25, 25, 25, + 25, 26, 27, 28, 29, 30, 31, 32, 31, 33, + 33, 35, 34, 34, 36, 36, 37, 37, 37, 37, + 37, 38, 39, 39, 39, 40, 40, 40, 41, 41, + 41, 42, 42, 43, 43, 43 }; -/* ACE_YYDEFACT[S] -- default rule to reduce with in state S when ACE_YYTABLE - doesn't specify something else to do. Zero means the default is an - error. */ -static const short ace_yydefact[] = +/* ACE_YYR2[ACE_YYN] -- Number of symbols composing right hand side of rule ACE_YYN. */ +static const unsigned char ace_yyr2[] = { - 3, 0, 2, 0, 0, 0, 0, 0, 0, 1, - 4, 5, 6, 7, 8, 9, 0, 41, 41, 12, - 13, 14, 16, 18, 19, 22, 0, 0, 0, 0, - 40, 10, 11, 22, 20, 15, 37, 39, 38, 42, - 43, 44, 0, 33, 0, 17, 24, 0, 31, 32, - 30, 0, 0, 0, 34, 21, 25, 26, 27, 28, - 29, 23, 36, 0, 35, 0, 0 + 0, 2, 2, 2, 0, 1, 1, 1, 1, 1, + 1, 3, 3, 2, 2, 2, 3, 0, 4, 1, + 1, 0, 4, 0, 2, 0, 1, 1, 1, 1, + 1, 4, 1, 1, 0, 3, 5, 4, 2, 2, + 2, 1, 0, 1, 1, 1 }; -static const short ace_yydefgoto[] = +/* ACE_YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when ACE_YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char ace_yydefact[] = { - 1, 9, 10, 11, 12, 13, 14, 15, 33, 25, - 35, 46, 52, 61, 17, 50, 43, 29, 31, 44 + 4, 0, 1, 3, 0, 0, 0, 0, 0, 0, + 2, 5, 6, 7, 8, 9, 10, 0, 42, 42, + 13, 14, 15, 17, 19, 20, 23, 0, 0, 0, + 0, 41, 11, 12, 23, 21, 16, 38, 40, 39, + 43, 44, 45, 0, 34, 0, 18, 25, 0, 32, + 33, 31, 0, 0, 0, 35, 22, 26, 27, 28, + 29, 30, 24, 37, 0, 36 }; -static const short ace_yypact[] = +/* ACE_YYDEFGOTO[NTERM-NUM]. */ +static const ace_yysigned_char ace_yydefgoto[] = { - -32768, 20,-32768, 1, 3, 7, 14, 18, 4,-32768, - -32768,-32768,-32768,-32768,-32768,-32768, 21, 19, 19,-32768, - -32768,-32768,-32768,-32768,-32768, -2, 12, 15, 16, -5, - -32768,-32768,-32768, -2,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768, 24, 0, 17,-32768,-32768, 22,-32768,-32768, - -32768, 25, -1, 26, 23,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768, 27,-32768, 41,-32768 + -1, 1, 10, 11, 12, 13, 14, 15, 16, 34, + 26, 36, 47, 53, 62, 18, 51, 44, 30, 32, + 45 }; -static const short ace_yypgoto[] = +/* ACE_YYPACT[STATE-NUM] -- Index in ACE_YYTABLE of the portion describing + STATE-NUM. */ +#define ACE_YYPACT_NINF -13 +static const ace_yysigned_char ace_yypact[] = { - -32768,-32768, -8, -7, -6, -3, 2,-32768,-32768,-32768, - 28,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 32,-32768 + -13, 20, -13, -13, 1, 3, 7, 14, 18, 4, + -13, -13, -13, -13, -13, -13, -13, 21, 19, 19, + -13, -13, -13, -13, -13, -13, -2, 12, 15, 16, + -5, -13, -13, -13, -2, -13, -13, -13, -13, -13, + -13, -13, -13, 24, 0, 17, -13, -13, 22, -13, + -13, -13, 25, -1, 26, 23, -13, -13, -13, -13, + -13, -13, -13, -13, 27, -13 }; +/* ACE_YYPGOTO[NTERM-NUM]. */ +static const ace_yysigned_char ace_yypgoto[] = +{ + -13, -13, -13, -9, -8, -12, -7, -4, -13, -13, + -13, 28, -13, -13, -13, -13, -13, -13, -13, 31, + -13 +}; -#define ACE_YYLAST 61 - - -static const short ace_yytable[] = +/* ACE_YYTABLE[ACE_YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what ACE_YYDEFACT says. + If ACE_YYTABLE_NINF, syntax error. */ +#define ACE_YYTABLE_NINF -1 +static const unsigned char ace_yytable[] = { - 23, 24, 3, 4, 5, 6, 7, 3, 4, 39, - 40, 41, 48, 49, 42, 34, 16, 55, 18, 22, - 65, 2, 19, 3, 4, 5, 6, 7, 8, 20, - 26, 27, 28, 21, 36, 30, 51, 37, 38, 47, - 54, 66, 53, 63, 56, 57, 58, 62, 64, 59, - 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, - 0, 45 + 24, 25, 4, 5, 6, 7, 8, 4, 5, 40, + 41, 42, 49, 50, 43, 35, 17, 56, 19, 23, + 2, 3, 20, 4, 5, 6, 7, 8, 9, 21, + 27, 28, 29, 22, 37, 31, 52, 38, 39, 48, + 55, 59, 54, 64, 57, 58, 60, 63, 65, 61, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 46 }; -static const short ace_yycheck[] = +static const ace_yysigned_char ace_yycheck[] = { - 8, 8, 3, 4, 5, 6, 7, 3, 4, 14, + 9, 9, 3, 4, 5, 6, 7, 3, 4, 14, 15, 16, 12, 13, 19, 17, 15, 18, 15, 15, 0, 1, 15, 3, 4, 5, 6, 7, 8, 15, 9, 10, 11, 15, 22, 16, 19, 22, 22, 15, - 15, 0, 20, 20, 52, 52, 52, 21, 21, 52, - 18, -1, -1, -1, 52, -1, -1, -1, -1, -1, - -1, 33 + 15, 53, 20, 20, 53, 53, 53, 21, 21, 53, + 19, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 34 }; -#define ACE_YYPURE 1 - -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ - -/* Skeleton output parser for bison, - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser when - the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* All symbols defined below should begin with ace_yy or ACE_YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -#if ! defined (ace_yyoverflow) || defined (ACE_YYERROR_VERBOSE) - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if ACE_YYSTACK_USE_ALLOCA -# define ACE_YYSTACK_ALLOC alloca -# else -# ifndef ACE_YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define ACE_YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define ACE_YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif -# ifdef ACE_YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define ACE_YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -ACE_END_VERSIONED_NAMESPACE_DECL -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -ACE_BEGIN_VERSIONED_NAMESPACE_DECL -# define ACE_YYSIZE_T size_t -# endif -# define ACE_YYSTACK_ALLOC malloc -# define ACE_YYSTACK_FREE free -# endif -#endif /* ! defined (ace_yyoverflow) || defined (ACE_YYERROR_VERBOSE) */ - - -#if (! defined (ace_yyoverflow) \ - && (! defined (__cplusplus) \ - || (ACE_YYLTYPE_IS_TRIVIAL && ACE_YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union ace_yyalloc +/* ACE_YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char ace_yystos[] = { - short ace_yyss; - ACE_YYSTYPE ace_yyvs; -# if ACE_YYLSP_NEEDED - ACE_YYLTYPE ace_yyls; -# endif + 0, 24, 0, 1, 3, 4, 5, 6, 7, 8, + 25, 26, 27, 28, 29, 30, 31, 15, 38, 15, + 15, 15, 15, 15, 26, 27, 33, 9, 10, 11, + 41, 16, 42, 42, 32, 17, 34, 22, 22, 22, + 14, 15, 16, 19, 40, 43, 34, 35, 15, 12, + 13, 39, 19, 36, 20, 15, 18, 26, 27, 28, + 29, 30, 37, 21, 20, 21 }; -/* The size of the maximum gap between one aligned stack and the next. */ -# define ACE_YYSTACK_GAP_MAX (sizeof (union ace_yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# if ACE_YYLSP_NEEDED -# define ACE_YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (ACE_YYSTYPE) + sizeof (ACE_YYLTYPE)) \ - + 2 * ACE_YYSTACK_GAP_MAX) -# else -# define ACE_YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (ACE_YYSTYPE)) \ - + ACE_YYSTACK_GAP_MAX) -# endif - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef ACE_YYCOPY -# if 1 < __GNUC__ -# define ACE_YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define ACE_YYCOPY(To, From, Count) \ - do \ - { \ - register ACE_YYSIZE_T ace_yyi; \ - for (ace_yyi = 0; ace_yyi < (Count); ace_yyi++) \ - (To)[ace_yyi] = (From)[ace_yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables ACE_YYSIZE and ACE_YYSTACKSIZE give the old and new number of - elements in the stack, and ACE_YYPTR gives the new location of the - stack. Advance ACE_YYPTR to a properly aligned location for the next - stack. */ -# define ACE_YYSTACK_RELOCATE(Stack) \ - do \ - { \ - ACE_YYSIZE_T ace_yynewbytes; \ - ACE_YYCOPY (&ace_yyptr->Stack, Stack, ace_yysize); \ - Stack = &ace_yyptr->Stack; \ - ace_yynewbytes = ace_yystacksize * sizeof (*Stack) + ACE_YYSTACK_GAP_MAX; \ - ace_yyptr += ace_yynewbytes / sizeof (*ace_yyptr); \ - } \ - while (0) - -#endif - - #if ! defined (ACE_YYSIZE_T) && defined (__SIZE_TYPE__) # define ACE_YYSIZE_T __SIZE_TYPE__ #endif @@ -385,9 +487,7 @@ union ace_yyalloc #endif #if ! defined (ACE_YYSIZE_T) # if defined (__STDC__) || defined (__cplusplus) -ACE_END_VERSIONED_NAMESPACE_DECL # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -ACE_BEGIN_VERSIONED_NAMESPACE_DECL # define ACE_YYSIZE_T size_t # endif #endif @@ -397,79 +497,99 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL #define ace_yyerrok (ace_yyerrstatus = 0) #define ace_yyclearin (ace_yychar = ACE_YYEMPTY) -#define ACE_YYEMPTY -2 +#define ACE_YYEMPTY (-2) #define ACE_YYEOF 0 + #define ACE_YYACCEPT goto ace_yyacceptlab -#define ACE_YYABORT goto ace_yyabortlab -#define ACE_YYERROR goto ace_yyerrlab1 +#define ACE_YYABORT goto ace_yyabortlab +#define ACE_YYERROR goto ace_yyerrorlab + + /* Like ACE_YYERROR except do call ace_yyerror. This remains here temporarily to ease the transition to the new meaning of ACE_YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ + #define ACE_YYFAIL goto ace_yyerrlab + #define ACE_YYRECOVERING() (!!ace_yyerrstatus) + #define ACE_YYBACKUP(Token, Value) \ do \ if (ace_yychar == ACE_YYEMPTY && ace_yylen == 1) \ { \ ace_yychar = (Token); \ ace_yylval = (Value); \ - ace_yychar1 = ACE_YYTRANSLATE (ace_yychar); \ + ace_yytoken = ACE_YYTRANSLATE (ace_yychar); \ ACE_YYPOPSTACK; \ goto ace_yybackup; \ } \ else \ { \ - ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, "syntax error: cannot back up"); \ + ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, "syntax error: cannot back up");\ ACE_YYERROR; \ } \ while (0) + #define ACE_YYTERROR 1 #define ACE_YYERRCODE 256 -/* ACE_YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). - - When ACE_YYLLOC_DEFAULT is run, CURRENT is set the location of the - first token. By default, to implement support for ranges, extend - its range to the last symbol. */ +/* ACE_YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ +#define ACE_YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef ACE_YYLLOC_DEFAULT -# define ACE_YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; +# define ACE_YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first_line = ACE_YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = ACE_YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = ACE_YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = ACE_YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + ACE_YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + ACE_YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (0) #endif -/* ACE_YYLEX -- calling `ace_yylex' with the right arguments. */ +/* ACE_YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ -#if ACE_YYPURE -# if ACE_YYLSP_NEEDED -# ifdef ACE_YYLEX_PARAM -# define ACE_YYLEX ace_yylex (&ace_yylval, &ace_yylloc, ACE_YYLEX_PARAM) -# else -# define ACE_YYLEX ace_yylex (&ace_yylval, &ace_yylloc) -# endif -# else /* !ACE_YYLSP_NEEDED */ -# ifdef ACE_YYLEX_PARAM -# define ACE_YYLEX ace_yylex (&ace_yylval, ACE_YYLEX_PARAM) -# else -# define ACE_YYLEX ace_yylex (&ace_yylval) -# endif -# endif /* !ACE_YYLSP_NEEDED */ -#else /* !ACE_YYPURE */ -# define ACE_YYLEX ace_yylex () -#endif /* !ACE_YYPURE */ +#ifndef ACE_YY_LOCATION_PRINT +# if ACE_YYLTYPE_IS_TRIVIAL +# define ACE_YY_LOCATION_PRINT(File, Loc) \ + ACE_OS::fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define ACE_YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* ACE_YYLEX -- calling `ace_yylex' with the right arguments. */ +#ifdef ACE_YYLEX_PARAM +# define ACE_YYLEX ace_yylex (&ace_yylval, ACE_YYLEX_PARAM) +#else +# define ACE_YYLEX ace_yylex (&ace_yylval) +#endif /* Enable debugging if requested. */ #if ACE_YYDEBUG # ifndef ACE_YYFPRINTF -ACE_END_VERSIONED_NAMESPACE_DECL # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -ACE_BEGIN_VERSIONED_NAMESPACE_DECL # define ACE_YYFPRINTF ACE_OS::fprintf # endif @@ -478,13 +598,86 @@ do { \ if (ace_yydebug) \ ACE_YYFPRINTF Args; \ } while (0) + +# define ACE_YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (ace_yydebug) \ + { \ + ACE_YYFPRINTF (stderr, "%s ", Title); \ + ace_yysymprint (stderr, \ + Type, Value); \ + ACE_YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| ace_yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +ace_yy_stack_print (short int *bottom, short int *top) +#else +static void +ace_yy_stack_print (bottom, top) + short int *bottom; + short int *top; +#endif +{ + ACE_YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + ACE_YYFPRINTF (stderr, " %d", *bottom); + ACE_YYFPRINTF (stderr, "\n"); +} + +# define ACE_YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (ace_yydebug) \ + ace_yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the ACE_YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +ace_yy_reduce_print (int ace_yyrule) +#else +static void +ace_yy_reduce_print (ace_yyrule) + int ace_yyrule; +#endif +{ + int ace_yyi; + unsigned int ace_yylno = ace_yyrline[ace_yyrule]; + ACE_YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + ace_yyrule - 1, ace_yylno); + /* Print the symbols being reduced, and their result. */ + for (ace_yyi = ace_yyprhs[ace_yyrule]; 0 <= ace_yyrhs[ace_yyi]; ace_yyi++) + ACE_YYFPRINTF (stderr, "%s ", ace_yytname [ace_yyrhs[ace_yyi]]); + ACE_YYFPRINTF (stderr, "-> %s\n", ace_yytname [ace_yyr1[ace_yyrule]]); +} + +# define ACE_YY_REDUCE_PRINT(Rule) \ +do { \ + if (ace_yydebug) \ + ace_yy_reduce_print (Rule); \ +} while (0) + /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int ace_yydebug; #else /* !ACE_YYDEBUG */ # define ACE_YYDPRINTF(Args) +# define ACE_YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define ACE_YY_STACK_PRINT(Bottom, Top) +# define ACE_YY_REDUCE_PRINT(Rule) #endif /* !ACE_YYDEBUG */ + /* ACE_YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef ACE_YYINITDEPTH # define ACE_YYINITDEPTH 200 @@ -497,15 +690,13 @@ int ace_yydebug; SIZE_MAX < ACE_YYSTACK_BYTES (ACE_YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ -#if ACE_YYMAXDEPTH == 0 -# undef ACE_YYMAXDEPTH -#endif - #ifndef ACE_YYMAXDEPTH # define ACE_YYMAXDEPTH 10000 #endif - -#ifdef ACE_YYERROR_VERBOSE + + + +#if ACE_YYERROR_VERBOSE # ifndef ace_yystrlen # if defined (__GLIBC__) && defined (_STRING_H) @@ -514,13 +705,13 @@ int ace_yydebug; /* Return the length of ACE_YYSTR. */ static ACE_YYSIZE_T # if defined (__STDC__) || defined (__cplusplus) -ace_yystrlen (const ACE_TCHAR *ace_yystr) +ace_yystrlen (const char *ace_yystr) # else ace_yystrlen (ace_yystr) - const ACE_TCHAR *ace_yystr; + const char *ace_yystr; # endif { - register const ACE_TCHAR *ace_yys = ace_yystr; + register const char *ace_yys = ace_yystr; while (*ace_yys++ != '\0') continue; @@ -536,17 +727,17 @@ ace_yystrlen (ace_yystr) # else /* Copy ACE_YYSRC to ACE_YYDEST, returning the address of the terminating '\0' in ACE_YYDEST. */ -static ACE_TCHAR * +static char * # if defined (__STDC__) || defined (__cplusplus) -ace_yystpcpy (ACE_TCHAR *ace_yydest, const ACE_TCHAR *ace_yysrc) +ace_yystpcpy (ACE_TCHAR *ace_yydest, const char *ace_yysrc) # else ace_yystpcpy (ace_yydest, ace_yysrc) - ACE_TCHAR *ace_yydest; - const ACE_TCHAR *ace_yysrc; + char *ace_yydest; + const char *ace_yysrc; # endif { - register ACE_TCHAR *ace_yyd = ace_yydest; - register const ACE_TCHAR *ace_yys = ace_yysrc; + register char *ace_yyd = ace_yydest; + register const char *ace_yys = ace_yysrc; while ((*ace_yyd++ = *ace_yys++) != '\0') continue; @@ -555,85 +746,139 @@ ace_yystpcpy (ace_yydest, ace_yysrc) } # endif # endif + +#endif /* !ACE_YYERROR_VERBOSE */ + + + +#if ACE_YYDEBUG +/*--------------------------------. +| Print this symbol on ACE_YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +ace_yysymprint (FILE *ace_yyoutput, int ace_yytype, ACE_YYSTYPE *ace_yyvaluep) +#else +static void +ace_yysymprint (ace_yyoutput, ace_yytype, ace_yyvaluep) + FILE *ace_yyoutput; + int ace_yytype; + ACE_YYSTYPE *ace_yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) ace_yyvaluep; + + if (ace_yytype < ACE_YYNTOKENS) + ACE_YYFPRINTF (ace_yyoutput, "token %s (", ace_yytname[ace_yytype]); + else + ACE_YYFPRINTF (ace_yyoutput, "nterm %s (", ace_yytname[ace_yytype]); + + +# ifdef ACE_YYPRINT + if (ace_yytype < ACE_YYNTOKENS) + ACE_YYPRINT (ace_yyoutput, ace_yytoknum[ace_yytype], *ace_yyvaluep); +# endif + switch (ace_yytype) + { + default: + break; + } + ACE_YYFPRINTF (ace_yyoutput, ")"); +} + +#endif /* ! ACE_YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +ace_yydestruct (const char *ace_yymsg, int ace_yytype, ACE_YYSTYPE *ace_yyvaluep) +#else +static void +ace_yydestruct (ace_yymsg, ace_yytype, ace_yyvaluep) + const char *ace_yymsg; + int ace_yytype; + ACE_YYSTYPE *ace_yyvaluep; #endif - +{ + /* Pacify ``unused variable'' warnings. */ + (void) ace_yyvaluep; + if (!ace_yymsg) + ace_yymsg = "Deleting"; + ACE_YY_SYMBOL_PRINT (ace_yymsg, ace_yytype, ace_yyvaluep, ace_yylocationp); -/* The user can define ACE_YYPARSE_PARAM as the name of an argument to be passed - into ace_yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ + switch (ace_yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ #ifdef ACE_YYPARSE_PARAM # if defined (__STDC__) || defined (__cplusplus) -# define ACE_YYPARSE_PARAM_ARG void *ACE_YYPARSE_PARAM -# define ACE_YYPARSE_PARAM_DECL +int ace_yyparse (void *ACE_YYPARSE_PARAM); # else -# define ACE_YYPARSE_PARAM_ARG ACE_YYPARSE_PARAM -# define ACE_YYPARSE_PARAM_DECL void *ACE_YYPARSE_PARAM; +int ace_yyparse (); # endif -#else /* !ACE_YYPARSE_PARAM */ -# define ACE_YYPARSE_PARAM_ARG -# define ACE_YYPARSE_PARAM_DECL -#endif /* !ACE_YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -# ifdef ACE_YYPARSE_PARAM -int ace_yyparse (void *); -# else +#else /* ! ACE_YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) int ace_yyparse (void); -# endif +#else +int ace_yyparse (); #endif +#endif /* ! ACE_YYPARSE_PARAM */ -/* ACE_YY_DECL_VARIABLES -- depending whether we use a pure parser, - variables are global, or local to ACE_YYPARSE. */ - -#define ACE_YY_DECL_NON_LSP_VARIABLES \ -/* The lookahead symbol. */ \ -int ace_yychar; \ - \ -/* The semantic value of the lookahead symbol. */ \ -ACE_YYSTYPE ace_yylval; \ - \ -/* Number of parse errors so far. */ \ -int ace_yynerrs; -#if ACE_YYLSP_NEEDED -# define ACE_YY_DECL_VARIABLES \ -ACE_YY_DECL_NON_LSP_VARIABLES \ - \ -/* Location data for the lookahead symbol. */ \ -ACE_YYLTYPE ace_yylloc; -#else -# define ACE_YY_DECL_VARIABLES \ -ACE_YY_DECL_NON_LSP_VARIABLES -#endif -/* If nonreentrant, generate the variables here. */ -#if !ACE_YYPURE -ACE_YY_DECL_VARIABLES -#endif /* !ACE_YYPURE */ +/*----------. +| ace_yyparse. | +`----------*/ + +#ifdef ACE_YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int ace_yyparse (void *ACE_YYPARSE_PARAM) +# else +int ace_yyparse (ACE_YYPARSE_PARAM) + void *ACE_YYPARSE_PARAM; +# endif +#else /* ! ACE_YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +ace_yyparse (void) +#else int -ace_yyparse (ACE_YYPARSE_PARAM_ARG) - ACE_YYPARSE_PARAM_DECL +ace_yyparse () + +#endif +#endif { - /* If reentrant, generate the variables here. */ -#if ACE_YYPURE - ACE_YY_DECL_VARIABLES -#endif /* !ACE_YYPURE */ + /* The look-ahead symbol. */ +int ace_yychar; + +/* The semantic value of the look-ahead symbol. */ +ACE_YYSTYPE ace_yylval; + +/* Number of syntax errors so far. */ +int ace_yynerrs; register int ace_yystate; register int ace_yyn; int ace_yyresult; /* Number of tokens to shift before error messages enabled. */ int ace_yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int ace_yychar1 = 0; + /* Look-ahead token as an internal (translated) token number. */ + int ace_yytoken = 0; /* Three stacks and their tools: `ace_yyss': related to states, @@ -643,41 +888,29 @@ ace_yyparse (ACE_YYPARSE_PARAM_ARG) Refer to the stacks thru separate pointers, to allow ace_yyoverflow to reallocate them elsewhere. */ - /* The state stack. */ - short ace_yyssa[ACE_YYINITDEPTH]; - short *ace_yyss = ace_yyssa; - register short *ace_yyssp; + /* The state stack. */ + short int ace_yyssa[ACE_YYINITDEPTH]; + short int *ace_yyss = ace_yyssa; + register short int *ace_yyssp; /* The semantic value stack. */ ACE_YYSTYPE ace_yyvsa[ACE_YYINITDEPTH]; ACE_YYSTYPE *ace_yyvs = ace_yyvsa; register ACE_YYSTYPE *ace_yyvsp; -#if ACE_YYLSP_NEEDED - /* The location stack. */ - ACE_YYLTYPE ace_yylsa[ACE_YYINITDEPTH]; - ACE_YYLTYPE *ace_yyls = ace_yylsa; - ACE_YYLTYPE *ace_yylsp; -#endif -#if ACE_YYLSP_NEEDED -# define ACE_YYPOPSTACK (ace_yyvsp--, ace_yyssp--, ace_yylsp--) -#else -# define ACE_YYPOPSTACK (ace_yyvsp--, ace_yyssp--) -#endif - ACE_YYSIZE_T ace_yystacksize = ACE_YYINITDEPTH; +#define ACE_YYPOPSTACK (ace_yyvsp--, ace_yyssp--) + ACE_YYSIZE_T ace_yystacksize = ACE_YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ ACE_YYSTYPE ace_yyval; -#if ACE_YYLSP_NEEDED - ACE_YYLTYPE ace_yyloc; -#endif + /* When reducing, the number of symbols on the RHS of the reduced - rule. */ + rule. */ int ace_yylen; ACE_YYDPRINTF ((stderr, "Starting parse\n")); @@ -694,9 +927,10 @@ ace_yyparse (ACE_YYPARSE_PARAM_ARG) ace_yyssp = ace_yyss; ace_yyvsp = ace_yyvs; -#if ACE_YYLSP_NEEDED - ace_yylsp = ace_yyls; -#endif + + + ace_yyvsp[0] = ace_yylval; + goto ace_yysetstate; /*------------------------------------------------------------. @@ -711,181 +945,136 @@ ace_yyparse (ACE_YYPARSE_PARAM_ARG) ace_yysetstate: *ace_yyssp = ace_yystate; - if (ace_yyssp >= ace_yyss + ace_yystacksize - 1) + if (ace_yyss + ace_yystacksize - 1 <= ace_yyssp) { /* Get the current used size of the three stacks, in elements. */ ACE_YYSIZE_T ace_yysize = ace_yyssp - ace_yyss + 1; #ifdef ace_yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - ACE_YYSTYPE *ace_yyvs1 = ace_yyvs; - short *ace_yyss1 = ace_yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. */ -# if ACE_YYLSP_NEEDED - ACE_YYLTYPE *ace_yyls1 = ace_yyls; - /* This used to be a conditional around just the two extra args, - but that might be undefined if ace_yyoverflow is a macro. */ - ace_yyoverflow ("parser stack overflow", - &ace_yyss1, ace_yysize * sizeof (*ace_yyssp), - &ace_yyvs1, ace_yysize * sizeof (*ace_yyvsp), - &ace_yyls1, ace_yysize * sizeof (*ace_yylsp), - &ace_yystacksize); - ace_yyls = ace_yyls1; -# else - ace_yyoverflow ("parser stack overflow", - &ace_yyss1, ace_yysize * sizeof (*ace_yyssp), - &ace_yyvs1, ace_yysize * sizeof (*ace_yyvsp), - &ace_yystacksize); -# endif - ace_yyss = ace_yyss1; - ace_yyvs = ace_yyvs1; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + ACE_YYSTYPE *ace_yyvs1 = ace_yyvs; + short int *ace_yyss1 = ace_yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if ace_yyoverflow is a macro. */ + ace_yyoverflow ("parser stack overflow", + &ace_yyss1, ace_yysize * sizeof (*ace_yyssp), + &ace_yyvs1, ace_yysize * sizeof (*ace_yyvsp), + + &ace_yystacksize); + + ace_yyss = ace_yyss1; + ace_yyvs = ace_yyvs1; } #else /* no ace_yyoverflow */ # ifndef ACE_YYSTACK_RELOCATE goto ace_yyoverflowlab; # else /* Extend the stack our own way. */ - if (ace_yystacksize >= ACE_YYMAXDEPTH) - goto ace_yyoverflowlab; + if (ACE_YYMAXDEPTH <= ace_yystacksize) + goto ace_yyoverflowlab; ace_yystacksize *= 2; - if (ace_yystacksize > ACE_YYMAXDEPTH) - ace_yystacksize = ACE_YYMAXDEPTH; + if (ACE_YYMAXDEPTH < ace_yystacksize) + ace_yystacksize = ACE_YYMAXDEPTH; { - short *ace_yyss1 = ace_yyss; - union ace_yyalloc *ace_yyptr = - (union ace_yyalloc *) ACE_YYSTACK_ALLOC (ACE_YYSTACK_BYTES (ace_yystacksize)); - if (! ace_yyptr) - goto ace_yyoverflowlab; - ACE_YYSTACK_RELOCATE (ace_yyss); - ACE_YYSTACK_RELOCATE (ace_yyvs); -# if ACE_YYLSP_NEEDED - ACE_YYSTACK_RELOCATE (ace_yyls); -# endif -# undef ACE_YYSTACK_RELOCATE - if (ace_yyss1 != ace_yyssa) - ACE_YYSTACK_FREE (ace_yyss1); + short int *ace_yyss1 = ace_yyss; + union ace_yyalloc *ace_yyptr = + (union ace_yyalloc *) ACE_YYSTACK_ALLOC (ACE_YYSTACK_BYTES (ace_yystacksize)); + if (! ace_yyptr) + goto ace_yyoverflowlab; + ACE_YYSTACK_RELOCATE (ace_yyss); + ACE_YYSTACK_RELOCATE (ace_yyvs); + +# undef ACE_YYSTACK_RELOCATE + if (ace_yyss1 != ace_yyssa) + ACE_YYSTACK_FREE (ace_yyss1); } # endif #endif /* no ace_yyoverflow */ ace_yyssp = ace_yyss + ace_yysize - 1; ace_yyvsp = ace_yyvs + ace_yysize - 1; -#if ACE_YYLSP_NEEDED - ace_yylsp = ace_yyls + ace_yysize - 1; -#endif + ACE_YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) ace_yystacksize)); + (unsigned long int) ace_yystacksize)); - if (ace_yyssp >= ace_yyss + ace_yystacksize - 1) - ACE_YYABORT; + if (ace_yyss + ace_yystacksize - 1 <= ace_yyssp) + ACE_YYABORT; } ACE_YYDPRINTF ((stderr, "Entering state %d\n", ace_yystate)); goto ace_yybackup; - /*-----------. | ace_yybackup. | `-----------*/ ace_yybackup: /* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ +/* Read a look-ahead token if we need one and don't already have one. */ /* ace_yyresume: */ - /* First try to decide what to do without reference to lookahead token. */ + /* First try to decide what to do without reference to look-ahead token. */ ace_yyn = ace_yypact[ace_yystate]; - if (ace_yyn == ACE_YYFLAG) + if (ace_yyn == ACE_YYPACT_NINF) goto ace_yydefault; - /* Not known => get a lookahead token if don't already have one. */ - - /* ace_yychar is either ACE_YYEMPTY or ACE_YYEOF - or a valid token in external form. */ + /* Not known => get a look-ahead token if don't already have one. */ + /* ACE_YYCHAR is either ACE_YYEMPTY or ACE_YYEOF or a valid look-ahead symbol. */ if (ace_yychar == ACE_YYEMPTY) { ACE_YYDPRINTF ((stderr, "Reading a token: ")); ace_yychar = ACE_YYLEX; } - /* Convert token to internal form (in ace_yychar1) for indexing tables with */ - - if (ace_yychar <= 0) /* This means end of input. */ + if (ace_yychar <= ACE_YYEOF) { - ace_yychar1 = 0; - ace_yychar = ACE_YYEOF; /* Don't call ACE_YYLEX any more */ - + ace_yychar = ace_yytoken = ACE_YYEOF; ACE_YYDPRINTF ((stderr, "Now at end of input.\n")); } else { - ace_yychar1 = ACE_YYTRANSLATE (ace_yychar); - -#if ACE_YYDEBUG - /* We have to keep this `#if ACE_YYDEBUG', since we use variables - which are defined only if `ACE_YYDEBUG' is set. */ - if (ace_yydebug) - { - ACE_YYFPRINTF (stderr, "Next token is %d (%s", - ace_yychar, ace_yytname[ace_yychar1]); - /* Give the individual parser a way to print the precise - meaning of a token, for further debugging info. */ -# ifdef ACE_YYPRINT - ACE_YYPRINT (stderr, ace_yychar, ace_yylval); -# endif - ACE_YYFPRINTF (stderr, ")\n"); - } -#endif + ace_yytoken = ACE_YYTRANSLATE (ace_yychar); + ACE_YY_SYMBOL_PRINT ("Next token is", ace_yytoken, &ace_yylval, &ace_yylloc); } - ace_yyn += ace_yychar1; - if (ace_yyn < 0 || ace_yyn > ACE_YYLAST || ace_yycheck[ace_yyn] != ace_yychar1) + /* If the proper action on seeing token ACE_YYTOKEN is to reduce or to + detect an error, take that action. */ + ace_yyn += ace_yytoken; + if (ace_yyn < 0 || ACE_YYLAST < ace_yyn || ace_yycheck[ace_yyn] != ace_yytoken) goto ace_yydefault; - ace_yyn = ace_yytable[ace_yyn]; - - /* ace_yyn is what to do for this token type in this state. - Negative => reduce, -ace_yyn is rule number. - Positive => shift, ace_yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (ace_yyn < 0) + if (ace_yyn <= 0) { - if (ace_yyn == ACE_YYFLAG) - goto ace_yyerrlab; + if (ace_yyn == 0 || ace_yyn == ACE_YYTABLE_NINF) + goto ace_yyerrlab; ace_yyn = -ace_yyn; goto ace_yyreduce; } - else if (ace_yyn == 0) - goto ace_yyerrlab; if (ace_yyn == ACE_YYFINAL) ACE_YYACCEPT; - /* Shift the lookahead token. */ - ACE_YYDPRINTF ((stderr, "Shifting token %d (%s), ", - ace_yychar, ace_yytname[ace_yychar1])); + /* Shift the look-ahead token. */ + ACE_YY_SYMBOL_PRINT ("Shifting", ace_yytoken, &ace_yylval, &ace_yylloc); /* Discard the token being shifted unless it is eof. */ if (ace_yychar != ACE_YYEOF) ace_yychar = ACE_YYEMPTY; *++ace_yyvsp = ace_yylval; -#if ACE_YYLSP_NEEDED - *++ace_yylsp = ace_yylloc; -#endif + /* Count tokens shifted since error; after three, turn off error status. */ @@ -916,142 +1105,156 @@ ace_yyreduce: /* If ACE_YYLEN is nonzero, implement the default value of the action: `$$ = $1'. - Otherwise, the following line sets ACE_YYVAL to the semantic value of - the lookahead token. This behavior is undocumented and Bison + Otherwise, the following line sets ACE_YYVAL to garbage. + This behavior is undocumented and Bison users should not rely upon it. Assigning to ACE_YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that ACE_YYVAL may be used uninitialized. */ ace_yyval = ace_yyvsp[1-ace_yylen]; -#if ACE_YYLSP_NEEDED - /* Similarly for the default location. Let the user run additional - commands if for instance locations are ranges. */ - ace_yyloc = ace_yylsp[1-ace_yylen]; - ACE_YYLLOC_DEFAULT (ace_yyloc, (ace_yylsp - ace_yylen), ace_yylen); -#endif -#if ACE_YYDEBUG - /* We have to keep this `#if ACE_YYDEBUG', since we use variables which - are defined only if `ACE_YYDEBUG' is set. */ - if (ace_yydebug) + ACE_YY_REDUCE_PRINT (ace_yyn); + switch (ace_yyn) { - int ace_yyi; - - ACE_YYFPRINTF (stderr, "Reducing via rule %d (line %d), ", - ace_yyn, ace_yyrline[ace_yyn]); - - /* Print the symbols being reduced, and their result. */ - for (ace_yyi = ace_yyprhs[ace_yyn]; ace_yyrhs[ace_yyi] > 0; ace_yyi++) - ACE_YYFPRINTF (stderr, "%s ", ace_yytname[ace_yyrhs[ace_yyi]]); - ACE_YYFPRINTF (stderr, " -> %s\n", ace_yytname[ace_yyr1[ace_yyn]]); - } -#endif - - switch (ace_yyn) { + case 2: -case 1: -{ - if (ace_yyvsp[0].parse_node_ != 0) + { + if ((ace_yyvsp[0].parse_node_) != 0) { - ace_yyvsp[0].parse_node_->apply (ACE_SVC_CONF_PARAM->yyerrno); delete ace_yyvsp[0].parse_node_; + (ace_yyvsp[0].parse_node_)->apply (ACE_SVC_CONF_PARAM->config, ACE_SVC_CONF_PARAM->yyerrno); + delete (ace_yyvsp[0].parse_node_); } ACE_SVC_CONF_PARAM->obstack.release (); - ; - break;} -case 2: -{ + ;} + break; + + case 3: + + { ACE_SVC_CONF_PARAM->obstack.release (); - ; - break;} -case 10: -{ - if (ace_yyvsp[-1].svc_record_ != 0) - ace_yyval.parse_node_ = new ACE_Dynamic_Node (ace_yyvsp[-1].svc_record_, ace_yyvsp[0].ident_); + ;} + break; + + case 11: + + { + if ((ace_yyvsp[-1].svc_record_) != 0) + (ace_yyval.parse_node_) = new ACE_Dynamic_Node ((ace_yyvsp[-1].svc_record_), (ace_yyvsp[0].ident_)); else - ace_yyval.parse_node_ = 0; - ; - break;} -case 11: -{ - ace_yyval.parse_node_ = new ACE_Static_Node (ace_yyvsp[-1].ident_, ace_yyvsp[0].ident_); - ; - break;} -case 12: -{ - ace_yyval.parse_node_ = new ACE_Suspend_Node (ace_yyvsp[0].ident_); - ; - break;} -case 13: -{ - ace_yyval.parse_node_ = new ACE_Resume_Node (ace_yyvsp[0].ident_); - ; - break;} -case 14: -{ - ace_yyval.parse_node_ = new ACE_Remove_Node (ace_yyvsp[0].ident_); - ; - break;} -case 15: -{ - ace_yyval.parse_node_ = new ACE_Stream_Node (ace_yyvsp[-1].static_node_, ace_yyvsp[0].parse_node_); - ; - break;} -case 16: -{ ace_yyval.static_node_ = new ACE_Static_Node (ace_yyvsp[0].ident_); ; - break;} -case 17: -{ - ace_yyval.parse_node_ = new ACE_Dummy_Node (ace_yyvsp[-1].static_node_, ace_yyvsp[0].parse_node_); - ; - break;} -case 18: -{ - ; - break;} -case 19: -{ - ; - break;} -case 20: -{ + (ace_yyval.parse_node_) = 0; + ;} + break; + + case 12: + + { + (ace_yyval.parse_node_) = new ACE_Static_Node ((ace_yyvsp[-1].ident_), (ace_yyvsp[0].ident_)); + ;} + break; + + case 13: + + { + (ace_yyval.parse_node_) = new ACE_Suspend_Node ((ace_yyvsp[0].ident_)); + ;} + break; + + case 14: + + { + (ace_yyval.parse_node_) = new ACE_Resume_Node ((ace_yyvsp[0].ident_)); + ;} + break; + + case 15: + + { + (ace_yyval.parse_node_) = new ACE_Remove_Node ((ace_yyvsp[0].ident_)); + ;} + break; + + case 16: + + { + (ace_yyval.parse_node_) = new ACE_Stream_Node ((ace_yyvsp[-1].static_node_), (ace_yyvsp[0].parse_node_)); + ;} + break; + + case 17: + + { (ace_yyval.static_node_) = new ACE_Static_Node ((ace_yyvsp[0].ident_)); ;} + break; + + case 18: + + { + (ace_yyval.parse_node_) = new ACE_Dummy_Node ((ace_yyvsp[-1].static_node_), (ace_yyvsp[0].parse_node_)); + ;} + break; + + case 19: + + { + ;} + break; + + case 20: + + { + ;} + break; + + case 21: + + { // Initialize left context... - ace_yyval.static_node_ = ace_yyvsp[-1].static_node_; - ; - break;} -case 21: -{ - ace_yyval.parse_node_ = ace_yyvsp[-1].parse_node_; - ; - break;} -case 22: -{ ace_yyval.parse_node_ = 0; ; - break;} -case 23: -{ - if (ace_yyvsp[0].parse_node_ != 0) + (ace_yyval.static_node_) = (ace_yyvsp[-1].static_node_); + ;} + break; + + case 22: + + { + (ace_yyval.parse_node_) = (ace_yyvsp[-1].parse_node_); + ;} + break; + + case 23: + + { (ace_yyval.parse_node_) = 0; ;} + break; + + case 24: + + { + if ((ace_yyvsp[0].parse_node_) != 0) { - ace_yyvsp[0].parse_node_->link (ace_yyvsp[-1].parse_node_); - ace_yyval.parse_node_ = ace_yyvsp[0].parse_node_; + (ace_yyvsp[0].parse_node_)->link ((ace_yyvsp[-1].parse_node_)); + (ace_yyval.parse_node_) = (ace_yyvsp[0].parse_node_); } - ; - break;} -case 24: -{ ace_yyval.parse_node_ = 0; ; - break;} -case 25: -{ - ACE_Static_Node *svc_type = ace_yyvsp[0].static_node_; + ;} + break; + + case 25: + + { (ace_yyval.parse_node_) = 0; ;} + break; + + case 26: + + { + ACE_Static_Node *svc_type = (ace_yyvsp[0].static_node_); if (svc_type != 0) { - ACE_Static_Node *module = ace_yyvsp[-2].static_node_; + ACE_Static_Node *module = (ace_yyvsp[-2].static_node_); ACE_ARGV args (svc_type->parameters ()); - ACE_Module_Type *mt = ace_get_module (module, - svc_type, + ACE_Module_Type *mt = ace_get_module (module->record (ACE_SVC_CONF_PARAM->config), + svc_type->record (ACE_SVC_CONF_PARAM->config), ACE_SVC_CONF_PARAM->yyerrno); ACE_Stream_Type *st = - dynamic_cast<ACE_Stream_Type *> (const_cast<ACE_Service_Type_Impl *> (module->record ()->type ())); + dynamic_cast<ACE_Stream_Type *> (const_cast<ACE_Service_Type_Impl *> (module->record (ACE_SVC_CONF_PARAM->config)->type ())); if (mt->init (args.argc (), args.argv ()) == -1 || st->push (mt) == -1) @@ -1062,50 +1265,61 @@ case 25: ACE_SVC_CONF_PARAM->yyerrno++; } } - ; - break;} -case 26: -{ - ACE_Module_Type *mt = ace_get_module (ace_yyvsp[-2].static_node_, - ace_yyvsp[0].static_node_->name (), + ;} + break; + + case 27: + + { + ACE_Static_Node *sn = (ace_yyvsp[-2].static_node_); + ACE_Module_Type *mt = ace_get_module (sn->record (ACE_SVC_CONF_PARAM->config), + (ace_yyvsp[0].static_node_)->name (), ACE_SVC_CONF_PARAM->yyerrno); - if (((ACE_Stream_Type *) (ace_yyvsp[-2].static_node_)->record ()->type ())->push (mt) == -1) + if (((ACE_Stream_Type *) sn->record (ACE_SVC_CONF_PARAM->config)->type ())->push (mt) == -1) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("Problem with static\n"))); ACE_SVC_CONF_PARAM->yyerrno++; } - ; - break;} -case 27: -{ - ACE_Module_Type *mt = ace_get_module (ace_yyvsp[-2].static_node_, - ace_yyvsp[0].static_node_->name (), + ;} + break; + + case 28: + + { + ACE_Static_Node *sn = (ace_yyvsp[-2].static_node_); + ACE_Module_Type *mt = ace_get_module (sn->record (ACE_SVC_CONF_PARAM->config), + sn->name (), ACE_SVC_CONF_PARAM->yyerrno); if (mt != 0) mt->suspend (); - ; - break;} -case 28: -{ - ACE_Module_Type *mt = ace_get_module (ace_yyvsp[-2].static_node_, - ace_yyvsp[0].static_node_->name (), + ;} + break; + + case 29: + + { + ACE_Static_Node *sn = (ace_yyvsp[-2].static_node_); + ACE_Module_Type *mt = ace_get_module (sn->record (ACE_SVC_CONF_PARAM->config), + (ace_yyvsp[0].static_node_)->name (), ACE_SVC_CONF_PARAM->yyerrno); if (mt != 0) mt->resume (); - ; - break;} -case 29: -{ - ACE_Static_Node *stream = ace_yyvsp[-2].static_node_; - ACE_Static_Node *module = ace_yyvsp[0].static_node_; - ACE_Module_Type *mt = ace_get_module (stream, + ;} + break; + + case 30: + + { + ACE_Static_Node *stream = (ace_yyvsp[-2].static_node_); + ACE_Static_Node *module = (ace_yyvsp[0].static_node_); + ACE_Module_Type *mt = ace_get_module (stream->record (ACE_SVC_CONF_PARAM->config), module->name (), ACE_SVC_CONF_PARAM->yyerrno); ACE_Stream_Type *st = - dynamic_cast<ACE_Stream_Type *> (const_cast<ACE_Service_Type_Impl *> (stream->record ()->type ())); + dynamic_cast<ACE_Stream_Type *> (const_cast<ACE_Service_Type_Impl *> (stream->record (ACE_SVC_CONF_PARAM->config)->type ())); if (mt != 0 && st->remove (mt) == -1) { ACE_ERROR ((LM_ERROR, @@ -1114,116 +1328,98 @@ case 29: stream->name ())); ACE_SVC_CONF_PARAM->yyerrno++; } - ; - break;} -case 30: -{ - u_int flags - = ACE_Service_Type::DELETE_THIS - | (ace_yyvsp[-1].location_node_->dispose () == 0 ? 0 : ACE_Service_Type::DELETE_OBJ); - ACE_Service_Object_Exterminator gobbler = 0; - void *sym = ace_yyvsp[-1].location_node_->symbol (ACE_SVC_CONF_PARAM->yyerrno, &gobbler); + ;} + break; - if (sym != 0) - { - ACE_Service_Type_Impl *stp - = ACE_Service_Config::create_service_type_impl (ace_yyvsp[-3].ident_, - ace_yyvsp[-2].type_, - sym, - flags, - gobbler); - if (stp == 0) - ++ACE_SVC_CONF_PARAM->yyerrno; - - ace_yyval.svc_record_ = new ACE_Service_Type (ace_yyvsp[-3].ident_, - stp, - ace_yyvsp[-1].location_node_->dll (), - ace_yyvsp[0].type_); - } - else - { - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("Unable to find service: %s\n"), - ace_yyvsp[-3].ident_)); - ++ACE_SVC_CONF_PARAM->yyerrno; - ace_yyval.svc_record_ = 0; - } - delete ace_yyvsp[-1].location_node_; - ; - break;} -case 31: -{ - ace_yyval.type_ = 1; - ; - break;} -case 32: -{ - ace_yyval.type_ = 0; - ; - break;} -case 33: -{ - ace_yyval.type_ = 1; - ; - break;} -case 34: -{ - ace_yyval.location_node_ = new ACE_Object_Node (ace_yyvsp[-2].ident_, ace_yyvsp[0].ident_); - ; - break;} -case 35: -{ - ace_yyval.location_node_ = new ACE_Function_Node (ace_yyvsp[-4].ident_, ace_yyvsp[-2].ident_); - ; - break;} -case 36: -{ - ace_yyval.location_node_ = new ACE_Static_Function_Node (ace_yyvsp[-2].ident_); - ; - break;} -case 37: -{ - ace_yyval.type_ = ACE_MODULE_T; - ; - break;} -case 38: -{ - ace_yyval.type_ = ACE_SVC_OBJ_T; - ; - break;} -case 39: -{ - ace_yyval.type_ = ACE_STREAM_T; - ; - break;} -case 41: -{ ace_yyval.ident_ = 0; ; - break;} -} + case 31: + { + (ace_yyval.svc_record_) = new ACE_Service_Type_Factory ((ace_yyvsp[-3].ident_), (ace_yyvsp[-2].type_), (ace_yyvsp[-1].location_node_), (ace_yyvsp[0].type_)); + ;} + break; - - ace_yyvsp -= ace_yylen; - ace_yyssp -= ace_yylen; -#if ACE_YYLSP_NEEDED - ace_yylsp -= ace_yylen; -#endif + case 32: + + { + (ace_yyval.type_) = 1; + ;} + break; + + case 33: + + { + (ace_yyval.type_) = 0; + ;} + break; + + case 34: + + { + (ace_yyval.type_) = 1; + ;} + break; + + case 35: + + { + (ace_yyval.location_node_) = new ACE_Object_Node ((ace_yyvsp[-2].ident_), (ace_yyvsp[0].ident_)); + ;} + break; + + case 36: + + { + (ace_yyval.location_node_) = new ACE_Function_Node ((ace_yyvsp[-4].ident_), (ace_yyvsp[-2].ident_)); + ;} + break; + + case 37: + + { + (ace_yyval.location_node_) = new ACE_Static_Function_Node ((ace_yyvsp[-2].ident_)); + ;} + break; + + case 38: + + { + (ace_yyval.type_) = ACE_MODULE_T; + ;} + break; + + case 39: -#if ACE_YYDEBUG - if (ace_yydebug) { - short *ace_yyssp1 = ace_yyss - 1; - ACE_YYFPRINTF (stderr, "state stack now"); - while (ace_yyssp1 != ace_yyssp) - ACE_YYFPRINTF (stderr, " %d", *++ace_yyssp1); - ACE_YYFPRINTF (stderr, "\n"); + (ace_yyval.type_) = ACE_SVC_OBJ_T; + ;} + break; + + case 40: + + { + (ace_yyval.type_) = ACE_STREAM_T; + ;} + break; + + case 42: + + { (ace_yyval.ident_) = 0; ;} + break; + + } -#endif + +/* Line 1037 of yacc.c. */ + + + ace_yyvsp -= ace_yylen; + ace_yyssp -= ace_yylen; + + + ACE_YY_STACK_PRINT (ace_yyss, ace_yyssp); *++ace_yyvsp = ace_yyval; -#if ACE_YYLSP_NEEDED - *++ace_yylsp = ace_yyloc; -#endif + /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule @@ -1231,11 +1427,11 @@ case 41: ace_yyn = ace_yyr1[ace_yyn]; - ace_yystate = ace_yypgoto[ace_yyn - ACE_YYNTBASE] + *ace_yyssp; - if (ace_yystate >= 0 && ace_yystate <= ACE_YYLAST && ace_yycheck[ace_yystate] == *ace_yyssp) + ace_yystate = ace_yypgoto[ace_yyn - ACE_YYNTOKENS] + *ace_yyssp; + if (0 <= ace_yystate && ace_yystate <= ACE_YYLAST && ace_yycheck[ace_yystate] == *ace_yyssp) ace_yystate = ace_yytable[ace_yystate]; else - ace_yystate = ace_yydefgoto[ace_yyn - ACE_YYNTBASE]; + ace_yystate = ace_yydefgoto[ace_yyn - ACE_YYNTOKENS]; goto ace_yynewstate; @@ -1248,155 +1444,159 @@ ace_yyerrlab: if (!ace_yyerrstatus) { ++ace_yynerrs; - -#ifdef ACE_YYERROR_VERBOSE +#if ACE_YYERROR_VERBOSE ace_yyn = ace_yypact[ace_yystate]; - if (ace_yyn > ACE_YYFLAG && ace_yyn < ACE_YYLAST) - { - ACE_YYSIZE_T ace_yysize = 0; - ACE_TCHAR *ace_yymsg; - int ace_yyx, ace_yycount; - - ace_yycount = 0; - /* Start ACE_YYX at -ACE_YYN if negative to avoid negative indexes in - ACE_YYCHECK. */ - for (ace_yyx = ace_yyn < 0 ? -ace_yyn : 0; - ace_yyx < (int) (sizeof (ace_yytname) / sizeof (ACE_TCHAR *)); ace_yyx++) - if (ace_yycheck[ace_yyx + ace_yyn] == ace_yyx) - ace_yysize += ace_yystrlen (ace_yytname[ace_yyx]) + 15, ace_yycount++; - ace_yysize += ace_yystrlen ("parse error, unexpected ") + 1; - ace_yysize += ace_yystrlen (ace_yytname[ACE_YYTRANSLATE (ace_yychar)]); - ace_yymsg = (ACE_TCHAR *) ACE_YYSTACK_ALLOC (ace_yysize); - if (ace_yymsg != 0) - { - ACE_TCHAR *ace_yyp = ace_yystpcpy (ace_yymsg, "parse error, unexpected "); - ace_yyp = ace_yystpcpy (ace_yyp, ace_yytname[ACE_YYTRANSLATE (ace_yychar)]); - - if (ace_yycount < 5) - { - ace_yycount = 0; - for (ace_yyx = ace_yyn < 0 ? -ace_yyn : 0; - ace_yyx < (int) (sizeof (ace_yytname) / sizeof (ACE_TCHAR *)); - ace_yyx++) - if (ace_yycheck[ace_yyx + ace_yyn] == ace_yyx) - { - const ACE_TCHAR *ace_yyq = ! ace_yycount ? ", expecting " : " or "; - ace_yyp = ace_yystpcpy (ace_yyp, ace_yyq); - ace_yyp = ace_yystpcpy (ace_yyp, ace_yytname[ace_yyx]); - ace_yycount++; - } - } - ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, ace_yymsg); - ACE_YYSTACK_FREE (ace_yymsg); - } - else - ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, "parse error; also virtual memory exhausted"); - } + if (ACE_YYPACT_NINF < ace_yyn && ace_yyn < ACE_YYLAST) + { + ACE_YYSIZE_T ace_yysize = 0; + int ace_yytype = ACE_YYTRANSLATE (ace_yychar); + const char* ace_yyprefix; + char *ace_yymsg; + int ace_yyx; + + /* Start ACE_YYX at -ACE_YYN if negative to avoid negative indexes in + ACE_YYCHECK. */ + int ace_yyxbegin = ace_yyn < 0 ? -ace_yyn : 0; + + /* Stay within bounds of both ace_yycheck and ace_yytname. */ + int ace_yychecklim = ACE_YYLAST - ace_yyn; + int ace_yyxend = ace_yychecklim < ACE_YYNTOKENS ? ace_yychecklim : ACE_YYNTOKENS; + int ace_yycount = 0; + + ace_yyprefix = ", expecting "; + for (ace_yyx = ace_yyxbegin; ace_yyx < ace_yyxend; ++ace_yyx) + if (ace_yycheck[ace_yyx + ace_yyn] == ace_yyx && ace_yyx != ACE_YYTERROR) + { + ace_yysize += ace_yystrlen (ace_yyprefix) + ace_yystrlen (ace_yytname [ace_yyx]); + ace_yycount += 1; + if (ace_yycount == 5) + { + ace_yysize = 0; + break; + } + } + ace_yysize += (sizeof ("syntax error, unexpected ") + + ace_yystrlen (ace_yytname[ace_yytype])); + ace_yymsg = (ACE_TCHAR *) ACE_YYSTACK_ALLOC (ace_yysize); + if (ace_yymsg != 0) + { + char *ace_yyp = ace_yystpcpy (ace_yymsg, "syntax error, unexpected "); + ace_yyp = ace_yystpcpy (ace_yyp, ace_yytname[ace_yytype]); + + if (ace_yycount < 5) + { + ace_yyprefix = ", expecting "; + for (ace_yyx = ace_yyxbegin; ace_yyx < ace_yyxend; ++ace_yyx) + if (ace_yycheck[ace_yyx + ace_yyn] == ace_yyx && ace_yyx != ACE_YYTERROR) + { + ace_yyp = ace_yystpcpy (ace_yyp, ace_yyprefix); + ace_yyp = ace_yystpcpy (ace_yyp, ace_yytname[ace_yyx]); + ace_yyprefix = " or "; + } + } + ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, ace_yymsg); + ACE_YYSTACK_FREE (ace_yymsg); + } + else + ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, "syntax error; also virtual memory exhausted"); + } else -#endif /* defined (ACE_YYERROR_VERBOSE) */ - ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, "parse error"); +#endif /* ACE_YYERROR_VERBOSE */ + ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, "syntax error"); } - goto ace_yyerrlab1; -/*--------------------------------------------------. -| ace_yyerrlab1 -- error raised explicitly by an action | -`--------------------------------------------------*/ -ace_yyerrlab1: + if (ace_yyerrstatus == 3) { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - /* return failure if at end of input */ - if (ace_yychar == ACE_YYEOF) - ACE_YYABORT; - ACE_YYDPRINTF ((stderr, "Discarding token %d (%s).\n", - ace_yychar, ace_yytname[ace_yychar1])); - ace_yychar = ACE_YYEMPTY; + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (ace_yychar <= ACE_YYEOF) + { + /* If at end of input, pop the error token, + then the rest of the stack, then return failure. */ + if (ace_yychar == ACE_YYEOF) + for (;;) + { + + ACE_YYPOPSTACK; + if (ace_yyssp == ace_yyss) + ACE_YYABORT; + ace_yydestruct ("Error: popping", + ace_yystos[*ace_yyssp], ace_yyvsp); + } + } + else + { + ace_yydestruct ("Error: discarding", ace_yytoken, &ace_yylval); + ace_yychar = ACE_YYEMPTY; + } } - /* Else will try to reuse lookahead token after shifting the error + /* Else will try to reuse look-ahead token after shifting the error token. */ - - ace_yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto ace_yyerrhandle; + goto ace_yyerrlab1; -/*-------------------------------------------------------------------. -| ace_yyerrdefault -- current state does not do anything special for the | -| error token. | -`-------------------------------------------------------------------*/ -ace_yyerrdefault: -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ +/*---------------------------------------------------. +| ace_yyerrorlab -- error raised explicitly by ACE_YYERROR. | +`---------------------------------------------------*/ +ace_yyerrorlab: - /* If its default is to accept any token, ok. Otherwise pop it. */ - ace_yyn = ace_yydefact[ace_yystate]; - if (ace_yyn) - goto ace_yydefault; +#ifdef __GNUC__ + /* Pacify GCC when the user code never invokes ACE_YYERROR and the label + ace_yyerrorlab therefore never appears in user code. */ + if (0) + goto ace_yyerrorlab; #endif +ace_yyvsp -= ace_yylen; + ace_yyssp -= ace_yylen; + ace_yystate = *ace_yyssp; + goto ace_yyerrlab1; + -/*---------------------------------------------------------------. -| ace_yyerrpop -- pop the current state because it cannot handle the | -| error token | -`---------------------------------------------------------------*/ -ace_yyerrpop: - if (ace_yyssp == ace_yyss) - ACE_YYABORT; - ace_yyvsp--; - ace_yystate = *--ace_yyssp; -#if ACE_YYLSP_NEEDED - ace_yylsp--; -#endif +/*-------------------------------------------------------------. +| ace_yyerrlab1 -- common code for both syntax error and ACE_YYERROR. | +`-------------------------------------------------------------*/ +ace_yyerrlab1: + ace_yyerrstatus = 3; /* Each real token shifted decrements this. */ -#if ACE_YYDEBUG - if (ace_yydebug) + for (;;) { - short *ace_yyssp1 = ace_yyss - 1; - ACE_YYFPRINTF (stderr, "Error: state stack now"); - while (ace_yyssp1 != ace_yyssp) - ACE_YYFPRINTF (stderr, " %d", *++ace_yyssp1); - ACE_YYFPRINTF (stderr, "\n"); - } -#endif + ace_yyn = ace_yypact[ace_yystate]; + if (ace_yyn != ACE_YYPACT_NINF) + { + ace_yyn += ACE_YYTERROR; + if (0 <= ace_yyn && ace_yyn <= ACE_YYLAST && ace_yycheck[ace_yyn] == ACE_YYTERROR) + { + ace_yyn = ace_yytable[ace_yyn]; + if (0 < ace_yyn) + break; + } + } -/*--------------. -| ace_yyerrhandle. | -`--------------*/ -ace_yyerrhandle: - ace_yyn = ace_yypact[ace_yystate]; - if (ace_yyn == ACE_YYFLAG) - goto ace_yyerrdefault; + /* Pop the current state because it cannot handle the error token. */ + if (ace_yyssp == ace_yyss) + ACE_YYABORT; - ace_yyn += ACE_YYTERROR; - if (ace_yyn < 0 || ace_yyn > ACE_YYLAST || ace_yycheck[ace_yyn] != ACE_YYTERROR) - goto ace_yyerrdefault; - ace_yyn = ace_yytable[ace_yyn]; - if (ace_yyn < 0) - { - if (ace_yyn == ACE_YYFLAG) - goto ace_yyerrpop; - ace_yyn = -ace_yyn; - goto ace_yyreduce; + ace_yydestruct ("Error: popping", ace_yystos[ace_yystate], ace_yyvsp); + ACE_YYPOPSTACK; + ace_yystate = *ace_yyssp; + ACE_YY_STACK_PRINT (ace_yyss, ace_yyssp); } - else if (ace_yyn == 0) - goto ace_yyerrpop; if (ace_yyn == ACE_YYFINAL) ACE_YYACCEPT; - ACE_YYDPRINTF ((stderr, "Shifting error token, ")); - *++ace_yyvsp = ace_yylval; -#if ACE_YYLSP_NEEDED - *++ace_yylsp = ace_yylloc; -#endif + + + /* Shift the error token. */ + ACE_YY_SYMBOL_PRINT ("Shifting", ace_yystos[ace_yyn], ace_yyvsp, ace_yylsp); ace_yystate = ace_yyn; goto ace_yynewstate; @@ -1413,16 +1613,21 @@ ace_yyacceptlab: | ace_yyabortlab -- ACE_YYABORT comes here. | `-----------------------------------*/ ace_yyabortlab: + ace_yydestruct ("Error: discarding lookahead", + ace_yytoken, &ace_yylval); + ace_yychar = ACE_YYEMPTY; ace_yyresult = 1; goto ace_yyreturn; -/*---------------------------------------------. -| ace_yyoverflowab -- parser overflow comes here. | -`---------------------------------------------*/ +#ifndef ace_yyoverflow +/*----------------------------------------------. +| ace_yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ ace_yyoverflowlab: ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, "parser stack overflow"); ace_yyresult = 2; /* Fall through. */ +#endif ace_yyreturn: #ifndef ace_yyoverflow @@ -1432,6 +1637,9 @@ ace_yyreturn: return ace_yyresult; } + + + // Prints the error string to standard output. Cleans up the error // messages. @@ -1455,11 +1663,10 @@ ace_yyerror (int ace_yyerrno, int ace_yylineno, const char *s) // record. static ACE_Module_Type * -ace_get_module (ACE_Static_Node *str_rec, +ace_get_module (const ACE_Service_Type *sr, const ACE_TCHAR *svc_name, int & ace_yyerrno) { - const ACE_Service_Type *sr = str_rec->record (); const ACE_Service_Type_Impl *type = sr->type (); ACE_Stream_Type *st = sr == 0 ? 0 @@ -1471,7 +1678,7 @@ ace_get_module (ACE_Static_Node *str_rec, ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("cannot locate Module_Type %s in STREAM_Type %s\n"), svc_name, - str_rec->name ())); + sr->name ())); ace_yyerrno++; } @@ -1479,24 +1686,23 @@ ace_get_module (ACE_Static_Node *str_rec, } static ACE_Module_Type * -ace_get_module (ACE_Static_Node *str_rec, - ACE_Static_Node *svc_type, +ace_get_module (const ACE_Service_Type *sr, + const ACE_Service_Type *sv, int & ace_yyerrno) { - const ACE_Service_Type *sr = str_rec->record (); const ACE_Service_Type_Impl *type = sr->type (); ACE_Stream_Type *st = sr == 0 ? 0 : (ACE_Stream_Type *) type; - const ACE_Service_Type *sv = svc_type->record (); + type = sv->type (); ACE_Module_Type *mt = (ACE_Module_Type *) type; - const ACE_TCHAR *module_type_name = svc_type->name (); + const ACE_TCHAR *module_type_name = sr->name (); if (sr == 0 || st == 0 || mt == 0) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("cannot locate Module_Type %s or STREAM_Type %s\n"), module_type_name, - str_rec->name ())); + sr->name ())); ace_yyerrno++; } @@ -1520,7 +1726,7 @@ ace_get_module (ACE_Static_Node *str_rec, // Main driver program. int -main (int argc, ACE_TCHAR *argv[]) +main (int argc, char *argv[]) { ACE_Svc_Conf_Param param (stdin); @@ -1535,3 +1741,4 @@ main (int argc, ACE_TCHAR *argv[]) ACE_END_VERSIONED_NAMESPACE_DECL #endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ + diff --git a/ace/svcconf.mpb b/ace/svcconf.mpb index 7627592eb7c..cbdcdce227f 100644 --- a/ace/svcconf.mpb +++ b/ace/svcconf.mpb @@ -8,8 +8,10 @@ feature(ace_svcconf) { DLL.cpp DLL_Manager.cpp Dynamic_Service_Base.cpp + Dynamic_Service_Dependency.cpp Parse_Node.cpp Service_Config.cpp + Service_Gestalt.cpp Service_Manager.cpp Service_Object.cpp Service_Repository.cpp @@ -29,15 +31,15 @@ feature(ace_svcconf) { "Svc_Conf_y.cpp: Svc_Conf.y" "ifeq ($(notdir $(YACC)), bison)" " $(YACC) -l -d Svc_Conf.y" - " sed -e 's/char \\*getenv/char *ace_foo/g' \\" - " -e 's/= getenv/= ACE_OS::getenv/g' \\" - " -e 's/fprintf/ACE_OS::fprintf/g' \\" + " sed -e 's/char \\*getenv/char *ace_foo/g' \\" // Eliminates getenv prototype, use ACE's + " -e 's/= getenv/= ACE_OS::getenv/g' \\" // ... like this - qualified. + " -e 's/fprintf/ACE_OS::fprintf/g' \\" // Use ACE's fprintf, not library's " -e 's/yy/ace_yy/g' \\" - " -e 's/->ace_yyerrno/->yyerrno/g' \\" - " -e 's/->ace_yylineno/->yylineno/g' \\" + " -e 's/->ace_yyerrno/->yyerrno/g' \\" // These reverse the unwanted ace_ prefix + " -e 's/->ace_yylineno/->yylineno/g' \\" // added by the substitution, above. " -e 's/YY/ACE_YY/g' \\" " -e 's/^char /ACE_TCHAR /g' \\" - " -e 's/ char / ACE_TCHAR /g' \\" + " -e 's/\([^d]\) char /\$1 ACE_TCHAR /g' \\" " -e 's/(char/(ACE_TCHAR/g' \\" " -e 's/ NULL/ 0/g' \\" " -e 's/ace_yyerror[ ]*(\"/ace_yyerror (ACE_SVC_CONF_PARAM->yyerrno, ACE_SVC_CONF_PARAM->yylineno, \"/g' \\" @@ -46,12 +48,18 @@ feature(ace_svcconf) { " -e 's@#include <stdio\.h>@@' \\" " -e 's/Svc_Conf\\.tab\\.c/Svc_Conf_y.cpp/g' < Svc_Conf.tab.c > /tmp/$@" " cp /tmp/$@ $@" - " echo \/\/ '$$I''d$$' > Svc_Conf_Tokens.h" - " cat Svc_Conf.tab.h >> Svc_Conf_Tokens.h" + " echo \/\/ '$$I''d:$$' >Svc_Conf_Tokens.h" + " echo '#ifndef BISON_SVC_CONF_TAB_H' >>Svc_Conf_Tokens.h" // Inclusion protection macros + " echo '# define BISON_SVC_CONF_TAB_H' >>Svc_Conf_Tokens.h" // ... same ... + " echo '# define ACE_YYSTYPE_IS_DECLARED 1' >>Svc_Conf_Tokens.h" // Don't use Svc_Conf_y.cpp's + " sed -e 's/yy/ace_yy/g' \\" + " -e 's/YY/ACE_YY/g' <Svc_Conf.tab.h >>Svc_Conf_Tokens.h" + " echo '#endif \/\* ifndef BISON_SVC_CONF_TAB_H \*\/' >>Svc_Conf_Tokens.h" " $(RM) -f /tmp/$@ Svc_Conf.tab.c Svc_Conf.tab.h Svc_Conf_y.cpp.orig" "else" " @echo 'ERROR: You must use bison 1.35 or higher to process this file'" " @/bin/false" "endif" + } } diff --git a/bin/tao_orb_tests.lst b/bin/tao_orb_tests.lst index f76dfc6237f..cd95ec64cc9 100644 --- a/bin/tao_orb_tests.lst +++ b/bin/tao_orb_tests.lst @@ -9,6 +9,14 @@ # # NOTE: This file contains tests only for TAO's ORB. Please do not # include things like performance-tests, and examples here. + +TAO/tests/ORB_Local_Config/Bunch/run_test.pl: !MINIMUM !ST +TAO/tests/ORB_Local_Config/Limits/run_test.pl: !MINIMUM !ST +TAO/tests/ORB_Local_Config/Separation/run_test.pl: !MINIMUM !ST +TAO/tests/ORB_Local_Config/Service_Dependency/run_test.pl: !MINIMUM !ST +TAO/tests/ORB_Local_Config/Shared/run_test.pl: !MINIMUM !ST +TAO/tests/ORB_Local_Config/Simple/run_test.pl: !MINIMUM !ST +TAO/tests/ORB_Local_Config/Two_DLL_ORB/run_test.pl: !MINIMUM !ST TAO/tests/Param_Test/run_test.pl: !MINIMUM TAO/tests/Param_Test/run_test_dii.pl: !MINIMUM TAO/tests/AMI/run_test.pl: !MINIMUM |