summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs
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/orbsvcs/orbsvcs
parent9d296f7fa51116ff7040ecb2ad18612cd94b5fd1 (diff)
downloadATCD-5e030faf84086ab02059fcbcc3faed224bd57b95.tar.gz
Merge in OCI_Reliability_Enhancements branch.
Diffstat (limited to 'TAO/orbsvcs/orbsvcs')
-rw-r--r--TAO/orbsvcs/orbsvcs/CosEvent.mpc2
-rw-r--r--TAO/orbsvcs/orbsvcs/CosNaming_Serv.mpc1
-rw-r--r--TAO/orbsvcs/orbsvcs/FT_NamingManager.idl63
-rw-r--r--TAO/orbsvcs/orbsvcs/FT_NamingReplication.idl79
-rw-r--r--TAO/orbsvcs/orbsvcs/FT_Naming_Serv.mpc42
-rw-r--r--TAO/orbsvcs/orbsvcs/FtNaming.mpc28
-rw-r--r--TAO/orbsvcs/orbsvcs/FtNamingReplication.mpc25
-rw-r--r--TAO/orbsvcs/orbsvcs/FtRtEvent/Utils/FTEC_Gateway.cpp6
-rw-r--r--TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.cpp2
-rw-r--r--TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.h2
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp2
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadAverage.cpp2
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMinimum.cpp2
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Location_Index_Map.h42
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp747
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h351
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp179
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h110
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp1196
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h189
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp132
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h82
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp182
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h132
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp111
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h75
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp40
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h56
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp76
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h95
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp183
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h112
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp47
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h66
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_export.h58
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_intf_export.h58
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp717
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.h184
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Flat_File_Persistence.cpp386
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Flat_File_Persistence.h95
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Hash_Naming_Context.cpp106
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.cpp20
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.h18
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.cpp34
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.h8
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Naming_Server.cpp158
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Naming_Server.h33
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.cpp37
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.h21
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.cpp35
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.h14
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.cpp39
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.h62
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable.h83
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable.inl65
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp501
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h123
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp58
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.h25
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp49
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h72
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.cpp270
-rw-r--r--TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.h64
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp345
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h92
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp289
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h119
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp152
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h70
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.cpp11
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h10
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp571
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.h194
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp28
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.cpp2
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.h2
-rw-r--r--TAO/orbsvcs/orbsvcs/cosnaming_serv_persistence.mpb4
77 files changed, 8441 insertions, 1300 deletions
diff --git a/TAO/orbsvcs/orbsvcs/CosEvent.mpc b/TAO/orbsvcs/orbsvcs/CosEvent.mpc
index 80efa635a0a..97b0de957d9 100644
--- a/TAO/orbsvcs/orbsvcs/CosEvent.mpc
+++ b/TAO/orbsvcs/orbsvcs/CosEvent.mpc
@@ -84,7 +84,7 @@ project (CosEvent_Skel) : orbsvcslib, orbsvcs_output, install, avoids_minimum_co
}
-project (CosEvent_Serv) : orbsvcslib, orbsvcs_output, install, avoids_minimum_corba, event_skel, ec_typed_events_serv, messaging_optional, naming, svc_utils {
+project (CosEvent_Serv) : orbsvcslib, orbsvcs_output, install, avoids_minimum_corba, event_skel, ec_typed_events_serv, messaging_optional, ifr_client, naming, svc_utils {
sharedname = TAO_CosEvent_Serv
dynamicflags += TAO_EVENT_SERV_BUILD_DLL
tagchecks += CosEvent
diff --git a/TAO/orbsvcs/orbsvcs/CosNaming_Serv.mpc b/TAO/orbsvcs/orbsvcs/CosNaming_Serv.mpc
index 9e683abb6d9..9cd821e7bf3 100644
--- a/TAO/orbsvcs/orbsvcs/CosNaming_Serv.mpc
+++ b/TAO/orbsvcs/orbsvcs/CosNaming_Serv.mpc
@@ -17,6 +17,7 @@ project(CosNaming_Serv) : cosnaming_serv_persistence, orbsvcslib, orbsvcs_output
Naming/Naming_Context_Interface.cpp
Naming/Naming_Loader.cpp
Naming/Naming_Server.cpp
+ Naming/Storable_Naming_Context_Factory.cpp
Naming/Transient_Naming_Context.cpp
}
}
diff --git a/TAO/orbsvcs/orbsvcs/FT_NamingManager.idl b/TAO/orbsvcs/orbsvcs/FT_NamingManager.idl
new file mode 100644
index 00000000000..ae13105d9aa
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/FT_NamingManager.idl
@@ -0,0 +1,63 @@
+/* -*- IDL -*- */
+//=============================================================================
+/**
+ * @file FT_NamingManager.idl
+ *
+ * $Id$
+ *
+ * This file is part of Fault Tolerant Naming Service.
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef _FT_NAMING_MANAGER_IDL_
+#define _FT_NAMING_MANAGER_IDL_
+
+#include "orbsvcs/PortableGroup.idl"
+
+module FT_Naming
+{
+ typedef PortableGroup::ObjectGroup ObjectGroup;
+
+ const string TAO_FT_OBJECT_GROUP_NAME = "TAO_FT_GroupName";
+ const string TAO_FT_LOAD_BALANCING_STRATEGY = "TAO_FT_LB_Strategy";
+
+ typedef long LoadBalancingStrategyValue;
+ const LoadBalancingStrategyValue ROUND_ROBIN = 0;
+ const LoadBalancingStrategyValue RANDOM = 1;
+ const LoadBalancingStrategyValue LEAST = 2;
+
+ typedef string GroupName;
+ typedef sequence<string> GroupNames;
+
+ // Specification of NamingManager Interface
+ interface NamingManager : PortableGroup::PropertyManager,
+ PortableGroup::ObjectGroupManager
+ {
+ ObjectGroup create_object_group (in GroupName group_name,
+ in LoadBalancingStrategyValue lb_strategy,
+ in PortableGroup::Criteria the_criteria)
+ raises (PortableGroup::ObjectNotCreated,
+ PortableGroup::InvalidCriteria,
+ PortableGroup::InvalidProperty,
+ PortableGroup::CannotMeetCriteria);
+
+ void delete_object_group (in string group_name)
+ raises (PortableGroup::ObjectGroupNotFound);
+
+ ObjectGroup get_object_group_ref_from_name (
+ in string group_name)
+ raises (PortableGroup::ObjectGroupNotFound);
+
+ void set_load_balancing_strategy (in string group_name,
+ in LoadBalancingStrategyValue lb_strategy);
+
+ // Return names of all groups defined in the NamingManager
+ GroupNames groups (in LoadBalancingStrategyValue target_stategy);
+
+ };
+};
+
+
+#endif // _FT_NAMING_MANAGER_IDL_
diff --git a/TAO/orbsvcs/orbsvcs/FT_NamingReplication.idl b/TAO/orbsvcs/orbsvcs/FT_NamingReplication.idl
new file mode 100644
index 00000000000..df1c1178422
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/FT_NamingReplication.idl
@@ -0,0 +1,79 @@
+/* -*- IDL -*- */
+//=============================================================================
+/**
+ * @file FT_NamingReplication.idl
+ *
+ * $Id$
+ *
+ * This file is part of Fault Tolerant Naming Service in support of
+ * replication between redundant servers.
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef _FT_NAMING_REPLICATION_IDL_
+#define _FT_NAMING_REPLICATION_IDL_
+
+#include <orbsvcs/CosNaming.idl>
+#include <orbsvcs/FT_NamingManager.idl>
+#include <orbsvcs/FT_CORBA_ORB.idl>
+
+module FT_Naming
+{
+
+ enum ChangeType { NEW, UPDATED, DELETED };
+
+ exception NotAvailable
+ {
+ };
+
+ /*
+ * A structure that describes the updated element in a Naming Service
+ */
+ struct NamingContextUpdate
+ {
+ /// The name of context being updated
+ string context_name;
+ /// The type of change that is being reported
+ ChangeType change_type;
+ };
+
+ struct ReplicaInfo
+ {
+ CosNaming::NamingContext root_context;
+ FT_Naming::NamingManager naming_manager;
+ };
+
+ /*
+ * A structure that describes the updated element within
+ * an Object Group Manager
+ */
+ struct ObjectGroupUpdate
+ {
+ /// This is used to identify object group references.
+ PortableGroup::ObjectGroupId id;
+ /// The type of change that is being reported
+ ChangeType change_type;
+ };
+
+ interface ReplicationManager
+ {
+ /*
+ * Register with a peer replica providing an object reference for
+ * notification of updates. Each replica will maintain their state
+ * in a shared repository and the update notification indicates the
+ * element that was changed.
+ */
+ ReplicaInfo register_replica (in ReplicationManager replica,
+ in ReplicaInfo replica_info)
+ raises (NotAvailable);
+
+ oneway void notify_updated_object_group(in ObjectGroupUpdate group_info);
+
+ oneway void notify_updated_context(in NamingContextUpdate context_info);
+ };
+};
+
+
+#endif // _FT_NAMING_REPLICATION_IDL_
diff --git a/TAO/orbsvcs/orbsvcs/FT_Naming_Serv.mpc b/TAO/orbsvcs/orbsvcs/FT_Naming_Serv.mpc
new file mode 100644
index 00000000000..6f963a8f725
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/FT_Naming_Serv.mpc
@@ -0,0 +1,42 @@
+// -*- MPC -*-
+// $Id$
+
+project (FT_Naming_Serv) : orbsvcslib, orbsvcs_output, ftnaming, ftnaming_replication, install, naming_serv, naming, portablegroup, avoids_minimum_corba {
+ sharedname = TAO_FT_Naming_Serv
+ idlflags += -Wb,export_macro=TAO_FtNaming_Export -Wb,export_include=orbsvcs/Naming/FaultTolerant/ftnaming_export.h
+ dynamicflags += TAO_FTNAMING_BUILD_DLL
+ tagchecks += FaultTolerantNaming
+
+ IDL_Files {
+ }
+
+ Source_Files (ORBSVCS_COMPONENTS) {
+ Naming/FaultTolerant/FT_Naming_Manager.cpp
+ Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp
+ Naming/FaultTolerant/FT_Naming_Server.cpp
+ Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp
+ Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp
+ Naming/FaultTolerant/FT_Round_Robin.cpp
+ Naming/FaultTolerant/FT_Storable_Naming_Context.cpp
+ Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp
+ Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp
+ Naming/FaultTolerant/FT_PG_Group_Factory.cpp
+ }
+
+ Header_Files {
+ Naming/FaultTolerant/FT_Naming_Manager.h
+ Naming/FaultTolerant/FT_Naming_Replication_Manager.h
+ Naming/FaultTolerant/FT_Naming_Server.h
+ Naming/FaultTolerant/FT_Persistent_Naming_Context.h
+ Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h
+ Naming/FaultTolerant/FT_Round_Robin.h
+ Naming/FaultTolerant/FT_Storable_Naming_Context.h
+ Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h
+ Naming/FaultTolerant/FT_PG_Object_Group_Storable.h
+ Naming/FaultTolerant/FT_PG_Group_Factory.h
+ Naming/FaultTolerant/ftnaming_export.h
+ Naming/FaultTolerant/ftnaming_intf_export.h
+ }
+
+}
+
diff --git a/TAO/orbsvcs/orbsvcs/FtNaming.mpc b/TAO/orbsvcs/orbsvcs/FtNaming.mpc
new file mode 100644
index 00000000000..c36764fa984
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/FtNaming.mpc
@@ -0,0 +1,28 @@
+// -*- MPC -*-
+// $Id$
+
+project (FtNaming) : orbsvcslib, orbsvcs_output, install, naming_serv, portablegroup, avoids_minimum_corba {
+ sharedname = TAO_FtNaming
+ idlflags += -Wb,export_macro=TAO_FtNaming_Intf_Export \
+ -Wb,export_include=orbsvcs/Naming/FaultTolerant/ftnaming_intf_export.h
+ dynamicflags += TAO_FTNAMING_INTF_BUILD_DLL
+ tagchecks += FtNaming
+
+ IDL_Files {
+ idlflags += -GC
+ FT_NamingManager.idl
+ }
+
+ Source_Files (ORBSVCS_COMPONENTS) {
+ FT_NamingManagerC.cpp
+ FT_NamingManagerS.cpp
+ Naming/FaultTolerant/nsgroup_svc.cpp
+ }
+
+ Header_Files {
+ FT_NamingManagerC.h
+ FT_NamingManagerS.h
+ Naming/FaultTolerant/nsgroup_svc.h
+ }
+}
+
diff --git a/TAO/orbsvcs/orbsvcs/FtNamingReplication.mpc b/TAO/orbsvcs/orbsvcs/FtNamingReplication.mpc
new file mode 100644
index 00000000000..cb329f671ca
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/FtNamingReplication.mpc
@@ -0,0 +1,25 @@
+// -*- MPC -*-
+// $Id$
+
+project (FtNamingReplication) : ftnaming, orbsvcslib, orbsvcs_output, install, naming_serv, portablegroup, avoids_minimum_corba {
+ sharedname = TAO_FtNamingReplication
+ idlflags += -Wb,export_macro=TAO_FtNaming_Export -Wb,export_include=orbsvcs/Naming/FaultTolerant/ftnaming_export.h
+ dynamicflags += TAO_FTNAMING_BUILD_DLL
+
+ IDL_Files {
+ idlflags += -GC
+ FT_NamingReplication.idl
+ }
+
+ Source_Files (ORBSVCS_COMPONENTS) {
+ FT_NamingReplicationC.cpp
+ FT_NamingReplicationS.cpp
+ }
+
+ Header_Files {
+ FT_NamingReplicationC.h
+ FT_NamingReplicationS.h
+ }
+
+}
+
diff --git a/TAO/orbsvcs/orbsvcs/FtRtEvent/Utils/FTEC_Gateway.cpp b/TAO/orbsvcs/orbsvcs/FtRtEvent/Utils/FTEC_Gateway.cpp
index f6592820c0f..18e2bb69a54 100644
--- a/TAO/orbsvcs/orbsvcs/FtRtEvent/Utils/FTEC_Gateway.cpp
+++ b/TAO/orbsvcs/orbsvcs/FtRtEvent/Utils/FTEC_Gateway.cpp
@@ -242,7 +242,7 @@ void FTEC_Gateway::remove_observer (RtecEventChannelAdmin::Observer_Handle handl
void FTEC_Gateway::push(RtecEventChannelAdmin::ProxyPushConsumer_ptr proxy_consumer,
const RtecEventComm::EventSet & data)
{
- PortableServer::ObjectId_var object_id =
+ const PortableServer::ObjectId_var object_id =
impl_->poa->reference_to_id(proxy_consumer);
FtRtecEventComm::ObjectId** result;
ACE_OS::memcpy(&result, &object_id[0], sizeof(FtRtecEventComm::ObjectId**));
@@ -315,9 +315,9 @@ get_remote_oid_ptr(CORBA::ORB_ptr orb)
{
PortableServer::Current_var current =
resolve_init<PortableServer::Current>(orb,
- "POACurrent");
+ "POACurrent");
- PortableServer::ObjectId_var object_id =
+ const PortableServer::ObjectId_var object_id =
current->get_object_id();
FtRtecEventComm::ObjectId** result;
diff --git a/TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.cpp b/TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.cpp
index b69a58ea11e..cb65c9c3a69 100644
--- a/TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.cpp
+++ b/TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.cpp
@@ -279,7 +279,7 @@ TAO::HTIOP::Profile::add_endpoint (TAO::HTIOP::Endpoint *endp)
}
char *
-TAO::HTIOP::Profile::to_string (void)
+TAO::HTIOP::Profile::to_string (void) const
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
diff --git a/TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.h b/TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.h
index ef0dc3fa9dc..f292660153d 100644
--- a/TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.h
+++ b/TAO/orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.h
@@ -88,7 +88,7 @@ namespace TAO
* This is used to create url-style reference. Only one
* endpoint is included into the string.
*/
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
/**
* Endpoints are transmitted using TAO-proprietory tagged component.
diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp
index b14c5612c23..0ba928de2fe 100644
--- a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp
+++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp
@@ -155,7 +155,7 @@ TAO_LB_LeastLoaded::get_loads (CosLoadBalancing::LoadManager_ptr load_manager,
this->push_loads (the_location,
loads.in (),
- loads[0]);
+ loads.inout ()[0]);
return loads._retn ();
}
diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadAverage.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadAverage.cpp
index 56b5157d4a7..463f4c3da83 100644
--- a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadAverage.cpp
+++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadAverage.cpp
@@ -153,7 +153,7 @@ TAO_LB_LoadAverage::get_loads (CosLoadBalancing::LoadManager_ptr load_manager,
this->push_loads (the_location,
loads.in (),
- loads[0]);
+ loads.inout ()[0]);
return loads._retn ();
}
diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMinimum.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMinimum.cpp
index 90dd6c015e4..6f2e8a65abf 100644
--- a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMinimum.cpp
+++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_LoadMinimum.cpp
@@ -154,7 +154,7 @@ TAO_LB_LoadMinimum::get_loads (CosLoadBalancing::LoadManager_ptr load_manager,
this->push_loads (the_location,
loads.in (),
- loads[0]);
+ loads.inout ()[0]);
return loads._retn ();
}
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Location_Index_Map.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Location_Index_Map.h
new file mode 100644
index 00000000000..fa1fe4e3cee
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Location_Index_Map.h
@@ -0,0 +1,42 @@
+// -*- C++ -*-
+
+//=======================================================================
+/**
+ * @file FT_Location_Index_Map.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=======================================================================
+
+
+#ifndef TAO_FT_LOCATION_INDEX_MAP_H
+#define TAO_FT_LOCATION_INDEX_MAP_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/PortableGroupC.h"
+
+#include "ace/Functor.h"
+#include "ace/Hash_Map_Manager_T.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/// Location index map.
+typedef ACE_Hash_Map_Manager_Ex<
+ PortableGroup::ObjectGroupId,
+ CORBA::ULong,
+ ACE_Hash<ACE_UINT64>,
+ ACE_Equal_To<ACE_UINT64>,
+ ACE_Null_Mutex> TAO_FT_Location_Index_Map;
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_FT_LOCATION_INDEX_MAP_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp
new file mode 100644
index 00000000000..011f25b2190
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp
@@ -0,0 +1,747 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Naming_Manager.cpp
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h"
+#include "orbsvcs/FT_NamingManagerC.h"
+#include "orbsvcs/PortableGroup/PG_Property_Utils.h"
+#include "orbsvcs/PortableGroup/PG_Property_Set.h"
+#include "orbsvcs/PortableGroup/PG_Object_Group.h"
+#include "orbsvcs/PortableGroup/PG_conf.h"
+#include "orbsvcs/PortableGroup/PG_Utils.h"
+
+#include "tao/debug.h"
+#include "tao/ORB_Constants.h"
+
+#include "ace/SString.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_string.h"
+
+// Use this macro at the beginning of CORBA methods
+// to aid in debugging.
+#define METHOD_ENTRY(name) \
+ if (TAO_debug_level > 6) \
+ { \
+ ACE_DEBUG (( LM_DEBUG, \
+ "Enter %s\n", #name \
+ )); \
+ }
+
+// Use this macro to return from CORBA methods
+// to aid in debugging. Note that you can specify
+// the return value after the macro, for example:
+// METHOD_RETURN(Plugh::plover) xyzzy; is equivalent
+// to return xyzzy;
+// METHOD_RETURN(Plugh::troll); is equivalent to
+// return;
+// WARNING: THIS GENERATES TWO STATEMENTS!!! THE FOLLOWING
+// will not do what you want it to:
+// if (cave_is_closing) METHOD_RETURN(Plugh::pirate) aarrggh;
+// Moral: Always use braces.
+#define METHOD_RETURN(name) \
+ if (TAO_debug_level > 6) \
+ { \
+ ACE_DEBUG (( LM_DEBUG, \
+ "Leave %s\n", #name \
+ )); \
+ } \
+ return /* value goes here */
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_FT_Naming_Manager::TAO_FT_Naming_Manager (void)
+ : factory_registry_ ("NamingManager::FactoryRegistry"),
+ group_factory_ (),
+ built_in_balancing_strategy_name_ (1),
+ object_group_property_name_ (1)
+
+{
+ // The name for the property which contains the load balancing strategy value
+ this->built_in_balancing_strategy_name_.length (1);
+ this->built_in_balancing_strategy_name_[0].id =
+ FT_Naming::TAO_FT_LOAD_BALANCING_STRATEGY;
+
+ // The name for the property which contains the object group name
+ this->object_group_property_name_.length (1);
+ this->object_group_property_name_[0].id =
+ FT_Naming::TAO_FT_OBJECT_GROUP_NAME;
+}
+
+TAO_FT_Naming_Manager::~TAO_FT_Naming_Manager (void)
+{
+ this->object_group_property_name_.length (0);
+ this->built_in_balancing_strategy_name_.length (0);
+}
+
+
+CORBA::Object_ptr
+TAO_FT_Naming_Manager::create_object_group (
+ const char * group_name,
+ FT_Naming::LoadBalancingStrategyValue lb_strategy,
+ const ::PortableGroup::Criteria & the_criteria)
+{
+ // The when creating the object group, it starts as a generic
+ // CORBA Object. It will become the type of the first added
+ // member.
+ const char * type_id = ACE_TEXT ("IDL:omg.org:CORBA/Object:1.0");
+
+ // Add the group name to the criteria and create the object
+ TAO::PG_Property_Set property_set (the_criteria);
+ PortableGroup::Value value;
+ value <<= group_name;
+ property_set.set_property (FT_Naming::TAO_FT_OBJECT_GROUP_NAME, value);
+
+ // Add the load balancing strategy to the properties
+ value <<= lb_strategy;
+ property_set.set_property (FT_Naming::TAO_FT_LOAD_BALANCING_STRATEGY, value);
+
+ PortableGroup::Criteria new_criteria;
+ property_set.export_properties (new_criteria);
+ PortableGroup::GenericFactory::FactoryCreationId_var fcid;
+
+ return this->create_object (group_name, type_id, new_criteria, fcid.out());
+}
+
+void
+TAO_FT_Naming_Manager::delete_object_group (const char * group_name)
+{
+ // Find the object group with the specified name and delete the object
+ PortableGroup::ObjectGroup_var group =
+ this->get_object_group_ref_from_name (group_name);
+
+ if (!CORBA::is_nil (group.in()))
+ {
+ PortableGroup::ObjectGroupId group_id =
+ this->get_object_group_id (group);
+
+ // Delete the object group from the factory
+ this->group_factory_.delete_group (group_id);
+ }
+ else
+ {
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+
+}
+
+PortableGroup::ObjectGroup_ptr
+TAO_FT_Naming_Manager::get_object_group_ref_from_name (const char * group_name)
+{
+ TAO::PG_Object_Group* group;
+ if (this->group_factory_.find_group_with_name (group_name, group))
+ {
+ return group->reference ();
+ }
+ else
+ {
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+}
+
+::FT_Naming::GroupNames *
+TAO_FT_Naming_Manager::groups (::FT_Naming::LoadBalancingStrategyValue target_strategy)
+{
+ PortableGroup::ObjectGroups_var all_groups = this->group_factory_.all_groups ();
+ int num_groups = all_groups->length ();
+
+ FT_Naming::GroupNames* group_names;
+ ACE_NEW_THROW_EX (
+ group_names,
+ FT_Naming::GroupNames (num_groups),
+ CORBA::NO_MEMORY());
+
+ int matching_groups = 0;
+ for (int i = 0; i < num_groups; ++i)
+ {
+ PortableGroup::ObjectGroup_var obj_group = (all_groups.in ())[i].in ();
+
+ // Extract the group's Load Balancing property
+ PortableGroup::Name lb_strat_property_name (1);
+ lb_strat_property_name.length (1);
+ lb_strat_property_name[0].id = CORBA::string_dup (::FT_Naming::TAO_FT_LOAD_BALANCING_STRATEGY);
+ PortableGroup::Properties_var props = this->get_properties (obj_group);
+ PortableGroup::Value value;
+ TAO_PG::get_property_value (lb_strat_property_name, props.in (), value);
+ ::FT_Naming::LoadBalancingStrategyValue lb_strategy_val;
+ value >>= lb_strategy_val;
+
+ if (lb_strategy_val == target_strategy)
+ { // Groups load balancing strategy matches the target
+ // Increment the count of matching groups
+ ++matching_groups;
+ char* name;
+
+ // Get the group name and add it to the list to return.
+ if (this->group_name (obj_group.in (), name))
+ { // Group does have a name
+ group_names->length (matching_groups);
+ (*group_names)[matching_groups-1] = name;
+ }
+ else
+ {
+ { // Group has no name
+ (*group_names)[i] = CORBA::string_dup ("<unnamed group>");
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - FT_Naming_Manager::groups: no name ")
+ ACE_TEXT ("property set on group.\n")
+ ));
+ }
+ }
+ }
+ }
+ // Set the length to the actual num added
+ group_names->length (matching_groups);
+ return group_names;
+}
+
+void
+TAO_FT_Naming_Manager::set_load_balancing_strategy (
+ const char * group_name,
+ ::FT_Naming::LoadBalancingStrategyValue lb_strategy)
+{
+ CORBA::Object_var group = this->get_object_group_ref_from_name (group_name);
+
+ TAO::PG_Property_Set property_set;
+ PortableGroup::Value value;
+ // Add the load balancing strategy to the properties
+ value <<= lb_strategy;
+ property_set.set_property (FT_Naming::TAO_FT_LOAD_BALANCING_STRATEGY, value);
+ PortableGroup::Properties properties;
+ property_set.export_properties (properties);
+ this->set_properties_dynamically (group, properties);
+}
+
+
+bool
+TAO_FT_Naming_Manager::group_name (PortableGroup::ObjectGroup_ptr group,
+ char*& name)
+{
+ if (CORBA::is_nil (group))
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - FT_Naming_Manager::group_name: ")
+ ACE_TEXT ("cannot get name for a null object.\n")
+ ));
+ return false;
+ }
+
+ TAO::PG_Object_Group* pg_group;
+ if (this->group_factory_.find_group (group, pg_group))
+ { // Found the object group in the factory
+ const char* grp_name = pg_group->get_name ();
+ if (grp_name != 0)
+ { // Valid group name defined
+ name = CORBA::string_dup (grp_name);
+ return true;
+ }
+ else
+ { // The group has no name
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO_FT_Naming_Manager::group_name - ")
+ ACE_TEXT ("object group does not have a name")),
+ false);
+ }
+ }
+ else
+ { // The factory does not know about the group
+ return false;
+ }
+}
+
+void
+TAO_FT_Naming_Manager::set_default_properties (
+ const PortableGroup::Properties & props)
+{
+
+ this->properties_support_.set_default_properties (props);
+ //@@ validate properties?
+}
+
+PortableGroup::Properties *
+TAO_FT_Naming_Manager::get_default_properties ()
+{
+ return this->properties_support_.get_default_properties ();
+}
+
+void
+TAO_FT_Naming_Manager::remove_default_properties (
+ const PortableGroup::Properties & props)
+{
+ this->properties_support_.remove_default_properties (props);
+}
+
+void
+TAO_FT_Naming_Manager::set_type_properties (
+ const char *type_id,
+ const PortableGroup::Properties & overrides)
+{
+ this->properties_support_.set_type_properties (
+ type_id,
+ overrides);
+}
+
+PortableGroup::Properties *
+TAO_FT_Naming_Manager::get_type_properties (
+ const char *type_id)
+{
+ return this->properties_support_.get_type_properties (type_id);
+}
+
+void
+TAO_FT_Naming_Manager::remove_type_properties (
+ const char *type_id,
+ const PortableGroup::Properties & props)
+{
+ this->properties_support_.remove_type_properties (
+ type_id,
+ props);
+}
+
+void
+TAO_FT_Naming_Manager::set_properties_dynamically (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Properties & overrides)
+{
+
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (object_group, group))
+ {
+ group->set_properties_dynamically (overrides);
+ }
+ else
+ {
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+}
+
+PortableGroup::Properties *
+TAO_FT_Naming_Manager::get_properties (
+ PortableGroup::ObjectGroup_ptr object_group)
+{
+ PortableGroup::Properties_var result;
+ ACE_NEW_THROW_EX (result, PortableGroup::Properties(), CORBA::NO_MEMORY ());
+
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (object_group, group))
+ {
+ group->get_properties (result);
+ }
+ else
+ {
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+ return result._retn();
+}
+
+PortableGroup::ObjectGroup_ptr
+TAO_FT_Naming_Manager::create_member (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Location & the_location,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria)
+{
+ PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil();
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (object_group, group))
+ {
+ group->create_member (the_location, type_id, the_criteria);
+ result = group->reference ();
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ( (LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - FT_Naming_Manager::create_member: ")
+ ACE_TEXT ("unknown group\n")
+ ));
+ }
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+ return result._retn();
+}
+
+PortableGroup::ObjectGroup_ptr
+TAO_FT_Naming_Manager::add_member (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Location & the_location,
+ CORBA::Object_ptr member)
+{
+ METHOD_ENTRY (TAO::FT_Naming_Manager::add_member);
+ PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil ();
+
+ // Find the object group corresponding to this IOGR
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (object_group, group))
+ {
+ try {
+
+ group->add_member (the_location,
+ member);
+ }
+ catch (...)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_FT_Naming_Manager::add_member - ")
+ ACE_TEXT ("Issue with IOR of group or member.\n")));
+ throw PortableGroup::ObjectNotAdded ();
+ }
+
+ result = group->reference ();
+
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ( (LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - FT_Naming_Manager::add_member ")
+ ACE_TEXT ("to unknown group\n")
+ ));
+ }
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+ METHOD_RETURN (TAO::FT_Naming_Manager::add_member) result._retn ();
+}
+
+
+PortableGroup::ObjectGroup_ptr
+TAO_FT_Naming_Manager::remove_member (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Location & the_location)
+{
+ PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil ();
+
+ // Find the object group corresponding to this IOGR
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (object_group, group))
+ {
+ group->remove_member (the_location);
+
+ group->minimum_populate ();
+ //@@ how about the case where the member was removed successfully,
+ // but for one reason or another we were unable to bring the group
+ // back up to minimum_number_of_replicas?
+
+ result = group->reference ();
+ }
+ else
+ {
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+ return result._retn ();
+}
+
+
+PortableGroup::Locations *
+TAO_FT_Naming_Manager::locations_of_members (
+ PortableGroup::ObjectGroup_ptr object_group)
+{
+ PortableGroup::Locations_var result = 0;
+
+ // Find the object group corresponding to this IOGR
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (object_group, group))
+ {
+ result = group->locations_of_members ();
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ( (LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - FT_Naming_Manager::")
+ ACE_TEXT ("locations_of_members: unknown group\n")
+ ));
+ }
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+ return result._retn ();
+}
+
+PortableGroup::ObjectGroups *
+TAO_FT_Naming_Manager::groups_at_location (
+ const PortableGroup::Location & the_location)
+{
+ return this->group_factory_.groups_at_location (the_location);
+}
+
+PortableGroup::ObjectGroupId
+TAO_FT_Naming_Manager::get_object_group_id (
+ PortableGroup::ObjectGroup_ptr object_group)
+{
+ PortableGroup::ObjectGroupId result = 0;
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (object_group, group))
+ {
+ group->get_object_group_id ();
+ result = group->get_object_group_id ();
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ( (LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - FT_Naming_Manager::")
+ ACE_TEXT ("get_object_group_id: unknown group\n")
+ ));
+ }
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+ return result;
+}
+
+PortableGroup::ObjectGroup_ptr
+TAO_FT_Naming_Manager::get_object_group_ref (
+ PortableGroup::ObjectGroup_ptr object_group)
+{
+ PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil ();
+
+ // Find the object group corresponding to this IOGR
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (object_group, group))
+ {
+ result = group->reference ();
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ( (LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - FT_Naming_Manager::")
+ ACE_TEXT ("get_object_group_ref: unknown group\n")
+ ));
+ }
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+ return result._retn();
+}
+
+PortableGroup::ObjectGroup_ptr TAO_FT_Naming_Manager::get_object_group_ref_from_id (
+ PortableGroup::ObjectGroupId group_id)
+{
+ PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil ();
+
+ // Find the object group corresponding to this IOGR
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (group_id, group))
+ {
+ result = group->reference ();
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ( (LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - FT_Naming_Manager::")
+ ACE_TEXT ("get_object_group_ref_from_id: unknown group\n")
+ ));
+ }
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+ return result._retn();
+}
+
+CORBA::Object_ptr
+TAO_FT_Naming_Manager::get_member_ref (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Location & the_location)
+{
+ CORBA::Object_var result = CORBA::Object::_nil();
+
+ // Find the object group corresponding to this IOGR
+ TAO::PG_Object_Group * group = 0;
+ if (this->group_factory_.find_group (object_group, group))
+ {
+ result = group->get_member_reference (the_location);
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ( (LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - FT_Naming_Manager::")
+ ACE_TEXT ("get_member_ref: unknown group\n")
+ ));
+ }
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+ return result._retn();
+}
+
+CORBA::Object_ptr
+TAO_FT_Naming_Manager::create_object (
+ const char * object_name,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ PortableGroup::GenericFactory::FactoryCreationId_out
+ factory_creation_id)
+{
+ METHOD_ENTRY (TAO::FT_Naming_Manager::create_object);
+
+ ////////////////////////////////
+ // find the properties for this
+ // type of object group
+ ACE_Auto_Ptr<TAO::PG_Property_Set> typeid_properties
+ (this->properties_support_.find_typeid_properties (type_id));
+
+ TAO::PG_Object_Group * group
+ = this->group_factory_.create_group (
+ type_id,
+ the_criteria,
+ typeid_properties.get ());
+
+ // The group now owns the properties.
+ typeid_properties.release ();
+
+ group->set_name (object_name);
+
+ // Dont distribute the object group for its usage in the FT_Naming_Manager
+ group->distribute (0);
+
+ group->initial_populate ();
+ //@@ on error we should remove the group from the Group_Factory
+ // doing this "right" will require a var-type pointer to the object group
+ // that knows about the factory, too.
+
+ // Allocate a new FactoryCreationId for use as an "out" parameter.
+ PortableGroup::GenericFactory::FactoryCreationId_ptr factory_id_ptr = 0;
+ ACE_NEW_THROW_EX (factory_id_ptr,
+ PortableGroup::GenericFactory::FactoryCreationId,
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+ PortableGroup::GenericFactory::FactoryCreationId_var factory_id = factory_id_ptr;
+ PortableGroup::ObjectGroupId group_id = group->get_object_group_id ();
+ factory_id <<= group_id;
+ factory_creation_id = factory_id._retn();
+
+ METHOD_RETURN (TAO::FT_Naming_Manager::create_object) group->reference ();
+}
+
+void
+TAO_FT_Naming_Manager::delete_object (
+ const PortableGroup::GenericFactory::FactoryCreationId &
+ factory_creation_id)
+{
+
+ PortableGroup::ObjectGroupId group_id = 0;
+ if (factory_creation_id >>= group_id)
+ {
+ this->group_factory_.delete_group (
+ group_id);
+ }
+ else
+ {
+ throw PortableGroup::ObjectNotFound ();
+ }
+}
+
+void
+TAO_FT_Naming_Manager::initialize (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr naming_mgr_poa)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX,
+ guard,
+ this->lock_);
+
+ // Initialize the components used to implement the PortableGroup interfaces
+ this->factory_registry_.init (orb);
+ PortableGroup::FactoryRegistry_var factory_ref =
+ factory_registry_.reference ();
+ this->group_factory_.init (orb,
+ naming_mgr_poa,
+ factory_ref.in ());
+}
+
+CORBA::Object_ptr
+TAO_FT_Naming_Manager::next_member (PortableGroup::ObjectGroup_ptr object_group)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ monitor,
+ this->lock_,
+ CORBA::Object::_nil ()
+ );
+
+ ACE_Auto_Ptr<PortableGroup::Properties> props (
+ this->get_properties (object_group));
+ PortableGroup::Value value;
+ CORBA::Boolean found =
+ TAO_PG::get_property_value (built_in_balancing_strategy_name_,
+ *(props.get ()),
+ value);
+
+ // If there is no TAO_FT_LOAD_BALANCING_STRATEGY property in the object group
+ // return failure
+ if (!found)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - TAO_FT_Naming_Manager::next_member: ")
+ ACE_TEXT ("object group has no TAO_FT_LOAD_BALANCING_STRATEGY ")
+ ACE_TEXT ("property.\n")
+ ));
+
+ return CORBA::Object::_nil();
+ }
+
+ // Extract the load balancing strategy value
+ FT_Naming::LoadBalancingStrategyValue load_bal_strategy;
+ value >>= load_bal_strategy;
+
+ PortableGroup::Location next_location;
+
+ bool result = false;
+
+ switch (load_bal_strategy)
+ {
+ case FT_Naming::ROUND_ROBIN:
+ result = this->round_robin_.next_location (object_group, this, next_location);
+ break;
+ default:
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - TAO_FT_Naming_Manager::next_location: ")
+ ACE_TEXT ("unsupported load balancing strategy requested.\n")
+ ));
+
+ return CORBA::Object::_nil();
+ break;
+ }
+
+ if (result == true)
+ return this->get_member_ref (object_group, next_location);
+ else
+ return CORBA::Object::_nil();
+}
+
+
+void
+TAO_FT_Naming_Manager::preprocess_properties (PortableGroup::Properties &)
+{
+ // Nothing to do here for now.
+}
+
+void
+TAO_FT_Naming_Manager::set_object_group_storable_factory (TAO::Storable_Factory * factory)
+{
+ this->group_factory_.set_object_group_storable_factory (factory);
+}
+
+void
+TAO_FT_Naming_Manager::set_object_group_stale (const FT_Naming::ObjectGroupUpdate & group_info)
+{
+ this->group_factory_.set_object_group_stale (group_info);
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h
new file mode 100644
index 00000000000..97193b9d9fe
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h
@@ -0,0 +1,351 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Naming_Manager.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_FT_NAMING_MANAGER_H
+#define TAO_FT_NAMING_MANAGER_H
+
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+
+#include "orbsvcs/FT_NamingManagerS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/FT_NamingManagerC.h"
+
+#include "orbsvcs/PortableGroup/PG_FactoryRegistry.h"
+#include "orbsvcs/PortableGroup/PG_Properties_Support.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h"
+
+#include "ace/Task.h"
+#include "tao/Condition.h"
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ class Storable_Factory;
+}
+
+namespace FT_Naming
+{
+ struct ObjectGroupUpdate;
+}
+
+/**
+ * @class TAO_FT_Naming_Manager
+ * @brief Implements the NamingManager interface for the Fault
+ * tolerant naming service.
+ *
+ * This class implements the NamingManager interface in support
+ * of the load balancing features of the FaultTolerant Naming
+ * Service. Uses can create and manage object groups which can be
+ * bound in the Naming Service, which will provide the load balancing
+ * functionality.
+ */
+class TAO_FtNaming_Export TAO_FT_Naming_Manager
+ : public virtual POA_FT_Naming::NamingManager,
+ public ACE_Task_Base
+{
+public:
+
+ /// Constructor.
+ TAO_FT_Naming_Manager (void);
+
+ /**
+ * @name FT::NamingManager Methods
+ *
+ *
+ */
+
+ /// Creates an object group with the specified name and load
+ /// balancing strategy.
+ /// @param[in] group_name The symbolic name of the group that can
+ /// be used to refer to the group in other operations.
+ /// @param[in] lb_strategy The strategy to be used by the Naming
+ /// Service when this object group is resolved.
+ ///@param[in] the_criteria Properties to be used by the object group.
+ virtual PortableGroup::ObjectGroup_ptr create_object_group (
+ const char * group_name,
+ FT_Naming::LoadBalancingStrategyValue lb_strategy,
+ const ::PortableGroup::Criteria & the_criteria);
+
+ /// Deletes the object group with the provided group_name.
+ virtual void delete_object_group (
+ const char * group_name);
+
+ /// Retreives a reference to a group with the specified name
+ virtual PortableGroup::ObjectGroup_ptr get_object_group_ref_from_name (
+ const char * group_name);
+
+ /// Provide a new load balancing strategy for the group with the provided
+ /// name.
+ virtual void set_load_balancing_strategy (
+ const char * group_name,
+ FT_Naming::LoadBalancingStrategyValue lb_strategy);
+
+ /// Retreive the names of the groups with the specified load balanacing
+ /// strategy that have been created in this Naming Manager.
+ virtual FT_Naming::GroupNames * groups (
+ ::FT_Naming::LoadBalancingStrategyValue target_strategy);
+
+ /**
+ * @name PortableGroup::PropertyManager Methods
+ *
+ * Methods required by the PortableGroup::PropertyManager interface.
+ */
+ //@{
+
+ /// Set the default properties to be used by all object groups.
+ virtual void set_default_properties (
+ const PortableGroup::Properties & props);
+
+ /// Get the default properties used by all object groups.
+ virtual PortableGroup::Properties * get_default_properties ();
+
+ /// Remove default properties.
+ virtual void remove_default_properties (
+ const PortableGroup::Properties & props);
+
+ /// Set properties associated with a given Replica type. These
+ /// properties override the default properties.
+ virtual void set_type_properties (
+ const char * type_id,
+ const PortableGroup::Properties & overrides);
+
+ /**
+ * Return the properties associated with a give Replica type. These
+ * properties include the type-specific properties in use, in
+ * addition to the default properties that were not overridden.
+ */
+ virtual PortableGroup::Properties * get_type_properties (
+ const char * type_id);
+
+ /// Remove the given properties associated with the Replica type ID.
+ virtual void remove_type_properties (
+ const char * type_id,
+ const PortableGroup::Properties & props);
+
+ /**
+ * Dynamically set the properties associated with a given object
+ * group as the load balancer and replicas are being executed.
+ * These properties override the type-specific and default
+ * properties.
+ */
+ virtual void set_properties_dynamically (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Properties & overrides);
+
+ /**
+ * Return the properties currently in use by the given object
+ * group. These properties include those that were set dynamically,
+ * type-specific properties that weren't overridden, properties that
+ * were used when the Replica was created, and default properties
+ * that weren't overridden.
+ */
+ virtual PortableGroup::Properties * get_properties (
+ PortableGroup::ObjectGroup_ptr object_group);
+
+ //@}
+
+ /**
+ * @name PortableGroup::ObjectGroupManager methods
+ *
+ * Methods required by the PortableGroup::ObjectGroupManager
+ * interface.
+ */
+ //@{
+
+ /// Create a member using the load balancer ObjectGroupManager, and
+ /// add the created object to the ObjectGroup.
+ virtual PortableGroup::ObjectGroup_ptr create_member (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Location & the_location,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria);
+
+ /// Add an existing object to the ObjectGroup.
+ /// @param[in] object_group A reference for the group to which the
+ /// specified member is to be added.
+ /// @param[in] the_location The symbolic value that specifies this
+ /// specific member. The location can be any string value.
+ /// @param[in] member The object reference for the member. The first
+ /// member's type is used to defined the object group type. All subsequence
+ /// members must have the same type.
+ virtual PortableGroup::ObjectGroup_ptr add_member (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Location & the_location,
+ CORBA::Object_ptr member);
+
+ /**
+ * Remove an object at a specific location from the given
+ * ObjectGroup. Deletion of application created objects must be
+ * deleted by the application. Objects created by the
+ * infrastructure (load balancer) will be deleted by the
+ * infrastructure.
+ */
+ virtual PortableGroup::ObjectGroup_ptr remove_member (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Location & the_location);
+
+ /// Return the locations of the members in the given ObjectGroup.
+ virtual PortableGroup::Locations * locations_of_members (
+ PortableGroup::ObjectGroup_ptr object_group);
+
+ /// Return the locations of the members in the given ObjectGroup.
+ virtual PortableGroup::ObjectGroups * groups_at_location (
+ const PortableGroup::Location & the_location);
+
+ /// Return the ObjectGroupId for the given ObjectGroup.
+ virtual PortableGroup::ObjectGroupId get_object_group_id (
+ PortableGroup::ObjectGroup_ptr object_group);
+
+ /// TAO specific method
+ virtual PortableGroup::ObjectGroup_ptr get_object_group_ref_from_id (
+ PortableGroup::ObjectGroupId group_id);
+
+ /// Return the reference corresponding to the Replica of a given
+ /// ObjectGroup at the given location.
+ virtual CORBA::Object_ptr get_member_ref (
+ PortableGroup::ObjectGroup_ptr object_group,
+ const PortableGroup::Location & loc);
+
+ //@}
+
+ /**
+ * @name PortableGroup::GenericFactory methods
+ *
+ * Methods required by the PortableGroup::GenericFactory interface.
+ */
+ //@{
+
+ /**
+ * Create an object of the specified type that adheres to the
+ * restrictions defined by the provided Criteria. The out
+ * FactoryCreationId parameter may be passed to the delete_object()
+ * method to delete the object. This signature is modified from
+ * the generic factory operation to support the use of an object
+ * name in addition to the factory_creation_id.
+ */
+ virtual CORBA::Object_ptr create_object (
+ const char * object_name,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ PortableGroup::GenericFactory::FactoryCreationId_out
+ factory_creation_id);
+
+ /**
+ * Delete the object corresponding to the provided
+ * FactoryCreationId. If the object is actually an ObjectGroup,
+ * then all members within the ObjectGroup will be deleted.
+ * Afterward, the ObjectGroup itself will be deleted.
+ */
+ virtual void delete_object (
+ const PortableGroup::GenericFactory::FactoryCreationId &
+ factory_creation_id);
+
+ //@}
+
+ /// Initialize the naming manager. This will provide the poa to
+ /// the naming manager and underlying components for use in
+ /// managing the object groups.
+ void initialize (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr root_poa);
+
+
+ /// Utilizing the load balancing strategy identified by the object
+ /// group property, return the next object reference from the object
+ /// group which should be used to service the next CORBA request
+ CORBA::Object_ptr next_member (PortableGroup::ObjectGroup_ptr object_group);
+
+ /// Load/save state of object groups from/to file for fault
+ /// tolerant purposes.
+ void
+ set_object_group_storable_factory (TAO::Storable_Factory *
+ factory);
+
+ /// Indicate the object group state is stale.
+ /// Only valid when object group persistence is enabled.
+ void set_object_group_stale (const FT_Naming::ObjectGroupUpdate & group_info);
+
+ /// Destructor.
+ ~TAO_FT_Naming_Manager (void);
+
+private:
+ /// A utility to ensure we can access the latest object reference for
+ /// the object group when referenced externally.
+ virtual PortableGroup::ObjectGroup_ptr get_object_group_ref (
+ PortableGroup::ObjectGroup_ptr object_group);
+
+ /// TAO specific method /// Preprocess Strategy or CustomStrategy properties.
+ /**
+ * This method takes care of converting StrategyInfo properties to
+ * Strategy properties, and verifying that CustomStrategy references
+ * are not nil.
+ */
+ void preprocess_properties (PortableGroup::Properties & props);
+
+ /// Utility for accessing the object group name. Returns true if a
+ /// name is found and allocates a string with the name assigned to
+ /// the name parameter.
+ bool group_name (PortableGroup::ObjectGroup_ptr group, char*& name);
+
+ /// Mutex that provides synchronization for the TAO_FT_Naming_Manager's
+ /// state.
+ TAO_SYNCH_MUTEX lock_;
+
+ /// an object that manages default and type_id related properties
+ TAO::PG_Properties_Support properties_support_;
+
+ /// Registry used by the PG_Group_Factory
+ TAO::PG_FactoryRegistry factory_registry_;
+
+ /// The group factory responsible for creating object groups
+ TAO::FT_PG_Group_Factory group_factory_;
+
+ /**
+ * @name Built-in load balancing strategy implementations
+ *
+ * "Built-in" load balancing strategies. Currently only RoundRobin
+ * is supported.
+ */
+ //@{
+
+ /// The "RoundRobin" load balancing strategy.
+ TAO_FT_Round_Robin round_robin_;
+ //@}
+
+ /// Cached instance of the Property name
+ /// "org.omg.CosLoadBalancing.Strategy".
+ PortableGroup::Name built_in_balancing_strategy_name_;
+
+ PortableGroup::Name object_group_property_name_;
+
+ TAO_SYNCH_MUTEX validate_lock_;
+ TAO_Condition<TAO_SYNCH_MUTEX> validate_condition_;
+
+ bool shutdown_;
+
+};
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_FT_NAMING_MANAGER_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp
new file mode 100644
index 00000000000..f86ffb96e0f
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp
@@ -0,0 +1,179 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Naming_Replication_Manager.cpp
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h"
+#include "tao/corba.h"
+#include "ace/SStringfwd.h"
+
+FT_Naming::ReplicationManager_var
+TAO_FT_Naming_Replication_Manager::peer_replica_ (0);
+
+TAO_FT_Naming_Replication_Manager::TAO_FT_Naming_Replication_Manager (
+ TAO_FT_Naming_Server *naming_svr,
+ const char* repl_mgr_name)
+ : naming_svr_ (naming_svr),
+ repl_mgr_name_ (repl_mgr_name)
+{
+}
+
+
+TAO_FT_Naming_Replication_Manager::~TAO_FT_Naming_Replication_Manager(void)
+{
+ this->reference_ = FT_Naming::ReplicationManager::_nil ();
+}
+
+void
+TAO_FT_Naming_Replication_Manager::initialize (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr repl_mgr_poa)
+{
+ ACE_UNUSED_ARG (orb);
+ repl_mgr_poa_ = PortableServer::POA::_duplicate (repl_mgr_poa);
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId (this->repl_mgr_name_.c_str ());
+ CORBA::Object_var obj = repl_mgr_poa_->id_to_reference (id.in ());
+ this->reference_ = FT_Naming::ReplicationManager::_narrow (obj.in ());
+}
+
+FT_Naming::ReplicaInfo*
+TAO_FT_Naming_Replication_Manager::register_replica (
+ ::FT_Naming::ReplicationManager_ptr replica,
+ const ::FT_Naming::ReplicaInfo & replica_info)
+{
+ ACE_TRACE ( ACE_TEXT("TAO_FT_Naming_Replication_Manager::register_replica"));
+
+ ACE_GUARD_THROW_EX (ACE_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
+ // Store a copy of the provided reference and other ReplicaInfo
+ peer_replica_ = FT_Naming::ReplicationManager::_duplicate (replica);
+
+ // Store the provided peer references
+ this->naming_svr_->peer_root_context (replica_info.root_context);
+ this->naming_svr_->peer_naming_manager (replica_info.naming_manager);
+
+ // Return my references to the peer
+ FT_Naming::ReplicaInfo* my_info = new FT_Naming::ReplicaInfo;
+
+ my_info->root_context = CosNaming::NamingContext::_duplicate (
+ this->naming_svr_->my_root_context ());
+
+ my_info->naming_manager = FT_Naming::NamingManager::_duplicate (
+ this->naming_svr_->my_naming_manager ());
+
+ return my_info;
+}
+
+void
+TAO_FT_Naming_Replication_Manager::notify_updated_object_group (
+ const FT_Naming::ObjectGroupUpdate & group_info)
+{
+ ACE_TRACE ( ACE_TEXT ("TAO_FT_Naming_Replication_Manager::")
+ ACE_TEXT ("notify_updated_object_group"));
+
+ // Make sure that we have a valid naming server
+ ACE_ASSERT (naming_svr_);
+ int result = this->naming_svr_->update_object_group (group_info);
+
+ if (result != 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Unable to update object group.\n")));
+}
+
+void
+TAO_FT_Naming_Replication_Manager::notify_updated_context (
+ const FT_Naming::NamingContextUpdate & context_info)
+{
+ ACE_TRACE (ACE_TEXT ("TAO_FT_Naming_Replication_Manager::")
+ ACE_TEXT ("notify_updated_context"));
+ ACE_ASSERT (naming_svr_);
+ int result = this->naming_svr_->update_naming_context (context_info);
+
+ if (result != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Error while updating naming context.\n")));
+ }
+}
+
+FT_Naming::ReplicationManager_ptr
+TAO_FT_Naming_Replication_Manager::peer_replica (void)
+{
+ ACE_TRACE (ACE_TEXT ("TAO_FT_Naming_Replication_Manager::peer_replica"));
+ // Return a copy of the stored peer to the requester
+ return FT_Naming::ReplicationManager::_duplicate (peer_replica_.in ());
+}
+
+int
+TAO_FT_Naming_Replication_Manager::register_with_peer_replica (
+ FT_Naming::ReplicationManager_ptr replica,
+ CosNaming::NamingContext_ptr nc,
+ FT_Naming::NamingManager_ptr nm)
+{
+ ACE_TRACE (ACE_TEXT ("TAO_FT_Naming_Replication_Manager::")
+ ACE_TEXT ("register_with_peer_replica"));
+
+ int result = 0;
+ FT_Naming::ReplicaInfo my_info;
+ { // Guard the access to the Replication Manager state
+ ACE_GUARD_THROW_EX (ACE_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
+ // Store a copy of the peer reference for future access
+ this->peer_replica_ =
+ FT_Naming::ReplicationManager::_duplicate (replica);
+
+ my_info.root_context = CosNaming::NamingContext::_duplicate (nc);
+ my_info.naming_manager = FT_Naming::NamingManager::_duplicate (nm);
+ }
+
+ try {
+ FT_Naming::ReplicationManager_var my_ref =
+ this->reference ();
+
+ // Register with the peer replica
+ FT_Naming::ReplicaInfo_var peer_info =
+ this->peer_replica_->register_replica (my_ref.in (),
+ my_info);
+
+ ACE_GUARD_THROW_EX (ACE_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
+ // Store the returned references locally
+ this->naming_svr_->peer_root_context (peer_info->root_context);
+ this->naming_svr_->peer_naming_manager (peer_info->naming_manager);
+ }
+ catch (const CORBA::Exception& ex) {
+ // Unable to contact the peer replica.
+ if (TAO_debug_level > 1)
+ ex._tao_print_exception (
+ ACE_TEXT ("TAO_FT_Naming_Replication_Manager::")
+ ACE_TEXT ("register_with_peer_replica\n"));
+ result = -1;
+ }
+
+ return result;
+
+}
+
+FT_Naming::ReplicationManager_ptr
+TAO_FT_Naming_Replication_Manager::reference (void)
+{
+ ACE_TRACE (ACE_TEXT ("TAO_FT_Naming_Replication_Manager::reference"));
+ return FT_Naming::ReplicationManager::_duplicate (reference_.in ());
+}
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h
new file mode 100644
index 00000000000..8dc9521576e
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h
@@ -0,0 +1,110 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Naming_Replication_Manager.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_FT_NAMING_REPLICATION_MANAGER_H
+#define TAO_FT_NAMING_REPLICATION_MANAGER_H
+
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+#include "orbsvcs/FT_NamingReplicationS.h"
+#include "ace/Recursive_Thread_Mutex.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/FT_NamingReplicationC.h"
+
+class TAO_FT_Naming_Server;
+
+/**
+ * @class TAO_FT_Naming_Replication_Manager
+ * @brief The class that implements the FT_Naming::ReplicationManager
+ * interface.
+ */
+class TAO_FtNaming_Export TAO_FT_Naming_Replication_Manager
+ : public virtual POA_FT_Naming::ReplicationManager
+{
+public:
+
+ /// Create a Replication Manager and provide it with the naming server
+ /// to be updated whenever notified by the peer replica
+ TAO_FT_Naming_Replication_Manager(TAO_FT_Naming_Server *naming_svr,
+ const char* repl_mgr_name);
+
+ virtual ~TAO_FT_Naming_Replication_Manager(void);
+
+ /// Initialize the naming manager. This will provide the poa to
+ /// the naming manager and underlying components for use in
+ /// managing the object groups.
+ void initialize (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr root_poa);
+
+
+ /// Implementation of the FT_Naming::ReplicationManager interface
+ virtual ::FT_Naming::ReplicaInfo * register_replica (
+ ::FT_Naming::ReplicationManager_ptr replica,
+ const ::FT_Naming::ReplicaInfo & replica_info);
+
+ /// This method implements the operation invoked by the peer replica when an
+ /// object group is updated on the remote process.
+ virtual void notify_updated_object_group (
+ const FT_Naming::ObjectGroupUpdate & group_info);
+
+ /// This method implements the operation invoked by the peer replica when an
+ /// naming context is updated on the remote process.
+ virtual void notify_updated_context (
+ const FT_Naming::NamingContextUpdate & group_info);
+
+ /// Retrieve the object reference for the peer naming service
+ /// ReplicationManager.
+ static FT_Naming::ReplicationManager_ptr peer_replica (void);
+
+ /*
+ * Utilities for implementing the FT_Naming::ReplicationManager
+ */
+
+ /// Stores the peer in the peer_replica_ data member and invokes the
+ /// register_replica interface method with the peer. Returns 0 if
+ /// successful and -1 if unable to contact the peer.
+ int register_with_peer_replica (FT_Naming::ReplicationManager_ptr replica,
+ CosNaming::NamingContext_ptr nc,
+ FT_Naming::NamingManager_ptr rm);
+
+ /// The object reference for this servant instance
+ FT_Naming::ReplicationManager_ptr reference (void);
+
+protected:
+
+ // The object which implements the naming service and the object manager
+ TAO_FT_Naming_Server *naming_svr_;
+
+ // Store the reference to the replica object reference
+ // For now only a single replica is supported.
+ static FT_Naming::ReplicationManager_var peer_replica_;
+
+ PortableServer::POA_var repl_mgr_poa_;
+
+ ACE_CString repl_mgr_name_;
+
+ FT_Naming::ReplicationManager_var reference_;
+
+ /// Lock used to serialize access to fault tolerant extensions
+ /// to Naming Service.
+ TAO_SYNCH_MUTEX lock_;
+
+};
+#include /**/ "ace/post.h"
+
+#endif /* TAO_FT_NAMING_REPLICATION_MANAGER_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp
new file mode 100644
index 00000000000..d5eb451e92d
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp
@@ -0,0 +1,1196 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Naming_Server.cpp
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h"
+#include "orbsvcs/Naming/Naming_Server.h"
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h"
+#include "orbsvcs/Naming/Storable.h"
+#include "orbsvcs/Naming/Storable_Naming_Context.h"
+#include "orbsvcs/Naming/Storable_Naming_Context_Activator.h"
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h"
+#include "orbsvcs/Naming/Persistent_Context_Index.h"
+#include "orbsvcs/Naming/Naming_Context_Interface.h"
+
+
+#include "ace/Arg_Shifter.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_unistd.h"
+
+#include "tao/IORTable/IORTable.h"
+#include "tao/ORB_Core.h"
+
+#include "tao/debug.h"
+#include "tao/default_ports.h"
+#include "tao/Storable_FlatFileStream.h"
+
+#include "tao/debug.h"
+#include "tao/default_ports.h"
+
+#include "tao/IORManipulation/IORManip_Loader.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+#include "tao/Messaging/Messaging.h"
+#endif
+
+#include "tao/AnyTypeCode/Any.h"
+
+const ACE_TCHAR*
+TAO_FT_Naming_Server::primary_replica_ior_filename =
+ ACE_TEXT ("ns_replica_primary.ior");
+
+const ACE_TCHAR*
+TAO_FT_Naming_Server::backup_replica_ior_filename =
+ ACE_TEXT ("ns_replica_backup.ior");
+
+/// Default Constructor.
+TAO_FT_Naming_Server::TAO_FT_Naming_Server (void)
+ : replica_id_ (0),
+ naming_manager_ (),
+ replication_manager_ (0),
+ combined_naming_service_ior_file_name_ (0),
+ combined_naming_manager_ior_file_name_ (0),
+ naming_manager_ior_file_name_ (0),
+ naming_manager_persistence_file_name_ (0),
+ use_object_group_persistence_ (0),
+ server_role_ (STANDALONE)
+{
+}
+
+int
+TAO_FT_Naming_Server::init_with_orb (int argc,
+ ACE_TCHAR *argv [],
+ CORBA::ORB_ptr orb)
+{
+ // Invoke the base class initialization to setup the naming service
+ // What follows after that are the initialization steps to support
+ // fault tolerance and load balancing with the FT_Naming_Manager
+ int result = TAO_Naming_Server::init_with_orb (argc, argv, orb);
+
+ // Check the result to make sure it executed Ok.
+ if (result != 0)
+ return result;
+
+ if (this->use_object_group_persistence_)
+ {
+ // Make sure the object group directory is accessible
+ if (ACE_OS::access (this->object_group_dir_.c_str (), W_OK|X_OK))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Invalid object ")
+ ACE_TEXT ("group persistence directory\n")),
+ -1);
+ }
+
+ TAO::Storable_Factory * object_group_storable_factory;
+ ACE_NEW_RETURN (object_group_storable_factory,
+ TAO::Storable_FlatFileFactory (this->object_group_dir_),
+ -1);
+
+ naming_manager_.set_object_group_storable_factory (
+ object_group_storable_factory);
+ }
+
+ // Provide the naming manager reference for use in
+ // TAO_FT_Persistent_Naming_Contexts for load balancing functionality
+ TAO_FT_Storable_Naming_Context::set_naming_manager (&naming_manager_);
+
+ // Initialize the naming manager which supports the Object Group Manager
+ // interface
+ result = this->init_naming_manager_with_orb (argc, argv, orb);
+ if (result != 0)
+ return result;
+
+ try {
+
+ // Initialize the replication manager
+ result = init_replication_manager_with_orb (argc, argv, orb);
+ if (result != 0)
+ return result;
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("TAO_FT_Naming_Server::init_with_orb"));
+ return -1;
+ }
+
+ // If we successfully initialized the replication manager and we are
+ // a backup server, then we should export the multi-profile
+ // references to files.
+ if (this->server_role_ == TAO_FT_Naming_Server::BACKUP)
+ {
+ // The backup should write out the combined IOR for the primary
+ // and backup naming service and naming manager.
+ result = export_ft_naming_references ();
+ }
+
+ return result;
+}
+
+int
+TAO_FT_Naming_Server::init_naming_manager_with_orb (int argc,
+ ACE_TCHAR *argv [],
+ CORBA::ORB_ptr orb)
+{
+ ACE_UNUSED_ARG (argc);
+ ACE_UNUSED_ARG (argv);
+
+ int result = 0;
+
+ // Need to lock during startup to prevent access of partially
+ // initialized variables
+ ACE_GUARD_THROW_EX (ACE_SYNCH_RECURSIVE_MUTEX,
+ ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
+ try {
+
+ // Get the POA from the ORB.
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references (ACE_TEXT_ALWAYS_CHAR ("RootPOA"));
+
+ if (CORBA::is_nil (poa_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT(" (%P|%t) ERROR: Unable to initialize the POA.\n")),
+ -1);
+ }
+
+ if (result != 0)
+ return result;
+
+ // Get the POA object.
+ this->root_poa_ = PortableServer::POA::_narrow (poa_object.in ());
+
+ // Get the POA_Manager.
+ PortableServer::POAManager_var poa_manager =
+ this->root_poa_->the_POAManager ();
+
+ int numPolicies = 2;
+
+ CORBA::PolicyList policies (numPolicies);
+ policies.length (numPolicies);
+
+ // Id Assignment policy
+ policies[0] =
+ this->root_poa_->create_id_assignment_policy (PortableServer::USER_ID);
+
+ // Lifespan policy
+ policies[1] =
+ this->root_poa_->create_lifespan_policy (PortableServer::PERSISTENT);
+
+ /* Register the naming manager with a POA
+ * TODO: 1) Error checking
+ * 2) Write IOR to file
+ * 3) Persistence for Object Group Manager
+ */
+
+ // We use a different POA, otherwise the user would have to change
+ // the object key each time it invokes the server.
+ this->naming_manager_poa_ = this->root_poa_->create_POA (
+ ACE_TEXT_ALWAYS_CHAR ("NamingManager"),
+ poa_manager.in (),
+ policies);
+ // Warning! If create_POA fails, then the policies won't be
+ // destroyed and there will be hell to pay in memory leaks!
+
+ // Creation of the new POAs over, so destroy the Policy_ptr's.
+ for (CORBA::ULong i = 0;
+ i < policies.length ();
+ ++i)
+ {
+ CORBA::Policy_ptr policy = policies[i];
+ policy->destroy ();
+ }
+
+ poa_manager->activate ();
+
+ // Register with the POA.
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId (
+ ACE_TEXT_ALWAYS_CHAR ("NamingManager"));
+
+ this->naming_manager_poa_->activate_object_with_id (
+ id.in (),
+ &this->naming_manager_);
+
+ CORBA::Object_var nm_obj =
+ this->naming_manager_poa_->id_to_reference (id.in ());
+
+ this->my_naming_manager_ = FT_Naming::NamingManager::_narrow (nm_obj.in ());
+
+ this->naming_manager_ior_ =
+ orb->object_to_string (this->my_naming_manager_.in ());
+
+ // write out our object reference to the file defined in the -h option
+ if (this->naming_manager_ior_file_name_ != 0)
+ {
+ if (this->write_ior_to_file (this->naming_manager_ior_.in (),
+ this->naming_manager_ior_file_name_)
+ != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Unable to open %s ")
+ ACE_TEXT ("for writing:(%u) %p\n"),
+ this->naming_manager_ior_file_name_,
+ ACE_ERRNO_GET,
+ ACE_TEXT ("TAO_Naming_Server::")
+ ACE_TEXT ("init_naming_manager_with_orb")),
+ -1);
+ }
+ }
+
+ this->naming_manager_.initialize (this->orb_,
+ this->naming_manager_poa_);
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("TAO_FT_Naming_Server::init_naming_manager_with_orb"));
+ return -1;
+ }
+
+ // Make the Object Group Manager easily accessible using Interoperable
+ // Naming Service IORs
+ CORBA::Object_var table_object =
+ orb->resolve_initial_references (ACE_TEXT_ALWAYS_CHAR ("IORTable"));
+
+ IORTable::Table_var adapter =
+ IORTable::Table::_narrow (table_object.in ());
+ if (CORBA::is_nil (adapter.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: TAO_FT_Naming_Server::")
+ ACE_TEXT ("init_naming_manager_with_orb - Nil IORTable\n")));
+ }
+ else
+ {
+ CORBA::String_var ior = this->naming_manager_ior ();
+ adapter->bind (ACE_TEXT_ALWAYS_CHAR ("NamingManager"), ior.in ());
+ }
+
+ return 0;
+}
+
+int
+TAO_FT_Naming_Server::init_replication_manager_with_orb (int argc,
+ ACE_TCHAR *argv [],
+ CORBA::ORB_ptr orb)
+{
+ ACE_UNUSED_ARG (argc);
+ ACE_UNUSED_ARG (argv);
+
+ // Need to lock during startup to prevent access of partially initialized
+ // variables
+ ACE_GUARD_THROW_EX (ACE_SYNCH_RECURSIVE_MUTEX,
+ ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
+ // If redundancy is not requested, then do not initialize the
+ // replication manager
+ if (!this->use_redundancy_)
+ return 0;
+
+ int result = 0;
+
+ try {
+
+ // Get the POA from the ORB.
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references (ACE_TEXT_ALWAYS_CHAR ("RootPOA"));
+
+ if (CORBA::is_nil (poa_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT(" (%P|%t) ERROR: Unable to initialize the POA.\n")),
+ -1);
+ }
+
+ if (result != 0)
+ return result;
+
+ // Get the POA object.
+ this->root_poa_ = PortableServer::POA::_narrow (poa_object.in ());
+
+ // Get the POA_Manager.
+ PortableServer::POAManager_var poa_manager =
+ this->root_poa_->the_POAManager ();
+
+ int numPolicies = 2;
+
+ CORBA::PolicyList policies (numPolicies);
+ policies.length (numPolicies);
+
+ // Id Assignment policy
+ policies[0] =
+ this->root_poa_->create_id_assignment_policy (PortableServer::USER_ID);
+
+ // Lifespan policy
+ policies[1] =
+ this->root_poa_->create_lifespan_policy (PortableServer::PERSISTENT);
+
+ // We use a different POA, otherwise the user would have to change
+ // the object key each time it invokes the server.
+ this->replication_manager_poa_ = this->root_poa_->create_POA (
+ ACE_TEXT_ALWAYS_CHAR (this->replica_id_ ),
+ poa_manager.in (),
+ policies);
+
+ // Warning! If create_POA fails, then the policies won't be
+ // destroyed and there will be hell to pay in memory leaks!
+
+ // Creation of the new POAs over, so destroy the Policy_ptr's.
+ for (CORBA::ULong i = 0;
+ i < policies.length ();
+ ++i)
+ {
+ CORBA::Policy_ptr policy = policies[i];
+ policy->destroy ();
+ }
+
+ poa_manager->activate ();
+
+ // Construct the replication manager providing it with its ID
+ ACE_NEW_RETURN (this->replication_manager_,
+ TAO_FT_Naming_Replication_Manager (this,
+ this->replica_id_),
+ -1);
+
+ // Register with the POA.
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId (
+ ACE_TEXT_ALWAYS_CHAR (this->replica_id_));
+
+ this->replication_manager_poa_->activate_object_with_id (
+ id.in (),
+ this->replication_manager_);
+
+ CORBA::Object_var repl_mgr_ref =
+ this->replication_manager_poa_->id_to_reference (id.in ());
+
+ this->replication_manager_ior_ =
+ orb->object_to_string (repl_mgr_ref.in ());
+
+ // Provide the replication manager its ORB and POA
+ this->replication_manager_->initialize (
+ this->orb_.in (),
+ this->replication_manager_poa_.in ());
+
+ ACE_CString primary_file_name (this->persistence_file_name_);
+ primary_file_name += ACE_TEXT ("/");
+ primary_file_name +=
+ TAO_FT_Naming_Server::primary_replica_ior_filename;
+
+ ACE_CString backup_file_name (this->persistence_file_name_);
+ backup_file_name += ACE_TEXT ("/");
+ backup_file_name +=
+ TAO_FT_Naming_Server::backup_replica_ior_filename;
+
+ if (this->server_role_ == PRIMARY)
+ { // We are the primary
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server ")
+ ACE_TEXT ("is a primary\n")));
+
+ // Write out this replicas IOR for the backup to use to bootstrap
+ CORBA::String_var replication_ior = naming_service_ior ();
+ this->write_ior_to_file (this->replication_manager_ior_.in (),
+ primary_file_name.c_str ());
+
+ // Check if there is already a backup IOR file. If so, then the backup
+ // may be up and running so we should register with it.
+ CORBA::Object_var backup_ior;
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server reading ")
+ ACE_TEXT ("backup ior file\n")));
+
+ if ((ACE_OS::access (primary_file_name.c_str (),
+ R_OK) == 0) &&
+ this->read_reference_from_file (backup_file_name.c_str (),
+ backup_ior.out ()) == 0)
+ {// Success in reading backup IOR file
+ // Store the backup reference as our peer
+ FT_Naming::ReplicationManager_var peer_ref =
+ FT_Naming::ReplicationManager::_narrow (backup_ior.in ());
+
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server ")
+ ACE_TEXT ("narrowing IOR\n")));
+ if (CORBA::is_nil (peer_ref.in ()))
+ ACE_ERROR_RETURN (
+ (LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: IOR in file %s is not ")
+ ACE_TEXT ("a FT_Naming::ReplicationManager\n"),
+ primary_file_name.c_str ()),
+ -1);
+
+ try {
+ if (TAO_debug_level > 3)
+ ACE_DEBUG (
+ (LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server registering ")
+ ACE_TEXT ("with backup.\n")));
+
+ // Register with the backup
+ CosNaming::NamingContext_var root = this->my_root_context ();
+ FT_Naming::NamingManager_var nm = this->my_naming_manager ();
+
+ int registration_result =
+ this->replication_manager_->register_with_peer_replica (
+ peer_ref.in (),
+ root.in (),
+ nm.in ());
+
+ if (registration_result == 0)
+ {
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server ")
+ ACE_TEXT ("registered with backup.\n")));
+ }
+ else
+ {
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server:Backup peer ")
+ ACE_TEXT ("replica not started yet.\n")));
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ // Its Ok that we were unable to contact the backup peer.
+ // It has apparently not started yet.
+ // It will register with the primary when it starts up.
+ ex._tao_print_exception (
+ ACE_TEXT ("Backup peer replica not started yet.\n"));
+ }
+ }
+ else
+ {
+ // Could not get the backup replica from the IOR file, which is OK.
+ // The backup will register with us in the future.
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server no Replica ")
+ ACE_TEXT ("IOR file. Waiting for registration.\n")));
+ }
+ }
+ else if (this->server_role_ == TAO_FT_Naming_Server::BACKUP)
+ { // We are the backup
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server:Is a Backup\n")));
+
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server writing ")
+ ACE_TEXT ("replica ior\n")));
+ // Write out the backup ior for use by the primary if it must be restarted.
+ this->write_ior_to_file (replication_manager_ior_.in (),
+ backup_file_name.c_str ());
+
+ // Get the ior file for the primary from the
+ // persistence directory. If not there, fail.
+ CORBA::Object_var primary_ref = CORBA::Object::_nil ();
+
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server ")
+ ACE_TEXT ("reading primary ior file\n")));
+ // Check for the primary IOR. We must have it to bootstrap the redundant
+ // naming pair.
+ if ((ACE_OS::access (primary_file_name.c_str (), R_OK) == 0) &&
+ (this->read_reference_from_file (primary_file_name.c_str (),
+ primary_ref.out ()) == 0))
+ {
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server ")
+ ACE_TEXT ("toring the primary reference ior\n")));
+ // Store the primary reference as our peer
+ FT_Naming::ReplicationManager_var peer_ref =
+ FT_Naming::ReplicationManager::_narrow (primary_ref.in ());
+
+ if (CORBA::is_nil (peer_ref.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: IOR in file %s ")
+ ACE_TEXT ("is not a FT_Naming::ReplicationManager\n"),
+ primary_file_name.c_str ()),
+ -1);
+
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server ")
+ ACE_TEXT ("backup registering with primary.\n")));
+ // Register with the primary
+ CosNaming::NamingContext_var root = this->my_root_context ();
+ FT_Naming::NamingManager_var nm = this->my_naming_manager ();
+ int registration_result =
+ this->replication_manager_->register_with_peer_replica (peer_ref.in (),
+ root.in (),
+ nm.in ());
+ if (registration_result == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Backup unable to ")
+ ACE_TEXT ("register with the primary\n")),
+ -1);
+ }
+ else
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: No primary IOR ")
+ ACE_TEXT ("available. Have you started the ")
+ ACE_TEXT ("primary? Exiting.\n")),
+ -1);
+ }
+ }
+ else
+ {// We are neither a primary or replica, but running in standalone mode
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server:Is Standalone\n")));
+
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("TAO_FT_Naming_Server::init_replication_manager_with_orb.\n"));
+ return -1;
+ }
+
+ // Success
+ return 0;
+}
+
+
+int
+TAO_FT_Naming_Server::parse_args (int argc,
+ ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("b:c:do:p:s:f:m:z:r:u:v:g:h:"));
+
+ // Define the arguments for primary and backup
+ get_opts.long_option (ACE_TEXT ("primary"), ACE_Get_Opt::NO_ARG);
+ get_opts.long_option (ACE_TEXT ("backup"), ACE_Get_Opt::NO_ARG);
+ bool role_defined = false;
+
+ int c;
+ int size;
+#if !defined (CORBA_E_MICRO)
+ int result;
+
+ // This is declared this way to avoid warnings from
+ // some compilers that complain about mismatching types
+ // in the sscanf.
+#if ACE_SIZEOF_VOID_P == ACE_SIZEOF_LONG_LONG
+ ptrdiff_t address;
+#else
+ long int address;
+#endif /* ACE_SIZEOF_VOID_P */
+#endif /* CORBA_E_MICRO */
+
+ // Make sure only one naming context persistence option is specified
+ int f_opt_used = 0;
+ int u_opt_used = 0;
+ int r_opt_used = 0;
+
+ int v_opt_used = 0;
+
+ // TODO: remove unsupported options with FT Naming Server
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'd': // debug flag.
+ ++TAO_debug_level;
+ break;
+ case 'o': // outputs this servers naming service ior to a file.
+ this->ior_file_name_ = get_opts.opt_arg ();
+ break;
+ case 'c': // outputs the multi-profile naming service ior file
+ this->combined_naming_service_ior_file_name_ = get_opts.opt_arg ();
+ break;
+ case 'g': // outputs the mutli-profile object group manager ior file
+ this->combined_naming_manager_ior_file_name_ = get_opts.opt_arg ();
+ break;
+ case 'h': // outputs the object group manager ior to a file
+ this->naming_manager_ior_file_name_ = get_opts.opt_arg ();
+ break;
+ case 'p':
+ this->pid_file_name_ = get_opts.opt_arg ();
+ break;
+ case 's':
+ size = ACE_OS::atoi (get_opts.opt_arg ());
+ if (size >= 0)
+ this->context_size_ = size;
+ break;
+ case 'm':
+ this->multicast_ = ACE_OS::atoi(get_opts.opt_arg ());
+ break;
+#if !defined (CORBA_E_MICRO)
+ case 'b':
+ result = ::sscanf (ACE_TEXT_ALWAYS_CHAR (get_opts.opt_arg ()),
+#if ACE_SIZEOF_VOID_P == ACE_SIZEOF_LONG_LONG
+ ACE_INT64_FORMAT_SPECIFIER_ASCII,
+#else
+ "%ld",
+#endif /* ACE_SIZEOF_VOID_P */
+ &address);
+ if (result == 0 || result == EOF)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Unable to ")
+ ACE_TEXT ("process <-b> option")),
+ -1);
+ this->base_address_ = (void *) address;
+ break;
+ case 'f':
+ this->persistence_file_name_ = get_opts.opt_arg ();
+ f_opt_used = 1;
+ break;
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT)
+ case 'r':
+ this->use_redundancy_ = 1;
+ this->use_storable_context_ = 1;
+ this->persistence_file_name_ = get_opts.opt_arg ();
+ r_opt_used = 1;
+ break;
+ case 'u':
+ this->use_storable_context_ = 1;
+ this->persistence_file_name_ = get_opts.opt_arg ();
+ u_opt_used = 1;
+ break;
+ case 'v':
+ this->use_object_group_persistence_ = 1;
+ this->object_group_dir_ = get_opts.opt_arg ();
+ v_opt_used = 1;
+ break;
+
+#endif /* TAO_HAS_MINIMUM_POA == 0 */
+#endif /* !CORBA_E_MICRO */
+ case 'z':
+ this->use_round_trip_timeout_ = 1;
+ this->round_trip_timeout_ =
+ (int)1.0e7 * ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case 0: // A long option was found
+ {
+ const char* long_option = get_opts.long_option ();
+ if (ACE_OS::strcmp (long_option, ACE_TEXT ("backup")) == 0)
+ {
+ this->replica_id_ = ACE_TEXT ("Backup");
+ this->server_role_ = TAO_FT_Naming_Server::BACKUP;
+ role_defined = true;
+ }
+ else if (ACE_OS::strcmp (long_option,
+ ACE_TEXT ("primary")) == 0)
+ {
+ this->replica_id_ = ACE_TEXT ("Primary");
+ this->server_role_ = TAO_FT_Naming_Server::PRIMARY;
+ role_defined = true;
+ }
+ }
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("usage: %s\n")
+ ACE_TEXT ("--primary (not used with --backup)\n")
+ ACE_TEXT ("--backup (not used with --primary)\n")
+ ACE_TEXT ("-d\n")
+ ACE_TEXT ("-c <multi-profile_name_service_ior_file>\n")
+ ACE_TEXT ("-o <name_svc_ior_output_file>\n")
+ ACE_TEXT ("-g <multi-profile_naming_mgr_ior_file>\n")
+ ACE_TEXT ("-h <naming_mgr_ior_output_file>\n")
+ ACE_TEXT ("-p <pid_file_name>\n")
+ ACE_TEXT ("-s <context_size>\n")
+ ACE_TEXT ("-b <base_address>\n")
+ ACE_TEXT ("-m <1=enable multicast,")
+ ACE_TEXT (" 0=disable multicast(default)>\n")
+ ACE_TEXT ("-n <num_threads>\n")
+ ACE_TEXT ("-f <persistence_file_name>\n")
+ ACE_TEXT ("-u <storable_persistence_directory")
+ ACE_TEXT (" (not used with -f)>\n")
+ ACE_TEXT ("-v <storable_object_group_persistence")
+ ACE_TEXT ("_directory>\n")
+ ACE_TEXT ("-r <redundant_persistence_directory>\n")
+ ACE_TEXT ("-z <relative round trip timeout>\n")
+ ACE_TEXT ("\n"),
+ argv [0]),
+ -1);
+ }
+
+
+ if (f_opt_used + u_opt_used + r_opt_used > 1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Only one persistence option ")
+ ACE_TEXT ("can be provided.\n\n")),
+ -1);
+
+ // If naming context or object group persistence is being used then
+ // enable backup/restore compability of persitent files.
+ if (u_opt_used || r_opt_used || v_opt_used)
+ {
+ TAO::Storable_Base::use_backup_default = true;
+ }
+
+ if (!role_defined)
+ { // No role specified, so we will become a STANDALONE server
+ this->replica_id_ = ACE_TEXT ("Standalone");
+ this->server_role_ = TAO_FT_Naming_Server::STANDALONE;
+ // User has not provided a role, so we will not use redundancy option
+ if (this->use_redundancy_ == 1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("INFO: Cannot run standalone with ")
+ ACE_TEXT ("-r option. Using -u instead.\n")
+ ACE_TEXT ("Must start a '--primary' and a '--backup' ")
+ ACE_TEXT ("server to run as a Fault \n")
+ ACE_TEXT ("Tolerant Naming Service. \n")));
+ this->use_redundancy_ = 0;
+ }
+
+ }
+ else
+ {
+ // Only the backup should be requested to write the multi-profile IOR
+ if ((this->server_role_ != TAO_FT_Naming_Server::BACKUP) &&
+ (this->combined_naming_service_ior_file_name_ != 0))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Must export the multi-profile ")
+ ACE_TEXT ("IOR (using '-c' option) from the backup")
+ ACE_TEXT (" server.\n\n")),
+ -1);
+
+ // Only the backup should be requested to write the multi-profile IOR
+ if ((this->server_role_ == TAO_FT_Naming_Server::BACKUP) &&
+ (this->combined_naming_service_ior_file_name_ == 0))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Must export the multi-profile ")
+ ACE_TEXT ("IOR (using '-c' option) from the backup")
+ ACE_TEXT (" server.\n\n")),
+ -1);
+
+ }
+ return 0;
+}
+
+int
+TAO_FT_Naming_Server::fini (void)
+{
+ // Destroy the child POAs created when initializing
+ // the FT Naming Service
+ try
+ {
+ if (!CORBA::is_nil (this->naming_manager_poa_.in ()))
+ this->naming_manager_poa_->destroy (1, 1);
+ this->naming_manager_poa_ = PortableServer::POA::_nil ();
+
+ if (!CORBA::is_nil (this->replication_manager_poa_.in ()))
+ this->replication_manager_poa_->destroy (1, 1);
+
+ this->replication_manager_poa_ = PortableServer::POA::_nil ();
+ CORBA::Object_var table_object =
+ this->orb_->resolve_initial_references (
+ ACE_TEXT_ALWAYS_CHAR ("IORTable"));
+
+ IORTable::Table_var adapter =
+ IORTable::Table::_narrow (table_object.in ());
+ if (CORBA::is_nil (adapter.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Nil IORTable\n")));
+ }
+ else
+ {
+ adapter->unbind (ACE_TEXT_ALWAYS_CHAR ("NameService"));
+ adapter->unbind (ACE_TEXT_ALWAYS_CHAR ("NamingManager"));
+ }
+
+#if !defined (CORBA_E_MICRO)
+ CORBA::Object_var svc =
+ this->orb_->unregister_initial_reference (
+ ACE_TEXT_ALWAYS_CHAR ("NameService"));
+ this->orb_->unregister_initial_reference (
+ ACE_TEXT_ALWAYS_CHAR ("NamingManager"));
+#endif /* CORBA_E_MICRO */
+
+ }
+ catch (const CORBA::Exception&)
+ {
+ // Ignore
+ }
+
+ // Specific FT_Naming cleanup
+ naming_manager_poa_ = PortableServer::POA::_nil ();
+ replication_manager_poa_ = PortableServer::POA::_nil ();
+ my_naming_manager_ = FT_Naming::NamingManager::_nil ();
+ peer_naming_manager_ = FT_Naming::NamingManager::_nil ();
+ peer_root_context_ = CosNaming::NamingContext::_nil ();
+
+#if !defined (CORBA_E_MICRO)
+ delete this->context_index_;
+ delete replication_manager_;
+#endif /* CORBA_E_MICRO */
+
+ // Invoke the base class fini
+ return TAO_Naming_Server::fini ();
+}
+
+TAO_Storable_Naming_Context_Factory *
+TAO_FT_Naming_Server::storable_naming_context_factory (size_t context_size)
+{
+ return new (ACE_nothrow) TAO_FT_Storable_Naming_Context_Factory (context_size);
+}
+
+TAO_Persistent_Naming_Context_Factory *
+TAO_FT_Naming_Server::persistent_naming_context_factory (void)
+{
+ return new (ACE_nothrow) TAO_FT_Persistent_Naming_Context_Factory;
+}
+
+
+int
+TAO_FT_Naming_Server::read_reference_from_file (const char* replica_file_name,
+ CORBA::Object_out obj_ref)
+{
+
+ ACE_CString replica_ior_string ("file://");
+ replica_ior_string += replica_file_name;
+
+ try {
+ CORBA::Object_var object =
+ this->orb_->string_to_object (replica_ior_string.c_str ());
+ if (CORBA::is_nil (object.in ()))
+ {
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) - invalid ior in file <%s>\n"),
+ replica_file_name));
+
+ return -1;
+ }
+
+ obj_ref = object._retn ();
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Invalid object reference in file: %s\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+TAO_FT_Naming_Server::export_ft_naming_references (void)
+{
+ int result = 0;
+
+ switch (this->server_role_) {
+ // Neither the PRIMARY or STANDALONE server roles are able to write
+ // a multi-profile IOR for the redundant server pair.
+ case TAO_FT_Naming_Server::STANDALONE:
+ case TAO_FT_Naming_Server::PRIMARY:
+
+ if (this->naming_manager_ior_file_name_ != 0)
+ {
+ FT_Naming::NamingManager_var my_nm =
+ this->my_naming_manager ();
+ CORBA::String_var naming_manager_ior_string =
+ this->orb_->object_to_string (my_nm.in ());
+ this->write_ior_to_file (naming_manager_ior_string.in (),
+ this->naming_manager_ior_file_name_);
+ }
+
+ // Make sure the user provided an ior_file_name for the comb
+ if (this->combined_naming_service_ior_file_name_ != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Unable to write combined")
+ ACE_TEXT (" NameService IOR file. ")
+ ACE_TEXT ("Only supported by the backup naming service.\n")
+ ACE_TEXT ("Provide the -c option to the --backup role.\n")),
+ -1);
+ }
+ return 0;
+ break;
+
+ case TAO_FT_Naming_Server::BACKUP:
+ {
+ // Make sure the user provided an ior_file_name for the multi-profile ior file
+ if (this->combined_naming_service_ior_file_name_ == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Unable to write combined")
+ ACE_TEXT (" NameService IOR file. ")
+ ACE_TEXT ("No file name provided.\n")),
+ -1);
+ return 0;
+ }
+
+ CORBA::Object_var peer_root_cxt = this->peer_root_context ();
+ if (CORBA::is_nil (peer_root_cxt.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Unable to get the primary")
+ ACE_TEXT (" NameService object ref")),
+ -1);
+ }
+
+ CORBA::Object_var my_root_cxt = this->my_root_context ();
+ if (CORBA::is_nil (my_root_cxt.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Unable to get this")
+ ACE_TEXT (" services NameService object ref")),
+ -1);
+ }
+
+ CORBA::Object_ptr IORM =
+ this->orb_->resolve_initial_references (TAO_OBJID_IORMANIPULATION, 0);
+
+ TAO_IOP::TAO_IOR_Manipulation_var iorm =
+ TAO_IOP::TAO_IOR_Manipulation::_narrow (IORM);
+
+ // Combine the primary and backup (my) object references for the naming service
+ CORBA::Object_var combined_obj_ref =
+ iorm->add_profiles (peer_root_cxt.in (),
+ my_root_cxt.in ());
+
+ if (CORBA::is_nil (combined_obj_ref.in ()))
+ {
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("(%P|%t) ERROR: could not combine")
+ ACE_TEXT(" primary and backup IORs for")
+ ACE_TEXT(" fault tolerant Naming Service.\n")));
+ return -1;
+ }
+
+ CORBA::String_var combined_nameservice_ior_string =
+ this->orb_->object_to_string (combined_obj_ref.in ());
+
+ // Write out the combined IOR for the NameService
+ this->write_ior_to_file (combined_nameservice_ior_string.in (),
+ this->combined_naming_service_ior_file_name_);
+
+ // Verify that a naming manager ior file name was provided by user
+ if (this->combined_naming_manager_ior_file_name_ == 0)
+ {
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - FT_Naming_Server:No NamingManager")
+ ACE_TEXT (" IOR file name provided")
+ ACE_TEXT (" with -g option. Not writing IOR.\n")));
+ }
+ else
+ {// A file name was provided to store the naming manager IOR
+
+ FT_Naming::NamingManager_var peer_nm =
+ this->peer_naming_manager ();
+ FT_Naming::NamingManager_var my_nm =
+ this->my_naming_manager ();
+
+ // This is the object reference for the fault tolerant
+ // naming manager. The primary should be first.
+ combined_obj_ref =
+ iorm->add_profiles (peer_nm.in (),
+ my_nm.in ());
+
+ if (CORBA::is_nil (combined_obj_ref.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT("(%P|%t) ERROR: could not combine")
+ ACE_TEXT(" primary and backup IORs for")
+ ACE_TEXT(" fault tolerant Naming Manager.\n")),
+ -1);
+ }
+
+ CORBA::String_var combined_naming_manager_ior_string =
+ this->orb_->object_to_string (combined_obj_ref.in ());
+
+ // Write out the combined IOR for the NameService
+ this->write_ior_to_file (combined_naming_manager_ior_string.in (),
+ this->combined_naming_manager_ior_file_name_);
+ }
+
+ return 0;
+ }
+ break;
+ };
+ return result;
+}
+
+
+
+/// Return the IOR for the registered replication manager
+char*
+TAO_FT_Naming_Server::replication_manager_ior (void)
+{
+ return CORBA::string_dup (this->replication_manager_ior_.in ());
+}
+
+
+/// Return the IOR for the registered object group manager
+char*
+TAO_FT_Naming_Server::naming_manager_ior (void)
+{
+ return CORBA::string_dup (this->naming_manager_ior_.in ());
+}
+
+int
+TAO_FT_Naming_Server::update_object_group (
+ const FT_Naming::ObjectGroupUpdate & group_info)
+{
+ ACE_GUARD_THROW_EX (ACE_SYNCH_RECURSIVE_MUTEX,
+ ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
+ if (this->use_object_group_persistence_)
+ {
+ if (TAO_debug_level > 3)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%T %n (%P|%t) - ")
+ ACE_TEXT ("An update of object group with ID %lld ")
+ ACE_TEXT ("has been made by the peer"),
+ group_info.id
+ ));
+ }
+ this->naming_manager_.set_object_group_stale (group_info);
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Attempting to update object group ")
+ ACE_TEXT ("as stale with obect group persistence not ")
+ ACE_TEXT ("enabled.")));
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+TAO_FT_Naming_Server::update_naming_context (
+ const FT_Naming::NamingContextUpdate & context_info)
+{
+ ACE_GUARD_THROW_EX (ACE_SYNCH_RECURSIVE_MUTEX,
+ ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
+ PortableServer::ServantBase_var servant;
+
+ // Lookup the servant for the identified context and see if it is
+ // active here locally.
+ try {
+ // Get the servant if it exists in this process
+ PortableServer::ObjectId_var context_id =
+ PortableServer::string_to_ObjectId (context_info.context_name);
+ servant = this->ns_poa_->id_to_servant (context_id);
+ }
+ catch (PortableServer::POA::ObjectNotActive&)
+ { // No servant registered for this object reference so no need to create it.
+ // It will be created on first access in incarnate function
+
+ // This context is not currently active in this server so
+ // there is nothing to be done, so return success.
+ return 0;
+ }
+
+ TAO_Naming_Context* changed_context_servant =
+ dynamic_cast<TAO_Naming_Context*> (servant.in ());
+
+ if (changed_context_servant == 0)
+ { // Another type of class was used as the servant. Should not happen.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Invalid servant type registered")
+ ACE_TEXT (" with oid: %s"),
+ context_info.context_name.in ()));
+ return -1;
+ }
+
+ if (TAO_debug_level > 3)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%T %n (%P|%t) - ")
+ ACE_TEXT ("An update of naming context with name %s ")
+ ACE_TEXT ("has been made by the peer"),
+ context_info.context_name.in ()
+ ));
+ }
+
+ // Mark the local context stale, so we will reload it next
+ // time it is modified or accessed.
+ changed_context_servant->stale (true);
+
+ return 0;
+}
+
+/// Destructor.
+TAO_FT_Naming_Server::~TAO_FT_Naming_Server (void)
+{
+ // Clear out the static naming manager from the persistent naming context
+ TAO_FT_Persistent_Naming_Context::set_naming_manager_impl (0);
+}
+
+
+void
+TAO_FT_Naming_Server::peer_root_context (CosNaming::NamingContext_ptr peer_cxt)
+{
+ peer_root_context_ = CosNaming::NamingContext::_duplicate (peer_cxt);
+}
+
+CosNaming::NamingContext_ptr
+TAO_FT_Naming_Server::peer_root_context (void)
+{
+ return CosNaming::NamingContext::_duplicate (peer_root_context_.in ());
+}
+
+CosNaming::NamingContext_ptr
+TAO_FT_Naming_Server::my_root_context (void) const
+{
+ return CosNaming::NamingContext::_duplicate (this->naming_context_.in ());
+}
+
+void
+TAO_FT_Naming_Server::peer_naming_manager (FT_Naming::NamingManager_ptr peer_cxt)
+{
+ peer_naming_manager_ = FT_Naming::NamingManager::_duplicate (peer_cxt);
+}
+
+FT_Naming::NamingManager_ptr
+TAO_FT_Naming_Server::peer_naming_manager (void)
+{
+ return FT_Naming::NamingManager::_duplicate (peer_naming_manager_.in ());
+}
+
+FT_Naming::NamingManager_ptr
+TAO_FT_Naming_Server::my_naming_manager (void) const
+{
+ return FT_Naming::NamingManager::_duplicate (this->my_naming_manager_.in ());
+}
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h
new file mode 100644
index 00000000000..053db29c525
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h
@@ -0,0 +1,189 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Naming_Server.h
+ *
+ * $Id$
+ *
+ * Implement functionality necessary for fault tolerant naming service.
+ * Adds support for Object Group Manager interfaces as well. This class
+ * extends the TAO_Naming_Server.
+ *
+ * @author Kevin Stanley
+ */
+//=============================================================================
+//
+
+#ifndef TAO_FT_NAMING_SERVER_H
+#define TAO_FT_NAMING_SERVER_H
+
+#include "orbsvcs/Naming/Naming_Server.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h"
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+#include "tao/IORManipulation/IORManip_Loader.h"
+#include "ace/Recursive_Thread_Mutex.h"
+
+/**
+ * @class TAO_FT_Naming_Server
+ *
+ * @brief Defines a class derived from the TAO_Naming_Server to extend
+ the functionality to support an ObjectGroupManager interface and a
+ load balancing capability for objects that are bound within an object
+ group within the naming service. The Naming Service will extend the
+ resolve and resolve_str operations to perform load balancing on the
+ objects within the object group using a specified load balancing
+ strategy.
+ */
+class TAO_FtNaming_Export TAO_FT_Naming_Server : public TAO_Naming_Server
+{
+public:
+ /// Default Constructor.
+ TAO_FT_Naming_Server (void);
+
+ /// Initialize the Naming Service and Object Group Manager with the command line
+ /// arguments and the ORB. Overrridden from TAO_Naming_Server
+ virtual int init_with_orb (int argc, ACE_TCHAR *argv [], CORBA::ORB_ptr orb);
+
+ /**
+ * Accessors and mutators for object references.
+ */
+ /// Returns a <NamingContext_ptr> for the root Naming Context.
+ CosNaming::NamingContext_ptr my_root_context (void) const;
+
+ /// Returns the reference for this servers local naming manager servant.
+ FT_Naming::NamingManager_ptr my_naming_manager (void) const;
+
+ void peer_root_context (CosNaming::NamingContext_ptr peer_cxt);
+ CosNaming::NamingContext_ptr peer_root_context (void);
+
+ void peer_naming_manager (FT_Naming::NamingManager_ptr peer_nm);
+ FT_Naming::NamingManager_ptr peer_naming_manager (void);
+
+ /// Initialize the naming manager with the ORB.
+ int init_naming_manager_with_orb (int argc,
+ ACE_TCHAR *argv [],
+ CORBA::ORB_ptr orb);
+
+ /// Initialize the replication manager with the ORB.
+ int init_replication_manager_with_orb (int argc,
+ ACE_TCHAR *argv [],
+ CORBA::ORB_ptr orb);
+
+ /// Overridden parse operation. Only allows options supported by the FT_Naming_Server
+ /// and adds options for the object group manager
+ virtual int parse_args (int argc,
+ ACE_TCHAR *argv[]);
+
+ /// Factory method to create a naming context factory for use with
+ /// the -u and -r options.
+ virtual TAO_Storable_Naming_Context_Factory *
+ storable_naming_context_factory (size_t context_size);
+
+ /// Factory method to create a naming context factory for use with
+ /// the -f option.
+ virtual TAO_Persistent_Naming_Context_Factory *
+ persistent_naming_context_factory (void);
+
+ /// Returns the IOR of the replication manager.
+ char* replication_manager_ior (void);
+
+ /// Returns the IOR of the naming manager.
+ char * naming_manager_ior (void);
+
+ virtual int update_object_group (
+ const FT_Naming::ObjectGroupUpdate & group_info);
+
+ virtual int update_naming_context (
+ const FT_Naming::NamingContextUpdate & naming_context);
+
+ /// Destroy the child POAs created in @c init_with_orb,
+ /// @c init_naming_manager_with_orb, and
+ /// @c init_replication_manager_with_orb
+ virtual int fini (void);
+
+ /// Destructor.
+ virtual ~TAO_FT_Naming_Server (void);
+
+protected:
+
+ /// Read the replica from the specified file
+ int read_reference_from_file (const char* replica_file_name,
+ CORBA::Object_out obj_ref);
+
+ /// Export the NameService and NameManager combined object references
+ /// to the file names provided
+ int export_ft_naming_references (void);
+
+ const ACE_TCHAR * replica_id_;
+
+ /// The object that implements the ObjectGroupManager, PropertyManager,
+ /// and GenericFactory interfaces.
+ TAO_FT_Naming_Manager naming_manager_;
+
+ /// Object reference for the local naming manager servant.
+ FT_Naming::NamingManager_var my_naming_manager_;
+
+ /// Object reference for the peer naming service's naming manager.
+ FT_Naming::NamingManager_var peer_naming_manager_;
+
+ /// Object reference for the peer naming service's naming manager.
+ CosNaming::NamingContext_var peer_root_context_;
+
+ /// The object that implements the FT_Naming::Replication_Manager
+ /// interface.
+ TAO_FT_Naming_Replication_Manager* replication_manager_;
+
+ /// File to output for the multi-profile root naming context IOR.
+ const ACE_TCHAR *combined_naming_service_ior_file_name_;
+
+ /// File to output the multi-profile object group manager IOR.
+ const ACE_TCHAR *combined_naming_manager_ior_file_name_;
+
+ /// File to output the object group manager IOR.
+ const ACE_TCHAR *naming_manager_ior_file_name_;
+
+ /// Path to the file to be used to store/read in Object Group Manager
+ /// persistent state.
+ const ACE_TCHAR *naming_manager_persistence_file_name_;
+
+ /// The IOR string of the object group manager.
+ CORBA::String_var naming_manager_ior_;
+
+ /// The IOR string of the object group manager.
+ CORBA::String_var replication_manager_ior_;
+
+ /// The IOR string of the peer replica.
+ CORBA::String_var replica_peer_ior_;
+
+ /// The Object Group Manager POA.
+ PortableServer::POA_var naming_manager_poa_;
+
+ /// The POA used for replication coordination between
+ /// primary and backup.
+ PortableServer::POA_var replication_manager_poa_;
+
+ int use_object_group_persistence_;
+ ACE_CString object_group_dir_;
+
+ /// The role this server is supporting in the dual redundant
+ /// replication scheme.
+ enum ServerRole { PRIMARY, BACKUP, STANDALONE };
+
+ /// The role this server is to take on. Controlled by the
+ /// --primary or --backup command line arguments. Defaults
+ /// to STANDALONE if no role is provided in command line.
+ ServerRole server_role_;
+
+ /// Lock used to serialize access to fault tolerant extensions
+ /// to Naming Service.
+ TAO_SYNCH_RECURSIVE_MUTEX lock_;
+
+private:
+ static const ACE_TCHAR* primary_replica_ior_filename;
+ static const ACE_TCHAR* backup_replica_ior_filename;
+
+ };
+
+#endif /* TAO_FT_NAMING_SERVER_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp
new file mode 100644
index 00000000000..07e2e52a3f8
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp
@@ -0,0 +1,132 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_PG_Group_Factory.cpp
+ *
+ * $Id$
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h"
+
+#include "orbsvcs/PortableGroup/PG_Group_List_Store.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO::FT_PG_Group_Factory::FT_PG_Group_Factory()
+{
+}
+
+TAO::FT_PG_Group_Factory::~FT_PG_Group_Factory()
+{
+}
+
+void
+TAO::FT_PG_Group_Factory::set_object_group_stale (
+ const FT_Naming::ObjectGroupUpdate & group_info)
+{
+ if (this->use_persistence_)
+ {
+ PortableGroup::ObjectGroupId group_id = group_info.id;
+
+ // If a group was added or destroyed then the group list could be stale.
+ if (group_info.change_type == FT_Naming::NEW ||
+ group_info.change_type == FT_Naming::DELETED)
+ {
+ if (TAO_debug_level > 3)
+ {
+ ACE_CString change_type_str (ACE_TEXT ("created"));
+ if (group_info.change_type == FT_Naming::DELETED)
+ change_type_str = ACE_TEXT ("deleted");
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%T %n (%P|%t) - ")
+ ACE_TEXT ("Setting list store as stale "),
+ ACE_TEXT ("because of group with ID %lld "),
+ ACE_TEXT ("was %s"),
+ group_id, change_type_str.c_str ()
+ ));
+ }
+ this->list_store_->stale(true);
+ }
+
+ PG_Object_Group * group = 0;
+ if (!find_group (group_id, group))
+ {
+ throw PortableGroup::ObjectNotFound ();
+ }
+ FT_PG_Object_Group_Storable * og =
+ dynamic_cast<FT_PG_Object_Group_Storable *> (group);
+
+ if (TAO_debug_level > 3)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%T %n (%P|%t) - ")
+ ACE_TEXT ("Setting object group with ID %lld as stale"),
+ group_id
+ ));
+ }
+ og->stale (true);
+ }
+ else
+ {
+ throw CORBA::INTERNAL ();
+ }
+}
+
+TAO::PG_Object_Group_Storable *
+TAO::FT_PG_Group_Factory::create_persistent_group (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ CORBA::Object_ptr empty_group,
+ const PortableGroup::TagGroupTaggedComponent & tagged_component,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ TAO::PG_Property_Set * type_properties,
+ TAO::Storable_Factory & storable_factory)
+{
+ TAO::PG_Object_Group_Storable * objectGroup = 0;
+ ACE_NEW_THROW_EX (
+ objectGroup,
+ TAO::FT_PG_Object_Group_Storable (
+ orb,
+ factory_registry,
+ manipulator,
+ empty_group,
+ tagged_component,
+ type_id,
+ the_criteria,
+ type_properties,
+ storable_factory
+ ),
+ CORBA::NO_MEMORY());
+ return objectGroup;
+}
+
+TAO::PG_Object_Group_Storable *
+TAO::FT_PG_Group_Factory::restore_persistent_group (
+ PortableGroup::ObjectGroupId group_id,
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ TAO::Storable_Factory & storable_factory)
+{
+ TAO::PG_Object_Group_Storable * objectGroup = 0;
+ ACE_NEW_THROW_EX (
+ objectGroup,
+ TAO::FT_PG_Object_Group_Storable (
+ group_id,
+ orb,
+ factory_registry,
+ manipulator,
+ storable_factory
+ ),
+ CORBA::NO_MEMORY());
+ return objectGroup;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h
new file mode 100644
index 00000000000..22d0b0c88b9
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h
@@ -0,0 +1,82 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_PG_Group_Factory.h
+ *
+ * $Id$
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FT_TAO_PG_GROUP_FACTORY_H
+#define FT_TAO_PG_GROUP_FACTORY_H
+
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+
+#include "orbsvcs/PortableGroup/PG_Group_Factory.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace FT_Naming
+{
+ struct ObjectGroupUpdate;
+}
+
+namespace TAO
+{
+
+ /**
+ * class FT_PG_Group_Factory
+ */
+ class TAO_FtNaming_Export FT_PG_Group_Factory : public PG_Group_Factory
+ {
+ public:
+
+ /// Constructor.
+ FT_PG_Group_Factory ();
+
+ /// Destructor.
+ ~FT_PG_Group_Factory ();
+
+ /**
+ * indicate the object group state is stale.
+ * only valid when object group persistence is enabled.
+ */
+ void set_object_group_stale (const FT_Naming::ObjectGroupUpdate & group_info);
+
+ protected:
+
+ virtual PG_Object_Group_Storable * create_persistent_group (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ CORBA::Object_ptr empty_group,
+ const PortableGroup::TagGroupTaggedComponent & tagged_component,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ TAO::PG_Property_Set * type_properties,
+ TAO::Storable_Factory & storable_factory);
+
+ virtual PG_Object_Group_Storable * restore_persistent_group (
+ PortableGroup::ObjectGroupId group_id,
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ TAO::Storable_Factory & storable_factory);
+
+ };
+} // namespace TAO
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* FT_TAO_PG_GROUP_FACTORY_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp
new file mode 100644
index 00000000000..4617755347d
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp
@@ -0,0 +1,182 @@
+// $Id$
+
+#include "orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h"
+#include "orbsvcs/PortableGroup/PG_Object_Group_Storable.h"
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h"
+#include "tao/Stub.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO::FT_PG_Object_Group_Storable::FT_PG_Object_Group_Storable (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ CORBA::Object_ptr empty_group,
+ const PortableGroup::TagGroupTaggedComponent & tagged_component,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ TAO::PG_Property_Set * type_properties,
+ TAO::Storable_Factory & storable_factory)
+ : PG_Object_Group_Storable(orb,
+ factory_registry,
+ manipulator,
+ empty_group,
+ tagged_component,
+ type_id,
+ the_criteria,
+ type_properties,
+ storable_factory)
+ , stale_ (false)
+ , file_created_ (false)
+{
+}
+
+TAO::FT_PG_Object_Group_Storable::FT_PG_Object_Group_Storable (
+ PortableGroup::ObjectGroupId group_id,
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ TAO::Storable_Factory & storable_factory)
+ : PG_Object_Group_Storable(group_id,
+ orb,
+ factory_registry,
+ manipulator,
+ storable_factory)
+ , stale_ (false)
+ , file_created_ (true)
+{
+}
+
+TAO::FT_PG_Object_Group_Storable::~FT_PG_Object_Group_Storable (void)
+{
+}
+
+void
+TAO::FT_PG_Object_Group_Storable::stale (bool is_stale)
+{
+ this->stale_ = is_stale;
+}
+
+bool
+TAO::FT_PG_Object_Group_Storable::stale ()
+{
+ return this->stale_;
+}
+
+int
+TAO::FT_PG_Object_Group_Storable::propagate_update_notification
+ (FT_Naming::ChangeType change_type)
+{
+ // Notify the peer of the changed context
+ FT_Naming::ReplicationManager_var peer =
+ TAO_FT_Naming_Replication_Manager::peer_replica ();
+
+ if (CORBA::is_nil (peer.in ()))
+ {
+ // Replication is not supported without a peer replica.
+ return 1;
+ }
+
+ FT_Naming::ObjectGroupUpdate object_group_info;
+ object_group_info.id = PG_Object_Group::get_object_group_id ();
+ object_group_info.change_type = change_type;
+
+ try {
+ // Notify the naming_manager of the updated context
+ if (TAO_debug_level > 3)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%T %n (%P|%t) - ")
+ ACE_TEXT ("Notifying peer that object group with ID %lld ")
+ ACE_TEXT ("has been updated"), object_group_info.id
+ ));
+ }
+ peer->notify_updated_object_group (object_group_info);
+ }
+ catch (CORBA::Exception& ex)
+ {
+ if (TAO_debug_level > 3)
+ ex._tao_print_exception (
+ ACE_TEXT ("Unable to communicate with peer.\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+TAO::FT_PG_Object_Group_Storable::state_written (void)
+{
+ FT_Naming::ChangeType change_type;
+
+ if (!this->file_created_)
+ {
+ change_type = FT_Naming::NEW;
+ this->file_created_ = true;
+ }
+ else if (this->destroyed_)
+ change_type = FT_Naming::DELETED;
+ else
+ change_type = FT_Naming::UPDATED;
+
+ // If peer is available notify that state has changed.
+ // Otherwise, rely on file time stamps exclusively
+ // for update notification.
+ this->propagate_update_notification (change_type);
+
+ this->write_occurred_ = false;
+}
+
+bool
+TAO::FT_PG_Object_Group_Storable::is_obsolete (time_t stored_time)
+{
+ ACE_UNUSED_ARG (stored_time);
+ return (!this->loaded_from_stream_) || this->stale_;
+}
+
+PortableGroup::ObjectGroup_ptr
+TAO::FT_PG_Object_Group_Storable::add_member_to_iogr (CORBA::Object_ptr member)
+{
+ // If this is the first member added to the group and it's type_id does
+ // not match the member, then the object group should assume the same
+ // type id as the first member. We will need to replace the object
+ // reference with an empty reference of the specified type id.
+
+ if (CORBA::is_nil (member))
+ {// A null object reference is not an acceptable member of the group.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Unable to add null member ")
+ ACE_TEXT ("to object group with id: %s\n"),
+ this->tagged_component_.object_group_id));
+ return CORBA::Object::_nil ();
+ }
+
+ const char* member_type_id = member->_stubobj ()->type_id.in ();
+
+ if ((this->members_.current_size () == 0) &&
+ (ACE_OS::strcmp (this->type_id_, member_type_id) != 0) )
+ {
+ try {
+ this->type_id_ = member_type_id;
+ this->reference_ = manipulator_.create_object_group_using_id (
+ this->type_id_,
+ this->tagged_component_.group_domain_id,
+ this->tagged_component_.object_group_id);
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) ERROR: Unable to add member ")
+ ACE_TEXT ("to object group with id: %s for object ")
+ ACE_TEXT ("of type: %s\n"),
+ this->tagged_component_.object_group_id,
+ member_type_id));
+ return CORBA::Object::_nil ();
+ }
+ }
+
+ return PG_Object_Group::add_member_to_iogr (member);
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h
new file mode 100644
index 00000000000..374400188f0
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h
@@ -0,0 +1,132 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_PG_Object_Group_Storable.h
+ *
+ * $Id$
+ *
+ * Contains declaration for class FT_PG_Object_Group_Storable.
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FT_TAO_PG_OBJECT_GROUP_STORABLE_H_
+#define FT_TAO_PG_OBJECT_GROUP_STORABLE_H_
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+/////////////////////////////////
+// Includes needed by this header
+#include "orbsvcs/PortableGroup/PG_Object_Group_Storable.h"
+#include "orbsvcs/FT_NamingReplicationC.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+////////////////
+// Class declarations
+namespace TAO
+{
+ /**
+ * An object group whose state persists to a stream so that its state
+ * can be saved/retrieved between processes that use the group.
+ */
+ class TAO_FtNaming_Export FT_PG_Object_Group_Storable
+ : public PG_Object_Group_Storable
+ {
+
+ /////////////////////
+ // Construct/Destruct
+ public:
+
+ /**
+ * This constructor is suitable for creating an object group from
+ * scratch.
+ */
+ FT_PG_Object_Group_Storable (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ CORBA::Object_ptr empty_group,
+ const PortableGroup::TagGroupTaggedComponent & tagged_component,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ TAO::PG_Property_Set * type_properties,
+ TAO::Storable_Factory & storable_factory);
+
+ /**
+ * This constructor is suitable for creating an object group from
+ * persistent store.
+ */
+ FT_PG_Object_Group_Storable (
+ PortableGroup::ObjectGroupId group_id,
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ TAO::Storable_Factory & storable_factory);
+
+ /// Destructor
+ ~FT_PG_Object_Group_Storable ();
+
+ /////////////////
+ // public methods
+
+ public:
+
+ virtual void stale (bool is_stale);
+ virtual bool stale ();
+
+ protected:
+
+ virtual void state_written ();
+
+ virtual bool is_obsolete (time_t stored_time);
+
+ /// Provide support for modifying the object group type_id when first
+ /// member is added to the group.
+ virtual PortableGroup::ObjectGroup_ptr add_member_to_iogr(
+ CORBA::Object_ptr member);
+
+ private:
+
+ /////////////////////////
+ // Forbidden methods
+ FT_PG_Object_Group_Storable ();
+ FT_PG_Object_Group_Storable (const FT_PG_Object_Group_Storable & rhs);
+ FT_PG_Object_Group_Storable & operator = (
+ const FT_PG_Object_Group_Storable & rhs);
+
+ /// Replication persistence support
+
+ bool stale_;
+
+ /// Track if the persistent file used for storage has been created yet
+ /// so can know if we should propagate a change type of NEW.
+ bool file_created_;
+
+ /**
+ * Although it is assumed for replication that services
+ * using object groups share the persistent store, a
+ * CORBA message is sent upon update from one replica to
+ * another so the object group data can be marked as stale.
+ * This is because using the file time stamp to detect
+ * if the data has been updated only provides one second
+ * resolution.
+ */
+ int propagate_update_notification (FT_Naming::ChangeType change_type);
+
+ };
+} // namespace TAO
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif // FT_TAO_PG_OBJECT_GROUP_STORABLE_H_
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp
new file mode 100644
index 00000000000..ab1a1ae2737
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp
@@ -0,0 +1,111 @@
+// $Id$
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h"
+#include "orbsvcs/FT_NamingManagerC.h"
+#include "orbsvcs/PortableGroup/PG_Utils.h"
+#include "orbsvcs/PortableGroup/PG_Property_Utils.h"
+
+#include "orbsvcs/Naming/Persistent_Context_Index.h"
+#include "ace/OS_NS_stdio.h"
+
+#include "ace/Auto_Ptr.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// Initialize the static naming manager
+TAO_FT_Naming_Manager *TAO_FT_Persistent_Naming_Context::naming_manager_impl_ = 0;
+
+TAO_FT_Persistent_Naming_Context::TAO_FT_Persistent_Naming_Context (
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO_Persistent_Context_Index *context_index,
+ HASH_MAP *map,
+ ACE_UINT32 *counter)
+ : TAO_Persistent_Naming_Context (poa,
+ poa_id,
+ context_index,
+ map,
+ counter)
+{
+
+}
+
+
+TAO_FT_Persistent_Naming_Context::~TAO_FT_Persistent_Naming_Context (void)
+{
+ // Perform appropriate cleanup based on the destruction level specified.
+}
+
+
+CORBA::Boolean
+TAO_FT_Persistent_Naming_Context::is_object_group (CORBA::Object_ptr obj) const
+{
+ // If there is a tagged component with tag = IOP::TAG_FT_GROUP in
+ // the object reference then it is an object group
+ PortableGroup::TagGroupTaggedComponent tagged_component;
+ return TAO::PG_Utils::get_tagged_component (obj, tagged_component);
+}
+
+CORBA::Object_ptr
+TAO_FT_Persistent_Naming_Context::resolve (const CosNaming::Name& n)
+{
+ // Invoke the base class resolve operation to acquire the object at the
+ // specified compound name.
+ // Any exceptions should flow back to client.
+ CORBA::Object_var resolved_ref =
+ TAO_Persistent_Naming_Context::resolve(n);
+
+ ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon, this->lock_,
+ CORBA::INTERNAL ());
+
+ // Get the locations of the object group members and we will use them to
+ // do the load balancing
+ try {
+
+ // Make sure object is an object group.
+ // We will return the object reference all the way back out to the client
+ // if not
+ if (!this->is_object_group (resolved_ref.in ()))
+ return resolved_ref._retn ();
+
+ // If there is no naming manager, we will fail and report an error.
+ if ( this->naming_manager_impl_ == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO_FT_Persistent_Naming_Context::resolve ")
+ ACE_TEXT ("- No NamingManager defined.\n")));
+
+ throw CORBA::INTERNAL ();
+ }
+
+ // The Naming Manager will apply the appropriate strategy to get the
+ // next object reference from the object group.
+ resolved_ref = this->naming_manager_impl_->next_member (resolved_ref.in ());
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ // This is apparently not an object group, so we should return the
+ // object reference itself
+ // No action required
+ }
+ catch (CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("TAO_FT_Persistent_Naming_Context::resolve ")
+ ACE_TEXT ("- Some unhandled error occurred\n"));
+ return CORBA::Object::_nil ();
+ }
+
+ return resolved_ref._retn ();
+}
+
+void
+TAO_FT_Persistent_Naming_Context::set_naming_manager_impl (
+ TAO_FT_Naming_Manager *mgr_impl)
+{
+ naming_manager_impl_ = (mgr_impl);
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h
new file mode 100644
index 00000000000..1303c78daae
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Persistent_Naming_Context.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_FT_PERSISTENT_NAMING_CONTEXT_H
+#define TAO_FT_PERSISTENT_NAMING_CONTEXT_H
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/Naming/Persistent_Naming_Context.h"
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+#include "orbsvcs/orbsvcs/PortableGroupC.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class TAO_FT_Persistent_Naming_Context
+ *
+ * @brief This class specializes the TAO_Persistent_Naming_Context
+ * 'ConcreteImplementor' in the Bridge pattern architecture of the
+ * CosNaming::NamingContext implementation.
+ *
+ */
+class TAO_FtNaming_Export TAO_FT_Persistent_Naming_Context :
+ public TAO_Persistent_Naming_Context
+{
+public:
+ /// Underlying data structure - typedef for ease of use.
+ typedef TAO_Persistent_Naming_Context::HASH_MAP HASH_MAP;
+
+ // = Initialization and termination methods.
+
+ /**
+ * Constructor that takes in preallocated data structure and takes
+ * ownership of it. Derived class from TAO_Persistent_Naming_Context
+ * provides specialization of the resolve operation to support
+ * load balancing.
+ */
+ TAO_FT_Persistent_Naming_Context (PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO_Persistent_Context_Index *context_index,
+ HASH_MAP * map = 0,
+ ACE_UINT32 *counter = 0);
+
+ /// Destructor.
+ virtual ~TAO_FT_Persistent_Naming_Context (void);
+
+ /**
+ * Override the resolve operation to support load balancing using
+ * the object group manager and associated strategy.
+ */
+ virtual CORBA::Object_ptr resolve (const CosNaming::Name &n);
+
+ static void set_naming_manager_impl (TAO_FT_Naming_Manager *mgr_impl);
+
+ bool is_object_group (const CORBA::Object_ptr obj) const;
+
+protected:
+ static TAO_FT_Naming_Manager *naming_manager_impl_;
+
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* TAO_FT_PERSISTENT_NAMING_CONTEXT_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp
new file mode 100644
index 00000000000..5ba6a1d38c4
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp
@@ -0,0 +1,40 @@
+// $Id$
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ /// Constructor.
+TAO_FT_Persistent_Naming_Context_Factory::TAO_FT_Persistent_Naming_Context_Factory (void)
+: TAO_Persistent_Naming_Context_Factory ()
+{
+
+}
+
+ /// Destructor. Does not deallocate the hash map: if an instance of
+ /// this class goes out of scope, its hash_map remains in persistent storage.
+TAO_FT_Persistent_Naming_Context_Factory::~TAO_FT_Persistent_Naming_Context_Factory (void)
+{
+}
+
+
+/// Factory method for creating an implementation object for naming contexts
+TAO_Persistent_Naming_Context*
+TAO_FT_Persistent_Naming_Context_Factory::create_naming_context_impl (
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO_Persistent_Context_Index *context_index,
+ HASH_MAP * map,
+ ACE_UINT32 *counter)
+{
+ // Construct the naming context, forwarding the map and counter even if they
+ // are defaulted
+ return new (ACE_nothrow) TAO_FT_Persistent_Naming_Context (poa,
+ poa_id,
+ context_index,
+ map,
+ counter);
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h
new file mode 100644
index 00000000000..bebf02fdbc7
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Persistent_Naming_Context_Factory.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_FT_PERSISTENT_NAMING_CONTEXT_FACTORY_H
+#define TAO_FT_PERSISTENT_NAMING_CONTEXT_FACTORY_H
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/Naming/Persistent_Naming_Context_Factory.h"
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class TAO_FT_Persistent_Naming_Context_Factory
+ *
+ * @brief An implementation of the TAO_Naming_Context_Factory that creates
+ * TAO_FT_Persistent_Naming_Context to implement the COS Naming Service
+ * NamingContext interface.
+ */
+class TAO_FtNaming_Export TAO_FT_Persistent_Naming_Context_Factory
+ : public TAO_Persistent_Naming_Context_Factory
+{
+public:
+
+ // = Initialization and termination methods.
+
+ /// Constructor.
+ TAO_FT_Persistent_Naming_Context_Factory (void);
+
+ /// Destructor. Does not deallocate the hash map: if an instance of
+ /// this class goes out of scope, its hash_map remains in persistent storage.
+ virtual ~TAO_FT_Persistent_Naming_Context_Factory (void);
+
+ /// Factory method for creating an implementation object for naming contexts
+ virtual TAO_Persistent_Naming_Context* create_naming_context_impl (
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO_Persistent_Context_Index *context_index,
+ HASH_MAP * map = 0,
+ ACE_UINT32 *counter = 0);
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* TAO_FT_PERSISTENT_NAMING_CONTEXT_FACTORY_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp
new file mode 100644
index 00000000000..132d2a25d3a
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp
@@ -0,0 +1,76 @@
+// -*- C++ -*-
+// $Id$
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h"
+
+#include "orbsvcs/PortableGroup/PG_conf.h"
+
+#include "tao/debug.h"
+#include "tao/ORB_Constants.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_FT_Round_Robin::TAO_FT_Round_Robin (void)
+ : lock_ (),
+ location_index_map_ (TAO_PG_MAX_OBJECT_GROUPS)
+{
+}
+
+TAO_FT_Round_Robin::~TAO_FT_Round_Robin (void)
+{
+}
+
+
+bool
+TAO_FT_Round_Robin::next_location (
+ PortableGroup::ObjectGroup_ptr object_group,
+ TAO_FT_Naming_Manager *naming_manager,
+ PortableGroup::Location& location)
+{
+ const PortableGroup::ObjectGroupId id =
+ naming_manager->get_object_group_id (object_group);
+
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ monitor,
+ this->lock_,
+ 0);
+
+ PortableGroup::Locations_var locations =
+ naming_manager->locations_of_members (object_group);
+
+ const CORBA::ULong len = locations->length ();
+
+ // No locations exist, so we can't get the next one
+ if (len == 0)
+ return false;
+
+ TAO_FT_Location_Index_Map::ENTRY * entry;
+ if (this->location_index_map_.find (id, entry) == 0)
+ {
+ CORBA::ULong & i = entry->int_id_;
+
+ if (len <= i)
+ i = 0; // Reset, i.e. wrap around
+
+ location = locations[i];
+
+ // Increment index to point to next location.
+ ++i;
+
+ return true;
+ }
+
+ // Could not find an entry
+ // Create an entry at location 0
+ CORBA::ULong start = 0;
+ location = locations[start++];
+ if (this->location_index_map_.bind (id, start) != 0)
+ { // The location was already bound or some failure occured. Should not happen.
+ throw CORBA::INTERNAL ();
+ }
+ return true;
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h
new file mode 100644
index 00000000000..3708771bba8
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h
@@ -0,0 +1,95 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Round_Robin.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef FT_ROUND_ROBIN_H
+#define FT_ROUND_ROBIN_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/Null_Mutex.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Location_Index_Map.h"
+
+
+#include "orbsvcs/CosLoadBalancingS.h"
+#include "ace/Vector_T.h"
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+
+class TAO_FT_Naming_Manager;
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class TAO_LB_RoundRobin_Strategy
+ *
+ * @brief "Round Robin" load balancing strategy used by the
+ * TAO_FT_Naming_Service.
+ *
+ * This load balancing strategy is designed to select an object group
+ * member residing at the next location from an object group managed
+ * by a specific Naming Manager. It selects an object from the object
+ * group in the order in which they are stored.
+ */
+class TAO_FtNaming_Export TAO_FT_Round_Robin
+{
+public:
+
+ /// Constructor.
+ TAO_FT_Round_Robin (void);
+
+ /// This function obtains the next object's location as it is bound
+ /// within the object group.
+ /// @param naming_manager The TAO_FT_Naming_Manager which houses the
+ /// object groups.
+ /// @param location The resulting location
+ /// @param object_group The object group from which the object is to
+ /// be selected
+ /// @return False on error. Returns true if a valid object can
+ /// be selected using the Round Robin load balancing strategy.
+ virtual bool next_location (
+ PortableGroup::ObjectGroup_ptr object_group,
+ TAO_FT_Naming_Manager *naming_manager,
+ PortableGroup::Location& location);
+
+ /// Destructor
+ virtual ~TAO_FT_Round_Robin (void);
+
+private:
+
+ /// Lock used to ensure atomic access to state retained by this
+ /// class.
+ TAO_SYNCH_MUTEX lock_;
+
+ /// Table that maps PortableGroup::ObjectGroupId to location
+ /// sequence index specific to a given object group.
+ /**
+ * The location sequence corresponds to the sequence containing the
+ * locations of the members of a given object group. The value
+ * stored in this map corresponds to the index of the next element
+ * in that sequence. For example, if the index stored in the map is
+ * 2, location[2] will be used when retrieving the object reference
+ * to be returned from the Strategy::next_member() method.
+ */
+ TAO_FT_Location_Index_Map location_index_map_;
+
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* FT_ROUND_ROBIN_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp
new file mode 100644
index 00000000000..653b4ef90c0
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp
@@ -0,0 +1,183 @@
+// $Id$
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h"
+#include "orbsvcs/FT_NamingManagerC.h"
+#include "orbsvcs/PortableGroup/PG_Utils.h"
+#include "orbsvcs/PortableGroup/PG_Property_Utils.h"
+
+#include "orbsvcs/Naming/Persistent_Context_Index.h"
+#include "ace/OS_NS_stdio.h"
+
+#include "ace/Auto_Ptr.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// Initialize the static naming manager
+TAO_FT_Naming_Manager *TAO_FT_Storable_Naming_Context::naming_manager_ = 0;
+
+TAO_FT_Storable_Naming_Context::TAO_FT_Storable_Naming_Context (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO_Storable_Naming_Context_Factory *cxt_factory,
+ TAO::Storable_Factory *pers_factory)
+ : TAO_Storable_Naming_Context (orb,
+ poa,
+ poa_id,
+ cxt_factory,
+ pers_factory),
+ stale_ (false)
+{
+
+}
+
+
+TAO_FT_Storable_Naming_Context::~TAO_FT_Storable_Naming_Context (void)
+{
+ // Perform appropriate cleanup based on the destruction level specified.
+}
+
+
+CORBA::Boolean
+TAO_FT_Storable_Naming_Context::is_object_group (CORBA::Object_ptr obj) const
+{
+ // Ensure the object is not nil first. If so, it cannot be an ObjectGroup.
+ if (CORBA::is_nil (obj))
+ return 0;
+
+ // If there is a tagged component with tag = IOP::TAG_FT_GROUP in the
+ // object reference then it is an object group
+ PortableGroup::TagGroupTaggedComponent tagged_component;
+ return TAO::PG_Utils::get_tagged_component (obj, tagged_component);
+}
+
+CORBA::Object_ptr
+TAO_FT_Storable_Naming_Context::resolve (const CosNaming::Name& n)
+{
+ // Invoke the base class resolve operation to acquire the object at the
+ // specified compound name. Any exceptions should flow back to client.
+ CORBA::Object_var resolved_ref =
+ TAO_Storable_Naming_Context::resolve(n);
+
+ ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon, this->lock_,
+ CORBA::INTERNAL ());
+
+ try {
+
+ // Make sure object is an object group.
+ // We will return the object reference as is all the way back
+ // out to the client if not
+ if (!this->is_object_group (resolved_ref.in ()))
+ return resolved_ref._retn ();
+
+ // If there is no naming manager, we will fail and report an error.
+ if ( this->naming_manager_ == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO_FT_Storable_Naming_Context::resolve ")
+ ACE_TEXT ("- No NamingManager defined.\n")));
+
+ throw CORBA::INTERNAL ();
+ }
+
+ // The Naming Manager will apply the appropriate strategy to get the
+ // next object reference from the object group.
+ resolved_ref = this->naming_manager_->next_member (resolved_ref.in ());
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ // This is apparently not an object group, so we should return the
+ // object reference itself
+ // No action required
+ }
+ catch (CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("TAO_FT_Storable_Naming_Context::resolve - ")
+ ACE_TEXT ("Some unhandled error occurred\n"));
+ return CORBA::Object::_nil ();
+ }
+
+ return resolved_ref._retn ();
+}
+
+int
+TAO_FT_Storable_Naming_Context::propagate_update_notification (
+ FT_Naming::ChangeType change_type)
+{
+ // Notify the peer of the changed context
+ FT_Naming::ReplicationManager_var peer =
+ TAO_FT_Naming_Replication_Manager::peer_replica ();
+
+ if (CORBA::is_nil (peer.in ()))
+ {
+ // Replication is not supported without a peer replica.
+ return 1;
+ }
+
+ FT_Naming::NamingContextUpdate context_info;
+ context_info.context_name = this->context_name_.c_str ();
+
+ // We are are updating the context one element before the specified name
+ context_info.change_type = change_type;
+
+ try {
+ // Notify the naming_manager of the updated context
+ peer->notify_updated_context (context_info);
+ }
+ catch (CORBA::Exception& ex)
+ {
+ if (TAO_debug_level > 3)
+ ex._tao_print_exception (ACE_TEXT ("Unable to communicate with peer.\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+TAO_FT_Storable_Naming_Context::set_naming_manager (
+ TAO_FT_Naming_Manager *mgr_impl)
+{
+ naming_manager_ = mgr_impl;
+}
+
+void
+TAO_FT_Storable_Naming_Context::stale (bool is_stale)
+{
+ this->stale_ = is_stale;
+}
+
+
+bool
+TAO_FT_Storable_Naming_Context::stale (void)
+{
+ return stale_;
+}
+
+
+void
+TAO_FT_Storable_Naming_Context::context_written (void)
+{
+ FT_Naming::ChangeType change_type;
+
+ if (this->destroyed_)
+ change_type = FT_Naming::DELETED;
+ else
+ change_type = FT_Naming::UPDATED;
+
+ propagate_update_notification (change_type);
+}
+
+bool
+TAO_FT_Storable_Naming_Context::is_obsolete (time_t stored_time)
+{
+ // If data has never been loaded, then the context_ object will
+ // be a null pointer.
+ return ((this->context_ == 0) || // Has not been loaded
+ this->stale () || // Explicitly marked stale by peer
+ (stored_time > this->last_changed_)); // File has been updated
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h
new file mode 100644
index 00000000000..96b0f4d0317
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Storable_Naming_Context.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_FT_STORABLE_NAMING_CONTEXT_H
+#define TAO_FT_STORABLE_NAMING_CONTEXT_H
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/Naming/Storable_Naming_Context.h"
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+#include "orbsvcs/orbsvcs/PortableGroupC.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h"
+#include "orbsvcs/FT_NamingReplicationC.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class FT_TAO_Storable_Naming_Context
+ *
+ * @brief This class specializes the TAO_Storable_Naming_Context
+ * 'ConcreteImplementor' in the Bridge pattern architecture of the
+ * CosNaming::NamingContext implementation.
+ *
+ */
+class TAO_FtNaming_Export TAO_FT_Storable_Naming_Context :
+ public TAO_Storable_Naming_Context
+{
+public:
+ // = Initialization and termination methods.
+
+ /**
+ * Constructor that takes in preallocated data structure and takes
+ * ownership of it. Derived class from TAO_Persistent_Naming_Context
+ * provides specialization of the resolve operation to support
+ * load balancing.
+ */
+ TAO_FT_Storable_Naming_Context (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO_Storable_Naming_Context_Factory *cxt_factory,
+ TAO::Storable_Factory *factory);
+
+ /// Destructor.
+ virtual ~TAO_FT_Storable_Naming_Context (void);
+
+ /**
+ * Override the resolve operation to support load balancing using
+ * the object group manager and associated strategy.
+ */
+ virtual CORBA::Object_ptr resolve (const CosNaming::Name &n);
+
+ // Set the Naming Manager as a static so that it is available for all
+ // naming context implementations.
+ static void set_naming_manager (TAO_FT_Naming_Manager *mgr_impl);
+
+ bool is_object_group (const CORBA::Object_ptr obj) const;
+
+ /**
+ * Tell the peer replica that this context has been updated.
+ * Returns 0 if successfully reported. Returns 1 if no peer
+ * has been registered. Returns -1 on failure to communicate
+ * with the peer.
+ */
+ int propagate_update_notification (FT_Naming::ChangeType change_type);
+
+ /**
+ * Find the indicated context below this context. Returns 0
+ * if it cannot be found.
+ */
+ TAO_FT_Storable_Naming_Context* find_relative_context (
+ const CosNaming::Name &n);
+
+ /**
+ * Mark the implementation as stale for replicated persistence support.
+ */
+ virtual void stale (bool is_stale);
+
+ virtual bool stale (void);
+
+ /**
+ * An internal utility used to signal that this context was updated.
+ * Check the last_changed_ attribute for the time of the write.
+ */
+ void context_written (void);
+
+ /**
+ * An internal callback invoked by the File_Open_Lock_and_Check
+ * object to determine if this context is obsolete with respect to the
+ * file object .
+ */
+ virtual bool is_obsolete (time_t stored_time);
+
+protected:
+
+ static TAO_FT_Naming_Manager *naming_manager_;
+ bool stale_;
+
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* TAO_FT_STORABLE_NAMING_CONTEXT_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp
new file mode 100644
index 00000000000..9a35f407ab7
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp
@@ -0,0 +1,47 @@
+// $Id$
+
+#include "orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ /// Constructor.
+TAO_FT_Storable_Naming_Context_Factory::TAO_FT_Storable_Naming_Context_Factory (
+ size_t hash_table_size)
+ : TAO_Storable_Naming_Context_Factory (hash_table_size)
+{
+
+}
+
+ /// Destructor. Does not deallocate the hash map: if an instance of
+ /// this class goes out of scope, its hash_map remains in persistent storage.
+TAO_FT_Storable_Naming_Context_Factory::~TAO_FT_Storable_Naming_Context_Factory (void)
+{
+
+}
+
+
+TAO_Storable_Naming_Context*
+TAO_FT_Storable_Naming_Context_Factory::create_naming_context_impl (
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO::Storable_Factory *persistence_factory
+ )
+{
+ // Construct the naming context, forwarding the map and counter
+ // even if they are defaulted
+ TAO_FT_Storable_Naming_Context *context_impl;
+ ACE_NEW_THROW_EX (context_impl,
+ TAO_FT_Storable_Naming_Context (orb,
+ poa,
+ poa_id,
+ this,
+ persistence_factory),
+ CORBA::NO_MEMORY ());
+
+ return context_impl;
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h
new file mode 100644
index 00000000000..b714d052914
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h
@@ -0,0 +1,66 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file FT_Storable_Naming_Context_Factory.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_FT_STORABLE_NAMING_CONTEXT_FACTORY_H
+#define TAO_FT_STORABLE_NAMING_CONTEXT_FACTORY_H
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/Naming/Storable_Naming_Context_Factory.h"
+#include "tao/ORB.h"
+#include "orbsvcs/Naming/nsconf.h"
+#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h"
+#include "orbsvcs/Naming/Hash_Naming_Context.h"
+#include "orbsvcs/Naming/Storable_Naming_Context.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class TAO_Naming_Context_Factory
+ *
+ * @brief
+ */
+class TAO_FtNaming_Export TAO_FT_Storable_Naming_Context_Factory :
+ public TAO_Storable_Naming_Context_Factory
+{
+public:
+
+ /// Data structure used by TAO_Persistent_Context_Index -
+ /// typedef for ease of use.
+ typedef TAO_Storable_Naming_Context_Factory::HASH_MAP HASH_MAP;
+
+ // = Initialization and termination methods.
+
+ /// Constructor.
+ TAO_FT_Storable_Naming_Context_Factory (
+ size_t hash_table_size = ACE_DEFAULT_MAP_SIZE);
+
+ /// Destructor. Does not deallocate the hash map: if an instance of
+ /// this class goes out of scope, its hash_map remains in persistent storage.
+ virtual ~TAO_FT_Storable_Naming_Context_Factory (void);
+
+ /// Factory method for creating an implementation object for naming contexts.
+ /// If an existing naming context implementation is being rebuilt,
+ /// the map and counter parameters should be provided to the underlying
+ /// HASH_MAP implementation
+ virtual TAO_Storable_Naming_Context* create_naming_context_impl (
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO::Storable_Factory *factory);
+
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* TAO_FT_STORABLE_NAMING_CONTEXT_FACTORY_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_export.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_export.h
new file mode 100644
index 00000000000..e8a204363c9
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl TAO_FtNaming
+// ------------------------------
+#ifndef TAO_FTNAMING_EXPORT_H
+#define TAO_FTNAMING_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (TAO_FTNAMING_HAS_DLL)
+# define TAO_FTNAMING_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && TAO_FTNAMING_HAS_DLL */
+
+#if !defined (TAO_FTNAMING_HAS_DLL)
+# define TAO_FTNAMING_HAS_DLL 1
+#endif /* ! TAO_FTNAMING_HAS_DLL */
+
+#if defined (TAO_FTNAMING_HAS_DLL) && (TAO_FTNAMING_HAS_DLL == 1)
+# if defined (TAO_FTNAMING_BUILD_DLL)
+# define TAO_FtNaming_Export ACE_Proper_Export_Flag
+# define TAO_FTNAMING_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define TAO_FTNAMING_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* TAO_FTNAMING_BUILD_DLL */
+# define TAO_FtNaming_Export ACE_Proper_Import_Flag
+# define TAO_FTNAMING_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define TAO_FTNAMING_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* TAO_FTNAMING_BUILD_DLL */
+#else /* TAO_FTNAMING_HAS_DLL == 1 */
+# define TAO_FtNaming_Export
+# define TAO_FTNAMING_SINGLETON_DECLARATION(T)
+# define TAO_FTNAMING_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* TAO_FTNAMING_HAS_DLL == 1 */
+
+// Set TAO_FTNAMING_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (TAO_FTNAMING_NTRACE)
+# if (ACE_NTRACE == 1)
+# define TAO_FTNAMING_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define TAO_FTNAMING_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !TAO_FTNAMING_NTRACE */
+
+#if (TAO_FTNAMING_NTRACE == 1)
+# define TAO_FTNAMING_TRACE(X)
+#else /* (TAO_FTNAMING_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define TAO_FTNAMING_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (TAO_FTNAMING_NTRACE == 1) */
+
+#endif /* TAO_FTNAMING_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_intf_export.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_intf_export.h
new file mode 100644
index 00000000000..6b52adde64a
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_intf_export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl TAO_FtNaming_Intf
+// ------------------------------
+#ifndef TAO_FTNAMING_INTF_EXPORT_H
+#define TAO_FTNAMING_INTF_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (TAO_FTNAMING_INTF_HAS_DLL)
+# define TAO_FTNAMING_INTF_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && TAO_FTNAMING_INTF_HAS_DLL */
+
+#if !defined (TAO_FTNAMING_INTF_HAS_DLL)
+# define TAO_FTNAMING_INTF_HAS_DLL 1
+#endif /* ! TAO_FTNAMING_INTF_HAS_DLL */
+
+#if defined (TAO_FTNAMING_INTF_HAS_DLL) && (TAO_FTNAMING_INTF_HAS_DLL == 1)
+# if defined (TAO_FTNAMING_INTF_BUILD_DLL)
+# define TAO_FtNaming_Intf_Export ACE_Proper_Export_Flag
+# define TAO_FTNAMING_INTF_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define TAO_FTNAMING_INTF_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* TAO_FTNAMING_INTF_BUILD_DLL */
+# define TAO_FtNaming_Intf_Export ACE_Proper_Import_Flag
+# define TAO_FTNAMING_INTF_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define TAO_FTNAMING_INTF_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* TAO_FTNAMING_INTF_BUILD_DLL */
+#else /* TAO_FTNAMING_INTF_HAS_DLL == 1 */
+# define TAO_FtNaming_Intf_Export
+# define TAO_FTNAMING_INTF_SINGLETON_DECLARATION(T)
+# define TAO_FTNAMING_INTF_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* TAO_FTNAMING_INTF_HAS_DLL == 1 */
+
+// Set TAO_FTNAMING_INTF_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (TAO_FTNAMING_INTF_NTRACE)
+# if (ACE_NTRACE == 1)
+# define TAO_FTNAMING_INTF_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define TAO_FTNAMING_INTF_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !TAO_FTNAMING_INTF_NTRACE */
+
+#if (TAO_FTNAMING_INTF_NTRACE == 1)
+# define TAO_FTNAMING_INTF_TRACE(X)
+#else /* (TAO_FTNAMING_INTF_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define TAO_FTNAMING_INTF_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (TAO_FTNAMING_INTF_NTRACE == 1) */
+
+#endif /* TAO_FTNAMING_INTF_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp
new file mode 100644
index 00000000000..bc134bd8626
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp
@@ -0,0 +1,717 @@
+//=============================================================================
+/**
+ * @file nsgroup_svc.cpp
+ *
+ * $Id$
+ *
+ * This file implements nsgroup utility operations
+ *
+ * @author Phillip LaBanca <labancap@ociweb.com>
+ */
+//=============================================================================
+
+#include "orbsvcs/Naming/FaultTolerant/nsgroup_svc.h"
+#include "ace/OS_NS_strings.h"
+
+
+NS_group_svc::NS_group_svc (void)
+{
+}
+
+FT_Naming::LoadBalancingStrategyValue
+NS_group_svc::determine_policy_string (const ACE_TCHAR *policy)
+{
+ if (ACE_OS::strcasecmp (policy,
+ ACE_TEXT_ALWAYS_CHAR ("rand")) == 0) {
+ return FT_Naming::RANDOM;
+ } else if (ACE_OS::strcasecmp (policy,
+ ACE_TEXT_ALWAYS_CHAR ("least")) == 0) {
+ return FT_Naming::LEAST;
+ } else {
+ return FT_Naming::ROUND_ROBIN; // Default case
+ }
+}
+
+int
+NS_group_svc::set_orb( CORBA::ORB_ptr orb)
+{
+
+ this->orb_ = CORBA::ORB::_duplicate (orb);
+
+ if (CORBA::is_nil (this->orb_))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" (%P|%t) Unable to initialize the ")
+ ACE_TEXT ("ORB.\n")),
+ -1);
+ return 0;
+}
+
+int
+NS_group_svc::set_naming_manager( FT_Naming::NamingManager_ptr nm)
+{
+
+ this->naming_manager_ = FT_Naming::NamingManager::_duplicate (nm);
+
+ if (CORBA::is_nil (this->naming_manager_))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" (%P|%t) Invalid Naming Manager.\n")),
+ -1);
+ return 0;
+}
+
+int
+NS_group_svc::set_name_context( CosNaming::NamingContextExt_ptr nc)
+{
+
+ this->name_service_ = CosNaming::NamingContextExt::_duplicate (nc);
+
+ if (CORBA::is_nil (this->name_service_))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" (%P|%t) Invalid Name Context.\n")),
+ -1);
+ return 0;
+}
+
+bool
+NS_group_svc::group_exist (
+ const ACE_TCHAR* group_name
+)
+{
+ if (group_name == 0 )
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("group_exist args not provided\n")),
+ false);
+ }
+
+ try
+ {
+ PortableGroup::ObjectGroup_var group_var =
+ this->naming_manager_->get_object_group_ref_from_name (group_name);
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * The naming service shall provide a command line utility for creating
+ * object groups. Adds the object group to to the load balancing service
+ * with the specified selection policy. On Creation, an object group
+ * contains no member objects.
+ */
+
+int
+NS_group_svc::group_create (
+ const ACE_TCHAR* group_name,
+ const ACE_TCHAR* policy )
+{
+
+ if (group_name == 0 || policy == 0 )
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("group_create args not provided\n")),
+ -2);
+ }
+
+ try
+ {
+
+ /// Verify that the group does not already exist
+ /// Group names must be unique
+ if ( true == group_exist (ACE_TEXT_ALWAYS_CHAR (group_name)))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Group %C already exists\n"),
+ group_name),
+ -1);
+ }
+
+ PortableGroup::Criteria criteria (1);
+ criteria.length (1);
+
+ PortableGroup::Property &property = criteria[0];
+ property.nam.length (1);
+
+ property.nam[0].id = CORBA::string_dup (
+ ACE_TEXT_ALWAYS_CHAR ("org.omg.PortableGroup.MembershipStyle"));
+
+ PortableGroup::MembershipStyleValue msv = PortableGroup::MEMB_APP_CTRL;
+ property.val <<= msv;
+
+ CORBA::Object_var obj =
+ this->naming_manager_->create_object_group (
+ ACE_TEXT_ALWAYS_CHAR (group_name),
+ determine_policy_string(ACE_TEXT_ALWAYS_CHAR (policy)),
+ criteria);
+
+ if (CORBA::is_nil (obj.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to create group %C.\n"),
+ group_name),
+ -1);
+ }
+
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to create group %C\n"),
+ group_name),
+ -1);
+ }
+
+ return 0;
+}
+
+/**
+ * The naming service shall provide a command line utility for binding an object
+ * group to a path in the naming service.
+ * Binds the specified object group to the specified path in the naming service.
+ * When clients resolve that path, they tranparently obtain a member of the
+ * specified object group.
+ */
+int
+NS_group_svc::group_bind (
+ const ACE_TCHAR* group_name,
+ const ACE_TCHAR* path)
+{
+
+ if (group_name == 0 || path == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("group_bind args not provided\n")),
+ -2);
+ }
+
+ try
+ {
+
+ PortableGroup::ObjectGroup_var group_var =
+ this->naming_manager_->get_object_group_ref_from_name (
+ ACE_TEXT_ALWAYS_CHAR(group_name));
+
+ if (CORBA::is_nil (group_var.in()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to get reference.\n")),
+ -1);
+
+ CORBA::String_var str = CORBA::string_dup( ACE_TEXT_ALWAYS_CHAR (path) );
+ CosNaming::Name_var name = this->name_service_->to_name ( str.in() );
+
+ this->name_service_->rebind (name.in(), group_var.in());
+
+ }
+ catch (const CosNaming::NamingContextExt::InvalidName& ex){
+ ex._tao_print_exception ("InvalidName Exception in group_bind");
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\n%C is invalid\n"),
+ path),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::CannotProceed&){
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nCannot proceed with %C\n"),
+ path),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::NotFound&){
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find %C\n"),
+ path),
+ -1);
+ }
+ catch (const CORBA::SystemException& ex){
+
+ ex._tao_print_exception ("SystemException Exception in group_bind");
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to bind %C\n"),
+ path),
+ -1);
+ }
+ catch (const CORBA::Exception& ex){
+
+ ex._tao_print_exception ("Exception in group_bind");
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to bind %C\n"),
+ path),
+ -1);
+ }
+ return 0;
+}
+
+int
+NS_group_svc::group_unbind (const ACE_TCHAR* path){
+ if ( path == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("group_unbind args not provided\n")),
+ -2);
+ }
+
+ try
+ {
+
+ CORBA::String_var str = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR (path));
+ CosNaming::Name_var name = this->name_service_->to_name ( str.in() );
+ this->name_service_->unbind (name.in());
+
+ }
+ catch (const CosNaming::NamingContext::NotFound&){
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find %C\n"),
+ path),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::CannotProceed&){
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nCannot proceed with %C\n"),
+ path),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::InvalidName&) {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\n%C is invalid\n"),
+ path),
+ -1);
+ }
+ catch (const CORBA::SystemException& ex) {
+
+ ex._tao_print_exception ("Exception in group_unbind");
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to unbind %C\n"),
+ path),
+ -1);
+ }
+ catch (const CORBA::Exception& ex) {
+
+ ex._tao_print_exception ("Exception in group_unbind");
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to unbind %C\n"),
+ path),
+ -1);
+ }
+ return 0;
+}
+
+/**
+ * The naming service shall provide a command line utility to display all
+ * defined object groups within the naming service.
+ * Displays all object groups that currently exist in the naming service.
+ */
+int
+NS_group_svc::group_list (void)
+{
+
+ // KCS: The group list is independent of locations. I created a new operation in the
+ // naming manager IDL to support requesting the group list - which is a list of names
+
+ /// Display object group list for each load balancing strategy
+ int rc = 0;
+ if( display_load_policy_group (FT_Naming::ROUND_ROBIN,
+ ACE_TEXT ("Round Robin")) < 0 )
+ {
+ rc = -1;
+ }
+ if( display_load_policy_group (FT_Naming::RANDOM,
+ ACE_TEXT ("Random")) < 0 )
+ {
+ rc = -1;
+ }
+ if( display_load_policy_group (FT_Naming::LEAST,
+ ACE_TEXT ("Least")) < 0 )
+ {
+ rc = -1;
+ }
+ return rc;
+}
+
+int
+NS_group_svc::display_load_policy_group(
+ FT_Naming::LoadBalancingStrategyValue strategy,
+ const ACE_TCHAR *display_label) {
+
+ if( display_label == 0 ) {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("display_load_policy_group args ")
+ ACE_TEXT ("not provided\n")),
+ -2);
+ }
+
+ try
+ {
+
+ FT_Naming::GroupNames_var list = this->naming_manager_->groups (strategy);
+
+ std::cout << ACE_TEXT ("\n")
+ << display_label
+ << ACE_TEXT (" Load Balancing Groups:")
+ << std::endl;
+
+ if ( list->length () > 0 ) {
+
+ for (unsigned int i = 0; i < list->length (); ++i)
+ {
+ std::cout << ACE_TEXT (" ")
+ << (*list)[i]
+ << std::endl;
+ }
+
+ } else {
+
+ std::cout << ACE_TEXT ("No ")
+ << display_label
+ << ACE_TEXT (" Load Balancing Groups Registered")
+ << std::endl;
+
+ }
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception in group_list");
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to get %C group list\n"),
+ display_label),
+ -1);
+ }
+ return 0;
+}
+
+/**
+ * The naming service shall provide a command line utility to modify the load
+ * balancing strategy for a specified object group.
+ * Changes the selection algorithm for the specified object group. An object
+ * group's selection algorithm determines how the naming service directs client
+ * requests to object group members.
+ */
+int
+NS_group_svc::group_modify (
+ const ACE_TCHAR* group_name,
+ const ACE_TCHAR* policy)
+{
+ if (group_name == 0 || policy == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("group_modify args not provided\n")),
+ -2);
+ }
+
+ try
+ {
+ this->naming_manager_->set_load_balancing_strategy (
+ ACE_TEXT_ALWAYS_CHAR (group_name),
+ determine_policy_string(policy) );
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find group %C\n"),
+ group_name),
+ -1);
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to modify group %C\n"),
+ group_name),
+ -1);
+ }
+
+ return 0;
+}
+
+/**
+ * The naming service shall provide a command line utility to remove a specified
+ * object group from the naming service.
+ * Removes the specified object group from the naming service.
+ */
+int
+NS_group_svc::group_remove (const ACE_TCHAR* group_name)
+{
+ if (group_name == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("group_remove args not provided\n")),
+ -2);
+ }
+
+ try
+ {
+ this->naming_manager_->delete_object_group (
+ ACE_TEXT_ALWAYS_CHAR (group_name));
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find group %C\n"),
+ group_name),
+ -1);
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to remove group %C\n"),
+ group_name),
+ -1);
+ }
+
+ return 0;
+}
+
+/**
+ * The naming service shall provide a command line utility for adding object
+ * references to an object group.
+ * Adds an object to the specified object group. After being added, the object
+ * is available for selection.
+ */
+int
+NS_group_svc::member_add (
+ const ACE_TCHAR* group_name,
+ const ACE_TCHAR* location,
+ const ACE_TCHAR* ior)
+{
+ if (group_name == 0 || location == 0 || ior == 0 )
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("member_add args not provided\n")),
+ -2);
+ }
+
+ try
+ {
+ PortableGroup::Location location_name;
+ location_name.length (1);
+ location_name[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR (location));
+
+ PortableGroup::ObjectGroup_var group_var =
+ this->naming_manager_->get_object_group_ref_from_name (
+ ACE_TEXT_ALWAYS_CHAR (group_name));
+
+ CORBA::Object_var ior_var =
+ this->orb_->string_to_object(ACE_TEXT_ALWAYS_CHAR (ior));
+
+ if (CORBA::is_nil (ior_var.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nInvalid member IOR provided.\n")),
+ -1);
+ }
+
+ this->naming_manager_->add_member (
+ group_var.in(),
+ location_name,
+ ior_var.in());
+
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find group %C\n"),
+ group_name),
+ -1);
+ }
+ catch (const PortableGroup::ObjectNotAdded&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to add location %C to group %C\n"),
+ location, group_name),
+ -1);
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to add location %C to group %C\n"),
+ location, group_name),
+ -1);
+ }
+
+ return 0;
+}
+
+/**
+ * The naming service shall provide a command line utility for displaying all
+ * members (object references) for a specified object group.
+ * Lists the members of the specified object group.
+ */
+int
+NS_group_svc::member_list (const ACE_TCHAR* group_name)
+{
+ if (group_name == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("member_list args not provided\n")),
+ -2);
+ }
+
+ try
+ {
+ PortableGroup::ObjectGroup_var group_var =
+ this->naming_manager_->get_object_group_ref_from_name (
+ ACE_TEXT_ALWAYS_CHAR (group_name));
+
+ PortableGroup::Locations_var locations =
+ this->naming_manager_->locations_of_members (group_var.in());
+
+ for (unsigned int i = 0; i < locations->length(); ++i)
+ {
+ const PortableGroup::Location & loc = locations[i];
+ if (loc.length() > 0) {
+ std::cout << loc[0].id.in() << std::endl;
+ }
+ }
+
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find group %C\n"),
+ group_name),
+ -1);
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to list members for group %C\n"),
+ group_name),
+ -1);
+ }
+
+ return 0;
+}
+
+/**
+ * The naming service shall provide a command line utility for removing object
+ * references from an object group.
+ * Removes the specified member object from the specified object group.
+ */
+int
+NS_group_svc::member_remove (
+ const ACE_TCHAR* group_name,
+ const ACE_TCHAR* location)
+{
+ if (group_name == 0 || location == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("member_remove args not provided\n")),
+ -2);
+ }
+
+ /**
+ * Remove an object at a specific location from the given
+ * ObjectGroup. Deletion of application created objects must be
+ * deleted by the application. Objects created by the
+ * infrastructure (load balancer) will be deleted by the
+ * infrastructure.
+ */
+
+ try
+ {
+ PortableGroup::Location location_name;
+ location_name.length (1);
+ location_name[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR (location));
+
+ PortableGroup::ObjectGroup_var group_var =
+ this->naming_manager_->get_object_group_ref_from_name (
+ ACE_TEXT_ALWAYS_CHAR (group_name));
+
+ this->naming_manager_->remove_member (
+ group_var.in(),
+ location_name);
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find group %C\n"),
+ group_name),
+ -1);
+ }
+ catch (const PortableGroup::MemberNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find member %C\n"),
+ location),
+ -1);
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to remove member %C\n"),
+ location),
+ -1);
+ }
+
+ return 0;
+}
+
+/**
+ * The naming service shall provide a command line utility to display an object
+ * reference from a specified object group.
+ * Displays the object reference that cooresponds to the specified member of an
+ * object group.
+ */
+int
+NS_group_svc::member_show (
+ const ACE_TCHAR* group_name,
+ const ACE_TCHAR* location)
+{
+ if (group_name == 0 || location == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("member_show args not provided\n")),
+ -2);
+ }
+
+ //Get and display IOR for the member location
+ try
+ {
+ PortableGroup::Location location_name (1);
+ location_name.length (1);
+ location_name[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR (location));
+
+ PortableGroup::ObjectGroup_var group_var =
+ this->naming_manager_->get_object_group_ref_from_name (
+ ACE_TEXT_ALWAYS_CHAR (group_name));
+
+ CORBA::Object_var ior_var =
+ this->naming_manager_->get_member_ref (group_var.in(), location_name);
+
+ CORBA::String_var ior_string =
+ this->orb_->object_to_string (ior_var.in());
+
+ std::cout << ior_string.in() << std::endl;
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find group %C\n"),
+ group_name),
+ -1);
+ }
+ catch (const PortableGroup::MemberNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to find member location %C\n"),
+ location),
+ -1);
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("\nUnable to show member location %C\n"),
+ location),
+ -1);
+ }
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.h
new file mode 100644
index 00000000000..6f819780764
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.h
@@ -0,0 +1,184 @@
+//==========================================================================
+/**
+ * @file nsgroup_svc.h
+ *
+ * $Id$
+ *
+ * @author Phillip LaBanca <labancap@ociweb.com>
+ */
+//==========================================================================
+
+#ifndef i_nsgroup_svc_h
+#define i_nsgroup_svc_h
+
+#include "orbsvcs/FT_NamingManagerC.h"
+#include /**/ "orbsvcs/Naming/FaultTolerant/ftnaming_intf_export.h"
+
+/**
+ * @class NS_group_svc
+ *
+ * @brief Encapsulate the NS group operations in a class.
+ *
+ *
+ */
+class TAO_FtNaming_Intf_Export NS_group_svc
+{
+public:
+
+ /**
+ * Constructor
+ */
+ NS_group_svc (void);
+
+ /**
+ * The naming service shall provide a command line utility for creating
+ * object groups.
+ *
+ * @param group group name
+ * @param policy round | rand | least
+ *
+ * @return 0 on success, -1 on failure, -2 on bad argument.
+ */
+ int group_create (const ACE_TCHAR* group, const ACE_TCHAR* policy);
+
+ /**
+ * The naming service shall provide a command line utility for binding an
+ * object group to a path in the naming service.
+ *
+ * @param group group name
+ * @param path stringified name in the naming service
+ *
+ * @return 0 on success, -1 on failure, -2 on bad argument.
+ */
+ int group_bind (const ACE_TCHAR* group, const ACE_TCHAR* path);
+
+ /**
+ * @param group group name
+ * @param path stringified name in the naming service
+ *
+ * @return 0 on success, -1 on failure, -2 on bad argument.
+ */
+ int group_unbind (const ACE_TCHAR* path);
+
+ /**
+ * The naming service shall provide a command line utility to display all
+ * defined object groups within the naming service.
+ *
+ * @return 0 on success, -1 on failure, -2 on bad argument.
+ */
+ int group_list (void);
+
+ /**
+ * The naming service shall provide a command line utility to modify the load
+ * balancing strategy for a specified object group.
+ *
+ * @param group group name
+ * @param policy round | rand | least
+ *
+ * @return 0 on success, -1 on failure, -2 on bad argument.
+ */
+ int group_modify (const ACE_TCHAR* group, const ACE_TCHAR* policy);
+
+ /**
+ * The naming service shall provide a command line utility to remove a
+ * specified object group from the naming service.
+ *
+ * @param group group name
+ *
+ * @return 0 on success, -1 on failure, -2 on bad argument.
+ */
+ int group_remove (const ACE_TCHAR* group);
+
+ /**
+ * The naming service shall provide a command line utility for adding object
+ * references to an object group.
+ *
+ * @param group group name
+ * @param location member location string
+ * @param ior member stringified ior
+ *
+ * @return 0 on success, -1 on failure, -2 on bad argument.
+ */
+ int member_add (const ACE_TCHAR* group,
+ const ACE_TCHAR* location,
+ const ACE_TCHAR* ior);
+
+ /**
+ * The naming service shall provide a command line utility for displaying all
+ * members (object references) for a specified object group.
+ *
+ * @param group group name
+ *
+ * @return 0 on success, -1 on failure, -2 on bad argument.
+ */
+ int member_list (const ACE_TCHAR* group);
+
+ /**
+ * The naming service shall provide a command line utility for removing
+ * object references from an object group.
+ *
+ * @param group group name
+ * @param location member location string
+ *
+ * @return 0 on success, -1 on failure, -2 on bad argument.
+ */
+ int member_remove (const ACE_TCHAR* group, const ACE_TCHAR* location);
+
+ /**
+ * The naming service shall provide a command line utility to display an
+ * object reference from a specified object group.
+ *
+ * @param group group name
+ * @param location member location string
+ *
+ * @return zero for success; nonzero for failure.
+ */
+ int member_show (const ACE_TCHAR* group, const ACE_TCHAR* location);
+
+ /**
+ * @param group group name
+ *
+ * @return true if the specified object group name is found
+ */
+ bool group_exist (const ACE_TCHAR* group_name);
+
+ /**
+ * @return 0 on success, -1 on failure.
+ */
+ int set_orb( CORBA::ORB_ptr value);
+
+ /**
+ * @return 0 on success, -1 on failure.
+ */
+ int set_naming_manager( FT_Naming::NamingManager_ptr value);
+
+ /**
+ * @return 0 on success, -1 on failure.
+ */
+ int set_name_context( CosNaming::NamingContextExt_ptr value);
+
+private:
+
+ /**
+ * determine stategy based on policy string value default to ROUND_ROBIN
+ *
+ * @param policy round | rand | least
+ */
+ FT_Naming::LoadBalancingStrategyValue determine_policy_string (const ACE_TCHAR *policy);
+
+ /**
+ * @return 0 on success, -1 on failure.
+ */
+ int display_load_policy_group( FT_Naming::LoadBalancingStrategyValue strategy, const ACE_TCHAR *display_label);
+
+private:
+
+ FT_Naming::NamingManager_var naming_manager_;
+
+ CosNaming::NamingContextExt_var name_service_;
+
+ CORBA::ORB_var orb_;
+
+};
+
+#endif
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Flat_File_Persistence.cpp b/TAO/orbsvcs/orbsvcs/Naming/Flat_File_Persistence.cpp
deleted file mode 100644
index 072951cd015..00000000000
--- a/TAO/orbsvcs/orbsvcs/Naming/Flat_File_Persistence.cpp
+++ /dev/null
@@ -1,386 +0,0 @@
-// $Id$
-
-//-----------------------------------------------------------------------------
-// Flat File class implementations
-//-----------------------------------------------------------------------------
-#include "orbsvcs/Naming/Flat_File_Persistence.h"
-
-#include "ace/Log_Msg.h"
-#include "ace/Numeric_Limits.h"
-#include "ace/Auto_Ptr.h"
-#include "ace/OS_NS_sys_stat.h"
-#include "ace/OS_NS_unistd.h"
-#include "ace/OS_NS_fcntl.h"
-
-TAO_BEGIN_VERSIONED_NAMESPACE_DECL
-
-TAO_NS_FlatFileStream::TAO_NS_FlatFileStream (const ACE_CString & file,
- const char * mode)
- : fl_ (0)
-{
- ACE_TRACE("TAO_NS_FlatFileStream");
- file_ = file;
- mode_ = mode;
-}
-
-TAO_NS_FlatFileStream::~TAO_NS_FlatFileStream ()
-{
- ACE_TRACE("~TAO_NS_FlatFileStream");
- if ( fl_ != 0 )
- this->close();
-}
-
-void
-TAO_NS_FlatFileStream::remove ()
-{
- ACE_TRACE("remove");
- ACE_OS::unlink(ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()));
-}
-
-int
-TAO_NS_FlatFileStream::exists ()
-{
- ACE_TRACE("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_NS_FlatFileStream::open()
-{
- ACE_TRACE("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 = "r+";
- 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_NS_FlatFileStream::close()
-{
- ACE_TRACE("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_NS_FlatFileStream::flock (int whence, int start, int len)
-{
- ACE_TRACE("flock");
-#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_NS_FlatFileStream::funlock (int whence, int start, int len)
-{
- ACE_TRACE("funlock");
-#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_NS_FlatFileStream::last_changed(void)
-{
- ACE_TRACE("TAO_NS_FlatFileStream::last_changed");
- ACE_stat st;
- ACE_OS::fstat(filelock_.handle_, &st);
- return st.st_mtime;
-}
-
-TAO_Storable_Base &
-TAO_NS_FlatFileStream::operator <<(
- const TAO_NS_Persistence_Header &header)
-{
- ACE_TRACE("TAO_NS_FlatFileStream::operator <<");
- ACE_OS::rewind(this->fl_);
- ACE_OS::fprintf(this->fl_, "%d\n%d\n", header.size(), header.destroyed());
- ACE_OS::fflush(this->fl_);
-
- return *this;
-}
-
-TAO_Storable_Base &
-TAO_NS_FlatFileStream::operator >>(
- TAO_NS_Persistence_Header &header)
-{
- ACE_TRACE("TAO_NS_FlatFileStream::operator >>");
- unsigned int size;
- int destroyed;
-
- ACE_OS::rewind(this->fl_);
- switch (fscanf(fl_, "%u\n", &size))
- {
- case 0:
- this->setstate (badbit);
- return *this;
- case EOF:
- this->setstate (eofbit);
- return *this;
- }
- header.size(size);
-
- switch (fscanf(fl_, "%d\n", &destroyed))
- {
- case 0:
- this->setstate (badbit);
- return *this;
- case EOF:
- this->setstate (eofbit);
- return *this;
- }
- header.destroyed(destroyed);
-
- return *this;
-
-}
-
-TAO_Storable_Base &
-TAO_NS_FlatFileStream::operator <<(
- const TAO_NS_Persistence_Record &record)
-{
- ACE_TRACE("TAO_NS_FlatFileStream::operator <<");
- TAO_NS_Persistence_Record::Record_Type type = record.type();
- ACE_OS::fprintf(this->fl_, "%d\n", type);
-
- ACE_CString id = record.id();
- ACE_OS::fprintf(this->fl_, ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT("\n%s\n"),
- id.length(), id.c_str());
-
- ACE_CString kind = record.kind();
- ACE_OS::fprintf(this->fl_, ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("\n%s\n"),
- kind.length(), kind.c_str());
-
- ACE_CString ref = record.ref();
- ACE_OS::fprintf(this->fl_, ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT ("\n%s\n"),
- ref.length(), ref.c_str());
-
- ACE_OS::fflush(this->fl_);
-
- return *this;
-}
-
-TAO_Storable_Base &
-TAO_NS_FlatFileStream::operator >>(TAO_NS_Persistence_Record &record)
-{
- ACE_TRACE("TAO_NS_FlatFileStream::operator >>");
-
- int temp_type_in;
- switch (fscanf(fl_, "%d\n", &temp_type_in))
- {
- case 0:
- this->setstate (badbit);
- return *this;
- case EOF:
- this->setstate (eofbit);
- return *this;
- }
- TAO_NS_Persistence_Record::Record_Type type =
- (TAO_NS_Persistence_Record::Record_Type) temp_type_in;
- record.type (type);
-
- int bufSize = 0;
- ACE_CString::size_type const max_buf_len =
- ACE_Numeric_Limits<ACE_CString::size_type>::max ();
-
- //id
- switch (fscanf(fl_, "%d\n", &bufSize))
- {
- case 0:
- this->setstate (badbit);
- return *this;
- case EOF:
- this->setstate (eofbit);
- return *this;
- }
-
- if (bufSize < 0
- || static_cast<ACE_CString::size_type> (bufSize) >= max_buf_len)
- {
- this->setstate (badbit);
- return *this;
- }
- {
- ACE_Auto_Basic_Array_Ptr<char> the_id (new char[bufSize + 1]);
- the_id[0] = '\0';
- if (ACE_OS::fgets (ACE_TEXT_CHAR_TO_TCHAR (the_id.get ()),
- bufSize + 1,
- fl_) == 0
- && bufSize != 0)
- {
- this->setstate (badbit);
- return *this;
- }
- record.id (ACE_CString (the_id.get (), 0, false));
- }
-
- //kind
- switch (fscanf(fl_, "%d\n", &bufSize))
- {
- case 0:
- this->setstate (badbit);
- return *this;
- case EOF:
- this->setstate (eofbit);
- return *this;
- }
-
- if (bufSize < 0
- || static_cast<ACE_CString::size_type> (bufSize) >= max_buf_len)
- {
- this->setstate (badbit);
- return *this;
- }
-
- {
- ACE_Auto_Basic_Array_Ptr<char> the_kind (new char[bufSize + 1]);
- the_kind[0] = '\0';
- if (ACE_OS::fgets (ACE_TEXT_CHAR_TO_TCHAR (the_kind.get ()),
- bufSize + 1,
- fl_) == 0
- && bufSize != 0)
- {
- this->setstate (badbit);
- return *this;
- }
- record.kind (ACE_CString (the_kind.get (), 0, false));
- }
-
- //ref
- switch (fscanf(fl_, "%d\n", &bufSize))
- {
- case 0:
- this->setstate (badbit);
- return *this;
- case EOF:
- this->setstate (eofbit);
- return *this;
- }
-
- if (bufSize < 0
- || static_cast<ACE_CString::size_type> (bufSize) >= max_buf_len)
- {
- this->setstate (badbit);
- return *this;
- }
-
- {
- ACE_Auto_Basic_Array_Ptr<char> the_ref (new char[bufSize + 1]);
- the_ref[0] = '\0';
- if (ACE_OS::fgets (ACE_TEXT_CHAR_TO_TCHAR (the_ref.get ()),
- bufSize + 1,
- fl_) == 0
- && bufSize != 0)
- {
- this->setstate (badbit);
- return *this;
- }
- record.ref (ACE_CString (the_ref.get (), 0, false));
- }
-
- return *this;
-
-}
-
-TAO_Storable_Base &
-TAO_NS_FlatFileStream::operator <<(
- const TAO_NS_Persistence_Global &global)
-{
- ACE_TRACE("TAO_NS_FlatFileStream::operator <<");
- ACE_OS::rewind(this->fl_);
- ACE_OS::fprintf(this->fl_, "%d\n", global.counter());
- ACE_OS::fflush(this->fl_);
-
- return *this;
-}
-
-TAO_Storable_Base &
-TAO_NS_FlatFileStream::operator >>(
- TAO_NS_Persistence_Global &global)
-{
- ACE_TRACE("TAO_NS_FlatFileStream::operator >>");
- unsigned int counter = 0;
-
- ACE_OS::rewind(this->fl_);
- switch (fscanf(fl_, "%u\n", &counter))
- {
- case 0:
- this->setstate (badbit);
- break; // Still set the global.counter (to 0)
- case EOF:
- this->setstate (eofbit);
- break; // Still set the global.counter (to 0)
- }
- global.counter(counter);
-
- return *this;
-}
-
-
-TAO_Storable_Base *
-TAO_NS_FlatFileFactory::create_stream (const ACE_CString & file,
- const ACE_TCHAR * mode)
-{
- ACE_TRACE("TAO_NS_FlatFileFactory::create_stream");
- TAO_Storable_Base *stream = 0;
-
- ACE_NEW_RETURN (stream,
- TAO_NS_FlatFileStream(file, ACE_TEXT_ALWAYS_CHAR (mode)),
- 0);
- return stream;
-}
-
-TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Flat_File_Persistence.h b/TAO/orbsvcs/orbsvcs/Naming/Flat_File_Persistence.h
deleted file mode 100644
index 7b03ba75b03..00000000000
--- a/TAO/orbsvcs/orbsvcs/Naming/Flat_File_Persistence.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// -*- C++ -*-
-
-//=============================================================================
-/**
- * @file Flat_File_Persistence.h
- *
- * $Id$
- *
- * @author Marina Spivak <marina@cs.wustl.edu>
- */
-//=============================================================================
-
-#ifndef TAO_FLAT_FILE_PERSISTENCE_H
-#define TAO_FLAT_FILE_PERSISTENCE_H
-
-#include "orbsvcs/Naming/Storable.h"
-#include "ace/OS_NS_stdio.h"
-
-TAO_BEGIN_VERSIONED_NAMESPACE_DECL
-
-//------------------------------------------------------------------------
-// The Flat File concrete classes
-//------------------------------------------------------------------------
-class TAO_NS_FlatFileStream : public TAO_Storable_Base
-{
-public:
-
- TAO_NS_FlatFileStream(const ACE_CString & file, const char * mode);
- virtual ~TAO_NS_FlatFileStream();
-
- /// Remove a file by name (file is not open)
- virtual void remove();
-
- /// 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();
-
- /// Close an open file
- 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);
-
- /// Write a header to disk
- virtual TAO_Storable_Base& operator << (
- const TAO_NS_Persistence_Header& header);
-
- /// Read a header from disk
- virtual TAO_Storable_Base& operator >> (
- TAO_NS_Persistence_Header& header);
-
- /// Write a record to disk
- virtual TAO_Storable_Base& operator << (
- const TAO_NS_Persistence_Record& record);
-
- /// Read a record from disk
- virtual TAO_Storable_Base& operator >> (
- TAO_NS_Persistence_Record& record);
-
- /// Write the global data to disk
- virtual TAO_Storable_Base& operator << (
- const TAO_NS_Persistence_Global& global);
-
- /// Read the global data from disk
- virtual TAO_Storable_Base& operator >> (
- TAO_NS_Persistence_Global& global);
-
-private:
- ACE_OS::ace_flock_t filelock_;
- FILE* fl_;
- ACE_CString file_;
- ACE_CString mode_;
-};
-
-class TAO_NS_FlatFileFactory : public TAO_Naming_Service_Persistence_Factory
-{
-public:
- // Factory Methods
-
- /// Create the stream that can operate on a disk file
- virtual TAO_Storable_Base *create_stream(const ACE_CString & file,
- const ACE_TCHAR * mode);
-};
-
-TAO_END_VERSIONED_NAMESPACE_DECL
-
-#endif
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Hash_Naming_Context.cpp b/TAO/orbsvcs/orbsvcs/Naming/Hash_Naming_Context.cpp
index f3b6182e33e..de3c6d1c4f5 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Hash_Naming_Context.cpp
+++ b/TAO/orbsvcs/orbsvcs/Naming/Hash_Naming_Context.cpp
@@ -97,10 +97,6 @@ TAO_Hash_Naming_Context::get_context (const CosNaming::Name &name)
void
TAO_Hash_Naming_Context::bind (const CosNaming::Name& n, CORBA::Object_ptr obj)
{
- ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
- ace_mon, this->lock_,
- CORBA::INTERNAL ());
-
// Check to make sure this object didn't have <destroy> method
// invoked on it.
if (this->destroyed_)
@@ -136,6 +132,10 @@ TAO_Hash_Naming_Context::bind (const CosNaming::Name& n, CORBA::Object_ptr obj)
// If we received a simple name, we need to bind it in this context.
else
{
+ ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
+ ace_mon, this->lock_,
+ CORBA::INTERNAL ());
+
// Try binding the name.
int result = this->context_->bind (n[0].id,
n[0].kind,
@@ -154,10 +154,6 @@ void
TAO_Hash_Naming_Context::rebind (const CosNaming::Name& n,
CORBA::Object_ptr obj)
{
- ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon,
- this->lock_,
- CORBA::INTERNAL ());
-
// Check to make sure this object didn't have <destroy> method
// invoked on it.
if (this->destroyed_)
@@ -194,6 +190,10 @@ TAO_Hash_Naming_Context::rebind (const CosNaming::Name& n,
// If we received a simple name, we need to rebind it in this
// context.
{
+ ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
int result = this->context_->rebind (n[0].id,
n[0].kind,
obj,
@@ -212,10 +212,6 @@ void
TAO_Hash_Naming_Context::bind_context (const CosNaming::Name &n,
CosNaming::NamingContext_ptr nc)
{
- ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon,
- this->lock_,
- CORBA::INTERNAL ());
-
// Check to make sure this object didn't have <destroy> method
// invoked on it.
if (this->destroyed_)
@@ -255,6 +251,10 @@ TAO_Hash_Naming_Context::bind_context (const CosNaming::Name &n,
// If we received a simple name, we need to bind it in this context.
else
{
+ ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
// Try binding the name.
int result = this->context_->bind (n[0].id,
n[0].kind,
@@ -273,10 +273,6 @@ void
TAO_Hash_Naming_Context::rebind_context (const CosNaming::Name &n,
CosNaming::NamingContext_ptr nc)
{
- ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon,
- this->lock_,
- CORBA::INTERNAL ());
-
// Check to make sure this object didn't have <destroy> method
// invoked on it.
if (this->destroyed_)
@@ -314,6 +310,10 @@ TAO_Hash_Naming_Context::rebind_context (const CosNaming::Name &n,
// If we received a simple name, we need to rebind it in this
// context.
{
+ ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
int result = this->context_->rebind (n[0].id,
n[0].kind,
nc,
@@ -332,9 +332,6 @@ TAO_Hash_Naming_Context::rebind_context (const CosNaming::Name &n,
CORBA::Object_ptr
TAO_Hash_Naming_Context::resolve (const CosNaming::Name& n)
{
- ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon, this->lock_,
- CORBA::INTERNAL ());
-
// Check to make sure this object didn't have <destroy> method
// invoked on it.
if (this->destroyed_)
@@ -355,14 +352,16 @@ TAO_Hash_Naming_Context::resolve (const CosNaming::Name& n)
// Stores the object reference bound to the first name component.
CORBA::Object_var result;
- if (this->context_->find (n[0].id,
- n[0].kind,
- result.out (),
- type) == -1)
- throw CosNaming::NamingContext::NotFound(
- CosNaming::NamingContext::missing_node,
- n);
-
+ {
+ ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon, this->lock_,
+ CORBA::INTERNAL ());
+ if (this->context_->find (n[0].id,
+ n[0].kind,
+ result.out (),
+ type) == -1)
+ throw CosNaming::NamingContext::NotFound
+ (CosNaming::NamingContext::missing_node, n);
+ }
// If the name we have to resolve is a compound name, we need to
// resolve it recursively.
if (name_len > 1)
@@ -410,11 +409,25 @@ TAO_Hash_Naming_Context::resolve (const CosNaming::Name& n)
}
catch (const CORBA::SystemException&)
{
- throw CosNaming::NamingContext::CannotProceed(
- context.in (), rest_of_name);
+ throw CosNaming::NamingContext::CannotProceed
+ (context.in (), rest_of_name);
}
}
}
+ else
+ {
+ ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
+ if (this->context_->find (n[0].id,
+ n[0].kind,
+ result.out (),
+ type) == -1)
+ throw CosNaming::NamingContext::NotFound
+ (CosNaming::NamingContext::missing_node, n);
+ }
+
// If the name we had to resolve was simple, we just need to return
// the result.
return result._retn ();
@@ -423,10 +436,6 @@ TAO_Hash_Naming_Context::resolve (const CosNaming::Name& n)
void
TAO_Hash_Naming_Context::unbind (const CosNaming::Name& n)
{
- ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon,
- this->lock_,
- CORBA::INTERNAL ());
-
// Check to make sure this object didn't have <destroy> method
// invoked on it.
if (this->destroyed_)
@@ -463,20 +472,21 @@ TAO_Hash_Naming_Context::unbind (const CosNaming::Name& n)
// If we received a simple name, we need to unbind it in this
// context.
else
- if (this->context_->unbind (n[0].id,
- n[0].kind) == -1)
- throw CosNaming::NamingContext::NotFound(
- CosNaming::NamingContext::missing_node, n);
+ {
+ ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX, ace_mon,
+ this->lock_,
+ CORBA::INTERNAL ());
+
+ if (this->context_->unbind (n[0].id,
+ n[0].kind) == -1)
+ throw CosNaming::NamingContext::NotFound
+ (CosNaming::NamingContext::missing_node, n);
+ }
}
CosNaming::NamingContext_ptr
TAO_Hash_Naming_Context::bind_new_context (const CosNaming::Name& n)
{
- ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
- ace_mon,
- this->lock_,
- CORBA::INTERNAL ());
-
// Check to make sure this object didn't have <destroy> method
// invoked on it.
if (this->destroyed_)
@@ -506,16 +516,15 @@ TAO_Hash_Naming_Context::bind_new_context (const CosNaming::Name& n)
// If we received a simple name, we need to bind it in this context.
// Stores our new Naming Context.
- CosNaming::NamingContext_var result =
- CosNaming::NamingContext::_nil ();
+ CosNaming::NamingContext_var result = CosNaming::NamingContext::_nil ();
// Create new context.
- result = new_context ();
+ result = this->new_context ();
// Bind the new context to the name.
try
{
- bind_context (n, result.in ());
+ this->bind_context (n, result.in ());
}
catch (const CORBA::Exception&)
{
@@ -540,11 +549,6 @@ TAO_Hash_Naming_Context::bind_new_context (const CosNaming::Name& n)
void
TAO_Hash_Naming_Context::destroy (void)
{
- ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
- ace_mon,
- this->lock_,
- CORBA::INTERNAL ());
-
// Check to make sure this object didn't have <destroy> method
// invoked on it.
if (this->destroyed_)
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.cpp b/TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.cpp
index df5cb7b77e7..675ce30a086 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.cpp
+++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.cpp
@@ -461,8 +461,28 @@ TAO_Naming_Context::resolve_str (const char * n)
return this->resolve (name.in ());
}
+void
+TAO_Naming_Context::stale (bool value)
+{
+ this->impl_->stale (value);
+}
+
TAO_Naming_Context_Impl::~TAO_Naming_Context_Impl (void)
{
}
+void
+TAO_Naming_Context_Impl::stale (bool value)
+{
+ ACE_UNUSED_ARG (value);
+ // Default implementation is no-op
+}
+
+bool
+TAO_Naming_Context_Impl::stale (void)
+{
+ // Default implementation is to reply false
+ return false;
+}
+
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.h b/TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.h
index 27d907e5f36..8a0fb32be8e 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.h
+++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Context_Interface.h
@@ -177,6 +177,12 @@ public:
*/
virtual CORBA::Object_ptr resolve_str (const char * n);
+ /**
+ * Mark the implementation stale state for replicated
+ * persistence support.
+ */
+ void stale (bool value);
+
/// Returns the Default POA of this Servant object
virtual PortableServer::POA_ptr _default_POA (void);
@@ -339,6 +345,18 @@ public:
/// Returns the Default POA of this Servant object
virtual PortableServer::POA_ptr _default_POA (void) = 0;
+
+ /**
+ * Set the stale flag for replicated persistence support.
+ */
+ virtual void stale (bool value);
+
+ /**
+ * Query if the the implementation is stale for replicated
+ * persistence support.
+ */
+ virtual bool stale (void);
+
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.cpp b/TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.cpp
index 44736086700..72b836a1c9f 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.cpp
+++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.cpp
@@ -17,19 +17,25 @@
#include "ace/Dynamic_Service.h"
#include "ace/Argv_Type_Converter.h"
-
-
+#include "orbsvcs/Naming/Naming_Server.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
-TAO_Naming_Loader::TAO_Naming_Loader (void)
+TAO_Naming_Loader::TAO_Naming_Loader (TAO_Naming_Server *server)
+: naming_server_(server)
{
// Constructor
+
+ // If no server was provided, then we will construct one of the
+ // base class type.
+ if (naming_server_ == 0)
+ ACE_NEW (naming_server_, TAO_Naming_Server);
}
TAO_Naming_Loader::~TAO_Naming_Loader (void)
{
- // Destructor
+ // Destroy the naming server that was created
+ delete naming_server_;
}
int
@@ -63,7 +69,7 @@ int
TAO_Naming_Loader::fini (void)
{
// Remove the Naming Service.
- return this->naming_server_.fini ();
+ return this->naming_server_->fini ();
}
CORBA::Object_ptr
@@ -71,10 +77,20 @@ TAO_Naming_Loader::create_object (CORBA::ORB_ptr orb,
int argc,
ACE_TCHAR *argv[])
{
- // Initializes the Naming Service. Returns -1
- // on an error.
- if (this->naming_server_.init_with_orb (argc, argv, orb) == -1)
- return CORBA::Object::_nil ();
+
+ if (this->naming_server_ == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO_Naming_Loader::create_object - naming_server_ ")
+ ACE_TEXT ("never set.\n")));
+ }
+ else
+ {
+ // Initializes the Naming Service. Returns -1
+ // on an error.
+ if (this->naming_server_->init_with_orb (argc, argv, orb) == -1)
+ return CORBA::Object::_nil ();
+ }
return CORBA::Object::_nil ();
}
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.h b/TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.h
index 7365fa103e7..c5bb1016bee 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.h
+++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Loader.h
@@ -33,7 +33,10 @@ class TAO_Naming_Serv_Export TAO_Naming_Loader : public TAO_Object_Loader
public:
/// Constructor
- TAO_Naming_Loader (void);
+ /// By default will use the standard Naming_Server. If a server is provided
+ /// it will use that one instead. This object takes ownership of the provided
+ /// Naming Server.
+ TAO_Naming_Loader (TAO_Naming_Server *server = 0);
/// Destructor
~TAO_Naming_Loader (void);
@@ -53,8 +56,9 @@ public:
ACE_TCHAR *argv[]);
protected:
+ /// TODO: Need to set up service configurator to initialize the naming server
/// Instance of the TAO_Naming_Server
- TAO_Naming_Server naming_server_;
+ TAO_Naming_Server* naming_server_;
private:
TAO_Naming_Loader (const TAO_Naming_Loader &);
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.cpp b/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.cpp
index 1a021f655ff..9aa2073f9b6 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.cpp
+++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.cpp
@@ -2,12 +2,17 @@
#include "orbsvcs/Naming/Naming_Server.h"
#include "orbsvcs/Naming/Transient_Naming_Context.h"
+#include "orbsvcs/Naming/Persistent_Naming_Context_Factory.h"
+#include "orbsvcs/Naming/Storable_Naming_Context_Factory.h"
+
#if !defined (CORBA_E_MICRO)
#include "orbsvcs/Naming/Persistent_Context_Index.h"
#include "orbsvcs/Naming/Storable_Naming_Context.h"
#include "orbsvcs/Naming/Storable_Naming_Context_Activator.h"
-#include "orbsvcs/Naming/Flat_File_Persistence.h"
+
+#include "tao/Storable_FlatFileStream.h"
+
#endif /* CORBA_E_MICRO */
#include "orbsvcs/CosNamingC.h"
@@ -269,6 +274,7 @@ TAO_Naming_Server::parse_args (int argc,
ACE_TEXT ("-p <pid_file_name> ")
ACE_TEXT ("-s <context_size> ")
ACE_TEXT ("-b <base_address> ")
+ ACE_TEXT ("-u <persistence dir name> ")
ACE_TEXT ("-m <1=enable multicast, 0=disable multicast(default) ")
ACE_TEXT ("%s")
ACE_TEXT ("-z <relative round trip timeout> ")
@@ -419,10 +425,12 @@ TAO_Naming_Server::init_with_orb (int argc,
return -1;
}
+ // If an ior file name was provided on command line
if (this->ior_file_name_ != 0)
{
- FILE *iorf = ACE_OS::fopen (this->ior_file_name_, ACE_TEXT("w"));
- if (iorf == 0)
+ CORBA::String_var ns_ior = this->naming_service_ior ();
+ if (this->write_ior_to_file (ns_ior.in (),
+ this->ior_file_name_) != 0)
{
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT("Unable to open %s for writing:(%u) %p\n"),
@@ -431,11 +439,6 @@ TAO_Naming_Server::init_with_orb (int argc,
ACE_TEXT("TAO_Naming_Server::init_with_orb")),
-1);
}
-
- CORBA::String_var str = this->naming_service_ior ();
-
- ACE_OS::fprintf (iorf, "%s\n", str.in ());
- ACE_OS::fclose (iorf);
}
if (this->pid_file_name_ != 0)
@@ -476,9 +479,18 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb,
// In lieu of a fully implemented service configurator version
// of this Reader and Writer, let's just take something off the
// command line for now.
- TAO_Naming_Service_Persistence_Factory* pf = 0;
- ACE_NEW_RETURN(pf, TAO_NS_FlatFileFactory, -1);
- auto_ptr<TAO_Naming_Service_Persistence_Factory> persFactory(pf);
+ TAO::Storable_Factory* pf = 0;
+ ACE_NEW_RETURN (pf, TAO::Storable_FlatFileFactory(persistence_location), -1);
+ auto_ptr<TAO::Storable_Factory> persFactory(pf);
+
+ // Use an auto_ptr to ensure that we clean up the factory in the case
+ // of a failure in creating and registering the Activator.
+ TAO_Storable_Naming_Context_Factory* cf =
+ this->storable_naming_context_factory (context_size);
+ // Make sure we got a factory
+ if (cf == 0) return -1;
+ auto_ptr<TAO_Storable_Naming_Context_Factory> contextFactory (cf);
+
// This instance will either get deleted after recreate all or,
// in the case of a servant activator's use, on destruction of the
// activator.
@@ -487,7 +499,7 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb,
if (persistence_location == 0)
{
// No, assign the default location "NameService"
- persistence_location = ACE_TEXT("NameService");
+ persistence_location = ACE_TEXT ("NameService");
}
// Now make sure this directory exists
@@ -502,34 +514,70 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb,
ACE_NEW_THROW_EX (this->servant_activator_,
TAO_Storable_Naming_Context_Activator (orb,
persFactory.get(),
- persistence_location,
- context_size),
+ contextFactory.get (),
+ persistence_location),
CORBA::NO_MEMORY ());
this->ns_poa_->set_servant_manager(this->servant_activator_);
}
#endif /* TAO_HAS_MINIMUM_POA */
+ try { // The following might throw an exception.
+ this->naming_context_ =
+ TAO_Storable_Naming_Context::recreate_all (orb,
+ poa,
+ TAO_ROOT_NAMING_CONTEXT,
+ context_size,
+ 0,
+ contextFactory.get (),
+ persFactory.get (),
+ use_redundancy_);
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ // The activator already took over the factories so we need to release the auto_ptr
+ if (this->use_servant_activator_)
+ {
+ // The context factory is now owned by the activator
+ // so we should release it
+ contextFactory.release ();
+ // If using a servant activator, the activator now owns the
+ // factory, so we should release it
+ persFactory.release ();
+ }
+ // Print out the exception and return failure
+ ex._tao_print_exception (
+ "TAO_Naming_Server::init_new_naming");
+ return -1;
+ }
+
+ // Kind of a duplicate of the above here, but we must also release the
+ // factory autoptrs in the good case as well.
+ if (this->use_servant_activator_)
+ {
+ // The context factory is now owned by the activator
+ // so we should release it
+ contextFactory.release ();
+ // If using a servant activator, the activator now owns the
+ // factory, so we should release it
+ persFactory.release ();
+ }
- this->naming_context_ =
- TAO_Storable_Naming_Context::recreate_all (orb,
- poa,
- TAO_ROOT_NAMING_CONTEXT,
- context_size,
- 0,
- persFactory.get(),
- persistence_location,
- use_redundancy_);
-
- if (this->use_servant_activator_)
- persFactory.release();
- }
+ }
else if (persistence_location != 0)
//
// Initialize Persistent Naming Service.
//
{
+
+ // Create Naming Context Implementation Factory to be used for the creation of
+ // naming contexts by the TAO_Persistent_Context_Index
+ TAO_Persistent_Naming_Context_Factory *naming_context_factory =
+ this->persistent_naming_context_factory ();
+ // Make sure we got a factory.
+ if (naming_context_factory == 0) return -1;
+
// Allocate and initialize Persistent Context Index.
ACE_NEW_RETURN (this->context_index_,
- TAO_Persistent_Context_Index (orb, poa),
+ TAO_Persistent_Context_Index (orb, poa, naming_context_factory),
-1);
if (this->context_index_->open (persistence_location,
@@ -706,6 +754,51 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb,
}
int
+TAO_Naming_Server::write_ior_to_file (const char* ior_string,
+ const char* file_name)
+{
+ if ((file_name != 0) &&
+ (ior_string != 0))
+ {
+ FILE *iorf = ACE_OS::fopen (file_name, ACE_TEXT("w"));
+ if (iorf == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT("Unable to open %s for writing:(%u) %p\n"),
+ file_name,
+ ACE_ERRNO_GET,
+ ACE_TEXT("Naming_Server::write_ior_to_file")),
+ -1);
+ }
+
+ ACE_OS::fprintf (iorf, "%s\n", ior_string);
+ ACE_OS::fclose (iorf);
+ }
+ else
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Invalid file name or IOR string provided")
+ ACE_TEXT ("to TAO_Naming_Server::write_ior_to_file\n")),
+ -1);
+
+ }
+
+ return 0;
+}
+
+TAO_Storable_Naming_Context_Factory *
+TAO_Naming_Server::storable_naming_context_factory (size_t context_size)
+{
+ return new (ACE_nothrow) TAO_Storable_Naming_Context_Factory (context_size);
+}
+
+TAO_Persistent_Naming_Context_Factory *
+TAO_Naming_Server::persistent_naming_context_factory (void)
+{
+ return new (ACE_nothrow) TAO_Persistent_Naming_Context_Factory;
+}
+
+int
TAO_Naming_Server::fini (void)
{
// First get rid of the multi cast handler
@@ -773,12 +866,17 @@ TAO_Naming_Server::operator-> (void) const
return this->naming_context_.ptr ();
}
+
TAO_Naming_Server::~TAO_Naming_Server (void)
{
#if (TAO_HAS_MINIMUM_POA == 0) && \
!defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
- if (this->use_servant_activator_)
- delete this->servant_activator_;
+ if (this->use_servant_activator_ &&
+ this->servant_activator_)
+ {
+ // Activator is reference counted. Don't delete it directly.
+ this->servant_activator_->_remove_ref ();
+ }
#endif /* TAO_HAS_MINIMUM_POA */
}
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.h b/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.h
index dd609ec461a..4d970da3706 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.h
+++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.h
@@ -34,6 +34,9 @@ class TAO_Persistent_Context_Index;
class TAO_Storable_Naming_Context_Activator;
#endif /* !CORBA_E_MICRO */
+class TAO_Storable_Naming_Context_Factory;
+class TAO_Persistent_Naming_Context_Factory;
+
/**
* @class TAO_Naming_Server
*
@@ -121,13 +124,13 @@ public:
/// Initialize the Naming Service with the command line arguments and
/// the ORB.
- int init_with_orb (int argc, ACE_TCHAR *argv [], CORBA::ORB_ptr orb);
+ virtual int init_with_orb (int argc, ACE_TCHAR *argv [], CORBA::ORB_ptr orb);
/// Destroy the child POA created in @c init_with_orb
- int fini (void);
+ virtual int fini (void);
/// Destructor.
- ~TAO_Naming_Server (void);
+ virtual ~TAO_Naming_Server (void);
/// Returns the IOR of the naming service.
char * naming_service_ior (void);
@@ -137,7 +140,8 @@ public:
protected:
/**
- * Helper method: create Naming Service locally.
+ * Helper method: create Naming Service locally. Can be specialized to
+ * refine how Naming Service components are created and initialized
* Make the root context of size
* <context_size>, register it under the <root_poa>, and make the Naming
* Service persistent if <persistence_location> is not 0.
@@ -146,7 +150,7 @@ protected:
* If <enable_multicast> is not zero then the service will respond
* to multicast location queries.
*/
- int init_new_naming (CORBA::ORB_ptr orb,
+ virtual int init_new_naming (CORBA::ORB_ptr orb,
PortableServer::POA_ptr root_poa,
const ACE_TCHAR *persistence_location,
void *base_addr,
@@ -157,7 +161,23 @@ protected:
int use_round_trip_timeout = 0);
/// parses the arguments.
- int parse_args (int argc, ACE_TCHAR *argv[]);
+ virtual int parse_args (int argc, ACE_TCHAR *argv[]);
+
+ /// Write the provided ior_string to the file. Return 0 if success.
+ int write_ior_to_file (const char* ior_string,
+ const char* file_name);
+
+ /* Factory method to create a naming context factory for use with
+ * the -u and -r options.
+ */
+ virtual TAO_Storable_Naming_Context_Factory *
+ storable_naming_context_factory (size_t context_size);
+
+ /* Factory method to create a naming context factory for use with
+ * the -f option.
+ */
+ virtual TAO_Persistent_Naming_Context_Factory *
+ persistent_naming_context_factory (void);
/// Root NamingContext_ptr.
CosNaming::NamingContext_var naming_context_;
@@ -233,6 +253,7 @@ protected:
/// If not zero use round trip timeout policy set to value specified
int round_trip_timeout_;
int use_round_trip_timeout_;
+
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.cpp b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.cpp
index 34b74c6b5de..5da2864d20e 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.cpp
+++ b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.cpp
@@ -2,6 +2,7 @@
#include "orbsvcs/Naming/Persistent_Context_Index.h"
#include "orbsvcs/Naming/Persistent_Naming_Context.h"
+#include "orbsvcs/Naming/Persistent_Naming_Context_Factory.h"
#include "tao/debug.h"
@@ -80,19 +81,22 @@ TAO_Persistent_Context_Index::bind (const char *poa_id,
TAO_Persistent_Context_Index::TAO_Persistent_Context_Index
(CORBA::ORB_ptr orb,
- PortableServer::POA_ptr poa)
+ PortableServer::POA_ptr poa,
+ TAO_Persistent_Naming_Context_Factory * context_impl_factory)
: allocator_ (0),
index_ (0),
index_file_ (0),
base_address_ (0),
orb_ (CORBA::ORB::_duplicate (orb)),
- poa_ (PortableServer::POA::_duplicate (poa))
+ poa_ (PortableServer::POA::_duplicate (poa)),
+ context_impl_factory_ (context_impl_factory)
{
}
TAO_Persistent_Context_Index::~TAO_Persistent_Context_Index (void)
{
delete allocator_;
+ delete context_impl_factory_;
ACE_OS::free (reinterpret_cast<void *> (const_cast<ACE_TCHAR *> (index_file_)));
}
@@ -181,17 +185,14 @@ TAO_Persistent_Context_Index::recreate_all (void)
{
index_iter->next (entry);
- // Put together a servant for the new Naming Context.
-
- TAO_Persistent_Naming_Context *context_impl = 0;
- ACE_NEW_RETURN (context_impl,
- TAO_Persistent_Naming_Context (poa_.in (),
- entry->ext_id_.poa_id_,
- this,
- entry->int_id_.hash_map_,
- entry->int_id_.counter_),
- -1);
-
+ // Put together a servant for the new Naming Context
+ // Using the naming context factory to create a naming context of the appropriate type
+ TAO_Persistent_Naming_Context *context_impl =
+ this->context_impl_factory_->create_naming_context_impl (poa_.in (),
+ entry->ext_id_.poa_id_,
+ this,
+ entry->int_id_.hash_map_,
+ entry->int_id_.counter_);
// Put <context_impl> into the auto pointer temporarily, in case next
// allocation fails.
@@ -228,6 +229,16 @@ TAO_Persistent_Context_Index::recreate_all (void)
return 0;
}
+TAO_Persistent_Naming_Context*
+TAO_Persistent_Context_Index::create_naming_context_impl (
+ PortableServer::POA_ptr poa,
+ const char *poa_id)
+{
+ return this->context_impl_factory_->create_naming_context_impl(poa,
+ poa_id,
+ this);
+}
+
int
TAO_Persistent_Context_Index::create_index (void)
{
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.h b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.h
index fe807eae71b..9b7f0a26010 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.h
+++ b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Context_Index.h
@@ -23,6 +23,9 @@
#include "ace/Malloc_T.h"
#include "ace/MMAP_Memory_Pool.h"
+class TAO_Persistent_Naming_Context;
+class TAO_Persistent_Naming_Context_Factory;
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
/**
@@ -64,8 +67,10 @@ public:
// = Initialization and termination methods.
/// Constructor.
- TAO_Persistent_Context_Index (CORBA::ORB_ptr orb,
- PortableServer::POA_ptr poa);
+ TAO_Persistent_Context_Index (
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ TAO_Persistent_Naming_Context_Factory *context_impl_factory);
/**
* Create ACE_Allocator, open/create memory-mapped file with the
@@ -86,6 +91,15 @@ public:
int init (size_t context_size);
/**
+ * Create a naming context implementation to be used for this index
+ * using the naming context factory that was provided in the ctor
+ * for the index.
+ */
+ TAO_Persistent_Naming_Context *create_naming_context_impl (
+ PortableServer::POA_ptr poa,
+ const char *poa_id);
+
+ /**
* Destructor. The memory mapped file that was opened/created is
* not deleted, since we want it to keep the state of the Naming
* Service until the next run.
@@ -161,6 +175,9 @@ private:
/// The reference to the root Naming Context.
CosNaming::NamingContext_var root_context_;
+
+ /// The factory for constructing naming contexts within the index
+ TAO_Persistent_Naming_Context_Factory *context_impl_factory_;
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.cpp b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.cpp
index caa29847f7b..6a90a325ae9 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.cpp
+++ b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.cpp
@@ -235,23 +235,6 @@ TAO_Persistent_Bindings_Map::shared_bind (const char * id,
TAO_Persistent_Naming_Context::TAO_Persistent_Naming_Context (PortableServer::POA_ptr poa,
const char *poa_id,
- TAO_Persistent_Context_Index *context_index)
-
- : TAO_Hash_Naming_Context (poa,
- poa_id),
- counter_ (0),
- persistent_context_ (0),
- index_ (context_index)
-{
- ACE_NEW (this->persistent_context_,
- TAO_Persistent_Bindings_Map (context_index->orb ()));
-
- // Set the superclass pointer.
- context_ = persistent_context_;
-}
-
-TAO_Persistent_Naming_Context::TAO_Persistent_Naming_Context (PortableServer::POA_ptr poa,
- const char *poa_id,
TAO_Persistent_Context_Index *context_index,
HASH_MAP *map,
ACE_UINT32 *counter)
@@ -267,7 +250,10 @@ TAO_Persistent_Naming_Context::TAO_Persistent_Naming_Context (PortableServer::PO
// Set the superclass pointer.
context_ = persistent_context_;
- persistent_context_->set (map, index_->allocator ());
+ // If a map was provided (i.e., not defaulted) then set it in the
+ // persistent_context_
+ if (map != 0)
+ persistent_context_->set (map, index_->allocator ());
}
int
@@ -309,12 +295,13 @@ TAO_Persistent_Naming_Context::make_new_context (PortableServer::POA_ptr poa,
// Put together a servant for the new Naming Context.
- TAO_Persistent_Naming_Context *context_impl = 0;
- ACE_NEW_THROW_EX (context_impl,
- TAO_Persistent_Naming_Context (poa,
- poa_id,
- ind),
- CORBA::NO_MEMORY ());
+ TAO_Persistent_Naming_Context *context_impl = ind->create_naming_context_impl(
+ poa,
+ poa_id);
+
+ // Verify that a context implementation was created. If not, throw an exception
+ if (context_impl == 0)
+ throw CORBA::NO_MEMORY ();
// Put <context_impl> into the auto pointer temporarily, in case next
// allocation fails.
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.h b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.h
index 8659c497466..56e7a886c1f 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.h
+++ b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.h
@@ -169,12 +169,6 @@ public:
// = Initialization and termination methods.
- /// Constructor. MUST be followed up by <init> to allocate the
- /// underlying data structure from persistent storage!
- TAO_Persistent_Naming_Context (PortableServer::POA_ptr poa,
- const char *poa_id,
- TAO_Persistent_Context_Index *context_index);
-
/// Allocate the underlying data structure from persistent storage.
/// Returns 0 on success and -1 on failure.
int init (size_t hash_table_size = ACE_DEFAULT_MAP_SIZE);
@@ -182,13 +176,15 @@ public:
/**
* Constructor that takes in preallocated data structure and takes
* ownership of it. This constructor is for 'recreating' servants
- * from persistent state.
+ * from persistent state. If no map is provided, it MUST be followed
+ * up by <init> to allocate the underlying data structure from
+ * persistent storage!
*/
TAO_Persistent_Naming_Context (PortableServer::POA_ptr poa,
const char *poa_id,
TAO_Persistent_Context_Index *context_index,
- HASH_MAP * map,
- ACE_UINT32 *counter);
+ HASH_MAP * map = 0,
+ ACE_UINT32 *counter = 0);
/// Destructor.
virtual ~TAO_Persistent_Naming_Context (void);
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.cpp b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.cpp
new file mode 100644
index 00000000000..6cc93bdef1f
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.cpp
@@ -0,0 +1,39 @@
+// $Id$
+
+#include "orbsvcs/Naming/Persistent_Naming_Context_Factory.h"
+#include "orbsvcs/Naming/Persistent_Naming_Context.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/// Constructor.
+TAO_Persistent_Naming_Context_Factory::TAO_Persistent_Naming_Context_Factory (void)
+{
+
+}
+
+/// Destructor. Does not deallocate the hash map: if an instance of
+/// this class goes out of scope, its hash_map remains in persistent storage.
+TAO_Persistent_Naming_Context_Factory::~TAO_Persistent_Naming_Context_Factory (void)
+{
+}
+
+
+/// Factory method for creating an implementation object for naming contexts
+TAO_Persistent_Naming_Context*
+TAO_Persistent_Naming_Context_Factory::create_naming_context_impl (
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO_Persistent_Context_Index *context_index,
+ HASH_MAP * map,
+ ACE_UINT32 *counter)
+{
+ // Construct the naming context, forwarding the map and counter even if they
+ // are defaulted
+ return new (ACE_nothrow) TAO_Persistent_Naming_Context (poa,
+ poa_id,
+ context_index,
+ map,
+ counter);
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.h b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.h
new file mode 100644
index 00000000000..570536be79c
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.h
@@ -0,0 +1,62 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Persistent_Naming_Context_Factory.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_PERSISTENT_NAMING_CONTEXT_FACTORY_H
+#define TAO_PERSISTENT_NAMING_CONTEXT_FACTORY_H
+#include /**/ "ace/pre.h"
+
+#include "tao/ORB.h"
+#include "orbsvcs/Naming/nsconf.h"
+#include "orbsvcs/Naming/naming_serv_export.h"
+#include "orbsvcs/Naming/Hash_Naming_Context.h"
+#include "orbsvcs/Naming/Persistent_Entries.h"
+#include "orbsvcs/Naming/Persistent_Naming_Context.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_Persistent_Naming_Context;
+
+/**
+ * @class TAO_Persistent_Naming_Context_Factory
+ *
+ * @brief A factory that creates TAO_Persistent_Naming_Context
+ * objects to implement the COS Naming Service NamingContext interface.
+ */
+class TAO_Naming_Serv_Export TAO_Persistent_Naming_Context_Factory
+{
+public:
+
+ // = Initialization and termination methods.
+ /// Data structure used by TAO_Persistent_Context_Index - typedef for ease of use.
+ typedef TAO_Persistent_Naming_Context::HASH_MAP HASH_MAP;
+
+ /// Constructor.
+ TAO_Persistent_Naming_Context_Factory (void);
+
+ /// Destructor. Does not deallocate the hash map: if an instance of
+ /// this class goes out of scope, its hash_map remains in persistent storage.
+ virtual ~TAO_Persistent_Naming_Context_Factory (void);
+
+ /// Factory method for creating an implementation object for naming contexts
+ virtual TAO_Persistent_Naming_Context*
+ create_naming_context_impl (PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO_Persistent_Context_Index *context_index,
+ HASH_MAP * map = 0,
+ ACE_UINT32 *counter = 0);
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* TAO_PERSISTENT_NAMING_CONTEXT_FACTORY_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable.h b/TAO/orbsvcs/orbsvcs/Naming/Storable.h
index 394a1863447..56755d18a0d 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Storable.h
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable.h
@@ -21,8 +21,9 @@
#pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
-#include "tao/Versioned_Namespace.h"
+#include "tao/Storable_Base.h"
#include "ace/SString.h"
+#include "orbsvcs/Naming/naming_serv_export.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -68,7 +69,7 @@ class TAO_NS_Persistence_Record
ACE_CString ref_;
};
-class TAO_NS_Persistence_Global
+class TAO_Naming_Serv_Export TAO_NS_Persistence_Global
{
public:
void counter (unsigned int counter);
@@ -78,84 +79,6 @@ class TAO_NS_Persistence_Global
unsigned int counter_;
};
-class TAO_Storable_Base
-{
-public:
- TAO_Storable_Base();
-
- virtual ~TAO_Storable_Base();
-
- virtual void remove() = 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;
-
- virtual TAO_Storable_Base& operator << (
- const TAO_NS_Persistence_Header& header) = 0;
-
- virtual TAO_Storable_Base& operator << (
- const TAO_NS_Persistence_Record& record) = 0;
-
- virtual TAO_Storable_Base& operator >> (
- TAO_NS_Persistence_Header& header) = 0;
-
- virtual TAO_Storable_Base& operator >> (
- TAO_NS_Persistence_Record& record) = 0;
-
- virtual TAO_Storable_Base& operator << (
- const TAO_NS_Persistence_Global& global) = 0;
-
- virtual TAO_Storable_Base& operator >> (
- TAO_NS_Persistence_Global& global) = 0;
-
-private:
- Storable_State state_;
-};
-
-class TAO_Naming_Service_Persistence_Factory
-{
-public:
- TAO_Naming_Service_Persistence_Factory();
-
- virtual ~TAO_Naming_Service_Persistence_Factory();
-
- // Factory Methods
-
- virtual TAO_Storable_Base *create_stream(const ACE_CString & file,
- const ACE_TCHAR * mode) = 0;
-};
-
TAO_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable.inl b/TAO/orbsvcs/orbsvcs/Naming/Storable.inl
index 2df1d497262..c020a68042e 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Storable.inl
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable.inl
@@ -99,69 +99,4 @@ TAO_NS_Persistence_Global::counter () const
return this->counter_;
}
-
-ACE_INLINE
-TAO_Naming_Service_Persistence_Factory::TAO_Naming_Service_Persistence_Factory()
-{
-}
-
-ACE_INLINE
-TAO_Naming_Service_Persistence_Factory::~TAO_Naming_Service_Persistence_Factory()
-{
-}
-
-ACE_INLINE
-TAO_Storable_Base::TAO_Storable_Base()
- : state_ (goodbit)
-{
-}
-
-ACE_INLINE
-TAO_Storable_Base::~TAO_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/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp
index e37f995cce6..51415d75293 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp
@@ -1,9 +1,13 @@
// $Id$
#include "orbsvcs/Naming/Storable_Naming_Context.h"
+#include "orbsvcs/Naming/Storable_Naming_Context_Factory.h"
+#include "orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.h"
#include "orbsvcs/Naming/Bindings_Iterator_T.h"
#include "tao/debug.h"
+#include "tao/Storable_Base.h"
+#include "tao/Storable_Factory.h"
#include "ace/Auto_Ptr.h"
#include "ace/OS_NS_stdio.h"
@@ -12,7 +16,7 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL
const char * TAO_Storable_Naming_Context::root_name_;
ACE_UINT32 TAO_Storable_Naming_Context::gcounter_;
-ACE_Auto_Ptr<TAO_Storable_Base> TAO_Storable_Naming_Context::gfl_;
+ACE_Auto_Ptr<TAO::Storable_Base> TAO_Storable_Naming_Context::gfl_;
int TAO_Storable_Naming_Context::redundant_;
TAO_Storable_IntId::TAO_Storable_IntId (void)
@@ -238,316 +242,138 @@ TAO_Storable_Bindings_Map::shared_bind (const char * id,
}
}
-void TAO_Storable_Naming_Context::Write(TAO_Storable_Base& wrtr)
+void TAO_Storable_Naming_Context::Write (TAO::Storable_Base& wrtr)
{
ACE_TRACE("Write");
- TAO_NS_Persistence_Header header;
-
- header.size (static_cast<unsigned int> (storable_context_->current_size()));
- header.destroyed (destroyed_);
-
- wrtr << header;
-
- if (0u == header.size ())
- return;
-
- ACE_Hash_Map_Iterator<TAO_Storable_ExtId,TAO_Storable_IntId,
- ACE_Null_Mutex> it = storable_context_->map().begin();
- ACE_Hash_Map_Iterator<TAO_Storable_ExtId,TAO_Storable_IntId,
- ACE_Null_Mutex> itend = storable_context_->map().end();
-
- ACE_Hash_Map_Entry<TAO_Storable_ExtId,TAO_Storable_IntId> ent = *it;
-
- while (!(it == itend))
- {
- TAO_NS_Persistence_Record record;
-
- ACE_CString name;
- CosNaming::BindingType bt = (*it).int_id_.type_;
- if (bt == CosNaming::ncontext)
- {
- CORBA::Object_var
- obj = orb_->string_to_object ((*it).int_id_.ref_.in ());
- if (obj->_is_collocated ())
- {
- // This is a local (i.e. non federated context) we therefore
- // store only the ObjectID (persistence filename) for the object.
-
- // The driving force behind storing ObjectIDs rather than IORs for
- // local contexts is to provide for a redundant naming service.
- // That is, a naming service that runs simultaneously on multiple
- // machines sharing a file system. It allows multiple redundant
- // copies to be started and stopped independently.
- // The original target platform was Tru64 Clusters where there was
- // a cluster address. In that scenario, clients may get different
- // servers on each request, hence the requirement to keep
- // synchronized to the disk. It also works on non-cluster system
- // where the client picks one of the redundant servers and uses it,
- // while other systems can pick different servers. (However in this
- // scenario, if a server fails and a client must pick a new server,
- // that client may not use any saved context IORs, instead starting
- // from the root to resolve names. So this latter mode is not quite
- // transparent to clients.) [Rich Seibel (seibel_r) of ociweb.com]
-
- PortableServer::ObjectId_var
- oid = poa_->reference_to_id (obj.in ());
- CORBA::String_var
- nm = PortableServer::ObjectId_to_string (oid.in ());
- const char
- *newname = nm.in ();
- name.set (newname); // The local ObjectID (persistance filename)
- record.type (TAO_NS_Persistence_Record::LOCAL_NCONTEXT);
- }
- else
- {
- // Since this is a foreign (federated) context, we can not store
- // the objectID (because it isn't in our storage), if we did, when
- // we restore, we would end up either not finding a permanent
- // record (and thus ending up incorrectly assuming the context was
- // destroyed) or loading another context altogether (just because
- // the contexts shares its objectID filename which is very likely).
- // [Simon Massey (sma) of prismtech.com]
-
- name.set ((*it).int_id_.ref_.in ()); // The federated context IOR
- record.type (TAO_NS_Persistence_Record::REMOTE_NCONTEXT);
- }
- }
- else // if (bt == CosNaming::nobject) // shouldn't be any other, can there?
- {
- name.set ((*it).int_id_.ref_.in ()); // The non-context object IOR
- record.type (TAO_NS_Persistence_Record::OBJREF);
- }
- record.ref(name);
-
- const char *myid = (*it).ext_id_.id();
- ACE_CString id(myid);
- record.id(id);
-
- const char *mykind = (*it).ext_id_.kind();
- ACE_CString kind(mykind);
- record.kind(kind);
-
- wrtr << record;
- it.advance();
- }
+ TAO_Storable_Naming_Context_ReaderWriter rw(wrtr);
+ rw.write(*this);
}
-// Helper function to load a new context into the binding_map
+// Helpers function to load a new context into the binding_map
int
-TAO_Storable_Naming_Context::load_map(File_Open_Lock_and_Check *flck)
+TAO_Storable_Naming_Context::load_map (TAO::Storable_Base& storable)
{
ACE_TRACE("load_map");
- // assume file already open for reading
- TAO_Storable_Bindings_Map *bindings_map;
-
- // create the new bindings map
- ACE_NEW_THROW_EX (bindings_map,
- TAO_Storable_Bindings_Map (hash_table_size_,orb_.in()),
- CORBA::NO_MEMORY ());
-
- // get the data for this bindings map from the file
-
- TAO_NS_Persistence_Header header;
- TAO_NS_Persistence_Record record;
+ TAO_Storable_Naming_Context_ReaderWriter rw (storable);
+ return rw.read (*this);
+}
- // we are only using the size from this header
- flck->peer() >> header;
- if (!flck->peer ().good ())
+TAO_Storable_Naming_Context::
+File_Open_Lock_and_Check::File_Open_Lock_and_Check (
+ TAO_Storable_Naming_Context * context,
+ Method_Type method_type)
+: TAO::Storable_File_Guard (TAO_Storable_Naming_Context::redundant_),
+ context_(context)
+{
+ try
{
- flck->peer ().clear ();
- throw CORBA::INTERNAL ();
+ this->init (method_type);
}
-
- // reset the destroyed flag
- this->destroyed_ = header.destroyed();
-
- // read in the data for the map
- for (unsigned int i= 0u; i<header.size(); ++i)
+ catch (const TAO::Storable_Read_Exception &)
{
- flck->peer() >> record;
- if (!flck->peer ().good ())
- {
- flck->peer ().clear ();
- throw CORBA::INTERNAL ();
- }
-
- if (TAO_NS_Persistence_Record::LOCAL_NCONTEXT == record.type ())
- {
- PortableServer::ObjectId_var
- id = PortableServer::string_to_ObjectId (record.ref ().c_str ());
- const char
- *intf = interface_->_interface_repository_id ();
- CORBA::Object_var
- objref = poa_->create_reference_with_id (id.in (), intf);
- bindings_map->bind ( record.id ().c_str (),
- record.kind ().c_str (),
- objref.in (),
- CosNaming::ncontext );
- }
- else
- {
- CORBA::Object_var
- objref = orb_->string_to_object (record.ref ().c_str ());
- bindings_map->bind ( record.id ().c_str (),
- record.kind ().c_str (),
- objref.in (),
- ((TAO_NS_Persistence_Record::REMOTE_NCONTEXT == record.type ())
- ? CosNaming::ncontext // REMOTE_NCONTEXT
- : CosNaming::nobject )); // OBJREF
- }
+ throw CORBA::INTERNAL ();
}
- storable_context_ = bindings_map;
- context_ = storable_context_;
- return 0;
}
TAO_Storable_Naming_Context::
-File_Open_Lock_and_Check::File_Open_Lock_and_Check(
- TAO_Storable_Naming_Context * context,
- const char * mode)
-:closed_(1),
- context_(context)
+File_Open_Lock_and_Check::~File_Open_Lock_and_Check ()
{
- ACE_TRACE("File_Open_Lock_and_Check");
- // We only accept a subset of mode argument, check it
- rwflags_ = 0;
- for( unsigned int i = 0; i<ACE_OS::strlen(mode); i++ )
- {
- switch (mode[i])
+ this->release ();
+
+ // Check if a write occurred for this context and
+ // notify the context if it did.
+ if (context_->write_occurred_ == 1)
{
- case 'r': rwflags_ |= mode_read;
- break;
- case 'w': rwflags_ |= mode_write;
- break;
- case 'c': rwflags_ |= mode_create;
- break;
- default: rwflags_ = -1;
+ context_->context_written ();
+ // We have to make sure we clear the flag
+ // for subsequent times through.
+ context_->write_occurred_ = 0;
}
- }
- if( rwflags_ <= 0 )
- {
- errno = EINVAL;
- throw CORBA::PERSIST_STORE();
- }
-
- // build the file name
- ACE_CString file_name(context->persistence_directory_);
- file_name += "/";
- file_name += context->name_;
-
- // Create the stream
- fl_ = context->factory_->create_stream(file_name, ACE_TEXT_CHAR_TO_TCHAR(mode));
- if (TAO_Storable_Naming_Context::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();
- }
+bool
+TAO_Storable_Naming_Context::
+File_Open_Lock_and_Check::object_obsolete (void)
+{
- // now that the file is successfully opened and locked it must be
- // unlocked/closed before we leave this class
- closed_ = 0;
+ // Query the underlying context if it is obsolete with respect
+ // to the provided file last-changed time
+ return (context_->is_obsolete (fl_->last_changed ()));
+}
- if ( ! (rwflags_ & mode_create) )
- {
- // Check if our copy is up to date
- time_t new_last_changed = fl_->last_changed();
- if( new_last_changed > context->last_changed_ )
- {
- context->last_changed_ = new_last_changed;
- // Throw our map away
- delete context->storable_context_;
- // and build a new one from disk
- context->load_map(this);
- }
- }
- }
- else if ( ! context->storable_context_ || (rwflags_ & mode_write) )
- {
- if (fl_->open() != 0)
- {
- delete fl_;
- throw CORBA::PERSIST_STORE();
- }
+void
+TAO_Storable_Naming_Context::
+File_Open_Lock_and_Check::mark_object_current (void)
+{
+ // Reset the stale flag
+ context_->stale (false);
+ // Set the last update time to the file last update time
+ this->set_object_last_changed (fl_->last_changed ());
+}
- // now that the file is successfully opened
- // unlocked/closed before we leave this class
- closed_ = 0;
+void
+TAO_Storable_Naming_Context::
+File_Open_Lock_and_Check::set_object_last_changed (const time_t & time)
+{
+ context_->last_changed_ = time;
+}
- if(!context->storable_context_)
- {
- // Load the map from disk
- context->load_map(this);
- }
- }
- else
- {
- // Need to insure that fl_ gets deleted
- delete fl_;
- }
+time_t
+TAO_Storable_Naming_Context::
+File_Open_Lock_and_Check::get_object_last_changed ()
+{
+ return context_->last_changed_;
}
void
TAO_Storable_Naming_Context::
-File_Open_Lock_and_Check::release(void)
+File_Open_Lock_and_Check::load_from_stream ()
{
- ACE_TRACE("release");
- if ( ! closed_ )
- {
- // If we updated the disk, save the time stamp
- if(TAO_Storable_Naming_Context::redundant_)
- {
- if( rwflags_ & mode_write )
- context_->last_changed_ = fl_->last_changed();
- fl_->funlock(0, 0, 0);
- }
- fl_->close();
- delete fl_;
- closed_ = 1;
- }
+ // Throw our map away
+ delete context_->storable_context_;
+ // and build a new one from disk
+ context_->load_map (this->peer());
}
+bool
TAO_Storable_Naming_Context::
-File_Open_Lock_and_Check::~File_Open_Lock_and_Check(void)
+File_Open_Lock_and_Check::is_loaded_from_stream ()
{
- ACE_TRACE("~File_Open_Lock_and_Check");
- this->release();
+ return context_->storable_context_ != 0;
}
-TAO_Storable_Base &
-TAO_Storable_Naming_Context::File_Open_Lock_and_Check::peer(void)
+TAO::Storable_Base *
+TAO_Storable_Naming_Context::
+File_Open_Lock_and_Check::create_stream (const char * mode)
{
- ACE_TRACE("peer");
- return *fl_;
+ ACE_CString file_name = context_->context_name_;
+
+ // Create the stream
+ return context_->factory_->create_stream(file_name, ACE_TEXT_CHAR_TO_TCHAR(mode));
}
+// Make shortcut to get to Method_Type enums
+typedef TAO::Storable_File_Guard SFG;
+
TAO_Storable_Naming_Context::TAO_Storable_Naming_Context (
CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa,
- const char *poa_id,
- TAO_Naming_Service_Persistence_Factory *factory,
- const ACE_TCHAR *persistence_directory,
+ const char *context_name,
+ TAO_Storable_Naming_Context_Factory *cxt_factory,
+ TAO::Storable_Factory *factory,
size_t hash_table_size)
: TAO_Hash_Naming_Context (poa,
- poa_id),
+ context_name),
counter_ (0),
storable_context_ (0),
orb_(CORBA::ORB::_duplicate (orb)),
- name_ (poa_id),
+ context_name_ (context_name),
poa_ (PortableServer::POA::_duplicate (poa)),
- factory_(factory),
- persistence_directory_ (ACE_TEXT_ALWAYS_CHAR(persistence_directory)),
- hash_table_size_(hash_table_size),
- last_changed_(0)
+ context_factory_ (cxt_factory),
+ factory_ (factory),
+ hash_table_size_ (hash_table_size),
+ last_changed_ (0),
+ write_occurred_ (0)
{
ACE_TRACE("TAO_Storable_Naming_Context");
}
@@ -562,12 +388,10 @@ TAO_Storable_Naming_Context::~TAO_Storable_Naming_Context (void)
if (this->destroyed_)
{
// Make sure we delete the associated stream
- ACE_CString file_name (this->persistence_directory_);
- file_name += "/";
- file_name += this->name_;
+ ACE_CString file_name = this->context_name_;
// Now delete the file
- ACE_Auto_Ptr<TAO_Storable_Base>
+ ACE_Auto_Ptr<TAO::Storable_Base>
fl (
this->factory_->create_stream(file_name.c_str(),
ACE_TEXT("r"))
@@ -586,10 +410,9 @@ CosNaming::NamingContext_ptr
TAO_Storable_Naming_Context::make_new_context (
CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa,
- const char *poa_id,
- size_t context_size,
- TAO_Naming_Service_Persistence_Factory *factory,
- const ACE_TCHAR *persistence_directory,
+ const char *context_name,
+ TAO_Storable_Naming_Context_Factory *cxt_factory,
+ TAO::Storable_Factory *pers_factory,
TAO_Storable_Naming_Context **new_context)
{
ACE_TRACE("make_new_context");
@@ -598,15 +421,14 @@ TAO_Storable_Naming_Context::make_new_context (
// Put together a servant for the new Naming Context.
- TAO_Storable_Naming_Context *context_impl = 0;
- ACE_NEW_THROW_EX (context_impl,
- TAO_Storable_Naming_Context (orb,
- poa,
- poa_id,
- factory,
- persistence_directory,
- context_size),
- CORBA::NO_MEMORY ());
+ TAO_Storable_Naming_Context *context_impl =
+ cxt_factory->create_naming_context_impl (orb,
+ poa,
+ context_name,
+ pers_factory);
+
+ if (context_impl == 0)
+ throw CORBA::NO_MEMORY ();
// Put <context_impl> into the auto pointer temporarily, in case next
// allocation fails.
@@ -627,7 +449,7 @@ TAO_Storable_Naming_Context::make_new_context (
// Register the new context with the POA.
PortableServer::ObjectId_var id =
- PortableServer::string_to_ObjectId (poa_id);
+ PortableServer::string_to_ObjectId (context_name);
// If we try to register a naming context that is already registered,
// the following activation causes a POA::ObjectAlreadyActive exception be
@@ -663,7 +485,7 @@ TAO_Storable_Naming_Context::new_context (void)
{
// Open the backing file
- File_Open_Lock_and_Check flck(this, "r");
+ File_Open_Lock_and_Check flck(this, SFG::ACCESSOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -672,8 +494,8 @@ TAO_Storable_Naming_Context::new_context (void)
}
TAO_NS_Persistence_Global global;
+ TAO_Storable_Naming_Context_ReaderWriter rw(*gfl_.get());
- // Generate a POA id for the new context.
if(redundant_)
{
// acquire a lock on the file that holds our counter
@@ -685,25 +507,21 @@ TAO_Storable_Naming_Context::new_context (void)
if (gfl_ -> flock(0, 0, 0) != 0)
throw CORBA::INTERNAL();
// get the counter from disk
- *gfl_.get() >> global;
- if (!gfl_.get ()->good () &&
- gfl_.get ()->rdstate () != TAO_Storable_Base::eofbit)
- {
- gfl_.get ()->clear ();
- throw CORBA::INTERNAL ();
- }
+ rw.read_global(global);
gcounter_ = global.counter();
// use it to generate a new name
}
- char poa_id[BUFSIZ];
- ACE_OS::sprintf (poa_id,
+
+ // Generate an Object id for the new context.
+ char object_id[BUFSIZ];
+ ACE_OS::sprintf (object_id,
"%s_%d",
root_name_,
gcounter_++);
// then save it back on disk
- global.counter(gcounter_);
- *gfl_.get() << global;
- if(redundant_)
+ global.counter (gcounter_);
+ rw.write_global (global);
+ if (redundant_)
{
// and release our lock
if (gfl_ -> flock(0, 0, 0) != 0)
@@ -716,10 +534,9 @@ TAO_Storable_Naming_Context::new_context (void)
CosNaming::NamingContext_var result =
make_new_context (this->orb_.in (),
this->poa_.in (),
- poa_id,
- this->storable_context_->total_size (),
+ object_id,
+ this->context_factory_,
this->factory_,
- ACE_TEXT_CHAR_TO_TCHAR (this->persistence_directory_.c_str ()),
&new_context);
// Since this is a new context, make an empty map in it
@@ -728,7 +545,7 @@ TAO_Storable_Naming_Context::new_context (void)
CORBA::NO_MEMORY ());
new_context->context_ = new_context->storable_context_;
- File_Open_Lock_and_Check flck(new_context, "wc");
+ File_Open_Lock_and_Check flck(new_context, SFG::CREATE_WITHOUT_FILE);
new_context->Write(flck.peer());
return result._retn ();
@@ -752,7 +569,7 @@ TAO_Storable_Naming_Context::rebind (const CosNaming::Name& n,
CORBA::INTERNAL ());
// Open the backing file
- File_Open_Lock_and_Check flck(this, name_len > 1 ? "r" : "rw");
+ File_Open_Lock_and_Check flck(this, name_len > 1 ? SFG::ACCESSOR : SFG::MUTATOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -819,7 +636,7 @@ TAO_Storable_Naming_Context::bind_context (const CosNaming::Name &n,
CORBA::INTERNAL ());
// Open the backing file
- File_Open_Lock_and_Check flck(this, name_len > 1 ? "r" : "rw");
+ File_Open_Lock_and_Check flck(this, name_len > 1 ? SFG::ACCESSOR : SFG::MUTATOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -879,7 +696,7 @@ TAO_Storable_Naming_Context::rebind_context (const CosNaming::Name &n,
CORBA::INTERNAL ());
// Open the backing file
- File_Open_Lock_and_Check flck(this, name_len > 1 ? "r" : "rw");
+ File_Open_Lock_and_Check flck(this, name_len > 1 ? SFG::ACCESSOR : SFG::MUTATOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -938,7 +755,7 @@ TAO_Storable_Naming_Context::resolve (const CosNaming::Name& n)
CORBA::INTERNAL ());
// Open the backing file
- File_Open_Lock_and_Check flck(this, "r");
+ File_Open_Lock_and_Check flck(this, SFG::ACCESSOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -1027,7 +844,8 @@ TAO_Storable_Naming_Context::unbind (const CosNaming::Name& n)
CORBA::INTERNAL ());
// Open the backing file
- File_Open_Lock_and_Check flck(this, name_len > 1 ? "r" : "rw");
+ File_Open_Lock_and_Check flck(this, name_len > 1 ?
+ SFG::ACCESSOR : SFG::MUTATOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -1086,7 +904,8 @@ TAO_Storable_Naming_Context::bind_new_context (const CosNaming::Name& n)
throw CORBA::OBJECT_NOT_EXIST ();
// Open the backing file
- File_Open_Lock_and_Check flck(this, name_len > 1 ? "r" : "rw");
+ File_Open_Lock_and_Check flck(this, name_len > 1 ?
+ SFG::ACCESSOR : SFG::MUTATOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -1155,7 +974,7 @@ TAO_Storable_Naming_Context::destroy (void)
CORBA::INTERNAL ());
// Open the backing file
- File_Open_Lock_and_Check flck(this, "rw");
+ File_Open_Lock_and_Check flck(this, SFG::MUTATOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -1190,6 +1009,21 @@ TAO_Storable_Naming_Context::destroy (void)
}
}
+void
+TAO_Storable_Naming_Context::context_written (void)
+{
+ // No-op. Overridden by derived class.
+}
+
+bool
+TAO_Storable_Naming_Context::is_obsolete (time_t stored_time)
+{
+ // If the context_ has not been populated or
+ // the time in the persistent store is greater than this
+ // object last change time, the context is obsolete
+ return (this->context_ == 0) ||
+ (stored_time > this->last_changed_);
+}
void
TAO_Storable_Naming_Context::bind (const CosNaming::Name& n,
@@ -1209,7 +1043,8 @@ TAO_Storable_Naming_Context::bind (const CosNaming::Name& n,
CORBA::INTERNAL ());
// Open the backing file
- File_Open_Lock_and_Check flck(this, name_len > 1 ? "r" : "rw");
+ File_Open_Lock_and_Check flck(this, name_len > 1 ?
+ SFG::ACCESSOR : SFG::MUTATOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -1247,7 +1082,7 @@ TAO_Storable_Naming_Context::bind (const CosNaming::Name& n,
else if (result == -1)
throw CORBA::INTERNAL ();
- this->Write(flck.peer());
+ this->Write (flck.peer());
}
}
@@ -1272,7 +1107,7 @@ TAO_Storable_Naming_Context::list (CORBA::ULong how_many,
CORBA::INTERNAL ());
// Open the backing file
- File_Open_Lock_and_Check flck(this, "r");
+ File_Open_Lock_and_Check flck(this, SFG::ACCESSOR);
// Check to make sure this object didn't have <destroy> method
// invoked on it.
@@ -1382,14 +1217,14 @@ TAO_END_VERSIONED_NAMESPACE_DECL
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
-CosNaming::NamingContext_ptr TAO_Storable_Naming_Context::recreate_all(
+CosNaming::NamingContext_ptr TAO_Storable_Naming_Context::recreate_all (
CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa,
const char *poa_id,
size_t context_size,
int reentering,
- TAO_Naming_Service_Persistence_Factory *factory,
- const ACE_TCHAR *persistence_directory,
+ TAO_Storable_Naming_Context_Factory *cxt_factory,
+ TAO::Storable_Factory *pers_factory,
int use_redundancy)
{
ACE_TRACE("recreate_all");
@@ -1408,20 +1243,18 @@ CosNaming::NamingContext_ptr TAO_Storable_Naming_Context::recreate_all(
make_new_context (orb,
poa,
poa_id,
- context_size,
- factory,
- persistence_directory,
+ cxt_factory,
+ pers_factory,
&new_context);
// Now does this already exist on disk?
- ACE_TString file_name(persistence_directory);
- file_name += ACE_TEXT("/");
- file_name += ACE_TEXT_CHAR_TO_TCHAR(poa_id);
- ACE_Auto_Ptr<TAO_Storable_Base> fl (factory->create_stream(ACE_TEXT_ALWAYS_CHAR(file_name.c_str()), ACE_TEXT("r")));
- if (fl->exists())
+ ACE_TString file_name = ACE_TEXT_CHAR_TO_TCHAR(poa_id);
+ ACE_Auto_Ptr<TAO::Storable_Base> fl (
+ pers_factory->create_stream (ACE_TEXT_ALWAYS_CHAR (file_name.c_str ()), ACE_TEXT ("r")));
+ if (fl->exists ())
{
// Load the map from disk
- File_Open_Lock_and_Check flck(new_context, "r");
+ File_Open_Lock_and_Check flck (new_context, SFG::CREATE_WITH_FILE);
}
else
{
@@ -1430,15 +1263,20 @@ CosNaming::NamingContext_ptr TAO_Storable_Naming_Context::recreate_all(
TAO_Storable_Bindings_Map (context_size,orb),
CORBA::NO_MEMORY ());
new_context->context_ = new_context->storable_context_;
- File_Open_Lock_and_Check flck(new_context, "wc");
- new_context->Write(flck.peer());
+ File_Open_Lock_and_Check flck (new_context, SFG::CREATE_WITHOUT_FILE);
+ new_context->Write (flck.peer ());
}
// build the global file name
file_name += ACE_TEXT("_global");
- // Create the stream for the counter used to uniquely creat context names
- gfl_.reset(factory->create_stream(ACE_TEXT_ALWAYS_CHAR(file_name.c_str()), ACE_TEXT("crw")));
+ // Create the stream for the counter used to uniquely create context names
+ // Pass false for use_backup since access to this file is not wrapped
+ // around a Storable_File_Guard derived class.
+ gfl_.reset(pers_factory->
+ create_stream (ACE_TEXT_ALWAYS_CHAR(file_name.c_str()),
+ ACE_TEXT("crw"),
+ false));
if (gfl_->open() != 0)
{
delete gfl_.release();
@@ -1447,13 +1285,8 @@ CosNaming::NamingContext_ptr TAO_Storable_Naming_Context::recreate_all(
// get the counter from disk
TAO_NS_Persistence_Global global;
- *gfl_.get() >> global;
- if (!gfl_.get ()->good () &&
- gfl_.get ()->rdstate () != TAO_Storable_Base::eofbit)
- {
- gfl_.get ()->clear ();
- throw CORBA::INTERNAL ();
- }
+ TAO_Storable_Naming_Context_ReaderWriter rw(*gfl_.get());
+ rw.read_global(global);
gcounter_ = global.counter();
if(redundant_) gfl_->close();
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h
index fe4d33ae149..9d28d4d4c31 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h
@@ -15,6 +15,7 @@
#include /**/ "ace/pre.h"
#include "orbsvcs/Naming/Hash_Naming_Context.h"
+#include "tao/Storable_File_Guard.h"
#include "ace/Hash_Map_Manager.h"
#include "ace/Auto_Ptr.h"
@@ -26,6 +27,14 @@
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+namespace TAO
+{
+ class Storable_Base;
+ class Storable_Factory;
+}
+
+class TAO_Storable_Naming_Context_Factory;
+
class TAO_Naming_Serv_Export TAO_Storable_IntId
{
public:
@@ -229,8 +238,8 @@ public:
TAO_Storable_Naming_Context (CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa,
const char *poa_id,
- TAO_Naming_Service_Persistence_Factory *factory,
- const ACE_TCHAR *persistence_directory,
+ TAO_Storable_Naming_Context_Factory *cxt_factory,
+ TAO::Storable_Factory *factory,
size_t hash_table_size = ACE_DEFAULT_MAP_SIZE);
/// Destructor.
@@ -247,22 +256,21 @@ public:
static CosNaming::NamingContext_ptr make_new_context (
CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa,
- const char *poa_id,
- size_t context_size,
- TAO_Naming_Service_Persistence_Factory *factory,
- const ACE_TCHAR *persistence_directory,
+ const char *context_id,
+ TAO_Storable_Naming_Context_Factory *cxt_factory,
+ TAO::Storable_Factory *pers_factory,
TAO_Storable_Naming_Context **new_context);
// = Methods not implemented in TAO_Hash_Naming_Context.
- static CosNaming::NamingContext_ptr recreate_all(
+ static CosNaming::NamingContext_ptr recreate_all (
CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa,
- const char *poa_id,
+ const char *context_id,
size_t context_size,
int reentering,
- TAO_Naming_Service_Persistence_Factory *factory,
- const ACE_TCHAR *persistence_directory,
+ TAO_Storable_Naming_Context_Factory *cxt_factory,
+ TAO::Storable_Factory *pers_factory,
int use_redundancy);
@@ -353,6 +361,21 @@ public:
protected:
+ /**
+ * An internal callback invoked by the File_Open_Lock_and_Check object to
+ * signal that this context was updated and written to disk.
+ * This will have been done after the file is closed. Check the
+ * last_changed_ attribute for the time of the write.
+ */
+ virtual void context_written (void);
+
+ /**
+ * An internal callback invoked by the File_Open_Lock_and_Check
+ * object to determine if this context is obsolete with respect to the
+ * file object .
+ */
+ virtual bool is_obsolete (time_t stored_time);
+
/// Global counter used for generation of POA ids for children Naming
/// Contexts.
static ACE_UINT32 gcounter_;
@@ -371,11 +394,16 @@ protected:
CORBA::ORB_var orb_;
- ACE_CString name_;
+ /// The name of the context used as its object id when registered
+ /// with the POA.
+ ACE_CString context_name_;
+ /// The POA that this context was registered with.
PortableServer::POA_var poa_;
- TAO_Naming_Service_Persistence_Factory *factory_;
+ TAO_Storable_Naming_Context_Factory *context_factory_;
+
+ TAO::Storable_Factory *factory_;
/// The directory in which to store the files
ACE_CString persistence_directory_;
@@ -386,73 +414,72 @@ protected:
/// Disk time that match current memory state
time_t last_changed_;
- /// Flag to tell use whether we are redundant or not
+ /// Flag to tell us whether we are redundant or not
static int redundant_;
static const char * root_name_;
/// The pointer to the global file used to allocate new contexts
- static ACE_Auto_Ptr<TAO_Storable_Base> gfl_;
+ static ACE_Auto_Ptr<TAO::Storable_Base> gfl_;
/**
* @class File_Open_Lock_and_Check
*
- * @brief Helper class for the TAO_Storable_Naming_Context.
- *
- * Guard class for the TAO_Storable_Naming_Context. It 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.
+ * @brief File guard specific for storable naming contexts.
*
- * The destructor insures that the lock gets released.
- *
- * <pre>
- * How to use this class:
- * File_Open_Lock_and_Check flck(this, name_len > 1 ? "r" : "rw");
- * </pre>
*/
-class File_Open_Lock_and_Check
+class TAO_Naming_Serv_Export File_Open_Lock_and_Check :
+public TAO::Storable_File_Guard
{
public:
/// Constructor - we always need the object which we guard.
- File_Open_Lock_and_Check(TAO_Storable_Naming_Context * context,
- const char * mode);
+ File_Open_Lock_and_Check (TAO_Storable_Naming_Context * context,
+ Method_Type method_type);
+
+ ~File_Open_Lock_and_Check ();
+
+protected:
+
+ /// Check if the guarded object is current with the last
+ /// update which could have been performed independently of
+ /// the owner of this object.
+ virtual bool object_obsolete (void);
+
+ /// Mark the object as current with respect to the
+ /// file to which it was persisted.
+ virtual void mark_object_current (void);
- /// Destructor
- ~File_Open_Lock_and_Check(void);
+ /// Mark the time at which the object was modified and
+ virtual void set_object_last_changed (const time_t & time);
- /// Releases the lock, closes the file, and deletes the I/O stream.
- void release(void);
+ /// Get the time which the object was last written to the
+ /// file.
+ virtual time_t get_object_last_changed ();
- /// Returns the stream to read/write on
- TAO_Storable_Base & peer(void);
+ virtual void load_from_stream ();
+
+ virtual bool is_loaded_from_stream ();
+
+ virtual TAO::Storable_Base * create_stream (const char * mode);
private:
/// Default constructor
File_Open_Lock_and_Check(void);
- /// A flag to keep us from trying to close things more than once.
- int closed_;
-
- /// We need to save the pointer to our parent for cleaning up
TAO_Storable_Naming_Context * context_;
- /// The pointer to the actual file I/O (bridge pattern)
- TAO_Storable_Base *fl_;
-
- /// The flags that we were opened with
- int rwflags_;
-
- /// Symbolic values for the flags in the above
- enum{ mode_write = 1, mode_read = 2, mode_create = 4 };
}; // end of embedded class File_Open_Lock_and_Check
friend class File_Open_Lock_and_Check;
+ friend class TAO_Storable_Naming_Context_ReaderWriter;
- int load_map(File_Open_Lock_and_Check *flck);
+ int load_map(TAO::Storable_Base& storable);
- void Write(TAO_Storable_Base& wrtr);
+ void Write(TAO::Storable_Base& wrtr);
+ /// Is set by the Write operation. Used to determine
+ int write_occurred_;
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp
index 5f5f31a4530..28a52a40254 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp
@@ -14,26 +14,29 @@
#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
#include "orbsvcs/Naming/Naming_Context_Interface.h"
#include "orbsvcs/Naming/Storable_Naming_Context.h"
+#include "orbsvcs/Naming/Storable_Naming_Context_Factory.h"
#include "orbsvcs/Naming/Storable.h"
+#include "tao/Storable_Factory.h"
#include "ace/Auto_Ptr.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
TAO_Storable_Naming_Context_Activator::TAO_Storable_Naming_Context_Activator (
CORBA::ORB_ptr orb,
- TAO_Naming_Service_Persistence_Factory *factory,
- const ACE_TCHAR *persistence_directory,
- size_t context_size)
+ TAO::Storable_Factory *persistence_factory,
+ TAO_Storable_Naming_Context_Factory *context_impl_factory,
+ const ACE_TCHAR *persistence_directory)
: orb_(orb),
- factory_(factory),
- persistence_directory_(persistence_directory),
- context_size_(context_size)
+ persistence_factory_(persistence_factory),
+ context_impl_factory_(context_impl_factory),
+ persistence_directory_(persistence_directory)
{
}
TAO_Storable_Naming_Context_Activator::~TAO_Storable_Naming_Context_Activator ()
{
- delete factory_;
+ delete persistence_factory_;
+ delete this->context_impl_factory_;
}
PortableServer::Servant
@@ -43,7 +46,10 @@ TAO_Storable_Naming_Context_Activator::incarnate (
{
// Make sure complete initialization has been done
- ACE_ASSERT (factory_ != 0);
+ ACE_ASSERT (persistence_factory_ != 0);
+
+ // Make sure complete initialization has been done
+ ACE_ASSERT (context_impl_factory_ != 0);
CORBA::String_var poa_id = PortableServer::ObjectId_to_string (oid);
@@ -53,29 +59,25 @@ TAO_Storable_Naming_Context_Activator::incarnate (
// context is accessed it will be determined that the contents of
// the persistence elment needs to be read in.
- // Does this already exist on disk?
- ACE_TString file_name(persistence_directory_);
- file_name += ACE_TEXT("/");
- file_name += ACE_TEXT_CHAR_TO_TCHAR(poa_id.in());
- TAO_Storable_Base * fl = factory_->create_stream(ACE_TEXT_ALWAYS_CHAR(file_name.c_str()), ACE_TEXT("rw"));
- if (!fl->exists()) {
- throw CORBA::OBJECT_NOT_EXIST ();
- }
+ { // Does this already exist on disk?
- // Store the stub we will return here.
- CosNaming::NamingContext_var result (CosNaming::NamingContext::_nil());
+ ACE_TString file_name = ACE_TEXT_CHAR_TO_TCHAR (poa_id.in ());
+ ACE_Auto_Ptr<TAO::Storable_Base> fl (
+ persistence_factory_->create_stream (ACE_TEXT_ALWAYS_CHAR (file_name.c_str ()),
+ ACE_TEXT ("rw")));
- // Put together a servant for the new Naming Context.
+ if (!fl->exists()) {
+ throw CORBA::OBJECT_NOT_EXIST ();
+ }
+ }
- TAO_Storable_Naming_Context *context_impl = 0;
- ACE_NEW_THROW_EX (context_impl,
- TAO_Storable_Naming_Context (orb_,
- poa,
- poa_id.in (),
- factory_,
- persistence_directory_,
- context_size_),
- CORBA::NO_MEMORY ());
+ // Put together a servant for the new Naming Context.
+ // Will throw NO_MEMORY exception if unable to construct one
+ TAO_Storable_Naming_Context *context_impl =
+ this->context_impl_factory_->create_naming_context_impl (orb_,
+ poa,
+ poa_id.in (),
+ persistence_factory_);
// Put <context_impl> into the auto pointer temporarily, in case next
// allocation fails.
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.h b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.h
index d4770ed1c60..d7cbfeb79ba 100644
--- a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.h
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.h
@@ -26,7 +26,12 @@
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
-class TAO_Naming_Service_Persistence_Factory;
+namespace TAO
+{
+ class Storable_Factory;
+}
+
+class TAO_Storable_Naming_Context_Factory;
/**
* A servant activator to be use with a TAO_Storable_Naming_Context.
@@ -43,10 +48,11 @@ public:
* The constructor takes arguments needed to create a
* TAO_Storable_Naming_Context and TAO_Naming_Context on demand.
*/
- TAO_Storable_Naming_Context_Activator(CORBA::ORB_ptr orb,
- TAO_Naming_Service_Persistence_Factory *factory,
- const ACE_TCHAR *persistence_directory,
- size_t context_size);
+ TAO_Storable_Naming_Context_Activator (
+ CORBA::ORB_ptr orb,
+ TAO::Storable_Factory *factory,
+ TAO_Storable_Naming_Context_Factory *context_impl_factory,
+ const ACE_TCHAR *persistence_directory);
virtual ~TAO_Storable_Naming_Context_Activator();
@@ -70,9 +76,14 @@ public:
private:
CORBA::ORB_ptr orb_;
- TAO_Naming_Service_Persistence_Factory *factory_;
+
+ /// The factory for constructing the persistence mechanism for the contexts
+ TAO::Storable_Factory *persistence_factory_;
+
+ /// The factory for constructing naming contexts within the index
+ TAO_Storable_Naming_Context_Factory *context_impl_factory_;
+
const ACE_TCHAR *persistence_directory_;
- size_t context_size_;
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp
new file mode 100644
index 00000000000..78a91dd1a57
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp
@@ -0,0 +1,49 @@
+// $Id$
+
+#include "orbsvcs/Naming/Storable_Naming_Context_Factory.h"
+#include "orbsvcs/Naming/Storable_Naming_Context.h"
+
+#include "tao/Storable_Factory.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/// Constructor.
+TAO_Storable_Naming_Context_Factory::TAO_Storable_Naming_Context_Factory (
+ size_t hash_table_size)
+: context_size_(hash_table_size)
+{
+
+}
+
+/// Destructor. Does not deallocate the hash map: if an instance of
+/// this class goes out of scope, its hash_map remains in persistent storage.
+TAO_Storable_Naming_Context_Factory::~TAO_Storable_Naming_Context_Factory (void)
+{
+
+}
+
+
+TAO_Storable_Naming_Context*
+TAO_Storable_Naming_Context_Factory::create_naming_context_impl (
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO::Storable_Factory *persistence_factory)
+{
+ // Construct the naming context, forwarding the map and counter even if they
+ // are defaulted
+ TAO_Storable_Naming_Context *context_impl;
+ ACE_NEW_THROW_EX (context_impl,
+ TAO_Storable_Naming_Context (orb,
+ poa,
+ poa_id,
+ this,
+ persistence_factory,
+ this->context_size_),
+ CORBA::NO_MEMORY ());
+
+ return context_impl;
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h
new file mode 100644
index 00000000000..748bd60f772
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h
@@ -0,0 +1,72 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Naming_Context_Factory.h
+ *
+ * $Id$
+ *
+ * @author Kevin Stanley stanleyk@ociweb.com>
+ */
+//=============================================================================
+
+
+#ifndef TAO_STORABLE_NAMING_CONTEXT_FACTORY_H
+#define TAO_STORABLE_NAMING_CONTEXT_FACTORY_H
+#include /**/ "ace/pre.h"
+
+#include "tao/ORB.h"
+#include "orbsvcs/Naming/nsconf.h"
+#include "orbsvcs/Naming/naming_serv_export.h"
+#include "orbsvcs/Naming/Hash_Naming_Context.h"
+#include "orbsvcs/Naming/Storable_Naming_Context.h"
+
+namespace TAO
+{
+ class Storable_Factory;
+}
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class TAO_Storable_Naming_Context_Factory
+ *
+ * @brief
+ */
+class TAO_Naming_Serv_Export TAO_Storable_Naming_Context_Factory
+{
+public:
+
+ /// Data structure used by TAO_Persistent_Context_Index
+ /// - typedef for ease of use.
+ typedef TAO_Storable_Naming_Context::HASH_MAP HASH_MAP;
+
+ // = Initialization and termination methods.
+
+ /// Constructor.
+ TAO_Storable_Naming_Context_Factory (
+ size_t hash_table_size = ACE_DEFAULT_MAP_SIZE);
+
+ /// Destructor. Does not deallocate the hash map: if an instance of
+ /// this class goes out of scope, its hash_map remains in persistent storage.
+ virtual ~TAO_Storable_Naming_Context_Factory (void);
+
+ /// Factory method for creating an implementation object for naming contexts.
+ /// If an existing naming context implementation is being rebuilt, the map
+ /// and counter parameters should be provided to the underlying HASH_MAP
+ /// implementation
+ virtual TAO_Storable_Naming_Context* create_naming_context_impl (
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char *poa_id,
+ TAO::Storable_Factory *factory);
+
+protected:
+ /// The size for persisted naming context objects in hash map
+ size_t context_size_;
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* TAO_STORABLE_NAMING_CONTEXT_FACTORY_H */
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.cpp b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.cpp
new file mode 100644
index 00000000000..c21b331f6d9
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.cpp
@@ -0,0 +1,270 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Naming_Context_ReaderWriter.cpp
+ *
+ * $Id$
+ *
+ * @author Marina Spivak <marina@cs.wustl.edu>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.h"
+#include "orbsvcs/Naming/Storable_Naming_Context.h"
+#include "orbsvcs/Naming/Storable.h"
+
+#include "tao/Storable_Base.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_Storable_Naming_Context_ReaderWriter::
+TAO_Storable_Naming_Context_ReaderWriter (TAO::Storable_Base & stream)
+ : stream_(stream)
+{
+}
+
+void
+TAO_Storable_Naming_Context_ReaderWriter::write (TAO_Storable_Naming_Context & context)
+{
+ TAO_NS_Persistence_Header header;
+
+ header.size (static_cast<unsigned int> (context.storable_context_->current_size()));
+ header.destroyed (context.destroyed_);
+
+ this->write_header(header);
+
+ if (0u == header.size ())
+ return;
+
+ ACE_Hash_Map_Iterator<TAO_Storable_ExtId,TAO_Storable_IntId,
+ ACE_Null_Mutex> it = context.storable_context_->map().begin();
+ ACE_Hash_Map_Iterator<TAO_Storable_ExtId,TAO_Storable_IntId,
+ ACE_Null_Mutex> itend = context.storable_context_->map().end();
+
+ ACE_Hash_Map_Entry<TAO_Storable_ExtId,TAO_Storable_IntId> ent = *it;
+
+ while (!(it == itend))
+ {
+ TAO_NS_Persistence_Record record;
+
+ ACE_CString name;
+ CosNaming::BindingType bt = (*it).int_id_.type_;
+ if (bt == CosNaming::ncontext)
+ {
+ CORBA::Object_var
+ obj = context.orb_->string_to_object ((*it).int_id_.ref_.in ());
+ if (obj->_is_collocated ())
+ {
+ // This is a local (i.e. non federated context) we therefore
+ // store only the ObjectID (persistence filename) for the object.
+
+ // The driving force behind storing ObjectIDs rather than IORs for
+ // local contexts is to provide for a redundant naming service.
+ // That is, a naming service that runs simultaneously on multiple
+ // machines sharing a file system. It allows multiple redundant
+ // copies to be started and stopped independently.
+ // The original target platform was Tru64 Clusters where there was
+ // a cluster address. In that scenario, clients may get different
+ // servers on each request, hence the requirement to keep
+ // synchronized to the disk. It also works on non-cluster system
+ // where the client picks one of the redundant servers and uses it,
+ // while other systems can pick different servers. (However in this
+ // scenario, if a server fails and a client must pick a new server,
+ // that client may not use any saved context IORs, instead starting
+ // from the root to resolve names. So this latter mode is not quite
+ // transparent to clients.) [Rich Seibel (seibel_r) of ociweb.com]
+
+ PortableServer::ObjectId_var
+ oid = context.poa_->reference_to_id (obj.in ());
+ CORBA::String_var
+ nm = PortableServer::ObjectId_to_string (oid.in ());
+ const char
+ *newname = nm.in ();
+ name.set (newname); // The local ObjectID (persistance filename)
+ record.type (TAO_NS_Persistence_Record::LOCAL_NCONTEXT);
+ }
+ else
+ {
+ // Since this is a foreign (federated) context, we can not store
+ // the objectID (because it isn't in our storage), if we did, when
+ // we restore, we would end up either not finding a permanent
+ // record (and thus ending up incorrectly assuming the context was
+ // destroyed) or loading another context altogether (just because
+ // the contexts shares its objectID filename which is very likely).
+ // [Simon Massey (sma) of prismtech.com]
+
+ name.set ((*it).int_id_.ref_.in ()); // The federated context IOR
+ record.type (TAO_NS_Persistence_Record::REMOTE_NCONTEXT);
+ }
+ }
+ else // if (bt == CosNaming::nobject) // shouldn't be any other, can there?
+ {
+ name.set ((*it).int_id_.ref_.in ()); // The non-context object IOR
+ record.type (TAO_NS_Persistence_Record::OBJREF);
+ }
+ record.ref(name);
+
+ const char *myid = (*it).ext_id_.id();
+ ACE_CString id(myid);
+ record.id(id);
+
+ const char *mykind = (*it).ext_id_.kind();
+ ACE_CString kind(mykind);
+ record.kind(kind);
+
+ write_record (record);
+ it.advance();
+ }
+
+ context.write_occurred_ = 1;
+}
+
+int
+TAO_Storable_Naming_Context_ReaderWriter::read (TAO_Storable_Naming_Context & context)
+{
+ // assume file already open for reading
+ TAO_Storable_Bindings_Map *bindings_map;
+
+ // create the new bindings map
+ ACE_NEW_THROW_EX (bindings_map,
+ TAO_Storable_Bindings_Map (context.hash_table_size_, context.orb_.in()),
+ CORBA::NO_MEMORY ());
+
+ // get the data for this bindings map from the file
+
+ TAO_NS_Persistence_Header header;
+ TAO_NS_Persistence_Record record;
+
+ // we are only using the size from this header
+ this->read_header(header);
+
+ // reset the destroyed flag
+ context.destroyed_ = header.destroyed();
+
+ // read in the data for the map
+ for (unsigned int i= 0u; i<header.size(); ++i)
+ {
+ this->read_record(record);
+
+ if (TAO_NS_Persistence_Record::LOCAL_NCONTEXT == record.type ())
+ {
+ PortableServer::ObjectId_var
+ id = PortableServer::string_to_ObjectId (record.ref ().c_str ());
+ const char
+ *intf = context.interface_->_interface_repository_id ();
+ CORBA::Object_var
+ objref = context.poa_->create_reference_with_id (id.in (), intf);
+ bindings_map->bind ( record.id ().c_str (),
+ record.kind ().c_str (),
+ objref.in (),
+ CosNaming::ncontext );
+ }
+ else
+ {
+ CORBA::Object_var
+ objref = context.orb_->string_to_object (record.ref ().c_str ());
+ bindings_map->bind ( record.id ().c_str (),
+ record.kind ().c_str (),
+ objref.in (),
+ ((TAO_NS_Persistence_Record::REMOTE_NCONTEXT == record.type ())
+ ? CosNaming::ncontext // REMOTE_NCONTEXT
+ : CosNaming::nobject )); // OBJREF
+ }
+ }
+ context.storable_context_ = bindings_map;
+ context.context_ = context.storable_context_;
+ return 0;
+}
+
+void
+TAO_Storable_Naming_Context_ReaderWriter::write_header (const TAO_NS_Persistence_Header & header)
+{
+ stream_.rewind();
+ stream_ << header.size();
+ stream_ << header.destroyed();
+ stream_.flush();
+}
+void
+TAO_Storable_Naming_Context_ReaderWriter::read_header (TAO_NS_Persistence_Header & header)
+{
+ unsigned int size;
+ int destroyed;
+
+ stream_.rewind();
+
+ stream_ >> size;
+ header.size(size);
+
+ stream_ >> destroyed;
+ header.destroyed(destroyed);
+}
+
+void
+TAO_Storable_Naming_Context_ReaderWriter::write_record (const TAO_NS_Persistence_Record & record)
+{
+ TAO_NS_Persistence_Record::Record_Type type = record.type();
+ stream_ << type;
+
+ stream_ << record.id();
+ stream_ << record.kind();
+ stream_ << record.ref();
+
+ stream_.flush();
+}
+
+void
+TAO_Storable_Naming_Context_ReaderWriter::read_record (TAO_NS_Persistence_Record & record)
+{
+ int temp_type_in;
+ stream_ >> temp_type_in;
+ TAO_NS_Persistence_Record::Record_Type type =
+ (TAO_NS_Persistence_Record::Record_Type) temp_type_in;
+ record.type (type);
+
+ ACE_CString record_id;
+ stream_ >> record_id;
+ record.id (record_id);
+
+ ACE_CString record_kind;
+ stream_ >> record_kind;
+ record.kind (record_kind);
+
+ ACE_CString record_ref;
+ stream_ >> record_ref;
+ record.ref (record_ref);
+}
+
+void
+TAO_Storable_Naming_Context_ReaderWriter::write_global (const TAO_NS_Persistence_Global & global)
+{
+ stream_.rewind();
+ stream_ << global.counter();
+ stream_.flush();
+}
+
+void
+TAO_Storable_Naming_Context_ReaderWriter::read_global (TAO_NS_Persistence_Global
+ & global)
+{
+ unsigned int counter = 0;
+
+ stream_.rewind();
+ // We expect an exception to be thrown with EOF state if the file is empty.
+ try
+ {
+ stream_ >> counter;
+ }
+ catch (TAO::Storable_Read_Exception &ex)
+ {
+ if (ex.get_state() != TAO::Storable_Base::goodbit &&
+ ex.get_state() != TAO::Storable_Base::eofbit)
+ throw CORBA::INTERNAL ();
+ }
+
+ global.counter(counter);
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.h b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.h
new file mode 100644
index 00000000000..e0c06856ae3
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.h
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Naming_Context_ReaderWriter.h
+ *
+ * $Id$
+ *
+ * @author Marina Spivak <marina@cs.wustl.edu>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_STORABLE_NAMING_CONTEXT_READERWRITER_H
+#define TAO_STORABLE_NAMING_CONTEXT_READERWRITER_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/orbconf.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ class Storable_Base;
+}
+
+class TAO_Storable_Naming_Context;
+class TAO_NS_Persistence_Record;
+class TAO_NS_Persistence_Header;
+class TAO_NS_Persistence_Global;
+
+class TAO_Storable_Naming_Context_ReaderWriter
+{
+public:
+
+ TAO_Storable_Naming_Context_ReaderWriter (TAO::Storable_Base & stream);
+
+ int read (TAO_Storable_Naming_Context & context);
+
+ void write (TAO_Storable_Naming_Context & context);
+
+ void write_global (const TAO_NS_Persistence_Global & global);
+ void read_global (TAO_NS_Persistence_Global & global);
+
+private:
+
+ void write_header (const TAO_NS_Persistence_Header & header);
+ void read_header (TAO_NS_Persistence_Header & header);
+
+ void write_record (const TAO_NS_Persistence_Record & record);
+ void read_record (TAO_NS_Persistence_Record & record);
+
+ TAO::Storable_Base &stream_;
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* TAO_STORABLE_NAMING_CONTEXT_READERWRITER_H */
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp
index fc10e0bb552..3ea3d1ee299 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp
@@ -7,24 +7,56 @@
* $Id$
*
* @author Dale Wilson <wilson_d@ociweb.com>
+ * @author Byron Harris <harrisb@ociweb.com>
*/
//=============================================================================
#include "orbsvcs/PortableGroup/PG_Group_Factory.h"
#include "orbsvcs/PortableGroup/PG_Property_Utils.h"
+#include "orbsvcs/PortableGroup/PG_Group_List_Store.h"
#include "orbsvcs/PortableGroup/PG_conf.h"
#include "orbsvcs/PortableGroupC.h"
#include "orbsvcs/PortableGroup/PG_Object_Group.h"
+#include "orbsvcs/PortableGroup/PG_Object_Group_Storable.h"
#include <orbsvcs/PortableGroup/PG_Utils.h>
+#include "tao/Storable_Factory.h"
+
+#include <ace/SString.h>
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+namespace
+{
+ // Find the elements in set1 that
+ // are missing in set2.
+ template <class T>
+ void
+ find_missing(const std::set<T> & set1,
+ const std::set<T> & set2,
+ std::set<T> & missing_in_2)
+ {
+ missing_in_2.clear();
+ for (typename std::set<T>::const_iterator it = set1.begin();
+ it != set1.end(); ++it)
+ {
+ if (set2.find(*it) == set2.end())
+ {
+ missing_in_2.insert(*it);
+ }
+ }
+ }
+}
+
TAO::PG_Group_Factory::PG_Group_Factory ()
- : orb_ (CORBA::ORB::_nil())
+ : use_persistence_ (false)
+ , list_store_ (0)
+ , orb_ (CORBA::ORB::_nil())
, poa_ (PortableServer::POA::_nil())
, manipulator_ ()
- , domain_id_ ("default-domain")
-
+ , domain_id_ (ACE_TEXT_ALWAYS_CHAR ("default-domain"))
+ , groups_read_ (false)
+ , storable_factory_ (0)
{
}
@@ -38,6 +70,8 @@ TAO::PG_Group_Factory::~PG_Group_Factory (void)
delete group;
}
this->group_map_.unbind_all ();
+ delete this->list_store_;
+ delete this->storable_factory_;
}
@@ -52,7 +86,9 @@ void TAO::PG_Group_Factory::init (
this->orb_ = CORBA::ORB::_duplicate(orb);
this->poa_ = PortableServer::POA::_duplicate (poa);
- this->factory_registry_ = PortableGroup::FactoryRegistry::_duplicate (factory_registry);
+
+ this->factory_registry_ =
+ PortableGroup::FactoryRegistry::_duplicate (factory_registry);
ACE_ASSERT (!CORBA::is_nil (this->orb_.in ()));
@@ -72,11 +108,25 @@ TAO::PG_Object_Group * TAO::PG_Group_Factory::create_group (
// Create an empty group reference
PortableGroup::ObjectGroupId group_id = 0;
- PortableGroup::ObjectGroup_var empty_group =
- this->manipulator_.create_object_group (
- type_id,
- this->domain_id_,
- group_id);
+ PortableGroup::ObjectGroup_var empty_group;
+
+ if (this->use_persistence_)
+ {
+ group_id = this->list_store_->get_next_group_id ();
+ empty_group =
+ this->manipulator_.create_object_group_using_id (
+ type_id,
+ this->domain_id_,
+ group_id);
+ }
+ else
+ {
+ empty_group =
+ this->manipulator_.create_object_group (
+ type_id,
+ this->domain_id_,
+ group_id);
+ }
// pick up the object group information as assigned by
// ObjectGroupManager
@@ -89,19 +139,37 @@ TAO::PG_Object_Group * TAO::PG_Group_Factory::create_group (
TAO::PG_Object_Group * objectGroup = 0;
- ACE_NEW_THROW_EX (
- objectGroup,
- TAO::PG_Object_Group (
- this->orb_.in (),
- this->factory_registry_.in (),
- this->manipulator_,
- empty_group.in (),
- tagged_component,
- type_id,
- the_criteria,
- typeid_properties
- ),
- CORBA::NO_MEMORY());
+ if (this->use_persistence_)
+ {
+ objectGroup = this->create_persistent_group (
+ this->orb_.in (),
+ this->factory_registry_.in (),
+ this->manipulator_,
+ empty_group.in (),
+ tagged_component,
+ type_id,
+ the_criteria,
+ typeid_properties,
+ *storable_factory_);
+
+ this->list_store_->add(group_id);
+ }
+ else
+ {
+ ACE_NEW_THROW_EX (
+ objectGroup,
+ TAO::PG_Object_Group (
+ this->orb_.in (),
+ this->factory_registry_.in (),
+ this->manipulator_,
+ empty_group.in (),
+ tagged_component,
+ type_id,
+ the_criteria,
+ typeid_properties
+ ),
+ CORBA::NO_MEMORY());
+ }
if (this->group_map_.bind (group_id, objectGroup) != 0)
{
@@ -111,7 +179,8 @@ TAO::PG_Object_Group * TAO::PG_Group_Factory::create_group (
return objectGroup;
}
-void TAO::PG_Group_Factory::delete_group (PortableGroup::ObjectGroup_ptr object_group)
+void TAO::PG_Group_Factory::delete_group (
+ PortableGroup::ObjectGroup_ptr object_group)
{
if (! destroy_group (object_group))
{
@@ -120,7 +189,8 @@ void TAO::PG_Group_Factory::delete_group (PortableGroup::ObjectGroup_ptr object_
}
-void TAO::PG_Group_Factory::delete_group (PortableGroup::ObjectGroupId group_id)
+void TAO::PG_Group_Factory::delete_group (
+ PortableGroup::ObjectGroupId group_id)
{
if (! destroy_group (group_id))
{
@@ -134,17 +204,20 @@ int TAO::PG_Group_Factory::insert_group ( ::TAO::PG_Object_Group * group)
return insert_group (group->get_object_group_id(), group);
}
-int TAO::PG_Group_Factory::insert_group (PortableGroup::ObjectGroupId group_id, ::TAO::PG_Object_Group * group)
+int TAO::PG_Group_Factory::insert_group (PortableGroup::ObjectGroupId group_id,
+ ::TAO::PG_Object_Group * group)
{
- return (this->group_map_.bind (group_id, group) == 0);
+ return (this->get_group_map ().bind (group_id, group) == 0);
}
-int TAO::PG_Group_Factory::find_group (PortableGroup::ObjectGroupId group_id, ::TAO::PG_Object_Group *& group) const
+int TAO::PG_Group_Factory::find_group (PortableGroup::ObjectGroupId group_id,
+ ::TAO::PG_Object_Group *& group)
{
- return (this->group_map_.find (group_id , group) == 0);
+ return (this->get_group_map ().find (group_id , group) == 0);
}
-int TAO::PG_Group_Factory::find_group (PortableGroup::ObjectGroup_ptr object_group, ::TAO::PG_Object_Group *& group) const
+int TAO::PG_Group_Factory::find_group (PortableGroup::ObjectGroup_ptr object_group,
+ ::TAO::PG_Object_Group *& group)
{
int result = 0;
PortableGroup::TagGroupTaggedComponent tc;
@@ -155,13 +228,49 @@ int TAO::PG_Group_Factory::find_group (PortableGroup::ObjectGroup_ptr object_gro
return result;
}
+int TAO::PG_Group_Factory::find_group_with_name (const char* target_group_name,
+ TAO::PG_Object_Group *& group_target)
+{
+ int result = 0;
+
+ // Search through the group map for the group with that property
+ Group_Map & group_map = this->get_group_map ();
+ for (Group_Map_Iterator it = group_map.begin ();
+ it != group_map.end ();
+ ++it)
+ {
+ TAO::PG_Object_Group * a_group = (*it).int_id_;
+ // If the group has the group name in the property
+ //
+ const char* a_group_name = a_group->get_name ();
+ if (a_group_name != 0 &&
+ ACE_OS::strcmp (target_group_name,
+ a_group_name) == 0)
+ { // This is the group we were looking for
+ group_target = a_group;
+ result = 1;
+ break;
+ }
+ }
+ return result;
+}
+
int TAO::PG_Group_Factory::destroy_group (PortableGroup::ObjectGroupId group_id)
{
::TAO::PG_Object_Group * group = 0;
- int result = (this->group_map_.unbind (group_id, group) == 0);
+ int result = (this->get_group_map ().unbind (group_id, group) == 0);
if (result)
{
- delete group;
+ if (this->use_persistence_)
+ {
+ PG_Object_Group_Storable *og =
+ dynamic_cast<PG_Object_Group_Storable *> (group);
+ og->set_destroyed (true);
+ result = (this->list_store_->remove (group->get_object_group_id ())
+ == 0);
+ }
+ if (result)
+ delete group;
}
return result;
}
@@ -179,7 +288,8 @@ PortableGroup::ObjectGroups *
TAO::PG_Group_Factory::groups_at_location (
const PortableGroup::Location & the_location)
{
- size_t upper_limit = this->group_map_.current_size ();
+ Group_Map & group_map = this->get_group_map ();
+ size_t upper_limit = group_map.current_size ();
PortableGroup::ObjectGroups * result = 0;
ACE_NEW_THROW_EX (
result,
@@ -189,8 +299,8 @@ TAO::PG_Group_Factory::groups_at_location (
result->length(upper_limit);
size_t group_count = 0;
- for (Group_Map_Iterator it = this->group_map_.begin ();
- it != this->group_map_.end ();
+ for (Group_Map_Iterator it = group_map.begin ();
+ it != group_map.end ();
++it)
{
TAO::PG_Object_Group * group = (*it).int_id_;
@@ -204,4 +314,171 @@ TAO::PG_Group_Factory::groups_at_location (
return result;
}
+PortableGroup::ObjectGroups *
+TAO::PG_Group_Factory::all_groups (void)
+{
+ Group_Map & group_map = this->get_group_map ();
+ size_t upper_limit = group_map.current_size ();
+ PortableGroup::ObjectGroups * result = 0;
+ ACE_NEW_THROW_EX (
+ result,
+ PortableGroup::ObjectGroups (upper_limit),
+ CORBA::NO_MEMORY());
+
+ result->length(upper_limit);
+
+ size_t group_count = 0;
+ for (Group_Map_Iterator it = group_map.begin ();
+ it != group_map.end ();
+ ++it)
+ {
+ TAO::PG_Object_Group * group = (*it).int_id_;
+ (*result)[group_count] = CORBA::Object::_duplicate(group->reference ());
+ ++group_count;
+ }
+ result->length (group_count);
+ return result;
+}
+
+void
+TAO::PG_Group_Factory::set_object_group_storable_factory (
+ TAO::Storable_Factory * factory)
+{
+ this->use_persistence_ = true;
+ this->storable_factory_ = factory;
+ ACE_NEW_THROW_EX (this->list_store_,
+ TAO::PG_Group_List_Store (*this->storable_factory_),
+ CORBA::NO_MEMORY ());
+
+}
+
+TAO::PG_Group_Factory::Group_Map &
+TAO::PG_Group_Factory::get_group_map ()
+{
+ if (this->use_persistence_)
+ {
+ // List of groups in persistent store may
+ // have changed since group_map_ was last
+ // updated.
+
+ if (!this->groups_read_ || this->list_store_->list_obsolete ())
+ {
+ // Extract IDs from group_map_ to set for comparison with IDs in persistent store
+ // This is to avoid having to repopulate the map from scratch.
+ PG_Group_List_Store::Group_Ids map_ids;
+ for (Group_Map_Iterator it = group_map_.begin ();
+ it != group_map_.end (); ++it)
+ {
+ map_ids.insert (it->key ());
+ }
+
+ // Get the latest groups from persistent store
+ const PG_Group_List_Store::Group_Ids & persistent_ids =
+ list_store_->get_group_ids ();
+
+ // Find groups added since map was last updated
+ PG_Group_List_Store::Group_Ids groups_added;
+ find_missing (persistent_ids, map_ids, groups_added);
+
+ // Find groups removed since map was last updated
+ PG_Group_List_Store::Group_Ids groups_removed;
+ find_missing (map_ids, persistent_ids, groups_removed);
+
+ // Bind added groups
+ for (PG_Group_List_Store::Group_Id_Const_Iterator it = groups_added.begin ();
+ it != groups_added.end (); ++it)
+ {
+ PortableGroup::ObjectGroupId group_id = *it;
+ TAO::PG_Object_Group * objectGroup = 0;
+ objectGroup = this->restore_persistent_group (
+ group_id,
+ this->orb_.in (),
+ this->factory_registry_.in (),
+ this->manipulator_,
+ *storable_factory_);
+
+ if (this->group_map_.bind (group_id, objectGroup) != 0)
+ {
+ delete objectGroup;
+ throw PortableGroup::ObjectNotCreated ();
+ }
+ }
+
+ // Unbind removed groups
+ for (PG_Group_List_Store::Group_Id_Const_Iterator it = groups_removed.begin ();
+ it != groups_removed.end (); ++it)
+ {
+ PortableGroup::ObjectGroupId group_id = *it;
+ PG_Object_Group * group = 0;
+ int result = (this->get_group_map ().unbind (group_id, group) == 0);
+ if (result)
+ {
+ delete group;
+ }
+ else
+ throw PortableGroup::ObjectGroupNotFound ();
+ }
+
+ this->groups_read_ = true;
+
+ }
+
+ }
+
+ return group_map_;
+}
+
+TAO::PG_Object_Group_Storable *
+TAO::PG_Group_Factory::create_persistent_group (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ CORBA::Object_ptr empty_group,
+ const PortableGroup::TagGroupTaggedComponent & tagged_component,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ TAO::PG_Property_Set * type_properties,
+ TAO::Storable_Factory & storable_factory)
+{
+ TAO::PG_Object_Group_Storable * objectGroup = 0;
+ ACE_NEW_THROW_EX (
+ objectGroup,
+ TAO::PG_Object_Group_Storable (
+ orb,
+ factory_registry,
+ manipulator,
+ empty_group,
+ tagged_component,
+ type_id,
+ the_criteria,
+ type_properties,
+ storable_factory
+ ),
+ CORBA::NO_MEMORY());
+ return objectGroup;
+}
+
+TAO::PG_Object_Group_Storable *
+TAO::PG_Group_Factory::restore_persistent_group (
+ PortableGroup::ObjectGroupId group_id,
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ TAO::Storable_Factory & storable_factory)
+{
+ TAO::PG_Object_Group_Storable * objectGroup = 0;
+ ACE_NEW_THROW_EX (
+ objectGroup,
+ TAO::PG_Object_Group_Storable (
+ group_id,
+ orb,
+ factory_registry,
+ manipulator,
+ storable_factory
+ ),
+ CORBA::NO_MEMORY());
+ return objectGroup;
+}
+
+
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h
index 950513257e7..540d2bcd3b8 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h
@@ -7,6 +7,7 @@
* $Id$
*
* @author Dale Wilson <wilson_d@ociweb.com>
+ * @author Byron Harris <harrisb@ociweb.com>
*/
//=============================================================================
@@ -22,7 +23,6 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h"
-
#include "orbsvcs/PortableGroupC.h"
#include "tao/PortableServer/PortableServer.h"
@@ -34,11 +34,14 @@
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
//////////////////
-// Forward reference
+// Forward references
namespace TAO
{
class PG_Property_Set;
-} // namespace TAO_PG
+ class PG_Group_List_Store;
+ class PG_Object_Group_Storable;
+ class Storable_Factory;
+}
namespace TAO
{
@@ -53,14 +56,16 @@ namespace TAO
{
////////////////////////////////////////////////////////////
// typedef private implementation classes
- typedef ACE_Hash_Map_Manager_Ex<
+ typedef ACE_Hash_Map_Manager_Ex <
PortableGroup::ObjectGroupId,
::TAO::PG_Object_Group *,
ACE_Hash<ACE_UINT64>,
ACE_Equal_To<ACE_UINT64>,
TAO_SYNCH_MUTEX> Group_Map;
- typedef ACE_Hash_Map_Entry <PortableGroup::ObjectGroupId, ::TAO::PG_Object_Group *> Group_Map_Entry;
+ typedef ACE_Hash_Map_Entry <
+ PortableGroup::ObjectGroupId,
+ ::TAO::PG_Object_Group *> Group_Map_Entry;
typedef ACE_Hash_Map_Iterator_Ex <
PortableGroup::ObjectGroupId,
@@ -75,7 +80,7 @@ namespace TAO
PG_Group_Factory ();
/// Destructor.
- ~PG_Group_Factory ();
+ virtual ~PG_Group_Factory ();
void init (
CORBA::ORB_ptr orb,
@@ -98,6 +103,11 @@ namespace TAO
groups_at_location (
const PortableGroup::Location & the_location);
+ /**
+ * return all groups in the factory
+ */
+ PortableGroup::ObjectGroups *
+ all_groups (void);
/**
@@ -105,26 +115,40 @@ namespace TAO
* note: uses group id extracted from group object
* @return bool true if insertion successful
*/
- int insert_group ( ::TAO::PG_Object_Group * group);
+ int insert_group (::TAO::PG_Object_Group * group);
/**
* insert group. Take ownership
* @return bool true if insertion successful
*/
- int insert_group (PortableGroup::ObjectGroupId group_id, ::TAO::PG_Object_Group * group);
+ int insert_group (
+ PortableGroup::ObjectGroupId group_id,
+ ::TAO::PG_Object_Group * group);
/**
* find group
* @return bool true if found
*/
- int find_group (PortableGroup::ObjectGroupId group_id, ::TAO::PG_Object_Group *& group) const;
+ int find_group (
+ PortableGroup::ObjectGroupId group_id,
+ ::TAO::PG_Object_Group *& group);
/**
* find group
* note: uses group id extracted from object_group
* @return bool true if found
*/
- int find_group (PortableGroup::ObjectGroup_ptr object_group, ::TAO::PG_Object_Group *& group) const;
+ int find_group (
+ PortableGroup::ObjectGroup_ptr object_group,
+ ::TAO::PG_Object_Group *& group);
+
+ /**
+ * find group with the property with the designated value
+ * @return bool true if found
+ */
+ int find_group_with_name (
+ const char* group_name,
+ ::TAO::PG_Object_Group *& group);
/**
* remove group from map and delete it.
@@ -139,7 +163,42 @@ namespace TAO
*/
int destroy_group (PortableGroup::ObjectGroup_ptr object_group);
- private:
+ /**
+ * persist internal state to file for fault tolerant purposes.
+ */
+ void set_object_group_storable_factory (TAO::Storable_Factory * factory);
+
+ protected:
+
+ /**
+ * Factory function to create a storable object object from
+ * scratch.
+ */
+ virtual PG_Object_Group_Storable * create_persistent_group (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ CORBA::Object_ptr empty_group,
+ const PortableGroup::TagGroupTaggedComponent & tagged_component,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ TAO::PG_Property_Set * type_properties,
+ TAO::Storable_Factory & storable_factory);
+
+ /**
+ * Factory function to restore an object group from
+ * persistent store.
+ */
+ virtual PG_Object_Group_Storable * restore_persistent_group (
+ PortableGroup::ObjectGroupId group_id,
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ TAO::Storable_Factory & storable_factory);
+
+ bool use_persistence_;
+
+ PG_Group_List_Store * list_store_;
private:
@@ -155,8 +214,19 @@ namespace TAO
const char * domain_id_;
+ /**
+ * If persistence is being used, update the map as
+ * necessary based on what's in the group list store.
+ */
+ Group_Map & get_group_map ();
+
Group_Map group_map_;
+ ///// Support for object group persistent /////
+
+ // Lazily read groups from store
+ bool groups_read_;
+ Storable_Factory * storable_factory_;
};
} // namespace TAO
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp
new file mode 100644
index 00000000000..97541e4c009
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp
@@ -0,0 +1,289 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file PG_Group_List_Store.cpp
+ *
+ * $Id$
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+
+#include "orbsvcs/PortableGroup/PG_Group_List_Store.h"
+
+#include "tao/Storable_Base.h"
+#include "tao/Storable_Factory.h"
+#include "tao/Storable_File_Guard.h"
+
+#include <algorithm>
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ class PG_Group_List_Store_File_Guard : public TAO::Storable_File_Guard
+ {
+ public:
+ PG_Group_List_Store_File_Guard (PG_Group_List_Store & list_store,
+ Method_Type method_type);
+
+ ~PG_Group_List_Store_File_Guard ();
+
+ virtual void set_object_last_changed (const time_t & time);
+
+ virtual time_t get_object_last_changed ();
+
+ virtual bool object_obsolete ();
+
+ virtual void mark_object_current ();
+
+ virtual void load_from_stream ();
+
+ virtual bool is_loaded_from_stream ();
+
+ virtual TAO::Storable_Base * create_stream (const char * mode);
+
+private:
+
+ PG_Group_List_Store & list_store_;
+ };
+}
+
+TAO::PG_Group_List_Store_File_Guard::PG_Group_List_Store_File_Guard (
+ PG_Group_List_Store & list_store, Method_Type method_type)
+ : TAO::Storable_File_Guard(true),
+ list_store_(list_store)
+{
+ try
+ {
+ this->init (method_type);
+ }
+ catch (const TAO::Storable_Read_Exception &)
+ {
+ throw CORBA::INTERNAL ();
+ }
+}
+
+TAO::PG_Group_List_Store_File_Guard::~PG_Group_List_Store_File_Guard ()
+{
+ this->release ();
+}
+
+void
+TAO::PG_Group_List_Store_File_Guard::set_object_last_changed (
+ const time_t & time)
+{
+ list_store_.last_changed_ = time;
+}
+
+time_t
+TAO::PG_Group_List_Store_File_Guard::get_object_last_changed ()
+{
+ return list_store_.last_changed_;
+}
+
+bool
+TAO::PG_Group_List_Store_File_Guard::object_obsolete ()
+{
+ return list_store_.is_obsolete (fl_->last_changed ());
+}
+
+void
+TAO::PG_Group_List_Store_File_Guard::mark_object_current ()
+{
+ // Reset the stale flag
+ list_store_.stale(false);
+ // Set the last update time to the file last update time
+ this->set_object_last_changed (fl_->last_changed ());
+}
+
+void
+TAO::PG_Group_List_Store_File_Guard::load_from_stream ()
+{
+ list_store_.read (this->peer ());
+ list_store_.loaded_from_stream_ = true;
+ this->peer ().rewind ();
+}
+
+bool
+TAO::PG_Group_List_Store_File_Guard::is_loaded_from_stream ()
+{
+ return list_store_.loaded_from_stream_;
+}
+
+TAO::Storable_Base *
+TAO::PG_Group_List_Store_File_Guard::create_stream (const char * mode)
+{
+ return list_store_.create_stream (mode);
+}
+
+typedef TAO::PG_Group_List_Store_File_Guard File_Guard;
+
+// Make shortcut to get to Method_Type enums
+typedef TAO::Storable_File_Guard SFG;
+
+TAO::PG_Group_List_Store::PG_Group_List_Store (
+ Storable_Factory & storable_factory)
+ : next_group_id_ (0)
+ , storable_factory_ (storable_factory)
+ , loaded_from_stream_ (false)
+ , last_changed_ (0)
+ , stale_ (false)
+{
+ // Create a temporary stream simply to check if a readable
+ // version already exists.
+ bool stream_exists = false;
+ {
+ ACE_Auto_Ptr<TAO::Storable_Base> stream (
+ this->create_stream (ACE_TEXT_ALWAYS_CHAR ("r")));
+
+ if (stream->exists ())
+ stream_exists = true;
+ }
+
+ if (stream_exists)
+ {
+ File_Guard fg(*this, SFG::CREATE_WITH_FILE);
+ }
+ else
+ {
+ File_Guard fg(*this, SFG::CREATE_WITHOUT_FILE);
+ this->write (fg.peer ());
+ }
+}
+
+TAO::PG_Group_List_Store::~PG_Group_List_Store ()
+{
+}
+
+PortableGroup::ObjectGroupId
+TAO::PG_Group_List_Store::get_next_group_id ()
+{
+ File_Guard fg(*this, SFG::ACCESSOR);
+ PortableGroup::ObjectGroupId next_id = this->next_group_id_;
+ ++this->next_group_id_;
+ this->write (fg.peer ());
+ return next_id;
+}
+
+int
+TAO::PG_Group_List_Store::add (PortableGroup::ObjectGroupId id)
+{
+ File_Guard fg(*this, SFG::MUTATOR);
+ Group_Id_Const_Iterator it = std::find (this->group_ids_.begin (),
+ this->group_ids_.end (),
+ id);
+ if (it != this->group_ids_.end())
+ return -1;
+ this->group_ids_.insert (id);
+ this->write (fg.peer ());
+ return 0;
+}
+
+int
+TAO::PG_Group_List_Store::remove (PortableGroup::ObjectGroupId id)
+{
+ File_Guard fg(*this, SFG::MUTATOR);
+ Group_Id_Iterator it = std::find (this->group_ids_.begin (),
+ this->group_ids_.end (),
+ id);
+ if (it == this->group_ids_.end ())
+ return -1;
+ this->group_ids_.erase (it);
+ this->write (fg.peer ());
+ return 0;
+}
+
+TAO::PG_Group_List_Store::Group_Ids &
+TAO::PG_Group_List_Store::get_group_ids ()
+{
+ File_Guard fg(*this, SFG::ACCESSOR);
+ return group_ids_;
+}
+
+void
+TAO::PG_Group_List_Store::read (TAO::Storable_Base & stream)
+{
+ group_ids_.clear ();
+
+ stream.rewind ();
+
+ unsigned int next_group_id;
+ stream >> next_group_id;
+ this->next_group_id_ = next_group_id;
+
+ int size;
+ stream >> size;
+
+ // TODO: Look at adding streaming of unsigned long long
+ // PortableGroup::ObjectGroupId group_id;
+ int group_id;
+ for (int i = 0; i < size; ++i)
+ {
+ stream >> group_id;
+ group_ids_.insert (group_id);
+ }
+}
+
+void
+TAO::PG_Group_List_Store::write (TAO::Storable_Base & stream)
+{
+ stream.rewind ();
+
+ unsigned int next_group_id = static_cast<unsigned int> (this->next_group_id_);
+ stream << next_group_id;
+
+ int size = group_ids_.size ();
+ stream << size;
+ for (Group_Id_Const_Iterator it = group_ids_.begin ();
+ it != group_ids_.end (); ++it)
+ {
+ int group_id = static_cast<int> (*it);
+ stream << group_id;
+ }
+
+ stream.flush ();
+}
+
+TAO::Storable_Base *
+TAO::PG_Group_List_Store::create_stream (const char * mode)
+{
+ return this->storable_factory_.create_stream (
+ ACE_TEXT_ALWAYS_CHAR ("ObjectGroup_global"), mode);
+}
+
+bool
+TAO::PG_Group_List_Store::list_obsolete ()
+{
+ // TODO: Upate if obsolete flag is set based on CORBA call.
+ ACE_Auto_Ptr<TAO::Storable_Base> stream (this->create_stream ("r"));
+ if (!stream->exists ())
+ throw CORBA::INTERNAL ();
+ stream->open ();
+ return this->is_obsolete (stream->last_changed ());
+}
+
+bool
+TAO::PG_Group_List_Store::is_obsolete (time_t stored_time)
+{
+ return
+ (!this->loaded_from_stream_) ||
+ this->stale () ||
+ (stored_time > this->last_changed_);
+}
+
+void
+TAO::PG_Group_List_Store::stale (bool is_stale)
+{
+ this->stale_ = is_stale;
+}
+
+bool
+TAO::PG_Group_List_Store::stale ()
+{
+ return this->stale_;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h
new file mode 100644
index 00000000000..8801ec6598d
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h
@@ -0,0 +1,119 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file PG_Group_List_Store.h
+ *
+ * $Id$
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef PG_GROUP_LIST_STORE_H
+#define PG_GROUP_LIST_STORE_H
+
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/PortableGroup/portablegroup_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/PortableGroupC.h"
+
+#include <set>
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ class Storable_Base;
+ class Storable_Factory;
+}
+
+namespace TAO
+{
+ /**
+ * @class PG_Group_List_Store
+ * Persists a list of object groups that are themselves persisted.
+ * All creation and deletion of persistent object groups should
+ * result in the list store being updated.
+ * This is done to support multiple group factories using the same
+ * persistent object groups.
+ * @see PG_Object_Group_Storable
+ */
+ class TAO_PortableGroup_Export PG_Group_List_Store
+ {
+ public:
+ PG_Group_List_Store (Storable_Factory & storable_factory);
+
+ ~PG_Group_List_Store ();
+
+ /**
+ * Return a group ID that can be used for creating a new object group.
+ */
+ PortableGroup::ObjectGroupId get_next_group_id ();
+
+ int add (PortableGroup::ObjectGroupId id);
+
+ int remove (PortableGroup::ObjectGroupId id);
+
+ typedef std::set<PortableGroup::ObjectGroupId> Group_Ids;
+
+ typedef std::set<PortableGroup::ObjectGroupId>::iterator
+ Group_Id_Iterator;
+
+ typedef std::set<PortableGroup::ObjectGroupId>::reverse_iterator
+ Group_Id_Revers_Iterator;
+
+ typedef std::set<PortableGroup::ObjectGroupId>::const_iterator
+ Group_Id_Const_Iterator;
+
+ Group_Ids & get_group_ids ();
+
+ /**
+ * Make explicit that state is stale instead of relying only
+ * on persistent file time stamp.
+ */
+ void stale (bool is_stale);
+
+ bool stale ();
+
+ /**
+ * Answer if the list is obsolete because the persistent store has been updated.
+ * Used by PG_Group_Factory to avoid having to compare IDs in group_map_ with
+ * the list contained here.
+ */
+ bool list_obsolete ();
+
+ private:
+
+ Group_Ids group_ids_;
+
+ /// Ensure ID is monotonically increasing even when groups gets
+ /// removed.
+ PortableGroup::ObjectGroupId next_group_id_;
+
+ TAO::Storable_Base * create_stream (const char * mode);
+
+ Storable_Factory & storable_factory_;
+ bool loaded_from_stream_;
+ time_t last_changed_;
+ bool stale_;
+ void read (TAO::Storable_Base & stream);
+ void write (TAO::Storable_Base & stream);
+
+ bool is_obsolete (time_t stored_time);
+
+ friend class PG_Group_List_Store_File_Guard;
+
+ };
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* PG_GROUP_LIST_STORE_H */
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp
index f0ab31d5342..33ce7d67bb5 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp
@@ -6,6 +6,9 @@
#include "orbsvcs/PortableGroup/PG_Operators.h" // Borrow operator== on CosNaming::Name
#include "orbsvcs/PortableGroup/PG_Utils.h"
+#include "tao/MProfile.h"
+#include "tao/Profile.h"
+#include "tao/Stub.h"
#include "tao/debug.h"
#include "ace/Get_Opt.h"
@@ -61,11 +64,13 @@ TAO::PG_Object_Group::PG_Object_Group (
, orb_ (CORBA::ORB::_duplicate (orb))
, factory_registry_ (PortableGroup::FactoryRegistry::_duplicate (factory_registry))
, manipulator_ (manipulator)
+ , distribute_ (1)
, empty_ (1)
, role_ (type_id)
, type_id_ (CORBA::string_dup (type_id))
, tagged_component_ (tagged_component)
, reference_ (CORBA::Object::_duplicate(empty_group))
+ , group_name_ (0)
, members_ ()
, primary_location_(0)
, properties_ (the_criteria, type_properties)
@@ -75,16 +80,35 @@ TAO::PG_Object_Group::PG_Object_Group (
{
}
+TAO::PG_Object_Group::PG_Object_Group (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator)
+ : internals_()
+ , orb_ (CORBA::ORB::_duplicate (orb))
+ , factory_registry_ (PortableGroup::FactoryRegistry::_duplicate (factory_registry))
+ , manipulator_ (manipulator)
+ , distribute_ (1)
+ , empty_ (1)
+ , role_ ("")
+ , type_id_ ()
+ , tagged_component_ ()
+ , reference_ (CORBA::Object::_nil ())
+ , group_name_ (0)
+ , members_ ()
+ , primary_location_(0)
+ , properties_ ()
+ , initial_number_members_ (0)
+ , minimum_number_members_ (0)
+ , group_specific_factories_ ()
+{
+}
+
TAO::PG_Object_Group::~PG_Object_Group (void)
{
- for (MemberMap_Iterator it = this->members_.begin();
- it != this->members_.end();
- ++it)
- {
- MemberInfo * member = (*it).int_id_;
- delete member;
- }
- this->members_.unbind_all ();
+ CORBA::string_free (this->group_name_);
+
+ this->clear_members_map ();
}
#if 0 // may want this again someday
@@ -127,7 +151,7 @@ TAO::PG_Object_Group::get_group_specific_factories (
}
const PortableGroup::Location &
-TAO::PG_Object_Group::get_primary_location (void) const
+TAO::PG_Object_Group::get_primary_location (void)
{
ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
guard,
@@ -192,11 +216,55 @@ TAO::PG_Object_Group::add_member (const PortableGroup::Location & the_location,
// IORs, not IOGRs to send new IOGRs out
// to replicas.
+ // Verify that the member is not using V1.0 profiles
+ // since IIOP V1.0 does not support tagged components
+ const TAO_MProfile &member_profiles =
+ member->_stubobj ()->base_profiles ();
+ CORBA::ULong member_profile_count =
+ member_profiles.profile_count ();
+ if (member_profile_count > 0)
+ {
+ const TAO_GIOP_Message_Version & version =
+ member_profiles.get_profile (0)->version ();
+ if (version.major_version () == 1 &&
+ version.minor_version () == 0)
+ {
+ if (TAO_debug_level > 3)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%T %n (%P|%t) - ")
+ ACE_TEXT ("Can't add member because first profile ")
+ ACE_TEXT ("is IIOP version 1.0, which does not ")
+ ACE_TEXT ("support tagged components.\n")
+ ));
+ }
+ throw PortableGroup::ObjectNotAdded ();
+ }
+ }
+
CORBA::String_var member_ior_string =
orb_->object_to_string (member);
- PortableGroup::ObjectGroup_var new_reference =
- add_member_to_iogr (member);
+ PortableGroup::ObjectGroup_var new_reference;
+ try {
+ new_reference =
+ this->add_member_to_iogr (member);
+ }
+ catch (const TAO_IOP::Duplicate&)
+ {
+ throw PortableGroup::MemberAlreadyPresent ();
+ }
+ catch (const TAO_IOP::Invalid_IOR&)
+ {
+ throw PortableGroup::ObjectNotAdded ();
+ }
+ catch (...)
+ {
+ throw;
+ }
+
+ if (CORBA::is_nil (new_reference.in ()))
+ throw PortableGroup::ObjectNotAdded ();
// Convert new member back to a (non group) ior.
CORBA::Object_var member_ior =
@@ -216,20 +284,21 @@ TAO::PG_Object_Group::add_member (const PortableGroup::Location & the_location,
this->reference_ = new_reference; // note var-to-var assignment does
// a duplicate
+
if (this->increment_version ())
{
this->distribute_iogr ();
}
else
- {
+ { // Issue with incrementing the version
throw PortableGroup::ObjectNotAdded ();
}
if (TAO_debug_level > 6)
- {
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT("PG (%P|%t) exit Object_Group add_member\n")));
- }
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("PG (%P|%t) exit Object_Group add_member\n")));
+ }
}
int
@@ -247,8 +316,8 @@ TAO::PG_Object_Group::set_primary_member (
{
int cleared = 0;
this->primary_location_ = the_location;
- for (MemberMap_Iterator it = this->members_.begin();
- !cleared && it != this->members_.end();
+ for (MemberMap_Iterator it = this->members_.begin ();
+ !cleared && it != this->members_.end ();
++it)
{
cleared = (*it).int_id_->is_primary_;
@@ -314,7 +383,7 @@ TAO::PG_Object_Group::remove_member (
MemberInfo * info = 0;
if (this->members_.unbind (the_location, info) == 0)
{
- if (this->members_.current_size() > 0)
+ if (this->members_.current_size () > 0)
{
this->reference_ =
this->manipulator_.remove_profiles (this->reference_.in (),
@@ -329,7 +398,7 @@ TAO::PG_Object_Group::remove_member (
if (the_location == this->primary_location_)
{
- this->primary_location_.length(0);
+ this->primary_location_.length (0);
}
if (this->increment_version ())
@@ -343,8 +412,8 @@ TAO::PG_Object_Group::remove_member (
if (TAO_debug_level > 6)
{
ACE_DEBUG ((LM_DEBUG,
- "TAO-PG (%P|%t) - "
- "remove_member throwing MemberNotFound.\n"
+ ACE_TEXT ("TAO-PG (%P|%t) - ")
+ ACE_TEXT ("remove_member throwing MemberNotFound.\n")
));
}
throw PortableGroup::MemberNotFound();
@@ -425,6 +494,10 @@ TAO::PG_Object_Group::increment_version (void)
void
TAO::PG_Object_Group::distribute_iogr (void)
{
+ // Check if the object group is configured to distribute
+ if (!this->distribute_)
+ return;
+
// assume internals is locked
CORBA::String_var iogr =
this->orb_->object_to_string (this->reference_.in());
@@ -509,6 +582,7 @@ TAO::PG_Object_Group::locations_of_members (void)
const PortableGroup::Location & location = (*it).ext_id_;
PortableGroup::Location & out = (*result)[pos];
out = location;
+ ++pos;
}
return result;
}
@@ -795,5 +869,39 @@ TAO::PG_Object_Group::has_member_at (const PortableGroup::Location & location)
return (0 == this->members_.find (location));
}
+void
+TAO::PG_Object_Group::distribute (int value)
+{
+ this->distribute_ = value;
+}
+
+void
+TAO::PG_Object_Group::set_name (const char* group_name)
+{
+ if (group_name_ != 0)
+ CORBA::string_free (group_name_);
+
+ group_name_ = CORBA::string_dup (group_name);
+}
+
+const char*
+TAO::PG_Object_Group::get_name (void)
+{
+ return group_name_;
+}
+
+void
+TAO::PG_Object_Group::clear_members_map (void)
+{
+ for (MemberMap_Iterator it = this->members_.begin();
+ it != this->members_.end();
+ ++it)
+ {
+ MemberInfo * member = (*it).int_id_;
+ delete member;
+ }
+ this->members_.unbind_all ();
+}
+
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h
index f5b5328b68e..176e3ef2f7d 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h
@@ -57,6 +57,9 @@ namespace TAO
*/
class TAO_PortableGroup_Export PG_Object_Group
{
+
+ protected:
+
// Information about an object group member
struct MemberInfo
{
@@ -73,7 +76,6 @@ namespace TAO
/// Location where this member exists
PortableGroup::Location location_;
-
/// TRUE if this is primary member
CORBA::Boolean is_primary_;
@@ -126,16 +128,24 @@ namespace TAO
const PortableGroup::Criteria & the_criteria,
TAO::PG_Property_Set * type_properties);
+ /**
+ * This constructor is to be used for initialization when
+ * reading the object group from a stream.
+ */
+ PG_Object_Group (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator);
/// Destructor
- ~PG_Object_Group ();
+ virtual ~PG_Object_Group ();
/////////////////
// public methods
public:
/// return a duplicated reference to this group (IOGR)
- PortableGroup::ObjectGroup_ptr reference()const;
+ PortableGroup::ObjectGroup_ptr reference() const;
/**
* Note the caller receives a copy of the factoryinfos in the result argument.
@@ -146,7 +156,7 @@ namespace TAO
/**
* get location of primary member
*/
- const PortableGroup::Location & get_primary_location() const;
+ virtual const PortableGroup::Location & get_primary_location();
/**
* returns a duplicate
@@ -186,14 +196,14 @@ namespace TAO
/**
* @@TODO DOC
*/
- PortableGroup::ObjectGroupId get_object_group_id () const;
+ virtual PortableGroup::ObjectGroupId get_object_group_id () const;
/**
* Add a new member to the group.
* @param the_location the location for the new member
* @param member the member to be added
*/
- void add_member (
+ virtual void add_member (
const PortableGroup::Location & the_location,
CORBA::Object_ptr member);
@@ -204,21 +214,21 @@ namespace TAO
* it returns a boolean result. A false return means caller should
* throw FT::PrimaryNot_Set.
*/
- int set_primary_member (
+ virtual int set_primary_member (
TAO_IOP::TAO_IOR_Property * prop,
const PortableGroup::Location & the_location);
/**
* @@TODO DOC
*/
- void remove_member (
+ virtual void remove_member (
const PortableGroup::Location & the_location);
/**
* @@TODO DOC
*/
- void create_member (
+ virtual void create_member (
const PortableGroup::Location & the_location,
const char * type_id,
const PortableGroup::Criteria & the_criteria);
@@ -226,30 +236,41 @@ namespace TAO
/**
* @@TODO DOC
*/
- PortableGroup::Locations * locations_of_members (void);
+ virtual PortableGroup::Locations * locations_of_members (void);
/**
* @@TODO DOC
*/
- CORBA::Object_ptr get_member_reference (
+ virtual CORBA::Object_ptr get_member_reference (
const PortableGroup::Location & the_location);
/**
* @@TODO DOC
*/
- void initial_populate (void);
+ virtual void initial_populate (void);
/**
* @@TODO DOC
*/
- void minimum_populate (void);
+ virtual void minimum_populate (void);
/**
* @@TODO DOC
*/
- int has_member_at (const PortableGroup::Location & location );
+ virtual int has_member_at (const PortableGroup::Location & location );
+
+
+ /**
+ * Tell the object group that it should distribute updates to the object
+ * group state.
+ */
+ virtual void distribute (int value);
+
+ virtual void set_name (const char* group_name);
+
+ virtual const char* get_name (void);
/////////////////////////
// Implementation methods
@@ -259,11 +280,13 @@ namespace TAO
void distribute_iogr (void);
- PortableGroup::ObjectGroup_ptr add_member_to_iogr(CORBA::Object_ptr member);
+ void create_members (size_t count);
+ protected:
- void create_members (size_t count);
+ virtual PortableGroup::ObjectGroup_ptr add_member_to_iogr(CORBA::Object_ptr member);
+ void clear_members_map (void);
/////////////////////////
// Forbidden methods
@@ -290,19 +313,28 @@ namespace TAO
*/
mutable TAO_SYNCH_MUTEX internals_;
+ protected:
CORBA::ORB_var orb_;
+ private:
+
/// Where to find the factories for replicas.
PortableGroup::FactoryRegistry_var factory_registry_;
+ protected:
// The object group manipulator
TAO::PG_Object_Group_Manipulator & manipulator_;
+ /// boolean true if updates should be distributed
+ int distribute_;
+
/// boolean true if empty group
int empty_;
ACE_CString role_;
+
+
PortableGroup::TypeId_var type_id_;
/**
@@ -325,6 +357,12 @@ namespace TAO
*/
PortableServer::ObjectId_var object_id_;
+ /**
+ * an optional attribute of the object group which is a string
+ * name that is assigned to the object group by the creator.
+ */
+ char* group_name_;
+
// group members
MemberMap members_;
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.cpp
index 8e91038f8be..e8ccd41d89b 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.cpp
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.cpp
@@ -61,7 +61,16 @@ TAO::PG_Object_Group_Manipulator::create_object_group (
PortableGroup::ObjectGroupId & group_id)
{
allocate_ogid(group_id);
- PortableServer::ObjectId_var oid = convert_ogid_to_oid (group_id);
+ return this->create_object_group_using_id(type_id, domain_id, group_id);
+}
+
+PortableGroup::ObjectGroup_ptr
+TAO::PG_Object_Group_Manipulator::create_object_group_using_id(
+ const char * type_id,
+ const char * domain_id,
+ const PortableGroup::ObjectGroupId & group_id)
+{
+ PortableServer::ObjectId_var oid = convert_ogid_to_oid (group_id);
// Create a reference for the ObjectGroup
CORBA::Object_var object_group =
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h
index 91c37045d1f..35a2fbbd524 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h
@@ -63,6 +63,16 @@ namespace TAO
const char * domain_id,
PortableGroup::ObjectGroupId & group_id);
+ /**
+ * Create an empty object group using a specific ID.
+ * Note that this should not also be used with create_object_group ()
+ * as the next object group ID to use will not necessarily be unique.
+ */
+ PortableGroup::ObjectGroup_ptr create_object_group_using_id (
+ const char * type_id,
+ const char * domain_id,
+ const PortableGroup::ObjectGroupId & group_id);
+
PortableGroup::ObjectGroup_ptr remove_profiles (
PortableGroup::ObjectGroup_ptr group,
PortableGroup::ObjectGroup_ptr profile) const;
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp
new file mode 100644
index 00000000000..7a457881ca4
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp
@@ -0,0 +1,571 @@
+// $Id$
+
+#include "orbsvcs/PortableGroup/PG_Object_Group_Storable.h"
+
+#include "tao/Storable_File_Guard.h"
+#include "tao/Storable_Factory.h"
+#include "tao/CDR.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace
+{
+ template <typename T>
+ void read_cdr (TAO::Storable_Base & stream, T & corba_data)
+ {
+ int size;
+ stream >> size;
+
+ char *tmp = 0;
+ ACE_NEW_THROW_EX (tmp, char [size], CORBA::NO_MEMORY ());
+ ACE_Auto_Basic_Array_Ptr<char> buf (tmp);
+ stream.read (size, buf.get ());
+
+ TAO_InputCDR cdr (buf.get (), size);
+ cdr >> corba_data;
+ if (!cdr.good_bit ())
+ {
+ stream.clear ();
+ throw CORBA::INTERNAL ();
+ }
+ }
+}
+
+namespace TAO
+{
+
+ class Object_Group_File_Guard : public TAO::Storable_File_Guard
+ {
+ public:
+
+ Object_Group_File_Guard ( TAO::PG_Object_Group_Storable & object_group,
+ Method_Type method_type);
+
+ ~Object_Group_File_Guard ();
+
+ virtual void set_object_last_changed (const time_t & time);
+
+ virtual time_t get_object_last_changed ();
+
+ /// Check if the guarded object is current with the last
+ /// update which could have been performed independently of
+ /// the owner of this object.
+ virtual bool object_obsolete ();
+
+ /// Mark the object as current with respect to the
+ /// file to which it was persisted.
+ virtual void mark_object_current ();
+
+ virtual void load_from_stream ();
+
+ virtual bool is_loaded_from_stream ();
+
+ virtual TAO::Storable_Base * create_stream (const char * mode);
+
+ private:
+
+ TAO::PG_Object_Group_Storable & object_group_;
+ };
+
+}
+
+TAO::Object_Group_File_Guard::Object_Group_File_Guard (
+ TAO::PG_Object_Group_Storable & object_group,
+ Method_Type method_type)
+ : TAO::Storable_File_Guard(true)
+ , object_group_(object_group)
+{
+ try
+ {
+ this->init (method_type);
+ }
+ catch (const TAO::Storable_Read_Exception &)
+ {
+ throw CORBA::INTERNAL ();
+ }
+}
+
+TAO::Object_Group_File_Guard::~Object_Group_File_Guard ()
+{
+ this->release ();
+
+ // Notify if persistent store was updated.
+ if (object_group_.write_occurred_)
+ object_group_.state_written ();
+}
+
+void
+TAO::Object_Group_File_Guard::set_object_last_changed (const time_t & time)
+{
+ object_group_.last_changed_ = time;
+}
+
+time_t
+TAO::Object_Group_File_Guard::get_object_last_changed ()
+{
+ return object_group_.last_changed_;
+}
+
+bool
+TAO::Object_Group_File_Guard::object_obsolete ()
+{
+ return object_group_.is_obsolete (fl_->last_changed ());
+}
+
+void
+TAO::Object_Group_File_Guard::mark_object_current ()
+{
+ object_group_.stale (false);
+ TAO::Storable_File_Guard::mark_object_current ();
+}
+
+void
+TAO::Object_Group_File_Guard::load_from_stream ()
+{
+ object_group_.read (this->peer ());
+ object_group_.loaded_from_stream_ = true;
+}
+
+bool
+TAO::Object_Group_File_Guard::is_loaded_from_stream ()
+{
+ return object_group_.loaded_from_stream_;
+}
+
+TAO::Storable_Base *
+TAO::Object_Group_File_Guard::create_stream (const char * mode)
+{
+ return object_group_.create_stream (mode);
+}
+
+// Make shortcut to get to Method_Type enums
+typedef TAO::Storable_File_Guard SFG;
+
+TAO::PG_Object_Group_Storable::PG_Object_Group_Storable (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ CORBA::Object_ptr empty_group,
+ const PortableGroup::TagGroupTaggedComponent & tagged_component,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ TAO::PG_Property_Set * type_properties,
+ TAO::Storable_Factory & storable_factory)
+ : PG_Object_Group(orb,
+ factory_registry,
+ manipulator,
+ empty_group,
+ tagged_component,
+ type_id,
+ the_criteria,
+ type_properties)
+ , group_previously_stored_(false)
+ , group_id_previously_stored_(0)
+ , storable_factory_ (storable_factory)
+ , last_changed_ (0)
+ , loaded_from_stream_ (false)
+ , destroyed_ (false)
+ , write_occurred_ (false)
+{
+ // Create a temporary stream simply to check if a readable
+ // version already exists.
+ bool stream_exists = false;
+ {
+ ACE_Auto_Ptr<TAO::Storable_Base> stream (
+ this->create_stream (ACE_TEXT_ALWAYS_CHAR ("r")));
+
+ if (stream->exists ())
+ stream_exists = true;
+ }
+
+ if (stream_exists)
+ {
+ Object_Group_File_Guard fg (*this, SFG::CREATE_WITH_FILE);
+ }
+ else
+ {
+ Object_Group_File_Guard fg (*this, SFG::CREATE_WITHOUT_FILE);
+ this->write (fg.peer ());
+ }
+}
+
+TAO::PG_Object_Group_Storable::PG_Object_Group_Storable (
+ PortableGroup::ObjectGroupId group_id,
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ TAO::Storable_Factory & storable_factory)
+ : PG_Object_Group(orb,
+ factory_registry,
+ manipulator)
+ , group_previously_stored_(true)
+ , group_id_previously_stored_(group_id)
+ , storable_factory_ (storable_factory)
+ , last_changed_ (0)
+ , loaded_from_stream_ (false)
+ , destroyed_ (false)
+ , write_occurred_ (false)
+{
+ // Create a temporary stream to simply to check if a readable
+ // version already exists.
+ bool stream_exists = false;
+ {
+ ACE_Auto_Ptr<TAO::Storable_Base> stream (
+ this->create_stream (ACE_TEXT_ALWAYS_CHAR ("r")));
+
+ if (stream->exists ())
+ stream_exists = true;
+ }
+
+ if (stream_exists)
+ {
+ Object_Group_File_Guard fg (*this, SFG::ACCESSOR);
+ }
+ else
+ {
+ throw CORBA::INTERNAL ();
+ }
+}
+
+TAO::PG_Object_Group_Storable::~PG_Object_Group_Storable (void)
+{
+ if (destroyed_)
+ {
+ ACE_Auto_Ptr<TAO::Storable_Base> stream (
+ this->create_stream (ACE_TEXT_ALWAYS_CHAR ("r")));
+
+ if (stream->exists ())
+ {
+ stream->remove ();
+ }
+
+ }
+
+}
+
+void
+TAO::PG_Object_Group_Storable::set_destroyed (bool destroyed)
+{
+ this->destroyed_ = destroyed;
+}
+
+const PortableGroup::Location &
+TAO::PG_Object_Group_Storable::get_primary_location (void)
+{
+ Object_Group_File_Guard fg (*this, SFG::ACCESSOR);
+ return TAO::PG_Object_Group::get_primary_location ();
+}
+
+
+void
+TAO::PG_Object_Group_Storable::add_member (
+ const PortableGroup::Location & the_location,
+ CORBA::Object_ptr member)
+{
+ Object_Group_File_Guard fg (*this, SFG::MUTATOR);
+ PG_Object_Group::add_member (the_location, member);
+ this->write (fg.peer ());
+}
+
+int
+TAO::PG_Object_Group_Storable::set_primary_member (
+ TAO_IOP::TAO_IOR_Property * prop,
+ const PortableGroup::Location & the_location)
+{
+ Object_Group_File_Guard fg (*this, SFG::MUTATOR);
+ int primary_member = PG_Object_Group::set_primary_member (prop, the_location);
+ this->write (fg.peer ());
+ return primary_member;
+}
+
+void
+TAO::PG_Object_Group_Storable::remove_member (
+ const PortableGroup::Location & the_location)
+{
+ Object_Group_File_Guard fg (*this, SFG::MUTATOR);
+ PG_Object_Group::remove_member (the_location);
+ this->write (fg.peer ());
+}
+
+
+PortableGroup::Locations *
+TAO::PG_Object_Group_Storable::locations_of_members (void)
+{
+ Object_Group_File_Guard fg (*this, SFG::ACCESSOR);
+ return PG_Object_Group::locations_of_members ();
+}
+
+void
+TAO::PG_Object_Group_Storable::create_member (
+ const PortableGroup::Location & the_location,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria)
+{
+ Object_Group_File_Guard fg (*this, SFG::MUTATOR);
+ PG_Object_Group::create_member (the_location,
+ type_id,
+ the_criteria);
+ this->write (fg.peer ());
+}
+
+void
+TAO::PG_Object_Group_Storable::set_name (const char* group_name)
+{
+ Object_Group_File_Guard fg (*this, SFG::MUTATOR);
+ PG_Object_Group::set_name (group_name);
+ this->write (fg.peer ());
+}
+
+const char*
+TAO::PG_Object_Group_Storable::get_name (void)
+{
+ Object_Group_File_Guard fg (*this, SFG::ACCESSOR);
+ return PG_Object_Group::get_name ();
+}
+
+void
+TAO::PG_Object_Group_Storable::initial_populate (void)
+{
+ Object_Group_File_Guard fg (*this, SFG::MUTATOR);
+ PG_Object_Group::initial_populate ();
+ this->write (fg.peer ());
+}
+
+void
+TAO::PG_Object_Group_Storable::minimum_populate (void)
+{
+ Object_Group_File_Guard fg (*this, SFG::MUTATOR);
+ PG_Object_Group::minimum_populate ();
+ this->write (fg.peer ());
+}
+
+int
+TAO::PG_Object_Group_Storable::has_member_at (
+ const PortableGroup::Location & location)
+{
+ Object_Group_File_Guard fg (*this, SFG::ACCESSOR);
+ return PG_Object_Group::has_member_at (location);
+}
+
+void
+TAO::PG_Object_Group_Storable::distribute (int value)
+{
+ Object_Group_File_Guard fg (*this, SFG::MUTATOR);
+ PG_Object_Group::distribute (value);
+ this->write (fg.peer ());
+}
+
+CORBA::Object_ptr
+TAO::PG_Object_Group_Storable::get_member_reference (
+ const PortableGroup::Location & the_location)
+{
+ Object_Group_File_Guard fg (*this, SFG::ACCESSOR);
+ return PG_Object_Group::get_member_reference (the_location);
+}
+
+PortableGroup::ObjectGroupId
+TAO::PG_Object_Group_Storable::get_object_group_id () const
+{
+ if (this->group_previously_stored_)
+ return this->group_id_previously_stored_;
+
+ return PG_Object_Group::get_object_group_id ();
+}
+
+TAO::Storable_Base *
+TAO::PG_Object_Group_Storable::create_stream (const char * mode)
+{
+ char file_name[BUFSIZ];
+ // Although PortableGroup::ObjectGroupId is a typedef
+ // to long long int, make ID type explicit to avoid
+ // GNU C++ warning on sprintf statement.
+ long long int id = this->get_object_group_id ();
+ ACE_OS::sprintf (file_name, ACE_TEXT_ALWAYS_CHAR ("ObjectGroup_%lld"), id);
+ return this->storable_factory_.create_stream (file_name, mode);
+}
+
+void
+TAO::PG_Object_Group_Storable::read (TAO::Storable_Base & stream)
+{
+ stream.rewind ();
+
+ ACE_CString group_name;
+ stream >> group_name;
+
+ PG_Object_Group::set_name(group_name.c_str());
+
+ stream >> this->distribute_;
+
+ stream >> this->role_;
+
+ ///// primary_location_ /////
+ read_cdr (stream, this->primary_location_);
+
+ ///// reference_ /////
+ ACE_CString reference_ior;
+ stream >> reference_ior;
+ this->reference_ = this->orb_->string_to_object (reference_ior.c_str ());
+
+ ///// tagged_component_ /////
+ read_cdr (stream, this->tagged_component_);
+
+ ///// type_id_ /////
+ read_cdr(stream, this->type_id_);
+
+ ///// properties_ /////
+ PortableGroup::Criteria properties;
+ read_cdr (stream, properties);
+ PG_Object_Group::set_properties_dynamically (properties);
+
+ ///// members_ /////
+ int num_members;
+ stream >> num_members;
+
+ this->clear_members_map ();
+
+ for (int i = 0; i < num_members; ++i)
+ {
+ ///// location used as members_ key /////
+ PortableGroup::Location the_location;
+ read_cdr (stream, the_location);
+
+ ///// member /////
+ ACE_CString member_ior;
+ stream >> member_ior;
+ CORBA::Object_var member =
+ this->orb_->string_to_object (member_ior.c_str ());
+ if (CORBA::is_nil (member))
+ throw CORBA::INV_OBJREF ();
+
+ ///// location /////
+ PortableGroup::Location location;
+ read_cdr (stream, location);
+
+ ///// factory /////
+ ACE_CString factory_ior;
+ stream >> factory_ior;
+ CORBA::Object_var obj =
+ this->orb_->string_to_object (factory_ior.c_str ());
+ PortableGroup::GenericFactory_var factory =
+ PortableGroup::GenericFactory::_narrow (obj.in());
+
+ ///// factory_id (typedef of CORBA::Any) /////
+ PortableGroup::GenericFactory::FactoryCreationId factory_id;
+ read_cdr (stream, factory_id);
+
+ ///// is_primary /////
+ int is_primary;
+ stream >> is_primary;
+
+ MemberInfo * info = 0;
+ ACE_NEW_THROW_EX (info, MemberInfo(member.in (),
+ the_location,
+ factory,
+ factory_id),
+ CORBA::NO_MEMORY());
+
+ info->is_primary_ = is_primary;
+
+ if (this->members_.bind (the_location, info) != 0)
+ {
+ throw CORBA::NO_MEMORY();
+ }
+ }
+}
+
+void
+TAO::PG_Object_Group_Storable::write (TAO::Storable_Base & stream)
+{
+ stream.rewind ();
+
+ ACE_CString group_name = PG_Object_Group::get_name ();
+ stream << group_name;
+ stream << this->distribute_;
+ stream << this->role_;
+
+ TAO_OutputCDR primary_location_cdr;
+ primary_location_cdr << PG_Object_Group::get_primary_location ();
+ stream << primary_location_cdr;
+
+ ACE_CString reference_ior =
+ this->orb_->object_to_string (this->reference_.in ());
+ stream << reference_ior;
+
+ TAO_OutputCDR tagged_component_cdr;
+ tagged_component_cdr << this->tagged_component_;
+ stream << tagged_component_cdr;
+
+ TAO_OutputCDR type_id_cdr;
+ PortableGroup::TypeId_var type_id = PG_Object_Group::get_type_id ();
+ type_id_cdr << type_id;
+ stream << type_id_cdr;
+
+ TAO_OutputCDR properties_cdr;
+ PortableGroup::Criteria properties;
+ this->properties_.export_properties (properties);
+ properties_cdr << properties;
+ stream << properties_cdr;
+
+ ///// members_ /////
+ int num_members = this->members_.current_size ();
+ stream << num_members;
+ for (MemberMap_Iterator it = this->members_.begin ();
+ it != this->members_.end ();
+ ++it)
+ {
+ PortableGroup::Location the_location = it->key ();
+ TAO_OutputCDR the_location_cdr;
+ the_location_cdr << the_location;
+ stream << the_location_cdr;
+
+ MemberInfo * member = it->item ();
+ ACE_CString member_ior =
+ this->orb_->object_to_string (member->member_.in ());
+ stream << member_ior;
+
+ TAO_OutputCDR location_cdr;
+ location_cdr << member->location_;
+ stream << location_cdr;
+
+ ACE_CString factory_ior =
+ this->orb_->object_to_string (member->factory_.in ());
+ stream << factory_ior;
+
+ TAO_OutputCDR factory_id_cdr;
+ factory_id_cdr << member->factory_id_;
+ stream << factory_id_cdr;
+
+ stream << member->is_primary_;
+ }
+ stream.flush ();
+ this->write_occurred_ = true;
+}
+
+void
+TAO::PG_Object_Group_Storable::stale (bool is_stale)
+{
+ ACE_UNUSED_ARG (is_stale);
+ // Default implementation is no-op
+}
+
+bool
+TAO::PG_Object_Group_Storable::stale ()
+{
+ // Default is to return false
+ return false;
+}
+
+void
+TAO::PG_Object_Group_Storable::state_written (void)
+{
+ // No-op. Overridden by derived class.
+}
+
+bool
+TAO::PG_Object_Group_Storable::is_obsolete (time_t stored_time)
+{
+ return (!this->loaded_from_stream_) ||
+ stored_time > this->last_changed_;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.h
new file mode 100644
index 00000000000..56d86677624
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.h
@@ -0,0 +1,194 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file PG_Object_Group_Storable.h
+ *
+ * $Id$
+ *
+ * Contains declaration for class PG_Object_Group_Storable.
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_PG_OBJECT_GROUP_STORABLE_H_
+#define TAO_PG_OBJECT_GROUP_STORABLE_H_
+#include /**/ "ace/pre.h"
+
+#include "orbsvcs/PortableGroup/portablegroup_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+/////////////////////////////////
+// Includes needed by this header
+#include "orbsvcs/PortableGroup/PG_Object_Group.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/////////////////////
+// Forward references
+namespace TAO
+{
+ class Storable_Factory;
+ class Storable_Base;
+}
+
+////////////////
+// Class declarations
+namespace TAO
+{
+ /**
+ * An object group whose state persists to a stream so that its state
+ * can be saved/retrieved between processes that use the group.
+ */
+ class TAO_PortableGroup_Export PG_Object_Group_Storable
+ : public PG_Object_Group
+ {
+
+ /////////////////////
+ // Construct/Destruct
+ public:
+
+ /**
+ * This constructor is suitable for creating an object group from
+ * scratch.
+ */
+ PG_Object_Group_Storable (
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ CORBA::Object_ptr empty_group,
+ const PortableGroup::TagGroupTaggedComponent & tagged_component,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria,
+ TAO::PG_Property_Set * type_properties,
+ TAO::Storable_Factory & storable_factory);
+
+ /**
+ * This constructor is suitable for creating an object group from
+ * persistent store.
+ */
+ PG_Object_Group_Storable (
+ PortableGroup::ObjectGroupId group_id,
+ CORBA::ORB_ptr orb,
+ PortableGroup::FactoryRegistry_ptr factory_registry,
+ TAO::PG_Object_Group_Manipulator & manipulator,
+ TAO::Storable_Factory & storable_factory);
+
+ /// Destructor
+ ~PG_Object_Group_Storable ();
+
+ /////////////////
+ // public methods
+
+ public:
+
+ /**
+ * Indicate that this object group is to be permanently
+ * destroyed. During destruction the persistent store
+ * for this will then be removed.
+ * This is to distinguish between deletion from a process
+ * shutdown verses deletion from a destroy request.
+ */
+ void set_destroyed (bool destroyed);
+
+ /**
+ * Allow for replication persistence support by
+ * derived classes.
+ */
+ virtual void stale (bool is_stale);
+ virtual bool stale ();
+
+ virtual const PortableGroup::Location & get_primary_location ();
+
+ virtual void add_member (
+ const PortableGroup::Location & the_location,
+ CORBA::Object_ptr member);
+
+ virtual int set_primary_member (
+ TAO_IOP::TAO_IOR_Property * prop,
+ const PortableGroup::Location & the_location);
+
+ virtual void remove_member (
+ const PortableGroup::Location & the_location);
+
+ virtual void create_member (
+ const PortableGroup::Location & the_location,
+ const char * type_id,
+ const PortableGroup::Criteria & the_criteria);
+
+ virtual PortableGroup::Locations * locations_of_members (void);
+
+ virtual CORBA::Object_ptr get_member_reference (
+ const PortableGroup::Location & the_location);
+
+ virtual void initial_populate (void);
+
+ virtual void minimum_populate (void);
+
+ virtual int has_member_at (const PortableGroup::Location & location );
+
+ virtual void distribute (int value);
+
+ virtual void set_name (const char* group_name);
+
+ virtual const char* get_name (void);
+
+ virtual PortableGroup::ObjectGroupId get_object_group_id () const;
+
+ private:
+
+ /////////////////////////
+ // Forbidden methods
+ PG_Object_Group_Storable ();
+ PG_Object_Group_Storable (const PG_Object_Group_Storable & rhs);
+ PG_Object_Group_Storable & operator = (const PG_Object_Group_Storable & rhs);
+
+ /// Indicate if instance of object group has been restored from store
+ bool group_previously_stored_;
+ PortableGroup::ObjectGroupId group_id_previously_stored_;
+
+ TAO::Storable_Base * create_stream (const char * mode);
+
+ void read (TAO::Storable_Base & stream);
+
+ void write (TAO::Storable_Base & stream);
+
+ TAO::Storable_Factory & storable_factory_;
+ time_t last_changed_;
+
+ protected:
+
+ bool loaded_from_stream_;
+
+ bool destroyed_;
+
+ /// To set when state written out.
+ bool write_occurred_;
+
+ /**
+ * Signals that this context was updated.
+ */
+ virtual void state_written (void);
+
+ /**
+ * A callback invoked by the object group file guard
+ * to determine if this context is obsolete with respect to
+ * the peristent store.
+ */
+ virtual bool is_obsolete (time_t stored_time);
+
+ friend class Object_Group_File_Guard;
+
+ };
+} // namespace TAO
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif // TAO_PG_OBJECT_GROUP_STORABLE_H_
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp
index 07739231579..ede4d544d03 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp
@@ -149,24 +149,22 @@ void TAO::PG_Property_Set::set_property (
CORBA::NO_MEMORY ());
const PortableGroup::Value * replaced_value = 0;
- if (0 == this->values_.rebind (name, value_copy, replaced_value))
- {
- if (0 != replaced_value)
- {
+ int rebind_result = this->values_.rebind (name, value_copy, replaced_value);
+ if (1 == rebind_result)
+ { // Existing value was replaced
delete replaced_value;
}
- }
- else
- {
- if (TAO_debug_level > 3)
- {
- ACE_ERROR ( (LM_ERROR,
- "%n\n%T: Property_set: rebind failed.\n"
- ));
+ else if (-1 == rebind_result)
+ { // Value was not rebound.
+ if (TAO_debug_level > 3)
+ {
+ ACE_ERROR ( (LM_ERROR,
+ "%n\n%T: Property_set: rebind failed.\n"
+ ));
+ }
+ // @@ should throw something here
+ throw CORBA::NO_MEMORY ();
}
- // @@ should throw something here
- throw CORBA::NO_MEMORY ();
- }
}
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.cpp
index fecf55c86b8..10a7057b444 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.cpp
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.cpp
@@ -547,7 +547,7 @@ TAO_UIPMC_Profile::endpoint_count (void) const
}
char *
-TAO_UIPMC_Profile::to_string (void)
+TAO_UIPMC_Profile::to_string (void) const
{
// corbaloc:miop:1.0@1.0-group_id-1-1/host:port
diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.h b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.h
index 994af6d4274..7406a16b0d1 100644
--- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.h
+++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.h
@@ -82,7 +82,7 @@ public:
/// a useable decode_endpoints
virtual int decode (TAO_InputCDR &cdr);
virtual void parse_string (const char *string);
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
virtual int encode_endpoints (void);
virtual void encodeAddressInfo (TAO_OutputCDR &stream) const;
virtual TAO_Endpoint *endpoint (void);
diff --git a/TAO/orbsvcs/orbsvcs/cosnaming_serv_persistence.mpb b/TAO/orbsvcs/orbsvcs/cosnaming_serv_persistence.mpb
index 1caf3ca3f1f..8318fbecd86 100644
--- a/TAO/orbsvcs/orbsvcs/cosnaming_serv_persistence.mpb
+++ b/TAO/orbsvcs/orbsvcs/cosnaming_serv_persistence.mpb
@@ -5,13 +5,15 @@
feature(!corba_e_micro) {
Source_Files(ORBSVCS_COMPONENTS) {
Naming {
- Naming/Flat_File_Persistence.cpp
Naming/Persistent_Context_Index.cpp
Naming/Persistent_Entries.cpp
Naming/Persistent_Naming_Context.cpp
Naming/Storable.cpp
Naming/Storable_Naming_Context.cpp
Naming/Storable_Naming_Context_Activator.cpp
+ Naming/Storable_Naming_Context_ReaderWriter.cpp
+ Naming/Persistent_Naming_Context_Factory.cpp
+ Naming/Storable_Naming_Context_Factory.cpp
}
}
}