summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjeliazkov_i <jeliazkov_i@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2006-04-26 21:21:54 +0000
committerjeliazkov_i <jeliazkov_i@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2006-04-26 21:21:54 +0000
commitb0cf9bd42665d557f4522c8fa45d5dca4d586442 (patch)
treea9b9968661496861e290f57b51d11264f75c299f
parentd4a143a940ad9f1a81e1959e3fff7105509660ab (diff)
downloadATCD-b0cf9bd42665d557f4522c8fa45d5dca4d586442.tar.gz
ChangeLogTag: Wed Apr 26 20:21:49 UTC 2006 Iliyan Jeliazkov <iliyan@ociweb.com>
-rw-r--r--ChangeLog358
-rw-r--r--TAO/ChangeLog243
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp2
-rw-r--r--TAO/tao/Codeset/Codeset_Manager_i.cpp5
-rw-r--r--TAO/tao/Codeset/Codeset_Manager_i.h10
-rw-r--r--TAO/tao/DLL_Parser.cpp6
-rw-r--r--TAO/tao/ORB.cpp64
-rw-r--r--TAO/tao/ORB_Core.cpp328
-rw-r--r--TAO/tao/ORB_Core.h7
-rw-r--r--TAO/tao/ORB_Core.i40
-rw-r--r--TAO/tao/PI/ORBInitializer_Registry_Impl.cpp65
-rw-r--r--TAO/tao/PI/ORBInitializer_Registry_Impl.h11
-rw-r--r--TAO/tao/PI/PI.cpp58
-rw-r--r--TAO/tao/PI/PI.h16
-rw-r--r--TAO/tao/PI/PolicyFactory_Loader.cpp9
-rw-r--r--TAO/tao/PI/PolicyFactory_Loader.h6
-rw-r--r--TAO/tao/Parser_Registry.cpp3
-rw-r--r--TAO/tao/PortableServer/Root_POA.cpp3
-rw-r--r--TAO/tao/TAO_Internal.cpp632
-rw-r--r--TAO/tao/TAO_Internal.h21
-rw-r--r--TAO/tao/default_resource.cpp17
-rw-r--r--TAO/tao/default_resource.h7
-rw-r--r--TAO/tests/DLL_ORB/Test_Client_Module.cpp56
-rw-r--r--TAO/tests/DLL_ORB/Test_Server_Module.cpp40
-rw-r--r--TAO/tests/ORB_Local_Config/Bunch/Bunch.mpc15
-rw-r--r--TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.confbin0 -> 2006 bytes
-rw-r--r--TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf.xmlbin0 -> 2874 bytes
-rw-r--r--TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.confbin0 -> 4008 bytes
-rw-r--r--TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf.xmlbin0 -> 5744 bytes
-rw-r--r--TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.conf19
-rw-r--r--TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.conf.xml27
-rw-r--r--TAO/tests/ORB_Local_Config/Bunch/Test.cpp315
-rwxr-xr-xTAO/tests/ORB_Local_Config/Bunch/run_test.pl49
-rw-r--r--TAO/tests/ORB_Local_Config/Limits/Limits.mpc15
-rw-r--r--TAO/tests/ORB_Local_Config/Limits/Test.cpp21
-rwxr-xr-xTAO/tests/ORB_Local_Config/Limits/run_test.pl49
-rw-r--r--TAO/tests/ORB_Local_Config/ORB_Local_Config.mwc14
-rw-r--r--TAO/tests/ORB_Local_Config/README50
-rw-r--r--TAO/tests/ORB_Local_Config/Separation/Separation.mpc14
-rw-r--r--TAO/tests/ORB_Local_Config/Separation/Test.cpp55
-rwxr-xr-xTAO/tests/ORB_Local_Config/Separation/run_test.pl49
-rw-r--r--TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.cpp196
-rw-r--r--TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL.h69
-rw-r--r--TAO/tests/ORB_Local_Config/Service_Dependency/Service_Config_DLL_Export.h38
-rw-r--r--TAO/tests/ORB_Local_Config/Service_Dependency/Service_Dependency.mpc28
-rw-r--r--TAO/tests/ORB_Local_Config/Service_Dependency/Test.cpp66
-rwxr-xr-xTAO/tests/ORB_Local_Config/Service_Dependency/run_test.pl49
-rw-r--r--TAO/tests/ORB_Local_Config/Shared/Shared.mpc14
-rw-r--r--TAO/tests/ORB_Local_Config/Shared/Test.cpp50
-rwxr-xr-xTAO/tests/ORB_Local_Config/Shared/run_test.pl49
-rw-r--r--TAO/tests/ORB_Local_Config/Simple/Simple.mpc15
-rw-r--r--TAO/tests/ORB_Local_Config/Simple/Test.cpp39
-rwxr-xr-xTAO/tests/ORB_Local_Config/Simple/run_test.pl49
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.cpp134
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL.h112
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/ORB_DLL_Export.h54
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test.conf5
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/Service_Config_ORB_Test2.conf1
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test.cpp34
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test.idl20
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test_i.cpp25
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test_i.h33
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/Two_DLL_ORB.mpc63
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/client.cpp110
-rwxr-xr-xTAO/tests/ORB_Local_Config/Two_DLL_ORB/run_test.pl49
-rw-r--r--TAO/tests/ORB_Local_Config/Two_DLL_ORB/server.cpp129
-rw-r--r--TAO/tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.cpp58
-rw-r--r--TAO/tests/ORB_Local_Config/lib/Service_Configuration_Per_ORB.h82
-rw-r--r--TAO/tests/ORB_Local_Config/lib/lib.mpc15
-rwxr-xr-xTAO/tests/ORB_Local_Config/run_tests_all.pl62
-rw-r--r--ace/ACE.cpp3
-rw-r--r--ace/DLL.cpp27
-rw-r--r--ace/DLL.h10
-rw-r--r--ace/DLL_Manager.cpp106
-rw-r--r--ace/Dynamic_Service.cpp12
-rw-r--r--ace/Dynamic_Service.h18
-rw-r--r--ace/Dynamic_Service.inl10
-rw-r--r--ace/Dynamic_Service_Base.cpp69
-rw-r--r--ace/Dynamic_Service_Base.h25
-rw-r--r--ace/Dynamic_Service_Dependency.cpp52
-rw-r--r--ace/Dynamic_Service_Dependency.h73
-rw-r--r--ace/Dynamic_Service_Dependency.inl20
-rw-r--r--ace/Global_Macros.h4
-rw-r--r--ace/Parse_Node.cpp152
-rw-r--r--ace/Parse_Node.h169
-rw-r--r--ace/Service_Config.cpp961
-rw-r--r--ace/Service_Config.h237
-rw-r--r--ace/Service_Config.inl94
-rw-r--r--ace/Service_Gestalt.cpp1108
-rw-r--r--ace/Service_Gestalt.h440
-rw-r--r--ace/Service_Gestalt.inl64
-rw-r--r--ace/Service_Object.cpp21
-rw-r--r--ace/Service_Object.h19
-rw-r--r--ace/Service_Object.inl5
-rw-r--r--ace/Service_Repository.cpp140
-rw-r--r--ace/Service_Repository.h13
-rw-r--r--ace/Service_Types.cpp20
-rw-r--r--ace/Svc_Conf.h104
-rw-r--r--ace/Svc_Conf.y88
-rw-r--r--ace/Svc_Conf_Param.h140
-rw-r--r--ace/Svc_Conf_Tokens.h94
-rw-r--r--ace/Svc_Conf_y.cpp1967
-rw-r--r--ace/svcconf.mpb24
-rw-r--r--bin/tao_orb_tests.lst8
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
new file mode 100644
index 00000000000..e5d36fd215f
--- /dev/null
+++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf
Binary files differ
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
new file mode 100644
index 00000000000..1d75d2763c0
--- /dev/null
+++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.UTF-16.conf.xml
Binary files differ
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
new file mode 100644
index 00000000000..a36db0600c9
--- /dev/null
+++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf
Binary files differ
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
new file mode 100644
index 00000000000..88e7c26e8eb
--- /dev/null
+++ b/TAO/tests/ORB_Local_Config/Bunch/Service_Config_Test.WCHAR_T.conf.xml
Binary files differ
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