summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2006-04-27 20:45:26 +0000
committernobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2006-04-27 20:45:26 +0000
commit317d8c1ce78436f0107f056418c0c5f5b4231069 (patch)
treed432edf6760c4d9b42f941ba9453db96cd3fa75e
parent664244e804da11536f2712a61116204e8042f312 (diff)
downloadATCD-317d8c1ce78436f0107f056418c0c5f5b4231069.tar.gz
This commit was manufactured by cvs2svn to create branch
'oci_dave_wchar_refactor_branch'.
-rw-r--r--TAO/tao/EndpointPolicy/EndpointPolicyC.cpp351
-rw-r--r--TAO/tao/EndpointPolicy/EndpointPolicyC.h383
-rw-r--r--TAO/tao/EndpointPolicy/Endpoint_Acceptor_Filter.cpp156
-rw-r--r--TAO/tao/EndpointPolicy/Endpoint_Value_Impl.cpp16
-rw-r--r--TAO/tao/EndpointPolicy/Endpoint_Value_Impl.h61
-rw-r--r--TAO/tao/PortableServer/POAManagerFactory.cpp162
-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.cpp19
-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.cpp37
-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.cpp32
-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/Dynamic_Service_Dependency.cpp48
-rw-r--r--ace/Dynamic_Service_Dependency.h70
-rw-r--r--ace/Service_Gestalt.cpp1114
-rw-r--r--ace/Service_Gestalt.h438
-rw-r--r--ace/Service_Gestalt.inl64
-rw-r--r--ace/Svc_Conf_Param.h140
-rw-r--r--tests/Sendfile_Test.cpp316
59 files changed, 5653 insertions, 0 deletions
diff --git a/TAO/tao/EndpointPolicy/EndpointPolicyC.cpp b/TAO/tao/EndpointPolicy/EndpointPolicyC.cpp
new file mode 100644
index 00000000000..1cfa58e8522
--- /dev/null
+++ b/TAO/tao/EndpointPolicy/EndpointPolicyC.cpp
@@ -0,0 +1,351 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// **** Code generated by the The ACE ORB (TAO) IDL Compiler ****
+// TAO and the TAO IDL Compiler have been developed by:
+// Center for Distributed Object Computing
+// Washington University
+// St. Louis, MO
+// USA
+// http://www.cs.wustl.edu/~schmidt/doc-center.html
+// and
+// Distributed Object Computing Laboratory
+// University of California at Irvine
+// Irvine, CA
+// USA
+// http://doc.ece.uci.edu/
+// and
+// Institute for Software Integrated Systems
+// Vanderbilt University
+// Nashville, TN
+// USA
+// http://www.isis.vanderbilt.edu/
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
+// TAO_IDL - Generated from
+// be/be_codegen.cpp:282
+
+
+#include "EndpointPolicyC.h"
+#include "tao/CDR.h"
+#include "ace/OS_NS_string.h"
+
+// TAO_IDL - Generated from
+// be/be_visitor_arg_traits.cpp:71
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+
+
+// Arg traits specializations.
+namespace TAO
+{
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+
+
+// TAO_IDL - Generated from
+// be/be_visitor_interface/interface_cs.cpp:60
+
+// Traits specializations for EndpointPolicy::EndpointValueBase.
+
+EndpointPolicy::EndpointValueBase_ptr
+TAO::Objref_Traits<EndpointPolicy::EndpointValueBase>::duplicate (
+ EndpointPolicy::EndpointValueBase_ptr p
+ )
+{
+ return EndpointPolicy::EndpointValueBase::_duplicate (p);
+}
+
+void
+TAO::Objref_Traits<EndpointPolicy::EndpointValueBase>::release (
+ EndpointPolicy::EndpointValueBase_ptr p
+ )
+{
+ ::CORBA::release (p);
+}
+
+EndpointPolicy::EndpointValueBase_ptr
+TAO::Objref_Traits<EndpointPolicy::EndpointValueBase>::nil (void)
+{
+ return EndpointPolicy::EndpointValueBase::_nil ();
+}
+
+::CORBA::Boolean
+TAO::Objref_Traits<EndpointPolicy::EndpointValueBase>::marshal (
+ const EndpointPolicy::EndpointValueBase_ptr p,
+ TAO_OutputCDR & cdr
+ )
+{
+ return ::CORBA::Object::marshal (p, cdr);
+}
+
+EndpointPolicy::EndpointValueBase::EndpointValueBase (void)
+{}
+
+EndpointPolicy::EndpointValueBase::~EndpointValueBase (void)
+{}
+
+EndpointPolicy::EndpointValueBase_ptr
+EndpointPolicy::EndpointValueBase::_narrow (
+ ::CORBA::Object_ptr _tao_objref
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ return EndpointValueBase::_duplicate (
+ dynamic_cast<EndpointValueBase_ptr> (_tao_objref)
+ );
+}
+
+EndpointPolicy::EndpointValueBase_ptr
+EndpointPolicy::EndpointValueBase::_unchecked_narrow (
+ ::CORBA::Object_ptr _tao_objref
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ return EndpointValueBase::_duplicate (
+ dynamic_cast<EndpointValueBase_ptr> (_tao_objref)
+ );
+}
+
+EndpointPolicy::EndpointValueBase_ptr
+EndpointPolicy::EndpointValueBase::_duplicate (EndpointValueBase_ptr obj)
+{
+ if (! ::CORBA::is_nil (obj))
+ {
+ obj->_add_ref ();
+ }
+
+ return obj;
+}
+
+void
+EndpointPolicy::EndpointValueBase::_tao_release (EndpointValueBase_ptr obj)
+{
+ ::CORBA::release (obj);
+}
+
+::CORBA::Boolean
+EndpointPolicy::EndpointValueBase::_is_a (
+ const char *value
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ if (
+ !ACE_OS::strcmp (
+ value,
+ "IDL:EndpointPolicy/EndpointValueBase:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/CORBA/LocalObject:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/CORBA/Object:1.0"
+ )
+ )
+ {
+ return true; // success using local knowledge
+ }
+ else
+ {
+ return false;
+ }
+}
+
+const char* EndpointPolicy::EndpointValueBase::_interface_repository_id (void) const
+{
+ return "IDL:EndpointPolicy/EndpointValueBase:1.0";
+}
+
+::CORBA::Boolean
+EndpointPolicy::EndpointValueBase::marshal (TAO_OutputCDR &)
+{
+ return false;
+}
+
+// TAO_IDL - Generated from
+// be/be_visitor_sequence/sequence_cs.cpp:65
+
+#if !defined (_ENDPOINTPOLICY_ENDPOINTLIST_CS_)
+#define _ENDPOINTPOLICY_ENDPOINTLIST_CS_
+
+EndpointPolicy::EndpointList::EndpointList (void)
+{}
+
+EndpointPolicy::EndpointList::EndpointList (
+ ::CORBA::ULong max
+ )
+ : TAO::unbounded_object_reference_sequence<
+ EndpointValueBase,
+ EndpointValueBase_var
+ >
+ (max)
+{}
+
+EndpointPolicy::EndpointList::EndpointList (
+ ::CORBA::ULong max,
+ ::CORBA::ULong length,
+ EndpointPolicy::EndpointValueBase_ptr * buffer,
+ ::CORBA::Boolean release
+ )
+ : TAO::unbounded_object_reference_sequence<
+ EndpointValueBase,
+ EndpointValueBase_var
+ >
+ (max, length, buffer, release)
+{}
+
+EndpointPolicy::EndpointList::EndpointList (
+ const EndpointList &seq
+ )
+ : TAO::unbounded_object_reference_sequence<
+ EndpointValueBase,
+ EndpointValueBase_var
+ >
+ (seq)
+{}
+
+EndpointPolicy::EndpointList::~EndpointList (void)
+{}
+
+void EndpointPolicy::EndpointList::_tao_any_destructor (
+ void * _tao_void_pointer
+ )
+{
+ EndpointList * _tao_tmp_pointer =
+ static_cast<EndpointList *> (_tao_void_pointer);
+ delete _tao_tmp_pointer;
+}
+
+#endif /* end #if !defined */
+
+// TAO_IDL - Generated from
+// be/be_visitor_interface/interface_cs.cpp:60
+
+// Traits specializations for EndpointPolicy::Policy.
+
+EndpointPolicy::Policy_ptr
+TAO::Objref_Traits<EndpointPolicy::Policy>::duplicate (
+ EndpointPolicy::Policy_ptr p
+ )
+{
+ return EndpointPolicy::Policy::_duplicate (p);
+}
+
+void
+TAO::Objref_Traits<EndpointPolicy::Policy>::release (
+ EndpointPolicy::Policy_ptr p
+ )
+{
+ ::CORBA::release (p);
+}
+
+EndpointPolicy::Policy_ptr
+TAO::Objref_Traits<EndpointPolicy::Policy>::nil (void)
+{
+ return EndpointPolicy::Policy::_nil ();
+}
+
+::CORBA::Boolean
+TAO::Objref_Traits<EndpointPolicy::Policy>::marshal (
+ const EndpointPolicy::Policy_ptr p,
+ TAO_OutputCDR & cdr
+ )
+{
+ return ::CORBA::Object::marshal (p, cdr);
+}
+
+EndpointPolicy::Policy::Policy (void)
+{}
+
+EndpointPolicy::Policy::~Policy (void)
+{}
+
+EndpointPolicy::Policy_ptr
+EndpointPolicy::Policy::_narrow (
+ ::CORBA::Object_ptr _tao_objref
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ return Policy::_duplicate (
+ dynamic_cast<Policy_ptr> (_tao_objref)
+ );
+}
+
+EndpointPolicy::Policy_ptr
+EndpointPolicy::Policy::_unchecked_narrow (
+ ::CORBA::Object_ptr _tao_objref
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ return Policy::_duplicate (
+ dynamic_cast<Policy_ptr> (_tao_objref)
+ );
+}
+
+EndpointPolicy::Policy_ptr
+EndpointPolicy::Policy::_duplicate (Policy_ptr obj)
+{
+ if (! ::CORBA::is_nil (obj))
+ {
+ obj->_add_ref ();
+ }
+
+ return obj;
+}
+
+void
+EndpointPolicy::Policy::_tao_release (Policy_ptr obj)
+{
+ ::CORBA::release (obj);
+}
+
+::CORBA::Boolean
+EndpointPolicy::Policy::_is_a (
+ const char *value
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ if (
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/CORBA/Policy:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:EndpointPolicy/Policy:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/CORBA/LocalObject:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/CORBA/Object:1.0"
+ )
+ )
+ {
+ return true; // success using local knowledge
+ }
+ else
+ {
+ return false;
+ }
+}
+
+const char* EndpointPolicy::Policy::_interface_repository_id (void) const
+{
+ return "IDL:EndpointPolicy/Policy:1.0";
+}
+
+::CORBA::Boolean
+EndpointPolicy::Policy::marshal (TAO_OutputCDR &)
+{
+ return false;
+}
diff --git a/TAO/tao/EndpointPolicy/EndpointPolicyC.h b/TAO/tao/EndpointPolicy/EndpointPolicyC.h
new file mode 100644
index 00000000000..6993b9640bd
--- /dev/null
+++ b/TAO/tao/EndpointPolicy/EndpointPolicyC.h
@@ -0,0 +1,383 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// **** Code generated by the The ACE ORB (TAO) IDL Compiler ****
+// TAO and the TAO IDL Compiler have been developed by:
+// Center for Distributed Object Computing
+// Washington University
+// St. Louis, MO
+// USA
+// http://www.cs.wustl.edu/~schmidt/doc-center.html
+// and
+// Distributed Object Computing Laboratory
+// University of California at Irvine
+// Irvine, CA
+// USA
+// http://doc.ece.uci.edu/
+// and
+// Institute for Software Integrated Systems
+// Vanderbilt University
+// Nashville, TN
+// USA
+// http://www.isis.vanderbilt.edu/
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
+// TAO_IDL - Generated from
+// be/be_codegen.cpp:154
+
+#ifndef _TAO_IDL_ENDPOINTPOLICYC_H_
+#define _TAO_IDL_ENDPOINTPOLICYC_H_
+
+#include /**/ "ace/pre.h"
+
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/EndpointPolicy/EndpointPolicy_Export.h"
+#include "tao/ORB.h"
+#include "tao/SystemException.h"
+#include "tao/Environment.h"
+#include "tao/Object.h"
+#include "tao/Sequence_T.h"
+#include "tao/Objref_VarOut_T.h"
+#include "tao/Seq_Var_T.h"
+#include "tao/Seq_Out_T.h"
+#include "tao/Versioned_Namespace.h"
+
+#include "tao/PolicyC.h"
+#include "tao/EndpointPolicy/EndpointPolicyTypeC.h"
+
+#if defined (TAO_EXPORT_MACRO)
+#undef TAO_EXPORT_MACRO
+#endif
+#define TAO_EXPORT_MACRO TAO_EndpointPolicy_Export
+
+// TAO_IDL - Generated from
+// be/be_visitor_module/module_ch.cpp:49
+
+namespace EndpointPolicy
+{
+
+ // TAO_IDL - Generated from
+ // be/be_interface.cpp:640
+
+#if !defined (_ENDPOINTPOLICY_ENDPOINTVALUEBASE__VAR_OUT_CH_)
+#define _ENDPOINTPOLICY_ENDPOINTVALUEBASE__VAR_OUT_CH_
+
+ class EndpointValueBase;
+ typedef EndpointValueBase *EndpointValueBase_ptr;
+
+ typedef
+ TAO_Objref_Var_T<
+ EndpointValueBase
+ >
+ EndpointValueBase_var;
+
+ typedef
+ TAO_Objref_Out_T<
+ EndpointValueBase
+ >
+ EndpointValueBase_out;
+
+#endif /* end #if !defined */
+
+ // TAO_IDL - Generated from
+ // be/be_visitor_interface/interface_ch.cpp:54
+
+#if !defined (_ENDPOINTPOLICY_ENDPOINTVALUEBASE_CH_)
+#define _ENDPOINTPOLICY_ENDPOINTVALUEBASE_CH_
+
+ class TAO_EndpointPolicy_Export EndpointValueBase
+ : public virtual ::CORBA::Object
+ {
+ public:
+ typedef EndpointValueBase_ptr _ptr_type;
+ typedef EndpointValueBase_var _var_type;
+
+ // The static operations.
+ static EndpointValueBase_ptr _duplicate (EndpointValueBase_ptr obj);
+
+ static void _tao_release (EndpointValueBase_ptr obj);
+
+ static EndpointValueBase_ptr _narrow (
+ ::CORBA::Object_ptr obj
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ static EndpointValueBase_ptr _unchecked_narrow (
+ ::CORBA::Object_ptr obj
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ static EndpointValueBase_ptr _nil (void)
+ {
+ return static_cast<EndpointValueBase_ptr> (0);
+ }
+
+
+
+ // TAO_IDL - Generated from
+ // be/be_visitor_operation/operation_ch.cpp:46
+
+ virtual ::CORBA::ULong protocol_tag (
+ ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ ::CORBA::SystemException
+ )) = 0;
+
+ // TAO_IDL - Generated from
+ // be/be_visitor_interface/interface_ch.cpp:210
+
+ virtual ::CORBA::Boolean _is_a (
+ const char *type_id
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ virtual const char* _interface_repository_id (void) const;
+ virtual ::CORBA::Boolean marshal (TAO_OutputCDR &cdr);
+
+ protected:
+ // Abstract or local interface only.
+ EndpointValueBase (void);
+
+ virtual ~EndpointValueBase (void);
+
+ private:
+ // Private and unimplemented for concrete interfaces.
+ EndpointValueBase (const EndpointValueBase &);
+
+ void operator= (const EndpointValueBase &);
+ };
+
+#endif /* end #if !defined */
+
+ // TAO_IDL - Generated from
+ // be/be_visitor_sequence/sequence_ch.cpp:101
+
+#if !defined (_ENDPOINTPOLICY_ENDPOINTLIST_CH_)
+#define _ENDPOINTPOLICY_ENDPOINTLIST_CH_
+
+ class EndpointList;
+
+ typedef
+ TAO_VarSeq_Var_T<
+ EndpointList
+ >
+ EndpointList_var;
+
+ typedef
+ TAO_Seq_Out_T<
+ EndpointList
+ >
+ EndpointList_out;
+
+ class TAO_EndpointPolicy_Export EndpointList
+ : public
+ TAO::unbounded_object_reference_sequence<
+ EndpointValueBase,
+ EndpointValueBase_var
+ >
+ {
+ public:
+ EndpointList (void);
+ EndpointList ( ::CORBA::ULong max);
+ EndpointList (
+ ::CORBA::ULong max,
+ ::CORBA::ULong length,
+ EndpointValueBase_ptr* buffer,
+ ::CORBA::Boolean release = false
+ );
+ EndpointList (const EndpointList &);
+ ~EndpointList (void);
+
+ static void _tao_any_destructor (void *);
+
+ typedef EndpointList_var _var_type;
+ };
+
+#endif /* end #if !defined */
+
+ // TAO_IDL - Generated from
+ // be/be_interface.cpp:640
+
+#if !defined (_ENDPOINTPOLICY_POLICY__VAR_OUT_CH_)
+#define _ENDPOINTPOLICY_POLICY__VAR_OUT_CH_
+
+ class Policy;
+ typedef Policy *Policy_ptr;
+
+ typedef
+ TAO_Objref_Var_T<
+ Policy
+ >
+ Policy_var;
+
+ typedef
+ TAO_Objref_Out_T<
+ Policy
+ >
+ Policy_out;
+
+#endif /* end #if !defined */
+
+ // TAO_IDL - Generated from
+ // be/be_visitor_interface/interface_ch.cpp:54
+
+#if !defined (_ENDPOINTPOLICY_POLICY_CH_)
+#define _ENDPOINTPOLICY_POLICY_CH_
+
+ class TAO_EndpointPolicy_Export Policy
+ : public virtual ::CORBA::Policy
+ {
+ public:
+ typedef Policy_ptr _ptr_type;
+ typedef Policy_var _var_type;
+
+ // The static operations.
+ static Policy_ptr _duplicate (Policy_ptr obj);
+
+ static void _tao_release (Policy_ptr obj);
+
+ static Policy_ptr _narrow (
+ ::CORBA::Object_ptr obj
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ static Policy_ptr _unchecked_narrow (
+ ::CORBA::Object_ptr obj
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ static Policy_ptr _nil (void)
+ {
+ return static_cast<Policy_ptr> (0);
+ }
+
+
+
+ // TAO_IDL - Generated from
+ // be/be_visitor_operation/operation_ch.cpp:46
+
+ virtual ::EndpointPolicy::EndpointList * value (
+ ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ ::CORBA::SystemException
+ )) = 0;
+
+ // TAO_IDL - Generated from
+ // be/be_visitor_operation/operation_ch.cpp:46
+
+ virtual ::CORBA::Policy_ptr copy (
+ ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ ::CORBA::SystemException
+ )) = 0;
+
+ // TAO_IDL - Generated from
+ // be/be_visitor_operation/operation_ch.cpp:46
+
+ virtual void destroy (
+ ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ ::CORBA::SystemException
+ )) = 0;
+
+ // TAO_IDL - Generated from
+ // be/be_visitor_interface/interface_ch.cpp:210
+
+ virtual ::CORBA::Boolean _is_a (
+ const char *type_id
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ virtual const char* _interface_repository_id (void) const;
+ virtual ::CORBA::Boolean marshal (TAO_OutputCDR &cdr);
+
+ protected:
+ // Abstract or local interface only.
+ Policy (void);
+
+ virtual ~Policy (void);
+
+ private:
+ // Private and unimplemented for concrete interfaces.
+ Policy (const Policy &);
+
+ void operator= (const Policy &);
+ };
+
+#endif /* end #if !defined */
+
+// TAO_IDL - Generated from
+// be/be_visitor_module/module_ch.cpp:78
+
+} // module EndpointPolicy
+
+// TAO_IDL - Generated from
+// be/be_visitor_traits.cpp:63
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+
+
+// Traits specializations.
+namespace TAO
+{
+
+#if !defined (_ENDPOINTPOLICY_ENDPOINTVALUEBASE__TRAITS_)
+#define _ENDPOINTPOLICY_ENDPOINTVALUEBASE__TRAITS_
+
+ template<>
+ struct TAO_EndpointPolicy_Export Objref_Traits< ::EndpointPolicy::EndpointValueBase>
+ {
+ static ::EndpointPolicy::EndpointValueBase_ptr duplicate (
+ ::EndpointPolicy::EndpointValueBase_ptr
+ );
+ static void release (
+ ::EndpointPolicy::EndpointValueBase_ptr
+ );
+ static ::EndpointPolicy::EndpointValueBase_ptr nil (void);
+ static ::CORBA::Boolean marshal (
+ const ::EndpointPolicy::EndpointValueBase_ptr p,
+ TAO_OutputCDR & cdr
+ );
+ };
+
+#endif /* end #if !defined */
+
+#if !defined (_ENDPOINTPOLICY_POLICY__TRAITS_)
+#define _ENDPOINTPOLICY_POLICY__TRAITS_
+
+ template<>
+ struct TAO_EndpointPolicy_Export Objref_Traits< ::EndpointPolicy::Policy>
+ {
+ static ::EndpointPolicy::Policy_ptr duplicate (
+ ::EndpointPolicy::Policy_ptr
+ );
+ static void release (
+ ::EndpointPolicy::Policy_ptr
+ );
+ static ::EndpointPolicy::Policy_ptr nil (void);
+ static ::CORBA::Boolean marshal (
+ const ::EndpointPolicy::Policy_ptr p,
+ TAO_OutputCDR & cdr
+ );
+ };
+
+#endif /* end #if !defined */
+}
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* ifndef */
diff --git a/TAO/tao/EndpointPolicy/Endpoint_Acceptor_Filter.cpp b/TAO/tao/EndpointPolicy/Endpoint_Acceptor_Filter.cpp
new file mode 100644
index 00000000000..b44df235724
--- /dev/null
+++ b/TAO/tao/EndpointPolicy/Endpoint_Acceptor_Filter.cpp
@@ -0,0 +1,156 @@
+// @(#) $Id$
+
+#include "tao/EndpointPolicy/Endpoint_Acceptor_Filter.h"
+#include "tao/EndpointPolicy/EndpointPolicyC.h"
+#include "tao/EndpointPolicy/Endpoint_Value_Impl.h"
+
+#include "tao/Transport_Acceptor.h"
+#include "tao/MProfile.h"
+#include "tao/IIOP_Profile.h"
+
+ACE_RCSID(EndpointPolicy,
+ Endpoint_Acceptor_Filter,
+ "$Id$")
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_Endpoint_Acceptor_Filter::TAO_Endpoint_Acceptor_Filter (EndpointPolicy::Policy_ptr p)
+: endpoints_(p->value())
+{
+}
+
+int
+TAO_Endpoint_Acceptor_Filter::fill_profile (const TAO::ObjectKey &object_key,
+ TAO_MProfile &mprofile,
+ TAO_Acceptor **acceptors_begin,
+ TAO_Acceptor **acceptors_end,
+ CORBA::Short priority)
+{
+ CORBA::ULong num_endpoints = endpoints_->length ();
+
+ for (TAO_Acceptor** acceptor = acceptors_begin;
+ acceptor != acceptors_end;
+ ++acceptor)
+ {
+ bool tagfound = false;
+ for (CORBA::ULong epx = 0; !tagfound && epx < num_endpoints; epx++)
+ {
+ tagfound = (*acceptor)->tag () == endpoints_[epx]->protocol_tag();
+ }
+ if (!tagfound)
+ continue;
+
+ if ((*acceptor)->create_profile (object_key,
+ mprofile,
+ priority) == -1)
+ return -1;
+ }
+
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("(%P|%t) EndpointPolicy filtering acceptors")
+ ACE_TEXT(" - mprofile has %d profiles,")
+ ACE_TEXT(" endpoint list has %d entries\n"),
+ mprofile.profile_count(), num_endpoints));
+
+ for (TAO_PHandle pfile_ndx = 0;
+ pfile_ndx < mprofile.profile_count ();
+ ++pfile_ndx)
+ {
+ TAO_Profile *pfile =mprofile.get_profile (pfile_ndx);
+
+ TAO_Endpoint *ep_in_pfile = pfile->endpoint ();
+
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("(%P|%t) Testing profile %d - ")
+ ACE_TEXT("it contains %d endpoints\n"),
+ pfile_ndx, pfile->endpoint_count()));
+
+ bool first_endpoint = true;
+ // Iterate the endpoints in the profile.
+ while (ep_in_pfile != 0 && pfile->endpoint_count() > 0)
+ {
+ // Iterate the endpoints in the endpoint policy to see if the endpoint
+ // in the profile matches.
+ CORBA::ULong ep_ndx = 0;
+ bool epmatch = false;
+ for (ep_ndx = 0; !epmatch && ep_ndx < num_endpoints; ++ep_ndx)
+ {
+ if (endpoints_[ep_ndx]->protocol_tag() != pfile->tag())
+ continue;
+
+ const EndpointPolicy::EndpointValueBase *evb =
+ endpoints_[ep_ndx];
+
+ const TAO_Endpoint_Value_Impl *evi =
+ dynamic_cast <const TAO_Endpoint_Value_Impl*>(evb);
+
+ epmatch = evi->is_equivalent(ep_in_pfile);
+ }
+
+ // The endpoint in profile does not match the endpoint specified in
+ // Endpoint policy, now remove the endpoint from the profile.
+ if (!epmatch)
+ {
+ //Get next endpoint before removing current one.
+ TAO_Endpoint * next = ep_in_pfile->next ();
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) EndpointPolicy filter ")
+ ACE_TEXT ("removing endpoint\n")));
+ pfile->remove_generic_endpoint (ep_in_pfile);
+ ep_in_pfile = first_endpoint ? pfile->endpoint() : next;
+ }
+ else
+ {
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) EndpointPolicy filter ")
+ ACE_TEXT ("Endpoint matched policy value\n")));
+ ep_in_pfile = ep_in_pfile->next();
+ first_endpoint = false;
+ }
+ }
+ // Remove the profiles that have no endpoints match the endpoints in
+ // endpoint policy.
+ if (pfile->endpoint_count () == 0)
+ {
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("(%P|%t) EndpointPolicy filter ")
+ ACE_TEXT("removing profile\n")));
+ mprofile.remove_profile (pfile);
+ --pfile_ndx; // step back one, we've just shifted the profile list.
+ }
+ else
+ {
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("(%P|%t) EndpointPolicy filter ")
+ ACE_TEXT("profile retained with %d endpoints\n"),
+ pfile->endpoint_count()));
+ }
+ }
+
+ if (mprofile.profile_count () == 0) {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("(%P|%t) EndpointPolicy filter ")
+ ACE_TEXT("eliminated all profiles\n")));
+
+ return -1;
+ }
+
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("(%P|%t) EndpointPolicy filter returning mprofile ")
+ ACE_TEXT("with %d profiles\n"),
+ mprofile.profile_count()));
+
+ return 0;
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/EndpointPolicy/Endpoint_Value_Impl.cpp b/TAO/tao/EndpointPolicy/Endpoint_Value_Impl.cpp
new file mode 100644
index 00000000000..cf81937bfd6
--- /dev/null
+++ b/TAO/tao/EndpointPolicy/Endpoint_Value_Impl.cpp
@@ -0,0 +1,16 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file Endpoint_Value_Impl.cpp
+ *
+ * $Id$
+ *
+ * @author Phil Mesnier <mesnier_p@ociweb.com>
+ */
+//=============================================================================
+
+#include "tao/EndpointPolicy/Endpoint_Value_Impl.h"
+
+TAO_Endpoint_Value_Impl::~TAO_Endpoint_Value_Impl()
+{
+}
diff --git a/TAO/tao/EndpointPolicy/Endpoint_Value_Impl.h b/TAO/tao/EndpointPolicy/Endpoint_Value_Impl.h
new file mode 100644
index 00000000000..4151f19f572
--- /dev/null
+++ b/TAO/tao/EndpointPolicy/Endpoint_Value_Impl.h
@@ -0,0 +1,61 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file Endpoint_Value_Impl.h
+ *
+ * $Id$
+ *
+ * Implementation of the IIOP-Specific endpoint policy value
+ *
+ * @author Phil Mesnier <mesnier_p@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef _TAO_ENDPOINT_VALUE_IMPL_H_
+#define _TAO_ENDPOINT_VALUE_IMPL_H_
+
+#include /**/ "ace/pre.h"
+
+#include "tao/Basic_Types.h"
+#include "tao/EndpointPolicy/EndpointPolicy_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class TAO_Endpoint;
+class TAO_Acceptor;
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class Endpoint_Value_Impl
+ *
+ * @brief Abstract base class to be mixed in to servants of protocol
+ * specific EndpointValues.
+ *
+ * This inteface defines the methods necessary for the
+ * protocol-specific endpoint value to be used with the endpoint
+ * policy
+ */
+
+class TAO_EndpointPolicy_Export TAO_Endpoint_Value_Impl
+{
+public:
+ virtual ~TAO_Endpoint_Value_Impl(void);
+
+ /// This method is used to compare a candidate IOR endpoint with the
+ /// endpoint defined by this policy value.
+ virtual CORBA::Boolean is_equivalent (const TAO_Endpoint * ) const = 0;
+
+ /// This method is used by the framework to validate that an
+ /// acceptor is available to produce an endpoint required by at
+ /// least one of the endpoint policies values.
+ virtual CORBA::Boolean validate_acceptor (TAO_Acceptor *) const = 0;
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* _TAO_Endpoint_Value_Impl_H_ */
diff --git a/TAO/tao/PortableServer/POAManagerFactory.cpp b/TAO/tao/PortableServer/POAManagerFactory.cpp
new file mode 100644
index 00000000000..25d6b0bdc28
--- /dev/null
+++ b/TAO/tao/PortableServer/POAManagerFactory.cpp
@@ -0,0 +1,162 @@
+// $Id$
+
+#include "tao/PortableServer/POAManagerFactory.h"
+#include "tao/PortableServer/POAManager.h"
+#include "tao/EndpointPolicy/EndpointPolicyTypeC.h"
+
+#include "ace/OS_NS_string.h"
+
+ACE_RCSID (PortableServer,
+ POAManagerFactory,
+ "$Id$")
+
+
+TAO_POAManager_Factory::TAO_POAManager_Factory (TAO_Object_Adapter &object_adapter) :
+ object_adapter_ (object_adapter)
+{
+}
+
+TAO_POAManager_Factory::~TAO_POAManager_Factory (void)
+{
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)~TAO_POAManager_Factory \n"));
+ }
+
+ for (POAMANAGERSET::iterator iterator = this->poamanager_set_.begin ();
+ iterator != this->poamanager_set_.end ();
+ ++iterator)
+ {
+ ::PortableServer::POAManager_ptr poamanager = (*iterator);
+ CORBA::release (poamanager);
+ }
+}
+
+::PortableServer::POAManager_ptr
+TAO_POAManager_Factory::create_POAManager (
+ const char * id,
+ const ::CORBA::PolicyList & policies
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ ::PortableServer::POAManagerFactory::ManagerAlreadyExists,
+ ::CORBA::PolicyError))
+{
+ if (policies.length () > 1
+ || (policies.length () == 1 &&
+ policies[0]->policy_type () != EndpointPolicy::ENDPOINT_POLICY_TYPE))
+ {
+ ACE_THROW_RETURN (CORBA::PolicyError (CORBA::BAD_POLICY),
+ ::PortableServer::POAManager::_nil ());
+ }
+
+ PortableServer::POAManager_var poamanager =
+ PortableServer::POAManager::_nil ();
+ if (id != 0)
+ {
+ poamanager = this->find (id ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (::PortableServer::POAManager::_nil ());
+
+ // If we already have a manager with the same name throw an exception
+ if (!CORBA::is_nil (poamanager.in()))
+ {
+ ACE_THROW_RETURN (
+ ::PortableServer::POAManagerFactory::ManagerAlreadyExists (),
+ ::PortableServer::POAManager::_nil ());
+ }
+ }
+
+ // this indirection brought to you by borland's compiler and its refusal
+ // to directly assign the newly crated TAO_POA_Manager to a POAManager_var.
+ {
+ PortableServer::POAManager_ptr pm = 0;
+ ACE_NEW_THROW_EX (pm,
+ TAO_POA_Manager (object_adapter_, id, policies, this),
+ CORBA::NO_MEMORY
+ (CORBA::SystemException::_tao_minor_code (0, ENOMEM),
+ CORBA::COMPLETED_NO));
+ ACE_CHECK_RETURN (::PortableServer::POAManager::_nil ());
+ poamanager = pm;
+ }
+
+ this->register_poamanager (poamanager.in ());
+
+ return PortableServer::POAManager::_duplicate (poamanager.in ());
+}
+
+::PortableServer::POAManagerFactory::POAManagerSeq *
+TAO_POAManager_Factory::list (
+ ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ::PortableServer::POAManagerFactory::POAManagerSeq_var poamanagers;
+ CORBA::ULong number_of_poamanagers = static_cast <CORBA::ULong>
+ (this->poamanager_set_.size ());
+ ACE_NEW_THROW_EX (poamanagers,
+ PortableServer::POAManagerFactory::POAManagerSeq (
+ number_of_poamanagers),
+ CORBA::NO_MEMORY ());
+ ACE_CHECK_RETURN (0);
+
+ poamanagers->length (number_of_poamanagers);
+
+ CORBA::ULong index = 0;
+ for (POAMANAGERSET::iterator iterator = this->poamanager_set_.begin ();
+ iterator != this->poamanager_set_.end ();
+ ++iterator, ++index)
+ {
+ ::PortableServer::POAManager_ptr poamanager = (*iterator);
+ poamanagers[index] =
+ PortableServer::POAManager::_duplicate (poamanager);
+ }
+
+ return poamanagers._retn ();
+}
+
+::PortableServer::POAManager_ptr
+TAO_POAManager_Factory::find (
+ const char * id ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ::PortableServer::POAManager_ptr poamanager =
+ ::PortableServer::POAManager::_nil();
+
+ for (POAMANAGERSET::iterator iterator = this->poamanager_set_.begin ();
+ iterator != this->poamanager_set_.end ();
+ ++iterator)
+ {
+ CORBA::String_var poamanagerid =
+ (*iterator)->get_id (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (::PortableServer::POAManager::_nil());
+
+ if (ACE_OS::strcmp (id, poamanagerid) == 0)
+ {
+ poamanager = PortableServer::POAManager::_duplicate (*iterator);
+ break;
+ }
+ }
+
+ return poamanager;
+}
+
+int
+TAO_POAManager_Factory::remove_poamanager (
+ ::PortableServer::POAManager_ptr poamanager)
+{
+ int retval = 0;
+ retval = this->poamanager_set_.remove (poamanager);
+
+ if (retval == 0)
+ {
+ CORBA::release (poamanager);
+ }
+
+ return retval;
+}
+
+int
+TAO_POAManager_Factory::register_poamanager (
+ ::PortableServer::POAManager_ptr poamanager)
+{
+ return this->poamanager_set_.insert (
+ PortableServer::POAManager::_duplicate (poamanager));
+}
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..ddaae2341c3
--- /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 (33 == 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..c0b3b4ecc75
--- /dev/null
+++ b/TAO/tests/ORB_Local_Config/Limits/Test.cpp
@@ -0,0 +1,19 @@
+// $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_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..2ffbdab6f80
--- /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_Dependent_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_Dependent_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_Dependent_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_Dependent_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..2701ce4e293
--- /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_Dependent_DLL TAO
+ exename = Test
+ includes += ../lib
+ libpaths += ../lib
+ libs += lib
+ Source_Files {
+ Test.cpp
+ }
+}
+
+project(Service Config Dependent DLL) : acelib {
+ sharedname = Service_Config_Dependent_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..e6ecf217d95
--- /dev/null
+++ b/TAO/tests/ORB_Local_Config/Simple/Test.cpp
@@ -0,0 +1,37 @@
+// $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_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..d61650d07e6
--- /dev/null
+++ b/TAO/tests/ORB_Local_Config/Two_DLL_ORB/Test.cpp
@@ -0,0 +1,32 @@
+// $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_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..725f103fcc5
--- /dev/null
+++ b/TAO/tests/ORB_Local_Config/lib/lib.mpc
@@ -0,0 +1,15 @@
+// -*- MPC -*-
+// $Id$
+
+
+project(*) : acelib {
+
+ 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/Dynamic_Service_Dependency.cpp b/ace/Dynamic_Service_Dependency.cpp
new file mode 100644
index 00000000000..cfb556f3e1c
--- /dev/null
+++ b/ace/Dynamic_Service_Dependency.cpp
@@ -0,0 +1,48 @@
+#include "ace/DLL_Manager.h"
+#include "ace/Dynamic_Service_Dependency.h"
+#include "ace/Service_Config.h"
+
+ACE_RCSID (ace,
+ Dynamic_Service_Dependency,
+ "$Id$")
+
+
+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..8f4b3b3cd18
--- /dev/null
+++ b/ace/Dynamic_Service_Dependency.h
@@ -0,0 +1,70 @@
+// -*- 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
+
+
+#include /**/ "ace/post.h"
+
+#endif /* ACE_DYNAMIC_SERVICE_DEPENDENCY_H */
diff --git a/ace/Service_Gestalt.cpp b/ace/Service_Gestalt.cpp
new file mode 100644
index 00000000000..456958ac732
--- /dev/null
+++ b/ace/Service_Gestalt.cpp
@@ -0,0 +1,1114 @@
+// $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?
+ if (ret < 0 && ret != -2)
+ {
+ ACE_ERROR ((LM_WARNING,
+ ACE_LIB_TEXT ("(%P|%t) FWDCL::end - Failed (%d) to find %s\n"),
+ ret, this->name_));
+ 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..39618b402d6
--- /dev/null
+++ b/ace/Service_Gestalt.h
@@ -0,0 +1,438 @@
+// -*- 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/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/tests/Sendfile_Test.cpp b/tests/Sendfile_Test.cpp
new file mode 100644
index 00000000000..df151194bc0
--- /dev/null
+++ b/tests/Sendfile_Test.cpp
@@ -0,0 +1,316 @@
+// $Id$
+
+/**
+ * @file Sendfile_Test.cpp
+ *
+ * This is a test of the @c ACE_OS::sendfile() wrapper function. It
+ * is primarily meant to test the case when ACE_HAS_SENDFILE is not
+ * defined, i.e. when sendfile() support is emulated.
+ *
+ * @author
+ * Steve Huston <shuston@riverace.com>
+ * Ossama Othman <ossama@dre.vanderbilt.edu>
+ */
+
+#include "test_config.h"
+#include "ace/OS_NS_sys_wait.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/Thread.h"
+#include "ace/Thread_Manager.h"
+#include "ace/Time_Value.h"
+#include "ace/SOCK_Connector.h"
+#include "ace/SOCK_Acceptor.h"
+#include "ace/SOCK_Stream.h"
+#include "ace/OS_NS_sys_sendfile.h"
+
+// Change to non-zero if test fails
+static int Test_Result = 0;
+
+#if !defined (ACE_LACKS_FORK) || defined (ACE_HAS_THREADS)
+
+// This test sends a large amount of data. The purpose is to overflow the
+// TCP send window, causing the sender to block (it's a send_n). This value
+// is the amount to send. The assumption is that no implementation has a
+// receive window larger than 128K bytes. If one is found, this is the place
+// to change it.
+// For some odd reason, NT will try to send a single large buffer, but not
+// multiple smaller ones that add up to the large size.
+const size_t Test3_Send_Size = 4*1024;
+const size_t Test3_Loops = 10;
+const size_t Test3_Total_Size = Test3_Send_Size * Test3_Loops;
+
+
+static void *
+client (void *arg)
+{
+ ACE_INET_Addr *remote_addr = reinterpret_cast<ACE_INET_Addr *> (arg);
+ ACE_INET_Addr server_addr (remote_addr->get_port_number (),
+ ACE_LOCALHOST);
+ ACE_SOCK_Stream cli_stream;
+ ACE_SOCK_Connector con;
+ ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) Connecting to port %d\n"),
+ server_addr.get_port_number()));
+
+ // Initiate connection with server; don't wait forever
+ if (con.connect (cli_stream,
+ server_addr,
+ &timeout) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("connection failed")));
+ Test_Result = 1;
+ return 0;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) connected to %s\n"),
+ ACE_TEXT_CHAR_TO_TCHAR(server_addr.get_host_name ())));
+
+ //******************* TEST 1 ******************************
+ //
+ // Send the 255 byte buffer in 5 chunks. The
+ // server will verify that the correct data is sent, and that there
+ // is no more and no less.
+
+ u_char buffer[255];
+ size_t i;
+
+ // The server will verify that this data pattern gets there intact.
+
+ for (i = 0; i < sizeof buffer; ++i)
+ buffer[i] = static_cast<u_char> (i);
+
+ ACE_TCHAR const test_file[] = ACE_TEXT ("Sendfile_Test_File");
+ ACE_HANDLE in_fd =
+ ACE_OS::open (test_file,
+ O_CREAT | O_RDWR | O_TRUNC,
+ ACE_DEFAULT_FILE_PERMS);
+
+ ACE_ASSERT (in_fd != ACE_INVALID_HANDLE);
+
+ ACE_OS::unlink (test_file);
+
+ ssize_t const byte_count =
+ ACE_OS::write (in_fd, buffer, sizeof (buffer));
+
+ ACE_ASSERT (byte_count == static_cast<ssize_t> (sizeof (buffer)));
+
+ off_t offset = 0;
+
+ ssize_t len =
+ ACE_OS::sendfile (cli_stream.get_handle (),
+ in_fd,
+ &offset,
+ byte_count);
+
+ if (len == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("Test 1, sendfile failed")));
+ Test_Result = 1;
+ }
+ else
+ ACE_ASSERT (len == 255);
+
+ //******************* TEST 2 ******************************
+ //
+ // The same data is coming back - receive it using recv (size_t n,
+ // ...) and compare it to the original data.
+
+ u_char buffer2[255];
+ // Give it a chance to get here
+ ACE_OS::sleep (2);
+ len = cli_stream.recv (4,
+ buffer2,
+ 150,
+ &buffer2[150],
+ 105);
+ if (len != 255)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p; len is %d, but should be 255!\n"),
+ len));
+ }
+ ACE_ASSERT (len == 255);
+
+ for (i = 0; i < 255; i++)
+ if (buffer2[i] != buffer[i])
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Test 2, rcvd byte %d is %d, not %d\n"),
+ i, buffer2[i], buffer[i]));
+ Test_Result = 1;
+ }
+
+
+ cli_stream.close ();
+ (void) ACE_OS::close (in_fd);
+
+ return 0;
+}
+
+static void *
+server (void *arg)
+{
+ ACE_SOCK_Acceptor *peer_acceptor = (ACE_SOCK_Acceptor *) arg;
+ ACE_SOCK_Stream sock_str;
+ ACE_INET_Addr cli_addr;
+ ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
+
+ // Accept the connection over which the stream tests will run.
+ // Don't lock up if client doesn't connect
+ if (peer_acceptor->accept (sock_str,
+ &cli_addr,
+ &timeout) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("accept")));
+ Test_Result = 1;
+ return 0;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) client %s connected from %d\n"),
+ ACE_TEXT_CHAR_TO_TCHAR(cli_addr.get_host_name ()),
+ cli_addr.get_port_number ()));
+
+ //******************* TEST 1 ******************************
+ //
+ // Do a iovec recvv - the client should send 255 bytes, which we
+ // will be detected and read into a ACE-allocated buffer. Use a 5
+ // second timeout to give the client a chance to send it all.
+
+ ACE_OS::sleep (5);
+
+ u_char buffer[255];
+ ssize_t len;
+ int i;
+
+ len = sock_str.recv (buffer, 255);
+ if (len == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("Test 1, recvv failed")));
+ Test_Result = 1;
+ }
+
+ ACE_ASSERT (len == 255);
+ for (i = 0; i < 255; i++)
+ if (buffer[i] != i)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Test 1, rcvd byte %d is %d, not %d\n"),
+ i,
+ buffer[i],
+ i));
+ Test_Result = 1;
+ }
+
+ //******************* TEST 2 ******************************
+ //
+ // Send the buffer back, using send (size_t n, ...) in 3 pieces.
+
+ len = sock_str.send (6,
+ buffer,
+ 42,
+ &buffer[42],
+ 189,
+ &buffer[231],
+ 24);
+ ACE_ASSERT (len == 255);
+
+
+ sock_str.close();
+
+ return 0;
+}
+
+#endif /* !ACE_LACKS_FORK || ACE_HAS_THREADS */
+
+static void
+spawn (void)
+{
+ // Acceptor
+ ACE_SOCK_Acceptor peer_acceptor;
+
+ // Create a server address.
+ ACE_INET_Addr server_addr;
+
+ // Bind listener to any port and then find out what the port was.
+ if (peer_acceptor.open (ACE_Addr::sap_any) == -1
+ || peer_acceptor.get_local_addr (server_addr) == -1)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("open")));
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) starting server at port %d\n"),
+ server_addr.get_port_number ()));
+
+#if !defined (ACE_LACKS_FORK)
+ switch (ACE_OS::fork (ACE_TEXT ("child")))
+ {
+ case -1:
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n%a"),
+ ACE_TEXT ("fork failed"),
+ 1));
+ /* NOTREACHED */
+ case 0:
+ client (&server_addr);
+ ACE_OS::exit (0);
+ /* NOTREACHED */
+ default:
+ server (reinterpret_cast<void *> (&peer_acceptor));
+ ACE_OS::wait ();
+ }
+#elif defined (ACE_HAS_THREADS)
+ if (ACE_Thread_Manager::instance ()->spawn
+ (ACE_THR_FUNC (server),
+ reinterpret_cast<void *> (&peer_acceptor),
+ THR_NEW_LWP | THR_DETACHED) == -1)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n%a"),
+ ACE_TEXT ("thread create failed"),
+ 1));
+
+ if (ACE_Thread_Manager::instance ()->spawn
+ (ACE_THR_FUNC (client),
+ reinterpret_cast<void *> (&server_addr),
+ THR_NEW_LWP | THR_DETACHED) == -1)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n%a"),
+ ACE_TEXT ("thread create failed"),
+ 1));
+
+ // Wait for the threads to exit.
+ ACE_Thread_Manager::instance ()->wait ();
+#else
+ ACE_ERROR ((LM_INFO,
+ ACE_TEXT ("(%P|%t) ")
+ ACE_TEXT ("only one thread may be run ")
+ ACE_TEXT ("in a process on this platform\n")));
+#endif /* ACE_HAS_THREADS */
+
+ peer_acceptor.close ();
+ }
+}
+
+int
+run_main (int, ACE_TCHAR *[])
+{
+ ACE_START_TEST (ACE_TEXT ("Sendfile_Test"));
+
+ spawn ();
+
+ ACE_END_TEST;
+ return Test_Result;
+}