summaryrefslogtreecommitdiff
path: root/TAO/tao
diff options
context:
space:
mode:
authorstanleyk <stanleyk@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2013-02-05 21:11:03 +0000
committerstanleyk <stanleyk@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2013-02-05 21:11:03 +0000
commit5e030faf84086ab02059fcbcc3faed224bd57b95 (patch)
tree3a62df45ac6ccf599fb07cf6a03d672456ce2e3d /TAO/tao
parent9d296f7fa51116ff7040ecb2ad18612cd94b5fd1 (diff)
downloadATCD-5e030faf84086ab02059fcbcc3faed224bd57b95.tar.gz
Merge in OCI_Reliability_Enhancements branch.
Diffstat (limited to 'TAO/tao')
-rw-r--r--TAO/tao/AnyTypeCode/Struct_TypeCode.cpp13
-rw-r--r--TAO/tao/AnyTypeCode/Struct_TypeCode.h3
-rw-r--r--TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp371
-rw-r--r--TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h112
-rw-r--r--TAO/tao/AnyTypeCode/Union_TypeCode.cpp13
-rw-r--r--TAO/tao/AnyTypeCode/Union_TypeCode.h3
-rw-r--r--TAO/tao/AnyTypeCode/Value_TypeCode.cpp26
-rw-r--r--TAO/tao/AnyTypeCode/Value_TypeCode.h6
-rw-r--r--TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp61
-rw-r--r--TAO/tao/CSD_Framework/CSD_ORBInitializer.h2
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp1
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h2
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp175
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp7
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Task.h2
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp56
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h10
-rw-r--r--TAO/tao/Client_Strategy_Factory.h10
-rw-r--r--TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp13
-rw-r--r--TAO/tao/DynamicInterface/DII_Invocation_Adapter.h9
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Config.cpp327
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Config.h124
-rw-r--r--TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp132
-rw-r--r--TAO/tao/Dynamic_TP/DTP_ORBInitializer.h72
-rw-r--r--TAO/tao/Dynamic_TP/DTP_ORB_Loader.cpp113
-rw-r--r--TAO/tao/Dynamic_TP/DTP_ORB_Loader.h63
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Loader.cpp199
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Loader.h62
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Strategy.cpp422
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Strategy.h220
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Strategy.inl35
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Task.cpp479
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Task.h199
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Task.inl7
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp131
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h124
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp456
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Pool.h249
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Pool.inl43
-rw-r--r--TAO/tao/Dynamic_TP/Dynamic_TP.mpc10
-rw-r--r--TAO/tao/Dynamic_TP/dynamic_tp_export.h58
-rw-r--r--TAO/tao/IIOP_Profile.cpp2
-rw-r--r--TAO/tao/IIOP_Profile.h2
-rw-r--r--TAO/tao/IIOP_Transport.cpp3
-rw-r--r--TAO/tao/IORManipulation/IORManipulation.cpp8
-rw-r--r--TAO/tao/ImR_Client/ImR_Client.cpp311
-rw-r--r--TAO/tao/ImR_Client/ImR_Client.h5
-rw-r--r--TAO/tao/ImR_Client/ImR_Client.mpc2
-rw-r--r--TAO/tao/Invocation_Adapter.cpp20
-rw-r--r--TAO/tao/Invocation_Adapter.h9
-rw-r--r--TAO/tao/Invocation_Retry_Params.cpp20
-rw-r--r--TAO/tao/Invocation_Retry_Params.h61
-rw-r--r--TAO/tao/Invocation_Retry_State.cpp176
-rw-r--r--TAO/tao/Invocation_Retry_State.h98
-rw-r--r--TAO/tao/Invocation_Utils.h2
-rw-r--r--TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp5
-rw-r--r--TAO/tao/Messaging/Asynch_Invocation_Adapter.h3
-rw-r--r--TAO/tao/ORB_Core.cpp57
-rw-r--r--TAO/tao/PortableServer/ImR_Client_Adapter.h15
-rw-r--r--TAO/tao/PortableServer/LifespanStrategy.h10
-rw-r--r--TAO/tao/PortableServer/LifespanStrategyPersistent.cpp27
-rw-r--r--TAO/tao/PortableServer/LifespanStrategyPersistent.h3
-rw-r--r--TAO/tao/PortableServer/LifespanStrategyTransient.cpp7
-rw-r--r--TAO/tao/PortableServer/LifespanStrategyTransient.h3
-rw-r--r--TAO/tao/PortableServer/Root_POA.cpp71
-rw-r--r--TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp28
-rw-r--r--TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h2
-rw-r--r--TAO/tao/Profile.cpp2
-rw-r--r--TAO/tao/Profile.h4
-rw-r--r--TAO/tao/Seq_Var_T.h9
-rw-r--r--TAO/tao/Seq_Var_T.inl15
-rw-r--r--TAO/tao/Storable_Base.cpp97
-rw-r--r--TAO/tao/Storable_Base.h181
-rw-r--r--TAO/tao/Storable_Base.inl74
-rw-r--r--TAO/tao/Storable_Factory.cpp25
-rw-r--r--TAO/tao/Storable_Factory.h52
-rw-r--r--TAO/tao/Storable_File_Guard.cpp266
-rw-r--r--TAO/tao/Storable_File_Guard.h124
-rw-r--r--TAO/tao/Storable_FlatFileStream.cpp475
-rw-r--r--TAO/tao/Storable_FlatFileStream.h145
-rw-r--r--TAO/tao/Strategies/COIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/COIOP_Profile.h2
-rw-r--r--TAO/tao/Strategies/DIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/DIOP_Profile.h2
-rw-r--r--TAO/tao/Strategies/SCIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/SCIOP_Profile.h2
-rw-r--r--TAO/tao/Strategies/SHMIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/SHMIOP_Profile.h2
-rw-r--r--TAO/tao/Strategies/UIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/UIOP_Profile.h2
-rw-r--r--TAO/tao/Stub.cpp32
-rw-r--r--TAO/tao/Stub.h6
-rw-r--r--TAO/tao/Stub.inl59
-rw-r--r--TAO/tao/Synch_Invocation.cpp340
-rw-r--r--TAO/tao/Synch_Invocation.h10
-rw-r--r--TAO/tao/Transport.cpp7
-rw-r--r--TAO/tao/Transport.h9
-rw-r--r--TAO/tao/VarOut_T.h4
-rw-r--r--TAO/tao/VarOut_T.inl16
-rw-r--r--TAO/tao/default_client.cpp160
-rw-r--r--TAO/tao/default_client.h5
-rw-r--r--TAO/tao/params.cpp39
-rw-r--r--TAO/tao/params.h26
-rw-r--r--TAO/tao/tao.mpc6
104 files changed, 7002 insertions, 576 deletions
diff --git a/TAO/tao/AnyTypeCode/Struct_TypeCode.cpp b/TAO/tao/AnyTypeCode/Struct_TypeCode.cpp
index b920fd9f483..0418ed99896 100644
--- a/TAO/tao/AnyTypeCode/Struct_TypeCode.cpp
+++ b/TAO/tao/AnyTypeCode/Struct_TypeCode.cpp
@@ -108,6 +108,19 @@ template <typename StringType,
typename TypeCodeType,
class FieldArrayType,
class RefCountPolicy>
+const FieldArrayType&
+TAO::TypeCode::Struct<StringType,
+ TypeCodeType,
+ FieldArrayType,
+ RefCountPolicy>::fields (void) const
+{
+ return fields_;
+}
+
+template <typename StringType,
+ typename TypeCodeType,
+ class FieldArrayType,
+ class RefCountPolicy>
CORBA::Boolean
TAO::TypeCode::Struct<StringType,
TypeCodeType,
diff --git a/TAO/tao/AnyTypeCode/Struct_TypeCode.h b/TAO/tao/AnyTypeCode/Struct_TypeCode.h
index 422b6b3fdf8..27ede78e202 100644
--- a/TAO/tao/AnyTypeCode/Struct_TypeCode.h
+++ b/TAO/tao/AnyTypeCode/Struct_TypeCode.h
@@ -78,6 +78,9 @@ namespace TAO
virtual void tao_release (void);
//@}
+ /// Accessor for fields_
+ const FieldArrayType& fields() const;
+
protected:
/**
diff --git a/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp b/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp
index 661e8414d57..6e05e19bfd1 100644
--- a/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp
+++ b/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp
@@ -60,7 +60,7 @@ namespace TAO
namespace
{
- bool add_to_recursion_list (CORBA::TypeCode_ptr & tc,
+ bool add_to_tc_info_list (CORBA::TypeCode_ptr & tc,
TAO::TypeCodeFactory::TC_Info_List & infos)
{
// Since we created a new tc, add it to the list.
@@ -127,24 +127,30 @@ namespace
// Use an ACE::Value_Ptr to provide exception safety and proper
// copying semantics.
- typedef ACE::Value_Ptr<TAO::TypeCode::Case<CORBA::String_var, CORBA::TypeCode_var> > union_elem_type;
+ typedef ACE::Value_Ptr<TAO::TypeCode::Case<CORBA::String_var,
+ CORBA::TypeCode_var> > union_elem_type;
typedef ACE_Array_Base<union_elem_type> union_case_array_type;
// ------------------------------------------------------------
/// Demarshal a TypeCode.
- bool tc_demarshal (TAO_InputCDR & cdr,
- CORBA::TypeCode_ptr & tc,
- TAO::TypeCodeFactory::TC_Info_List & infos);
+ bool tc_demarshal (
+ TAO_InputCDR & cdr,
+ CORBA::TypeCode_ptr & tc,
+ TAO::TypeCodeFactory::TC_Info_List & indirect_infos,
+ TAO::TypeCodeFactory::TC_Info_List & direct_infos);
/// Demarshal an indirected TypeCode.
- bool tc_demarshal_indirection (TAO_InputCDR & cdr,
- CORBA::TypeCode_ptr & tc,
- TAO::TypeCodeFactory::TC_Info_List & infos);
-
- bool find_recursive_tc (char const * id,
- TAO::TypeCodeFactory::TC_Info_List & tcs,
- TAO::TypeCodeFactory::TC_Info_List & infos)
+ bool tc_demarshal_indirection (
+ TAO_InputCDR & cdr,
+ CORBA::TypeCode_ptr & tc,
+ TAO::TypeCodeFactory::TC_Info_List & indirect_infos,
+ TAO::TypeCodeFactory::TC_Info_List & direct_infos);
+
+ bool find_recursive_tc (
+ char const * id,
+ TAO::TypeCodeFactory::TC_Info_List & tcs,
+ TAO::TypeCodeFactory::TC_Info_List & infos)
{
// See comments above for rationale behind using an array instead
// of a map.
@@ -170,12 +176,25 @@ namespace
return (tcs.size () > 0) ;
}
+
+ // For TC_Info_List whose elements are duplicated prior to addition,
+ // clean up the list by calling release on the typecode pointers.
+ void cleanup_tc_info_list (TAO::TypeCodeFactory::TC_Info_List & infos)
+ {
+ size_t const len = infos.size ();
+
+ for (size_t i = 0; i < len; ++i)
+ {
+ CORBA::release(infos[i].type);
+ }
+ }
}
bool
TAO::TypeCodeFactory::tc_null_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_null);
@@ -187,6 +206,7 @@ bool
TAO::TypeCodeFactory::tc_void_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_void);
@@ -198,6 +218,7 @@ bool
TAO::TypeCodeFactory::tc_short_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_short);
@@ -209,6 +230,7 @@ bool
TAO::TypeCodeFactory::tc_long_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_long);
@@ -220,6 +242,7 @@ bool
TAO::TypeCodeFactory::tc_ushort_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_ushort);
@@ -231,6 +254,7 @@ bool
TAO::TypeCodeFactory::tc_ulong_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_ulong);
@@ -242,6 +266,7 @@ bool
TAO::TypeCodeFactory::tc_float_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_float);
@@ -253,6 +278,7 @@ bool
TAO::TypeCodeFactory::tc_double_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_double);
@@ -264,6 +290,7 @@ bool
TAO::TypeCodeFactory::tc_boolean_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_boolean);
@@ -275,6 +302,7 @@ bool
TAO::TypeCodeFactory::tc_char_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_char);
@@ -286,6 +314,7 @@ bool
TAO::TypeCodeFactory::tc_octet_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_octet);
@@ -297,6 +326,7 @@ bool
TAO::TypeCodeFactory::tc_any_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_any);
@@ -308,6 +338,7 @@ bool
TAO::TypeCodeFactory::tc_TypeCode_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_TypeCode);
@@ -319,6 +350,7 @@ bool
TAO::TypeCodeFactory::tc_Principal_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_Principal);
@@ -330,6 +362,7 @@ bool
TAO::TypeCodeFactory::tc_objref_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
// The remainder of a tk_objref TypeCode is encoded in a CDR
@@ -343,11 +376,14 @@ TAO::TypeCodeFactory::tc_objref_factory (CORBA::TCKind kind,
if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)))
return false;
- static char const Object_id[] = "IDL:omg.org/CORBA/Object:1.0";
- static char const CCMObject_id[] = "IDL:omg.org/CORBA/CCMObject:1.0";
- static char const CCMHome_id[] = "IDL:omg.org/CORBA/CCMHome:1.0";
+ static char const Object_id[] =
+ ACE_TEXT_ALWAYS_CHAR ("IDL:omg.org/CORBA/Object:1.0");
+ static char const CCMObject_id[] =
+ ACE_TEXT_ALWAYS_CHAR ("IDL:omg.org/CORBA/CCMObject:1.0");
+ static char const CCMHome_id[] =
+ ACE_TEXT_ALWAYS_CHAR ("IDL:omg.org/CORBA/CCMHome:1.0");
- char const * tc_constant_id = "";
+ char const * tc_constant_id = ACE_TEXT_ALWAYS_CHAR ("");
switch (kind)
{
@@ -415,7 +451,8 @@ bool
TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
ACE_ASSERT (kind == CORBA::tk_struct || kind == CORBA::tk_except);
@@ -443,7 +480,10 @@ TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
for (CORBA::ULong i = 0; i < nfields; ++i)
{
if (!(cdr >> TAO_InputCDR::to_string (fields[i].name.out (), 0)
- && tc_demarshal (cdr, fields[i].type.out (), infos)))
+ && tc_demarshal (cdr,
+ fields[i].type.out (),
+ indirect_infos,
+ direct_infos)))
return false;
}
@@ -455,7 +495,9 @@ TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
// Check if struct TypeCode is recursive.
TAO::TypeCodeFactory::TC_Info_List recursive_tc;
- if (kind == CORBA::tk_struct && find_recursive_tc (id.in (), recursive_tc, infos))
+ if (kind == CORBA::tk_struct && find_recursive_tc (id.in (),
+ recursive_tc,
+ indirect_infos))
{
// Set remaining parameters.
typedef TAO::TypeCode::Recursive_Type<typecode_type,
@@ -476,7 +518,9 @@ TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
if (!rtc)
return false; // Should never occur.
- assigned_params |= rtc->struct_parameters (name.in (), fields, nfields);
+ assigned_params |= rtc->struct_parameters (name.in (),
+ fields,
+ nfields);
}
// If no parameters were assigned then the reference in the
@@ -502,6 +546,10 @@ TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
false);
}
+ CORBA::TypeCode_ptr dup_tc = CORBA::TypeCode::_duplicate(tc);
+ if (!add_to_tc_info_list(dup_tc, direct_infos)) {
+ return false;
+ }
return true;
}
@@ -509,7 +557,8 @@ bool
TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
// The remainder of a tk_enum TypeCode is encoded in a CDR
// encapsulation.
@@ -559,7 +608,8 @@ TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
{
elem_type & member = cases[i];
- TAO::TypeCode::Case<CORBA::String_var, CORBA::TypeCode_var> * the_case = 0;
+ TAO::TypeCode::Case<CORBA::String_var, CORBA::TypeCode_var> *
+ the_case = 0;
// Ugly. *sigh*
switch (discriminant_kind)
@@ -709,7 +759,9 @@ TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
CORBA::TypeCode_var the_type;
if (!(cdr >> TAO_InputCDR::to_string (the_name.out (), 0)
- && tc_demarshal (cdr, the_type.out (), infos)))
+ && tc_demarshal (cdr, the_type.out (),
+ indirect_infos,
+ direct_infos)))
return false;
member->name (the_name.in ());
@@ -723,7 +775,7 @@ TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
// Check if we have recursive members. There could be multiple.
TAO::TypeCodeFactory::TC_Info_List recursive_tc;
- if (find_recursive_tc (id.in (), recursive_tc, infos))
+ if (find_recursive_tc (id.in (), recursive_tc, indirect_infos))
{
// Set remaining parameters.
@@ -777,6 +829,10 @@ TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
false);
}
+ CORBA::TypeCode_ptr dup_tc = CORBA::TypeCode::_duplicate(tc);
+ if (!add_to_tc_info_list(dup_tc, direct_infos)) {
+ return false;
+ }
return true;
}
@@ -784,6 +840,7 @@ bool
TAO::TypeCodeFactory::tc_enum_factory (CORBA::TCKind /* kind */,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
// The remainder of a tk_enum TypeCode is encoded in a CDR
@@ -828,6 +885,7 @@ bool
TAO::TypeCodeFactory::tc_string_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
// A tk_string/tk_wstring TypeCode has a simple parameter list,
@@ -863,7 +921,8 @@ bool
TAO::TypeCodeFactory::tc_sequence_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
ACE_ASSERT (kind == CORBA::tk_sequence || kind == CORBA::tk_array);
@@ -877,7 +936,7 @@ TAO::TypeCodeFactory::tc_sequence_factory (CORBA::TCKind kind,
CORBA::TypeCode_var content_type;
CORBA::ULong length;
- if (!(tc_demarshal (cdr, content_type.out (), infos)
+ if (!(tc_demarshal (cdr, content_type.out (), indirect_infos, direct_infos)
&& cdr >> length))
return false;
@@ -896,16 +955,18 @@ bool
TAO::TypeCodeFactory::tc_array_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_sequence_factory (kind, cdr, tc, infos);
+ return tc_sequence_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_alias_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
// The remainder of a tk_alias or tk_value_box TypeCode is encoded
// in a CDR encapsulation.
@@ -918,7 +979,10 @@ TAO::TypeCodeFactory::tc_alias_factory (CORBA::TCKind kind,
CORBA::TypeCode_var content_type;
if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)
&& cdr >> TAO_InputCDR::to_string (name.out (), 0)
- && tc_demarshal (cdr, content_type.out (), infos)))
+ && tc_demarshal (cdr,
+ content_type.out (),
+ indirect_infos,
+ direct_infos)))
{
return false;
}
@@ -941,15 +1005,17 @@ bool
TAO::TypeCodeFactory::tc_except_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_struct_factory (kind, cdr, tc, infos);
+ return tc_struct_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_longlong_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_longlong);
@@ -961,6 +1027,7 @@ bool
TAO::TypeCodeFactory::tc_ulonglong_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_ulonglong);
@@ -972,6 +1039,7 @@ bool
TAO::TypeCodeFactory::tc_longdouble_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_longdouble);
@@ -983,6 +1051,7 @@ bool
TAO::TypeCodeFactory::tc_wchar_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_wchar);
@@ -994,15 +1063,17 @@ bool
TAO::TypeCodeFactory::tc_wstring_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_string_factory (kind, cdr, tc, infos);
+ return tc_string_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_fixed_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
// A tk_fixed TypeCode has a simple parameter list, i.e. it is not
@@ -1025,7 +1096,8 @@ bool
TAO::TypeCodeFactory::tc_value_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
// The remainder of a tk_value/tk_event TypeCode is encoded in a
// CDR encapsulation
@@ -1061,7 +1133,7 @@ TAO::TypeCodeFactory::tc_value_factory (CORBA::TCKind kind,
CORBA::TypeCode_var> & field = fields[i];
if (!(cdr >> TAO_InputCDR::to_string (field.name.out (), 0)
- && tc_demarshal (cdr, field.type.out (), infos)
+ && tc_demarshal (cdr, field.type.out (), indirect_infos, direct_infos)
&& cdr >> field.visibility))
return false;
}
@@ -1074,7 +1146,7 @@ TAO::TypeCodeFactory::tc_value_factory (CORBA::TCKind kind,
// Check if valuetype/eventtype TypeCode is recursive.
TAO::TypeCodeFactory::TC_Info_List recursive_tc;
- if (find_recursive_tc (id.in (), recursive_tc, infos))
+ if (find_recursive_tc (id.in (), recursive_tc, indirect_infos))
{
// Set remaining parameters.
@@ -1127,6 +1199,10 @@ TAO::TypeCodeFactory::tc_value_factory (CORBA::TCKind kind,
false);
}
+ CORBA::TypeCode_ptr dup_tc = CORBA::TypeCode::_duplicate(tc);
+ if (!add_to_tc_info_list(dup_tc, direct_infos)) {
+ return false;
+ }
return true;
}
@@ -1134,63 +1210,74 @@ bool
TAO::TypeCodeFactory::tc_value_box_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_alias_factory (kind, cdr, tc, infos);
+ return tc_alias_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_native_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_native, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_native, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_abstract_interface_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_abstract_interface, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_abstract_interface,
+ cdr,
+ tc,
+ indirect_infos,
+ direct_infos);
}
bool
TAO::TypeCodeFactory::tc_local_interface_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_local_interface, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_local_interface, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_component_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_component, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_component, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_home_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_home, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_home, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_event_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_value_factory (kind, cdr, tc, infos);
+ return tc_value_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
// ---------------------------------------------------------------
@@ -1200,7 +1287,8 @@ namespace
bool
tc_demarshal (TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TAO::TypeCodeFactory::TC_Info_List & infos)
+ TAO::TypeCodeFactory::TC_Info_List & indirect_infos,
+ TAO::TypeCodeFactory::TC_Info_List & direct_infos)
{
// ULong since we need to detect indirected TypeCodes, too.
@@ -1210,8 +1298,9 @@ namespace
&& kind != TYPECODE_INDIRECTION))
return false;
- if (kind == TYPECODE_INDIRECTION)
- return tc_demarshal_indirection (cdr, tc, infos);
+ if (kind == TYPECODE_INDIRECTION) {
+ return tc_demarshal_indirection (cdr, tc, indirect_infos, direct_infos);
+ }
using namespace TAO::TypeCodeFactory;
@@ -1259,13 +1348,16 @@ namespace
return factory_map[kind] (static_cast<CORBA::TCKind> (kind),
cdr,
tc,
- infos);
+ indirect_infos,
+ direct_infos);
}
bool
- tc_demarshal_indirection (TAO_InputCDR & cdr,
- CORBA::TypeCode_ptr & tc,
- TAO::TypeCodeFactory::TC_Info_List & infos)
+ tc_demarshal_indirection (
+ TAO_InputCDR & cdr,
+ CORBA::TypeCode_ptr & tc,
+ TAO::TypeCodeFactory::TC_Info_List & indirect_infos,
+ TAO::TypeCodeFactory::TC_Info_List & direct_infos)
{
CORBA::Long offset;
@@ -1332,7 +1424,10 @@ namespace
CORBA::String_var name;
CORBA::TypeCode_var content_type;
if (!(indir_stream >> TAO_InputCDR::to_string (name.out (), 0)
- && tc_demarshal (indir_stream, content_type.out (), infos)))
+ && tc_demarshal (indir_stream,
+ content_type.out (),
+ indirect_infos,
+ direct_infos)))
{
return false;
}
@@ -1357,7 +1452,7 @@ namespace
// Check if we already have a tc for this RECURSIVE type, if yes, use that
TAO::TypeCodeFactory::TC_Info_List recursive_tc;
- if (find_recursive_tc (id.in (), recursive_tc, infos))
+ if (find_recursive_tc (id.in (), recursive_tc, indirect_infos))
{
tc = CORBA::TypeCode::_duplicate(recursive_tc[0].type);
}
@@ -1386,8 +1481,9 @@ namespace
id.in ()),
false);
- // Since we created a new recursive tc, add it to the "Recursive" list.
- return add_to_recursion_list (tc, infos);
+ // Since we created a new recursive tc, add it to
+ // the "Recursive" list.
+ return add_to_tc_info_list (tc, indirect_infos);
}
break;
case CORBA::tk_union:
@@ -1410,8 +1506,9 @@ namespace
id.in ()),
false);
- // Since we created a new recursive tc, add it to the "Recursive" list.
- return add_to_recursion_list (tc, infos);
+ // Since we created a new recursive tc, add it
+ // to the "Recursive" list.
+ return add_to_tc_info_list (tc, indirect_infos);
}
break;
case CORBA::tk_value:
@@ -1438,8 +1535,9 @@ namespace
id.in ()),
false);
- // Since we created a new recursive tc, add it to the "Recursive" list.
- return add_to_recursion_list (tc, infos);
+ // Since we created a new recursive tc, add it
+ // to the "Recursive" list.
+ return add_to_tc_info_list (tc, indirect_infos);
}
break;
default:
@@ -1455,9 +1553,146 @@ namespace
CORBA::Boolean
operator>> (TAO_InputCDR & cdr, CORBA::TypeCode_ptr & tc)
{
- TAO::TypeCodeFactory::TC_Info_List infos;
+ TAO::TypeCodeFactory::TC_Info_List indirect_infos;
+ TAO::TypeCodeFactory::TC_Info_List direct_infos;
+
+ if (!tc_demarshal (cdr, tc, indirect_infos, direct_infos)) {
+ cleanup_tc_info_list(direct_infos);
+ return false;
+ }
+
+ if (indirect_infos.size() == 0) {
+ cleanup_tc_info_list(direct_infos);
+ return true;
+ }
+
+ for (size_t i = 0; i < direct_infos.size(); ++i) {
+ CORBA::TypeCode_ptr& tc = direct_infos[i].type;
+
+ TAO::TypeCodeFactory::TC_Info_List recursive_tc;
+ if (find_recursive_tc(tc->id(), recursive_tc, indirect_infos)) {
+ size_t const len = recursive_tc.size ();
+ bool assigned_params = false;
+
+ switch (tc->kind()) {
+ case CORBA::tk_struct:
+ {
+ // Set remaining parameters.
+ typedef ACE_Array_Base<TAO::TypeCode::Struct_Field<CORBA::String_var,
+ CORBA::TypeCode_var> >
+ member_array_type;
+
+ typedef TAO::TypeCode::Struct<
+ CORBA::String_var,
+ CORBA::TypeCode_var,
+ member_array_type,
+ TAO::True_RefCount_Policy> typecode_type;
+
+ typedef TAO::TypeCode::Recursive_Type<typecode_type,
+ CORBA::TypeCode_var,
+ member_array_type>
+ recursive_typecode_type;
+
+ typecode_type * const tc_struct = dynamic_cast<typecode_type *>(tc);
+ for (size_t i = 0; i < len; ++i)
+ {
+ TAO::TypeCodeFactory::TC_Info & info = recursive_tc[i];
+
+ recursive_typecode_type * const rtc =
+ dynamic_cast<recursive_typecode_type *> (info.type);
+
+ if (!rtc)
+ return false; // Should never occur.
+
+ assigned_params |= rtc->struct_parameters (
+ tc_struct->name(),
+ tc_struct->fields(),
+ tc_struct->member_count());
+ }
+ }
+ break;
+ case CORBA::tk_union:
+ {
+ // Set remaining parameters.
+ typedef union_case_array_type case_array_type;
+
+ typedef TAO::TypeCode::Union<CORBA::String_var,
+ CORBA::TypeCode_var,
+ case_array_type,
+ TAO::True_RefCount_Policy>
+ typecode_type;
+
+ typedef TAO::TypeCode::Recursive_Type<typecode_type,
+ CORBA::TypeCode_var,
+ case_array_type>
+ recursive_typecode_type;
+
+ typecode_type * const tc_union = dynamic_cast<typecode_type *>(tc);
+ for (size_t i = 0; i < len; ++i)
+ {
+ TAO::TypeCodeFactory::TC_Info & info = recursive_tc[i];
+
+ recursive_typecode_type * const rtc =
+ dynamic_cast<recursive_typecode_type *> (info.type);
+
+ if (!rtc)
+ return false; // Should never occur.
+
+ assigned_params |= rtc->union_parameters (
+ tc_union->name(),
+ tc_union->discriminator_type(),
+ tc_union->cases(), // Will be copied.
+ tc_union->member_count(),
+ tc_union->default_index());
+ }
+ }
+ break;
+ case CORBA::tk_value:
+ case CORBA::tk_event:
+ {
+ // Set remaining parameters.
+ typedef ACE_Array_Base<TAO::TypeCode::Value_Field<CORBA::String_var,
+ CORBA::TypeCode_var> >
+ member_array_type;
+
+ typedef TAO::TypeCode::Value<CORBA::String_var,
+ CORBA::TypeCode_var,
+ member_array_type,
+ TAO::True_RefCount_Policy>
+ typecode_type;
+
+ typedef TAO::TypeCode::Recursive_Type<typecode_type,
+ CORBA::TypeCode_var,
+ member_array_type>
+ recursive_typecode_type;
+
+ typecode_type * const tc_value = dynamic_cast<typecode_type *>(tc);
+ for (size_t i = 0; i < len; ++i)
+ {
+ TAO::TypeCodeFactory::TC_Info & info = recursive_tc[i];
- return tc_demarshal (cdr, tc, infos);
+ recursive_typecode_type * const rtc =
+ dynamic_cast<recursive_typecode_type *> (info.type);
+
+ if (!rtc)
+ return false; // Should never occur.
+
+ assigned_params |= rtc->valuetype_parameters (
+ tc_value->name(),
+ tc_value->type_modifier(),
+ tc_value->concrete_base(),
+ tc_value->fields(), // Will be copied.
+ tc_value->member_count());
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ cleanup_tc_info_list(direct_infos);
+ return true;
}
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h b/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h
index 0e6d6015c97..3d99e69751e 100644
--- a/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h
+++ b/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h
@@ -39,156 +39,194 @@ namespace TAO
typedef bool (*factory) (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr &,
+ TC_Info_List &,
TC_Info_List &);
bool tc_null_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_void_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_short_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_long_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_ushort_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_ulong_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_float_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_double_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_boolean_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_char_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_octet_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_any_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_TypeCode_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_Principal_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_objref_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_struct_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_union_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_enum_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_string_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_sequence_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_array_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_alias_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_except_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_longlong_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_ulonglong_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_longdouble_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_wchar_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_wstring_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_fixed_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_value_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_value_box_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_native_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_abstract_interface_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_local_interface_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_component_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_home_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_event_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
} // End namespace TypeCodeFactory
} // End namespace TAO
diff --git a/TAO/tao/AnyTypeCode/Union_TypeCode.cpp b/TAO/tao/AnyTypeCode/Union_TypeCode.cpp
index 6e616e79366..27c7eb6a8d1 100644
--- a/TAO/tao/AnyTypeCode/Union_TypeCode.cpp
+++ b/TAO/tao/AnyTypeCode/Union_TypeCode.cpp
@@ -104,6 +104,19 @@ template <typename StringType,
typename TypeCodeType,
class CaseArrayType,
class RefCountPolicy>
+const CaseArrayType &
+TAO::TypeCode::Union<StringType,
+ TypeCodeType,
+ CaseArrayType,
+ RefCountPolicy>::cases (void) const
+{
+ return cases_;
+}
+
+template <typename StringType,
+ typename TypeCodeType,
+ class CaseArrayType,
+ class RefCountPolicy>
CORBA::Boolean
TAO::TypeCode::Union<StringType,
TypeCodeType,
diff --git a/TAO/tao/AnyTypeCode/Union_TypeCode.h b/TAO/tao/AnyTypeCode/Union_TypeCode.h
index 9757c9f9d65..abc4fe801e4 100644
--- a/TAO/tao/AnyTypeCode/Union_TypeCode.h
+++ b/TAO/tao/AnyTypeCode/Union_TypeCode.h
@@ -82,6 +82,9 @@ namespace TAO
virtual void tao_release (void);
//@}
+ /// Accessor for cases_
+ const CaseArrayType& cases(void) const;
+
protected:
/**
diff --git a/TAO/tao/AnyTypeCode/Value_TypeCode.cpp b/TAO/tao/AnyTypeCode/Value_TypeCode.cpp
index dc6aa73d6f7..8155a50d06c 100644
--- a/TAO/tao/AnyTypeCode/Value_TypeCode.cpp
+++ b/TAO/tao/AnyTypeCode/Value_TypeCode.cpp
@@ -112,6 +112,32 @@ template <typename StringType,
typename TypeCodeType,
class FieldArrayType,
class RefCountPolicy>
+const TypeCodeType&
+TAO::TypeCode::Value<StringType,
+ TypeCodeType,
+ FieldArrayType,
+ RefCountPolicy>::concrete_base (void) const
+{
+ return concrete_base_;
+}
+
+template <typename StringType,
+ typename TypeCodeType,
+ class FieldArrayType,
+ class RefCountPolicy>
+const FieldArrayType&
+TAO::TypeCode::Value<StringType,
+ TypeCodeType,
+ FieldArrayType,
+ RefCountPolicy>::fields (void) const
+{
+ return fields_;
+}
+
+template <typename StringType,
+ typename TypeCodeType,
+ class FieldArrayType,
+ class RefCountPolicy>
CORBA::Boolean
TAO::TypeCode::Value<StringType,
TypeCodeType,
diff --git a/TAO/tao/AnyTypeCode/Value_TypeCode.h b/TAO/tao/AnyTypeCode/Value_TypeCode.h
index 8f386b2e731..34abe3b7ec4 100644
--- a/TAO/tao/AnyTypeCode/Value_TypeCode.h
+++ b/TAO/tao/AnyTypeCode/Value_TypeCode.h
@@ -83,6 +83,12 @@ namespace TAO
virtual void tao_release (void);
//@}
+ /// Accessor for concrete_base_
+ const TypeCodeType& concrete_base(void) const;
+
+ /// Accessor for fields_
+ const FieldArrayType& fields() const;
+
protected:
/**
diff --git a/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp b/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp
index 62f9d46786c..5f9e5e65791 100644
--- a/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp
+++ b/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp
@@ -4,10 +4,6 @@
#include "tao/CSD_Framework/CSD_Framework_Loader.h"
#include "tao/CSD_Framework/CSD_Object_Adapter_Factory.h"
#include "tao/CSD_Framework/CSD_Strategy_Repository.h"
-#include "tao/CSD_Framework/CSD_ORBInitializer.h"
-#include "tao/PI/DLL_Resident_ORB_Initializer.h"
-#include "tao/ORBInitializer_Registry.h"
-#include "tao/ORB_Core.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -24,13 +20,12 @@ TAO_CSD_Framework_Loader::~TAO_CSD_Framework_Loader (void)
int
TAO_CSD_Framework_Loader::static_init (void)
{
- ACE_Service_Config::process_directive
- (ace_svc_desc_TAO_CSD_Object_Adapter_Factory);
-
- ACE_Service_Config::process_directive
- (ace_svc_desc_TAO_CSD_Strategy_Repository);
-
- ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_Framework_Loader);
+ ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_CSD_Object_Adapter_Factory);
+ ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_CSD_Strategy_Repository);
+ ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_CSD_Framework_Loader);
return 0;
}
@@ -46,50 +41,6 @@ TAO_CSD_Framework_Loader::init (int, ACE_TCHAR* [])
this->initialized_ = true;
- // Register the ORB initializer.
- try
- {
- PortableInterceptor::ORBInitializer_ptr temp_orb_initializer =
- PortableInterceptor::ORBInitializer::_nil ();
-
- /// Register the CSD ORBInitializer.
- ACE_NEW_THROW_EX (temp_orb_initializer,
- TAO_CSD_ORBInitializer,
- CORBA::NO_MEMORY (
- CORBA::SystemException::_tao_minor_code (
- TAO::VMCID,
- ENOMEM),
- CORBA::COMPLETED_NO));
-
- PortableInterceptor::ORBInitializer_var orb_initializer;
- orb_initializer = temp_orb_initializer;
-
- PortableInterceptor::ORBInitializer_ptr temp_dll_initializer =
- PortableInterceptor::ORBInitializer::_nil ();
-
- ACE_NEW_THROW_EX (temp_dll_initializer,
- PortableInterceptor::DLL_Resident_ORB_Initializer(
- orb_initializer.in (),
- ACE_TEXT ("TAO_CSD_ThreadPool")),
- CORBA::NO_MEMORY (
- CORBA::SystemException::_tao_minor_code (
- TAO::VMCID,
- ENOMEM),
- CORBA::COMPLETED_NO));
-
- PortableInterceptor::ORBInitializer_var dll_initializer;
- dll_initializer = temp_dll_initializer;
-
- PortableInterceptor::register_orb_initializer (dll_initializer.in ());
- }
- catch (const ::CORBA::Exception& ex)
- {
- ex._tao_print_exception (
- "Unexpected exception caught while "
- "initializing the CSD Framework");
- return 1;
- }
-
return 0;
}
diff --git a/TAO/tao/CSD_Framework/CSD_ORBInitializer.h b/TAO/tao/CSD_Framework/CSD_ORBInitializer.h
index 1b8570ca311..d82a8c5d8c6 100644
--- a/TAO/tao/CSD_Framework/CSD_ORBInitializer.h
+++ b/TAO/tao/CSD_Framework/CSD_ORBInitializer.h
@@ -36,7 +36,7 @@
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
-class TAO_CSD_ORBInitializer
+class TAO_CSD_FW_Export TAO_CSD_ORBInitializer
: public virtual PortableInterceptor::ORBInitializer
, public virtual ::CORBA::LocalObject
{
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp
index 87edf4b4c13..49603a489a6 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp
@@ -36,6 +36,7 @@ TAO::CSD::TP_Queue::put(TP_Request* request)
this->tail_->next_ = request;
this->tail_ = request;
}
+
}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h
index 9912c0e613a..3cdfdbe942c 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h
@@ -22,6 +22,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/Versioned_Namespace.h"
+#include "tao/orbconf.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -77,7 +78,6 @@ namespace TAO
/// visiting every request).
void accept_visitor(TP_Queue_Visitor& visitor);
-
private:
/// The request at the front of the queue.
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp
index a1e7be7af59..df57ecaaac7 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp
@@ -34,103 +34,90 @@ TAO::CSD::TP_Strategy_Factory::init (int argc,
initialized = 1;
TAO_CSD_Strategy_Repository *repo =
- ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance ("TAO_CSD_Strategy_Repository");
-
- if (repo != 0)
- repo->init(0,0);
+ ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
+ (ACE_TEXT ("TAO_CSD_Strategy_Repository"));
+
+ if (repo == 0)
+ {
+ TAO_CSD_ThreadPool::init ();
+ repo = ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
+ (ACE_TEXT ("TAO_CSD_Strategy_Repository"));
+ }
+
+ if (repo == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - TP_Strategy_Factory - ")
+ ACE_TEXT ("cannot initialize strategy repo\n")));
+ }
+ return -1;
+ }
+
+ repo->init(0,0);
// Parse any service configurator parameters.
for (int curarg = 0; curarg < argc; curarg++)
- if (ACE_OS::strcasecmp (argv[curarg],
- ACE_TEXT("-CSDtp")) == 0)
- {
- ACE_CString poa_name;
- unsigned long num_threads = 1;
- bool serialize_servants = true;
-
- curarg++;
- if (curarg < argc)
- {
- // Parse the parameter
- ACE_CString arg ((const char *)argv[curarg]);
- ACE_CString::size_type pos = arg.find (':');
-
- if (pos == ACE_CString::npos)
- {
- poa_name = arg;
- }
- else
- {
- poa_name = arg.substr (0, pos);
-
- ACE_CString arg_remainder =
- arg.substr (pos + 1, arg.length () - pos);
-
- ACE_CString num_thread_str;
-
- pos = arg_remainder.find (':');
-
- if (pos == ACE_CString::npos)
- {
- num_thread_str = arg_remainder;
- }
- else
- {
- num_thread_str = arg_remainder.substr (0, pos);
-
- ACE_CString off_str =
- arg_remainder.substr (pos + 1, arg.length () - pos);
-
- // Case-insensitive string comparison.
- if (ACE_OS::strcasecmp (off_str.c_str(), "OFF") == 0)
- {
- serialize_servants = false;
- }
- }
-
- num_threads = ACE_OS::strtoul (num_thread_str.c_str (), 0, 10);
-
- if (num_threads == 0)
- {
- // Minimum of 1 thread required.
- num_threads = 1;
- }
- }
-
- // Create the ThreadPool strategy for each named poa.
- TP_Strategy* strategy = 0;
- ACE_NEW_RETURN (strategy,
- TP_Strategy (num_threads, serialize_servants),
- -1);
- CSD_Framework::Strategy_var objref = strategy;
-
- TAO_CSD_Strategy_Repository *repo =
- ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
- ("TAO_CSD_Strategy_Repository");
-
- if (repo == 0)
- {
- TAO_CSD_ThreadPool::init ();
- repo = ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance (
- "TAO_CSD_Strategy_Repository"
- );
- }
-
-
- repo->add_strategy (poa_name, strategy);
- }
- }
- else
- {
- if (TAO_debug_level > 0)
- {
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT("CSD_ORB_Loader: Unknown option ")
- ACE_TEXT("<%s>.\n"),
- argv[curarg]));
- }
- }
-
+ {
+ if (ACE_OS::strcasecmp (argv[curarg],
+ ACE_TEXT("-CSDtp")) == 0)
+ {
+ ACE_CString poa_name;
+ unsigned long num_threads = 1;
+ bool serialize_servants = true;
+
+ curarg++;
+ if (curarg >= argc)
+ {
+ return -1;
+ }
+
+ // Parse the parameter
+ ACE_TCHAR *sep = ACE_OS::strchr (argv[curarg],':');
+ if (sep == 0)
+ {
+ poa_name = ACE_TEXT_ALWAYS_CHAR (argv[curarg]);
+ }
+ else
+ {
+ *sep = 0;
+ poa_name = ACE_TEXT_ALWAYS_CHAR (argv[curarg]);
+ num_threads = ACE_OS::strtol (sep + 1, &sep, 10);
+ if (*sep != 0 && *sep != ':')
+ {
+ return -1;
+ }
+ if (*sep == ':')
+ {
+ if (ACE_OS::strcasecmp (sep + 1, "OFF") == 0)
+ {
+ serialize_servants = false;
+ }
+ }
+ }
+
+ // Create the ThreadPool strategy for each named poa.
+ TP_Strategy* strategy = 0;
+ ACE_NEW_RETURN (strategy,
+ TP_Strategy (num_threads, serialize_servants),
+ -1);
+ CSD_Framework::Strategy_var objref = strategy;
+ repo->add_strategy (poa_name, strategy);
+
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT("CSD_ORB_Loader: Unknown option ")
+ ACE_TEXT("<%s>.\n"),
+ argv[curarg]));
+ }
+ return -1;
+ }
+ }
return 0;
}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp
index c96a65eccb6..80f1ac5f23a 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp
@@ -45,11 +45,11 @@ TAO::CSD::TP_Task::add_request(TP_Request* request)
int
-TAO::CSD::TP_Task::open(void* num_threads_ptr)
+TAO::CSD::TP_Task::open(void* args)
{
Thread_Counter num = 1;
- Thread_Counter* tmp = static_cast<Thread_Counter*> (num_threads_ptr);
+ Thread_Counter* tmp = static_cast<Thread_Counter*> (args);
if (tmp == 0)
{
@@ -78,7 +78,8 @@ TAO::CSD::TP_Task::open(void* num_threads_ptr)
{
ACE_ERROR_RETURN((LM_ERROR,
ACE_TEXT ("(%P|%t) TP_Task failed to open. ")
- ACE_TEXT ("num_threads (%u) is too large. Max is %d.\n"),
+ ACE_TEXT ("num_threads (%u) is too large. ")
+ ACE_TEXT ("Max is %d.\n"),
num, MAX_THREADPOOL_TASK_WORKER_THREADS),
-1);
}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h
index fea7b2ecc4e..ce5c4b705c6 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h
@@ -89,7 +89,7 @@ namespace TAO
bool add_request(TP_Request* request);
/// Activate the worker threads
- virtual int open(void* num_threads_ptr = 0);
+ virtual int open(void* args = 0);
/// The "mainline" executed by each worker thread.
virtual int svc();
diff --git a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp
index 6b83baebc12..120f88a3a73 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp
+++ b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp
@@ -6,6 +6,12 @@
#include "tao/debug.h"
#include "ace/Dynamic_Service.h"
+#include "tao/CSD_Framework/CSD_ORBInitializer.h"
+#include "tao/PI/DLL_Resident_ORB_Initializer.h"
+#include "tao/ORBInitializer_Registry.h"
+#include "tao/ORB_Core.h"
+
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
int
@@ -17,7 +23,55 @@ TAO_CSD_ThreadPool::init (void)
initialized = 1;
TAO_CSD_Framework_Loader::static_init();
- return ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_TP_Strategy_Factory);
+
+ // Register the ORB initializer.
+ try
+ {
+ PortableInterceptor::ORBInitializer_ptr temp_orb_initializer =
+ PortableInterceptor::ORBInitializer::_nil ();
+
+ /// Register the CSD ORBInitializer.
+ ACE_NEW_THROW_EX (temp_orb_initializer,
+ TAO_CSD_ORBInitializer,
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+
+ PortableInterceptor::ORBInitializer_var orb_initializer;
+ orb_initializer = temp_orb_initializer;
+
+ PortableInterceptor::ORBInitializer_ptr temp_dll_initializer =
+ PortableInterceptor::ORBInitializer::_nil ();
+
+ ACE_NEW_THROW_EX (temp_dll_initializer,
+ PortableInterceptor::DLL_Resident_ORB_Initializer(
+ orb_initializer.in (),
+ ACE_TEXT ("TAO_CSD_ThreadPool")),
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+
+ PortableInterceptor::ORBInitializer_var dll_initializer;
+ dll_initializer = temp_dll_initializer;
+
+ PortableInterceptor::register_orb_initializer (
+ dll_initializer.in ());
+ }
+ catch (const ::CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ "Unexpected exception caught while "
+ "initializing the CSD Framework");
+ return 1;
+ }
+
+
+ return ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_CSD_TP_Strategy_Factory);
}
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h
index 82a5f082ee4..8b22f1a1b2c 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h
+++ b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h
@@ -17,8 +17,6 @@
#include "tao/CSD_ThreadPool/CSD_TP_Export.h"
#include "tao/Versioned_Namespace.h"
-#include "ace/Service_Object.h"
-#include "ace/Service_Config.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
@@ -28,11 +26,13 @@
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
/**
- * @class TP_Strategy_Factory
+ * @class TAO_CSD_ThreadPool
*
- * @brief An ACE_Service_Object capable of creating TP_Strategy objects.
+ * @brief the static initializer for the CSD Thread Pool library
*
- * TBD - Explain in more detail.
+ * The loader appears to be born of the CSD_TP_Factory, which is the
+ * real service object. This separation seems to be necesary to ensure
+ * the CSD_Framework gets loaded prior to initializing the TP Factory.
*
*/
class TAO_CSD_TP_Export TAO_CSD_ThreadPool
diff --git a/TAO/tao/Client_Strategy_Factory.h b/TAO/tao/Client_Strategy_Factory.h
index ece676673ea..4ccdc1543f6 100644
--- a/TAO/tao/Client_Strategy_Factory.h
+++ b/TAO/tao/Client_Strategy_Factory.h
@@ -32,6 +32,11 @@ ACE_END_VERSIONED_NAMESPACE_DECL
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+namespace TAO
+{
+ struct Invocation_Retry_Params;
+}
+
class TAO_Transport_Mux_Strategy;
class TAO_Wait_Strategy;
class TAO_Transport;
@@ -84,6 +89,11 @@ public:
* Only applicable to RW wait strategy
*/
virtual bool use_cleanup_options (void) const = 0;
+
+ /// Return the parameters used to optionally retry invocation
+ /// after an exception occurs.
+ virtual const TAO::Invocation_Retry_Params &invocation_retry_params (void) const = 0;
+
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp
index e302ccaff0f..1385d2fb5e5 100644
--- a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp
+++ b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp
@@ -96,8 +96,11 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
+ ACE_UNUSED_ARG (retry_state);
+
// Simple sanity check
if (this->mode_ != TAO_DII_INVOCATION ||
this->type_ != TAO_TWOWAY_INVOCATION)
@@ -216,8 +219,11 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
+ ACE_UNUSED_ARG (retry_state);
+
// Simple sanity check
if (this->mode_ != TAO_DII_DEFERRED_INVOCATION ||
this->type_ != TAO_TWOWAY_INVOCATION)
@@ -288,7 +294,8 @@ namespace TAO
TAO_Operation_Details &,
CORBA::Object_var &,
Profile_Transport_Resolver &,
- ACE_Time_Value *&)
+ ACE_Time_Value *&,
+ Invocation_Retry_State *)
{
return TAO_INVOKE_FAILURE;
}
diff --git a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.h b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.h
index 80b2c6f9274..a7586d5a71b 100644
--- a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.h
+++ b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.h
@@ -102,7 +102,8 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
virtual Invocation_Status invoke_collocated_i (
TAO_Stub *stub,
@@ -154,7 +155,8 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
virtual Invocation_Status invoke_collocated_i (
TAO_Stub *stub,
@@ -199,7 +201,8 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
};
#endif /* TAO_HAS_AMI */
diff --git a/TAO/tao/Dynamic_TP/DTP_Config.cpp b/TAO/tao/Dynamic_TP/DTP_Config.cpp
new file mode 100644
index 00000000000..47768ce0b99
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Config.cpp
@@ -0,0 +1,327 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_Config.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/DTP_ORBInitializer.h"
+
+#include "tao/debug.h"
+#include "ace/Dynamic_Service.h"
+#include "ace/OS_NS_strings.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_Config_Registry_Installer::TAO_DTP_Config_Registry_Installer (void)
+{
+ ACE_Service_Config::process_directive (ace_svc_desc_TAO_DTP_Config_Registry);
+}
+
+
+TAO_DTP_Config_Registry::TAO_DTP_Config_Registry (void)
+{
+}
+
+TAO_DTP_Config_Registry::~TAO_DTP_Config_Registry (void)
+{
+}
+
+int
+TAO_DTP_Config_Registry::init (int , ACE_TCHAR* [] )
+{
+ return 0;
+}
+
+bool
+TAO_DTP_Config_Registry::find (const ACE_CString& name,
+ TAO_DTP_Definition &entry)
+{
+ return registry_.find (name, entry) == 0;
+}
+
+int
+TAO_DTP_Config_Registry::bind (const ACE_CString& name,
+ TAO_DTP_Definition &entry)
+{
+ return registry_.bind (name, entry);
+}
+
+int
+TAO_DTP_Config_Registry::rebind (const ACE_CString& name,
+ TAO_DTP_Definition &entry)
+{
+ return registry_.rebind (name, entry);
+}
+
+//-------------------------------------------------------------------------
+
+TAO_DTP_Config::TAO_DTP_Config (void)
+{
+}
+
+TAO_DTP_Config::~TAO_DTP_Config (void)
+{
+}
+
+int
+TAO_DTP_Config::init (int argc, ACE_TCHAR* argv[])
+{
+ TAO_DTP_Definition entry;
+
+ ACE_TCHAR *name = 0;
+ bool overwrite = false;
+
+ int curarg = 0;
+ int r = 0;
+
+ for (curarg = 0; curarg < argc; ++curarg)
+ {
+ long val = 0;
+ if ((r = this->parse_string (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPName"),name )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ }
+ else if ((r = this->parse_bool (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPOverwrite"),
+ overwrite )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPMin"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.min_threads_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPInit"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.init_threads_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPMax"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.max_threads_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPStack"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.stack_size_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPTImeout"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.timeout_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPQueue"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.queue_depth_ = val;
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Config - ")
+ ACE_TEXT ("Unrecognized argv[%d], %C\n"),
+ curarg, argv[curarg]));
+ }
+ return -1;
+ }
+ }
+
+ if ((entry.max_threads_ != -1 && entry.max_threads_ < entry.init_threads_) ||
+ (entry.min_threads_ > entry.init_threads_))
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Config - ")
+ ACE_TEXT ("thread count constraint ")
+ ACE_TEXT ("violated, min: %d <= init: %d <= max: ")
+ ACE_TEXT ("%d or max = -1\n"),
+ entry.min_threads_,
+ entry.init_threads_,
+ entry.max_threads_));
+ }
+ return 0;
+ }
+
+ ACE_CString name_str = name;
+ ACE_Service_Gestalt *current = ACE_Service_Config::current();
+ TAO_DTP_Config_Registry* registry =
+ ACE_Dynamic_Service<TAO_DTP_Config_Registry>::instance
+ (current, "DTP_Config_Registry", true);
+
+ if (registry == 0)
+ {
+ current->process_directive (ace_svc_desc_TAO_DTP_Config_Registry);
+ registry = ACE_Dynamic_Service<TAO_DTP_Config_Registry>::instance
+ (current, "DTP_Config_Registry", true);
+ if (registry == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Config - ")
+ ACE_TEXT ("cannot initialize registry\n")));
+ }
+ return -1;
+ }
+ }
+
+ if (!overwrite)
+ {
+ return registry->bind(name_str, entry);
+ }
+ else
+ {
+ return registry->rebind(name_str, entry);
+ }
+ return 0;
+}
+
+int
+TAO_DTP_Config::parse_long (int &curarg,
+ int argc, ACE_TCHAR *argv[],
+ const ACE_TCHAR *match, long &value)
+{
+ ACE_TCHAR *str;
+ int result = this->parse_string (curarg, argc, argv, match, str);
+ if (result < 1)
+ return result;
+
+ ACE_TCHAR *err = 0;
+ value = ACE_OS::strtol (str, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (match, str);
+ return -1;
+ }
+ return 1;
+}
+
+int
+TAO_DTP_Config::parse_bool (int &curarg,
+ int argc, ACE_TCHAR *argv[],
+ const ACE_TCHAR *match, bool &value)
+{
+ long num;
+ int result = this->parse_long (curarg, argc, argv, match, num);
+ if (result < 1)
+ return result;
+
+ value = num != 0;
+
+ return 1;
+}
+
+int
+TAO_DTP_Config::parse_string (int &curarg,
+ int argc, ACE_TCHAR *argv[],
+ const ACE_TCHAR *match, ACE_TCHAR *&value)
+{
+ if (ACE_OS::strcasecmp (argv[curarg], match) != 0)
+ return 0;
+
+ ++curarg;
+ if (curarg >= argc)
+ {
+ this->report_option_value_error (match, ACE_TEXT("<missing>"));
+ return -1;
+ }
+
+ value = argv[curarg];
+ return 1;
+}
+
+
+void
+TAO_DTP_Config::report_option_value_error (const ACE_TCHAR* option_name,
+ const ACE_TCHAR* option_value)
+{
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Config - unknown ")
+ ACE_TEXT ("argument <%s> for <%s>\n"),
+ option_value, option_name));
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_Config_Registry)
+ACE_STATIC_SVC_DEFINE (TAO_DTP_Config_Registry,
+ ACE_TEXT ("DTP_Config_Registry"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_Config_Registry),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_Config)
+ACE_STATIC_SVC_DEFINE (TAO_DTP_Config,
+ ACE_TEXT ("DTP_Config"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_Config),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 */
+
diff --git a/TAO/tao/Dynamic_TP/DTP_Config.h b/TAO/tao/Dynamic_TP/DTP_Config.h
new file mode 100644
index 00000000000..6deddf381de
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Config.h
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file
+ *
+ * $Id$
+ *
+ * Header file for Loading DynamicTP Configurations.
+ *
+ *
+ * @author
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_CONFIG_H
+#define TAO_DYNAMIC_TP_CONFIG_H
+#include /**/ "ace/pre.h"
+
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "ace/Service_Object.h"
+#include "ace/Service_Config.h"
+#include "ace/RB_Tree.h"
+#include "ace/Synch.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+struct TAO_Dynamic_TP_Export TAO_DTP_Definition
+{
+ int min_threads_; // a default of -1 implies Lifespan of INFINITE, > 0 implies IDLE
+ int init_threads_; // default to 5
+ int max_threads_; // a default of -1 implies no limit.
+ size_t stack_size_;
+ ACE_Time_Value timeout_; // default to 60 seconds
+ int queue_depth_;
+
+ // Create explicit constructor to eliminate issues with non-initialized struct values.
+ TAO_DTP_Definition() :
+ min_threads_(-1),
+ init_threads_(5),
+ max_threads_(-1),
+ stack_size_(ACE_DEFAULT_THREAD_STACKSIZE),
+ timeout_(60,0),
+ queue_depth_(0){}
+
+};
+
+class TAO_Dynamic_TP_Export TAO_DTP_Config_Registry_Installer
+{
+ public:
+ TAO_DTP_Config_Registry_Installer (void);
+};
+
+class TAO_Dynamic_TP_Export TAO_DTP_Config_Registry : public ACE_Service_Object
+{
+public:
+ TAO_DTP_Config_Registry (void);
+ virtual ~TAO_DTP_Config_Registry (void);
+
+ virtual int init (int argc, ACE_TCHAR* []);
+
+ /// initializes the supplied set value with the configuration associated with the name, or returns false.
+ bool find (const ACE_CString& name, TAO_DTP_Definition &entry);
+
+ int bind (const ACE_CString& name, TAO_DTP_Definition &entry);
+ int rebind (const ACE_CString& name, TAO_DTP_Definition &entry);
+
+ private:
+ typedef ACE_RB_Tree<ACE_CString, TAO_DTP_Definition, ACE_Less_Than<ACE_CString>, ACE_Null_Mutex> Registry;
+ Registry registry_;
+};
+
+class TAO_Dynamic_TP_Export TAO_DTP_Config : public ACE_Service_Object
+{
+public:
+ /// Constructor.
+ TAO_DTP_Config (void);
+
+ /// Destructor.
+ virtual ~TAO_DTP_Config (void);
+
+ /// Read a definition parameter set from the supplied args.
+ /// There must be a -TPName argument, which, if replicated will cause the set to be ignored, unless -TPOverwrite is also set
+ /// constriants: min threads <= initial threads <= max_threads.
+ /// defaults: min threads = initial = max = 5
+ /// default lifespan = infinite
+ /// idle timeout is in secondes, default = 60
+ /// default stack size = 0, system defined default used.
+ /// queue depth is in number of messages, default is infinite
+ /// Init can be called multiple times,
+ virtual int init (int argc, ACE_TCHAR* []);
+
+private:
+ int parse_long (int &curarg, int argc, ACE_TCHAR* argv[], const ACE_TCHAR *match, long &value);
+ int parse_bool (int &curarg, int argc, ACE_TCHAR* argv[], const ACE_TCHAR *match, bool &value);
+ int parse_string (int &curarg, int argc, ACE_TCHAR* argv[], const ACE_TCHAR *match, ACE_TCHAR *&value);
+ void report_option_value_error (const ACE_TCHAR* option_name,
+ const ACE_TCHAR* option_value);
+
+};
+
+static TAO_DTP_Config_Registry_Installer config_installer;
+
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP, TAO_DTP_Config_Registry)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP, TAO_DTP_Config_Registry)
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP, TAO_DTP_Config)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP, TAO_DTP_Config)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+#endif /* TAO_DYNAMIC_TP_CONFIG_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp
new file mode 100644
index 00000000000..d193c3b54ea
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp
@@ -0,0 +1,132 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_ORBInitializer.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h"
+#include "tao/Dynamic_TP/DTP_Thread_Pool.h"
+#include "tao/Exception.h"
+#include "tao/ORB_Core.h"
+#include "tao/PI/ORBInitInfo.h"
+#include "tao/debug.h"
+
+#include "ace/Service_Repository.h"
+#include "ace/Svc_Conf.h"
+#include "ace/Sched_Params.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_ORBInitializer::TAO_DTP_ORBInitializer (/*const ACE_CString &tplist*/)
+{
+
+}
+
+void
+TAO_DTP_ORBInitializer::pre_init (PortableInterceptor::ORBInitInfo_ptr info)
+{
+ TAO_ORBInitInfo_var tao_info = TAO_ORBInitInfo::_narrow (info);
+
+ if (CORBA::is_nil (tao_info.in ()))
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) TAO_DTP_ORBInitializer::pre_init:\n")
+ ACE_TEXT ("(%P|%t) Unable to narrow ")
+ ACE_TEXT ("\"PortableInterceptor::ORBInitInfo_ptr\" to\n")
+ ACE_TEXT ("(%P|%t) \"TAO_ORBInitInfo *.\"\n")));
+
+ throw ::CORBA::INTERNAL ();
+ }
+
+
+ ACE_Service_Gestalt *gestalt = tao_info->orb_core ()->configuration();
+
+ ACE_Service_Object * const config_obj =
+ ACE_Dynamic_Service<ACE_Service_Object>::instance (
+ gestalt,
+ "DTP_Config",
+ true);
+ if (config_obj == 0)
+ {
+ // no config manager object loaded
+ return;
+ }
+
+ TAO_DTP_Config *config_mgr = dynamic_cast<TAO_DTP_Config *>(config_obj);
+ if (config_mgr == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) TAO_DTP_ORBInitializer::pre_init:\n")
+ ACE_TEXT ("(%P|%t) Unable to resolve DTP_Config ")
+ ACE_TEXT ("object\n")));
+
+ throw ::CORBA::INTERNAL ();
+ }
+
+ // Set the name of the thread lane resources manager to be
+ // DTP_Thread_Lane_Resources_Manager.
+ tao_info->orb_core ()->orb_params ()
+ ->thread_lane_resources_manager_factory_name (
+ "DTP_Thread_Lane_Resources_Manager_Factory");
+ ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_DTP_Thread_Lane_Resources_Manager_Factory);
+
+}
+
+void
+TAO_DTP_ORBInitializer::post_init (PortableInterceptor::ORBInitInfo_ptr info)
+{
+ TAO_ORBInitInfo_var tao_info = TAO_ORBInitInfo::_narrow (info);
+
+ TAO_Thread_Lane_Resources_Manager &tlrm =
+ tao_info->orb_core ()->thread_lane_resources_manager();
+
+ ACE_Service_Gestalt *gestalt = tao_info->orb_core ()->configuration();
+
+ const char *dtp_name =
+ tao_info->orb_core ()->orb_params ()->dynamic_thread_pool_config_name ();
+
+ if (dtp_name != 0 && dtp_name[0] != 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) TAO_DTP_ORBInitializer::post_init ")
+ ACE_TEXT ("using thread pool name %s\n"), dtp_name));
+ }
+
+ TAO_DTP_Config_Registry *config_registry =
+ dynamic_cast<TAO_DTP_Config_Registry *>
+ (ACE_Dynamic_Service<ACE_Service_Object>::instance
+ (gestalt, "DTP_Config_Registry", true));
+
+ TAO_DTP_Definition def;
+
+ if (!config_registry->find(dtp_name, def))
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) TAO_DTP_ORBInitializer::")
+ ACE_TEXT ("post_init:\n")
+ ACE_TEXT ("(%P|%t) Unable to resolve ")
+ ACE_TEXT ("DTP_Config object\n")));
+
+ throw ::CORBA::INTERNAL ();
+ }
+
+ TAO_DTP_Thread_Lane_Resources_Manager &dtp_tlrm =
+ dynamic_cast<TAO_DTP_Thread_Lane_Resources_Manager &>(tlrm);
+
+ dtp_tlrm.tp_manager().create_threadpool (def);
+ }
+
+
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_ORBInitializer.h b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.h
new file mode 100644
index 00000000000..770ac31b50d
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.h
@@ -0,0 +1,72 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_ORBInitializer.h
+ *
+ * $Id$
+ *
+ * @author Ossama Othman <ossama@uci.edu>
+ */
+//=============================================================================
+
+
+#ifndef TAO_DYNAMIC_TP_ORB_INITIALIZER_H
+#define TAO_DYNAMIC_TP_ORB_INITIALIZER_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/PI/PI.h"
+#include "tao/LocalObject.h"
+
+// This is to remove "inherits via dominance" warnings from MSVC.
+// MSVC is being a little too paranoid.
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4250)
+#endif /* _MSC_VER */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/// Dynamic_TP ORB initializer.
+class TAO_DTP_ORBInitializer
+ : public virtual PortableInterceptor::ORBInitializer
+ , public virtual ::CORBA::LocalObject
+{
+public:
+
+ TAO_DTP_ORBInitializer (void);
+
+ virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info);
+
+ virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info);
+
+private:
+
+ /// Register Dynamic_TP policy factories.
+ void register_policy_factories (PortableInterceptor::ORBInitInfo_ptr info);
+
+private:
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_DYNAMIC_TP_ORB_INITIALIZER_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_ORB_Loader.cpp b/TAO/tao/Dynamic_TP/DTP_ORB_Loader.cpp
new file mode 100644
index 00000000000..838e0a7e3d1
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_ORB_Loader.cpp
@@ -0,0 +1,113 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_ORB_Loader.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/DTP_ORBInitializer.h"
+
+#include "tao/debug.h"
+#include "tao/ORB_Constants.h"
+#include "tao/ORBInitializer_Registry.h"
+#include "tao/SystemException.h"
+#include "ace/Dynamic_Service.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/Arg_Shifter.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_ORB_Loader::TAO_DTP_ORB_Loader (void)
+ : initialized_ (false)
+{
+}
+
+TAO_DTP_ORB_Loader::~TAO_DTP_ORB_Loader (void)
+{
+}
+
+int
+TAO_DTP_ORB_Loader::init (int argc, ACE_TCHAR* argv[])
+{
+ ACE_TRACE ("TAO_DTP_ORB_Loader::init");
+
+ // Only allow initialization once.
+ if (this->initialized_)
+ return 0;
+ this->initialized_ = true;
+
+ int curarg = 0;
+ for (curarg = 0; curarg < argc; ++curarg)
+ {
+ if (ACE_OS::strcasecmp (argv[curarg], ACE_TEXT ("-DTPORB")) == 0)
+ {
+ ++curarg;
+ if (curarg >= argc)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_ORB_Loader - ")
+ ACE_TEXT ("DTPORB argument missing value\n")));
+ }
+ return -1;
+ }
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_ORB_Loader -")
+ ACE_TEXT (" Unrecognized argv[%d], %C\n"),
+ curarg, argv[curarg]));
+ }
+ return -1;
+ }
+ }
+
+ // Register the ORB initializer.
+ try
+ {
+ PortableInterceptor::ORBInitializer_ptr temp_orb_initializer =
+ PortableInterceptor::ORBInitializer::_nil ();
+
+ /// Register the DynamicTP ORBInitializer.
+ ACE_NEW_THROW_EX (temp_orb_initializer,
+ TAO_DTP_ORBInitializer (),
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+
+ PortableInterceptor::ORBInitializer_var orb_initializer;
+ orb_initializer = temp_orb_initializer;
+
+ PortableInterceptor::register_orb_initializer (orb_initializer.in ());
+ }
+ catch (const ::CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ "Unexpected exception caught while "
+ "initializing the RTORB");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_ORB_Loader)
+ACE_STATIC_SVC_DEFINE (TAO_DTP_ORB_Loader,
+ ACE_TEXT ("DTP_ORB_Loader"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_ORB_Loader),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 */
+
diff --git a/TAO/tao/Dynamic_TP/DTP_ORB_Loader.h b/TAO/tao/Dynamic_TP/DTP_ORB_Loader.h
new file mode 100644
index 00000000000..ffef32befd2
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_ORB_Loader.h
@@ -0,0 +1,63 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_ORB_Loader.h
+ *
+ * $Id$
+ *
+ * Header file for Loading DynamicTP.
+ *
+ *
+ * @author Phil Mesnier <mesnier_p@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_ORB_LOADER_H
+#define TAO_DYNAMIC_TP_ORB_LOADER_H
+#include /**/ "ace/pre.h"
+
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "ace/Service_Object.h"
+#include "ace/Service_Config.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_ORB_Core;
+
+class TAO_Dynamic_TP_Export TAO_DTP_ORB_Loader : public ACE_Service_Object
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_ORB_Loader (void);
+
+ /// Destructor.
+ virtual ~TAO_DTP_ORB_Loader (void);
+
+ /// Initialize the DynamicTP loader hooks.
+ virtual int init (int argc, ACE_TCHAR* []);
+
+private:
+ /// Set to true after init is called.
+ bool initialized_;
+};
+
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP, TAO_DTP_ORB_Loader)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP, TAO_DTP_ORB_Loader)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+#endif /* TAO_DYNAMIC_TP_ORB_LOADER_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Loader.cpp b/TAO/tao/Dynamic_TP/DTP_POA_Loader.cpp
new file mode 100644
index 00000000000..b11349f98a4
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Loader.cpp
@@ -0,0 +1,199 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_POA_Loader.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/debug.h"
+#include "tao/CSD_Framework/CSD_Framework_Loader.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/Dynamic_TP/DTP_POA_Strategy.h"
+#include "ace/OS_NS_strings.h"
+#include "tao/CSD_Framework/CSD_ORBInitializer.h"
+#include "tao/PI/DLL_Resident_ORB_Initializer.h"
+#include "tao/ORBInitializer_Registry.h"
+#include "tao/ORB_Core.h"
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_POA_Loader::TAO_DTP_POA_Loader (void)
+{
+}
+
+TAO_DTP_POA_Loader::~TAO_DTP_POA_Loader (void)
+{
+}
+
+int
+TAO_DTP_POA_Loader::init (int argc, ACE_TCHAR* argv[])
+{
+ //TAO_debug_level = 5;
+
+ ACE_TRACE ("TAO_DTP_POA_Loader::init");
+
+ // Only allow initialization once.
+ static bool initialized = false;
+ if (initialized)
+ return 0;
+ initialized = true;
+
+ TAO_CSD_Strategy_Repository * repo =
+ ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
+ ("TAO_CSD_Strategy_Repository");
+
+
+ /* Now create a POA Configuration Map Registry to look up what
+ thread pool settings are associated with each POA
+ */
+
+ if (repo == 0)
+ {
+ ACE_Service_Config::process_directive(
+ ace_svc_desc_TAO_CSD_Strategy_Repository);
+ repo = ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
+ ("TAO_CSD_Strategy_Repository");
+ }
+
+ if (repo == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Loader - ")
+ ACE_TEXT ("cannot initialize strategy repo\n")));
+ }
+ return -1;
+ }
+
+ repo->init(0,0);
+
+ for (int curarg = 0; curarg < argc; curarg++)
+ {
+
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Loader - ")
+ ACE_TEXT ("parsing args\n")));
+ }
+
+ if (ACE_OS::strcasecmp (argv[curarg], ACE_TEXT ("-DTPPOAConfigMap"))
+ == 0)
+ {
+ ++curarg;
+ if (curarg >= argc)
+ {
+ this->report_option_value_error (ACE_TEXT ("-DTPPOAConfigMap"),
+ ACE_TEXT("<missing>"));
+ return -1;
+ }
+ if ((this->load_poa_map (argv[curarg], repo)) < 0)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+
+ /*
+ If we get here then we have another map set to process and
+ add to the map registry.
+ */
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("DTP_POA_Loader: Missing option\n")
+ ACE_TEXT ("Usage: -DTPPOAConfigMap <comma-separated ")
+ ACE_TEXT ("list of POAs>:<POA Config Name>\n")
+ ACE_TEXT ("<%s>.\n"),
+ argv[curarg]));
+ }
+ }
+
+ }
+
+ return 0;
+}
+
+
+int
+TAO_DTP_POA_Loader::load_poa_map (ACE_TCHAR *map,
+ TAO_CSD_Strategy_Repository *repo)
+{
+
+ ACE_CString poa_name;
+ ACE_CString config_name;
+ TAO_DTP_POA_Strategy * strategy_container = 0;
+
+ ACE_TCHAR *sep = ACE_OS::strchr (map, ':');
+
+ if (sep == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("DTP_POA_Loader: Missing option\n")
+ ACE_TEXT ("Usage: -DTPPOAConfigMap <comma-separated ")
+ ACE_TEXT ("list of POAs>:<POA Config Name>\n<%s>.\n"),
+ map));
+ }
+ return -1;
+ }
+
+ config_name = ACE_TEXT_ALWAYS_CHAR (sep + 1);
+ *sep = 0;
+
+ // Now that we have a config name and a null strategy
+ // implementation class we can allocate a new instance of a
+ // strategy configuration container.
+
+ ACE_NEW_RETURN(strategy_container,
+ TAO_DTP_POA_Strategy(config_name,
+ false), -1);
+
+ sep = ACE_OS::strchr (map, ',');
+ while (sep != 0)
+ {
+ *sep = 0;
+ poa_name = ACE_TEXT_ALWAYS_CHAR (map);
+ repo->add_strategy (poa_name, strategy_container);
+ map = sep + 1;
+ sep = ACE_OS::strchr (map, ',');
+ }
+ poa_name = ACE_TEXT_ALWAYS_CHAR (map);
+ repo->add_strategy(poa_name, strategy_container);
+
+ return 0;
+}
+
+void
+TAO_DTP_POA_Loader::report_option_value_error (const ACE_TCHAR* name,
+ const ACE_TCHAR* value)
+{
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Loader - unknown ")
+ ACE_TEXT ("argument <%s> for <%s>\n"),
+ value, name));
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_POA_Loader)
+ACE_STATIC_SVC_DEFINE (TAO_DTP_POA_Loader,
+ ACE_TEXT ("DTP_POA_Loader"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_POA_Loader),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Loader.h b/TAO/tao/Dynamic_TP/DTP_POA_Loader.h
new file mode 100644
index 00000000000..6af4993b46c
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Loader.h
@@ -0,0 +1,62 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_POA_Loader.h
+ *
+ * $Id$
+ *
+ * Header file for Loading DynamicTP.
+ *
+ *
+ * @author Phil Mesnier <mesnier_p@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_POA_LOADER_H
+#define TAO_DYNAMIC_TP_POA_LOADER_H
+#include /**/ "ace/pre.h"
+#include "tao/orbconf.h"
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/CSD_Framework/CSD_Strategy_Repository.h"
+#include "ace/Synch.h"
+#include "ace/Service_Object.h"
+#include "ace/Service_Config.h"
+#include "ace/RB_Tree.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_Dynamic_TP_Export TAO_DTP_POA_Loader : public ACE_Service_Object
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_POA_Loader (void);
+
+ /// Destructor.
+ virtual ~TAO_DTP_POA_Loader (void);
+
+ /// Initialize the DynamicTP loader hooks.
+ virtual int init (int argc, ACE_TCHAR* []);
+
+private:
+ /// Set to true after init is called.
+ int load_poa_map (ACE_TCHAR *map_str,
+ TAO_CSD_Strategy_Repository * reg);
+
+ void report_option_value_error (const ACE_TCHAR* option_name,
+ const ACE_TCHAR* option_value);
+};
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP, TAO_DTP_POA_Loader)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP, TAO_DTP_POA_Loader)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* TAO_DYNAMIC_TP_POA_LOADER_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Strategy.cpp b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.cpp
new file mode 100644
index 00000000000..e715319750b
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.cpp
@@ -0,0 +1,422 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_POA_Strategy.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Remote_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h"
+#include "tao/ORB_Core.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+
+#if !defined (__ACE_INLINE__)
+#include "tao/Dynamic_TP/DTP_POA_Strategy.inl"
+#endif /* ! __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+
+TAO_DTP_POA_Strategy::~TAO_DTP_POA_Strategy()
+{
+}
+
+TAO_DTP_POA_Strategy::CustomRequestOutcome
+TAO_DTP_POA_Strategy::custom_synch_request(
+ TAO::CSD::TP_Custom_Request_Operation* op)
+{
+
+ TAO::CSD::TP_Servant_State::HandleType servant_state =
+ this->get_servant_state(op->servant());
+
+ TAO::CSD::TP_Custom_Synch_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Custom_Synch_Request(op, servant_state.in ()),
+ REQUEST_REJECTED);
+
+ TAO::CSD::TP_Custom_Synch_Request_Handle request = req_ptr;
+
+ if (!this->dtp_task_.add_request (request.in ()))
+ {
+ // The request was rejected by the task.
+ return REQUEST_REJECTED;
+ }
+
+ // Now we wait until the request is handled (executed or cancelled).
+ return (request->wait ()) ? REQUEST_EXECUTED : REQUEST_CANCELLED;
+}
+
+TAO_DTP_POA_Strategy::CustomRequestOutcome
+TAO_DTP_POA_Strategy::custom_asynch_request (
+ TAO::CSD::TP_Custom_Request_Operation* op)
+{
+
+ TAO::CSD::TP_Servant_State::HandleType servant_state =
+ this->get_servant_state (op->servant ());
+
+ TAO::CSD::TP_Custom_Asynch_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Custom_Asynch_Request (op, servant_state.in ()),
+ REQUEST_REJECTED);
+
+ TAO::CSD::TP_Custom_Asynch_Request_Handle request = req_ptr;
+
+ return (this->dtp_task_.add_request (request.in ()))
+ ? REQUEST_DISPATCHED : REQUEST_REJECTED;
+}
+
+bool
+TAO_DTP_POA_Strategy::poa_activated_event_i (TAO_ORB_Core& orb_core)
+{
+
+ this->dtp_task_.thr_mgr (orb_core.thr_mgr ());
+
+ // Activates the worker threads, and waits until all have been started.
+ if (!this->config_initialized_)
+ {
+ TAO_DTP_Config_Registry * config_repo =
+ ACE_Dynamic_Service<TAO_DTP_Config_Registry>::instance
+ ("DTP_Config_Registry");
+
+ if (config_repo == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy - ")
+ ACE_TEXT ("cannot retrieve configuration repo\n")));
+ }
+ return false;
+ }
+ else
+ {
+ TAO_DTP_Definition config_entry;
+ if (!config_repo->find (this->dynamic_tp_config_name_, config_entry))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy - ")
+ ACE_TEXT ("warning: config not found...using ")
+ ACE_TEXT ("defaults!\n")));
+
+ }
+ this->set_dtp_config (config_entry);
+ //this->dtp_task_.set_init_pool_threads(config_entry.init_threads_);
+ //this->dtp_task_.set_min_pool_threads(config_entry.min_threads_);
+ //this->dtp_task_.set_max_pool_threads(config_entry.max_threads_);
+ //this->dtp_task_.set_thread_idle_time(config_entry.timeout_);
+ //this->dtp_task_.set_thread_stack_size(config_entry.stack_size_);
+ //this->dtp_task_.set_max_request_queue_depth(config_entry.queue_depth_);
+ }
+
+
+
+ }
+ return (this->dtp_task_.open () == 0);
+
+}
+
+void
+TAO_DTP_POA_Strategy::poa_deactivated_event_i ()
+{
+ // Passing in a value of 1 means that we want to shutdown the task, which
+ // equates to causing all worker threads to shutdown. The worker threads
+ // themselves will also invoke the close() method, but the passed-in value
+ // will be 0. So, a 1 means "shutdown", and a 0 means "a single worker
+ // thread is going away".
+ this->dtp_task_.close(1);
+}
+
+TAO::CSD::Strategy_Base::DispatchResult
+TAO_DTP_POA_Strategy::dispatch_remote_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant)
+{
+ TAO::CSD::TP_Servant_State::HandleType servant_state =
+ this->get_servant_state (servant);
+
+ // Now we can create the TP_Remote_Request object, and then add it to our
+ // task_'s "request queue".
+ //
+ // TBD-CSD: Need to use a Cached Allocator to "create" the
+ // TP_Remote_Request objects. For now, use the heap.
+ TAO::CSD::TP_Remote_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Remote_Request (server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in ()),
+ TAO::CSD::Strategy_Base::DISPATCH_REJECTED);
+
+ TAO::CSD::TP_Remote_Request_Handle request = req_ptr;
+
+ // Hand the request object to our task so that it can add the request
+ // to its "request queue".
+ if (!this->dtp_task_.add_request (request.in ()))
+ {
+ // Return the DISPATCH_REJECTED return code so that the caller (our
+ // base class' dispatch_request() method) knows that we did
+ // not handle the request, and that it should be rejected.
+ return TAO::CSD::Strategy_Base::DISPATCH_REJECTED;
+ }
+
+ return TAO::CSD::Strategy_Base::DISPATCH_HANDLED;
+}
+
+TAO::CSD::Strategy_Base::DispatchResult
+TAO_DTP_POA_Strategy::dispatch_collocated_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant)
+{
+
+
+ TAO::CSD::TP_Servant_State::HandleType servant_state =
+ this->get_servant_state (servant);
+
+ bool is_sync_with_server = server_request.sync_with_server ();
+ bool is_synchronous = server_request.response_expected ();
+
+ TAO::CSD::TP_Collocated_Synch_Request_Handle
+ synch_request;
+ TAO::CSD::TP_Collocated_Synch_With_Server_Request_Handle
+ synch_with_server_request;
+ TAO::CSD::TP_Request_Handle
+ request;
+
+ // Create the request object using the appropriate concrete type.
+ if (is_sync_with_server)
+ {
+ TAO::CSD::TP_Collocated_Synch_With_Server_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Collocated_Synch_With_Server_Request
+ (server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in ()),
+ DISPATCH_REJECTED);
+
+ synch_with_server_request = req_ptr;
+
+ // Give the request handle its own "copy".
+ synch_with_server_request->_add_ref ();
+ request = synch_with_server_request.in ();
+ }
+ else if (is_synchronous)
+ {
+
+ TAO::CSD::TP_Collocated_Synch_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Collocated_Synch_Request (
+ server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in ()),
+ DISPATCH_REJECTED);
+
+ synch_request = req_ptr;
+
+ // Give the request handle its own "copy".
+ synch_request->_add_ref ();
+ request = synch_request.in ();
+ }
+ else
+ {
+ TAO::CSD::TP_Collocated_Asynch_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Collocated_Asynch_Request (server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in ()),
+ DISPATCH_REJECTED);
+
+ // Just use the (base) request handle to hold the request object.
+ request = req_ptr;
+ }
+
+ // Hand the request object to our task so that it can add the request
+ // to its "request queue".
+ if (!this->dtp_task_.add_request (request.in ()))
+ {
+ // Return the DISPATCH_REJECTED return code so that the caller (our
+ // base class' dispatch_request() method) knows that we did
+ // not handle the request, and that it should be rejected.
+ return DISPATCH_REJECTED;
+ }
+
+ // We need to wait on the request object if the request type is a
+ // synchronous request.
+ if (!synch_request.is_nil ())
+ {
+ int srw = synch_request->wait ();
+ if (srw == false)
+ {
+ // Raise exception when request was cancelled.
+ throw ::CORBA::NO_IMPLEMENT ();
+ }
+ }
+ else if (!synch_with_server_request.is_nil())
+ {
+ bool swsr = synch_with_server_request->wait();
+ if (swsr == false)
+ {
+ // Raise exception when request was cancelled.
+ throw ::CORBA::NO_IMPLEMENT ();
+ }
+ }
+
+ return DISPATCH_HANDLED;
+}
+
+void
+TAO_DTP_POA_Strategy::servant_activated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId&)
+{
+ if (this->serialize_servants_)
+ {
+ // Add the servant to the servant state map.
+ this->servant_state_map_.insert (servant);
+ }
+}
+
+void
+TAO_DTP_POA_Strategy::servant_deactivated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId&)
+{
+ // Cancel all requests stuck in the queue for the specified servant.
+ this->dtp_task_.cancel_servant (servant);
+
+ if (this->serialize_servants_)
+ {
+ // Remove the servant from the servant state map.
+ this->servant_state_map_.remove (servant);
+ }
+}
+
+void
+TAO_DTP_POA_Strategy::cancel_requests (PortableServer::Servant servant)
+{
+ // Cancel all requests stuck in the queue for the specified servant.
+ this->dtp_task_.cancel_servant (servant);
+}
+
+TAO::CSD::TP_Servant_State::HandleType
+TAO_DTP_POA_Strategy::get_servant_state (PortableServer::Servant servant)
+{
+ TAO::CSD::TP_Servant_State::HandleType servant_state;
+
+ if (this->serialize_servants_)
+ {
+ servant_state = this->servant_state_map_.find (servant);
+ }
+
+ return servant_state;
+}
+
+void
+TAO_DTP_POA_Strategy::set_dtp_config (TAO_DTP_Definition &tp_config)
+{
+
+ if (tp_config.min_threads_ <= 0)
+ {
+ this->dtp_task_.set_min_pool_threads (1);
+ this->dtp_task_.set_thread_idle_time (ACE_Time_Value (0,0));
+ }
+ else
+ {
+ this->dtp_task_.set_min_pool_threads (tp_config.min_threads_);
+ this->dtp_task_.set_thread_idle_time (tp_config.timeout_);
+ }
+
+ // initial_pool_threads_
+ if ((tp_config.init_threads_ <= 0) ||
+ (tp_config.init_threads_ < tp_config.min_threads_))
+ {
+ this->dtp_task_.set_init_pool_threads (this->dtp_task_.get_min_pool_threads());
+ }
+ else
+ {
+ this->dtp_task_.set_init_pool_threads (tp_config.init_threads_);
+ }
+
+ // max_pool_threads_
+
+ if (tp_config.max_threads_ <= 0)
+ {
+ // Set to 0 so that max is unbounded.
+ this->dtp_task_.set_max_pool_threads(0);
+ }
+ else
+ if (tp_config.max_threads_ < tp_config.init_threads_)
+ {
+ this->dtp_task_.set_max_pool_threads(
+ this->dtp_task_.get_init_pool_threads ());
+ }
+ else
+ {
+ this->dtp_task_.set_max_pool_threads (tp_config.max_threads_);
+ }
+
+ // thread_stack_size_
+
+ if (tp_config.stack_size_ <= 0)
+ {
+ this->dtp_task_.set_thread_stack_size (ACE_DEFAULT_THREAD_STACKSIZE);
+ }
+ else
+ {
+ this->dtp_task_.set_thread_stack_size (tp_config.stack_size_);
+ }
+
+ // max_request_queue_depth_
+ if (tp_config.queue_depth_ < 0)
+ {
+ this->dtp_task_.set_max_request_queue_depth (0);
+ }
+ else
+ {
+ this->dtp_task_.set_max_request_queue_depth (tp_config.queue_depth_);
+ }
+
+
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy: ")
+ ACE_TEXT ("Initialized with:\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy initial_pool_threads_=")
+ ACE_TEXT ("[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy min_pool_threads_=[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy max_pool_threads_=[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy max_request_queue_depth_=")
+ ACE_TEXT ("[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy thread_stack_size_=[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy thread_idle_time_=[%d]\n"),
+ this->dtp_task_.get_init_pool_threads(),
+ this->dtp_task_.get_min_pool_threads(),
+ this->dtp_task_.get_max_pool_threads(),
+ this->dtp_task_.get_max_request_queue_depth(),
+ this->dtp_task_.get_thread_stack_size(),
+ this->dtp_task_.get_thread_idle_time()));
+ }
+}
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Strategy.h b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.h
new file mode 100644
index 00000000000..51533e334b1
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.h
@@ -0,0 +1,220 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_POA_Strategy.h
+ *
+ * $Id$
+ *
+ * @author Marc Neeley <neeleym@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_POA_STRATEGY_H
+#define TAO_DYNAMIC_TP_POA_STRATEGY_H
+
+#include /**/ "ace/pre.h"
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/Dynamic_TP/DTP_Task.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/CSD_Framework/CSD_Strategy_Base.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+#include "ace/OS_NS_strings.h"
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+
+class TAO_DTP_POA_Strategy;
+typedef TAO_Intrusive_Ref_Count_Handle<TAO_DTP_POA_Strategy>
+ TAO_DTP_POA_Strategy_Handle;
+
+namespace TAO
+{
+ namespace CSD
+ {
+ class TP_Custom_Request_Operation;
+ }
+}
+
+
+/**
+ * @class TAO_DTP_POA_Strategy
+ *
+ * @brief
+ *
+ */
+class TAO_Dynamic_TP_Export TAO_DTP_POA_Strategy:
+ public TAO::CSD::Strategy_Base
+{
+ public:
+
+ /// Constructors.
+ /// This constructor supports situations where dynamic instantiation
+ /// of a thread pool for POAs is initiated from a svc.conf file.
+ /// A configuration name is passed in such that the object can
+ /// lookup a configuration in a pre-populated repository.
+ TAO_DTP_POA_Strategy(ACE_CString tp_config_name,
+ bool serialize_servants = true);
+
+ /// This constructor supports situations where explicit instantiation
+ /// of a thread pool for POAs is initiated from an application, such as
+ /// the use of the apply_to() method.
+ TAO_DTP_POA_Strategy(TAO_DTP_Definition * tp_config,
+ bool serialize_servants = true);
+
+ /// Virtual Destructor.
+ virtual ~TAO_DTP_POA_Strategy();
+
+ /// Turn on/off serialization of servants.
+ void set_servant_serialization(bool serialize_servants);
+
+ /// Return codes for the custom dispatch_request() methods.
+ enum CustomRequestOutcome
+ {
+ /// The request was successfully put on the request queue.
+ REQUEST_DISPATCHED,
+ /// The request has been executed/completed by a worker thread.
+ REQUEST_EXECUTED,
+ /// The request was removed from the queue and cancelled.
+ REQUEST_CANCELLED,
+ /// The request queue rejected the request
+ REQUEST_REJECTED
+ };
+
+ /// Inject a synchronous, custom request into the request queue.
+ /// This will block the calling thread until the request is handled
+ /// (dispatched or cancelled) or rejected.
+ /// Will return REQUEST_EXECUTED, REQUEST_CANCELLED, or REQUEST_REJECTED.
+ CustomRequestOutcome custom_synch_request
+ (TAO::CSD::TP_Custom_Request_Operation* op);
+
+ /// Inject an asynchronous, custom request into the request queue.
+ /// This will return control to the calling thread once the request
+ /// has been placed into the queue (or rejected).
+ /// Will return REQUEST_DISPATCHED or REQUEST_REJECTED.
+ CustomRequestOutcome custom_asynch_request
+ (TAO::CSD::TP_Custom_Request_Operation* op);
+
+ /// Cancel all requests that are targeted for the provided servant.
+ /// This is requested on the user application level.
+ void cancel_requests(PortableServer::Servant servant);
+
+
+ protected:
+
+ /// Handle the dispatching of a remote request.
+ ///
+ /// This will cause a new "request" object to be created and pushed
+ /// on to a "request queue". The worker threads are responsible for
+ /// servicing the queue, and performing the actual dispatch logic.
+ virtual Strategy_Base::DispatchResult dispatch_remote_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant);
+
+ /// Handle the dispatching of a collocated request.
+ ///
+ /// This will cause a new "request" object to be created and pushed
+ /// on to a "request queue". The worker threads are responsible for
+ /// servicing the queue, and performing the actual dispatch logic.
+ virtual Strategy_Base::DispatchResult dispatch_collocated_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant);
+
+ /// Event - The POA has been activated.
+ /// This will activate the worker thread(s).
+ /// Returns true if the worker threads were activated successfully.
+ /// Otherwise, returns false.
+ virtual bool poa_activated_event_i(TAO_ORB_Core& orb_core);
+
+ /// Event - The POA has been deactivated.
+ /// This will shutdown the worker thread(s).
+ virtual void poa_deactivated_event_i();
+
+ /// Event - A servant has been activated
+ virtual void servant_activated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid);
+
+ /// Event - A servant has been deactivated
+ virtual void servant_deactivated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid);
+
+ private:
+
+
+ /**
+ * Helper method that is responsible for looking up the servant
+ * state object in the servant state map *if* the "serialize
+ * servants" flag is set to true. In the case where the
+ * "serialize servants" flag is set to false, then a "nil"
+ * servant state handle object is returned.
+ *
+ * @param servant - input - a pointer to the servant object.
+ *
+ * @returns a handle to a servant state object.
+ *
+ * @throw PortableServer::POA::ServantNotActive if the servant
+ * state cannot be determined.
+ */
+ TAO::CSD::TP_Servant_State::HandleType get_servant_state
+ (PortableServer::Servant servant);
+
+ /// The "serialize servants" flag.
+ bool serialize_servants_;
+
+ /// The map of servant state objects - only used when the
+ /// "serialize servants" flag is set to true.
+ TAO::CSD::TP_Servant_State_Map servant_state_map_;
+
+ /// This holds the name of a configuration that have been loaded
+ /// into a DTP_Config_Registry. This is the key to the RB
+ /// Tree entry.
+
+ ACE_CString dynamic_tp_config_name_;
+
+ /// This is the active object used by the worker threads.
+ /// The request queue is owned/managed by the task object.
+ /// The strategy object puts requests into the task's request
+ /// queue, and the worker threads service the queued requests
+ /// by performing the actual servant request dispatching logic.
+ TAO_DTP_Task dtp_task_;
+
+
+ /// This boolean is used to determine if the configuration has
+ /// been sent in from an application or, if false, needs to be
+ /// looked up from a Dynamic TP Config repo. It works in conjunction with
+ /// dynamic_tp_config_name_ above.
+
+ bool config_initialized_;
+
+
+ void set_dtp_config(TAO_DTP_Definition &tp_config);
+};
+
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "tao/Dynamic_TP/DTP_POA_Strategy.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_DYNAMIC_TP_POA_STRATEGY_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Strategy.inl b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.inl
new file mode 100644
index 00000000000..3ce52bb554b
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.inl
@@ -0,0 +1,35 @@
+// -*- C++ -*-
+//
+// $Id$
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_INLINE
+/// Constructor.
+TAO_DTP_POA_Strategy::TAO_DTP_POA_Strategy (ACE_CString tp_config_name,
+ bool ss)
+ : serialize_servants_ (ss),
+ config_initialized_ (false)
+{
+ this->dynamic_tp_config_name_ = tp_config_name;
+}
+
+ACE_INLINE
+TAO_DTP_POA_Strategy::TAO_DTP_POA_Strategy (TAO_DTP_Definition * tp_config,
+ bool ss)
+ : serialize_servants_ (ss),
+ config_initialized_ (true)
+{
+ this->set_dtp_config (*tp_config);
+}
+
+ACE_INLINE
+void
+TAO_DTP_POA_Strategy::set_servant_serialization (bool serialize_servants)
+{
+ // Simple Mutator.
+ this->serialize_servants_ = serialize_servants;
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Dynamic_TP/DTP_Task.cpp b/TAO/tao/Dynamic_TP/DTP_Task.cpp
new file mode 100644
index 00000000000..cc6f30c310c
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Task.cpp
@@ -0,0 +1,479 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_Task.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h"
+
+#if !defined (__ACE_INLINE__)
+# include "tao/Dynamic_TP/DTP_Task.inl"
+#endif /* ! __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_Task::TAO_DTP_Task ()
+ : aw_lock_ (),
+ queue_lock_ (),
+ work_lock_ (),
+ work_available_ (this->work_lock_),
+ active_workers_ (this->aw_lock_),
+ accepting_requests_ (false),
+ shutdown_ (false),
+ opened_ (false),
+ num_queue_requests_ ((size_t)0)
+{
+}
+
+TAO_DTP_Task::~TAO_DTP_Task()
+{
+}
+
+bool
+TAO_DTP_Task::add_request (TAO::CSD::TP_Request* request)
+{
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->queue_lock_, false);
+ ++this->num_queue_requests_;
+ if ((this->num_queue_requests_ > this->max_request_queue_depth_) &&
+ (this->max_request_queue_depth_ != 0))
+ {
+ this->accepting_requests_ = false;
+ }
+
+ if (!this->accepting_requests_)
+ {
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::add_request() ")
+ ACE_TEXT ("not accepting requests.\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::add_request() ")
+ ACE_TEXT ("num_queue_requests_ : [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::add_request() ")
+ ACE_TEXT ("max_request_queue_depth_ : [%d]\n"),
+ this->num_queue_requests_,
+ this->max_request_queue_depth_));
+ }
+ --this->num_queue_requests_;
+ return false;
+ }
+
+ // We have made the decision that the request is going to be placed upon
+ // the queue_. Inform the request that it is about to be placed into
+ // a request queue. Some requests may not need to do anything in
+ // preparation of being placed into a queue. Others, however, may need
+ // to perfom a "clone" operation on some underlying request data before
+ // the request can be properly placed into a queue.
+ request->prepare_for_queue();
+
+ this->queue_.put(request);
+ }
+
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->work_lock_, false);
+ this->work_available_.signal ();
+ if (TAO_debug_level > 4 )
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::add_request() - ")
+ ACE_TEXT ("work available\n")));
+ }
+ }
+
+ return true;
+}
+
+size_t
+TAO_DTP_Task::get_init_pool_threads ()
+{
+ return (this->init_pool_threads_);
+}
+
+size_t
+TAO_DTP_Task::get_min_pool_threads ()
+{
+ return(this->min_pool_threads_);
+}
+
+size_t TAO_DTP_Task::get_max_pool_threads ()
+{
+ return(this->max_pool_threads_);
+}
+
+size_t
+TAO_DTP_Task::get_max_request_queue_depth ()
+{
+ return(this->max_request_queue_depth_);
+}
+
+size_t
+TAO_DTP_Task::get_thread_stack_size ()
+{
+ return(this->thread_stack_size_);
+}
+
+time_t
+TAO_DTP_Task::get_thread_idle_time ()
+{
+ return(this->thread_idle_time_.sec());
+}
+
+int
+TAO_DTP_Task::open (void* /* args */)
+{
+ size_t num = 1;
+
+ // Open_Args* tmp = static_cast<Open_Args *> (args);
+
+ //if (tmp == 0)
+ // {
+ // //FUZZ: disable check_for_lack_ACE_OS
+ // ACE_ERROR_RETURN ((LM_ERROR,
+ // ACE_TEXT ("(%P|%t) DTP_Task::open() failed to open. ")
+ // ACE_TEXT ("Invalid argument type passed to open().\n")),
+ // -1);
+ // //FUZZ: enable check_for_lack_ACE_OS
+ // }
+
+ num = this->init_pool_threads_;
+
+ // Set the busy_threads_ to the number of init_threads
+ // now. When they startup they will decrement themselves
+ // as they go into a wait state.
+
+ this->busy_threads_ = 0;
+
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() initialized with:\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() init_threads_ \t\t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() min_pool_threads_ \t\t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() max_pool_threads_ \t\t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() max_request_queue_depth_ \t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() thread_stack_size_ \t\t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() thread_idle_time_ \t\t: [%d]\n"),
+ this->init_pool_threads_,
+ this->min_pool_threads_,
+ this->max_pool_threads_,
+ this->max_request_queue_depth_,
+ this->thread_stack_size_,
+ this->thread_idle_time_.sec ())
+ );
+ }
+
+ // We can't activate 0 threads. Make sure this isn't the case.
+ if (num < 1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) DTP_Task::open() failed to open. ")
+ ACE_TEXT ("num_threads (%u) is less-than 1.\n"),
+ num),
+ -1);
+ }
+
+ // We need the lock acquired from here on out.
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->aw_lock_, -1);
+
+ // We can assume that we are in the proper state to handle this open()
+ // call as long as we haven't been open()'ed before.
+ if (this->opened_)
+ {
+ //FUZZ: disable check_for_lack_ACE_OS
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) DTP_Task::open() failed to open. ")
+ ACE_TEXT ("Task has previously been open()'ed.\n")),
+ -1);
+ //FUZZ: enable check_for_lack_ACE_OS
+ }
+ // Create the stack size arrays if the stack size is set > 0.
+
+ // Activate this task object with 'num' worker threads.
+ if (this->thread_stack_size_ == 0)
+ {
+ if (this->activate (THR_NEW_LWP | THR_DETACHED, num, 1) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) DTP_Task::open() failed to activate ")
+ ACE_TEXT ("(%d) worker threads.\n"),
+ num),
+ -1);
+ }
+ }
+ else
+ {
+ size_t * stack_sz_arr = new size_t[num];
+ for (size_t z = 0; z < num; z++)
+ {
+ stack_sz_arr[z] = this->thread_stack_size_;
+ }
+
+ if (this->activate (THR_NEW_LWP | THR_DETACHED,
+ num,
+ 1,
+ ACE_DEFAULT_THREAD_PRIORITY,
+ -1,
+ 0,
+ 0,
+ 0,
+ stack_sz_arr) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) DTP_Task::open() failed to activate ")
+ ACE_TEXT ("(%d) worker threads.\n"),
+ num),
+ -1);
+ }
+
+ delete[] stack_sz_arr;
+ }
+ this->opened_ = true;
+ this->accepting_requests_ = true;
+
+ return 0;
+}
+
+bool
+TAO_DTP_Task::request_ready (TAO::CSD::TP_Dispatchable_Visitor &v,
+ TAO::CSD::TP_Request_Handle &r)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->queue_lock_, false);
+ if (!this->queue_.is_empty())
+ {
+ this->queue_.accept_visitor(v);
+ r = v.request();
+ return !r.is_nil();
+ }
+ return false;
+}
+
+void
+TAO_DTP_Task::clear_request (TAO::CSD::TP_Request_Handle &r)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->queue_lock_);
+ --this->num_queue_requests_;
+ if (this->max_request_queue_depth_ > 0)
+ {
+ this->accepting_requests_ = true;
+ }
+
+ if (TAO_debug_level > 4 )
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Decrementing num_queue_requests.")
+ ACE_TEXT ("New queue depth:%d\n"),
+ this->num_queue_requests_));
+ }
+
+ r->mark_as_ready ();
+}
+
+int
+TAO_DTP_Task::svc (void)
+{
+ ++this->busy_threads_;
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("New thread created.\n")));
+ }
+
+ TAO::CSD::TP_Dispatchable_Visitor dispatchable_visitor;
+ while (!this->shutdown_)
+ {
+ TAO::CSD::TP_Request_Handle request;
+
+ while (!this->shutdown_ && request.is_nil ())
+ {
+ if (!this->request_ready (dispatchable_visitor, request))
+ {
+ --this->busy_threads_;
+
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Decrementing busy_threads_. ")
+ ACE_TEXT ("Busy thread count:%d\n"),
+ this->busy_threads_.value()));
+ }
+
+ ACE_Time_Value tmp_sec = this->thread_idle_time_.to_absolute_time();
+
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->work_lock_, false);
+ int wait_state = this->thread_idle_time_.sec () == 0
+ ? this->work_available_.wait ()
+ : this->work_available_.wait (&tmp_sec);
+
+ // Check for timeout
+ if (this->shutdown_)
+ return 0;
+ if (wait_state == -1)
+ {
+ if (errno != ETIME ||
+ (this->thr_count() > this->min_pool_threads_ &&
+ this->min_pool_threads_ > 0))
+ {
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Existing thread expiring.\n")));
+ }
+ return 0;
+ }
+ }
+ }
+
+ ++this->busy_threads_;
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Incrementing busy_threads_. ")
+ ACE_TEXT ("Busy thread count:%d\n"),
+ this->busy_threads_.value ()));
+ }
+ }
+ }
+
+ size_t count = this->thr_count ();
+ if ((this->busy_threads_ == count) &&
+ ((this->max_pool_threads_ == 0) ||
+ (count < this->max_pool_threads_)))
+ {
+ if (this->activate(THR_NEW_LWP | THR_DETACHED,
+ 1,
+ 1,
+ ACE_DEFAULT_THREAD_PRIORITY,
+ -1,
+ 0,
+ 0,
+ 0,
+ this->thread_stack_size_ == 0 ? 0 :
+ &this->thread_stack_size_) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) DTP_Task::svc() failed to grow ")
+ ACE_TEXT ("to %d worker threads.\n"), count));
+ }
+ else
+ {
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Growing threadcount. ")
+ ACE_TEXT ("New thread count:%d\n"),
+ this->thr_count ()));
+ }
+ }
+ }
+
+ request->dispatch ();
+ this->clear_request (request);
+ dispatchable_visitor.reset ();
+ }
+ return 0;
+}
+
+
+int
+TAO_DTP_Task::close(u_long flag)
+{
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->aw_lock_, 0);
+ if (flag == 0)
+ {
+ this->active_workers_.signal ();
+ return 0;
+ }
+
+ if (!this->opened_)
+ {
+ return 0;
+ }
+ this->opened_ = false;
+ this->shutdown_ = true;
+ this->accepting_requests_ = false;
+ }
+
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->work_lock_, 0);
+ this->work_available_.broadcast();
+ }
+
+ size_t in_task = (this->thr_mgr ()->task () == this) ? 1 : 0;
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::close() ")
+ ACE_TEXT ("shutting down. in_task = %d, Count = %d \n"),
+ in_task, this->thr_count ()));
+ }
+
+ while (this->thr_count () != in_task)
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->aw_lock_, 0);
+ this->active_workers_.wait ();
+ }
+
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->queue_lock_, 0);
+ TAO::CSD::TP_Cancel_Visitor v;
+ this->queue_.accept_visitor (v);
+ }
+ return 0;
+}
+
+
+void
+TAO_DTP_Task::set_init_pool_threads (size_t thr_count)
+{
+ this->init_pool_threads_ = thr_count;
+}
+
+void
+TAO_DTP_Task::set_min_pool_threads (size_t thr_count)
+{
+ this->min_pool_threads_ = thr_count;
+}
+
+void
+TAO_DTP_Task::set_max_pool_threads (size_t thr_count)
+{
+ this->max_pool_threads_ = thr_count;
+}
+
+void
+TAO_DTP_Task::set_thread_stack_size (size_t stack_sz)
+{
+ this->thread_stack_size_ = stack_sz;
+}
+
+void
+TAO_DTP_Task::set_thread_idle_time(ACE_Time_Value thr_timeout)
+{
+ this->thread_idle_time_ = thr_timeout;
+}
+
+void
+TAO_DTP_Task::set_max_request_queue_depth (size_t queue_depth)
+{
+ this->max_request_queue_depth_ = queue_depth;
+}
+
+void
+TAO_DTP_Task::cancel_servant (PortableServer::Servant servant)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->queue_lock_);
+
+ // Cancel the requests targeted for the provided servant.
+ TAO::CSD::TP_Cancel_Visitor cancel_visitor (servant);
+ this->queue_.accept_visitor (cancel_visitor);
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Dynamic_TP/DTP_Task.h b/TAO/tao/Dynamic_TP/DTP_Task.h
new file mode 100644
index 00000000000..0b18950e75d
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Task.h
@@ -0,0 +1,199 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_Task.h
+ *
+ * $Id$
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_TASK_H
+#define TAO_DYNAMIC_TP_TASK_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Queue.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/Condition.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Task.h"
+#include "ace/Synch.h"
+#include "ace/Containers_T.h"
+#include "ace/Vector_T.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ /**
+ * @class TP_Task
+ *
+ * @brief Active Object managing a queue of request objects.
+ *
+ * There are two types of "users" of a TP_Task object:
+ *
+ * 1) The TP_Strategy object that "owns" this task object.
+ * 2) The worker threads that "run" this task object as an
+ * "active object".
+ *
+ * The TP_Strategy object that "owns" this task object dictates
+ * when the worker threads are activated and when they are shutdown. It
+ * also injects requests into this task's queue via calls to the
+ * add_request() method. It is also the TP_Strategy object that
+ * dictates the number of worker threads to be activated via a call to
+ * the set_num_threads() method.
+ *
+ * The active object pattern is implemented via the use of the
+ * the ACE_Task_Base base class, and each worker thread will
+ * invoke this task's svc() method, and when the svc() returns, the
+ * worker thread will invoke this task's close() method (with the
+ * flag argument equal to 0).
+ */
+ class TAO_Dynamic_TP_Export TAO_DTP_Task : public ACE_Task_Base
+ {
+ public:
+
+ /// Default Constructor.
+ TAO_DTP_Task();
+
+ /// Virtual Destructor.
+ virtual ~TAO_DTP_Task();
+
+ struct Open_Args {
+ TAO_DTP_Definition task_thread_config;
+ };
+
+
+ /// Put a request object on to the request queue.
+ /// Returns true if successful, false otherwise (it has been "rejected").
+ bool add_request(TAO::CSD::TP_Request* request);
+
+ /// Activate the worker threads
+ virtual int open(void* args = 0);
+
+ /// The "mainline" executed by each worker thread.
+ virtual int svc();
+
+ virtual int close (u_long flag = 0);
+
+ /// Set the thread and queue config.
+
+ void set_init_pool_threads(size_t thr_count);
+
+ void set_min_pool_threads(size_t thr_count);
+
+ void set_max_pool_threads(size_t thr_count);
+
+ void set_thread_stack_size(size_t stack_sz);
+
+ void set_thread_idle_time(ACE_Time_Value thr_timeout);
+
+ void set_max_request_queue_depth(size_t queue_depth);
+
+ /// Get the thread and queue config.
+
+ size_t get_init_pool_threads();
+
+ size_t get_min_pool_threads();
+
+ size_t get_max_pool_threads();
+
+ size_t get_max_request_queue_depth();
+
+ size_t get_thread_stack_size();
+
+ time_t get_thread_idle_time();
+
+ /// Cancel all requests that are targeted for the provided servant.
+ void cancel_servant (PortableServer::Servant servant);
+
+ private:
+ /// get the next available request. Return true if one available, nonblocking
+ bool request_ready (TAO::CSD::TP_Dispatchable_Visitor &v,
+ TAO::CSD::TP_Request_Handle &r);
+
+ /// release the request, reset the accepting flag if necessary
+ void clear_request (TAO::CSD::TP_Request_Handle &r);
+
+
+
+ typedef TAO_SYNCH_MUTEX LockType;
+ typedef TAO_Condition<LockType> ConditionType;
+
+ /// Lock used to synchronize the "active_workers_" condition
+ LockType aw_lock_;
+ /// Lock used to synchronize manipulation of the queue
+ LockType queue_lock_;
+ /// Lock used to synchronize the "work_available_" condition
+ LockType work_lock_;
+
+ /// Condition used to signal worker threads that they may be able to
+ /// find a request in the queue_ that needs to be dispatched to a
+ /// servant that is currently "not busy".
+ /// This condition will be signal()'ed each time a new request is
+ /// added to the queue_, and also when a servant has become "not busy".
+ ConditionType work_available_;
+
+ /// This condition will be signal()'ed each time the num_threads_
+ /// data member has its value changed. This is used to keep the
+ /// close(1) invocation (ie, a shutdown request) blocked until all
+ /// of the worker threads have stopped running.
+ ConditionType active_workers_;
+
+ /// Flag used to indicate when this task will (or will not) accept
+ /// requests via the the add_request() method.
+ bool accepting_requests_;
+
+ /// Flag used to initiate a shutdown request to all worker threads.
+ bool shutdown_;
+
+ /// Flag used to avoid multiple open() calls.
+ bool opened_;
+
+ /// The number of requests in the local queue.
+ size_t num_queue_requests_;
+
+ /// The number of currently active worker threads.
+ ACE_Atomic_Op <TAO_SYNCH_MUTEX, unsigned long> busy_threads_;
+
+ /// The queue of pending servant requests (a.k.a. the "request queue").
+ TAO::CSD::TP_Queue queue_;
+
+ /// The low water mark for dynamic threads to settle to.
+ size_t init_pool_threads_;
+
+ /// The low water mark for dynamic threads to settle to.
+ size_t min_pool_threads_;
+
+ /// The high water mark for dynamic threads to be limited to.
+ size_t max_pool_threads_;
+
+ /// If the max_pool_threads_ value has been met, then ORB requests coming in can be queued.
+ /// This is the maximum number that will be allowed.
+ size_t max_request_queue_depth_;
+
+ /// This is the memory stack size allowable for each thread.
+ size_t thread_stack_size_;
+
+ /// This is the maximum amount of time in seconds that an idle thread can
+ /// stay alive before being taken out of the pool.
+ ACE_Time_Value thread_idle_time_;
+ };
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+# include "tao/Dynamic_TP/DTP_Task.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_DYNAMIC_TP_TASK_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_Task.inl b/TAO/tao/Dynamic_TP/DTP_Task.inl
new file mode 100644
index 00000000000..5b9eaafbd7d
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Task.inl
@@ -0,0 +1,7 @@
+// -*- C++ -*-
+//
+// $Id$
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp b/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp
new file mode 100644
index 00000000000..1b70111c86b
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp
@@ -0,0 +1,131 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/ORB_Core.h"
+#include "tao/ORB_Core_TSS_Resources.h"
+#include "tao/Acceptor_Registry.h"
+#include "tao/Thread_Lane_Resources.h"
+#include "tao/Dynamic_TP/DTP_Thread_Pool.h"
+#include "tao/LF_Follower.h"
+#include "tao/Leader_Follower.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_Thread_Lane_Resources_Manager::TAO_DTP_Thread_Lane_Resources_Manager
+ (TAO_ORB_Core &orb_core)
+ : TAO_Thread_Lane_Resources_Manager (orb_core),
+ default_lane_resources_ (0),
+ tp_manager_ (0)
+{
+ // Create the default resources.
+ ACE_NEW (this->default_lane_resources_,
+ TAO_Thread_Lane_Resources (orb_core));
+
+ // Create the thread-pool manager.
+ ACE_NEW (this->tp_manager_,
+ TAO_DTP_Thread_Pool_Manager (orb_core));
+
+}
+
+TAO_DTP_Thread_Lane_Resources_Manager::~TAO_DTP_Thread_Lane_Resources_Manager (void)
+{
+ // Delete the default resources.
+ delete this->default_lane_resources_;
+
+ // Delete the thread-pool manager.
+ delete this->tp_manager_;
+}
+
+int
+TAO_DTP_Thread_Lane_Resources_Manager::open_default_resources (void)
+{
+ TAO_ORB_Parameters *params =
+ this->orb_core_->orb_params ();
+
+ TAO_EndpointSet endpoint_set;
+
+ params->get_endpoint_set (TAO_DEFAULT_LANE, endpoint_set);
+
+ bool ignore_address = false;
+
+ int const result =
+ this->default_lane_resources_->open_acceptor_registry (endpoint_set,
+ ignore_address);
+
+ return result;
+}
+
+void
+TAO_DTP_Thread_Lane_Resources_Manager::finalize (void)
+{
+ // Finalize default resources.
+ this->default_lane_resources_->finalize ();
+}
+
+void
+TAO_DTP_Thread_Lane_Resources_Manager::shutdown_reactor (void)
+{
+ // Shutdown default reactors.
+ this->default_lane_resources_->shutdown_reactor ();
+ // This is the only reactor in use with this thread pool
+}
+
+void
+TAO_DTP_Thread_Lane_Resources_Manager::close_all_transports (void)
+{
+ // Shutdown default reactors.
+ this->default_lane_resources_->close_all_transports ();
+}
+
+int
+TAO_DTP_Thread_Lane_Resources_Manager::is_collocated (const TAO_MProfile &mprofile)
+{
+ return this->default_lane_resources_->is_collocated (mprofile);
+}
+
+TAO_Thread_Lane_Resources &
+TAO_DTP_Thread_Lane_Resources_Manager::lane_resources (void)
+{
+ return *this->default_lane_resources_;
+}
+
+TAO_Thread_Lane_Resources &
+TAO_DTP_Thread_Lane_Resources_Manager::default_lane_resources (void)
+{
+ return *this->default_lane_resources_;
+}
+
+TAO_DTP_Thread_Pool_Manager &
+TAO_DTP_Thread_Lane_Resources_Manager::tp_manager (void)
+{
+ return *this->tp_manager_;
+}
+
+TAO_Thread_Lane_Resources_Manager *
+TAO_DTP_Thread_Lane_Resources_Manager_Factory::create_thread_lane_resources_manager (
+ TAO_ORB_Core &core)
+{
+ TAO_Thread_Lane_Resources_Manager *manager = 0;
+
+ /// Create the RT Thread Lane Resources Manager.
+ ACE_NEW_RETURN (manager,
+ TAO_DTP_Thread_Lane_Resources_Manager (core),
+ 0);
+
+ return manager;
+}
+
+ACE_STATIC_SVC_DEFINE (TAO_DTP_Thread_Lane_Resources_Manager_Factory,
+ ACE_TEXT ("DTP_Thread_Lane_Resources_Manager_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_Thread_Lane_Resources_Manager_Factory),
+ ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
+ 0)
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_Thread_Lane_Resources_Manager_Factory)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h b/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h
new file mode 100644
index 00000000000..79278ec7726
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_Thread_Lane_Resources_Manager.h
+ *
+ * $Id$
+ *
+ * @author Irfan Pyarali
+ */
+// ===================================================================
+
+#ifndef TAO_RT_THREAD_LANE_RESOURCES_MANAGER_H
+#define TAO_RT_THREAD_LANE_RESOURCES_MANAGER_H
+
+#include /**/ "ace/pre.h"
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Thread_Lane_Resources_Manager.h"
+#include "ace/Service_Config.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_DTP_Thread_Pool_Manager;
+
+/**
+ * @class TAO_DTP_Thread_Lane_Resources_Manager
+ *
+ * @brief Manager for thread lane resources.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_Thread_Lane_Resources_Manager :
+ public TAO_Thread_Lane_Resources_Manager
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_Thread_Lane_Resources_Manager (TAO_ORB_Core &orb_core);
+
+ /// Destructor.
+ ~TAO_DTP_Thread_Lane_Resources_Manager (void);
+
+ /// Finalize resources.
+ void finalize (void);
+
+ /// Open default resources.
+ int open_default_resources (void);
+
+ /// Shutdown reactor.
+ void shutdown_reactor (void);
+
+ /// Certain ORB policies such as dropping replies on shutdown
+ /// would need cleanup of transports to wake threads up.
+ void close_all_transports (void);
+
+ /// Does @a mprofile belong to us?
+ int is_collocated (const TAO_MProfile &mprofile);
+
+ /// @name Accessors
+ // @{
+
+ TAO_Thread_Lane_Resources &lane_resources (void);
+
+ TAO_Thread_Lane_Resources &default_lane_resources (void);
+
+ TAO_DTP_Thread_Pool_Manager &tp_manager (void);
+
+ // @}
+
+private:
+ void operator= (const TAO_DTP_Thread_Lane_Resources_Manager &);
+ TAO_DTP_Thread_Lane_Resources_Manager (const TAO_DTP_Thread_Lane_Resources_Manager &);
+
+protected:
+
+ /// Default lane resources.
+ TAO_Thread_Lane_Resources *default_lane_resources_;
+
+ /// Thread Pool Manager.
+ TAO_DTP_Thread_Pool_Manager *tp_manager_;
+};
+
+/**
+ * @class TAO_DTP_Thread_Lane_Resources_Manager_Factory
+ *
+ * @brief This class is a factory for managers of thread resources.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_Thread_Lane_Resources_Manager_Factory
+ : public TAO_Thread_Lane_Resources_Manager_Factory
+{
+public:
+
+ /// Factory method.
+ TAO_Thread_Lane_Resources_Manager *create_thread_lane_resources_manager (
+ TAO_ORB_Core &core);
+
+};
+
+
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP,
+ TAO_DTP_Thread_Lane_Resources_Manager_Factory)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP,
+ TAO_DTP_Thread_Lane_Resources_Manager_Factory)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_RT_THREAD_LANE_RESOURCES_MANAGER_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp
new file mode 100644
index 00000000000..9d03eb8cb48
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp
@@ -0,0 +1,456 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_Thread_Pool.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#if ! defined (__ACE_INLINE__)
+#include "tao/Dynamic_TP/DTP_Thread_Pool.inl"
+#endif /* __ACE_INLINE__ */
+
+#include "tao/Exception.h"
+#include "tao/ORB_Core.h"
+#include "tao/ORB_Core_TSS_Resources.h"
+#include "tao/TSS_Resources.h"
+#include "tao/ORB.h"
+#include "tao/Acceptor_Registry.h"
+#include "tao/debug.h"
+#include "tao/LF_Follower.h"
+#include "tao/Leader_Follower.h"
+#include "ace/Auto_Ptr.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_New_Leader_Generator::TAO_DTP_New_Leader_Generator (
+ TAO_DTP_Thread_Pool &p)
+ : pool_ (p)
+{
+}
+
+void
+TAO_DTP_New_Leader_Generator::no_leaders_available (void)
+{
+ this->pool_.new_dynamic_thread ();
+}
+
+TAO_DTP_Thread_Pool_Threads::TAO_DTP_Thread_Pool_Threads (TAO_DTP_Thread_Pool &p)
+ : ACE_Task_Base (p.manager ().orb_core ().thr_mgr ()),
+ pool_ (p)
+{
+}
+
+int
+TAO_DTP_Thread_Pool_Threads::svc (void)
+{
+ TAO_ORB_Core &orb_core = this->pool_.manager ().orb_core ();
+ if (orb_core.has_shutdown ())
+ return 0;
+
+ try
+ {
+ // Do the work
+ this->run (orb_core);
+ }
+ catch (const ::CORBA::Exception& ex)
+ {
+ // No point propagating this exception. Print it out.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("orb->run() raised exception for thread %t\n")));
+
+ ex._tao_print_exception ("");
+ }
+
+ return 0;
+}
+
+int
+TAO_DTP_Thread_Pool_Threads::run (TAO_ORB_Core &orb_core)
+{
+ CORBA::ORB_ptr orb = orb_core.orb ();
+ // A timeout is specified, run the ORB in an idle loop, if we
+ // don't handle any operations for the given timeout we just
+ // exit the loop and this thread ends itself.
+ ACE_Time_Value tv (this->pool_.dynamic_thread_time ());
+
+ while (!orb_core.has_shutdown ())
+ {
+ bool has_work = orb->work_pending (tv);
+ if (!has_work && this->pool_.above_minimum ())
+ {
+ // we've timed out, but the pool is not yet at the minimum
+ break;
+ }
+
+ // Run the ORB for the specified timeout, this prevents looping
+ // between work_pending/handle_events
+ tv = this->pool_.dynamic_thread_time ();
+ orb->run (tv);
+ // Reset the idle timeout
+ tv = this->pool_.dynamic_thread_time ();
+ }
+
+ if (TAO_debug_level > 7)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO Process %P Pool %d Thread %t\n")
+ ACE_TEXT ("Current number of dynamic threads left = %d; ")
+ ACE_TEXT ("DTP worker thread is ending!\n"),
+ this->pool_.id (),
+ this->thr_count () - 1));
+ }
+
+ return 0;
+}
+
+bool
+TAO_DTP_Thread_Pool::above_minimum (void)
+{
+ return this->definition_.min_threads_ > 0 &&
+ (int)this->threads_.thr_count () > this->definition_.min_threads_;
+}
+
+bool
+TAO_DTP_Thread_Pool::new_dynamic_thread (void)
+{
+ // Note that we are checking this condition below without the lock
+ // held.
+ if (this->definition_.max_threads_ > 0 &&
+ (int)this->threads_.thr_count () >= this->definition_.max_threads_)
+ return false;
+
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_,
+ false);
+
+ if (!this->manager_.orb_core ().has_shutdown () && !this->shutdown_ &&
+ (this->definition_.max_threads_ == -1 ||
+ (int)this->threads_.thr_count () < this->definition_.max_threads_))
+ {
+ if (TAO_debug_level > 7)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO Process %P Pool %d Thread %t\n")
+ ACE_TEXT ("Current number of threads = %d; ")
+ ACE_TEXT ("min threads = %d; max threads = %d\n")
+ ACE_TEXT ("No leaders available; DTP creating new leader!\n"),
+ this->id_,
+ this->threads_.thr_count (),
+ this->definition_.min_threads_,
+ this->definition_.max_threads_));
+
+ if (this->create_threads_i (1, THR_BOUND | THR_DETACHED))
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Pool %d Thread %t: ")
+ ACE_TEXT ("cannot create dynamic thread\n"),
+ this->id_));
+ }
+ return false;
+ }
+ }
+
+ return true;
+}
+
+CORBA::ULong
+TAO_DTP_Thread_Pool::current_threads (void) const
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_,
+ 0);
+
+ return this->threads_.thr_count ();
+}
+
+int
+TAO_DTP_Thread_Pool::create_initial_threads (void)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_,
+ 0);
+
+ // Create initial threads.
+ // first, create the minimum number of threads as static
+ // if the min threads count is -1 that means all threads are static
+
+ size_t count = (size_t)this->definition_.init_threads_;
+ size_t extra = 0;
+ if (this->definition_.min_threads_ != -1)
+ {
+ extra = count - (size_t) this->definition_.min_threads_;
+ count = (size_t) this->definition_.min_threads_;
+ }
+
+ if (TAO_debug_level > 7)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) DTP_Thread_Pool::create_initial_threads ")
+ ACE_TEXT ("Creating %d static and %d dynamic threads\n"),
+ count, extra));
+ }
+
+ int result = this->create_threads_i (count, THR_NEW_LWP | THR_JOINABLE);
+ if (result != -1 && extra > 0)
+ {
+ result = this->create_threads_i (extra, THR_BOUND | THR_DETACHED);
+ }
+ return result;
+}
+
+int
+TAO_DTP_Thread_Pool::create_dynamic_threads (size_t count)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_,
+ 0);
+
+ return this->create_threads_i (count, THR_BOUND | THR_DETACHED);
+}
+
+int
+TAO_DTP_Thread_Pool::create_threads_i (size_t count,
+ long thread_flags)
+{
+ // Overwritten parameters.
+ int force_active = 1;
+
+ // Default parameters.
+ int default_grp_id = -1;
+ ACE_Task_Base *default_task = 0;
+ ACE_hthread_t *default_thread_handles = 0;
+ void **default_stack = 0;
+
+ // Setting stack size.
+ size_t *stack_size_array = 0;
+ ACE_NEW_RETURN (stack_size_array,
+ size_t[count],
+ -1);
+ size_t index;
+ for (index = 0; index != count; ++index)
+ stack_size_array[index] =
+ this->definition_.stack_size_;
+
+ // Make sure the dynamically created stack size array is properly
+ // deleted.
+ ACE_Auto_Basic_Array_Ptr<size_t> auto_stack_size_array (stack_size_array);
+
+ TAO_ORB_Core &orb_core = manager_.orb_core ();
+
+ long flags =
+ thread_flags |
+ orb_core.orb_params ()->thread_creation_flags ();
+
+ int default_priority = 0;
+
+ // Activate the threads.
+ int result =
+ this->threads_.activate (flags,
+ count,
+ force_active,
+ default_grp_id,
+ default_priority,
+ default_task,
+ default_thread_handles,
+ default_stack,
+ stack_size_array);
+ return result;
+}
+
+TAO_DTP_Thread_Pool::TAO_DTP_Thread_Pool (TAO_DTP_Thread_Pool_Manager &manager,
+ CORBA::ULong id,
+ TAO_DTP_Definition &def)
+ : manager_ (manager),
+ id_ (id),
+ shutdown_ (false),
+ definition_ (def),
+ threads_ (*this),
+ new_thread_generator_ (*this)
+{
+ manager_.orb_core ().leader_follower ().set_new_leader_generator (
+ &new_thread_generator_);
+}
+
+void
+TAO_DTP_Thread_Pool::open (void)
+{
+ // Nothing to do for now
+}
+
+TAO_DTP_Thread_Pool::~TAO_DTP_Thread_Pool (void)
+{
+}
+
+void
+TAO_DTP_Thread_Pool::shutting_down (void)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_);
+
+ // We are shutting down, this way we are not creating any more new dynamic
+ // threads
+ this->shutdown_ = true;
+}
+
+
+void
+TAO_DTP_Thread_Pool::wait (void)
+{
+ this->threads_.wait ();
+}
+
+#define TAO_THREAD_POOL_MANAGER_GUARD \
+ ACE_GUARD_THROW_EX ( \
+ TAO_SYNCH_MUTEX, \
+ mon, \
+ this->lock_, \
+ CORBA::INTERNAL ( \
+ CORBA::SystemException::_tao_minor_code ( \
+ TAO_GUARD_FAILURE, \
+ 0), \
+ CORBA::COMPLETED_NO));
+
+TAO_DTP_Thread_Pool_Manager::TAO_DTP_Thread_Pool_Manager (TAO_ORB_Core &orb_core)
+ : orb_core_ (orb_core),
+ thread_pools_ (),
+ thread_pool_id_counter_ (1),
+ lock_ ()
+{
+}
+
+TAO_DTP_Thread_Pool_Manager::~TAO_DTP_Thread_Pool_Manager (void)
+{
+ // Delete all the pools.
+ for (THREAD_POOLS::ITERATOR iterator = this->thread_pools_.begin ();
+ iterator != this->thread_pools_.end ();
+ ++iterator)
+ delete (*iterator).int_id_;
+}
+
+
+void
+TAO_DTP_Thread_Pool_Manager::wait (void)
+{
+ for (THREAD_POOLS::ITERATOR iterator = this->thread_pools_.begin ();
+ iterator != this->thread_pools_.end ();
+ ++iterator)
+ (*iterator).int_id_->wait ();
+}
+
+CORBA::ULong
+TAO_DTP_Thread_Pool_Manager::create_threadpool (TAO_DTP_Definition &def)
+{
+ TAO_THREAD_POOL_MANAGER_GUARD;
+
+ return this->create_threadpool_i (def);
+}
+
+void
+TAO_DTP_Thread_Pool_Manager::destroy_threadpool (CORBA::ULong threadpool)
+{
+ TAO_DTP_Thread_Pool *tao_thread_pool = 0;
+
+ // The guard is just for the map, don't do a wait inside the guard, because
+ // during the wait other threads can try to access the thread pool manager
+ // also, this can be one of the threads we are waiting for, which then
+ // results in a deadlock
+ {
+ TAO_THREAD_POOL_MANAGER_GUARD;
+
+ // Unbind the thread pool from the map.
+ int const result = this->thread_pools_.unbind (threadpool, tao_thread_pool);
+
+ // If the thread pool is not found in our map.
+ if (result != 0)
+ return; //throw RTCORBA::RTORB::InvalidThreadpool ();
+ }
+
+ // Mark the thread pool that we are shutting down.
+ tao_thread_pool->shutting_down ();
+
+ // Wait for the threads.
+ tao_thread_pool->wait ();
+
+ // Delete the thread pool.
+ delete tao_thread_pool;
+
+}
+
+CORBA::ULong
+TAO_DTP_Thread_Pool_Manager::create_threadpool_i (TAO_DTP_Definition &def)
+{
+ // Create the thread pool.
+ TAO_DTP_Thread_Pool *thread_pool = 0;
+
+ ACE_NEW_THROW_EX (thread_pool,
+ TAO_DTP_Thread_Pool (*this,
+ this->thread_pool_id_counter_,
+ def
+ ),
+ CORBA::NO_MEMORY ());
+
+ return this->create_threadpool_helper (thread_pool);
+}
+
+CORBA::ULong
+TAO_DTP_Thread_Pool_Manager::create_threadpool_helper (TAO_DTP_Thread_Pool *thread_pool)
+{
+ // Make sure of safe deletion in case of errors.
+ auto_ptr<TAO_DTP_Thread_Pool> safe_thread_pool (thread_pool);
+
+ // Open the pool.
+ thread_pool->open ();
+
+ // Create the static threads.
+ int result = thread_pool->create_initial_threads ();
+
+ // Throw exception in case of errors.
+ if (result != 0)
+ {
+ throw ::CORBA::INTERNAL
+ (
+ CORBA::SystemException::_tao_minor_code
+ (
+ 0, //TAO_RTCORBA_THREAD_CREATION_LOCATION_CODE,
+ errno),
+ CORBA::COMPLETED_NO);
+ }
+
+ // Bind thread to internal table.
+ result = this->thread_pools_.bind (this->thread_pool_id_counter_, thread_pool);
+
+ TAO_ORB_Core_TSS_Resources &tss =
+ *this->orb_core_.get_tss_resources ();
+ // Associate the thread pool with the ORB for later retrieval
+ tss.lane_ = thread_pool;
+
+ //
+ // Throw exception in case of errors.
+ if (result != 0)
+ throw ::CORBA::INTERNAL ();
+
+ //
+ // Success.
+ //
+
+ // No need to delete thread pool.
+ safe_thread_pool.release ();
+
+ // Return current counter and perform post-increment.
+ return this->thread_pool_id_counter_++;
+}
+
+TAO_ORB_Core &
+TAO_DTP_Thread_Pool_Manager::orb_core (void) const
+{
+ return this->orb_core_;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h
new file mode 100644
index 00000000000..6dae84f7fa4
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h
@@ -0,0 +1,249 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_Thread_Pool.h
+ *
+ * $Id$
+ *
+ * @author Irfan Pyarali
+ * @author Johnny Willemsen
+ * @author Phil Mesnier
+ */
+// ===================================================================
+
+#ifndef TAO_DTP_THREAD_POOL_H
+#define TAO_DTP_THREAD_POOL_H
+
+#include /**/ "ace/pre.h"
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Hash_Map_Manager.h"
+#include "tao/Thread_Lane_Resources.h"
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/New_Leader_Generator.h"
+#include "ace/Task.h"
+#include "ace/Null_Mutex.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_ORB_Core;
+class TAO_DTP_Thread_Pool;
+class TAO_DTP_Thread_Pool_Manager;
+
+/**
+ * @class TAO_DTP_New_Leader_Generator
+ *
+ * @brief Class for creating dynamic threads.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_New_Leader_Generator
+ : public TAO_New_Leader_Generator
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_New_Leader_Generator (TAO_DTP_Thread_Pool &lane);
+
+ /// Leader/Follower class uses this method to notify the system that
+ /// we are out of leaders.
+ void no_leaders_available (void);
+
+private:
+
+ /// Pool associated with this leader generator.
+ TAO_DTP_Thread_Pool &pool_;
+};
+
+/**
+ * @class TAO_DTP_Thread_Pool_Threads
+ *
+ * @brief Class representing a static thread running in a thread lane.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_DTP_Thread_Pool_Threads : public ACE_Task_Base
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_Thread_Pool_Threads (TAO_DTP_Thread_Pool &pool);
+
+ /// Method executed when a thread is spawned.
+ int svc (void);
+
+ /// Accessor to the pool to which this thread belongs to.
+ TAO_DTP_Thread_Pool &pool (void) const;
+
+protected:
+ /// Do the real work
+ virtual int run (TAO_ORB_Core &orb_core);
+
+ /// Pool to which this thread belongs to.
+ TAO_DTP_Thread_Pool &pool_;
+};
+
+
+/**
+ * @class TAO_DTP_Thread_Pool
+ *
+ * @brief Class representing the thread pool inside a thread pool
+ * manager.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_Thread_Pool
+{
+public:
+ TAO_DTP_Thread_Pool (TAO_DTP_Thread_Pool_Manager &manager,
+ CORBA::ULong id,
+ TAO_DTP_Definition &definition);
+
+ /// Destructor.
+ ~TAO_DTP_Thread_Pool (void);
+
+ /// Open the pool.
+ void open (void);
+
+ /// Wait for threads to exit.
+ void wait (void);
+
+ /// Mark this thread pool that we are shutting down.
+ void shutting_down (void);
+
+ /// Create the initial threads - only called once.
+ int create_initial_threads (void);
+
+ /// Called by the TAO_DTP_New_Leader_Generator to request a new dynamic
+ /// thread.
+ /**
+ * It can be that no thread can be created because the number of
+ * threads is equal to the maximum we can have or the Thread Lane
+ * is shutting down.
+ * @retval true A new thread is created
+ * @retval false No thread could be created
+ */
+ bool new_dynamic_thread (void);
+
+ /// Called by the run loop to determine if to expire a thread or not
+ /// when the dynamic timeout is reached.
+ bool above_minimum (void);
+
+ /// @name Accessors
+ // @{
+
+ bool use_timeouts (void) const;
+ const ACE_Time_Value& dynamic_thread_time (void) const;
+
+ TAO_DTP_Thread_Pool_Manager &manager (void) const;
+ CORBA::ULong id (void) const;
+ CORBA::ULong current_threads (void) const;
+
+ // @}
+
+private:
+
+ int create_threads_i (size_t count, long thread_flags);
+
+ /// Create @a number_of_threads of dynamic threads. Can be called
+ /// multiple times.
+ int create_dynamic_threads (size_t count);
+
+ TAO_DTP_Thread_Pool_Manager &manager_;
+
+ CORBA::ULong id_;
+
+ /// This boolean is set when we are shutting down, then we will not create
+ /// any new dynamic threads
+ bool shutdown_;
+
+ TAO_DTP_Definition definition_;
+
+ /// Array with all threads
+ TAO_DTP_Thread_Pool_Threads threads_;
+
+ TAO_DTP_New_Leader_Generator new_thread_generator_;
+
+ /// Lock to guard all members of the pool
+ mutable TAO_SYNCH_MUTEX lock_;
+};
+
+/**
+ * @class TAO_DTP_Thread_Pool_Manager
+ *
+ * @brief Class for managing thread pools.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_Thread_Pool_Manager
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_Thread_Pool_Manager (TAO_ORB_Core &orb_core);
+
+ /// Destructor.
+ ~TAO_DTP_Thread_Pool_Manager (void);
+
+ /// Wait for threads to exit.
+ void wait (void);
+
+ /// Create a threadpool without lanes.
+ CORBA::ULong create_threadpool (TAO_DTP_Definition &def);
+
+ /// Destroy a threadpool.
+ void destroy_threadpool (CORBA::ULong threadpool);
+
+ /// Collection of thread pools.
+ typedef ACE_Hash_Map_Manager<CORBA::ULong, TAO_DTP_Thread_Pool *,
+ ACE_Null_Mutex> THREAD_POOLS;
+
+ /// @name Accessors
+ // @{
+ TAO_ORB_Core &orb_core (void) const;
+ // @}
+
+private:
+
+ /// @name Helpers
+ // @{
+
+ CORBA::ULong
+ create_threadpool_i (TAO_DTP_Definition &def);
+
+ CORBA::ULong
+ create_threadpool_helper (TAO_DTP_Thread_Pool *thread_pool);
+ // @}
+
+private:
+
+ TAO_ORB_Core &orb_core_;
+
+ THREAD_POOLS thread_pools_;
+ CORBA::ULong thread_pool_id_counter_;
+ TAO_SYNCH_MUTEX lock_;
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "tao/Dynamic_TP/DTP_Thread_Pool.inl"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_THREAD_POOL_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.inl b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.inl
new file mode 100644
index 00000000000..9c28cc41e0e
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.inl
@@ -0,0 +1,43 @@
+// -*- C++ -*-
+//
+// $Id$
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_INLINE
+TAO_DTP_Thread_Pool &
+TAO_DTP_Thread_Pool_Threads::pool (void) const
+{
+ return this->pool_;
+}
+
+ACE_INLINE
+TAO_DTP_Thread_Pool_Manager &
+TAO_DTP_Thread_Pool::manager (void) const
+{
+ return this->manager_;
+}
+
+ACE_INLINE
+CORBA::ULong
+TAO_DTP_Thread_Pool::id (void) const
+{
+ return this->id_;
+}
+
+ACE_INLINE
+bool
+TAO_DTP_Thread_Pool::use_timeouts (void) const
+{
+ return this->definition_.max_threads_ > -1;
+}
+
+ACE_INLINE
+const ACE_Time_Value&
+TAO_DTP_Thread_Pool::dynamic_thread_time (void) const
+{
+ return this->definition_.timeout_;
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Dynamic_TP/Dynamic_TP.mpc b/TAO/tao/Dynamic_TP/Dynamic_TP.mpc
new file mode 100644
index 00000000000..764cc76884b
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/Dynamic_TP.mpc
@@ -0,0 +1,10 @@
+//$Id$
+
+project(Dynamic_TP) : taolib, tao_output, install, pi, csd_framework, csd_threadpool {
+ sharedname = TAO_Dynamic_TP
+ dynamicflags += TAO_DYNAMIC_TP_BUILD_DLL
+
+ specific {
+ install_dir = tao/Dynamic_TP
+ }
+}
diff --git a/TAO/tao/Dynamic_TP/dynamic_tp_export.h b/TAO/tao/Dynamic_TP/dynamic_tp_export.h
new file mode 100644
index 00000000000..3c6fd2ff524
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/dynamic_tp_export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl TAO_Dynamic_TP
+// ------------------------------
+#ifndef TAO_DYNAMIC_TP_EXPORT_H
+#define TAO_DYNAMIC_TP_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (TAO_DYNAMIC_TP_HAS_DLL)
+# define TAO_DYNAMIC_TP_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && TAO_DYNAMIC_TP_HAS_DLL */
+
+#if !defined (TAO_DYNAMIC_TP_HAS_DLL)
+# define TAO_DYNAMIC_TP_HAS_DLL 1
+#endif /* ! TAO_DYNAMIC_TP_HAS_DLL */
+
+#if defined (TAO_DYNAMIC_TP_HAS_DLL) && (TAO_DYNAMIC_TP_HAS_DLL == 1)
+# if defined (TAO_DYNAMIC_TP_BUILD_DLL)
+# define TAO_Dynamic_TP_Export ACE_Proper_Export_Flag
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* TAO_DYNAMIC_TP_BUILD_DLL */
+# define TAO_Dynamic_TP_Export ACE_Proper_Import_Flag
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* TAO_DYNAMIC_TP_BUILD_DLL */
+#else /* TAO_DYNAMIC_TP_HAS_DLL == 1 */
+# define TAO_Dynamic_TP_Export
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARATION(T)
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* TAO_DYNAMIC_TP_HAS_DLL == 1 */
+
+// Set TAO_DYNAMIC_TP_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (TAO_DYNAMIC_TP_NTRACE)
+# if (ACE_NTRACE == 1)
+# define TAO_DYNAMIC_TP_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define TAO_DYNAMIC_TP_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !TAO_DYNAMIC_TP_NTRACE */
+
+#if (TAO_DYNAMIC_TP_NTRACE == 1)
+# define TAO_DYNAMIC_TP_TRACE(X)
+#else /* (TAO_DYNAMIC_TP_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define TAO_DYNAMIC_TP_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (TAO_DYNAMIC_TP_NTRACE == 1) */
+
+#endif /* TAO_DYNAMIC_TP_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tao/IIOP_Profile.cpp b/TAO/tao/IIOP_Profile.cpp
index 512d80f5afe..79e01c083bc 100644
--- a/TAO/tao/IIOP_Profile.cpp
+++ b/TAO/tao/IIOP_Profile.cpp
@@ -474,7 +474,7 @@ TAO_IIOP_Profile::add_generic_endpoint (TAO_Endpoint *endp)
}
char *
-TAO_IIOP_Profile::to_string (void)
+TAO_IIOP_Profile::to_string (void) const
{
// corbaloc:iiop:1.2@host:port,iiop:1.2@host:port,.../key
diff --git a/TAO/tao/IIOP_Profile.h b/TAO/tao/IIOP_Profile.h
index ebb886e9958..1bb6fb16d10 100644
--- a/TAO/tao/IIOP_Profile.h
+++ b/TAO/tao/IIOP_Profile.h
@@ -95,7 +95,7 @@ public:
virtual char object_key_delimiter (void) const;
/// Template methods. Please see Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
/// Encode endpoints for RT profiles, using a single TAO_TAG_ENDPOINT
/// component.
diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp
index 3dc71149072..c4cb2025e99 100644
--- a/TAO/tao/IIOP_Transport.cpp
+++ b/TAO/tao/IIOP_Transport.cpp
@@ -166,6 +166,8 @@ TAO_IIOP_Transport::recv (char *buf,
size_t len,
const ACE_Time_Value *max_wait_time)
{
+ this->connection_closed_on_read_ = false;
+
ssize_t const n = this->connection_handler_->peer ().recv (buf,
len,
max_wait_time);
@@ -196,6 +198,7 @@ TAO_IIOP_Transport::recv (char *buf,
// @@ What are the other error handling here??
else if (n == 0)
{
+ this->connection_closed_on_read_ = true;
return -1;
}
diff --git a/TAO/tao/IORManipulation/IORManipulation.cpp b/TAO/tao/IORManipulation/IORManipulation.cpp
index 51b83283892..cbeb0e36bec 100644
--- a/TAO/tao/IORManipulation/IORManipulation.cpp
+++ b/TAO/tao/IORManipulation/IORManipulation.cpp
@@ -27,9 +27,9 @@ TAO_IOR_Manipulation_impl::merge_iors (
{
// we need to create a new CORBA::Object which has the union of the
// two profile lists. However, if any profiles are duplicates (i.e. in
- // bott lisis) then an exception is raised.
+ // both lists) then an exception is raised.
- // Deterinine how many profiles we have
+ // Determine how many profiles we have
// Get an estimate of the size - pfile count could change since we
// neither lock nor get a copy in this loop.
CORBA::ULong i, count=0;
@@ -56,12 +56,12 @@ TAO_IOR_Manipulation_impl::merge_iors (
for (i = 1; i < iors.length () ; i++)
{
- // this gets a copy of the MProfile, hense the auto_ptr;
+ // this gets a copy of the MProfile, hence the auto_ptr;
ACE_auto_ptr_reset (tmp_pfiles,
iors[i]->_stubobj ()->make_profiles ());
- // check to see if any of the profile in tmp_pfiles are already
+ // check to see if any of the profiles in tmp_pfiles are already
// in Merged_Profiles. If so raise exception.
if (Merged_Profiles.is_equivalent (tmp_pfiles.get ()))
throw TAO_IOP::Duplicate ();
diff --git a/TAO/tao/ImR_Client/ImR_Client.cpp b/TAO/tao/ImR_Client/ImR_Client.cpp
index 010b938b876..810872ab321 100644
--- a/TAO/tao/ImR_Client/ImR_Client.cpp
+++ b/TAO/tao/ImR_Client/ImR_Client.cpp
@@ -2,6 +2,7 @@
#include "tao/ImR_Client/ImR_Client.h"
+#include "ace/Vector_T.h"
#include "tao/debug.h"
#include "tao/ORB_Core.h"
#include "tao/Stub.h"
@@ -10,9 +11,193 @@
#include "tao/PortableServer/Non_Servant_Upcall.h"
#include "tao/ImR_Client/ServerObject_i.h"
#include "tao/ImR_Client/ImplRepoC.h"
+#include "tao/IORManipulation/IORManip_Loader.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+namespace
+{
+ char* find_delimiter (char* const ior, const char delimiter)
+ {
+ // Search for "corbaloc:" alone, without the protocol. This code
+ // should be protocol neutral.
+ const char corbaloc[] = ACE_TEXT_ALWAYS_CHAR ("corbaloc:");
+ char *pos = ACE_OS::strstr (ior, corbaloc);
+ pos = ACE_OS::strchr (pos + sizeof (corbaloc), ':');
+
+ pos = ACE_OS::strchr (pos + 1, delimiter);
+
+ return pos;
+ }
+
+ CORBA::Object_ptr combine (TAO_ORB_Core& orb_core,
+ const TAO_Profile& profile,
+ const char* const key_str,
+ const char* type_id)
+ {
+ CORBA::String_var profile_str = profile.to_string ();
+
+// if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("************** IMR partial IOR =\n%C\n"),
+ profile_str.in ()));
+
+ char* const pos = find_delimiter (profile_str.inout (),
+ profile.object_key_delimiter ());
+ if (pos)
+ pos[1] = 0; // Crop the string.
+ else
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Could not parse ImR IOR, skipping ImRification\n")));
+ return CORBA::Object::_nil();
+ }
+
+ ACE_CString ior (profile_str.in ());
+
+ // Add the key.
+ ior += key_str;
+
+// if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("************** ImR-ified IOR =\n%C\n\n"),
+ ior.c_str ()));
+
+ CORBA::Object_ptr obj = orb_core.orb ()->string_to_object (ior.c_str ());
+ obj->_stubobj()->type_id = type_id;
+ return obj;
+ }
+
+ class ImRifyProfiles
+ {
+ public:
+ ImRifyProfiles (const TAO_MProfile& base_profiles,
+ const TAO_Profile* const profile_in_use,
+ TAO_ORB_Core& orb_core,
+ const char* const key_str,
+ const char* type_id)
+ : base_profiles_ (base_profiles),
+ profile_in_use_ (profile_in_use),
+ orb_core_ (orb_core),
+ key_str_ (key_str),
+ type_id_ (type_id),
+ objs_ (base_profiles.profile_count()),
+ list_buffer_ (new CORBA::Object_ptr[base_profiles.profile_count()]),
+ ior_list_ (base_profiles.profile_count (),
+ base_profiles.profile_count (),
+ list_buffer_,
+ 0)
+ {
+ }
+
+ CORBA::Object_ptr combined_ior ()
+ {
+ const CORBA::ULong pcount = base_profiles_.profile_count ();
+ for (CORBA::ULong i = 0; i < pcount; ++i)
+ {
+ if (!combine_profile (i))
+ {
+ return default_obj (
+ ACE_TEXT_ALWAYS_CHAR ("could not resolve IORManipulation"));
+ }
+ }
+
+ CORBA::Object_var IORM = orb_core_.orb ()
+ ->resolve_initial_references (TAO_OBJID_IORMANIPULATION, 0);
+
+ if (CORBA::is_nil (IORM.in ()))
+ {
+ return default_obj (
+ ACE_TEXT_ALWAYS_CHAR ("could not resolve IORManipulation"));
+ }
+
+ TAO_IOP::TAO_IOR_Manipulation_var iorm =
+ TAO_IOP::TAO_IOR_Manipulation::_narrow (IORM.in ());
+
+ if (CORBA::is_nil (iorm.in ()))
+ {
+ return default_obj (
+ ACE_TEXT_ALWAYS_CHAR ("could not narrow IORManipulation"));
+ }
+
+ try
+ {
+ return iorm->merge_iors(ior_list_);
+ }
+ catch (const ::CORBA::Exception& )
+ {
+ return default_obj (
+ ACE_TEXT_ALWAYS_CHAR ("could not ImRify object with all profiles."));
+ }
+ }
+ private:
+ bool combine_profile(const CORBA::ULong i)
+ {
+ try
+ {
+ // store the combined profile+key
+ list_buffer_[i] = combine (orb_core_,
+ *(base_profiles_.get_profile (i)),
+ key_str_,
+ type_id_);
+ // manage the memory
+ objs_[i] = list_buffer_[i];
+
+ return true;
+ }
+ catch (const ::CORBA::Exception& )
+ {
+ return false;
+ }
+ }
+
+ CORBA::Object_ptr default_obj(const char* desc)
+ {
+ const CORBA::ULong pcount = base_profiles_.profile_count ();
+ const char* info =
+ ACE_TEXT ("because couldn't find ImR profile_in_use in profiles");
+
+ // identify the profile in use to see if we can default to
+ // that profiles partial ImR-ification
+ for (CORBA::ULong i = 0; i < pcount; ++i)
+ {
+ if (profile_in_use_ == base_profiles_.get_profile (i))
+ {
+ // if there is no object then try one last time to combine
+ // the profile
+ if (CORBA::is_nil(objs_[i].in ()) && !combine_profile (i))
+ {
+ info = ACE_TEXT ("because couldn't ImR-ify profile_in_use");
+ break;
+ }
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("ERROR: %C. ")
+ ACE_TEXT("Defaulting to ImR-ifying profile_in_use\n"),
+ desc));
+ return objs_[i]._retn ();
+ }
+ }
+
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT ("ERROR: %C, ")
+ ACE_TEXT ("but cannot default to ImR-ifying profile_in_use %C\n"),
+ desc,
+ info));
+ return CORBA::Object::_nil();
+ }
+
+ const TAO_MProfile& base_profiles_;
+ const TAO_Profile* const profile_in_use_;
+ TAO_ORB_Core& orb_core_;
+ const char* const key_str_;
+ const char* const type_id_;
+ ACE_Vector<CORBA::Object_var> objs_;
+ CORBA::Object_ptr* const list_buffer_;
+ TAO_IOP::TAO_IOR_Manipulation::IORList ior_list_;
+ };
+}
+
namespace TAO
{
namespace ImR_Client
@@ -38,7 +223,18 @@ namespace TAO
}
if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG, "Notifying ImR of startup\n"));
+ {
+ ACE_CString imr_info;
+ if (TAO_debug_level > 1)
+ {
+ CORBA::ORB_ptr orb = poa->orb_core ().orb ();
+ CORBA::String_var ior = orb->object_to_string (imr.in ());
+ imr_info = ACE_CString (", IMR IOR=") + ior.in ();
+ }
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Notifying ImR of startup%s\n"),
+ imr_info.c_str ()));
+ }
ImplementationRepository::Administration_var imr_locator;
@@ -51,7 +247,7 @@ namespace TAO
ImplementationRepository::Administration::_narrow (imr.in ());
}
- if (CORBA::is_nil(imr_locator.in ()))
+ if (CORBA::is_nil (imr_locator.in ()))
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) ERROR: Narrowed IMR initial reference ")
@@ -82,7 +278,7 @@ namespace TAO
poa->server_priority (),
wait_occurred_restart_call_ignored);
- CORBA::Object_var obj = root_poa->id_to_reference_i (id.in (), false);
+ CORBA::Object_var obj = root_poa->id_to_reference_i (id.in (), false);
ImplementationRepository::ServerObject_var svr
= ImplementationRepository::ServerObject::_narrow (obj.in ());
@@ -93,24 +289,23 @@ namespace TAO
return;
}
- CORBA::String_var ior =
- svr->_stubobj ()->profile_in_use ()->to_string ();
+ CORBA::String_var full_ior = root_poa->_get_orb()->object_to_string (obj.in ());
+ TAO_Profile& profile = *(svr->_stubobj ()->profile_in_use ());
+ CORBA::String_var ior = profile.to_string();
+ ACE_DEBUG((LM_INFO,
+ "\n\nfull_ior=<%s>\n\nior=<%s>\n\n",
+ full_ior.in(),
+ ior.in()));
- // Search for "corbaloc:" alone, without the protocol. This code
- // should be protocol neutral.
- const char corbaloc[] = "corbaloc:";
- char *pos = ACE_OS::strstr (ior.inout (), corbaloc);
- pos = ACE_OS::strchr (pos + sizeof (corbaloc), ':');
+ char* const pos = find_delimiter (ior.inout (),
+ profile.object_key_delimiter ());
- pos = ACE_OS::strchr (pos + 1,
- svr->_stubobj ()->profile_in_use ()->object_key_delimiter ());
-
- ACE_CString partial_ior(ior.in (), (pos - ior.in()) + 1);
+ const ACE_CString partial_ior (ior.in (), (pos - ior.in ()) + 1);
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
- "Informing IMR that we are running at: %C\n",
- partial_ior.c_str()));
+ ACE_TEXT ("Informing IMR that we are running at: %C\n"),
+ partial_ior.c_str ()));
try
{
@@ -122,16 +317,16 @@ namespace TAO
ACE_CString name;
if (serverId.empty ())
{
- name = poa->name();
+ name = poa->name ();
}
else
{
- name = serverId + ":" + poa->name();
+ name = serverId + ":" + poa->name ();
}
imr_locator->server_is_running (name.c_str (),
- partial_ior.c_str(),
- svr.in());
+ partial_ior.c_str (),
+ svr.in ());
}
catch (const ::CORBA::SystemException&)
{
@@ -145,7 +340,8 @@ namespace TAO
}
if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG, "Successfully notified ImR of Startup\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Successfully notified ImR of Startup\n")));
}
void
@@ -165,7 +361,7 @@ namespace TAO
{
CORBA::String_var poaname = poa->the_name ();
ACE_DEBUG ((LM_DEBUG,
- "Notifying IMR of Shutdown server:%s\n",
+ ACE_TEXT ("Notifying IMR of Shutdown server:%s\n"),
poaname.in ()));
}
@@ -177,7 +373,7 @@ namespace TAO
ImplementationRepository::Administration_var imr_locator =
ImplementationRepository::Administration::_narrow (imr.in ());
- imr_locator->server_is_shutting_down (poa->name().c_str ());
+ imr_locator->server_is_shutting_down (poa->name ().c_str ());
}
catch (const ::CORBA::COMM_FAILURE&)
{
@@ -185,13 +381,17 @@ namespace TAO
// configured to drop replies during shutdown (it does by default in
// the LF model) we get a COMM_FAILURE exception which we ignore
if (TAO_debug_level > 0)
- ACE_DEBUG((LM_DEBUG, "Ignoring COMM_FAILURE while unregistering from ImR.\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Ignoring COMM_FAILURE while unregistering")
+ ACE_TEXT ("from ImR.\n")));
}
catch (const ::CORBA::TRANSIENT&)
{
// Similarly, there are cases where we could get a TRANSIENT.
if (TAO_debug_level > 0)
- ACE_DEBUG((LM_DEBUG, "Ignoring TRANSIENT while unregistering from ImR.\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Ignoring TRANSIENT while unregistering")
+ ACE_TEXT ("from ImR.\n")));
}
catch (const ::CORBA::Exception& ex)
{
@@ -202,9 +402,11 @@ namespace TAO
if (this->server_object_)
{
- PortableServer::POA_var default_poa = this->server_object_->_default_POA ();
+ PortableServer::POA_var default_poa =
+ this->server_object_->_default_POA ();
- TAO_Root_POA *root_poa = dynamic_cast <TAO_Root_POA*> (default_poa.in ());
+ TAO_Root_POA *root_poa =
+ dynamic_cast <TAO_Root_POA*> (default_poa.in ());
if (!root_poa)
{
@@ -214,7 +416,7 @@ namespace TAO
PortableServer::ObjectId_var id =
root_poa->servant_to_id_i (this->server_object_);
- root_poa->deactivate_object_i (id.in());
+ root_poa->deactivate_object_i (id.in ());
this->server_object_ = 0;
}
@@ -227,16 +429,63 @@ namespace TAO
int
ImR_Client_Adapter_Impl::Initializer (void)
{
- TAO_Root_POA::imr_client_adapter_name ("Concrete_ImR_Client_Adapter");
+ TAO_Root_POA::imr_client_adapter_name (
+ ACE_TEXT_ALWAYS_CHAR ("Concrete_ImR_Client_Adapter"));
+
+ return ACE_Service_Config::process_directive (
+ ace_svc_desc_ImR_Client_Adapter_Impl);
+ }
+
+ CORBA::Object_ptr
+ ImR_Client_Adapter_Impl::imr_key_to_object(TAO_Root_POA* poa,
+ const TAO::ObjectKey &key,
+ const char* type_id) const
+ {
+ TAO_ORB_Core& orb_core = poa->orb_core ();
+ // Check to see if we alter the IOR.
+ CORBA::Object_var imr = orb_core.implrepo_service ();
+
+ if (CORBA::is_nil (imr.in ())
+ || !imr->_stubobj ()
+ || !imr->_stubobj ()->profile_in_use ())
+ {
+ if (TAO_debug_level > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Missing ImR IOR, will not use the ImR\n")));
+ }
+ return CORBA::Object::_nil();
+ }
+
+ const TAO_MProfile& base_profiles = imr->_stubobj ()->base_profiles ();
+ CORBA::String_var key_str;
+ TAO::ObjectKey::encode_sequence_to_string (key_str.inout (), key);
+
+ // if there is only one profile, no need to use IORManipulation
+ if (base_profiles.profile_count() == 1)
+ {
+ return combine(orb_core,
+ *base_profiles.get_profile(0),
+ key_str.in(),
+ ACE_TEXT_ALWAYS_CHAR (type_id));
+ }
+
+ // need to combine each profile in the ImR with the key and
+ // then merge them all together into one ImR-ified ior
+ ImRifyProfiles imrify (base_profiles,
+ imr->_stubobj ()->profile_in_use (),
+ orb_core,
+ key_str,
+ ACE_TEXT_ALWAYS_CHAR (type_id));
- return ACE_Service_Config::process_directive (ace_svc_desc_ImR_Client_Adapter_Impl);
+ return imrify.combined_ior ();
}
}
}
ACE_STATIC_SVC_DEFINE (
ImR_Client_Adapter_Impl,
- ACE_TEXT ("Concrete_ImR_Client_Adapter"),
+ ACE_TEXT_ALWAYS_CHAR ("Concrete_ImR_Client_Adapter"),
ACE_SVC_OBJ_T,
&ACE_SVC_NAME (ImR_Client_Adapter_Impl),
ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
diff --git a/TAO/tao/ImR_Client/ImR_Client.h b/TAO/tao/ImR_Client/ImR_Client.h
index ed270a2af03..02185598e6d 100644
--- a/TAO/tao/ImR_Client/ImR_Client.h
+++ b/TAO/tao/ImR_Client/ImR_Client.h
@@ -59,6 +59,11 @@ namespace TAO
/// ImplRepo helper method, notify the ImplRepo on shutdown
virtual void imr_notify_shutdown (TAO_Root_POA* poa);
+ /// ImplRepo helper method, create an IMR-ified object for a
+ /// key with a given type
+ virtual CORBA::Object_ptr imr_key_to_object(TAO_Root_POA* poa,
+ const TAO::ObjectKey &key,
+ const char *type_id) const;
private:
/// Implementation Repository Server Object
ServerObject_i *server_object_;
diff --git a/TAO/tao/ImR_Client/ImR_Client.mpc b/TAO/tao/ImR_Client/ImR_Client.mpc
index 26d5027ea46..4350825cc33 100644
--- a/TAO/tao/ImR_Client/ImR_Client.mpc
+++ b/TAO/tao/ImR_Client/ImR_Client.mpc
@@ -24,7 +24,7 @@ project(*idl) : tao_versioning_idl_defaults, install {
}
}
-project(ImR_Client) : taolib, tao_output, install, portableserver, taoidldefaults {
+project(ImR_Client) : taolib, tao_output, install, portableserver, taoidldefaults, iormanip {
after += *idl
sharedname = TAO_ImR_Client
dynamicflags += TAO_IMR_CLIENT_BUILD_DLL
diff --git a/TAO/tao/Invocation_Adapter.cpp b/TAO/tao/Invocation_Adapter.cpp
index f85187b0172..310cec2dad1 100644
--- a/TAO/tao/Invocation_Adapter.cpp
+++ b/TAO/tao/Invocation_Adapter.cpp
@@ -15,6 +15,7 @@
#include "tao/TAOC.h"
#include "tao/SystemException.h"
#include "tao/Collocation_Resolver.h"
+#include "tao/Invocation_Retry_State.h"
#include "ace/Service_Config.h"
#if !defined (__ACE_INLINE__)
@@ -69,6 +70,8 @@ namespace TAO
max_wait_time= &tmp_wait_time;
}
+ TAO::Invocation_Retry_State retry_state (*stub);
+
while (status == TAO_INVOKE_START || status == TAO_INVOKE_RESTART)
{
// Default we go to remote
@@ -95,7 +98,8 @@ namespace TAO
this->invoke_remote_i (stub,
details,
effective_target,
- max_wait_time);
+ max_wait_time,
+ &retry_state);
}
else
{
@@ -228,7 +232,8 @@ namespace TAO
Invocation_Adapter::invoke_remote_i (TAO_Stub *stub,
TAO_Operation_Details &details,
CORBA::Object_var &effective_target,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
(void) this->set_response_flags (stub, details);
@@ -270,7 +275,8 @@ namespace TAO
return this->invoke_twoway (details,
effective_target,
resolver,
- max_wait_time);
+ max_wait_time,
+ retry_state);
}
}
@@ -281,7 +287,8 @@ namespace TAO
Invocation_Adapter::invoke_twoway (TAO_Operation_Details &details,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
// Simple sanity check
if (this->mode_ != TAO_SYNCHRONOUS_INVOCATION ||
@@ -294,7 +301,10 @@ namespace TAO
CORBA::COMPLETED_NO);
}
- TAO::Synch_Twoway_Invocation synch (this->target_, r, details);
+ TAO::Synch_Twoway_Invocation synch (this->target_, r, details,
+ true);
+
+ synch.set_retry_state (retry_state);
Invocation_Status const status = synch.remote_twoway (max_wait_time);
diff --git a/TAO/tao/Invocation_Adapter.h b/TAO/tao/Invocation_Adapter.h
index f539c28de45..b1ec5f7db19 100644
--- a/TAO/tao/Invocation_Adapter.h
+++ b/TAO/tao/Invocation_Adapter.h
@@ -47,6 +47,7 @@ namespace TAO
class Argument;
struct Exception_Data;
class Profile_Transport_Resolver;
+ class Invocation_Retry_State;
/**
* @class Invocation_Adapter
@@ -124,7 +125,9 @@ namespace TAO
* @param ex_count Number of elements in the array.
*/
virtual void invoke (TAO::Exception_Data *ex, unsigned long ex_count);
+
protected:
+
/**
* The stub pointer passed to this call has all the details about
* the object to which the invocation needs to be routed to. The
@@ -163,7 +166,8 @@ namespace TAO
TAO_Stub *stub,
TAO_Operation_Details &details,
CORBA::Object_var &effective_target,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
/// Make a collocated call.
/**
@@ -193,7 +197,8 @@ namespace TAO
TAO_Operation_Details &details,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
/// Helper method to make a one way invocation.
/**
diff --git a/TAO/tao/Invocation_Retry_Params.cpp b/TAO/tao/Invocation_Retry_Params.cpp
new file mode 100644
index 00000000000..4d966613d36
--- /dev/null
+++ b/TAO/tao/Invocation_Retry_Params.cpp
@@ -0,0 +1,20 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#include "tao/Invocation_Retry_Params.h"
+#include "tao/Invocation_Utils.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO::Invocation_Retry_Params::Invocation_Retry_Params (void)
+ : forward_on_reply_closed_limit_ (0)
+ , init_retry_delay_ (0, 100000) // Set default to 0.1 seconds
+{
+ this->forward_on_exception_limit_[FOE_OBJECT_NOT_EXIST] = 0;
+ this->forward_on_exception_limit_[FOE_COMM_FAILURE] = 0;
+ this->forward_on_exception_limit_[FOE_TRANSIENT] = 0;
+ this->forward_on_exception_limit_[FOE_INV_OBJREF] = 0;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Invocation_Retry_Params.h b/TAO/tao/Invocation_Retry_Params.h
new file mode 100644
index 00000000000..659ad4f7655
--- /dev/null
+++ b/TAO/tao/Invocation_Retry_Params.h
@@ -0,0 +1,61 @@
+/* -*- C++ -*- $Id$ */
+//=============================================================================
+/**
+ * @file Invocation_Retry_Params.h
+ *
+ * $Id$
+ *
+ * @author Byron Harris (harrisb@ociweb.com)
+ */
+//=============================================================================
+
+#ifndef TAO_INVOCATION_RETRY_PARAMS_H
+#define TAO_INVOCATION_RETRY_PARAMS_H
+
+#include "tao/orbconf.h"
+#include "ace/Array_Map.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ /**
+ * @struct Invocation_Retry_Params
+ *
+ * @brief Contains the invocation retry parameters used when encountering
+ * CORBA exceptions.
+ * The parameters can be specified using either the Client_Strategy_Factory
+ * service given in the service configuration file or through the command line.
+ * Any command line parameter overrides the corresponding option in the service
+ * configurator file.
+ */
+ struct Invocation_Retry_Params
+ {
+ Invocation_Retry_Params();
+
+ typedef ACE_Array_Map<int, int> exception_limit_map_type;
+
+ /**
+ * The maximum number of retry attempts per exception type
+ * when exceptions are encountered. The profiles are
+ * cycled through during each attempt.
+ */
+ exception_limit_map_type forward_on_exception_limit_;
+
+ /**
+ * The maximum number of times to retry a an invocation
+ * if the the connection to the server is closed when
+ * trying to get a reply.
+ */
+ int forward_on_reply_closed_limit_;
+
+ /**
+ * The delay to use between cycles of base and forward profiles.
+ */
+ ACE_Time_Value init_retry_delay_;
+ };
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_INVOCATION_RETRY_PARAMS_H*/
diff --git a/TAO/tao/Invocation_Retry_State.cpp b/TAO/tao/Invocation_Retry_State.cpp
new file mode 100644
index 00000000000..7204250846a
--- /dev/null
+++ b/TAO/tao/Invocation_Retry_State.cpp
@@ -0,0 +1,176 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#include "tao/Invocation_Retry_State.h"
+#include "tao/ORB_Core.h"
+#include "tao/Client_Strategy_Factory.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace
+{
+ void retry_limit_calc (int ex,
+ TAO::Invocation_Retry_Params &command_line_params,
+ TAO::Invocation_Retry_Params &client_factory_params,
+ TAO::Invocation_Retry_Params &result)
+ {
+ if (command_line_params.forward_on_exception_limit_[ex] !=
+ result.forward_on_exception_limit_[ex])
+ result.forward_on_exception_limit_[ex] =
+ command_line_params.forward_on_exception_limit_[ex];
+ else if (client_factory_params.forward_on_exception_limit_[ex] !=
+ result.forward_on_exception_limit_[ex])
+ result.forward_on_exception_limit_[ex] =
+ client_factory_params.forward_on_exception_limit_[ex];
+ }
+
+ /// Calculate the retry parameters by giving a command line parameter
+ /// precedence over the corresponding client strategy factory parameter.
+ /// result is assumed to be passed with default values
+ void retry_params_calc (TAO::Invocation_Retry_Params &command_line_params,
+ TAO::Invocation_Retry_Params &client_factory_params,
+ TAO::Invocation_Retry_Params &result)
+ {
+
+ // Retry delay
+ if (command_line_params.init_retry_delay_ !=
+ result.init_retry_delay_)
+ result.init_retry_delay_ = command_line_params.init_retry_delay_;
+ else if (client_factory_params.init_retry_delay_ !=
+ result.init_retry_delay_)
+ result.init_retry_delay_ = client_factory_params.init_retry_delay_;
+
+ // Retry on reply closed limit
+ if (command_line_params.forward_on_reply_closed_limit_ !=
+ result.forward_on_reply_closed_limit_)
+ result.forward_on_reply_closed_limit_ =
+ command_line_params.forward_on_reply_closed_limit_;
+ else if (client_factory_params.forward_on_reply_closed_limit_ !=
+ result.forward_on_reply_closed_limit_)
+ result.forward_on_reply_closed_limit_ =
+ client_factory_params.forward_on_reply_closed_limit_;
+
+ // Forward on exception limits
+
+ retry_limit_calc (TAO::FOE_OBJECT_NOT_EXIST,
+ command_line_params,
+ client_factory_params,
+ result);
+
+ retry_limit_calc (TAO::FOE_COMM_FAILURE,
+ command_line_params,
+ client_factory_params,
+ result);
+
+ retry_limit_calc (TAO::FOE_TRANSIENT,
+ command_line_params,
+ client_factory_params,
+ result);
+
+ retry_limit_calc (TAO::FOE_INV_OBJREF,
+ command_line_params,
+ client_factory_params,
+ result);
+
+ }
+
+}
+
+TAO::Invocation_Retry_State::Invocation_Retry_State (TAO_Stub &stub)
+ : forward_on_reply_closed_count_ (0)
+ , forward_on_exception_limit_used_ (false)
+{
+ this->ex_count_map_[FOE_OBJECT_NOT_EXIST] = 0;
+ this->ex_count_map_[FOE_COMM_FAILURE] = 0;
+ this->ex_count_map_[FOE_TRANSIENT] = 0;
+ this->ex_count_map_[FOE_INV_OBJREF] = 0;
+
+ // Cast away const to avoid tedious iterator operations on the ACE_Array_Map.
+ TAO::Invocation_Retry_Params &command_line_params =
+ const_cast<TAO::Invocation_Retry_Params &> (stub.orb_core ()
+ ->orb_params ()->invocation_retry_params ());
+ TAO::Invocation_Retry_Params &client_factory_params =
+ const_cast<TAO::Invocation_Retry_Params &> (stub.orb_core ()
+ ->client_factory ()->invocation_retry_params ());
+
+ retry_params_calc(command_line_params,
+ client_factory_params,
+ this->retry_params_);
+
+ for (Invocation_Retry_Params::exception_limit_map_type::const_iterator i =
+ this->retry_params_.forward_on_exception_limit_.begin();
+ i != this->retry_params_.forward_on_exception_limit_.end(); ++i)
+ {
+ if (i->second > 0)
+ {
+ forward_on_exception_limit_used_ = true;
+ break;
+ }
+ }
+}
+
+TAO::Invocation_Retry_State::~Invocation_Retry_State ()
+{
+}
+
+bool
+TAO::Invocation_Retry_State::forward_on_exception_limit_used () const
+{
+ return forward_on_exception_limit_used_;
+}
+
+bool
+TAO::Invocation_Retry_State::forward_on_exception_increment (const int ef)
+{
+ if (!this->forward_on_exception_limit_used_)
+ return false;
+
+ int count = this->ex_count_map_[ef];
+ Invocation_Retry_Params::exception_limit_map_type::const_iterator i =
+ this->retry_params_.forward_on_exception_limit_.find (ef);
+ int limit = i->second;
+ if (count < limit)
+ {
+ this->ex_count_map_[ef] = count + 1;
+ return true;
+ }
+
+ return false;
+}
+
+bool
+TAO::Invocation_Retry_State::forward_on_reply_closed_increment ()
+{
+ if (this->forward_on_reply_closed_count_ <
+ this->retry_params_.forward_on_reply_closed_limit_)
+ {
+ ++this->forward_on_reply_closed_count_;
+ return true;
+ }
+
+ return false;
+}
+
+void
+TAO::Invocation_Retry_State::next_profile_retry (TAO_Stub &stub) const
+{
+ stub.next_profile_retry ();
+ this->sleep_at_starting_profile (stub);
+}
+
+void
+TAO::Invocation_Retry_State::sleep_at_starting_profile (TAO_Stub &stub) const
+{
+ if (stub.at_starting_profile ())
+ this->sleep ();
+}
+
+void
+TAO::Invocation_Retry_State::sleep () const
+{
+ ACE_OS::sleep (this->retry_params_.init_retry_delay_);
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Invocation_Retry_State.h b/TAO/tao/Invocation_Retry_State.h
new file mode 100644
index 00000000000..096f32fadf8
--- /dev/null
+++ b/TAO/tao/Invocation_Retry_State.h
@@ -0,0 +1,98 @@
+/* -*- C++ -*- $Id$ */
+//=============================================================================
+/**
+ * @file Invocation_Retry_State.h
+ *
+ * $Id$
+ *
+ * @author Byron Harris (harrisb@ociweb.com)
+ *
+ */
+//=============================================================================
+
+#ifndef TAO_INVOCATION_RETRY_STATE_H
+#define TAO_INVOCATION_RETRY_STATE_H
+
+#include "tao/Stub.h"
+#include "tao/Invocation_Retry_Params.h"
+
+#include "ace/Array_Map.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ /**
+ * @class Invocation_Retry_State
+ *
+ * @brief Maintains state of invocation retries.
+ */
+ class Invocation_Retry_State
+ {
+ public:
+ Invocation_Retry_State (TAO_Stub &stub);
+
+ ~Invocation_Retry_State ();
+
+ /**
+ * Answer if any profile forward on exception limit
+ * parameter is used.
+ */
+ bool forward_on_exception_limit_used () const;
+
+ /**
+ * Attempt to increment the count of profile
+ * forwards.
+ * @return false if forward on exception is not
+ * being used or the limit has been reached.
+ */
+ bool forward_on_exception_increment (const int ef);
+
+ /**
+ * Attempt to increment the count of retries
+ * when a server connection is seen as closed
+ * during reply.
+ */
+ bool forward_on_reply_closed_increment ();
+
+ /**
+ * Increment to next profile in preparation
+ * to retry using that profile.
+ * If the next profile is the starting
+ * base profile then also call
+ * sleep ().
+ * @see TAO_Stub::next_profile_retry()
+ */
+ void next_profile_retry (TAO_Stub &stub) const;
+
+ /**
+ * Sleep if profile is the starting
+ * base profile.
+ */
+ void sleep_at_starting_profile (TAO_Stub &stub) const;
+
+ /**
+ * Sleep according to the delay value
+ * in Invocation_Retry_Params.
+ */
+ void sleep () const;
+
+ private:
+
+ typedef ACE_Array_Map<int, int> Ex_Count_Map;
+ Ex_Count_Map ex_count_map_;
+ int forward_on_reply_closed_count_;
+ Invocation_Retry_Params retry_params_;
+ bool forward_on_exception_limit_used_;
+ };
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_INVOCATION_RETRY_STATE_H*/
diff --git a/TAO/tao/Invocation_Utils.h b/TAO/tao/Invocation_Utils.h
index 54e8ec6a0c5..f17df10c510 100644
--- a/TAO/tao/Invocation_Utils.h
+++ b/TAO/tao/Invocation_Utils.h
@@ -71,7 +71,7 @@ namespace TAO
TAO_DII_ASYNCH_INVOCATION
};
- enum Forward_Once_Exception
+ enum Forward_On_Exception
{
FOE_NON = 0x0,
FOE_OBJECT_NOT_EXIST = 0x1,
diff --git a/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp b/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
index e0b8a583be7..3e189293220 100644
--- a/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
+++ b/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
@@ -152,8 +152,11 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
+ ACE_UNUSED_ARG (retry_state);
+
// Simple sanity check
if (this->mode_ != TAO_ASYNCHRONOUS_CALLBACK_INVOCATION
|| this->type_ != TAO_TWOWAY_INVOCATION)
diff --git a/TAO/tao/Messaging/Asynch_Invocation_Adapter.h b/TAO/tao/Messaging/Asynch_Invocation_Adapter.h
index 4c78afaedae..c562f2fcba8 100644
--- a/TAO/tao/Messaging/Asynch_Invocation_Adapter.h
+++ b/TAO/tao/Messaging/Asynch_Invocation_Adapter.h
@@ -80,7 +80,8 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
virtual Invocation_Status invoke_collocated_i (
TAO_Stub *stub,
diff --git a/TAO/tao/ORB_Core.cpp b/TAO/tao/ORB_Core.cpp
index 6fa0711bba6..cdae1455171 100644
--- a/TAO/tao/ORB_Core.cpp
+++ b/TAO/tao/ORB_Core.cpp
@@ -1102,7 +1102,54 @@ TAO_ORB_Core::init (int &argc, char *argv[] )
arg_shifter.consume_arg ();
}
else if (0 != (current_arg = arg_shifter.get_the_parameter
- (ACE_TEXT("-ORBForwardOnceOnObjectNotExist"))))
+ (ACE_TEXT("-ORBForwardOnTransientLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.forward_on_exception_limit (TAO::FOE_TRANSIENT, limit);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnCommFailureLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.forward_on_exception_limit (
+ TAO::FOE_COMM_FAILURE, limit);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnObjectNotExistLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.forward_on_exception_limit (
+ TAO::FOE_OBJECT_NOT_EXIST, limit);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnInvObjrefLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.forward_on_exception_limit (
+ TAO::FOE_INV_OBJREF, limit);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnReplyClosedLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.invocation_retry_params ()
+ .forward_on_reply_closed_limit_ = limit;
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardDelay"))))
+ {
+ int msecs = ACE_OS::atoi (current_arg);
+ ACE_Time_Value delay(0, 1000*msecs);
+ this->orb_params_.forward_on_exception_delay (delay);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnceOnObjectNotExist"))))
{
int forward = ACE_OS::atoi (current_arg);
if (forward)
@@ -1138,12 +1185,18 @@ TAO_ORB_Core::init (int &argc, char *argv[] )
arg_shifter.consume_arg ();
}
else if (0 != (current_arg = arg_shifter.get_the_parameter
- (ACE_TEXT("-ORBAllowZIOPNoServerPolicies"))))
+ (ACE_TEXT("-ORBAllowZIOPNoServerPolicies"))))
{
// This option takes a boolean 0 (off/dissallow) or 1 (on/allow)
this->orb_params_.allow_ziop_no_server_policies (!!ACE_OS::atoi (current_arg));
arg_shifter.consume_arg ();
}
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBDynamicThreadPoolName"))))
+ {
+ this->orb_params_.dynamic_thread_pool_config_name (current_arg);
+ arg_shifter.consume_arg ();
+ }
////////////////////////////////////////////////////////////////
// catch any unknown -ORB args //
diff --git a/TAO/tao/PortableServer/ImR_Client_Adapter.h b/TAO/tao/PortableServer/ImR_Client_Adapter.h
index 70be6e3c5d2..600aaa43fe6 100644
--- a/TAO/tao/PortableServer/ImR_Client_Adapter.h
+++ b/TAO/tao/PortableServer/ImR_Client_Adapter.h
@@ -29,8 +29,16 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL
class TAO_Root_POA;
+namespace CORBA
+{
+ class Object;
+ typedef Object* Object_ptr;
+}
+
namespace TAO
{
+ class ObjectKey;
+
namespace Portable_Server
{
/**
@@ -53,6 +61,13 @@ namespace TAO
/// ImplRepo helper method, notify the ImplRepo on shutdown
virtual void imr_notify_shutdown (TAO_Root_POA* poa ) = 0;
+
+ /// ImplRepo helper method, create an IMR-ified object for a
+ /// key with a given type
+ virtual CORBA::Object_ptr imr_key_to_object(
+ TAO_Root_POA* poa,
+ const TAO::ObjectKey &key,
+ const char *type_id) const = 0;
};
}
}
diff --git a/TAO/tao/PortableServer/LifespanStrategy.h b/TAO/tao/PortableServer/LifespanStrategy.h
index 70e0c06c04d..7b562e8c801 100644
--- a/TAO/tao/PortableServer/LifespanStrategy.h
+++ b/TAO/tao/PortableServer/LifespanStrategy.h
@@ -37,9 +37,9 @@ namespace TAO
public:
LifespanStrategy (void);
- virtual void strategy_init(TAO_Root_POA *poa);
+ virtual void strategy_init (TAO_Root_POA *poa);
- virtual void strategy_cleanup(void);
+ virtual void strategy_cleanup (void);
void create (const char *name, const TAO::ObjectKey &key);
@@ -72,10 +72,14 @@ namespace TAO
/// Check the state of the POA.
virtual void check_state (void) = 0;
- virtual ::PortableServer::LifespanPolicyValue type() const = 0;
+ virtual ::PortableServer::LifespanPolicyValue type () const = 0;
virtual bool use_imr () const = 0;
+ virtual CORBA::Object_ptr imr_key_to_object (
+ const TAO::ObjectKey &key,
+ const char *type_id) const = 0;
+
protected:
TAO_Root_POA *poa_;
};
diff --git a/TAO/tao/PortableServer/LifespanStrategyPersistent.cpp b/TAO/tao/PortableServer/LifespanStrategyPersistent.cpp
index 093c7c5ef9e..0c82a670673 100644
--- a/TAO/tao/PortableServer/LifespanStrategyPersistent.cpp
+++ b/TAO/tao/PortableServer/LifespanStrategyPersistent.cpp
@@ -120,7 +120,7 @@ namespace TAO
}
}
- LifespanStrategyPersistent::LifespanStrategyPersistent() :
+ LifespanStrategyPersistent::LifespanStrategyPersistent () :
use_imr_ (true)
{
}
@@ -142,6 +142,31 @@ namespace TAO
{
return use_imr_;
}
+
+ CORBA::Object_ptr
+ LifespanStrategyPersistent::imr_key_to_object (const TAO::ObjectKey &key,
+ const char *type_id) const
+ {
+ if (!this->use_imr_)
+ {
+ // not using the imr
+ return CORBA::Object::_nil ();
+ }
+
+ // The user specified that the ImR should be used.
+ ImR_Client_Adapter *adapter =
+ ACE_Dynamic_Service<ImR_Client_Adapter>::instance (
+ TAO_Root_POA::imr_client_adapter_name ()
+ );
+ if (adapter == 0)
+ {
+ // couldn't load adapter, already reported error
+ return CORBA::Object::_nil ();
+ }
+
+ return adapter->imr_key_to_object (this->poa_, key, type_id);
+ }
+
} /* namespace Portable_Server */
} /* namespace TAO */
diff --git a/TAO/tao/PortableServer/LifespanStrategyPersistent.h b/TAO/tao/PortableServer/LifespanStrategyPersistent.h
index ce8c9a7bdd6..d379607a91b 100644
--- a/TAO/tao/PortableServer/LifespanStrategyPersistent.h
+++ b/TAO/tao/PortableServer/LifespanStrategyPersistent.h
@@ -61,6 +61,9 @@ namespace TAO
virtual bool use_imr () const;
+ virtual CORBA::Object_ptr imr_key_to_object(const TAO::ObjectKey &key,
+ const char *type_id) const;
+
private:
bool use_imr_;
};
diff --git a/TAO/tao/PortableServer/LifespanStrategyTransient.cpp b/TAO/tao/PortableServer/LifespanStrategyTransient.cpp
index eec9ca12ce0..afe60a9b338 100644
--- a/TAO/tao/PortableServer/LifespanStrategyTransient.cpp
+++ b/TAO/tao/PortableServer/LifespanStrategyTransient.cpp
@@ -104,6 +104,13 @@ namespace TAO
return false;
}
+ CORBA::Object_ptr
+ LifespanStrategyTransient::imr_key_to_object (const TAO::ObjectKey &,
+ const char *) const
+ {
+ return CORBA::Object::_nil();
+ }
+
::PortableServer::LifespanPolicyValue
LifespanStrategyTransient::type () const
{
diff --git a/TAO/tao/PortableServer/LifespanStrategyTransient.h b/TAO/tao/PortableServer/LifespanStrategyTransient.h
index 46ebb3f5a15..2a811c485c1 100644
--- a/TAO/tao/PortableServer/LifespanStrategyTransient.h
+++ b/TAO/tao/PortableServer/LifespanStrategyTransient.h
@@ -58,6 +58,9 @@ namespace TAO
virtual bool use_imr () const;
+ virtual CORBA::Object_ptr imr_key_to_object (const TAO::ObjectKey &key,
+ const char *type_id) const;
+
private:
TAO::Portable_Server::Creation_Time creation_time_;
};
diff --git a/TAO/tao/PortableServer/Root_POA.cpp b/TAO/tao/PortableServer/Root_POA.cpp
index 3de8235bf06..497ed456c83 100644
--- a/TAO/tao/PortableServer/Root_POA.cpp
+++ b/TAO/tao/PortableServer/Root_POA.cpp
@@ -1948,77 +1948,16 @@ TAO_Root_POA::key_to_object (const TAO::ObjectKey &key,
//
#if (TAO_HAS_MINIMUM_CORBA == 0)
- CORBA::Object_ptr obj = CORBA::Object::_nil ();
-
- if (indirect && this->active_policy_strategies_.lifespan_strategy()->use_imr ()
- && this->orb_core ().imr_endpoints_in_ior ())
+ if (indirect && this->orb_core ().imr_endpoints_in_ior ())
{
- // Check to see if we alter the IOR.
- CORBA::Object_var imr = this->orb_core ().implrepo_service ();
-
- if (CORBA::is_nil (imr.in ())
- || !imr->_stubobj ()
- || !imr->_stubobj ()->profile_in_use ())
+ CORBA::Object_ptr obj = this->active_policy_strategies_.
+ lifespan_strategy()->imr_key_to_object (key, type_id);
+ if (!CORBA::is_nil (obj))
{
- if (TAO_debug_level > 1)
- {
- ACE_DEBUG ((LM_DEBUG,
- "Missing ImR IOR, will not use the ImR\n"));
- }
- goto orbkey;
+ return obj;
}
-
- CORBA::String_var imr_str =
- imr->_stubobj ()->profile_in_use ()->to_string ();
-
- if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG,
- "IMR IOR =\n%C\n",
- imr_str.in ()));
-
- // Search for "corbaloc:" alone, without the protocol. This code
- // should be protocol neutral.
- const char corbaloc[] = "corbaloc:";
- char *pos = ACE_OS::strstr (imr_str.inout (), corbaloc);
- pos = ACE_OS::strchr (pos + sizeof (corbaloc), ':');
-
- pos = ACE_OS::strchr (pos + 1,
- imr->_stubobj ()->profile_in_use ()->object_key_delimiter ());
-
- if (pos)
- pos[1] = 0; // Crop the string.
- else
- {
- if (TAO_debug_level > 0)
- ACE_ERROR ((LM_ERROR,
- "Could not parse ImR IOR, skipping ImRification\n"));
- goto orbkey;
- }
-
- ACE_CString ior (imr_str.in ());
-
- // Add the key.
-
- CORBA::String_var key_str;
- TAO::ObjectKey::encode_sequence_to_string (key_str.inout (), key);
-
- ior += key_str.in ();
-
- if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG,
- "ImR-ified IOR =\n%C\n",
- ior.c_str ()));
-
- obj = this->orb_core_.orb ()->string_to_object (ior.c_str ());
-
- // type_id info is not in the corbaloc, so set it here
- obj->_stubobj()->type_id = type_id;
-
- return obj;
}
-orbkey:
-
#else
ACE_UNUSED_ARG (indirect);
#endif /* TAO_HAS_MINIMUM_CORBA */
diff --git a/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp b/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp
index d797edb925e..de26ec8ee98 100644
--- a/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp
+++ b/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp
@@ -17,6 +17,10 @@
#include "tao/PortableServer/Servant_Base.h"
#include "tao/debug.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/Time_Value.h"
+#include "ace/OS_NS_sys_time.h"
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
namespace TAO
@@ -24,7 +28,8 @@ namespace TAO
namespace Portable_Server
{
ServantRetentionStrategyNonRetain::ServantRetentionStrategyNonRetain (void) :
- poa_ (0)
+ poa_ (0),
+ sys_id_count_ (0)
{
}
@@ -188,12 +193,29 @@ namespace TAO
PortableServer::ObjectId user_id;
// Otherwise, it is the NON_RETAIN policy. Therefore, any ol'
- // object id will do (even an empty one).
+ // object id will do (even an empty one). However, to make an
+ // object id useful for discriminating objects in applications
+ // use a simple id of a counter and a time stamp. The use of a
+ // counter by itself is not sufficient for uniqueness over time
+ // and a timestamp isn't sufficient since multiple IDs may be
+ // requested within the same time unit.
+
PortableServer::ObjectId *sys_id = 0;
ACE_NEW_THROW_EX (sys_id,
- PortableServer::ObjectId,
+ PortableServer::ObjectId (8),
CORBA::NO_MEMORY ());
+ sys_id->length(8);
+
+ long count = this->sys_id_count_++;
+ ACE_Time_Value now = ACE_OS::gettimeofday();
+
+ *reinterpret_cast<ACE_UINT32 *>(sys_id->get_buffer()) =
+ count;
+
+ *reinterpret_cast<ACE_UINT32 *>(sys_id->get_buffer() + 4) =
+ static_cast<ACE_UINT32>(now.sec());
+
system_id = sys_id;
// User id is the same as system id.
diff --git a/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h b/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h
index bc4a2e1d50b..6870c1e018c 100644
--- a/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h
+++ b/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h
@@ -21,6 +21,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/PortableServer/Servant_Location.h"
+#include "ace/Atomic_Op.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -124,6 +125,7 @@ namespace TAO
protected:
TAO_Root_POA *poa_;
+ ACE_Atomic_Op<TAO_SYNCH_MUTEX,long> sys_id_count_;
};
}
}
diff --git a/TAO/tao/Profile.cpp b/TAO/tao/Profile.cpp
index 8cab33b26b8..4fdde3441a8 100644
--- a/TAO/tao/Profile.cpp
+++ b/TAO/tao/Profile.cpp
@@ -801,7 +801,7 @@ TAO_Unknown_Profile::object_key_delimiter (void) const
}
char *
-TAO_Unknown_Profile::to_string (void)
+TAO_Unknown_Profile::to_string (void) const
{
// @@ THROW something?
return 0;
diff --git a/TAO/tao/Profile.h b/TAO/tao/Profile.h
index 6b5570c9481..34461840ee2 100644
--- a/TAO/tao/Profile.h
+++ b/TAO/tao/Profile.h
@@ -182,7 +182,7 @@ public:
/// Return a string representation for this profile. Client must
/// deallocate memory. Only one endpoint is included into the
/// string.
- virtual char* to_string (void) = 0;
+ virtual char* to_string (void) const = 0;
/**
* Encodes this profile's endpoints into a tagged component.
@@ -430,7 +430,7 @@ public:
// = The TAO_Profile methods look above
virtual void parse_string (const char *string);
virtual char object_key_delimiter (void) const;
- virtual char* to_string (void);
+ virtual char* to_string (void) const;
virtual int decode (TAO_InputCDR& cdr);
virtual int encode (TAO_OutputCDR &stream) const;
virtual int encode_endpoints (void);
diff --git a/TAO/tao/Seq_Var_T.h b/TAO/tao/Seq_Var_T.h
index 3ec1449d834..4d91492f547 100644
--- a/TAO/tao/Seq_Var_T.h
+++ b/TAO/tao/Seq_Var_T.h
@@ -61,8 +61,10 @@ public:
_out_type out (void);
_retn_type _retn (void);
- /// TAO extension.
- _retn_type ptr (void) const;
+ /// TAO extension.
+ _retn_type ptr (void) const;
+ operator T *& ();
+
protected:
T * ptr_;
};
@@ -120,9 +122,6 @@ public:
T_elem operator[] (CORBA::ULong index);
T_const_elem operator[] (CORBA::ULong index) const;
-
- /// Variable-size base types only.
- operator T *& ();
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Seq_Var_T.inl b/TAO/tao/Seq_Var_T.inl
index b1c7c16d024..ede406b652d 100644
--- a/TAO/tao/Seq_Var_T.inl
+++ b/TAO/tao/Seq_Var_T.inl
@@ -106,6 +106,13 @@ TAO_Seq_Var_Base_T<T>::ptr (void) const
return this->ptr_;
}
+template<typename T>
+ACE_INLINE
+TAO_Seq_Var_Base_T<T>::operator T *& ()
+{
+ return this->ptr_;
+}
+
// ***************************************************************
template<typename T>
@@ -194,14 +201,6 @@ TAO_VarSeq_Var_T<T>::operator= (T * p)
return *this;
}
-// Variable-size types only.
-template<typename T>
-ACE_INLINE
-TAO_VarSeq_Var_T<T>::operator T *& ()
-{
- return this->ptr_;
-}
-
template<typename T>
ACE_INLINE
typename TAO_VarSeq_Var_T<T>::T_elem
diff --git a/TAO/tao/Storable_Base.cpp b/TAO/tao/Storable_Base.cpp
new file mode 100644
index 00000000000..dc588dd8db8
--- /dev/null
+++ b/TAO/tao/Storable_Base.cpp
@@ -0,0 +1,97 @@
+//=============================================================================
+/**
+ * @file Storable_Base.cpp
+ *
+ * $Id$
+ *
+ * @author Bruce Trask <trask_b@ociweb.com>
+ * @author Chanaka Liyanaarachchi <chanaka@ociweb.com>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "tao/Storable_Base.h"
+
+#if !defined (__ACE_INLINE__)
+#include "tao/Storable_Base.inl"
+#endif /* __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+bool TAO::Storable_Base::use_backup_default = false;
+
+void
+TAO::Storable_Base::remove (void)
+{
+ if (this->use_backup_)
+ {
+ this->remove_backup ();
+ }
+ this->do_remove ();
+}
+
+bool
+TAO::Storable_Base::use_backup ()
+{
+ return this->use_backup_;
+}
+
+ACE_CString
+TAO::Storable_Base::state_as_string (Storable_State state)
+{
+ ACE_CString state_string;
+ if (state == goodbit)
+ state_string = "goodbit";
+ else
+ {
+ if (state & badbit)
+ state_string = "badbit ";
+ if (state & eofbit)
+ state_string += "eofbit ";
+ if (state & failbit)
+ state_string += "failbit";
+ }
+ return state_string;
+}
+
+TAO::Storable_Exception::
+Storable_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name)
+ : storable_state_ (state)
+ , file_name_ (file_name)
+{
+}
+
+TAO::Storable_Exception::
+~Storable_Exception ()
+{
+}
+
+TAO::Storable_Base::Storable_State
+TAO::Storable_Exception::get_state () const
+{
+ return storable_state_;
+}
+
+const ACE_CString &
+TAO::Storable_Exception::get_file_name () const
+{
+ return file_name_;
+}
+
+TAO::Storable_Read_Exception::
+Storable_Read_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name)
+ : Storable_Exception (state, file_name)
+{
+}
+
+TAO::Storable_Write_Exception::
+Storable_Write_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name)
+ : Storable_Exception (state, file_name)
+{
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Storable_Base.h b/TAO/tao/Storable_Base.h
new file mode 100644
index 00000000000..b2fdcf7fc23
--- /dev/null
+++ b/TAO/tao/Storable_Base.h
@@ -0,0 +1,181 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Base.h
+ *
+ * $Id$
+ *
+ * @author Bruce Trask <trask_b@ociweb.com>
+ * @author Chanaka Liyanaarachchi <chanaka@ociweb.com>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_STORABLE_BASE_H
+#define TAO_STORABLE_BASE_H
+
+#include "tao/TAO_Export.h"
+#include "tao/orbconf.h"
+#include "tao/CDR.h"
+
+#include "ace/SString.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ class TAO_Export Storable_Base
+ {
+ public:
+
+ Storable_Base (bool use_backup);
+
+ virtual ~Storable_Base ();
+
+ /// The process-wide default policy
+ /// for doing a backup when close ()
+ /// is called.
+ /// The backup can then be restored if
+ /// restore_backup () is called.
+ /// The initial value for the default is false.
+ static bool use_backup_default;
+
+ bool use_backup ();
+
+ /// Remove the file that is assumed to not be open.
+ /// If backup are used, the backup will also be removed.
+ void remove();
+
+ virtual int create_backup () = 0;
+
+ virtual int exists() = 0;
+
+ virtual int open () = 0;
+
+ virtual int close () = 0;
+
+ virtual int flock (int whence, int start, int len) = 0;
+
+ virtual int funlock (int whence, int start, int len) = 0;
+
+ virtual time_t last_changed(void) = 0;
+
+ // Mimic a portion of the std::ios interface. We need to be able
+ // to indicate error states from the extraction operators below.
+ enum Storable_State { goodbit = 0,
+ badbit = 1,
+ eofbit = 2,
+ failbit = 4
+ };
+
+ void clear (Storable_State state = goodbit);
+
+ void setstate (Storable_State state);
+
+ Storable_State rdstate (void) const;
+
+ bool good (void) const;
+
+ bool bad (void) const;
+
+ bool eof (void) const;
+
+ bool fail (void) const;
+
+ static ACE_CString state_as_string (Storable_State state);
+
+ virtual void rewind (void) = 0;
+
+ virtual bool flush (void) = 0;
+
+ /// Force write of storable data to storage.
+ /// Returns 0 on success, otherwise EOF
+ virtual int sync (void) = 0;
+
+ virtual Storable_Base& operator << (const ACE_CString& str) = 0;
+
+ virtual Storable_Base& operator >> (ACE_CString& str) = 0;
+
+ virtual Storable_Base& operator << (int i) = 0;
+
+ virtual Storable_Base& operator >> (int &i) = 0;
+
+ virtual Storable_Base& operator << (unsigned int i) = 0;
+
+ virtual Storable_Base& operator >> (unsigned int &i) = 0;
+
+ virtual Storable_Base& operator << (const TAO_OutputCDR & cdr) = 0;
+
+ virtual size_t write (size_t size, const char * bytes) = 0;
+
+ virtual size_t read (size_t size, char * bytes) = 0;
+
+ virtual int restore_backup () = 0;
+
+ protected:
+
+ virtual void do_remove () = 0;
+
+ /// If a backup file exists, remove it.
+ virtual void remove_backup () = 0;
+
+ bool use_backup_;
+
+ private:
+ Storable_State state_;
+
+ };
+
+ /// Base class for exceptions thrown when encountering
+ /// errors working with persistent files.
+ class TAO_Export Storable_Exception
+ {
+ public:
+ Storable_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name);
+
+ virtual ~Storable_Exception ();
+
+ Storable_Base::Storable_State get_state () const;
+
+ const ACE_CString & get_file_name () const;
+
+ private:
+ TAO::Storable_Base::Storable_State storable_state_;
+ ACE_CString file_name_;
+ };
+
+ /// Exception thrown when an error is encountered
+ /// during reading of the persistent store.
+ class TAO_Export Storable_Read_Exception : public Storable_Exception
+ {
+ public:
+ Storable_Read_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name);
+ };
+
+ /// Exception thrown when an error is encountered
+ /// during writing to the persistent store.
+ class TAO_Export Storable_Write_Exception : public Storable_Exception
+ {
+ public:
+ Storable_Write_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name);
+ };
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "tao/Storable_Base.inl"
+#endif
+
+
+#endif
diff --git a/TAO/tao/Storable_Base.inl b/TAO/tao/Storable_Base.inl
new file mode 100644
index 00000000000..caddbdee3e7
--- /dev/null
+++ b/TAO/tao/Storable_Base.inl
@@ -0,0 +1,74 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Base.inl
+ *
+ * $Id$
+ *
+ * @author Bruce Trask <trask_b@ociweb.com>
+ * @author Chanaka Liyanaarachchi <chanaka@ociweb.com>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "tao/Storable_Base.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_INLINE
+TAO::Storable_Base::Storable_Base (bool use_backup)
+ : use_backup_ (use_backup)
+ , state_ (goodbit)
+{
+}
+
+ACE_INLINE
+TAO::Storable_Base::~Storable_Base ()
+{
+}
+
+ACE_INLINE void
+TAO::Storable_Base::clear (TAO::Storable_Base::Storable_State state)
+{
+ this->state_ = state;
+}
+
+ACE_INLINE void
+TAO::Storable_Base::setstate (TAO::Storable_Base::Storable_State state)
+{
+ this->clear (static_cast <TAO::Storable_Base::Storable_State> (
+ this->rdstate () | state));
+}
+
+ACE_INLINE TAO::Storable_Base::Storable_State
+TAO::Storable_Base::rdstate (void) const
+{
+ return this->state_;
+}
+
+ACE_INLINE bool
+TAO::Storable_Base::good (void) const
+{
+ return (this->state_ == goodbit);
+}
+
+ACE_INLINE bool
+TAO::Storable_Base::bad (void) const
+{
+ return (this->state_ & badbit);
+}
+
+ACE_INLINE bool
+TAO::Storable_Base::eof (void) const
+{
+ return (this->state_ & eofbit);
+}
+
+ACE_INLINE bool
+TAO::Storable_Base::fail (void) const
+{
+ return (this->state_ & failbit);
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Storable_Factory.cpp b/TAO/tao/Storable_Factory.cpp
new file mode 100644
index 00000000000..8850ac57246
--- /dev/null
+++ b/TAO/tao/Storable_Factory.cpp
@@ -0,0 +1,25 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Factory.cpp
+ *
+ * $Id$
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "tao/Storable_Factory.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO::Storable_Factory::Storable_Factory (void)
+{
+}
+
+TAO::Storable_Factory::~Storable_Factory (void)
+{
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Storable_Factory.h b/TAO/tao/Storable_Factory.h
new file mode 100644
index 00000000000..2532c774254
--- /dev/null
+++ b/TAO/tao/Storable_Factory.h
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Factory.h
+ *
+ * $Id$
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_STORABLE_FACTORY_H
+#define TAO_STORABLE_FACTORY_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Storable_Base.h"
+
+#include "ace/SString.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ class TAO_Export Storable_Factory
+ {
+ public:
+ Storable_Factory();
+
+ virtual ~Storable_Factory();
+
+ // Factory Methods
+
+ virtual Storable_Base *create_stream(const ACE_CString & file,
+ const ACE_TCHAR * mode,
+ bool use_backup =
+ Storable_Base::use_backup_default) = 0;
+ };
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_STORABLE_FACTORY_H */
diff --git a/TAO/tao/Storable_File_Guard.cpp b/TAO/tao/Storable_File_Guard.cpp
new file mode 100644
index 00000000000..1c20d904df9
--- /dev/null
+++ b/TAO/tao/Storable_File_Guard.cpp
@@ -0,0 +1,266 @@
+//=============================================================================
+/**
+ * @file Storable_File_Guard.cpp
+ *
+ * $Id$
+ *
+ * @author Rich Seibel (seibelr@ociweb.com)
+ * @author Byron Harris (harrisb@ociweb.com)
+ */
+//=============================================================================
+
+#include "tao/Storable_File_Guard.h"
+#include "tao/Storable_Base.h"
+
+#include "tao/SystemException.h"
+
+TAO::Storable_File_Guard::
+Storable_File_Guard (bool redundant, bool use_backup)
+ : redundant_(redundant)
+ , closed_(1)
+ , use_backup_(use_backup)
+{
+}
+
+TAO::Storable_File_Guard::
+~Storable_File_Guard ()
+{
+}
+
+void
+TAO::Storable_File_Guard::init(Method_Type method_type)
+{
+
+ ACE_CString mode;
+
+ // If backup is used then always need to open with
+ // write access since if the file is corrupt then
+ // will overwrite with backup file.
+ if (this->use_backup_)
+ {
+ switch (method_type)
+ {
+ case CREATE_WITH_FILE:
+ mode = "rw";
+ break;
+ case CREATE_WITHOUT_FILE:
+ mode = "rwc";
+ break;
+ case ACCESSOR:
+ mode = "rw";
+ break;
+ case MUTATOR:
+ mode = "rw";
+ break;
+ }
+ }
+ else
+ {
+ switch (method_type)
+ {
+ case CREATE_WITH_FILE:
+ mode = "r";
+ break;
+ case CREATE_WITHOUT_FILE:
+ mode = "wc";
+ break;
+ case ACCESSOR:
+ mode = "r";
+ break;
+ case MUTATOR:
+ mode = "rw";
+ break;
+ }
+ }
+
+ // We only accept a subset of mode argument, check it
+ rwflags_ = 0;
+ for( unsigned int i = 0; i < mode.length (); i++ )
+ {
+ switch (mode[i])
+ {
+ case 'r': rwflags_ |= mode_read;
+ break;
+ case 'w': rwflags_ |= mode_write;
+ break;
+ case 'c': rwflags_ |= mode_create;
+ break;
+ default: rwflags_ = -1;
+ }
+ }
+ if( rwflags_ <= 0 )
+ {
+ errno = EINVAL;
+ throw CORBA::PERSIST_STORE();
+ }
+
+ // Create the stream
+ fl_ = this->create_stream(mode.c_str ());
+ if (redundant_)
+ {
+ if (fl_->open() != 0)
+ {
+ delete fl_;
+ throw CORBA::PERSIST_STORE();
+ }
+
+ // acquire a lock on it
+ if (fl_ -> flock(0, 0, 0) != 0)
+ {
+ fl_->close();
+ delete fl_;
+ throw CORBA::INTERNAL();
+ }
+
+ // now that the file is successfully opened and locked it must be
+ // unlocked/closed before we leave this class
+ closed_ = 0;
+
+ if ( ! (rwflags_ & mode_create) )
+ {
+ // Check if our copy is up to date
+ if (this->object_obsolete ())
+ {
+ this->mark_object_current ();
+ this->load ();
+ }
+ }
+ }
+ else if ( ! this->is_loaded_from_stream () || (rwflags_ & mode_write) )
+ {
+ bool file_has_data = fl_->exists();
+
+ if (fl_->open() != 0)
+ {
+ delete fl_;
+ throw CORBA::PERSIST_STORE();
+ }
+
+ // now that the file is successfully opened
+ // unlocked/closed before we leave this class
+ closed_ = 0;
+
+ if (file_has_data && ! this->is_loaded_from_stream ())
+ {
+ this->load ();
+ }
+ }
+ else
+ {
+ // Need to insure that fl_ gets deleted
+ delete fl_;
+ }
+}
+
+bool
+TAO::Storable_File_Guard::object_obsolete (void)
+{ // Default implementation uses time to determine
+ // if obsolete.
+ return (fl_->last_changed () > this->get_object_last_changed ());
+}
+
+void
+TAO::Storable_File_Guard::mark_object_current (void)
+{ // Default implementation is to set the last changed
+ // time to that of the file lock.
+ this->set_object_last_changed (fl_->last_changed ());
+}
+
+void
+TAO::Storable_File_Guard::release (void)
+{
+ if ( ! closed_ )
+ {
+
+ if (this->use_backup_ )
+ {
+ fl_->create_backup ();
+ }
+
+ // If we updated the disk, save the time stamp
+ if(redundant_)
+ {
+ if( rwflags_ & mode_write )
+ {
+ // This is a costly call, but necessary if
+ // we are running redundant. It ensures that
+ // the data is written to disk.
+ fl_->sync ();
+
+ this->mark_object_current ();
+ }
+
+ // Release the lock
+ fl_->funlock(0, 0, 0);
+ }
+ fl_->close();
+ delete fl_;
+ closed_ = 1;
+ }
+
+}
+
+TAO::Storable_Base &
+TAO::Storable_File_Guard::peer ()
+{
+ return *fl_;
+}
+
+void
+TAO::Storable_File_Guard::load ()
+{
+ if (!this->use_backup_)
+ {
+ this->load_from_stream ();
+ return;
+ }
+
+ try
+ {
+ this->load_from_stream ();
+ }
+ catch (const Storable_Read_Exception &ex)
+ {
+ ACE_CString state_str = Storable_Base::state_as_string (ex.get_state());
+
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: State %s ")
+ ACE_TEXT ("encountered reading persistent ")
+ ACE_TEXT ("state from file\n%s\n"),
+ state_str.c_str (), ex.get_file_name().c_str ()));
+
+ int result = this->fl_->restore_backup ();
+
+ // result of 0 means OK.
+ if (!result)
+ {
+
+ ACE_ERROR ((LM_INFO,
+ ACE_TEXT ("TAO: (%P|%t) Attempting to restore ")
+ ACE_TEXT ("from backup\n")));
+
+ try
+ {
+ this->load_from_stream ();
+ }
+ catch (const Storable_Read_Exception &ex)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: Unable to restore ")
+ ACE_TEXT ("the state from backup.\n")));
+ throw;
+ }
+ ACE_ERROR ((LM_INFO,
+ ACE_TEXT ("TAO: (%P|%t) The state was restored ")
+ ACE_TEXT ("from backup.\n")));
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: Could not read ")
+ ACE_TEXT ("backup file\n")));
+ throw;
+ }
+
+ }
+}
diff --git a/TAO/tao/Storable_File_Guard.h b/TAO/tao/Storable_File_Guard.h
new file mode 100644
index 00000000000..6b4a055be38
--- /dev/null
+++ b/TAO/tao/Storable_File_Guard.h
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_File_Guard.h
+ *
+ * $Id$
+ *
+ * @author Rich Seibel (seibelr@ociweb.com)
+ * @author Byron Harris (harrisb@ociweb.com)
+ */
+//=============================================================================
+
+#ifndef TAO_STORABLE_FILE_GUARD_H
+#define TAO_STORABLE_FILE_GUARD_H
+
+#include "tao/Storable_Base.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ /**
+ * @class Storable_File_Guard
+ * @brief Base class to use with TAO_Storable_Base to synch object state
+ * with a storable base.
+ *
+ * A guard for Storable_Base that opens a file
+ * for read/write and sets a lock on it. It then checks if the file has
+ * changed and re-reads it if it has.
+ *
+ */
+ class TAO_Export Storable_File_Guard
+ {
+ public:
+
+ Storable_File_Guard (bool redundant,
+ bool use_backup = Storable_Base::use_backup_default);
+
+ virtual ~Storable_File_Guard ();
+
+ /// Releases the lock, closes the file, and deletes the I/O stream.
+ /// Destructors of derived classes should call this this will
+ /// virtual functions are available.
+ void release (void);
+
+ /// Return when the object in memory has last changed
+ virtual time_t get_object_last_changed () = 0;
+
+ /// Get the underlying stream being used.
+ TAO::Storable_Base & peer ();
+
+ /// Indicate how the state of the object is being used.
+ /// This is used for determine the mode for accessing
+ /// the persistent store.
+ enum Method_Type
+ {
+
+ /// Construction with persistent file already existing
+ CREATE_WITH_FILE,
+
+ /// Construction with persistent file not existing
+ CREATE_WITHOUT_FILE,
+
+ /// Getting object state
+ ACCESSOR,
+
+ /// Setting object state
+ MUTATOR
+ };
+
+ protected:
+
+ /// Should be called by constructors of derived classes
+ /// since can't call the virtual functions below in constructor
+ /// of this class.
+ void init (Method_Type method_type);
+
+ /// Check if the object is current with the last update.
+ virtual bool object_obsolete (void);
+
+ /// Mark the object as up to date
+ virtual void mark_object_current (void);
+
+ /// Indicate when the object in memory has last changed
+ virtual void set_object_last_changed (const time_t & time) = 0;
+
+ /// Load object from file to memory
+ virtual void load_from_stream () = 0;
+
+ /// Answer if object has been loaded from file
+ virtual bool is_loaded_from_stream () = 0;
+
+ virtual Storable_Base * create_stream (const char * mode) = 0;
+
+ /// The pointer to the actual file I/O (bridge pattern)
+ Storable_Base *fl_;
+
+ private:
+
+ void load ();
+
+ bool redundant_;
+
+ /// A flag to keep us from trying to close things more than once.
+ int closed_;
+
+ /// The flags that we were opened with
+ int rwflags_;
+
+ /// A flag indicating if backup/restore should be performed
+ bool use_backup_;
+
+ /// Symbolic values for the flags in the above
+ enum { mode_write = 1, mode_read = 2, mode_create = 4 };
+
+ };
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif
diff --git a/TAO/tao/Storable_FlatFileStream.cpp b/TAO/tao/Storable_FlatFileStream.cpp
new file mode 100644
index 00000000000..3a5977c9dd8
--- /dev/null
+++ b/TAO/tao/Storable_FlatFileStream.cpp
@@ -0,0 +1,475 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_FlatFileStream.cpp
+ *
+ * $Id$
+ *
+ * @author Marina Spivak <marina@cs.wustl.edu>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "tao/Storable_FlatFileStream.h"
+
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_fcntl.h"
+#include "ace/OS_NS_sys_stat.h"
+#include "ace/Numeric_Limits.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace
+{
+ /// Avoids using fscanf to read an integer as any
+ /// whitespace following the newline will be
+ /// consumed. This could create problems if
+ /// the data that follows the newline is binary.
+ template<typename T>
+ void read_integer(const char * format, T & i,
+ TAO::Storable_Base::Storable_State & state,
+ FILE * fl)
+ {
+ char buf[BUFSIZ];
+ char * result = fgets (buf, BUFSIZ, fl);
+
+ if (result == 0)
+ {
+ if (feof (fl))
+ {
+ state = TAO::Storable_Base::eofbit;
+ return;
+ }
+ state = TAO::Storable_Base::badbit;
+ return;
+ }
+
+ /// Consume any starting newline, as fscanf would
+ /// do.
+ if (buf[0] == '\n')
+ {
+ result = fgets (buf, BUFSIZ, fl);
+ }
+
+ if (result == 0)
+ {
+ if (feof (fl))
+ {
+ state = TAO::Storable_Base::eofbit;
+ return;
+ }
+ state = TAO::Storable_Base::badbit;
+ return;
+ }
+
+ switch (sscanf (buf, format, &i))
+ {
+ case 0:
+ state = TAO::Storable_Base::badbit;
+ return;
+ case EOF:
+ state = TAO::Storable_Base::eofbit;
+ return;
+ }
+ }
+
+ int file_copy(FILE *f1, FILE *f2)
+ {
+ char buffer[BUFSIZ];
+ size_t n_read;
+
+ bool all_read = false;
+ bool some_read = false;
+
+ while (!all_read)
+ {
+ n_read =
+ ACE_OS::fread(buffer, 1, sizeof(buffer), f1);
+ if (n_read > 0)
+ {
+ if (ACE_OS::fwrite(buffer, 1, n_read, f2) != n_read)
+ return -1;
+ some_read = true;
+ }
+ else if (!some_read)
+ {
+ // Nothing was read
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: could not read from file\n")));
+
+ if (ferror (f1))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%p\n",
+ "fread error"));
+ }
+ return -1;
+ }
+ else
+ {
+ all_read = true;
+ }
+ }
+
+ return 0;
+ }
+
+}
+
+TAO::Storable_FlatFileStream::Storable_FlatFileStream (const ACE_CString & file,
+ const char * mode,
+ bool use_backup)
+ : Storable_Base(use_backup)
+ , fl_ (0)
+{
+ file_ = file;
+ mode_ = mode;
+}
+
+TAO::Storable_FlatFileStream::~Storable_FlatFileStream ()
+{
+ if ( fl_ != 0 )
+ this->close();
+}
+
+void
+TAO::Storable_FlatFileStream::do_remove ()
+{
+ ACE_OS::unlink(ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()));
+}
+
+int
+TAO::Storable_FlatFileStream::exists ()
+{
+ // We could check the mode for this file, but for now just check exists
+ return ! ACE_OS::access(file_.c_str(), F_OK);
+}
+
+int
+TAO::Storable_FlatFileStream::open()
+{
+ // For now, three flags exist "r", "w", and "c"
+ int flags = 0;
+ const char *fdmode = 0;
+ if( ACE_OS::strchr(mode_.c_str(), 'r') )
+ if( ACE_OS::strchr(mode_.c_str(), 'w') )
+ flags = O_RDWR, fdmode = "w+";
+ else
+ flags = O_RDONLY, fdmode = "r";
+ else
+ flags = O_WRONLY, fdmode = "w";
+ if( ACE_OS::strchr(mode_.c_str(), 'c') )
+ flags |= O_CREAT;
+#ifndef ACE_WIN32
+ if( ACE_OS::flock_init (&filelock_, flags, ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()), 0666) != 0 )
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open file %s for mode %s: (%d) %s\n",
+ file_.c_str(), mode_.c_str(),
+ errno, ACE_OS::strerror(errno)),
+ -1);
+#else
+ if( (filelock_.handle_= ACE_OS::open (ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()), flags, 0)) == ACE_INVALID_HANDLE )
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open file %s for mode %s: (%d) %s\n",
+ file_.c_str(), mode_.c_str(),
+ ACE_ERRNO_GET, ACE_OS::strerror(ACE_ERRNO_GET)),
+ -1);
+#endif
+ this->fl_ = ACE_OS::fdopen(filelock_.handle_, ACE_TEXT_CHAR_TO_TCHAR(fdmode));
+ if (this->fl_ == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot fdopen file %s for mode %s: (%d) %s\n",
+ file_.c_str(), mode_.c_str(),
+ ACE_ERRNO_GET, ACE_OS::strerror(ACE_ERRNO_GET)),
+ -1);
+ return 0;
+}
+
+int
+TAO::Storable_FlatFileStream::close()
+{
+ ACE_OS::fflush(fl_);
+#ifndef ACE_WIN32
+ ACE_OS::flock_destroy (&filelock_, 0);
+#endif
+ ACE_OS::fclose (fl_); // even though flock_destroy closes the handle
+ // we still need to destroy the FILE*
+
+ fl_ = 0;
+ return 0;
+}
+
+int
+TAO::Storable_FlatFileStream::flock (int whence, int start, int len)
+{
+#if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+#else
+ if( ACE_OS::strcmp(mode_.c_str(), "r") == 0 )
+ ACE_OS::flock_rdlock(&filelock_, whence, start, len);
+ else
+ ACE_OS::flock_wrlock(&filelock_, whence, start, len);
+#endif
+ return 0;
+}
+
+int
+TAO::Storable_FlatFileStream::funlock (int whence, int start, int len)
+{
+#if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+#else
+ ACE_OS::flock_unlock(&filelock_, whence, start, len);
+#endif
+ return 0;
+}
+
+time_t
+TAO::Storable_FlatFileStream::last_changed(void)
+{
+ ACE_stat st;
+ ACE_OS::fstat(filelock_.handle_, &st);
+ return st.st_mtime;
+}
+
+void
+TAO::Storable_FlatFileStream::rewind (void)
+{
+ return ACE_OS::rewind(this->fl_);
+}
+
+bool
+TAO::Storable_FlatFileStream::flush (void)
+{
+ return ACE_OS::fflush(this->fl_);
+}
+
+int
+TAO::Storable_FlatFileStream::sync (void)
+{
+ return ACE_OS::fsync (this->filelock_.handle_);
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator << (const ACE_CString& str)
+{
+ int n =
+ ACE_OS::fprintf(this->fl_, ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT("\n%s\n"),
+ str.length(), str.c_str());
+ if (n < 0)
+ this->throw_on_write_error (badbit);
+
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator >> (ACE_CString& str)
+{
+ int bufSize = 0;
+ ACE_CString::size_type const max_buf_len =
+ ACE_Numeric_Limits<ACE_CString::size_type>::max ();
+ switch (fscanf(fl_, "%d\n", &bufSize))
+ {
+ case 0:
+ this->throw_on_read_error (badbit);
+ case EOF:
+ this->throw_on_read_error (eofbit);
+ }
+
+ if (bufSize < 0
+ || static_cast<ACE_CString::size_type> (bufSize) >= max_buf_len)
+ {
+ this->throw_on_read_error (badbit);
+ }
+ {
+ ACE_Auto_Basic_Array_Ptr<char> str_array (new char[bufSize + 1]);
+ str_array[0] = '\0';
+ if (ACE_OS::fgets (ACE_TEXT_CHAR_TO_TCHAR (str_array.get ()),
+ bufSize + 1,
+ this->fl_) == 0
+ && bufSize != 0)
+ {
+ this->throw_on_read_error (badbit);
+ }
+ str = ACE_CString (str_array.get (), 0, false);
+ }
+
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator << (int i)
+{
+ int n = ACE_OS::fprintf (this->fl_, "%d\n", i);
+ if (n < 0)
+ this->throw_on_write_error (badbit);
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator >> (int &i)
+{
+ Storable_State state = this->rdstate ();
+ read_integer ("%d\n", i, state, fl_);
+ this->throw_on_read_error (state);
+
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator << (unsigned int i)
+{
+ int n = ACE_OS::fprintf (this->fl_, "%u\n", i);
+ if (n < 0)
+ this->throw_on_write_error (badbit);
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator >> (unsigned int &i)
+{
+ Storable_State state = this->rdstate ();
+ read_integer ("%u\n", i, state, fl_);
+ this->throw_on_read_error (state);
+
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator << (const TAO_OutputCDR & cdr)
+{
+ unsigned int length = cdr.total_length ();
+ *this << length;
+ for (const ACE_Message_Block *i = cdr.begin (); i != 0; i = i->cont ())
+ {
+ const char *bytes = i->rd_ptr ();
+ size_t len = i->length ();
+ this->write (len, bytes);
+ }
+ return *this;
+}
+
+size_t
+TAO::Storable_FlatFileStream::write (size_t size, const char * bytes)
+{
+ return ACE_OS::fwrite (bytes, size, 1, fl_);
+}
+
+size_t
+TAO::Storable_FlatFileStream::read (size_t size, char * bytes)
+{
+ return ACE_OS::fread (bytes, size, 1, fl_);
+}
+
+ACE_CString
+TAO::Storable_FlatFileStream::backup_file_name ()
+{
+ return file_ + ".bak";
+}
+
+int
+TAO::Storable_FlatFileStream::create_backup ()
+{
+ FILE * backup = ACE_OS::fopen (this->backup_file_name ().c_str (), "w");
+ this->rewind();
+ int result = file_copy(this->fl_, backup);
+ if (result != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: Unable to create backup ")
+ ACE_TEXT ("of file\n%s\n"), file_.c_str ()));
+ }
+ ACE_OS::fclose (backup);
+ return result;
+}
+
+void
+TAO::Storable_FlatFileStream::remove_backup ()
+{
+ ACE_CString backup_name = this->backup_file_name ();
+
+ if (ACE_OS::access (ACE_TEXT_CHAR_TO_TCHAR (backup_name.c_str ()), F_OK) == 0)
+ {
+ ACE_OS::unlink (ACE_TEXT_CHAR_TO_TCHAR (backup_name.c_str ()));
+ }
+}
+
+int
+TAO::Storable_FlatFileStream::restore_backup ()
+{
+ ACE_CString backup_name = this->backup_file_name ().c_str ();
+
+ if (ACE_OS::access (ACE_TEXT_CHAR_TO_TCHAR (backup_name.c_str ()), F_OK))
+ return -1;
+
+ FILE * backup = ACE_OS::fopen (ACE_TEXT_CHAR_TO_TCHAR (backup_name.c_str ()),
+ "r");
+ this->rewind();
+ int result = file_copy(backup, this->fl_);
+ ACE_OS::fclose (backup);
+ this->flush ();
+ this->clear ();
+ return result;
+}
+
+void
+TAO::Storable_FlatFileStream::throw_on_read_error (Storable_State state)
+ throw (Storable_Read_Exception)
+{
+ this->setstate (state);
+
+ if (!this->good ())
+ {
+ throw Storable_Read_Exception (this->rdstate (), this->file_);
+ }
+}
+
+void
+TAO::Storable_FlatFileStream::throw_on_write_error (Storable_State state)
+ throw (Storable_Write_Exception)
+{
+ this->setstate (state);
+
+ if (!this->good ())
+ {
+ throw Storable_Write_Exception (this->rdstate (), this->file_);
+ }
+}
+
+TAO::Storable_FlatFileFactory::Storable_FlatFileFactory(const ACE_CString & directory)
+ : Storable_Factory ()
+ , directory_(directory)
+{
+}
+
+TAO::Storable_FlatFileFactory::~Storable_FlatFileFactory()
+{
+}
+
+const ACE_CString &
+TAO::Storable_FlatFileFactory::get_directory () const
+{
+ return directory_;
+}
+
+TAO::Storable_Base *
+TAO::Storable_FlatFileFactory::create_stream (const ACE_CString & file,
+ const ACE_TCHAR * mode,
+ bool use_backup)
+{
+ TAO::Storable_Base *stream = 0;
+ ACE_CString path = this->directory_ + "/" + file;
+ ACE_NEW_RETURN (stream,
+ TAO::Storable_FlatFileStream(path,
+ ACE_TEXT_ALWAYS_CHAR (mode),
+ use_backup),
+ 0);
+ return stream;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Storable_FlatFileStream.h b/TAO/tao/Storable_FlatFileStream.h
new file mode 100644
index 00000000000..10e5a9e4425
--- /dev/null
+++ b/TAO/tao/Storable_FlatFileStream.h
@@ -0,0 +1,145 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_FlatFileStream.h
+ *
+ * $Id$
+ *
+ * @author Marina Spivak <marina@cs.wustl.edu>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef STORABLE_FLATFILESTREAM_H
+#define STORABLE_FLATFILESTREAM_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Storable_Base.h"
+#include "tao/Storable_Factory.h"
+#include "ace/OS_NS_stdio.h"
+
+namespace TAO
+{
+
+ /**
+ * @brief A Storable_Base derived class that works with a file stream.
+ *
+ */
+ class TAO_Export Storable_FlatFileStream : public Storable_Base
+ {
+ public:
+
+ Storable_FlatFileStream(const ACE_CString & file, const char * mode,
+ bool use_backup =
+ Storable_Base::use_backup_default);
+
+ virtual ~Storable_FlatFileStream();
+
+ /// Check if a file exists on disk (file is not open)
+ virtual int exists ();
+
+ /// Open a file (the remaining methods below all require an open file)
+ virtual int open ();
+
+ /// Acquire a file lock
+ virtual int close ();
+
+ /// Acquire a file lock
+ virtual int flock (int whence, int start, int len);
+
+ /// Release a file lock
+ virtual int funlock (int whence, int start, int len);
+
+ /// Returns the last time an open file was changed
+ virtual time_t last_changed (void);
+
+ virtual void rewind (void);
+
+ virtual bool flush (void);
+
+ /// Force write of storable data to storage.
+ /// Returns 0 on success, otherwise EOF
+ virtual int sync (void);
+
+ virtual Storable_Base& operator << (const ACE_CString& str);
+
+ virtual Storable_Base& operator >> (ACE_CString& str);
+
+ virtual Storable_Base& operator << (int i);
+
+ virtual Storable_Base& operator >> (int &i);
+
+ virtual Storable_Base& operator << (unsigned int i);
+
+ virtual Storable_Base& operator >> (unsigned int &i);
+
+ virtual Storable_Base& operator << (const TAO_OutputCDR & cdr);
+
+ virtual size_t write (size_t size, const char * bytes);
+
+ virtual size_t read (size_t size, char * bytes);
+
+ virtual int restore_backup ();
+
+ protected:
+
+ virtual void do_remove ();
+
+ virtual void remove_backup ();
+
+ virtual int create_backup ();
+
+ private:
+
+ /// Throw a Storable_Read_Exception if the state
+ /// is not good due to a read error.
+ void throw_on_read_error (Storable_State state)
+ throw (Storable_Read_Exception);
+
+ /// Throw a Storable_Write_Exception if the state
+ /// is not good due to a write error.
+ void throw_on_write_error (Storable_State state)
+ throw (Storable_Write_Exception);
+
+ ACE_CString backup_file_name ();
+
+ ACE_OS::ace_flock_t filelock_;
+ FILE* fl_;
+ ACE_CString file_;
+ ACE_CString mode_;
+ };
+
+ class TAO_Export Storable_FlatFileFactory : public Storable_Factory
+ {
+ public:
+
+ /// @param directory Directory to contain file passed in
+ /// create_stream (). The directory is assumed to already exist.
+ Storable_FlatFileFactory(const ACE_CString & directory);
+
+ const ACE_CString & get_directory () const;
+
+ ~Storable_FlatFileFactory ();
+
+ // Factory Methods
+
+ /// Create the stream that can operate on a disk file
+ virtual Storable_Base *create_stream (const ACE_CString & file,
+ const ACE_TCHAR * mode,
+ bool use_backup =
+ Storable_Base::use_backup_default);
+ private:
+ ACE_CString directory_;
+
+ };
+}
+
+#include /**/ "ace/post.h"
+
+#endif /* STORABLE_FLATFILESTREAM_H */
diff --git a/TAO/tao/Strategies/COIOP_Profile.cpp b/TAO/tao/Strategies/COIOP_Profile.cpp
index ece1da6e39c..b2c075c2426 100644
--- a/TAO/tao/Strategies/COIOP_Profile.cpp
+++ b/TAO/tao/Strategies/COIOP_Profile.cpp
@@ -203,7 +203,7 @@ TAO_COIOP_Profile::add_endpoint (TAO_COIOP_Endpoint *endp)
}
char *
-TAO_COIOP_Profile::to_string (void)
+TAO_COIOP_Profile::to_string (void) const
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
diff --git a/TAO/tao/Strategies/COIOP_Profile.h b/TAO/tao/Strategies/COIOP_Profile.h
index 075a2ccdbe5..ded0bf29f4d 100644
--- a/TAO/tao/Strategies/COIOP_Profile.h
+++ b/TAO/tao/Strategies/COIOP_Profile.h
@@ -65,7 +65,7 @@ public:
~TAO_COIOP_Profile (void);
/// Template methods. Please tao/Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Strategies/DIOP_Profile.cpp b/TAO/tao/Strategies/DIOP_Profile.cpp
index b8b69911bab..2f5fc3c19b1 100644
--- a/TAO/tao/Strategies/DIOP_Profile.cpp
+++ b/TAO/tao/Strategies/DIOP_Profile.cpp
@@ -363,7 +363,7 @@ TAO_DIOP_Profile::add_endpoint (TAO_DIOP_Endpoint *endp)
}
char *
-TAO_DIOP_Profile::to_string (void)
+TAO_DIOP_Profile::to_string (void) const
{
// corbaloc:diop:1.2@host:port,diop:1.2@host:port,.../key
diff --git a/TAO/tao/Strategies/DIOP_Profile.h b/TAO/tao/Strategies/DIOP_Profile.h
index f2db5d68c01..5b4725c0418 100644
--- a/TAO/tao/Strategies/DIOP_Profile.h
+++ b/TAO/tao/Strategies/DIOP_Profile.h
@@ -77,7 +77,7 @@ public:
/// Template methods. Please tao/Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Strategies/SCIOP_Profile.cpp b/TAO/tao/Strategies/SCIOP_Profile.cpp
index 175fbe7bfd9..83899b63a7e 100644
--- a/TAO/tao/Strategies/SCIOP_Profile.cpp
+++ b/TAO/tao/Strategies/SCIOP_Profile.cpp
@@ -310,7 +310,7 @@ TAO_SCIOP_Profile::add_endpoint (TAO_SCIOP_Endpoint *endp)
}
char *
-TAO_SCIOP_Profile::to_string (void)
+TAO_SCIOP_Profile::to_string (void) const
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
diff --git a/TAO/tao/Strategies/SCIOP_Profile.h b/TAO/tao/Strategies/SCIOP_Profile.h
index 4aca872c3d7..264edc4cf57 100644
--- a/TAO/tao/Strategies/SCIOP_Profile.h
+++ b/TAO/tao/Strategies/SCIOP_Profile.h
@@ -73,7 +73,7 @@ public:
~TAO_SCIOP_Profile (void);
/// Template methods. Please see Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Strategies/SHMIOP_Profile.cpp b/TAO/tao/Strategies/SHMIOP_Profile.cpp
index 23f7c52818e..e13b03ac3c3 100644
--- a/TAO/tao/Strategies/SHMIOP_Profile.cpp
+++ b/TAO/tao/Strategies/SHMIOP_Profile.cpp
@@ -325,7 +325,7 @@ TAO_SHMIOP_Profile::add_endpoint (TAO_SHMIOP_Endpoint *endp)
}
char *
-TAO_SHMIOP_Profile::to_string (void)
+TAO_SHMIOP_Profile::to_string (void) const
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
diff --git a/TAO/tao/Strategies/SHMIOP_Profile.h b/TAO/tao/Strategies/SHMIOP_Profile.h
index 7d103435dc2..49689fb03bb 100644
--- a/TAO/tao/Strategies/SHMIOP_Profile.h
+++ b/TAO/tao/Strategies/SHMIOP_Profile.h
@@ -76,7 +76,7 @@ public:
/// Template methods, please see Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Strategies/UIOP_Profile.cpp b/TAO/tao/Strategies/UIOP_Profile.cpp
index 8cf254c9d6b..e74fcd28d0b 100644
--- a/TAO/tao/Strategies/UIOP_Profile.cpp
+++ b/TAO/tao/Strategies/UIOP_Profile.cpp
@@ -239,7 +239,7 @@ TAO_UIOP_Profile::add_endpoint (TAO_UIOP_Endpoint *endp)
char *
-TAO_UIOP_Profile::to_string (void)
+TAO_UIOP_Profile::to_string (void) const
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
diff --git a/TAO/tao/Strategies/UIOP_Profile.h b/TAO/tao/Strategies/UIOP_Profile.h
index 8870fcec6e5..eb4b146989d 100644
--- a/TAO/tao/Strategies/UIOP_Profile.h
+++ b/TAO/tao/Strategies/UIOP_Profile.h
@@ -75,7 +75,7 @@ public:
~TAO_UIOP_Profile (void);
/// Template methods. Please see Profile.h for documentation.
- virtual char *to_string (void);
+ virtual char *to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Stub.cpp b/TAO/tao/Stub.cpp
index 0703795d5d4..b6bdbeaea36 100644
--- a/TAO/tao/Stub.cpp
+++ b/TAO/tao/Stub.cpp
@@ -116,6 +116,13 @@ TAO_Stub::add_forward_profiles (const TAO_MProfile &mprofiles,
ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX,
guard,
this->profile_lock_));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::add_forward_profiles, ")
+ ACE_TEXT ("acquired profile lock this = 0x%x\n"),
+ this));
+ }
if (permanent_forward)
{
@@ -133,8 +140,10 @@ TAO_Stub::add_forward_profiles (const TAO_MProfile &mprofiles,
TAO_MProfile (mprofiles));
if (permanent_forward)
- // bookmark the new element at bottom of stack
- this->forward_profiles_perm_ = this->forward_profiles_;
+ {
+ // bookmark the new element at bottom of stack
+ this->forward_profiles_perm_ = this->forward_profiles_;
+ }
// forwarded profile points to the new IOR (profiles)
this->profile_in_use_->forward_to (this->forward_profiles_);
@@ -159,6 +168,14 @@ TAO_Stub::create_ior_info (IOP::IOR *&ior_info, CORBA::ULong &index)
guard,
this->profile_lock_,
-1));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::create_ior_info, acquired ")
+ ACE_TEXT ("profile lock this = 0x%x\n"),
+ this));
+ }
+
IOP::IOR *tmp_info = 0;
@@ -223,7 +240,8 @@ TAO_Stub::object_key (void) const
{
// Double-checked
// FUZZ: disable check_for_ACE_Guard
- ACE_Guard<TAO_SYNCH_MUTEX> obj (const_cast <TAO_SYNCH_MUTEX&>(this->profile_lock_));
+ ACE_Guard<TAO_SYNCH_MUTEX> obj (
+ const_cast <TAO_SYNCH_MUTEX&>(this->profile_lock_));
// FUZZ: enable check_for_ACE_Guard
if (obj.locked () != 0 && this->forward_profiles_ != 0)
@@ -520,6 +538,14 @@ TAO_Stub::marshal (TAO_OutputCDR &cdr)
guard,
this->profile_lock_,
0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::marshal, acquired ")
+ ACE_TEXT ("profile lock this = 0x%x\n"),
+ this));
+ }
+
ACE_ASSERT(this->forward_profiles_ !=0);
diff --git a/TAO/tao/Stub.h b/TAO/tao/Stub.h
index 789bc8e2e9b..a654e3931de 100644
--- a/TAO/tao/Stub.h
+++ b/TAO/tao/Stub.h
@@ -165,6 +165,11 @@ public:
*/
void reset_profiles (void);
+ /// Returns true if the profile in use is
+ /// the same as the profile in use after
+ /// reset_profiles() is called.
+ CORBA::Boolean at_starting_profile (void) const;
+
/// Returns true if a forward profile has successfully been used.
/// profile_success_ && forward_profiles_
CORBA::Boolean valid_forward_profile (void);
@@ -406,6 +411,7 @@ protected:
/// True if forwarding request upon some specific exceptions
/// (e.g. OBJECT_NOT_EXIST) already happened.
ACE_Atomic_Op<TAO_SYNCH_MUTEX, bool> forwarded_on_exception_;
+
};
// Define a TAO_Stub auto_ptr class.
diff --git a/TAO/tao/Stub.inl b/TAO/tao/Stub.inl
index d4b0ae3d8c7..714d1d736b2 100644
--- a/TAO/tao/Stub.inl
+++ b/TAO/tao/Stub.inl
@@ -3,6 +3,7 @@
// $Id$
#include "tao/ORB_Core.h"
+#include "ace/Reverse_Lock_T.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -56,6 +57,14 @@ TAO_Stub::reset_profiles (void)
ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX,
guard,
this->profile_lock_));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::reset_profiles, acquired ")
+ ACE_TEXT ("profile lock this = 0x%x\n"),
+ this));
+ }
+
this->reset_profiles_i ();
}
@@ -137,9 +146,30 @@ TAO_Stub::next_profile_i (void)
pfile_next = this->base_profiles_.get_next ();
}
- // We may have been forwarded to / from a collocated situation
- // Check for this and apply / remove optimisation if required.
- this->orb_core_->reinitialize_object (this);
+ {
+ typedef ACE_Reverse_Lock<ACE_MT_SYNCH::MUTEX> TAO_REVERSE_LOCK;
+ TAO_REVERSE_LOCK reverse (this->profile_lock_);
+ ACE_MT (ACE_GUARD_RETURN (TAO_REVERSE_LOCK, ace_mon, reverse, 0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::next_profile_i, ")
+ ACE_TEXT ("released profile lock to reinitialize ")
+ ACE_TEXT ("this = 0x%x\n"),
+ this));
+ }
+ // We may have been forwarded to / from a collocated situation
+ // Check for this and apply / remove optimisation if required.
+ this->orb_core_->reinitialize_object (this);
+ }
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::next_profile_i, ")
+ ACE_TEXT ("reacquired profile lock on object ")
+ ACE_TEXT ("this = 0x%x\n"),
+ this));
+ }
}
else
pfile_next = this->base_profiles_.get_next ();
@@ -160,6 +190,11 @@ TAO_Stub::next_profile (void)
guard,
this->profile_lock_,
0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::next_profile, acquired profile lock this = 0x%x\n"), this));
+ }
return this->next_profile_i ();
}
@@ -188,6 +223,12 @@ TAO_Stub::base_profiles (const TAO_MProfile &mprofiles)
guard,
this->profile_lock_,
0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::base_profiles, acquired profile lock this = 0x%x\n"), this));
+ }
+
// first reset things so we start from scratch!
@@ -208,6 +249,11 @@ TAO_Stub::next_profile_retry (void)
guard,
this->profile_lock_,
0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::next_profile_retry, acquired profile lock this = 0x%x\n"), this));
+ }
if (this->profile_success_ && this->forward_profiles_)
{
@@ -362,6 +408,13 @@ TAO_Stub::_decr_refcnt (void)
delete this;
}
+ACE_INLINE
+CORBA::Boolean
+TAO_Stub::at_starting_profile (void) const
+{
+ return profile_in_use_ == base_profiles_.get_profile(0);
+}
+
// ---------------------------------------------------------------
// Creator methods for TAO_Stub_Auto_Ptr (TAO_Stub Auto Pointer)
diff --git a/TAO/tao/Synch_Invocation.cpp b/TAO/tao/Synch_Invocation.cpp
index 40064362ca6..71ef977e300 100644
--- a/TAO/tao/Synch_Invocation.cpp
+++ b/TAO/tao/Synch_Invocation.cpp
@@ -1,6 +1,7 @@
// $Id$
#include "tao/Synch_Invocation.h"
+#include "tao/Invocation_Retry_State.h"
#include "tao/Profile_Transport_Resolver.h"
#include "tao/Profile.h"
#include "tao/Synch_Reply_Dispatcher.h"
@@ -42,9 +43,16 @@ namespace TAO
resolver,
detail,
response_expected)
+ , retry_state_ (0)
{
}
+ void
+ Synch_Twoway_Invocation::set_retry_state (Invocation_Retry_State *retry_state)
+ {
+ this->retry_state_ = retry_state;
+ }
+
Invocation_Status
Synch_Twoway_Invocation::remote_twoway (ACE_Time_Value *max_wait_time)
{
@@ -79,10 +87,25 @@ namespace TAO
if (!transport)
{
- // Way back, we failed to find a profile we could connect to.
- // We've come this far only so we reach the interception points
- // in case they can fix things. Time to bail....
- throw CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
+ if (this->retry_state_ &&
+ this->retry_state_->forward_on_exception_increment(FOE_TRANSIENT))
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("remote_twoway retrying on TRANSIENT ")
+ ACE_TEXT ("exception\n")));
+ this->retry_state_->next_profile_retry (*this->stub ());
+ return TAO_INVOKE_RESTART;
+ }
+ else
+ {
+ // Way back, we failed to find a profile we could connect to.
+ // We've come this far only so we reach the interception points
+ // in case they can fix things. Time to bail....
+ throw CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
+ }
+
}
ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon,
@@ -259,8 +282,8 @@ namespace TAO
if (TAO_debug_level > 0 && max_wait_time)
{
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply, "
- "timeout after recv is <%u> status <%d>\n",
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply, ")
+ ACE_TEXT ("timeout after recv is <%u> status <%d>\n"),
max_wait_time->msec (),
reply_error));
}
@@ -273,8 +296,9 @@ namespace TAO
if (TAO_debug_level > 3)
{
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply, "
- "recovering after an error\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("wait_for_reply, ")
+ ACE_TEXT ("recovering after an error\n")));
}
// You the smarty, don't try to moving the unbind_dispatcher
@@ -312,6 +336,19 @@ namespace TAO
(void) bd.unbind_dispatcher ();
this->resolver_.transport ()->close_connection ();
+ if (this->retry_state_ &&
+ this->resolver_.transport ()->connection_closed_on_read() &&
+ this->retry_state_->forward_on_reply_closed_increment ())
+ {
+ if (TAO_debug_level > 4)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("wait_for_reply, forward profile on ")
+ ACE_TEXT ("connection closed\n")));
+ this->retry_state_->next_profile_retry (*this->stub ());
+ return TAO_INVOKE_RESTART;
+ }
+
try
{
return
@@ -322,7 +359,11 @@ namespace TAO
}
catch (const ::CORBA::Exception&)
{
- this->resolver_.stub ()->reset_profiles ();
+ if (this->retry_state_ == 0 ||
+ !this->retry_state_->forward_on_exception_limit_used ())
+ {
+ this->resolver_.stub ()->reset_profiles ();
+ }
throw;
}
}
@@ -386,8 +427,9 @@ namespace TAO
// permanent condition not given
if (TAO_debug_level > 3)
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::"
- "check_reply_status: unexpected LOCATION_FORWARD_PERM reply\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("check_reply_status: unexpected ")
+ ACE_TEXT ("LOCATION_FORWARD_PERM reply\n")));
throw ::CORBA::INTERNAL (0, CORBA::COMPLETED_NO);
}
@@ -439,8 +481,8 @@ namespace TAO
if (TAO_debug_level > 3)
{
ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::location_forward ")
- ACE_TEXT ("being handled\n")));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("location_forward being handled\n")));
}
CORBA::Object_var fwd;
@@ -469,8 +511,8 @@ namespace TAO
if (TAO_debug_level > 3)
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::"
- "handle_user_exception\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("handle_user_exception\n")));
// Pull the exception from the stream.
CORBA::String_var buf;
@@ -513,8 +555,8 @@ namespace TAO
if (TAO_debug_level > 3)
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::"
- "handle_system_exception\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("handle_system_exception\n")));
CORBA::String_var type_id;
@@ -533,40 +575,80 @@ namespace TAO
throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
}
+ bool retry_on_exception = false;
bool do_forward = false;
- int foe_kind = this->stub ()->orb_core ()->orb_params ()->forward_once_exception();
-
- if ((CORBA::CompletionStatus) completion != CORBA::COMPLETED_YES
- && (((foe_kind & TAO::FOE_TRANSIENT) == 0
- && ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0) ||
- ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/OBJ_ADAPTER:1.0") == 0 ||
- ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/NO_RESPONSE:1.0") == 0 ||
- ((foe_kind & TAO::FOE_COMM_FAILURE) == 0
- && ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0) ||
- (this->stub ()->orb_core ()->orb_params ()->forward_invocation_on_object_not_exist ()
- && ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0) ||
- (do_forward = ! this->stub ()->forwarded_on_exception ()
- && ((((foe_kind & TAO::FOE_OBJECT_NOT_EXIST) == TAO::FOE_OBJECT_NOT_EXIST)
- && (ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0)) ||
- (((foe_kind & TAO::FOE_COMM_FAILURE) == TAO::FOE_COMM_FAILURE)
- && (ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0)) ||
- (((foe_kind & TAO::FOE_TRANSIENT) == TAO::FOE_TRANSIENT)
- && (ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0)) ||
- (((foe_kind & TAO::FOE_INV_OBJREF) == TAO::FOE_INV_OBJREF)
- && (ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/INV_OBJREF:1.0") == 0))))))
+
+ const TAO_ORB_Parameters *orb_params = this->stub ()->orb_core ()->orb_params ();
+
+ if (this->retry_state_ &&
+ this->retry_state_->forward_on_exception_limit_used () &&
+ (CORBA::CompletionStatus) completion == CORBA::COMPLETED_NO)
+ {
+ if ((ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0 &&
+ this->retry_state_->forward_on_exception_increment (TAO::FOE_TRANSIENT)) ||
+ (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0 &&
+ this->retry_state_->forward_on_exception_increment (TAO::FOE_COMM_FAILURE)) ||
+ (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0 &&
+ this->retry_state_->forward_on_exception_increment (TAO::FOE_OBJECT_NOT_EXIST)) ||
+ (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/INV_OBJREF:1.0") == 0 &&
+ this->retry_state_->forward_on_exception_increment (TAO::FOE_INV_OBJREF))
+ )
+ {
+ retry_on_exception = true;
+ this->retry_state_->sleep_at_starting_profile (*this->stub ());
+ }
+ }
+ else
+ {
+ int foe_kind = orb_params->forward_once_exception();
+
+ retry_on_exception =
+ (CORBA::CompletionStatus) completion != CORBA::COMPLETED_YES
+ && (((foe_kind & TAO::FOE_TRANSIENT) == 0
+ && ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0) ||
+ ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/OBJ_ADAPTER:1.0") == 0 ||
+ ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/NO_RESPONSE:1.0") == 0 ||
+ ((foe_kind & TAO::FOE_COMM_FAILURE) == 0
+ && ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0) ||
+ (orb_params->forward_invocation_on_object_not_exist ()
+ && ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0) ||
+ (do_forward = ! this->stub ()->forwarded_on_exception ()
+ && ((((foe_kind & TAO::FOE_OBJECT_NOT_EXIST) == TAO::FOE_OBJECT_NOT_EXIST)
+ && (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0)) ||
+ (((foe_kind & TAO::FOE_COMM_FAILURE) == TAO::FOE_COMM_FAILURE)
+ && (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0)) ||
+ (((foe_kind & TAO::FOE_TRANSIENT) == TAO::FOE_TRANSIENT)
+ && (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0)) ||
+ (((foe_kind & TAO::FOE_INV_OBJREF) == TAO::FOE_INV_OBJREF)
+ && (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/INV_OBJREF:1.0") == 0)))));
+ }
+
+ if (retry_on_exception)
{
// If we are here then possibly we'll need a restart.
mon.set_status (TAO_INVOKE_RESTART);
+ if (TAO_debug_level > 4)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("handle_system_exception, profile forwarding ")
+ ACE_TEXT ("on exception "),
+ type_id.in (),
+ ACE_TEXT ("\n")));
+
if (do_forward)
this->stub ()->forwarded_on_exception (true);
@@ -625,8 +707,8 @@ namespace TAO
if (TAO_debug_level > 4)
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::"
- "handle_system_exception, about to raise\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("handle_system_exception, about to raise\n")));
mon.set_status (TAO_INVOKE_SYSTEM_EXCEPTION);
@@ -676,80 +758,98 @@ namespace TAO
if (!transport)
{
- // Way back, we failed to find a profile we could connect to.
- // We've come this far only so we reach the interception points
- // in case they can fix things. Time to bail....
- throw CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
- }
+ if (this->retry_state_ &&
+ this->retry_state_->forward_on_exception_limit_used ())
+ {
+ if (this->retry_state_->forward_on_exception_increment(FOE_TRANSIENT))
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Oneway_Invocation::")
+ ACE_TEXT ("remote_oneway retrying on TRANSIENT ")
+ ACE_TEXT ("exception\n")));
+ this->retry_state_->next_profile_retry (*this->stub ());
+ return TAO_INVOKE_RESTART;
+ }
+ }
+ else
+ {
+ // Way back, we failed to find a profile we could connect to.
+ // We've come this far only so we reach the interception points
+ // in case they can fix things. Time to bail....
+ throw CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
+ }
- {
- ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, transport->output_cdr_lock (),
- TAO_INVOKE_FAILURE);
+ }
- TAO_OutputCDR &cdr = transport->out_stream ();
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, transport->output_cdr_lock (),
+ TAO_INVOKE_FAILURE);
- cdr.message_attributes (this->details_.request_id (),
- this->resolver_.stub (),
- TAO_Message_Semantics (TAO_Message_Semantics::TAO_ONEWAY_REQUEST),
- max_wait_time);
+ TAO_OutputCDR &cdr = transport->out_stream ();
- this->write_header (cdr);
+ cdr.message_attributes (this->details_.request_id (),
+ this->resolver_.stub (),
+ TAO_Message_Semantics (TAO_Message_Semantics::TAO_ONEWAY_REQUEST),
+ max_wait_time);
- this->marshal_data (cdr);
+ this->write_header (cdr);
- countdown.update ();
+ this->marshal_data (cdr);
- if (transport->is_connected ())
- {
- // We have a connected transport so we can send the message
- s = this->send_message (cdr,
- TAO_Message_Semantics (TAO_Message_Semantics::TAO_ONEWAY_REQUEST),
- max_wait_time);
+ countdown.update ();
- if (transport->wait_strategy ()->non_blocking () == 0 &&
- transport->orb_core ()->client_factory ()->use_cleanup_options ())
- {
- if (!transport->wait_strategy ()->is_registered())
- {
- ACE_Event_Handler * const eh =
- transport->event_handler_i ();
-
- ACE_Reactor * const r =
- transport->orb_core ()->reactor ();
-
- if (r->register_handler (eh, ACE_Event_Handler::READ_MASK) == -1)
- {
- if (TAO_debug_level > 0)
- ACE_ERROR ((LM_ERROR,
- "TAO (%P|%t) - Synch_Oneway_Invocation::"
- "remote_oneway transport[%d] registration with"
- "reactor returned an error\n",
- transport->id ()));
- }
- else
- {
- // Only set this flag when registration succeeds
- transport->wait_strategy ()->is_registered(true);
- }
- }
- }
+ if (transport->is_connected ())
+ {
+ // We have a connected transport so we can send the message
+ s = this->send_message (cdr,
+ TAO_Message_Semantics (TAO_Message_Semantics::TAO_ONEWAY_REQUEST),
+ max_wait_time);
- }
- else
- {
- if (TAO_debug_level > 4)
- ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Oneway_Invocation::"
- "remote_oneway, queueing message\n"));
+ if (transport->wait_strategy ()->non_blocking () == 0 &&
+ transport->orb_core ()->client_factory ()->use_cleanup_options ())
+ {
+ if (!transport->wait_strategy ()->is_registered())
+ {
+ ACE_Event_Handler * const eh =
+ transport->event_handler_i ();
+
+ ACE_Reactor * const r =
+ transport->orb_core ()->reactor ();
+
+ if (r->register_handler (eh, ACE_Event_Handler::READ_MASK) == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Oneway_Invocation::")
+ ACE_TEXT ("remote_oneway transport[%d] registration with")
+ ACE_TEXT ("reactor returned an error\n"),
+ transport->id ()));
+ }
+ else
+ {
+ // Only set this flag when registration succeeds
+ transport->wait_strategy ()->is_registered (true);
+ }
+ }
+ }
- if (transport->format_queue_message (cdr,
- max_wait_time,
- this->resolver_.stub()) != 0)
- {
- s = TAO_INVOKE_FAILURE;
- }
- }
- }
+ }
+ else
+ {
+ if (TAO_debug_level > 4)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Oneway_Invocation::")
+ ACE_TEXT ("remote_oneway, queueing message\n")));
+
+ if (transport->format_queue_message (cdr,
+ max_wait_time,
+ this->resolver_.stub()) != 0)
+ {
+ s = TAO_INVOKE_FAILURE;
+ }
+ }
+ }
#if TAO_HAS_INTERCEPTORS == 1
s = this->receive_other_interception ();
@@ -763,7 +863,7 @@ namespace TAO
status == PortableInterceptor::TRANSPORT_RETRY)
s = TAO_INVOKE_RESTART;
else if (status == PortableInterceptor::SYSTEM_EXCEPTION
- || status == PortableInterceptor::USER_EXCEPTION)
+ || status == PortableInterceptor::USER_EXCEPTION)
throw;
}
catch (...)
@@ -771,14 +871,14 @@ namespace TAO
// Notify interceptors of non-CORBA exception, and propagate
// that exception to the caller.
- PortableInterceptor::ReplyStatus const st =
- this->handle_all_exception ();
+ PortableInterceptor::ReplyStatus const st =
+ this->handle_all_exception ();
- if (st == PortableInterceptor::LOCATION_FORWARD ||
- st == PortableInterceptor::TRANSPORT_RETRY)
- s = TAO_INVOKE_RESTART;
- else
- throw;
+ if (st == PortableInterceptor::LOCATION_FORWARD ||
+ st == PortableInterceptor::TRANSPORT_RETRY)
+ s = TAO_INVOKE_RESTART;
+ else
+ throw;
}
#endif /* TAO_HAS_INTERCEPTORS */
diff --git a/TAO/tao/Synch_Invocation.h b/TAO/tao/Synch_Invocation.h
index ca01bafcbf4..bec82241379 100644
--- a/TAO/tao/Synch_Invocation.h
+++ b/TAO/tao/Synch_Invocation.h
@@ -36,6 +36,7 @@ class TAO_Bind_Dispatcher_Guard;
namespace TAO
{
class Profile_Transport_Resolver;
+ class Invocation_Retry_State;
/**
* @class Synch_Twoway_Invocation
@@ -82,6 +83,12 @@ namespace TAO
*/
Invocation_Status remote_twoway (ACE_Time_Value *max_wait_time);
+ /**
+ * Indicate that retry state should be tracked and controlled
+ * in the presense of exceptions.
+ */
+ void set_retry_state (Invocation_Retry_State *retry_state);
+
protected:
/**
@@ -107,6 +114,8 @@ namespace TAO
TAO_Synch_Reply_Dispatcher &rd,
TAO_Bind_Dispatcher_Guard &bd);
+ Invocation_Retry_State *retry_state_;
+
private:
/// Helper method that checks the reply status of the
@@ -115,6 +124,7 @@ namespace TAO
* This method returns an exception when there is an error.
*/
Invocation_Status check_reply_status (TAO_Synch_Reply_Dispatcher &rd);
+
};
/**
diff --git a/TAO/tao/Transport.cpp b/TAO/tao/Transport.cpp
index 25b70346428..b85f65966e1 100644
--- a/TAO/tao/Transport.cpp
+++ b/TAO/tao/Transport.cpp
@@ -143,6 +143,7 @@ TAO_Transport::TAO_Transport (CORBA::ULong tag,
, recv_buffer_size_ (0)
, sent_byte_count_ (0)
, is_connected_ (false)
+ , connection_closed_on_read_ (false)
, messaging_object_ (0)
, char_translator_ (0)
, wchar_translator_ (0)
@@ -2881,6 +2882,12 @@ TAO_Transport::using_blocking_io_for_asynch_messages (void) const
return false;
}
+bool
+TAO_Transport::connection_closed_on_read (void) const
+{
+ return connection_closed_on_read_;
+}
+
/*
* Hook to add concrete implementations from the derived class onto
* TAO's transport.
diff --git a/TAO/tao/Transport.h b/TAO/tao/Transport.h
index 914ede4db9b..84920bf9c7a 100644
--- a/TAO/tao/Transport.h
+++ b/TAO/tao/Transport.h
@@ -648,6 +648,9 @@ public:
/// Is this transport really connected
bool is_connected (void) const;
+ /// Was a connection seen as closed during a read
+ bool connection_closed_on_read (void) const;
+
/// Perform all the actions when this transport get opened
bool post_open (size_t id);
@@ -1183,6 +1186,12 @@ protected:
/// buffer the requests in this transport until the connection is ready
bool is_connected_;
+ /// Track if connection was seen as closed during a read so that
+ /// invocation can optionally be retried using a different profile.
+ /// Note that this could result in violate the "at most once" CORBA
+ /// semantics.
+ bool connection_closed_on_read_;
+
private:
/// Our messaging object.
diff --git a/TAO/tao/VarOut_T.h b/TAO/tao/VarOut_T.h
index c1608cab33a..fd3f1f4f041 100644
--- a/TAO/tao/VarOut_T.h
+++ b/TAO/tao/VarOut_T.h
@@ -54,6 +54,7 @@ public:
// TAO extension.
T * ptr (void) const;
+ operator T *& ();
protected:
T * ptr_;
@@ -113,9 +114,6 @@ public:
TAO_Var_Var_T & operator= (T *);
TAO_Var_Var_T & operator= (const TAO_Var_Var_T<T> &);
- // Variable size types only.
- operator T *& ();
-
operator const T & () const;
operator T & ();
operator T & () const;
diff --git a/TAO/tao/VarOut_T.inl b/TAO/tao/VarOut_T.inl
index d73084b4b16..7735ef6cefb 100644
--- a/TAO/tao/VarOut_T.inl
+++ b/TAO/tao/VarOut_T.inl
@@ -62,6 +62,14 @@ TAO_Var_Base_T<T>::ptr (void) const
{
return this->ptr_;
}
+
+template<typename T>
+ACE_INLINE
+TAO_Var_Base_T<T>::operator T *& ()
+{
+ return this->ptr_;
+}
+
// *************************************************************
template<typename T>
@@ -179,14 +187,6 @@ TAO_Var_Var_T<T>::operator= (T * p)
return *this;
}
-// Variable-size types only.
-template<typename T>
-ACE_INLINE
-TAO_Var_Var_T<T>::operator T *& ()
-{
- return this->ptr_;
-}
-
template<typename T>
ACE_INLINE
TAO_Var_Var_T<T>::operator const T & () const
diff --git a/TAO/tao/default_client.cpp b/TAO/tao/default_client.cpp
index ac2e0c1a57c..5e3044e9b98 100644
--- a/TAO/tao/default_client.cpp
+++ b/TAO/tao/default_client.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-// $Id: default_client.cpp 93686 2011-03-31 12:12:12Z johnnyw $
+// $Id$
#include "tao/default_client.h"
#include "tao/Wait_On_Read.h"
@@ -12,6 +12,7 @@
#include "tao/Reactive_Connect_Strategy.h"
#include "tao/LF_Connect_Strategy.h"
#include "tao/orbconf.h"
+#include "tao/Invocation_Utils.h"
#include "ace/Lock_Adapter_T.h"
#include "ace/Recursive_Thread_Mutex.h"
@@ -99,11 +100,13 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_TEXT("MT_NOUPCALL")) == 0)
this->wait_strategy_ = TAO_WAIT_ON_LF_NO_UPCALL;
else
- this->report_option_value_error (ACE_TEXT("-ORBClientConnectionHandler"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBClientConnectionHandler"), name);
}
}
else if (ACE_OS::strcasecmp (argv[curarg],
- ACE_TEXT("-ORBTransportMuxStrategy")) == 0)
+ ACE_TEXT("-ORBTransportMuxStrategy"))
+ == 0)
{
curarg++;
if (curarg < argc)
@@ -117,11 +120,13 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_TEXT("EXCLUSIVE")) == 0)
this->transport_mux_strategy_ = TAO_EXCLUSIVE_TMS;
else
- this->report_option_value_error (ACE_TEXT("-ORBTransportMuxStrategy"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBTransportMuxStrategy"), name);
}
}
else if (ACE_OS::strcasecmp (argv[curarg],
- ACE_TEXT("-ORBTransportMuxStrategyLock")) == 0)
+ ACE_TEXT("-ORBTransportMuxStrategyLock"))
+ == 0)
{
curarg++;
if (curarg < argc)
@@ -135,7 +140,8 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_TEXT("thread")) == 0)
this->muxed_strategy_lock_type_ = TAO_THREAD_LOCK;
else
- this->report_option_value_error (ACE_TEXT("-ORBTransportMuxStrategyLock"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBTransportMuxStrategyLock"), name);
}
}
else if (ACE_OS::strcasecmp (argv[curarg],
@@ -156,11 +162,14 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_TEXT("LF")) == 0)
this->connect_strategy_ = TAO_LEADER_FOLLOWER_CONNECT;
else
- this->report_option_value_error (ACE_TEXT("-ORBConnectStrategy"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBConnectStrategy"),
+ name);
}
}
else if (ACE_OS::strcasecmp (argv[curarg],
- ACE_TEXT("-ORBReplyDispatcherTableSize")) == 0)
+ ACE_TEXT("-ORBReplyDispatcherTableSize"))
+ == 0)
{
curarg++;
if (curarg < argc)
@@ -183,7 +192,118 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_OS::strcasecmp (name, ACE_TEXT("true")) == 0)
this->use_cleanup_options_ = true;
else
- this->report_option_value_error (ACE_TEXT("-ORBConnectionHandlerCleanup"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBConnectionHandlerCleanup"), name);
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnCommFailureLimit"))
+ == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnCommFailureLimit"),
+ name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_exception_limit_[TAO::FOE_COMM_FAILURE] =
+ limit;
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnTransientLimit")) == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnTransientLimit"),
+ name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_exception_limit_[TAO::FOE_TRANSIENT] =
+ limit;
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnObjectNotExistLimit"))
+ == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnObjectNotExistLimit"),
+ name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_exception_limit_[TAO::FOE_OBJECT_NOT_EXIST] =
+ limit;
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnInvObjrefLimit")) == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnInvObjrefLimit"), name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_exception_limit_[TAO::FOE_INV_OBJREF] =
+ limit;
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnReplyClosedLimit"))
+ == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnReplyClosedLimit"), name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_reply_closed_limit_ = limit;
}
}
else if (ACE_OS::strncmp (argv[curarg], ACE_TEXT("-ORB"), 4) == 0)
@@ -208,7 +328,8 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
/// Create the correct client transport muxing strategy.
TAO_Transport_Mux_Strategy *
-TAO_Default_Client_Strategy_Factory::create_transport_mux_strategy (TAO_Transport *transport)
+TAO_Default_Client_Strategy_Factory::create_transport_mux_strategy (
+ TAO_Transport *transport)
{
TAO_Transport_Mux_Strategy *tms = 0;
@@ -266,13 +387,14 @@ TAO_Default_Client_Strategy_Factory::reply_dispatcher_table_size (void) const
}
TAO_Wait_Strategy *
-TAO_Default_Client_Strategy_Factory::create_wait_strategy (TAO_Transport *transport)
+TAO_Default_Client_Strategy_Factory::create_wait_strategy (
+ TAO_Transport *transport)
{
TAO_Wait_Strategy *ws = 0;
/*
- * Hook to customize the wait strategy object when the concrete wait strategy
- * object is known a priori.
+ * Hook to customize the wait strategy object when the concrete
+ * wait strategy object is known a priori.
*/
//@@ WAIT_STRATEGY_SPL_COMMENT_HOOK_START
switch (this->wait_strategy_)
@@ -318,7 +440,8 @@ TAO_Default_Client_Strategy_Factory::connect_strategy (void) const
}
TAO_Connect_Strategy *
-TAO_Default_Client_Strategy_Factory::create_connect_strategy (TAO_ORB_Core *orb_core)
+TAO_Default_Client_Strategy_Factory::create_connect_strategy (
+ TAO_ORB_Core *orb_core)
{
TAO_Connect_Strategy *cs = 0;
@@ -374,13 +497,20 @@ TAO_Default_Client_Strategy_Factory::use_cleanup_options (void) const
return this->use_cleanup_options_;
}
+const TAO::Invocation_Retry_Params &
+TAO_Default_Client_Strategy_Factory::invocation_retry_params (void) const
+{
+ return this->invocation_retry_params_;
+}
+
// ****************************************************************
ACE_STATIC_SVC_DEFINE (TAO_Default_Client_Strategy_Factory,
ACE_TEXT ("Client_Strategy_Factory"),
ACE_SVC_OBJ_T,
&ACE_SVC_NAME (TAO_Default_Client_Strategy_Factory),
- ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
0)
ACE_FACTORY_DEFINE (TAO, TAO_Default_Client_Strategy_Factory)
diff --git a/TAO/tao/default_client.h b/TAO/tao/default_client.h
index 3d7ea54f599..bd506384cec 100644
--- a/TAO/tao/default_client.h
+++ b/TAO/tao/default_client.h
@@ -22,6 +22,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/Client_Strategy_Factory.h"
+#include "tao/Invocation_Retry_Params.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -61,6 +62,7 @@ public:
virtual TAO_Connect_Strategy *create_connect_strategy (TAO_ORB_Core *);
virtual bool use_cleanup_options (void) const;
virtual Connect_Strategy connect_strategy (void) const;
+ virtual const TAO::Invocation_Retry_Params &invocation_retry_params (void) const;
protected:
void report_option_value_error (const ACE_TCHAR* option_name,
@@ -104,6 +106,9 @@ private:
/// Cleanupoptions for RW strategy
bool use_cleanup_options_;
+
+ /// Retry options when exceptions occur
+ TAO::Invocation_Retry_Params invocation_retry_params_;
};
ACE_STATIC_SVC_DECLARE_EXPORT (TAO, TAO_Default_Client_Strategy_Factory)
diff --git a/TAO/tao/params.cpp b/TAO/tao/params.cpp
index 7adbe9e5cff..bc286c1a0e5 100644
--- a/TAO/tao/params.cpp
+++ b/TAO/tao/params.cpp
@@ -57,6 +57,7 @@ TAO_ORB_Parameters::TAO_ORB_Parameters (void)
, stub_factory_name_ ("Default_Stub_Factory")
, endpoint_selector_factory_name_ ("Default_Endpoint_Selector_Factory")
, thread_lane_resources_manager_factory_name_ ("Default_Thread_Lane_Resources_Manager_Factory")
+ , dynamic_thread_pool_config_name_ ()
, poa_factory_name_ ("TAO_Object_Adapter_Factory")
, poa_factory_directive_
(ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE("TAO_Object_Adapter_Factory",
@@ -65,7 +66,7 @@ TAO_ORB_Parameters::TAO_ORB_Parameters (void)
"_make_TAO_Object_Adapter_Factory",
""))
, forward_invocation_on_object_not_exist_ (false)
- , forward_once_exception_ (TAO::FOE_NON)
+ , forward_once_exception_ (0)
, collocation_resolver_name_ ("Default_Collocation_Resolver")
, allow_ziop_no_server_policies_ (!!TAO_ALLOW_ZIOP_NO_SERVER_POLICIES_DEFAULT)
{
@@ -365,6 +366,18 @@ TAO_ORB_Parameters::thread_lane_resources_manager_factory_name (void) const
}
void
+TAO_ORB_Parameters::dynamic_thread_pool_config_name (const char *s)
+{
+ this->dynamic_thread_pool_config_name_ = s;
+}
+
+const char *
+TAO_ORB_Parameters::dynamic_thread_pool_config_name (void) const
+{
+ return this->dynamic_thread_pool_config_name_.c_str ();
+}
+
+void
TAO_ORB_Parameters::stub_factory_name (const char *s)
{
this->stub_factory_name_ = s;
@@ -412,4 +425,28 @@ TAO_ORB_Parameters::endpoint_selector_factory_name (void) const
return this->endpoint_selector_factory_name_.c_str ();
}
+const TAO::Invocation_Retry_Params &
+TAO_ORB_Parameters::invocation_retry_params (void) const
+{
+ return this->invocation_retry_params_;
+}
+
+TAO::Invocation_Retry_Params &
+TAO_ORB_Parameters::invocation_retry_params (void)
+{
+ return this->invocation_retry_params_;
+}
+
+void
+TAO_ORB_Parameters::forward_on_exception_limit (const int ef, const int limit)
+{
+ this->invocation_retry_params_.forward_on_exception_limit_[ef] = limit;
+}
+
+void
+TAO_ORB_Parameters::forward_on_exception_delay (const ACE_Time_Value &delay)
+{
+ this->invocation_retry_params_.init_retry_delay_ = delay;
+}
+
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/params.h b/TAO/tao/params.h
index 90c5c80c4e4..b9c91ebaaa1 100644
--- a/TAO/tao/params.h
+++ b/TAO/tao/params.h
@@ -14,9 +14,11 @@
#define TAO_PARAMS_H
#include /**/ "ace/pre.h"
+#include "tao/Invocation_Retry_Params.h"
#include "ace/Unbounded_Queue.h"
#include "ace/Array_Map.h"
#include "ace/Synch.h"
+#include "ace/Time_Value.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -42,6 +44,8 @@ typedef ACE_Unbounded_Queue_Const_Iterator<ACE_CString> TAO_EndpointSetIterator;
// -------------------------------------------------------------------
+
+
/**
* @class TAO_ORB_Parameters
*
@@ -237,6 +241,9 @@ public:
void thread_lane_resources_manager_factory_name (const char *s);
const char *thread_lane_resources_manager_factory_name (void) const;
+ void dynamic_thread_pool_config_name (const char *s);
+ const char *dynamic_thread_pool_config_name (void) const;
+
void stub_factory_name (const char *s);
const char *stub_factory_name (void) const;
@@ -255,7 +262,13 @@ public:
void forward_invocation_on_object_not_exist (bool opt);
bool forward_invocation_on_object_not_exist (void) const;
- void forward_once_exception (const int);
+ void forward_on_exception_limit (const int ef, const int limit);
+ void forward_on_exception_delay (const ACE_Time_Value &delay);
+
+ TAO::Invocation_Retry_Params &invocation_retry_params (void);
+ const TAO::Invocation_Retry_Params &invocation_retry_params (void) const;
+
+ void forward_once_exception (const int ef);
int forward_once_exception () const;
void allow_ziop_no_server_policies (bool opt);
@@ -458,6 +471,13 @@ private:
ACE_CString thread_lane_resources_manager_factory_name_;
/**
+ * Name of the non-RT dynamic thread pool configuration set to load.
+ * This is only used if the Dynamic_TP library is linked. Default
+ * is an empty string.
+ */
+ ACE_CString dynamic_thread_pool_config_name_;
+
+ /**
* Name of the service object used to create the RootPOA. The
* default value is "TAO_POA". If TAO_RTCORBA is loaded, this
* will be changed to TAO_RT_POA so that a POA equipped with
@@ -478,13 +498,15 @@ private:
*/
bool forward_invocation_on_object_not_exist_;
+ TAO::Invocation_Retry_Params invocation_retry_params_;
/**
* The exceptions upon which the requests will be forwarded once.
+ * This is retained for backward compatibility of behavior.
*/
int forward_once_exception_;
- /**
+/**
* Name of the collocation resolver that needs to be instantiated.
* The default value is "Default_Collocation_Resolver". If
* TAO_RTCORBA is linked, the set_collocation_resolver will be
diff --git a/TAO/tao/tao.mpc b/TAO/tao/tao.mpc
index b26544fbf41..e2aff7dbe5c 100644
--- a/TAO/tao/tao.mpc
+++ b/TAO/tao/tao.mpc
@@ -174,6 +174,8 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
Invocation_Adapter.cpp
Invocation_Base.cpp
Invocation_Endpoint_Selectors.cpp
+ Invocation_Retry_State.cpp
+ Invocation_Retry_Params.cpp
IOPC.cpp
IOR_Parser.cpp
IORInterceptor_Adapter.cpp
@@ -274,6 +276,10 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
ShortSeqC.cpp
String_Alloc.cpp
StringSeqC.cpp
+ Storable_Base.cpp
+ Storable_FlatFileStream.cpp
+ Storable_Factory.cpp
+ Storable_File_Guard.cpp
Stub.cpp
Stub_Factory.cpp
Synch_Invocation.cpp