summaryrefslogtreecommitdiff
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
parent9d296f7fa51116ff7040ecb2ad18612cd94b5fd1 (diff)
downloadATCD-5e030faf84086ab02059fcbcc3faed224bd57b95.tar.gz
Merge in OCI_Reliability_Enhancements branch.
-rw-r--r--ACE/ACEXML/common/FileCharStream.cpp29
-rw-r--r--ACE/ACEXML/common/FileCharStream.h10
-rw-r--r--ACE/ChangeLog113
-rw-r--r--ACE/ace/Mem_Map.inl4
-rw-r--r--ACE/ace/Message_Block.cpp141
-rw-r--r--ACE/include/makeinclude/platform_clang_common.GNU1
-rw-r--r--ACE/tests/Message_Block_Large_Copy_Test.cpp153
-rw-r--r--ACE/tests/run_test.lst1
-rw-r--r--ACE/tests/tests.mpc7
-rw-r--r--TAO/ChangeLog4835
-rw-r--r--TAO/DevGuideExamples/Multithreading/DynamicThreadPool/DynamicThreadPool.mpc37
-rw-r--r--TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger.idl10
-rw-r--r--TAO/DevGuideExamples/Multithreading/DynamicThreadPool/MessengerClient.cpp74
-rw-r--r--TAO/DevGuideExamples/Multithreading/DynamicThreadPool/MessengerServer.cpp104
-rw-r--r--TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.cpp36
-rw-r--r--TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.h36
-rw-r--r--TAO/DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.cpp3
-rw-r--r--TAO/DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.h12
-rw-r--r--TAO/MPC/config/dynamic_tp.mpb7
-rw-r--r--TAO/MPC/config/ft_naming_serv.mpb7
-rw-r--r--TAO/MPC/config/ftnaming.mpb9
-rw-r--r--TAO/MPC/config/ftnaming_replication.mpb7
-rw-r--r--TAO/MPC/config/imr_client.mpb2
-rw-r--r--TAO/NEWS49
-rw-r--r--TAO/TAO_IDL/tao_idl.mpc4
-rw-r--r--TAO/bin/tao_orb_tests.lst8
-rw-r--r--TAO/bin/tao_other_tests.lst16
-rw-r--r--TAO/docs/Options.html403
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp315
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Config_Backing_Store.h125
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp76
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp18
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl49
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp899
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h38
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc7
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp146
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Options.h22
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp789
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h181
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp108
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h48
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/README154
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp21
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Server_Info.h4
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp1366
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Shared_Backing_Store.h302
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp323
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/XML_Backing_Store.h161
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp15
-rw-r--r--TAO/orbsvcs/Naming_Service/FT_Naming_Main.cpp64
-rw-r--r--TAO/orbsvcs/Naming_Service/FT_Naming_Service.cpp31
-rw-r--r--TAO/orbsvcs/Naming_Service/FT_Naming_Service.h52
-rw-r--r--TAO/orbsvcs/Naming_Service/Naming_Service.cpp35
-rw-r--r--TAO/orbsvcs/Naming_Service/Naming_Service.h16
-rw-r--r--TAO/orbsvcs/Naming_Service/Naming_Service.mpc12
-rw-r--r--TAO/orbsvcs/Naming_Service/README88
-rw-r--r--TAO/orbsvcs/Naming_Service/README.FT_Naming252
-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
-rwxr-xr-xTAO/orbsvcs/tests/Bug_2777_Regression/run_test.pl31
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Basic.cpp64
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Basic.h59
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerant.mpc32
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/LB_server.cpp229
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/LB_server.h98
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/README234
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Test.idl27
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp2324
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_0bin0 -> 4858 bytes
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_global3
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService5
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_05
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_18
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_25
-rwxr-xr-xTAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_equivalence_test.pl423
-rwxr-xr-xTAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_failover_test.pl416
-rwxr-xr-xTAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_persistence_test.pl652
-rwxr-xr-xTAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_test.pl44
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/server.cpp121
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/FaultTolerant/test_object.idl11
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Federation/Federation.mpc38
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Federation/Hello.cpp23
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Federation/Hello.h31
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Federation/README70
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Federation/Test.idl26
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Federation/client.cpp78
-rwxr-xr-xTAO/orbsvcs/tests/FT_Naming/Federation/run_test.pl268
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Federation/server.cpp176
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp61
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h59
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp222
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.h98
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Load_Balancing_Name_Service.mpc34
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/README8
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Test.idl27
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp160
-rwxr-xr-xTAO/orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl229
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/server.cpp119
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/svc.conf3
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf3
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf.xml10
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Replication/README54
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Replication/Replication.mpc7
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Replication/client.cpp689
-rwxr-xr-xTAO/orbsvcs/tests/FT_Naming/Replication/run_test.pl212
-rw-r--r--TAO/orbsvcs/tests/FT_Naming/Replication/test_object.idl11
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/README25
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp6
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger.idl18
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/MessengerClient.cpp82
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/MessengerServer.cpp117
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.cpp53
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.h43
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/README10
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/RestartServer.mpc37
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/Terminator.cpp40
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/Terminator.h13
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/RestartServer/client.conf3
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/RestartServer/run_test.pl245
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/airplane_client_i.cpp9
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/airplane_client_i.h2
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/airplane_server_i.cpp25
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/airplane_server_i.h3
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/run_test.pl2265
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_1884_Regression/common.h4
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_1884_Regression/filter.cpp4
-rwxr-xr-xTAO/orbsvcs/tests/Notify/Bug_3688_Regression/common.h4
-rw-r--r--TAO/orbsvcs/tests/Notify/Persistent_Filter/Filter.cpp8
-rw-r--r--TAO/orbsvcs/tests/Redundant_Naming/client.cpp97
-rwxr-xr-xTAO/orbsvcs/tests/Redundant_Naming/run_test.pl10
-rw-r--r--TAO/orbsvcs/tests/Simple_Naming/client.cpp15
-rwxr-xr-xTAO/orbsvcs/tests/Simple_Naming/run_test_ffp.pl92
-rwxr-xr-xTAO/orbsvcs/tests/Simple_Naming/run_test_ft.pl217
-rw-r--r--TAO/tao/AnyTypeCode/Struct_TypeCode.cpp13
-rw-r--r--TAO/tao/AnyTypeCode/Struct_TypeCode.h3
-rw-r--r--TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp371
-rw-r--r--TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h112
-rw-r--r--TAO/tao/AnyTypeCode/Union_TypeCode.cpp13
-rw-r--r--TAO/tao/AnyTypeCode/Union_TypeCode.h3
-rw-r--r--TAO/tao/AnyTypeCode/Value_TypeCode.cpp26
-rw-r--r--TAO/tao/AnyTypeCode/Value_TypeCode.h6
-rw-r--r--TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp61
-rw-r--r--TAO/tao/CSD_Framework/CSD_ORBInitializer.h2
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp1
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h2
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp175
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp7
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Task.h2
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp56
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h10
-rw-r--r--TAO/tao/Client_Strategy_Factory.h10
-rw-r--r--TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp13
-rw-r--r--TAO/tao/DynamicInterface/DII_Invocation_Adapter.h9
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Config.cpp327
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Config.h124
-rw-r--r--TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp132
-rw-r--r--TAO/tao/Dynamic_TP/DTP_ORBInitializer.h72
-rw-r--r--TAO/tao/Dynamic_TP/DTP_ORB_Loader.cpp113
-rw-r--r--TAO/tao/Dynamic_TP/DTP_ORB_Loader.h63
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Loader.cpp199
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Loader.h62
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Strategy.cpp422
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Strategy.h220
-rw-r--r--TAO/tao/Dynamic_TP/DTP_POA_Strategy.inl35
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Task.cpp479
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Task.h199
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Task.inl7
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp131
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h124
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp456
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Pool.h249
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Pool.inl43
-rw-r--r--TAO/tao/Dynamic_TP/Dynamic_TP.mpc10
-rw-r--r--TAO/tao/Dynamic_TP/dynamic_tp_export.h58
-rw-r--r--TAO/tao/IIOP_Profile.cpp2
-rw-r--r--TAO/tao/IIOP_Profile.h2
-rw-r--r--TAO/tao/IIOP_Transport.cpp3
-rw-r--r--TAO/tao/IORManipulation/IORManipulation.cpp8
-rw-r--r--TAO/tao/ImR_Client/ImR_Client.cpp311
-rw-r--r--TAO/tao/ImR_Client/ImR_Client.h5
-rw-r--r--TAO/tao/ImR_Client/ImR_Client.mpc2
-rw-r--r--TAO/tao/Invocation_Adapter.cpp20
-rw-r--r--TAO/tao/Invocation_Adapter.h9
-rw-r--r--TAO/tao/Invocation_Retry_Params.cpp20
-rw-r--r--TAO/tao/Invocation_Retry_Params.h61
-rw-r--r--TAO/tao/Invocation_Retry_State.cpp176
-rw-r--r--TAO/tao/Invocation_Retry_State.h98
-rw-r--r--TAO/tao/Invocation_Utils.h2
-rw-r--r--TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp5
-rw-r--r--TAO/tao/Messaging/Asynch_Invocation_Adapter.h3
-rw-r--r--TAO/tao/ORB_Core.cpp57
-rw-r--r--TAO/tao/PortableServer/ImR_Client_Adapter.h15
-rw-r--r--TAO/tao/PortableServer/LifespanStrategy.h10
-rw-r--r--TAO/tao/PortableServer/LifespanStrategyPersistent.cpp27
-rw-r--r--TAO/tao/PortableServer/LifespanStrategyPersistent.h3
-rw-r--r--TAO/tao/PortableServer/LifespanStrategyTransient.cpp7
-rw-r--r--TAO/tao/PortableServer/LifespanStrategyTransient.h3
-rw-r--r--TAO/tao/PortableServer/Root_POA.cpp71
-rw-r--r--TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp28
-rw-r--r--TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h2
-rw-r--r--TAO/tao/Profile.cpp2
-rw-r--r--TAO/tao/Profile.h4
-rw-r--r--TAO/tao/Seq_Var_T.h9
-rw-r--r--TAO/tao/Seq_Var_T.inl15
-rw-r--r--TAO/tao/Storable_Base.cpp97
-rw-r--r--TAO/tao/Storable_Base.h181
-rw-r--r--TAO/tao/Storable_Base.inl74
-rw-r--r--TAO/tao/Storable_Factory.cpp25
-rw-r--r--TAO/tao/Storable_Factory.h52
-rw-r--r--TAO/tao/Storable_File_Guard.cpp266
-rw-r--r--TAO/tao/Storable_File_Guard.h124
-rw-r--r--TAO/tao/Storable_FlatFileStream.cpp475
-rw-r--r--TAO/tao/Storable_FlatFileStream.h145
-rw-r--r--TAO/tao/Strategies/COIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/COIOP_Profile.h2
-rw-r--r--TAO/tao/Strategies/DIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/DIOP_Profile.h2
-rw-r--r--TAO/tao/Strategies/SCIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/SCIOP_Profile.h2
-rw-r--r--TAO/tao/Strategies/SHMIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/SHMIOP_Profile.h2
-rw-r--r--TAO/tao/Strategies/UIOP_Profile.cpp2
-rw-r--r--TAO/tao/Strategies/UIOP_Profile.h2
-rw-r--r--TAO/tao/Stub.cpp32
-rw-r--r--TAO/tao/Stub.h6
-rw-r--r--TAO/tao/Stub.inl59
-rw-r--r--TAO/tao/Synch_Invocation.cpp340
-rw-r--r--TAO/tao/Synch_Invocation.h10
-rw-r--r--TAO/tao/Transport.cpp7
-rw-r--r--TAO/tao/Transport.h9
-rw-r--r--TAO/tao/VarOut_T.h4
-rw-r--r--TAO/tao/VarOut_T.inl16
-rw-r--r--TAO/tao/default_client.cpp160
-rw-r--r--TAO/tao/default_client.h5
-rw-r--r--TAO/tao/params.cpp39
-rw-r--r--TAO/tao/params.h26
-rw-r--r--TAO/tao/tao.mpc6
-rw-r--r--TAO/tests/Dynamic_TP/Config_Loader/Config_Loader.mpc5
-rw-r--r--TAO/tests/Dynamic_TP/Config_Loader/Test.cpp80
-rw-r--r--TAO/tests/Dynamic_TP/Config_Loader/svc.conf16
-rw-r--r--TAO/tests/Dynamic_TP/ORB_ThreadPool/Client.cpp130
-rw-r--r--TAO/tests/Dynamic_TP/ORB_ThreadPool/ORB_ThreadPool.mpc35
-rw-r--r--TAO/tests/Dynamic_TP/ORB_ThreadPool/Server.cpp111
-rw-r--r--TAO/tests/Dynamic_TP/ORB_ThreadPool/Test.idl19
-rw-r--r--TAO/tests/Dynamic_TP/ORB_ThreadPool/Test_i.cpp24
-rw-r--r--TAO/tests/Dynamic_TP/ORB_ThreadPool/Test_i.h29
-rw-r--r--TAO/tests/Dynamic_TP/ORB_ThreadPool/client.conf4
-rwxr-xr-xTAO/tests/Dynamic_TP/ORB_ThreadPool/run_test.pl77
-rw-r--r--TAO/tests/Dynamic_TP/ORB_ThreadPool/server.conf4
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Dynamic_TP_POA_Test_Dynamic.mpc35
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.cpp43
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.h34
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Test.idl24
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/client.cpp98
-rwxr-xr-xTAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/run_test.pl404
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/server.cpp122
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc1.conf4
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc2.conf4
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc3.conf4
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc4.conf4
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Dynamic_TP_POA_Test_Static.mpc35
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.cpp43
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.h34
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Test.idl24
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/client.cpp98
-rwxr-xr-xTAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl403
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/server.cpp196
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/POA_Loader.mpc5
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/Test.cpp102
-rw-r--r--TAO/tests/Dynamic_TP/POA_Loader/svc.conf15
-rw-r--r--TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.cpp26
-rw-r--r--TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.h33
-rw-r--r--TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/README14
-rw-r--r--TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Retry_On_Connection_Failure.mpc37
-rw-r--r--TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Test.idl22
-rw-r--r--TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/client.cpp87
-rwxr-xr-xTAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/run_test.pl104
-rw-r--r--TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/server.cpp115
-rwxr-xr-xTAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/README23
-rwxr-xr-xTAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/Retry_On_Reply_Failure.mpc35
-rwxr-xr-xTAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/client.cpp278
-rwxr-xr-xTAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl152
-rwxr-xr-xTAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/server.cpp121
-rwxr-xr-xTAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test.idl8
-rwxr-xr-xTAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.cpp58
-rwxr-xr-xTAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.h46
-rw-r--r--TAO/tests/POA/Non_Retain_System_Id/Non_Retain_System_Id.mpc6
-rwxr-xr-xTAO/tests/POA/Non_Retain_System_Id/run_test.pl22
-rw-r--r--TAO/tests/POA/Non_Retain_System_Id/test.cpp215
-rw-r--r--TAO/tests/POA/Non_Retain_System_Id/test.idl6
-rw-r--r--TAO/tests/Storable/README14
-rw-r--r--TAO/tests/Storable/Savable.cpp228
-rw-r--r--TAO/tests/Storable/Savable.h61
-rw-r--r--TAO/tests/Storable/Storable.mpc6
-rw-r--r--TAO/tests/Storable/data_files/bad_binary.dat6
-rw-r--r--TAO/tests/Storable/data_files/bad_int.dat3
-rw-r--r--TAO/tests/Storable/data_files/bad_string.dat2
-rw-r--r--TAO/tests/Storable/data_files/bad_unsigned_int.dat4
-rw-r--r--TAO/tests/Storable/data_files/good.dat11
-rwxr-xr-xTAO/tests/Storable/run_test.pl156
-rw-r--r--TAO/tests/Storable/test.cpp188
-rw-r--r--TAO/tests/Var_Deref/README.txt8
-rw-r--r--TAO/tests/Var_Deref/Test.idl19
-rw-r--r--TAO/tests/Var_Deref/Var_Deref.mpc23
-rw-r--r--TAO/tests/Var_Deref/var_deref.cpp83
-rw-r--r--TAO/utils/logWalker/GIOP_Buffer.cpp597
-rw-r--r--TAO/utils/logWalker/GIOP_Buffer.h117
-rw-r--r--TAO/utils/logWalker/HostProcess.cpp115
-rw-r--r--TAO/utils/logWalker/HostProcess.h16
-rw-r--r--TAO/utils/logWalker/Invocation.cpp721
-rw-r--r--TAO/utils/logWalker/Invocation.h82
-rw-r--r--TAO/utils/logWalker/Log.cpp1020
-rw-r--r--TAO/utils/logWalker/Log.h105
-rw-r--r--TAO/utils/logWalker/PeerObject.cpp7
-rw-r--r--TAO/utils/logWalker/PeerProcess.cpp95
-rw-r--r--TAO/utils/logWalker/PeerProcess.h16
-rw-r--r--TAO/utils/logWalker/Session.cpp33
-rw-r--r--TAO/utils/logWalker/Session.h8
-rw-r--r--TAO/utils/logWalker/Thread.cpp154
-rw-r--r--TAO/utils/logWalker/Thread.h32
-rw-r--r--TAO/utils/logWalker/logWalker.cpp44
-rw-r--r--TAO/utils/nsgroup/README.nsgroup156
-rw-r--r--TAO/utils/nsgroup/nsgroup.cpp519
-rw-r--r--TAO/utils/nsgroup/nsgroup.mpc9
-rwxr-xr-xTAO/utils/nsgroup/run_test.pl443
-rw-r--r--TAO/utils/nsgroup/windows.conf3
-rw-r--r--TAO/utils/nsgroup/windows.conf.xml10
-rw-r--r--TAO/utils/nslist/nslist.cpp109
-rw-r--r--TAO/utils/utils.mwc2
405 files changed, 44000 insertions, 5006 deletions
diff --git a/ACE/ACEXML/common/FileCharStream.cpp b/ACE/ACEXML/common/FileCharStream.cpp
index 68178850707..f6ed10308d4 100644
--- a/ACE/ACEXML/common/FileCharStream.cpp
+++ b/ACE/ACEXML/common/FileCharStream.cpp
@@ -12,7 +12,8 @@
#endif /* ACE_USES_WCHAR */
ACEXML_FileCharStream::ACEXML_FileCharStream (void)
- : filename_ (0), encoding_ (0), size_ (0), infile_ (0), peek_ (0)
+ : filename_ (0), encoding_ (0), size_ (0), infile_ (0),
+ close_infile_ (true), peek_ (0)
{
}
@@ -22,7 +23,7 @@ ACEXML_FileCharStream::~ACEXML_FileCharStream (void)
}
int
-ACEXML_FileCharStream::open (const ACEXML_Char *name)
+ACEXML_FileCharStream::use_stream_i (FILE* open_file, const ACEXML_Char *name)
{
delete[] this->filename_;
this->filename_ = 0;
@@ -30,7 +31,7 @@ ACEXML_FileCharStream::open (const ACEXML_Char *name)
delete[] this->encoding_;
this->encoding_ = 0;
- this->infile_ = ACE_OS::fopen (name, ACE_TEXT ("r"));
+ this->infile_ = open_file;
if (this->infile_ == 0)
return -1;
@@ -44,6 +45,23 @@ ACEXML_FileCharStream::open (const ACEXML_Char *name)
}
int
+ACEXML_FileCharStream::use_stream (FILE* open_file, const ACEXML_Char *name)
+{
+ if (open_file != 0)
+ ACE_OS::rewind(open_file);
+
+ this->close_infile_ = false;
+ return use_stream_i(open_file, name);
+}
+
+int
+ACEXML_FileCharStream::open (const ACEXML_Char *name)
+{
+ this->close_infile_ = true;
+ return use_stream_i(ACE_OS::fopen (name, ACE_TEXT ("r")), name);
+}
+
+int
ACEXML_FileCharStream::determine_encoding (void)
{
if (this->infile_ == 0)
@@ -114,7 +132,10 @@ ACEXML_FileCharStream::close (void)
{
if (this->infile_ != 0)
{
- ACE_OS::fclose (this->infile_);
+ if (this->close_infile_)
+ {
+ ACE_OS::fclose (this->infile_);
+ }
this->infile_ = 0;
}
delete[] this->filename_;
diff --git a/ACE/ACEXML/common/FileCharStream.h b/ACE/ACEXML/common/FileCharStream.h
index 1f208e0f8fe..129b169e34e 100644
--- a/ACE/ACEXML/common/FileCharStream.h
+++ b/ACE/ACEXML/common/FileCharStream.h
@@ -41,6 +41,12 @@ public:
int open (const ACEXML_Char *name);
/**
+ * Accept an already opened file. The stream does not
+ * assume ownership of open_file.
+ */
+ int use_stream (FILE* open_file, const ACEXML_Char *name);
+
+ /**
* Returns the available ACEXML_Char in the buffer. -1
* if the object is not initialized properly.
*/
@@ -113,10 +119,14 @@ private:
#endif /* ACE_USES_WCHAR */
+ /// internal accept an already opened file.
+ int use_stream_i (FILE* open_file, const ACEXML_Char *name);
+
ACEXML_Char* filename_;
ACEXML_Char* encoding_;
ACE_OFF_T size_;
FILE* infile_;
+ bool close_infile_;
// This is needed to ensure that we can implement a peek operation on a
// UTF-16 encoded file. It is a bit hackish, but there is no other way of
// implementing a peek() as the standard I/O FILE* guarantees only one
diff --git a/ACE/ChangeLog b/ACE/ChangeLog
index 3db1bdf1e4b..7dc8b7903b5 100644
--- a/ACE/ChangeLog
+++ b/ACE/ChangeLog
@@ -1,3 +1,116 @@
+Tue Feb 5 21:04:17 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ Several new features and bug fixes captured in Bugzilla 4091, 4092, 4093,
+ 4094, 4095, and 4096. Also includes Bugzilla 3247. Specific details of the
+ changes described below through the tag at the end bookmarked with:
+ ***** OCI_Reliability_Enhancements Changes
+
+ Tue Feb 5 17:01:48 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * ace/Auto_Event.h:
+ * bin/valgrind.supp:
+ * protocols/ace/INet/inet.mpc:
+ * protocols/examples/INet:
+ * tests/CDR_Test.cpp:
+ * protocols/ace/INet/FTP_Simple_exec.cpp:
+ * protocols/ace/INet/HTTP_Simple_exec.cpp:
+
+ Merged changes from trunk in preparation for merge. The
+ above files had changes.
+
+ Thu Jan 31 22:39:53 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * ace/Message_Block.cpp:
+
+ Fixed problem with allocator in clone and duplicate
+
+ * tests/Message_Block_Large_Copy_Test.cpp:
+
+ Added reference count output
+
+ Thu Jan 31 18:41:26 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * tests/Message_Block_Large_Copy_Test.cpp:
+
+ Corrected test for scoreboard
+
+ Thu Jan 31 14:38:03 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * tests/Message_Block_Large_Copy_Test.cpp:
+
+ Fixed another error in allocation missed the first time.
+
+ Thu Jan 31 14:31:17 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * tests/Message_Block_Large_Copy_Test.cpp:
+
+ Fixed error in allocation of character array.
+
+ Wed Jan 30 23:54:14 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * ace/Message_Block.cpp:
+
+ Applied bug 3247 duplicate patch that replaced recursion with
+ iteration to support the copying of large message blocks.
+
+ * tests/Message_Block_Large_Copy_Test.cpp:
+ * tests/run_test.lst:
+ * tests/tests.mpc:
+
+ Created test to cover the cloning and duplication of
+ large Message_Blocks.
+
+ Tue Jan 29 15:15:09 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * include/makeinclude/platform_sunos5_g++.GNU:
+
+ Merged trunk into branch.
+
+ Mon Jan 28 16:13:07 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * ace/config-macosx-lion.h:
+ * ace/config-macosx-mountainlion.h:
+ * ace/config-macosx-snowleopard.h:
+ * examples/Shared_Memory/test_MM.cpp:
+ * examples/Shared_Memory/test_SV.cpp:
+ * include/makeinclude/platform_macosx_mountainlion.GNU:
+ * ace/config-macosx-mountain-lion.h:
+ * include/makeinclude/platform_macosx_mountain_lion.GNU:
+
+ Merged trunk into branch. The above files were changed in the
+ trunk.
+
+ Wed Dec 19 17:52:25 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * ace/Mem_Map.inl:
+
+ Fix a warning about signed/unsigned mix.
+
+ * include/makeinclude/platform_clang_common.GNU:
+
+ Increase the warning level used by the CLang++ compiler to show all warnings
+
+ Mon Dec 17 14:39:07 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * ACEXML/common/FileCharStream.cpp:
+
+ Fixed to not close the infile_ if it was passed to the
+ FileCharStream.
+
+ Fri Dec 14 17:31:22 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * ACEXML/common/FileCharStream.h:
+ * ACEXML/common/FileCharStream.cpp:
+
+ Added interface to accept an already open FILE stream.
+
+ Mon Oct 15 18:26:57 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * OCI_RE_ChangeLog:
+ Created change log for the OCI Reliability Enhancements branch
+
+ ***** OCI_Reliability_Enhancements Changes
+
Mon Feb 4 08:58:35 UTC 2013 Johnny Willemsen <jwillemsen@remedy.nl>
* protocols/ace/INet/inet.mpc:
diff --git a/ACE/ace/Mem_Map.inl b/ACE/ace/Mem_Map.inl
index 78a99646a88..4fd43d4f3de 100644
--- a/ACE/ace/Mem_Map.inl
+++ b/ACE/ace/Mem_Map.inl
@@ -122,7 +122,7 @@ ACE_Mem_Map::unmap (ssize_t len)
if (this->base_addr_ != MAP_FAILED)
{
int const result = ACE_OS::munmap (this->base_addr_,
- len < 0 ? this->length_ : len);
+ len < 0 ? this->length_ : (size_t)len);
this->base_addr_ = MAP_FAILED;
return result;
}
@@ -140,7 +140,7 @@ ACE_Mem_Map::unmap (void *addr, ssize_t len)
this->close_filemapping_handle ();
return ACE_OS::munmap (addr,
- len < 0 ? this->length_ : len);
+ len < 0 ? this->length_ : (size_t)len);
}
// Sync <len> bytes of the memory region to the backing store starting
diff --git a/ACE/ace/Message_Block.cpp b/ACE/ace/Message_Block.cpp
index 867cf699bf1..d4ad6ad4488 100644
--- a/ACE/ace/Message_Block.cpp
+++ b/ACE/ace/Message_Block.cpp
@@ -1016,78 +1016,93 @@ ACE_Message_Block::duplicate (void) const
{
ACE_TRACE ("ACE_Message_Block::duplicate");
+ ACE_Message_Block *nb_top = 0;
ACE_Message_Block *nb = 0;
- // Create a new <ACE_Message_Block> that contains unique copies of
- // the message block fields, but a reference counted duplicate of
- // the <ACE_Data_Block>.
-
- // If there is no allocator, use the standard new and delete calls.
- if (this->message_block_allocator_ == 0)
- ACE_NEW_RETURN (nb,
- ACE_Message_Block (0, // size
- ACE_Message_Type (0), // type
- 0, // cont
- 0, // data
- 0, // allocator
- 0, // locking strategy
- 0, // flags
- this->priority_, // priority
- ACE_EXECUTION_TIME,
- ACE_DEADLINE_TIME,
- // Get a pointer to a
- // "duplicated" <ACE_Data_Block>
- // (will simply increment the
- // reference count).
- this->data_block ()->duplicate (),
- this->data_block ()->data_block_allocator (),
- this->message_block_allocator_),
- 0);
- else // Otherwise, use the message_block_allocator passed in.
- ACE_NEW_MALLOC_RETURN (nb,
- static_cast<ACE_Message_Block*> (
- message_block_allocator_->malloc (sizeof (ACE_Message_Block))),
- ACE_Message_Block (0, // size
- ACE_Message_Type (0), // type
- 0, // cont
- 0, // data
- 0, // allocator
- 0, // locking strategy
- 0, // flags
- this->priority_, // priority
- ACE_EXECUTION_TIME,
- ACE_DEADLINE_TIME,
- // Get a pointer to a
- // "duplicated" <ACE_Data_Block>
- // (will simply increment the
- // reference count).
- this->data_block ()->duplicate (),
- this->data_block ()->data_block_allocator (),
- this->message_block_allocator_),
- 0);
-
- // Set the read and write pointers in the new <Message_Block> to the
- // same relative offset as in the existing <Message_Block>. Note
- // that we are assuming that the data_block()->base() pointer
- // doesn't change when it's duplicated.
- nb->rd_ptr (this->rd_ptr_);
- nb->wr_ptr (this->wr_ptr_);
+ const ACE_Message_Block *current = this;
// Increment the reference counts of all the continuation messages.
- if (this->cont_)
+ while (current)
{
- nb->cont_ = this->cont_->duplicate ();
+ ACE_Message_Block* cur_dup = 0;
+
+ // Create a new <ACE_Message_Block> that contains unique copies of
+ // the message block fields, but a reference counted duplicate of
+ // the <ACE_Data_Block>.
+
+ // If there is no allocator, use the standard new and delete calls.
+ if (current->message_block_allocator_ == 0)
+ ACE_NEW_NORETURN (cur_dup,
+ ACE_Message_Block (0, // size
+ ACE_Message_Type (0), // type
+ 0, // cont
+ 0, // data
+ 0, // allocator
+ 0, // locking strategy
+ 0, // flags
+ current->priority_, // priority
+ ACE_EXECUTION_TIME,
+ ACE_DEADLINE_TIME,
+ // Get a pointer to a
+ // "duplicated" <ACE_Data_Block>
+ // (will simply increment the
+ // reference count).
+ current->data_block ()->duplicate (),
+ current->data_block ()->data_block_allocator (),
+ current->message_block_allocator_));
+ else // Otherwise, use the message_block_allocator passed in.
+ ACE_NEW_MALLOC_NORETURN (cur_dup,
+ static_cast<ACE_Message_Block*> (
+ current->message_block_allocator_->malloc (sizeof (ACE_Message_Block))),
+ ACE_Message_Block (0, // size
+ ACE_Message_Type (0), // type
+ 0, // cont
+ 0, // data
+ 0, // allocator
+ 0, // locking strategy
+ 0, // flags
+ current->priority_, // priority
+ ACE_EXECUTION_TIME,
+ ACE_DEADLINE_TIME,
+ // Get a pointer to a
+ // "duplicated" <ACE_Data_Block>
+ // (will simply increment the
+ // reference count).
+ current->data_block ()->duplicate (),
+ current->data_block ()->data_block_allocator (),
+ current->message_block_allocator_));
+
+
+ // If allocation failed above, release everything done so far and return NULL
+ if (cur_dup == 0)
+ {
+ nb_top->release ();
+ return NULL;
+ }
+
+ // Set the read and write pointers in the new <Message_Block> to the
+ // same relative offset as in the existing <Message_Block>. Note
+ // that we are assuming that the data_block()->base() pointer
+ // doesn't change when it's duplicated.
+ cur_dup->rd_ptr (current->rd_ptr_);
+ cur_dup->wr_ptr (current->wr_ptr_);
- // If things go wrong, release all of our resources and return
- // 0.
- if (nb->cont_ == 0)
+ if (!nb)
+ {
+ /* First in the list: set leading pointers */
+ nb_top = nb = cur_dup;
+ }
+ else
{
- nb->release ();
- nb = 0;
+ /* Continuing on: append to nb and walk down the list */
+ nb->cont_ = cur_dup;
+ nb = nb->cont_;
}
+
+ current = current->cont_;
}
- return nb;
+ return nb_top;
}
ACE_Message_Block *
@@ -1216,7 +1231,7 @@ ACE_Message_Block::clone (Message_Flags mask) const
// the cloned data block that was created above. If we used
// ACE_NEW_MALLOC_RETURN, there would be a memory leak because the
// above db pointer would be left dangling.
- new_message_block = static_cast<ACE_Message_Block*> (message_block_allocator_->malloc (sizeof (ACE_Message_Block)));
+ new_message_block = static_cast<ACE_Message_Block*> (old_message_block->message_block_allocator_->malloc (sizeof (ACE_Message_Block)));
if (new_message_block != 0)
new (new_message_block) ACE_Message_Block (0, // size
ACE_Message_Type (0), // type
diff --git a/ACE/include/makeinclude/platform_clang_common.GNU b/ACE/include/makeinclude/platform_clang_common.GNU
index ec63f7cf721..3c8e1dbab71 100644
--- a/ACE/include/makeinclude/platform_clang_common.GNU
+++ b/ACE/include/makeinclude/platform_clang_common.GNU
@@ -117,3 +117,4 @@ else
CPPFLAGS += -DACE_HAS_CUSTOM_EXPORT_MACROS=0
endif # shared_libs
+FLAGS_C_CC += -W -Wall
diff --git a/ACE/tests/Message_Block_Large_Copy_Test.cpp b/ACE/tests/Message_Block_Large_Copy_Test.cpp
new file mode 100644
index 00000000000..062ddb34017
--- /dev/null
+++ b/ACE/tests/Message_Block_Large_Copy_Test.cpp
@@ -0,0 +1,153 @@
+
+//=============================================================================
+/**
+ * @file Message_Block_Large_Copy_Test.cpp
+ *
+ * $Id$
+ *
+ * This test program tests large Message Block duplication and cloning.
+ *
+ *
+ * @author Phillip LaBanca <labancap@ociweb.com>
+ */
+//=============================================================================
+
+
+#include "test_config.h"
+#include "ace/Message_Block.h"
+
+size_t
+run_duplicate_test (const size_t msg_block_count,
+ const char * block,
+ const size_t msg_block_size)
+{
+ size_t rc = 0;
+
+ ACE_Message_Block* mb_top = new ACE_Message_Block ();
+ ACE_Message_Block* mb = mb_top;
+
+ for (size_t j = 0; j != msg_block_count; ++j)
+ {
+ ACE_Message_Block* next = new ACE_Message_Block (block, msg_block_size);
+ next->copy (block);
+ mb->cont (next);
+ mb = next;
+ }
+
+ ACE_Message_Block* mb_test = mb_top->duplicate ();
+ if (mb_test != 0)
+ {
+ rc = mb_test->total_size();
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) %u top reference_count ()\n"),
+ mb_top->reference_count ()));
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) duplicated: %@ %d %d\n"),
+ mb_test,
+ mb_test->total_size(),
+ mb_test->total_length()));
+ mb_test-> release();
+ }
+
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) %u top reference_count ()\n"),
+ mb_top->reference_count ()));
+
+ mb_top-> release ();
+ return rc;
+}
+
+size_t
+run_clone_test (const size_t msg_block_count,
+ const char * block,
+ const size_t msg_block_size)
+{
+ size_t rc = 0;
+
+ ACE_Message_Block* mb_top = new ACE_Message_Block ();
+ ACE_Message_Block* mb = mb_top;
+
+ for (size_t j = 0; j != msg_block_count; ++j)
+ {
+ ACE_Message_Block* next = new ACE_Message_Block (block, msg_block_size);
+ next->copy (block);
+ mb->cont (next);
+ mb = next;
+ }
+
+ ACE_Message_Block* mb_test = mb_top->clone ();
+ if (mb_test != 0)
+ {
+ rc = mb_test->total_size();
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) %u top reference_count ()\n"),
+ mb_top->reference_count ()));
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) cloned: %@ %d %d\n"),
+ mb_test,
+ mb_test->total_size(),
+ mb_test->total_length()));
+ mb_test-> release();
+ }
+
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) %u top reference_count ()\n"),
+ mb_top->reference_count ()));
+
+ mb_top-> release();
+ return rc;
+}
+
+int
+run_main (int , ACE_TCHAR *[])
+{
+
+ int rc = 0;
+
+ ACE_START_TEST (ACE_TEXT ("Message_Block_Large_Copy_Test"));
+ {
+
+ // Message_Block size() and Length() of 24,000,000
+ const size_t MSG_BLOCK_COUNT = 8000;
+ const size_t MSG_BLOCK_SIZE = 3000;
+ const size_t MSG_BLOCK_TOTAL = MSG_BLOCK_COUNT * MSG_BLOCK_SIZE;
+
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) %u blocks %u bytes each, total %u\n"),
+ MSG_BLOCK_COUNT,
+ MSG_BLOCK_SIZE,
+ MSG_BLOCK_TOTAL));
+
+ char block[MSG_BLOCK_SIZE];
+ for(size_t j = 0 ; j != MSG_BLOCK_SIZE; j++)
+ block[j] = 'A';
+ block[MSG_BLOCK_SIZE-1] = 0;
+
+ size_t duplicate_total = run_duplicate_test (
+ MSG_BLOCK_COUNT,
+ block,
+ MSG_BLOCK_SIZE);
+ if (duplicate_total != MSG_BLOCK_TOTAL )
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) duplicate(): returned total of %u\n"),
+ duplicate_total));
+ rc = 1;
+ }
+
+ size_t clone_total = run_clone_test (
+ MSG_BLOCK_COUNT,
+ block,
+ MSG_BLOCK_SIZE);
+ if (clone_total != MSG_BLOCK_TOTAL )
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) clone(): returned total of %u \n"),
+ clone_total));
+ rc = 1;
+ }
+
+ }
+ ACE_END_TEST;
+ return rc;
+}
diff --git a/ACE/tests/run_test.lst b/ACE/tests/run_test.lst
index 914b5699bb3..de4d8aeca49 100644
--- a/ACE/tests/run_test.lst
+++ b/ACE/tests/run_test.lst
@@ -138,6 +138,7 @@ Map_Test: !ACE_FOR_TAO
Max_Default_Port_Test: !ST
Mem_Map_Test: !VxWorks !nsk !ACE_FOR_TAO
Memcpy_Test: !ACE_FOR_TAO
+Message_Block_Large_Copy_Test
Message_Block_Test: !ACE_FOR_TAO
Message_Queue_Notifications_Test
Message_Queue_Test: !ACE_FOR_TAO
diff --git a/ACE/tests/tests.mpc b/ACE/tests/tests.mpc
index a5c13da5c2b..318b4d184dd 100644
--- a/ACE/tests/tests.mpc
+++ b/ACE/tests/tests.mpc
@@ -1407,6 +1407,13 @@ project(Simple Message Block Test) : acetest {
}
}
+project(Message Block Large Copy Test) : acetest {
+ exename = Message_Block_Large_Copy_Test
+ Source_Files {
+ Message_Block_Large_Copy_Test.cpp
+ }
+}
+
project(Singleton Test) : acetest {
exename = Singleton_Test
Source_Files {
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index b6a1f97540b..51bf0ace43d 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,4838 @@
+Tue Feb 5 21:02:55 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ Several new features and bug fixes captured in Bugzilla 4091, 4092, 4093,
+ 4094, 4095, and 4096. Specific details of the changes described below
+ through the tag at the end bookmarked with:
+ ***** OCI_Reliability_Enhancements Changes
+
+ Tue Feb 5 17:10:58 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * TAO_IDL/be/be_enum.cpp:
+ * TAO_IDL/be/be_visitor_enum/enum_cs.cpp:
+
+ Merged additional changes from trunk in preparation for merge. The
+ above files had changes.
+
+ Tue Feb 5 17:00:14 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * bin/tao_orb_tests.lst:
+ * docs/Options.html:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Transport.cpp:
+ * tao/AnyTypeCode/Any_Dual_Impl_T.h:
+ * tao/AnyTypeCode/Any_Dual_Impl_T.cpp:
+ * tao/GIOP_Message_Base.cpp:
+ * tests/Bug_4082_Regression/run_test.pl:
+
+ Merged changes from trunk in preparation for merge. The
+ above files had changes.
+
+ Mon Feb 4 22:57:48 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_Service.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+
+ Updates to doxygen comments.
+
+ * orbsvcs/Naming_Service/README.FT_Naming:
+
+ Added in two missing options to summary description.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp:
+
+ Filled in incomplete documentation.
+
+ Fri Feb 1 21:55:33 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * tests/Storable/run_test.pl:
+
+ Allow number of loops and loop delay to be specified
+ from the command line to manually determine values
+ that could cause test failure.
+
+ * tests/Storable/test.cpp:
+
+ Code clean up.
+
+ Fri Feb 1 21:44:54 UTC 2013 Marc Neeley <neeley_m@ociweb.com>
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+ Changed the way the backup files were cleaned up in
+ run script as it was causing an indirect error to occur
+ in the scoreboard log.
+
+ Trapped XML parse errors in run script for tests where
+ the XML persistence files were purposefully corrupted
+ causing false tests fail condition in the scoreboard log.
+
+ Thu Jan 31 23:31:54 UTC 2013 Marc Neeley <neeley_m@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+ Three tests were added to test a corruption of
+ (1) a primary listing file - persistent_listingcorrupt
+ (2) a primary activator file - persistent_activatorcorrupt
+ (3) a primary server file - persistent_servercorrupt
+
+ Thu Jan 31 23:21:08 UTC 2013 Marc Neeley <neeley_m@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+ Added a new method to Shared_Backing_Store class called write_listing.
+ This new method is refactoring to allow either a primary or backup
+ listing file to be written. Modifications were also made to write to
+ a primary and a backup file (the primary file name with a .bak ext)
+ for the server and activator services. Reading modifications were
+ made for listing, server, and activator files such that if the read
+ from primary failed, then the read from the backup would be performed.
+
+ Thu Jan 31 19:12:02 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+
+ Avoid running Redundant_Naming test on Windows. Not supported on that platform.
+
+ * orbsvcs/tests/Bug_2777_Regression/run_test.pl:
+
+ Run tao_nslist from $ACE_ROOT/bin instead of searching for it.
+
+ Thu Jan 31 15:59:23 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * bin/tao_orb_tests.lst:
+
+ Disable Storable test under Windows because of file locking
+ problems.
+
+ Thu Jan 31 14:10:56 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+
+ Fixed formatting issues. Lines too long.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp:
+
+ Fixed error in which exception was being printed in catch block.
+
+ * tao/ORB_Core.cpp:
+
+ Fixed copy paste error in comment.
+
+ Wed Jan 30 19:03:33 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * docs/Options.html:
+
+ Fix typos for for a few invocation retry parameters.
+
+ * tao/DynamicInterface/DII_Invocation_Adapter.h:
+ * tao/DynamicInterface/DII_Invocation_Adapter.cpp:
+ * tao/Invocation_Adapter.h:
+ * tao/Invocation_Adapter.cpp:
+ * tao/Invocation_Retry_State.h:
+ * tao/Invocation_Retry_State.cpp:
+ * tao/Messaging/Asynch_Invocation_Adapter.h:
+ * tao/Messaging/Asynch_Invocation_Adapter.cpp:
+ * tao/Stub.h:
+ * tao/Stub.cpp:
+ * tao/Synch_Invocation.h:
+ * tao/Synch_Invocation.cpp:
+
+ Fixed bad assumption I made for invocation retries
+ that Invocation_Adapter::invoke () would not be
+ done asynchronously with the same TAO_Stub.
+
+ Tue Jan 29 15:13:13 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * ChangeLog:
+ * TAO_IDL:
+ * TAO_IDL/be/be_sequence.cpp:
+ * examples/Advanced/ch_12/client.cpp:
+ * examples/Advanced/ch_18/client.cpp:
+ * examples/Advanced/ch_21/client.cpp:
+ * examples/Advanced/ch_8_and_10/client.cpp:
+ * orbsvcs/tests/Miop/McastFragmentation/client.cpp:
+ * orbsvcs/tests/Miop/McastFragmentation/run_test.pl:
+ * orbsvcs/tests/Miop/McastFragmentation/run_test_ipv6.pl:
+ * orbsvcs/tests/Miop/McastFragmentation/uipmc_client.conf:
+ * orbsvcs/tests/Miop/McastFragmentation/uipmc_server.conf:
+ * orbsvcs/tests/Miop/McastFragmentation/uipmc_server_m.conf:
+ * orbsvcs/tests/Miop/McastFragmentation/uipmc_server_n.conf:
+
+ Merged Doc group trunk into branch to resolve issues with building examples.
+
+ Mon Jan 28 22:54:36 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/README:
+
+ Update documentation for fault tolerant tao_imr_locator
+
+ * utils/nsgroup/run_test.pl:
+
+ Fix file redirection option check in run_client()
+
+ Mon Jan 28 22:20:12 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Naming_Loader.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Loader.cpp:
+
+ Creates the Naming Server object if one is not passed in
+ as it did before. Allows user to pass in a derived
+ Naming Server if they wish to use it.
+
+ * utils/nslist/nslist.cpp:
+
+ Avoid warnings regarding conversions.
+
+ Mon Jan 28 22:22:09 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * tests/Storable/run_test.pl:
+
+ Redirect output as was similary done in previous commit.
+
+ Mon Jan 28 20:09:12 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_persistence_test.pl:
+
+ Redirect output wih expected error messages encountered
+ reading corrupt files so that these messages will not
+ indicated test failure.
+
+ Mon Jan 28 16:09:03 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+ * docs/Options.html:
+
+ Resolved conflict between trunk update and branch changes.
+
+ * NEWS:
+ * TAO_IDL/be/be_visitor_interface/interface_ch.cpp:
+ * TAO_IDL/be/be_visitor_interface/interface_cs.cpp:
+ * examples/Advanced/ch_12/client.cpp:
+ * examples/Advanced/ch_18/client.cpp:
+ * examples/Advanced/ch_21/client.cpp:
+ * examples/Advanced/ch_8_and_10/client.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Transport.h:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Transport.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/miop_resource.h:
+ * orbsvcs/orbsvcs/PortableGroup/miop_resource.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/miopconf.h:
+ * orbsvcs/tests/Miop/McastFragmentation/Hello_Impl.h:
+ * orbsvcs/tests/Miop/McastFragmentation/Hello_Impl.cpp:
+ * orbsvcs/tests/Miop/McastFragmentation/client.cpp:
+ * orbsvcs/tests/Miop/McastFragmentation/run_test.pl:
+ * orbsvcs/tests/Miop/McastFragmentation/run_test_ipv6.pl:
+ * orbsvcs/tests/Miop/McastFragmentation/server.cpp:
+ * tao/DynamicInterface/Request.h:
+
+ Merged trunk to OCI_Reliability_Enhancements branch. These files were changed on
+ the trunk.
+
+ Sun Jan 27 18:57:35 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_Base.h:
+ * tao/Storable_Base.inl:
+ * tao/Storable_Base.cpp:
+ * tao/Storable_Factory.h:
+ * tao/Storable_File_Guard.h:
+ * tao/Storable_File_Guard.cpp:
+ * tao/Storable_FlatFileStream.h:
+ * tao/Storable_FlatFileStream.cpp:
+
+ Added exceptions to throw when read and write
+ failures occur.
+ Added support to backup persistent files
+ and restoring when an exception is encountered
+ when trying to read from the file.
+
+ * tests/Storable/Savable.h:
+ * tests/Storable/Savable.cpp:
+ * tests/Storable/data_files:
+ * tests/Storable/data_files/bad_binary.dat:
+ * tests/Storable/data_files/bad_int.dat:
+ * tests/Storable/data_files/bad_string.dat:
+ * tests/Storable/data_files/bad_unsigned_int.dat:
+ * tests/Storable/data_files/good.dat:
+ * tests/Storable/run_test.pl:
+ * tests/Storable/test.cpp:
+
+ Update to test that backup file will be
+ used if an exception is encountered.
+ Verify this works for reading of various
+ types of data.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp:
+
+ Removed streaming reading error handling and let
+ Storable_FlatFileStream operations throw
+ Storable_Read_Exceptions instead. This way Storable_File_Guard
+ can transparently try to use backup files if a read exception
+ is encountered during reading.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Enable support for backup/restore of persistent files.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_0:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_global:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_0:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_1:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_2:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_persistence_test.pl:
+
+ Update persistence test to verify that backup files are
+ generated and will be used if a corrupt file is being
+ read.
+
+ Fri Jan 25 22:39:26 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp:
+
+ Fixed warnings for unused exception variables. Some of them were
+ printing the wrong exception.
+
+ * utils/logWalker/Log.cpp:
+
+ Fixed warning for sprintf of size_t.
+
+ * utils/nslist/nslist.cpp:
+
+ Changed variables to size_t to avoid potential loss of data warning.
+
+ Fri Jan 25 22:05:54 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/README:
+
+ Updated FaultTolerant_ImR_Locator section
+
+ Thu Jan 24 16:01:37 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ Merged trunk to OCI_Reliability_Enhancements branch.
+
+ Wed Jan 23 23:05:41 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp:
+
+ Add yield calls to equivalence test section to avert race conditions
+ on some platforms.
+
+ * utils/nslist/nslist.cpp:
+
+ Change count argument conversion to strtoul to better match range.
+
+ Wed Jan 23 16:55:34 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/Naming_Service.mpc:
+
+ Removed install to $ACE_ROOT/bin to revert back to how
+ Naming Service was previously.
+
+ Wed Jan 23 00:05:57 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nslist/nslist.cpp:
+
+ Added --count argument to override the default maximum number of
+ entries to retrieve per request to the NameService. The tao_ft_naming
+ server returns CORBA:NO_IMPLEMENT when the number of entries is greater
+ than the how_many argument and the tao_ft_naming server was started
+ the -u or -r flags. The tao_ft_naming server is not able to support the
+ iterator interface in redundant mode (-u or -r flags).
+
+ Tue Jan 22 22:52:17 UTC 2013 Quynh Nguyen <nguyenq@stladvantage.com>
+
+ * orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp:
+
+ * tao/ImR_Client:
+ * tao/Monitor:
+ * tao/Utils:
+
+ Fix bug 479 caused by the Activator, which truncated a
+ server's command line string it is more than 1024 bytes.
+
+
+ Tue Jan 22 19:37:57 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.cpp:
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp:
+
+ * tao/Storable_Base.h:
+ * tao/Storable_Base.inl:
+ * tao/Storable_File_Guard.cpp:
+ * tao/Storable_FlatFileStream.h:
+ * tao/Storable_FlatFileStream.cpp:
+
+ Additional ACE Development Guidelines conformance updates in
+ preparation for merge.
+
+ Tue Jan 22 15:12:59 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * utils/logWalker/GIOP_Buffer.h:
+ * utils/logWalker/GIOP_Buffer.cpp:
+ * utils/logWalker/Invocation.cpp:
+ * utils/logWalker/Thread.cpp:
+
+ Fixed type conversion issues - size_t to long & int.
+
+ * utils/nsgroup/nsgroup.cpp:
+
+ Fixed warning for unused exception variable.
+
+ Tue Jan 22 04:05:51 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+
+ Excluded tests for FT_Naming from Win32.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Added missing initialization for naming_manager_ior_file_name_.
+
+ Mon Jan 21 22:52:17 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+
+ Added check for nil object prior to querying if it is a group.
+
+ * utils/nsgroup/run_test.pl:
+
+ Added tests to expose the issue with nil objects in naming service.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp:
+
+ * tao/CSD_Framework/CSD_Framework_Loader.cpp:
+
+ * tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Task.cpp:
+ * tao/CSD_ThreadPool/CSD_ThreadPool.cpp:
+
+ * tao/Dynamic_TP/DTP_Config.cpp:
+ * tao/Dynamic_TP/DTP_ORBInitializer.cpp:
+ * tao/Dynamic_TP/DTP_ORB_Loader.cpp:
+ * tao/Dynamic_TP/DTP_POA_Loader.h:
+ * tao/Dynamic_TP/DTP_POA_Loader.cpp:
+ * tao/Dynamic_TP/DTP_POA_Strategy.inl:
+ * tao/Dynamic_TP/DTP_POA_Strategy.cpp:
+ * tao/Dynamic_TP/DTP_Task.cpp:
+ * tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h:
+ * tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp:
+ * tao/Dynamic_TP/DTP_Thread_Pool.h:
+ * tao/Dynamic_TP/DTP_Thread_Pool.cpp:
+
+ * tao/ImR_Client/ImR_Client.cpp:
+
+ * tao/Invocation_Adapter.cpp:
+ * tao/Invocation_Retry_State.cpp:
+ * tao/ORB_Core.cpp:
+
+ * tao/PortableServer/LifespanStrategy.h:
+ * tao/PortableServer/LifespanStrategyPersistent.cpp:
+ * tao/PortableServer/LifespanStrategyTransient.h:
+ * tao/PortableServer/LifespanStrategyTransient.cpp:
+ * tao/PortableServer/Root_POA.cpp:
+
+ * tao/Stub.inl:
+ * tao/Stub.cpp:
+ * tao/Synch_Invocation.cpp:
+ * tao/default_client.cpp:
+
+ * utils/logWalker/GIOP_Buffer.h:
+ * utils/logWalker/GIOP_Buffer.cpp:
+
+ * utils/nsgroup/nsgroup.cpp:
+
+ Additional updates to conform with ACE Development Guidelines
+ in preparation for merge.
+
+ Mon Jan 21 21:43:20 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Persistent_Context_Index.h:
+ * orbsvcs/orbsvcs/Naming/Persistent_Context_Index.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.cpp:
+
+ Updated based on ACE Development Guidelines in preparation
+ for merge.
+
+ Fri Jan 18 23:51:32 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_Main.cpp:
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h:
+
+ Updated based on ACE Development Guidelines in preparation
+ for merge.
+
+ Fri Jan 18 22:43:55 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/INS_Locator.cpp:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+ * orbsvcs/ImplRepo_Service/Server_Info.cpp:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/tao_imr_i.cpp:
+ * orbsvcs/orbsvcs/FtRtEvent/Utils/FTEC_Gateway.cpp:
+ * orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp:
+ * orbsvcs/orbsvcs/LoadBalancing/LB_LoadAverage.cpp:
+ * orbsvcs/orbsvcs/LoadBalancing/LB_LoadMinimum.cpp:
+ * tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp:
+
+ Updated based on ACE Development Guidelines in preparation
+ for merge.
+
+ Thu Jan 17 19:36:08 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp:
+
+ Wrapped literal strings in ACE_TEXT.
+
+ * utils/nsgroup/run_test.pl:
+
+ Removed test steps for Redmine Bug #468.
+
+ Thu Jan 17 15:32:12 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+
+ Throw exception if trying to add a member whose first
+ profile is at IIOP version 1.0 since this version does
+ not support tagged components.
+
+ Thu Jan 17 14:36:29 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * bin/tao_orb_tests.lst:
+
+ fix path in Dynamic TP ORB test declaration.
+
+ Tue Jan 15 21:18:30 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp:
+
+ Cleanup unused arguments
+
+ * tests/Storable/Savable.cpp:
+
+ Replaced const integer literal value with ACE_CHAR_MAX macro
+
+ Tue Jan 15 18:18:12 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp:
+
+ Wrapped literal strings in ACE_TEXT.
+
+ Tue Jan 15 01:28:10 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp:
+
+ Added check for invalid nil object reference being passed in to
+ add_member_to_iogr.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp:
+
+ Added check for user passing in a null object reference as a member.
+
+ * utils/nsgroup/run_test.pl:
+
+ Added test steps to expose Redmine Bug #468.
+
+ Mon Jan 14 21:49:20 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/Federation/Hello.cpp:
+ * orbsvcs/tests/FT_Naming/Federation/client.cpp:
+ * orbsvcs/tests/FT_Naming/Federation/server.cpp:
+
+ Added missing ACE_TEXT wrapper macros
+
+ * orbsvcs/tests/FT_Naming/Federation/README:
+
+ Added test documentation
+
+ * orbsvcs/tests/FT_Naming/Federation/NamingTask.h:
+ * orbsvcs/tests/FT_Naming/Federation/NamingTask.cpp:
+
+ Removed these files.
+
+ Mon Jan 14 19:51:29 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * tests/Storable/README:
+ * tests/Storable/Savable.h:
+ * tests/Storable/Savable.cpp:
+ * tests/Storable/run_test.pl:
+ * tests/Storable/test.cpp:
+
+ Clean up of the test.
+
+ * bin/tao_orb_tests.lst:
+
+ Added Storable test to the list.
+
+ * bin/tao_other_tests.lst:
+
+ Removed restriction that FT_Naming tests
+ are not to run for static builds.
+
+ Sun Jan 13 01:53:16 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/README.FT_Naming:
+
+ Renamed file.
+
+ * orbsvcs/Naming_Service/FT_Naming_README:
+
+ Removed this file.
+
+ Fri Jan 11 22:42:28 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp:
+
+ Added debug level filter
+
+ Fri Jan 11 22:05:18 UTC 2013 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Fixing crash from ior file for defunct backup ImR_Locator.
+
+ Fri Jan 11 20:17:59 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/README:
+
+ Updated README to incorporate tao_ft_naming ior option changes made
+ to the equivalence test.
+
+ Fri Jan 11 03:55:40 UTC 2013 Carey Morris <morrisc@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/tao_imr_i.cpp
+
+ Fix ior to strip JACORB: from server name if present.
+
+ Fri Jan 11 19:11:55 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Fixed -h option to work in standalone, primary and backup roles.
+ Fixed -g option to only work in the backup role.
+ Added -h option to usage description.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_equivalence_test.pl:
+
+ Refactored equivalence test to use the single profile ior files
+ instead of corbaloc object references. Added object reference
+ validation checks to verify that the primary and backup references
+ point to different objects.
+
+ * utils/nsgroup/run_test.pl:
+
+ Change the tests tao_ft_naming -g option to -h since -g is now only
+ valid when the tao_ft_naming is running in the backup role.
+
+ Fri Jan 11 17:17:51 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * bin/tao_orb_tests.lst:
+
+ Add ORB_ThreadPool test to suite.
+
+ * tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp:
+ * tao/Dynamic_TP/DTP_Thread_Pool.h:
+ * tao/Dynamic_TP/DTP_Thread_Pool.inl:
+ * tao/Dynamic_TP/DTP_Thread_Pool.cpp:
+
+ Clean up intermediate changes and debug output.
+
+ * tests/Dynamic_TP/ORB_ThreadPool/Client.cpp:
+ * tests/Dynamic_TP/ORB_ThreadPool/Server.cpp:
+ * tests/Dynamic_TP/ORB_ThreadPool/run_test.pl:
+ * tests/Dynamic_TP/ORB_ThreadPool/server.conf:
+
+ Fix the run_test.pl and clean up client/server sources.
+
+ Fri Jan 11 03:55:40 UTC 2013 Phil Mesnier <mesnier_p@office.socket.net>
+
+ * tao/Dynamic_TP/DTP_ORBInitializer.cpp:
+ * tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp:
+ * tao/Dynamic_TP/DTP_Thread_Pool.h:
+ * tao/Dynamic_TP/DTP_Thread_Pool.cpp:
+
+ Fix assorted bugs exposed by new test.
+
+ * tests/Dynamic_TP/ORB_ThreadPool:
+
+ * tests/Dynamic_TP/ORB_ThreadPool/Client.cpp:
+ * tests/Dynamic_TP/ORB_ThreadPool/ORB_ThreadPool.mpc:
+ * tests/Dynamic_TP/ORB_ThreadPool/Server.cpp:
+ * tests/Dynamic_TP/ORB_ThreadPool/Test.idl:
+ * tests/Dynamic_TP/ORB_ThreadPool/Test_i.h:
+ * tests/Dynamic_TP/ORB_ThreadPool/Test_i.cpp:
+ * tests/Dynamic_TP/ORB_ThreadPool/client.conf:
+ * tests/Dynamic_TP/ORB_ThreadPool/run_test.pl:
+ * tests/Dynamic_TP/ORB_ThreadPool/server.conf:
+
+ New test for the dynamic ORB thread pool. The run_test.pl script
+ is not ready yet.
+
+ Thu Jan 10 23:21:36 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp:
+
+ Added missing ACE_TEXT macros and changed char to ACE_TCHAR
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_equivalence_test.pl:
+
+ Added test support for tao_ft_naming single profile ior and
+ multiple profile ior file option arguments.
+
+
+ Thu Jan 10 21:25:44 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_README:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Added option, -h, to output naming manager IOR
+ of service being launched.
+
+ Thu Jan 10 16:34:22 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp:
+
+ Fix so the actual persistent directory is passed to the
+ Storable_FlatFileFactory constructor and that is then
+ used by the factory to construct the full path of the
+ persistent file using the directory name and file name.
+ This simplies the code and allows absolute directory
+ paths to work properly.
+
+ Thu Jan 10 15:24:09 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_README:
+
+ Clarified usage of options.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Updated usage to print info on -n option for tao_ft_naming.
+
+ Thu Jan 10 00:59:01 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp:
+
+ Fixed main so that ORB_init() processes arguments before parsing
+ other arguments.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_equivalence_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_failover_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_persistence_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_test.pl:
+
+ Fixed ORBDebugLevel processing in all of the scripts
+
+ Wed Jan 9 22:54:44 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * DevGuideExamples/Multithreading/DynamicThreadPool/MessengerServer.cpp:
+
+ Update to use the new DTP_* class names.
+
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+ * orbsvcs/Naming_Service/FT_Naming_README:
+ * tao/Dynamic_TP/DTP_POA_Strategy.inl:
+ * tao/Dynamic_TP/DTP_POA_Strategy.cpp:
+
+ Fuzz fixes.
+
+ Wed Jan 9 20:23:33 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerant.mpc:
+
+ Renamed FaultTolerance.mpc to correspond with directory name change.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/README:
+
+ Updated test documentation.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp:
+
+ Added more missing ACE_TEXT macros
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_equivalence_test.pl:
+
+ Minor cleanup
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/run_persistence_test.pl:
+
+ Removed duplicate argument.
+
+ * utils/nsgroup/README.nsgroup:
+
+ Updated by removing references to type_id argument
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerance.mpc:
+
+ Removed this file.
+
+ Wed Jan 9 19:51:27 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/Naming_Service/Naming_Service.mpc:
+
+ Set install variable to $(ACE_ROOT)/bin so
+ that executables will have sym links in
+ $ACE_ROOT/bin like other orbsvcs services.
+
+ Wed Jan 9 19:38:32 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp:
+
+ Fixed memory leak.
+
+ Wed Jan 9 19:09:43 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/Dynamic_TP/DTP_Config.h:
+ * tao/Dynamic_TP/DTP_Config.cpp:
+ * tao/Dynamic_TP/DTP_ORBInitializer.h:
+ * tao/Dynamic_TP/DTP_ORBInitializer.cpp:
+ * tao/Dynamic_TP/DTP_ORB_Loader.h:
+ * tao/Dynamic_TP/DTP_ORB_Loader.cpp:
+ * tao/Dynamic_TP/DTP_POA_Loader.h:
+ * tao/Dynamic_TP/DTP_POA_Loader.cpp:
+ * tao/Dynamic_TP/DTP_POA_Strategy.h:
+ * tao/Dynamic_TP/DTP_POA_Strategy.inl:
+ * tao/Dynamic_TP/DTP_POA_Strategy.cpp:
+ * tao/Dynamic_TP/DTP_Task.h:
+ * tao/Dynamic_TP/DTP_Task.inl:
+ * tao/Dynamic_TP/DTP_Task.cpp:
+ * tao/Dynamic_TP/DTP_Thread_Pool.h:
+
+ Added these files.
+
+ * tests/Dynamic_TP/Config_Loader/Test.cpp:
+ * tests/Dynamic_TP/Config_Loader/svc.conf:
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/run_test.pl:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/server.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc1.conf:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc2.conf:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc3.conf:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc4.conf:
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/server.cpp:
+
+ * tests/Dynamic_TP/POA_Loader/Test.cpp:
+ * tests/Dynamic_TP/POA_Loader/svc.conf:
+
+ Modified these files.
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.h:
+ * tao/Dynamic_TP/Dynamic_TP_Config.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_ORBInitializer.h:
+ * tao/Dynamic_TP/Dynamic_TP_ORBInitializer.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_ORB_Loader.h:
+ * tao/Dynamic_TP/Dynamic_TP_ORB_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.inl:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ Removed these files.
+
+ Unified the naming convension for the Dynamic_TP library. All class names and
+ svc.conf objects are prefixed with DTP_ or TAO_DTP_ as appropriate.
+
+ Wed Jan 9 16:46:56 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp:
+
+ Removed original object group and member creation
+ and validation code as it's been supplanted by
+ testing of groups and members created using server.cpp,
+ LB_server, and Basic code.
+
+ Wed Jan 9 16:15:12 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerant:
+
+ Renamed FaultTolerance directory to
+ FaultTolerant to be consistent with
+ FT naming directories elsewhere.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance:
+
+ Removed.
+
+ * bin/tao_other_tests.lst:
+
+ Update to account for test directory
+ nam change.
+
+ Wed Jan 9 15:40:43 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Fix previous commit that had incorrect variable setting.
+
+ Wed Jan 9 15:29:44 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/Basic.h:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/Basic.cpp:
+
+ Removed unneeded #include. Made comments more
+ descriptive.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Fixed spelling error. Made variable name more
+ descriptive.
+
+ Wed Jan 9 14:17:02 UTC 2013 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Fixed termination of filename string.
+
+ Wed Jan 9 13:17:17 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Pass ObjectGroupUpdate object instead of just object ID
+ to group factory when informing that object group is stale.
+ This is so that if the change type is NEW or DELETED the
+ object group list can be marked as stale.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Pass ObjectGroupUpdate object instead of just object ID
+ to naming manager when informing that object group is stale.
+ Add debug statements to verify update object group and
+ naming context calls have been made.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp:
+
+ In handling a stale object group, if the change type is
+ NEW or DELELETED, mark the list store as stale.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp:
+
+ Track if the persistent file has been created yet and if so
+ propagate the change type as NEW to peer.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Make list_store_ protected so that FT_PG_Group_Factory
+ can access.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+
+ Add stale attribute and use that to help decide if
+ state is obsolete.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Remove 1 second delay between name server calls in
+ object group equivalence test since we're no longer
+ bound by 1 second resolution of file time stamp
+ to determine if staleness.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_equivalence_test.pl:
+
+ Pass the debug_level variable to the naming service so
+ that debug statements can be seen.
+
+ Wed Jan 9 04:13:41 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_README:
+
+ Updated documentation to clarify use of the -o option.
+
+ Wed Jan 9 00:36:30 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp:
+ * tao/Dynamic_TP/DTP_Thread_Pool.h:
+ * tao/Dynamic_TP/DTP_Thread_Pool.inl:
+ * tao/Dynamic_TP/DTP_Thread_Pool.cpp:
+
+ Cleaned up unused indirection code. There are no separately configurable
+ lanes with this thread pool implementation.
+
+ Wed Jan 9 00:23:50 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/Basic.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/server.cpp:
+ * utils/nsgroup/nsgroup.cpp:
+
+ Added missing ACE_TEXT macros
+
+ Tue Jan 8 20:52:42 UTC 2013 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Removed unused parameters.
+
+ Tue Jan 8 20:44:08 UTC 2013 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Cleanup fuzz error.
+
+ Tue Jan 8 20:15:02 UTC 2013 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+
+ Fixed jacorb_server to be read in as a bool.
+
+ Tue Jan 8 19:22:59 UTC 2013 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Re-ordered and removed repeated calling of create_server
+ for new servers.
+
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Ensuring the info->server var is null if no object is
+ created.
+
+ Tue Jan 8 18:45:22 UTC 2013 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Missed writing out info.jacorb_server for XML persistence.
+
+ Tue Jan 8 18:15:28 UTC 2013 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Cleaned up dead code.
+
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Fixed warning.
+
+ * orbsvcs/ImplRepo_Service/README.txt:
+ * orbsvcs/tests/ImplRepo/README:
+
+ Added fault tolerant ImplRepo_Service documentation.
+
+ Tue Jan 8 17:55:22 UTC 2013 Carey Morris <morrisc@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp
+ * orbsvcs/ImplRepo_Service/INS_Locator.cpp
+ * orbsvcs/ImplRepo_Service/Server_Info.h
+ * orbsvcs/ImplRepo_Service/Server_Info.cpp
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.h
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.h
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.h
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp
+
+ Tue Jan 8 07:50:31 UTC 2013 Phil Mesnier <mesnier_p@office.socket.net>
+
+ * tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h:
+ * tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp:
+ * tao/Dynamic_TP/DTP_Thread_Pool.h:
+ * tao/Dynamic_TP/DTP_Thread_Pool.inl:
+ * tao/Dynamic_TP/DTP_Thread_Pool.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_Config.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_ORBInitializer.cpp:
+
+ * tao/ORB_Core.cpp:
+ * tao/params.h:
+ * tao/params.cpp:
+
+ Intermediate commit of ORB dynamic thread pool implementation. This borrows from
+ the RTCORBA ThreadPool policy but with an aim towards simplifying. The config
+ uses the same thread pool definition struct as the POA thread pool. To configure
+ an ORB, pass -ORBDynamicThreadPoolName to ORB_init().
+
+ Mon Jan 7 19:19:05 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Re-ordered pointer members to match reverse order
+ of deletes in destructor. (Should really matter
+ but seeing if it gets rid of or moves a seg fault
+ seen on a test server.)
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+
+ Remove static string as it's not needed.
+
+ Mon Jan 7 15:24:34 UTC 2013 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator.idl:
+
+ Added unique repo id for valid file names.
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+
+ Made Server and Activator hash map keys a typedef.
+
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.h:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+
+ Added reading in repo unique id parameters and refactored
+ creating servers and activators into XML_Backing_Store and
+ Shared_Backing_Store.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Added hash map for server and activator repo unique ids
+ to use to create valid filenames and refactored identifying
+ existing servers from Locator_XMLHandler and added tracking
+ repo unique ids.
+
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Added support to write extra name value pairs to XML and
+ refactored server and activator loading from
+ Locator_XMLHandler.
+
+ Fri Jan 4 23:03:10 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistence_test.pl:
+
+ Fix problem starting the group member object server when the
+ directory has been changed.
+
+ Fri Jan 4 22:19:52 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/Basic.h:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/Basic.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/LB_server.h:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/Test.idl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/server.cpp:
+
+ Added to create object group member server objects for fault tolerance
+ persistence tests.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/FaultTolerance.mpc:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistence_test.pl:
+
+ Modified to incorporate the object group member server for
+ fault tolerance persistence tests.
+
+ Fri Jan 4 19:51:21 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Moved sleep statement in object group equivance test
+ so server 2 can detect persistent change.
+
+ Fri Jan 4 19:14:49 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_FlatFileStream.cpp:
+
+ Handle EOF state correctly when reading an integer.
+
+ Fri Jan 4 18:29:28 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h:
+
+ Removed unneeded include.
+
+ Fri Jan 4 18:21:03 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Reordered the list store and storable factory members
+ so that the list store is deleted first since it has
+ a reference to the storable factory.
+
+ Thu Jan 3 23:02:01 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * MPC/config/ftnaming.mpb:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/FaultTolerance.mpc:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Load_Balancing_Name_Service.mpc:
+ * orbsvcs/tests/FT_Naming/Replication/Replication.mpc:
+
+ Removed extraneous dependencies.
+
+ Thu Jan 3 17:09:27 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Fix lazy loading of group map so get_group_map() will
+ always read from persistent store in the first invocation.
+
+ Wed Jan 2 22:13:53 UTC 2013 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp:
+
+ Construct file guards with redundant flag set.
+
+ Wed Jan 2 21:44:01 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant:
+
+ Removed this empty directory.
+
+ Wed Jan 2 21:09:23 UTC 2013 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/Naming_Service.mpc:
+
+ Removed reference to removed ft_portablegroup.mpb base project.
+
+ * orbsvcs/orbsvcs/FT_Naming_Serv.mpc:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp:
+
+ Moved FT_PG_* files into Naming/FaultTolerant directory. They are
+ tightly coupled with the FT_Naming Service and should not be an
+ independent library in PortableGroup.
+
+ * MPC/config/ft_portablegroup.mpb:
+
+ Removed unnecessary base file.
+
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PG_Group_Factory.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PG_Object_Group_Storable.h:
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PG_Object_Group_Storable.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PortableGroup.mpc:
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/ft_portablegroup_export.h:
+
+ Removed these files.
+ Moved FT_PG_* files into Naming/FaultTolerant directory. They are
+ tightly coupled with the FT_Naming Service and should not be an
+ independent library in PortableGroup.
+
+ Mon Dec 31 20:48:24 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Cleaned up unneeded parameter.
+
+ Mon Dec 31 15:24:48 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.h:
+
+ Added doxygen comments.
+
+ Sat Dec 29 05:27:51 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_Options.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Added doxygen comments and cleaned up virtual functions.
+
+ Sat Dec 29 00:27:11 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp:
+
+ Removed unnecessary include statements and updated doxygen
+ comments.
+
+ Fri Dec 28 21:53:11 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp:
+
+ Removed command line processing support
+ Added doxygen fields
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/README:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_failover_test.pl:
+
+ Updated test documentation
+
+ * utils/nsgroup/nsgroup.cpp:
+
+ Refactored to add command line processing support that was previously
+ provided by nsgroup_svc
+
+ Fri Dec 28 21:40:45 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Cleanup logging and wide character support.
+
+ Fri Dec 28 18:44:07 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+
+ Added fault tolerant ImplRepo test.
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+
+ Cleanup of log statements.
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Fixed return type for repo_mode.
+
+ Fri Dec 28 16:13:55 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+
+ Added back in unintentionally deleted code and cleaned up.
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+
+ Cleaned up logging.
+
+ Fri Dec 28 15:33:23 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/FtNaming.mpc:
+
+ Added nsgroup_svc to project.
+
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/nsgroup_svc.cpp:
+
+ Moved nsgroup_svc.h & cpp FaultTolerant Naming Service
+ directory.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/FaultTolerance.mpc:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+ * utils/nsgroup/nsgroup.mpc:
+ * utils/nsgroup/nsgroup.cpp:
+ * utils/nsgroup/run_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/Faulttolerance.mpc:
+
+ Modified to account for change in placement of the
+ nsgroup_svc class into the FtNaming library.
+
+ Fri Dec 28 14:01:24 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator.idl:
+
+ Made activator update oneway.
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+
+ Changed sync_load to pass no parameters and calling
+ sync_load in get_server and get_activator.
+
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+
+ Changed to force ping call when server is requested.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Changed to store off needed updates and not update the repo
+ until sync_load is called.
+
+ Thu Dec 27 21:49:00 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_Naming_Serv.mpc:
+
+ Fixed to not pickup undesired idl files.
+
+ Thu Dec 27 20:42:31 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_Naming_Serv.mpc:
+
+ Moved mpc file to orbsvcs directory to be standard.
+
+ * orbsvcs/orbsvcs/FtNaming.mpc:
+
+ Moved export file to FT_Naming_Serv.mpc.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Serv.mpc:
+
+ Removed this file.
+
+ Thu Dec 27 20:31:10 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_equivalence_test.pl:
+
+ Updated equivalence objectgroup test
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_failover_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistence_test.pl:
+
+ Made object group directory name consistent with name service directory
+ name
+
+
+ Thu Dec 27 18:01:25 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Fixing include error.
+
+ Thu Dec 27 13:05:53 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/orbsvcs/FtNaming.mpc:
+
+ Added missing file from project (needed for install).
+
+ Wed Dec 26 23:01:04 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_README:
+
+ Created README for the FT_Naming Service separate from the
+ TAO Naming Service.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Location_Index_Map.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h:
+
+ Updated documentation formatted for doxygen.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Made error messages clearer for invalid arguments and combinations of
+ arguments.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Replaced argument name with a more appropriate name. Was previoulsy POA
+ ID, but it is actually the id of the object as registered with the POA.
+
+ Wed Dec 26 21:40:39 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Changed main error return code
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_equivalence_test.pl:
+
+ Fixed error checking of client process
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_failover_test.pl:
+
+ Fixed error message
+
+
+ Wed Dec 26 19:09:59 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+
+ Added FaultTolerance and Federation tests.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Added process and thread printout to error messages. Changed debug level
+ fro printing out debug messages.
+
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PG_Object_Group_Storable.cpp:
+
+ Added catch for exceptions that might be created while creating a new
+ object group.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+
+ Throw mor meaningful exceptions when utilities encounter difficulties.
+
+ * orbsvcs/tests/FT_Naming/Federation/client.cpp:
+ * orbsvcs/tests/FT_Naming/Federation/server.cpp:
+
+ Extended test to bind the root context in another naming service to more
+ fully test a federated naming service.
+
+ Sun Dec 23 20:18:26 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+
+ Added missing include needed for for gettimeofday.
+
+ Fri Dec 21 22:58:59 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Removed extraneous comment. Added protection for leak against
+ thrown exception in creation.
+
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PG_Object_Group_Storable.cpp:
+
+ Removed duplicate code.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Removed unused arg warnings for now.
+
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Added printout of usage on failure of commands.
+
+ Fri Dec 21 22:43:47 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Updated Failover and Equivalance tests
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_failover_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistence_test.pl:
+
+ Additional cleanup of Failover and Persistance script files
+
+ * utils/nsgroup/run_test.pl:
+
+ Added directory exist test before directory cleanup
+
+ Fri Dec 21 20:46:55 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+
+ Fix so that when determining if state is obsolete
+ with respect to the persistent store that the stream
+ is opened before trying to determine time stamp.
+
+ Fri Dec 21 16:46:52 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+
+ Fix getting next group ID so that it always unique,
+ even among IDs for groups that have been deleted.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Created multiple object groups in the object group
+ persistence test.
+
+ Fri Dec 21 16:17:25 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.h:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+
+ Added code to check started to determine if ior should
+ be used to retrieve the server object from the orb. Also
+ changed to use rebind for the activator.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Fixed to truncate handle prior to calling fdopen.
+
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Added writing started to the server xml to indicate if
+ the server object should be created or removed in the
+ replica.
+
+ Fri Dec 21 03:41:20 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl:
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Updated to use -v argument and clean up the object
+ group persistence directory.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/NameService:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/NameService/README:
+
+ Removed these files.
+
+ Fri Dec 21 03:14:14 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+
+ Handle case where there are no group ids.
+
+ * utils/nsgroup/run_test.pl:
+
+ Add argument for object group persistence directory.
+
+ Fri Dec 21 00:01:59 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Refactored client.cpp to provide sub methods for all three fault
+ tolerant test use cases
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_equivalence_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistence_test.pl:
+
+ Refactored scripts to solely utilize the test client for all the
+ tests.
+
+ Thu Dec 20 20:57:26 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PG_Object_Group_Storable.cpp:
+
+ Updated implementation to replace the object reference
+ for the object group when the first member is added.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+
+ Modified order of empty_ and distribute_ to avoid warning.
+
+ * tests/Storable/test.cpp:
+
+ Added missing include file.
+
+ Thu Dec 20 20:46:40 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+
+ Fix computation of next group ID.
+
+ Thu Dec 20 17:29:49 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/CosEvent.mpc:
+
+ Added missing dependency on IFR_Client.
+
+ Thu Dec 20 16:40:36 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+
+ Removed type_id arguments from group_create method calls
+
+ Thu Dec 20 16:31:35 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp:
+
+ Fixed a "new char []" without delete [].
+
+ Thu Dec 20 16:21:56 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PG_Object_Group_Storable.h:
+ * orbsvcs/orbsvcs/PortableGroup/FaultTolerant/FT_PG_Object_Group_Storable.cpp:
+
+ Added add_member_to_iogr member function to support specialization.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h:
+
+ Made members protected to allow use in derived classes.
+ Made member function virtual to support overriding.
+
+ * orbsvcs/tests/Simple_Naming/client.cpp:
+
+ Added missing return for failure case. Added error message to describe
+ failure in another case.
+
+ Thu Dec 20 14:56:42 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+
+ Reset the count of start attempts on every new client attempt. This
+ prevents server lockout from occurring. warnings.
+
+ Wed Dec 19 16:34:54 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/Faulttolerance.mpc:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_equivalence_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_failover_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistence_test.pl:
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Refactored client to use nsgroup_svc for FT_Naming FaultTolerance tests
+
+ Wed Dec 19 14:03:08 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/Replication/client.cpp:
+ Fixed issue with exception.
+
+ * orbsvcs/tests/Redundant_Naming/client.cpp:
+
+ Added missing include file.
+
+ Wed Dec 19 13:36:22 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Refactoring to accommodate derived classes that work
+ with classes derived from PG_Object_Group_Storable,
+ as will be the case for OG FT support.
+
+ Wed Dec 19 05:57:23 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * TAO_IDL/tao_idl.mpc:
+
+ Fixed tao_idl installed build to work with 32 and 64 bit install.
+
+ * bin/tao_other_tests.lst:
+
+ Added persistence and failover tests.
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.h:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+
+ Added code to ensure updating of repo after server info changes.
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+
+ Added class to ensure Server_Info changes were reported to the
+ repository.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Added logic to handle identifying a peer replica file from a
+ defunct corba object.
+
+ Tue Dec 18 22:50:34 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * DevGuideExamples/Multithreading/DynamicThreadPool:
+
+ * DevGuideExamples/Multithreading/DynamicThreadPool/DynamicThreadPool.mpc:
+ * DevGuideExamples/Multithreading/DynamicThreadPool/Messenger.idl:
+ * DevGuideExamples/Multithreading/DynamicThreadPool/MessengerClient.cpp:
+ * DevGuideExamples/Multithreading/DynamicThreadPool/MessengerServer.cpp:
+ * DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.h:
+ * DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.cpp:
+ * DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.h:
+ * DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.cpp:
+
+ Created new dev guide example code to be used later for static
+ thread pool creation using apply_to() in a user application.
+
+ Tue Dec 18 22:47:55 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ Corrected a debug logging level issue for Growing new thread counts.
+
+ Tue Dec 18 16:22:04 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * bin/tao_orb_tests.lst:
+ Added run_test scripts into the nightly build for Dynamic Threadpooling
+
+ Tue Dec 18 16:20:38 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl:
+ Refactored static threadpool configuration run_test script to follow tthe same calling pattern as the dynamic script.
+
+ Tue Dec 18 00:44:12 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_equivalence_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_failover_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistence_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_test.pl:
+
+ Added support for object group repository directory and invoking
+ test client to eventually replace cmdline utility calls.
+ Also corrected script name spelling errors.
+
+ * orbsvcs/tests/FT_Naming/Federation/run_test.pl:
+
+ Added support for object group repository directory
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_equivalance_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistance_test.pl:
+
+ Removed these files.
+
+ Mon Dec 17 23:14:57 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/run_test.pl:
+
+ Reworked the perl test scripts for more flexibility and better detection
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc1.conf:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc3.conf:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc4.conf:
+
+ Adjusted the conf files to better reflect timing and success detection
+
+ Mon Dec 17 23:14:40 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.h:
+ * tao/Dynamic_TP/Dynamic_TP_Config.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ Did considerable work to refactor the rules to evaluate
+ parameters coming in for both apply_to( ) style and conf
+ file style parameter loading.
+
+ Also fixed the serialize servants boolean to be false as a
+ default so that multi-threaded apps are able to perform better
+ by default.
+
+ Mon Dec 17 22:45:37 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp:
+
+ Reworked to return next_member instead of next_location to
+ hide implementation details from Naming Context.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Use .in() operation instead of implicit conversion.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Reset the write_occurred_ flag after notification to remote
+ process.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+
+ Use string_free instead of delete to match creation style.
+
+ Mon Dec 17 15:26:15 UTC 2012 Weiqi Gao <gao_w@ociweb.com>
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Expanded failover_test to cover more usage scenarios.
+
+ Mon Dec 17 14:54:17 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+
+ Fixed warning.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Added file locking for non-windows.
+
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Changed to have load be able to accept an already open
+ file stream.
+
+ Mon Dec 17 14:53:41 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h:
+
+ Added missing TAO namespace end declaration.
+
+ Mon Dec 17 14:42:10 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+ * tao/Storable_Base.inl:
+ * tao/Storable_Factory.h:
+ * tao/Storable_FlatFileStream.cpp:
+ * tests/Storable/Storable.mpc:
+ * tests/Storable/test.cpp:
+
+ Fix fuzz errors.
+
+ Mon Dec 17 12:57:04 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_List_Store.cpp:
+
+ Added class to keep track of the list of persistent object
+ groups. The list itself is persistent.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Updated to use PG_Group_List_Store when adding/destroying
+ object groups or working with the map of object groups.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp:
+
+ Added a few items that weren't originally being persisted.
+ Added constructor suitable for initializing object from
+ persistent store.
+ Refactored usage of TAO_InputCDR so that common code
+ is handled in anonymous function.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+
+ Updates to accommodate enhancements to derived class
+ PG_Object_Group_Storable.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.cpp:
+
+ Allow group ID to also be predetermined instead of
+ only generating ID.
+
+ * tao/Storable_Base.h:
+ * tao/Storable_FlatFileStream.h:
+ * tao/Storable_FlatFileStream.cpp:
+
+ For read member function pass pointer by value, not by
+ reference.
+
+ Sat Dec 15 22:06:02 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.h:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Test.idl:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/client.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/run_test.pl:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/server.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc1.conf:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc2.conf:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc3.conf:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc4.conf:
+ New set of files to test loading of thread configuration from
+ svc.conf files rather from an apply_to() call from an application.
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/client.cpp:
+ Modified this file to help with test logging and pass/fail detection.
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc.conf:
+
+ Removed this file.
+
+ Sat Dec 15 22:05:47 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+
+ These files were modified to accommodate lazy configuration
+ when loading configuration from svc.conf files.
+
+ Sat Dec 15 17:49:30 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl:
+
+ Cleaned up condition where test 3 was failing.
+
+ Sat Dec 15 17:49:17 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.h:
+ * tao/Dynamic_TP/Dynamic_TP_ORB_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+
+ Fixed comparison condition where size_t was being compared to < 0
+ which is not valid.
+ Also set default of max_request_queue_depth to 0 rather than -1.
+
+ Fri Dec 14 22:52:03 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/Faulttolerance.mpc:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/client.cpp:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/test_object.idl:
+
+ Added a client process to provide a more robust test of the name service
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_failover_test.pl:
+
+ Updated to use the client process
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_equivalance_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistance_test.pl:
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Added guard to keep from deleting files when the repository directory
+ was not created.
+
+ Fri Dec 14 22:15:22 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl:
+ Fixed tests to adhere to new functionality
+
+ Fri Dec 14 22:03:35 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ Restructured initialization of Task thread variables.
+ Cleaned out un-needed member variables from Strategy class.
+
+ Fri Dec 14 21:53:37 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Removed case 'n' from parse args. It is handled elsewhere.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+
+ Updated comments to better describe operations.
+
+ * orbsvcs/tests/FT_Naming/Replication/client.cpp:
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Added performance tests. Added a kill of the
+ primary at the end to ensure that the replica
+ is invoked in nslist.
+
+ * orbsvcs/tests/Redundant_Naming/client.cpp:
+
+ Added performance tests.
+
+ * tao/Storable_File_Guard.cpp:
+
+ Moved sync call to only be invoked when rwflags_
+ indicate we are in write mode.
+
+ * tao/Storable_FlatFileStream.h:
+
+ Removed outdated todo comment.
+
+ * tao/Storable_FlatFileStream.cpp:
+
+ Replace int with size_t to avoid warning.
+
+ Fri Dec 14 17:33:50 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * tao/PortableServer/LifespanStrategyTransient.cpp:
+
+ Cleaned up warning.
+
+ * tests/Storable/run_test.pl:
+
+ Removed unneeded code.
+
+ Fri Dec 14 15:19:40 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_FlatFileStream.cpp:
+
+ For some reason, under Linux at least, newlines following
+ strings are not always consumed. So when reading an
+ integer account for first character possibly being a newline.
+
+ Fri Dec 14 00:19:06 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.inl:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ Refactored the task to make better use of services provided by
+ the base class. Also added separate locks to avoid the potential
+ of unnecessary blocking for different roles.
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/server.cpp:
+
+ Added some comments to the test server and fixed up the script to
+ use a client to trigger a shutdown from within the server.
+
+ Thu Dec 13 22:51:06 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Fixed leak of Factory_Registry when initializing the group factory.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+
+ Fixed leak of ReplicationManager when registering the replica.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Made tracing debug statements only execute when debug level is
+ set.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+
+ Fixed leak of TAO_Storable_Base when testing for existence
+ of a directory.
+
+ Thu Dec 13 22:38:33 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_FlatFileStream.cpp:
+
+ Revert for now after discovering Redundant_Naming test is
+ failing.
+
+ Thu Dec 13 20:40:08 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_FlatFileStream.cpp:
+
+ Don't use fscanf when reading integers as it will
+ consume whitespace _after_ the newline. This may cause
+ problems when binary data is included in the file,
+ as is the case for persistent object group data,
+ since binary data may look like whitespace.
+
+ * tests/Storable/Savable.h:
+ * tests/Storable/Savable.cpp:
+ * tests/Storable/test.cpp:
+
+ Updated to write/read binary data after an integer that
+ starts with what looks like whitespace and verify the
+ expected binary data is read.
+
+ Thu Dec 13 19:13:38 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_equivalance_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_failover_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_persistance_test.pl:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_test.pl:
+
+ Split the fault tolerant tests into seperate test scripts
+
+ Thu Dec 13 19:11:42 UTC 2012 Weiqi Gao <gao_w@ociweb.com>
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Turned on strict mode, fixed detected errors.
+
+ Thu Dec 13 15:49:06 UTC 2012 Weiqi Gao <gao_w@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+
+ Fixed tao_imr_locator crash when -o points to existing file
+
+ Wed Dec 12 23:38:39 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/Federation/run_test.pl:
+ * utils/nsgroup/run_test.pl:
+
+ Updated FT_Naming and nsgroup tests to cleanup after themselves
+
+ Tue Dec 11 22:36:37 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/CSD_ThreadPool/CSD_TP_Queue.h:
+ * tao/CSD_ThreadPool/CSD_TP_Queue.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Queue.cpp:
+
+ Cleaned out redundant queue depth tracking. This is handled in the TP
+ strategy class.
+
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ An attempt at lock optimization. Using the lock_ member to guard access
+ to the queue directly so that multiple threads can participate in the
+ wait.
+
+ Tue Dec 11 22:12:52 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * tao/Storable_Base.h:
+ * tao/Storable_File_Guard.cpp:
+ * tao/Storable_FlatFileStream.h:
+ * tao/Storable_FlatFileStream.cpp:
+
+ Added abstraction for sync for use in ensuring written
+ data persistent store. Implemented using fsync in
+ Storable_FlatFileStream.
+
+ Tue Dec 11 22:05:18 UTC 2012 Weiqi Gao <gao_w@ociweb.com>
+
+ * orbsvcs/tests/ImplRepo/airplane_client_i.h:
+ * orbsvcs/tests/ImplRepo/airplane_client_i.cpp:
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Added failover_test and persistent_ft_test.
+ Made airplane_client return an error code when an exception occurs.
+
+ Tue Dec 11 15:58:05 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_Main.cpp:
+
+ Modified to avoid leak of TAO_FT_Naming_Service object.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Modified to write out the single Naming Manager IOR
+ file when running standalone.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Fixed issue with fini. Base class fini called after derived
+ class to allow use of the orb while destroying POAs and
+ cleaning up the IORTable.
+
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Remove the persistence directory at conclusion of the test.
+
+ * utils/nsgroup/run_test.pl:
+
+ Fixed issues with test to run with standalone naming service.
+ Clean up the persistence directory at conclusion of the test.
+
+ Tue Dec 11 15:09:57 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+
+ Fixed "--primary" and "--backup" flags to not consume
+ the following argument.
+
+ Mon Dec 10 20:00:37 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/FtNaming.mpc:
+
+ Fixed issue with dynamicflags.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_intf_export.h:
+
+ Adding new file.
+
+ Mon Dec 10 17:13:47 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp:
+
+ Removed context_size argument from factory constructor since it is not used
+ by the factory.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Loader.cpp:
+
+ Removed include of removed Naming_Context_Factory.h
+
+ * orbsvcs/orbsvcs/cosnaming_serv_persistence.mpb:
+
+ Removed reference to removed Naming_Context_Factory.h/cpp files.
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Factory.cpp:
+
+ Removed these files since they are no longer used.
+
+ Mon Dec 10 16:44:11 UTC 2012 tests\Dynamic_TP <neeleym@ociweb.com>
+
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.h:
+ Added this file to correct build problem in nightly build.
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/TestS.cpp:
+
+ Removed this file.
+
+ Mon Dec 10 15:39:23 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator.idl:
+
+ Added exception for register_replica.
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+
+ Fixed memory leak (double char* duplication).
+
+ * orbsvcs/ImplRepo_Service/Locator_Options.h:
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+
+ Made ImR Locator options similar to the NamingService.
+ Now pass "--directory some_dir" to use multiple files
+ for persistance and either "--primary" or "--backup"
+ for fault tolerant ImR Locator.
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+
+ Made registered_ private with protected accessor.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Added error handling and temporary logging.
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Changes from Locator_Options.
+
+ * tao/PortableServer/Root_POA.cpp:
+
+ Refactored ImR-ification of key into LifespanStrategy
+ and Imr_Client.
+
+ * tao/PortableServer/LifespanStrategy.h:
+
+ Added interface for imr-ifying the key.
+
+ * tao/PortableServer/LifespanStrategyTransient.h:
+ * tao/PortableServer/LifespanStrategyTransient.cpp:
+
+ Added transient null implementation for imr-ifying the key.
+
+ * tao/PortableServer/LifespanStrategyPersistent.h:
+ * tao/PortableServer/LifespanStrategyPersistent.cpp:
+
+ Added persistent implementation for forwarding the call
+ to the ImR_Client if use_imr.
+
+ * tao/PortableServer/ImR_Client_Adapter.h:
+
+ Added interface for imr-ifying the key.
+
+ * tao/ImR_Client/ImR_Client.h:
+ * tao/ImR_Client/ImR_Client.cpp:
+
+ Added implementation for imr-ifying the key for each
+ profile in the IMR ior and then combining the profiles
+ into a single ior.
+
+ * tao/ImR_Client/ImR_Client.mpc:
+ * MPC/config/imr_client.mpb:
+
+ Added dependency on iormanip.
+
+ * tao/Profile.h:
+ * tao/Profile.cpp:
+
+ Made to_string const.
+
+ * orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.h:
+ * orbsvcs/orbsvcs/HTIOP/HTIOP_Profile.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.h:
+ * orbsvcs/orbsvcs/PortableGroup/UIPMC_Profile.cpp:
+ * tao/IIOP_Profile.h:
+ * tao/IIOP_Profile.cpp:
+ * tao/Strategies/COIOP_Profile.h:
+ * tao/Strategies/COIOP_Profile.cpp:
+ * tao/Strategies/DIOP_Profile.h:
+ * tao/Strategies/DIOP_Profile.cpp:
+ * tao/Strategies/SCIOP_Profile.h:
+ * tao/Strategies/SCIOP_Profile.cpp:
+ * tao/Strategies/SHMIOP_Profile.h:
+ * tao/Strategies/SHMIOP_Profile.cpp:
+ * tao/Strategies/UIOP_Profile.h:
+ * tao/Strategies/UIOP_Profile.cpp:
+
+ Same changes for to_string const from Profile.h.
+
+ Mon Dec 10 14:41:47 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/Naming_Service.cpp:
+
+ Added error check on creation of the naming server.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+
+ Use in() operation for var type.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Refactored to avoid duplication of the init_new_naming functionality
+ with the base Naming_Server.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp:
+
+ Removed unnecessary context_size argument from constructor.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Loader.h:
+
+ Removed forward declaration of TAO_Naming_Context_Factory since it is no
+ longer needed.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+
+ Refactored to allow for derived class to define which Naming Context impl
+ factory should be used.
+
+ * orbsvcs/orbsvcs/Naming/Persistent_Context_Index.h:
+ * orbsvcs/orbsvcs/Naming/Persistent_Context_Index.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h:
+
+ Removed TAO_Naming_Context_Factory generic base class since it
+ really does not provide a common abstraction.
+
+ Sun Dec 9 23:02:53 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/Replication/client.cpp:
+
+ Added code to deal with potential race conditions when modifying on
+ primary and checking the replica immediately.
+
+ Sun Dec 9 21:25:24 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * MPC/config/ftnaming.mpb:
+
+ Added orbsvcslib to base projects.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+
+ Added error message when exception occurs in registration.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+
+ Resolved ownership of contextFactory and persistenceFactory.
+ Fixed issue with exit on failed access to persistent store.
+
+ Sat Dec 8 21:37:27 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Addressed memory leaks.
+
+ Sat Dec 8 15:26:02 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/Federation/run_test.pl:
+
+ Changed to use the -c option instead of -o for multi-profile
+ IOR of redundant naming sevices.
+
+ Sat Dec 8 15:12:36 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_Main.cpp:
+
+ Fixed leak of Server object.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Added new option for combined naming service ior file name
+ to allow users to access the ior of the single server and to
+ obtain the combined/multi-profile IOR.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+
+ Removed delete of context impl factory from destructor. Still
+ need to work out ownership of the factory.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_test.pl:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl:
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Updated tests to use -c option for multi-profile ior.
+
+ Fri Dec 7 21:29:30 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/server.cpp:
+
+ Removed reference to deleted include.
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Dynamic_TP_POA_Test_Static.mpc:
+ Repaired generation of IDL to fix build looking for generated files.
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/TestS.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/server.cpp:
+
+ Inclusion of test for max_pool_threads.
+
+ * tests/Dynamic_TP/POA_Loader/Test.cpp:
+
+ Fixed warnings in nightly build.
+
+ Fri Dec 7 21:24:47 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ Continued implementation of max_pool_threads.
+
+ Fri Dec 7 21:04:34 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/Federation:
+ * orbsvcs/tests/FT_Naming/Federation/Federation.mpc:
+ * orbsvcs/tests/FT_Naming/Federation/Hello.h:
+ * orbsvcs/tests/FT_Naming/Federation/Hello.cpp:
+ * orbsvcs/tests/FT_Naming/Federation/NamingTask.h:
+ * orbsvcs/tests/FT_Naming/Federation/NamingTask.cpp:
+ * orbsvcs/tests/FT_Naming/Federation/Test.idl:
+ * orbsvcs/tests/FT_Naming/Federation/client.cpp:
+ * orbsvcs/tests/FT_Naming/Federation/run_test.pl:
+ * orbsvcs/tests/FT_Naming/Federation/server.cpp:
+
+ Added Fault Tolerant Name Service Federation test
+
+ Fri Dec 7 16:20:37 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Was passing the wrong time to the context to determine
+ if it was obsolete. Use the file time instead.
+
+ Fri Dec 7 12:44:53 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_Base.h:
+ * tao/Storable_FlatFileStream.h:
+ * tao/Storable_FlatFileStream.cpp:
+
+ Add operator << for TAO_OutputCDR and write
+ member function to use with TAO_InputCDRs.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp:
+
+ Fleshed out read/write of object group state to file.
+
+ Fri Dec 7 02:56:49 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+
+ Delete the Context Impl Factor to avoid leak.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.h:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Test.idl:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp:
+
+ Naming Manager interface is now in the FT_Naming module.
+
+ * orbsvcs/tests/FT_Naming/Replication/client.cpp:
+
+ Refined test for specific exceptions in case other CORBA
+ Exceptions are thrown which should not indicate success.
+
+ Thu Dec 6 22:49:38 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_NamingManager.idl:
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_NamingReplication.idl:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Moved Fault Tolerant Naming interfaces into the FT_Naming module
+ instead of FT since they are not standard CORBA interfaces.
+
+ Thu Dec 6 22:20:22 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tests/Storable/Savable.h:
+ * tests/Storable/Savable.cpp:
+ * tests/Storable/test.cpp:
+
+ Made test more robust in error handling. Corrected
+ file access modes in operations that modify state.
+
+ Thu Dec 6 21:19:48 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/run_test.pl:
+
+ Updated test to use tao_ft_naming standalone arguments
+
+ Thu Dec 6 14:44:27 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/CSD_ThreadPool/CSD_TP_Queue.h:
+ * tao/CSD_ThreadPool/CSD_TP_Queue.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Queue.cpp:
+
+ Implemented capture of queue depth as items are being added/removed.
+
+ Thu Dec 6 14:36:33 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static:
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Dynamic_TP_POA_Test_Static.mpc:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Test.idl:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/client.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/server.cpp:
+
+ Creation of tests for:
+ - min_pool_threads
+ - init_pool_threads
+ - thread_idle_time (timeout)
+ - max_request_queue_depth
+
+ Thu Dec 6 14:36:21 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.inl:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ Implementation of max_request_queue_depth.
+ Fuzz clean up.
+
+ Thu Dec 6 20:13:55 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_NamingReplication.idl:
+
+ Made notification calls oneway.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Added support for running in standalone mode to write out IORs.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Refactored to use is_obsolete. Allows Storable_Naming_Context to use
+ file time, while FT_Storable_Naming_Context uses the stale flag.
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_test.pl:
+
+ Updated test to use -o and -g to access the combined IORs more
+ consistently.
+
+ * tao/Storable_File_Guard.h:
+
+ Made accessor for get_object_last_changed to be public to allow
+ users of the abstraction to determine when the underlying store
+ changed.
+
+ Thu Dec 6 17:19:19 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_test.pl:
+ * utils/nsgroup/run_test.pl:
+
+ Restructured tests and corrected copy and paste errors
+
+ Thu Dec 6 13:40:38 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_Options.h:
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+
+ Added back "-y" option, which will allow Locator to use the
+ multi-file backing store, but without having replication.
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+
+ Moved poa activation to init.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Only reporting the ior when the fault tolerant imr is available,
+ and added handling for standalone IMR.
+
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Cleanup of warnings.
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Changes from locator options and making tests work.
+
+ Thu Dec 6 03:57:39 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+
+ Upated locking of fault tolerant naming service.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Minor formatting changes.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl:
+
+ FIxed test to use latest FT Naming Service arguments.
+
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Updated tests to use more descriptive variables.
+
+ Wed Dec 5 23:01:07 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Updates to combine object references and write out combined object
+ reference to a file.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+
+ Revised error message for writing ior to file.
+
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Modified test script to use new arguments for iors.
+
+ Wed Dec 5 18:00:43 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator.idl:
+
+ Changed to pass back the fault tolerant imr when registering
+ replicas.
+
+ * orbsvcs/ImplRepo_Service/Locator_Options.h:
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+
+ Changed "-y" option to "-primary" and "-backup" and removed
+ "-i".
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Changed to expect the other replica to write an ior file to the
+ shared directory for discovering the other replica.
+
+ * orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp:
+ * tao/ImR_Client/ImR_Client.cpp:
+
+ Adding logging.
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Adding to fault tolerance tests.
+
+ * orbsvcs/tests/Notify/Bug_1884_Regression/common.h:
+ * orbsvcs/tests/Notify/Bug_1884_Regression/filter.cpp:
+ * orbsvcs/tests/Notify/Bug_3688_Regression/common.h:
+ * orbsvcs/tests/Notify/Persistent_Filter/Filter.cpp:
+ * orbsvcs/tests/ImplRepo/RestartServer/MessengerClient.cpp:
+ * orbsvcs/tests/ImplRepo/RestartServer/Terminator.cpp:
+
+ Cleaning up compiler errors for vcexpress.
+
+ Wed Dec 5 16:29:17 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/run_test.pl:
+
+ Simplified targets and additional cleanup
+
+ Wed Dec 5 01:42:34 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_NamingReplication.idl:
+
+ Modified registration to pass references for replicated services
+ in support of creation of mulit-profile IOR.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+
+ Updated to support coordination of replication IORs transparently
+ and to create a multi-profile IOR.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Factored out writing IOR files.
+
+ * orbsvcs/tests/FT_Naming/Replication/client.cpp:
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+ * orbsvcs/tests/Redundant_Naming/run_test.pl:
+
+ Removed some extraneous prints. Revised perl to manage IOR
+ files better.
+
+ Tue Dec 4 23:04:01 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_test.pl:
+ * utils/nsgroup/run_test.pl:
+
+ Updated tests with tao_ft_naming command line arguments --primary
+ and --backup
+
+ Tue Dec 4 19:49:56 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Changed IOR name from ObjectGroupManager to NamingManager
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance/README:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_test.pl:
+
+ Updated to conform to use case test document
+
+ Tue Dec 4 19:19:34 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_File_Guard.cpp:
+
+ Don't try to load data from file that has just been
+ created.
+
+ * tests/Storable/Savable.cpp:
+
+ Changed to use term 'object' instead of 'child'.
+
+ Tue Dec 4 14:40:34 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp:
+
+ Fixed compile error.
+
+ Tue Dec 4 01:20:34 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_Main.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Reworked startup with primary and backup arguments.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Interface.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Interface.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Changed to use 'stale' terminology instead of 'dirty'
+
+ * orbsvcs/tests/FT_Naming/Replication/client.cpp:
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Changed arguments to use primary and backup
+
+ * orbsvcs/tests/Redundant_Naming/client.cpp:
+
+ Modified to use compound name for bind for more
+ robust test.
+
+ Mon Dec 3 19:13:51 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.h:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+
+ Refactored update interface implementation into Shared_Backing_Store.
+ Moved reporting of service ior into the repository.
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Changes from Locator_Repository refactoring.
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator.idl:
+
+ Added to the update interface and removed the replica locator
+ interface.
+
+ * orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc:
+
+ Added dependency on iormanip.mpb.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Added code to determine the fault tolerant ImR ior.
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Added tests for fault tolerance.
+
+ Mon Dec 3 16:46:58 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+ * tao/Storable_File_Guard.h:
+ * tao/Storable_File_Guard.cpp:
+ * tests/Storable/Savable.cpp:
+
+ With simplified Storable_Base class hierarchy now in
+ place, move derived file guards peer() to base class since
+ dynamic casting is no longer needed.
+
+ Mon Dec 3 16:15:40 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+
+ Fix invalid forward declaration.
+
+ Mon Dec 3 15:21:14 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_File_Guard.h:
+ * tao/Storable_File_Guard.cpp:
+
+ Renamed new obsolete/current member functions to account
+ for change in terms from previous commit.
+
+ Mon Dec 3 14:44:43 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_Base.h:
+ * tao/Storable_File_Guard.h:
+ * tao/Storable_File_Guard.cpp:
+ * tao/Storable_FlatFileStream.h:
+ * tao/Storable_FlatFileStream.cpp:
+
+ Extended to accommodate storable naming context to use
+ without needing its own specialized flat file stream. This
+ will avoid code duplication between storable object groups
+ and storable naming contexts.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_ReaderWriter.cpp:
+
+ Moved functionality from naming context flat file persistent
+ to new class that uses Storable_FlatFileStream.
+
+ * orbsvcs/orbsvcs/cosnaming_serv_persistence.mpb:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable.h:
+ * orbsvcs/orbsvcs/Naming/Storable.inl:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp:
+
+ Updated to use new reader-writer class and non-naming service
+ specific Storable_* classes.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp:
+
+ Further changes for persistent support of object groups.
+
+ * tests/Storable/Savable.h:
+ * tests/Storable/Savable.cpp:
+ * tests/Storable/test.cpp:
+
+ Account for renaming of some Storable_File_Guard member
+ functions.
+
+ * orbsvcs/orbsvcs/Naming/Flat_File_Persistence.h:
+ * orbsvcs/orbsvcs/Naming/Flat_File_Persistence.cpp:
+
+ Removed these files.
+
+ Mon Dec 3 04:13:48 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Interface.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Interface.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+ * tao/Storable_File_Guard.h:
+ * tao/Storable_File_Guard.cpp:
+
+ Refactored to allow for use of marking for out of date context
+ and file.
+
+ * orbsvcs/tests/FT_Naming/Replication/client.cpp:
+
+ Added printouts for testing.
+
+
+ Sun Dec 2 20:32:25 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tests/Storable/test.cpp:
+
+ Explicitly include header file that defines ACE_OS::sleep()
+ used in the source.
+
+ Sat Dec 1 13:28:00 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tests/Dynamic_TP/POA_Loader/Test.cpp:
+ Fixed error found in nightly build.
+ Removed reference to removed method.
+
+ Sat Dec 1 13:07:48 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.cpp:
+
+ Removed these files.
+
+ Fri Nov 30 23:20:59 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.h:
+ - changed constructor of TAO_DTP_Definition
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+ - Removed the TAO_Dynamic_TP_POA_StrategyImpl class dependency
+
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+ - Extensive implementation of init_pool_threads, min_pool_threads, max_pool_threads
+ thread_stack_size, and thread timeout.
+
+
+
+ Fri Nov 30 23:09:18 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Moved attribute to Storable_Naming_Context class
+ from the File class.
+
+ Fri Nov 30 23:05:32 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/FaultTolerance:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/README:
+ * orbsvcs/tests/FT_Naming/FaultTolerance/run_test.pl:
+
+ Added FT_Naming Fault Tolerance Test
+
+ Fri Nov 30 22:55:31 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+
+ Added Fault Tolerance Test.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Added functionality to respond to callback when file
+ is written.
+
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Print command line output as an aid for testing.
+
+ Fri Nov 30 17:50:08 UTC 2012 Weiqi Gao <gao_w@ociweb.com>
+
+ * tao/AnyTypeCode/Struct_TypeCode.h:
+ * tao/AnyTypeCode/Struct_TypeCode.cpp:
+ * tao/AnyTypeCode/TypeCode_CDR_Extraction.h:
+ * tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp:
+ * tao/AnyTypeCode/Union_TypeCode.h:
+ * tao/AnyTypeCode/Union_TypeCode.cpp:
+ * tao/AnyTypeCode/Value_TypeCode.h:
+ * tao/AnyTypeCode/Value_TypeCode.cpp:
+
+ Added support to demarshal indirection of repeated struct,
+ union, valuetype typecodes.
+
+ Fri Nov 30 17:26:09 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+
+ Updates to support replication notifications.
+
+ * tao/Storable_FlatFileStream.h:
+ * tao/Storable_FlatFileStream.cpp:
+
+ Added missing includes.
+
+ Fri Nov 30 17:23:23 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * utils/logWalker/HostProcess.h:
+ * utils/logWalker/HostProcess.cpp:
+ * utils/logWalker/Log.h:
+ * utils/logWalker/Log.cpp:
+ * utils/logWalker/PeerProcess.h:
+ * utils/logWalker/PeerProcess.cpp:
+ * utils/logWalker/Session.h:
+ * utils/logWalker/Session.cpp:
+ * utils/logWalker/Thread.cpp:
+
+ Synchronize with improvements added to TAO 2.0a.
+
+ Fri Nov 30 15:47:46 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/CosNaming_Serv.mpc:
+
+ Removed source file.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Added object group persistence option.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Use Storable_File_Guard instead of Naming_Service_File_Guard.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Storable.cpp:
+
+ Start of storable object group capability (no writing/reading
+ done yet).
+
+ * tao/Storable_Factory.h:
+ * tao/Storable_Factory.cpp:
+ * tao/Storable_File_Guard.h:
+ * tao/Storable_File_Guard.cpp:
+ * tao/Storable_FlatFileStream.h:
+ * tao/Storable_FlatFileStream.cpp:
+ * tao/tao.mpc:
+
+ Updates to accommodate object group persistence.
+
+ * tests/Storable:
+ * tests/Storable/Savable.h:
+ * tests/Storable/Savable.cpp:
+ * tests/Storable/Storable.mpc:
+ * tests/Storable/run_test.pl:
+ * tests/Storable/test.cpp:
+
+ Beginning of test for Storable code.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Service_File_Guard.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Service_File_Guard.cpp:
+
+ Removed these files.
+
+ Thu Nov 29 22:22:42 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_NamingReplication.idl:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+
+ Implementation of replication mechanisms.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Interface.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Interface.cpp:
+
+ Added operation to mark context dirty from replication manager.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+
+ Removed unnecessary stub creation.
+
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Added prints for tests to aid in debugging.
+
+ Thu Nov 29 20:03:54 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Fix GNU C++ compile error.
+
+ Wed Nov 28 23:17:07 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_NamingReplication.idl:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+
+ Updated interface to pass more information for context replication.
+
+ Wed Nov 28 17:37:37 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Added support for -r option.
+
+ Wed Nov 28 02:34:36 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Fixed initialization order in constructor.
+
+ Wed Nov 28 02:14:42 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/README:
+
+ Fixed typo.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp:
+
+ Refactored to minimize duplication in creation of Storable
+ Naming Context.
+
+ Tue Nov 27 21:26:34 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Fixed error of using private hash map copy constructor.
+
+ Tue Nov 27 19:14:37 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Implemented Replication Manager registration functionality.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+
+ Implemented notification of changed contexts.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl:
+
+ * orbsvcs/tests/FT_Naming/Replication/client.cpp:
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+
+ Updated tests to use replication arguments.
+
+ Tue Nov 27 16:27:39 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+
+ Added interface for forwarding UpdatePushNotification calls.
+ Added add bool param to persistent_update calls and cleaned
+ up.
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Changes from persistent_update interface changes.
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator.idl:
+
+ Added UpdatePushNotification interface.
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.h:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+
+ Added UpdatePushNotification implemenation, forwarding
+ to the repository_, replication handling, and cleanup.
+
+ * orbsvcs/ImplRepo_Service/Locator_Options.h:
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+
+ Added replica object key option.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Added implementatioln for forwarded UpdatePushNotification calls.
+ Added notifying of updates and identifying what needs to be
+ updated.
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Added replication testing.
+
+ Mon Nov 26 22:39:55 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Fixed compilation errors in print statements.
+
+ Mon Nov 26 22:19:23 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/Naming_Service.cpp:
+
+ Fixed initialization order in constructor.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Added initialization code for ReplicationManager interface.
+
+ * orbsvcs/tests/FT_Naming/Replication:
+ * orbsvcs/tests/FT_Naming/Replication/README:
+ * orbsvcs/tests/FT_Naming/Replication/Replication.mpc:
+ * orbsvcs/tests/FT_Naming/Replication/client.cpp:
+ * orbsvcs/tests/FT_Naming/Replication/run_test.pl:
+ * orbsvcs/tests/FT_Naming/Replication/test_object.idl:
+
+ Added tests for replication functionality in FT_Naming_Service.
+
+ Mon Nov 26 20:50:18 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/CosNaming_Serv.mpc:
+ * orbsvcs/orbsvcs/Naming/Naming_Service_File_Guard.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Service_File_Guard.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Prematurely deleted Naming_Service_File_Guard in
+ previous commit. Resurrecting.
+
+ Mon Nov 26 18:16:39 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Storable_Base.h:
+ * tao/Storable_Base.inl:
+ * tao/Storable_Base.cpp:
+ * tao/Storable_File_Guard.h:
+ * tao/Storable_File_Guard.cpp:
+ * tao/tao.mpc:
+
+ Extracted storable base and file guard classes
+ from naming server so they can be used in
+ other contexts such as object group persistence.
+
+ * orbsvcs/orbsvcs/CosNaming_Serv.mpc:
+ * orbsvcs/orbsvcs/Naming/Storable.h:
+ * orbsvcs/orbsvcs/Naming/Storable.inl:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Updatd to use base classes given above.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Service_File_Guard.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Service_File_Guard.cpp:
+
+ Removed these files.
+
+ Mon Nov 26 17:14:21 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * orbsvcs/orbsvcs/FtNaming.mpc:
+
+ Fix the project dependencies.
+
+ Sun Nov 25 15:27:16 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/Naming_Service.cpp:
+
+ Fixed initialization order of data members.
+
+ * orbsvcs/orbsvcs/Naming/Storable.h:
+
+ Added dll export for class.
+
+ Sat Nov 24 21:48:11 UTC 2012 unknown <unknown@>
+
+ * MPC/config/ft_naming_serv.mpb:
+
+ Add additional component.
+
+ * orbsvcs/Naming_Service/Naming_Service.cpp:
+
+ Fixed initialization order of data members.
+
+ Fri Nov 23 23:47:50 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/README.nsgroup:
+
+ Updated documentation for group_bind and group_unbind options
+
+ * utils/nsgroup/run_test.pl:
+
+ Tied output redirection to debug command line option
+
+ Fri Nov 23 14:57:58 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/tests/Simple_Naming/client.cpp:
+ * orbsvcs/tests/Simple_Naming/run_test_ft.pl:
+
+ Fixed test to clean out state on each run. Cleaned up fuzz errors.
+
+ Fri Nov 23 14:06:26 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+ * orbsvcs/tests/Simple_Naming/run_test_ft.pl:
+
+ Added simple naming tests for FT_Naming.
+
+ * orbsvcs/orbsvcs/FtNaming.mpc:
+
+ Removed unnecessary elements.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Removed printout to clean up error messages.
+
+ Wed Nov 21 23:07:07 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/CSD_ThreadPool/CSD_TP_Task.h:
+ * tao/CSD_ThreadPool/CSD_TP_Task.cpp:
+
+ Rename the argument to open to reinforce the generic nature
+ of the single void * argument.
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+
+ Minor scoreboard cleanup.
+
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+
+ Refactored the task open() signature to take a single void *
+ argument. This is important to avoid generating a new
+ signature. Since the argument is a void*, a struct is used to
+ pass multiple discrete values. This should probably just use the
+ TP_Definition struct, rather than define something new.
+
+ * tests/Dynamic_TP/Config_Loader/Test.cpp:
+ * tests/Dynamic_TP/POA_Loader/Test.cpp:
+
+ Minor scoreboard cleanup.
+
+ Wed Nov 21 23:20:54 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/nsgroup.cpp:
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Updated header paths
+
+ * utils/nsgroup/run_test.pl:
+
+ Added support for showing output files upon error detection.
+
+ Wed Nov 21 22:24:28 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/tests/Simple_Naming/run_test_ffp.pl:
+
+ Added tests for tao_ft_naming to the test suite.
+
+ Wed Nov 21 20:46:58 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+
+ Added documentation to describe why release is required.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Service_File_Guard.h:
+
+ Added TAO_Naming_Serv_Export to support dll.
+
+ Wed Nov 21 20:10:01 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/CosNaming_Serv.mpc:
+ * orbsvcs/orbsvcs/Naming/Naming_Service_File_Guard.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Service_File_Guard.cpp:
+
+ Added new class that's a more general version of
+ original File_Open_Lock_and_Check class so that
+ it can be used for other persistent data besides
+ contexts.
+
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp:
+
+ Changed File_Open_Lock_and_Check to derive from
+ Naming_Service_File_Guard and override pure virtual
+ functions as needed.
+
+ * orbsvcs/orbsvcs/Naming/Flat_File_Persistence.h:
+ * orbsvcs/orbsvcs/Naming/Flat_File_Persistence.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable.h:
+
+ Added stream operator on strings in anticipation
+ of using these operators on some of the object
+ group elements. Udating existing stream operators
+ to use string operators.
+
+ Wed Nov 21 20:03:03 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/run_test.pl:
+
+ Redirected output to files and more cleanup
+
+ Wed Nov 21 18:19:17 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+
+ Fixed bug in release of Activator.
+
+ Wed Nov 21 16:35:28 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.h:
+
+ * orbsvcs/Naming_Service/FT_Naming_Service.h:
+ * orbsvcs/Naming_Service/FT_Naming_Service.cpp:
+ * orbsvcs/Naming_Service/Naming_Service.h:
+ * orbsvcs/Naming_Service/Naming_Service.cpp:
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Context_Index.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp:
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp:
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp:
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/NameService/README:
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/server.cpp:
+
+ * orbsvcs/tests/ImplRepo/RestartServer/README:
+ * orbsvcs/tests/ImplRepo/RestartServer/Terminator.cpp:
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/server.cpp:
+
+ * tests/Dynamic_TP/POA_Loader/Test.cpp:
+
+ * tests/Var_Deref/README.txt:
+
+ More unfuzzing.
+
+ Wed Nov 21 13:35:40 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Fixed compilation errors.
+
+ Wed Nov 21 06:16:58 UTC 2012 Phil Mesnier <mesnier_p@local>
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.inl:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ Fuzz fixes.
+
+ Wed Nov 21 04:42:24 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_NamingReplication.idl:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp:
+
+ Fixed to resolve fuzz issues.
+
+ * utils/nsgroup/run_test.pl:
+
+ Modified argument to tao_nslist, tao_nsadd passing in the IOR for
+ the naming service.
+
+ Wed Nov 21 02:40:16 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Storable.h:
+
+ Added TAO_Naming_Serv_Export to TAO_Naming_Service_Persistence_Factory.
+
+ Wed Nov 21 02:30:08 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp:
+
+ Added files to implement the replication interface.
+
+ Wed Nov 21 01:32:17 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.h:
+
+ created constructor in TAO_DTP_Definition struct
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.cpp:
+
+ removed conflicting constructor
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+
+ removed unnecessary include
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.inl:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ completed StrategyImpl initialization started the delegation
+ functions; this needs a lot of dependency removal from CSD_Task.
+
+ Tue Nov 20 23:42:31 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/CSD_Framework/CSD_ORBInitializer.h:
+
+ added class visibility token.
+
+ * tao/Dynamic_TP/Dynamic_TP_ORBInitializer.h:
+ * tao/Dynamic_TP/Dynamic_TP_ORBInitializer.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_ORB_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+
+ Fuzz and other clean up.
+
+ Tue Nov 20 22:44:07 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/run_test.pl:
+
+ Corrected type_id string passed in test
+
+ Tue Nov 20 22:42:06 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * ChangeLog:
+
+ * MPC/config/ft_naming_serv.mpb:
+ * orbsvcs/Naming_Service/Naming_Service.mpc:
+ * orbsvcs/orbsvcs/FtNaming.mpc:
+
+ Support building FT Naming Service with replication.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_NamingReplication.idl:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Serv.mpc:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+
+ Functionality to support Replication interface between naming
+ service instances.
+
+ Tue Nov 20 19:32:12 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/nsgroup.mpc:
+
+ Added $ID
+
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Changed group_bind and group_unbind to use the NamingContextExt
+ interface to properly convert stringified names to compound names.
+
+ * utils/nsgroup/run_test.pl:
+
+ Add calls to tao_nslist, tao_nsadd and tao_nsdel to augment name
+ service verification.
+
+ Tue Nov 20 15:05:32 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Hash_Naming_Context.cpp:
+
+ While refactoring the lock utilization, I inadvertently removed
+ a critical section from the resolve() implementation. That's been
+ restored.
+
+ Mon Nov 19 22:33:49 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/CSD_Framework/CSD_Framework_Loader.cpp:
+
+ The loader was incorrectly introducing a dependency on the
+ TAO_CSD_ThreadPool library. This is wrong because the latter
+ is but one possible implementation for the framework.
+
+ * tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp:
+ * tao/CSD_ThreadPool/CSD_ThreadPool.h:
+ * tao/CSD_ThreadPool/CSD_ThreadPool.cpp:
+
+ Have the CSD_Threadpool properly initialize the framework,
+ rather than vice versa. Also, cleaned up the parameter parsing to
+ be a little more efficient.
+
+ * tao/Dynamic_TP/Dynamic_TP.mpc:
+ * tao/Dynamic_TP/Dynamic_TP_ORBInitializer.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_ORB_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+
+ Sorted out the initialization of POAs with threadpools declared
+ via service configuration. The key was to actually initialize the
+ CSD_Strategy_Repository prior to inserting any strategy instances.
+
+ Also removed a dependency on RTCORBA. This dependency was causing
+ the RT POA factory name to be loaded after the CSD POA factory name
+ which in turn disabled the creation of CSD POAs.
+
+ * tests/Dynamic_TP/POA_Loader/Test.cpp:
+
+ The test seemed to have a typo.
+
+ Mon Nov 19 22:27:44 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * orbsvcs/Naming_Service/README:
+
+ Add documentation of the -n command line argument used for thread
+ pooling. Also, sort out the parmaters description so they are ordered
+ alphabetically.
+
+ * orbsvcs/orbsvcs/Naming/Hash_Naming_Context.cpp:
+
+ Refactored the thread acquisition so that the context is locked
+ only when the local store is going to be modified, not if another
+ repository is to be upated.
+
+ Mon Nov 19 18:00:27 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/CosNaming_Serv.mpc:
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Activator.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/cosnaming_serv_persistence.mpb:
+
+ Added support for Abstract factory to create Storable Naming Contexts.
+ This enables the overriding of the resolve operation in support of
+ load balancing.
+
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/server.cpp:
+
+ Updated test internals to return 0 on success.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/README:
+ Updated README to more correctly describe the test being performed.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/NameService:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/NameService/README:
+ Created directory to store the NameService state when using the
+ -u option.
+
+ Mon Nov 19 16:46:05 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+
+ Added ImR persistance tests for hash and shared backing stores.
+
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+
+ Refactored xml, heap, and registry backing store code into a virtual
+ interface.
+
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp:
+
+ Refactored out Locator_Repository REPO_HEAP and REPO_REGISTRY code.
+
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp:
+
+ Refactored out Locator_Repository REPO_XML_FILE code.
+
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.h:
+ * orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp:
+
+ Added handling for a shared xml files backing store.
+ (this will eventually have file locking)
+
+ * orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc:
+
+ Added new xxx_Backin_Store.cpp files.
+
+ * orbsvcs/ImplRepo_Service/Locator_Options.h:
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+
+ Added "-y" flag to select shared xml files backing store.
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.h:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.h:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+
+ Refactored Locator_Repository Server_Repo_XML_Callback into Locator_XMLHandler.
+
+ * orbsvcs/ImplRepo_Service/Server_Info.h:
+ * orbsvcs/ImplRepo_Service/Server_Info.cpp:
+
+ Made const correct.
+
+ * orbsvcs/tests/ImplRepo/airplane_server_i.h:
+ * orbsvcs/tests/ImplRepo/airplane_server_i.cpp:
+
+ Added flag to provide the name the server should be registered under.
+
+ * orbsvcs/tests/ImplRepo/run_test.pl:
+
+ Added testing for heap and shared backing store persistence tests and added testing with multiple servers.
+
+ * tao/PortableServer/ServantRetentionStrategyNonRetain.cpp:
+ * orbsvcs/orbsvcs/FtRtEvent/Utils/FTEC_Gateway.cpp:
+ * orbsvcs/orbsvcs/LoadBalancing/LB_LeastLoaded.cpp:
+ * orbsvcs/orbsvcs/LoadBalancing/LB_LoadAverage.cpp:
+ * orbsvcs/orbsvcs/LoadBalancing/LB_LoadMinimum.cpp:
+
+ Fixed vc9 (express?) compiler errors.
+
+ Mon Nov 19 13:54:58 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp:
+
+ Add support for -u option to support fault tolerance using separate
+ files per context.
+
+ Sun Nov 18 16:03:28 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+
+ Add support for -u option to support fault tolerance using separate
+ files per context. Simplified interface for object group creation.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp:
+
+ Removed unnecessary data member.
+
+ * orbsvcs/orbsvcs/Naming/Flat_File_Persistence.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Storable.h:
+ * orbsvcs/orbsvcs/Naming/Storable_Naming_Context.h:
+
+ Suppport use from FT_Naming service.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+
+ Simplify searching for object groups by name.
+
+
+ Fri Nov 16 23:42:51 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/README.nsgroup:
+
+ Documents the nsgroup command line options
+
+ * utils/nsgroup/nsgroup.cpp:
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+ * utils/nsgroup/run_test.pl:
+
+ Changed some option names to avoid potential conflict.
+ Added group_unbind to complement the group_bind command option.
+
+ Fri Nov 16 17:19:32 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Invocation_Retry_Params.h:
+ * tao/Invocation_Retry_Params.cpp:
+ * tao/Invocation_Retry_State.h:
+ * tao/Invocation_Retry_State.cpp:
+ * tao/ORB_Core.cpp:
+ * tao/Synch_Invocation.cpp:
+ * tao/default_client.cpp:
+ * tao/params.h:
+
+ Fixed an incorrect assumption I had about not
+ forwarding profiles when connection closed during
+ reading of server reply.
+
+ * orbsvcs/tests/ImplRepo/RestartServer/README:
+ * orbsvcs/tests/ImplRepo/RestartServer/run_test.pl:
+
+ Updated test to reflect changed name of option
+ based on fix above.
+
+ * docs/Options.html:
+
+ Describes the invocation retry command-line and
+ Client_Strategy_Factory service options.
+
+ Fri Nov 16 16:28:08 UTC 2012 "Marc Neeley" <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_ORB_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_StrategyImpl.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_Task.h:
+ * tao/Dynamic_TP/Dynamic_TP_Task.inl:
+ * tao/Dynamic_TP/Dynamic_TP_Task.cpp:
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic:
+
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Dynamic_TP_POA_Test_Dynamic.mpc:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.h:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Test.idl:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/client.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/server.cpp:
+ * tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc.conf:
+
+ Inclusion of Dynamic Threadpool strategy to leverage CSD Framework. Associated tests included.
+ WARNING: this is an interim check-in and the tests are not working.
+
+ Fri Nov 16 02:48:45 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Fixed a spelling error in group_create error message.
+ Extended group_list description labels.
+
+ Thu Nov 15 20:58:23 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/Stub.inl:
+ * tao/Stub.cpp:
+
+ There is a potential for a deadlock when a stub contains profiles
+ that are forwarded and also self-referencial. The use case which
+ exposed this involves the name service and the ImR. In this case,
+ the root context of a name service is registered with the ImR. This
+ is then added to a name service as a new context with a name and the
+ reference pointing to the ImR-ified context. When this new context
+ happens to be the local root context, a deadlock occurs.
+
+ The deadlock ie related to the Stub's profile_lock_, which is a simple
+ thread mutex. This patch addresses the deadlock by momentarily releasing
+ the lock before leaving the Stub code, then reaquiring upon return. This
+ works for my specific use case, but I have added temporary debugging in
+ case issues arise in nightly tests. I intend to remove the debugging
+ prior to formal integration with the main trunk.
+
+ Thu Nov 15 23:15:33 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Fixed bug in groups operation.
+
+ Thu Nov 15 22:30:52 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+
+ Added orbsvcs/tests/FT_Naming/Load_Balancing test
+ Added utils/nsgroup test
+
+ Thu Nov 15 21:37:29 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_NamingManager.idl:
+
+ Changed LoadBalancingStrategyValue ACTIVE to LEAST
+
+ * utils/nsgroup/README.nsgroup:
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+ * utils/nsgroup/run_test.pl:
+
+ Modified group_list to display groups by load strategy
+
+ Thu Nov 15 19:16:32 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl:
+
+ Added test for the load balancing function of the FT_Naming_Service.
+
+ Thu Nov 15 18:58:01 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_NamingManager.idl:
+
+ Updates to groups operation to allow it to request groups
+ with matching strategies.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Implements the new groups operation. Fixes to object reference
+ duplication and leaks.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Fixed bug in all_groups which did not duplicate the stored object
+ reference.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Test.idl:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp:
+
+ Modifications to support new signature for load balancing strategy
+ updates.
+
+ Thu Nov 15 18:02:04 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Invocation_Retry_State.h:
+ * tao/Invocation_Retry_State.cpp:
+
+ Added operations for getting next profile and
+ sleeping if at starting base profile.
+
+ * tao/Synch_Invocation.cpp:
+
+ Uses new Invocation_Retry_State operations. Beefed up
+ debug messages.
+
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.h:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.cpp:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Test.idl:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/client.cpp:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/run_test.pl:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/server.cpp:
+
+ Extend test to include oneway invocation.
+
+ * bin/tao_orb_tests.lst:
+
+ Added test for retry on connection failure for oneway call.
+
+ Thu Nov 15 17:16:12 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Cleaned up error messages
+
+ * utils/nsgroup/run_test.pl:
+
+ Added negative test for member_add
+
+ Thu Nov 15 16:06:29 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/README.nsgroup:
+ * utils/nsgroup/nsgroup.cpp:
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Implement group_modify and group_bind operations
+
+ * utils/nsgroup/run_test.pl:
+
+ Add support to positive and negative tests
+
+ Thu Nov 15 13:39:11 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Fix GNU C++ compile error.
+
+ Thu Nov 15 13:25:54 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Synch_Invocation.cpp:
+
+ Correct indentation for
+ Synch_Oneway_Invocation::remote_oneway().
+
+ Wed Nov 14 22:46:39 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_NamingManager.idl:
+
+ Added argument to create_object_group for the load balancing
+ strategy. Also added operation to change it dynamically without
+ having to use the property interface
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Support new constructor and manipulator for load balancing
+ strategy.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp:
+
+ Use new operations for load balancing strategy.
+
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Wed Nov 14 21:47:28 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_NamingManager.idl:
+
+ NamingManager no longer inherits from the GenericFactory
+ interface, to ensure that names are provided for object
+ groups.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ If no load balancing strategy is provided, then default to
+ using ROUND_ROBIN. Prevent warning for group state
+ distribution.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+
+ Prevent warning for group state distribution.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp:
+
+ Fixed bug in PG_Property_Set::set_property that
+ disallowed it from binding a new value when an existing
+ one was not present.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Test.idl:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp:
+
+ Updated tests to set new strategy value, and remove a group
+ member while running.
+
+ Wed Nov 14 20:24:41 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Invocation_Retry_Params.h:
+ * tao/Invocation_Retry_Params.cpp:
+ * tao/Invocation_Retry_State.h:
+ * tao/Invocation_Retry_State.cpp:
+ * tao/ORB_Core.cpp:
+ * tao/Synch_Invocation.cpp:
+ * tao/default_client.cpp:
+ * tao/params.h:
+ * tao/params.cpp:
+
+ Added new invocation parameter to indicate max
+ retries on reply connection closed and not base
+ max retries on comm failure limit. This is done
+ to treat retries on reply connection close
+ special since it could violate "at most once"
+ rule.
+
+ * orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.h:
+ * orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.cpp:
+ * orbsvcs/tests/ImplRepo/RestartServer/README:
+ * orbsvcs/tests/ImplRepo/RestartServer/run_test.pl:
+
+ Update test to account for using max retries on reply
+ connection closed.
+
+ Wed Nov 14 16:08:57 UTC 2012 Kevin Stanley <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp:
+
+ Simplified algorithm for Round Robin assuming mostly static
+ group members.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp:
+
+ Fixed bug in locations_of_members.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp:
+
+ Updates to tests to better match the load balancing approach.
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Load_Balancing_Name_Service.mpc:
+
+ Fix case of base project.
+
+ Wed Nov 14 14:43:17 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/ORB_Core.cpp:
+ * tao/Synch_Invocation.cpp:
+ * tao/params.h:
+ * tao/params.inl:
+ * tao/params.cpp:
+
+ Removed flag I added indicating a forward-once-on-exception
+ parameter was set. It was used to short circuit a
+ large conditional but it always set and the conditional
+ is in error handling code so optimization isn't critical.
+
+ Wed Nov 14 03:21:03 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/nsgroup_svc.cpp:
+ Changed output for member_show and member_list methods
+
+ * utils/nsgroup/run_test.pl:
+ Cleaned up tests
+
+ Tue Nov 13 22:28:27 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h:
+
+ Fix initialization order to avoid warning. Make Round Robin strategy
+ destructor virtual.
+
+ * orbsvcs/tests/FT_Naming:
+ * orbsvcs/tests/FT_Naming/Load_Balancing:
+
+ Add new directories to hold tests for FT_NamingService
+
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.h:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Load_Balancing_Name_Service.mpc:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/README:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/Test.idl:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/server.cpp:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/svc.conf:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf:
+ * orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf.xml:
+
+ Add tests for Load Balancing functionality of FT_Naming Service
+ * tao/Client_Strategy_Factory.h:
+
+ Change forward declaration type from class to struct to agree with definition.
+
+ Tue Nov 13 22:11:17 UTC 2012 Phillip LaBanca <labancap@ociweb.com>
+
+ * utils/nsgroup/README.nsgroup:
+
+ Updated to reflect changes
+
+ * utils/nsgroup/nsgroup.cpp:
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Change signature for member_add, member_remove, and member_show to not use member string argument.
+
+ * utils/nsgroup/run_test.pl:
+
+ Updated tests
+
+ * utils/utils.mwc:
+ Added nsgroup
+
+ Tue Nov 13 20:56:30 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * tao/Client_Strategy_Factory.h:
+ * tao/Invocation_Retry_Params.h:
+ * tao/Invocation_Retry_Params.cpp:
+ * tao/Invocation_Retry_State.h:
+ * tao/Invocation_Retry_State.cpp:
+ * tao/default_client.h:
+ * tao/default_client.cpp:
+ * tao/params.h:
+ * tao/params.cpp:
+ * tao/tao.mpc:
+
+ Allow invocation retry params to be specified
+ using Client_Strategy_Factory definition in
+ service config file in addition to -ORB
+ command line parameters.
+
+ * orbsvcs/tests/ImplRepo/RestartServer/client.conf:
+ * orbsvcs/tests/ImplRepo/RestartServer/run_test.pl:
+
+ Update test to read a retry parameter from a
+ service config file.
+
+ Mon Nov 12 23:05:55 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Catch exception when an invalid IOR is passed in for adding a member
+ to an object group.
+
+ * tao/Invocation_Retry_State.cpp:
+
+ Add missing include file.
+
+ Mon Nov 12 21:35:01 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * bin/tao_orb_tests.lst:
+ * bin/tao_other_tests.lst:
+
+ Added new invocation retry tests.
+
+ * orbsvcs/tests/ImplRepo/RestartServer/RestartServer.mpc:
+ * orbsvcs/tests/ImplRepo/RestartServer/Terminator.h:
+ * orbsvcs/tests/ImplRepo/RestartServer/Terminator.cpp:
+
+ Added missing files from test.
+
+ * tao/Synch_Invocation.cpp:
+
+ Added support for invocation reply if server sends
+ OBJECT_NOT_EXIST or INV_OBJREF exceptions.
+
+ * tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl:
+
+ Added configs for OBJECT_NOT_EXIST and INV_OBJREF exceptions.
+
+ Mon Nov 12 20:43:25 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_NamingManager.idl:
+
+ Add constants to support the creation of strategies.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Location_Index_Map.h:
+
+ Add new type to maintain the strategy state data.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Round_Robin.cpp:
+
+ Implement functionality in support of load balancing strategies.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Fixed functionality for looking up object groups with matching property value.
+
+ Mon Nov 12 18:19:10 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/tests/ImplRepo/RestartServer:
+
+ Renamed test ServerBounce to RestartServer to
+ be better compare with ReconnectServer test.
+
+ * orbsvcs/tests/ImplRepo/ServerBounce:
+ * orbsvcs/tests/ImplRepo/ServerBounce/Messenger.idl:
+ * orbsvcs/tests/ImplRepo/ServerBounce/MessengerClient.cpp:
+ * orbsvcs/tests/ImplRepo/ServerBounce/MessengerServer.cpp:
+ * orbsvcs/tests/ImplRepo/ServerBounce/Messenger_i.h:
+ * orbsvcs/tests/ImplRepo/ServerBounce/Messenger_i.cpp:
+ * orbsvcs/tests/ImplRepo/ServerBounce/README:
+ * orbsvcs/tests/ImplRepo/ServerBounce/ServerBounce.mpc:
+ * orbsvcs/tests/ImplRepo/ServerBounce/run_test.pl:
+
+ Removed these files.
+
+ Mon Nov 12 15:25:06 UTC 2012 Byron Harris <harrisb@ociweb.com>
+
+ * orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp:
+
+ Removed unused POA variable.
+
+ * orbsvcs/tests/ImplRepo/ServerBounce/Messenger.idl:
+ * orbsvcs/tests/ImplRepo/ServerBounce/MessengerClient.cpp:
+ * orbsvcs/tests/ImplRepo/ServerBounce/MessengerServer.cpp:
+ * orbsvcs/tests/ImplRepo/ServerBounce/Messenger_i.h:
+ * orbsvcs/tests/ImplRepo/ServerBounce/Messenger_i.cpp:
+ * orbsvcs/tests/ImplRepo/ServerBounce/README:
+ * orbsvcs/tests/ImplRepo/ServerBounce/ServerBounce.mpc:
+ * orbsvcs/tests/ImplRepo/ServerBounce/run_test.pl:
+
+ Test that shows client waiting for the ImR activator
+ to re-launch the server using new options
+ -ORBForwardOnCommFailureLimit and
+ -ORBForwardOnTransientLimit.
+
+ * tao/IIOP_Transport.cpp:
+ * tao/Invocation_Adapter.cpp:
+ * tao/Invocation_Retry_State.h:
+ * tao/Invocation_Retry_State.cpp:
+ * tao/Invocation_Utils.h:
+ * tao/ORB_Core.cpp:
+ * tao/Stub.h:
+ * tao/Stub.inl:
+ * tao/Stub.cpp:
+ * tao/Synch_Invocation.cpp:
+ * tao/Transport.h:
+ * tao/Transport.cpp:
+ * tao/params.h:
+ * tao/params.inl:
+ * tao/params.cpp:
+ * tao/tao.mpc:
+
+ Enhancements to TAO to support invocation retry during
+ initial connection to server, during reply from server,
+ and when the server reply contains exceptions.
+
+
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.h:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.cpp:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/README:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Retry_On_Connection_Failure.mpc:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Test.idl:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/client.cpp:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/run_test.pl:
+ * tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/server.cpp:
+
+ Test that shows client trying to connect to server
+ rather than throw a TRANSIENT exception when -ORBForwardOnTransientLimit
+ is used.
+
+ * tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/README:
+ * tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/Retry_On_Reply_Failure.mpc:
+ * tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/client.cpp:
+ * tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl:
+ * tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/server.cpp:
+ * tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test.idl:
+ * tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.h:
+ * tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.cpp:
+
+ Test that shows client trying invocation to server if
+ server replies with exception.
+
+ Mon Nov 12 01:20:54 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * utils/nsgroup/nsgroup_svc.cpp:
+ * utils/nsgroup/run_test.pl:
+
+ Modify bind_group command to use the -n option and format output
+ of group_list command to be more readable.
+
+ Sun Nov 11 21:34:42 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_NamingManager.idl:
+
+ Add operation for querying for all registered object groups.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+
+ Implement operation for querying for all registered object groups.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Add utility to implement query for all registered object groups.
+
+ * utils/nsgroup/nsgroup_svc.h:
+ * utils/nsgroup/nsgroup_svc.cpp:
+ * utils/nsgroup/run_test.pl:
+
+ Change signature for group_list to not use Location. Update implementation
+ to use the new operation defined in the NamingManager idl.
+
+ Sat Nov 10 20:45:07 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/FT_NamingManager.idl:
+
+ Add operations to create and destroy object groups as well
+ as find object groups by name.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp:
+
+ Provide implementations for the new operations defined in the FT_NamingManager.idl
+ for object group creation, deletion and retrieval by name.
+
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h:
+ * orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp:
+
+ Add an operation to find an object group with a matching property.
+ Primarily used to lookup an object group with a TAO_FT_OBJECT_GROUP_NAME
+ property set to the object group name.
+
+ * utils/nsgroup/nsgroup_svc.cpp:
+
+ Update to use the new create, delete and find operations by name.
+
+ * utils/nsgroup/run_test.pl:
+
+ Modifications to tests use naming manager instead of load manager.
+
+ Fri Nov 9 22:03:39 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/orbsvcs/Naming/Naming_Loader.cpp:
+
+ Fix incorrect capitalization for included file.
+
+ * tao/PortableServer/ServantRetentionStrategyNonRetain.cpp:
+
+ Fixed missing include and deal with mismatch in size expectations for time_t.
+
+ Fri Nov 9 21:20:45 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * orbsvcs/Naming_Service/FT_Naming_Main.cpp:
+ * orbsvcs/Naming_Service/FT_Naming_Service.h:
+ * orbsvcs/Naming_Service/FT_Naming_Service.cpp:
+
+ Add main and server files to implement the FT_Naming_Service and provide
+ refined implementation of the factory method in the FT_Naming_Service.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context_Factory.cpp:
+
+ Add new files to support the abstract factory pattern in the naming service.
+ Persistent_Naming_Context_Factory is the default used in the existing naming
+ service.
+
+ Fri Nov 9 19:35:51 UTC 2012 "Kevin Stanley" <stanleyk@ociweb.com>
+
+ * MPC/config/ftnaming.mpb:
+
+ Add new base project to support use of the FtNaming library components.
+
+ * orbsvcs/Naming_Service/Naming_Service.h:
+ * orbsvcs/Naming_Service/Naming_Service.cpp:
+
+ Refactored to support the use of derived TAO_Naming_Service objects.
+ Added factory method operation to allow the derived object to be
+ constructed and used.
+
+ * orbsvcs/Naming_Service/Naming_Service.mpc:
+
+ Added FT_Naming_Service project.
+
+ * orbsvcs/orbsvcs/FT_NamingManager.idl:
+
+ Define IDL to be used in FT_Naming_Service to define an aggregated
+ interface for PropertyManager, ObjectGroupManager, GenericFactory to
+ support the management of ObjectGroups used in the naming service to
+ provide a load balancing resolve operation
+
+ * orbsvcs/orbsvcs/FtNaming.mpc:
+
+ Provide a base library for the fault tolerant and load balancing
+ features in the FT_Naming_Service.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant:
+
+ Directory to hold the new FT_Naming_Service base component implementation
+ source.
+
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.h:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Persistent_Naming_Context_Factory.cpp:
+ * orbsvcs/orbsvcs/Naming/FaultTolerant/ftnaming_export.h:
+
+ Implements the FT_Naming_Service base classes. Specializes the
+ Persistent_Naming_Context to implement the load balancing feature.
+ The FT_Naming_Manager provides functionality to create and otherwise
+ manage object groups.
+
+ * orbsvcs/orbsvcs/Naming/Naming_Loader.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Loader.cpp:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.h:
+ * orbsvcs/orbsvcs/Naming/Naming_Server.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Context_Index.h:
+ * orbsvcs/orbsvcs/Naming/Persistent_Context_Index.cpp:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.h:
+ * orbsvcs/orbsvcs/Naming/Persistent_Naming_Context.cpp:
+
+ Refactoring of the Naming service base components to allow specialization
+ as required by the FT_Naming_Service.
+
+ * orbsvcs/orbsvcs/cosnaming_serv_persistence.mpb:
+
+ Added the Naming_Context_Factory as an abstract factory base class and
+ the Persistent_Naming_Context_Factory as a concrete implementation of
+ the abstract factory class.
+
+ Thu Nov 8 22:03:59 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * utils/logWalker/PeerProcess.h:
+ * utils/logWalker/PeerProcess.cpp:
+
+ Fix a warning not caught in the TAO 2.0a build.
+
+ Thu Nov 8 21:57:49 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * utils/logWalker/GIOP_Buffer.h:
+ * utils/logWalker/GIOP_Buffer.cpp:
+
+ Adding new files missed by the previous commit.
+
+ Thu Nov 8 21:51:42 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * utils/logWalker/HostProcess.h:
+ * utils/logWalker/HostProcess.cpp:
+ * utils/logWalker/Invocation.h:
+ * utils/logWalker/Invocation.cpp:
+ * utils/logWalker/Log.h:
+ * utils/logWalker/Log.cpp:
+ * utils/logWalker/PeerObject.cpp:
+ * utils/logWalker/PeerProcess.h:
+ * utils/logWalker/PeerProcess.cpp:
+ * utils/logWalker/Session.h:
+ * utils/logWalker/Session.cpp:
+ * utils/logWalker/Thread.h:
+ * utils/logWalker/Thread.cpp:
+ * utils/logWalker/logWalker.cpp:
+
+ Bringing over changes from OCI TAO 2.0a aimed at improving the
+ ability to handle logs from heavily threaded processes and for
+ inspecting some request contents for common service operations.
+
+ Wed Nov 7 18:04:55 UTC 2012 Brian Johnson <johnsonb@ociweb.com>
+
+ * tests/POA/Non_Retain_System_Id/Non_Retain_System_Id.mpc:
+
+ Changed project name to avoid collision (and to make sense).
+
+ Mon Nov 5 22:58:02 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/PortableServer/ServantRetentionStrategyNonRetain.h:
+ * tao/PortableServer/ServantRetentionStrategyNonRetain.cpp:
+
+ Force the POA to generate a unique object ID in the case where the ID
+ assignment policy is SYSTEM_ID, and the servant retention policy is
+ NONRETAIN. Historically this situation was ignored since the ID was only
+ considered useful in resolving servants from the AOM or when UISER_ID
+ assignment was set. However it is a valid usecase for a servant manager
+ or default servant to be used with system generated IDs.
+
+ * tests/POA/Non_Retain_System_Id:
+
+ New test to verify the correctness of the above change.
+
+ Fri Nov 2 21:10:42 UTC 2012 Marc Neeley <neeleym@ociweb.com>
+
+ * tests/Dynamic_TP:
+ * tests/Dynamic_TP/POA_Loader:
+ * tests/Dynamic_TP/POA_Loader/POA_Loader.mpc:
+ * tests/Dynamic_TP/POA_Loader/Test.cpp:
+ * tests/Dynamic_TP/POA_Loader/svc.conf:
+
+ Added first set of tests for POA loader.
+
+ Fri Nov 2 20:27:56 UTC 2012 Marc Neeley <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+
+ Implemented parsing of svc.conf files for mapping POA instances
+ to Thread Pool configs.
+
+ Mon Oct 29 16:14:14 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tests/Dynamic_TP/Config_Loader/Config_Loader.mpc:
+
+ Fix the project name so it plays nice with other test projects.
+
+ Fri Oct 26 21:53:26 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * MPC/Config/dynamic_tp.mpb:
+
+ A new base project used to simplify integration of the dynamic threadpool
+ library into application code.
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.h:
+ * tao/Dynamic_TP/Dynamic_TP_Config.cpp:
+
+ Completed the implementation to comply with written definition.
+
+ * tests/Dynamic_TP:
+ * tests/Dynamic_TP/Config_Loader:
+ * tests/Dynamic_TP/Config_Loader/Config_Loader.mpc:
+ * tests/Dynamic_TP/Config_Loader/Test.cpp:
+ * tests/Dynamic_TP/Config_Loader/svc.conf:
+
+ A test to validate the config loader.
+
+ Thu Oct 25 22:31:31 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.h:
+ * tao/Dynamic_TP/Dynamic_TP_Config.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_ORBInitializer.h:
+ * tao/Dynamic_TP/Dynamic_TP_ORBInitializer.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_ORB_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+
+ Fixed build dependencies, added parsing of configuration parameters.
+ not complete, this is an intermediate commit.
+
+ * tao/Dynamic_TP/Dynamic_TP_ORB_ORBInitializer.h:
+
+ Removed this file.
+
+ Wed Oct 24 22:37:11 UTC 2012 Marc Neeley <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP/Dynamic_TP_Config.h:
+ * tao/Dynamic_TP/Dynamic_TP_Config.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.inl:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Strategy.cpp:
+
+ Added new class for managing Threadpool Configurations. Continued expanding new Dynamic Threadpool Strategy implementation.
+
+ Tue Oct 23 13:07:15 UTC 2012 Marc Neeley <neeleym@ociweb.com>
+
+ * tao/Dynamic_TP:
+
+ * tao/Dynamic_TP/Dynamic_TP.mpc:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+
+ Added csd_threadpool to the mpc file. Began initialization of POA threadpool service.
+
+ Mon Oct 22 14:40:47 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/Dynamic_TP:
+
+ * tao/Dynamic_TP/Dynamic_TP.mpc:
+ * tao/Dynamic_TP/Dynamic_TP_ORB_Loader.h:
+ * tao/Dynamic_TP/Dynamic_TP_ORB_Loader.cpp:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.h:
+ * tao/Dynamic_TP/Dynamic_TP_POA_Loader.cpp:
+ * tao/Dynamic_TP/dynamic_tp_export.h:
+
+ New container library for Dynamic Thread Pools applied to either ORB or POA.
+
+ Fri Oct 19 17:24:49 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/Seq_Var_T.h:
+ * tao/Seq_Var_T.inl:
+ * tao/VarOut_T.h:
+ * tao/VarOut_T.inl:
+
+ Move explicit point dereference operation from variable length
+ vars to base so it can be applied to vars for fixed length types
+ as well. This is intended to improve portability away from ORBs
+ that provided this operation. Caution should be exercised when
+ using the returned pointer as the var still owns the reference and
+ will clean it up when it goes out of scope.
+
+ * tests/Var_Deref:
+
+ Added a test for the above. The test will not compile unless
+ the explicit cast operation is available for fixed types.
+
+ Mon Oct 15 18:26:57 UTC 2012 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * OCI_RE_ChangeLog:
+ Created change log for the OCI Reliability Enhancements branch
+
+ ***** OCI_Reliability_Enhancements Changes
+
Tue Feb 5 16:21:20 UTC 2013 Jeff Parsons <j.parsons@vanderbilt.edu>
* TAO_IDL/be/be_enum.cpp (gen_ostream_operator):
diff --git a/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/DynamicThreadPool.mpc b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/DynamicThreadPool.mpc
new file mode 100644
index 00000000000..0588996b1be
--- /dev/null
+++ b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/DynamicThreadPool.mpc
@@ -0,0 +1,37 @@
+// $Id$
+
+project(*idl): taoidldefaults {
+ idlflags += -Wb,pch_include=started_pch.h
+ IDL_Files {
+ Messenger.idl
+ }
+ custom_only = 1
+}
+
+project(*Server): taoserver, csd_framework, dynamic_tp {
+ exename = MessengerServer
+ after += *idl
+ Source_Files {
+ Messenger_i.cpp
+ MessengerServer.cpp
+ }
+ Source_Files {
+ MessengerC.cpp
+ MessengerS.cpp
+ }
+ IDL_Files {
+ }
+}
+
+project(*Client): taoclient {
+ exename = MessengerClient
+ after += *idl
+ Source_Files {
+ MessengerClient.cpp
+ }
+ Source_Files {
+ MessengerC.cpp
+ }
+ IDL_Files {
+ }
+}
diff --git a/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger.idl b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger.idl
new file mode 100644
index 00000000000..f58cb4e25aa
--- /dev/null
+++ b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger.idl
@@ -0,0 +1,10 @@
+// $Id$
+
+// Messenger.idl
+
+interface Messenger
+{
+ boolean send_message(in string user_name,
+ in string subject,
+ inout string message);
+};
diff --git a/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/MessengerClient.cpp b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/MessengerClient.cpp
new file mode 100644
index 00000000000..3f41a9b2e3b
--- /dev/null
+++ b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/MessengerClient.cpp
@@ -0,0 +1,74 @@
+// $Id$
+
+#include "started_pch.h"
+
+#include "MessengerC.h"
+#include <iostream>
+#include "ace/Get_Opt.h"
+
+const ACE_TCHAR *ior = ACE_TEXT ("file://Messenger.ior");
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'k':
+ ior = get_opts.opt_arg ();
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-k <ior> "
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int ACE_TMAIN (int argc, ACE_TCHAR* argv[])
+{
+ try {
+ // Initialize the ORB.
+ CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ // Read and destringify the Messenger object's IOR.
+ CORBA::Object_var obj = orb->string_to_object( ior );
+ if( CORBA::is_nil( obj.in() ) ) {
+ std::cerr << "Could not get Messenger IOR." << std::endl;
+ return 1;
+ }
+
+ // Narrow the IOR to a Messenger object reference.
+ Messenger_var messenger = Messenger::_narrow( obj.in() );
+ if( CORBA::is_nil( messenger.in() ) ) {
+ std::cerr << "IOR was not a Messenger object reference." << std::endl;
+ return 1;
+ }
+
+ // Send a message the the Messenger object.
+ CORBA::String_var msg = CORBA::string_dup( "Hello!" );
+ messenger->send_message( "TAO User", "TAO Test", msg.inout() );
+
+ // Print the Messenger's reply.
+ std::cout << "Reply: " << msg.in() << std::endl;
+
+ return 0;
+ }
+ catch(const CORBA::Exception& ex) {
+ std::cerr << "CORBA exception: " << ex << std::endl;
+ }
+
+ return 1;
+}
diff --git a/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/MessengerServer.cpp b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/MessengerServer.cpp
new file mode 100644
index 00000000000..b148b7f2494
--- /dev/null
+++ b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/MessengerServer.cpp
@@ -0,0 +1,104 @@
+// $Id$
+
+#include "started_pch.h"
+
+#include "Messenger_i.h"
+#include "tao/Dynamic_TP/DTP_POA_Strategy.h"
+#include <iostream>
+#include <fstream>
+#include "ace/Get_Opt.h"
+
+const ACE_TCHAR *ior_output_file = ACE_TEXT ("Messenger.ior");
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-o <iorfile>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try {
+ // Initialize the ORB.
+ CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ //Get reference to the RootPOA.
+ CORBA::Object_var obj = orb->resolve_initial_references( "RootPOA" );
+ PortableServer::POA_var poa = PortableServer::POA::_narrow( obj.in() );
+
+ // Create a configuration structure and set the values
+ TAO_DTP_Definition tp_config;
+
+ tp_config.min_threads_ = 1; // Set low water mark to 1 thread.
+ tp_config.init_threads_ = 3; // Start 3 threads to start.
+ tp_config.max_threads_ = -1; // Create threads as needed (no limit).
+ tp_config.queue_depth_ = -1; // Allow infinite queue depth.
+ tp_config.stack_size_ = (64 * 1024); // Each thread with 64K stacksize.
+ tp_config.timeout_ = ACE_Time_Value(30,0); // Expire thread that is idle for 30 sec.
+
+ // Create the dynamic thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO_DTP_POA_Strategy> dtp_strategy =
+ new TAO_DTP_POA_Strategy(&tp_config, false);
+
+ // Tell the strategy to apply itself to the child poa.
+ if (dtp_strategy->apply_to(poa.in()) == false)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to root poa.\n"));
+ return -1;
+ }
+
+
+ // Activate the POAManager.
+ PortableServer::POAManager_var mgr = poa->the_POAManager();
+ mgr->activate();
+
+ // Create a servant.
+ PortableServer::Servant_var<Messenger_i> servant = new Messenger_i();
+
+ // Register the servant with the RootPOA, obtain its object
+ // reference, stringify it, and write it to a file.
+ PortableServer::ObjectId_var oid = poa->activate_object( servant.in() );
+ obj = poa->id_to_reference( oid.in() );
+ CORBA::String_var str = orb->object_to_string( obj.in() );
+ std::ofstream iorFile( ACE_TEXT_ALWAYS_CHAR(ior_output_file) );
+ iorFile << str.in() << std::endl;
+ iorFile.close();
+ std::cout << "IOR written to file " << ACE_TEXT_ALWAYS_CHAR(ior_output_file) << std::endl;
+
+ // Accept requests from clients.
+ orb->run();
+ orb->destroy();
+
+ return 0;
+ }
+ catch(const CORBA::Exception& ex) {
+ std::cerr << "CORBA exception: " << ex << std::endl;
+ }
+
+ return 1;
+}
diff --git a/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.cpp b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.cpp
new file mode 100644
index 00000000000..2e6a819f7d2
--- /dev/null
+++ b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.cpp
@@ -0,0 +1,36 @@
+#include "started_pch.h"
+/* -*- C++ -*- $Id$ */
+
+// ****** Code generated by the The ACE ORB (TAO) IDL Compiler *******
+// TAO and the TAO IDL Compiler have been developed by the Center for
+// Distributed Object Computing at Washington University, St. Louis.
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
+#include "Messenger_i.h"
+#include <iostream>
+// Implementation skeleton constructor
+Messenger_i::Messenger_i (void)
+{
+}
+
+// Implementation skeleton destructor
+Messenger_i::~Messenger_i (void)
+{
+}
+
+CORBA::Boolean
+Messenger_i::send_message (
+ const char * user_name,
+ const char * subject,
+ char *& message)
+{
+ std::cout << "Message from: " << user_name << std::endl;
+ std::cout << "Subject: " << subject << std::endl;
+ std::cout << "Message: " << message << std::endl;
+ CORBA::string_free(message);
+ message = CORBA::string_dup("Thanks for the message.");
+ return true;
+}
+
diff --git a/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.h b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.h
new file mode 100644
index 00000000000..4af885c4b50
--- /dev/null
+++ b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/Messenger_i.h
@@ -0,0 +1,36 @@
+/* -*- C++ -*- $Id$ */
+
+// ****** Code generated by the The ACE ORB (TAO) IDL Compiler *******
+// TAO and the TAO IDL Compiler have been developed by the Center for
+// Distributed Object Computing at Washington University, St. Louis.
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
+#ifndef MESSENGER_I_H_
+#define MESSENGER_I_H_
+
+#include "MessengerS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+//Class Messenger_i
+class Messenger_i : public virtual POA_Messenger
+{
+public:
+ //Constructor
+ Messenger_i (void);
+
+ //Destructor
+ virtual ~Messenger_i (void);
+
+ virtual CORBA::Boolean send_message (
+ const char * user_name,
+ const char * subject,
+ char *& message);
+};
+
+
+#endif /* MESSENGERI_H_ */
diff --git a/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.cpp b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.cpp
new file mode 100644
index 00000000000..c2c8b943b32
--- /dev/null
+++ b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.cpp
@@ -0,0 +1,3 @@
+// $Id$
+
+#include "started_pch.h"
diff --git a/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.h b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.h
new file mode 100644
index 00000000000..fe6d2628083
--- /dev/null
+++ b/TAO/DevGuideExamples/Multithreading/DynamicThreadPool/started_pch.h
@@ -0,0 +1,12 @@
+// $Id$
+
+#ifndef PCH_H
+#define PCH_H
+
+#ifdef USING_PCH
+#include "tao/corba.h"
+#include "tao/ORB_Core.h"
+#include "tao/Stub.h"
+#endif
+
+#endif
diff --git a/TAO/MPC/config/dynamic_tp.mpb b/TAO/MPC/config/dynamic_tp.mpb
new file mode 100644
index 00000000000..8682db73c3f
--- /dev/null
+++ b/TAO/MPC/config/dynamic_tp.mpb
@@ -0,0 +1,7 @@
+// -*- MPC -*-
+// $Id$
+
+project : taolib, pi {
+ after += Dynamic_TP
+ libs += TAO_Dynamic_TP
+}
diff --git a/TAO/MPC/config/ft_naming_serv.mpb b/TAO/MPC/config/ft_naming_serv.mpb
new file mode 100644
index 00000000000..8d54dab6727
--- /dev/null
+++ b/TAO/MPC/config/ft_naming_serv.mpb
@@ -0,0 +1,7 @@
+// -*- MPC -*-
+// $Id$
+
+project : orbsvcslib, naming_skel, naming_serv, iortable, messaging_optional, svc_utils {
+ after += FT_Naming_Serv
+ libs += TAO_FT_Naming_Serv
+}
diff --git a/TAO/MPC/config/ftnaming.mpb b/TAO/MPC/config/ftnaming.mpb
new file mode 100644
index 00000000000..13ed71ed8a6
--- /dev/null
+++ b/TAO/MPC/config/ftnaming.mpb
@@ -0,0 +1,9 @@
+// -*- MPC -*-
+// $Id$
+
+project : naming, portablegroup, orbsvcslib, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro {
+ after += FtNaming
+ libs += TAO_FtNaming
+ tagchecks += FtNaming
+
+}
diff --git a/TAO/MPC/config/ftnaming_replication.mpb b/TAO/MPC/config/ftnaming_replication.mpb
new file mode 100644
index 00000000000..b69e2e6b49f
--- /dev/null
+++ b/TAO/MPC/config/ftnaming_replication.mpb
@@ -0,0 +1,7 @@
+// -*- MPC -*-
+// $Id$
+
+project : avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro {
+ after += FtNamingReplication
+ libs += TAO_FtNamingReplication
+}
diff --git a/TAO/MPC/config/imr_client.mpb b/TAO/MPC/config/imr_client.mpb
index bcae2e9f14b..5060897c4de 100644
--- a/TAO/MPC/config/imr_client.mpb
+++ b/TAO/MPC/config/imr_client.mpb
@@ -1,7 +1,7 @@
// -*- MPC -*-
// $Id$
-project : taolib, portableserver {
+project : taolib, portableserver, iormanip {
libs += TAO_ImR_Client
after += ImR_Client
}
diff --git a/TAO/NEWS b/TAO/NEWS
index be9e95205df..4042fabe450 100644
--- a/TAO/NEWS
+++ b/TAO/NEWS
@@ -1,5 +1,54 @@
USER VISIBLE CHANGES BETWEEN TAO-2.1.7 and TAO-2.1.8
====================================================
+. Fault Tolerant Implementation Repository [#4091] - The Implementation
+ Repository Locator now supports a dual-redundant fault tolerant
+ configuration which provides replication and seamless failover between
+ the primary and backup locator servers.
+
+. Fault Tolerant Naming Service [#4092 & #4095] - A new Fault Tolerant
+ Naming Service (tao_ft_naming), provides dual-redundant fault tolerant
+ servers which utilize replication and seamless failover between the
+ primary and backup server. The Fault Tolerant Naming Service can be
+ used to provide load balancing capabilities (only the round-robin load
+ balancing strategy is currently supported) through the use object groups.
+ This feature is supported by a separate utility for managing the object
+ groups (tao_nsgroup) as well as a programatic interface via IDL.
+
+. Configurable Persistence Mechanism [#4092] - Extracted persistence
+ mechanism used for storable naming context into Storable_* classes so
+ that it can be reused. Simplified use of storable read/write so that
+ it behaves more like C++ streams to read/write binary and CDR data.
+ Added support for creating a backup mechanism to accomodate
+ potentially corrupted files. Providing configurable hooks so
+ applications can decide if files are obsolete and need to be written
+ to the persistence store.
+
+. ORB Dynamic Thread Pool [#4093] - Added a new ORB thread pool strategy
+ to dynamically adjust the number of threads which the ORB uses to
+ service received calls based on several configuration parameters.
+ These parameters include initial threads, minimum pool threads,
+ maximum pool threads, request queue depth, thread stack size, and
+ thread idle time.
+
+. POA Dynamic Thread Pool [#4094] - A new Dynamic Thread Pool and
+ Queuing strategy was created for POA usage. It leverages the
+ existing Custom Servant Dispatching framework for invocation and
+ activation. The strategy also dynamically adjusts the number of
+ threads using configuration parameters similar to the ORB Dynamic
+ Thread Pool. The Dynamic Thread Pool POA Strategy supports
+ applications in associating a single thread pool with either
+ 1) a single POA in a dedicated configuration, or 2) multiple
+ POAs in a shared configuration. The strategy controls a request
+ queue used to accept calls directed to an associated servant and
+ a pool of threads that wait to service calls coming in on a
+ particular queue.
+
+. Enhanced TAO Invocation Retry [#4096] - Extended TAO to support retry
+ in the presence of COMM_FAILURE exceptions. This feature is used to
+ support fault tolerant services (specifically the Fault Tolerant
+ Naming and Implementation Repository services described earlier).
+ The new invocation retry support allows configuration on how many
+ times to try to connect to each server and the delay between tries.
. Added MIOP configuration options -ORBSendThrottling and -ORBEagerDequeueing,
along with #define overrides for their default settings. See the descriptions
diff --git a/TAO/TAO_IDL/tao_idl.mpc b/TAO/TAO_IDL/tao_idl.mpc
index 22cc56b6926..d9822c6d3da 100644
--- a/TAO/TAO_IDL/tao_idl.mpc
+++ b/TAO/TAO_IDL/tao_idl.mpc
@@ -35,8 +35,8 @@ project(TAO_IDL_EXE) : aceexe, install, tao_output, tao_idl_fe {
verbatim(gnuace, postinstall) {
" @$(MKDIR) $(DESTDIR)$(INSTALL_PREFIX)/share/ace/bin"
" ln -sf $(INSTALL_PREFIX)/bin/tao_idl $(DESTDIR)$(INSTALL_PREFIX)/share/ace/bin"
-" @$(MKDIR) $(DESTDIR)$(INSTALL_PREFIX)/share/ace/$(INSTALL_LIB)"
-" ln -sf $(INSTALL_PREFIX)/$(INSTALL_LIB)/$(LIB_PREFIX)TAO_IDL_[FB]E.$(SOEXT) $(DESTDIR)$(INSTALL_PREFIX)/share/ace/$(INSTALL_LIB)"
+" @$(MKDIR) $(DESTDIR)$(INSTALL_PREFIX)/share/ace/lib"
+" ln -sf $(INSTALL_PREFIX)/$(INSTALL_LIB)/$(LIB_PREFIX)TAO_IDL_[FB]E.$(SOEXT) $(DESTDIR)$(INSTALL_PREFIX)/share/ace/lib"
}
Source_Files {
diff --git a/TAO/bin/tao_orb_tests.lst b/TAO/bin/tao_orb_tests.lst
index 68506142ae8..307d82c9491 100644
--- a/TAO/bin/tao_orb_tests.lst
+++ b/TAO/bin/tao_orb_tests.lst
@@ -454,6 +454,9 @@ TAO/tests/CSD_Strategy_Tests/TP_Test_4/run_test.pl big: !ST !CORBA_E_MICRO !Lynx
TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/run_test.pl: !STATIC !ST !CORBA_E_MICRO !LynxOS
TAO/tests/CSD_Strategy_Tests/TP_Test_Static/run_test.pl: !ST !CORBA_E_MICRO !LynxOS
TAO/tests/CSD_Collocation/run_test.pl: !ST !CORBA_E_COMPACT !CORBA_E_MICRO !MINIMUM !LynxOS
+TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl: !ST !CORBA_E_MICRO !LynxOS
+TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/run_test.pl: !ST !CORBA_E_MICRO !LynxOS
+TAO/tests/Dynamic_TP/ORB_ThreadPool/run_test.pl: !ST !CORBA_E_MICRO !LynxOS
TAO/tests/Permanent_Forward/run_test.pl:
TAO/tests/Parallel_Connect_Strategy/run_test.pl: !QUICK55
TAO/tests/Parallel_Connect_Strategy/run_test.pl -quick : QUICK55
@@ -465,6 +468,11 @@ TAO/tests/ZIOP/run_test.pl: ZLIB BZIP2
TAO/tests/ForwardUponObjectNotExist/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !ACE_FOR_TAO
TAO/tests/ForwardOnceUponException/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !ACE_FOR_TAO !ST
TAO/tests/Bug_3853_Regression/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !ACE_FOR_TAO
+TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/run_test.pl:
+TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/run_test.pl -oneway:
+TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl:
+# Storable test can't run under Windows because the file locking doesn't work on that platform.
+TAO/tests/Storable/run_test.pl: !Win32
TAO/DevGuideExamples/BiDirectionalGIOP/run_test.pl: !MINIMUM !CORBA_E_MICRO
TAO/DevGuideExamples/GettingStarted/run_test.pl:
TAO/DevGuideExamples/LocalObjects/Messenger/run_test.pl:
diff --git a/TAO/bin/tao_other_tests.lst b/TAO/bin/tao_other_tests.lst
index 9b0ef8b192d..b55276fdfb4 100644
--- a/TAO/bin/tao_other_tests.lst
+++ b/TAO/bin/tao_other_tests.lst
@@ -81,7 +81,8 @@ TAO/orbsvcs/tests/HTIOP/AMI/run_test.pl: !NO_UUID !ST !STATIC !MINIMUM !CORBA_E_
TAO/orbsvcs/tests/HTIOP/BiDirectional/run_test.pl: !NO_UUID !STATIC !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ACE_FOR_TAO !LynxOS
TAO/orbsvcs/tests/Simple_Naming/run_test.pl: !ST !NO_MESSAGING !ACE_FOR_TAO !LynxOS !CORBA_E_MICRO !DISTRIBUTED
TAO/orbsvcs/tests/Simple_Naming/run_test_ffp.pl: !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !NO_MESSAGING !ACE_FOR_TAO !DISTRIBUTED
-TAO/orbsvcs/tests/Redundant_Naming/run_test.pl: !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ACE_FOR_TAO !DISTRIBUTED
+TAO/orbsvcs/tests/Simple_Naming/run_test_ft.pl: !Win32 !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !NO_MESSAGING !ACE_FOR_TAO !DISTRIBUTED
+TAO/orbsvcs/tests/Redundant_Naming/run_test.pl: !Win32 !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ACE_FOR_TAO !DISTRIBUTED
TAO/orbsvcs/tests/Trading/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO
TAO/orbsvcs/tests/unit/Trading/Interpreter/run_test.pl: !CORBA_E_MICRO
TAO/orbsvcs/tests/Event/Basic/run_test.pl: !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ACE_FOR_TAO
@@ -116,6 +117,13 @@ TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_ir: !MINIMUM !CORBA_E_COMPACT
TAO/orbsvcs/tests/ImplRepo/run_test.pl nt_service_ir: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR Win32 !ACE_FOR_TAO
TAO/orbsvcs/tests/ImplRepo/run_test.pl shutdown: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !LynxOS !ACE_FOR_TAO
TAO/orbsvcs/tests/ImplRepo/run_test.pl perclient: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO
+TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_ir_hash: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO
+TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_ir_shared: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !Win32
+TAO/orbsvcs/tests/ImplRepo/run_test.pl failover -replica: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !Win32
+TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_ft -replica: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !Win32
+TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_listingcorrupt -replica: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !Win32
+TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_activatorcorrupt -replica: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !Win32
+TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_servercorrupt -replica: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !Win32
TAO/orbsvcs/tests/ImplRepo/NameService/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO
TAO/orbsvcs/tests/ImplRepo/locked/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !LynxOS !ACE_FOR_TAO
TAO/orbsvcs/tests/ImplRepo/scale/run_test.pl -servers 5 -objects 5: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS
@@ -124,6 +132,7 @@ TAO/orbsvcs/tests/ImplRepo/Bug_2604_Regression/run_test.pl: !MINIMUM !CORBA_E_CO
TAO/orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS
TAO/orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl -forwardalways: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS
TAO/orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl -forwardonce: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS
+TAO/orbsvcs/tests/ImplRepo/RestartServer/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS
TAO/orbsvcs/examples/ImR/Combined_Service/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !STATIC !ST !ACE_FOR_TAO !LynxOS
TAO/orbsvcs/examples/CosEC/TypedSimple/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !NO_IFR !ACE_FOR_TAO !WCHAR
TAO/orbsvcs/tests/CosEvent/Timeout/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ST !NO_MESSAGING !ACE_FOR_TAO !LynxOS
@@ -259,3 +268,8 @@ TAO/orbsvcs/DevGuideExamples/NamingService/corbaname_Messenger/run_test.pl: !COR
TAO/orbsvcs/DevGuideExamples/ValueTypes/Notify/run_test.pl: !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !LynxOS
TAO/orbsvcs/DevGuideExamples/InterfaceRepo/run_test.pl: !MINIMUM !NO_IFR !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO
TAO/orbsvcs/DevGuideExamples/PortableInterceptors/PICurrent_NameService/run_test.pl: !MINIMUM !DISABLE_INTERCEPTORS !LynxOS !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO
+TAO/utils/nsgroup/run_test.pl: !Win32 !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !STATIC !ACE_FOR_TAO !LynxOS !ST
+TAO/orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl: !Win32 !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !ACE_FOR_TAO !LynxOS !ST
+TAO/orbsvcs/tests/FT_Naming/Replication/run_test.pl: !Win32 !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !ACE_FOR_TAO !LynxOS !ST
+TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_test.pl: !Win32 !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !ACE_FOR_TAO !LynxOS !ST
+TAO/orbsvcs/tests/FT_Naming/Federation/run_test.pl: !Win32 !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !ACE_FOR_TAO !LynxOS !ST
diff --git a/TAO/docs/Options.html b/TAO/docs/Options.html
index 7763f252650..0161ad646bc 100644
--- a/TAO/docs/Options.html
+++ b/TAO/docs/Options.html
@@ -23,6 +23,7 @@
<li><a href="#ORP">Optimizing Request Processing </a> </li>
<li><a href="#CMPS">Connection Management and Protocol
Selection </a> </li>
+ <li><a href="#IRO">Invocation Retry Options</a></li>
<li><a href="#MO">Miscellaneous Options </a></li>
</ol>
</li>
@@ -447,7 +448,7 @@ also removes the ability to interoperate with ORBs on systems using
alternative character or wide charater encodings. The default value may be set
at compile time by defining <CODE>TAO_NEGOTIATE_CODESETS 0</CODE> in
<CODE>orbconf.h</CODE>. Codeset negotiation support is enabled by default in
-TAO as shipped.<br> <bold>Note to static lib users</bold> In order to build
+TAO as shipped.<br> <b>Note to static lib users</b> In order to build
TAO statically and get the codeset negotiation feature, two additional steps
are needed to ensure the TAO_Codeset library is linked in and initalized. Add the MPC feature "negotiate_codesets=1" to the default.features file and regenerate your makefiles, and add <CODE>#include "tao/Codeset/Codeset.h"</CODE> somewhere in your application source, such as the cpp file containing your main.</td>
</tr>
@@ -886,7 +887,129 @@ is set. The default is true. </td>
</table>
</p>
</blockquote>
-<h4><a name="MO">5. Miscellaneous Options</a></h4>
+<h4><a name="IRO">5. Invocation Retry Options</a></h4>
+In cases such as connection timing issues or a load balancing server
+is temporarily not able to handle requests, it may be desirable to have
+the ORB transparently retry an invocation a maximum number of times
+until a successful invocation is made. To support this, a set of
+parameters can be used to cycle over base and location forwarded
+profiles until an invocation is successful. When cycling over
+profiles and the first base profile is to be used, a user-defined
+delay is made before retrying.
+<p></p>
+These parameters are used in the following situations:
+<p></p>
+<ul>
+ <li>Initial connection: If the connection to a server would result
+in a TRANSIENT exception being thrown, cycle over profiles no more than the value of
+the -ORBForwardOnTransientLimit option before throwing the exception.
+ <p></p>
+ </li>
+ <li>Waiting for a reply from the server: When using the IIOP protocol,
+on many platforms if zero bytes is read as the server's reply, this could
+indicate that the server may have had a disorderly shutdown or the
+connection to the server was abruptly terminated. In this case
+cycling through the profiles to retry the request will not exceeding the
+value of -ORBForwardOnReplyClosedLimit. If for example the Implementation
+Repository and Activator are used to start the server then this cycling could be
+used to give the server enough time to re-launch. When this option is
+used the -ORBForwardOnTransientLimit option should also be used to
+avoid exceptions being thrown when trying to reestablish a connection.
+<b>Note that because it is not known if the request was sent, this
+could result in the request being processed more than one by the
+server. Therefore this option should be used with care.</b>
+This is why, although a COMM_FAILURE exception is normally thrown in this case,
+this option is kept distinct from -ORBForwardOnCommFailureLimit
+discussed below.
+ <p></p>
+ <li>Server sends an exception as a reply: A reply is received
+and it is checked if it is an exception. If the exception is
+of type COMM_FAILURE with completion status of COMPLETED_NO, then
+the profiles will be cycled no more than the value of option
+-ORBForwardOnCommFailureLimit until a successful reply is
+received. Similar retries can be applied to TRANSIENT exceptions
+(-ORBForwardOnTransientLimit), OBJECT_NOT_EXIST exceptions
+(-ORBForwardOnObjectNotExistLimit), and INV_OBJREF exceptions
+(-ORBForwardOnInvObjrefLimit).
+ <p></p>
+ </li>
+</ul>
+
+The retry options are given in the table below. Note that for
+backward compatibility, the -ORBForward* options described in the
+<a href="#MO">Miscellaneous Options </a> section are retained.
+However, if any option in this section is used, then any
+-ORBForward* option given in the Miscellaneous Options
+section is ignored.
+ <p></p>
+
+These options can also be used in the list of
+ <a href="#TCSF">Client_Strategy_Factory</a> options
+in the service configurator file.
+Using the service configurator file can help insure these
+options are uniformly applied across multiple clients by
+having them use the same configurator file.
+
+<blockquote>
+ <p>
+ <table border="2" cellpadding="0" cellspacing="2">
+ <tbody>
+ <tr>
+ <th>Option</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>-ORBForwardOnTransientLimit</code> <em>limit</em></td>
+ <td>Use this option to cycle through profiles when
+ establishing a connection with a server or when a
+ server replies to a request with a TRANSIENT
+ exception.
+ The number of retries will not exceed <em>limit</em>.</td>
+ </tr>
+ <tr>
+ <td><code>-ORBForwardOnCommFailureLimit</code> <em>limit</em></td>
+ <td>Use this option to cycle through profiles when a
+ server replies to a request with a COMM_FAILURE
+ exception.
+ The number of retries will not exceed <em>limit</em>.</td>
+ </tr>
+ <tr>
+ <td><code>-ORBForwardOnObjectNotExistLimit</code> <em>limit</em></td>
+ <td>Use this option to cycle through profiles when a
+ server replies to a request with a OBJECT_NOT_EXIST
+ exception.
+ The number of retries will not exceed <em>limit</em>.</td>
+ </tr>
+ <tr>
+ <td><code>-ORBForwardOnInvObjrefLimit</code> <em>limit</em></td>
+ <td>Use this option to cycle through profiles when a
+ server replies to a request with a INV_OBJREF
+ exception.
+ The number of retries will not exceed <em>limit</em>.</td>
+ </tr>
+ <tr>
+ <td><code>-ORBForwardOnReplyClosedLimit</code> <em>limit</em></td>
+ <td>Use this option to cycle through profiles when it has
+ been detected that a connection is closed when reading a server reply.
+ The number of retries will not exceed <em>limit</em>.
+ If this option is used then -ORBForwardOnTransientLimit should
+ also be used to avoid a TRANSIENT exception being thrown.
+ </td>
+ </tr>
+ <tr>
+ <td><code>-ORBForwardDelay</code> <em>int msecs</em></td>
+ <td>Defines the number of milliseconds to delay while
+ cycling through profiles when the first base profile
+ is to be tried. The default is 100,000 milliseconds
+ (0.1 seconds).</td>
+ </tr>
+ </tbody>
+ </table>
+ </p>
+</blockquote>
+
+
+<h4><a name="MO">6. Miscellaneous Options</a></h4>
Options in this category don't control the behavior of the ORB in
terms of resouces or strategies. Instead, they are helper options
provided for specific application requirements.
@@ -907,7 +1030,7 @@ coexisting ORBs (when there is more than one ORB).</td>
</tr>
<tr>
<td><code>-ORBServerId</code> <em>server_id</em></td>
- <td><a name="-ORBId"></a>This option allows setting a name/id
+ <td><a name="-ORBServerId"></a>This option allows setting a name/id
to a server to uniquely identify a server to TAO's <a href="implrepo">Implementation
Repository</a>. </td>
</tr>
@@ -1011,7 +1134,7 @@ use MIOP protocol.
<p></p>
</li>
<li> <a href="#TTSM">Time Policy Strategy Manager.</a> This factory
-manages the TIME_POLICY strategy used by the ORB for timers and
+manages the TIME_POLICY strategy used by the ORB for timers and
countdowns.
<p></p>
</li>
@@ -1663,63 +1786,73 @@ the protocols in TAO (such as SHMIOP and SSLIOP) can only use the <em>blocked</e
strategy.
</td>
</tr>
+ <tr>
+ <td>Invocation Retry options</td>
+ <td>Options of the same names as the command-line options
+ described in <a href="#IRO">Invocation Retry Options</a>
+ can also be applied client strategy factory service. Any
+ option provided on the command line will override the
+ corresponding option in the service configurator
+ file.
+ </td>
+ </tr>
</tbody>
</table>
</p>
</blockquote>
<h4><a name="TMSF">4. MIOP_Strategy_Factory</a></h4>
- This factory is located in the <code>TAO_PortableGroup</code> library and it
- accepts the options below. This factory can be loaded dynamically using a
+ This factory is located in the <code>TAO_PortableGroup</code> library and it
+ accepts the options below. This factory can be loaded dynamically using a
service configurator directive of the form (all on one line):
- <p><code>dynamic MIOP_Resource_Factory Service_Object *
+ <p><code>dynamic MIOP_Resource_Factory Service_Object *
TAO_PortableGroup:_make_TAO_MIOP_Resource_Factory () ""</code></p>
- Normally in order to set up the MIOP implementation correctly, the application
+ Normally in order to set up the MIOP implementation correctly, the application
will have to use other service configurator directives as well (for example):
- <p><code>dynamic UIPMC_Factory Service_Object *
+ <p><code>dynamic UIPMC_Factory Service_Object *
TAO_PortableGroup:_make_TAO_UIPMC_Protocol_Factory() ""<br>
- static Resource_Factory "&#8209;ORBProtocolFactory IIOP_Factory
+ static Resource_Factory "&#8209;ORBProtocolFactory IIOP_Factory
&#8209;ORBProtocolFactory UIPMC_Factory"<br>
- dynamic PortableGroup_Loader Service_Object *
+ dynamic PortableGroup_Loader Service_Object *
TAO_PortableGroup:_make_TAO_PortableGroup_Loader() ""<br>
- dynamic MIOP_Resource_Factory Service_Object *
+ dynamic MIOP_Resource_Factory Service_Object *
TAO_PortableGroup:_make_TAO_MIOP_Resource_Factory () ""</code></p>
- Any options required to be given to the MIOP_Resource_Factory should be
- specified between the two double-quotes shown above as a space separated list;
- however none are required as all options take default values if not specified.
- Since MIOP uses UDP sockets (which is not a "reliable" transport unlike tcp/ip)
- it is easy to configure MIOP in such a way that messages will not actually
- reach the servant. The options below are intended to maximize MIOP reliability
- but they must be used with care; users of MIOP must understand that large
- messages are sent in fragments and they have to be reassembled by the server in
- their entirety to be usable by the servant. If even a single data
- fragment/packet is lost, the whole message cannot be reconstructed and will be
- unusable. There is no way for the servant to even know it has missed such a
- MIOP message, and being a one-way protocol, neither will the client be aware
- that the message has been lost. Fragments can be lost due to a variety of
+ Any options required to be given to the MIOP_Resource_Factory should be
+ specified between the two double-quotes shown above as a space separated list;
+ however none are required as all options take default values if not specified.
+ Since MIOP uses UDP sockets (which is not a "reliable" transport unlike tcp/ip)
+ it is easy to configure MIOP in such a way that messages will not actually
+ reach the servant. The options below are intended to maximize MIOP reliability
+ but they must be used with care; users of MIOP must understand that large
+ messages are sent in fragments and they have to be reassembled by the server in
+ their entirety to be usable by the servant. If even a single data
+ fragment/packet is lost, the whole message cannot be reconstructed and will be
+ unusable. There is no way for the servant to even know it has missed such a
+ MIOP message, and being a one-way protocol, neither will the client be aware
+ that the message has been lost. Fragments can be lost due to a variety of
reasons:
<p></p>
<ul>
<li>
- The client sends too large a message fragment, or sends messages too fast,
- overwhelming the client socket's transmission buffer. (In this case the
- client-side OS simply ignores the excess send requests and some of the
+ The client sends too large a message fragment, or sends messages too fast,
+ overwhelming the client socket's transmission buffer. (In which case the
+ client-side OS simply ignores the excess send requests and some of the
fragments are not actually sent on the wire.)
<li>
- The server socket's receive buffer became too full to acquire the fragments off
- the wire. (In this case the client is again sending messages too fast, but this
- time it is the servant that is too slow to process the messages it has already
+ The server socket's receive buffer became too full to acquire the fragments off
+ the wire. (In this case the client is again sending messages too fast, but this
+ time it is the servant that is too slow to process the messages it has already
received.)
<li>
- Something happend to the network or routing and the packet was lost between the
- client and the server, or the server OS failed to react to the hardware network
+ Something happend to the network or routing and the packet was lost between the
+ client and the server, or the server OS failed to react to the hardware network
device in a timely manor so that network packets were lost.</li></ul>
<p></p>
- <p style="Z-INDEX: 0">In the first two cases above, the loss can be mitigated by
- the client adapting/throttling its sending rate so as to not overflow the
- capacity of the client's operating system sending buffer and the receiving
- buffer of the server socket. If there are multiple clients all sending to the
- same server, all of these clients must be configured to slow down their sending
- rate (as a software system design descision) as otherwise the server's receive
+ <p style="Z-INDEX: 0">In the first two cases above, the loss can be mitigated by
+ the client adapting/throttling its sending rate so as to not overflow the
+ capacity of the client's operating system sending buffer and the receiving
+ buffer of the server socket. If there are multiple clients all sending to the
+ same server, all of these clients must be configured to slow down their sending
+ rate (as a software system design descision) as otherwise the server's receive
buffer will become swamped and some messages will be lost.</p>
<blockquote>
<p>
@@ -1733,120 +1866,120 @@ strategy.
</tr>
<tr>
<td ALIGN="left"><code>&#8209;ORBMaxFragments</code> <em>limit</em></td>
- <td ALIGN="left">This is a client-side option used to limit the maximum number of
- fragments that a client can break the outgoing message up into. The limit must
- be a positive number or zero (indicating an unlimited number). The default is
- normally <em>0 (i.e. unlimited)</em>, but this default can be overriden when
- the TAO libraries are built in <code>ace/config.h</code>, by specifying the
+ <td ALIGN="left">This is a client-side option used to limit the maximum number of
+ fragments that a client can break the outgoing message up into. The limit must
+ be a positive number or zero (indicating an unlimited number). The default is
+ normally <em>0 (i.e. unlimited)</em>, but this default can be overriden when
+ the TAO libraries are built in <code>ace/config.h</code>, by specifying the
new default limit such as <code>#define&nbsp;TAO_DEFAULT_MIOP_MAX_FRAGMENTS&nbsp;1</code>
- which in this case would turn off fragmentation by default (as only a single
- fragment would be allowed), unless a new limit is specified in the service
- file. Any messages that are too large and require more fragments than allowed
- by this setting are simply not transmitted by the client (the message is
- effectly lost without any error indication, other than possibly a debug
- message). This setting can be used as a safety setting to stop swamping the
- network and servants with abnormally large messages, or during testing to
+ which in this case would turn off fragmentation by default (as only a single
+ fragment would be allowed), unless a new limit is specified in the service
+ file. Any messages that are too large and require more fragments than allowed
+ by this setting are simply not transmitted by the client (the message is
+ effectly lost without any error indication, other than possibly a debug
+ message). This setting can be used as a safety setting to stop swamping the
+ network and servants with abnormally large messages, or during testing to
"lose" large messages for whatever reason.
</td>
</tr>
<tr>
<td ALIGN="left"><code>&#8209;ORBMaxFragmentSize</code> <em>bytes</em></td>
- <td ALIGN="left">Another client-side option used to limit the number of bytes in
+ <td ALIGN="left">Another client-side option used to limit the number of bytes in
each individual MIOP fragment, which must be between <em>272</em> and <em><code>ACE_MAX_UDP_PACKET_SIZE</code>
- (normally 65507)</em> bytes inclusive. Smaller values increase (and larger
- values decrease) the number of fragments required to send the actual payload
- data. Each fragment requires the overhead of a new MIOP header (32 bytes)
- prefixing the actual data being sent, with the header reducing the actual
- usable payload data inside each fragment. Roughly this value can be considered
- as the MTU (Maximum Transmission Unit) set for the specific connection. The
- default takes the same value as the <code>ACE_MAX_UDP_PACKET_SIZE</code> for
- the system, but this can be overridden in <code>ace/config.h</code> by
+ (normally 65507)</em> bytes inclusive. Smaller values increase (and larger
+ values decrease) the number of fragments required to send the actual payload
+ data. Each fragment requires the overhead of a new MIOP header (32 bytes)
+ prefixing the actual data being sent, with the header reducing the actual
+ usable payload data inside each fragment. Roughly this value can be considered
+ as the MTU (Maximum Transmission Unit) set for the specific connection. The
+ default takes the same value as the <code>ACE_MAX_UDP_PACKET_SIZE</code> for
+ the system, but this can be overridden in the <code>ace/config.h</code> by
giving a new value for <code>#define&nbsp;TAO_DEFAULT_MIOP_FRAGMENT_SIZE&nbsp;65507</code>
- when the TAO libraries are built. <b>Note: most gateways and routing networks
- define an MTU of around <em>1458-1500</em>; it is therefore advisable to
- specify the correct <code>&#8209;ORBMaxFragmentSize</code> value otherwise some
- fragments may be lost.</b> See also the <code>&#8209;ORBSndSock</code> option
- below. Note also if this value is changed (during development) and the <code>&#8209;ORBSendThrottling</code> option
- (see below) is enabled, you should change any specified <code>&#8209;ORBMaxFragmentRate</code>
- value (see below) by the same factor, otherwise the speed of transmission will
- be effected, as these two options specify a working ratio.
+ when the TAO libraries are built. <b>Note: most gateways and routing networks
+ define an MTU of around <em>1458-1500</em>; it is therefore advisable to
+ specify the correct <code>&#8209;ORBMaxFragmentSize</code> value otherwise some
+ fragments may be lost.</b> See also the <code>&#8209;ORBSndSock</code> option
+ below. Note also if this value is changed (during development) and the <code>&#8209;ORBMaxFragmentRate</code>
+ option below is also specified, you should change that value by the same
+ factor, otherwise the speed of transmission will be effected as these two
+ options specify a working ratio.
</td>
</tr>
<tr>
<td ALIGN="left"><code>&#8209;ORBMaxFragmentRate</code> <em>microseconds</em></td>
<td ALIGN="left">
- <P>This client-side option (if enabled, see <code>&#8209;ORBSendThrottling</code>
- below) specifies a non-zero, positive amount of time (in uSec, i.e.
- microseconds) that it takes to transmit and process an individual message
- fragment of the maximum size; see the <code>&#8209;ORBMaxFragmentSize</code> option
- above. (This is the total of the client&#8209;&gt;server&#8209;&gt;servant
- processing time, not just the average network transmission delay). The client
- attempts to keep the rate at which it sends messages down to this speed by
- purposely delaying sending message fragments, if it would exceed this
- capacity (but also see the <code>&#8209;ORBSendHighWaterMark</code> option
- below). The default is the same value as specified, or is defaulted by the <code>&#8209;ORBMaxFragmentSize</code>
- option above, but this time teated as microseconds not bytes. (This default
- delay value is approximately the time required to transmit that number of bytes
- on a 10Base&#8209;T network.) Larger values will throttle back the clients
- transmission rate, smaller values will speed it up; but note this value is used
- with the <code>&#8209;ORBMaxFragmentSize</code> option
- above&nbsp;to&nbsp;specify a working ratio&nbsp;so this value may need to be
- altered if the size is changed.
+ <P>This client-side option (if enabled, see <code>&#8209;ORBSendThrottling</code> below)
+ specifies a non-zero, positive amount of time (in
+ uSec, i.e. microseconds) that it takes to transmit and process an individual
+ message fragment of the maximum size; see the <code>&#8209;ORBMaxFragmentSize</code>
+ option above. (This is the total of the
+ client&#8209;&gt;server&#8209;&gt;servant processing time not just the average
+ network transmission delay.) The client attempts to keep the rate at which it
+ sends messages down to this speed by purposly delaying sending message
+ fragments, if it would exceeding this capacity (but also see the <code>&#8209;ORBSendHighWaterMark</code>
+ option below). The default is same value as specified, or is defaulted by, the <code>
+ &#8209;ORBMaxFragmentSize</code> option above, but this time teated as
+ microseconds not bytes. (This default delay value is approximatly the time
+ required to transmit that number of bytes on a 10Base&#8209;T network.) Larger
+ values will throttle back the clients transmittion rate, smaller values will
+ speed it up; but note this value is used with the <code>&#8209;ORBMaxFragmentSize</code>
+ option above&nbsp;to&nbsp;specify a working ratio&nbsp;so this value may need
+ to be altered if the size is changed.
</P>
</td>
</tr>
<tr>
<td ALIGN="left"><code>&#8209;ORBSendHighWaterMark</code> <em>bytes</em></td>
- <td ALIGN="left">This client-side option (if enabled, see <code>&#8209;ORBSendThrottling</code>
- below) is the usable size of the message buffer, i.e. how much data can be sent
- without introducing delays into the transmission of individual MIOP fragments
- (due to the <code>&#8209;ORBMaxFragmentRate</code> option above). Its default
- value is the size of the buffer maintained by the Operating System for the
- sending socket at the client side (see the <code>&#8209;ORBSndSock</code> option
- below) as although it should ideally be based on the server's receive socket
- buffer size, that information is not available to the client, and the two
- values normally default to the same size anyway.</B> If in doubt specify this
- value and&nbsp;set it to a smaller value than the full size of the servers <CODE>&#8209;ORBRcvSock</CODE>
- option&nbsp;(especially if multiple clients are all broadcasting to the same
- server, when each client should only use a fraction of the full buffer size
- based upon the number of clients actually in use).
+ <td ALIGN="left">This client-side option (if enabled, see <code>&#8209;ORBSendThrottling</code> below)
+ is the usable size of the message
+ buffer, i.e how much data can be sent without introducing delays into the
+ transmition of individual MIOP fragments (due to the <code>&#8209;ORBMaxFragmentRate</code>
+ option above). <b>Its default value is the size of the buffer maintained by the
+ Operating System for the sending socket at the client side (see the <code>&#8209;ORBSndSock</code>
+ option below) and although it should ideally be based on the server's receive
+ socket buffer size, that information is not available to the client, and the
+ two values normally default to the same size anyway.</b> If in doubt specify
+ this value and&nbsp;set it to a smaller value than the full size of the servers <CODE>
+ &#8209;ORBRcvSock</CODE> option&nbsp;(especially if multiple clients are all
+ broadcasting to the same server, when each client should only use a fraction of
+ the full buffer size based upon the number of clients actually in use).
</td>
</tr>
<tr>
<td ALIGN="left"><code>&#8209;ORBSendThrottling</code> <em>0 | 1</em></td>
- <td ALIGN="left">This is a client-side option that is enabled by default;
- although this default can be overriden when the TAO libraries are built in <CODE>
+ <td ALIGN="left">This is a client-side option that is enabled by default;
+ although this default can be overriden when the TAO libraries are built in the <CODE>
ace/config.h</CODE>, by specifying the new default such as <CODE>#define&nbsp;TAO_DEFAULT_MIOP_SEND_THROTTLING&nbsp;false</CODE>
- which in this case would turn off throttling by default, unless specified in
- the service file. If disabled (0) the client will always attempt to transmit
- all MIOP message fragments without any delay. If enabled (1) the client will
- attempt to automatically restrict the speed of sending individual MIOP messages
+ which in this case would turn off throttling by default, unless specified in
+ the service file. If disabled (0) the client will always attempt to transmit
+ all MIOP message fragments without any delay. If enabled (1) the client will
+ attempt to automatically restrict the speed of sending individual MIOP messages
to maintain an average of <code>&#8209;ORBMaxFragmentSize</code> bytes per <code>&#8209;ORBMaxFragmentRate</code>
- microseconds once the threshold of <code>&#8209;ORBSendHighWaterMark</code> bytes
+ microseconds once the threshold of <code>&#8209;ORBSendHighWaterMark</code> bytes
of data are currently being transmitted or are in progress via each individual transport
(i.e. each individual client-side connection to the server).
</td>
</tr>
<tr>
<td ALIGN="left"><code>&#8209;ORBSndSock</code> <em>bytes</em></td>
- <td ALIGN="left">This client-side option is the size of the outgoing socket's
- message buffer. If specified in the service configuration file, this value will
- override (for MIOP only) the value specified by the corresponding ORB_init
- parameter. If NOT specified in either place, the default value for the system
- itself will be used. NOTE: the <code>&#8209;ORBSndSock</code> size normally
- limits the maximum size of an individual message fragment, larger fragments can
- be simply ignored (i.e. packet loss) by the client's socket without any error
- indication; this value and the <code>&#8209;ORBMaxFragmentSize</code> should be
- set with care. For a Linux type OS, the system's SndSock is usually defaulted to
- about <b>65535</b> bytes, but whatever value is actually specified it is
- normally doubled internally to take account of the control structures required
+ <td ALIGN="left">This client-side option is the size of the outgoing socket's
+ message buffer. If specified in the service configuration file, this value will
+ override (for MIOP only) the value specified by the corresponding ORB_init
+ parameter. If NOT specified in either place, the default value for the system
+ itself will be used. NOTE: the <code>&#8209;ORBSndSock</code> size normally
+ limits the maximum size of an individual message fragment, larger fragments can
+ be simply ignored (i.e. packet loss) by the client's socket without any error
+ indication; this value and the <code>&#8209;ORBMaxFragmentSize</code> should be
+ set with care. For a Linux type OS, the system's SndSock is usually defaulted to
+ about <b>65535</b> bytes, but whatever value is actually specified it is
+ normally doubled internally to take account of the control structures required
to track the messages themselves and so it is not a hard limit.
</td>
</tr>
<tr>
<td ALIGN="left"><code>&#8209;ORBRcvSock</code> <em>bytes</em></td>
<td ALIGN="left">This server-side option is the size of the incoming socket's
- message buffer, i.e. how much data can be received directly off the wire by the
+ message buffer, i.e., how much data can be received directly off the wire by the
server and queued for processing by the servant whilst it is busy. If specified
in the service configuration file, this value will override (for MIOP only) the
value specified by the corresponding ORB_init parameter. If NOT specified in
@@ -1863,8 +1996,8 @@ strategy.
</tr>
<tr>
<td ALIGN="left"><code>&#8209;ORBEagerDequeueing</code> <em>0 | 1</em></td>
- <td ALIGN="left">This is a server-side option that is enabled by default,
- although this default can be overriden when the TAO libraries are built in <CODE>
+ <td ALIGN="left">This is a server-side option that is enabled by default;
+ although this default can be overriden when the TAO libraries are built in the <CODE>
ace/config.h</CODE>, by specifying the new default such as <CODE>#define&nbsp;TAO_DEFAULT_MIOP_EAGER_DEQUEUEING&nbsp;false</CODE>
which in this case would turn this off by default, unless specified in the
service file. If disabled (0) each thread servicing the MIOP listener will only
@@ -1883,26 +2016,26 @@ strategy.
miss due to the OS sockets receive buffer becoming full.
</td>
</tr>
- <tr>
- <td ALIGN="left"><code>&#8209;ORBFragmentsCleanupStrategy</code> <em>DELAY | NUMBER
+ <tr>
+ <td ALIGN="left"><code>&#8209;ORBFragmentsCleanupStrategy</code> <em>DELAY | NUMBER
| MEMORY</em></td>
- <td ALIGN="left">This option is used on the server to specify the incomplete
- fragments cleanup strategy. The default is <em>DELAY</em>, indicating that the
- fragments that cannot be reassembled after a certain delay should be removed
+ <td ALIGN="left">This option is used on the server to specify the incomplete
+ fragments cleanup strategy. The default is <em>DELAY</em>, indicating that the
+ fragments that cannot be reassembled after a certain delay should be removed
from the waiting queue (i.e. considered lost messages). The other options are <em>
- NUMBER</em> and <em>MEMORY</em>, which respectively mean the number of
- messages in the waiting queue will be limited, or the whole memory comsumed by
+ NUMBER</em> and <em>MEMORY</em>, which respectively mean the number of
+ messages in the waiting queue will be limited, or the whole memory comsumed by
the incomplete messages in the waiting queue will be limited.
</td>
</tr>
<tr>
<td ALIGN="left"><code>&#8209;ORBFragmentsCleanupBound</code> <em>limit</em></td>
<td ALIGN="left">This option specifies the numerical limit for the server's <code>&#8209;ORBFragmentsCleanupStrategy</code>
- option. If the strategy is <em>DELAY</em>, the value indicates the delay in
- milliseconds (defaulting to 1000 milliseconds i.e. 1 second). If the strategy
- is <em>NUMBER</em>, the limit indicates the number of non-reassembled messages
- in the queue (defaulting to 5 messages). If the strategy is <em>MEMORY</em>,
- the limit indicates the number of bytes reserved for the whole queue (with the
+ option. If the strategy is <em>DELAY</em>, the value indicates the delay in
+ milliseconds (defaulting to 1000 milliseconds i.e. 1 second). If the strategy
+ is <em>NUMBER</em>, the limit indicates the number of non-reassembled messages
+ in the queue (defaulting to 5 messages). If the strategy is <em>MEMORY</em>,
+ the limit indicates the number of bytes reserved for the whole queue (with the
default being 3000000 bytes).
</td>
</tr>
@@ -1920,7 +2053,7 @@ configurator
<code>svc.conf</code> file (all in one line)</p>
<p><code>static
Time_Policy_Manager "[option]"</code></p>
-<p> would load the option listed within "".
+<p> would load the option listed within "".
An <a href="../tests/Time_Policy/hr_time.conf">example</a>
is available that shows how to specify this option in the <code>svc.conf</code>
file.</p>
@@ -1935,9 +2068,9 @@ file.</p>
</tr>
<tr>
<td><code>-ORBTimePolicyStrategy</code> <em>strategy</em></td>
- <td><p><a name="-ORBTimePolicyStrategy"></a>The <em>strategy</em> argument
+ <td><p><a name="-ORBTimePolicyStrategy"></a>The <em>strategy</em> argument
defines the TIME_POLICY strategy to load. TAO provides two
-standard TIME_POLICY strategies:</p>
+standard TIME_POLICY strategies:</p>
<p><em>OS</em> denotes the system time policy strategy which uses the systems
equivalent of <code>gettimeofday</code> to return a current time value. This is the default for
TAO (unless <code>TAO_USE_HR_TIME_POLICY_STRATEGY</code> has been defined).</p>
@@ -1946,7 +2079,7 @@ equivalent of a <code>MONOTONIC</code> timer source to return a current time val
<code>TAO_USE_HR_TIME_POLICY_STRATEGY</code> has been defined this becomes the default for TAO).</p>
<p>Any other value is assumed to denote the exact name of a dynamically loadable
TIME_POLICY strategy. The <a href="../tests/Time_Policy_Custom">Time_Policy_Custom</a>
-test provides an example of this functionality.</p>
+test provides an example of this functionality.</p>
</td>
</tr>
</tbody>
diff --git a/TAO/orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp b/TAO/orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp
new file mode 100644
index 00000000000..9ab6842d1a6
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Config_Backing_Store.cpp
@@ -0,0 +1,315 @@
+// $Id$
+
+#include "Config_Backing_Store.h"
+#include "Server_Info.h"
+#include "Activator_Info.h"
+#include "utils.h"
+#include "ace/OS_NS_unistd.h"
+
+static const ACE_TCHAR* STARTUP_COMMAND = ACE_TEXT("StartupCommand");
+static const ACE_TCHAR* WORKING_DIR = ACE_TEXT("WorkingDir");
+static const ACE_TCHAR* ENVIRONMENT = ACE_TEXT("Environment");
+static const ACE_TCHAR* ACTIVATION = ACE_TEXT("Activation");
+static const ACE_TCHAR* PARTIAL_IOR = ACE_TEXT("Location");
+static const ACE_TCHAR* IOR = ACE_TEXT("IOR");
+static const ACE_TCHAR* START_LIMIT = ACE_TEXT("StartLimit");
+static const ACE_TCHAR* ACTIVATOR = ACE_TEXT("Activator");
+static const ACE_TCHAR* SERVERS_ROOT_KEY = ACE_TEXT("Servers");
+static const ACE_TCHAR* ACTIVATORS_ROOT_KEY = ACE_TEXT("Activators");
+static const ACE_TCHAR* TOKEN = ACE_TEXT("Token");
+static const ACE_TCHAR* SERVER_ID = ACE_TEXT("ServerId");
+static const ACE_TCHAR* JACORB_SERVER = ACE_TEXT("JacORBServer");
+
+#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
+static const char* WIN32_REG_KEY = "Software\\TAO\\ImplementationRepository";
+#endif
+
+Config_Backing_Store::Config_Backing_Store (const Options& opts,
+ CORBA::ORB_ptr orb,
+ ACE_Configuration& config)
+: Locator_Repository (opts, orb),
+ config_ (config),
+ status_ (-1)
+{
+}
+
+Config_Backing_Store::~Config_Backing_Store ()
+{
+}
+
+void Config_Backing_Store::loadActivators ()
+{
+ ACE_Configuration_Section_Key root;
+ int err =
+ config_.open_section (config_.root_section (), ACTIVATORS_ROOT_KEY, 0, root);
+ if (err == 0)
+ {
+ int index = 0;
+ ACE_TString name;
+ while (config_.enumerate_sections (root, index, name) == 0)
+ {
+ ACE_CString ior;
+ u_int token;
+
+ ACE_Configuration_Section_Key key;
+
+ // Can't fail, because we're enumerating
+ config_.open_section (root, name.c_str(), 0, key);
+
+ config_.get_string_value (key, IOR, ior);
+ config_.get_integer_value (key, TOKEN, token);
+
+ Activator_Info* ai;
+ ACE_NEW (ai, Activator_Info (name, token, ior));
+
+ Activator_Info_Ptr info (ai);
+ activators ().bind (lcase (name), info);
+ ++index;
+ }
+ }
+}
+
+void
+Config_Backing_Store::loadServers ()
+{
+ ACE_Configuration_Section_Key root;
+ int err =
+ config_.open_section (config_.root_section (), SERVERS_ROOT_KEY, 0, root);
+ if (err == 0)
+ {
+ int index = 0;
+ ACE_TString name;
+ while (config_.enumerate_sections (root, index, name) == 0)
+ {
+ ACE_CString server_id, cmdline, dir, envstr, partial_ior, ior, aname, jacorbstr;
+ u_int amodeint = ImplementationRepository::MANUAL;
+ u_int start_limit;
+
+ ACE_Configuration_Section_Key key;
+
+ // Can't fail, because we're enumerating
+ config_.open_section (root, name.c_str(), 0, key);
+
+ // Ignore any missing values. Server name is enough on its own.
+ config_.get_string_value (key, SERVER_ID, server_id);
+ config_.get_string_value (key, JACORB_SERVER, jacorbstr);
+ config_.get_string_value (key, ACTIVATOR, aname);
+ config_.get_string_value (key, STARTUP_COMMAND, cmdline);
+ config_.get_string_value (key, WORKING_DIR, dir);
+ config_.get_string_value (key, ENVIRONMENT, envstr);
+ config_.get_integer_value (key, ACTIVATION, amodeint);
+ config_.get_string_value (key, PARTIAL_IOR, partial_ior);
+ config_.get_string_value (key, IOR, ior);
+ config_.get_integer_value (key, START_LIMIT, start_limit);
+
+ ImplementationRepository::ActivationMode amode =
+ static_cast <ImplementationRepository::ActivationMode> (amodeint);
+
+ ImplementationRepository::EnvironmentList env_vars =
+ ImR_Utils::parseEnvList (envstr);
+
+ bool jacorb_server = jacorbstr == "1" ? true : false;
+
+ Server_Info *si;
+ ACE_NEW (si,
+ Server_Info (server_id, name, jacorb_server, aname,
+ cmdline, env_vars, dir, amode, start_limit,
+ partial_ior, ior));
+ Server_Info_Ptr info (si);
+ servers ().bind (name, info);
+ ++index;
+ }
+ }
+}
+
+int
+Config_Backing_Store::persistent_remove (const ACE_CString& name,
+ bool activator)
+{
+ const ACE_TCHAR* const key =
+ (activator ? ACTIVATORS_ROOT_KEY : SERVERS_ROOT_KEY);
+ return remove (name, key);
+}
+
+int
+Config_Backing_Store::remove (const ACE_CString& name, const ACE_TCHAR* key)
+{
+ ACE_Configuration_Section_Key root;
+ int err = config_.open_section (config_.root_section (), key, 0, root);
+ if (err != 0)
+ {
+ if (this->opts_.debug () > 9)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT ("could not remove %C, already gone!\n"),
+ name.c_str()));
+ }
+ return 0; // Already gone.
+ }
+ return config_.remove_section (root, name.c_str(), 1);
+}
+
+static int get_key (ACE_Configuration& cfg, const ACE_CString& name,
+ const ACE_TCHAR* const sub_section,
+ ACE_Configuration_Section_Key& key)
+{
+ ACE_Configuration_Section_Key root;
+ int err = cfg.open_section (cfg.root_section(), sub_section, 1, root);
+ if (err != 0)
+ {
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("Unable to open config section:%s\n"),
+ sub_section));
+ return err;
+ }
+ err = cfg.open_section (root, name.c_str (), 1, key);
+ if (err != 0)
+ {
+ ACE_ERROR((LM_ERROR, ACE_TEXT ("Unable to open config section:%C\n"),
+ name.c_str ()));
+ }
+ return err;
+}
+
+int
+Config_Backing_Store::persistent_update(const Server_Info_Ptr& info, bool )
+{
+ ACE_Configuration_Section_Key key;
+ int err = get_key(this->config_, info->name, SERVERS_ROOT_KEY, key);
+ if (err != 0)
+ {
+ ACE_ERROR((LM_ERROR, ACE_TEXT ("ERROR: could not get key for %C\n"),
+ info->name.c_str ()));
+ return err;
+ }
+
+ if (this->opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT ("updating %C\n"), info->name.c_str()));
+ }
+ ACE_CString envstr = ImR_Utils::envListToString(info->env_vars);
+
+ this->config_.set_string_value (key, SERVER_ID, info->server_id.c_str());
+ this->config_.set_string_value (key, JACORB_SERVER, info->jacorb_server ? "1" : "0");
+ this->config_.set_string_value (key, ACTIVATOR, info->activator.c_str());
+ this->config_.set_string_value (key, STARTUP_COMMAND, info->cmdline.c_str());
+ this->config_.set_string_value (key, WORKING_DIR, info->dir.c_str());
+ this->config_.set_string_value (key, ENVIRONMENT, envstr);
+ this->config_.set_integer_value (key, ACTIVATION, info->activation_mode);
+ this->config_.set_integer_value (key, START_LIMIT, info->start_limit);
+ this->config_.set_string_value (key, PARTIAL_IOR, info->partial_ior.c_str());
+ this->config_.set_string_value (key, IOR, info->ior.c_str());
+
+ return 0;
+}
+
+int
+Config_Backing_Store::persistent_update(const Activator_Info_Ptr& info, bool )
+{
+ ACE_Configuration_Section_Key key;
+ int err = get_key (this->config_, info->name, ACTIVATORS_ROOT_KEY, key);
+ if (err != 0)
+ {
+ ACE_DEBUG((LM_INFO,
+ ACE_TEXT ("ERROR: could not get key for activator %C\n"),
+ info->name.c_str ()));
+ return err;
+ }
+
+ if (this->opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT ("updating activator %C\n"),
+ info->name.c_str ()));
+ }
+ this->config_.set_integer_value (key, TOKEN, info->token);
+ this->config_.set_string_value (key, IOR, info->ior.c_str());
+
+ return 0;
+}
+
+int
+Config_Backing_Store::init_repo (PortableServer::POA_ptr )
+{
+ if (status_ != 0)
+ {
+ if (this->opts_.debug () > 9)
+ {
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("not loading\n")));
+ }
+ return status_;
+ }
+
+ loadActivators();
+ loadServers();
+
+ return 0;
+}
+
+Heap_Backing_Store::Heap_Backing_Store (const Options& opts,
+ CORBA::ORB_ptr orb)
+: Config_Backing_Store (opts, orb, heap_),
+ filename_ (opts.persist_file_name())
+{
+ if (opts.repository_erase ())
+ {
+ if (this->opts_.debug () > 9)
+ {
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("Heap start clean\n")));
+ }
+ ACE_OS::unlink ( this->filename_.c_str() );
+ }
+
+ status_ = heap_.open (this->filename_.c_str());
+}
+
+Heap_Backing_Store::~Heap_Backing_Store ()
+{
+}
+
+const ACE_TCHAR*
+Heap_Backing_Store::repo_mode() const
+{
+ return this->filename_.c_str();
+}
+
+#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
+static HKEY setup_registry (const bool start_clean)
+{
+ if (start_clean)
+ {
+ ACE_Configuration_Win32Registry config ( HKEY_LOCAL_MACHINE );
+ ACE_Configuration_Section_Key root;
+ config.open_section (config.root_section(), "Software\\TAO", 0, root);
+ config.remove_section (root, "ImplementationRepository", 1);
+ }
+
+ return ACE_Configuration_Win32Registry::
+ resolve_key (HKEY_LOCAL_MACHINE, WIN32_REG_KEY);
+}
+#endif
+
+Registry_Backing_Store::Registry_Backing_Store(const Options& opts,
+ CORBA::ORB_ptr orb)
+#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
+: Config_Backing_Store(opts, orb, win32registry_),
+ win32registry_ (setup_registry (opts.repository_erase()))
+#else
+: Config_Backing_Store (opts, orb, invalid_config_)
+#endif
+{
+#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
+ status_ = 0;
+#else
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("Registry persistence is only ")
+ ACE_TEXT ("supported on Windows\n")));
+ status_ = -1;
+#endif
+}
+
+Registry_Backing_Store::~Registry_Backing_Store ()
+{
+}
+
+const ACE_TCHAR*
+Registry_Backing_Store::repo_mode () const
+{
+ return ACE_TEXT("Registry");
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Config_Backing_Store.h b/TAO/orbsvcs/ImplRepo_Service/Config_Backing_Store.h
new file mode 100644
index 00000000000..9044436c20b
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Config_Backing_Store.h
@@ -0,0 +1,125 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+* @file Config_Backing_Store.h
+*
+* $Id$
+*
+* These classes define ACE_Configuration implementations of the backing store.
+*
+* @author Darrell Brunsch <brunsch@cs.wustl.edu>
+* @author Priyanka Gontla <gontla_p@ociweb.com>
+*/
+//=============================================================================
+
+#ifndef CONFIG_BACKING_STORE_H
+#define CONFIG_BACKING_STORE_H
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "Locator_Repository.h"
+
+class ACE_Configuration;
+
+/**
+* @class Config_Backing_Store
+*
+* @brief ACE_Configuration backing store interface containing all ImR persistent
+* information.
+*
+*/
+class Config_Backing_Store : public Locator_Repository
+{
+public:
+ Config_Backing_Store(const Options& opts,
+ CORBA::ORB_ptr orb,
+ ACE_Configuration& config);
+
+ virtual ~Config_Backing_Store();
+
+protected:
+ /// perform config backing store specific initialization
+ /// (loads servers and activators from the backing store)
+ virtual int init_repo(PortableServer::POA_ptr imr_poa);
+
+ /// perform server persistent update
+ virtual int persistent_update(const Server_Info_Ptr& info, bool add);
+
+ /// perform activator persistent update
+ virtual int persistent_update(const Activator_Info_Ptr& info, bool add);
+
+ /// perform persistent remove
+ virtual int persistent_remove(const ACE_CString& name, bool activator);
+
+ /// remove the section with the given name from the key section
+ int remove(const ACE_CString& name, const ACE_TCHAR* key);
+
+ /// the ACE_Configuration backing store
+ ACE_Configuration& config_;
+ /// the status of the config_
+ int status_;
+
+private:
+ /// load all servers
+ void loadServers();
+ /// load all activators
+ void loadActivators();
+};
+
+/**
+* @class Heap_Backing_Store
+*
+* @brief Heap file backing store containing all ImR persistent information.
+*
+*/
+class Heap_Backing_Store : public Config_Backing_Store
+{
+public:
+ Heap_Backing_Store(const Options& opts,
+ CORBA::ORB_ptr orb);
+
+ virtual ~Heap_Backing_Store();
+
+ /// indicate the Heap filename as the persistence mode for the repository
+ virtual const ACE_TCHAR* repo_mode() const;
+
+private:
+ /// the Heap filename
+ const ACE_TString filename_;
+ /// the Heap used for the actual backing store
+ ACE_Configuration_Heap heap_;
+};
+
+/**
+* @class Registry_Backing_Store
+*
+* @brief Win32 registry backing store containing all ImR persistent
+* information.
+*
+*/
+class Registry_Backing_Store : public Config_Backing_Store
+{
+public:
+ Registry_Backing_Store(const Options& opts,
+ CORBA::ORB_ptr orb);
+
+ virtual ~Registry_Backing_Store();
+
+ /// indicate Registry as the persistence mode for the repository
+ virtual const ACE_TCHAR* repo_mode() const;
+
+private:
+#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
+ /// the Win32 registry used for the actual backing store
+ ACE_Configuration_Win32Registry win32registry_;
+#else
+ // invalid config (used to simplify #defines)
+ ACE_Configuration_Heap invalid_config_;
+#endif
+};
+
+
+#endif /* CONFIG_BACKING_STORE_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp b/TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp
index 6820bc9285f..a364a85db5e 100644
--- a/TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp
@@ -56,10 +56,78 @@ INS_Locator::locate (const char* object_key)
}
catch (const ImplementationRepository::NotFound&)
{
+ ACE_CString objkey (object_key);
+
+ // check to see if there are more slashes beyond the first one
+ ssize_t poaidx2 = objkey.rfind ('/');
+ ssize_t poaidx1 = objkey.find ('/');
+ if (poaidx1 <= 0 || poaidx2 <= 0 || poaidx1 == poaidx2)
+ {
+ throw CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_IMPLREPO_MINOR_CODE,
+ 0),
+ CORBA::COMPLETED_NO);
+ }
+
+ // remove the data field beyond the last delimiter
+ // which is assumed to be the object id.
+ ACE_CString key2 = objkey.substring(0, poaidx2);
+ while (poaidx2 > poaidx1)
+ {
+ try
+ {
+ if (imr_locator_.debug () > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR: Try activating server using <%s>.\n"),
+ key2.c_str ()));
+ }
+
+ CORBA::String_var located =
+ this->imr_locator_.activate_server_by_object (key2.c_str ());
+
+ ACE_CString tmp = located.in ();
+ tmp += object_key;
+
+ if (imr_locator_.debug () > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR: Forwarding invocation on <%s> ")
+ ACE_TEXT ("to <%s>\n"), key2.c_str (), tmp.c_str()));
+ }
+
+ return CORBA::string_dup (tmp.c_str ());
+ }
+ catch (const ImplementationRepository::CannotActivate&)
+ {
+ throw CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_IMPLREPO_MINOR_CODE,
+ 0),
+ CORBA::COMPLETED_NO);
+ }
+ catch (const ImplementationRepository::NotFound&)
+ {
+ poaidx2 = key2.rfind ('/');
+ if (poaidx2 > poaidx1)
+ {
+ // continue to try again
+ key2 = key2.substring(0, poaidx2);
+ continue;
+ }
+ else
+ {
+ break;
+ }
+ }
+ } // while()
+
+ // No match is found
throw CORBA::TRANSIENT (
- CORBA::SystemException::_tao_minor_code (
- TAO_IMPLREPO_MINOR_CODE,
- 0),
- CORBA::COMPLETED_NO);
+ CORBA::SystemException::_tao_minor_code (
+ TAO_IMPLREPO_MINOR_CODE,
+ 0),
+ CORBA::COMPLETED_NO);
}
}
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
index 15d28889e53..ad7f91357c7 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
@@ -76,6 +76,13 @@ ImR_Activator_i::register_with_imr (ImplementationRepository::Activator_ptr acti
if (!CORBA::is_nil (locator_.in ()))
{
+ if (this->debug_ > 9)
+ {
+ CORBA::String_var ior = orb_->object_to_string (obj.in ());
+ ACE_DEBUG((LM_DEBUG, "ImR Activator: ImplRepoService ior=<%s>\n",
+ ior.in()));
+ }
+
this->registration_token_ =
locator_->register_activator (name_.c_str (), activator);
@@ -84,6 +91,8 @@ ImR_Activator_i::register_with_imr (ImplementationRepository::Activator_ptr acti
return;
}
+ else if (this->debug_ > 1)
+ ACE_DEBUG((LM_DEBUG, "ImR Activator: ImplRepoService not found\n"));
}
catch (const CORBA::Exception& ex)
{
@@ -278,12 +287,17 @@ ImR_Activator_i::start_server(const char* name,
{
if (debug_ > 1)
ACE_DEBUG((LM_DEBUG, "ImR Activator: Starting server <%s>...\n", name));
+
+ ACE_TString cmdline_tstr(ACE_TEXT_CHAR_TO_TCHAR(cmdline));
+ size_t cmdline_buf_len = cmdline_tstr.length();
if (debug_ > 1)
- ACE_DEBUG((LM_DEBUG, "\tcommand line : <%s>\n\tdirectory : <%s>\n", cmdline, dir));
+ ACE_DEBUG((LM_DEBUG,
+ "\tcommand line : len=%d <%s>\n\tdirectory : <%C>\n",
+ cmdline_buf_len, cmdline_tstr.c_str(), dir) );
ACE_Process_Options proc_opts (
1,
- ACE_Process_Options::DEFAULT_COMMAND_LINE_BUF_LEN,
+ cmdline_buf_len + 1,
this->env_buf_len_, this->max_env_vars_);
proc_opts.command_line (ACE_TEXT_CHAR_TO_TCHAR(cmdline));
proc_opts.working_directory (dir);
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl
index 604081c7c68..c61361b8165 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl
@@ -18,5 +18,54 @@ module ImplementationRepository
/// process that it had started.
void notify_child_death (in string name);
};
+
+ enum UpdateType
+ {
+ repo_add,
+ repo_update,
+ repo_remove
+ };
+
+ typedef long SequenceNum;
+
+ struct ServerUpdate
+ {
+ string name;
+ string server_id;
+ UpdateType type;
+ long repo_id;
+ long repo_type;
+ SequenceNum seq_num;
+ };
+
+ struct ActivatorUpdate
+ {
+ string name;
+ UpdateType type;
+ long repo_id;
+ long repo_type;
+ SequenceNum seq_num;
+ };
+
+ exception InvalidPeer
+ {
+ string reason;
+ };
+
+ interface UpdatePushNotification
+ {
+ /// indicate existing server with name was updated
+ oneway void notify_updated_server(in ServerUpdate server);
+
+ /// indicate existing activator with name was updated
+ //oneway void notify_updated_activator(in ActivatorUpdate activator);
+ oneway void notify_updated_activator(in ActivatorUpdate activator);
+
+ /// register peer as replica and indicate sequence number
+ void register_replica(in UpdatePushNotification peer,
+ inout string ft_imr_ior,
+ out SequenceNum seq_num)
+ raises (InvalidPeer);
+ };
};
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
index b0f1d714109..3946f8bdc11 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
@@ -4,13 +4,13 @@
#include "utils.h"
#include "Iterator.h"
#include "INS_Locator.h"
+#include "Locator_Repository.h"
+#include "Config_Backing_Store.h"
+#include "Shared_Backing_Store.h"
+#include "XML_Backing_Store.h"
#include "orbsvcs/Time_Utilities.h"
-#include "tao/IORTable/IORTable.h"
-#include "tao/PortableServer/PortableServer.h"
-#include "tao/ORB_Core.h"
-#include "tao/default_ports.h"
#include "tao/Messaging/Messaging.h"
#include "tao/AnyTypeCode/Any.h"
@@ -20,7 +20,8 @@
static const int DEFAULT_START_LIMIT = 1;
-static const int PING_RETRY_SCHEDULE[] = {0, 10, 100, 500, 1000, 1000, 1000, 1000, 5000, 5000};
+static const int PING_RETRY_SCHEDULE[] = {0, 10, 100, 500, 1000, 1000, 1000,
+ 1000, 5000, 5000};
static const ACE_Time_Value DEFAULT_SERVER_TIMEOUT (0, 10 * 1000); // 10ms
@@ -107,7 +108,8 @@ ImR_Locator_i::init_with_orb (CORBA::ORB_ptr orb, Options& opts)
ACE_ASSERT (! CORBA::is_nil (this->imr_poa_.in ()));
waiter_svt_.debug (debug_ > 1);
- PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId ("ImR_AsyncStartupWaiter");
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId ("ImR_AsyncStartupWaiter");
this->imr_poa_->activate_object_with_id (id.in (), &waiter_svt_);
obj = this->imr_poa_->id_to_reference (id.in ());
if (startup_timeout_ > ACE_Time_Value::zero)
@@ -120,56 +122,58 @@ ImR_Locator_i::init_with_orb (CORBA::ORB_ptr orb, Options& opts)
this->imr_poa_->activate_object_with_id (id.in (), this);
obj = this->imr_poa_->id_to_reference (id.in ());
- CORBA::String_var ior = this->orb_->object_to_string (obj.in ());
+ ImplementationRepository::Locator_var locator =
+ ImplementationRepository::Locator::_narrow (obj.in ());
+ ACE_ASSERT(! CORBA::is_nil (locator.in ()));
+ const CORBA::String_var ior = this->orb_->object_to_string (obj.in ());
+
+ // create the selected Locator_Repository with backing store
+ switch (opts.repository_mode())
+ {
+ case Options::REPO_REGISTRY:
+ {
+ repository_.reset(new Registry_Backing_Store(opts, orb));
+ break;
+ }
+ case Options::REPO_HEAP_FILE:
+ {
+ repository_.reset(new Heap_Backing_Store(opts, orb));
+ break;
+ }
+ case Options::REPO_XML_FILE:
+ {
+ repository_.reset(new XML_Backing_Store(opts, orb));
+ break;
+ }
+ case Options::REPO_SHARED_FILES:
+ {
+ repository_.reset(new Shared_Backing_Store(opts, orb));
+ break;
+ }
+ case Options::REPO_NONE:
+ {
+ repository_.reset(new No_Backing_Store(opts, orb));
+ break;
+ }
+ default:
+ {
+ bool invalid_rmode_specified = false;
+ ACE_ASSERT (invalid_rmode_specified);
+ ACE_UNUSED_ARG (invalid_rmode_specified);
+ ACE_ERROR_RETURN ((
+ LM_ERROR, ACE_TEXT ("Repository failed to initialize\n")), -1);
+ }
+ }
// Register the ImR for use with INS
obj = orb->resolve_initial_references ("IORTable");
IORTable::Table_var ior_table = IORTable::Table::_narrow (obj.in ());
ACE_ASSERT (! CORBA::is_nil (ior_table.in ()));
- ior_table->bind ("ImplRepoService", ior.in ());
- ior_table->bind ("ImR", ior.in ());
ior_table->set_locator (this->ins_locator_.in ());
- // Set up multicast support (if enabled)
- if (opts.multicast ())
- {
- ACE_Reactor* reactor = orb->orb_core ()->reactor ();
- if (this->setup_multicast (reactor, ior.in ()) != 0)
- return -1;
- }
-
- // Initialize the persistent storage. This will load any values that
+ // initialize the repository. This will load any values that
// may have been persisted before.
- // The init can return 1 if there is no persistent file yet. In
- // that case, we need not do anything for now.
- int init_result =
- this->repository_.init (opts);
- if (init_result == -1)
- {
- ACE_ERROR_RETURN ((LM_ERROR, "Repository failed to initialize\n"), -1);
- }
-
- // Activate the two poa managers
- PortableServer::POAManager_var poaman =
- this->root_poa_->the_POAManager ();
- poaman->activate ();
- poaman = this->imr_poa_->the_POAManager ();
- poaman->activate ();
-
- // We write the ior file last so that the tests can know we are ready.
- if (opts.ior_filename ().length () > 0)
- {
- FILE* fp = ACE_OS::fopen (opts.ior_filename ().c_str (), "w");
- if (fp == 0)
- {
- ACE_ERROR_RETURN ((LM_ERROR,
- "ImR: Could not open file: %s\n", opts.ior_filename ().c_str ()), -1);
- }
- ACE_OS::fprintf (fp, "%s", ior.in ());
- ACE_OS::fclose (fp);
- }
-
- return 0;
+ return this->repository_->init(this->root_poa_, this->imr_poa_, ior);
}
int
@@ -197,20 +201,21 @@ ImR_Locator_i::run (void)
// debug () came out garbled and the read-only string
// caused an ACCESS VIOLATION -- Chad Elliott 10/4/2006
ACE_DEBUG ((LM_DEBUG,
- "Implementation Repository: Running\n"
- "\tPing Interval : %dms\n"
- "\tStartup Timeout : %ds\n"
- "\tPersistence : %s\n"
- "\tMulticast : %C\n",
+ ACE_TEXT ("Implementation Repository: Running\n")
+ ACE_TEXT ("\tPing Interval : %dms\n")
+ ACE_TEXT ("\tStartup Timeout : %ds\n")
+ ACE_TEXT ("\tPersistence : %s\n")
+ ACE_TEXT ("\tMulticast : %C\n"),
ping_interval_.msec (),
startup_timeout_.sec (),
- repository_.repo_mode (),
- ior_multicast_.reactor () != 0 ? "Enabled" : "Disabled"));
+ this->repository_->repo_mode (),
+ (this->repository_->multicast () != 0 ?
+ "Enabled" : "Disabled")));
ACE_DEBUG ((LM_DEBUG,
- "\tDebug : %d\n"
- "\tLocked : %C\n\n",
+ ACE_TEXT ("\tDebug : %d\n")
+ ACE_TEXT ("\tLocked : %C\n\n"),
debug (),
- read_only_ ? "True" : "False"));
+ (read_only_ ? "True" : "False")));
}
this->auto_start_servers ();
@@ -221,16 +226,18 @@ ImR_Locator_i::run (void)
void
ImR_Locator_i::shutdown (CORBA::Boolean activators, CORBA::Boolean servers)
{
- if (servers != 0 && this->repository_.servers ().current_size () > 0)
+ if (servers != 0 && this->repository_->servers ().current_size () > 0)
{
// Note : shutdown is oneway, so we can't throw
- ACE_ERROR ((LM_ERROR, "ImR: Shutdown of all servers not implemented.\n"));
+ ACE_ERROR ((
+ LM_ERROR,
+ ACE_TEXT ("ImR: Shutdown of all servers not implemented.\n")));
}
- if (activators != 0 && this->repository_.activators ().current_size () > 0)
+ if (activators != 0 && this->repository_->activators ().current_size () > 0)
{
ACE_Vector<ImplementationRepository::Activator_var> acts;
Locator_Repository::AIMap::ENTRY* entry = 0;
- Locator_Repository::AIMap::ITERATOR it (this->repository_.activators ());
+ Locator_Repository::AIMap::ITERATOR it (this->repository_->activators ());
for (;it.next (entry) != 0; it.advance ())
{
Activator_Info_Ptr info = entry->int_id_;
@@ -255,13 +262,15 @@ ImR_Locator_i::shutdown (CORBA::Boolean activators, CORBA::Boolean servers)
if (debug_ > 1)
{
ex._tao_print_exception (
- "ImR: shutdown activator");
+ ACE_TEXT ("ImR: shutdown activator"));
}
}
}
if (debug_ > 0 && shutdown_errs > 0)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Some activators could not be shut down.\n"));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Some activators could not be shut down.\n")));
}
}
// Technically, we should wait for all the activators to unregister, but
@@ -281,92 +290,25 @@ ImR_Locator_i::fini (void)
try
{
if (debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Shutting down...\n"));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Shutting down...\n")));
- teardown_multicast ();
+ this->repository_.release();
this->root_poa_->destroy (1, 1);
this->orb_->destroy ();
if (debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Shut down successfully.\n"));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Shut down successfully.\n")));
}
catch (const CORBA::Exception& ex)
{
- ex._tao_print_exception ("ImR_Locator_i::fini");
+ ex._tao_print_exception (ACE_TEXT ("ImR_Locator_i::fini"));
throw;
}
return 0;
}
-void
-ImR_Locator_i::teardown_multicast ()
-{
- ACE_Reactor* r = ior_multicast_.reactor ();
- if (r != 0) {
- r->remove_handler (&ior_multicast_, ACE_Event_Handler::READ_MASK);
- ior_multicast_.reactor (0);
- }
-}
-
-int
-ImR_Locator_i::setup_multicast (ACE_Reactor* reactor, const char* ior)
-{
- ACE_ASSERT (reactor != 0);
- ACE_ASSERT (ior != 0);
-#if defined (ACE_HAS_IP_MULTICAST)
-
- TAO_ORB_Core* core = TAO_ORB_Core_instance ();
- // See if the -ORBMulticastDiscoveryEndpoint option was specified.
- ACE_CString mde (core->orb_params ()->mcast_discovery_endpoint ());
-
- if (mde.length () != 0)
- {
- if (this->ior_multicast_.init (ior,
- mde.c_str (), TAO_SERVICEID_IMPLREPOSERVICE) == -1)
- {
- return -1;
- }
- }
- else
- {
- // Port can be specified as param, env var, or default
- CORBA::UShort port =
- core->orb_params ()->service_port (TAO::MCAST_IMPLREPOSERVICE);
- if (port == 0)
- {
- // Check environment var. for multicast port.
- const char* port_number = ACE_OS::getenv ("ImplRepoServicePort");
-
- if (port_number != 0)
- port = static_cast<CORBA::UShort> (ACE_OS::atoi (port_number));
- }
- if (port == 0)
- port = TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT;
-
- if (this->ior_multicast_.init (ior, port,
- ACE_DEFAULT_MULTICAST_ADDR, TAO_SERVICEID_IMPLREPOSERVICE) == -1)
- {
- return -1;
- }
- }
-
- // Register event handler for the ior multicast.
- if (reactor->register_handler (&this->ior_multicast_,
- ACE_Event_Handler::READ_MASK) == -1)
- {
- if (debug_ >= 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: cannot register Event handler\n"));
- return -1;
- }
-#else /* ACE_HAS_IP_MULTICAST*/
- ACE_UNUSED_ARG (reactor);
- ACE_UNUSED_ARG (ior);
-#endif /* ACE_HAS_IP_MULTICAST*/
- return 0;
-}
-
CORBA::Long
ImR_Locator_i::register_activator (const char* aname,
ImplementationRepository::Activator_ptr activator)
@@ -383,12 +325,13 @@ ImR_Locator_i::register_activator (const char* aname,
CORBA::Long token = ACE_OS::gettimeofday ().msec ();
- int err = this->repository_.add_activator (aname, token, ior.in (), activator);
+ int err = this->repository_->add_activator (aname, token, ior.in (), activator);
ACE_ASSERT (err == 0);
ACE_UNUSED_ARG (err);
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Activator registered for %C.\n", aname));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Activator registered for %C.\n"),
+ aname));
return token;
}
@@ -404,19 +347,27 @@ ImR_Locator_i::unregister_activator (const char* aname,
{
if (info->token != token && this->debug_ > 0)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Ignoring unregister activator:%C. Wrong token.\n", aname));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Ignoring unregister activator:%C. Wrong token.\n"),
+ aname));
return;
}
this->unregister_activator_i (aname);
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Activator %C unregistered.\n", aname));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Activator %C unregistered.\n"),
+ aname));
}
else
{
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Ignoring unregister activator: %C. Unknown activator.\n", aname));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Ignoring unregister activator: %C. ")
+ ACE_TEXT ("Unknown activator.\n"),
+ aname));
}
}
@@ -424,7 +375,7 @@ void
ImR_Locator_i::unregister_activator_i (const char* aname)
{
ACE_ASSERT (aname != 0);
- int err = this->repository_.remove_activator (aname);
+ int err = this->repository_->remove_activator (aname);
ACE_UNUSED_ARG (err);
}
@@ -434,23 +385,19 @@ ImR_Locator_i::notify_child_death (const char* name)
ACE_ASSERT (name != 0);
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Server has died <%C>.\n", name));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Server has died <%C>.\n"), name));
- Server_Info_Ptr info = this->repository_.get_server (name);
+ UpdateableServerInfo info(this->repository_.get(), name);
if (! info.null ())
{
- info->ior = "";
- info->partial_ior = "";
-
- int err = this->repository_.update_server (*info);
- ACE_ASSERT (err == 0);
- ACE_UNUSED_ARG (err);
+ info.edit()->ior = "";
+ info.edit()->partial_ior = "";
}
else
{
if (this->debug_ > 1)
ACE_DEBUG ((LM_DEBUG,
- "ImR: Failed to find server in repository.\n"));
+ ACE_TEXT ("ImR: Failed to find server in repository.\n")));
}
}
@@ -459,7 +406,8 @@ ImR_Locator_i::activate_server (const char* server)
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Manually activating server <%C>\n", server));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Manually activating server <%C>\n"),
+ server));
}
// This is the version called by tao_imr to activate the server, manually
@@ -475,14 +423,24 @@ ImR_Locator_i::activate_server_by_name (const char* name, bool manual_start)
// servers unless manual_start=true
ACE_ASSERT (name != 0);
- Server_Info_Ptr info = this->repository_.get_server (name);
+ ACE_CString serverKey;
+ ACE_CString server_id;
+ bool jacorb_server = false;
+ parse_id(name, server_id, serverKey, jacorb_server);
+ UpdateableServerInfo info(this->repository_.get(), serverKey);
if (info.null ())
{
- ACE_ERROR ((LM_ERROR, "ImR: Cannot find info for server <%C>\n", name));
+ ACE_ERROR ((
+ LM_ERROR,
+ ACE_TEXT ("ImR: Cannot find info for server <%C>\n"),
+ name));
throw ImplementationRepository::NotFound ();
}
- return activate_server_i (*info, manual_start);
+ //MDM
+ info.edit()->start_count = 0;
+
+ return activate_server_i (info, manual_start);
}
char*
@@ -495,15 +453,28 @@ ImR_Locator_i::activate_server_by_object (const char* object_name)
ACE_CString server_name (object_name);
ACE_CString::size_type pos = server_name.find ('/');
if (pos != ACE_CString::npos)
- server_name = server_name.substr (pos + 1);
-
- return activate_server_by_name (server_name.c_str (), false);
+ {
+ try
+ {
+ return activate_server_by_name (object_name, false);
+ }
+ catch (const ImplementationRepository::NotFound&)
+ {
+ server_name = server_name.substr (pos + 1);
+ return activate_server_by_name (server_name.c_str (), false);
+ }
+ }
+ else
+ {
+ return activate_server_by_name (server_name.c_str (), false);
+ }
}
char*
-ImR_Locator_i::activate_server_i (Server_Info& info, bool manual_start)
+ImR_Locator_i::activate_server_i (UpdateableServerInfo& info,
+ bool manual_start)
{
- if (info.activation_mode == ImplementationRepository::PER_CLIENT)
+ if (info->activation_mode == ImplementationRepository::PER_CLIENT)
{
return activate_perclient_server_i (info, manual_start);
}
@@ -514,146 +485,162 @@ ImR_Locator_i::activate_server_i (Server_Info& info, bool manual_start)
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Successfully activated <%C> at \n\t%C\n",
- info.name.c_str (), info.partial_ior.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Successfully activated <%C> at \n\t%C\n"),
+ info->name.c_str (), info->partial_ior.c_str ()));
}
- info.start_count = 0;
+ info.edit ()->start_count = 0;
- waiter_svt_.unblock_all (info.name.c_str ());
+ waiter_svt_.unblock_all (info->name.c_str ());
- return CORBA::string_dup (info.partial_ior.c_str ());
+ return CORBA::string_dup (info->partial_ior.c_str ());
}
- info.reset ();
+ info.edit()->reset ();
- if (! info.starting && info.start_count >= info.start_limit)
+ if (! info->starting && info->start_count >= info->start_limit)
{
if (this->debug_ > 0)
{
ACE_DEBUG ((LM_DEBUG,
- "ImR: Cannot Activate <%C>.\n", info.name.c_str ()));
+ ACE_TEXT ("ImR: Cannot Activate <%C>.\n"),
+ info->name.c_str ()));
}
- waiter_svt_.unblock_all (info.name.c_str ());
+ waiter_svt_.unblock_all (info->name.c_str ());
throw ImplementationRepository::CannotActivate(
- CORBA::string_dup (
- "Cannot start server."));
+ "Cannot start server.");
}
// Note: We already updated info with StartupInfo in server_is_running ()
ImplementationRepository::StartupInfo_var si =
- start_server (info, manual_start, info.waiting_clients);
+ start_server (info, manual_start, info.edit()->waiting_clients);
}
}
char*
-ImR_Locator_i::activate_perclient_server_i (Server_Info info, bool manual_start)
+ImR_Locator_i::activate_perclient_server_i (UpdateableServerInfo& shared_info,
+ bool manual_start)
{
- Server_Info_Ptr shared_info = this->repository_.get_server (info.name);
+ // create a copy of shared_info that can be edited without affecting memory
+ // in the repository
+ UpdateableServerInfo info (*shared_info);
do
{
ImplementationRepository::StartupInfo* psi =
- start_server (info, manual_start, shared_info->waiting_clients);
+ start_server (info, manual_start, shared_info.edit()->waiting_clients);
+ // waiting_clients will be updated by each call to start_server
+ shared_info.update_repo ();
if (psi != 0)
{
ImplementationRepository::StartupInfo_var si = psi;
- ACE_ASSERT (info.name == si->name.in ());
- info.partial_ior = si->partial_ior.in ();
- info.ior = si->ior.in ();
+ ACE_ASSERT (info->name == si->name.in ());
+ info.edit ()->partial_ior = si->partial_ior.in ();
+ info.edit ()->ior = si->ior.in ();
if (is_alive (info))
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Successfully activated <%C> at \n\t%C\n",
- info.name.c_str (), info.partial_ior.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Successfully activated <%C> at \n\t%C\n"),
+ info->name.c_str (), info->partial_ior.c_str ()));
}
- return CORBA::string_dup (info.partial_ior.c_str ());
+ return CORBA::string_dup (info->partial_ior.c_str ());
}
- info.reset ();
+ info.edit()->reset ();
}
- } while (info.start_count < info.start_limit);
+ } while (info->start_count < info->start_limit);
if (this->debug_ > 0)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: Cannot Activate <%C>.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Cannot Activate <%C>.\n"),
+ info->name.c_str ()));
}
- throw ImplementationRepository::CannotActivate(
- CORBA::string_dup (
- "Cannot start server."));
+ throw ImplementationRepository::CannotActivate("Cannot start server.");
}
ImplementationRepository::StartupInfo*
-ImR_Locator_i::start_server (Server_Info& info, bool manual_start,
+ImR_Locator_i::start_server (UpdateableServerInfo& info, bool manual_start,
int& waiting_clients)
{
- if (info.activation_mode == ImplementationRepository::MANUAL && ! manual_start)
+ if (info->activation_mode == ImplementationRepository::MANUAL && ! manual_start)
{
if (debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Cannot start server <%C>. ActivationMode=MANUAL\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Cannot start server <%C>. ActivationMode=MANUAL\n"),
+ info->name.c_str ()));
+
throw ImplementationRepository::CannotActivate(
- CORBA::string_dup (
- "Cannot implicitly activate MANUAL server."));
+ "Cannot implicitly activate MANUAL server.");
}
- if (info.cmdline.length () == 0)
+ if (info->cmdline.length () == 0)
{
if (debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Cannot start server <%C>."
- " No command line.\n", info.name.c_str ()));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Cannot start server <%C>.")
+ ACE_TEXT (" No command line.\n"), info->name.c_str ()));
throw ImplementationRepository::CannotActivate(
- CORBA::string_dup (
- "No command line registered for server."));
+ "No command line registered for server.");
}
- Activator_Info_Ptr ainfo = get_activator (info.activator);
+ Activator_Info_Ptr ainfo = get_activator (info->activator);
if (ainfo.null () || CORBA::is_nil (ainfo->activator.in ()))
{
if (debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Cannot start server <%C>. "
- "Activator <%C> not found.\n", info.name.c_str (), info.activator.c_str ()));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Cannot start server <%C>. ")
+ ACE_TEXT ("Activator <%C> not found.\n"),
+ info->name.c_str (), info->activator.c_str ()));
throw ImplementationRepository::CannotActivate(
- CORBA::string_dup (
- "No activator registered for server."));
+ "No activator registered for server.");
}
+ ImplementationRepository::StartupInfo_var si;
try
{
++waiting_clients;
if (waiting_clients <= 1 ||
- info.activation_mode == ImplementationRepository::PER_CLIENT)
+ info->activation_mode == ImplementationRepository::PER_CLIENT)
{
- info.starting = true;
- ++info.start_count;
- ACE_ASSERT (info.start_count <= info.start_limit);
+ info.edit()->starting = true;
+ ++(info.edit()->start_count);
+ ACE_ASSERT (info->start_count <= info->start_limit);
if (this->debug_ > 0)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Starting server <%C>. Attempt %d/%d.\n",
- info.name.c_str (), info.start_count, info.start_limit));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Starting server <%C>. Attempt %d/%d.\n"),
+ info->name.c_str (), info->start_count, info->start_limit));
}
ainfo->activator->start_server (
- info.name.c_str (),
- info.cmdline.c_str (),
- info.dir.c_str (),
- info.env_vars);
+ info->name.c_str (),
+ info->cmdline.c_str (),
+ info->dir.c_str (),
+ info->env_vars);
}
- if (info.partial_ior.length () == 0)
+ if (info->partial_ior.length () == 0)
{
if (this->debug_ > 0)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Waiting for <%C> to start...\n", info.name.c_str ()));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR: Waiting for <%C> to start...\n"),
+ info->name.c_str ()));
}
ImplementationRepository::StartupInfo_var si =
- waiter_->wait_for_startup (info.name.c_str ());
+ waiter_->wait_for_startup (info->name.c_str ());
--waiting_clients;
- info.starting = false;
+ info.edit()->starting = false;
return si._retn ();
}
@@ -661,43 +648,53 @@ ImR_Locator_i::start_server (Server_Info& info, bool manual_start,
{
if (this->debug_ > 0)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: <%C> Skipping wait. Already started.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Skipping wait. Already started.\n"),
+ info->name.c_str ()));
}
--waiting_clients;
- info.starting = false;
+ info.edit()->starting = false;
}
}
catch (const CORBA::TIMEOUT&)
{
--waiting_clients;
- info.starting = false;
+ info.edit()->starting = false;
// We may have connected successfully, because the timeout could occur before
// the AsyncStartupWaiter manages to return. In fact, when the ImR is very busy
// this is the most likely code path.
- if (info.partial_ior.length () == 0)
+ if (info->partial_ior.length () == 0)
{
if (debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR : Timeout waiting for <%C> to start.\n", info.name.c_str ()));
- info.reset ();
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR : Timeout waiting for <%C> to start.\n"),
+ info->name.c_str ()));
+ info.edit()->reset ();
}
}
catch (const ImplementationRepository::CannotActivate&)
{
--waiting_clients;
- info.starting = false;
- info.reset ();
+ info.edit()->starting = false;
+ info.edit()->reset ();
if (debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Activator cannot start <%C>.\n", info.name.c_str ()));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR: Activator cannot start <%C>.\n"),
+ info->name.c_str ()));
}
catch (const CORBA::Exception& ex)
{
--waiting_clients;
- info.starting = false;
+ info.edit()->starting = false;
if (debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Unexpected exception while starting <%C>.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Unexpected exception while starting <%C>.\n"),
+ info->name.c_str ()));
if (debug_ > 1)
ex._tao_print_exception ("");
- info.reset ();
+ info.edit()->reset ();
// Before we reset the activator info, let's see if it's still
// there then let's keep it around for a while.
@@ -737,7 +734,8 @@ ImR_Locator_i::set_timeout_policy (CORBA::Object_ptr obj, const ACE_Time_Value&
CORBA::PolicyList policies (1);
policies.length (1);
- policies[0] = orb_->create_policy (Messaging::RELATIVE_RT_TIMEOUT_POLICY_TYPE, tmp);
+ policies[0] = orb_->create_policy (Messaging::RELATIVE_RT_TIMEOUT_POLICY_TYPE,
+ tmp);
ret = obj->_set_policy_overrides (policies, CORBA::ADD_OVERRIDE);
@@ -747,7 +745,8 @@ ImR_Locator_i::set_timeout_policy (CORBA::Object_ptr obj, const ACE_Time_Value&
{
if (this->debug_ > 0)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Unable to set timeout policy.\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR: Unable to set timeout policy.\n")));
}
ret = CORBA::Object::_duplicate (obj);
}
@@ -755,7 +754,7 @@ ImR_Locator_i::set_timeout_policy (CORBA::Object_ptr obj, const ACE_Time_Value&
catch (const CORBA::Exception& ex)
{
ex._tao_print_exception (
- "ImR_Locator_i::set_timeout_policy ()");
+ ACE_TEXT ("ImR_Locator_i::set_timeout_policy ()"));
}
return ret._retn ();
@@ -770,7 +769,11 @@ ImR_Locator_i::add_or_update_server (
if (this->read_only_)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Cannot add/update server <%C> due to locked database.\n", server));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Cannot add/update server <%C> due to locked ")
+ ACE_TEXT ("database.\n"),
+ server));
throw CORBA::NO_PERMISSION (
CORBA::SystemException::_tao_minor_code (
TAO_IMPLREPO_MINOR_CODE,
@@ -779,7 +782,7 @@ ImR_Locator_i::add_or_update_server (
}
if (debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Add/Update server <%C>.\n", server));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Add/Update server <%C>.\n"), server));
int limit = options.start_limit;
if (limit < 0)
@@ -791,14 +794,19 @@ ImR_Locator_i::add_or_update_server (
limit = 1;
}
- Server_Info_Ptr info = this->repository_.get_server (server);
+ ACE_CString serverKey;
+ ACE_CString server_id;
+ bool jacorb_server = false;
+ parse_id(server, server_id, serverKey, jacorb_server);
+ UpdateableServerInfo info(this->repository_.get(), serverKey);
if (info.null ())
{
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Adding server <%C>.\n", server));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Adding server <%C>.\n"), server));
- this->repository_.add_server ("",
- server,
+ this->repository_->add_server ("",
+ serverKey,
+ jacorb_server,
options.activator.in (),
options.command_line.in (),
options.environment,
@@ -809,30 +817,30 @@ ImR_Locator_i::add_or_update_server (
else
{
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Updating server <%C>.\n", server));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Updating server <%C>.\n"),
+ server));
+
+ info.edit ()->activator = options.activator.in ();
+ info.edit ()->cmdline = options.command_line.in ();
+ info.edit ()->env_vars = options.environment;
+ info.edit ()->dir = options.working_directory.in ();
+ info.edit ()->activation_mode = options.activation;
+ info.edit ()->start_limit = limit;
+ info.edit ()->start_count = 0;
- info->activator = options.activator.in ();
- info->cmdline = options.command_line.in ();
- info->env_vars = options.environment;
- info->dir = options.working_directory.in ();
- info->activation_mode = options.activation;
- info->start_limit = limit;
- info->start_count = 0;
- int err = this->repository_.update_server (*info);
- ACE_ASSERT (err == 0);
- ACE_UNUSED_ARG (err);
+ info.update_repo();
}
if (this->debug_ > 1)
{
// Note : The info var may be null, so we use options.
- ACE_DEBUG ((LM_DEBUG, "ImR: Server: %s\n"
- "\tActivator: %s\n"
- "\tCommand Line: %s\n"
- "\tWorking Directory: %s\n"
- "\tActivation: %s\n"
- "\tStart Limit: %d\n"
- "\n",
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Server: %C\n")
+ ACE_TEXT ("\tActivator: %C\n")
+ ACE_TEXT ("\tCommand Line: %C\n")
+ ACE_TEXT ("\tWorking Directory: %C\n")
+ ACE_TEXT ("\tActivation: %C\n")
+ ACE_TEXT ("\tStart Limit: %d\n")
+ ACE_TEXT ("\n"),
server,
options.activator.in (),
options.command_line.in (),
@@ -842,20 +850,47 @@ ImR_Locator_i::add_or_update_server (
));
for (CORBA::ULong i = 0; i < options.environment.length (); ++i)
- ACE_DEBUG ((LM_DEBUG, "Environment variable %s=%s\n",
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Environment variable %C=%C\n"),
options.environment[i].name.in (),
options.environment[i].value.in ()));
}
}
void
+ImR_Locator_i::parse_id(const char* id,
+ ACE_CString& server_id,
+ ACE_CString& name,
+ bool& jacorb_server)
+{
+ const char *pos = ACE_OS::strchr (id, ':');
+ if (pos)
+ {
+ ACE_CString idstr (id);
+ server_id = idstr.substr (0, pos - id);
+ name = idstr.substr (pos - id + 1);
+ if (server_id == "JACORB")
+ {
+ jacorb_server = true;
+ ssize_t idx = name.find("/");
+ server_id = name.substr(0, idx);
+ }
+ }
+ else
+ {
+ name = id;
+ }
+}
+
+void
ImR_Locator_i::remove_server (const char* name)
{
ACE_ASSERT (name != 0);
if (this->read_only_)
{
- ACE_ERROR ((LM_ERROR,
- "ImR: Can't remove server <%C> due to locked database.\n", name));
+ ACE_ERROR ((
+ LM_ERROR,
+ ACE_TEXT ("ImR: Can't remove server <%C> due to locked database.\n"),
+ name));
throw CORBA::NO_PERMISSION (
CORBA::SystemException::_tao_minor_code (
TAO_IMPLREPO_MINOR_CODE,
@@ -867,15 +902,21 @@ ImR_Locator_i::remove_server (const char* name)
// be valid, and the actual Server_Info will be destroyed when the last
// one goes out of scope.
- Server_Info_Ptr info = this->repository_.get_server (name);
+ ACE_CString serverKey;
+ ACE_CString server_id;
+ bool jacorb_server = false;
+ parse_id(name, server_id, serverKey, jacorb_server);
+ Server_Info_Ptr info = this->repository_->get_server (serverKey);
if (! info.null ())
{
- if (this->repository_.remove_server (name) == 0)
+ if (this->repository_->remove_server (serverKey) == 0)
{
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Removing Server <%C>...\n", name));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR: Removing Server <%C>...\n"),
+ name));
- PortableServer::POA_var poa = findPOA (name);
+ PortableServer::POA_var poa = findPOA (serverKey.c_str());
if (! CORBA::is_nil (poa.in ()))
{
bool etherealize = true;
@@ -883,13 +924,14 @@ ImR_Locator_i::remove_server (const char* name)
poa->destroy (etherealize, wait);
}
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Removed Server <%C>.\n", name));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Removed Server <%C>.\n"),
+ name));
}
}
else
{
ACE_ERROR ((LM_ERROR,
- "ImR: Can't remove unknown server <%s>.\n", name));
+ ACE_TEXT ("ImR: Can't remove unknown server <%C>.\n"), name));
throw ImplementationRepository::NotFound ();
}
}
@@ -914,43 +956,54 @@ ImR_Locator_i::shutdown_server (const char* server)
ACE_ASSERT (server != 0);
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Shutting down server <%C>.\n", server));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Shutting down server <%C>.\n"),
+ server));
+
+ ACE_CString name;
+ ACE_CString server_id;
+ bool jacorb_server = false;
+ parse_id(server, server_id, name, jacorb_server);
- Server_Info_Ptr info = this->repository_.get_server (server);
+ UpdateableServerInfo info(this->repository_.get(), name);
if (info.null ())
{
- ACE_ERROR ((LM_ERROR,
- "ImR: shutdown_server () Cannot find info for server <%C>\n", server));
+ ACE_ERROR ((
+ LM_ERROR,
+ ACE_TEXT ("ImR: shutdown_server () Cannot find info for server <%C>\n"),
+ server));
throw ImplementationRepository::NotFound ();
}
- this->connect_server (*info);
+ this->connect_server (info);
if (CORBA::is_nil (info->server.in ()))
{
- ACE_ERROR ((LM_ERROR,
- "ImR: shutdown_server () Cannot connect to server <%C>\n", server));
+ ACE_ERROR ((
+ LM_ERROR,
+ ACE_TEXT ("ImR: shutdown_server () Cannot connect to server <%C>\n"),
+ server));
throw ImplementationRepository::NotFound ();
}
try
{
- CORBA::Object_var obj = this->set_timeout_policy (info->server.in (), DEFAULT_SHUTDOWN_TIMEOUT);
+ CORBA::Object_var obj = this->set_timeout_policy (info->server.in (),
+ DEFAULT_SHUTDOWN_TIMEOUT);
ImplementationRepository::ServerObject_var server =
ImplementationRepository::ServerObject::_unchecked_narrow (obj.in ());
server->shutdown ();
}
catch (const CORBA::TIMEOUT&)
{
- info->reset ();
- int err = this->repository_.update_server (*info);
- ACE_ASSERT (err == 0);
- ACE_UNUSED_ARG (err);
+ info.edit ()->reset ();
// Note : This is a good thing. It means we didn't waste our time waiting for
// the server to finish shutting down.
if (this->debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Timeout while waiting for <%C> shutdown.\n", server));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Timeout while waiting for <%C> shutdown.\n"),
+ server));
}
throw;
}
@@ -958,17 +1011,16 @@ ImR_Locator_i::shutdown_server (const char* server)
{
if (this->debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: Exception ignored while shutting down <%C>\n", server));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Exception ignored while shutting down <%C>\n"),
+ server));
}
}
// Note : In most cases this has already been done in the server_is_shutting_down ()
// operation, but it doesn't hurt to update it again.
- info->reset ();
-
- int err = this->repository_.update_server (*info);
- ACE_ASSERT (err == 0);
- ACE_UNUSED_ARG (err);
+ info.edit ()->reset ();
}
void
@@ -982,42 +1034,36 @@ ImR_Locator_i::server_is_running (const char* id,
ACE_CString server_id;
ACE_CString name;
-
- const char *pos = ACE_OS::strchr (id, ':');
- if (pos)
- {
- ACE_CString idstr (id);
- server_id = idstr.substr (0, pos - id);
- name = idstr.substr (pos - id + 1);
- }
- else
- {
- name = id;
- }
+ bool jacorb_server = false;
+ parse_id(id, server_id, name, jacorb_server);
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Server %C is running at %C.\n",
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Server %C is running at %C.\n"),
name.c_str (), partial_ior));
CORBA::String_var ior = orb_->object_to_string (server);
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Server %C callback at %C.\n",
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Server %C callback at %C.\n"),
name.c_str (), ior.in ()));
if (this->unregister_if_address_reused_)
- this->repository_.unregister_if_address_reused (server_id, name, partial_ior);
+ this->repository_->unregister_if_address_reused (server_id, name, partial_ior);
- Server_Info_Ptr info = this->repository_.get_server (name);
+ UpdateableServerInfo info(this->repository_.get(), name);
if (info.null ())
{
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Auto adding NORMAL server <%C>.\n", name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Auto adding NORMAL server <%C>.\n"),
+ name.c_str ()));
ImplementationRepository::EnvironmentList env (0);
- this->repository_.add_server (server_id,
+ this->repository_->add_server (server_id,
name,
+ jacorb_server,
"", // no activator
"", // no cmdline
ImplementationRepository::EnvironmentList (),
@@ -1036,19 +1082,18 @@ ImR_Locator_i::server_is_running (const char* id,
if (! info->server_id.empty())
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("ImR - WARNING: server \"%C\" changed server id from ")
- ACE_TEXT ("\"%C\" to \"%C\" waiting PER_CLIENT clients.\n"),
- name.c_str (), info->server_id.c_str (), server_id.c_str ()));
- info->server_id = server_id;
+ ACE_TEXT ("\"%C\" to \"%C\" waiting PER_CLIENT clients.\n"),
+ name.c_str (), info->server_id.c_str (), server_id.c_str ()));
+ info.edit ()->server_id = server_id;
}
if (info->activation_mode != ImplementationRepository::PER_CLIENT) {
- info->ior = ior.in ();
- info->partial_ior = partial_ior;
- info->server = ImplementationRepository::ServerObject::_nil (); // Will connect at first access
+ info.edit ()->ior = ior.in ();
+ info.edit ()->partial_ior = partial_ior;
+ // Will connect at first access
+ info.edit ()->server = ImplementationRepository::ServerObject::_nil ();
- int err = this->repository_.update_server (*info);
- ACE_ASSERT (err == 0);
- ACE_UNUSED_ARG (err);
+ info.update_repo();
waiter_svt_.unblock_one (name.c_str (), partial_ior, ior.in (), false);
} else {
@@ -1072,25 +1117,25 @@ void
ImR_Locator_i::server_is_shutting_down (const char* server)
{
ACE_ASSERT (server != 0);
- Server_Info_Ptr info = this->repository_.get_server (server);
+ UpdateableServerInfo info(this->repository_.get(), server);
if (info.null ())
{
if (this->debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR_Locator_i::server_is_shutting_down: Unknown server:%C\n", server));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR_Locator_i::server_is_shutting_down: ")
+ ACE_TEXT ("Unknown server:%C\n"),
+ server));
}
return;
}
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Server <%C> is shutting down.\n", server));
-
- info->reset ();
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Server <%C> is shutting down.\n"),
+ server));
- int const err = this->repository_.update_server (*info);
- ACE_ASSERT (err == 0);
- ACE_UNUSED_ARG (err);
+ info.edit ()->reset ();
}
void
@@ -1099,42 +1144,49 @@ ImR_Locator_i::find (const char* server,
{
ACE_ASSERT (server != 0);
- Server_Info_Ptr info = this->repository_.get_server (server);
+ ACE_CString serverKey;
+ ACE_CString server_id;
+ bool jacorb_server = false;
+ parse_id(server, server_id, serverKey, jacorb_server);
+ UpdateableServerInfo info(this->repository_.get(), serverKey);
if (! info.null ())
{
imr_info = info->createImRServerInfo ();
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Found server %C.\n", server));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Found server %C.\n"), server));
}
else
{
- ACE_NEW_THROW_EX (imr_info, ImplementationRepository::ServerInformation, CORBA::NO_MEMORY ());
+ ACE_NEW_THROW_EX (imr_info, ImplementationRepository::ServerInformation,
+ CORBA::NO_MEMORY ());
imr_info->startup.activation= ImplementationRepository::NORMAL;
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Cannot find server <%C>\n", server));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: Cannot find server <%C>\n"),
+ server));
}
}
void
ImR_Locator_i::list (CORBA::ULong how_many,
- ImplementationRepository::ServerInformationList_out server_list,
- ImplementationRepository::ServerInformationIterator_out server_iterator)
+ ImplementationRepository::ServerInformationList_out server_list,
+ ImplementationRepository::ServerInformationIterator_out server_iterator)
{
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: List servers.\n"));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ImR: List servers.\n")));
// Initialize the out variables, so if we return early, they will
// not be dangling.
server_iterator = ImplementationRepository::ServerInformationIterator::_nil ();
ACE_NEW_THROW_EX (server_list,
- ImplementationRepository::ServerInformationList (0), CORBA::NO_MEMORY ());
+ ImplementationRepository::ServerInformationList (0),
+ CORBA::NO_MEMORY ());
Locator_Repository::SIMap::ENTRY* entry = 0;
- Locator_Repository::SIMap::ITERATOR it (this->repository_.servers ());
+ Locator_Repository::SIMap::ITERATOR it (this->repository_->servers ());
// Number of servers that will go into the server_list.
- CORBA::ULong n = this->repository_.servers ().current_size ();
+ CORBA::ULong n = this->repository_->servers ().current_size ();
if (how_many > 0 && n > how_many)
{
n = how_many;
@@ -1143,7 +1195,10 @@ ImR_Locator_i::list (CORBA::ULong how_many,
server_list->length (n);
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR_Locator_i::list: Filling ServerList with %d servers\n", n));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR_Locator_i::list: Filling ServerList with %d servers\n"),
+ n));
for (CORBA::ULong i = 0; i < n; i++)
{
@@ -1151,22 +1206,27 @@ ImR_Locator_i::list (CORBA::ULong how_many,
it.advance ();
ACE_ASSERT (entry != 0);
- Server_Info_Ptr info = entry->int_id_;
+ const Server_Info& info = *(entry->int_id_);
- ImplementationRepository::ServerInformation_var imr_info = info->createImRServerInfo ();
+ ImplementationRepository::ServerInformation_var imr_info =
+ info.createImRServerInfo ();
server_list[i] = *imr_info;
}
- if (this->repository_.servers ().current_size () > n)
+ if (this->repository_->servers ().current_size () > n)
{
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR_Locator_i::list: Creating ServerInformation Iterator\n"));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR_Locator_i::list: Creating ServerInformation ")
+ ACE_TEXT ("Iterator\n")));
ImR_Iterator* imr_iter = 0;
- ACE_NEW_THROW_EX (imr_iter,
- ImR_Iterator (n, this->repository_, this->imr_poa_.in ()),
- CORBA::NO_MEMORY ());
+ ACE_NEW_THROW_EX (
+ imr_iter,
+ ImR_Iterator (n, *this->repository_, this->imr_poa_.in ()),
+ CORBA::NO_MEMORY ());
PortableServer::ServantBase_var tmp (imr_iter);
@@ -1188,7 +1248,7 @@ ImR_Locator_i::list (CORBA::ULong how_many,
Activator_Info_Ptr
ImR_Locator_i::get_activator (const ACE_CString& aname)
{
- Activator_Info_Ptr info = this->repository_.get_activator (aname);
+ Activator_Info_Ptr info = this->repository_->get_activator (aname);
if (! info.null ())
{
this->connect_activator (*info);
@@ -1228,7 +1288,10 @@ ImR_Locator_i::connect_activator (Activator_Info& info)
}
if (debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Connected to activator <%C>\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Connected to activator <%C>\n"),
+ info.name.c_str ()));
}
catch (const CORBA::Exception&)
{
@@ -1239,18 +1302,18 @@ ImR_Locator_i::connect_activator (Activator_Info& info)
void
ImR_Locator_i::auto_start_servers (void)
{
- if (this->repository_.servers ().current_size () == 0)
+ if (this->repository_->servers ().current_size () == 0)
return;
Locator_Repository::SIMap::ENTRY* server_entry;
- Locator_Repository::SIMap::ITERATOR server_iter (this->repository_.servers ());
+ Locator_Repository::SIMap::ITERATOR server_iter (this->repository_->servers ());
// For each of the entries in the Locator_Repository, get the startup
// information and activate the servers, if they are not already
// running.
for (;server_iter.next (server_entry) != 0; server_iter.advance ())
{
- Server_Info_Ptr info = server_entry->int_id_;
+ UpdateableServerInfo info(this->repository_.get(), server_entry->int_id_);
ACE_ASSERT (! info.null ());
try
@@ -1259,16 +1322,17 @@ ImR_Locator_i::auto_start_servers (void)
&& info->cmdline.length () > 0)
{
CORBA::String_var cleanup =
- this->activate_server_i (*info, true);
+ this->activate_server_i (info, true);
}
}
catch (const CORBA::Exception& ex)
{
if (this->debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: AUTO_START Could not activate <%C>\n",
- server_entry->ext_id_.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: AUTO_START Could not activate <%C>\n"),
+ server_entry->ext_id_.c_str ()));
ex._tao_print_exception ("AUTO_START");
}
// Ignore exceptions
@@ -1277,51 +1341,53 @@ ImR_Locator_i::auto_start_servers (void)
}
void
-ImR_Locator_i::connect_server (Server_Info& info)
+ImR_Locator_i::connect_server (UpdateableServerInfo& info)
{
- if (! CORBA::is_nil (info.server.in ()))
+ if (! CORBA::is_nil (info->server.in ()))
{
return; // already connected
}
- if (info.ior.length () == 0)
+ if (info->ior.length () == 0)
{
- info.reset ();
+ info.edit ()->reset ();
return; // can't connect
}
try
{
- CORBA::Object_var obj = orb_->string_to_object (info.ior.c_str ());
+ CORBA::Object_var obj = orb_->string_to_object (info->ior.c_str ());
if (CORBA::is_nil (obj.in ()))
{
- info.reset ();
+ info.edit ()->reset ();
return;
}
obj = this->set_timeout_policy (obj.in (), DEFAULT_SERVER_TIMEOUT);
- info.server =
+ info.edit ()->server =
ImplementationRepository::ServerObject::_unchecked_narrow (obj.in ());
- if (CORBA::is_nil (info.server.in ()))
+ if (CORBA::is_nil (info->server.in ()))
{
- info.reset ();
+ info.edit ()->reset ();
return;
}
if (debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Connected to server <%C>\n", info.name.c_str ()));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR: Connected to server <%C>\n"),
+ info->name.c_str ()));
}
catch (const CORBA::Exception&)
{
- info.reset ();
+ info.edit ()->reset ();
}
}
bool
-ImR_Locator_i::is_alive (Server_Info& info)
+ImR_Locator_i::is_alive (UpdateableServerInfo& info)
{
const size_t table_size = sizeof (PING_RETRY_SCHEDULE) /
sizeof (*PING_RETRY_SCHEDULE);
@@ -1356,29 +1422,33 @@ ImR_Locator_i::is_alive (Server_Info& info)
}
if (debug_ > 0)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> Ping retry count exceeded. alive=maybe.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Ping retry count exceeded. alive=maybe.\n"),
+ info->name.c_str ()));
}
- // We return true here, because the server *might* be alive, it's just not starting in a timely
- // manner. We can't return false, because then we'll just try to start another instance, and the
- // same thing will likely happen.
- info.last_ping = ACE_OS::gettimeofday ();
+ // We return true here, because the server *might* be alive, it's just
+ // not starting in a timely manner. We can't return false, because then
+ // we'll just try to start another instance, and the same thing will
+ // likely happen.
+ info.edit ()->last_ping = ACE_OS::gettimeofday ();
return true;
}
int
-ImR_Locator_i::is_alive_i (Server_Info& info)
+ImR_Locator_i::is_alive_i (UpdateableServerInfo& info)
{
// This is used by the ACE_TRY below when exceptions are turned off.
- if (info.ior.length () == 0 || info.partial_ior.length () == 0)
+ if (info->ior.length () == 0 || info->partial_ior.length () == 0)
{
if (debug_ > 1)
{
ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> not running. alive=false.\n", info.name.c_str ()));
+ ACE_TEXT ("ImR: <%C> not running. alive=false.\n"),
+ info->name.c_str ()));
}
- info.last_ping = ACE_Time_Value::zero;
+ info.edit ()->last_ping = ACE_Time_Value::zero;
return 0;
}
@@ -1386,18 +1456,22 @@ ImR_Locator_i::is_alive_i (Server_Info& info)
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> Ping verification disabled. alive=true.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Ping verification disabled. alive=true.\n"),
+ info->name.c_str ()));
}
return 1;
}
- if ((ACE_OS::gettimeofday () - info.last_ping) < ping_interval_)
+ if ((ACE_OS::gettimeofday () - info->last_ping) < ping_interval_)
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> within ping interval. alive=true.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> within ping interval. alive=true.\n"),
+ info->name.c_str ()));
}
return 1;
}
@@ -1405,24 +1479,28 @@ ImR_Locator_i::is_alive_i (Server_Info& info)
// If we don't have enough information to start the server if it isn't already
// then we might as well assume it is running. That way the client can get the
// status directly from the server.
- if (info.cmdline.length () == 0 || ! repository_.has_activator (info.activator))
+ if (info->cmdline.length () == 0 || ! repository_->has_activator (info->activator))
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: Ping verification skipped. <%C> not startable.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: Ping verification skipped. <%C> not startable.\n"),
+ info->name.c_str ()));
}
return 1;
}
this->connect_server (info);
- if (CORBA::is_nil (info.server.in ()))
+ if (CORBA::is_nil (info->server.in ()))
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> Could not connect. alive=false.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Could not connect. alive=false.\n"),
+ info->name.c_str ()));
}
return 0;
}
@@ -1430,17 +1508,19 @@ ImR_Locator_i::is_alive_i (Server_Info& info)
try
{
// Make a copy, in case the info is updated during the ping.
- ImplementationRepository::ServerObject_var server = info.server;
+ ImplementationRepository::ServerObject_var server = info->server;
// This will timeout if it takes too long
server->ping ();
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> Ping successful. alive=true\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Ping successful. alive=true\n"),
+ info->name.c_str ()));
}
- info.last_ping = ACE_OS::gettimeofday ();
+ info.edit ()->last_ping = ACE_OS::gettimeofday ();
}
catch (const CORBA::TRANSIENT& ex)
{
@@ -1451,19 +1531,23 @@ ImR_Locator_i::is_alive_i (Server_Info& info)
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> Local TRANSIENT. alive=false.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Local TRANSIENT. alive=false.\n"),
+ info->name.c_str ()));
}
}
- info.last_ping = ACE_Time_Value::zero;
+ info.edit ()->last_ping = ACE_Time_Value::zero;
return 0;
case TAO_POA_DISCARDING:
case TAO_POA_HOLDING:
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> Remote TRANSIENT. alive=maybe.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Remote TRANSIENT. alive=maybe.\n"),
+ info->name.c_str ()));
}
}
return -1; // We keep trying to ping, because returning 1 now, would just lead
@@ -1473,10 +1557,12 @@ ImR_Locator_i::is_alive_i (Server_Info& info)
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> TRANSIENT exception. alive=false.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> TRANSIENT exception. alive=false.\n"),
+ info->name.c_str ()));
}
- info.last_ping = ACE_Time_Value::zero;
+ info.edit ()->last_ping = ACE_Time_Value::zero;
}
return 0;
}
@@ -1487,18 +1573,26 @@ ImR_Locator_i::is_alive_i (Server_Info& info)
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> Ping timed out during connection. alive=false.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Ping timed out during connection. ")
+ ACE_TEXT ("alive=false.\n"),
+ info->name.c_str ()));
}
- info.last_ping = ACE_Time_Value::zero;
- return 0; // still potentially ambiguous, the server could be so busy it couldn't
- // even accept a connection. However the more likely assumption is the server is on
- // windows, and is dead, but the host ignored the request rather than rejecting it.
+ info.edit ()->last_ping = ACE_Time_Value::zero;
+ // still potentially ambiguous, the server could be so busy
+ // it couldn't even accept a connection. However the more
+ // likely assumption is the server is on windows, and is dead,
+ // but the host ignored the request rather than rejecting it.
+ return 0;
}
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG,
- "ImR: <%C> Ping timed out, maybe completed. alive=true.\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Ping timed out, maybe completed. ")
+ ACE_TEXT ("alive=true.\n"),
+ info->name.c_str ()));
}
return 1; // This is "alive" as far as we're concerned. Presumably the client
// will have a less stringent timeout policy, or will want to know
@@ -1509,10 +1603,13 @@ ImR_Locator_i::is_alive_i (Server_Info& info)
{
if (debug_ > 1)
{
- ACE_DEBUG ((LM_DEBUG, "ImR: <%C> Unexpected Ping exception. alive=false\n", info.name.c_str ()));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("ImR: <%C> Unexpected Ping exception. alive=false\n"),
+ info->name.c_str ()));
ex._tao_print_exception ("\n");
}
- info.last_ping = ACE_Time_Value::zero;
+ info.edit ()->last_ping = ACE_Time_Value::zero;
return 0;
}
return 1;
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
index fc26f46433e..ad4a301bfef 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
@@ -8,14 +8,14 @@
#include "locator_export.h"
#include "Adapter_Activator.h"
+#include "Activator_Info.h"
#include "Forwarder.h"
#include "Locator_Options.h"
-#include "Locator_Repository.h"
+#include "Server_Info.h"
+#include "ace/Auto_Ptr.h"
#include "AsyncStartupWaiter_i.h"
#include "tao/IORTable/IORTable.h"
-#include "orbsvcs/IOR_Multicast.h"
-
#include "ImR_LocatorS.h"
#include "AsyncStartupWaiterS.h"
@@ -28,6 +28,8 @@ class ACE_Reactor;
ACE_END_VERSIONED_NAMESPACE_DECL
class INS_Locator;
+class Locator_Repository;
+class UpdateableServerInfo;
/// Gets a request from a client and depending on the POA name,
/// requests an activator to take care of activating the
@@ -96,20 +98,19 @@ public:
private:
- char* activate_server_i (Server_Info& info, bool manual_start);
+ char* activate_server_i (UpdateableServerInfo& info,
+ bool manual_start);
- char* activate_perclient_server_i (Server_Info info, bool manual_start);
+ char* activate_perclient_server_i (UpdateableServerInfo& info,
+ bool manual_start);
ImplementationRepository::StartupInfo*
- start_server(Server_Info& info, bool manual_start, int& waiting_clients);
-
- bool is_alive(Server_Info& info);
- int is_alive_i(Server_Info& info);
+ start_server(UpdateableServerInfo& info,
+ bool manual_start,
+ int& waiting_clients);
- // Set up the multicast related if 'm' is passed on the command
- // line.
- int setup_multicast (ACE_Reactor *reactor, const char *ior);
- void teardown_multicast();
+ bool is_alive(UpdateableServerInfo& info);
+ int is_alive_i(UpdateableServerInfo& info);
void unregister_activator_i(const char* activator);
@@ -118,11 +119,14 @@ private:
void auto_start_servers(void);
- CORBA::Object_ptr set_timeout_policy(CORBA::Object_ptr obj, const ACE_Time_Value& to);
+ CORBA::Object_ptr set_timeout_policy(CORBA::Object_ptr obj,
+ const ACE_Time_Value& to);
- void connect_server(Server_Info& info);
+ void connect_server(UpdateableServerInfo& info);
PortableServer::POA_ptr findPOA(const char* name);
+
+ void parse_id(const char* id, ACE_CString& server_id, ACE_CString& name, bool& jacorb_server);
private:
// The class that handles the forwarding.
@@ -140,9 +144,7 @@ private:
int debug_;
- TAO_IOR_Multicast ior_multicast_;
-
- Locator_Repository repository_;
+ auto_ptr<Locator_Repository> repository_;
AsyncStartupWaiter_i waiter_svt_;
ImplementationRepository::AsyncStartupWaiter_var waiter_;
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc b/TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc
index d6deafcb117..881141bd54b 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc
+++ b/TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc
@@ -63,7 +63,7 @@ project(ImR_Activator) : orbsvcslib, orbsvcs_output, conv_lib, acexml, avoids_mi
}
}
-project(ImR_Locator) : orbsvcslib, orbsvcs_output, conv_lib, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro, iortable, portableserver, messaging, svc_utils, acexml, imr_client {
+project(ImR_Locator) : orbsvcslib, orbsvcs_output, conv_lib, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro, iortable, portableserver, messaging, svc_utils, acexml, imr_client, iormanip {
sharedname = TAO_ImR_Locator
dynamicflags += LOCATOR_BUILD_DLL
after += ImR_Locator_IDL ImR_Activator_IDL
@@ -82,6 +82,9 @@ project(ImR_Locator) : orbsvcslib, orbsvcs_output, conv_lib, avoids_minimum_corb
Iterator.cpp
Server_Info.cpp
Locator_Repository.cpp
+ Config_Backing_Store.cpp
+ XML_Backing_Store.cpp
+ Shared_Backing_Store.cpp
}
header_files {
utils.h
@@ -91,7 +94,7 @@ project(ImR_Locator) : orbsvcslib, orbsvcs_output, conv_lib, avoids_minimum_corb
}
}
-project(ImR_Locator_Service) : orbsvcsexe, install, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro, iortable, messaging, acexml ,svc_utils, pi_server, imr_client {
+project(ImR_Locator_Service) : orbsvcsexe, install_bin, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro, iortable, messaging, acexml ,svc_utils, pi_server, imr_client, iormanip {
exename = tao_imr_locator
after += ImR_Locator ImR_Activator_IDL ImR_Locator_IDL
libs += TAO_ImR_Locator TAO_ImR_Activator_IDL TAO_ImR_Locator_IDL
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp
index 8761db1bbaf..265e6bd69ed 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp
@@ -29,11 +29,12 @@ Options::Options ()
, debug_ (1)
, multicast_ (false)
, service_ (false)
-, ping_interval_(DEFAULT_PING_INTERVAL)
-, startup_timeout_(DEFAULT_START_TIMEOUT)
+, ping_interval_ (DEFAULT_PING_INTERVAL)
+, startup_timeout_ (DEFAULT_START_TIMEOUT)
, readonly_ (false)
-, service_command_(SC_NONE)
+, service_command_ (SC_NONE)
, unregister_if_address_reused_ (false)
+, imr_type_ (STANDALONE_IMR)
{
}
@@ -57,18 +58,21 @@ Options::parse_args (int &argc, ACE_TCHAR *argv[])
}
if (ACE_OS::strcasecmp (shifter.get_current (),
- ACE_TEXT ("install")) == 0)
+ ACE_TEXT ("install")) == 0)
{
this->service_command_ = SC_INSTALL;
}
else if (ACE_OS::strcasecmp (shifter.get_current (),
- ACE_TEXT ("remove")) == 0)
+ ACE_TEXT ("remove")) == 0)
{
this->service_command_ = SC_REMOVE;
}
else
{
- ACE_ERROR((LM_ERROR, "Error: Unknown service command : %s\n", shifter.get_current()));
+ ACE_ERROR ((
+ LM_ERROR,
+ ACE_TEXT ("Error: Unknown service command : %s\n"),
+ shifter.get_current ()));
this->print_usage ();
return -1;
}
@@ -165,6 +169,38 @@ Options::parse_args (int &argc, ACE_TCHAR *argv[])
this->repo_mode_ = REPO_XML_FILE;
}
else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("--primary")) == 0)
+ {
+ this->imr_type_ = PRIMARY_IMR;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("--backup")) == 0)
+ {
+ this->imr_type_ = BACKUP_IMR;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("--directory")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Error: --directory option needs a filename\n")));
+ this->print_usage ();
+ return -1;
+ }
+
+ this->persist_file_name_ = shifter.get_current ();
+ this->repo_mode_ = REPO_SHARED_FILES;
+
+ if (this->persist_file_name_.length() &&
+ this->persist_file_name_[this->persist_file_name_.length() - 1] != '/')
+ {
+ this->persist_file_name_ += '/';
+ }
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
ACE_TEXT ("-e")) == 0)
{
this->erase_repo_ = true;
@@ -176,7 +212,8 @@ Options::parse_args (int &argc, ACE_TCHAR *argv[])
if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
{
- ACE_ERROR ((LM_ERROR, "Error: -t option needs a value\n"));
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Error: -t option needs a value\n")));
this->print_usage ();
return -1;
}
@@ -190,7 +227,8 @@ Options::parse_args (int &argc, ACE_TCHAR *argv[])
if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
{
- ACE_ERROR ((LM_ERROR, "Error: -v option needs a value\n"));
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Error: -v option needs a value\n")));
this->print_usage ();
return -1;
}
@@ -239,20 +277,27 @@ void
Options::print_usage (void) const
{
ACE_ERROR ((LM_ERROR,
- "Usage:\n"
- "\n"
- "ImplRepo_Service [-c cmd] [-d 0|1|2] [-m] [-o file]\n"
- " [-r|-p file|-x file] [-s] [-t secs] [-v secs]\n"
- " -c command Runs nt service commands ('install' or 'remove')\n"
- " -d level Sets the debug level (default 1)\n"
- " -l Lock the database\n"
- " -m Turn on multicast\n"
- " -o file Outputs the ImR's IOR to a file\n"
- " -p file Use file for storing/loading settings\n"
- " -x file Use XML file for storing/loading setting\n"
- " -r Use the registry for storing/loading settings\n"
- " -t secs Server startup timeout.(Default=60s)\n"
- " -v msecs Server verification interval.(Default=10s)\n"
+ ACE_TEXT ("Usage:\n")
+ ACE_TEXT ("\n")
+ ACE_TEXT ("ImplRepo_Service [-c cmd] [-d 0|1|2] [-e] [-m] [-o file]\n")
+ ACE_TEXT (" [-r|-p file|-x file|--directory dir [--primary|--backup] ]\n")
+ ACE_TEXT (" [-s] [-t secs] [-v secs]\n")
+ ACE_TEXT (" -c command Runs nt service commands ('install' or 'remove')\n")
+ ACE_TEXT (" -d level Sets the debug level (default 1)\n")
+ ACE_TEXT (" -e Erase the persisted repository at startup\n")
+ ACE_TEXT (" -l Lock the database\n")
+ ACE_TEXT (" -m Turn on multicast\n")
+ ACE_TEXT (" -o file Outputs the ImR's IOR to a file\n")
+ ACE_TEXT (" -p file Use file for storing/loading settings\n")
+ ACE_TEXT (" -x file Use XML file for storing/loading settings\n")
+ ACE_TEXT (" --directory dir Use individual XML files for storing/loading\n")
+ ACE_TEXT (" settings in the provided directory\n")
+ ACE_TEXT (" --primary Replicate the ImplRepo as the primary ImR\n")
+ ACE_TEXT (" --backup Replicate the ImplRepo as the backup ImR\n")
+ ACE_TEXT (" -r Use the registry for storing/loading settings\n")
+ ACE_TEXT (" -s Run as a service\n")
+ ACE_TEXT (" -t secs Server startup timeout.(Default=60s)\n")
+ ACE_TEXT (" -v msecs Server verification interval.(Default=10s)\n")
));
}
@@ -265,7 +310,7 @@ Options::save_registry_options ()
LONG err = ACE_TEXT_RegCreateKeyEx (SERVICE_REG_ROOT,
SERVICE_REG_PATH,
0,
- const_cast<ACE_TCHAR*> (ACE_TEXT("")), // class
+ const_cast<ACE_TCHAR*> (ACE_TEXT ("")), // class
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
0,
@@ -276,47 +321,51 @@ Options::save_registry_options ()
{
return -1;
}
- err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT("ORBInitOptions"), 0, REG_SZ,
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("ORBInitOptions"), 0, REG_SZ,
(LPBYTE) this->cmdline_.c_str (), this->cmdline_.length () + 1);
ACE_ASSERT (err == ERROR_SUCCESS);
- err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT("IORFile"), 0, REG_SZ,
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("IORFile"), 0, REG_SZ,
(LPBYTE) ior_output_file_.c_str (), ior_output_file_.length () + 1);
ACE_ASSERT (err == ERROR_SUCCESS);
- err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT("DebugLevel"), 0, REG_DWORD,
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("DebugLevel"), 0, REG_DWORD,
(LPBYTE) &debug_ , sizeof (debug_));
ACE_ASSERT(err == ERROR_SUCCESS);
- err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT("PersistFile"), 0, REG_SZ,
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("PersistFile"), 0, REG_SZ,
(LPBYTE) this->persist_file_name_.c_str (), this->persist_file_name_.length () + 1);
ACE_ASSERT (err == ERROR_SUCCESS);
DWORD tmp = this->ping_interval_.msec ();
- err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT("PingInterval"), 0, REG_DWORD,
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("PingInterval"), 0, REG_DWORD,
(LPBYTE) &tmp, sizeof (DWORD));
ACE_ASSERT (err == ERROR_SUCCESS);
tmp = this->readonly_ ? 1 : 0;
- err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT("Lock"), 0, REG_DWORD,
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("Lock"), 0, REG_DWORD,
(LPBYTE) &tmp, sizeof (DWORD));
ACE_ASSERT (err == ERROR_SUCCESS);
tmp = this->repo_mode_;
- err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT("PersistType"), 0, REG_DWORD,
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("PersistType"), 0, REG_DWORD,
(LPBYTE) &tmp, sizeof (DWORD));
ACE_ASSERT (err == ERROR_SUCCESS);
tmp = static_cast<DWORD> (this->startup_timeout_.sec());
- err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT("Timeout"), 0, REG_DWORD,
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("Timeout"), 0, REG_DWORD,
(LPBYTE) &tmp, sizeof (DWORD));
ACE_ASSERT (err == ERROR_SUCCESS);
- tmp = multicast_ ? 1 : 0;
- err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT("Multicast"), 0, REG_DWORD,
+ tmp = this->multicast_ ? 1 : 0;
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("Multicast"), 0, REG_DWORD,
(LPBYTE) &tmp, sizeof (DWORD));
ACE_ASSERT (err == ERROR_SUCCESS);
+ err = ACE_TEXT_RegSetValueEx (key, ACE_TEXT ("ImrType"), 0, REG_DWORD,
+ (LPBYTE) &this->imr_type_ , sizeof (this->imr_type_));
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
err = ::RegCloseKey (key);
ACE_ASSERT (err == ERROR_SUCCESS);
#endif
@@ -343,7 +392,7 @@ Options::load_registry_options ()
ACE_TCHAR tmpstr[4096];
DWORD sz = sizeof (tmpstr);
DWORD type = 0;
- err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT("ORBInitOptions"), 0, &type,
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("ORBInitOptions"), 0, &type,
(LPBYTE) tmpstr, &sz);
if (err == ERROR_SUCCESS)
{
@@ -353,7 +402,7 @@ Options::load_registry_options ()
}
sz = sizeof(tmpstr);
- err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT("IORFile"), 0, &type,
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("IORFile"), 0, &type,
(LPBYTE) tmpstr, &sz);
if (err == ERROR_SUCCESS)
{
@@ -363,7 +412,7 @@ Options::load_registry_options ()
}
sz = sizeof(debug_);
- err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT("DebugLevel"), 0, &type,
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("DebugLevel"), 0, &type,
(LPBYTE) &this->debug_ , &sz);
if (err == ERROR_SUCCESS)
{
@@ -372,7 +421,7 @@ Options::load_registry_options ()
DWORD tmp = 0;
sz = sizeof(tmp);
- err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT("PingInterval"), 0, &type,
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("PingInterval"), 0, &type,
(LPBYTE) &tmp, &sz);
if (err == ERROR_SUCCESS)
{
@@ -382,7 +431,7 @@ Options::load_registry_options ()
tmp = 0;
sz = sizeof(tmp);
- err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT("Lock"), 0, &type,
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("Lock"), 0, &type,
(LPBYTE) &tmp, &sz);
if (err == ERROR_SUCCESS)
{
@@ -391,7 +440,7 @@ Options::load_registry_options ()
}
sz = sizeof(this->repo_mode_);
- err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT("PersistType"), 0, &type,
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("PersistType"), 0, &type,
(LPBYTE) &this->repo_mode_, &sz);
if (err == ERROR_SUCCESS)
{
@@ -400,7 +449,7 @@ Options::load_registry_options ()
tmp = 0;
sz = sizeof(tmp);
- err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT("Timeout"), 0, &type,
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("Timeout"), 0, &type,
(LPBYTE) &tmp, &sz);
if (err == ERROR_SUCCESS)
{
@@ -410,7 +459,7 @@ Options::load_registry_options ()
tmp = 0;
sz = sizeof(tmp);
- err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT("Multicast"), 0, &type,
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("Multicast"), 0, &type,
(LPBYTE) &tmp, &sz);
if (err == ERROR_SUCCESS)
{
@@ -419,7 +468,7 @@ Options::load_registry_options ()
}
sz = sizeof(tmpstr);
- err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT("PersistFile"), 0, &type,
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("PersistFile"), 0, &type,
(LPBYTE) tmpstr, &sz);
if (err == ERROR_SUCCESS)
{
@@ -428,6 +477,14 @@ Options::load_registry_options ()
this->persist_file_name_ = tmpstr;
}
+ sz = sizeof(imr_type_);
+ err = ACE_TEXT_RegQueryValueEx (key, ACE_TEXT ("ImrType"), 0, &type,
+ (LPBYTE) &this->imr_type_ , &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_DWORD);
+ }
+
err = ::RegCloseKey (key);
ACE_ASSERT (err == ERROR_SUCCESS);
#endif
@@ -509,3 +566,8 @@ Options::unregister_if_address_reused (void) const
{
return this->unregister_if_address_reused_;
}
+
+Options::ImrType
+Options::imr_type(void) const {
+ return this->imr_type_;
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h
index 6f041cfdd71..8c62959de12 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h
@@ -41,13 +41,6 @@ public:
SC_REMOVE
};
- enum RepoMode {
- REPO_NONE,
- REPO_XML_FILE,
- REPO_HEAP_FILE,
- REPO_REGISTRY
- };
-
Options ();
/// Parse the command-line arguments and initialize the options.
@@ -81,6 +74,14 @@ public:
/// Do we allow modifications to the servers?
bool readonly (void) const;
+ /// Which type of repository is to be used?
+ enum RepoMode {
+ REPO_NONE,
+ REPO_XML_FILE,
+ REPO_SHARED_FILES,
+ REPO_HEAP_FILE,
+ REPO_REGISTRY
+ };
RepoMode repository_mode (void) const;
/// Do we wish to clear out the repository
@@ -96,6 +97,10 @@ public:
bool unregister_if_address_reused (void) const;
+ /// Indicate what type of ImR Locator this is.
+ enum ImrType { BACKUP_IMR, PRIMARY_IMR, STANDALONE_IMR };
+ ImrType imr_type(void) const;
+
private:
/// Parses and pulls out arguments for the ImR
int parse_args (int &argc, ACE_TCHAR *argv[]);
@@ -148,6 +153,9 @@ private:
/// Should check the server address and remove previous server if
/// the address is reused.
bool unregister_if_address_reused_;
+
+ /// The type of ImR Locator this is.
+ ImrType imr_type_;
};
#endif
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
index 5833e0f4e98..9dcc0d4383b 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
@@ -1,369 +1,222 @@
// $Id$
#include "Locator_Repository.h"
-#include "Locator_XMLHandler.h"
#include "utils.h"
+#include "tao/ORB_Core.h"
+#include "tao/default_ports.h"
+#include "ace/Read_Buffer.h"
#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_strings.h"
#include "ace/OS_NS_ctype.h"
#include "ace/OS_NS_unistd.h"
+#include "ace/Vector_T.h"
-#include "ACEXML/parser/parser/Parser.h"
-#include "ACEXML/common/FileCharStream.h"
-#include "ACEXML/common/XML_Util.h"
-
-static const ACE_TCHAR* STARTUP_COMMAND = ACE_TEXT("StartupCommand");
-static const ACE_TCHAR* WORKING_DIR = ACE_TEXT("WorkingDir");
-static const ACE_TCHAR* ENVIRONMENT = ACE_TEXT("Environment");
-static const ACE_TCHAR* ACTIVATION = ACE_TEXT("Activation");
-static const ACE_TCHAR* PARTIAL_IOR = ACE_TEXT("Location");
-static const ACE_TCHAR* IOR = ACE_TEXT("IOR");
-static const ACE_TCHAR* START_LIMIT = ACE_TEXT("StartLimit");
-static const ACE_TCHAR* ACTIVATOR = ACE_TEXT("Activator");
-static const ACE_TCHAR* SERVERS_ROOT_KEY = ACE_TEXT("Servers");
-static const ACE_TCHAR* ACTIVATORS_ROOT_KEY = ACE_TEXT("Activators");
-static const ACE_TCHAR* TOKEN = ACE_TEXT("Token");
-static const ACE_TCHAR* SERVER_ID = ACE_TEXT("ServerId");
-
-#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
-static const char* WIN32_REG_KEY = "Software\\TAO\\ImplementationRepository";
-#endif
-
-static ACE_CString lcase (const ACE_CString& s)
+Locator_Repository::Locator_Repository (const Options& opts,
+ CORBA::ORB_ptr orb)
+: opts_ (opts),
+ orb_(CORBA::ORB::_duplicate(orb)),
+ registered_(false)
{
- ACE_CString ret(s);
- for (size_t i = 0; i < ret.length (); ++i)
- {
- ret[i] = static_cast<char>(ACE_OS::ace_tolower (s[i]));
- }
- return ret;
}
-static void loadActivatorsAsBinary (ACE_Configuration& config, Locator_Repository::AIMap& map)
+Locator_Repository::~Locator_Repository ()
{
- ACE_Configuration_Section_Key root;
- int err = config.open_section (config.root_section (), ACTIVATORS_ROOT_KEY, 0, root);
- if (err == 0)
- {
- int index = 0;
- ACE_TString name;
- while (config.enumerate_sections (root, index, name) == 0)
- {
- ACE_CString ior;
- u_int token;
-
- ACE_Configuration_Section_Key key;
-
- // Can't fail, because we're enumerating
- config.open_section (root, name.c_str(), 0, key);
-
- config.get_string_value (key, IOR, ior);
- config.get_integer_value (key, TOKEN, token);
-
- Activator_Info_Ptr info (new Activator_Info (name, token, ior));
- map.bind (lcase (name), info);
- index++;
- }
- }
+ teardown_multicast();
}
-static void loadServersAsBinary(ACE_Configuration& config, Locator_Repository::SIMap& map)
+int
+Locator_Repository::init (PortableServer::POA_ptr root_poa,
+ PortableServer::POA_ptr imr_poa,
+ const char* this_ior)
{
- ACE_Configuration_Section_Key root;
- int err = config.open_section (config.root_section (), SERVERS_ROOT_KEY, 0, root);
- if (err == 0)
+ this->imr_ior_ = this_ior;
+ int err = init_repo(imr_poa);
+ if (err != 0)
{
- int index = 0;
- ACE_TString name;
- while (config.enumerate_sections (root, index, name) == 0)
- {
- ACE_CString server_id, cmdline, dir, envstr, partial_ior, ior, aname;
- u_int amodeint = ImplementationRepository::MANUAL;
- u_int start_limit;
-
- ACE_Configuration_Section_Key key;
-
- // Can't fail, because we're enumerating
- config.open_section (root, name.c_str (), 0, key);
-
- // Ignore any missing values. Server name is enough on its own.
- config.get_string_value (key, SERVER_ID, server_id);
- config.get_string_value (key, ACTIVATOR, aname);
- config.get_string_value (key, STARTUP_COMMAND, cmdline);
- config.get_string_value (key, WORKING_DIR, dir);
- config.get_string_value (key, ENVIRONMENT, envstr);
- config.get_integer_value(key, ACTIVATION, amodeint);
- config.get_string_value (key, PARTIAL_IOR, partial_ior);
- config.get_string_value (key, IOR, ior);
- config.get_integer_value(key, START_LIMIT, start_limit);
-
- ImplementationRepository::ActivationMode amode =
- static_cast <ImplementationRepository::ActivationMode> (amodeint);
-
- ImplementationRepository::EnvironmentList env_vars =
- ImR_Utils::parseEnvList (envstr);
-
- Server_Info_Ptr info (new Server_Info(server_id, name, aname, cmdline,
- env_vars, dir, amode, start_limit, partial_ior, ior));
- map.bind (name, info);
- index++;
- }
+ return err;
}
-}
-static void loadAsBinary (ACE_Configuration& config, Locator_Repository& repo)
-{
- loadServersAsBinary (config, repo.servers ());
- loadActivatorsAsBinary (config, repo.activators ());
-}
+ // Activate the two poa managers
+ PortableServer::POAManager_var poaman =
+ root_poa->the_POAManager ();
+ poaman->activate ();
+ poaman = imr_poa->the_POAManager ();
+ poaman->activate ();
-// Note : There is no saveAsBinary(), because the ACE_Configuration class
-// supports saving of individual entries.
+ err = report_ior(imr_poa);
+ return err;
+}
-static void convertEnvList (const Locator_XMLHandler::EnvList& in, ImplementationRepository::EnvironmentList& out)
+int
+Locator_Repository::report_ior (PortableServer::POA_ptr )
{
- CORBA::ULong sz = in.size ();
- out.length (sz);
- for (CORBA::ULong i = 0; i < sz; ++i)
+ if (this->registered_)
{
- out[i].name = in[i].name.c_str ();
- out[i].value = in[i].value.c_str ();
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Repository already reported IOR\n")), -1);
}
-}
-
-class Server_Repo_XML_Callback : public Locator_XMLHandler::Callback
-{
-public:
- Server_Repo_XML_Callback(Locator_Repository& repo)
- : repo_ (repo)
- {
- }
- virtual void next_server (const ACE_CString& server_id,
- const ACE_CString& name, const ACE_CString& aname,
- const ACE_CString& cmdline, const Locator_XMLHandler::EnvList& envlst,
- const ACE_CString& dir, const ACE_CString& amodestr, int start_limit,
- const ACE_CString& partial_ior, const ACE_CString& ior)
- {
- ImplementationRepository::ActivationMode amode =
- ImR_Utils::parseActivationMode (amodestr);
- ImplementationRepository::EnvironmentList env_vars;
- convertEnvList (envlst, env_vars);
-
- int limit = start_limit < 1 ? 1 : start_limit;
-
- Server_Info_Ptr si (new Server_Info (server_id, name, aname, cmdline,
- env_vars, dir, amode, limit, partial_ior, ior));
+ if (this->opts_.debug () > 0)
+ {
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("report_ior <%C>\n"),
+ this->imr_ior_.in ()));
+ }
- this->repo_.servers ().bind (name, si);
- }
- virtual void next_activator (const ACE_CString& aname,
- long token,
- const ACE_CString& ior)
- {
- Activator_Info_Ptr si (new Activator_Info (aname, token, ior));
- this->repo_.activators ().bind (lcase (aname), si);
- }
-private:
- Locator_Repository& repo_;
-};
+ // Register the ImR for use with INS
+ CORBA::Object_var obj = this->orb_->resolve_initial_references ("IORTable");
+ IORTable::Table_var ior_table = IORTable::Table::_narrow (obj.in ());
+ ACE_ASSERT (! CORBA::is_nil (ior_table.in ()));
-static int loadAsXML (const ACE_CString& fname, Locator_Repository& repo)
-{
- ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream; // xml input source will take ownership
+ ior_table->bind ("ImplRepoService", this->imr_ior_.in());
+ ior_table->bind ("ImR", this->imr_ior_.in());
- if (fstm->open (fname.c_str()) != 0)
+ // Set up multicast support (if enabled)
+ if (this->opts_.multicast ())
{
- // This is not a real error. The xml file may not exist yet.
- delete fstm;
- return 0;
+ ACE_Reactor* reactor = this->orb_->orb_core ()->reactor ();
+ if (this->setup_multicast (reactor, this->imr_ior_.in ()) != 0)
+ return -1;
}
- Server_Repo_XML_Callback cb (repo);
-
- Locator_XMLHandler handler (cb);
+ // We write the ior file last so that the tests can know we are ready.
+ if (this->opts_.ior_filename ().length () > 0)
+ {
+ FILE* orig_fp = ACE_OS::fopen(this->opts_.ior_filename ().c_str(),
+ ACE_TEXT("r"));
- ACEXML_Parser parser;
+ bool write_data = true;
+ if (orig_fp != 0)
+ {
+ ACE_Read_Buffer reader (orig_fp, false);
- // InputSource takes ownership
- ACEXML_InputSource input (fstm);
+ char* string = reader.read ();
- parser.setContentHandler (&handler);
- parser.setDTDHandler (&handler);
- parser.setErrorHandler (&handler);
- parser.setEntityResolver (&handler);
+ if (string != 0)
+ {
+ write_data =
+ (ACE_OS::strcasecmp (string, this->imr_ior_.in ()) != 0);
+ reader.alloc ()->free (string);
+ }
+ ACE_OS::fclose (orig_fp);
+ }
- try
- {
- parser.parse (&input);
- }
- catch (const ACEXML_Exception& ex)
- {
- ACE_ERROR ((LM_ERROR, "Error during load of ImR persistence xml file."));
- ex.print ();
- return -1;
+ if (write_data)
+ {
+ FILE* fp = ACE_OS::fopen (this->opts_.ior_filename ().c_str (),
+ ACE_TEXT("w"));
+ if (fp == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT("ImR: Could not open file: %s\n"),
+ this->opts_.ior_filename ().c_str ()), -1);
+ }
+ ACE_OS::fprintf (fp, "%s", this->imr_ior_.in ());
+ ACE_OS::fclose (fp);
+ }
}
+
+ registered_ = true;
+
return 0;
}
-// Note : Would pass servers by const&, but ACE hash map const_iterator is broken.
-static void saveAsXML (const ACE_CString& fname, Locator_Repository& repo)
+int
+Locator_Repository::setup_multicast (ACE_Reactor* reactor, const char* ior)
{
- FILE* fp = ACE_OS::fopen (fname.c_str (), "w");
- if (fp == 0)
+ ACE_ASSERT (reactor != 0);
+#if defined (ACE_HAS_IP_MULTICAST)
+
+ TAO_ORB_Core* core = TAO_ORB_Core_instance ();
+ // See if the -ORBMulticastDiscoveryEndpoint option was specified.
+ ACE_CString mde (core->orb_params ()->mcast_discovery_endpoint ());
+
+ if (mde.length () != 0)
{
- ACE_ERROR ((LM_ERROR, "Couldn't write to file %C\n", fname.c_str()));
- return;
+ if (this->ior_multicast_.init (ior,
+ mde.c_str (), TAO_SERVICEID_IMPLREPOSERVICE) == -1)
+ {
+ return -1;
+ }
}
- ACE_OS::fprintf (fp,"<?xml version=\"1.0\"?>\n");
- ACE_OS::fprintf (fp,"<%s>\n", Locator_XMLHandler::ROOT_TAG);
-
- // Save servers
- Locator_Repository::SIMap::ENTRY* sientry = 0;
- Locator_Repository::SIMap::ITERATOR siit (repo.servers ());
- for (; siit.next (sientry); siit.advance() )
+ else
{
- Server_Info_Ptr& info = sientry->int_id_;
-
- ACE_CString server_id = ACEXML_escape_string (info->server_id);
- ACE_CString name = ACEXML_escape_string (info->name);
- ACE_CString activator = ACEXML_escape_string (info->activator);
- ACE_CString cmdline = ACEXML_escape_string (info->cmdline);
- ACE_CString wdir = ACEXML_escape_string (info->dir);
- ACE_CString partial_ior = ACEXML_escape_string (info->partial_ior);
- ACE_CString ior = ACEXML_escape_string (info->ior);
-
- ACE_OS::fprintf (fp,"\t<%s", Locator_XMLHandler::SERVER_INFO_TAG);
- ACE_OS::fprintf (fp," server_id=\"%s\"", server_id.c_str ());
- ACE_OS::fprintf (fp," name=\"%s\"", name.c_str ());
- ACE_OS::fprintf (fp," activator=\"%s\"", activator.c_str ());
- ACE_OS::fprintf (fp," command_line=\"%s\"", cmdline.c_str ());
- ACE_OS::fprintf (fp," working_dir=\"%s\"", wdir.c_str ());
- ACE_CString amodestr = ImR_Utils::activationModeToString (info->activation_mode);
- ACE_OS::fprintf (fp," activation_mode=\"%s\"", amodestr.c_str ());
- ACE_OS::fprintf (fp," start_limit=\"%d\"", info->start_limit);
- ACE_OS::fprintf (fp," partial_ior=\"%s\"", partial_ior.c_str ());
- ACE_OS::fprintf (fp," ior=\"%s\"", ior.c_str ());
- ACE_OS::fprintf (fp,">\n");
-
- for (CORBA::ULong i = 0; i < info->env_vars.length (); ++i)
+ // Port can be specified as param, env var, or default
+ CORBA::UShort port =
+ core->orb_params ()->service_port (TAO::MCAST_IMPLREPOSERVICE);
+ if (port == 0)
{
- ACE_OS::fprintf (fp,"\t\t<%s", Locator_XMLHandler::ENVIRONMENT_TAG);
- ACE_OS::fprintf (fp," name=\"%s\"", info->env_vars[i].name.in ());
- ACE_CString val = ACEXML_escape_string (info->env_vars[i].value.in ());
- ACE_OS::fprintf (fp," value=\"%s\"", val.c_str ());
- ACE_OS::fprintf (fp,"/>\n");
+ // Check environment var. for multicast port.
+ const char* port_number = ACE_OS::getenv ("ImplRepoServicePort");
+
+ if (port_number != 0)
+ port = static_cast<CORBA::UShort> (ACE_OS::atoi (port_number));
}
+ if (port == 0)
+ port = TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT;
- ACE_OS::fprintf (fp,"\t</%s>\n", Locator_XMLHandler::SERVER_INFO_TAG);
+ if (this->ior_multicast_.init (ior, port,
+ ACE_DEFAULT_MULTICAST_ADDR, TAO_SERVICEID_IMPLREPOSERVICE) == -1)
+ {
+ return -1;
+ }
}
- // Save Activators
- Locator_Repository::AIMap::ENTRY* aientry = 0;
- Locator_Repository::AIMap::ITERATOR aiit (repo.activators ());
- for (; aiit.next (aientry); aiit.advance ())
+ // Register event handler for the ior multicast.
+ if (reactor->register_handler (&this->ior_multicast_,
+ ACE_Event_Handler::READ_MASK) == -1)
{
- ACE_CString aname = aientry->ext_id_;
- Activator_Info_Ptr& info = aientry->int_id_;
- ACE_OS::fprintf (fp,"\t<%s", Locator_XMLHandler::ACTIVATOR_INFO_TAG);
- ACE_OS::fprintf( fp," name=\"%s\"", aname.c_str ());
- ACE_OS::fprintf (fp," token=\"%d\"", info->token);
- ACE_OS::fprintf (fp," ior=\"%s\"", info->ior.c_str ());
- ACE_OS::fprintf (fp,"/>\n");
+ if (this->opts_.debug() > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: cannot register Event handler\n"));
+ return -1;
}
-
- ACE_OS::fprintf (fp,"</%s>\n", Locator_XMLHandler::ROOT_TAG);
- ACE_OS::fclose (fp);
+#else /* ACE_HAS_IP_MULTICAST*/
+ ACE_UNUSED_ARG (reactor);
+ ACE_UNUSED_ARG (ior);
+#endif /* ACE_HAS_IP_MULTICAST*/
+ return 0;
}
-Locator_Repository::Locator_Repository ()
-: rmode_ (Options::REPO_NONE)
-, config_ (0)
-, debug_ (0)
+void
+Locator_Repository::teardown_multicast ()
{
+ ACE_Reactor* r = ior_multicast_.reactor ();
+ if (r != 0) {
+ r->remove_handler (&ior_multicast_, ACE_Event_Handler::READ_MASK);
+ ior_multicast_.reactor (0);
+ }
}
-int
-Locator_Repository::init(const Options& opts)
+bool
+Locator_Repository::multicast() const
{
- this->rmode_ = opts.repository_mode ();
- this->fname_ = opts.persist_file_name ();
- this->debug_ = opts.debug ();
+ return this->ior_multicast_.reactor () != 0;
+}
- int err = 0;
- switch (this->rmode_)
+ACE_CString
+Locator_Repository::lcase (const ACE_CString& s)
+{
+ ACE_CString ret(s);
+ for (size_t i = 0; i < ret.length (); ++i)
{
- case Options::REPO_NONE:
- {
- break;
- }
- case Options::REPO_HEAP_FILE:
- {
- if (opts.repository_erase ())
- {
- ACE_OS::unlink ( this->fname_.c_str () );
- }
- ACE_Configuration_Heap* heap = new ACE_Configuration_Heap ();
- this->config_.reset (heap);
- err = heap->open (this->fname_.c_str ());
- if (err == 0)
- {
- loadAsBinary (*this->config_, *this);
- }
- break;
- }
- case Options::REPO_REGISTRY:
- {
-#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
- if (opts.repository_erase ())
- {
- ACE_Configuration_Win32Registry config ( HKEY_LOCAL_MACHINE );
- ACE_Configuration_Section_Key root;
- config.open_section (config.root_section(), "Software\\TAO", 0, root);
- config.remove_section (root, "ImplementationRepository", 1);
- }
- HKEY root = ACE_Configuration_Win32Registry::
- resolve_key (HKEY_LOCAL_MACHINE, WIN32_REG_KEY);
- this->config_.reset (new ACE_Configuration_Win32Registry( root));
- loadAsBinary (*this->config_, *this);
-#else
- ACE_ERROR ((LM_ERROR, "Registry persistence is only "
- "supported on Windows\n"));
- err = -1;
-#endif
- break;
- }
- case Options::REPO_XML_FILE:
- {
- if (opts.repository_erase ())
- {
- ACE_OS::unlink ( this->fname_.c_str() );
- }
- err = loadAsXML (this->fname_, *this);
- break;
- }
- default:
- {
- bool invalid_rmode_specified = false;
- ACE_ASSERT (invalid_rmode_specified);
- ACE_UNUSED_ARG (invalid_rmode_specified);
- err = -1;
- }
+ ret[i] = static_cast<char> (ACE_OS::ace_tolower (s[i]));
}
- return err;
+ return ret;
}
-
int
Locator_Repository::unregister_if_address_reused (
const ACE_CString& server_id,
const ACE_CString& name,
const char* partial_ior)
{
- if (this->debug_ > 0)
+ if (this->opts_.debug() > 0)
{
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)ImR: checking reuse address ")
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t)ImR: checking reuse address ")
ACE_TEXT ("for server \"%C %C\" ior \"%C\"\n"),
- server_id.c_str(), name.c_str (), partial_ior));
+ server_id.c_str(),
+ name.c_str (),
+ partial_ior));
}
ACE_Vector<ACE_CString> srvs;
@@ -374,9 +227,10 @@ Locator_Repository::unregister_if_address_reused (
{
Server_Info_Ptr& info = sientry->int_id_;
- if (this->debug_)
+ if (this->opts_.debug() > 0)
{
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)ImR: iterating - registered server")
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t)ImR: iterating - registered server")
ACE_TEXT ("\"%C %C\" ior \"%C\"\n"), info->server_id.c_str(),
info->name.c_str (), info->partial_ior.c_str ()));
}
@@ -385,10 +239,11 @@ Locator_Repository::unregister_if_address_reused (
&& name != info->name
&& info->server_id != server_id)
{
- if (this->debug_)
+ if (this->opts_.debug() > 0)
{
- ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)ImR: reuse address %C so remove")
- ACE_TEXT ("server %C \n"), info->partial_ior.c_str (), info->name.c_str ()));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t)ImR: reuse address %C so remove server %C \n"),
+ info->partial_ior.c_str (), info->name.c_str ()));
}
if (! info->name.empty ())
{
@@ -410,31 +265,38 @@ Locator_Repository::unregister_if_address_reused (
return err;
}
-
-
int
-Locator_Repository::add_server (const ACE_CString& server_id,
- const ACE_CString& name,
- const ACE_CString& aname,
- const ACE_CString& startup_command,
- const ImplementationRepository::EnvironmentList& env_vars,
- const ACE_CString& working_dir,
- ImplementationRepository::ActivationMode activation,
- int start_limit,
- const ACE_CString& partial_ior,
- const ACE_CString& ior,
- ImplementationRepository::ServerObject_ptr svrobj)
+Locator_Repository::add_server (
+ const ACE_CString& server_id,
+ const ACE_CString& name,
+ bool jacorbs,
+ const ACE_CString& aname,
+ const ACE_CString& startup_command,
+ const ImplementationRepository::EnvironmentList& env_vars,
+ const ACE_CString& working_dir,
+ ImplementationRepository::ActivationMode activation,
+ int start_limit,
+ const ACE_CString& partial_ior,
+ const ACE_CString& ior,
+ ImplementationRepository::ServerObject_ptr svrobj)
{
+ int err = sync_load ();
+ if (err != 0)
+ {
+ return err;
+ }
+
int limit = start_limit < 1 ? 1 : start_limit;
- Server_Info_Ptr info(new Server_Info (server_id, name, aname, startup_command,
- env_vars, working_dir, activation, limit, partial_ior, ior, svrobj));
+ Server_Info_Ptr info(new Server_Info (server_id, name, jacorbs, aname,
+ startup_command, env_vars, working_dir, activation, limit, partial_ior,
+ ior, svrobj));
- int err = servers ().bind (name, info);
+ err = servers ().bind (name, info);
if (err != 0)
{
return err;
}
- this->update_server (*info);
+ this->persistent_update(info, true);
return 0;
}
@@ -444,97 +306,40 @@ Locator_Repository::add_activator (const ACE_CString& name,
const ACE_CString& ior,
ImplementationRepository::Activator_ptr act)
{
+ int err = sync_load ();
+ if (err != 0)
+ {
+ return err;
+ }
+
Activator_Info_Ptr info (new Activator_Info (name, token, ior, act));
- int err = activators ().bind (lcase (name), info);
+ err = activators ().bind (lcase (name), info);
if (err != 0)
{
return err;
}
- this->update_activator (*info);
+ this->persistent_update(info, true);
return 0;
}
int
-Locator_Repository::update_server (const Server_Info& info)
+Locator_Repository::update_server (const Server_Info_Ptr& info)
{
- if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
- {
- ACE_ASSERT (this->config_.get () != 0);
-
- ACE_Configuration& cfg = *this->config_;
-
- ACE_Configuration_Section_Key root;
- ACE_Configuration_Section_Key key;
- int err = cfg.open_section (cfg.root_section(), SERVERS_ROOT_KEY, 1, root);
- if (err != 0)
- {
- ACE_ERROR ((LM_ERROR, "Unable to open config section:%s\n", SERVERS_ROOT_KEY));
- return err;
- }
- err = cfg.open_section (root, info.name.c_str (), 1, key);
- if (err != 0)
- {
- ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str()));
- return err;
- }
-
- ACE_CString envstr = ImR_Utils::envListToString(info.env_vars);
-
- cfg.set_string_value (key, SERVER_ID, info.server_id.c_str ());
- cfg.set_string_value (key, ACTIVATOR, info.activator.c_str ());
- cfg.set_string_value (key, STARTUP_COMMAND, info.cmdline.c_str ());
- cfg.set_string_value (key, WORKING_DIR, info.dir.c_str ());
- cfg.set_string_value (key, ENVIRONMENT, envstr);
- cfg.set_integer_value (key, ACTIVATION, info.activation_mode);
- cfg.set_integer_value (key, START_LIMIT, info.start_limit);
- cfg.set_string_value (key, PARTIAL_IOR, info.partial_ior.c_str ());
- cfg.set_string_value (key, IOR, info.ior.c_str());
- }
- else if (rmode_ == Options::REPO_XML_FILE)
- {
- saveAsXML (this->fname_, *this);
- }
- return 0;
+ return this->persistent_update(info, false);
}
int
-Locator_Repository::update_activator (const Activator_Info& info)
+Locator_Repository::update_activator (const Activator_Info_Ptr& info)
{
- if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
- {
- ACE_ASSERT(this->config_.get () != 0);
-
- ACE_Configuration& cfg = *this->config_;
-
- ACE_Configuration_Section_Key root;
- ACE_Configuration_Section_Key key;
- int err = cfg.open_section (cfg.root_section(), ACTIVATORS_ROOT_KEY, 1, root);
- if (err != 0)
- {
- ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", ACTIVATORS_ROOT_KEY));
- return err;
- }
- err = cfg.open_section (root, info.name.c_str (), 1, key);
- if (err != 0)
- {
- ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str()));
- return err;
- }
-
- cfg.set_integer_value (key, TOKEN, info.token);
- cfg.set_string_value (key, IOR, info.ior.c_str ());
- }
- else if (rmode_ == Options::REPO_XML_FILE)
- {
- saveAsXML( this->fname_, *this);
- }
- return 0;
+ return this->persistent_update(info, false);
}
Server_Info_Ptr
Locator_Repository::get_server (const ACE_CString& name)
{
+ sync_load ();
+
Server_Info_Ptr server (0);
servers ().find (name, server);
return server;
@@ -543,6 +348,8 @@ Locator_Repository::get_server (const ACE_CString& name)
Activator_Info_Ptr
Locator_Repository::get_activator (const ACE_CString& name)
{
+ sync_load ();
+
Activator_Info_Ptr activator (0);
activators ().find (lcase (name), activator);
return activator;
@@ -558,57 +365,37 @@ Locator_Repository::has_activator (const ACE_CString& name)
int
Locator_Repository::remove_server (const ACE_CString& name)
{
+ int err = sync_load ();
+ if (err != 0)
+ {
+ return err;
+ }
+
int ret = this->servers().unbind (name);
if (ret != 0)
{
return ret;
}
- if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
- {
- ACE_ASSERT (this->config_.get() != 0);
- ACE_Configuration& cfg = *this->config_;
- ACE_Configuration_Section_Key root;
- int err = cfg.open_section (cfg.root_section (), SERVERS_ROOT_KEY, 0, root);
- if (err != 0)
- {
- return 0; // Already gone.
- }
- ret = cfg.remove_section (root, name.c_str (), 1);
- }
- else if (rmode_ == Options::REPO_XML_FILE)
- {
- saveAsXML (this->fname_, *this);
- }
- return ret;
+ return persistent_remove(name, false);
}
int
Locator_Repository::remove_activator (const ACE_CString& name)
{
+ int err = sync_load ();
+ if (err != 0)
+ {
+ return err;
+ }
+
int ret = activators().unbind (lcase(name));
if (ret != 0)
{
return ret;
}
- if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
- {
- ACE_ASSERT (this->config_.get () != 0);
- ACE_Configuration& cfg = *this->config_;
- ACE_Configuration_Section_Key root;
- int err = cfg.open_section (cfg.root_section (), ACTIVATORS_ROOT_KEY, 0, root);
- if (err != 0)
- {
- return 0; // Already gone.
- }
- ret = cfg.remove_section (root, name.c_str (), 1);
- }
- else if (rmode_ == Options::REPO_XML_FILE)
- {
- saveAsXML (this->fname_, *this);
- }
- return ret;
+ return persistent_remove(name, true);
}
Locator_Repository::SIMap&
@@ -617,24 +404,150 @@ Locator_Repository::servers (void)
return server_infos_;
}
+const Locator_Repository::SIMap&
+Locator_Repository::servers (void) const
+{
+ return server_infos_;
+}
+
Locator_Repository::AIMap&
Locator_Repository::activators (void)
{
return activator_infos_;
}
-const char*
-Locator_Repository::repo_mode ()
+const Locator_Repository::AIMap&
+Locator_Repository::activators (void) const
{
- switch (rmode_)
- {
- case Options::REPO_XML_FILE:
- case Options::REPO_HEAP_FILE:
- return fname_.c_str ();
- case Options::REPO_REGISTRY:
- return "Registry";
- case Options::REPO_NONE:
- return "Disabled";
- }
- return "Disabled";
+ return activator_infos_;
+}
+
+int
+Locator_Repository::sync_load ()
+{
+ // nothing more to do for default server/activator load
+ return 0;
+}
+
+bool
+Locator_Repository::registered () const
+{
+ return this->registered_;
+}
+
+UpdateableServerInfo::UpdateableServerInfo (
+ Locator_Repository* repo, const ACE_CString& name)
+: repo_(repo),
+ si_(repo->get_server (name)),
+ needs_update_(false)
+{
+}
+
+UpdateableServerInfo::UpdateableServerInfo (Locator_Repository* repo,
+ const Server_Info_Ptr& si)
+: repo_(repo),
+ si_(si),
+ needs_update_(false)
+{
+}
+
+UpdateableServerInfo::UpdateableServerInfo (const Server_Info& si)
+: repo_(0),
+ si_(new Server_Info(si)),
+ needs_update_(false)
+{
+}
+
+UpdateableServerInfo::~UpdateableServerInfo ()
+{
+ update_repo();
+}
+
+void
+UpdateableServerInfo::update_repo ()
+{
+ if (!needs_update_)
+ return;
+
+ needs_update_ = false;
+ int err = repo_->update_server (si_);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+}
+
+const Server_Info*
+UpdateableServerInfo::operator-> () const
+{
+ return si_.get();
+}
+
+const Server_Info&
+UpdateableServerInfo::operator* () const
+{
+ return *(si_.get());
+}
+
+
+const Server_Info_Ptr&
+UpdateableServerInfo::edit ()
+{
+ needs_update_ = repo_ != 0;
+ return si_;
+}
+
+void
+UpdateableServerInfo::needs_update ()
+{
+ needs_update_ = true;
+}
+
+bool
+UpdateableServerInfo::null() const
+{
+ return si_.null();
+}
+
+No_Backing_Store::No_Backing_Store (const Options& opts,
+ CORBA::ORB_ptr orb)
+ : Locator_Repository(opts, orb)
+{
+}
+
+No_Backing_Store::~No_Backing_Store ()
+{
+}
+
+const ACE_TCHAR*
+No_Backing_Store::repo_mode () const
+{
+ return ACE_TEXT ("Disabled");
}
+
+int
+No_Backing_Store::init_repo (PortableServer::POA_ptr )
+{
+ // nothing more to do for no backing store init
+ return 0;
+}
+
+int
+No_Backing_Store::persistent_update (const Server_Info_Ptr& , bool )
+{
+ // nothing more to do for no backing store update
+ return 0;
+}
+
+int
+No_Backing_Store::persistent_update (const Activator_Info_Ptr& , bool )
+{
+ // nothing more to do for no backing store update
+ return 0;
+}
+
+int
+No_Backing_Store::persistent_remove (const ACE_CString& , bool )
+{
+ // nothing more to do for no backing store remove
+ return 0;
+}
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h
index 7d7092769bc..204f1541c70 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h
@@ -20,6 +20,10 @@
#include "Activator_Info.h"
#include "Locator_Options.h"
+#include "tao/IORTable/IORTable.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "orbsvcs/IOR_Multicast.h"
+
#include "ace/Hash_Map_Manager.h"
#include "ace/Configuration.h"
#include "ace/Auto_Ptr.h"
@@ -28,6 +32,8 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+class ACE_Reactor;
+
/**
* @class Locator_Repository
*
@@ -37,22 +43,23 @@
class Locator_Repository
{
public:
- typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
+ typedef ACE_CString ServerKey;
+ typedef ACE_Hash_Map_Manager_Ex<ServerKey,
Server_Info_Ptr,
- ACE_Hash<ACE_CString>,
- ACE_Equal_To<ACE_CString>,
+ ACE_Hash<ServerKey>,
+ ACE_Equal_To<ServerKey>,
ACE_Null_Mutex> SIMap;
- typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
+ typedef ACE_CString ActivatorKey;
+ typedef ACE_Hash_Map_Manager_Ex<ActivatorKey,
Activator_Info_Ptr,
- ACE_Hash<ACE_CString>,
- ACE_Equal_To<ACE_CString>,
+ ACE_Hash<ActivatorKey>,
+ ACE_Equal_To<ActivatorKey>,
ACE_Null_Mutex> AIMap;
- Locator_Repository();
+ Locator_Repository(const Options& opts, CORBA::ORB_ptr orb);
- /// Initializes the Server Repository
- int init (const Options& opts);
+ virtual ~Locator_Repository();
int unregister_if_address_reused (const ACE_CString& server_id,
const ACE_CString& name,
@@ -61,6 +68,7 @@ public:
/// Add a new server to the Repository
int add_server (const ACE_CString& server_id,
const ACE_CString& name,
+ bool jacorbs,
const ACE_CString& aname,
const ACE_CString& startup_command,
const ImplementationRepository::EnvironmentList& environment_vars,
@@ -69,19 +77,21 @@ public:
int start_limit,
const ACE_CString& partial_ior = ACE_CString(""),
const ACE_CString& ior = ACE_CString(""),
- ImplementationRepository::ServerObject_ptr svrobj = ImplementationRepository::ServerObject::_nil()
+ ImplementationRepository::ServerObject_ptr svrobj =
+ ImplementationRepository::ServerObject::_nil()
);
/// Add a new activator to the Repository
int add_activator (const ACE_CString& name,
const CORBA::Long token,
const ACE_CString& ior = ACE_CString(""),
- ImplementationRepository::Activator_ptr act = ImplementationRepository::Activator::_nil()
+ ImplementationRepository::Activator_ptr act =
+ ImplementationRepository::Activator::_nil()
);
/// Update the associated information.
- int update_server (const Server_Info& info);
+ int update_server (const Server_Info_Ptr& info);
/// Update the associated information.
- int update_activator (const Activator_Info& info);
+ int update_activator (const Activator_Info_Ptr& info);
/// Returns information related to startup.
Server_Info_Ptr get_server (const ACE_CString& name);
@@ -97,25 +107,154 @@ public:
/// Returns the internal hash map containing the server information.
SIMap& servers(void);
+ const SIMap& servers(void) const;
/// Returns the internal hash map containing the activator information.
AIMap& activators(void);
+ const AIMap& activators(void) const;
+
+ /// indicate the persistence mode for the repository
+ virtual const ACE_TCHAR* repo_mode() const = 0;
+
+ /// convert to lower case
+ static ACE_CString lcase (const ACE_CString& s);
+
+ /// Initialize the repo
+ int init(PortableServer::POA_ptr root_poa,
+ PortableServer::POA_ptr imr_poa,
+ const char* this_ior);
+
+ /// Indicate if multicast should be used
+ bool multicast() const;
+
+protected:
+ /// perform repo mode specific initialization
+ virtual int init_repo(PortableServer::POA_ptr imr_poa) = 0;
+
+ /// perform sync of repo with backing store
+ /// defaults to no-op, only shared backing stores
+ /// need to sync
+ virtual int sync_load();
+
+ /// perform server persistent update
+ virtual int persistent_update(const Server_Info_Ptr& info, bool add) = 0;
+
+ /// perform activator persistent update
+ virtual int persistent_update(const Activator_Info_Ptr& info, bool add) = 0;
+
+ /// perform persistent remove
+ virtual int persistent_remove(const ACE_CString& name, bool activator) = 0;
+
+ /// report the ImR Locator's IOR
+ virtual int report_ior(PortableServer::POA_ptr imr_poa);
+
+ int setup_multicast (ACE_Reactor* reactor, const char* imr_ior);
+ void teardown_multicast();
- const char* repo_mode();
+ bool registered() const;
+
+ const Options& opts_;
+ TAO_IOR_Multicast ior_multicast_;
+ const CORBA::ORB_var orb_;
+ CORBA::String_var imr_ior_;
private:
- /// Type mechanism to use for persistence.
- Options::RepoMode rmode_;
+ bool registered_;
/// The in-memory list of the server information.
SIMap server_infos_;
/// The in-memory list of the activator information.
AIMap activator_infos_;
- /// Several rmode_ values require this.
- ACE_Auto_Ptr<ACE_Configuration> config_;
- /// XML requires the file name
- ACE_CString fname_;
+};
+
+/**
+* @class XML_Backing_Store
+*
+* @brief XML backing store interface containing all ImR persistent information
+* in a single file
+*
+*/
+class No_Backing_Store : public Locator_Repository
+{
+public:
+ No_Backing_Store(const Options& opts,
+ CORBA::ORB_ptr orb);
- unsigned int debug_;
+ virtual ~No_Backing_Store();
+
+ /// indicate the persistence mode for the repository
+ virtual const ACE_TCHAR* repo_mode() const;
+
+private:
+ /// perform repo mode specific initialization (no-op)
+ virtual int init_repo(PortableServer::POA_ptr imr_poa);
+
+ /// perform server persistent update (no-op)
+ virtual int persistent_update(const Server_Info_Ptr& info, bool add);
+
+ /// perform activator persistent update (no-op)
+ virtual int persistent_update(const Activator_Info_Ptr& info, bool add);
+
+ /// perform persistent remove (no-op)
+ virtual int persistent_remove(const ACE_CString& name, bool activator);
};
+/**
+* @class UpdateableServerInfo
+*
+* @brief Class for managing changes to ServerInfo memory to ensure
+* it is persisted
+*
+*/
+class UpdateableServerInfo
+{
+public:
+ /// constructor
+ /// @param repo the repo to report updates to
+ /// @param name the name of the server to retrieve
+ UpdateableServerInfo(Locator_Repository* repo, const ACE_CString& name);
+
+ /// constructor
+ /// @param repo the repo to report updates to
+ /// @param si an already retrieved Server_Info_Ptr
+ UpdateableServerInfo(Locator_Repository* repo, const Server_Info_Ptr& si);
+
+ /// constructor (no repo updates will be performed)
+ /// @param si a Server_Info to create a non-stored Server_Info_Ptr from
+ UpdateableServerInfo(const Server_Info& si);
+
+ /// destructor (updates repo if needed)
+ ~UpdateableServerInfo();
+
+ /// explicitly update repo if needed
+ void update_repo();
+
+ /// const Server_Info access
+ const Server_Info* operator->() const;
+
+ /// const Server_Info& access
+ const Server_Info& operator*() const;
+
+ /// retrieve smart pointer to non-const Server_Info
+ /// and indicate repo update required
+ const Server_Info_Ptr& edit();
+
+ /// force indication of update needed
+ void needs_update();
+
+ /// indicate it Server_Info_Ptr is null
+ bool null() const;
+private:
+ UpdateableServerInfo(const UpdateableServerInfo& );
+ const UpdateableServerInfo& operator=(const UpdateableServerInfo& );
+
+ /// the repo
+ Locator_Repository* const repo_;
+
+ /// the retrieved, passed, or non-stored server info
+ const Server_Info_Ptr si_;
+
+ /// the server info has changes and needs to be updated to the repo
+ bool needs_update_;
+};
+
#endif /* REPOSITORY_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp
index cca3d951a82..765edf5deef 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp
@@ -1,18 +1,39 @@
// $Id$
#include "Locator_XMLHandler.h"
+#include "XML_Backing_Store.h"
+#include "utils.h"
#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_sys_time.h"
const ACE_TCHAR* Locator_XMLHandler::ROOT_TAG = ACE_TEXT("ImplementationRepository");
const ACE_TCHAR* Locator_XMLHandler::SERVER_INFO_TAG = ACE_TEXT("Servers");
const ACE_TCHAR* Locator_XMLHandler::ACTIVATOR_INFO_TAG = ACE_TEXT("Activators");
const ACE_TCHAR* Locator_XMLHandler::ENVIRONMENT_TAG = ACE_TEXT("EnvironmentVariables");
-Locator_XMLHandler::Locator_XMLHandler (Callback& cb)
-: callback_ (cb)
+Locator_XMLHandler::Locator_XMLHandler (XML_Backing_Store& repo,
+ CORBA::ORB_ptr orb)
+: repo_(repo),
+ start_limit_(0),
+ server_started_(false),
+ repo_id_(0),
+ repo_type_(0),
+ orb_(CORBA::ORB::_duplicate(orb))
{
}
+static void convertEnvList (const Locator_XMLHandler::EnvList& in,
+ ImplementationRepository::EnvironmentList& out)
+{
+ CORBA::ULong sz = in.size ();
+ out.length (sz);
+ for (CORBA::ULong i = 0; i < sz; ++i)
+ {
+ out[i].name = in[i].name.c_str ();
+ out[i].value = in[i].value.c_str ();
+ }
+}
+
void
Locator_XMLHandler::startElement (const ACEXML_Char*,
const ACEXML_Char*,
@@ -25,31 +46,60 @@ Locator_XMLHandler::startElement (const ACEXML_Char*,
// We'll use this as a key to determine if we've got a valid record
this->server_name_ = ACE_TEXT("");
this->env_vars_.clear();
+ this->jacorb_server_ = false;
- if (attrs != 0 && attrs->getLength () == 9)
+ // if attrs exists and if the previously required 9 fields
+ const size_t previous_size = 9;
+ if (attrs != 0 && attrs->getLength () >= previous_size)
{
- this->server_id_ = attrs->getValue ((size_t)0);
- this->server_name_ = attrs->getValue ((size_t)1);
- this->activator_name_ = attrs->getValue ((size_t)2);
- this->command_line_ = attrs->getValue ((size_t)3);
- this->working_dir_ = attrs->getValue ((size_t)4);
- this->activation_ = attrs->getValue ((size_t)5);
+ size_t index = 0;
+ this->server_id_ = attrs->getValue (index++);
+ this->server_name_ = attrs->getValue (index++);
+ this->activator_name_ = attrs->getValue (index++);
+ this->command_line_ = attrs->getValue (index++);
+ this->working_dir_ = attrs->getValue (index++);
+ this->activation_ = attrs->getValue (index++);
this->env_vars_.clear ();
- int limit = ACE_OS::atoi (attrs->getValue ((size_t)6));
+ int limit = ACE_OS::atoi (attrs->getValue (index++));
this->start_limit_ = limit;
- this->partial_ior_ = attrs->getValue ((size_t)7);
- this->server_object_ior_ = attrs->getValue ((size_t)8);
+ this->partial_ior_ = attrs->getValue (index++);
+ this->server_object_ior_ = attrs->getValue (index++);
+
+ if (attrs->getLength () >= index)
+ {
+ this->server_started_ =
+ (ACE_OS::atoi (attrs->getValue (index++)) != 0);
+ }
+ if (attrs->getLength () >= index)
+ {
+ this->jacorb_server_ =
+ (ACE_OS::atoi (attrs->getValue (index++)) != 0);
+ }
+ for ( ; index < attrs->getLength(); ++index)
+ {
+ this->extra_params_.push_back(std::make_pair(
+ attrs->getLocalName(index), attrs->getValue(index)));
+ }
}
}
else if (ACE_OS::strcasecmp (qName, ACTIVATOR_INFO_TAG) == 0)
{
- if (attrs != 0 && attrs->getLength () == 3)
+ if (attrs != 0 && attrs->getLength () >= 3)
{
- ACE_CString aname = ACE_TEXT_ALWAYS_CHAR(attrs->getValue ((size_t)0));
- ACE_TString token_str = attrs->getValue ((size_t)1);
+ size_t index = 0;
+ const ACE_CString aname =
+ ACE_TEXT_ALWAYS_CHAR(attrs->getValue (index++));
+ const ACE_TString token_str = attrs->getValue (index++);
long token = ACE_OS::atoi (token_str.c_str ());
- ACE_CString ior = ACE_TEXT_ALWAYS_CHAR(attrs->getValue ((size_t)2));
- this->callback_.next_activator (aname, token, ior);
+ const ACE_CString ior =
+ ACE_TEXT_ALWAYS_CHAR(attrs->getValue (index++));
+ NameValues extra_params;
+ for ( ; index < attrs->getLength(); ++index)
+ {
+ extra_params.push_back(std::make_pair(
+ attrs->getLocalName(index), attrs->getValue(index)));
+ }
+ this->repo_.load_activator (aname, token, ior, extra_params);
}
}
else if (ACE_OS::strcasecmp (qName, ENVIRONMENT_TAG) == 0)
@@ -73,11 +123,25 @@ Locator_XMLHandler::endElement (const ACEXML_Char*,
if (ACE_OS::strcasecmp (qName, SERVER_INFO_TAG) == 0
&& this->server_name_.length () > 0)
{
- this->callback_.next_server (
- this->server_id_, this->server_name_,
- this->activator_name_, this->command_line_,
- this->env_vars_, this->working_dir_, this->activation_,
- this->start_limit_, this->partial_ior_, this->server_object_ior_);
+ const int limit = this->start_limit_ < 1 ? 1 : this->start_limit_;
+ ImplementationRepository::ActivationMode amode =
+ ImR_Utils::parseActivationMode (this->activation_);
+
+ ImplementationRepository::EnvironmentList env_vars;
+ convertEnvList (this->env_vars_, env_vars);
+ this->repo_.load_server(this->server_id_,
+ this->server_name_,
+ this->jacorb_server_,
+ this->activator_name_,
+ this->command_line_,
+ env_vars,
+ this->working_dir_,
+ amode,
+ limit,
+ this->partial_ior_,
+ this->server_object_ior_,
+ this->server_started_,
+ this->extra_params_);
}
// activator info is handled in the startElement
}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h
index 643ea3408f3..4bffbdfb3cb 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h
@@ -14,19 +14,23 @@
#include "ACEXML/common/DefaultHandler.h"
-#include "ace/Vector_T.h"
+#include "tao/ORB.h"
+
+#include <vector>
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+class XML_Backing_Store;
/**
- * Callback SAX XML Handler for parsing XML.
+ * Callback SAX XML Handler for parsing Locator XML.
*/
class Locator_XMLHandler : public ACEXML_DefaultHandler
{
public:
-
+ typedef std::pair<ACE_CString, ACE_CString> NameValue;
+ typedef std::vector<NameValue> NameValues;
// XML ELEMENT names
static const ACE_TCHAR* ROOT_TAG;
static const ACE_TCHAR* SERVER_INFO_TAG;
@@ -40,41 +44,32 @@ public:
bool operator!=(const EnvVar&) const; // To allow Vector explicit instantiation
};
- typedef ACE_Vector<EnvVar> EnvList;
-
- struct Callback {
- virtual ~Callback() {}
-
- virtual void next_server (const ACE_CString& server_id,
- const ACE_CString& server_name, const ACE_CString& aname,
- const ACE_CString& startup_cmd, const EnvList& env_vars,
- const ACE_CString& working_dir, const ACE_CString& actmode,
- int start_limit, const ACE_CString& partial_ior,
- const ACE_CString& ior) = 0;
+ typedef std::vector<EnvVar> EnvList;
- virtual void next_activator (const ACE_CString& activator_name,
- long token,
- const ACE_CString& ior) = 0;
- };
-
- Locator_XMLHandler (Callback& cb);
+ /// constructor
+ /// @param repo the repo to update based on XML
+ /// @param orb the orb (used to create server object)
+ Locator_XMLHandler (XML_Backing_Store& repo, CORBA::ORB_ptr orb);
+ /// provide implementation for handling a new XML element
virtual void startElement (const ACEXML_Char* namespaceURI,
const ACEXML_Char* localName,
const ACEXML_Char* qName,
ACEXML_Attributes* atts);
+ /// provide implementation for handling terminating an XML element
virtual void endElement (const ACEXML_Char* namespaceURI,
const ACEXML_Char* localName,
const ACEXML_Char* qName);
private:
+ /// the repository
+ XML_Backing_Store& repo_;
- // callback on completion of an element
- Callback& callback_;
-
+ /// the server related parameters
ACE_CString server_id_;
ACE_TString server_name_;
+ bool jacorb_server_;
ACE_TString activator_name_;
ACE_TString command_line_;
ACE_TString activation_;
@@ -82,7 +77,14 @@ public:
ACE_TString server_object_ior_;
ACE_TString partial_ior_;
int start_limit_;
+ bool server_started_;
+ NameValues extra_params_;
+ unsigned int repo_id_;
+ unsigned int repo_type_;
EnvList env_vars_;
+
+ /// the orb
+ CORBA::ORB_var orb_;
};
#endif /* Locator_XMLHandler_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/README b/TAO/orbsvcs/ImplRepo_Service/README
index 9579012f2d7..c5465941cc1 100644
--- a/TAO/orbsvcs/ImplRepo_Service/README
+++ b/TAO/orbsvcs/ImplRepo_Service/README
@@ -1,5 +1,7 @@
/** -*- HTML-Helper -*- $Id$
+$Id$
+
@mainpage Implementation Repository
@section intro Introduction
@@ -30,7 +32,7 @@ as the specification for TAO's ImR.
@ref ntservice - Running the ImR as a NT Service
-@ref imrandnaming - Using the Naming Service with the Implmentation Repository
+@ref imrandnaming - Using the Naming Service with the Implementation Repository
@ref movefromoldImR - Moving from IMR as in TAO 1.2.2 to the present version.
@@ -63,7 +65,7 @@ As with any program, there is always a wishlist of things to do.
@subsection ort Use Object Reference Template (ORT) Features
- Use ORT so that the ImR-ified IORs doesnt have any information
+ Use ORT so that the ImR-ified IORs doesn't have any information
about the ImR_Activators. Right now, even though, the ImplRepo_Service is
the one that is exposed to the client, the IOR will have a reference
to the ImR_Activator. By using ORT features, we want the IOR to refer
@@ -138,7 +140,7 @@ Nothing yet.
@subsection XML Database Support
As of now, the support is only to be able to have the information
- about a registered server written to an XML file. Have to support
+ about a registered server written to an XML file. Have to support
retrieving information from the XML file to be able to do any actions
on the registered servers.
@@ -161,7 +163,7 @@ communicate with an Implementation Repository, if one is available.
@subsection description The New ImR
- The new ImR is based on the ImR in TAO 1.2.2 with added
+ The new ImR is based on the ImR in TAO 1.2.2 with added
features to help improve throughput and load balancing. The work to be
performed by the Implementation Repository is distributed between two
entities (ImplRepo_Service and ImR_Activator) to help achieve the goal of
@@ -169,7 +171,7 @@ better throughput and load balance.
@subsection locator ImplRepo_Service
- The ImplRepo_Service acts as the main server which is visible to
+ The ImplRepo_Service acts as the main server which is visible to
the application intending to use the ImR. It receives requests sent
via tao_ImR and distributes the work to the registered ImR_Activators.
It is stateless and does not maintain any information except about the
@@ -186,39 +188,118 @@ Commandline Arguments that can be passed to ImplRepo_Service
-o generate the ior.
-x support persistence to the ImplRepo_Service. We use XML to support
persistence. Names of the activators registered with the locator,
- their IORs, and the servers registered with each of the activators are
- saved to the xml file. Use this option to pass the name of the file
- where the data has to be saved.
-
- And, ofcourse, the ORB Options.
+ their IORs, and the servers registered with each of the activators are
+ saved to the xml file. Use this option to pass the name of the file
+ where the data has to be saved.
+-p similar to "-x" but using an ACE_Configuration_Heap file to persist
+ the data.
+-r similar to "-p" but using an ACE_Configuration_Win32Registry to persist
+ the data. (only available on Win32 platforms)
+--directory similar to "-x" option, but the repository will be written out
+ to multiple files in the indicated directory: "imr_listings.xml" which
+ indicates all servers and activators in the repository indicating the
+ filename containing that server's or activator's persistence data.
+ This option is used along with the "--primary" or "--backup" option
+ to create a Fault Tolerant ImplRepo_Service.
+--primary pass along with "--directory <dir>" to startup the primary
+ ImR_Locator. See ft_imr_locator subsection.
+--backup pass along with "--directory <dir>" to startup the backup
+ ImR_Locator. See ft_imr_locator subsection.
+
+ And, of course, the ORB Options.
+
+@subsection ft_imr_locator FaultTolerant_ImR_Locator
+
+The ImR_Locator implements a fault tolerant service with the following options:
+
+ The --primary option tells the ImR_Locator that it will startup as the primary
+ in a redundant service pair.
+
+ The --backup option tells the ImR_Locator that it will startup as the backup
+ in a redundant service pair.
+
+ The --directory <ft_imr_shared_dir> option tells the ImR_Locator the shared
+ file system directory to use as the backing store for the redundant service
+ pair.
+
+ The -o <ft_imr_ior_filename> option tells the ImR_Locator to output the
+ redundant service pair ImRService ior file, which it can only do after
+ successfully starting the primary and backup ImRService instances. The ior
+ file contains the combined profiles of the primary and backup ImRLocators. The
+ client must use the ior file to use the fault tolerent ImplRepo_Service.
+
+The primary and backup ImRLocator instances should have the same ORBEndPoint
+protocol list so that any client can send a request to either primary or backup
+regardless of protocol (IIOP,UIOP,etc...).
+
+The ImR_Locator primary and backup options cannot be passed on the command
+line along with -ORBObjRefStyle URL, since that style will cause the backup
+profile to not be available in the ior.
+
+At startup the primary must be started first, then the backup. When
+a single ImR_Locator goes down, it can be restarted at anytime
+(using the same ORBEndPoints). If they are both shutdown then Fault Tolerant
+ImplRepo_Service will be down until both the primary and backup are restarted
+in that order.. The previous ior file will only remain valid if the ORBEndPoint
+list remains the same for both instances.
+
+As long as both the primary and backup ImR_Locators are not shutdown at the
+same time the Fault Tolerant ImplRepo_Service will always be available.
+
+@subsection ft_imr_locator_startup FaultTolerant_ImR_Locator Startup
+<ol>
+ <li>
+ <em>Start the primary.</em><br>
+ It will write the replication ior to a file in the shared persistence
+ directory.<br>
+ <code>
+ tao_imr_locator
+ --primary
+ -ORBEndpoint <primary_hostname:port>
+ --directory <ft_imr_shared_dir>
+ </code>
+ </li>
+ <li>
+ </em>Start the backup.</em><br>
+ Reads the primary replication ior from the shared persistence directory.<br>
+ Writes the multi-profile ior to ft_imr_ior_filename<br>.
+ <code>
+ tao_imr_locator
+ --backup
+ -ORBEndpoint <backup_hostname:port>
+ --directory <ft_imr_shared_dir>
+ -o <ft_imr_ior_filename>
+ </code>
+ </li>
+</ol>
@subsection activator ImR_Activator
- ImR_Activators, as you might have guessed, do the real work of
+ ImR_Activators, as you might have guessed, do the real work of
activating servers or shutting them down and maintaining the information
about servers related to them. Only one instance of an ImR_Activator
can be run on one host. The ImR_Activator is not exposed at all to the
application. Only the ImplRepo_Service needs to and it is the only one that
can contact the ImR_Activator.
- An instance of ImR_Activator first registers itself with the
+ An instance of ImR_Activator first registers itself with the
ImplRepo_Service so that it can begin to receive requests. When registering
with the ImplRepo_Service, it passes the hostname where it is being run and
its IOR to the ImplRepo_Service. And, the ImplRepo_Service reaches it using the
same information.
-The Commandline paramters that are valid for ImR_Activator are
+The Commandline parameters that are valid for ImR_Activator are
--c: Run the Service command.
+-c: Run the Service command.
-d:number Debug Information
--l lock the database.
--o Generate the IOR to a file (just in case some one wants
- to read the IOR)
--r Enable Win32 regsitry implementation.
--s Run as a service.
--t Set a timeout value.
--h Prints the help.
+-l lock the database.
+-o Generate the IOR to a file (just in case some one wants to read the
+ IOR)
+-r Enable Win32 regsitry implementation.
+-s Run as a service.
+-t Set a timeout value.
+-h Prints the help.
When Persistence of an ImR_Activator is required, we will save
the information about the server's that this ImR_Activator is related
@@ -227,44 +308,44 @@ information about each server include its startup options, location,
working directory which are needed to execute the requests that can
passed by tao_imr with regards to the server.
- There are two ways in which you can store data in the
+ There are two ways in which you can store data in the
file. One way is to use ACE_Configuration_Heap to save all
the information to the file. To do this, we have to pass the '-p' option.
--p Pass the ImplRepo service a filename to use for the
+-p Pass the ImplRepo service a filename to use for the
backing store. Uses ACE_Configuration_Heap.
- The second way is to save in XML-ized format.
+ The second way is to save in XML-ized format.
--x Pass the filename where the repository information should
+-x Pass the filename where the repository information should
be saved. Use XML format.
@subsection work So how does the whole thing work?
- The first thing to do is to have an ImplRepo_Service running. Once
+ The first thing to do is to have an ImplRepo_Service running. Once
the ImplRepo_Service is running, we can instantiate one or more ImR_Activators
as needed per the application. As mentioned already, the
ImR_Activators, upon instantiation, register with the ImplRepo_Service to
be able to receive requests.
- When a new server has to be added or any change has to the
+ When a new server has to be added or any change has to the
done to an existing server, a request is to be sent to the ImplRepo_Service
via the tao_imr utility. Startup commands, the working directory, the
host where the server should be started up and such other information
-are passed to the ImplRepo_Service via the TAO_ImR commandline arguments.
+are passed to the ImplRepo_Service via the TAO_ImR command line arguments.
- If the host where the server should be started up is passed
+ If the host where the server should be started up is passed
while adding a new server, the ImplRepo_Service chooses the ImR_Activator
that is running on that host to be responsible for the server's
activities. Otherwise, an ImR_Activator is chosen based on the Round
robin algorithm. We plan to use better algorithms based on the
existing load for the same purpose in future. Whatever way the
ImR_Activator is chosen for a server, once an ImR_Activator is chosen,
-that ImR_Activator remains reponsible for the server throughout the
+that ImR_Activator remains responsible for the server throughout the
server's lifetime.
- After an ImR_Activator is chosen, the ImplRepo_Service passes the
+ After an ImR_Activator is chosen, the ImplRepo_Service passes the
request to the chosen ImR_Activator. The ImR_Activator acts on the request
and updates its database to reflect the new state of the server.
@@ -459,13 +540,13 @@ registered to it each time it starts up. The way to accomplish this is to add<br
to the ImR_Activator's startup command line. The host
name can be obtained portably in C++ code with the lines<br>
- ACE_INET_addr ad;<br>
- char *hostname = ad.get_host_name ();<br>
+ ACE_INET_addr ad;<br>
+ char *hostname = ad.get_host_name ();<br>
or in a Perl script by adding<br>
- use Sys::Hostname;<br>
- $hostname = hostname();<br>
+ use Sys::Hostname;<br>
+ $hostname = hostname();<br>
There are even specific port numbers, assigned to the OMG by the IANA,
which can be used for this purpose. They are 683 (for IIOP) and 684
@@ -574,7 +655,7 @@ balance.
<b>.</b> The added step that you would have to now do is run the
ImR_Activator. You can just run one instance of it to get the same
-behaviour as you were getting before.
+behavior as you were getting before.
If you run the ImplRepo_Service in multicast mode, the
ImR_Activator will be able to get access to it via
@@ -588,3 +669,4 @@ now be passed to the ImR_Activator since that is the one that is
dealing with the database.
*/
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp b/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp
index d87476130f8..23ad5469001 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp
@@ -5,6 +5,7 @@ Server_Info::Server_Info
(
const ACE_CString& serverId,
const ACE_CString& server_name,
+ bool jacorbs,
const ACE_CString& aname,
const ACE_CString& cmdline,
const ImplementationRepository::EnvironmentList& env,
@@ -16,6 +17,7 @@ Server_Info::Server_Info
ImplementationRepository::ServerObject_ptr svrobj)
: server_id (serverId)
, name (server_name)
+ , jacorb_server( jacorbs)
, activator (aname)
, cmdline( cmdline)
, env_vars (env)
@@ -32,12 +34,22 @@ Server_Info::Server_Info
}
ImplementationRepository::ServerInformation*
-Server_Info::createImRServerInfo (void)
+Server_Info::createImRServerInfo (void) const
{
ImplementationRepository::ServerInformation* info;
- ACE_NEW_THROW_EX (info, ImplementationRepository::ServerInformation, CORBA::NO_MEMORY ());
+ ACE_NEW_THROW_EX (info,
+ ImplementationRepository::ServerInformation,
+ CORBA::NO_MEMORY ());
+
+ info->startup.command_line = cmdline.c_str ();
+ if (jacorb_server)
+ {
+ ACE_CString jacorb_name (ACE_TEXT ("JACORB:") + name);
+ info->server = jacorb_name.c_str();
+ }
+ else
+ info->server = name.c_str();
- info->server = name.c_str ();
info->startup.command_line = cmdline.c_str ();
info->startup.environment = env_vars;
info->startup.working_directory = dir.c_str ();
@@ -63,5 +75,6 @@ Server_Info::reset (void)
partial_ior = "";
last_ping = ACE_Time_Value::zero;
server = ImplementationRepository::ServerObject::_nil ();
- // start_count = 0; Note : We can't do this, because it would be reset during startup.
+ // start_count = 0; Note : We can't do this, because it would
+ // be reset during startup.
}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Server_Info.h b/TAO/orbsvcs/ImplRepo_Service/Server_Info.h
index 12403532beb..a1deb9f6acb 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Server_Info.h
+++ b/TAO/orbsvcs/ImplRepo_Service/Server_Info.h
@@ -30,6 +30,7 @@ struct Server_Info
{
Server_Info (const ACE_CString& serverId,
const ACE_CString& name,
+ bool jacorbs,
const ACE_CString& aname,
const ACE_CString& cmdline,
const ImplementationRepository::EnvironmentList& env,
@@ -42,13 +43,14 @@ struct Server_Info
);
/// Convert to the corba type
- ImplementationRepository::ServerInformation* createImRServerInfo(void);
+ ImplementationRepository::ServerInformation* createImRServerInfo(void) const;
void reset();
/// The name of the server.
ACE_CString server_id;
ACE_CString name;
+ bool jacorb_server;
/// The name of the activator in which this server runs
ACE_CString activator;
diff --git a/TAO/orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp b/TAO/orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp
new file mode 100644
index 00000000000..b4cbb0dafff
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Shared_Backing_Store.cpp
@@ -0,0 +1,1366 @@
+// $Id$
+
+#include "Shared_Backing_Store.h"
+#include "Server_Info.h"
+#include "Activator_Info.h"
+#include "utils.h"
+#include "Locator_XMLHandler.h"
+#include "ImR_LocatorC.h"
+#include "ace/File_Lock.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/OS_NS_unistd.h"
+#include "ACEXML/parser/parser/Parser.h"
+#include "ACEXML/common/FileCharStream.h"
+#include "ACEXML/common/XML_Util.h"
+#include "tao/IORManipulation/IORManip_Loader.h"
+
+namespace {
+ class Lockable_File
+ {
+ public:
+ Lockable_File()
+ : file_(0),
+ flags_(0),
+ locked_(false),
+ unlink_in_destructor_(false)
+ {
+ }
+
+ Lockable_File(const ACE_TString& file,
+ const int flags,
+ bool unlink_in_destructor = false)
+ : file_(0),
+ flags_(0),
+ locked_(false),
+ unlink_in_destructor_(false)
+ {
+ init_fl(file, flags, unlink_in_destructor);
+ }
+
+ ~Lockable_File()
+ {
+ release();
+ }
+
+ void release()
+ {
+ if (this->file_ == 0)
+ return;
+
+ close_file();
+ this->file_lock_.reset();
+ this->locked_ = false;
+ }
+
+ FILE* get_file()
+ {
+ lock();
+
+ return this->file_;
+ }
+
+ FILE* get_file(const ACE_TString& file,
+ const int flags,
+ bool unlink_in_destructor = false)
+ {
+ init_fl(file, flags, unlink_in_destructor);
+ return get_file();
+ }
+
+ private:
+ void init_fl(const ACE_TString& file,
+ const int flags,
+ bool unlink_in_destructor = false)
+ {
+ release();
+
+ flags_ = flags | O_CREAT;
+ unlink_in_destructor_ = unlink_in_destructor;
+
+ const ACE_TCHAR* const flags_str =
+ ((flags_ & O_RDWR) != 0) ? ACE_TEXT("r+") :
+ (((flags_ & O_WRONLY) != 0) ? ACE_TEXT("w") : ACE_TEXT("r"));
+#ifdef ACE_WIN32
+ this->filename_ = file;
+ this->file_ = ACE_OS::fopen(file.c_str(), flags_str);
+#else
+ this->file_lock_.reset(
+ new ACE_File_Lock(ACE_TEXT_CHAR_TO_TCHAR(file.c_str ()),
+ flags_,
+ 0666,
+ unlink_in_destructor));
+
+ // Truncating output so this will not allow reading then writing
+
+ ACE_OS::ftruncate(this->file_lock_->get_handle(), 0);
+ this->file_ = ACE_OS::fdopen(this->file_lock_->get_handle(), flags_str);
+#endif
+ }
+
+ void close_file()
+ {
+ if (this->file_ == 0)
+ return;
+
+ ACE_OS::fflush(this->file_);
+ ACE_OS::fclose(this->file_);
+ this->file_ = 0;
+#ifdef ACE_WIN32
+ if (this->unlink_in_destructor_)
+ {
+ ACE_OS::unlink(this->filename_.c_str());
+ this->unlink_in_destructor_ = false;
+ }
+#endif
+ }
+
+ void lock()
+ {
+#ifndef ACE_WIN32
+ if (this->locked_)
+ return;
+
+ if ((this->flags_ & O_RDWR) != 0)
+ file_lock_->acquire();
+ if ((this->flags_ & O_WRONLY) != 0)
+ file_lock_->acquire_write();
+ else
+ file_lock_->acquire_read();
+
+ this->locked_ = true;
+#endif
+ }
+
+ auto_ptr<ACE_File_Lock> file_lock_;
+ FILE* file_;
+ int flags_;
+ bool locked_;
+ bool unlink_in_destructor_;
+ ACE_TString filename_;
+ };
+}
+
+Shared_Backing_Store::Shared_Backing_Store(const Options& opts,
+ CORBA::ORB_ptr orb)
+: XML_Backing_Store(opts, orb, true),
+ listing_file_(opts.persist_file_name() + ACE_TEXT("imr_listing.xml")),
+ seq_num_(0),
+ replica_seq_num_(0),
+ imr_type_(opts.imr_type()),
+ sync_needed_(NO_SYNC),
+ repo_id_(1),
+ repo_values_(2)
+{
+ IMR_REPLICA[Options::PRIMARY_IMR] = ACE_TEXT ("ImR_ReplicaPrimary");
+ IMR_REPLICA[Options::BACKUP_IMR] = ACE_TEXT ("ImR_ReplicaBackup");
+ IMR_REPLICA[Options::STANDALONE_IMR] = ACE_TEXT ("ImR_NoReplica");
+
+ this->repo_values_[REPO_TYPE] =
+ std::make_pair(ACE_CString(ACE_TEXT ("repo_type")),
+ ACE_CString());
+ this->repo_values_[REPO_ID] =
+ std::make_pair(ACE_CString(ACE_TEXT ("repo_id")),
+ ACE_CString());
+}
+
+Shared_Backing_Store::~Shared_Backing_Store()
+{
+}
+
+
+static void replicate(
+ Shared_Backing_Store::Replica_ptr replica,
+ const ImplementationRepository::ServerUpdate& update)
+{
+ // replicate the ServerUpdate to our replicated locator
+ replica->notify_updated_server(update);
+}
+
+static void replicate(
+ Shared_Backing_Store::Replica_ptr replica,
+ const ImplementationRepository::ActivatorUpdate& update)
+{
+ // replicate the ActivatorUpdate to our replicated locator
+ replica->notify_updated_activator(update);
+}
+
+static void set_key(ImplementationRepository::ServerUpdate& update,
+ const Locator_Repository::SIMap::KEY& key)
+{
+ update.name = key.c_str();
+}
+
+static void set_key(ImplementationRepository::ActivatorUpdate& update,
+ const Locator_Repository::AIMap::KEY& key)
+{
+ update.name = key.c_str();
+}
+
+template< typename Update, typename Map>
+static void replicate(
+ Shared_Backing_Store::Replica_ptr replica,
+ const typename Map::ENTRY& entry,
+ const ImplementationRepository::UpdateType type,
+ const ImplementationRepository::SequenceNum seq_num)
+{
+ if (CORBA::is_nil (replica))
+ {
+ return;
+ }
+
+ try
+ {
+ Update update;
+ set_key(update, entry.ext_id_);
+ update.type = type;
+ update.seq_num = seq_num;
+ update.repo_id = entry.int_id_.repo_id;
+ update.repo_type = entry.int_id_.repo_type;
+ replicate(replica, update);
+ }
+ catch (const CORBA::COMM_FAILURE&)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("(%P|%t) Replicated ImR: COMM_FAILURE Exception\n")));
+ }
+ catch (const CORBA::TRANSIENT&)
+ {
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT("(%P|%t) Replicated ImR: TRANSIENT Exception\n")));
+ }
+ catch (const CORBA::OBJECT_NOT_EXIST&)
+ {
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT("(%P|%t) Replicated ImR: OBJECT_NOT_EXIST ")
+ ACE_TEXT("Exception, dropping replica\n")));
+ replica = TAO::Objref_Traits
+ <ImplementationRepository::UpdatePushNotification>::nil ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT("Replicated ImR: notify update"));
+ replica = 0;
+ }
+}
+
+template<typename Map>
+static typename Map::ENTRY& unique_id(
+ const typename Map::KEY& key,
+ Map& unique_ids,
+ const Shared_Backing_Store::UniqueId& id)
+{
+ typename Map::ENTRY* entry = 0;
+ unique_ids.bind(key, id, entry);
+
+ return *entry;
+}
+
+static Shared_Backing_Store::UniqueId create_uid(
+ const Options::ImrType repo_type,
+ const unsigned int repo_id)
+{
+ Shared_Backing_Store::UniqueId id;
+ id.repo_id = repo_id;
+ id.repo_type = repo_type;
+ ACE_TCHAR id_str[50];
+ ACE_OS::itoa((unsigned int)repo_type, id_str, 10);
+
+ id.repo_type_str = id_str;
+
+ size_t current = ACE_OS::strlen(id_str);
+ id_str[current++] = ACE_TEXT('_');
+ ACE_OS::itoa(repo_id, &(id_str[current]), 10);
+
+ id.repo_id_str = &(id_str[current]);
+
+ current = ACE_OS::strlen(id_str);
+ id_str[current++] = ACE_TEXT('.');
+ id_str[current++] = ACE_TEXT('x');
+ id_str[current++] = ACE_TEXT('m');
+ id_str[current++] = ACE_TEXT('l');
+ id_str[current++] = ACE_TEXT('\0');
+ id.unique_filename = id_str;
+
+ return id;
+}
+
+template<typename Map>
+static const typename Map::ENTRY& unique_id(
+ const typename Map::KEY& key,
+ Map& unique_ids,
+ const Options::ImrType type,
+ unsigned int& next_repo_id)
+{
+ typename Map::ENTRY* entry;
+ if (unique_ids.find(key, entry) == 0)
+ return *entry;
+ const unsigned int repo_id = next_repo_id++;
+ Shared_Backing_Store::UniqueId id = create_uid(type, repo_id);
+ return unique_id(key, unique_ids, id);
+}
+
+static ACE_CString identify_key(const ACE_CString& name)
+{
+ ACE_CString id("name=");
+ id += name;
+ return id;
+}
+
+/* TODO: bdj - will need this when server container changed to name and id
+static ACE_CString identify_key(const Shared_Backing_Store::ServerKey& name)
+{
+ ACE_CString id("name=");
+ id += info.name;
+ return id;
+}
+*/
+template<typename Map>
+static const typename Map::ENTRY& unique_id(
+ const typename Map::KEY& key,
+ Map& unique_ids,
+ const Options::ImrType this_repo_type,
+ unsigned int& this_repo_id,
+ Options::ImrType& entry_repo_type,
+ unsigned int& entry_repo_id)
+{
+ typename Map::ENTRY* temp_entry;
+ const bool found = (unique_ids.find(key, temp_entry) == 0);
+
+ Shared_Backing_Store::UniqueId temp_id =
+ create_uid(entry_repo_type, entry_repo_id);
+ typename Map::ENTRY& entry = unique_id(key, unique_ids, temp_id);
+
+ if (entry_repo_id == 0)
+ {
+ // if no repo id provided, treat it like it came from this repo
+ entry_repo_id = this_repo_id++;
+ entry_repo_type = this_repo_type;
+ }
+ else if (found)
+ {
+ Shared_Backing_Store::UniqueId& id = entry.int_id_;
+ if (entry_repo_id != id.repo_id &&
+ entry_repo_type != id.repo_type)
+ {
+ // if already existed, replace the contents
+ ACE_ERROR((
+ LM_ERROR,
+ ACE_TEXT("(%P|%t) ERROR: replacing %C with existing repo_id=%d ")
+ ACE_TEXT("and imr_type=%d, with repo_id=%d and imr_type=%d\n"),
+ identify_key(key).c_str(), id.repo_id, id.repo_type,
+ entry_repo_id, entry_repo_type));
+ id = temp_id;
+ }
+ }
+
+ if (entry_repo_type == this_repo_type && entry_repo_id >= this_repo_id)
+ {
+ // persisting existing entries for this repo, so move the repo_id past
+ // the entries id
+ this_repo_id = entry_repo_id + 1;
+ }
+
+ return entry;
+}
+
+template< typename Update, typename Map>
+static int remove(
+ const typename Map::KEY& key,
+ const Map& unique_ids,
+ const ACE_TString& path,
+ Lockable_File& listing_lf,
+ Shared_Backing_Store::Replica_ptr peer_replica,
+ ImplementationRepository::SequenceNum& seq_num)
+{
+ typename Map::ENTRY* entry;
+ const int err = unique_ids.find(key, entry);
+ if (err != 0)
+ {
+ ACE_ERROR((
+ LM_ERROR,
+ ACE_TEXT("(%P|%t) Couldn't find unique repo id for %C\n"),
+ identify_key(key).c_str()));
+ return err;
+ }
+
+ const ACE_TString fname = path + entry->int_id_.unique_filename;
+
+ {
+ // take the lock, then remove the file
+ Lockable_File file(fname, O_WRONLY, true);
+ }
+ listing_lf.release();
+
+ replicate<Update, Map>
+ (peer_replica, *entry, ImplementationRepository::repo_remove, ++seq_num);
+
+ return 0;
+}
+
+int
+Shared_Backing_Store::persistent_remove (const ACE_CString& name,
+ bool activator)
+{
+ Lockable_File listing_lf;
+ int err = persist_listings(listing_lf);
+ if (err != 0)
+ {
+ return err;
+ }
+
+ if (activator)
+ {
+ err = remove<ImplementationRepository::ActivatorUpdate>
+ (name, this->activator_uids_, this->filename_, listing_lf,
+ this->peer_replica_, this->seq_num_);
+ }
+ else
+ {
+ err = remove<ImplementationRepository::ServerUpdate>
+ (name, this->server_uids_, this->filename_, listing_lf,
+ this->peer_replica_, this->seq_num_);
+ }
+ return err;
+}
+
+int
+Shared_Backing_Store::persistent_update(const Server_Info_Ptr& info, bool add)
+{
+ Lockable_File listing_lf;
+ if (add)
+ {
+ const int err = persist_listings(listing_lf);
+ if (err != 0)
+ {
+ return err;
+ }
+ }
+
+ ACE_CString name = ACEXML_escape_string (info->name);
+
+ const ServerUIMap::ENTRY& entry =
+ unique_id(info->name, this->server_uids_, this->imr_type_, this->repo_id_);
+ const ACE_TString fname = this->filename_ + entry.int_id_.unique_filename;
+ if (this->opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT ("Persisting to %s(%C)\n"),
+ fname.c_str(), info->name.c_str()));
+ }
+ Lockable_File server_file(fname, O_WRONLY);
+ const ACE_TString bfname = fname.c_str() + ACE_TString(".bak");
+ FILE* fp = server_file.get_file();
+ if (fp == 0)
+ {
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("Couldn't write to file %s\n"),
+ fname.c_str()));
+ return -1;
+ }
+ // successfully added file (if adding), so release the listing file lock
+ listing_lf.release();
+ ACE_OS::fprintf (fp,"<?xml version=\"1.0\"?>\n");
+
+ this->repo_values_[REPO_TYPE].second = entry.int_id_.repo_type_str;
+ this->repo_values_[REPO_ID].second = entry.int_id_.repo_id_str;
+
+ persist(fp, *info, "", this->repo_values_);
+
+ // Copy the current file to a backup.
+ FILE* bfp = ACE_OS::fopen(bfname.c_str(),ACE_TEXT("w"));
+ ACE_OS::fprintf (bfp,"<?xml version=\"1.0\"?>\n");
+ persist(bfp, *info, "", this->repo_values_);
+ ACE_OS::fflush(bfp);
+ ACE_OS::fclose(bfp);
+ server_file.release();
+
+ const ImplementationRepository::UpdateType type = add ?
+ ImplementationRepository::repo_add :
+ ImplementationRepository::repo_update;
+ replicate<ImplementationRepository::ServerUpdate, ServerUIMap>
+ (peer_replica_, entry, type, ++seq_num_);
+ return 0;
+}
+
+
+int
+Shared_Backing_Store::persistent_update(const Activator_Info_Ptr& info,
+ bool add)
+{
+ Lockable_File listing_lf;
+ if (add)
+ {
+ const int err = persist_listings(listing_lf);
+ if (err != 0)
+ {
+ return err;
+ }
+ }
+
+ ACE_CString name = lcase (info->name);
+
+ const ActivatorUIMap::ENTRY& entry =
+ unique_id(name, this->activator_uids_, this->imr_type_, this->repo_id_);
+ const ACE_TString fname = this->filename_ + entry.int_id_.unique_filename;
+ if (this->opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT ("Persisting to %s(%C)\n"),
+ fname.c_str(), info->name.c_str()));
+ }
+ Lockable_File activator_file(fname, O_WRONLY);
+ const ACE_TString bfname = fname.c_str() + ACE_TString(".bak");
+ FILE* fp = activator_file.get_file();
+ if (fp == 0)
+ {
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("Couldn't write to file %s\n"),
+ fname.c_str()));
+ return -1;
+ }
+ // successfully added file (if adding), so release the listing file lock
+ listing_lf.release();
+ ACE_OS::fprintf (fp,"<?xml version=\"1.0\"?>\n");
+
+ this->repo_values_[REPO_TYPE].second = entry.int_id_.repo_type_str;
+ this->repo_values_[REPO_ID].second = entry.int_id_.repo_id_str;
+
+ persist(fp, *info, "", this->repo_values_);
+
+ // Copy the current file to a backup.
+ FILE* bfp = ACE_OS::fopen(bfname.c_str(),ACE_TEXT("w+"));
+ ACE_OS::fprintf (bfp,"<?xml version=\"1.0\"?>\n");
+ persist(bfp, *info, "", this->repo_values_);
+ ACE_OS::fflush(bfp);
+ ACE_OS::fclose(bfp);
+ activator_file.release();
+
+ const ImplementationRepository::UpdateType type = add ?
+ ImplementationRepository::repo_add :
+ ImplementationRepository::repo_update;
+ replicate<ImplementationRepository::ActivatorUpdate, ActivatorUIMap>
+ (peer_replica_, entry, type, ++seq_num_);
+ return 0;
+}
+
+const ACE_TCHAR*
+Shared_Backing_Store::repo_mode() const
+{
+ return this->listing_file_.c_str();
+}
+
+int
+Shared_Backing_Store::connect_replicas (Replica_ptr this_replica)
+{
+ const ACE_TString& replica_ior = replica_ior_filename(true);
+ if (this->opts_.debug() > 1)
+ {
+ ACE_DEBUG((LM_INFO,
+ ACE_TEXT("Resolving ImR replica %s\n"), replica_ior.c_str()));
+ }
+
+ CORBA::Object_var obj =
+ this->orb_->string_to_object (replica_ior.c_str());
+
+ if (!CORBA::is_nil (obj.in ()))
+ {
+ bool non_exist = true;
+ try
+ {
+ this->peer_replica_ = ImplementationRepository::
+ UpdatePushNotification::_narrow (obj.in());
+ non_exist = (this->peer_replica_->_non_existent() == 1);
+ }
+ catch (const CORBA::Exception& )
+ {
+ // let error be handled below
+ }
+
+ if (non_exist)
+ {
+ this->peer_replica_ =
+ ImplementationRepository::UpdatePushNotification::_nil();
+ }
+ }
+
+ if (CORBA::is_nil (this->peer_replica_.in()))
+ {
+ if (this->imr_type_ == Options::BACKUP_IMR)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT("Error: No primary ImR replica file found <%s>\n"),
+ replica_ior.c_str()), -1);
+ }
+
+ // no connection currently, just wait for backup
+ return 0;
+ }
+
+ if (opts_.debug() > 1)
+ {
+ ACE_DEBUG((LM_INFO,
+ ACE_TEXT("Registering with previously running ImR replica\n")));
+ }
+
+ try
+ {
+ this->peer_replica_->register_replica(this_replica,
+ this->imr_ior_.inout(),
+ this->replica_seq_num_);
+ }
+ catch (const ImplementationRepository::InvalidPeer& ip)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT("Error: obj key <%s> is an invalid ImR replica because %s\n"),
+ replica_ior.c_str(), ip.reason.in()), -1);
+ }
+
+ if (opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO,
+ ACE_TEXT("Initializing repository with ft ior=<%C> ")
+ ACE_TEXT("and replica seq number %d\n"),
+ this->imr_ior_.in(), replica_seq_num_));
+ }
+
+ return 0;
+}
+
+int
+Shared_Backing_Store::init_repo(PortableServer::POA_ptr imr_poa)
+{
+ this->non_ft_imr_ior_ = this->imr_ior_;
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId ("ImR_Replica");
+ imr_poa->activate_object_with_id (id.in (), this);
+
+ if (this->imr_type_ != Options::STANDALONE_IMR)
+ {
+ CORBA::Object_var obj = imr_poa->id_to_reference (id.in ());
+
+ Replica_var this_replica =
+ ImplementationRepository::UpdatePushNotification::_narrow (obj.in());
+ const int err = connect_replicas(this_replica.in());
+ if (err != 0)
+ {
+ return err;
+ }
+ }
+
+ // only start the repo clean if no replica is running
+ if (this->opts_.repository_erase() &&
+ CORBA::is_nil (this->peer_replica_.in ()))
+ {
+ Lockable_File listing_lf;
+ const XMLHandler_Ptr listings = get_listings(listing_lf, false);
+ if (listings.null())
+ {
+ if (this->opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO,
+ ACE_TEXT ("Persisted Repository already empty\n")));
+ }
+ }
+ else
+ {
+ const ACE_Vector<ACE_TString>& filenames = listings->filenames();
+ CORBA::ULong sz = filenames.size ();
+ for (CORBA::ULong i = 0; i < sz; ++i)
+ {
+ if (this->opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT ("Removing %s\n"),
+ filenames[i].c_str()));
+ }
+ ACE_OS::unlink ( filenames[i].c_str () );
+ }
+
+ if (this->opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT ("Removing %s\n"),
+ this->listing_file_.c_str()));
+ }
+ ACE_OS::unlink ( this->listing_file_.c_str () );
+ }
+ }
+
+ // ignore persistent_load return since files don't have to exist
+ persistent_load(false);
+
+ if (this->opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO,
+ ACE_TEXT ("ImR Repository initialized\n")));
+ }
+
+ return 0;
+}
+
+int
+Shared_Backing_Store::persistent_load (bool only_changes)
+{
+ Lockable_File listing_lf;
+ const XMLHandler_Ptr listings = get_listings(listing_lf, only_changes);
+ if (listings.null())
+ {
+ // failed to retrieve listings
+ return -1;
+ }
+
+ if (only_changes)
+ {
+ listings->remove_unmatched(*this);
+ }
+
+ const ACE_Vector<ACE_TString>& filenames = listings->filenames();
+ CORBA::ULong sz = filenames.size ();
+ if (this->opts_.debug() > 9)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT ("persistent_load %d files\n"), sz));
+ }
+ for (CORBA::ULong i = 0; i < sz; ++i)
+ {
+ const ACE_TString& fname = filenames[i];
+ Lockable_File file(fname, O_RDONLY);
+
+ if(load(fname, file.get_file()) != 0)
+ {
+ load(fname + ".bak");
+ }
+ }
+
+ return 0;
+}
+
+Shared_Backing_Store::XMLHandler_Ptr
+Shared_Backing_Store::get_listings(Lockable_File& listing_lf,
+ bool only_changes) const
+{
+ XMLHandler_Ptr listings_handler;
+ if (only_changes)
+ {
+ listings_handler.reset(new LocatorListings_XMLHandler(
+ this->filename_, servers(), activators()));
+ }
+ else
+ {
+ listings_handler.reset(new LocatorListings_XMLHandler(this->filename_));
+ }
+
+ if (load(this->listing_file_,
+ *listings_handler,
+ this->opts_.debug(),
+ listing_lf.get_file(this->listing_file_, O_RDONLY)) != 0)
+ {
+
+ if (load(this->listing_file_ + ".bak",
+ *listings_handler,
+ this->opts_.debug()) != 0)
+ {
+ listings_handler.reset();
+ }
+ }
+
+ return listings_handler;
+}
+
+int
+Shared_Backing_Store::sync_load ()
+{
+ int err = 0;
+ if (this->opts_.debug() > 5)
+ {
+ ACE_DEBUG((
+ LM_INFO,
+ ACE_TEXT("(%P|%t) sync_load %d, %d\n"),
+ this->sync_needed_, this->sync_files_.size()));
+ }
+ if (this->sync_needed_ == FULL_SYNC)
+ {
+ err = persistent_load(false);
+ }
+ else if (this->sync_needed_ == INC_SYNC)
+ {
+ std::set<ACE_TString>::const_iterator fname = this->sync_files_.begin();
+ for ( ; fname != this->sync_files_.end(); ++fname)
+ {
+ if (this->opts_.debug() > 6)
+ {
+ ACE_DEBUG((LM_INFO,
+ ACE_TEXT("(%P|%t) sync_load %s\n"),
+ fname->c_str()));
+ }
+ Lockable_File file(*fname, O_RDONLY);
+ int ind_err = load(*fname, file.get_file());
+ if (ind_err != 0)
+ {
+ err = ind_err;
+ }
+ }
+ this->sync_files_.clear();
+ }
+
+ this->sync_needed_ = NO_SYNC;
+ return err;
+}
+
+static void write_listing_item(FILE* list, const ACE_TString& fname,
+ const ACE_CString& name, const ACE_TCHAR* tag)
+{
+ ACE_OS::fprintf (list, "\t<%s", tag);
+ ACE_OS::fprintf (list, " fname=\"%s\"", fname.c_str ());
+ ACE_OS::fprintf (list, " name=\"%s\" />\n", name.c_str ());
+}
+
+void
+Shared_Backing_Store::write_listing(FILE* list)
+{
+ ACE_OS::fprintf (list,"<?xml version=\"1.0\"?>\n");
+ ACE_OS::fprintf (list,"<ImRListing>\n");
+
+ // Save servers
+ Locator_Repository::SIMap::ENTRY* sientry = 0;
+ Locator_Repository::SIMap::CONST_ITERATOR siit (this->servers ());
+ for (; siit.next (sientry); siit.advance() )
+ {
+ const Server_Info_Ptr& info = sientry->int_id_;
+
+ const Shared_Backing_Store::ServerUIMap::ENTRY& entry =
+ unique_id(sientry->ext_id_, this->server_uids_,
+ this->imr_type_, this->repo_id_);
+ ACE_CString listing_name = ACEXML_escape_string (info->name);
+ write_listing_item(list, entry.int_id_.unique_filename, listing_name,
+ Locator_XMLHandler::SERVER_INFO_TAG);
+ }
+
+ // Save Activators
+ Locator_Repository::AIMap::ENTRY* aientry = 0;
+ Locator_Repository::AIMap::CONST_ITERATOR aiit (this->activators ());
+ for (; aiit.next (aientry); aiit.advance ())
+ {
+ const ACE_CString& aname = aientry->ext_id_;
+ const ActivatorUIMap::ENTRY& entry =
+ unique_id(aname, this->activator_uids_,
+ this->imr_type_, this->repo_id_);
+ write_listing_item(list, entry.int_id_.unique_filename, aname,
+ Locator_XMLHandler::ACTIVATOR_INFO_TAG);
+ }
+
+ ACE_OS::fprintf (list,"</ImRListing>\n");
+}
+
+int
+Shared_Backing_Store::persist_listings (Lockable_File& listing_lf)
+{
+ FILE* list = listing_lf.get_file(this->listing_file_, O_WRONLY);
+ if (list == 0)
+ {
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("Couldn't write to file %s\n"),
+ this->listing_file_.c_str()));
+ return -1;
+ }
+
+ write_listing(list);
+
+ const ACE_TString bfname = this->listing_file_.c_str() + ACE_TString(".bak");
+
+ // Write backup file
+ FILE* baklist = ACE_OS::fopen(bfname.c_str(),ACE_TEXT("w"));
+ if (baklist == 0)
+ {
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("Couldn't write to file %s\n"),
+ bfname.c_str()));
+ return -1;
+ }
+
+ write_listing(baklist);
+ ACE_OS::fflush(baklist);
+ ACE_OS::fclose(baklist);
+
+ return 0;
+}
+
+int
+Shared_Backing_Store::report_ior(PortableServer::POA_ptr imr_poa)
+{
+ if (this->imr_type_ == Options::STANDALONE_IMR)
+ {
+ return Locator_Repository::report_ior(imr_poa);
+ }
+
+ CORBA::Object_var obj = this->orb_->resolve_initial_references ("IORTable");
+ IORTable::Table_var ior_table = IORTable::Table::_narrow (obj.in ());
+ ACE_ASSERT (! CORBA::is_nil (ior_table.in ()));
+
+ const char* const replica_name(IMR_REPLICA[this->imr_type_]);
+ ACE_TString replica_filename = replica_ior_filename(false);
+ FILE* fp = ACE_OS::fopen (replica_filename.c_str (), "w");
+ if (fp == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT("ImR: Could not open file: %s\n"),
+ replica_filename.c_str ()), -1);
+ }
+ obj = imr_poa->servant_to_reference (this);
+ const CORBA::String_var replica_ior = this->orb_->object_to_string (obj.in ());
+ ior_table->bind(replica_name, replica_ior.in());
+ ACE_OS::fprintf (fp, "%s", replica_ior.in ());
+ ACE_OS::fclose (fp);
+
+ int err = 0;
+ // only report the imr ior if the fault tolerant ImR is complete
+ if (!CORBA::is_nil (this->peer_replica_.in()))
+ {
+ err = Locator_Repository::report_ior(imr_poa);
+ }
+
+ return err;
+}
+
+char*
+Shared_Backing_Store::locator_service_ior(const char* peer_ior) const
+{
+ const CORBA::Object_ptr this_obj =
+ this->orb_->string_to_object(this->non_ft_imr_ior_.in());
+ const CORBA::Object_ptr peer_obj =
+ this->orb_->string_to_object(peer_ior);
+ const CORBA::Object_ptr& obj1 =
+ (this->imr_type_ == Options::PRIMARY_IMR) ? this_obj : peer_obj;
+ const CORBA::Object_ptr& obj2 =
+ (this->imr_type_ != Options::PRIMARY_IMR) ? this_obj : peer_obj;
+
+ CORBA::Object_var IORM =
+ this->orb_->resolve_initial_references (TAO_OBJID_IORMANIPULATION, 0);
+
+ TAO_IOP::TAO_IOR_Manipulation_var iorm =
+ TAO_IOP::TAO_IOR_Manipulation::_narrow (IORM.in());
+
+ CORBA::Object_var locator_service = iorm->add_profiles(obj1, obj2);
+
+ char* const combined_ior =
+ this->orb_->object_to_string(locator_service.in());
+ return combined_ior;
+
+}
+
+template<typename Map>
+static const typename Map::ENTRY& unique_id(
+ const typename Map::KEY& key,
+ const XML_Backing_Store::NameValues& repo_values,
+ const XML_Backing_Store::NameValues& extra_params,
+ Map& unique_ids,
+ const Options::ImrType this_repo_type,
+ unsigned int& this_repo_id,
+ const unsigned int debug)
+{
+ const unsigned int size = extra_params.size();
+ if ((size != 2) && (debug > 4))
+ {
+ ACE_ERROR((
+ LM_ERROR,
+ ACE_TEXT("(%P|%t) Persisted server id=%C name=%C doesn't have all ")
+ ACE_TEXT("unique id params. (%d of 2)\n"),
+ size));
+ };
+
+ unsigned int repo_id = 0;
+ // default to this repo
+ Options::ImrType repo_type = this_repo_type;
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ ACE_DEBUG((LM_INFO,
+ ACE_TEXT ("name values %C=%C (%C)\n"),
+ extra_params[i].first.c_str(),
+ extra_params[i].second.c_str(),
+ repo_values[i].first.c_str()));
+ }
+ if ((size > Shared_Backing_Store::REPO_TYPE) &&
+ (extra_params[Shared_Backing_Store::REPO_TYPE].first ==
+ repo_values[Shared_Backing_Store::REPO_TYPE].first))
+ repo_type = (Options::ImrType)ACE_OS::atoi(
+ extra_params[Shared_Backing_Store::REPO_TYPE].second.c_str());
+
+ if ((size > Shared_Backing_Store::REPO_ID) &&
+ (extra_params[Shared_Backing_Store::REPO_ID].first ==
+ repo_values[Shared_Backing_Store::REPO_ID].first))
+ repo_id =
+ ACE_OS::atoi(extra_params[Shared_Backing_Store::REPO_ID].second.c_str());
+ else
+ {
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("(%P|%t) Persisted %C did not supply a repo_id\n"),
+ identify_key(key).c_str()));
+ }
+
+ return
+ unique_id(key, unique_ids, this_repo_type,
+ this_repo_id, repo_type, repo_id);
+}
+
+void
+Shared_Backing_Store::load_server (
+ const ACE_CString& server_id,
+ const ACE_CString& server_name,
+ bool jacorb_server,
+ const ACE_CString& activator_name,
+ const ACE_CString& startup_cmd,
+ const ImplementationRepository::EnvironmentList& env_vars,
+ const ACE_CString& working_dir,
+ const ImplementationRepository::ActivationMode actmode,
+ int start_limit,
+ const ACE_CString& partial_ior,
+ const ACE_CString& ior,
+ bool server_started,
+ const NameValues& extra_params)
+{
+ // ensure there is an entry for this server
+ unique_id(server_name, this->repo_values_, extra_params,
+ this->server_uids_, this->imr_type_, this->repo_id_,
+ this->opts_.debug());
+ Server_Info_Ptr si;
+ const bool new_server = (this->servers ().find (server_name, si) != 0);
+
+ if (new_server)
+ {
+ // create new or replace the existing entry
+ XML_Backing_Store::load_server(
+ server_id, server_name, jacorb_server, activator_name, startup_cmd,
+ env_vars, working_dir, actmode, start_limit, partial_ior, ior,
+ server_started, extra_params);
+ return;
+ }
+
+ // is the server object new
+ const bool new_ior = si->ior != ior;
+ if (new_ior)
+ si->ior = ior;
+
+ si->server_id = server_id;
+ si->jacorb_server = jacorb_server;
+ si->activator = activator_name;
+ si->cmdline = startup_cmd;
+ si->env_vars = env_vars;
+ si->dir = working_dir;
+ si->activation_mode = actmode;
+ si->start_limit = start_limit;
+ si->partial_ior = partial_ior;
+
+ if (!server_started)
+ si->server = ImplementationRepository::ServerObject::_nil();
+ else
+ // will create a new server below if no previous server
+ // or the ior has changed
+ server_started = CORBA::is_nil(si->server) || new_ior;
+
+ create_server(server_started, si);
+}
+
+void
+Shared_Backing_Store::load_activator (const ACE_CString& activator_name,
+ long token,
+ const ACE_CString& ior,
+ const NameValues& extra_params)
+{
+ // use this to make sure an unique id entry is created
+ unique_id(activator_name, this->repo_values_, extra_params,
+ this->activator_uids_, this->imr_type_, this->repo_id_,
+ this->opts_.debug());
+ XML_Backing_Store::load_activator(activator_name, token, ior, extra_params);
+}
+
+void
+Shared_Backing_Store::notify_updated_server(
+ const ImplementationRepository::ServerUpdate& server)
+{
+ if (this->opts_.debug() > 5)
+ {
+ ACE_DEBUG((
+ LM_INFO,
+ ACE_TEXT("(%P|%t) notify_updated_server=%C\n"),
+ server.name.in()));
+ }
+ if ((this->sync_needed_ == FULL_SYNC) ||
+ (++this->replica_seq_num_ != server.seq_num))
+ {
+ this->replica_seq_num_ = server.seq_num;
+ this->sync_needed_ = FULL_SYNC;
+ this->sync_files_.clear();
+ return;
+ }
+
+ const ACE_CString name = server.name.in();
+ if (server.type == ImplementationRepository::repo_remove)
+ {
+ // sync_needed_ doesn't change, since we handle the change
+ // imme;diately
+ this->servers().unbind (name);
+ return;
+ }
+
+ this->sync_needed_ = INC_SYNC;
+ Options::ImrType repo_type = (Options::ImrType)server.repo_type;
+ unsigned int repo_id = server.repo_id;
+ const ServerUIMap::ENTRY& entry =
+ unique_id(name, this->server_uids_, this->imr_type_, this->repo_id_,
+ repo_type, repo_id);
+ const ACE_TString fname = this->filename_ + entry.int_id_.unique_filename;
+ this->sync_files_.insert(fname);
+}
+
+void
+Shared_Backing_Store::notify_updated_activator(
+ const ImplementationRepository::ActivatorUpdate& activator)
+{
+ if (this->opts_.debug() > 5)
+ {
+ ACE_DEBUG((
+ LM_INFO,
+ ACE_TEXT("(%P|%t) notify_updated_activator=%C\n"),
+ activator.name.in()));
+ }
+ if ((this->sync_needed_ == FULL_SYNC) ||
+ (++this->replica_seq_num_ != activator.seq_num))
+ {
+ this->replica_seq_num_ = activator.seq_num;
+ this->sync_needed_ = FULL_SYNC;
+ this->sync_files_.clear();
+ return;
+ }
+
+ const ACE_CString name = lcase(activator.name.in());
+ if (activator.type == ImplementationRepository::repo_remove)
+ {
+ // sync_needed_ doesn't change, since we handle the change
+ // immediately
+ this->activators().unbind (name);
+ return;
+ }
+
+ this->sync_needed_ = INC_SYNC;
+ Options::ImrType repo_type = (Options::ImrType)activator.repo_type;
+ unsigned int repo_id = activator.repo_id;
+ const ActivatorUIMap::ENTRY& entry =
+ unique_id(name, this->activator_uids_, this->imr_type_, this->repo_id_,
+ repo_type, repo_id);
+ const ACE_TString fname = this->filename_ + entry.int_id_.unique_filename;
+ this->sync_files_.insert(fname);
+}
+
+void
+Shared_Backing_Store::register_replica(
+ ImplementationRepository::UpdatePushNotification_ptr replica,
+ char*& ft_imr_ior,
+ ImplementationRepository::SequenceNum_out seq_num)
+{
+ ACE_ASSERT (! CORBA::is_nil (replica));
+ this->peer_replica_ =
+ ImplementationRepository::UpdatePushNotification::_duplicate (replica);
+
+ seq_num = this->seq_num_;
+ if (this->imr_type_ == Options::STANDALONE_IMR)
+ {
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("Error: Non-replicated ImR receiving replica ")
+ ACE_TEXT("registration <%s>\n"),
+ ft_imr_ior));
+ return;
+ }
+
+ this->replica_seq_num_ = 0;
+
+ // store off original char* to ensure memory cleanup
+ CORBA::String_var ior = ft_imr_ior;
+
+ // if we already have the fault tolerant ImR ior
+ // then just copy it
+ if (registered())
+ {
+ if (this->opts_.debug() > 2)
+ {
+ ACE_DEBUG((
+ LM_INFO,
+ ACE_TEXT("(%P|%t) Already registered <%C>\n"),
+ this->imr_ior_.in()));
+ }
+ // make a copy
+ ior = this->imr_ior_.in();
+ // handoff memory
+ ft_imr_ior = ior._retn();
+ return;
+ }
+
+ // otherwise we need to combine the primary and backup ior to make
+ // the fault tolerant ImR ior
+ char* combined_ior = 0;
+ CORBA::String_var reason;
+ try
+ {
+ combined_ior = locator_service_ior(ft_imr_ior);
+ }
+ catch (const TAO_IOP::Invalid_IOR& )
+ {
+ reason = "invalid ior";
+ }
+ catch (const TAO_IOP::EmptyProfileList& )
+ {
+ reason = "no profiles";
+ }
+ catch (const TAO_IOP::Duplicate& )
+ {
+ reason = "duplicate profile";
+ }
+
+ if (combined_ior == 0)
+ {
+ // give back the original pointer and don't clean it up
+ ft_imr_ior = ior._retn();
+ ACE_ERROR((LM_ERROR,
+ "ERROR: Failed to create Fault Tolerant ImR, reason=%s\n",
+ reason.in()));
+ throw ImplementationRepository::InvalidPeer(reason.in());
+ }
+
+ ft_imr_ior = combined_ior;
+ // pass as const char* to make sure string is copied
+ this->imr_ior_ = (const char*)ft_imr_ior;
+
+ PortableServer::POA_var null_poa;
+ Locator_Repository::report_ior(null_poa);
+}
+
+ACE_CString
+Shared_Backing_Store::replica_ior_filename(bool peer_ior_file) const
+{
+ Options::ImrType desired_type = this->imr_type_;
+ if (peer_ior_file)
+ {
+ desired_type = (desired_type == Options::PRIMARY_IMR) ?
+ Options::BACKUP_IMR :
+ Options::PRIMARY_IMR;
+ }
+ ACE_CString ior =
+ this->filename_ + IMR_REPLICA[desired_type] + ACE_TEXT(".ior");
+ if (peer_ior_file)
+ {
+ // the peer ior file needs the file prefix
+ ior = "file://" + ior;
+ }
+
+ return ior;
+}
+
+Shared_Backing_Store::LocatorListings_XMLHandler::LocatorListings_XMLHandler(
+ const ACE_TString& dir)
+: dir_(dir),
+ only_changes_(false)
+{
+}
+
+Shared_Backing_Store::LocatorListings_XMLHandler::LocatorListings_XMLHandler(
+ const ACE_TString& dir,
+ const Locator_Repository::SIMap& servers,
+ const Locator_Repository::AIMap& activators)
+: dir_(dir),
+ only_changes_(true)
+{
+ Locator_Repository::SIMap::ENTRY* sientry = 0;
+ Locator_Repository::SIMap::CONST_ITERATOR siit (servers);
+ for (; siit.next (sientry); siit.advance() )
+ {
+ unmatched_servers_.bind (sientry->ext_id_, sientry->int_id_);
+ }
+
+ Locator_Repository::AIMap::ENTRY* aientry = 0;
+ Locator_Repository::AIMap::CONST_ITERATOR aiit (activators);
+ for (; aiit.next (aientry); aiit.advance() )
+ {
+ unmatched_activators_.bind (aientry->ext_id_, aientry->int_id_);
+ }
+}
+
+void
+Shared_Backing_Store::LocatorListings_XMLHandler::startElement (
+ const ACEXML_Char* ,
+ const ACEXML_Char* ,
+ const ACEXML_Char* qName,
+ ACEXML_Attributes* attrs)
+{
+ const bool server =
+ (ACE_OS::strcasecmp (qName, Locator_XMLHandler::SERVER_INFO_TAG) == 0);
+ if (!server &&
+ (ACE_OS::strcasecmp (qName, Locator_XMLHandler::ACTIVATOR_INFO_TAG) != 0))
+ {
+ return;
+ }
+
+ if (attrs != 0 && attrs->getLength () == 2)
+ {
+ ACE_TString fname = attrs->getValue ((size_t)0);
+ bool store_fname = !only_changes_;
+ if (only_changes_)
+ {
+ ACE_CString name = ACE_TEXT_ALWAYS_CHAR(attrs->getValue ((size_t)1));
+ // if the name is not present, then this is an add, so store it
+ store_fname = server ?
+ (unmatched_servers_.unbind (name) != 0) :
+ (unmatched_activators_.unbind (name) != 0);
+ }
+
+ if (store_fname)
+ {
+ filenames_.push_back(dir_ + fname);
+ }
+ }
+ else
+ ACE_DEBUG((
+ LM_INFO,
+ ACE_TEXT ("LocatorListings_XMLHandler::startElement ")
+ ACE_TEXT ("incorrect number of attrs (%d)\n"),
+ attrs->getLength ()));
+
+}
+
+void
+Shared_Backing_Store::LocatorListings_XMLHandler::endElement (
+ const ACEXML_Char* ,
+ const ACEXML_Char* ,
+ const ACEXML_Char* )
+{
+}
+
+void
+Shared_Backing_Store::LocatorListings_XMLHandler::remove_unmatched(
+ Locator_Repository& repo)
+{
+ Locator_Repository::SIMap::ENTRY* sientry = 0;
+ Locator_Repository::SIMap::CONST_ITERATOR siit (this->unmatched_servers_);
+ for (; siit.next (sientry); siit.advance() )
+ {
+ int ret = repo.servers().unbind (sientry->ext_id_);
+ if (ret != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT ("ERROR: could not remove server: %s\n"),
+ sientry->int_id_->name.c_str()));
+ }
+ }
+
+ Locator_Repository::AIMap::ENTRY* aientry = 0;
+ Locator_Repository::AIMap::CONST_ITERATOR aiit (this->unmatched_activators_);
+ for (; aiit.next (aientry); aiit.advance ())
+ {
+ int ret = repo.activators().unbind (aientry->ext_id_);
+ if (ret != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT ("ERROR: could not remove activator: %s\n"),
+ aientry->int_id_->name.c_str()));
+ }
+ }
+}
+
+const ACE_Vector<ACE_TString>&
+Shared_Backing_Store::LocatorListings_XMLHandler::filenames() const
+{
+ return this->filenames_;
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Shared_Backing_Store.h b/TAO/orbsvcs/ImplRepo_Service/Shared_Backing_Store.h
new file mode 100644
index 00000000000..fc235ba2b88
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Shared_Backing_Store.h
@@ -0,0 +1,302 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+* @file Shared_Backing_Store.h
+*
+* $Id$
+*
+* This class defines an implementation of the backing store as multiple XML files
+* shared between multiple Locators.
+*
+* @author Darrell Brunsch <brunsch@cs.wustl.edu>
+* @author Priyanka Gontla <gontla_p@ociweb.com>
+*/
+//=============================================================================
+
+#ifndef SHARED_BACKING_STORE_H
+#define SHARED_BACKING_STORE_H
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "XML_Backing_Store.h"
+
+#include "ImR_LocatorS.h"
+#include "ace/Bound_Ptr.h"
+#include "ace/Vector_T.h"
+#include "ACEXML/common/DefaultHandler.h"
+
+#include <set>
+
+class ACE_Configuration;
+class ACEXML_FileCharStream;
+class LocatorListings_XMLHandler;
+
+namespace {
+ class Lockable_File;
+}
+
+/**
+* @class Shared_Backing_Store
+*
+* @brief XML backing store containing all ImR persistent information in
+* multiple files shared between multiple Locators
+*
+*/
+class Shared_Backing_Store
+ : public XML_Backing_Store,
+ public virtual POA_ImplementationRepository::UpdatePushNotification
+{
+public:
+ typedef ImplementationRepository::UpdatePushNotification_var Replica_var;
+ typedef ImplementationRepository::UpdatePushNotification_ptr Replica_ptr;
+ struct UniqueId
+ {
+ Options::ImrType repo_type;
+ unsigned int repo_id;
+ ACE_TString repo_type_str;
+ ACE_TString repo_id_str;
+ ACE_TString unique_filename;
+ };
+ typedef ACE_Hash_Map_Manager_Ex<ServerKey,
+ UniqueId,
+ ACE_Hash<ServerKey>,
+ ACE_Equal_To<ServerKey>,
+ ACE_Null_Mutex> ServerUIMap;
+
+ typedef ACE_Hash_Map_Manager_Ex<ActivatorKey,
+ UniqueId,
+ ACE_Hash<ActivatorKey>,
+ ACE_Equal_To<ActivatorKey>,
+ ACE_Null_Mutex> ActivatorUIMap;
+
+ enum ExtraParams { REPO_TYPE = 0, REPO_ID = 1 };
+
+ Shared_Backing_Store(const Options& opts,
+ CORBA::ORB_ptr orb);
+
+ virtual ~Shared_Backing_Store();
+
+ /// indicate the persistence mode for the repository
+ virtual const ACE_TCHAR* repo_mode() const;
+
+ /// provide the implementation for being notified of a
+ /// server update
+ virtual void notify_updated_server(
+ const ImplementationRepository::ServerUpdate& server);
+
+ /// provide the implementation for being notified of a
+ /// activator update
+ virtual void notify_updated_activator(
+ const ImplementationRepository::ActivatorUpdate& activator);
+
+ /// provide the implementation for registering a peer replica
+ /// @param replica the peer replica
+ /// @param ft_imr_ior the fault tolerant ImR IOR (passed in
+ /// as the replica's ImR IOR, passed back as fault
+ /// tolerant ImR IOR)
+ /// @param seq_num current sequence number to return to replica
+ virtual void register_replica(
+ ImplementationRepository::UpdatePushNotification_ptr replica,
+ char*& ft_imr_ior,
+ ImplementationRepository::SequenceNum_out seq_num);
+
+ /// enum to indicate whether the repo is in-sync, individual
+ /// server and/or activator files need to be sync-ed or if
+ /// a full sync of servers and activators is needed
+ enum SyncType { NO_SYNC, INC_SYNC, FULL_SYNC };
+
+ /// create the Server_Info server object
+ /// @param server_id the Server_Info server_id
+ /// @param server_name the Server_Info server_name
+ /// @param activator_name the Server_Info activator
+ /// @param cmdline the Server_Info cmdline
+ /// @param env_vars the Server_Info env_vars
+ /// @param workin_dir the Server_Info dir
+ /// @param actmode the Server_Info activation_mode
+ /// @param start_limit the Server_Info start_limit
+ /// @param partial_ior the Server_Info partial_ior
+ /// @param ior the Server_Info ior
+ /// @param server_started indicates if the server object
+ /// existed when data was persisted
+ /// @param extra_params extra name value pairs that
+ /// were reported for the server
+ virtual void load_server (
+ const ACE_CString& server_id,
+ const ACE_CString& server_name,
+ bool jacorb_server,
+ const ACE_CString& activator_name,
+ const ACE_CString& cmdline,
+ const ImplementationRepository::EnvironmentList& env_vars,
+ const ACE_CString& working_dir,
+ ImplementationRepository::ActivationMode actmode,
+ int start_limit,
+ const ACE_CString& partial_ior,
+ const ACE_CString& ior,
+ bool server_started,
+ const NameValues& extra_params);
+
+ /// create the Activator_Info activator object
+ /// @param activator_name the Activator_Info name
+ /// @param token the Activator_Info token
+ /// @param ior the Activator_Info ior
+ /// @param extra_params extra name value pairs that
+ /// were reported for the activator
+ virtual void load_activator (const ACE_CString& activator_name,
+ long token,
+ const ACE_CString& ior,
+ const NameValues& extra_params);
+protected:
+ /// perform shared backing store specific initialization
+ /// (activates this Shared_Backing_Store as the "ImR_Replica",
+ /// trys to connect to the peer replica, unless it is a
+ /// STANDALONE_IMR, clears out the persisted store if needed,
+ /// and loads the repo from the persisted store)
+ virtual int init_repo(PortableServer::POA_ptr imr_poa);
+
+ /// perform server persistent update
+ virtual int persistent_update(const Server_Info_Ptr& info, bool add);
+
+ /// perform activator persistent update
+ virtual int persistent_update(const Activator_Info_Ptr& info, bool add);
+
+ /// perform persistent remove
+ virtual int persistent_remove(const ACE_CString& name, bool activator);
+
+ /// perform sync of repo with backing store
+ /// uses sync_needed_ and sync_files_ to determine what to update
+ virtual int sync_load ();
+
+ /// calls Locator_Repository::report_ior with the Fault Tolerant ImR
+ /// Locator's IOR if available, otherwise reporting the ior is delayed
+ /// until the peer replica registers with this replica
+ virtual int report_ior(PortableServer::POA_ptr imr_poa);
+
+ /// create the Fault Tolerant ImR Locator IOR, using the peer_ior and
+ /// this ImR Locator's IOR
+ char* locator_service_ior(const char* peer_ior) const;
+
+private:
+ /**
+ * Callback SAX XML Handler for parsing the imr_listings.xml file.
+ */
+ class LocatorListings_XMLHandler : public ACEXML_DefaultHandler
+ {
+ public:
+ /// constructor
+ /// @param dir the directory path to add to the server or activator
+ /// filename
+ LocatorListings_XMLHandler(const ACE_TString& dir);
+
+ /// constructor for tracking only changes to what servers and activators
+ /// are currently in the repo
+ /// @param dir the directory path to add to the server or activator
+ /// filename
+ /// @param servers a map of servers currently in the repo
+ /// @param servers a map of activators currently in the repo
+ LocatorListings_XMLHandler(const ACE_TString& dir,
+ const Locator_Repository::SIMap& servers,
+ const Locator_Repository::AIMap& activators);
+
+ /// provide implementation for handling a new XML element
+ virtual void startElement (const ACEXML_Char* namespaceURI,
+ const ACEXML_Char* localName,
+ const ACEXML_Char* qName,
+ ACEXML_Attributes* attrs);
+
+ /// provide implementation for handling terminating an XML element
+ virtual void endElement (const ACEXML_Char* namespaceURI,
+ const ACEXML_Char* localName,
+ const ACEXML_Char* qName);
+
+ /// remove the servers and activators that were in the repo but not
+ /// in the listings file (this does nothing if existing servers and
+ /// activators were not provided in constructor)
+ void remove_unmatched(Locator_Repository& repo);
+
+ /// the filenames identified in the listings file, if tracking changes
+ /// only then only the filenames of the new servers and activators
+ const ACE_Vector<ACE_TString>& filenames() const;
+
+ private:
+ /// the directory to add to the listings file relative filenames
+ const ACE_TString& dir_;
+ /// the filenames identified in the listings file (or the new filenames)
+ ACE_Vector<ACE_TString> filenames_;
+ /// the existing servers in the repo that were not present in the
+ /// listings file
+ Locator_Repository::SIMap unmatched_servers_;
+ /// the existing activators in the repo that were not present in the
+ /// listings file
+ Locator_Repository::AIMap unmatched_activators_;
+ /// indicates if only changes should be tracked
+ const bool only_changes_;
+ };
+ typedef ACE_Strong_Bound_Ptr
+ <LocatorListings_XMLHandler, ACE_Null_Mutex> XMLHandler_Ptr;
+
+ /// determine the filename where the replica ior is reported
+ /// @param peer_ior_file if this is the filename for the peer
+ /// replica or this replica
+ ACE_CString replica_ior_filename(bool peer_ior_file) const;
+
+ /// get the listings file contents
+ /// @param listing_lf a Lockable_File for the listings file
+ /// that will be locked when the function returns
+ /// @param only_changes if only changes to the repo should be
+ /// reported
+ /// @return a pointer to the LocatorListings_XMLHandler
+ XMLHandler_Ptr get_listings(Lockable_File& listing_lf,
+ bool only_changes) const;
+
+ /// perform a persistent load from the backing store
+ /// @param only_changes if only changes to the repo should be
+ /// loaded
+ int persistent_load(bool only_changes);
+
+ /// persistent the listings file
+ /// @param listing_lf a Lockable_File for the listings file
+ /// that will be locked when the function returns
+ int persist_listings(Lockable_File& listing_lf);
+
+ /// write content to the listings file and optionally its backup
+ /// @param File pointer to write to. Can be primary or backup.
+ void write_listing(FILE *);
+
+ /// connect this replica to its peer replica
+ /// @param this_replica a pointer to this Replica object
+ int connect_replicas(Replica_ptr this_replica);
+
+ /// the path and filename for the listings file
+ const ACE_TString listing_file_;
+ /// the path and filename for the listings file
+ Replica_var peer_replica_;
+ /// the current sequence number for reporting changes made directly to
+ /// this repo
+ ImplementationRepository::SequenceNum seq_num_;
+ /// the current sequence number last reported by the peer replica
+ ImplementationRepository::SequenceNum replica_seq_num_;
+ /// the imr type of this Shared_Backing_Store
+ const Options::ImrType imr_type_;
+ /// the current type of sync needed by the repo
+ SyncType sync_needed_;
+ /// the server and activator files that need to be updated for
+ /// sync_needed_ == INC_SYNC
+ std::set<ACE_TString> sync_files_;
+ /// the ior for just this ImR Locator
+ CORBA::String_var non_ft_imr_ior_;
+ /// an array associating ImrType with the appropriate name
+ const char* IMR_REPLICA[3];
+ /// map for server unique ids
+ ServerUIMap server_uids_;
+ /// map for activator unique ids
+ ActivatorUIMap activator_uids_;
+ /// next unique repo id
+ unsigned int repo_id_;
+ /// extra parameters for XML
+ XML_Backing_Store::NameValues repo_values_;
+};
+
+#endif /* SHARED_BACKING_STORE_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp b/TAO/orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp
new file mode 100644
index 00000000000..1f7e6822fa8
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/XML_Backing_Store.cpp
@@ -0,0 +1,323 @@
+// $Id$
+
+#include "XML_Backing_Store.h"
+#include "Server_Info.h"
+#include "Activator_Info.h"
+#include "utils.h"
+#include "Locator_XMLHandler.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/OS_NS_unistd.h"
+#include "ACEXML/parser/parser/Parser.h"
+#include "ACEXML/common/FileCharStream.h"
+#include "ACEXML/common/XML_Util.h"
+
+XML_Backing_Store::XML_Backing_Store(const Options& opts,
+ CORBA::ORB_ptr orb,
+ bool suppress_erase)
+: Locator_Repository(opts, orb),
+ filename_(opts.persist_file_name())
+{
+ if (opts.repository_erase() && !suppress_erase)
+ {
+ ACE_OS::unlink ( this->filename_.c_str () );
+ }
+}
+
+XML_Backing_Store::~XML_Backing_Store()
+{
+}
+
+int
+XML_Backing_Store::persistent_remove (const ACE_CString& , bool )
+{
+ // one big XML file, need to persist everything
+ return persist();
+}
+
+int
+XML_Backing_Store::persistent_update(const Server_Info_Ptr& , bool )
+{
+ // one big XML file, need to persist everything
+ return persist();
+}
+
+int
+XML_Backing_Store::persistent_update(const Activator_Info_Ptr& , bool )
+{
+ // one big XML file, need to persist everything
+ return persist();
+}
+
+int
+XML_Backing_Store::persist ()
+{
+ FILE* fp = ACE_OS::fopen (this->filename_.c_str (), "w");
+ if (fp == 0)
+ {
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("Couldn't write to file %C\n"),
+ this->filename_.c_str()));
+ return -1;
+ }
+ ACE_OS::fprintf (fp,"<?xml version=\"1.0\"?>\n");
+ ACE_OS::fprintf (fp,"<%s>\n", Locator_XMLHandler::ROOT_TAG);
+
+ // Save servers
+ Locator_Repository::SIMap::ENTRY* sientry = 0;
+ Locator_Repository::SIMap::ITERATOR siit (this->servers ());
+ for (; siit.next (sientry); siit.advance() )
+ {
+ persist(fp, *sientry->int_id_, "\t");
+ }
+
+ // Save Activators
+ Locator_Repository::AIMap::ENTRY* aientry = 0;
+ Locator_Repository::AIMap::ITERATOR aiit (this->activators ());
+ for (; aiit.next (aientry); aiit.advance ())
+ {
+ ACE_CString aname = aientry->ext_id_;
+ persist(fp, *aientry->int_id_, "\t");
+ }
+
+ ACE_OS::fprintf (fp,"</%s>\n", Locator_XMLHandler::ROOT_TAG);
+ ACE_OS::fclose (fp);
+
+ return 0;
+}
+
+void
+XML_Backing_Store::persist (FILE* fp,
+ const Server_Info& info,
+ const char* tag_prepend,
+ const NameValues& name_values)
+{
+ ACE_CString server_id = ACEXML_escape_string (info.server_id);
+ ACE_CString name = ACEXML_escape_string (info.name);
+ ACE_CString activator = ACEXML_escape_string (info.activator);
+ ACE_CString cmdline = ACEXML_escape_string (info.cmdline);
+ ACE_CString wdir = ACEXML_escape_string (info.dir);
+ ACE_CString partial_ior = ACEXML_escape_string (info.partial_ior);
+ ACE_CString ior = ACEXML_escape_string (info.ior);
+
+ ACE_OS::fprintf (fp,"%s<%s", tag_prepend,
+ Locator_XMLHandler::SERVER_INFO_TAG);
+ ACE_OS::fprintf (fp," server_id=\"%s\"", server_id.c_str ());
+ ACE_OS::fprintf (fp," name=\"%s\"", name.c_str ());
+ ACE_OS::fprintf (fp," activator=\"%s\"", activator.c_str ());
+ ACE_OS::fprintf (fp," command_line=\"%s\"", cmdline.c_str ());
+ ACE_OS::fprintf (fp," working_dir=\"%s\"", wdir.c_str ());
+ ACE_CString amodestr =
+ ImR_Utils::activationModeToString (info.activation_mode);
+ ACE_OS::fprintf (fp," activation_mode=\"%s\"", amodestr.c_str ());
+ ACE_OS::fprintf (fp," start_limit=\"%d\"", info.start_limit);
+ ACE_OS::fprintf (fp," partial_ior=\"%s\"", partial_ior.c_str ());
+ ACE_OS::fprintf (fp," ior=\"%s\"", ior.c_str ());
+ ACE_OS::fprintf (fp," started=\"%d\"", !CORBA::is_nil(info.server.in()));
+ ACE_OS::fprintf (fp," jacorb_server=\"%d\"", info.jacorb_server);
+
+ NameValues::const_iterator name_value;
+ for (name_value = name_values.begin(); name_value != name_values.end(); ++name_value)
+ {
+ ACE_OS::fprintf (fp," %s=\"%s\"",
+ name_value->first.c_str(), name_value->second.c_str());
+ }
+
+ const CORBA::ULong length = info.env_vars.length ();
+ if (length > 0)
+ {
+ ACE_OS::fprintf (fp,">\n");
+ for (CORBA::ULong i = 0; i < info.env_vars.length (); ++i)
+ {
+ ACE_OS::fprintf (fp,"%s\t<%s", tag_prepend,
+ Locator_XMLHandler::ENVIRONMENT_TAG);
+ ACE_OS::fprintf (fp," name=\"%s\"", info.env_vars[i].name.in ());
+ ACE_CString val = ACEXML_escape_string(info.env_vars[i].value.in());
+ ACE_OS::fprintf (fp," value=\"%s\"", val.c_str());
+ ACE_OS::fprintf (fp,"/>\n");
+ }
+
+ ACE_OS::fprintf (fp,"%s</%s>\n", tag_prepend,
+ Locator_XMLHandler::SERVER_INFO_TAG);
+ }
+ else
+ {
+ ACE_OS::fprintf (fp,"/>\n");
+ }
+}
+
+void
+XML_Backing_Store::persist (FILE* fp,
+ const Activator_Info& info,
+ const char* tag_prepend,
+ const NameValues& name_values)
+{
+ ACE_OS::fprintf (fp,"%s<%s", tag_prepend,
+ Locator_XMLHandler::ACTIVATOR_INFO_TAG);
+ ACE_OS::fprintf( fp," name=\"%s\"", info.name.c_str ());
+ ACE_OS::fprintf (fp," token=\"%d\"", info.token);
+ ACE_OS::fprintf (fp," ior=\"%s\"", info.ior.c_str ());
+
+ NameValues::const_iterator name_value;
+ for (name_value = name_values.begin(); name_value != name_values.end(); ++name_value)
+ {
+ ACE_OS::fprintf (fp," %s=\"%s\"",
+ name_value->first.c_str(), name_value->second.c_str());
+ }
+
+ ACE_OS::fprintf (fp,"/>\n");
+}
+
+int
+XML_Backing_Store::init_repo(PortableServer::POA_ptr )
+{
+ // ignore load return since files don't have to exist
+ load(this->filename_);
+ return 0;
+}
+
+int
+XML_Backing_Store::load (const ACE_TString& filename, FILE* open_file)
+{
+ Locator_XMLHandler xml_handler (*this, this->orb_.in());
+ return load(filename, xml_handler, this->opts_.debug(), open_file);
+}
+
+int
+XML_Backing_Store::load (const ACE_TString& filename,
+ ACEXML_DefaultHandler& xml_handler,
+ unsigned int debug,
+ FILE* open_file)
+{
+ // xml input source will take ownership
+ ACEXML_FileCharStream* fstm;
+ ACE_NEW_RETURN (fstm,
+ ACEXML_FileCharStream,
+ -1);
+
+ int err;
+ // use the open_file stream if it is provided
+ if (open_file != 0)
+ err = fstm->use_stream(open_file,
+ filename.c_str());
+ else
+ err = fstm->open (filename.c_str());
+
+ if (debug > 9)
+ {
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("load %s%C\n"), filename.c_str(),
+ ((err == 0) ? ACE_TEXT ("")
+ : ACE_TEXT (" (file doesn't exist)"))));
+ }
+
+ if (err != 0)
+ {
+ delete fstm;
+ return err;
+ }
+
+ ACEXML_Parser parser;
+
+ // InputSource takes ownership
+ ACEXML_InputSource input (fstm);
+
+ parser.setContentHandler (&xml_handler);
+ parser.setDTDHandler (&xml_handler);
+ parser.setErrorHandler (&xml_handler);
+ parser.setEntityResolver (&xml_handler);
+
+ try
+ {
+ parser.parse (&input);
+ }
+ catch (const ACEXML_Exception& ex)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Error during load of ImR persistence xml file (%s)."),
+ filename.c_str()));
+ ex.print ();
+ return -1;
+ }
+ catch ( const ACEXML_SAXParseException* sax_ex)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Error during load of ImR persistence xml file (%s)."),
+ filename.c_str()));
+ sax_ex->print ();
+ return -1;
+ }
+
+
+
+ return 0;
+}
+
+const ACE_TCHAR*
+XML_Backing_Store::repo_mode() const
+{
+ return this->filename_.c_str();
+}
+
+void
+XML_Backing_Store::load_server (
+ const ACE_CString& server_id,
+ const ACE_CString& server_name,
+ bool jacorb_server,
+ const ACE_CString& activator_name,
+ const ACE_CString& startup_cmd,
+ const ImplementationRepository::EnvironmentList& env_vars,
+ const ACE_CString& working_dir,
+ ImplementationRepository::ActivationMode actmode,
+ int start_limit,
+ const ACE_CString& partial_ior,
+ const ACE_CString& ior,
+ bool server_started,
+ const NameValues& )
+{
+ const int limit = start_limit < 1 ? 1 : start_limit;
+
+ Server_Info *serv_inf;
+ ACE_NEW (serv_inf,
+ Server_Info (server_id, server_name, jacorb_server,
+ activator_name, startup_cmd, env_vars,
+ working_dir, actmode, limit,
+ partial_ior, ior));
+
+ Server_Info_Ptr si (serv_inf);
+
+ this->servers().rebind(server_name, si);
+
+ create_server(server_started, si);
+}
+
+void
+XML_Backing_Store::create_server(bool server_started,
+ const Server_Info_Ptr& si)
+{
+ if (!server_started || si->ior.is_empty())
+ return;
+
+ CORBA::Object_var obj = this->orb_->string_to_object(si->ior.c_str());
+ if (!CORBA::is_nil(obj.in()))
+ {
+ si->server =
+ ImplementationRepository::ServerObject::_unchecked_narrow (obj.in());
+ si->last_ping = ACE_Time_Value::zero;
+ }
+ else
+ si->server = ImplementationRepository::ServerObject::_nil();
+}
+
+void
+XML_Backing_Store::load_activator (const ACE_CString& activator_name,
+ long token,
+ const ACE_CString& ior,
+ const NameValues& )
+{
+ Activator_Info *ai;
+ ACE_NEW (ai,
+ Activator_Info (activator_name, token, ior));
+
+ Activator_Info_Ptr info (ai);
+ this->activators().rebind(activator_name, info);
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/XML_Backing_Store.h b/TAO/orbsvcs/ImplRepo_Service/XML_Backing_Store.h
new file mode 100644
index 00000000000..b4fe9900d5a
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/XML_Backing_Store.h
@@ -0,0 +1,161 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+* @file XML_Backing_Store.h
+*
+* $Id$
+*
+* This class defines an implementation of the backing store as a single XML file.
+*
+* @author Darrell Brunsch <brunsch@cs.wustl.edu>
+* @author Priyanka Gontla <gontla_p@ociweb.com>
+*/
+//=============================================================================
+
+#ifndef XML_BACKING_STORE_H
+#define XML_BACKING_STORE_H
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "Locator_Repository.h"
+
+#include <vector>
+
+class ACE_Configuration;
+class ACEXML_FileCharStream;
+class ACEXML_DefaultHandler;
+
+/**
+* @class XML_Backing_Store
+*
+* @brief XML backing store interface containing all ImR persistent information
+* in a single file
+*
+*/
+class XML_Backing_Store : public Locator_Repository
+{
+public:
+ typedef std::pair<ACE_CString, ACE_CString> NameValue;
+ typedef std::vector<NameValue> NameValues;
+ XML_Backing_Store(const Options& opts,
+ CORBA::ORB_ptr orb,
+ bool suppress_erase = false);
+
+ virtual ~XML_Backing_Store();
+
+ /// indicate the XML filename as the persistence mode for the repository
+ virtual const ACE_TCHAR* repo_mode() const;
+
+ /// create the Server_Info server object
+ /// @param server_id the Server_Info server_id
+ /// @param server_name the Server_Info server_name
+ /// @param activator_name the Server_Info activator
+ /// @param cmdline the Server_Info cmdline
+ /// @param env_vars the Server_Info env_vars
+ /// @param workin_dir the Server_Info dir
+ /// @param actmode the Server_Info activation_mode
+ /// @param start_limit the Server_Info start_limit
+ /// @param partial_ior the Server_Info partial_ior
+ /// @param ior the Server_Info ior
+ /// @param server_started indicates if the server object
+ /// existed when data was persisted
+ /// @param extra_params extra name value pairs that
+ /// were reported for the server
+ virtual void load_server (
+ const ACE_CString& server_id,
+ const ACE_CString& server_name,
+ bool jacorb_server,
+ const ACE_CString& activator_name,
+ const ACE_CString& cmdline,
+ const ImplementationRepository::EnvironmentList& env_vars,
+ const ACE_CString& working_dir,
+ ImplementationRepository::ActivationMode actmode,
+ int start_limit,
+ const ACE_CString& partial_ior,
+ const ACE_CString& ior,
+ bool server_started,
+ const NameValues& extra_params);
+
+ /// create the Activator_Info activator object
+ /// @param activator_name the Activator_Info name
+ /// @param token the Activator_Info token
+ /// @param ior the Activator_Info ior
+ /// @param extra_params extra name value pairs that
+ /// were reported for the activator
+ virtual void load_activator (const ACE_CString& activator_name,
+ long token,
+ const ACE_CString& ior,
+ const NameValues& extra_params);
+protected:
+ /// perform XML backing store specific initialization
+ /// (loads servers and activators from the backing store)
+ virtual int init_repo(PortableServer::POA_ptr imr_poa);
+
+ /// perform server persistent update
+ virtual int persistent_update(const Server_Info_Ptr& info, bool add);
+
+ /// perform activator persistent update
+ virtual int persistent_update(const Activator_Info_Ptr& info, bool add);
+
+ /// perform persistent remove
+ virtual int persistent_remove(const ACE_CString& name, bool activator);
+
+ /// load the contents of a file into the repo using a Locator_XMLHandler
+ /// @param filename the filename to read the contents from
+ /// @param open_file the already open FILE stream for the
+ /// filename
+ int load(const ACE_TString& filename, FILE* open_file = 0);
+
+ /// load the contents of a file into the repo using the provided
+ /// ACEXML_DefaultHandler
+ /// @param filename the filename to read the contents from
+ /// @param xml_handler the ACEXML_DefaultHandler to use to parse
+ /// the file
+ /// @param open_file the already open FILE stream for the
+ /// filename
+ static int load(const ACE_TString& filename,
+ ACEXML_DefaultHandler& xml_handler,
+ unsigned int debug,
+ FILE* open_file = 0);
+
+ /// persist the server
+ /// @param fp the FILE stream to persist the server contents to
+ /// @param info the Server_Info to persist
+ /// @param tag_prepend a character string to prepend at the start
+ /// of every xml line to maintain proper indentation
+ /// @param name_values extra name value pairs to write as attributes
+ void persist(FILE* fp,
+ const Server_Info& info,
+ const char* tag_prepend,
+ const NameValues& name_values = NameValues());
+
+ /// persist the activator
+ /// @param fp the FILE stream to persist the activator contents to
+ /// @param info the Server_Info to persist
+ /// @param tag_prepend a character string to prepend at the start
+ /// of every xml line to maintain proper indentation
+ /// @param name_values extra name value pairs to write as attributes
+ void persist(FILE* fp,
+ const Activator_Info& info,
+ const char* tag_prepend,
+ const NameValues& name_values = NameValues());
+
+ /// create the Server_Info server object
+ /// @param server_started indication from persistence indicating if the
+ /// server object was present
+ /// @param si the server info in question
+ void create_server(bool server_started, const Server_Info_Ptr& si);
+
+protected:
+ /// the filename indicated in the Options for the backing store
+ const ACE_TString filename_;
+
+private:
+ /// persist all servers and activators
+ int persist();
+};
+
+#endif /* XML_BACKING_STORE_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp
index 674a60b437a..2837ef12135 100644
--- a/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp
@@ -817,9 +817,18 @@ TAO_IMR_Op_IOR::run (void)
ACE_CString ior (imr_str.in ());
// Add the key
- ior += this->server_name_;
+ const char jacorb[] = ACE_TEXT_ALWAYS_CHAR ("JACORB:");
+ const char *posjacorb = ACE_OS::strstr (server_name_.c_str (), jacorb);
+ if (posjacorb)
+ {
+ ior += posjacorb + sizeof(jacorb) - 1;
+ }
+ else
+ {
+ ior += this->server_name_;
+ }
- ACE_DEBUG ((LM_DEBUG, "%s\n", ior.c_str ()));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s\n"), ior.c_str ()));
if (this->filename_.length () > 0)
{
@@ -828,7 +837,7 @@ TAO_IMR_Op_IOR::run (void)
if (file == 0)
{
ACE_ERROR_RETURN ((LM_ERROR,
- "Error: Unable to open %s for writing: %p\n",
+ ACE_TEXT ("Error: Unable to open %s for writing: %p\n"),
this->filename_.c_str ()),
-1);
}
diff --git a/TAO/orbsvcs/Naming_Service/FT_Naming_Main.cpp b/TAO/orbsvcs/Naming_Service/FT_Naming_Main.cpp
new file mode 100644
index 00000000000..4086db3d9a4
--- /dev/null
+++ b/TAO/orbsvcs/Naming_Service/FT_Naming_Main.cpp
@@ -0,0 +1,64 @@
+// $Id$
+
+#include "FT_Naming_Service.h"
+#include "ace/OS_main.h"
+
+#include "orbsvcs/Shutdown_Utilities.h"
+#include "tao/debug.h"
+
+#include "tao/ImR_Client/ImR_Client.h"
+
+class Naming_Svc_Shutdown : public Shutdown_Functor
+{
+public:
+ Naming_Svc_Shutdown (TAO_Naming_Service& ns);
+
+ void operator() (int which_signal);
+private:
+ TAO_Naming_Service& ns_;
+};
+
+Naming_Svc_Shutdown::Naming_Svc_Shutdown (TAO_Naming_Service& ns)
+ : ns_(ns)
+{
+}
+
+void
+Naming_Svc_Shutdown::operator() (int which_signal)
+{
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("FT Name Service: shutting down on signal %d\n"),
+ which_signal));
+ (void) this->ns_.shutdown ();
+}
+
+// Driver function for the TAO FT Naming Service.
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ TAO_FT_Naming_Service naming_service;
+
+ // Stuff to insure that we're gracefully shut down...
+ Naming_Svc_Shutdown killer (naming_service);
+ Service_Shutdown kill_contractor(killer);
+
+ if (naming_service.init (argc, argv) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT("Failed to start the Naming Service.\n")),
+ 1);
+ try
+ {
+ naming_service.run ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("NamingService"));
+ return 1;
+ }
+
+ naming_service.fini ();
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/Naming_Service/FT_Naming_Service.cpp b/TAO/orbsvcs/Naming_Service/FT_Naming_Service.cpp
new file mode 100644
index 00000000000..913c39088f8
--- /dev/null
+++ b/TAO/orbsvcs/Naming_Service/FT_Naming_Service.cpp
@@ -0,0 +1,31 @@
+// $Id$
+
+#include "FT_Naming_Service.h"
+#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h"
+#include "orbsvcs/Naming/Persistent_Naming_Context_Factory.h"
+
+// Default Constructor.
+TAO_FT_Naming_Service::TAO_FT_Naming_Service (void)
+{
+}
+
+// Constructor taking command-line arguments.
+TAO_FT_Naming_Service::TAO_FT_Naming_Service (int argc, ACE_TCHAR* argv[])
+ : TAO_Naming_Service (argc, argv)
+{
+}
+
+
+
+/// Create a server object for the naming service
+TAO_Naming_Server*
+TAO_FT_Naming_Service::create_naming_server ()
+{
+ return new (ACE_nothrow) TAO_FT_Naming_Server ();
+}
+
+
+// Destructor.
+TAO_FT_Naming_Service::~TAO_FT_Naming_Service (void)
+{
+}
diff --git a/TAO/orbsvcs/Naming_Service/FT_Naming_Service.h b/TAO/orbsvcs/Naming_Service/FT_Naming_Service.h
new file mode 100644
index 00000000000..3d77b0e0de5
--- /dev/null
+++ b/TAO/orbsvcs/Naming_Service/FT_Naming_Service.h
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+
+//==========================================================================
+/**
+ * @file FT_Naming_Service.h
+ *
+ * $Id$
+ *
+ * This class provides an override for the Naming_Service class factory
+ * method: create_naming_server ()
+ *
+ * @author Kevin Stanley <stanleyk@ociweb.com>
+ */
+//==========================================================================
+
+
+#ifndef TAO_FT_NAMING_SERVICE_H
+#define TAO_FT_NAMING_SERVICE_H
+
+#include /**/ "Naming_Service.h"
+
+#include "tao/ORB.h"
+
+class TAO_Naming_Server;
+
+/**
+ * @class TAO_FT_Naming_Service
+ *
+ * @brief Defines a class that encapsulates the implementation of the
+ * Fault Tolerant Naming Service.
+ *
+ * This class overrides the create_naming_server factory method inherited
+ * from <TAO_Naming_Service>.
+ */
+class TAO_FT_Naming_Service : public TAO_Naming_Service
+{
+public:
+ /// Default Constructor.
+ TAO_FT_Naming_Service (void);
+
+ /// Constructor taking the command-line arguments.
+ TAO_FT_Naming_Service (int argc, ACE_TCHAR* argv[]);
+
+ /// Factory method to create a server object for the naming service
+ virtual TAO_Naming_Server* create_naming_server ();
+
+ /// Destructor.
+ virtual ~TAO_FT_Naming_Service (void);
+
+};
+
+#endif /* TAO_FT_NAMING_SERVICE_H */
diff --git a/TAO/orbsvcs/Naming_Service/Naming_Service.cpp b/TAO/orbsvcs/Naming_Service/Naming_Service.cpp
index bb1a7fe56d7..73682314357 100644
--- a/TAO/orbsvcs/Naming_Service/Naming_Service.cpp
+++ b/TAO/orbsvcs/Naming_Service/Naming_Service.cpp
@@ -2,6 +2,7 @@
#include "Naming_Service.h"
+#include "orbsvcs/Naming/Naming_Server.h"
#include "orbsvcs/Daemon_Utilities.h"
#include "ace/Get_Opt.h"
#include "ace/Argv_Type_Converter.h"
@@ -9,14 +10,16 @@
// Default Constructor.
TAO_Naming_Service::TAO_Naming_Service (void)
- : time_ (0),
+ : my_naming_server_ (0),
+ time_ (0),
num_threads_ (1)
{
}
// Constructor taking command-line arguments.
TAO_Naming_Service::TAO_Naming_Service (int argc, ACE_TCHAR* argv[])
- : time_ (0),
+ : my_naming_server_(0),
+ time_ (0),
num_threads_ (1)
{
this->init (argc, argv);
@@ -41,14 +44,26 @@ TAO_Naming_Service::init (int argc, ACE_TCHAR* argv[])
// arguments.
this->parse_args (argc, argv);
+ // Factory method used to construct a naming server to be used in
+ // creation and initialization of the naming service components.
+ this->my_naming_server_ = this->create_naming_server ();
+
+ // For some reason we are unable to create a naming server.
+ if (this->my_naming_server_ == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO_Naming_Service::init -- ")
+ ACE_TEXT ("Unable to create a Naming_Server. Exiting.\n")),
+ -1);
+
// This function call initializes the naming service and returns
// '-1' in case of an exception.
- int const result = this->my_naming_server_.init_with_orb (argc,
+ int const result = this->my_naming_server_->init_with_orb (argc,
argv,
this->orb_.in ());
if (result == -1)
return result;
+
}
catch (const CORBA::Exception& ex)
{
@@ -172,7 +187,7 @@ TAO_Naming_Service::shutdown (void)
int
TAO_Naming_Service::fini (void)
{
- this->my_naming_server_.fini();
+ this->my_naming_server_->fini();
try
{
@@ -190,8 +205,18 @@ TAO_Naming_Service::fini (void)
return 0;
}
+/// Factory method used to create a server object for the naming service
+TAO_Naming_Server*
+TAO_Naming_Service::create_naming_server ()
+{
+ // Default behavior is to use the Naming_Server located in orbsvcs\orbsvcs\Naming
+ return new (ACE_nothrow) TAO_Naming_Server;
+}
+
+
// Destructor.
TAO_Naming_Service::~TAO_Naming_Service (void)
{
- // Destructor
+ // Invoke destructor of naming server which was created using the factory method
+ delete this->my_naming_server_;
}
diff --git a/TAO/orbsvcs/Naming_Service/Naming_Service.h b/TAO/orbsvcs/Naming_Service/Naming_Service.h
index 71a2eb6e211..abcf7df0516 100644
--- a/TAO/orbsvcs/Naming_Service/Naming_Service.h
+++ b/TAO/orbsvcs/Naming_Service/Naming_Service.h
@@ -17,7 +17,10 @@
#ifndef TAO_NAMING_SERVICE_H
#define TAO_NAMING_SERVICE_H
-#include "orbsvcs/Naming/Naming_Server.h"
+#include /**/ "ace/pre.h"
+#include "tao/ORB.h"
+
+class TAO_Naming_Server;
/**
* @class TAO_Naming_Service
@@ -44,10 +47,13 @@ public:
virtual int fini (void);
/// Run the TAO_Naming_Service.
- int run (void);
+ virtual int run (void);
/// Shut down the TAO_Naming_Service; you must still call fini().
- void shutdown (void);
+ virtual void shutdown (void);
+
+ /// Factory method to create a server object for the naming service
+ virtual TAO_Naming_Server* create_naming_server ();
/// Destructor.
virtual ~TAO_Naming_Service (void);
@@ -62,7 +68,7 @@ protected:
CORBA::ORB_var orb_;
/// Naming Server instance.
- TAO_Naming_Server my_naming_server_;
+ TAO_Naming_Server* my_naming_server_;
/// After how long the server should stop listening to requests (in
/// seconds).
@@ -72,4 +78,6 @@ protected:
int num_threads_;
};
+#include /**/ "ace/post.h"
+
#endif /* TAO_NAMING_SERVICE_H */
diff --git a/TAO/orbsvcs/Naming_Service/Naming_Service.mpc b/TAO/orbsvcs/Naming_Service/Naming_Service.mpc
index cba797ebd34..e8052b297d4 100644
--- a/TAO/orbsvcs/Naming_Service/Naming_Service.mpc
+++ b/TAO/orbsvcs/Naming_Service/Naming_Service.mpc
@@ -13,6 +13,18 @@ project : orbsvcsexe, install, naming_serv, imr_client, svc_utils {
}
}
+project (FT_Naming_Service) : orbsvcsexe, install, ft_naming_serv, naming_serv, imr_client, svc_utils {
+ exename = tao_ft_naming
+ Header_Files {
+ FT_Naming_Service.h
+ }
+ Source_Files {
+ FT_Naming_Main.cpp
+ FT_Naming_Service.cpp
+ Naming_Service.cpp
+ }
+}
+
project(NT_Naming_Service) : orbsvcsexe, install, naming_serv, svc_utils {
requires += winnt
exename = tao_nt_cosnaming
diff --git a/TAO/orbsvcs/Naming_Service/README b/TAO/orbsvcs/Naming_Service/README
index c6f84e5ddf6..7030d444f6a 100644
--- a/TAO/orbsvcs/Naming_Service/README
+++ b/TAO/orbsvcs/Naming_Service/README
@@ -13,17 +13,18 @@ The following describes how to run the TAO Naming Service.
1. Syntax
% Naming_Service [-ORBNameServicePort nsport]
+ [-b base_address]
+ [-d ]
+ [-f persistence_file_name]
+ [-m (1=enable multicast responses,0=disable(default)]
+ [-n number_of_threads]
[-o ior_output_file]
[-p pid_file_name]
+ [-r directory]
[-s context_size]
[-t time]
- [-f persistence_file_name]
- [-b base_address]
- [-m (1=enable multicast responses,0=disable(default)]
- [-z time]
- [-d ]
[-u directory]
- [-r directory]
+ [-z time]
2. Optional Command-line Arguments
@@ -34,23 +35,15 @@ The following describes how to run the TAO Naming Service.
use of multicast. This is only used when multicast
responding is enabled via '-m 1'.
- -o ior_output_file
- The name of the file, in which to store the IOR of the
- root Naming Service context.
-
- -p pid_file_name
- The name of the file, in which to store the process id
- of the Naming Service server.
-
- -s context_size
- Size of the hash table allocated for the root Naming
- Context (if one is created). All contexts created
- under the root will use the same size for their hash
- tables. The default is 1024.
+ -b base_address
+ The address used for memory mapping the file specified
+ with the "-f" option above. The value supplied with
+ this option is only used when the Naming Service runs
+ in persistent mode, i.e., "-f" option is present.
- -t time
- How long (in seconds) the server should listen for
- client requests before terminating.
+ -d
+ Provides Naming Service specific debug information. By default
+ no diagnostics are given.
-f persistence_file_name
The name of the file to use to store/retrieve
@@ -58,12 +51,6 @@ The following describes how to run the TAO Naming Service.
option, Naming Service is started in non-persistent
mode.
- -b base_address
- The address used for memory mapping the file specified
- with the "-f" option above. The value supplied with
- this option is only used when the Naming Service runs
- in persistent mode, i.e., "-f" option is present.
-
-m <0|1>
TAO offers a simple, very non-standard method for
clients to discover the initial reference for the
@@ -74,29 +61,46 @@ The following describes how to run the TAO Naming Service.
such multicast queries (use the Interoperable Naming
Service bootstrap options instead).
- -z time
- A relative round trip timeout value (in seconds) that
- the service should wait for when trying to progress an
- operation through a federated naming context before
- timing out and throwing a 'Cannot proceed' exception
- to the client. If no value is set this will never occur.
+ -n number_of_threads
+ Specify a number of threads to be used to run the ORB.
+ Default is 1.
- -d
- Provides Naming Service specific debug information. By default
- no diagnostics are given.
+ -o ior_output_file
+ The name of the file, in which to store the IOR of the
+ root Naming Service context.
- -u directory
- Use a flat-file persistence implementation that stores object
- reference information in a file per context. Each context file
- is placed in the directory specified.
+ -p pid_file_name
+ The name of the file, in which to store the process id
+ of the Naming Service server.
+
+ -s context_size
+ Size of the hash table allocated for the root Naming
+ Context (if one is created). All contexts created
+ under the root will use the same size for their hash
+ tables. The default is 1024.
+
+ -t time
+ How long (in seconds) the server should listen for
+ client requests before terminating.
-r directory
- Use redundant flat-file persistnece; same as the -u option,
+ Use redundant flat-file persistence; same as the -u option,
except more than one instance of the TAO Naming Service server
can run, each using the same set of disk files, to achieve a
degree of fault tolerence (as long as directory is accessible
to both servers).
+ -u directory
+ Use a flat-file persistence implementation that stores object
+ reference information in a file per context. Each context file
+ is placed in the directory specified.
+
+ -z time
+ A relative round trip timeout value (in seconds) that
+ the service should wait for when trying to progress an
+ operation through a federated naming context before
+ timing out and throwing a 'Cannot proceed' exception
+ to the client. If no value is set this will never occur.
3. Environment Variables
diff --git a/TAO/orbsvcs/Naming_Service/README.FT_Naming b/TAO/orbsvcs/Naming_Service/README.FT_Naming
new file mode 100644
index 00000000000..c499e7198d5
--- /dev/null
+++ b/TAO/orbsvcs/Naming_Service/README.FT_Naming
@@ -0,0 +1,252 @@
+$Id$
+
+This directory contains files that implement a server for the TAO
+FT Naming Service. The FT Naming Service supports a dual redundant
+scheme for fault tolerance and also implements a load balancing
+mechanism when objects are bound to an object group within a named
+element in the naming service.
+
+How to Run the TAO FT Naming Service
+=================================
+
+1. Syntax
+
+ % tao_ft_naming [-ORBNameServicePort nsport]
+ [--primary]
+ [--backup]
+ [-b base_address]
+ [-d debug_flag]
+ [-m (1=enable multicast responses,0=disable(default)]
+ [-n number_of_threads]
+ [-c ft_naming_service_ior_file]
+ [-g ft_naming_manager_ior_file]
+ [-o this_servers_object_ref_ior_file]
+ [-r directory_for_naming_context_replication]
+ [-v directory_for_object_group_replication]
+ [-s context_size]
+ [-z time]
+
+2. Optional Command-line Arguments
+
+ --primary
+ Start this FT Naming Server in the primary role for the
+ dual redundant replication scheme. The primary must be
+ started first and then the backup. If neither primary
+ nor backup options are supplied, the server will run
+ standalone without support for fault tolerance.
+
+ --backup
+ Start this FT Naming Service in the backup role for the
+ dual redundant replication scheme. The backup must be
+ started after the primary and will coordinate with the
+ primary to set up the notifications with the peer for
+ changes to the naming contexts and object groups.
+
+ -ORBNameServicePort nsport
+ Multicast port for listening for requests from clients
+ trying to bootstrap to a Naming Service through the
+ use of multicast. This is only used when multicast
+ responding is enabled via '-m 1'.
+
+ -b base_address
+ The address used for memory mapping the file specified
+ with the "-f" option above. The value supplied with
+ this option is only used when the Naming Service runs
+ in persistent mode, i.e., "-f" option is present.
+
+ -d
+ Provides Naming Service specific debug information. By default
+ no diagnostics are given.
+
+ -m <0|1>
+ TAO offers a simple, very non-standard method for
+ clients to discover the initial reference for the
+ Naming Service. However, since it can be inadequate and cause
+ unexpected results if, for example, there are multiple
+ naming services running on the network, the DEFAULT
+ behavior is for the Naming Service to NOT RESPOND to
+ such multicast queries (use the Interoperable Naming
+ Service bootstrap options instead). The multicast option
+ only works with for standalone servers and fault tolerance
+ will not be supported by the server when started with this
+ option.
+
+ -n number_of_threads
+ Specify a number of threads to be used to run the ORB.
+ Default is 1.
+
+ -c ns_ior_output_file
+ The name of the file, in which to store the IOR containing
+ the profiles for both this naming servers root naming
+ context and the peer naming service root naming context.
+ This option should only be used for the --backup naming
+ service.
+
+ -g nm_ior_output_file
+ The name of the file, in which to store the IOR containing
+ the profiles for both this naming manager and the peer naming
+ manager. This option should only be used for the --backup
+ naming service.
+
+ -h nm_ior_output_file
+ The name of the file, in wich to store the IOR of the
+ naming manager for just this service. This option can
+ be useful for testing.
+
+ -o ior_output_file
+ The name of the file, in which to store the IOR of the
+ root Naming Service context for just this server. This
+ option is useful if you want to run the naming service
+ standalone, without the backup and need to obtain the
+ IOR of the root context implemented by this process.
+
+ -p pid_file_name
+ The name of the file, in which to store the process id
+ of the Naming Service server.
+
+ -s context_size
+ Size of the hash table allocated for the root Naming
+ Context (if one is created). All contexts created
+ under the root will use the same size for their hash
+ tables. The default is 1024.
+
+ -t time
+ How long (in seconds) the server should listen for
+ client requests before terminating.
+
+ -f persistence_file_name
+ The name of the file to use to store/retrieve
+ persistent state of the Naming Service.
+
+ -r directory
+ Use redundant flat-file persistence; same as the -u option,
+ except more than one instance of the TAO Naming Service server
+ can run, each using the same set of disk files, to achieve a
+ degree of fault tolerence (as long as directory is accessible
+ to both servers). Make sure you start the --primary and --backup
+ with the same directory so they will share the persistence
+ directory.
+
+ -u directory
+ Use a flat-file persistence implementation that stores object
+ reference information in a file per context. Each context file
+ is placed in the directory specified. This option can be used
+ when running the FT Naming Service standalone - without
+ fault tolerance/redundancyl.
+
+ -v directory
+ Use redundant flat-file persistence for naming contexts that
+ are created within this server. Users can add object to the
+ object group and bind the object group to a name within the
+ naming service to obtain a load balancing capability.
+ Make sure you start the --primary and --backup
+ with the same directory so they will share the persistence
+ directory.
+
+ -z time
+ A relative round trip timeout value (in seconds) that
+ the service should wait for when trying to progress an
+ operation through a federated naming context before
+ timing out and throwing a 'Cannot proceed' exception
+ to the client. If no value is set this will never occur.
+
+3. Environment Variables
+
+ NameServicePort
+ Multicast port for listening for requests from clients
+ trying to bootstrap to a Naming Service through the
+ use of multicast. This is only used when multicast
+ responding is enabled via '-m 1'.
+
+4. Persistence
+
+ When running as a fault tolerant service, the TAO FT Naming Service
+ uses flat file persistence. It may also be run with no persistence,
+ however, upon the failure of the process, no state will be saved
+ and it will not provide the dual-redundant fault-tolerance capability.
+
+ 1. If the specified persistence directories for naming context
+ data and object group data do not exist, the server will exit.
+
+ 2. If the specified file exists, it is scanned and:
+
+ a) If any inconsistency is detected in the stored
+ state, or the file is not recognized by the Naming
+ Service, the server exits. (This may happen, for
+ example, if a server or host crashed in the middle of
+ writing a record to this file on a previous run). A
+ noncorrupted version of the file must be used instead.
+
+ b) If the file is recognized and is ok, the state
+ stored in the file becomes the current state of the
+ Naming Service.
+
+5. Implementation Policies
+
+ a. No support for BindingIterators
+
+ With the use of redundancy between a pair of naming
+ servers, there is no way to guarantee that the context
+ structure being iterated on would remain consistent,
+ so the user must ensure that when invoking the list
+ operation that a 'how_many' value must be provided that
+ is sufficiently large to hold all returned bindings in
+ a BindingList with no BindingIterator being needed. If
+ the 'how_many' parameter is insufficiently large, the
+ FT Naming Service will throw a CORBA::NO_IMPLEMENT
+ exception.
+
+ b. Dealing with orphaned contexts
+
+ This implementation of the Naming Service does not
+ include any form of 'garbage collection' for orphaned
+ naming contexts. It is solely the responsibility of
+ clients to clean up after themselves and not leak
+ server resources. All the resources, including
+ orphaned contexts, are released during the Naming
+ Server shutdown.
+
+6. Clients: ways to bootstrap to the Naming Service:
+
+ There are several methods for a client to bootstrap to a
+ Naming Service, i.e., there are several mechanisms
+ <resolve_initial_references> can use when asked for
+ "NameService". In order of predictable behavior, they are:
+
+ 1. Command-line options
+
+ The "-ORBInitRef NameService=IOR:..." or environment
+ variable NameServiceIOR can be used on the client side
+ to specify the object that the call to
+ <resolve_initial_references> should return to the
+ client. (On the server side, -c option can be used in
+ the backup Naming Service to write the ior).
+
+ Example (Unix, same host):
+
+ % $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service
+ -r NameService -v ObjectGroups --primary
+ % $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service
+ -r NameService -v ObjectGroups -c ns_ior_file --backup
+ % my_client -ORBInitRef NameService=file://ns_ior_file
+
+ On the first line, we start the primary Naming
+ Service. On the second line we start the backup
+ Naming Service and output the multi-profile IOR to
+ to <ns_ior_file>. On the third line, we start
+ some client, and specify the ior
+ <resolve_initial_references> should return for
+ the Naming Service in a file format.
+
+
+Troubleshooting
+============================================
+
+Q1. Error Message: "Invalid persistence directory" or "Invalid object
+group persistence directory"
+
+A1. On starting, the error message "Invalid persistence directory"
+indicates that the supplied value for the -r option does not point
+to a directory that can be used to store the state of the naming contexts
+or object groups. Make sure that the provided directories exist and
+that they are write enabled.
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
}
}
}
diff --git a/TAO/orbsvcs/tests/Bug_2777_Regression/run_test.pl b/TAO/orbsvcs/tests/Bug_2777_Regression/run_test.pl
index 60fbbfbcf21..e6bfe97b362 100755
--- a/TAO/orbsvcs/tests/Bug_2777_Regression/run_test.pl
+++ b/TAO/orbsvcs/tests/Bug_2777_Regression/run_test.pl
@@ -17,36 +17,7 @@ foreach $i (@ARGV) {
}
}
-my $exec_extn = "";
-if ($^O eq "MSWin32") {
- $exec_extn = ".exe";
-}
-
-my @nslist_paths = (["../../../../bin", ""],
- ["../../../bin", ""],
- ["../../../../TAO/utils/nslist", ""]);
-if (grep(($_ eq 'ARCH'), @PerlACE::ConfigList::Configs)) {
- push @nslist_paths, ["../../../../bin/" . $PerlACE::Process::ExeSubDir,
- "../../../../bin"];
-}
-
-my $nslist_path = "";
-for my $p (@nslist_paths) {
- my $use_path = ($p->[1] eq "") ? $p->[0] : $p->[1];
- if (-e $p->[0] . '/tao_nslist') {
- $nslist_path = $use_path . '/tao_nslist';
- last;
- }
- if ($exec_extn ne "" && -e $p->[0] . '/tao_nslist' . $exec_extn) {
- $nslist_path = $use_path . '/tao_nslist';
- last;
- }
-}
-
-if ($nslist_path eq "") {
- print STDERR "ERROR: tao_nslist utility not found.\n";
- exit 1;
-}
+my $nslist_path = "$ENV{ACE_ROOT}/bin/tao_nslist";
## The two test targets will communicate over shared memory (SHMIOP) so they
## can't be 32-bit and 64-bit executables on the same host.
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Basic.cpp b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Basic.cpp
new file mode 100644
index 00000000000..3f2061b3483
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Basic.cpp
@@ -0,0 +1,64 @@
+// $Id$
+
+#include "Basic.h"
+
+Basic::Basic (CORBA::Object_ptr object_group,
+ FT_Naming::NamingManager_ptr lm,
+ CORBA::ORB_ptr orb,
+ const char *loc)
+ : object_group_name_ (ACE_TEXT_ALWAYS_CHAR ("BasicGroup")),
+ orb_ (CORBA::ORB::_duplicate (orb))
+{
+ this->object_group_ = CORBA::Object::_duplicate (object_group);
+ this->nm_ = FT_Naming::NamingManager::_duplicate (lm);
+ this->location_ = CORBA::string_dup (loc);
+}
+
+char *
+Basic::get_string (void)
+{
+ return CORBA::string_dup (this->location_.in ());
+}
+
+void
+Basic::remove_member (void)
+{
+ try
+ {
+ PortableGroup::Location location (1);
+ location.length (1);
+ location[0].id = CORBA::string_dup (this->location_.in ());
+ this->nm_->remove_member (this->object_group_.in (),
+ location);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - Removed Member at Location <%s>\n"),
+ this->location_.in ()));
+
+ }
+ catch (const PortableGroup::ObjectNotFound& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Caught exception in remove_member"));
+ throw CORBA::INTERNAL ();
+ }
+ catch (const PortableGroup::MemberNotFound& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Caught exception in remove_member"));
+ throw CORBA::INTERNAL ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception caught while destroying member\n"));
+ }
+
+}
+
+
+void
+Basic::shutdown (void)
+{
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Basic.h b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Basic.h
new file mode 100644
index 00000000000..1664eddc322
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Basic.h
@@ -0,0 +1,59 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#ifndef BASIC_H
+#define BASIC_H
+
+#include "TestS.h"
+#include "orbsvcs/FT_NamingManagerC.h"
+#include "orbsvcs/PortableGroupC.h"
+
+#if defined (_MSC_VER)
+# pragma warning(push)
+# pragma warning (disable:4250)
+#endif /* _MSC_VER */
+
+class LB_Basic_Test;
+
+/// Implement the Test::Basic interface
+class Basic
+ : public virtual POA_Test::Basic
+{
+public:
+ /// Constructor
+ Basic (CORBA::Object_ptr object_group,
+ FT_Naming::NamingManager_ptr lm,
+ CORBA::ORB_ptr orb,
+ const char *loc);
+
+ virtual char * get_string (void);
+
+ virtual void shutdown (void);
+
+ virtual void remove_member (void);
+
+private:
+
+ const char* object_group_name_;
+
+ /// Use an ORB reference to convert strings to objects and shutdown
+ /// the application.
+ CORBA::ORB_var orb_;
+
+ /// Naming Manager Reference used to delete the member from the
+ /// object group.
+ FT_Naming::NamingManager_var nm_;
+
+ /// location of the member
+ CORBA::String_var location_;
+
+ /// Object Group reference.
+ CORBA::Object_var object_group_;
+};
+
+#if defined(_MSC_VER)
+# pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* BASIC_H */
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerant.mpc b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerant.mpc
new file mode 100644
index 00000000000..5a6f64227f4
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerant.mpc
@@ -0,0 +1,32 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Client) : ftnaming {
+ exename = client
+
+ Source_Files {
+ client.cpp
+ }
+
+}
+
+project(*idl): taoidldefaults {
+ IDL_Files {
+ Test.idl
+ }
+ custom_only = 1
+}
+
+project(*server): ftnaming {
+ after += *idl
+ exename = server
+ Source_Files {
+ TestC.cpp
+ TestS.cpp
+ server.cpp
+ LB_server.cpp
+ Basic.cpp
+ }
+ IDL_Files {
+ }
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/LB_server.cpp b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/LB_server.cpp
new file mode 100644
index 00000000000..ee4f5dd9ed9
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/LB_server.cpp
@@ -0,0 +1,229 @@
+// $Id$
+
+#include "LB_server.h"
+#include "Basic.h"
+
+#include "TestC.h"
+#include "ace/OS_NS_stdio.h"
+
+LB_server::LB_server (int argc, ACE_TCHAR **argv)
+ : argc_ (argc)
+ , argv_ (argv)
+ , ior_output_file_ (ACE_TEXT ("obj.ior"))
+{
+}
+
+int
+LB_server::destroy (void)
+{
+ try
+ {
+ this->naming_manager_->delete_object_group (
+ ACE_TEXT_ALWAYS_CHAR ("BasicGroup"));
+
+ //TODO: Does the FT_NamingManager need a destroy method?
+// this->naming_manager_->destroy (1, 1);
+
+ this->orb_->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception caught while destroying LB_server\n"));
+ return -1;
+ }
+ return 0;
+
+}
+
+CORBA::ORB_ptr
+LB_server::orb (void)
+{
+ return this->orb_.in ();
+}
+
+CORBA::Object_ptr
+LB_server::object_group (void)
+{
+ return this->object_group_.in ();
+}
+
+FT_Naming::NamingManager_ptr
+LB_server::naming_manager (void)
+{
+ return this->naming_manager_.in ();
+}
+
+int
+LB_server::write_ior_to_file (const char *ior)
+{
+ FILE *output_file =
+ ACE_OS::fopen (this->ior_output_file_, ACE_TEXT_ALWAYS_CHAR("w"));
+
+ if (output_file == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Cannot open output file for writing IOR:")));
+ return -1;
+ }
+
+ ACE_OS::fprintf (output_file, ACE_TEXT_ALWAYS_CHAR ("%s"), ior);
+ ACE_OS::fclose (output_file);
+ return 0;
+}
+
+int
+LB_server::parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ this->ior_output_file_ = get_opts.opt_arg ();
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("usage: %s ")
+ ACE_TEXT ("-o <iorfile>")
+ ACE_TEXT ("\n"),
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+LB_server::start_orb_and_poa (void)
+{
+ try
+ {
+ // Initialise the ORB.
+ this->orb_ = CORBA::ORB_init (this->argc_, this->argv_);
+
+ CORBA::Object_var poa_object =
+ this->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) Unable to initialize ")
+ ACE_TEXT ("the POA.\n")),
+ -1);
+
+ this->root_poa_ = PortableServer::POA::_narrow (poa_object.in ());
+
+ PortableServer::POAManager_var poa_manager =
+ this->root_poa_->the_POAManager ();
+
+ poa_manager->activate ();
+
+ ACE_Time_Value timeout (10); // Wait up to 10 seconds for the naming service
+ if (name_svc_.init (this->orb_, &timeout) != 0)
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ ACE_TEXT (" (%P|%t) LB_server: Could not connect ")
+ ACE_TEXT ("to naming service.\n")),
+ -1);
+
+ CORBA::Object_var obj = this->orb_->resolve_initial_references (
+ ACE_TEXT_ALWAYS_CHAR ("NamingManager"));
+
+ this->naming_manager_ =
+ FT_Naming::NamingManager::_narrow (obj.in ());
+
+ if (CORBA::is_nil (this->naming_manager_.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" (%P|%t) Unable to get Naming Manager ")
+ ACE_TEXT ("Reference.\n")),
+ -1);
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception raised initialising ORB or POA"));
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int
+LB_server::create_object_group (void)
+{
+ try
+ {
+ if (this->parse_args (argc_, argv_) != 0)
+ return -1;
+
+ PortableGroup::Criteria criteria (2);
+ criteria.length (1);
+
+ PortableGroup::Property &mem_style = criteria[0];
+ mem_style.nam.length (1);
+
+ // Set the membership style property
+ mem_style.nam[0].id = CORBA::string_dup (
+ ACE_TEXT_ALWAYS_CHAR ("org.omg.PortableGroup.MembershipStyle"));
+
+ PortableGroup::MembershipStyleValue msv =
+ PortableGroup::MEMB_APP_CTRL;
+ mem_style.val <<= msv;
+
+ this->object_group_ = this->naming_manager_->create_object_group (
+ ACE_TEXT_ALWAYS_CHAR ("BasicGroup"),
+ FT_Naming::ROUND_ROBIN,
+ criteria);
+
+ CORBA::String_var ior =
+ this->orb_->object_to_string (this->object_group_.in ());
+
+ this->write_ior_to_file (ior.in ());
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception raised while creating object group"));
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int
+LB_server::register_servant (Basic *servant, const char *loc)
+{
+ try
+ {
+ Test::Basic_var basic =
+ servant->_this ();
+
+ PortableGroup::Location location (1);
+ location.length (1);
+
+ location[0].id = CORBA::string_dup (loc);
+
+ this->naming_manager_->add_member (this->object_group_.in (),
+ location,
+ basic.in ());
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception raised while registering servant"));
+ return -1;
+ }
+
+ return 0;
+}
+
+TAO_Naming_Client&
+LB_server::name_svc ()
+{
+ return name_svc_;
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/LB_server.h b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/LB_server.h
new file mode 100644
index 00000000000..d6df78c52f8
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/LB_server.h
@@ -0,0 +1,98 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file LB_server.h
+ *
+ * $Id$
+ *
+ * @author Jaiganesh Balasubramanian <jai@doc.ece.uci.edu>
+ * @author Ossama Othman <ossama@uci.edu>
+ */
+//=============================================================================
+
+
+#include "orbsvcs/FT_NamingManagerC.h"
+#include "orbsvcs/PortableGroupC.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "ace/Get_Opt.h"
+#include "orbsvcs/Naming/Naming_Client.h"
+
+// Forward Declaration of the kind of servant we would like to handle
+// by the server.
+class Basic;
+
+/**
+ * @class LB_server
+ *
+ * @brief Encapsulate the test in class.
+ *
+ * TODO: Fix description
+ * This is a class used to retrieve the NamingManager reference and
+ * create the Object Group. Servants add themselves to the object
+ * group and the object group reference is published to the clients.
+ * Clients then invoke the "servant operations" on the NamingManager
+ * itself. At this point the Load Balancing cycle starts.
+ */
+class LB_server
+{
+public:
+
+ /// Constructor
+ LB_server (int argc, ACE_TCHAR **argv);
+
+ /// destroys NamingManager, ORB and POA.
+ int destroy (void);
+
+ /// start the ORB.
+ int start_orb_and_poa (void);
+
+ /// Get the NamingManager Interface.
+ int init (int argc, ACE_TCHAR **argv);
+
+ /// Create the Object Group using the Load Manager Reference.
+ int create_object_group (void);
+
+ /// register the servants with the object group.
+ int register_servant (Basic *servant, const char *loc);
+
+ /// obtain the name service facade
+ TAO_Naming_Client& name_svc ();
+
+ /// for servants to register to the initialised ORB.
+ CORBA::ORB_ptr orb (void);
+
+ /// for servants to get the reference for object_group.
+ CORBA::Object_ptr object_group (void);
+
+ /// for servants to get the reference for object_group.
+ FT_Naming::NamingManager_ptr naming_manager (void);
+
+private:
+
+ int parse_args (int, ACE_TCHAR **);
+
+private:
+
+ /// Load Manager
+ FT_Naming::NamingManager_var naming_manager_;
+
+ /// Object Group.
+ CORBA::Object_var object_group_;
+
+ /// factory id for the object group.
+ PortableGroup::GenericFactory::FactoryCreationId_var fcid_;
+
+ /// Used to force the creation of the object group only once.
+ static int called_once_;
+
+ /// write the IOR to a file so that it can be read later.
+ int write_ior_to_file (const char *);
+
+ CORBA::ORB_var orb_;
+ int argc_;
+ ACE_TCHAR **argv_;
+ PortableServer::POA_var root_poa_;
+ const ACE_TCHAR *ior_output_file_;
+ TAO_Naming_Client name_svc_;
+};
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/README b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/README
new file mode 100644
index 00000000000..ba1c835824b
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/README
@@ -0,0 +1,234 @@
+$Id$
+
+This program tests the following fault tolerant naming service implementation
+use cases:
+
+1) Failover: Validate that a client can seamlessly connect to the alternate
+ server of a server naming server pair after the other server has been
+ terminated.
+
+2) Persistence: Validate that repository data written by the naming service is
+ available upon startup.
+
+3) Equivalence: Validate that a client can seamlessly invoke naming operations
+ on either server instance.
+
+
+================================================================================
+Failover Test
+================================================================================
+
+<hostname> = <local_host>
+<port1> = <first unused port>
+<port2> = <second unused port>
+
+1) Create empty NameService and GroupService directories
+
+ cd $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant
+ mkdir NameService
+ mkdir GroupService
+
+2) Start primary tao_ft_naming process
+ $TAO_ROOT/orbsvcs/Naming_Service/tao_ft_naming --primary \
+ -ORBListenEndPoints iiop://<hostname>:<port1> \
+ -m 0 \
+ -r NameService \
+ -v GroupService &
+
+3) Start backup tao_ft_naming process
+
+ $TAO_ROOT/orbsvcs/Naming_Service/tao_ft_naming --backup \
+ -ORBListenEndPoints iiop://<hostname>:<port2> \
+ -m 0 \
+ -c $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant/ns.ior \
+ -g $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant/nm.ior \
+ -r NameService \
+ -v GroupService &
+
+4) Terminate primary tao_ft_naming process
+
+5) Run client with failover argument
+
+ client --failover \
+ -p file:///$TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant/ns.ior \
+ -r file://$TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant/nm.ior \
+ -b 4 -d 4
+
+ ==============================================================================
+ Example Output:
+ ==============================================================================
+ INFO: Failover Name Test OK
+ INFO: nm1ref: file:///tmp/ramdisk/tmp/nm.ior
+ INFO: Object Group Found In Repository
+ INFO: Failover ObjectGroup Test OK
+
+6) Cleanup
+
+ rm -rf NameService
+ rm -rf GroupService
+
+================================================================================
+Persistence Test
+================================================================================
+
+<hostname> = <local_host>
+<port1> = <unused port>
+
+1) Create empty NameService and GroupService directories
+
+ cd $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant
+ mkdir NameService
+ mkdir GroupService
+
+2) Start tao_ft_naming
+
+ $TAO_ROOT/orbsvcs/Naming_Service/tao_ft_naming \
+ -ORBListenEndPoints iiop://<hostname>:<port1> \
+ -g $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant/nm.ior \
+ -o $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant/ns.ior \
+ -v GroupService \
+ -u NameService &
+
+3) Start test object server
+
+ server -ORBDefaultInitRef corbaloc:iiop:<hostname>:<port1> \
+ -o $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant/srv.ior &
+
+4) Run the test client with the persistence and create arguments
+
+ client --persistence --create \
+ -p corbaloc:iiop:<hostname>:<port1>/NameService \
+ -r corbaloc:iiop:<hostname>:<port1>/NamingManager \
+ -b 4 -d 4
+
+ ==============================================================================
+ Example Output:
+ ==============================================================================
+ INFO: Persistence Creation Name Test OK
+ INFO: Object Group BasicGroup Found In Repository
+ INFO: validating group member location1
+ INFO: object group member at location1 reports location1
+ INFO: validating group member location2
+ INFO: object group member at location2 reports location2
+ INFO: validating group member location3
+ INFO: object group member at location3 reports location3
+ INFO: validating group member location4
+ INFO: object group member at location4 reports location4
+ INFO: validating group member location5
+ INFO: object group member at location5 reports location5
+ INFO: validating group member location6
+ INFO: object group member at location6 reports location6
+ INFO: Persistence Creation ObjectGroup Test OK
+
+
+5) Terminate tao_ft_naming and then restart it with the original arguments
+
+ kill `pidof $TAO_ROOT/orbsvcs/Naming_Service/tao_ft_naming`
+
+ $TAO_ROOT/orbsvcs/Naming_Service/tao_ft_naming \
+ -ORBListenEndPoints iiop://<hostname>:<port1> \
+ -g $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant/nm.ior \
+ -o $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant/ns.ior \
+ -v GroupService \
+ -u NameService &
+
+6) Now run the test client with the persistence and valdiate arguments
+
+ client --persistence --validate \
+ -p corbaloc:iiop:<hostname>:<port1>/NameService \
+ -r corbaloc:iiop:<hostname>:<port1>/NamingManager \
+ -b 4 -d 4
+
+ ==============================================================================
+ Example Output:
+ ==============================================================================
+ INFO: Persistence Validation Name Test OK
+ INFO: Object Group BasicGroup Found In Repository
+ INFO: validating group member location1
+ INFO: object group member at location1 reports location1
+ INFO: validating group member location2
+ INFO: object group member at location2 reports location2
+ INFO: validating group member location3
+ INFO: object group member at location3 reports location3
+ INFO: validating group member location4
+ INFO: object group member at location4 reports location4
+ INFO: validating group member location5
+ INFO: object group member at location5 reports location5
+ INFO: validating group member location6
+ INFO: object group member at location6 reports location6
+ INFO: Persistence Validation ObjectGroup Test OK
+
+7) Cleanup
+
+ rm -rf NameService
+ rm -rf GroupService
+
+
+================================================================================
+Redundant Equivalancy Test
+================================================================================
+
+<hostname> = <local_host>
+<port1> = <first unused port>
+<port2> = <second unused port>
+
+1) Create empty NameService and GroupService directories
+
+ cd $TAO_ROOT/orbsvcs/tests/FT_Naming/FaultTolerant
+ mkdir NameService
+ mkdir GroupService
+
+2) Start primary tao_ft_naming process
+
+ $TAO_ROOT/orbsvcs/Naming_Service/tao_ft_naming \
+ --primary \
+ -ORBListenEndPoints iiop://<hostname>:<port1> \
+ -o /tmp/ns_primary.ior \
+ -h /tmp/nm_primary.ior \
+ -r NameService \
+ -v GroupService &
+
+3) Start backup tao_ft_naming process
+
+ $TAO_ROOT/orbsvcs/Naming_Service/tao_ft_naming \
+ --backup \
+ -ORBListenEndPoints iiop://<hostname>:<port2> \
+ -o /tmp/ns_backup.ior \
+ -h /tmp/nm_backup.ior \
+ -c /tmp/ns_multi_profile.ior \
+ -g /tmp/nm_multi_profile.ior \
+ -r NameService \
+ -v GroupService &
+
+4) Now run the test client with the equivalence argument
+
+ client --equivalence \
+ -p file:///tmp/ns_primary.ior \
+ -q file:///tmp/ns_backup.ior \
+ -r file:///tmp/nm_primary.ior \
+ -s file:///tmp/nm_backup.ior \
+ -b 4 -d 4
+
+ ==============================================================================
+ Example Output:
+ ==============================================================================
+ INFO: ns1ref is not equivalent to ns2ref
+ INFO: ns1ref profile count: 1
+ INFO: ns2ref profile count: 1
+ INFO: Equivalence Name Test OK
+ INFO: nm1ref: file:///tmp/nm_primary.ior
+ INFO: nm2ref: file:///tmp/nm_backup.ior
+ INFO: nm1ref is not equivalent to nm2ref
+ INFO: nm1ref profile count: 1
+ INFO: nm2ref profile count: 1
+ INFO: Primary Found Object Group test_group_1 Created By Primary In Repository
+ INFO: Backup Found Object Group test_group_2 Created By Backup In Repository
+ INFO: Primary Found Object Group test_group_2 Created By Backup In Repository
+ INFO: Backup Found Object Group test_group_1 Created By Primary In Repository
+ INFO: Equivalence ObjectGroup Test OK
+
+5) Cleanup
+
+ rm -rf NameService
+ rm -rf GroupService
+
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Test.idl b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Test.idl
new file mode 100644
index 00000000000..21d10f6644c
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/Test.idl
@@ -0,0 +1,27 @@
+//
+// $Id$
+
+#include "orbsvcs/FT_NamingManager.idl"
+
+/// Put the interfaces in a module, to avoid global namespace pollution
+module Test
+{
+ typedef FT_Naming::LoadBalancingStrategyValue LoadBalancingStrategyValue;
+
+ /// A very simple interface
+ interface Basic
+ {
+ /// Return a simple string
+ string get_string ();
+
+ /// A method to shutdown the ORB
+ /**
+ * This method is used to simplify the test shutdown process
+ */
+ oneway void shutdown ();
+
+ /// A method to remove the servant from the NamingManager Object Group.
+ oneway void remove_member ();
+ };
+};
+
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp
new file mode 100644
index 00000000000..1b4b8a6d975
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/client.cpp
@@ -0,0 +1,2324 @@
+//=============================================================================
+/**
+ * @file client.cpp
+ *
+ * $Id$
+ *
+ * This class implements a CORBA test client for the Fault Tolerant Naming Service.
+ *
+ * @author Rich Seibel <seibel_r@ociweb.com>
+ * @author Phillip LaBanca <labancap@ociweb.com>
+ */
+//=============================================================================
+
+#include "TestC.h"
+#include "test_objectS.h"
+#include "orbsvcs/CosNamingC.h"
+#include "orbsvcs/FT_NamingManagerC.h"
+#include "orbsvcs/Naming/Naming_Server.h"
+#include "tao/debug.h"
+#include "tao/Stub.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_unistd.h"
+#include "orbsvcs/Naming/FaultTolerant/nsgroup_svc.h"
+
+#if defined (_MSC_VER)
+# pragma warning (disable : 4250)
+#endif /* _MSC_VER */
+
+//==============================================================================
+//
+//==============================================================================
+class My_Test_Object :
+ public virtual POA_Test_Object
+{
+public:
+ // = Initialization and termination methods.
+ My_Test_Object (CORBA::Short id = 0);
+ // Constructor.
+
+ ~My_Test_Object (void);
+ // Destructor.
+
+ // = Interface implementation accessor methods.
+
+ void id (CORBA::Short id);
+ // Sets id.
+
+ CORBA::Short id (void);
+ // Gets id.
+
+private:
+ short id_;
+};
+
+My_Test_Object::My_Test_Object (CORBA::Short id)
+ : id_ (id)
+{
+}
+
+My_Test_Object::~My_Test_Object (void)
+{
+}
+
+CORBA::Short
+My_Test_Object::id (void)
+{
+ return id_;
+}
+
+void
+My_Test_Object::id (CORBA::Short id)
+{
+ id_ = id;
+}
+
+//==============================================================================
+//
+//==============================================================================
+/// Failover Name Test
+int
+do_failover_name_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *ns1ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth );
+
+/// Failover ObjectGroup Test
+int
+do_failover_objectgroup_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *nm1ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth );
+
+//==============================================================================
+//
+//==============================================================================
+/// Persistence Name Test
+int
+do_persistence_name_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *ns1ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth,
+ bool validate_only);
+
+/// Persistence ObjectGroup Test
+int
+do_persistence_objectgroup_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *nm1ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth,
+ bool validate_only);
+
+//==============================================================================
+//
+//==============================================================================
+/// Equivalence Name Test
+int
+do_equivalence_name_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *ns1ref,
+ ACE_TCHAR *ns2ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth);
+
+/// Equivalence ObjectGroup Test
+int
+do_equivalence_objectgroup_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *nm1ref,
+ ACE_TCHAR *nm2ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth);
+
+
+//==============================================================================
+//
+//==============================================================================
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ const int RC_SUCCESS = 0;
+ const int RC_ERROR = 1;
+
+ int rc = RC_SUCCESS;
+
+ int c_breadth = 4;
+ int c_depth = 4;
+ int o_breadth = 4;
+
+ ACE_TCHAR *ns1ref = 0;
+ ACE_TCHAR *ns2ref = 0;
+
+ ACE_TCHAR *nm1ref = 0;
+ ACE_TCHAR *nm2ref = 0;
+
+ typedef enum {
+ TT_FAILOVER,
+ TT_PERSISTENCE,
+ TT_EQUIVALENCE
+ } fault_tolerant_test;
+ fault_tolerant_test test_type = TT_FAILOVER;
+
+ typedef enum {
+ TT_INIT,
+ TT_CREATE,
+ TT_VALIDATE
+ } fault_tolerant_test_phase;
+ fault_tolerant_test_phase test_phase = TT_INIT;
+
+ //////////////////////////////////////////////////////////////////////////////
+ // optional
+ //////////////////////////////////////////////////////////////////////////////
+ // -b <breadth of context tree>
+ // -d <depth of context tree>
+ // -o <breadth of object tree>
+ //////////////////////////////////////////////////////////////////////////////
+ // required
+ //////////////////////////////////////////////////////////////////////////////
+ // -p <ior of first name server>
+ // -q <ior of second name server>
+ // -r <ior of first naming service>
+ // -s <ior of second naming service>
+ // --failover run fault tolerant failover test
+ // --persistence run fault tolerant persistence test
+ // --equivalence run fault tolerant equivalence test
+ //////////////////////////////////////////////////////////////////////////////
+ // required with persistance
+ //////////////////////////////////////////////////////////////////////////////
+ // --create run creation test phase
+ // --validate run validation test phase
+
+ try
+ {
+ // Initialize orb
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
+
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("b:d:o:p:q:r:s:"));
+ int c;
+ int i;
+ get_opts.long_option (ACE_TEXT ("failover"), ACE_Get_Opt::NO_ARG);
+ get_opts.long_option (ACE_TEXT ("persistence"), ACE_Get_Opt::NO_ARG);
+ get_opts.long_option (ACE_TEXT ("equivalence"), ACE_Get_Opt::NO_ARG);
+ get_opts.long_option (ACE_TEXT ("create"), ACE_Get_Opt::NO_ARG);
+ get_opts.long_option (ACE_TEXT ("validate"), ACE_Get_Opt::NO_ARG);
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'b':
+ i = ACE_OS::atoi(get_opts.opt_arg ());
+ if (i<2)
+ {
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT ("Invalid breadth, must be 2 or more\n")));
+ ACE_OS::exit(RC_ERROR);
+ }
+ c_breadth = i;
+ break;
+ case 'd':
+ i = ACE_OS::atoi(get_opts.opt_arg ());
+ if (i<2)
+ {
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT ("Invalid depth, must be 2 or more\n")));
+ ACE_OS::exit(RC_ERROR);
+ }
+ c_depth = i;
+ break;
+ case 'o':
+ i = ACE_OS::atoi(get_opts.opt_arg ());
+ if (i<2)
+ {
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT ("Invalid breadth, must be 2 or more\n")));
+ ACE_OS::exit(RC_ERROR);
+ }
+ o_breadth = i;
+ break;
+ case 'p':
+ ns1ref = get_opts.opt_arg ();
+ break;
+ case 'q':
+ ns2ref = get_opts.opt_arg ();
+ break;
+ case 'r':
+ nm1ref = get_opts.opt_arg ();
+ break;
+ case 's':
+ nm2ref = 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 ("failover")) == 0)
+ {
+ test_type = TT_FAILOVER;
+ }
+ else if (ACE_OS::strcmp (long_option,
+ ACE_TEXT ("persistence")) == 0)
+ {
+ test_type = TT_PERSISTENCE;
+ }
+ else if (ACE_OS::strcmp (long_option,
+ ACE_TEXT ("equivalence")) == 0)
+ {
+ test_type = TT_EQUIVALENCE;
+ }
+ else if (ACE_OS::strcmp (long_option,
+ ACE_TEXT ("create")) == 0)
+ {
+ test_phase = TT_CREATE;
+ }
+ else if (ACE_OS::strcmp (long_option,
+ ACE_TEXT ("validate")) == 0)
+ {
+ test_phase = TT_VALIDATE;
+ }
+ }
+ break;
+
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Argument %c \n usage: %s")
+ ACE_TEXT (" [-b <breadth of context tree>]")
+ ACE_TEXT (" [-d <depth of context tree>]")
+ ACE_TEXT (" [-o <breadth of object tree>]")
+ ACE_TEXT (" -p <ior of first name server>")
+ ACE_TEXT (" -q <ior of second name server>")
+ ACE_TEXT (" -r <ior of first naming server>")
+ ACE_TEXT (" -s <ior of second naming server>")
+ ACE_TEXT ("\n")),
+ RC_ERROR);
+ }
+
+ switch(test_type) {
+
+ case TT_FAILOVER:
+
+ if( RC_SUCCESS != do_failover_name_test (
+ orb.in (),
+ ns1ref,
+ c_breadth,
+ c_depth,
+ o_breadth ))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ERROR: Failover Name Test Failed\n")));
+ rc = RC_ERROR;
+ } else {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: Failover Name Test OK\n")));
+ }
+
+ if( RC_SUCCESS != do_failover_objectgroup_test (
+ orb.in (),
+ nm1ref,
+ c_breadth,
+ c_depth,
+ o_breadth ))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ERROR: Failover ObjectGroup ")
+ ACE_TEXT ("Test Failed\n")));
+ rc = RC_ERROR;
+ } else {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: Failover ObjectGroup Test OK\n")));
+ }
+
+ break;
+
+ case TT_PERSISTENCE:
+
+ switch(test_phase){
+
+ case TT_CREATE:
+ if (RC_SUCCESS != do_persistence_name_test (
+ orb.in (),
+ ns1ref,
+ c_breadth,
+ c_depth,
+ o_breadth,
+ false ))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ERROR: Persistence Creation Name ")
+ ACE_TEXT ("Test Failed\n")));
+ rc = RC_ERROR;
+ } else {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: Persistence Creation Name ")
+ ACE_TEXT ("Test OK\n")));
+ }
+ if (RC_SUCCESS != do_persistence_objectgroup_test(
+ orb.in (),
+ nm1ref,
+ c_breadth,
+ c_depth,
+ o_breadth,
+ false ))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ERROR: Persistence Creation ObjectGroup ")
+ ACE_TEXT ("Test Failed\n")));
+ rc = RC_ERROR;
+ } else {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: Persistence Creation ObjectGroup ")
+ ACE_TEXT ("Test OK\n")));
+ }
+ break;
+
+ case TT_VALIDATE:
+ if (RC_SUCCESS != do_persistence_name_test (
+ orb.in (),
+ ns1ref,
+ c_breadth,
+ c_depth,
+ o_breadth,
+ true ))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ERROR: Persistence Validation ")
+ ACE_TEXT ("Name Test Failed\n")));
+ rc = RC_ERROR;
+ } else {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: Persistence Validation ")
+ ACE_TEXT ("Name Test OK\n")));
+ }
+
+ if (RC_SUCCESS != do_persistence_objectgroup_test (
+ orb.in (),
+ nm1ref,
+ c_breadth,
+ c_depth,
+ o_breadth,
+ true ))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ERROR: Persistence Validation ")
+ ACE_TEXT ("ObjectGroup Test Failed\n")));
+ rc = RC_ERROR;
+ } else {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: Persistence Validation ")
+ ACE_TEXT ("ObjectGroup Test OK\n")));
+ }
+ break;
+
+ case TT_INIT:
+ default:
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ERROR: Missing Required Persistence ")
+ ACE_TEXT ("Argument [--create|--validate] \n")));
+ rc = RC_ERROR;
+ break;
+ }
+ break;
+
+ case TT_EQUIVALENCE:
+
+ if (RC_SUCCESS != do_equivalence_name_test (
+ orb.in (),
+ ns1ref,
+ ns2ref,
+ c_breadth,
+ c_depth,
+ o_breadth ))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ERROR: Equivalence Name Test\n")));
+ rc = RC_ERROR;
+ } else {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: Equivalence Name Test OK\n")));
+ }
+
+ if (RC_SUCCESS != do_equivalence_objectgroup_test(
+ orb.in (),
+ nm1ref,
+ nm2ref,
+ c_breadth,
+ c_depth,
+ o_breadth ))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ERROR: Equivalence ObjectGroup Test\n")));
+ rc = RC_ERROR;
+ } else {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: Equivalence ObjectGroup Test OK\n")));
+ }
+ break;
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to resolve name servers"));
+ return RC_ERROR;
+ }
+
+
+ return rc;
+
+}
+
+//==============================================================================
+//
+//==============================================================================
+/// Failover Name Test
+int
+do_failover_name_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *ns1ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth )
+{
+ const int RC_SUCCESS = 0;
+ const int RC_ERROR = -1;
+ CosNaming::NamingContext_var root_context_1;
+ int i;
+
+ try {
+
+ CORBA::ORB_var orb = CORBA::ORB::_duplicate(theOrb);
+
+ if (CORBA::is_nil (orb.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (ns1ref))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ns1\n")),
+ RC_ERROR);
+ }
+
+ CORBA::Object_var ns1obj =
+ orb->string_to_object (ACE_TEXT_ALWAYS_CHAR (ns1ref));
+
+ if (CORBA::is_nil (ns1obj.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),ns1ref),
+ RC_ERROR);
+ }
+
+ root_context_1 = CosNaming::NamingContext::_narrow (ns1obj.in ());
+
+ if (CORBA::is_nil (root_context_1.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),ns1ref),
+ RC_ERROR);
+ }
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to resolve name servers"));
+ return RC_ERROR;
+ }
+
+ // Create a bunch of objects in one context
+ // Note: strings to the naming service must be char, not wchar
+ try
+ {
+ // Bind one context level under root.
+ CosNaming::Name level1;
+ level1.length (1);
+ level1[0].id = CORBA::string_dup ("level1_context");
+ CosNaming::NamingContext_var level1_context;
+ level1_context = root_context_1->bind_new_context (level1);
+ ACE_OS::thr_yield ();
+
+ for (i=0; i<o_breadth; i++)
+ {
+ // Instantiate a dummy object and bind it under the new context.
+ My_Test_Object *impl1 = new My_Test_Object (i+1);
+ Test_Object_var obj1 = impl1->_this ();
+
+ impl1->_remove_ref ();
+
+ level1.length (2);
+
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("obj_%d"), i);
+ level1[1].id = CORBA::string_dup (wide_name);
+
+ root_context_1->bind (level1, obj1.in ());
+ ACE_OS::thr_yield ();
+
+ // See if the newly bound object is available in the
+ // replica
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_1->resolve (level1);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("INFO: Unable to resolve object from replica.\n"));
+
+ // Try again...
+ try {
+
+ CORBA::Object_var obj1_on_replica =
+ root_context_1->resolve (level1);
+
+ // We did find the object on the replica, but only after a wait.
+ // This would be caused by a race condition to access the variable.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("INFO: Object appeared after a short ")
+ ACE_TEXT ("wait.\n")));
+ }
+ catch (const CosNaming::NamingContext::NotFound& second_ex)
+ {
+ second_ex._tao_print_exception (
+ ACE_TEXT ("ERROR: It really is not there. Failing...\n"));
+ return RC_ERROR;
+ }
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to create a lot of objects"));
+ return RC_ERROR;
+ }
+
+ // Create a deep context tree
+ try
+ {
+ CosNaming::NamingContext_var next_context = root_context_1;
+ for (i=0; i<c_depth; i++)
+ {
+ // Bind level1 context under root.
+ CosNaming::Name deep;
+ deep.length (1);
+ char deep_name[16];
+ ACE_OS::sprintf(deep_name, ACE_TEXT_ALWAYS_CHAR ("deep_%d"), i);
+ deep[0].id = CORBA::string_dup (deep_name);
+ CosNaming::NamingContext_var deep_context;
+ deep_context = next_context->bind_new_context (deep);
+ ACE_OS::thr_yield ();
+ next_context = deep_context;
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to create deep context"));
+ return RC_ERROR;
+ }
+
+ // Create a wide context tree
+ try
+ {
+ for (i=0; i<c_breadth; i++)
+ {
+ // Bind all level of context under root.
+ CosNaming::Name wide;
+ wide.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("wide_%d"), i);
+ wide[0].id = CORBA::string_dup (wide_name);
+ CosNaming::NamingContext_var wide_context;
+ wide_context = root_context_1->bind_new_context (wide);
+ ACE_OS::thr_yield ();
+
+ try {
+ // Check if the new context is available in the replica
+ CORBA::Object_var obj1_on_replica = root_context_1->resolve (wide);
+ // Make sure it is a context
+ CosNaming::NamingContext_var nc =
+ CosNaming::NamingContext::_narrow (obj1_on_replica);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("INFO: Unable to resolve wide context object from ")
+ ACE_TEXT ("replica.\n"));
+
+ // Try again to see if it just was a race condition
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_1->resolve (wide);
+ // We did find the object on the replica, but only after a wait.
+ // This would be caused by a race condition to access the variable.
+ ACE_ERROR (( LM_ERROR,
+ ACE_TEXT ("INFO: Object appeared after a short ")
+ ACE_TEXT ("wait.\n")));
+ }
+ catch (const CosNaming::NamingContext::NotFound& second_ex)
+ {
+ second_ex._tao_print_exception (
+ ACE_TEXT ("ERROR: It really is not there. Failing...\n"));
+ return RC_ERROR;
+ }
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to create wide context"));
+ return RC_ERROR;
+ }
+
+ // Delete three selected things, one from each tree
+ try {
+ // Remove the second to last object from the Naming Context
+ CosNaming::Name wide1;
+ wide1.length (2);
+ wide1[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("level1_context"));
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("obj_%d"), o_breadth-2);
+ wide1[1].id = CORBA::string_dup (wide_name);
+ root_context_1->unbind (wide1);
+ ACE_OS::thr_yield ();
+
+ bool retried = false;
+ // Make sure it is gone from the replica
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_1->resolve (wide1);
+
+ // An exception should be thrown by the above or
+ // there is an error. This means the replica did
+ // not register the loss of the context.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("INFO: Unbound deep context not removed from ")
+ ACE_TEXT ("replica. Trying again...\n")));
+ retried = true; // Mark this so it can be reported in catch block.
+
+ obj1_on_replica = root_context_1->resolve (wide1);
+
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Unbound context not removed from ")
+ ACE_TEXT ("on retry\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Not on replica --- as it should be.
+ if (retried) // Was found on the retry
+ ACE_ERROR (( LM_ERROR,
+ ACE_TEXT ("INFO: Was removed after short wait.\n")));
+ }
+
+ // Remove the second to last context from the wide root Naming Context
+ CosNaming::Name wide2;
+ wide2.length (1);
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("wide_%d"), c_breadth-2);
+ wide2[0].id = CORBA::string_dup (wide_name);
+
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (wide2);
+
+ CosNaming::NamingContext_var result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving wide context ")
+ ACE_TEXT ("- nil object ref.\n")),
+ RC_ERROR);
+ }
+
+ result_object->destroy();
+ root_context_1->unbind (wide2);
+ ACE_OS::thr_yield ();
+
+ // Remove the last context from the deep Naming Context
+ CosNaming::Name deep;
+ deep.length (c_depth);
+
+ char deep_name[16];
+ for (i=0; i<c_depth; i++)
+ {
+ ACE_OS::sprintf(deep_name, ACE_TEXT_ALWAYS_CHAR ("deep_%d"), i);
+ deep[i].id = CORBA::string_dup (deep_name);
+ }
+
+ result_obj_ref = root_context_1->resolve (deep);
+
+ result_object = CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving deep context ")
+ ACE_TEXT ("- nil object ref.\n")),
+ RC_ERROR);
+ }
+
+ result_object->destroy();
+ root_context_1->unbind (deep);
+ ACE_OS::thr_yield ();
+
+ retried = false;
+ // Make sure it is gone from the replica
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_1->resolve (deep);
+
+ // An exception should be thrown by the above or
+ // there is an error. This means the replica did
+ // not register the loss of the context.
+ ACE_ERROR (( LM_ERROR,
+ ACE_TEXT ("INFO: Unbound deep context not removed from ")
+ ACE_TEXT ("replica. Trying again...\n")));
+
+ retried = true; // Mark this so it can be reported in catch block.
+ obj1_on_replica = root_context_1->resolve (deep);
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Unbound context not removed from ")
+ ACE_TEXT ("on retry\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Not on replica --- as it should be.
+ if (retried) // Was found on the retry
+ ACE_ERROR (( LM_ERROR,
+ ACE_TEXT ("INFO: Was removed after short wait.\n")));
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to delete objects"));
+ return RC_ERROR;
+ }
+
+ // Now use the other name server to access 3 objects next to the
+ // deleted objects and the 3 deleted objects
+ try
+ {
+ // Access the last object from the Naming Context
+ CosNaming::Name wide;
+ wide.length (2);
+ wide[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("level1_context"));
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("obj_%d"), o_breadth-1);
+ wide[1].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (wide);
+ Test_Object_var result_object = Test_Object::_narrow (result_obj_ref.in ());
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving object from ")
+ ACE_TEXT ("redundant server - nil object ref.\n")),
+ RC_ERROR);
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to resolve object from redundant server"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the deleted second to last object from the Naming Context
+ CosNaming::Name wide;
+ wide.length (2);
+ wide[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("level1_context"));
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("obj_%d"), o_breadth-2);
+ wide[1].id = CORBA::string_dup (wide_name);
+
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (wide);
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving object from ")
+ ACE_TEXT ("redundant server - deleted object found.\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ // expect exception since the context was deleted.
+ // Make sure the right exception reason is provided.
+ if (ex.why != CosNaming::NamingContext::missing_node)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Wrong exception returned during resolve.\n")),
+ RC_ERROR);
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Wrong exception type returned from resolve.\n"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the last context from the wide Naming Context
+ CosNaming::Name wide;
+ wide.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("wide_%d"), c_breadth-1);
+ wide[0].id = CORBA::string_dup (wide_name);
+
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (wide);
+
+ CosNaming::NamingContext_var result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving wide context from ")
+ ACE_TEXT ("redundant server - nil object ref.\n")),
+ RC_ERROR);
+ }
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Expected exception
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ( ACE_TEXT ("ERROR: Unexpected Exception received.\n"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the deleted second to last object from the Naming Context
+ CosNaming::Name wide;
+ wide.length (2);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("wide_%d"), c_breadth-2);
+ wide[0].id = CORBA::string_dup (wide_name);
+
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (wide);
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving wide context from ")
+ ACE_TEXT ("redundant server - deleted object found.\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Expected exception
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ( ACE_TEXT ("ERROR: Unexpected Exception received.\n"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the deleted last context from the deep Naming Context
+ CosNaming::Name deep;
+ deep.length (c_depth);
+ char deep_name[16];
+ for (i=0; i<c_depth; i++)
+ {
+ ACE_OS::sprintf(deep_name, ACE_TEXT_ALWAYS_CHAR ("deep_%d"), i);
+ deep[i].id = CORBA::string_dup (deep_name);
+ }
+
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (deep);
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving deep context from ")
+ ACE_TEXT ("redundant server - deleted object found.\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Expected exception
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unexpected Exception received resolving ")
+ ACE_TEXT ("deep cxt from redundant server.\n"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the second to last object from the Naming Context
+ CosNaming::Name deep;
+ deep.length (c_depth-1);
+ char deep_name[16];
+ for (i=0; i<c_depth-1; i++)
+ {
+ ACE_OS::sprintf(deep_name, ACE_TEXT_ALWAYS_CHAR ("deep_%d"), i);
+ deep[i].id = CORBA::string_dup (deep_name);
+ }
+
+ CORBA::Object_var result_obj_ref =
+ root_context_1->resolve (deep);
+
+ CosNaming::NamingContext_var result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving deep context from ")
+ ACE_TEXT ("redundant server - nil object ref.\n")),
+ RC_ERROR);
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to resolve deep context from redundant server"));
+ return RC_ERROR;
+ }
+
+ return RC_SUCCESS;
+}
+
+/// Failover ObjectGroup Test
+int
+do_failover_objectgroup_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *nm1ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth )
+{
+ ACE_UNUSED_ARG (c_breadth);
+ ACE_UNUSED_ARG (c_depth);
+ ACE_UNUSED_ARG (o_breadth);
+
+ const int RC_SUCCESS = 0;
+ const int RC_ERROR = -1;
+
+ FT_Naming::NamingManager_var naming_manager_1;
+
+ try {
+
+ CORBA::ORB_var orb = CORBA::ORB::_duplicate(theOrb);
+ if (CORBA::is_nil (orb.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (nm1ref))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid nm1\n")),
+ RC_ERROR);
+ }
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("INFO: nm1ref: %s\n"), nm1ref));
+
+ CORBA::Object_var nm1obj =
+ orb->string_to_object (ACE_TEXT_ALWAYS_CHAR (nm1ref));
+
+ if (CORBA::is_nil (nm1obj.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),nm1ref),
+ RC_ERROR);
+ }
+
+ naming_manager_1 = FT_Naming::NamingManager::_narrow (nm1obj.in ());
+ if (CORBA::is_nil (naming_manager_1.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),nm1ref),
+ RC_ERROR);
+ }
+
+ NS_group_svc svc;
+
+ if (RC_SUCCESS != svc.set_orb (theOrb))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if (RC_SUCCESS != svc.set_naming_manager (naming_manager_1))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),nm1ref),
+ RC_ERROR);
+ }
+
+
+ const char* test_group = "test_group";
+ const char* policy = "round";
+
+ if (RC_SUCCESS != svc.group_create (test_group, policy))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: unable to create %s\n"),test_group),
+ RC_ERROR);
+ }
+
+ if (false == svc.group_exist(test_group))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Object Group Not Found In Repository\n")),
+ RC_ERROR);
+ } else {
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: Object Group Found In Repository\n")));
+ }
+
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to resolve name manager servers"));
+ return RC_ERROR;
+ }
+
+ return RC_SUCCESS;
+}
+
+
+//==============================================================================
+//
+//==============================================================================
+/// Persistence Name Test
+int
+do_persistence_name_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *ns1ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth,
+ bool validate_only)
+{
+ const int RC_ERROR = -1;
+ const int RC_SUCCESS = 0;
+ CosNaming::NamingContext_var root_context_1;
+ int i;
+
+ try {
+
+ CORBA::ORB_var orb = CORBA::ORB::_duplicate(theOrb);
+
+ if (CORBA::is_nil (orb.in () ))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (ns1ref))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ns1\n")),
+ RC_ERROR);
+ }
+
+ CORBA::Object_var ns1obj =
+ orb->string_to_object (ACE_TEXT_ALWAYS_CHAR (ns1ref));
+
+ if (CORBA::is_nil (ns1obj.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),ns1ref),
+ RC_ERROR);
+ }
+
+ root_context_1 = CosNaming::NamingContext::_narrow (ns1obj.in ());
+
+ if (CORBA::is_nil (root_context_1.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),ns1ref),
+ RC_ERROR);
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("ERROR: Unable to resolve name servers"));
+ return RC_ERROR;
+ }
+
+ // Create a bunch of objects in one context
+ // Note: strings to the naming service must be char, not wchar
+ try
+ {
+ // Bind one context level under root.
+ CosNaming::Name level1;
+ level1.length (1);
+ level1[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("level1_context"));
+
+ if( false == validate_only ) {
+ CosNaming::NamingContext_var level1_context;
+ level1_context = root_context_1->bind_new_context (level1);
+ ACE_OS::thr_yield ();
+ }
+
+ for (i=0; i<o_breadth; i++)
+ {
+ // Instantiate a dummy object and bind it under the new context.
+ My_Test_Object *impl1 = new My_Test_Object (i+1);
+ Test_Object_var obj1 = impl1->_this ();
+ impl1->_remove_ref ();
+
+ level1.length (2);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("obj_%d"), i);
+ level1[1].id = CORBA::string_dup (wide_name);
+
+ if( false == validate_only ) {
+ root_context_1->bind (level1, obj1.in ());
+ ACE_OS::thr_yield ();
+ }
+
+
+ // See if the newly bound object is available in the repository
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_1->resolve (level1);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to resolve object from repository.\n"));
+
+ // Try again...
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_1->resolve (level1);
+ // We did find the object on the repository, but only after a wait.
+ // This would be caused by a race condition to access the variable.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("INFO: Object appeared after a short wait.\n")));
+ }
+ catch (const CosNaming::NamingContext::NotFound& second_ex)
+ {
+ second_ex._tao_print_exception (
+ ACE_TEXT ("ERROR: It really is not there. Failing...\n"));
+ return RC_ERROR;
+ }
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to create or validate a lot of objects"));
+
+ return RC_ERROR;
+ }
+
+ if( false == validate_only ) {
+ // Create a deep context tree
+ try
+ {
+ CosNaming::NamingContext_var next_context = root_context_1;
+ for (i=0; i<c_depth; i++)
+ {
+ // Bind level1 context under root.
+ CosNaming::Name deep;
+ deep.length (1);
+ char deep_name[16];
+ ACE_OS::sprintf(deep_name, ACE_TEXT_ALWAYS_CHAR ("deep_%d"), i);
+ deep[0].id = CORBA::string_dup (deep_name);
+
+ CosNaming::NamingContext_var deep_context;
+ deep_context = next_context->bind_new_context (deep);
+ ACE_OS::thr_yield ();
+ next_context = deep_context;
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("ERROR: Unable to create deep context"));
+ return RC_ERROR;
+ }
+ }
+
+ // Create a wide context tree
+ try
+ {
+ for (i=0; i<c_breadth; i++)
+ {
+ // Bind all level of context under root.
+ CosNaming::Name wide;
+ wide.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("wide_%d"), i);
+ wide[0].id = CORBA::string_dup (wide_name);
+
+ if( false == validate_only ) {
+ CosNaming::NamingContext_var wide_context;
+ wide_context = root_context_1->bind_new_context (wide);
+ ACE_OS::thr_yield ();
+ }
+
+ try {
+
+ // Check if the new context is available in the repository
+ CORBA::Object_var obj1_on_replica =
+ root_context_1->resolve (wide);
+
+ // Make sure it is a context
+ CosNaming::NamingContext_var nc =
+ CosNaming::NamingContext::_narrow (obj1_on_replica);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("INFO: Unable to resolve wide context object from ")
+ ACE_TEXT ("repository.\n"));
+
+ // Try again to see if it just was a race condition
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_1->resolve (wide);
+ // We did find the object on the replica, but only after a wait.
+ // This would be caused by a race condition to access the variable.
+ ACE_ERROR (( LM_ERROR,
+ ACE_TEXT ("INFO: Object appeared after a short ")
+ ACE_TEXT ("wait.\n")));
+ }
+ catch (const CosNaming::NamingContext::NotFound& second_ex)
+ {
+ second_ex._tao_print_exception (
+ ACE_TEXT ("ERROR: It really is not there. Failing...\n"));
+ return RC_ERROR;
+ }
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to create or validate wide context"));
+ return RC_ERROR;
+ }
+
+ return RC_SUCCESS;
+
+}
+
+
+/// Persistence ObjectGroup Test
+int
+do_persistence_objectgroup_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *nm1ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth,
+ bool validate_only)
+{
+ ACE_UNUSED_ARG (c_breadth);
+ ACE_UNUSED_ARG (c_depth);
+ ACE_UNUSED_ARG (o_breadth);
+ ACE_UNUSED_ARG (validate_only);
+
+ const int RC_ERROR = -1;
+ const int RC_SUCCESS = 0;
+
+ FT_Naming::NamingManager_var naming_manager_1;
+
+ try {
+
+ CORBA::ORB_var orb = CORBA::ORB::_duplicate(theOrb);
+
+ if (CORBA::is_nil (orb.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (nm1ref))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid nm1\n")),
+ RC_ERROR);
+ }
+
+ //ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("nm1ref: %s\n"), nm1ref));
+
+ CORBA::Object_var nm1obj =
+ orb->string_to_object (ACE_TEXT_ALWAYS_CHAR (nm1ref));
+
+ if (CORBA::is_nil (nm1obj.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),nm1ref),
+ RC_ERROR);
+ }
+
+ naming_manager_1 = FT_Naming::NamingManager::_narrow (nm1obj.in ());
+ if (CORBA::is_nil (naming_manager_1.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),nm1ref),
+ RC_ERROR);
+ }
+
+ NS_group_svc group_svc;
+
+ if( RC_SUCCESS != group_svc.set_orb (theOrb) )
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if( RC_SUCCESS != group_svc.set_naming_manager (naming_manager_1) )
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),nm1ref),
+ RC_ERROR);
+ }
+
+ /// get BasicGroup member object and verify that it reports the same location
+ const char* basic_group_name = "BasicGroup";
+
+ if (false == group_svc.group_exist(basic_group_name))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Object Group %s Not Found In Repository\n"),
+ basic_group_name),
+ RC_ERROR);
+ } else {
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: Object Group %s Found In Repository\n"),
+ basic_group_name));
+ }
+
+ try
+ {
+ PortableGroup::ObjectGroup_var group_var =
+ naming_manager_1->get_object_group_ref_from_name (basic_group_name);
+
+ PortableGroup::Locations_var locations =
+ naming_manager_1->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) {
+
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: validating group member %C\n"),
+ loc[0].id.in()));
+
+ try
+ {
+
+ PortableGroup::Location location_name (1);
+ location_name.length (1);
+ location_name[0].id = CORBA::string_dup(loc[0].id.in());
+
+ CORBA::Object_var ior_var =
+ naming_manager_1->get_member_ref (group_var.in(), location_name);
+
+ // Narrow it to a Basic object
+ Test::Basic_var basic = Test::Basic::_narrow (ior_var.in ());
+ if (CORBA::is_nil (basic.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Unable to narrow from member ior from %C\n"),
+ loc[0].id.in()),
+ RC_ERROR);
+ }
+
+ try
+ {
+ CORBA::String_var the_string = basic->get_string ();
+
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: object group member at %C reports ")
+ ACE_TEXT ("%C\n"),
+ loc[0].id.in(),
+ the_string.in ()));
+
+ if ( ACE_OS::strcmp (the_string.in (), loc[0].id.in()) != 0 ) {
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: object group member at %C reports %C\n\n"),
+ loc[0].id.in(),
+ the_string.in ()),
+ RC_ERROR);
+ }
+ }
+ catch (CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("ERROR: invoking get_string on Basic object.\n");
+ return RC_ERROR;
+ }
+ }
+ catch (const PortableGroup::MemberNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Unable to find member location %C\n"),
+ loc[0].id.in()),
+ RC_ERROR);
+ }
+ }
+ }
+
+ }
+ catch (const PortableGroup::ObjectGroupNotFound&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Unable to find group %C\n"),
+ basic_group_name),
+ RC_ERROR);
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Unable to list members for group %C\n"),
+ basic_group_name),
+ RC_ERROR);
+ }
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable To Resolve Name Manager Servers"));
+ return RC_ERROR;
+ }
+
+ return RC_SUCCESS;
+}
+
+//==============================================================================
+//
+//==============================================================================
+/// Equivalence Name Test
+int
+do_equivalence_name_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *ns1ref,
+ ACE_TCHAR *ns2ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth)
+{
+ const int RC_SUCCESS = 0;
+ const int RC_ERROR = -1;
+
+ CosNaming::NamingContext_var root_context_1;
+ CosNaming::NamingContext_var root_context_2;
+ int i;
+
+ try {
+
+ CORBA::ORB_var orb = CORBA::ORB::_duplicate(theOrb);
+
+ if (CORBA::is_nil (orb.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (ns1ref))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ns1\n")),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (ns2ref))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ns2\n")),
+ RC_ERROR);
+ }
+
+ CORBA::Object_var ns1obj =
+ orb->string_to_object (ACE_TEXT_ALWAYS_CHAR (ns1ref));
+
+ CORBA::Object_var ns2obj =
+ orb->string_to_object (ACE_TEXT_ALWAYS_CHAR (ns2ref));
+
+ if (CORBA::is_nil (ns1obj.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),ns1ref),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (ns2obj.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),ns2ref),
+ RC_ERROR);
+ }
+
+ root_context_1 = CosNaming::NamingContext::_narrow (ns1obj.in ());
+ root_context_2 = CosNaming::NamingContext::_narrow (ns2obj.in ());
+
+ if (CORBA::is_nil (root_context_1.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),ns1ref),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (root_context_2.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),ns2ref),
+ RC_ERROR);
+ }
+
+ /// Make sure the two naming manager references point to different objects
+ if ( true == root_context_1->_stubobj ()->is_equivalent (
+ root_context_2.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: ns1ref is equivalent to ns2ref\n")),
+ RC_ERROR);
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: ns1ref is not equivalent to ns2ref\n")));
+
+ int ns1_count =
+ root_context_1->_stubobj ()->base_profiles ().profile_count ();
+
+ int ns2_count =
+ root_context_2->_stubobj ()->base_profiles ().profile_count ();
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: ns1ref profile count: %d\n"),
+ ns1_count));
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: ns2ref profile count: %d\n"),
+ ns2_count));
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("ERROR: Unable to resolve name servers"));
+ return RC_ERROR;
+ }
+
+ // Create a bunch of objects in one context
+ // Note: strings to the naming service must be char, not wchar
+ try
+ {
+ // Bind one context level under root.
+ CosNaming::Name level1;
+ level1.length (1);
+ level1[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR("level1_context"));
+ CosNaming::NamingContext_var level1_context;
+ level1_context = root_context_1->bind_new_context (level1);
+ ACE_OS::thr_yield ();
+
+ for (i=0; i<o_breadth; i++)
+ {
+ // Instantiate a dummy object and bind it under the new context.
+ My_Test_Object *impl1 = new My_Test_Object (i+1);
+ Test_Object_var obj1 = impl1->_this ();
+ impl1->_remove_ref ();
+
+ level1.length (2);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("obj_%d"), i);
+ level1[1].id = CORBA::string_dup (wide_name);
+ root_context_1->bind (level1, obj1.in ());
+ ACE_OS::thr_yield ();
+
+ // See if the newly bound object is available in the
+ // replica
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_2->resolve (level1);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ ex._tao_print_exception ("INFO: Unable to resolve object from replica.\n");
+
+ // Try again...
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_2->resolve (level1);
+ // We did find the object on the replica, but only after a wait.
+ // This would be caused by a race condition to access the variable.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("INFO: Object appeared after a short ")
+ ACE_TEXT ("wait.\n")));
+ }
+ catch (const CosNaming::NamingContext::NotFound& second_ex)
+ {
+ second_ex._tao_print_exception (
+ ACE_TEXT ("ERROR: It really is not there. Failing...\n"));
+ return RC_ERROR;
+ }
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to create a lot of objects"));
+ return RC_ERROR;
+ }
+
+ // Create a deep context tree
+ try
+ {
+ CosNaming::NamingContext_var next_context = root_context_1;
+ for (i=0; i<c_depth; i++)
+ {
+ // Bind level1 context under root.
+ CosNaming::Name deep;
+ deep.length (1);
+ char deep_name[16];
+ ACE_OS::sprintf(deep_name, ACE_TEXT_ALWAYS_CHAR ("deep_%d"), i);
+ deep[0].id = CORBA::string_dup (deep_name);
+ CosNaming::NamingContext_var deep_context;
+ deep_context = next_context->bind_new_context (deep);
+ ACE_OS::thr_yield ();
+ next_context = deep_context;
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to create deep context"));
+ return RC_ERROR;
+ }
+
+ // Create a wide context tree
+ try
+ {
+ for (i=0; i<c_breadth; i++)
+ {
+ // Bind all level of context under root.
+ CosNaming::Name wide;
+ wide.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("wide_%d"), i);
+ wide[0].id = CORBA::string_dup (wide_name);
+ CosNaming::NamingContext_var wide_context;
+ wide_context = root_context_1->bind_new_context (wide);
+ ACE_OS::thr_yield ();
+
+ try {
+ // Check if the new context is available in the replica
+ CORBA::Object_var obj1_on_replica =
+ root_context_2->resolve (wide);
+
+ // Make sure it is a context
+ CosNaming::NamingContext_var nc =
+ CosNaming::NamingContext::_narrow (obj1_on_replica);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("INFO: Unable to resolve wide context object from ")
+ ACE_TEXT ("replica.\n"));
+
+ // Try again to see if it just was a race condition
+ try {
+
+ CORBA::Object_var obj1_on_replica =
+ root_context_2->resolve (wide);
+
+ // We did find the object on the replica, but only after a wait.
+ // This would be caused by a race condition to access the variable.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("INFO: Object appeared after a ")
+ ACE_TEXT ("short wait.\n")));
+ }
+ catch (const CosNaming::NamingContext::NotFound& second_ex)
+ {
+ second_ex._tao_print_exception (
+ ACE_TEXT ("ERROR: It really is not there. Failing...\n"));
+ return RC_ERROR;
+ }
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to create wide context"));
+ return RC_ERROR;
+ }
+
+ // Delete three selected things, one from each tree
+ try {
+ // Remove the second to last object from the Naming Context
+ CosNaming::Name wide1;
+ wide1.length (2);
+
+ wide1[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("level1_context"));
+
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("obj_%d"), o_breadth-2);
+ wide1[1].id = CORBA::string_dup (wide_name);
+ root_context_1->unbind (wide1);
+ ACE_OS::thr_yield ();
+
+ bool retried = false;
+ // Make sure it is gone from the replica
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_2->resolve (wide1);
+
+ // An exception should be thrown by the above or
+ // there is an error. This means the replica did
+ // not register the loss of the context.
+ ACE_ERROR (( LM_ERROR,
+ ACE_TEXT ("INFO: Unbound deep context not removed from ")
+ ACE_TEXT ("replica. Trying again...\n")));
+
+ retried = true; // Mark this so it can be reported in catch block.
+ obj1_on_replica = root_context_2->resolve (wide1);
+
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Unbound context not removed from ")
+ ACE_TEXT ("on retry\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Not on replica --- as it should be.
+ if (retried) // Was found on the retry
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("INFO: Was removed after short wait.\n")));
+ }
+
+ // Remove the second to last context from the wide root Naming Context
+ CosNaming::Name wide2;
+ wide2.length (1);
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("wide_%d"), c_breadth-2);
+ wide2[0].id = CORBA::string_dup (wide_name);
+
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (wide2);
+
+ CosNaming::NamingContext_var result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving wide")
+ ACE_TEXT (" context - nil object ref.\n")),
+ RC_ERROR);
+ }
+
+ result_object->destroy();
+ root_context_1->unbind (wide2);
+ ACE_OS::thr_yield ();
+
+ // Remove the last context from the deep Naming Context
+ CosNaming::Name deep;
+ deep.length (c_depth);
+ char deep_name[16];
+ for (i=0; i<c_depth; i++)
+ {
+ ACE_OS::sprintf(deep_name, ACE_TEXT_ALWAYS_CHAR ("deep_%d"), i);
+ deep[i].id = CORBA::string_dup (deep_name);
+ }
+ result_obj_ref = root_context_1->resolve (deep);
+ result_object = CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving deep")
+ ACE_TEXT (" context - nil object ref.\n")),
+ RC_ERROR);
+ }
+ result_object->destroy();
+ root_context_1->unbind (deep);
+ ACE_OS::thr_yield ();
+
+ retried = false;
+ // Make sure it is gone from the replica
+ try {
+ CORBA::Object_var obj1_on_replica = root_context_2->resolve (deep);
+
+ // An exception should be thrown by the above or
+ // there is an error. This means the replica did
+ // not register the loss of the context.
+ ACE_ERROR (( LM_ERROR,
+ ACE_TEXT ("INFO: Unbound deep context not removed from")
+ ACE_TEXT ("replica. Trying again...\n")));
+
+ retried = true; // Mark this so it can be reported in catch block.
+ obj1_on_replica = root_context_2->resolve (deep);
+
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Unbound context not removed from")
+ ACE_TEXT (" on retry\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Not on replica --- as it should be.
+ if (retried) // Was found on the retry
+ ACE_ERROR (( LM_ERROR,
+ ACE_TEXT ("INFO: Was removed after short wait.\n")));
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to delete objects"));
+ return RC_ERROR;
+ }
+
+ // Now use the other name server to access 3 objects next to the
+ // deleted objects and the 3 deleted objects
+ try
+ {
+ // Access the last object from the Naming Context
+ CosNaming::Name wide;
+ wide.length (2);
+ wide[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("level1_context"));
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("obj_%d"), o_breadth-1);
+ wide[1].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
+ Test_Object_var result_object = Test_Object::_narrow (result_obj_ref.in ());
+
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving object ")
+ ACE_TEXT ("from redundant server ")
+ ACE_TEXT ("- nil object ref.\n")),
+ RC_ERROR);
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to resolve object from redundant server"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the deleted second to last object from the Naming Context
+ CosNaming::Name wide;
+ wide.length (2);
+ wide[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("level1_context"));
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("obj_%d"), o_breadth-2);
+ wide[1].id = CORBA::string_dup (wide_name);
+
+ CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving object from ")
+ ACE_TEXT ("redundant server - deleted object found.\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ // expect exception since the context was deleted.
+ // Make sure the right exception reason is provided.
+ if (ex.why != CosNaming::NamingContext::missing_node)
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Wrong exception returned during ")
+ ACE_TEXT ("resolve.\n")),
+ RC_ERROR);
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Wrong exception type returned from resolve.\n"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the last context from the wide Naming Context
+ CosNaming::Name wide;
+ wide.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("wide_%d"), c_breadth-1);
+ wide[0].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
+
+ CosNaming::NamingContext_var result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving wide ")
+ ACE_TEXT ("context from redundant server ")
+ ACE_TEXT ("- nil object ref.\n")),
+ RC_ERROR);
+ }
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Expected exception
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ( ACE_TEXT ("ERROR: Unexpected Exception ")
+ ACE_TEXT ("received.\n"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the deleted second to last object from the Naming Context
+ CosNaming::Name wide;
+ wide.length (2);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, ACE_TEXT_ALWAYS_CHAR ("wide_%d"), c_breadth-2);
+ wide[0].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving wide context ")
+ ACE_TEXT ("from redundant server ")
+ ACE_TEXT ("- deleted object found.\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Expected exception
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ( ACE_TEXT ("ERROR: Unexpected Exception ")
+ ACE_TEXT ("received.\n"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the deleted last context from the deep Naming Context
+ CosNaming::Name deep;
+ deep.length (c_depth);
+ char deep_name[16];
+ for (i=0; i<c_depth; i++)
+ {
+ ACE_OS::sprintf(deep_name, ACE_TEXT_ALWAYS_CHAR ("deep_%d"), i);
+ deep[i].id = CORBA::string_dup (deep_name);
+ }
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (deep);
+
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving deep context ")
+ ACE_TEXT ("from redundant server ")
+ ACE_TEXT ("- deleted object found.\n")),
+ RC_ERROR);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Expected exception
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unexpected Exception received resolving ")
+ ACE_TEXT ("deep cxt from redundant server.\n"));
+ return RC_ERROR;
+ }
+
+ try
+ {
+ // Access the second to last object from the Naming Context
+ CosNaming::Name deep;
+ deep.length (c_depth-1);
+ char deep_name[16];
+ for (i=0; i<c_depth-1; i++)
+ {
+ ACE_OS::sprintf(deep_name, ACE_TEXT_ALWAYS_CHAR ("deep_%d"), i);
+ deep[i].id = CORBA::string_dup (deep_name);
+ }
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (deep);
+
+ CosNaming::NamingContext_var result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+
+ if (CORBA::is_nil (result_object.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("ERROR: Problems with resolving deep ")
+ ACE_TEXT ("context from redundant server ")
+ ACE_TEXT ("- nil object ref.\n")),
+ RC_ERROR);
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to resolve deep context from redundant server."));
+ return RC_ERROR;
+ }
+
+ return RC_SUCCESS;
+}
+
+
+/// Equivalence ObjectGroup Test
+int
+do_equivalence_objectgroup_test (
+ CORBA::ORB_ptr theOrb,
+ ACE_TCHAR *nm1ref,
+ ACE_TCHAR *nm2ref,
+ int c_breadth,
+ int c_depth,
+ int o_breadth )
+{
+ ACE_UNUSED_ARG (c_breadth);
+ ACE_UNUSED_ARG (c_depth);
+ ACE_UNUSED_ARG (o_breadth);
+
+ const int RC_SUCCESS = 0;
+ const int RC_ERROR = -1;
+ int error_count = 0;
+
+
+ FT_Naming::NamingManager_var naming_manager_1;
+ FT_Naming::NamingManager_var naming_manager_2;
+
+ try {
+
+ CORBA::ORB_var orb = CORBA::ORB::_duplicate(theOrb);
+ if (CORBA::is_nil (orb.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (nm1ref))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid nm1\n")),
+ RC_ERROR);
+ }
+
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: nm1ref: %s\n"),
+ nm1ref));
+
+ CORBA::Object_var nm1obj =
+ orb->string_to_object (ACE_TEXT_ALWAYS_CHAR (nm1ref));
+
+ if (CORBA::is_nil (nm1obj.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),
+ nm1ref),
+ RC_ERROR);
+ }
+
+ naming_manager_1 = FT_Naming::NamingManager::_narrow (nm1obj.in ());
+ if (CORBA::is_nil (naming_manager_1.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),
+ nm1ref),
+ RC_ERROR);
+ }
+
+ if (CORBA::is_nil (nm2ref))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid nm2\n")),
+ RC_ERROR);
+ }
+
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: nm2ref: %s\n"),
+ nm2ref));
+
+ CORBA::Object_var nm2obj =
+ orb->string_to_object (ACE_TEXT_ALWAYS_CHAR (nm2ref));
+
+ if (CORBA::is_nil (nm2obj.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),
+ nm2ref),
+ RC_ERROR);
+ }
+
+ naming_manager_2 = FT_Naming::NamingManager::_narrow (nm2obj.in ());
+
+ if (CORBA::is_nil (naming_manager_2.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),
+ nm2ref),
+ RC_ERROR);
+ }
+
+ /// Make sure the two naming manager references point to different objects
+ if ( true == naming_manager_1->_stubobj ()->is_equivalent (
+ naming_manager_2.in ()))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: nm1ref is equivalent to nm2ref\n")),
+ RC_ERROR);
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: nm1ref is not equivalent to nm2ref\n")));
+ int nm1_count =
+ naming_manager_1->_stubobj ()->base_profiles ().profile_count ();
+
+ int nm2_count =
+ naming_manager_2->_stubobj ()->base_profiles ().profile_count ();
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: nm1ref profile count: %d\n"),
+ nm1_count));
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("INFO: nm2ref profile count: %d\n"),
+ nm2_count));
+
+
+ /// Setup 1st NS_group_svc with 1st Naming Manager
+ NS_group_svc svc1;
+ if (RC_SUCCESS != svc1.set_orb (theOrb))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if (RC_SUCCESS != svc1.set_naming_manager (naming_manager_1))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),
+ nm1ref),
+ RC_ERROR);
+ }
+
+ /// Setup 2nd NS_group_svc with 2nd Naming Manager
+ NS_group_svc svc2;
+ if (RC_SUCCESS != svc2.set_orb (theOrb))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid orb\n")),
+ RC_ERROR);
+ }
+
+ if (RC_SUCCESS != svc2.set_naming_manager (naming_manager_2))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: invalid ior <%s>\n"),nm2ref),
+ RC_ERROR);
+ }
+
+ /// Now validate seamless operations between the two instances of NS_group
+ const char* policy = ACE_TEXT_ALWAYS_CHAR ("round");
+ const char* test_group_1 = ACE_TEXT_ALWAYS_CHAR ("test_group_1");
+ const char* test_group_2 = ACE_TEXT_ALWAYS_CHAR ("test_group_2");
+
+ if (RC_SUCCESS != svc1.group_create (test_group_1, policy))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Unable to create %s\n"),
+ test_group_1),
+ RC_ERROR);
+ }
+
+ if (RC_SUCCESS != svc2.group_create (test_group_2, policy))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT ("ERROR: Unable to create %s\n"),
+ test_group_2),
+ RC_ERROR);
+ }
+
+ if (false == svc1.group_exist(test_group_1))
+ {
+ ++error_count;
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("ERROR: Primary Not Able To Find Object Group ")
+ ACE_TEXT ("%s Created By Primary In Repository\n"),
+ test_group_1));
+ } else {
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: Primary Found Object Group %s Created By ")
+ ACE_TEXT ("Primary In Repository\n"),
+ test_group_1));
+ }
+
+ if (false == svc2.group_exist(test_group_2))
+ {
+ ++error_count;
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("ERROR: Backup Not Able To Find Object Group %s ")
+ ACE_TEXT ("Created By Backup In Repository\n"),
+ test_group_2));
+ } else {
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: Backup Found Object Group %s Created By ")
+ ACE_TEXT ("Backup In Repository\n"),
+ test_group_2));
+ }
+
+ if (false == svc1.group_exist(test_group_2))
+ {
+ ++error_count;
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("ERROR: Primary Not Able To Find Object Group %s ")
+ ACE_TEXT ("Created By Backup In Repository\n"),
+ test_group_2));
+ } else {
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: Primary Found Object Group %s Created By ")
+ ACE_TEXT ("Backup In Repository\n"),
+ test_group_2));
+ }
+
+ if (false == svc2.group_exist(test_group_1))
+ {
+ ++error_count;
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("ERROR: Backup Not Able To Find Object Group %s ")
+ ACE_TEXT ("Created By Primary In Repository\n"),
+ test_group_1));
+ } else {
+ ACE_DEBUG (( LM_DEBUG,
+ ACE_TEXT ("INFO: Backup Found Object Group %s Created By ")
+ ACE_TEXT ("Primary In Repository\n"),
+ test_group_1));
+ }
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ++error_count;
+ ex._tao_print_exception (
+ ACE_TEXT ("ERROR: Unable to resolve name manager servers"));
+ }
+
+ return (error_count > 0) ? RC_ERROR : RC_SUCCESS;
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_0 b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_0
new file mode 100644
index 00000000000..0558ced7ed9
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_0
Binary files differ
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_global b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_global
new file mode 100644
index 00000000000..2f1465d1598
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/GroupService/ObjectGroup_global
@@ -0,0 +1,3 @@
+1
+1
+0
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService
new file mode 100644
index 00000000000..6b02ae41b97
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService
@@ -0,0 +1,5 @@
+7
+0
+0
+6
+wi \ No newline at end of file
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_0 b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_0
new file mode 100644
index 00000000000..d09c35a22ba
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_0
@@ -0,0 +1,5 @@
+4
+0
+1
+5
+ob \ No newline at end of file
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_1 b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_1
new file mode 100644
index 00000000000..5c1dc2a9185
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_1
@@ -0,0 +1,8 @@
+1
+0
+0
+6
+deep_1
+0
+
+1 \ No newline at end of file
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_2 b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_2
new file mode 100644
index 00000000000..11367bed4cf
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/corrupt_data/NameService/NameService_2
@@ -0,0 +1,5 @@
+1
+0
+0
+6
+de \ No newline at end of file
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_equivalence_test.pl b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_equivalence_test.pl
new file mode 100755
index 00000000000..9fa2e86f51e
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_equivalence_test.pl
@@ -0,0 +1,423 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+use Cwd;
+
+#$ENV{ACE_TEST_VERBOSE} = "1";
+
+my $startdir = getcwd();
+my $debug_level = '0';
+my $redirection_enabled = 0;
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $debug_level = '10';
+ $redirection_enabled = 0;
+ }
+}
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+
+
+# Variables for command-line arguments to client and server
+# executables.
+my $hostname = $server->HostName ();
+
+my $ns_orb_port1 = 10001 + $server->RandomPort ();
+my $ns_orb_port2 = 10002 + $server->RandomPort ();
+
+my $ns_endpoint1 = "iiop://$hostname:$ns_orb_port1";
+my $ns_endpoint2 = "iiop://$hostname:$ns_orb_port2";
+
+# References to primary naming service only
+my $primary_default_init_ref = "-ORBDefaultInitRef corbaloc:iiop:$hostname:$ns_orb_port1";
+
+# References to backup naming service only
+my $backup_default_init_ref = "-ORBDefaultInitRef corbaloc:iiop:$hostname:$ns_orb_port2";
+
+## Allow the user to determine where the persistence file will be located
+## just in case the current directory is not suitable for locking.
+## We can't change the name of the persistence file because that is not
+## sufficient to work around locking problems for Tru64 when the current
+## directory is NFS mounted from a system that does not properly support
+## locking.
+foreach my $possible ($ENV{TMPDIR}, $ENV{TEMP}, $ENV{TMP}) {
+ if (defined $possible && -d $possible) {
+ if (chdir($possible)) {
+ last;
+ }
+ }
+}
+
+my $status = 0;
+my $POSITIVE_TEST_RESULT = 0;
+my $NEGATIVE_TEST_RESULT = 1;
+
+my $NSGROUP = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsgroup");
+my $NSLIST = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nslist");
+my $NSADD = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsadd");
+my $NSDEL = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsdel");
+
+sub cat_file($)
+{
+ my $file_name = shift;
+ if (-s $file_name ) # size of file is greater than zero
+ {
+ open TESTFILE, $file_name or die "Couldn't open file: $!";
+ my @teststring = <TESTFILE>; # read in all of the file
+ print STDERR "\n@teststring\n";
+ close TESTFILE;
+ }
+}
+
+sub redirect_output()
+{
+ open (OLDOUT, ">&", \*STDOUT) or die "Can't dup STDOUT: $!";
+ open (OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!";
+ open STDERR, '>', $client_stderr_file;
+ open STDOUT, '>', $client_stdout_file;
+}
+
+sub restore_output()
+{
+ open (STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!";
+ open (STDOUT, ">&OLDOUT") or die "Can't dup OLDOUT: $!";
+}
+
+sub run_nsgroup ($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ my $arglist = "$args";
+
+ $NSGROUP->Arguments ($arglist);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ my $nsgroup_status = $NSGROUP->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nsgroup_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nsgroup returned $nsgroup_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nslist($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ $NSLIST->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nslist --ns file://ns.ior
+ my $nslist_status = $NSLIST->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nslist_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nslist returned $nslist_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nsadd($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ $NSADD->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nsadd --ns file://ns.ior --name iso --ctx
+ my $nsadd_status = $NSADD->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nsadd_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nsadd returned $nsadd_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nsdel($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ $NSDEL->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nsdel --ns file://ns.ior --name iso --destroy
+ my $nsdel_status = $NSDEL->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nsdel_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nsdel returned $nsdel_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub clean_persistence_dir($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ chdir $directory_name;
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $target->DeleteFile ($tmp);
+ }
+ chdir "..";
+}
+
+# Make sure that the directory to use to hold the naming contexts exists
+# and is cleaned out
+sub init_naming_context_directory($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ if ( ! -d $directory_name ) {
+ mkdir ($directory_name, 0777);
+ } else {
+ clean_persistence_dir ($target, $directory_name);
+ }
+}
+
+my $name_dir = "NameService";
+my $group_dir = "GroupService";
+my $ns_replica_primary_iorfile = "$name_dir/ns_replica_primary.ior";
+my $ns_multi_iorfile = "ns_multi.ior";
+my $nm_multi_iorfile = "nm_multi.ior";
+my $ns_primary_iorfile = "ns_primary.ior";
+my $nm_primary_iorfile = "nm_primary.ior";
+my $ns_backup_iorfile = "ns_backup.ior";
+my $nm_backup_iorfile = "nm_backup.ior";
+my $stderr_file = "test.err";
+my $stdout_file = "test.out";
+
+################################################################################
+# setup END block to cleanup after exit call
+################################################################################
+END
+{
+ $server->DeleteFile ($ns_replica_primary_iorfile);
+
+ $server->DeleteFile ($ns_multi_iorfile);
+ $server->DeleteFile ($nm_multi_iorfile);
+ $server->DeleteFile ($ns_primary_iorfile);
+ $server->DeleteFile ($nm_primary_iorfile);
+ $server->DeleteFile ($ns_backup_iorfile);
+ $server->DeleteFile ($nm_backup_iorfile);
+
+ $client->DeleteFile ($ns_primary_iorfile);
+ $client->DeleteFile ($nm_primary_iorfile);
+ $client->DeleteFile ($ns_backup_iorfile);
+ $client->DeleteFile ($nm_backup_iorfile);
+ $client->DeleteFile ($stdout_file);
+ $client->DeleteFile ($stderr_file);
+
+ if ( -d $name_dir ) {
+ print STDERR "INFO: removing <$name_dir>\n";
+ clean_persistence_dir ($server, $name_dir);
+ rmdir ($name_dir);
+ }
+
+ if ( -d $group_dir ) {
+ print STDERR "INFO: removing <$group_dir>\n";
+ clean_persistence_dir ($server, $group_dir);
+ rmdir ($group_dir);
+ }
+}
+
+################################################################################
+# Validate that a client can seamlessly invoke naming operations on either
+# server instance.
+################################################################################
+sub redundant_equivalency_test()
+{
+ my $previous_status = $status;
+ $status = 0;
+
+ print_msg("Redundant Equivalency Test");
+
+ init_naming_context_directory ($server, $name_dir);
+ init_naming_context_directory ($server, $group_dir);
+
+ # The file that is written by the primary when ready to start backup
+ my $server_primary_iorfile = $server->LocalFile ($ns_replica_primary_iorfile);
+ my $server_ns_multi_iorfile = $server->LocalFile ($ns_multi_iorfile);
+ my $server_nm_multi_iorfile = $server->LocalFile ($nm_multi_iorfile);
+
+ my $server_ns_primary_iorfile = $server->LocalFile ($ns_primary_iorfile);
+ my $server_nm_primary_iorfile = $server->LocalFile ($nm_primary_iorfile);
+ my $server_ns_backup_iorfile = $server->LocalFile ($ns_backup_iorfile);
+ my $server_nm_backup_iorfile = $server->LocalFile ($nm_backup_iorfile);
+
+ my $client_ns_primary_iorfile = $client->LocalFile ($ns_primary_iorfile);
+ my $client_nm_primary_iorfile = $client->LocalFile ($nm_primary_iorfile);
+ my $client_ns_backup_iorfile = $client->LocalFile ($ns_backup_iorfile);
+ my $client_nm_backup_iorfile = $client->LocalFile ($nm_backup_iorfile);
+
+ my $client_stdout_file = $client->LocalFile ($stdout_file);
+ my $client_stderr_file = $client->LocalFile ($stderr_file);
+
+ my $tao_ft_naming = "$ENV{TAO_ROOT}/orbsvcs/Naming_Service/tao_ft_naming";
+
+ # Run two Naming Servers
+ my $ns1_args = "--primary ".
+ "-ORBDebugLevel $debug_level " .
+ "-ORBListenEndPoints $ns_endpoint1 ".
+ "-o $server_ns_primary_iorfile ".
+ "-h $server_nm_primary_iorfile ".
+ "-r $name_dir ".
+ "-v $group_dir ";
+
+ my $ns2_args = "--backup ".
+ "-ORBDebugLevel $debug_level " .
+ "-ORBListenEndPoints $ns_endpoint2 ".
+ "-o $server_ns_backup_iorfile ".
+ "-h $server_nm_backup_iorfile ".
+ "-c $server_ns_multi_iorfile ".
+ "-g $server_nm_multi_iorfile ".
+ "-r $name_dir ".
+ "-v $group_dir ";
+
+ my $client_args = "--equivalence " .
+ "-ORBDebugLevel $debug_level " .
+ "-p file://$client_ns_primary_iorfile " .
+ "-q file://$client_ns_backup_iorfile " .
+ "-r file://$client_nm_primary_iorfile " .
+ "-s file://$client_nm_backup_iorfile " .
+ "-b 4 " .
+ "-d 4 ";
+
+ my $client_prog = "$startdir/client";
+
+
+ $NS1 = $server->CreateProcess ($tao_ft_naming, $ns1_args);
+ $NS2 = $server->CreateProcess ($tao_ft_naming, $ns2_args);
+ $CL = $client->CreateProcess ($client_prog, $client_args);
+
+ $server->DeleteFile ($ns_primary_iorfile);
+ $NS1->Spawn ();
+ if ($server->WaitForFileTimed ($ns_primary_iorfile,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_primary_iorfile>\n";
+ $NS1->Kill (); $NS1->TimedWait (1);
+ exit 1;
+ }
+
+ $server->DeleteFile ($ns_multi_iorfile);
+ $NS2->Spawn ();
+ if ($server->WaitForFileTimed ($ns_multi_iorfile,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_ns_multi_iorfile>\n";
+ $NS2->Kill (); $NS2->TimedWait (1);
+ $NS1->Kill (); $NS1->TimedWait (1);
+ exit 1;
+ }
+
+ print_msg("INFO: Starting the client");
+ $client_status = $CL->SpawnWaitKill ($client->ProcessStartWaitInterval()+5);
+ if ($client_status != 0) {
+ print STDERR "ERROR: client returned $client_status\n";
+ $status = 1;
+ }
+
+
+ $server_status = $NS2->TerminateWaitKill ($server->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server 2 returned $server_status\n";
+ $status = 1;
+ }
+
+ $server_status = $NS1->TerminateWaitKill ($server->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server 1 returned $server_status\n";
+ $status = 1;
+ }
+
+ if ( $status == 0 ) {
+ $status = $previous_status;
+ }
+
+ return $status;
+}
+
+sub print_msg($)
+{
+ my $msg = shift;
+ my $bar = "===============================================================================";
+ print STDERR "\n\n$bar\n$msg\n$bar\n";
+}
+
+sub show_result($$)
+{
+ my $test_result = shift;
+ my $test_name = shift;
+
+ if ( 0 == $test_result ) {
+ print_msg("$test_name: SUCCESS");
+ } else {
+ print_msg("$test_name: ERROR");
+ }
+}
+
+my $result = redundant_equivalency_test ();
+show_result($result, "Redundant Equivalency Test");
+
+exit $result;
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_failover_test.pl b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_failover_test.pl
new file mode 100755
index 00000000000..ad2aeba4eac
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_failover_test.pl
@@ -0,0 +1,416 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+use Cwd;
+
+#$ENV{ACE_TEST_VERBOSE} = "1";
+
+my $startdir = getcwd();
+my $debug_level = '0';
+my $redirection_enabled = 0;
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $debug_level = '10';
+ }
+ if ($i eq '-verbose') {
+ $redirection_enabled = 0;
+ }
+}
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+
+
+# Variables for command-line arguments to client and server
+# executables.
+my $hostname = $server->HostName ();
+
+
+my $ns_orb_port1 = 10001 + $server->RandomPort ();
+my $ns_orb_port2 = 10002 + $server->RandomPort ();
+
+my $ns_endpoint1 = "iiop://$hostname:$ns_orb_port1";
+my $ns_endpoint2 = "iiop://$hostname:$ns_orb_port2";
+
+
+
+# References to both naming services
+my $default_init_ref = "-ORBDefaultInitRef corbaloc:iiop:$hostname:$ns_orb_port1,iiop:$hostname:$ns_orb_port2";
+
+# References to primary naming service only
+my $primary_default_init_ref = "-ORBDefaultInitRef corbaloc:iiop:$hostname:$ns_orb_port1";
+
+# References to backup naming service only
+my $backup_default_init_ref = "-ORBDefaultInitRef corbaloc:iiop:$hostname:$ns_orb_port2";
+
+## Allow the user to determine where the persistence file will be located
+## just in case the current directory is not suitable for locking.
+## We can't change the name of the persistence file because that is not
+## sufficient to work around locking problems for Tru64 when the current
+## directory is NFS mounted from a system that does not properly support
+## locking.
+foreach my $possible ($ENV{TMPDIR}, $ENV{TEMP}, $ENV{TMP}) {
+ if (defined $possible && -d $possible) {
+ if (chdir($possible)) {
+ last;
+ }
+ }
+}
+
+my $status = 0;
+my $POSITIVE_TEST_RESULT = 0;
+my $NEGATIVE_TEST_RESULT = 1;
+
+my $NSGROUP = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsgroup");
+my $NSLIST = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nslist");
+my $NSADD = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsadd");
+my $NSDEL = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsdel");
+
+sub cat_file($)
+{
+ my $file_name = shift;
+ if (-s $file_name ) # size of file is greater than zero
+ {
+ open TESTFILE, $file_name or die "Couldn't open file: $!";
+ my @teststring = <TESTFILE>; # read in all of the file
+ print STDERR "\n@teststring\n";
+ close TESTFILE;
+ }
+}
+
+sub redirect_output()
+{
+ open (OLDOUT, ">&", \*STDOUT) or die "Can't dup STDOUT: $!";
+ open (OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!";
+ open STDERR, '>', $client_stderr_file;
+ open STDOUT, '>', $client_stdout_file;
+}
+
+sub restore_output()
+{
+ open (STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!";
+ open (STDOUT, ">&OLDOUT") or die "Can't dup OLDOUT: $!";
+}
+
+sub run_nsgroup ($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ my $arglist = "$args";
+
+ $NSGROUP->Arguments ($arglist);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ my $nsgroup_status = $NSGROUP->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nsgroup_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nsgroup returned $nsgroup_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nslist($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ $NSLIST->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nslist --ns file://ns.ior
+ my $nslist_status = $NSLIST->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nslist_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nslist returned $nslist_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nsadd($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ $NSADD->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nsadd --ns file://ns.ior --name iso --ctx
+ my $nsadd_status = $NSADD->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nsadd_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nsadd returned $nsadd_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nsdel($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ $NSDEL->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nsdel --ns file://ns.ior --name iso --destroy
+ my $nsdel_status = $NSDEL->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nsdel_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nsdel returned $nsdel_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub clean_persistence_dir($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+ chdir $directory_name;
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $target->DeleteFile ($tmp);
+ }
+ chdir "..";
+}
+
+# Make sure that the directory to use to hold the naming contexts exists
+# and is cleaned out
+sub init_naming_context_directory($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ if ( ! -d $directory_name ) {
+ mkdir ($directory_name, 0777);
+ } else {
+ clean_persistence_dir ($target, $directory_name);
+ }
+}
+
+my $name_dir = "NameService";
+my $group_dir = "GroupService";
+my $primary_iorfile = "$name_dir/ns_replica_primary.ior";
+my $nm_iorfile = "nm.ior";
+my $ns_iorfile = "ns.ior";
+my $stderr_file = "test.err";
+my $stdout_file = "test.out";
+
+################################################################################
+# setup END block to cleanup after exit call
+################################################################################
+END
+{
+ $server->DeleteFile($primary_iorfile);
+ $server->DeleteFile($nm_iorfile);
+ $server->DeleteFile($ns_iorfile);
+ $client->DeleteFile ($stdout_file);
+ $client->DeleteFile ($stderr_file);
+
+ if ( -d $name_dir ) {
+ print STDERR "INFO: removing <$name_dir>\n";
+ clean_persistence_dir ($server, $name_dir);
+ rmdir ($name_dir);
+ }
+
+ if ( -d $group_dir ) {
+ print STDERR "INFO: removing <$group_dir>\n";
+ clean_persistence_dir ($server, $group_dir);
+ rmdir ($group_dir);
+ }
+
+}
+
+################################################################################
+# Validate that a client can seamlessly connect to the alternate server of a
+# server naming server pair after the other server has been terminated.
+################################################################################
+sub failover_test()
+{
+ my $previous_status = $status;
+ $status = 0;
+
+ # The file that is written by the primary when ready to start backup
+ my $server_primary_iorfile = $server->LocalFile ($primary_iorfile);
+ my $server_nm_iorfile = $server->LocalFile ($nm_iorfile);
+ my $server_ns_iorfile = $server->LocalFile ($ns_iorfile);
+ my $client_stdout_file = $client->LocalFile ($stdout_file);
+ my $client_stderr_file = $client->LocalFile ($stderr_file);
+
+ print_msg("Failover Test");
+ init_naming_context_directory ($server, $name_dir );
+ init_naming_context_directory ($server, $group_dir );
+
+ # Run two Naming Servers
+ my $ns1_args = "--primary ".
+ "-ORBDebugLevel $debug_level ".
+ "-ORBListenEndPoints $ns_endpoint1 ".
+ "-m 0 ".
+ "-r $name_dir ".
+ "-v $group_dir";
+
+ my $ns2_args = "--backup ".
+ "-ORBDebugLevel $debug_level ".
+ "-ORBListenEndPoints $ns_endpoint2 ".
+ "-c $server_ns_iorfile ".
+ "-g $server_nm_iorfile ".
+ "-m 0 ".
+ "-r $name_dir ".
+ "-v $group_dir";
+
+ my $tao_ft_naming = "$ENV{TAO_ROOT}/orbsvcs/Naming_Service/tao_ft_naming";
+
+ my $client_args = "--failover " .
+ "-ORBDebugLevel $debug_level " .
+ "-p file://$server_ns_iorfile " .
+ "-r file://$server_nm_iorfile " .
+ "-b 4 " .
+ "-d 4 " ;
+
+ my $client_prog = "$startdir/client";
+
+ $NS1 = $server->CreateProcess ($tao_ft_naming, $ns1_args);
+ $NS2 = $server->CreateProcess ($tao_ft_naming, $ns2_args);
+ $CL = $client->CreateProcess ($client_prog, $client_args);
+
+ $server->DeleteFile ($primary_iorfile);
+ $server->DeleteFile ($ns_iorfile);
+ $server->DeleteFile ($nm_iorfile);
+
+ print_msg("INFO: Starting the primary");
+ $NS1->Spawn ();
+ if ($server->WaitForFileTimed ($primary_iorfile,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_primary_iorfile>\n";
+ $NS1->Kill (); $NS1->TimedWait (1);
+ exit 1;
+ }
+
+ print_msg("INFO: Starting the backup");
+ $NS2->Spawn ();
+ if ($server->WaitForFileTimed ($ns_iorfile,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_ns_iorfile>\n";
+ $NS2->Kill (); $NS2->TimedWait (1);
+ $NS1->Kill (); $NS1->TimedWait (1);
+ exit 1;
+ }
+
+ print_msg("INFO: Starting the client");
+ $CL->Spawn ();
+
+ $server_status = $NS1->TerminateWaitKill ($server->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server 1 returned $server_status\n";
+ $status = 1;
+ }
+
+ print_msg("INFO: restart primary server");
+ $NS1->Spawn ();
+
+ sleep(5);
+
+ $client_status = $CL->TerminateWaitKill ($client->ProcessStopWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client returned $client_status\n";
+ $status = 1;
+ }
+
+ $server_status = $NS2->TerminateWaitKill ($server->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server 2 returned $server_status\n";
+ $status = 1;
+ }
+
+ $server_status = $NS1->TerminateWaitKill ($server->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server 1 returned $server_status\n";
+ $status = 1;
+ }
+
+ if ( $status == 0 ) {
+ $status = $previous_status;
+ }
+
+ return $status;
+}
+
+sub print_msg($)
+{
+ my $msg = shift;
+ my $bar = "===============================================================================";
+ print STDERR "\n\n$bar\n$msg\n$bar\n";
+}
+
+sub show_result($$)
+{
+ my $test_result = shift;
+ my $test_name = shift;
+
+ if ( 0 == $test_result ) {
+ print_msg("$test_name: SUCCESS");
+ } else {
+ print_msg("$test_name: ERROR");
+ }
+}
+
+my $result = failover_test ();
+show_result($result, "Failover Test");
+
+exit $result;
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_persistence_test.pl b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_persistence_test.pl
new file mode 100755
index 00000000000..c71653cfec1
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_persistence_test.pl
@@ -0,0 +1,652 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+use Cwd;
+use File::Compare;
+use File::Copy;
+
+#$ENV{ACE_TEST_VERBOSE} = "1";
+
+my $startdir = getcwd();
+my $debug_level = '0';
+my $redirection_enabled = 0;
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $debug_level = '10';
+ }
+ if ($i eq '-verbose') {
+ $redirection_enabled = 0;
+ }
+
+}
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+my $server2 = PerlACE::TestTarget::create_target (3) || die "Create target 3 failed\n";
+
+
+
+# Variables for command-line arguments to client and server
+# executables.
+
+my $stdout_file = "test.out";
+my $stderr_file = "test.err";
+my $client_stdout_file = $client->LocalFile ($stdout_file);
+my $client_stderr_file = $client->LocalFile ($stderr_file);
+
+my $status = 0;
+my $POSITIVE_TEST_RESULT = 0;
+my $NEGATIVE_TEST_RESULT = 1;
+
+my $NSGROUP = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsgroup");
+my $NSLIST = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nslist");
+my $NSADD = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsadd");
+my $NSDEL = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsdel");
+
+## Allow the user to determine where the persistence file will be located
+## just in case the current directory is not suitable for locking.
+## We can't change the name of the persistence file because that is not
+## sufficient to work around locking problems for Tru64 when the current
+## directory is NFS mounted from a system that does not properly support
+## locking.
+foreach my $possible ($ENV{TMPDIR}, $ENV{TEMP}, $ENV{TMP}) {
+ if (defined $possible && -d $possible) {
+ if (chdir($possible)) {
+ last;
+ }
+ }
+}
+
+sub cat_file($)
+{
+ my $file_name = shift;
+ if (-s $file_name ) # size of file is greater than zero
+ {
+ open TESTFILE, $file_name or die "Couldn't open file: $!";
+ my @teststring = <TESTFILE>; # read in all of the file
+ print STDERR "\n@teststring\n";
+ close TESTFILE;
+ }
+}
+
+sub redirect_output()
+{
+ open (OLDOUT, ">&", \*STDOUT) or die "Can't dup STDOUT: $!";
+ open (OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!";
+ open STDERR, '>', $client_stderr_file;
+ open STDOUT, '>', $client_stdout_file;
+}
+
+sub restore_output()
+{
+ open (STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!";
+ open (STDOUT, ">&OLDOUT") or die "Can't dup OLDOUT: $!";
+}
+
+sub compare_file_with_backup($)
+{
+ my $file = shift;
+ my $backup = $file . ".bak";
+ unless (-e $backup) {
+ print STDERR "ERROR: Backup file $backup does not exist\n";
+ return 1;
+ }
+ my $result = compare ($file, $backup);
+ if ($result != 0) {
+ print STDERR "ERROR: Backup file $backup does not agree with $file\n";
+ }
+ return $result;
+}
+
+sub run_nsgroup ($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ my $arglist = "$args";
+
+ $NSGROUP->Arguments ($arglist);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ my $nsgroup_status = $NSGROUP->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nsgroup_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nsgroup returned $nsgroup_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nslist($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ $NSLIST->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nslist --ns file://ns.ior
+ my $nslist_status = $NSLIST->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nslist_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nslist returned $nslist_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nsadd($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ $NSADD->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nsadd --ns file://ns.ior --name iso --ctx
+ my $nsadd_status = $NSADD->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nsadd_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nsadd returned $nsadd_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nsdel($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ $NSDEL->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nsdel --ns file://ns.ior --name iso --destroy
+ my $nsdel_status = $NSDEL->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($nsdel_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: nsdel returned $nsdel_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub clean_persistence_dir($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ chdir $directory_name;
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $target->DeleteFile ($tmp);
+ }
+ chdir "..";
+}
+
+# Make sure that the directory to use to hold the naming contexts exists
+# and is cleaned out
+sub init_persistence_dir($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ if ( ! -d $directory_name ) {
+ mkdir ($directory_name, 0777);
+ } else {
+ clean_persistence_dir ($target, $directory_name);
+ }
+}
+
+my $name_dir = "NameService";
+my $group_dir = "GroupService";
+my $nm_iorfile = "nm.ior";
+my $ns_iorfile = "ns.ior";
+my $sv_iorfile = "obj.ior";
+my $ns_ref = "--ns file://$ns_iorfile";
+my $sv2_iorfile = $server2->LocalFile ($sv_iorfile);
+
+
+
+
+################################################################################
+# setup END block to cleanup after exit call
+################################################################################
+END
+{
+ $server->DeleteFile ($ns_iorfile);
+ $server->DeleteFile ($nm_iorfile);
+ $client->DeleteFile ($nm_iorfile);
+ $client->DeleteFile ($stdout_file);
+ $client->DeleteFile ($stderr_file);
+ $server2->DeleteFile($sv_iorfile);
+
+ if ( -d $name_dir ) {
+ print STDERR "INFO: removing <$name_dir>\n";
+ clean_persistence_dir ($server, $name_dir);
+ rmdir ($name_dir);
+ }
+
+ if ( -d $group_dir ) {
+ print STDERR "INFO: removing <$group_dir>\n";
+ clean_persistence_dir ($server, $group_dir);
+ rmdir ($group_dir);
+ }
+}
+
+################################################################################
+# Validate that repository data written by the name service is available upon
+# startup.
+################################################################################
+sub persistence_test ()
+{
+ my $previous_status = $status;
+ $status = 0;
+
+ my $hostname = $server->HostName ();
+ my $ns_orb_port1 = 10001 + $server->RandomPort ();
+ my $ns_endpoint1 = "iiop://$hostname:$ns_orb_port1";
+ my $default_init_ref = "-ORBDefaultInitRef corbaloc:iiop:$hostname:$ns_orb_port1";
+ my $client_nm_iorfile = $client->LocalFile ($nm_iorfile);
+
+ print_msg("Persistence Test");
+ init_persistence_dir ($server, $name_dir );
+ init_persistence_dir ($server, $group_dir );
+
+ my $ns_args = "-ORBListenEndPoints $ns_endpoint1 ".
+ "-ORBDebugLevel $debug_level " .
+ "-g $nm_iorfile ".
+ "-o $ns_iorfile ".
+ "-v $group_dir ".
+ "-u $name_dir ";
+
+ my $tao_ft_naming = "$ENV{TAO_ROOT}/orbsvcs/Naming_Service/tao_ft_naming";
+
+ my $client1_args = "--persistence " .
+ "--create " .
+ "-ORBDebugLevel $debug_level " .
+ "-p corbaloc:iiop:$hostname:$ns_orb_port1/NameService " .
+ "-r corbaloc:iiop:$hostname:$ns_orb_port1/NamingManager " .
+ "-b 4 " .
+ "-d 4 ";
+
+ my $client2_args = "--persistence " .
+ "--validate " .
+ "-ORBDebugLevel $debug_level " .
+ "-p corbaloc:iiop:$hostname:$ns_orb_port1/NameService " .
+ "-r corbaloc:iiop:$hostname:$ns_orb_port1/NamingManager " .
+ "-b 4 " .
+ "-d 4 ";
+
+ my $client_prog = "$startdir/client";
+
+
+ ##1. Run one instance of tao_ft_naming service
+ $NS1 = $server->CreateProcess ($tao_ft_naming, $ns_args);
+ $CL1 = $client->CreateProcess ($client_prog, $client1_args);
+ $CL2 = $client->CreateProcess ($client_prog, $client2_args);
+
+
+ my $server2_args = "-ORBdebuglevel $debug_level " .
+ "$default_init_ref ".
+ "-o $sv2_iorfile ";
+
+ $SV2 = $server2->CreateProcess ("$startdir/server", $server2_args);
+
+ $server->DeleteFile ($ns_iorfile);
+ $NS1->Spawn ();
+ if ($server->WaitForFileTimed ($ns_iorfile,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$ns_iorfile>\n";
+ $NS1->Kill (); $NS1->TimedWait (1);
+ exit 1;
+ }
+
+ ##2. Create new contexts and new object groups
+ print_msg("INFO: starting test server");
+ $server_status = $SV2->Spawn ();
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+ if ($server2->WaitForFileTimed ($sv_iorfile,
+ $server2->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$sv_iorfile>\n";
+ $SV2->Kill (); $SV2->TimedWait (1);
+ exit 1;
+ }
+
+ ##3. Creation additional contexts and object groups and verify
+ print_msg("INFO: Starting client1");
+ $client_status = $CL1->SpawnWaitKill ($client->ProcessStartWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client1 returned $client_status\n";
+ $status = 1;
+ }
+
+ ##4. Kill the tao_ft_naming server
+ print_msg("Kill the tao_ft_naming server");
+ $server_status = $NS1->TerminateWaitKill ($server->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server 1 returned $server_status\n";
+ $status = 1;
+ }
+
+ ##5. Start a new instance of the tao_ft_naming server
+ print_msg("Start a new instance of the tao_ft_naming server");
+ $server->DeleteFile ($ns_iorfile);
+ $NS1->Spawn ();
+ if ($server->WaitForFileTimed ($ns_iorfile,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$ns_iorfile>\n";
+ $NS1->Kill (); $NS1->TimedWait (1);
+ $status = 1;
+ }
+
+ ##6. Verify the new name, object group and member are in the tao_ft_naming repository.
+ print_msg("Verify the new name, object group and member are in the tao_ft_naming repository");
+ print_msg("INFO: Starting client2");
+ $client_status = $CL2->SpawnWaitKill ($client->ProcessStartWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client2 returned $client_status\n";
+ $status = 1;
+ }
+
+ print_msg("INFO: terminating test server");
+ $server_status = $SV2->TerminateWaitKill ($server2->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server_status = $NS1->TerminateWaitKill ($server->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server 1 returned $server_status\n";
+ $status = 1;
+ }
+
+ if ( $status == 0 ) {
+ $status = $previous_status;
+ }
+
+ return $status;
+}
+
+################################################################################
+# Validate that when a corrupt persistent file is read that the contents of the
+# backup file is used instead.
+################################################################################
+sub backup_restore_test ()
+{
+
+ my $num_child_contexts = 8;
+ my $num_object_groups = 1;
+
+ my $previous_status = $status;
+ $status = 0;
+
+ my $hostname = $server->HostName ();
+ my $ns_orb_port1 = 10001 + $server->RandomPort ();
+ my $ns_endpoint1 = "iiop://$hostname:$ns_orb_port1";
+ my $default_init_ref = "-ORBDefaultInitRef corbaloc:iiop:$hostname:$ns_orb_port1";
+ my $client_nm_iorfile = $client->LocalFile ($nm_iorfile);
+
+ print_msg("Backup/Restore Test");
+ init_persistence_dir ($server, $name_dir );
+ init_persistence_dir ($server, $group_dir );
+
+ my $ns_args = "-ORBListenEndPoints $ns_endpoint1 ".
+ "-ORBDebugLevel $debug_level " .
+ "-g $nm_iorfile ".
+ "-o $ns_iorfile ".
+ "-v $group_dir ".
+ "-u $name_dir ";
+
+ my $tao_ft_naming = "$ENV{TAO_ROOT}/orbsvcs/Naming_Service/tao_ft_naming";
+
+ my $client1_args = "--persistence " .
+ "--create " .
+ "-ORBDebugLevel $debug_level " .
+ "-p corbaloc:iiop:$hostname:$ns_orb_port1/NameService " .
+ "-r corbaloc:iiop:$hostname:$ns_orb_port1/NamingManager " .
+ "-b 4 " .
+ "-d 4 ";
+
+ my $client2_args = "--persistence " .
+ "--validate " .
+ "-ORBDebugLevel $debug_level " .
+ "-p corbaloc:iiop:$hostname:$ns_orb_port1/NameService " .
+ "-r corbaloc:iiop:$hostname:$ns_orb_port1/NamingManager " .
+ "-b 4 " .
+ "-d 4 ";
+
+ my $client_prog = "$startdir/client";
+
+
+ ##1. Run one instance of tao_ft_naming service
+ $NS1 = $server->CreateProcess ($tao_ft_naming, $ns_args);
+ $CL1 = $client->CreateProcess ($client_prog, $client1_args);
+ $CL2 = $client->CreateProcess ($client_prog, $client2_args);
+
+
+ my $server2_args = "-ORBdebuglevel $debug_level " .
+ "$default_init_ref ".
+ "-o $sv2_iorfile ";
+
+ $SV2 = $server2->CreateProcess ("$startdir/server", $server2_args);
+
+ $server->DeleteFile ($ns_iorfile);
+ $NS1->Spawn ();
+ if ($server->WaitForFileTimed ($ns_iorfile,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$ns_iorfile>\n";
+ $NS1->Kill (); $NS1->TimedWait (1);
+ exit 1;
+ }
+
+ ##2. Create new contexts and new object groups
+ print_msg("INFO: starting test server");
+ $server_status = $SV2->Spawn ();
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+ if ($server2->WaitForFileTimed ($sv_iorfile,
+ $server2->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$sv_iorfile>\n";
+ $SV2->Kill (); $SV2->TimedWait (1);
+ exit 1;
+ }
+
+ ##3. Creation additional contexts and object groups and verify
+ print_msg("INFO: Starting client1");
+ $client_status = $CL1->SpawnWaitKill ($client->ProcessStartWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client1 returned $client_status\n";
+ $status = 1;
+ }
+
+ ##4. Kill the tao_ft_naming server
+ print_msg("Kill the tao_ft_naming server");
+ $server_status = $NS1->TerminateWaitKill ($server->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server 1 returned $server_status\n";
+ $status = 1;
+ }
+
+ ##5. Verify that backup files are created
+
+ print_msg("Verifying naming context backup files");
+ $file = $name_dir . "/NameService";
+ if (compare_file_with_backup ($file) != 0) {
+ $status = 1;
+ }
+ for ($i = 0; $i < $num_child_contexts; $i++) {
+ $file = $name_dir . "/NameService_$i";
+ if (compare_file_with_backup ($file) != 0) {
+ $status = 1;
+ }
+ }
+
+ print_msg("Verifying object group backup files");
+ $file = $group_dir . "/ObjectGroup_global";
+ if (compare_file_with_backup ($file) != 0) {
+ $status = 1;
+ }
+ for ($i = 0; $i < $num_object_groups; $i++) {
+ $file = $group_dir . "/ObjectGroup_$i";
+ if (compare_file_with_backup ($file) != 0) {
+ $status = 1;
+ }
+ }
+
+ ##6. Replace some of the data files with corrupt files
+ print_msg("Replace data files with corrupt files");
+ my $corrupt_data_dir = $startdir . "/corrupt_data/";
+
+ my $corrupt_name_dir = $corrupt_data_dir . $name_dir . "/";
+ opendir(NAMEDIR, $corrupt_name_dir);
+ @allfiles = grep(/^NameService/, readdir(NAMEDIR));
+ closedir(NAMEDIR);
+ foreach $file (@allfiles) {
+ copy ($corrupt_name_dir . $file, $name_dir . "/" . $file) or die "Copy failed: $!\n";
+ }
+
+ my $corrupt_group_dir = $corrupt_data_dir . $group_dir . "/";
+ opendir(GROUPDIR, $corrupt_group_dir);
+ @allfiles = grep(/^ObjectGroup/, readdir(GROUPDIR));
+ closedir(GROUPDIR);
+ foreach $file (@allfiles) {
+ copy ($corrupt_group_dir . $file, $group_dir . "/" . $file) or die "Copy failed: $!\n";
+ }
+
+ ##7. Start a new instance of the tao_ft_naming server
+ print_msg("Start a new instance of the tao_ft_naming server and then running client 2");
+ $server->DeleteFile ($ns_iorfile);
+ # Redirect output so that expected error messages are not interpreted as
+ # test failure and rely instead of return status.
+ redirect_output();
+ my $restore_status = 0;
+ $NS1->Spawn ();
+ if ($server->WaitForFileTimed ($ns_iorfile,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$ns_iorfile>\n";
+ $NS1->Kill (); $NS1->TimedWait (1);
+ $status = 1;
+ $restorestatus = 1;
+ }
+
+ ##8. Verify the new name, object group and member are in the tao_ft_naming repository.
+ print_msg("Verify the backup files are used when the corrupt files are read");
+ print_msg("INFO: Starting client2");
+ $client_status = $CL2->SpawnWaitKill ($client->ProcessStartWaitInterval());
+ restore_output();
+ if ($client_status != 0) {
+ print STDERR "ERROR: client2 returned $client_status\n";
+ $status = 1;
+ $restorestatus = 1;
+ }
+
+ if ($restore_status == 1) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+
+ print_msg("INFO: terminating test server");
+ $server_status = $SV2->TerminateWaitKill ($server2->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server_status = $NS1->TerminateWaitKill ($server->ProcessStopWaitInterval());
+ if ($server_status != 0) {
+ print STDERR "ERROR: server 1 returned $server_status\n";
+ $status = 1;
+ }
+
+ if ( $status == 0 ) {
+ $status = $previous_status;
+ }
+
+ return $status;
+}
+
+sub print_msg($)
+{
+ my $msg = shift;
+ my $bar = "===============================================================================";
+ print STDERR "\n\n$bar\n$msg\n$bar\n";
+}
+
+sub show_result($$)
+{
+ my $test_result = shift;
+ my $test_name = shift;
+
+ if ( 0 == $test_result ) {
+ print_msg("$test_name: SUCCESS");
+ } else {
+ print_msg("$test_name: ERROR");
+ }
+}
+
+my $result = persistence_test ();
+my $result = backup_restore_test ();
+
+show_result($result, "Persistence Test");
+
+exit $result;
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_test.pl b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_test.pl
new file mode 100755
index 00000000000..1f2a652df81
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/run_test.pl
@@ -0,0 +1,44 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+use Cwd;
+
+
+my @list=("run_failover_test.pl",
+ "run_persistence_test.pl",
+ "run_equivalence_test.pl");
+
+my $status = 0;
+
+my $debug_option = '';
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $debug_option = '-debug';
+ }
+}
+
+for $cmd (@list) {
+ if (-f $cmd) {
+ if (system ("perl $cmd $debug_option") != 0) {
+ $status = 1;
+ }
+ } else {
+ print STDERR "ERROR: Can't find $cmd\n";
+ }
+}
+my $test_label = "FT_Naming FaultTolerant";
+
+if ($status != 0) {
+ print STDERR "ERROR: One or more $test_label tests Failed\n";
+} else {
+ print STDERR "INFO: All $test_label tests report OK\n";
+}
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/server.cpp b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/server.cpp
new file mode 100644
index 00000000000..57b661e1bd6
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/server.cpp
@@ -0,0 +1,121 @@
+// $Id$
+
+#include "LB_server.h"
+#include "Basic.h"
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ const char *location1 = ACE_TEXT_ALWAYS_CHAR ("location1");
+ const char *location2 = ACE_TEXT_ALWAYS_CHAR ("location2");
+ const char *location3 = ACE_TEXT_ALWAYS_CHAR ("location3");
+ const char *location4 = ACE_TEXT_ALWAYS_CHAR ("location4");
+ const char *location5 = ACE_TEXT_ALWAYS_CHAR ("location5");
+ const char *location6 = ACE_TEXT_ALWAYS_CHAR ("location6");
+
+ LB_server lb_server (argc, argv);
+
+ if (lb_server.start_orb_and_poa () != 0)
+ return 1;
+
+ if (lb_server.create_object_group () != 0)
+ return 1;
+
+ CosNaming::Name name (1);
+ name.length (1);
+ name[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("basic_name"));
+ try {
+ (lb_server.name_svc ())->rebind (name, lb_server.object_group ());
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Unable to bind object group in name service.\n"));
+ return 1;
+ }
+
+ Basic *basic_servant1;
+ Basic *basic_servant2;
+ Basic *basic_servant3;
+ Basic *basic_servant4;
+ Basic *basic_servant5;
+ Basic *basic_servant6;
+
+ ACE_NEW_RETURN (basic_servant1,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location1),
+ 1);
+ PortableServer::ServantBase_var owner_transfer1(basic_servant1);
+
+ ACE_NEW_RETURN (basic_servant2,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location2),
+ 1);
+ PortableServer::ServantBase_var owner_transfer2(basic_servant2);
+
+ ACE_NEW_RETURN (basic_servant3,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location3),
+ 1);
+ PortableServer::ServantBase_var owner_transfer3(basic_servant3);
+
+ ACE_NEW_RETURN (basic_servant4,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location4),
+ 1);
+ PortableServer::ServantBase_var owner_transfer4(basic_servant4);
+
+ ACE_NEW_RETURN (basic_servant5,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location5),
+ 1);
+ PortableServer::ServantBase_var owner_transfer5(basic_servant5);
+
+ ACE_NEW_RETURN (basic_servant6,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location6),
+ 1);
+ PortableServer::ServantBase_var owner_transfer6(basic_servant6);
+
+ if (lb_server.register_servant (basic_servant1, location1) == -1
+ || lb_server.register_servant (basic_servant2, location2) == -1
+ || lb_server.register_servant (basic_servant3, location3) == -1
+ || lb_server.register_servant (basic_servant4, location4) == -1
+ || lb_server.register_servant (basic_servant5, location5) == -1
+ || lb_server.register_servant (basic_servant6, location6) == -1)
+ {
+ (void) lb_server.destroy ();
+ return 1;
+ }
+
+ lb_server.orb ()->run ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) server - event loop finished\n")));
+
+ if (lb_server.destroy () == -1)
+ return 1;
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("lb_server exception"));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/test_object.idl b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/test_object.idl
new file mode 100644
index 00000000000..4737f6dc6c8
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/test_object.idl
@@ -0,0 +1,11 @@
+// $Id$
+
+interface Test_Object
+{
+ // = TITLE
+ // This is a simple interface that tests the Naming Service.
+
+ attribute short id;
+ // This provides an easy way to differentiate objects if each
+ // objects is served by a separate servant.
+};
diff --git a/TAO/orbsvcs/tests/FT_Naming/Federation/Federation.mpc b/TAO/orbsvcs/tests/FT_Naming/Federation/Federation.mpc
new file mode 100644
index 00000000000..eeab5127922
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Federation/Federation.mpc
@@ -0,0 +1,38 @@
+// -*- MPC -*-
+// $Id$
+
+project(*idl): taoidldefaults {
+ IDL_Files {
+ Test.idl
+ }
+ custom_only = 1
+}
+
+project(*Client): namingexe {
+ exename = client
+ after += *idl
+ Source_Files {
+ client.cpp
+ }
+ Source_Files {
+ TestC.cpp
+ }
+ IDL_Files {
+ }
+}
+
+project(*Server): namingexe, portableserver {
+ exename = server
+ after += *idl
+ Source_Files {
+ server.cpp
+ Hello.cpp
+ }
+ Source_Files {
+ TestC.cpp
+ TestS.cpp
+ }
+ IDL_Files {
+ }
+}
+
diff --git a/TAO/orbsvcs/tests/FT_Naming/Federation/Hello.cpp b/TAO/orbsvcs/tests/FT_Naming/Federation/Hello.cpp
new file mode 100644
index 00000000000..817955f5d36
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Federation/Hello.cpp
@@ -0,0 +1,23 @@
+//
+// $Id$
+//
+#include "Hello.h"
+
+
+
+Hello::Hello (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+{
+}
+
+char *
+Hello::get_string (void)
+{
+ return CORBA::string_dup ( ACE_TEXT ("Hello there!"));
+}
+
+void
+Hello::shutdown (void)
+{
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/Federation/Hello.h b/TAO/orbsvcs/tests/FT_Naming/Federation/Hello.h
new file mode 100644
index 00000000000..3a840d3d88d
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Federation/Hello.h
@@ -0,0 +1,31 @@
+//
+// $Id$
+//
+
+#ifndef HELLO_H
+#define HELLO_H
+#include /**/ "ace/pre.h"
+
+#include "TestS.h"
+
+/// Implement the Test::Hello interface
+class Hello
+ : public virtual POA_Test::Hello
+{
+public:
+ /// Constructor
+ Hello (CORBA::ORB_ptr orb);
+
+ // = The skeleton methods
+ virtual char * get_string (void);
+
+ virtual void shutdown (void);
+
+private:
+ /// Use an ORB reference to convert strings to objects and shutdown
+ /// the application.
+ CORBA::ORB_var orb_;
+};
+
+#include /**/ "ace/post.h"
+#endif /* HELLO_H */
diff --git a/TAO/orbsvcs/tests/FT_Naming/Federation/README b/TAO/orbsvcs/tests/FT_Naming/Federation/README
new file mode 100644
index 00000000000..b2d7e2838f4
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Federation/README
@@ -0,0 +1,70 @@
+$Id$
+
+This tests the federated fault tolerant naming service use case:
+
+To run all tests automatically -
+ execute Perl script run_test.pl
+
+Example Perl script execution output:
+$./run_test.pl
+Hello object bound in Naming Service B
+Root context of NS B bound in Naming Service A under name 'nsB'
+Wrote IOR file
+Starting client
+**** Narrowed root NamingContext
+**** Resolved #nsB/example/Hello
+(12960|3069859584) - string returned <Hello there!>
+INFO: server being killed.
+INFO: removing <NameService1>
+INFO: removing <NameService2>
+$
+
+To run tests manually -
+ start the 2 redundant pairs of tao_ft_naming (see
+ TAO/orbsvcs/Naming_Service/README for valid options),
+ then run ./server and ./client as shown below:
+
+NOTE: if running tests manually, the NameService1 and NameService2 directories
+must exist before starting the Naming Service and these directories must be
+cleaned out manually after stopping the Naming Service.
+
+1) server connects to Naming Service B (localhost:9932) and attempts to bind
+ context "example" to it.
+
+2) server attempts to bind "Hello" object to the newly created context "example".
+
+3) server connects to Naming Service A (localhost:9931) and bind
+ Naming Service B as name "nsB".
+
+4) server writes out ior file.
+
+5) client connects to Naming Service A (localhost:9931) and attempts to resolve
+ "nsB/example/Hello" from the root context.
+
+6) client attempts to narrow the Hello object and reports the output of the
+ Hello object's get_string() method.
+
+Example (on a Unix system):
+
+$tao_ft_naming --primary -ORBListenEndPoints iiop://localhost:9931 \
+ -r NameService1 &
+$tao_ft_naming --backup -ORBListenEndPoints iiop://localhost:9933 -c ns1.ior \
+ -g nm1.ior -r NameService1 &
+
+$tao_ft_naming --primary -ORBListenEndPoints iiop://localhost:9932 \
+ -r NameService2 &
+$tao_ft_naming --backup -ORBListenEndPoints iiop://localhost:9934 -c ns2.ior \
+ -g nm2.ior -r NameService2 &
+
+$./server -o test.ior &
+
+Hello object bound in Naming Service B
+Root context of NS B bound in Naming Service A under name 'nsB'
+Wrote IOR file
+
+$./client
+
+**** Narrowed root NamingContext
+**** Resolved #nsB/example/Hello
+(10911|3069798144) - string returned <Hello there!>
+
diff --git a/TAO/orbsvcs/tests/FT_Naming/Federation/Test.idl b/TAO/orbsvcs/tests/FT_Naming/Federation/Test.idl
new file mode 100644
index 00000000000..98ed1b2e3a3
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Federation/Test.idl
@@ -0,0 +1,26 @@
+//
+// $Id$
+//
+
+/// Put the interfaces in a module, to avoid global namespace pollution
+module Test
+{
+ /// A very simple interface
+ interface Hello
+ {
+ /// Return a simple string
+ string get_string ();
+
+ /// A method to shutdown the ORB
+ /**
+ * This method is used to simplify the test shutdown process
+ */
+ oneway void shutdown ();
+ };
+
+ /// A very simple interface
+ interface NsShutdown
+ {
+ oneway void shutdown ();
+ };
+};
diff --git a/TAO/orbsvcs/tests/FT_Naming/Federation/client.cpp b/TAO/orbsvcs/tests/FT_Naming/Federation/client.cpp
new file mode 100644
index 00000000000..0fa3468806d
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Federation/client.cpp
@@ -0,0 +1,78 @@
+// $Id$
+
+#include "TestC.h"
+#include "orbsvcs/CosNamingC.h"
+#include "ace/Get_Opt.h"
+
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
+
+ CORBA::Object_var tmp =
+ orb->string_to_object (
+ ACE_TEXT_ALWAYS_CHAR ("corbaloc:iiop:1.2@localhost:9931/NameService"));
+
+ CosNaming::NamingContext_var root =
+ CosNaming::NamingContext::_narrow (tmp.in ());
+
+ if (CORBA::is_nil (root.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ ACE_TEXT ("Nil NamingService reference\n")),
+ 1);
+ }
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("**** Narrowed root NamingContext\n")));
+
+ CosNaming::Name name;
+ name.length(3);
+ name[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("nsB"));
+ name[1].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("example"));
+ name[2].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("Hello"));
+
+ try
+ {
+ tmp = root->resolve (name);
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("**** Resolved #nsB/example/Hello\n")));
+
+ Test::Hello_var hello =
+ Test::Hello::_narrow (tmp.in ());
+
+ if (CORBA::is_nil (hello.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ ACE_TEXT ("Nil Test::Hello reference\n")),
+ 1);
+ }
+
+ CORBA::String_var the_string = hello->get_string ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - string returned <%C>\n"),
+ the_string.in ()));
+
+ hello->shutdown ();
+ }
+ catch (const CosNaming::NamingContext::CannotProceed&)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Caught correct exception\n")));
+ }
+
+ orb->shutdown ();
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("Exception caught:"));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/Federation/run_test.pl b/TAO/orbsvcs/tests/FT_Naming/Federation/run_test.pl
new file mode 100755
index 00000000000..b67cb26aa9a
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Federation/run_test.pl
@@ -0,0 +1,268 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# This is a Perl script that runs a Naming Service test. It starts
+# all the servers and clients as necessary.
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+use Cwd;
+
+#$ENV{ACE_TEST_VERBOSE} = "1";
+
+$status = 0;
+$debug_level = '0';
+$quiet = 0;
+
+if ($ARGV[0] eq '-q') {
+ $quiet = 1;
+}
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $debug_level = '10';
+ }
+}
+
+sub clean_persistence_dir($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ chdir $directory_name;
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $target->DeleteFile ($tmp);
+ }
+ chdir "..";
+}
+
+# Make sure that the directory to use to hold the naming contexts exists
+# and is cleaned out
+sub init_naming_context_directory($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ if ( ! -d $directory_name ) {
+ mkdir ($directory_name, 0777);
+ } else {
+ clean_persistence_dir ($target, $directory_name);
+ }
+}
+
+
+# Variables for command-line arguments to client and server
+# executables.
+my $ns_orb_primary_port1 = 9931;
+my $ns_orb_primary_port2 = 9932;
+my $ns_orb_backup_port1 = 9933;
+my $ns_orb_backup_port2 = 9934;
+
+my $ns_primary_endpoint1 = "iiop://localhost:$ns_orb_primary_port1";
+my $ns_backup_endpoint1 = "iiop://localhost:$ns_orb_backup_port1";
+my $ns_primary_endpoint2 = "iiop://localhost:$ns_orb_primary_port2";
+my $ns_backup_endpoint2 = "iiop://localhost:$ns_orb_backup_port2";
+
+my $ns1_ior = "ns1.ior";
+my $ns2_ior = "ns2.ior";
+my $nm1_ior = "nm1.ior";
+my $nm2_ior = "nm2.ior";
+my $iorbase = "test.ior";
+
+my $ns1 = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $ns2 = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+my $server = PerlACE::TestTarget::create_target (3) || die "Create target 3 failed\n";
+my $client = PerlACE::TestTarget::create_target (4) || die "Create target 4 failed\n";
+
+my $server_iorfile = $server->LocalFile ($iorbase);
+my $ns1_iorfile = $ns1->LocalFile ($ns1_ior);
+my $ns2_iorfile = $ns2->LocalFile ($ns2_ior);
+my $nm1_iorfile = $ns1->LocalFile ($nm1_ior);
+my $nm2_iorfile = $ns2->LocalFile ($nm2_ior);
+
+$server->DeleteFile ($iorbase);
+$ns1->DeleteFile ($ns1_ior);
+$ns2->DeleteFile ($ns2_ior);
+
+$SV = $server->CreateProcess ("server", "-ORBdebuglevel $debug_level -o $server_iorfile");
+$CL = $client->CreateProcess ("client", "-ORBdebuglevel $debug_level");
+
+my $tao_ft_naming = "$ENV{TAO_ROOT}/orbsvcs/Naming_Service/tao_ft_naming";
+
+my $name_dir1 = "NameService1";
+my $name_dir2 = "NameService2";
+
+init_naming_context_directory ($ns1, $name_dir1);
+init_naming_context_directory ($ns2, $name_dir2);
+
+my $ns1_primary_args = "--primary -ORBListenEndPoints $ns_primary_endpoint1 ".
+ "-r $name_dir1";
+
+my $ns1_backup_args = "--backup -ORBListenEndPoints $ns_backup_endpoint1 ".
+ "-c $ns1_iorfile -g $nm1_iorfile ".
+ "-r $name_dir1";
+
+my $ns2_primary_args = "--primary -ORBListenEndPoints $ns_primary_endpoint2 ".
+ "-r $name_dir2";
+
+my $ns2_backup_args = "--backup -ORBListenEndPoints $ns_backup_endpoint2 ".
+ "-c $ns2_iorfile -g $nm2_iorfile ".
+ "-r $name_dir2";
+
+$NS1_PRIMARY = $ns1->CreateProcess($tao_ft_naming, $ns1_primary_args );
+$NS1_BACKUP = $ns1->CreateProcess($tao_ft_naming, $ns1_backup_args );
+
+$NS2_PRIMARY = $ns2->CreateProcess($tao_ft_naming, $ns2_primary_args );
+$NS2_BACKUP = $ns2->CreateProcess($tao_ft_naming, $ns2_backup_args );
+
+my $replica_primary_ior = "ns_replica_primary.ior";
+my $ns1_replica_primary_ior = "$name_dir1/$replica_primary_ior";
+my $ns2_replica_primary_ior = "$name_dir2/$replica_primary_ior";
+
+################################################################################
+# setup END block to cleanup after exit call
+################################################################################
+END
+{
+ $server->DeleteFile ($iorbase);
+
+ $ns1->DeleteFile ($ns1_ior);
+ $ns1->DeleteFile ($nm1_ior);
+
+ $ns2->DeleteFile ($ns2_ior);
+ $ns2->DeleteFile ($nm2_ior);
+
+ if ( -d $name_dir1 ) {
+ print STDERR "INFO: removing <$name_dir1>\n";
+ clean_persistence_dir ($ns1, $name_dir1);
+ rmdir $name_dir1;
+ }
+
+ if ( -d $name_dir2 ) {
+ print STDERR "INFO: removing <$name_dir2>\n";
+ clean_persistence_dir ($ns2, $name_dir2);
+ rmdir $name_dir2;
+ }
+}
+
+# Run two Naming Servers
+$process_status = $NS1_PRIMARY->Spawn ();
+
+if ($process_status != 0) {
+ print STDERR "ERROR: ns1 returned $process_status\n";
+ exit 1;
+}
+
+if ($ns1->WaitForFileTimed ($ns1_replica_primary_ior,
+ $ns1->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$name_dir1/ns_replica_primary.ior>\n";
+ $NS1_PRIMARY->Kill (); $NS1_PRIMARY->TimedWait (1);
+ exit 1;
+}
+
+$process_status = $NS1_BACKUP->Spawn ();
+
+if ($process_status != 0) {
+ print STDERR "ERROR: ns1 returned $process_status\n";
+ exit 1;
+}
+
+if ($ns1->WaitForFileTimed ($ns1_ior,
+ $ns1->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$ns1_ior>\n";
+ $NS1_BACKUP->Kill (); $NS1_BACKUP->TimedWait (1);
+ $NS1_PRIMARY->Kill (); $NS1_PRIMARY->TimedWait (1);
+ exit 1;
+}
+
+$process_status = $NS2_PRIMARY->Spawn ();
+
+if ($process_status != 0) {
+ print STDERR "ERROR: ns2 returned $process_status\n";
+ $NS1_BACKUP->Kill (); $NS1_BACKUP->TimedWait (1);
+ $NS1_PRIMARY->Kill (); $NS1_PRIMARY->TimedWait (1);
+ exit 1;
+}
+
+if ($ns2->WaitForFileTimed ($ns2_replica_primary_ior,
+ $ns2->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$name_dir2/ns_replica_primary.ior>\n";
+ $NS1_BACKUP->Kill (); $NS1_BACKUP->TimedWait (1);
+ $NS1_PRIMARY->Kill (); $NS1_PRIMARY->TimedWait (1);
+ exit 1;
+}
+
+$process_status = $NS2_BACKUP->Spawn ();
+if ($process_status != 0) {
+ print STDERR "ERROR: ns2 returned $process_status\n";
+ $NS2_PRIMARY->Kill (); $NS2_PRIMARY->TimedWait (1);
+ $NS1_BACKUP->Kill (); $NS1_BACKUP->TimedWait (1);
+ $NS1_PRIMARY->Kill (); $NS1_PRIMARY->TimedWait (1);
+ exit 1;
+}
+
+if ($ns2->WaitForFileTimed ($ns2_ior,
+ $ns2->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$ns2_iorfile>\n";
+ $NS2_BACKUP->Kill (); $NS2_BACKUP->TimedWait (1);
+ $NS2_PRIMARY->Kill (); $NS2_PRIMARY->TimedWait (1);
+ $NS1_BACKUP->Kill (); $NS1_BACKUP->TimedWait (1);
+ $NS1_PRIMARY->Kill (); $NS1_PRIMARY->TimedWait (1);
+ exit 1;
+}
+
+$process_status = $SV->Spawn ();
+
+if ($process_status != 0) {
+ print STDERR "ERROR: server returned $process_status\n";
+ $NS2_BACKUP->Kill (); $NS2_BACKUP->TimedWait (1);
+ $NS2_PRIMARY->Kill (); $NS2_PRIMARY->TimedWait (1);
+ $NS1_BACKUP->Kill (); $NS1_BACKUP->TimedWait (1);
+ $NS1_PRIMARY->Kill (); $NS1_PRIMARY->TimedWait (1);
+ exit 1;
+}
+
+if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $NS2_BACKUP->Kill (); $NS2_BACKUP->TimedWait (1);
+ $NS2_PRIMARY->Kill (); $NS2_PRIMARY->TimedWait (1);
+ $NS1_BACKUP->Kill (); $NS1_BACKUP->TimedWait (1);
+ $NS1_PRIMARY->Kill (); $NS1_PRIMARY->TimedWait (1);
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+print STDERR "Starting client\n";
+$process_status = $CL->SpawnWaitKill (15);
+
+if ($process_status != 0) {
+ print STDERR "ERROR: client returned $process_status\n";
+ $status = 1;
+}
+
+$process_status = $SV->TerminateWaitKill ($server->ProcessStopWaitInterval());
+if ($process_status != 0) {
+ print STDERR "ERROR: server returned $process_status\n";
+ $status = 1;
+}
+
+$process_status = $CL->TerminateWaitKill ($client->ProcessStopWaitInterval());
+
+if ($process_status != 0) {
+ print STDERR "ERROR: client returned $process_status\n";
+ $status = 1;
+}
+
+$NS2_BACKUP->Kill (); $NS2_BACKUP->TimedWait (1);
+$NS2_PRIMARY->Kill (); $NS2_PRIMARY->TimedWait (1);
+$NS1_BACKUP->Kill (); $NS1_BACKUP->TimedWait (1);
+$NS1_PRIMARY->Kill (); $NS1_PRIMARY->TimedWait (1);
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/FT_Naming/Federation/server.cpp b/TAO/orbsvcs/tests/FT_Naming/Federation/server.cpp
new file mode 100644
index 00000000000..a1bee3a289b
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Federation/server.cpp
@@ -0,0 +1,176 @@
+// $Id$
+
+#include "Hello.h"
+#include "orbsvcs/CosNamingC.h"
+#include "ace/Get_Opt.h"
+#include "ace/Task.h"
+
+const ACE_TCHAR *ior_output_file = ACE_TEXT ("test.ior");
+
+class TestTask : public ACE_Task_Base
+{
+public:
+ TestTask (int argc, ACE_TCHAR **argv);
+ virtual int svc ();
+
+ int parse_args (int argc, ACE_TCHAR **argv);
+
+ void end();
+private:
+ CORBA::ORB_var orb_;
+ CORBA::Boolean shutdown_ns_;
+};
+
+TestTask::TestTask(int argc, ACE_TCHAR **argv)
+{
+ orb_ = CORBA::ORB_init (argc, argv, ACE_TEXT_ALWAYS_CHAR ("ServerORB"));
+ shutdown_ns_ = false;
+ parse_args (argc, argv);
+}
+
+void TestTask::end()
+{
+ orb_->shutdown(0);
+ this->wait();
+}
+
+int
+TestTask::parse_args (int argc, ACE_TCHAR **argv)
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("o:s"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 's':
+ shutdown_ns_ = true;
+ break;
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int TestTask::svc()
+{
+
+ try {
+ // Get reference to Root POA
+ CORBA::Object_var obj = orb_->resolve_initial_references (
+ ACE_TEXT_ALWAYS_CHAR ("RootPOA"));
+
+ PortableServer::POA_var poa = PortableServer::POA::_narrow (obj.in ());
+
+ // Activate POA Manager
+ PortableServer::POAManager_var mgr = poa->the_POAManager ();
+ mgr->activate ();
+
+ // Find the Naming Service
+ obj = orb_->string_to_object (
+ ACE_TEXT_ALWAYS_CHAR ("corbaloc:iiop:1.2@localhost:9932/NameService"));
+
+ CosNaming::NamingContext_var rootB =
+ CosNaming::NamingContext::_narrow (obj.in ());
+
+ if (CORBA::is_nil (rootB.in ())) {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Error, Nil Naming Context reference\n")));
+ return 1;
+ }
+ // Bind the example Naming Context, if necessary
+ CosNaming::NamingContext_var example_nc;
+ CosNaming::Name name;
+ name.length(1);
+ name[0].id = CORBA::string_dup( ACE_TEXT_ALWAYS_CHAR ("example"));
+ try
+ {
+ obj = rootB->resolve (name);
+ example_nc =
+ CosNaming::NamingContext::_narrow (obj.in ());
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ example_nc = rootB->bind_new_context (name);
+ }
+
+ // Bind the Test object
+ name.length (2);
+ name[1].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("Hello"));
+
+ // Create an object
+ Hello servant (orb_.in ());
+ PortableServer::ObjectId_var oid = poa->activate_object (&servant);
+ obj = poa->id_to_reference (oid.in ());
+ rootB->rebind (name, obj.in ());
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Hello object bound in Naming Service B\n")));
+
+ name.length (1);
+ name[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR ("nsB"));
+
+ obj = orb_->string_to_object (
+ ACE_TEXT_ALWAYS_CHAR ("corbaloc:iiop:1.2@localhost:9931/NameService"));
+
+ CosNaming::NamingContext_var rootA =
+ CosNaming::NamingContext::_narrow (obj.in ());
+
+ rootA->bind_context (name, rootB.in ());
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Root context of NS B bound in Naming Service A ")
+ ACE_TEXT ("under name 'nsB'\n")));
+
+ CORBA::String_var ior =
+ orb_->object_to_string (obj.in ());
+
+ // Output the IOR to the <ior_output_file>
+ FILE *output_file= ACE_OS::fopen (ior_output_file, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Cannot open output file %s for writing ")
+ ACE_TEXT ("IOR: %C\n"),
+ ior_output_file,
+ ior.in ()),
+ 1);
+ ACE_OS::fprintf (output_file, ACE_TEXT ("%s"), ior.in ());
+ ACE_OS::fclose (output_file);
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Wrote IOR file\n")));
+
+ // Normally we run the orb and the orb is shutdown by
+ // calling TestTask::end().
+ // Accept requests
+ orb_->run();
+ orb_->destroy();
+
+ return 0;
+ }
+ catch (CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("CORBA exception: "));
+ }
+
+ return -1;
+}
+
+int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ // Start the Test task
+ TestTask test_ (argc, argv);
+ if (test_.activate() == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to start test task.\n")),
+ -1);
+ }
+
+ // Wait the tasks to finish.
+ test_.thr_mgr ()->wait();
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp
new file mode 100644
index 00000000000..f39b658f78e
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Basic.cpp
@@ -0,0 +1,61 @@
+// $Id$
+
+#include "Basic.h"
+#include "LB_server.h"
+#include "orbsvcs/PortableGroup/PG_Property_Set.h"
+
+Basic::Basic (CORBA::Object_ptr object_group,
+ FT_Naming::NamingManager_ptr lm,
+ CORBA::ORB_ptr orb,
+ const char *loc)
+ : object_group_name_ ("Basic Group"), orb_ (CORBA::ORB::_duplicate (orb))
+{
+ this->object_group_ = CORBA::Object::_duplicate (object_group);
+ this->nm_ = FT_Naming::NamingManager::_duplicate (lm);
+ this->location_ = CORBA::string_dup (loc);
+}
+
+char *
+Basic::get_string (void)
+{
+ return CORBA::string_dup (this->location_.in ());
+}
+
+void
+Basic::remove_member (void)
+{
+ try
+ {
+ PortableGroup::Location location (1);
+ location.length (1);
+ location[0].id = CORBA::string_dup (this->location_.in ());
+ this->nm_->remove_member (this->object_group_.in (),
+ location);
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) - Removed Member at Location <%s>\n",
+ this->location_.in ()));
+
+ }
+ catch (const PortableGroup::ObjectNotFound& ex)
+ {
+ ex._tao_print_exception ("Caught exception in remove_member");
+ throw CORBA::INTERNAL ();
+ }
+ catch (const PortableGroup::MemberNotFound& ex)
+ {
+ ex._tao_print_exception ("Caught exception in remove_member");
+ throw CORBA::INTERNAL ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught while destroying member\n");
+ }
+
+}
+
+
+void
+Basic::shutdown (void)
+{
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h
new file mode 100644
index 00000000000..37aec36f681
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Basic.h
@@ -0,0 +1,59 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#ifndef BASIC_H
+#define BASIC_H
+
+#include "TestS.h"
+#include "orbsvcs/FT_NamingManagerC.h"
+#include "orbsvcs/PortableGroupC.h"
+
+#if defined (_MSC_VER)
+# pragma warning(push)
+# pragma warning (disable:4250)
+#endif /* _MSC_VER */
+
+class LB_Basic_Test;
+
+/// Implement the Test::Basic interface
+class Basic
+ : public virtual POA_Test::Basic
+{
+public:
+ /// Constructor
+ Basic (CORBA::Object_ptr object_group,
+ FT_Naming::NamingManager_ptr lm,
+ CORBA::ORB_ptr orb,
+ const char *loc);
+
+ virtual char * get_string (void);
+
+ virtual void shutdown (void);
+
+ virtual void remove_member (void);
+
+private:
+
+ const char* object_group_name_;
+
+ /// Use an ORB reference to convert strings to objects and shutdown
+ /// the application.
+ CORBA::ORB_var orb_;
+
+ /// Load Manager Reference used to delete the servant reference from the
+ /// object group.
+ FT_Naming::NamingManager_var nm_;
+
+ /// location of the servant
+ CORBA::String_var location_;
+
+ /// Object Group reference.
+ CORBA::Object_var object_group_;
+};
+
+#if defined(_MSC_VER)
+# pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* BASIC_H */
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp
new file mode 100644
index 00000000000..3bcff5045b7
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.cpp
@@ -0,0 +1,222 @@
+// $Id$
+
+#include "LB_server.h"
+#include "Basic.h"
+
+#include "TestC.h"
+#include "ace/OS_NS_stdio.h"
+
+LB_server::LB_server (int argc, ACE_TCHAR **argv)
+ : argc_ (argc)
+ , argv_ (argv)
+ , ior_output_file_(ACE_TEXT("obj.ior"))
+{
+}
+
+int
+LB_server::destroy (void)
+{
+ try
+ {
+ this->naming_manager_->delete_object_group ("Basic Group");
+ this->orb_->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception caught while destroying LB_server\n"));
+ return -1;
+ }
+ return 0;
+
+}
+
+CORBA::ORB_ptr
+LB_server::orb (void)
+{
+ return this->orb_.in ();
+}
+
+CORBA::Object_ptr
+LB_server::object_group (void)
+{
+ return this->object_group_.in ();
+}
+
+FT_Naming::NamingManager_ptr
+LB_server::naming_manager (void)
+{
+ return this->naming_manager_.in ();
+}
+
+int
+LB_server::write_ior_to_file (const char *ior)
+{
+ FILE *output_file =
+ ACE_OS::fopen (this->ior_output_file_, "w");
+
+ if (output_file == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Cannot open output file for writing IOR:")));
+ return -1;
+ }
+
+ ACE_OS::fprintf (output_file, "%s", ior);
+ ACE_OS::fclose (output_file);
+ return 0;
+}
+
+int
+LB_server::parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ this->ior_output_file_ = get_opts.opt_arg ();
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("usage: %s ")
+ ACE_TEXT ("-o <iorfile>")
+ ACE_TEXT ("\n"),
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+LB_server::start_orb_and_poa (void)
+{
+ try
+ {
+ // Initialise the ORB.
+ this->orb_ = CORBA::ORB_init (this->argc_, this->argv_);
+
+ CORBA::Object_var poa_object =
+ this->orb_->resolve_initial_references("RootPOA");
+
+ if (CORBA::is_nil (poa_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")),
+ -1);
+
+ this->root_poa_ = PortableServer::POA::_narrow (poa_object.in ());
+
+ PortableServer::POAManager_var poa_manager =
+ this->root_poa_->the_POAManager ();
+
+ poa_manager->activate ();
+
+ ACE_Time_Value timeout (10); // Wait up to 10 seconds for the naming service
+ if (name_svc_.init (this->orb_, &timeout) != 0)
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ ACE_TEXT ("LB_server: Could not connect to naming ")
+ ACE_TEXT ("service.\n")),
+ -1);
+
+ CORBA::Object_var obj =
+ this->orb_->resolve_initial_references ("NamingManager");
+
+ this->naming_manager_ =
+ FT_Naming::NamingManager::_narrow (obj.in ());
+
+ if (CORBA::is_nil (this->naming_manager_.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" (%P|%t) Unable to get Naming ")
+ ACE_TEXT ("Manager Reference\n")),
+ -1);
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception raised initialising ORB or POA"));
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int
+LB_server::create_object_group (void)
+{
+ try
+ {
+ if (this->parse_args (argc_, argv_) != 0)
+ return -1;
+
+ PortableGroup::Criteria criteria (2);
+ criteria.length (1);
+
+ PortableGroup::Property &mem_style = criteria[0];
+ mem_style.nam.length (1);
+
+ // Set the membership style property
+ mem_style.nam[0].id =
+ CORBA::string_dup (ACE_TEXT ("org.omg.PortableGroup.MembershipStyle"));
+ PortableGroup::MembershipStyleValue msv =
+ PortableGroup::MEMB_APP_CTRL;
+ mem_style.val <<= msv;
+
+ this->object_group_ = this->naming_manager_->create_object_group (
+ ACE_TEXT ("Basic Group"),
+ FT_Naming::ROUND_ROBIN,
+ criteria);
+
+ CORBA::String_var ior =
+ this->orb_->object_to_string (this->object_group_.in ());
+
+ this->write_ior_to_file (ior.in ());
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception raised while creating object group"));
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int
+LB_server::register_servant (Basic *servant, const char *loc)
+{
+ try
+ {
+ Test::Basic_var basic =
+ servant->_this ();
+
+ PortableGroup::Location location (1);
+ location.length (1);
+
+ location[0].id = CORBA::string_dup (loc);
+
+ this->naming_manager_->add_member (this->object_group_.in (),
+ location,
+ basic.in ());
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception raised while registering servant"));
+ return -1;
+ }
+
+ return 0;
+}
+
+TAO_Naming_Client&
+LB_server::name_svc ()
+{
+ return name_svc_;
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.h b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.h
new file mode 100644
index 00000000000..d6df78c52f8
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/LB_server.h
@@ -0,0 +1,98 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file LB_server.h
+ *
+ * $Id$
+ *
+ * @author Jaiganesh Balasubramanian <jai@doc.ece.uci.edu>
+ * @author Ossama Othman <ossama@uci.edu>
+ */
+//=============================================================================
+
+
+#include "orbsvcs/FT_NamingManagerC.h"
+#include "orbsvcs/PortableGroupC.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "ace/Get_Opt.h"
+#include "orbsvcs/Naming/Naming_Client.h"
+
+// Forward Declaration of the kind of servant we would like to handle
+// by the server.
+class Basic;
+
+/**
+ * @class LB_server
+ *
+ * @brief Encapsulate the test in class.
+ *
+ * TODO: Fix description
+ * This is a class used to retrieve the NamingManager reference and
+ * create the Object Group. Servants add themselves to the object
+ * group and the object group reference is published to the clients.
+ * Clients then invoke the "servant operations" on the NamingManager
+ * itself. At this point the Load Balancing cycle starts.
+ */
+class LB_server
+{
+public:
+
+ /// Constructor
+ LB_server (int argc, ACE_TCHAR **argv);
+
+ /// destroys NamingManager, ORB and POA.
+ int destroy (void);
+
+ /// start the ORB.
+ int start_orb_and_poa (void);
+
+ /// Get the NamingManager Interface.
+ int init (int argc, ACE_TCHAR **argv);
+
+ /// Create the Object Group using the Load Manager Reference.
+ int create_object_group (void);
+
+ /// register the servants with the object group.
+ int register_servant (Basic *servant, const char *loc);
+
+ /// obtain the name service facade
+ TAO_Naming_Client& name_svc ();
+
+ /// for servants to register to the initialised ORB.
+ CORBA::ORB_ptr orb (void);
+
+ /// for servants to get the reference for object_group.
+ CORBA::Object_ptr object_group (void);
+
+ /// for servants to get the reference for object_group.
+ FT_Naming::NamingManager_ptr naming_manager (void);
+
+private:
+
+ int parse_args (int, ACE_TCHAR **);
+
+private:
+
+ /// Load Manager
+ FT_Naming::NamingManager_var naming_manager_;
+
+ /// Object Group.
+ CORBA::Object_var object_group_;
+
+ /// factory id for the object group.
+ PortableGroup::GenericFactory::FactoryCreationId_var fcid_;
+
+ /// Used to force the creation of the object group only once.
+ static int called_once_;
+
+ /// write the IOR to a file so that it can be read later.
+ int write_ior_to_file (const char *);
+
+ CORBA::ORB_var orb_;
+ int argc_;
+ ACE_TCHAR **argv_;
+ PortableServer::POA_var root_poa_;
+ const ACE_TCHAR *ior_output_file_;
+ TAO_Naming_Client name_svc_;
+};
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Load_Balancing_Name_Service.mpc b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Load_Balancing_Name_Service.mpc
new file mode 100644
index 00000000000..0c1338cb2fd
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Load_Balancing_Name_Service.mpc
@@ -0,0 +1,34 @@
+// -*- MPC -*-
+// $Id$
+
+project(*idl): taoidldefaults {
+ IDL_Files {
+ Test.idl
+ }
+ custom_only = 1
+}
+
+project(*server): ftnaming {
+ after += *idl
+ exename = server
+ Source_Files {
+ TestC.cpp
+ TestS.cpp
+ server.cpp
+ LB_server.cpp
+ Basic.cpp
+ }
+ IDL_Files {
+ }
+}
+
+project(*client): ftnaming {
+ after += *idl
+ exename = client
+ Source_Files {
+ TestC.cpp
+ client.cpp
+ }
+ IDL_Files {
+ }
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/README b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/README
new file mode 100644
index 00000000000..44197dfb409
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/README
@@ -0,0 +1,8 @@
+$Id$
+
+This program tests the application controlled membership support
+of the FT_Naming_Service. The aim is to allow the application
+to create object groups and add them to the naming service. When
+the client resolves an object group from the naming service, the
+load balancing strategy is applied. Currently the test only supports
+the RoundRobin load balancing strategy.
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Test.idl b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Test.idl
new file mode 100644
index 00000000000..21d10f6644c
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/Test.idl
@@ -0,0 +1,27 @@
+//
+// $Id$
+
+#include "orbsvcs/FT_NamingManager.idl"
+
+/// Put the interfaces in a module, to avoid global namespace pollution
+module Test
+{
+ typedef FT_Naming::LoadBalancingStrategyValue LoadBalancingStrategyValue;
+
+ /// A very simple interface
+ interface Basic
+ {
+ /// Return a simple string
+ string get_string ();
+
+ /// A method to shutdown the ORB
+ /**
+ * This method is used to simplify the test shutdown process
+ */
+ oneway void shutdown ();
+
+ /// A method to remove the servant from the NamingManager Object Group.
+ oneway void remove_member ();
+ };
+};
+
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp
new file mode 100644
index 00000000000..17a8b7ad7d6
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/client.cpp
@@ -0,0 +1,160 @@
+// $Id$
+
+#include "TestC.h"
+#include "ace/Get_Opt.h"
+#include "orbsvcs/Naming/Naming_Client.h"
+#include "ace/Time_Value.h"
+
+const ACE_TCHAR *ior = ACE_TEXT("file://obj.ior");
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'k':
+ ior = get_opts.opt_arg ();
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("usage: %s ")
+ ACE_TEXT ("-k <ior> ")
+ ACE_TEXT ("\n"),
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - Acquiring Name Service\n")));
+
+ TAO_Naming_Client name_svc;
+ try {
+
+ ACE_Time_Value timeout (10); // Wait up to 10 seconds for the naming service
+ if (name_svc.init (orb.in (), &timeout) != 0)
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ ACE_TEXT ("client: Could not connect to ")
+ ACE_TEXT ("naming service.\n")),
+ 1);
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception caught while initializing name ")
+ ACE_TEXT ("service facade:"));
+ return 1;
+ }
+
+ CosNaming::Name name (1);
+ name.length (1);
+ name[0].id = CORBA::string_dup ("basic_name");
+
+ CORBA::Object_var tmp;
+ Test::Basic_var basic;
+
+ // Iterate enough so we get a few wraparrounds
+ for (int i = 0; i < 15; i++)
+ {
+ try {
+
+ // Each time we invoke resolve, we get a different member
+ tmp =
+ name_svc->resolve (name);
+
+ // Narrow it to a Basic object
+ basic =
+ Test::Basic::_narrow (tmp.in ());
+
+ }
+ catch (CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("Error resolving name.\n"));
+ }
+
+ if (CORBA::is_nil (basic.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ ACE_TEXT ("Server obj ref not obtained ")
+ ACE_TEXT ("from Load Balancing Name Service\n"),
+ ior),
+ 1);
+ }
+
+ try {
+ CORBA::String_var the_string =
+ basic->get_string ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - Client request handled ")
+ ACE_TEXT ("by object at <%s>\n"),
+ the_string.in ()));
+
+ }
+ catch (CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Error invoking get_string on Basic object.\n"));
+ return 1;
+ }
+
+ // Remove one member after we wrapped around to make sure naming manager can
+ // handle it successufully
+ if (i == 7)
+ {
+ try {
+ // Try removing a member
+ basic->remove_member ();
+ }
+ catch (CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Error invoking get_string on Basic object.\n"));
+ return 1;
+ }
+ }
+ }
+
+ try {
+
+ basic->shutdown ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) - Shutting down server\n")));
+ }
+ catch (CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Error invoking get_string on Basic object.\n"));
+ return 1;
+ }
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Exception caught in client.cpp:"));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl
new file mode 100755
index 00000000000..729d20d38aa
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/run_test.pl
@@ -0,0 +1,229 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+# This is a Perl script that runs a Naming Service test. It starts
+# all the servers and clients as necessary.
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+use Cwd;
+
+$status = 0;
+$debug_level = '0';
+$startdir = getcwd();
+
+my $test = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $server2 = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+my $client = PerlACE::TestTarget::create_target (3) || die "Create target 3 failed\n";
+
+
+# Variables for command-line arguments to naming service executables.
+$hostname = $test->HostName ();
+
+$ns_orb_port1 = 10001 + $test->RandomPort ();
+$ns_orb_port2 = 10002 + $test->RandomPort ();
+$ns_endpoint1 = "iiop://$hostname:$ns_orb_port1";
+$ns_endpoint2 = "iiop://$hostname:$ns_orb_port2";
+
+$naming_persistence_dir = "NameService";
+$groups_persistence_dir = "Groups";
+
+$primary_iorfile = "$naming_persistence_dir/ns_replica_primary.ior";
+$combined_ns_iorfile = "combined_ns.ior";
+$combined_nm_iorfile = "combined_nm.ior";
+
+my $test_combined_ns_iorfile = $test->LocalFile ($combined_ns_iorfile);
+my $test_combined_nm_iorfile = $test->LocalFile ($combined_nm_iorfile);
+my $test_primary_iorfile = $test->LocalFile ($primary_iorfile);
+
+my $server_obj_group_iorfile = "obj.ior";
+
+#Files used by the server2
+my $server2_nm_iorfile = $server2->LocalFile ($combined_nm_iorfile);
+$server2->DeleteFile($server2_nm_iorfile);
+my $server2_ns_iorfile = $server2->LocalFile ($combined_ns_iorfile);
+$server2->DeleteFile($server2_ns_iorfile);
+my $server2_obj_group_iorfile = $server2->LocalFile ($server_obj_group_iorfile);
+$server2->DeleteFile($server_obj_group_iorfile);
+
+#Files which used by client
+my $client_ns_iorfile = $client->LocalFile ($combined_ns_iorfile);
+$client->DeleteFile($client_ns_iorfile);
+
+$status = 0;
+
+print "INFO: Running the test in ", getcwd(), "\n";
+
+sub clean_persistence_dir($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ chdir $directory_name;
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $target->DeleteFile ($tmp);
+ }
+ chdir "..";
+}
+
+# Make sure that the directory to use to hold the persistence data
+# exists and is cleaned out.
+sub init_persistence_directory($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ if ( ! -d $directory_name ) {
+ mkdir ($directory_name, 0777);
+ } else {
+ clean_persistence_dir ($target, $directory_name);
+ }
+}
+
+
+my $args = "-ORBEndPoint $ns_endpoint1 " .
+ "-m 0 " .
+ "-r $naming_persistence_dir " .
+ "-v $groups_persistence_dir " .
+ "--primary";
+my $prog = "$startdir/../../../Naming_Service/tao_ft_naming";
+
+print STDERR "Starting Primary: $prog $args\n";
+
+$NS1 = $test->CreateProcess ("$prog", "$args");
+
+# Clean out the primary ior file to allow us to wait for it
+$test->DeleteFile ($primary_iorfile);
+
+init_persistence_directory ($test, $naming_persistence_dir);
+init_persistence_directory ($test, $groups_persistence_dir);
+
+$NS1->Spawn ();
+
+if ($test->WaitForFileTimed ($primary_iorfile,
+ $test->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$test_primary_iorfile>\n";
+ $NS1->Kill (); $NS1->TimedWait (1);
+ exit 1;
+}
+
+$args = "-ORBEndPoint $ns_endpoint2 " .
+ "-g $combined_nm_iorfile " .
+ "-c $combined_ns_iorfile " .
+ "-m 0 " .
+ "-r $naming_persistence_dir " .
+ "-v $groups_persistence_dir " .
+ "--backup";
+
+$prog = "$startdir/../../../Naming_Service/tao_ft_naming";
+
+print STDERR "Starting Backup: $prog $args\n";
+
+$NS2 = $test->CreateProcess ("$prog", "$args");
+
+# clean up the old generated ior files
+$test->DeleteFile ($combined_ns_iorfile);
+$test->DeleteFile ($combined_nm_iorfile);
+
+$NS2->Spawn ();
+
+if ($test->WaitForFileTimed ($combined_ns_iorfile,
+ $test->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$test_combined_ns_iorfile>\n";
+ $NS2->Kill (); $NS2->TimedWait (1);
+ exit 1;
+}
+
+$SV2 = $server2->CreateProcess ("server",
+ "-ORBdebuglevel $debug_level " .
+ "-ORBInitRef NameService=file://$server2_ns_iorfile " .
+ "-ORBInitRef NamingManager=file://$server2_nm_iorfile " .
+ "-o $server2_obj_group_iorfile");
+
+$CL = $client->CreateProcess ("client",
+ "-ORBInitRef NameService=file://$client_ns_iorfile");
+
+print STDERR "\n\n======== Running Application Controlled Membership Test================\n";
+print STDERR "\n";
+
+print STDERR "This test uses the RoundRobin Load Balancing strategy \n";
+
+print STDERR "6 servers are created and added into a Object Group\n";
+
+print STDERR "When the client accesses an object group through the naming service, the";
+print STDERR "FT_Naming_Service will apply the RoundRobin load balancing strategy\n";
+print STDERR "selects one of the servers and then the client makes an invocations on\n";
+print STDERR "the server. This is done 15 times to ensure we support the wraparround\n";
+print STDERR "condition. When done, the application has to delete the object from the\n";
+print STDERR "object group. This is called the application controlled membership of\n";
+print STDERR "object group.\n";
+print STDERR "\n";
+
+$server_status = $SV2->Spawn ();
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+}
+
+sub KillServers{
+ $SV1->Kill (); $SV1->TimedWait (1);
+ $SV2->Kill (); $SV2->TimedWait (1);
+}
+
+if ($server2->WaitForFileTimed ($server_obj_group_iorfile,
+ $server2->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server2_obj_group_iorfile>\n";
+ KillServers ();
+ exit 1;
+}
+
+if ($server2->GetFile ($server_obj_group_iorfile) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$server2_obj_group_iorfile>\n";
+ KillServers ();
+ exit 1;
+}
+
+if ($client->PutFile ($server_obj_group_iorfile) == -1) {
+ print STDERR "ERROR: cannot set file <$client_ns_iorfile>\n";
+ KillServers ();
+ exit 1;
+}
+
+$client_status = $CL->SpawnWaitKill ($client->ProcessStartWaitInterval() + 85);
+
+if ($client_status != 0) {
+ print STDERR "ERROR: client returned $client_status\n";
+ $status = 1;
+}
+
+$server_status = $SV2->WaitKill ($server2->ProcessStopWaitInterval());
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+}
+
+$server2->DeleteFile($nm_iorfile);
+$server2->DeleteFile($server_obj_group_iorfile);
+$client->DeleteFile($server_obj_group_iorfile);
+
+$NS1->Kill ();
+$NS2->Kill ();
+
+$test->DeleteFile ($primary_iorfile);
+$test->DeleteFile ($combined_ns_iorfile);
+
+clean_persistence_dir ($test, $naming_persistence_dir);
+clean_persistence_dir ($test, $groups_persistence_dir);
+rmdir ($naming_persistence_dir);
+rmdir ($groups_persistence_dir);
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/server.cpp b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/server.cpp
new file mode 100644
index 00000000000..258cddbe1de
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/server.cpp
@@ -0,0 +1,119 @@
+// $Id$
+
+#include "LB_server.h"
+#include "Basic.h"
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ const char *location1 = "MyLocation 1";
+ const char *location2 = "MyLocation 2";
+ const char *location3 = "MyLocation 3";
+ const char *location4 = "MyLocation 4";
+ const char *location5 = "MyLocation 5";
+ const char *location6 = "MyLocation 6";
+
+ LB_server lb_server (argc, argv);
+
+ if (lb_server.start_orb_and_poa () != 0)
+ return 1;
+
+ if (lb_server.create_object_group () != 0)
+ return 1;
+
+ CosNaming::Name name (1);
+ name.length (1);
+ name[0].id = CORBA::string_dup ("basic_name");
+ try {
+ (lb_server.name_svc ())->rebind (name, lb_server.object_group ());
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Unable to bind object group in name service.\n");
+ return 1;
+ }
+
+ Basic *basic_servant1;
+ Basic *basic_servant2;
+ Basic *basic_servant3;
+ Basic *basic_servant4;
+ Basic *basic_servant5;
+ Basic *basic_servant6;
+
+ ACE_NEW_RETURN (basic_servant1,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location1),
+ 1);
+ PortableServer::ServantBase_var owner_transfer1(basic_servant1);
+
+ ACE_NEW_RETURN (basic_servant2,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location2),
+ 1);
+ PortableServer::ServantBase_var owner_transfer2(basic_servant2);
+
+ ACE_NEW_RETURN (basic_servant3,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location3),
+ 1);
+ PortableServer::ServantBase_var owner_transfer3(basic_servant3);
+
+ ACE_NEW_RETURN (basic_servant4,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location4),
+ 1);
+ PortableServer::ServantBase_var owner_transfer4(basic_servant4);
+
+ ACE_NEW_RETURN (basic_servant5,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location5),
+ 1);
+ PortableServer::ServantBase_var owner_transfer5(basic_servant5);
+
+ ACE_NEW_RETURN (basic_servant6,
+ Basic (lb_server.object_group (),
+ lb_server.naming_manager (),
+ lb_server.orb (),
+ location6),
+ 1);
+ PortableServer::ServantBase_var owner_transfer6(basic_servant6);
+
+ if (lb_server.register_servant (basic_servant1, location1) == -1
+ || lb_server.register_servant (basic_servant2, location2) == -1
+ || lb_server.register_servant (basic_servant3, location3) == -1
+ || lb_server.register_servant (basic_servant4, location4) == -1
+ || lb_server.register_servant (basic_servant5, location5) == -1
+ || lb_server.register_servant (basic_servant6, location6) == -1)
+ {
+ (void) lb_server.destroy ();
+ return 1;
+ }
+
+ lb_server.orb ()->run ();
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop finished\n"));
+
+ if (lb_server.destroy () == -1)
+ return 1;
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("lb_server exception");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/svc.conf b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/svc.conf
new file mode 100644
index 00000000000..b6856698e51
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/svc.conf
@@ -0,0 +1,3 @@
+# $Id$
+
+static Resource_Factory "-ORBDropRepliesDuringShutdown 0"
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf
new file mode 100644
index 00000000000..e02d5089fce
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf
@@ -0,0 +1,3 @@
+# $Id$
+
+dynamic Advanced_Resource_Factory Service_Object* TAO_Strategies:_make_TAO_Advanced_Resource_Factory () "-ORBReactorType select_mt"
diff --git a/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf.xml b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf.xml
new file mode 100644
index 00000000000..37af1733d3b
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Load_Balancing/windows.conf.xml
@@ -0,0 +1,10 @@
+<?xml version='1.0'?>
+<!-- Converted from windows.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- -->
+ <!-- $Id$ -->
+ <!-- -->
+ <dynamic id="Advanced_Resource_Factory" type="Service_Object">
+ <initializer path="TAO_Strategies" init="_make_TAO_Advanced_Resource_Factory" params="-ORBReactorType select_mt"/>
+ </dynamic>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/FT_Naming/Replication/README b/TAO/orbsvcs/tests/FT_Naming/Replication/README
new file mode 100644
index 00000000000..12cc280c87f
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Replication/README
@@ -0,0 +1,54 @@
+$Id$
+
+This application tests the replication features of TAO's FT Naming Service.
+
+To run all tests automatically -
+ execute Perl script run_test.pl
+
+To run tests manually -
+ start the Naming Service (see
+ TAO/orbsvcs/Naming_Service/README for valid options),
+ then run ./client the optional options are shown below.
+
+NOTE: if running tests manually, the NameService directory must exist
+before starting the Naming Service and this directory must be cleaned out
+manually after stopping the Naming Service.
+
+The following options exist:
+---------------------------
+-b Breath of Context tree, default is 4, minimum is 2
+
+-d Depth of Context tree, default is 4, minimum is 2
+
+-o Breath of Object tree, default is 4, minimum is 2
+
+-p ior for Naming Server 1
+
+-q ior for Naming Server 2
+
+The client creates two context trees, one of breath b and one of depth d,
+and another node with o objects. It then removes the contexts b-1, d and
+the object o-1. All these are done using the first name server. The
+client then accesses contexts b, b-1, d, d-1, and objects o, o-1 looking
+for the appropriate found/not-found returns using the second name server.
+
+ Example (on a Unix system):
+ $ $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service -o nsior1\
+ -r NameService -ORBEndPoint iiop://localhost:10001 &
+ $ $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service -o nsior2\
+ -r NameService -ORBEndPoint iiop://localhost:10002 &
+ $ ./client -p file://nsior1 -q file://nsior2
+
+ where the steps correspond to 1&2)starting the Naming Service
+ in redundant mode, 3) running the client.
+ Don't forget to kill the name servers after you are done.
+
+
+
+EXPECTED OUTPUT FOR THIS TEST
+*****************************
+
+Redundancy test OK.
+
+
+
diff --git a/TAO/orbsvcs/tests/FT_Naming/Replication/Replication.mpc b/TAO/orbsvcs/tests/FT_Naming/Replication/Replication.mpc
new file mode 100644
index 00000000000..d4a8d42c12c
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Replication/Replication.mpc
@@ -0,0 +1,7 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Client) : ftnaming {
+ exename = client
+}
+
diff --git a/TAO/orbsvcs/tests/FT_Naming/Replication/client.cpp b/TAO/orbsvcs/tests/FT_Naming/Replication/client.cpp
new file mode 100644
index 00000000000..0c948882670
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Replication/client.cpp
@@ -0,0 +1,689 @@
+// $Id$
+
+// ============================================================================
+//
+// = DESCRIPTION
+// This class implements a CORBA client for a redundant CosNaming
+// Service using stubs generated by the TAO ORB IDL compiler.
+//
+// = AUTHORS
+// Rich Seibel <seibel_r@ociweb.com>
+// ============================================================================
+
+#include "test_objectS.h"
+#include "orbsvcs/CosNamingC.h"
+#include "orbsvcs/Naming/Naming_Server.h"
+#include "tao/debug.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/High_Res_Timer.h"
+
+#if defined (_MSC_VER)
+# pragma warning (disable : 4250)
+#endif /* _MSC_VER */
+
+class My_Test_Object :
+ public virtual POA_Test_Object
+{
+public:
+ // = Initialization and termination methods.
+ My_Test_Object (CORBA::Short id = 0);
+ // Constructor.
+
+ ~My_Test_Object (void);
+ // Destructor.
+
+ // = Interface implementation accessor methods.
+
+ void id (CORBA::Short id);
+ // Sets id.
+
+ CORBA::Short id (void);
+ // Gets id.
+
+private:
+ short id_;
+};
+
+My_Test_Object::My_Test_Object (CORBA::Short id)
+ : id_ (id)
+{
+}
+
+My_Test_Object::~My_Test_Object (void)
+{
+}
+
+CORBA::Short
+My_Test_Object::id (void)
+{
+ return id_;
+}
+
+void
+My_Test_Object::id (CORBA::Short id)
+{
+ id_ = id;
+}
+
+
+// This function runs the test.
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ int c_breadth = 4;
+ int c_depth = 4;
+ int o_breadth = 4;
+ ACE_TCHAR *ns1ref = 0;
+ ACE_TCHAR *ns2ref = 0;
+ int test_runs = 100;
+
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("b:d:o:p:q:t:"));
+ int c;
+ int i;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'b':
+ i = ACE_OS::atoi(get_opts.opt_arg ());
+ if (i<2)
+ {
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT ("Invalid breadth, must be 2 or more\n")));
+ ACE_OS::exit(1);
+ }
+ c_breadth = i;
+ break;
+ case 'd':
+ i = ACE_OS::atoi(get_opts.opt_arg ());
+ if (i<2)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Invalid depth, must be 2 or more\n")));
+ ACE_OS::exit (1);
+ }
+ c_depth = i;
+ break;
+ case 'o':
+ i = ACE_OS::atoi(get_opts.opt_arg ());
+ if (i<2)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Invalid breadth, must be 2 or more\n")));
+ ACE_OS::exit (1);
+ }
+ o_breadth = i;
+ break;
+ case 'p':
+ ns1ref = get_opts.opt_arg ();
+ break;
+ case 't':
+ i = ACE_OS::atoi (get_opts.opt_arg ());
+ if (i<1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Invalid number of test runs. ")
+ ACE_TEXT ("Must be 1 or more\n")));
+ ACE_OS::exit (1);
+ }
+ test_runs = i;
+ break;
+ case 'q':
+ ns2ref = get_opts.opt_arg ();
+ break;
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Argument %c \n usage: %s")
+ ACE_TEXT (" [-b <breadth of context tree>]")
+ ACE_TEXT (" [-d <depth of context tree>]")
+ ACE_TEXT (" [-o <breadth of object tree>]")
+ ACE_TEXT (" [-t <number of performance test runs>]")
+ ACE_TEXT (" -p <ior of first name server>")
+ ACE_TEXT (" -q <ior of second name server>")
+ ACE_TEXT ("\n")),
+ -1);
+ }
+
+ CosNaming::NamingContext_var root_context_1;
+ CosNaming::NamingContext_var root_context_2;
+
+ try
+ {
+ // Initialize orb
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
+
+ // ior's are specified for the name servers through a commandline
+ // option or a file.
+
+ // Resolve the first name server
+
+ CORBA::Object_var ns1obj = orb->string_to_object (
+ ACE_TEXT_ALWAYS_CHAR (ns1ref));
+
+ if (CORBA::is_nil (ns1obj.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("invalid ior <%s>\n"),
+ ns1ref),
+ -1);
+ root_context_1 = CosNaming::NamingContext::_narrow (ns1obj.in ());
+
+ // Resolve the second name server
+
+ CORBA::Object_var ns2obj = orb->string_to_object (
+ ACE_TEXT_ALWAYS_CHAR (ns2ref));
+
+ if (CORBA::is_nil (ns2obj.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("invalid ior <%s>\n"),
+ ns2ref),
+ -1);
+ root_context_2 = CosNaming::NamingContext::_narrow (ns2obj.in ());
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("Unable to resolve name servers"));
+ return -1;
+ }
+
+ // Create a bunch of objects in one context
+ // Note: strings to the naming service must be char, not wchar
+ try
+ {
+ // Bind one context level under root.
+ CosNaming::Name level1;
+ level1.length (1);
+ level1[0].id = CORBA::string_dup ("level1_context");
+ CosNaming::NamingContext_var level1_context;
+ level1_context = root_context_1->bind_new_context (level1);
+
+ for (i=0; i<o_breadth; i++)
+ {
+ // Instantiate a dummy object and bind it under the new context.
+ My_Test_Object *impl1 = new My_Test_Object (i+1);
+ Test_Object_var obj1 = impl1->_this ();
+ impl1->_remove_ref ();
+
+ level1.length (2);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", i);
+ level1[1].id = CORBA::string_dup (wide_name);
+ root_context_1->bind (level1, obj1.in ());
+
+ // See if the newly bound object is available in the
+ // replica
+ try {
+ CORBA::Object_var obj1_on_replica =
+ root_context_2->resolve (level1);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ ex._tao_print_exception ("Unable to resolve object from replica.\n");
+
+ // Try again...
+ try {
+ CORBA::Object_var obj1_on_replica =
+ root_context_2->resolve (level1);
+ // We did find the object on the replica, but only after a wait.
+ // This would be caused by a race condition to access the variable.
+ ACE_ERROR ((LM_ERROR,
+ "Object appeared after a short wait.\n"));
+ }
+ catch (const CosNaming::NamingContext::NotFound& second_ex)
+ {
+ second_ex._tao_print_exception ("It really is not there. Failing...\n");
+ return -1;
+ }
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("Unable to create a lot of objects"));
+ return -1;
+ }
+
+ // Create a deep context tree
+ try
+ {
+ CosNaming::NamingContext_var next_context = root_context_1;
+ for (i=0; i<c_depth; i++)
+ {
+ // Bind level1 context under root.
+ CosNaming::Name deep;
+ deep.length (1);
+ char deep_name[16];
+ ACE_OS::sprintf(deep_name, "deep_%d", i);
+ deep[0].id = CORBA::string_dup (deep_name);
+ CosNaming::NamingContext_var deep_context;
+ deep_context = next_context->bind_new_context (deep);
+ next_context = deep_context;
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("Unable to create deep context"));
+ return -1;
+ }
+
+ // Create a wide context tree
+ try
+ {
+ for (i=0; i<c_breadth; i++)
+ {
+ // Bind all level of context under root.
+ CosNaming::Name wide;
+ wide.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "wide_%d", i);
+ wide[0].id = CORBA::string_dup (wide_name);
+ CosNaming::NamingContext_var wide_context;
+ wide_context = root_context_1->bind_new_context (wide);
+
+ try {
+ // Check if the new context is available in the replica
+ CORBA::Object_var obj1_on_replica =
+ root_context_2->resolve (wide);
+ // Make sure it is a context
+ CosNaming::NamingContext_var nc =
+ CosNaming::NamingContext::_narrow (obj1_on_replica);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ ex._tao_print_exception ("Unable to resolve wide context object from replica.\n");
+
+ // Try again to see if it just was a race condition
+ try {
+ CORBA::Object_var obj1_on_replica =
+ root_context_2->resolve (wide);
+ // We did find the object on the replica, but only after a wait.
+ // This would be caused by a race condition to access the variable.
+ ACE_ERROR ((LM_ERROR,
+ "Object appeared after a short wait.\n"));
+ }
+ catch (const CosNaming::NamingContext::NotFound& second_ex)
+ {
+ second_ex._tao_print_exception ("It really is not there. Failing...\n");
+ return -1;
+ }
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("Unable to create wide context"));
+ return -1;
+ }
+
+ // Delete three selected things, one from each tree
+ try {
+ // Remove the second to last object from the Naming Context
+ CosNaming::Name wide1;
+ wide1.length (2);
+ wide1[0].id = CORBA::string_dup ("level1_context");
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", o_breadth-2);
+ wide1[1].id = CORBA::string_dup (wide_name);
+ root_context_1->unbind (wide1);
+
+ bool retried = false;
+ // Make sure it is gone from the replica
+ try {
+ CORBA::Object_var obj1_on_replica =
+ root_context_2->resolve (wide1);
+
+ // An exception should be thrown by the above or
+ // there is an error. This means the replica did
+ // not register the loss of the context.
+ ACE_ERROR ((LM_ERROR,
+ "Unbound deep context not removed from replica. Trying again...\n"));
+ retried = true; // Mark this so it can be reported in catch block.
+ obj1_on_replica =
+ root_context_2->resolve (wide1);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unbound context not removed from on retry\n"),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Not on replica --- as it should be.
+ if (retried) // Was found on the retry
+ ACE_ERROR ((LM_ERROR,
+ "Was removed after short wait.\n"));
+ }
+
+ // Remove the second to last context from the wide root Naming Context
+ CosNaming::Name wide2;
+ wide2.length (1);
+ ACE_OS::sprintf(wide_name, "wide_%d", c_breadth-2);
+ wide2[0].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (wide2);
+ CosNaming::NamingContext_var result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+ if (CORBA::is_nil (result_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problems with resolving wide context ")
+ ACE_TEXT ("- nil object ref.\n")),
+ -1);
+ result_object->destroy();
+ root_context_1->unbind (wide2);
+
+ // Remove the last context from the deep Naming Context
+ CosNaming::Name deep;
+ deep.length (c_depth);
+ char deep_name[16];
+ for (i=0; i<c_depth; i++)
+ {
+ ACE_OS::sprintf(deep_name, "deep_%d", i);
+ deep[i].id = CORBA::string_dup (deep_name);
+ }
+ result_obj_ref = root_context_1->resolve (deep);
+ result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+ if (CORBA::is_nil (result_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problems with resolving deep context ")
+ ACE_TEXT ("- nil object ref.\n")),
+ -1);
+ result_object->destroy();
+ root_context_1->unbind (deep);
+
+ retried = false;
+ // Make sure it is gone from the replica
+ try {
+ CORBA::Object_var obj1_on_replica =
+ root_context_2->resolve (deep);
+
+ // An exception should be thrown by the above or
+ // there is an error. This means the replica did
+ // not register the loss of the context.
+ ACE_ERROR ((LM_ERROR,
+ "Unbound deep context not removed from replica. Trying again...\n"));
+ retried = true; // Mark this so it can be reported in catch block.
+ obj1_on_replica =
+ root_context_2->resolve (deep);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unbound context not removed from on retry\n"),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Not on replica --- as it should be.
+ if (retried) // Was found on the retry
+ ACE_ERROR ((LM_ERROR,
+ "Was removed after short wait.\n"));
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("Unable to delete objects"));
+ return -1;
+ }
+
+ // Now use the other name server to access 3 objects next to the
+ // deleted objects and the 3 deleted objects
+ try
+ {
+ // Access the last object from the Naming Context
+ CosNaming::Name wide;
+ wide.length (2);
+ wide[0].id = CORBA::string_dup ("level1_context");
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", o_breadth-1);
+ wide[1].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
+ Test_Object_var result_object = Test_Object::_narrow (result_obj_ref.in ());
+ if (CORBA::is_nil (result_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problems with resolving object from ")
+ ACE_TEXT ("redundant server - nil object ref.\n")),
+ -1);
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT (
+ "Unable to resolve object from redundant server"));
+ return -1;
+ }
+
+ try
+ {
+ // Access the deleted second to last object from the Naming Context
+ CosNaming::Name wide;
+ wide.length (2);
+ wide[0].id = CORBA::string_dup ("level1_context");
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", o_breadth-2);
+ wide[1].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problems with resolving object from ")
+ ACE_TEXT ("redundant server - deleted object found.\n")),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::NotFound& ex)
+ {
+ // expect exception since the context was deleted.
+ // Make sure the right exception reason is provided.
+ if (ex.why != CosNaming::NamingContext::missing_node)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Wrong exception returned during resolve.\n")),
+ -1);
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("Wrong exception type returned from resolve.\n"));
+ return -1;
+ }
+ try
+ {
+ // Access the last context from the wide Naming Context
+ CosNaming::Name wide;
+ wide.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "wide_%d", c_breadth-1);
+ wide[0].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
+ CosNaming::NamingContext_var result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+ if (CORBA::is_nil (result_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problems with resolving wide context from ")
+ ACE_TEXT ("redundant server - nil object ref.\n")),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Expected exception
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Unexpected Exception received.\n"));
+ return -1;
+ }
+
+ try
+ {
+ // Access the deleted second to last object from the Naming Context
+ CosNaming::Name wide;
+ wide.length (2);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "wide_%d", c_breadth-2);
+ wide[0].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = root_context_2->resolve (wide);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problems with resolving wide context from ")
+ ACE_TEXT ("redundant server - deleted object found.\n")),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Expected exception
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Unexpected Exception received.\n"));
+ return -1;
+ }
+
+ try
+ {
+ // Access the deleted last context from the deep Naming Context
+ CosNaming::Name deep;
+ deep.length (c_depth);
+ char deep_name[16];
+ for (i=0; i<c_depth; i++)
+ {
+ ACE_OS::sprintf(deep_name, "deep_%d", i);
+ deep[i].id = CORBA::string_dup (deep_name);
+ }
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (deep);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problems with resolving deep context from ")
+ ACE_TEXT ("redundant server - deleted object found.\n")),
+ -1);
+ }
+ catch (const CosNaming::NamingContext::NotFound&)
+ {
+ // Expected exception
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT ("Unexpected Exception received resolving ")
+ ACE_TEXT ("deep cxt from redundant server.\n"));
+ return -1;
+ }
+
+ try
+ {
+ // Access the second to last object from the Naming Context
+ CosNaming::Name deep;
+ deep.length (c_depth-1);
+ char deep_name[16];
+ for (i=0; i<c_depth-1; i++)
+ {
+ ACE_OS::sprintf(deep_name, "deep_%d", i);
+ deep[i].id = CORBA::string_dup (deep_name);
+ }
+ CORBA::Object_var result_obj_ref = root_context_1->resolve (deep);
+ CosNaming::NamingContext_var result_object =
+ CosNaming::NamingContext::_narrow (result_obj_ref.in ());
+ if (CORBA::is_nil (result_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Problems with resolving deep context from ")
+ ACE_TEXT ("redundant server - nil object ref.\n")),
+ -1);
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ ACE_TEXT (
+ "Unable to resolve deep context from redundant server"));
+ return -1;
+ }
+
+ // TODO: Cleanup namespace
+
+
+ // TODO: Create object groups and bind them. Check the replica.
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Redundancy test OK.\n")
+ ACE_TEXT ("Starting performance tests.\n")));
+
+ // Test performance of binding a bunch of objects in one context
+ try
+ {
+ // Bind one context level under root.
+ CosNaming::Name level1;
+ level1.length (1);
+ level1[0].id = CORBA::string_dup ("perf_context");
+ CosNaming::NamingContext_var perf_context;
+ perf_context = root_context_1->bind_new_context (level1);
+
+ // Instantiate a dummy object and bind it under the new context.
+ My_Test_Object *impl1 = new My_Test_Object (i+1);
+ Test_Object_var obj1 = impl1->_this ();
+ impl1->_remove_ref ();
+
+ ACE_High_Res_Timer::global_scale_factor_type gsf =
+ ACE_High_Res_Timer::global_scale_factor ();
+
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+
+ // Test how long it takes to bind
+ for (i=0; i<test_runs; i++)
+ {
+ level1.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", i);
+ level1[0].id = CORBA::string_dup (wide_name);
+ perf_context->bind (level1, obj1.in ());
+ }
+
+ ACE_hrtime_t elapsed_time = ACE_OS::gethrtime () - start;
+ // convert to microseconds
+ ACE_UINT32 usecs = ACE_UINT32(elapsed_time / gsf);
+ double secs = usecs / 1000000.0;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Bound %i objects in %.2f secs\n",
+ test_runs, secs));
+
+ // Test how long it takes to resolve
+ start = ACE_OS::gethrtime ();
+ for (i=0; i<test_runs; i++)
+ {
+ level1.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", i);
+ level1[0].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = perf_context->resolve (level1);
+ }
+
+ elapsed_time = ACE_OS::gethrtime () - start;
+ // convert to microseconds
+ usecs = ACE_UINT32(elapsed_time / gsf);
+ secs = ((ACE_INT32) usecs) / 1000000.0;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Resolved %i objects in %.2f secs\n",
+ test_runs, secs));
+
+ // Test how long it takes to unbind
+ start = ACE_OS::gethrtime ();
+ for (i=0; i<test_runs; i++)
+ {
+ level1.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", i);
+ level1[0].id = CORBA::string_dup (wide_name);
+ perf_context->unbind (level1);
+ }
+
+ elapsed_time = ACE_OS::gethrtime () - start;
+ // convert to microseconds
+ usecs = ACE_UINT32(elapsed_time / gsf);
+ secs = ((ACE_INT32) usecs) / 1000000.0;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Unbound %i objects in %.2f secs\n",
+ test_runs, secs));
+
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("ERROR: Exception during performance test.\n"));
+ return -1;
+ }
+
+
+ return 0;
+
+}
diff --git a/TAO/orbsvcs/tests/FT_Naming/Replication/run_test.pl b/TAO/orbsvcs/tests/FT_Naming/Replication/run_test.pl
new file mode 100755
index 00000000000..3aa67068b69
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Replication/run_test.pl
@@ -0,0 +1,212 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+# This is a Perl script that runs a Naming Service test. It starts
+# all the servers and clients as necessary.
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+use Cwd;
+
+$startdir = getcwd();
+
+$quiet = 0;
+
+# check for -q flag
+if ($ARGV[0] eq '-q') {
+ $quiet = 1;
+}
+
+my $test = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+
+# Variables for command-line arguments to client and server
+# executables.
+$hostname = $test->HostName ();
+
+$ns_orb_port1 = 10001 + $test->RandomPort ();
+$ns_orb_port2 = 10002 + $test->RandomPort ();
+$ns_endpoint1 = "iiop://$hostname:$ns_orb_port1";
+$ns_endpoint2 = "iiop://$hostname:$ns_orb_port2";
+
+$naming_persistence_dir = "NameService";
+$groups_persistence_dir = "Groups";
+
+$primary_iorfile = "$naming_persistence_dir/ns_replica_primary.ior";
+$combined_ns_iorfile = "combined_ns.ior";
+$nm_iorfile = "nm.ior";
+
+print STDERR "$primary_iorfile\n";
+
+## Allow the user to determine where the persistent file will be located
+## just in case the current directory is not suitable for locking.
+## We can't change the name of the persistent file because that is not
+## sufficient to work around locking problems for Tru64 when the current
+## directory is NFS mounted from a system that does not properly support
+## locking.
+foreach my $possible ($ENV{TMPDIR}, $ENV{TEMP}, $ENV{TMP}) {
+ if (defined $possible && -d $possible) {
+ if (chdir($possible)) {
+ last;
+ }
+ }
+}
+
+my $test_combined_ns_iorfile = $test->LocalFile ($combined_ns_iorfile);
+my $test_nm_iorfile = $test->LocalFile ($nm_iorfile);
+my $test_primary_iorfile = $test->LocalFile ($primary_iorfile);
+
+$status = 0;
+
+sub clean_persistence_dir
+{
+ chdir $naming_persistence_dir;
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $test->DeleteFile ($tmp);
+ }
+ chdir "..";
+}
+
+print "INFO: Running the test in ", getcwd(), "\n";
+
+sub clean_persistence_dir($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ chdir $directory_name;
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $target->DeleteFile ($tmp);
+ }
+ chdir "..";
+}
+
+# Make sure that the directory to use to hold the persistence data
+# exists and is cleaned out.
+sub init_persistence_directory($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ if ( ! -d $directory_name ) {
+ mkdir ($directory_name, 0777);
+ } else {
+ clean_persistence_dir ($target, $directory_name);
+ }
+}
+
+
+# Run two Naming Servers and one client. Client uses iors
+# in files to find the individual copies of the Naming Servers.
+
+my $args = "-ORBEndPoint $ns_endpoint1 " .
+ "-m 0 " .
+ "-r $naming_persistence_dir " .
+ "-v $groups_persistence_dir " .
+ "-n 100 " .
+ "--primary";
+my $prog = "$startdir/../../../Naming_Service/tao_ft_naming";
+
+print STDERR "Starting Primary: $prog $args\n";
+
+$NS1 = $test->CreateProcess ("$prog", "$args");
+
+$test->DeleteFile ($primary_iorfile);
+
+init_persistence_directory ($test, $naming_persistence_dir);
+init_persistence_directory ($test, $groups_persistence_dir);
+
+$NS1->Spawn ();
+
+if ($test->WaitForFileTimed ($primary_iorfile,
+ $test->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$test_primary_iorfile>\n";
+ $NS1->Kill (); $NS1->TimedWait (1);
+ exit 1;
+}
+
+$args = "-ORBEndPoint $ns_endpoint2 " .
+ "-g $nm_iorfile " .
+ "-c $combined_ns_iorfile " .
+ "-m 0 " .
+ "-n 100 " .
+ "-r $naming_persistence_dir " .
+ "-v $groups_persistence_dir " .
+ "--backup";
+
+$prog = "$startdir/../../../Naming_Service/tao_ft_naming";
+
+print STDERR "Starting Backup: $prog $args\n";
+
+$NS2 = $test->CreateProcess ("$prog", "$args");
+
+$test->DeleteFile ($combined_ns_iorfile);
+$test->DeleteFile ($nm_iorfile);
+
+$NS2->Spawn ();
+
+if ($test->WaitForFileTimed ($combined_ns_iorfile,
+ $test->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$test_combined_ns_iorfile>\n";
+ $NS2->Kill (); $NS2->TimedWait (1);
+ exit 1;
+}
+
+# Use corbaloc to access each individual name service without
+# using the combined IOR.
+$args = "-p corbaloc:iiop:$hostname:$ns_orb_port1/NameService " .
+ "-q corbaloc:iiop:$hostname:$ns_orb_port2/NameService " .
+ "-b 4 " .
+ "-d 4 " .
+ "-t 100";
+$prog = "$startdir/client";
+
+print STDERR "Starting Client: $prog $args\n";
+
+$CL = $test->CreateProcess ("$prog", "$args");
+
+$client = $CL->SpawnWaitKill ($test->ProcessStartWaitInterval());
+
+if ($client != 0) {
+ print STDERR "ERROR: client returned $client\n";
+ $status = 1;
+}
+
+# Kill the first server and make sure the tree can be accessed
+# by the nslist
+print STDERR "Killing the primary naming service\n";
+$NS1->Kill ();
+
+print STDERR "Printing Naming Tree from combined Name Service pair.\n";
+
+$prog = "$startdir/../../../../utils/nslist/tao_nslist";
+$args = "--ns file://$combined_ns_iorfile";
+
+$NSL = $test->CreateProcess("$prog", "$args");
+
+
+$out = $NSL->SpawnWaitKill (60);
+
+# Now kill off the backup
+$NS2->Kill ();
+
+$test->DeleteFile ($primary_iorfile);
+$test->DeleteFile ($combined_ns_iorfile);
+
+# Clean out the persistence dir after the test completes
+clean_persistence_dir ($test, $naming_persistence_dir);
+clean_persistence_dir ($test, $groups_persistence_dir);
+
+rmdir ($naming_persistence_dir);
+rmdir ($groups_persistence_dir);
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/FT_Naming/Replication/test_object.idl b/TAO/orbsvcs/tests/FT_Naming/Replication/test_object.idl
new file mode 100644
index 00000000000..4737f6dc6c8
--- /dev/null
+++ b/TAO/orbsvcs/tests/FT_Naming/Replication/test_object.idl
@@ -0,0 +1,11 @@
+// $Id$
+
+interface Test_Object
+{
+ // = TITLE
+ // This is a simple interface that tests the Naming Service.
+
+ attribute short id;
+ // This provides an easy way to differentiate objects if each
+ // objects is served by a separate servant.
+};
diff --git a/TAO/orbsvcs/tests/ImplRepo/README b/TAO/orbsvcs/tests/ImplRepo/README
index d55a9c2f33d..91042fca6f3 100644
--- a/TAO/orbsvcs/tests/ImplRepo/README
+++ b/TAO/orbsvcs/tests/ImplRepo/README
@@ -9,10 +9,27 @@ nt_service_ir same as above but runs ImplRepo as an NT service.
nestea runs nestea client and server without ImplRepo.
nestea_ir same as above but uses ImplRepo.
both_ir combines airplane_ir and nestea_ir.
-persistent_ir same as airplane_ir, but using persistent ImplRepo.
-
-The nt_service_ir test will work only on Win32 platforms. For the test to
-run successfully, these conditions must be met:
+persistent_ir same as airplane_ir, but using persistent
+ "-x <file>" flag for the ImplRepo.
+persistent_ir_hash same as persistent_ir, but using "-p <file>" flag.
+persistent_ir_registry same as persistent_ir, but using "-r" flag
+ (windows registry flag).
+persistent_ir_shared same as persistent_ir, but using
+ "--directory <dir>" flag.
+persistent_ft runs a primary and backup ImR Locator, verifying
+ persistence works in different scenarios of
+ the primary or backup being shutdown. Must also
+ pass the "-replica" command to run_test.pl for
+ this test to run.
+failover runs a primary and backup ImR Locator, verifying
+ different scenarios of the primary or backup being
+ shutdown and clients, servers, activators, and
+ tao_imr activities being unaffected. Must also
+ pass the "-replica" command to run_test.pl for
+ this test to run.
+
+The nt_service_ir and persistent_ir_registry tests will work only on Win32
+platforms. For the test to run successfully, these conditions must be met:
-- The user must be logged in as administrator, or have administrative
priveleges (in order to register an NT service).
diff --git a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp
index bc61035a1b9..114f0be51cc 100755
--- a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp
+++ b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp
@@ -118,10 +118,6 @@ ACE_TMAIN(int argc, ACE_TCHAR *argv[])
}
CORBA::Object_var object = orb->resolve_initial_references ("RootPOA");
- PortableServer::POA_var rootPOA = PortableServer::POA::_narrow (object.in ());
-
- PortableServer::POAManager_var poa_manager = rootPOA->the_POAManager ();
- poa_manager->activate ();
object = orb->string_to_object(ior_input_file);
@@ -142,8 +138,6 @@ ACE_TMAIN(int argc, ACE_TCHAR *argv[])
task.wait ();
- // Destroy the POA, waiting until the destruction terminates
- rootPOA->destroy (1, 1);
orb->destroy ();
if (task.test_passed ())
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger.idl b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger.idl
new file mode 100644
index 00000000000..880e7790199
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger.idl
@@ -0,0 +1,18 @@
+// $Id$
+
+// messenger.idl
+
+interface Messenger
+{
+ boolean send_message ( in string user_name,
+ in string subject,
+ inout string message );
+
+ // After replying, abort process in
+ // delay_secs seconds.
+ void abort ( in short delay_secs );
+
+ // Perform a graceful shutdown.
+ oneway void shutdown ();
+};
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/MessengerClient.cpp b/TAO/orbsvcs/tests/ImplRepo/RestartServer/MessengerClient.cpp
new file mode 100644
index 00000000000..7cd8c1d5d08
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/MessengerClient.cpp
@@ -0,0 +1,82 @@
+// $Id$
+
+#include "MessengerC.h"
+#include <iostream>
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_unistd.h"
+
+const ACE_TCHAR *ior = ACE_TEXT("file://Messenger.ior");
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'k':
+ ior = get_opts.opt_arg ();
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-k <ior> "
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try {
+ // Initialize orb
+ CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ // Destringify ior
+ CORBA::Object_var obj = orb->string_to_object( ior );
+ if (CORBA::is_nil(obj.in())) {
+ std::cerr << "Nil Messenger reference" << std::endl;
+ return 1;
+ }
+
+ // Narrow
+ Messenger_var messenger = Messenger::_narrow( obj.in() );
+ if (CORBA::is_nil(messenger.in())) {
+ std::cerr << "Argument is not a Messenger reference" << std::endl;
+ return 1;
+ }
+
+ CORBA::String_var message = CORBA::string_dup( "Hello!" );
+
+ messenger->send_message( "TAO User", "Test 1", message.inout() );
+
+ // Force server to abort to verify it will be brought
+ // back up when send_message() is called.
+ messenger->abort(2);
+ ACE_OS::sleep(4);
+
+ ACE_DEBUG ((LM_INFO,
+ "(%P|%t) - Sending another message after abort of server\n"));
+
+ messenger->send_message( "TAO User", "Test 2", message.inout() );
+
+ std::cout << "messages were sent" << std::endl;
+ }
+ catch(const CORBA::Exception& ex) {
+ std::cerr << "Client main() Caught CORBA::Exception: " << ex << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/MessengerServer.cpp b/TAO/orbsvcs/tests/ImplRepo/RestartServer/MessengerServer.cpp
new file mode 100644
index 00000000000..370144b98d7
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/MessengerServer.cpp
@@ -0,0 +1,117 @@
+// $Id$
+
+// MessengerServer.cpp
+// This version uses the Implementation Repository.
+
+#include "Messenger_i.h"
+#include "Terminator.h"
+
+#include "tao/IORTable/IORTable.h"
+#include "tao/PortableServer/Root_POA.h"
+
+#include <iostream>
+
+PortableServer::POA_ptr
+createPOA(PortableServer::POA_ptr root_poa, const char* poa_name)
+{
+ PortableServer::LifespanPolicy_var life =
+ root_poa->create_lifespan_policy(PortableServer::PERSISTENT);
+
+ PortableServer::IdAssignmentPolicy_var assign =
+ root_poa->create_id_assignment_policy(PortableServer::USER_ID);
+
+ CORBA::PolicyList pols;
+ pols.length(2);
+ pols[0] = PortableServer::LifespanPolicy::_duplicate(life.in());
+ pols[1] = PortableServer::IdAssignmentPolicy::_duplicate(assign.in());
+
+ PortableServer::POAManager_var mgr = root_poa->the_POAManager();
+ PortableServer::POA_var poa =
+ root_poa->create_POA(poa_name, mgr.in(), pols);
+
+ life->destroy();
+ assign->destroy();
+
+ return poa._retn();
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try {
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
+
+ CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
+ PortableServer::POA_var root_poa = PortableServer::POA::_narrow(obj.in());
+
+ PortableServer::POAManager_var mgr = root_poa->the_POAManager();
+
+ const char* poa_name = "MessengerService";
+
+ PortableServer::POA_var messenger_poa = createPOA(root_poa.in(), poa_name);
+
+ Terminator terminator;
+ if (terminator.open (0) == -1)
+ ACE_ERROR_RETURN((LM_ERROR,
+ ACE_TEXT ("main Error opening terminator\n")),-1);
+
+ PortableServer::Servant_var<Messenger_i> messenger_servant =
+ new Messenger_i(orb.in(), terminator);
+
+ PortableServer::ObjectId_var object_id =
+ PortableServer::string_to_ObjectId("messenger_object");
+
+ //
+ // Activate the servant with the messenger POA,
+ // obtain its object reference, and get a
+ // stringified IOR.
+ //
+ messenger_poa->activate_object_with_id(object_id.in(), messenger_servant.in());
+
+ //
+ // Create binding between "MessengerService" and
+ // the messenger object reference in the IOR Table.
+ // Use a TAO extension to get the non imrified poa
+ // to avoid forwarding requests back to the ImR.
+
+ TAO_Root_POA* tpoa = dynamic_cast<TAO_Root_POA*>(messenger_poa.in());
+ obj = tpoa->id_to_reference_i(object_id.in(), false);
+ CORBA::String_var messenger_ior = orb->object_to_string(obj.in());
+ obj = orb->resolve_initial_references("IORTable");
+ IORTable::Table_var table = IORTable::Table::_narrow(obj.in());
+ table->bind(poa_name, messenger_ior.in());
+
+ //
+ // This server is now ready to run.
+ // This version does not create an IOR
+ // file as demonstrated in the
+ // Developer's Guide. It assumes that
+ // users create IORs for the client using
+ // the tao_imr utility.
+ //
+ //
+ // Stop discarding requests.
+ //
+ mgr->activate();
+
+ std::cout << "Messenger server ready." << std::endl;
+
+ orb->run();
+
+ std::cout << "Messenger server shutting down." << std::endl;
+
+ root_poa->destroy(1,1);
+ orb->destroy();
+
+ ACE_Message_Block *mb;
+ ACE_NEW_RETURN(mb, ACE_Message_Block(0, ACE_Message_Block::MB_HANGUP), -1);
+ terminator.putq(mb);
+ terminator.wait();
+ }
+ catch(const CORBA::Exception& ex) {
+ std::cerr << "Server main() Caught CORBA::Exception" << ex << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.cpp b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.cpp
new file mode 100644
index 00000000000..a701f84a1f5
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.cpp
@@ -0,0 +1,53 @@
+/* -*- C++ -*- $Id$ */
+
+// ****** Code generated by the The ACE ORB (TAO) IDL Compiler *******
+// TAO and the TAO IDL Compiler have been developed by the Center for
+// Distributed Object Computing at Washington University, St. Louis.
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
+#include "Messenger_i.h"
+#include "Terminator.h"
+
+#include <iostream>
+
+// Implementation skeleton constructor
+Messenger_i::Messenger_i (CORBA::ORB_ptr orb, Terminator &terminator)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+ , message_count_ (0)
+ , terminator_ (terminator)
+{
+}
+
+// Implementation skeleton destructor
+Messenger_i::~Messenger_i (void)
+{
+}
+
+CORBA::Boolean Messenger_i::send_message (
+ const char * user_name,
+ const char * subject,
+ char *& message)
+{
+ std::cout << "Message count: " << message_count_++ << std::endl;
+ std::cout << "Message from: " << user_name << std::endl
+ << "Subject: " << subject << std::endl
+ << "Message: " << message << std::endl;
+ return 1;
+}
+
+void
+Messenger_i::abort (CORBA::Short delay_secs)
+{
+ ACE_Message_Block *mb = 0;
+ ACE_NEW(mb, ACE_Message_Block(2));
+ ACE_OS::sprintf(mb->wr_ptr (), "%d", delay_secs);
+ terminator_.putq(mb);
+}
+
+void
+Messenger_i::shutdown (void)
+{
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.h b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.h
new file mode 100644
index 00000000000..45e7389c8df
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Messenger_i.h
@@ -0,0 +1,43 @@
+/* -*- C++ -*- $Id$ */
+
+#ifndef MESSENGERI_H_
+#define MESSENGERI_H_
+
+#include "MessengerS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class Terminator;
+
+//Class Messenger_i
+class Messenger_i : public virtual POA_Messenger
+{
+public:
+ //Constructor
+ Messenger_i (CORBA::ORB_ptr orb, Terminator &terminator);
+
+ //Destructor
+ virtual ~Messenger_i (void);
+
+ virtual CORBA::Boolean send_message (
+ const char * user_name,
+ const char * subject,
+ char *& message);
+
+ virtual void abort (CORBA::Short delay_secs);
+
+ virtual void shutdown (void);
+
+private:
+ /// Use an ORB reference to shutdown the application.
+ CORBA::ORB_var orb_;
+
+ int message_count_;
+
+ Terminator& terminator_;
+};
+
+
+#endif /* MESSENGERI_H_ */
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/README b/TAO/orbsvcs/tests/ImplRepo/RestartServer/README
new file mode 100644
index 00000000000..f69485fb4c1
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/README
@@ -0,0 +1,10 @@
+$Id$
+
+This test verifies that if a server launched by the ImR activator is terminated,
+then it will be relaunched transparently by the ORB if the client makes another
+request if -ORBForwardOnTransientLimit and -ORBForwardOnReplyClosedLimit options
+are used.
+
+Note that TAO does not have a way of knowing if server actually processed the
+request, so that the CORBA "at most once" guarantee may be violated if
+-ORBForwardOnReplyClosedLimit is used.
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/RestartServer.mpc b/TAO/orbsvcs/tests/ImplRepo/RestartServer/RestartServer.mpc
new file mode 100644
index 00000000000..c619da302e2
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/RestartServer.mpc
@@ -0,0 +1,37 @@
+// $Id$
+
+project(*idl): taoidldefaults {
+ IDL_Files {
+ Messenger.idl
+ }
+ custom_only = 1
+}
+
+project(*Server): taoserver, iortable, avoids_minimum_corba, avoids_corba_e_micro {
+ exename = MessengerServer
+ after += *idl
+ Source_Files {
+ Messenger_i.cpp
+ MessengerServer.cpp
+ Terminator.cpp
+ }
+ Source_Files {
+ MessengerC.cpp
+ MessengerS.cpp
+ }
+ IDL_Files {
+ }
+}
+
+project(*Client): taoclient, anytypecode, avoids_minimum_corba {
+ exename = MessengerClient
+ after += *idl
+ Source_Files {
+ MessengerClient.cpp
+ }
+ Source_Files {
+ MessengerC.cpp
+ }
+ IDL_Files {
+ }
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/Terminator.cpp b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Terminator.cpp
new file mode 100644
index 00000000000..23b4a0475e4
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Terminator.cpp
@@ -0,0 +1,40 @@
+/* -*- C++ -*- $Id$ */
+
+#include "Terminator.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_unistd.h"
+
+int
+Terminator::open(void*)
+{
+ if(this->activate (THR_NEW_LWP | THR_JOINABLE,
+ 1) == -1)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ ACE_TEXT("Terminator::open Error spawning thread %p\n"),
+ "err="),
+ -1);
+ }
+ return 0;
+}
+
+int
+Terminator::svc()
+{
+ while (1)
+ {
+ ACE_Message_Block* mb;
+ ACE_ASSERT(this->getq(mb) != -1);
+ if (mb->msg_type () == ACE_Message_Block::MB_HANGUP)
+ {
+ mb->release ();
+ break;
+ }
+ int delay_secs = ACE_OS::atoi(mb->rd_ptr());
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t|%T) Terminator::svc() Sleeping %d seconds before aborting\n", delay_secs));
+ ACE_OS::sleep(delay_secs);
+ ACE_OS::abort();
+ }
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/Terminator.h b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Terminator.h
new file mode 100644
index 00000000000..29be200f03e
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/Terminator.h
@@ -0,0 +1,13 @@
+/* -*- C++ -*- $Id$ */
+
+#include "ace/Task_T.h"
+
+class Terminator : public ACE_Task<ACE_MT_SYNCH>
+{
+ public:
+
+ virtual int open(void*);
+
+ virtual int svc();
+};
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/client.conf b/TAO/orbsvcs/tests/ImplRepo/RestartServer/client.conf
new file mode 100644
index 00000000000..409ad4afe86
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/client.conf
@@ -0,0 +1,3 @@
+# $Id$
+
+static Client_Strategy_Factory "-ORBForwardOnTransientLimit 20"
diff --git a/TAO/orbsvcs/tests/ImplRepo/RestartServer/run_test.pl b/TAO/orbsvcs/tests/ImplRepo/RestartServer/run_test.pl
new file mode 100755
index 00000000000..cc398aa4f03
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/RestartServer/run_test.pl
@@ -0,0 +1,245 @@
+# $Id$
+
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+$status = 0;
+$debug_level = '0';
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $debug_level = '10';
+ }
+}
+
+my $extra_timeout = 45;
+
+my $c1 = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $imr = PerlACE::TestTarget::create_target (3) || die "Create target 3 failed\n";
+my $act = PerlACE::TestTarget::create_target (4) || die "Create target 4 failed\n";
+my $ti = PerlACE::TestTarget::create_target (5) || die "Create target 5 failed\n";
+my $si = PerlACE::TestTarget::create_target (6) || die "Create target 6 failed\n";
+my $sdn = PerlACE::TestTarget::create_target (7) || die "Create target 7 failed\n";
+
+my $implrepo_server = "$ENV{TAO_ROOT}/orbsvcs/ImplRepo_Service/tao_imr_locator";
+my $imr_activator = "$ENV{TAO_ROOT}/orbsvcs/ImplRepo_Service/tao_imr_activator";
+my $tao_imr = "$ENV{ACE_ROOT}/bin/tao_imr";
+
+$implrepo_ior = "implrepo.ior";
+$activator_ior = "activator.ior";
+$messenger_ior = "Messenger.ior";
+
+# Use client strategy factory for one of retry parameters.
+$c1_conf = "client.conf";
+
+my $imr_imriorfile = $imr->LocalFile ($implrepo_ior);
+my $act_imriorfile = $act->LocalFile ($implrepo_ior);
+my $ti_imriorfile = $ti->LocalFile ($implrepo_ior);
+my $si_imriorfile = $si->LocalFile ($implrepo_ior);
+my $sdn_imriorfile = $sdn->LocalFile ($implrepo_ior);
+my $act_actiorfile = $act->LocalFile ($activator_ior);
+my $imr_srviorfile = $imr->LocalFile ($messenger_ior);
+my $c1_srviorfile = $c1->LocalFile ($messenger_ior);
+my $c1_conffile = $c1->LocalFile ($c1_conf);
+my $si_srviorfile = $si->LocalFile ($messenger_ior);
+
+# Make sure the files are gone, so we can wait on them.
+$imr->DeleteFile ($implrepo_ior);
+$act->DeleteFile ($implrepo_ior);
+$ti->DeleteFile ($implrepo_ior);
+$si->DeleteFile ($implrepo_ior);
+$sdn->DeleteFile ($implrepo_ior);
+$act->DeleteFile ($activator_ior);
+$imr->DeleteFile ($messenger_ior);
+$c1->DeleteFile ($messenger_ior);
+$si->DeleteFile ($messenger_ior);
+
+# Note : We don't actually use SVR, but we need a way to get the
+# path to the -ExeSubDir
+$SVR = $imr->CreateProcess ("MessengerServer", "-ORBdebuglevel $debug_level");
+my $server = $SVR->Executable ();
+my $srv_server = $imr->LocalFile ($server);
+
+$IR = $imr->CreateProcess ($implrepo_server, "-d 1 ".
+ "orbobjrefstyle url ".
+ "-t 5 ".
+ "-o $imr_imriorfile");
+print ">>> " . $IR->CommandLine() . "\n";
+
+$ACT = $act->CreateProcess ($imr_activator, "-d 1 ".
+ "orbobjrefstyle url ".
+ "-o $act_actiorfile ".
+ "-ORBInitRef ImplRepoService=file://$act_imriorfile");
+
+$TI = $ti->CreateProcess ($tao_imr, "-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
+ "add MessengerService ".
+ "-c \"$srv_server -orbobjrefstyle url -ORBUseIMR 1 -ORBInitRef ImplRepoService=file://$imr_imriorfile\" ");
+
+
+
+$SI = $si->CreateProcess ($tao_imr, "-ORBInitRef ImplRepoService=file://$si_imriorfile ".
+ "ior MessengerService ".
+ "-f $si_srviorfile ");
+
+$C1 = $c1->CreateProcess ("MessengerClient", "-k file://$c1_srviorfile ".
+ "-ORBForwardOnReplyClosedLimit 20 -ORBForwardDelay 500 ".
+ "-ORBSvcConf $c1_conffile -ORBdebuglevel $debug_level");
+
+$SDN = $sdn->CreateProcess ("$tao_imr", "-ORBInitRef ImplRepoService=file://$sdn_imriorfile ".
+ "shutdown MessengerService");
+
+
+$IR_status = $IR->Spawn ();
+
+if ($IR_status != 0) {
+ print STDERR "ERROR: ImplRepo Service returned $IR_status\n";
+ exit 1;
+}
+
+if ($imr->WaitForFileTimed ($implrepo_ior,$imr->ProcessStartWaitInterval() + $extra_timeout) == -1) {
+ print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ exit 1;
+}
+
+if ($imr->GetFile ($implrepo_ior) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$imr_imriorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ exit 1;
+}
+if ($act->PutFile ($implrepo_ior) == -1) {
+ print STDERR "ERROR: cannot set file <$act_imriorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ exit 1;
+}
+if ($ti->PutFile ($implrepo_ior) == -1) {
+ print STDERR "ERROR: cannot set file <$ti_imriorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ exit 1;
+}
+if ($si->PutFile ($implrepo_ior) == -1) {
+ print STDERR "ERROR: cannot set file <$si_imriorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ exit 1;
+}
+if ($sdn->PutFile ($implrepo_ior) == -1) {
+ print STDERR "ERROR: cannot set file <$sdn_imriorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ exit 1;
+}
+
+print ">>> " . $ACT->CommandLine() . "\n";
+$ACT_status = $ACT->Spawn ();
+
+if ($ACT_status != 0) {
+ print STDERR "ERROR: ImR_Activator returned $ACT_status\n";
+ exit 1;
+}
+
+if ($act->WaitForFileTimed ($activator_ior,$act->ProcessStartWaitInterval() + $extra_timeout) == -1) {
+ print STDERR "ERROR: cannot find file <$act_actiorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ exit 1;
+}
+
+print ">>> " . $TI->CommandLine() . "\n";
+# We want the tao_imr executable to be found exactly in the path
+# given, without being modified by the value of -ExeSubDir.
+# So, we tell its Process object to ignore the setting of -ExeSubDir.
+
+$TI->IgnoreExeSubDir (1);
+
+$TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval() + $extra_timeout);
+
+if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr returned $TI_status\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ exit 1;
+}
+
+print ">>> " . $SI->CommandLine() . "\n";
+$SI->IgnoreExeSubDir (1);
+
+
+$SI_status = $SI->SpawnWaitKill ($si->ProcessStartWaitInterval() + $extra_timeout);
+
+if ($SI_status != 0) {
+ print STDERR "ERROR: tao_imr returned $SI_status\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ exit 1;
+}
+
+if ($si->WaitForFileTimed ($messenger_ior,$si->ProcessStartWaitInterval() + $extra_timeout) == -1) {
+ print STDERR "ERROR: cannot find file <$si_srviorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ exit 1;
+}
+
+if ($si->GetFile ($messenger_ior) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$si_srviorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ exit 1;
+}
+if ($c1->PutFile ($messenger_ior) == -1) {
+ print STDERR "ERROR: cannot set file <$c1_srviorfile>\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ exit 1;
+}
+
+
+print ">>> " . $C1->CommandLine() . "\n";
+$C1_status = $C1->SpawnWaitKill ($c1->ProcessStartWaitInterval() + $extra_timeout);
+
+if ($C1_status != 0) {
+ print STDERR "ERROR: Client1 returned $C1_status\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ exit 1;
+}
+
+$SDN->IgnoreExeSubDir (1);
+$SDN_status = $SDN->SpawnWaitKill ($sdn->ProcessStartWaitInterval() + $extra_timeout);
+
+if ($SDN_status != 0) {
+ print STDERR "ERROR: Shutdown returned $SDN_status\n";
+ $IR->Kill (); $IR->TimedWait (1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ exit 1;
+}
+
+
+$IR_status = $IR->TerminateWaitKill ($imr->ProcessStopWaitInterval() + $extra_timeout);
+
+if ($IR_status != 0) {
+ print STDERR "ERROR: ImplRepo Server returned $IR_status\n";
+ $status = 1;
+}
+
+$ACT_status = $ACT->TerminateWaitKill ($act->ProcessStopWaitInterval() + $extra_timeout);
+
+if ($ACT_status != 0) {
+ print STDERR "ERROR: ImR_Activator returned $ACT_status\n";
+ $status = 1;
+}
+
+$imr->DeleteFile ($implrepo_ior);
+$act->DeleteFile ($implrepo_ior);
+$ti->DeleteFile ($implrepo_ior);
+$si->DeleteFile ($implrepo_ior);
+$sdn->DeleteFile ($implrepo_ior);
+$act->DeleteFile ($activator_ior);
+$imr->DeleteFile ($messenger_ior);
+$c1->DeleteFile ($messenger_ior);
+$si->DeleteFile ($messenger_ior);
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/ImplRepo/airplane_client_i.cpp b/TAO/orbsvcs/tests/ImplRepo/airplane_client_i.cpp
index df7a00e9391..cd1f1ff6878 100644
--- a/TAO/orbsvcs/tests/ImplRepo/airplane_client_i.cpp
+++ b/TAO/orbsvcs/tests/ImplRepo/airplane_client_i.cpp
@@ -56,9 +56,10 @@ Airplane_Client_i::parse_args (void)
// Retreives <count> paper airplanes from the server.
-void
+int
Airplane_Client_i::get_planes (size_t count)
{
+ int rc = 0;
for (size_t i = 0; i < count; i++)
{
try
@@ -72,8 +73,10 @@ Airplane_Client_i::get_planes (size_t count)
{
ACE_ERROR ((LM_ERROR, "Plane %d exception:\n", i));
ex._tao_print_exception ("get_planes");
+ rc = 1;
}
}
+ return rc;
}
@@ -82,9 +85,7 @@ Airplane_Client_i::get_planes (size_t count)
int
Airplane_Client_i::run ()
{
- this->get_planes (this->loop_count_);
-
- return 0;
+ return this->get_planes (this->loop_count_);
}
Airplane_Client_i::~Airplane_Client_i (void)
diff --git a/TAO/orbsvcs/tests/ImplRepo/airplane_client_i.h b/TAO/orbsvcs/tests/ImplRepo/airplane_client_i.h
index 5c949a386c1..67497a0720c 100644
--- a/TAO/orbsvcs/tests/ImplRepo/airplane_client_i.h
+++ b/TAO/orbsvcs/tests/ImplRepo/airplane_client_i.h
@@ -46,7 +46,7 @@ private:
int parse_args (void);
/// Ask the Paper Airplane Server for <count> planes.
- void get_planes (size_t count);
+ int get_planes (size_t count);
/// # of arguments on the command line.
int argc_;
diff --git a/TAO/orbsvcs/tests/ImplRepo/airplane_server_i.cpp b/TAO/orbsvcs/tests/ImplRepo/airplane_server_i.cpp
index 58dd5d3959e..873ec9dde5e 100644
--- a/TAO/orbsvcs/tests/ImplRepo/airplane_server_i.cpp
+++ b/TAO/orbsvcs/tests/ImplRepo/airplane_server_i.cpp
@@ -17,7 +17,8 @@ const char SERVER_NAME[] = "airplane_server";
Airplane_Server_i::Airplane_Server_i (void)
: server_impl_ (0),
- ior_output_file_ (0)
+ ior_output_file_ (0),
+ server_name_(SERVER_NAME)
{
// Nothing
}
@@ -25,7 +26,7 @@ Airplane_Server_i::Airplane_Server_i (void)
int
Airplane_Server_i::parse_args (void)
{
- ACE_Get_Opt get_opts (this->argc_, this->argv_, ACE_TEXT("do:"));
+ ACE_Get_Opt get_opts (this->argc_, this->argv_, ACE_TEXT("do:s:"));
int c;
while ((c = get_opts ()) != -1)
@@ -41,12 +42,16 @@ Airplane_Server_i::parse_args (void)
"Unable to open %s for writing: %p\n",
get_opts.opt_arg ()), -1);
break;
+ case 's': // extension to the server name.
+ this->server_name_ = get_opts.opt_arg ();
+ break;
case '?': // display help for use of the server.
default:
ACE_ERROR_RETURN ((LM_ERROR,
"usage: %s"
" [-d]"
- " [-o] <ior_output_file>"
+ " [-o <ior_output_file>]"
+ " [-s <the server name>]"
"\n",
argv_ [0]),
1);
@@ -59,10 +64,6 @@ Airplane_Server_i::parse_args (void)
int
Airplane_Server_i::init (int argc, ACE_TCHAR** argv)
{
- // Since the Implementation Repository keys off of the POA name, we need
- // to use the SERVER_NAME as the POA's name.
- const char *poa_name = SERVER_NAME;
-
try
{
// Initialize the ORB
@@ -101,10 +102,12 @@ Airplane_Server_i::init (int argc, ACE_TCHAR** argv)
policies[1] =
this->root_poa_->create_lifespan_policy (PortableServer::PERSISTENT);
+ // Since the Implementation Repository keys off of the POA name, we need
+ // to use the server_name_ as the POA's name.
this->airplane_poa_ =
- this->root_poa_->create_POA (poa_name,
- this->poa_manager_.in (),
- policies);
+ this->root_poa_->create_POA (this->server_name_.c_str(),
+ this->poa_manager_.in (),
+ policies);
// Creation of the new POA is over, so destroy the Policy_ptr's.
for (CORBA::ULong i = 0; i < policies.length (); ++i)
@@ -142,7 +145,7 @@ Airplane_Server_i::init (int argc, ACE_TCHAR** argv)
IORTable::Table_var adapter =
IORTable::Table::_narrow (obj.in ());
ACE_ASSERT(! CORBA::is_nil (adapter.in ()));
- adapter->bind (poa_name, plain_ior.in ());
+ adapter->bind (this->server_name_.c_str(), plain_ior.in ());
this->poa_manager_->activate ();
diff --git a/TAO/orbsvcs/tests/ImplRepo/airplane_server_i.h b/TAO/orbsvcs/tests/ImplRepo/airplane_server_i.h
index c3ffc51f973..1be339107b6 100644
--- a/TAO/orbsvcs/tests/ImplRepo/airplane_server_i.h
+++ b/TAO/orbsvcs/tests/ImplRepo/airplane_server_i.h
@@ -70,6 +70,9 @@ private:
/// File where the IOR of the server object is stored.
FILE *ior_output_file_;
+
+ /// the server name
+ ACE_CString server_name_;
};
#endif /* AIRPLANE_SERVER_I_H */
diff --git a/TAO/orbsvcs/tests/ImplRepo/run_test.pl b/TAO/orbsvcs/tests/ImplRepo/run_test.pl
index 318943a5fc9..43edcf5be04 100755
--- a/TAO/orbsvcs/tests/ImplRepo/run_test.pl
+++ b/TAO/orbsvcs/tests/ImplRepo/run_test.pl
@@ -8,50 +8,90 @@ eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
###############################################################################
+use strict;
use lib "$ENV{ACE_ROOT}/bin";
use PerlACE::TestTarget;
use File::Copy;
-$debug_level = '0';
+my $debug_level = '0';
+my $srv_debug_level = '0';
+my $test_debug_level = '2';
+my $num_srvr = 1;
+my $replica = 0;
+my $all_tests = 0;
-foreach $i (@ARGV) {
+foreach my $i (@ARGV) {
if ($i eq '-debug') {
$debug_level = '10';
+ $srv_debug_level = '10';
+ }
+ elsif ($i eq '-tdebug') {
+ $test_debug_level = 10;
+ }
+ elsif ($i eq '-tsilent') {
+ $test_debug_level = 0;
+ }
+ elsif ($i eq '-servers') {
+ $num_srvr = 3;
+ }
+ elsif ($i eq '-replica') {
+ $num_srvr = 2;
+ $replica = 1;
+ }
+ elsif ($i eq '-all') {
+ $all_tests = 1;
}
}
-my $imr = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
-my $act = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
-my $ti = PerlACE::TestTarget::create_target (3) || die "Create target 3 failed\n";
-my $a_srv = PerlACE::TestTarget::create_target (4) || die "Create target 4 failed\n";
-my $a_cli = PerlACE::TestTarget::create_target (5) || die "Create target 5 failed\n";
-my $n_srv = PerlACE::TestTarget::create_target (6) || die "Create target 6 failed\n";
-my $n_cli = PerlACE::TestTarget::create_target (7) || die "Create target 7 failed\n";
-my $p_srv = PerlACE::TestTarget::create_target (8) || die "Create target 8 failed\n";
-my $bin_imr = PerlACE::TestTarget::create_target (9) || die "Create target 9 failed\n";
-my $bin_act = PerlACE::TestTarget::create_target (10) || die "Create target 10 failed\n";
+my $tgt_num = 0;
+my $imr = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my $act = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my $ti = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my $n_srv = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my $n_cli = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my $bin_imr = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my $bin_act = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my @a_cli;
+my @a_srv;
+my @p_srv;
+my $index;
+for ($index = 0; $index < $num_srvr; ++$index) {
+ push(@a_cli, PerlACE::TestTarget::create_target (++$tgt_num)) || die "Create a_cli target $tgt_num failed\n";
+ push(@a_srv, PerlACE::TestTarget::create_target (++$tgt_num)) || die "Create a_srv target $tgt_num failed\n";
+ push(@p_srv, PerlACE::TestTarget::create_target (++$tgt_num)) || die "Create p_srv target $tgt_num failed\n";
+}
+
+my $replica_imr;
+if ($replica) {
+ $replica_imr = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create replica_imr target $tgt_num failed\n";
+ $replica_imr->AddLibPath ("$ENV{ACE_ROOT}/lib");
+}
$imr->AddLibPath ("$ENV{ACE_ROOT}/lib");
my $imriorfile = "imr_locator.ior";
my $actiorfile = "imr_activator.ior";
-my $airplaneiorfile = "airplane.ior";
+my $primaryiorfile = "ImR_ReplicaPrimary.ior";
+my $backupiorfile = "ImR_ReplicaBackup.ior";
+my $replica_imriorfile = "replica_imr_locator.ior";
my $nesteaiorfile = "nestea.ior";
-my $backing_store = "imr_backing_store.xml";
my $nestea_dat = "nestea.dat";
-my $a_cli_airplaneiorfile = $a_cli->LocalFile ($airplaneiorfile);
+my $stdout_file = "test.out";
+my $stderr_file = "test.err";
+
my $n_cli_nesteaiorfile = $n_cli->LocalFile ($nesteaiorfile);
my $refstyle = " -ORBObjRefStyle URL";
+my $imr_refstyle = "";# = " -ORBObjRefStyle URL";
my $protocol = "iiop";
my $imr_host = $imr->HostName ();
my $port = 12345;
my $endpoint = "-ORBEndpoint " . "$protocol" . "://:" . $port;
-$IMR = $imr->CreateProcess ("../../ImplRepo_Service/tao_imr_locator");
-$ACT = $act->CreateProcess ("../../ImplRepo_Service/tao_imr_activator");
-$TI = $ti->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_imr");
+my $IMR = $imr->CreateProcess ("../../ImplRepo_Service/tao_imr_locator");
+my $ACT = $act->CreateProcess ("../../ImplRepo_Service/tao_imr_activator");
+my $TI = $ti->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_imr");
# We want the tao_imr executable to be found exactly in the path
# given, without being modified by the value of -ExeSubDir.
@@ -59,79 +99,460 @@ $TI = $ti->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_imr");
$TI->IgnoreExeSubDir (1);
+my $replica_IMR;
+if ($replica) {
+ $replica_IMR = $replica_imr->CreateProcess ("../../ImplRepo_Service/tao_imr_locator");
+}
+
+my @airplaneiorfile;
+my @a_cli_airplaneiorfile;
+for ($index = 0; $index < $num_srvr; ++$index) {
+ push(@airplaneiorfile, "airplane$index.ior");
+ push(@a_cli_airplaneiorfile, $a_cli[$index]->LocalFile ($airplaneiorfile[$index]));
+}
+
sub create_acli {
- return $a_cli->CreateProcess ("airplane_client", " -k file://$a_cli_airplaneiorfile ");
+ my $select = shift;
+ return $a_cli[$select]->CreateProcess ("airplane_client", " -k file://$a_cli_airplaneiorfile[$select] ");
}
sub create_ncli {
return $n_cli->CreateProcess ("nestea_client", " -k file://$n_cli_nesteaiorfile ");
}
-my $A_SRV = $a_srv->CreateProcess ("airplane_server");
-my $A_CLI = create_acli();
-my $N_SRV = $a_cli->CreateProcess ("nestea_server");
-my $N_CLI = create_ncli();
-my $P_SRV = $p_srv->CreateProcess ("persist server");
+my @A_SRV;
+my @a_srv_name;
+my @A_SRV_cmd;
+my @imr_A_SRV_cmd;
+my @P_SRV;
+my @P_SRV_cmd;
+my @imr_P_SRV_cmd;
+for ($index = 0; $index < $num_srvr; ++$index) {
+ push(@a_srv_name, "airplane_server$index");
+ push(@A_SRV, $a_srv[$index]->CreateProcess ("airplane_server"));
+ my $p_srv_name = "persist server$index";
+ push(@P_SRV, $p_srv[$index]->CreateProcess ($p_srv_name));
+
+ push(@A_SRV_cmd, $A_SRV[$index]->Executable());
+ push(@imr_A_SRV_cmd, $imr->LocalFile ($A_SRV_cmd[$index]));
+ push(@P_SRV_cmd, $P_SRV[$index]->Executable());
+ push(@imr_P_SRV_cmd, $imr->LocalFile ($P_SRV_cmd[$index]));
+}
-my $A_SRV_cmd = $A_SRV->Executable();
-my $imr_A_SRV_cmd = $imr->LocalFile ($A_SRV_cmd);
+my @A_CLI;
+for ($index = 0; $index < $num_srvr; ++$index) {
+ push(@A_CLI, create_acli($index));
+}
+my $N_SRV = $a_cli[0]->CreateProcess ("nestea_server");
+my $N_CLI = create_ncli();
my $N_SRV_cmd = $N_SRV->Executable();
my $imr_N_SRV_cmd = $imr->LocalFile ($N_SRV_cmd);
-my $P_SRV_cmd = $P_SRV->Executable();
-my $imr_P_SRV_cmd = $imr->LocalFile ($P_SRV_cmd);
-# The Tests
+###############################################################################
+# Helper subroutines
+###############################################################################
+
+sub setup_repo
+{
+ my $repo_ref = shift;
+ my $the_imr = shift;
+ my $the_IMR = shift;
+ my $the_imriorfile = shift;
+ my $the_act = shift;
+ my $the_ACT = shift;
+ my $the_actiorfile = shift;
+ my $the_ti = shift;
+ my $the_TI = shift;
+ my $port = shift;
+ my $replication_role = shift;
+ my $the_replicaiorfile = shift;
+ my $explicit_act = shift;
+
+ my $the_imr_imriorfile = $the_imr->LocalFile ($the_imriorfile);
+ my $the_act_imriorfile = $the_act->LocalFile ($the_imriorfile);
+ my $the_ti_imriorfile = $the_ti->LocalFile ($the_imriorfile);
+ my $the_act_actiorfile = $the_act->LocalFile ($the_actiorfile);
+ my $the_imr_replicaiorfile = $the_imr->LocalFile ($the_replicaiorfile);
+
+ $repo_ref->{imr} = $the_imr;
+ $repo_ref->{IMR} = $the_IMR;
+ $repo_ref->{imriorfile} = $the_imriorfile;
+ $repo_ref->{imr_imriorfile} = $the_imr_imriorfile;
+ $repo_ref->{imr_endpoint_flag} = "-ORBEndpoint iiop://:$port ";
+ if ($replica) {
+ $repo_ref->{imr_backing_store} = ".";
+ $repo_ref->{imr_backing_store_flag} =
+ "--directory $repo_ref->{imr_backing_store} $replication_role ";
+ }
+ $repo_ref->{replicaiorfile} = $the_replicaiorfile;
+ $repo_ref->{imr_replicaiorfile} = $the_imr_replicaiorfile;
+
+ $repo_ref->{act} = $the_act;
+ $repo_ref->{ACT} = $the_ACT;
+ $repo_ref->{actiorfile} = $the_actiorfile;
+ $repo_ref->{act_imriorfile} = $the_act_imriorfile;
+ $repo_ref->{act_actiorfile} = $the_act_actiorfile;
+ if (defined($explicit_act)) {
+ $repo_ref->{server_act_flag} = "-l $explicit_act ";
+ $repo_ref->{act_explicit_flag} = "-n $explicit_act ";
+ }
+
+ $repo_ref->{ti} = $the_ti;
+ $repo_ref->{TI} = $the_TI;
+ $repo_ref->{ti_imriorfile} = $the_ti_imriorfile;
+}
###############################################################################
-sub airplane_test
+sub cleanup_replication
{
- my $status = 0;
+ my $dir = shift;
+ if (!defined($dir)) {
+ $dir = ".";
+ }
+
+ my $listings = "$dir/imr_listing.xml";
+ my $fnd = 0;
+ if (open FILE, "<$listings") {
+ while (<FILE>) {
+ if ($_ =~ /fname="([^"]+)"?/) {
+ $fnd = 1;
+ my $file = "$dir/$1";
+ test_info("deleting $file\n");
+ $imr->DeleteFile ($file);
+ $imr->DeleteFile ($file . ".bak");
+ }
+ }
+ close FILE;
+ }
+
+# If the primary listings file has been corrupt then perform the
+# deletions from the backup file.
+
+ if (!$fnd) {
+ if (open FILE, "<$listings" . ".bak") {
+ while (<FILE>) {
+ if ($_ =~ /fname="([^"]+)"?/) {
+ my $file = "$dir/$1";
+ test_info("deleting $file\n");
+ $imr->DeleteFile ($file);
+ $imr->DeleteFile ($file . ".bak");
+ }
+ }
+ close FILE;
+ }
+ }
+ test_info("deleting $listings\n");
+ $imr->DeleteFile ("$listings");
+ $imr->DeleteFile ("$listings" . ".bak");
+ $imr->DeleteFile ("$dir/$primaryiorfile");
+ $imr->DeleteFile ("$dir/$backupiorfile");
+}
- my $a_srv_airplaneiorfile = $a_srv->LocalFile ($airplaneiorfile);
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
+###############################################################################
- $A_SRV->Arguments ("-o $a_srv_airplaneiorfile $refstyle -ORBDebugLevel $debug_level");
- $A_SRV_status = $A_SRV->Spawn ();
- if ($A_SRV_status != 0) {
- print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
- return 1;
+sub test_info {
+ if ($test_debug_level < 10) {
+ return;
}
- if ($a_srv->WaitForFileTimed ($airplaneiorfile,$a_srv->ProcessStartWaitInterval()) == -1) {
- print STDERR "ERROR: cannot find file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
- return 1;
+
+ my $info = shift;
+ print "$info";
+}
+
+###############################################################################
+
+sub kill_imr
+{
+ $IMR->Kill (); $IMR->TimedWait (1);
+ if ($replica) {
+ $replica_IMR->Kill (); $replica_IMR->TimedWait (1);
}
- if ($a_srv->GetFile ($airplaneiorfile) == -1) {
- print STDERR "ERROR: cannot retrieve file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
- return 1;
+}
+
+###############################################################################
+
+sub kill_act
+{
+ $ACT->Kill (); $ACT->TimedWait (1);
+}
+
+###############################################################################
+
+sub add_servers
+{
+ my $repo_ref = shift;
+ my $iorfiles_ref = shift;
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nadding server $index using tao_imr\n";
+ $repo_ref->[$index]->{TI}->Arguments ("-ORBInitRef ImplRepoService" .
+ "=file://$repo_ref->[$index]->{ti_imriorfile} $refstyle " .
+ "add $a_srv_name[$index] -c \"$imr_A_SRV_cmd[$index] " .
+ "-o $iorfiles_ref->[$index] -s $a_srv_name[$index]\" " .
+ "$repo_ref->[$index]->{server_act_flag} ");
+ my $TI_status = $repo_ref->[$index]->{TI}->SpawnWaitKill (
+ $repo_ref->[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "added server $index with the locator using tao_imr\n";
}
- if ($a_cli->PutFile ($airplaneiorfile) == -1) {
- print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
- return 1;
+ return 0;
+}
+
+###############################################################################
+
+sub add_servers_again
+{
+ my $repo_ref = shift;
+ my $iorfiles_ref = shift;
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nadding server $index again using tao_imr\n";
+ $repo_ref->[$index]->{TI}->Arguments ("-ORBInitRef ImplRepoService" .
+ "=file://$repo_ref->[$index]->{ti_imriorfile} $refstyle " .
+ "add $a_srv_name[$index] -c \"$imr_A_SRV_cmd[$index] " .
+ "-o $iorfiles_ref->[$index] -s $a_srv_name[$index]\" " .
+ "$repo_ref->[$index]->{server_act_flag} ");
+ my $TI_status = $repo_ref->[$index]->{TI}->SpawnWaitKill (
+ $repo_ref->[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status eq 0) {
+ print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "tao_imr returned $TI_status when attempting to add server $index again\n";
}
+ return 0;
+}
-#$A_CLI = $a_cli->CreateProcess ("airplane_client", " -k file://$a_cli_airplaneiorfile");
- $A_CLI_status = $A_CLI->SpawnWaitKill ($a_cli->ProcessStartWaitInterval());
- if ($A_CLI_status != 0) {
- print STDERR "ERROR: Airplane Client returned $A_CLI_status\n";
- $status = 1;
+###############################################################################
+
+sub remove_servers
+{
+ my $repo_ref = shift;
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nremoving server $index using tao_imr\n";
+ $repo_ref->[$index]->{TI}->Arguments ("-ORBInitRef ImplRepoService" .
+ "=file://$repo_ref->[$index]->{ti_imriorfile} $refstyle " .
+ "remove $a_srv_name[$index]");
+ my $TI_status = $repo_ref->[$index]->{TI}->SpawnWaitKill (
+ $repo_ref->[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "removed server $index\n";
}
+ return 0;
+}
- $A_SRV_status = $A_SRV->TerminateWaitKill ($a_srv->ProcessStopWaitInterval());
- if ($A_SRV_status != 0) {
- print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
- $status = 1;
+###############################################################################
+
+sub start_clients
+{
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("starting client for $a_srv_name[$index]=" .
+ $A_CLI[$index]->CommandLine() . "\n");
+ my $A_CLI_status = $A_CLI[$index]->Spawn ();
+ if ($A_CLI_status != 0) {
+ print STDERR
+ "ERROR: Airplane Client ($index) failed to spawn returning $A_CLI_status\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+###############################################################################
+
+sub stop_clients
+{
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ my $A_CLI_status = $A_CLI[$index]->WaitKill ($a_cli[$index]->ProcessStartWaitInterval());
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: Airplane Client $index returned $A_CLI_status\n";
+ return 1;
+ }
+ print "\n\nstopped client $index\n\n\n";
+ }
+ return 0;
+}
+
+###############################################################################
+
+sub shutdown_servers_using_tao_imr
+{
+ my $repo_ref = shift;
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nshutting down server $index using tao_imr\n";
+ $repo_ref->[$index]->{TI}->Arguments ("-ORBInitRef ImplRepoService" .
+ "=file://$repo_ref->[$index]->{ti_imriorfile} $refstyle " .
+ "shutdown $a_srv_name[$index]");
+ my $TI_status = $repo_ref->[$index]->{TI}->SpawnWaitKill (
+ $repo_ref->[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "\n\nshut down server $index using tao_imr\n";
}
+ return 0;
+}
+
+###############################################################################
+
+sub wait_for_imr
+{
+ my $repo_ref = shift;
+ my $filekey = shift;
+
+ if (!defined($filekey)) {
+ $filekey = "imriorfile";
+ }
+ my $imr_only = ($filekey eq "imriorfile");
+
+ if ($repo_ref->{imr}->WaitForFileTimed (
+ $repo_ref->{$filekey},
+ $repo_ref->{imr}->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <" .
+ $repo_ref->{"imr_$filekey"} . ">\n";
+ kill_imr();
+ return 1;
+ }
+ if ($repo_ref->{imr}->GetFile ($repo_ref->{$filekey}) == -1) {
+ print STDERR "ERROR: cannot retrieve file <" .
+ $repo_ref->{"imr_$filekey"} . ">\n";
+ kill_imr();
+ return 1;
+ }
+ if (!$imr_only) {
+ if ($repo_ref->{act}->PutFile ($repo_ref->{$filekey}) == -1) {
+ print STDERR "ERROR: cannot set file <" .
+ $repo_ref->{"act_$filekey"} . ">\n";
+ kill_imr();
+ return 1;
+ }
+ if ($repo_ref->{ti}->PutFile ($repo_ref->{$filekey}) == -1) {
+ print STDERR "ERROR: cannot set file <" .
+ $repo_ref->{"act_$filekey"} . ">\n";
+ kill_imr();
+ return 1;
+ }
+ }
+ return 0;
+}
+
+###############################################################################
+
+sub kill_then_timed_wait
+{
+ my $srvrs = shift;
+ my $time = shift;
+ my $length = scalar(@{$srvrs});
+ for ($index = 0; $index < $length; ++$index) {
+ $srvrs->[$index]->Kill (); $srvrs->[$index]->TimedWait (1);
+ }
+}
+
+
+###############################################################################
+
+sub redirect_output
+{
+
+ my $test_stdout_file = shift;
+ my $test_stderr_file = shift;
+ open (OLDOUT, ">&", \*STDOUT) or die "Can't dup STDOUT: $!";
+ open (OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!";
+ open STDOUT, '>', $test_stdout_file;
+ open STDERR, '>', $test_stderr_file;
+}
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
+###############################################################################
+
+sub restore_output()
+{
+ open (STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!";
+ open (STDOUT, ">&OLDOUT") or die "Can't dup OLDOUT: $!";
+}
+
+
+###############################################################################
+# The Tests
+###############################################################################
+
+sub airplane_test
+{
+ my $status = 0;
+ my @a_srv_airplaneiorfile;
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ push(@a_srv_airplaneiorfile, $a_srv[$index]->LocalFile ($airplaneiorfile[$index]));
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+
+ $A_SRV[$index]->Arguments (
+ "-o $a_srv_airplaneiorfile[$index] $refstyle -ORBDebugLevel " .
+ "$srv_debug_level -s $a_srv_name[$index]");
+ my $A_SRV_status = $A_SRV[$index]->Spawn ();
+ if ($A_SRV_status != 0) {
+ print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->WaitForFileTimed ($airplaneiorfile[$index],$a_srv[$index]->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ return 1;
+ }
+ if ($a_srv[$index]->GetFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ return 1;
+ }
+ if ($a_cli[$index]->PutFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ my $A_CLI_status = $A_CLI[$index]->SpawnWaitKill ($a_cli[$index]->ProcessStartWaitInterval());
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: Airplane Client returned $A_CLI_status\n";
+ $status = 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ my $A_SRV_status = $A_SRV[$index]->TerminateWaitKill ($a_srv[$index]->ProcessStopWaitInterval());
+ if ($A_SRV_status != 0) {
+ print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
+ $status = 1;
+ }
+
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+ }
return $status;
}
@@ -145,8 +566,9 @@ sub nestea_test
$n_srv->DeleteFile ($nesteaiorfile);
$n_cli->DeleteFile ($nesteaiorfile);
- $N_SRV->Arguments ("-o $n_srv_nesteaiorfile $refstyle -ORBDebugLevel $debug_level");
- $N_SRV_status = $N_SRV->Spawn ();
+ $N_SRV->Arguments ("-o $n_srv_nesteaiorfile $refstyle -ORBDebugLevel " .
+ "$srv_debug_level");
+ my $N_SRV_status = $N_SRV->Spawn ();
if ($N_SRV_status != 0) {
print STDERR "ERROR: Nestea Server returned $N_SRV_status\n";
return 1;
@@ -167,7 +589,7 @@ sub nestea_test
return 1;
}
- $N_CLI_status = $N_CLI->SpawnWaitKill ($n_cli->ProcessStartWaitInterval());
+ my $N_CLI_status = $N_CLI->SpawnWaitKill ($n_cli->ProcessStartWaitInterval());
if ($N_CLI_status != 0) {
print STDERR "ERROR: Nestea Client returned $N_CLI_status\n";
$status = 1;
@@ -185,23 +607,25 @@ sub nestea_test
return $status;
}
+###############################################################################
+
sub nt_service_test_i
{
my ($imr_initref, $BIN_ACT, $BIN_IMR) = @_;
- my $a_srv_airplaneiorfile = $a_srv->LocalFile ($airplaneiorfile);
+ my $a_srv_airplaneiorfile = $a_srv[0]->LocalFile ($airplaneiorfile[0]);
print "Installing TAO ImR Services\n";
- $BIN_ACT->Arguments ("-c install $imr_initref -d 0 -ORBDebugLevel $debug_level");
- $BIN_IMR->Arguments ("-c install -d 0 -orbendpoint iiop://:8888");
+ $BIN_ACT->Arguments ("-c install $imr_initref -d $test_debug_level -ORBDebugLevel $debug_level");
+ $BIN_IMR->Arguments ("-c install -d $test_debug_level -orbendpoint iiop://:8888");
- $BIN_IMR_status = $BIN_IMR->SpawnWaitKill ($bin_imr->ProcessStartWaitInterval());
+ my $BIN_IMR_status = $BIN_IMR->SpawnWaitKill ($bin_imr->ProcessStartWaitInterval());
if ($BIN_IMR_status != 0) {
print STDERR "ERROR: ImR Service returned $BIN_IMR_status\n";
return 1;
}
- $BIN_ACT_status = $BIN_ACT->SpawnWaitKill ($bin_act->ProcessStartWaitInterval());
+ my $BIN_ACT_status = $BIN_ACT->SpawnWaitKill ($bin_act->ProcessStartWaitInterval());
if ($BIN_ACT_status != 0) {
print STDERR "ERROR: ImR Activator returned $BIN_ACT_status\n";
return 1;
@@ -214,11 +638,11 @@ sub nt_service_test_i
system("net start taoimractivator 2>&1");
# No need to specify imr_initref or -orbuseimr 1 for servers spawned by activator
- $TI->Arguments ("$imr_initref add airplane_server -c \"$imr_A_SRV_cmd\" ".
+ $TI->Arguments ("$imr_initref add $a_srv_name[0] -c \"$imr_A_SRV_cmd[0] -s $a_srv_name[0]\" ".
"-w \"$ENV{ACE_ROOT}/lib\"");
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ my $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr add airplane_server returned $TI_status\n";
+ print STDERR "ERROR: tao_imr add $a_srv_name[0] returned $TI_status\n";
return 1;
}
@@ -229,53 +653,55 @@ sub nt_service_test_i
return 1;
}
- $TI->Arguments ("$imr_initref ior airplane_server -f $a_srv_airplaneiorfile");
+ $TI->Arguments ("$imr_initref ior $a_srv_name[0] -f $a_srv_airplaneiorfile");
$TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr ior airplane_server returned $TI_status\n";
+ print STDERR "ERROR: tao_imr ior $a_srv_name[0] returned $TI_status\n";
return 1;
}
- if ($a_srv->WaitForFileTimed ($airplaneiorfile,$a_srv->ProcessStartWaitInterval()) == -1) {
+ if ($a_srv[0]->WaitForFileTimed ($airplaneiorfile[0],$a_srv[0]->ProcessStartWaitInterval()) == -1) {
print STDERR "ERROR: cannot find file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ kill_then_timed_wait(\@A_SRV, 1);
return 1;
}
- if ($a_srv->GetFile ($airplaneiorfile) == -1) {
+ if ($a_srv[0]->GetFile ($airplaneiorfile[0]) == -1) {
print STDERR "ERROR: cannot retrieve file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ kill_then_timed_wait(\@A_SRV, 1);
return 1;
}
- if ($a_cli->PutFile ($airplaneiorfile) == -1) {
- print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ if ($a_cli[0]->PutFile ($airplaneiorfile[0]) == -1) {
+ print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
return 1;
}
- $A_CLI_status = $A_CLI->SpawnWaitKill ($a_cli->ProcessStartWaitInterval()+5);
+ my $A_CLI_status = $A_CLI[0]->SpawnWaitKill ($a_cli[0]->ProcessStartWaitInterval()+5);
if ($A_CLI_status != 0) {
print STDERR "ERROR: airplane client returned $A_CLI_status\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ kill_then_timed_wait(\@A_SRV, 1);
return 1;
}
- $TI->Arguments ("$imr_initref shutdown airplane_server");
+ $TI->Arguments ("$imr_initref shutdown $a_srv_name[0]");
$TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval()+5);
if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr shutdown airplane_server returned $TI_status\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ print STDERR "ERROR: tao_imr shutdown $a_srv_name[0] returned $TI_status\n";
+ kill_then_timed_wait(\@A_SRV, 1);
return 1;
}
return 0;
}
+###############################################################################
+
sub nt_service_test
{
my $result = 0;
- my $a_srv_airplaneiorfile = $a_srv->LocalFile ($airplaneiorfile);
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
+ my $a_srv_airplaneiorfile = $a_srv[0]->LocalFile ($airplaneiorfile[0]);
+ $a_srv[0]->DeleteFile ($airplaneiorfile[0]);
+ $a_cli[0]->DeleteFile ($airplaneiorfile[0]);
my $bin_imr_host = $bin_imr->HostName ();
@@ -304,11 +730,11 @@ sub nt_service_test
print "Removing any existing TAO ImR Services\n";
$BIN_ACT->Arguments ("-c remove");
$BIN_IMR->Arguments ("-c remove");
- $BIN_ACT_status = $BIN_ACT->SpawnWaitKill ($bin_act->ProcessStartWaitInterval());
+ my $BIN_ACT_status = $BIN_ACT->SpawnWaitKill ($bin_act->ProcessStartWaitInterval());
if ($BIN_ACT_status < 0) {
print STDERR "ERROR: BIN Activator returned $BIN_ACT_status\n";
}
- $BIN_IMR_status = $BIN_IMR->SpawnWaitKill ($bin_imr->ProcessStartWaitInterval());
+ my $BIN_IMR_status = $BIN_IMR->SpawnWaitKill ($bin_imr->ProcessStartWaitInterval());
if ($BIN_IMR_status < 0) {
print STDERR "ERROR: BIN ImR Service returned $BIN_IMR_status\n";
}
@@ -335,8 +761,8 @@ sub nt_service_test
$bin_imr->DeleteFile ($BIN_IMR->Executable ());
$bin_act->DeleteFile ($BIN_ACT->Executable ());
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
+ $a_srv[0]->DeleteFile ($airplaneiorfile[0]);
+ $a_cli[0]->DeleteFile ($airplaneiorfile[0]);
return $result;
}
@@ -347,163 +773,293 @@ sub airplane_ir_test
{
my $status = 0;
- my $imr_imriorfile = $imr->LocalFile ($imriorfile);
- my $act_imriorfile = $act->LocalFile ($imriorfile);
- my $ti_imriorfile = $ti->LocalFile ($imriorfile);
- my $a_srv_imriorfile = $a_srv->LocalFile ($imriorfile);
- my $act_actiorfile = $act->LocalFile ($actiorfile);
- my $imr_airplaneiorfile = $imr->LocalFile ($airplaneiorfile);
- my $a_srv_airplaneiorfile = $a_srv->LocalFile ($airplaneiorfile);
+ if ($srv_debug_level < 2 && $replica) {
+ $srv_debug_level = 2;#"2 -ORBLogFile server.log";
+ }
+
+ my $imr_port = 10001 + $imr->RandomPort ();
+ print "\n\nimr_port=$imr_port\n";
+ my %repo;
+ setup_repo(\%repo, $imr, $IMR, $imriorfile, $act, $ACT, $actiorfile, $ti,
+ $TI, $imr_port, "--primary", $backupiorfile);
+
+ my %backup_repo;
+ if ($replica) {
+ setup_repo(\%backup_repo, $replica_imr, $replica_IMR,
+ $replica_imriorfile, $act, $ACT, $actiorfile,
+ $ti, $TI, $imr_port + 1, "--backup",
+ $primaryiorfile);
+ }
+
+ my @repo_for_srvr;
+ my @a_srv_imriorfile;
+ my @imr_airplaneiorfile;
+ my @a_srv_airplaneiorfile;
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($index == ($num_srvr - 1) && $replica) {
+ push(@repo_for_srvr, \%backup_repo);
+ }
+ else {
+ push(@repo_for_srvr, \%repo);
+ }
+
+ push(@a_srv_imriorfile, $a_srv[$index]->LocalFile ($repo_for_srvr[$index]->{imriorfile}));
+ push(@imr_airplaneiorfile, $repo_for_srvr[$index]->{imr}->LocalFile ($airplaneiorfile[$index]));
+ push(@a_srv_airplaneiorfile, $a_srv[$index]->LocalFile ($airplaneiorfile[$index]));
+ $a_srv[$index]->DeleteFile ($repo_for_srvr[$index]->{imriorfile});
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $repo_for_srvr[$index]->{imr}->DeleteFile ($airplaneiorfile[$index]);
+ }
$imr->DeleteFile ($imriorfile);
$act->DeleteFile ($imriorfile);
$ti->DeleteFile ($imriorfile);
- $a_srv->DeleteFile ($imriorfile);
$act->DeleteFile ($actiorfile);
- $imr->DeleteFile ($airplaneiorfile);
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
+ if ($replica) {
+ $replica_imr->DeleteFile ($replica_imriorfile);
+ cleanup_replication($repo{imr_backing_store});
+ }
- $IMR->Arguments ("-d 2 -o $imr_imriorfile $refstyle");
- $IMR_status = $IMR->Spawn ();
+ print "\n\nstarting IMR\n";
+ $repo{IMR}->Arguments ("-d $test_debug_level -o $repo{imr_imriorfile} " .
+ "$imr_refstyle $repo{imr_backing_store_flag} $repo{imr_endpoint_flag}");
+ my $IMR_status = $repo{IMR}->Spawn ();
if ($IMR_status != 0) {
print STDERR "ERROR: ImR Service returned $IMR_status\n";
return 1;
}
- if ($imr->WaitForFileTimed ($imriorfile,$imr->ProcessStartWaitInterval()) == -1) {
- print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
- }
- if ($imr->GetFile ($imriorfile) == -1) {
- print STDERR "ERROR: cannot retrieve file <$imr_imriorfile>\n";
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
- }
- if ($act->PutFile ($imriorfile) == -1) {
- print STDERR "ERROR: cannot set file <$act_imriorfile>\n";
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
- }
- if ($ti->PutFile ($imriorfile) == -1) {
- print STDERR "ERROR: cannot set file <$ti_imriorfile>\n";
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
- }
- if ($a_srv->PutFile ($imriorfile) == -1) {
- print STDERR "ERROR: cannot set file <$a_srv_imriorfile>\n";
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
- }
-
- $ACT->Arguments ("-d 2 -o $act_actiorfile -ORBInitRef ImplRepoService=file://$act_imriorfile");
- $ACT_status = $ACT->Spawn ();
+ if ($replica) {
+ if (wait_for_imr(\%backup_repo, "replicaiorfile")) {
+ return 1;
+ }
+ print "\n\nstarting backup IMR\n";
+ $backup_repo{IMR}->Arguments ("-d $test_debug_level -o " .
+ "$backup_repo{imr_imriorfile} $imr_refstyle " .
+ "$backup_repo{imr_backing_store_flag} " .
+ "$backup_repo{imr_endpoint_flag}");
+ my $replica_IMR_status = $backup_repo{IMR}->Spawn ();
+ if ($replica_IMR_status != 0) {
+ print STDERR "ERROR: ImR Service replica returned $replica_IMR_status\n";
+ return 1;
+ }
+ if (wait_for_imr(\%repo, "replicaiorfile")) {
+ return 1;
+ }
+ print "started backup IMR\n";
+ }
+ if (wait_for_imr(\%repo)) {
+ return 1;
+ }
+ print "started IMR\n";
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->PutFile ($repo_for_srvr[$index]->{imriorfile}) == -1) {
+ print STDERR "ERROR: cannot set file <$a_srv_imriorfile[$index]>\n";
+ kill_imr();
+ return 1;
+ }
+ }
+
+ print "\n\nstarting ACT\n";
+ $repo{ACT}->Arguments ("-d $test_debug_level -o $repo{act_actiorfile} " .
+ "-ORBInitRef ImplRepoService=file://$repo{act_imriorfile} $refstyle " .
+ $repo{act_explicit_flag});
+ my $ACT_status = $repo{ACT}->Spawn ();
if ($ACT_status != 0) {
print STDERR "ERROR: ImR Activator returned $ACT_status\n";
return 1;
}
- if ($act->WaitForFileTimed ($actiorfile,$act->ProcessStartWaitInterval()) == -1) {
- print STDERR "ERROR: cannot find file <$act_actiorfile>\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+
+ if ($repo{act}->WaitForFileTimed (
+ $repo{actiorfile},
+ $repo{act}->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <" .
+ $repo{act_actiorfile} . ">\n";
+ kill_act();
+ kill_imr();
return 1;
}
+ print "started ACT\n";
# No need to specify imr_initref or -orbuseimr 1 for servers spawned by activator
# Can use update to add servers.
- $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
- "update airplane_server -c \"$imr_A_SRV_cmd -o $imr_airplaneiorfile\"");
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
- if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr returned $TI_status\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
- }
-
- $A_SRV->Arguments ("-ORBUseIMR 1 -o $a_srv_airplaneiorfile ".
- "-ORBInitRef ImplRepoService=file://$a_srv_imriorfile ".
- "-ORBDebugLevel $debug_level");
- $A_SRV_status = $A_SRV->Spawn ();
- if ($A_SRV_status != 0) {
- print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
- return 1;
- }
- if ($a_srv->WaitForFileTimed ($airplaneiorfile,$a_srv->ProcessStartWaitInterval()) == -1) {
- print STDERR "ERROR: cannot find file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
- }
- if ($a_srv->GetFile ($airplaneiorfile) == -1) {
- print STDERR "ERROR: cannot retrieve file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
- }
- if ($a_cli->PutFile ($airplaneiorfile) == -1) {
- print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
- }
-
- $A_CLI_status = $A_CLI->SpawnWaitKill ($a_cli->ProcessStartWaitInterval());
- if ($A_CLI_status != 0) {
- print STDERR "ERROR: Airplane Client 1 returned $A_CLI_status\n";
- $status = 1;
- }
-
- $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile shutdown airplane_server");
-
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
- if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr 1 returned $TI_status\n";
- $status = 1;
- }
-
- # This client should force a new airplane_server to be started
- $A_CLI_status = $A_CLI->SpawnWaitKill ($a_cli->ProcessStartWaitInterval());
- if ($A_CLI_status != 0) {
- print STDERR "ERROR: Airplane Client 2 returned $A_CLI_status\n";
- $status = 1;
- }
-
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
- if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr 2 returned $TI_status\n";
- $status = 1;
- }
-
- $A_SRV_status = $A_SRV->WaitKill ($a_srv->ProcessStopWaitInterval());
- if ($A_SRV_status != 0) {
- print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
- $status = 1;
- }
-
- $ACT_status = $ACT->TerminateWaitKill ($act->ProcessStopWaitInterval());
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nstarting TI $index\n";
+ $repo_for_srvr[$index]->{TI}->Arguments ("-ORBInitRef ImplRepoService" .
+ "=file://$repo_for_srvr[$index]->{ti_imriorfile} $refstyle " .
+ "update $a_srv_name[$index] -c \"$imr_A_SRV_cmd[$index] " .
+ "-o $imr_airplaneiorfile[$index] -s $a_srv_name[$index]\" " .
+ "$repo_for_srvr[$index]->{server_act_flag} ");
+ my $TI_status = $repo_for_srvr[$index]->{TI}->SpawnWaitKill (
+ $repo_for_srvr[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "stopped TI $index\n";
+
+ print "\n\nstarting srv $index\n";
+ $A_SRV[$index]->Arguments (
+ "-ORBUseIMR 1 -o $a_srv_airplaneiorfile[$index] $refstyle ".
+ "-ORBInitRef ImplRepoService=file://$a_srv_imriorfile[$index] ".
+ "-ORBDebugLevel $srv_debug_level -s $a_srv_name[$index] ");
+ my $A_SRV_status = $A_SRV[$index]->Spawn ();
+ if ($A_SRV_status != 0) {
+ print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->WaitForFileTimed ($airplaneiorfile[$index],$a_srv[$index]->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ if ($a_srv[$index]->GetFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ if ($a_cli[$index]->PutFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "\n\nstarted srv $index\n\n";
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nstarting client $index\n";
+ my $A_CLI_status = $A_CLI[$index]->Spawn ();
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: Airplane Client $index failed to spawn returning $A_CLI_status\n";
+ $status = 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ my $A_CLI_status = $A_CLI[$index]->WaitKill ($a_cli[$index]->ProcessStartWaitInterval());
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: Airplane Client $index returned $A_CLI_status\n";
+ $status = 1;
+ }
+ print "\n\nstopped client $index\n\n\n";
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nstarting TI $index (2)\n";
+ $repo_for_srvr[$index]->{TI}->Arguments ("-ORBInitRef " .
+ "ImplRepoService=file://$repo_for_srvr[$index]->{ti_imriorfile} " .
+ "$refstyle shutdown $a_srv_name[$index]");
+
+ my $TI_status = $repo_for_srvr[$index]->{TI}->SpawnWaitKill (
+ $repo_for_srvr[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr 1 ($index) returned $TI_status\n";
+ $status = 1;
+ }
+ print "stopped TI $index (2)\n";
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nstarting client $index\n";
+ # This client should force a new airplane_server to be started
+ my $A_CLI_status = $A_CLI[$index]->SpawnWaitKill (
+ $a_cli[$index]->ProcessStartWaitInterval());
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: restarted Airplane Client $index returned " .
+ "$A_CLI_status\n";
+ $status = 1;
+ }
+ print "stopped client $index\n";
+
+ print "\n\nstarting client $index\n";
+ $repo_for_srvr[$index]->{TI}->Arguments ("-ORBInitRef " .
+ "ImplRepoService=file://$repo_for_srvr[$index]->{ti_imriorfile} " .
+ "$refstyle shutdown $a_srv_name[$index]");
+
+ my $TI_status = $repo_for_srvr[$index]->{TI}->SpawnWaitKill (
+ $repo_for_srvr[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr 2 ($index) returned $TI_status\n";
+ $status = 1;
+ }
+ print "stopped client $index\n";
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nkilling srv $index\n";
+ my $A_SRV_status = $A_SRV[$index]->WaitKill ($a_srv[$index]->ProcessStopWaitInterval());
+ if ($A_SRV_status != 0) {
+ print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
+ $status = 1;
+ }
+ print "stopped srv $index\n";
+ }
+
+ print "\n\nkilling ACT\n";
+ $ACT_status = $repo{ACT}->TerminateWaitKill (
+ $repo{act}->ProcessStopWaitInterval());
if ($ACT_status != 0) {
print STDERR "ERROR: Activator returned $ACT_status\n";
$status = 1;
}
+ print "stopped ACT\n";
- $IMR_status = $IMR->TerminateWaitKill ($imr->ProcessStopWaitInterval());
+ print "\n\nkilling IMR\n";
+ $IMR_status = $repo{IMR}->TerminateWaitKill (
+ $repo{imr}->ProcessStopWaitInterval());
if ($IMR_status != 0) {
print STDERR "ERROR: ImR returned $IMR_status\n";
$status = 1;
}
-
- $imr->DeleteFile ($imriorfile);
- $act->DeleteFile ($imriorfile);
- $ti->DeleteFile ($imriorfile);
- $a_srv->DeleteFile ($imriorfile);
- $act->DeleteFile ($actiorfile);
- $imr->DeleteFile ($airplaneiorfile);
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
-
+ print "stopped IMR\n";
+
+ if ($replica) {
+ print "\n\nkilling backup IMR\n";
+ $IMR_status = $backup_repo{IMR}->TerminateWaitKill (
+ $backup_repo{imr}->ProcessStopWaitInterval());
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: replica ImR returned $IMR_status\n";
+ $status = 1;
+ }
+ print "stopped backup IMR\n";
+ }
+
+ $repo{imr}->DeleteFile ($repo{imriorfile});
+ $repo{act}->DeleteFile ($repo{imriorfile});
+ $repo{ti}->DeleteFile ($repo{imriorfile});
+ $repo{act}->DeleteFile ($repo{actiorfile});
+
+ if ($replica) {
+ $backup_repo{imr}->DeleteFile (
+ $backup_repo{imriorfile});
+ $backup_repo{act}->DeleteFile (
+ $backup_repo{imriorfile});
+ $backup_repo{ti}->DeleteFile (
+ $backup_repo{imriorfile});
+ $backup_repo{act}->DeleteFile (
+ $backup_repo{actiorfile});
+ cleanup_replication($repo{imr_backing_store});
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ $repo_for_srvr[$index]->{imr}->DeleteFile (
+ $airplaneiorfile[$index]);
+ $a_srv[$index]->DeleteFile (
+ $repo_for_srvr[$index]->{imriorfile});
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+ }
return $status;
}
@@ -529,13 +1085,14 @@ sub nestea_ir_test
$n_srv->DeleteFile ($nesteaiorfile);
$n_cli->DeleteFile ($nesteaiorfile);
- $IMR->Arguments ("-d 2 -o $imr_imriorfile $refstyle");
- $IMR_status = $IMR->Spawn ();
+ $IMR->Arguments ("-d $test_debug_level -o $imr_imriorfile $imr_refstyle");
+ my $IMR_status = $IMR->Spawn ();
if ($IMR_status != 0) {
print STDERR "ERROR: ImR Service returned $IMR_status\n";
return 1;
}
- if ($imr->WaitForFileTimed ($imriorfile,$imr->ProcessStartWaitInterval()) == -1) {
+ if ($imr->WaitForFileTimed ($imriorfile,
+ $imr->ProcessStartWaitInterval()) == -1) {
print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
@@ -561,9 +1118,10 @@ sub nestea_ir_test
return 1;
}
- $ACT->Arguments ("-d 2 -o $act_actiorfile ".
- "-orbobjrefstyle URL -ORBInitRef ImplRepoService=file://$act_imriorfile");
- $ACT_status = $ACT->Spawn ();
+ $ACT->Arguments (
+ "-d $test_debug_level -o $act_actiorfile -orbobjrefstyle URL ".
+ "-ORBInitRef ImplRepoService=file://$act_imriorfile");
+ my $ACT_status = $ACT->Spawn ();
if ($ACT_status != 0) {
print STDERR "ERROR: ImR Activator returned $ACT_status\n";
return 1;
@@ -575,10 +1133,11 @@ sub nestea_ir_test
return 1;
}
- $N_SRV->Arguments ("-ORBUseIMR 1 -o $n_srv_nesteaiorfile ".
- "-orbobjrefstyle URL -ORBInitRef ImplRepoService=file://$n_srv_imriorfile ".
- "-ORBDebugLevel $debug_level");
- $N_SRV_status = $N_SRV->Spawn ();
+ $N_SRV->Arguments (
+ "-ORBUseIMR 1 -o $n_srv_nesteaiorfile -orbobjrefstyle URL ".
+ "-ORBInitRef ImplRepoService=file://$n_srv_imriorfile ".
+ "-ORBDebugLevel $srv_debug_level");
+ my $N_SRV_status = $N_SRV->Spawn ();
if ($N_SRV_status != 0) {
print STDERR "ERROR: Nestea Server returned $N_SRV_status\n";
return 1;
@@ -605,7 +1164,7 @@ sub nestea_ir_test
return 1;
}
- $N_CLI_status = $N_CLI->SpawnWaitKill ($n_cli->ProcessStartWaitInterval());
+ my $N_CLI_status = $N_CLI->SpawnWaitKill ($n_cli->ProcessStartWaitInterval());
if ($N_CLI_status != 0) {
print STDERR "ERROR: Nestea Client 1 returned $N_CLI_status\n";
$N_SRV->Kill (); $N_SRV->TimedWait (1);
@@ -617,7 +1176,7 @@ sub nestea_ir_test
$TI->Arguments ("-orbobjrefstyle URL -ORBInitRef ImplRepoService=file://$ti_imriorfile ".
" shutdown nestea_server");
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ my $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
if ($TI_status != 0) {
print STDERR "ERROR: tao_imr 1 returned $TI_status\n";
$N_SRV->Kill (); $N_SRV->TimedWait (1);
@@ -741,14 +1300,16 @@ sub perclient
my $imr_host = $imr->HostName ();
# specify an endpoint so that we can use corbaloc url for the client.
- $IMR->Arguments ("-d 2 -orbendpoint iiop://:8888 -o $imr_imriorfile $refstyle ".
- "-ORBDebugLevel $debug_level");
- $IMR_status = $IMR->Spawn ();
+ $IMR->Arguments (
+ "-d $test_debug_level -orbendpoint iiop://:8888 ".
+ "-o $imr_imriorfile $imr_refstyle -ORBDebugLevel $debug_level");
+ my $IMR_status = $IMR->Spawn ();
if ($IMR_status != 0) {
print STDERR "ERROR: ImR Service returned $IMR_status\n";
return 1;
}
- if ($imr->WaitForFileTimed ($imriorfile,$imr->ProcessStartWaitInterval()) == -1) {
+ if ($imr->WaitForFileTimed ($imriorfile,
+ $imr->ProcessStartWaitInterval()) == -1) {
print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
@@ -769,9 +1330,9 @@ sub perclient
return 1;
}
- $ACT->Arguments ("-d 2 -o $act_actiorfile ".
+ $ACT->Arguments ("-d $test_debug_level -o $act_actiorfile ".
"-orbobjrefstyle URL -ORBInitRef ImplRepoService=file://$act_imriorfile");
- $ACT_status = $ACT->Spawn ();
+ my $ACT_status = $ACT->Spawn ();
if ($ACT_status != 0) {
print STDERR "ERROR: ImR Activator returned $ACT_status\n";
return 1;
@@ -787,7 +1348,7 @@ sub perclient
$TI->Arguments ("-orbobjrefstyle URL -ORBInitRef ImplRepoService=file://$ti_imriorfile ".
"add nestea_server -a PER_CLIENT ".
"-c \"$imr_N_SRV_cmd -o $imr_nesteaiorfile\"");
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ my $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
if ($TI_status != 0) {
print STDERR "ERROR: tao_imr returned $TI_status\n";
$ACT->Kill (); $ACT->TimedWait (1);
@@ -798,21 +1359,21 @@ sub perclient
$N_CLI->Arguments("-k corbaloc::$imr_host:8888/nestea_server");
# Running the client should start a server instance
- $N_CLI_status = $N_CLI->SpawnWaitKill ($n_cli->ProcessStartWaitInterval()+5);
+ my $N_CLI_status = $N_CLI->SpawnWaitKill ($n_cli->ProcessStartWaitInterval()+5);
if ($N_CLI_status != 0) {
print STDERR "ERROR: Nestea Client 1 returned $N_CLI_status\n";
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- if ($n_cli->WaitForFileTimed ($nesteaiorfile,$a_cli->ProcessStartWaitInterval()) == -1) {
- print STDERR "ERROR: cannot find file <$a_cli_nesteaiorfile>\n";
+ if ($n_cli->WaitForFileTimed ($nesteaiorfile,$a_cli[0]->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$n_cli_nesteaiorfile>\n";
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- $a_cli->DeleteFile ($nesteaiorfile);
+ $a_cli[0]->DeleteFile ($nesteaiorfile);
$N_CLI->Arguments("-s -k corbaloc::$imr_host:8888/nestea_server");
@@ -824,8 +1385,8 @@ sub perclient
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- if ($n_cli->WaitForFileTimed ($nesteaiorfile,$a_cli->ProcessStartWaitInterval()) == -1) {
- print STDERR "ERROR: cannot find file <$a_cli_nesteaiorfile>\n";
+ if ($n_cli->WaitForFileTimed ($nesteaiorfile,$a_cli[0]->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$n_cli_nesteaiorfile>\n";
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
@@ -856,7 +1417,6 @@ sub perclient
return $status;
}
-
###############################################################################
sub shutdown_repo
@@ -878,14 +1438,15 @@ sub shutdown_repo
# Specify an endpoint so that we can restart on the same port.
# Specify persistence so that we can test that shutdown-repo -a works after reconnect
- $IMR->Arguments ("-p $imr_testrepo -d 1 -orbendpoint iiop://:8888 -o $imr_imriorfile $refstyle ".
+ $IMR->Arguments ("-p $imr_testrepo -d 1 -orbendpoint iiop://:8888 -o $imr_imriorfile $imr_refstyle ".
"-ORBDebugLevel $debug_level");
- $IMR_status = $IMR->Spawn ();
+ my $IMR_status = $IMR->Spawn ();
if ($IMR_status != 0) {
print STDERR "ERROR: ImR Service returned $IMR_status\n";
return 1;
}
- if ($imr->WaitForFileTimed ($imriorfile,$imr->ProcessStartWaitInterval()) == -1) {
+ if ($imr->WaitForFileTimed ($imriorfile,
+ $imr->ProcessStartWaitInterval()) == -1) {
print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
@@ -908,7 +1469,7 @@ sub shutdown_repo
$ACT->Arguments ("-d 1 -o $act_actiorfile ".
"-orbobjrefstyle URL -ORBInitRef ImplRepoService=file://$act_imriorfile");
- $ACT_status = $ACT->Spawn ();
+ my $ACT_status = $ACT->Spawn ();
if ($ACT_status != 0) {
print STDERR "ERROR: ImR Activator returned $ACT_status\n";
return 1;
@@ -923,7 +1484,7 @@ sub shutdown_repo
# Kill the ImR, but leave the activator running
$TI->Arguments ("-orbobjrefstyle URL -ORBInitRef ImplRepoService=file://$ti_imriorfile ".
"shutdown-repo");
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ my $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
if ($TI_status != 0) {
print STDERR "ERROR: tao_imr returned $TI_status\n";
$ACT->Kill (); $ACT->TimedWait (1);
@@ -944,7 +1505,8 @@ sub shutdown_repo
print STDERR "ERROR: ImR Service returned $IMR_status\n";
return 1;
}
- if ($imr->WaitForFileTimed ($imriorfile,$imr->ProcessStartWaitInterval()) == -1) {
+ if ($imr->WaitForFileTimed ($imriorfile,
+ $imr->ProcessStartWaitInterval()) == -1) {
print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
@@ -993,35 +1555,65 @@ sub shutdown_repo
sub persistent_ir_test
{
+ my $backing_store_flag = shift;
my $status = 0;
+ if ($srv_debug_level == 0) {
+ $srv_debug_level = 1;
+ }
+
+ test_info("persistent_ir_test start\n");
+
+ my $backing_store;
+ if ($backing_store_flag eq "-p") {
+ $backing_store = "test.repo";
+ } elsif ($backing_store_flag eq "--directory") {
+ $backing_store = ".";
+ } elsif ($backing_store_flag eq "-x") {
+ $backing_store = "imr_backing_store.xml";
+ }
+
my $imr_imriorfile = $imr->LocalFile ($imriorfile);
- my $imr_storefile = $imr->LocalFile ($backing_store);
+ my $imr_storefile;
+ if (defined($backing_store)) {
+ $imr_storefile = $imr->LocalFile ($backing_store);
+ }
my $act_imriorfile = $act->LocalFile ($imriorfile);
my $ti_imriorfile = $ti->LocalFile ($imriorfile);
- my $a_srv_imriorfile = $a_srv->LocalFile ($imriorfile);
my $act_actiorfile = $act->LocalFile ($actiorfile);
- my $imr_airplaneiorfile = $imr->LocalFile ($airplaneiorfile);
- my $a_srv_airplaneiorfile = $a_srv->LocalFile ($airplaneiorfile);
+
+ my @a_srv_imriorfile;
+ my @imr_airplaneiorfile;
+ my @a_srv_airplaneiorfile;
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ push(@a_srv_imriorfile, $a_srv[$index]->LocalFile ($imriorfile));
+ push(@imr_airplaneiorfile, $imr->LocalFile ($airplaneiorfile[$index]));
+ push(@a_srv_airplaneiorfile, $a_srv[$index]->LocalFile ($airplaneiorfile[$index]));
+ $a_srv[$index]->DeleteFile ($imriorfile);
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $imr->DeleteFile ($airplaneiorfile[$index]);
+ }
$imr->DeleteFile ($imriorfile);
- $imr->DeleteFile ($backing_store);
+ if ($backing_store_flag eq "--directory") {
+ cleanup_replication($imr_storefile);
+ }
$act->DeleteFile ($imriorfile);
$ti->DeleteFile ($imriorfile);
- $a_srv->DeleteFile ($imriorfile);
$act->DeleteFile ($actiorfile);
- $imr->DeleteFile ($airplaneiorfile);
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
## Be sure to start the ImR on a consistent endpoint, so that any created IORs
## remain valid even if the ImR restarts.
- $IMR->Arguments ("-orbendpoint iiop://:8888 -x $imr_storefile -d 2 -o $imr_imriorfile $refstyle");
- $IMR_status = $IMR->Spawn ();
+ my $imr_arguments = "-orbendpoint iiop://:8888 $backing_store_flag $imr_storefile -d $test_debug_level -o $imr_imriorfile $imr_refstyle ";
+ $IMR->Arguments ("$imr_arguments -e ");
+ test_info("starting IMR=" . $IMR->CommandLine() . "\n");
+ my $IMR_status = $IMR->Spawn ();
if ($IMR_status != 0) {
print STDERR "ERROR: ImR Service returned $IMR_status\n";
return 1;
}
- if ($imr->WaitForFileTimed ($imriorfile,$imr->ProcessStartWaitInterval()) == -1) {
+ if ($imr->WaitForFileTimed ($imriorfile,
+ $imr->ProcessStartWaitInterval()) == -1) {
print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
@@ -1041,18 +1633,23 @@ sub persistent_ir_test
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- if ($a_srv->PutFile ($imriorfile) == -1) {
- print STDERR "ERROR: cannot set file <$a_srv_imriorfile>\n";
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->PutFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot set file <$a_srv_imriorfile[$index]>\n";
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
}
- $ACT->Arguments ("-d 2 -o $act_actiorfile -ORBInitRef ImplRepoService=file://$act_imriorfile");
- $ACT_status = $ACT->Spawn ();
+ $ACT->Arguments ("-d $test_debug_level -o $act_actiorfile -ORBInitRef ImplRepoService=file://$act_imriorfile");
+ test_info("starting ACT=" . $ACT->CommandLine() . "\n");
+ my $ACT_status = $ACT->Spawn ();
if ($ACT_status != 0) {
print STDERR "ERROR: ImR Activator returned $ACT_status\n";
return 1;
}
+
if ($act->WaitForFileTimed ($actiorfile,$act->ProcessStartWaitInterval()) == -1) {
print STDERR "ERROR: cannot find file <$act_actiorfile>\n";
$ACT->Kill (); $ACT->TimedWait (1);
@@ -1066,190 +1663,923 @@ sub persistent_ir_test
return 1;
}
- $p_srv->DeleteFile ($P_SRV_cmd);
- # Copy the server to a path with spaces to ensure that these
- # work corrrectly.
- copy ($A_SRV_cmd, $P_SRV_cmd);
- chmod(0755, $P_SRV_cmd);
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ $p_srv[$index]->DeleteFile ($P_SRV_cmd[$index]);
+ # Copy the server to a path with spaces to ensure that these
+ # work corrrectly.
+ copy ($A_SRV_cmd[$index], $P_SRV_cmd[$index]);
+ chmod(0755, $P_SRV_cmd[$index]);
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ # No need to specify imr_initref or -orbuseimr 1 for servers spawned by activator
+ $TI->Arguments (
+ "-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
+ "add $a_srv_name[$index] -c \"\\\"$imr_P_SRV_cmd[$index]\\\" " .
+ "$refstyle -s $a_srv_name[$index]\"");
+ test_info("starting TI=" . $TI->CommandLine() . "\n");
+ my $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+ $p_srv[$index]->DeleteFile ($P_SRV_cmd[$index]);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ ## This will write out the imr-ified IOR. Note : If you don't use -orbendpoint
+ ## when starting the ImR, then this IOR will no longer be valid when the ImR
+ ## restarts below. You can fix this by creating a new valid IOR, or starting
+ ## the ImR on a consistent endpoint.
+ $A_SRV[$index]->Arguments (
+ "-o $a_srv_airplaneiorfile[$index] -ORBUseIMR 1 $refstyle ".
+ "-ORBInitRef ImplRepoService=file://$a_srv_imriorfile[$index] ".
+ "-ORBDebugLevel $srv_debug_level -s $a_srv_name[$index]");
+ test_info("starting $a_srv_name[$index]=" .
+ $A_SRV[$index]->CommandLine() . "\n");
+ my $A_SRV_status = $A_SRV[$index]->Spawn ();
+ if ($A_SRV_status != 0) {
+ print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->WaitForFileTimed (
+ $airplaneiorfile[$index],
+ $a_srv[$index]->ProcessStartWaitInterval()) == -1) {
+ print STDERR
+ "ERROR: cannot find file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($a_srv[$index]->GetFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR
+ "ERROR: cannot retrieve file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($a_cli[$index]->PutFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("starting client for $a_srv_name[$index]=" .
+ $A_CLI[$index]->CommandLine() . "\n");
+ my $A_CLI_status = $A_CLI[$index]->Spawn ();
+ if ($A_CLI_status != 0) {
+ print STDERR
+ "ERROR: Airplane Client ($index) failed to spawn returning $A_CLI_status\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("killing client for $a_srv_name[$index]\n");
+ my $A_CLI_status = $A_CLI[$index]->WaitKill ($a_cli[$index]->ProcessStartWaitInterval());
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: Airplane Client ($index) returned $A_CLI_status\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
+ "shutdown $a_srv_name[$index]");
+ test_info("starting TI=" . $TI->CommandLine() . "\n");
+ my $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr shutdown returned $TI_status\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("killing $a_srv_name[$index]\n");
+ my $A_SRV_status = $A_SRV[$index]->WaitKill ($a_srv[$index]->ProcessStartWaitInterval());
+ if ($A_SRV_status != 0) {
+ print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("starting client for $a_srv_name[$index]\n");
+ # Should cause the activator to spawn another server.
+ my $A_CLI_status = $A_CLI[$index]->Spawn ();
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: Airplane Client 2 ($index) failed to spawn returning $A_CLI_status\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("killing client for $a_srv_name[$index]\n");
+ # Should cause the activator to spawn another server.
+ my $A_CLI_status = $A_CLI[$index]->WaitKill ($a_cli[$index]->ProcessStartWaitInterval());
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: Airplane Client 2 ($index) returned $A_CLI_status\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ # Shutdown airplane_server
+ $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
+ "shutdown $a_srv_name[$index]");
+ test_info("starting TI=" . $TI->CommandLine() . "\n");
+ my $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr shutdown 2 ($index) returned $TI_status\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("killing IMR=" . $IMR->CommandLine() . "\n");
+ my $IMR_status = $IMR->TerminateWaitKill ($imr->ProcessStopWaitInterval());
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: ImR returned $IMR_status\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
+ return 1;
+ }
+ }
- # No need to specify imr_initref or -orbuseimr 1 for servers spawned by activator
- $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
- "add airplane_server -c \"\\\"$imr_P_SRV_cmd\\\" $refstyle\"");
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
- if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr returned $TI_status\n";
- $p_srv->DeleteFile ($P_SRV_cmd);
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
- return 1;
+ # Unlink so that we can wait on them again to know the server started.
+ $imr->DeleteFile ($imriorfile);
+ $act->DeleteFile ($imriorfile);
+ $ti->DeleteFile ($imriorfile);
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ $a_srv[$index]->DeleteFile ($imriorfile);
}
- ## This will write out the imr-ified IOR. Note : If you don't use -orbendpoint
- ## when starting the ImR, then this IOR will no longer be valid when the ImR
- ## restarts below. You can fix this by creating a new valid IOR, or starting
- ## the ImR on a consistent endpoint.
- $A_SRV->Arguments ("-o $a_srv_airplaneiorfile -ORBUseIMR 1 $refstyle ".
- "-ORBInitRef ImplRepoService=file://$a_srv_imriorfile ".
- "-ORBDebugLevel $debug_level");
- $A_SRV_status = $A_SRV->Spawn ();
- if ($A_SRV_status != 0) {
- print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
+ print "Restarting Implementation Repository.\n";
+ $IMR->Arguments ("$imr_arguments ");
+ test_info("restarting IMR=" . $IMR->CommandLine() . "\n");
+ $IMR_status = $IMR->Spawn ();
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: ImR Service returned $IMR_status\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
return 1;
}
- if ($a_srv->WaitForFileTimed ($airplaneiorfile,$a_srv->ProcessStartWaitInterval()) == -1) {
- print STDERR "ERROR: cannot find file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ if ($imr->WaitForFileTimed ($imriorfile,
+ $imr->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- if ($a_srv->GetFile ($airplaneiorfile) == -1) {
- print STDERR "ERROR: cannot retrieve file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ if ($imr->GetFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$imr_imriorfile>\n";
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- if ($a_cli->PutFile ($airplaneiorfile) == -1) {
- print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ if ($act->PutFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot set file <$act_imriorfile>\n";
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
-
- $A_CLI_status = $A_CLI->SpawnWaitKill ($a_cli->ProcessStartWaitInterval());
- if ($A_CLI_status != 0) {
- print STDERR "ERROR: Airplane Client returned $A_CLI_status\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ if ($ti->PutFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot set file <$ti_imriorfile>\n";
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
- "shutdown airplane_server");
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
- if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr shutdown returned $TI_status\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->PutFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot set file <$a_srv_imriorfile[$index]>\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("starting client for $a_srv_name[$index]\n");
+ # Should cause the activator to spawn another server.
+ my $A_CLI_status = $A_CLI[$index]->Spawn ();
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: Airplane Client 3 ($index) failed to spawn returning $A_CLI_status\n";
+ $status = 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("killing client for $a_srv_name[$index]\n");
+ # Should cause the activator to spawn another server.
+ my $A_CLI_status = $A_CLI[$index]->WaitKill ($a_cli[$index]->ProcessStartWaitInterval()+5);
+ if ($A_CLI_status != 0) {
+ print STDERR "ERROR: Airplane Client 3 ($index) returned $A_CLI_status\n";
+ $status = 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ # Shutdown airplane_server
+ $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
+ "shutdown $a_srv_name[$index]");
+ test_info("starting TI=" . $TI->CommandLine() . "\n");
+ my $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr shutdown 3 returned $TI_status\n";
+ $status = 1;
+ }
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ test_info("killing ACT\n");
+ $ACT_status = $ACT->TerminateWaitKill ($act->ProcessStopWaitInterval());
+ if ($ACT_status != 0) {
+ print STDERR "ERROR: Activator returned $ACT_status\n";
+ $status = 1;
+ }
+ }
+
+ test_info("killing IMR\n");
+ $IMR_status = $IMR->TerminateWaitKill ($imr->ProcessStopWaitInterval());
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: ImR returned $IMR_status\n";
+ $status = 1;
+ }
+
+ if (!defined($backing_store)) {
+ # startup ImR with "-e" flag to ensure cleanup of registry entries
+ $IMR->Arguments ("$imr_arguments -e");
+ test_info("starting IMR=" . $IMR->CommandLine() . "\n");
+ $IMR_status = $IMR->Spawn ();
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: ImR Service returned $IMR_status\n";
+ return 1;
+ }
+
+ $IMR->TimedWait ($imr->ProcessStartWaitInterval());
+
+ test_info("killing IMR\n");
+ $IMR_status = $IMR->TerminateWaitKill ($imr->ProcessStopWaitInterval());
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: ImR returned $IMR_status\n";
+ $status = 1;
+ }
+ }
+ elsif ($backing_store_flag eq "--directory") {
+ cleanup_replication($backing_store);
+ }
+ else {
+ $imr->DeleteFile ($backing_store);
+ }
+ $imr->DeleteFile ($imriorfile);
+ $act->DeleteFile ($imriorfile);
+ $ti->DeleteFile ($imriorfile);
+ $act->DeleteFile ($actiorfile);
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ $imr->DeleteFile ($airplaneiorfile[$index]);
+ $a_srv[$index]->DeleteFile ($imriorfile);
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $p_srv[$index]->DeleteFile ($P_SRV_cmd[$index]);
+ }
+
+ return $status;
+}
+
+###############################################################################
+
+sub failover_test
+{
+ if (!$replica) {
+ # The failover test needs the -replica flag
+ return 0;
+ }
+
+ my $status = 0;
+
+ my $imr_port = 10001 + $imr->RandomPort ();
+ my $replica_imr_port = $imr_port + 10;
+
+ my %repo;
+ setup_repo(\%repo, $imr, $IMR, $imriorfile, $act, $ACT, $actiorfile, $ti,
+ $TI, $imr_port, "--primary", $backupiorfile);
+
+ my %backup_repo;
+ setup_repo(\%backup_repo, $replica_imr, $replica_IMR, $replica_imriorfile,
+ $act, $ACT, $actiorfile, $ti, $TI,
+ $replica_imr_port, "--backup", $primaryiorfile);
+
+ my @repo_for_srvr;
+ my @a_srv_imriorfile;
+ my @imr_airplaneiorfile;
+ my @a_srv_airplaneiorfile;
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($index == ($num_srvr - 1)) {
+ push(@repo_for_srvr, \%backup_repo);
+ } else {
+ push(@repo_for_srvr, \%repo);
+ }
+
+ push(@a_srv_imriorfile, $a_srv[$index]->LocalFile ($repo_for_srvr[$index]->{imriorfile}));
+ push(@imr_airplaneiorfile, $repo_for_srvr[$index]->{imr}->LocalFile ($airplaneiorfile[$index]));
+ push(@a_srv_airplaneiorfile, $a_srv[$index]->LocalFile ($airplaneiorfile[$index]));
+ $a_srv[$index]->DeleteFile ($repo_for_srvr[$index]->{imriorfile});
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $repo_for_srvr[$index]->{imr}->DeleteFile ($airplaneiorfile[$index]);
+ }
+ $imr->DeleteFile ($imriorfile);
+ $imr->DeleteFile ($primaryiorfile);
+ $act->DeleteFile ($imriorfile);
+ $ti->DeleteFile ($imriorfile);
+ $act->DeleteFile ($actiorfile);
+ $replica_imr->DeleteFile ($replica_imriorfile);
+ $replica_imr->DeleteFile ($backupiorfile);
+
+ print "\n\nstarting primary tao_imr_locator\n";
+ $repo{IMR}->Arguments ("-d $test_debug_level -o $repo{imr_imriorfile} " .
+ "$repo{imr_endpoint_flag} $imr_refstyle $repo{imr_backing_store_flag} ");
+ my $IMR_status = $repo{IMR}->Spawn ();
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: ImR Service returned $IMR_status\n";
return 1;
}
- $A_SRV_status = $A_SRV->WaitKill ($a_srv->ProcessStartWaitInterval());
- if ($A_SRV_status != 0) {
- print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+ if (wait_for_imr(\%backup_repo, "replicaiorfile")) {
return 1;
}
- # Should cause the activator to spawn another server.
- $A_CLI_status = $A_CLI->SpawnWaitKill ($a_cli->ProcessStartWaitInterval());
- if ($A_CLI_status != 0) {
- print STDERR "ERROR: Airplane Client 2 returned $A_CLI_status\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+ print "\n\nstarting backup tao_imr_locator\n";
+ $backup_repo{IMR}->Arguments ("-d $test_debug_level -o " .
+ "$backup_repo{imriorfile} $imr_refstyle " .
+ "$backup_repo{imr_endpoint_flag} " .
+ "$backup_repo{imr_backing_store_flag}");
+ my $replica_IMR_status = $backup_repo{IMR}->Spawn ();
+ if ($replica_IMR_status != 0) {
+ print STDERR "ERROR: ImR Service replica returned $replica_IMR_status\n";
+ return 1;
+ }
+ if (wait_for_imr(\%repo, "replicaiorfile")) {
return 1;
}
+ print "started backup tao_imr_locator\n";
- # Shutdown airplane_server
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
- if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr shutdown 2 returned $TI_status\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+ if (wait_for_imr(\%repo)) {
return 1;
}
+ print "started primary tao_imr_locator\n";
- $IMR_status = $IMR->TerminateWaitKill ($imr->ProcessStopWaitInterval());
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->PutFile ($repo_for_srvr[$index]->{imriorfile}) == -1) {
+ print STDERR "ERROR: cannot set file <$a_srv_imriorfile[$index]>\n";
+ kill_imr();
+ return 1;
+ }
+ }
+
+ print "\n\nstarting tao_imr_activator\n";
+ $repo{ACT}->Arguments ("-d $test_debug_level -o $repo{act_actiorfile} " .
+ "-ORBInitRef ImplRepoService=file://$repo{act_imriorfile} $refstyle " .
+ $repo{act_explicit_flag});
+ my $ACT_status = $repo{ACT}->Spawn ();
+ if ($ACT_status != 0) {
+ print STDERR "ERROR: ImR Activator returned $ACT_status\n";
+ return 1;
+ }
+
+ if ($repo{act}->WaitForFileTimed (
+ $repo{actiorfile},
+ $repo{act}->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <" .
+ $repo{act_actiorfile} . ">\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "started tao_imr_activator\n";
+
+ if (add_servers (\@repo_for_srvr, \@imr_airplaneiorfile) != 0) {
+ return 1;
+ }
+# for ($index = 0; $index < $num_srvr; ++$index) {
+# print "\n\nadding server $index using tao_imr\n";
+# $repo_for_srvr[$index]->{TI}->Arguments ("-ORBInitRef ImplRepoService" .
+# "=file://$repo_for_srvr[$index]->{ti_imriorfile} $refstyle " .
+# "add $a_srv_name[$index] -c \"$imr_A_SRV_cmd[$index] " .
+# "-o $imr_airplaneiorfile[$index] -s $a_srv_name[$index]\" " .
+# "$repo_for_srvr[$index]->{server_act_flag} ");
+# my $TI_status = $repo_for_srvr[$index]->{TI}->SpawnWaitKill (
+# $repo_for_srvr[$index]->{ti}->ProcessStartWaitInterval());
+# if ($TI_status != 0) {
+# print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+# kill_act();
+# kill_imr();
+# return 1;
+# }
+# print "added server $index with the locator using tao_imr\n";
+# }
+
+ if (add_servers_again (\@repo_for_srvr, \@imr_airplaneiorfile) != 0) {
+ return 1;
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nstarting server $index using tao_imr\n";
+ $repo_for_srvr[$index]->{TI}->Arguments ("-ORBInitRef ImplRepoService" .
+ "=file://$repo_for_srvr[$index]->{ti_imriorfile} $refstyle " .
+ "start $a_srv_name[$index]");
+ my $TI_status = $repo_for_srvr[$index]->{TI}->SpawnWaitKill (
+ $repo_for_srvr[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "started server $index using tao_imr\n";
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->WaitForFileTimed (
+ $airplaneiorfile[$index],
+ $a_srv[$index]->ProcessStartWaitInterval()) == -1) {
+ print STDERR
+ "ERROR: cannot find file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($a_srv[$index]->GetFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR
+ "ERROR: cannot retrieve file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($a_cli[$index]->PutFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ if (start_clients() != 0) {
+ return 1;
+ }
+
+ if (stop_clients() != 0) {
+ return 1;
+ }
+
+ if (shutdown_servers_using_tao_imr(\@repo_for_srvr) != 0) {
+ return 1;
+ }
+
+ if (start_clients() != 0) {
+ return 1;
+ }
+
+ if (stop_clients() != 0) {
+ return 1;
+ }
+
+ print "\n\nkilling the primary tao_imr_locator\n";
+ $IMR->Kill(); $IMR->TimedWait();
+ print "killed the primary tao_imr_locator\n";
+
+ if (start_clients() != 0) {
+ return 1;
+ }
+
+ if (stop_clients() != 0) {
+ return 1;
+ }
+
+ if (shutdown_servers_using_tao_imr(\@repo_for_srvr) != 0) {
+ return 1;
+ }
+
+ if (add_servers_again(\@repo_for_srvr, \@imr_airplaneiorfile) != 0) {
+ return 1;
+ }
+
+ if (remove_servers(\@repo_for_srvr) != 0) {
+ return 1;
+ }
+
+ if (add_servers(\@repo_for_srvr, \@imr_airplaneiorfile) != 0) {
+ return 1;
+ }
+
+ print "\n\nstarting primary tao_imr_locator again\n";
+ $imr->DeleteFile ($imriorfile);
+ $repo{IMR}->Arguments ("-d $test_debug_level -o $repo{imr_imriorfile} " .
+ "$imr_refstyle $repo{imr_endpoint_flag} $repo{imr_backing_store_flag}");
+ $IMR_status = $repo{IMR}->Spawn ();
if ($IMR_status != 0) {
- print STDERR "ERROR: ImR returned $IMR_status\n";
- $ACT->Kill (); $ACT->TimedWait (1);
+ print STDERR "ERROR: ImR Service returned $IMR_status\n";
return 1;
}
+ if (wait_for_imr(\%repo)) {
+ return 1;
+ }
+ print "started primary tao_imr_locator again\n";
- # Unlink so that we can wait on them again to know the server started.
+ if (start_clients() != 0) {
+ return 1;
+ }
+
+ if (stop_clients() != 0) {
+ return 1;
+ }
+
+ if (shutdown_servers_using_tao_imr(\@repo_for_srvr) != 0) {
+ return 1;
+ }
+
+ print "\n\nkilling the backup tao_imr_locator\n";
+ $replica_IMR->Kill(); $replica_IMR->TimedWait();
+ $replica_imr->DeleteFile ($replica_imriorfile);
+ print "killed the backup tao_imr_locator\n";
+
+ print "\n\nstarting backup tao_imr_locator\n";
+ $backup_repo{IMR}->Arguments ("-d $test_debug_level -o " .
+ "$backup_repo{imriorfile} $imr_refstyle " .
+ "$backup_repo{imr_endpoint_flag} " .
+ "$backup_repo{imr_backing_store_flag}");
+ $replica_IMR_status = $backup_repo{IMR}->Spawn ();
+ if ($replica_IMR_status != 0) {
+ print STDERR "ERROR: ImR Service replica returned $replica_IMR_status\n";
+ return 1;
+ }
+ if (wait_for_imr(\%repo, "replicaiorfile")) {
+ return 1;
+ }
+ print "started backup tao_imr_locator again\n";
+
+ if (start_clients() != 0) {
+ return 1;
+ }
+
+ if (stop_clients() != 0) {
+ return 1;
+ }
+
+ if (shutdown_servers_using_tao_imr(\@repo_for_srvr) != 0) {
+ return 1;
+ }
+
+ $IMR->Kill(); $IMR->TimedWait();
+ $replica_IMR->Kill(); $replica_IMR->TimedWait();
+ $ACT->Kill(); $ACT->TimedWait();
+
+ cleanup_replication ();
+
+ # clean up IOR files
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ $a_srv[$index]->DeleteFile ($repo_for_srvr[$index]->{imriorfile});
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $repo_for_srvr[$index]->{imr}->DeleteFile ($airplaneiorfile[$index]);
+ }
$imr->DeleteFile ($imriorfile);
+ $imr->DeleteFile ($primaryiorfile);
$act->DeleteFile ($imriorfile);
$ti->DeleteFile ($imriorfile);
- $a_srv->DeleteFile ($imriorfile);
- print "Restarting Implementation Repository.\n";
- $IMR_status = $IMR->Spawn ();
+ $act->DeleteFile ($actiorfile);
+ $replica_imr->DeleteFile ($replica_imriorfile);
+ $replica_imr->DeleteFile ($backupiorfile);
+
+ return $status;
+}
+
+###############################################################################
+
+sub persistent_ft_test
+{
+ my $corrupted = shift;
+
+ if (!$corrupted) {
+ $corrupted = 0;
+ }
+
+ if (!$replica) {
+ # The persistent_ft test needs the -replica flag
+ return 0;
+ }
+
+ my $status = 0;
+
+ my $imr_port = 10001 + $imr->RandomPort ();
+ my $replica_imr_port = $imr_port + 1;
+
+ my %repo;
+ setup_repo(\%repo, $imr, $IMR, $imriorfile, $act, $ACT, $actiorfile, $ti,
+ $TI, $imr_port, "--primary", $backupiorfile);
+
+ my %backup_repo;
+ setup_repo(\%backup_repo, $replica_imr, $replica_IMR, $replica_imriorfile,
+ $act, $ACT, $actiorfile, $ti, $TI,
+ $replica_imr_port, "--backup", $primaryiorfile);
+
+ my @repo_for_srvr;
+ my @a_srv_imriorfile;
+ my @imr_airplaneiorfile;
+ my @a_srv_airplaneiorfile;
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($index == ($num_srvr - 1)) {
+ push(@repo_for_srvr, \%backup_repo);
+ } else {
+ push(@repo_for_srvr, \%repo);
+ }
+
+ push(@a_srv_imriorfile, $a_srv[$index]->LocalFile ($repo_for_srvr[$index]->{imriorfile}));
+ push(@imr_airplaneiorfile, $repo_for_srvr[$index]->{imr}->LocalFile ($airplaneiorfile[$index]));
+ push(@a_srv_airplaneiorfile, $a_srv[$index]->LocalFile ($airplaneiorfile[$index]));
+ $a_srv[$index]->DeleteFile ($repo_for_srvr[$index]->{imriorfile});
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $repo_for_srvr[$index]->{imr}->DeleteFile ($airplaneiorfile[$index]);
+ }
+ $imr->DeleteFile ($imriorfile);
+ $imr->DeleteFile ($primaryiorfile);
+ $act->DeleteFile ($imriorfile);
+ $ti->DeleteFile ($imriorfile);
+ $act->DeleteFile ($actiorfile);
+ $replica_imr->DeleteFile ($replica_imriorfile);
+ $replica_imr->DeleteFile ($backupiorfile);
+
+ print "\n\nstarting primary tao_imr_locator\n";
+ $repo{IMR}->Arguments ("-d $test_debug_level -o $repo{imr_imriorfile} " .
+ "$imr_refstyle $repo{imr_endpoint_flag} $repo{imr_backing_store_flag}");
+print "Comment line arguments: -d $test_debug_level -o $repo{imr_imriorfile} " . "$imr_refstyle $repo{imr_endpoint_flag} $repo{imr_backing_store_flag}\n";
+ my $IMR_status = $repo{IMR}->Spawn ();
if ($IMR_status != 0) {
print STDERR "ERROR: ImR Service returned $IMR_status\n";
- $ACT->Kill (); $ACT->TimedWait (1);
return 1;
}
- if ($imr->WaitForFileTimed ($imriorfile,$imr->ProcessStartWaitInterval()) == -1) {
- print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+
+ if (wait_for_imr(\%backup_repo, "replicaiorfile")) {
return 1;
}
- if ($imr->GetFile ($imriorfile) == -1) {
- print STDERR "ERROR: cannot retrieve file <$imr_imriorfile>\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+
+ print "\n\nstarting backup tao_imr_locator\n";
+ $backup_repo{IMR}->Arguments ("-d $test_debug_level -o " .
+ "$backup_repo{imriorfile} $imr_refstyle " .
+ "$backup_repo{imr_endpoint_flag} " .
+ "$backup_repo{imr_backing_store_flag}");
+ my $replica_IMR_status = $backup_repo{IMR}->Spawn ();
+ if ($replica_IMR_status != 0) {
+ print STDERR "ERROR: ImR Service replica returned $replica_IMR_status\n";
return 1;
}
- if ($act->PutFile ($imriorfile) == -1) {
- print STDERR "ERROR: cannot set file <$act_imriorfile>\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+ if (wait_for_imr(\%repo, "replicaiorfile")) {
return 1;
}
- if ($ti->PutFile ($imriorfile) == -1) {
- print STDERR "ERROR: cannot set file <$ti_imriorfile>\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+ print "started backup tao_imr_locator\n";
+
+ if (wait_for_imr(\%repo)) {
return 1;
}
- if ($a_srv->PutFile ($imriorfile) == -1) {
- print STDERR "ERROR: cannot set file <$a_srv_imriorfile>\n";
- $ACT->Kill (); $ACT->TimedWait (1);
- $IMR->Kill (); $IMR->TimedWait (1);
+ print "started primary tao_imr_locator\n";
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->PutFile ($repo_for_srvr[$index]->{imriorfile}) == -1) {
+ print STDERR "ERROR: cannot set file <$a_srv_imriorfile[$index]>\n";
+ kill_imr();
+ return 1;
+ }
+ }
+
+ print "\n\nstarting tao_imr_activator\n";
+ $repo{ACT}->Arguments ("-d $test_debug_level -o $repo{act_actiorfile} " .
+ "-ORBInitRef ImplRepoService=file://$repo{act_imriorfile} $refstyle " .
+ $repo{act_explicit_flag});
+ my $ACT_status = $repo{ACT}->Spawn ();
+ if ($ACT_status != 0) {
+ print STDERR "ERROR: ImR Activator returned $ACT_status\n";
return 1;
}
- # Should cause the activator to spawn another server.
- $A_CLI_status = $A_CLI->SpawnWaitKill ($a_cli->ProcessStartWaitInterval()+5);
- if ($A_CLI_status != 0) {
- print STDERR "ERROR: Airplane Client 3 returned $A_CLI_status\n";
- $status = 1;
+ if ($repo{act}->WaitForFileTimed (
+ $repo{actiorfile},
+ $repo{act}->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <" .
+ $repo{act_actiorfile} . ">\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "started tao_imr_activator\n";
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nupdating server $index using tao_imr\n";
+ $repo_for_srvr[$index]->{TI}->Arguments ("-ORBInitRef ImplRepoService" .
+ "=file://$repo_for_srvr[$index]->{ti_imriorfile} $refstyle " .
+ "update $a_srv_name[$index] -c \"$imr_A_SRV_cmd[$index] " .
+ "-o $imr_airplaneiorfile[$index] -s $a_srv_name[$index]\" " .
+ "$repo_for_srvr[$index]->{server_act_flag} ");
+ my $TI_status = $repo_for_srvr[$index]->{TI}->SpawnWaitKill (
+ $repo_for_srvr[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "updated server $index with the locator using tao_imr\n";
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ print "\n\nstarting server $index using tao_imr\n";
+ $repo_for_srvr[$index]->{TI}->Arguments ("-ORBInitRef ImplRepoService" .
+ "=file://$repo_for_srvr[$index]->{ti_imriorfile} $refstyle " .
+ "start $a_srv_name[$index]");
+ my $TI_status = $repo_for_srvr[$index]->{TI}->SpawnWaitKill (
+ $repo_for_srvr[$index]->{ti}->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr ($index) returned $TI_status\n";
+ kill_act();
+ kill_imr();
+ return 1;
+ }
+ print "started server $index using tao_imr\n";
+ }
+
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ if ($a_srv[$index]->WaitForFileTimed (
+ $airplaneiorfile[$index],
+ $a_srv[$index]->ProcessStartWaitInterval()) == -1) {
+ print STDERR
+ "ERROR: cannot find file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($a_srv[$index]->GetFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR
+ "ERROR: cannot retrieve file <$a_srv_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($a_cli[$index]->PutFile ($airplaneiorfile[$index]) == -1) {
+ print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ }
+
+ if (start_clients() != 0) {
+ return 1;
+ }
+
+ if (stop_clients() != 0) {
+ return 1;
+ }
+
+ if (shutdown_servers_using_tao_imr(\@repo_for_srvr) != 0) {
+ return 1;
+ }
+
+ print "\n\nkilling the primary tao_imr_locator\n";
+ $IMR->Kill(); $IMR->TimedWait();
+ $imr->DeleteFile ($imriorfile);
+ $imr->DeleteFile ($primaryiorfile);
+ print "killed the primary tao_imr_locator\n";
+
+ print "\n\nkilling the backup tao_imr_locator\n";
+ $replica_IMR->Kill(); $replica_IMR->TimedWait();
+ $replica_imr->DeleteFile ($replica_imriorfile);
+ $replica_imr->DeleteFile ($backupiorfile);
+ print "killed the backup tao_imr_locator\n";
+
+ if($corrupted == 1){
+ my $file= "./imr_listing.xml";
+ if (open LIST_FILE, ">$file") {
+ print LIST_FILE "I'm corrupt!!!";
+ }
+ } elsif ($corrupted > 1) {
+ my $file = "./1_" .($corrupted -1). ".xml";
+ if (open LIST_FILE, ">$file") {
+ print LIST_FILE "I'm corrupt!!!";
+ }
+ }
+
+
+ print "\n\nstarting primary tao_imr_locator again\n";
+ $repo{IMR}->Arguments ("-d $test_debug_level -o $repo{imr_imriorfile} " .
+ "$imr_refstyle $repo{imr_endpoint_flag} $repo{imr_backing_store_flag}");
+
+ my $test_stdout_file = $imr->LocalFile ($stdout_file);
+ my $test_stderr_file = $imr->LocalFile ($stderr_file);
+
+ $imr->DeleteFile ($stdout_file);
+ $imr->DeleteFile ($stderr_file);
+
+# Rely on return value only, so redirect output
+ redirect_output($test_stdout_file,$test_stderr_file);
+ $IMR_status = $repo{IMR}->Spawn ();
+ restore_output();
+
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: ImR Service returned $IMR_status\n";
+ return 1;
}
- # Shutdown airplane_server
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
- if ($TI_status != 0) {
- print STDERR "ERROR: tao_imr shutdown 3 returned $TI_status\n";
- $status = 1;
+ if ($repo{imr}->WaitForFileTimed($primaryiorfile,
+ $repo{imr}->ProcessStartWaitInterval()) == -1) {
+ return 1;
}
- $ACT_status = $ACT->TerminateWaitKill ($act->ProcessStopWaitInterval());
- if ($ACT_status != 0) {
- print STDERR "ERROR: Activator returned $ACT_status\n";
- $status = 1;
+ print "\n\nstarting backup tao_imr_locator again\n";
+ $backup_repo{IMR}->Arguments ("-d $test_debug_level -o " .
+ "$backup_repo{imriorfile} $imr_refstyle " .
+ "$backup_repo{imr_endpoint_flag} " .
+ "$backup_repo{imr_backing_store_flag}");
+
+ redirect_output($test_stdout_file,$test_stderr_file);
+ $replica_IMR_status = $backup_repo{IMR}->Spawn ();
+ restore_output();
+
+ if ($replica_IMR_status != 0) {
+ print STDERR "ERROR: ImR Service replica returned $replica_IMR_status\n";
+ return 1;
+ }
+ if ($backup_repo{imr}->WaitForFileTimed($backupiorfile,
+ $backup_repo{imr}->ProcessStartWaitInterval()) == -1) {
+ return 1;
}
+ print "started backup tao_imr_locator again\n";
- $IMR_status = $IMR->TerminateWaitKill ($imr->ProcessStopWaitInterval());
- if ($IMR_status != 0) {
- print STDERR "ERROR: ImR returned $IMR_status\n";
- $status = 1;
+ if (start_clients() != 0) {
+ return 1;
+ }
+
+ if (stop_clients() != 0) {
+ return 1;
}
+ if (shutdown_servers_using_tao_imr(\@repo_for_srvr) != 0) {
+ return 1;
+ }
+
+ $IMR->Kill(); $IMR->TimedWait();
+ $replica_IMR->Kill(); $replica_IMR->TimedWait();
+ $ACT->Kill(); $ACT->TimedWait();
+
+ cleanup_replication ();
+
+ # clean up IOR files
+ for ($index = 0; $index < $num_srvr; ++$index) {
+ $a_srv[$index]->DeleteFile ($repo_for_srvr[$index]->{imriorfile});
+ $a_srv[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $a_cli[$index]->DeleteFile ($airplaneiorfile[$index]);
+ $repo_for_srvr[$index]->{imr}->DeleteFile ($airplaneiorfile[$index]);
+ }
$imr->DeleteFile ($imriorfile);
- $imr->DeleteFile ($backing_store);
+ $imr->DeleteFile ($primaryiorfile);
$act->DeleteFile ($imriorfile);
$ti->DeleteFile ($imriorfile);
- $a_srv->DeleteFile ($imriorfile);
$act->DeleteFile ($actiorfile);
- $imr->DeleteFile ($airplaneiorfile);
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
- $p_srv->DeleteFile ($P_SRV_cmd);
+ $replica_imr->DeleteFile ($replica_imriorfile);
+ $replica_imr->DeleteFile ($backupiorfile);
return $status;
}
@@ -1263,30 +2593,31 @@ sub both_ir_test
my $imr_imriorfile = $imr->LocalFile ($imriorfile);
my $act_imriorfile = $act->LocalFile ($imriorfile);
my $ti_imriorfile = $ti->LocalFile ($imriorfile);
- my $a_srv_imriorfile = $a_srv->LocalFile ($imriorfile);
+ my $a_srv_imriorfile = $a_srv[0]->LocalFile ($imriorfile);
my $n_srv_imriorfile = $n_srv->LocalFile ($imriorfile);
my $act_actiorfile = $act->LocalFile ($actiorfile);
- my $a_srv_airplaneiorfile = $a_srv->LocalFile ($airplaneiorfile);
+ my $a_srv_airplaneiorfile = $a_srv[0]->LocalFile ($airplaneiorfile[0]);
my $n_srv_nesteaiorfile = $n_srv->LocalFile ($nesteaiorfile);
my $n_cli_nesteaiorfile = $n_cli->LocalFile ($nesteaiorfile);
$imr->DeleteFile ($imriorfile);
$act->DeleteFile ($imriorfile);
$ti->DeleteFile ($imriorfile);
- $a_srv->DeleteFile ($imriorfile);
+ $a_srv[0]->DeleteFile ($imriorfile);
$n_srv->DeleteFile ($imriorfile);
$act->DeleteFile ($actiorfile);
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
+ $a_srv[0]->DeleteFile ($airplaneiorfile[0]);
+ $a_cli[0]->DeleteFile ($airplaneiorfile[0]);
$n_srv->DeleteFile ($nesteaiorfile);
$n_cli->DeleteFile ($nesteaiorfile);
- $IMR->Arguments ("-d 2 -t 10 -o $imr_imriorfile $refstyle");
- $IMR_status = $IMR->Spawn ();
+ $IMR->Arguments ("-d $test_debug_level -t 10 -o $imr_imriorfile $imr_refstyle");
+ my $IMR_status = $IMR->Spawn ();
if ($IMR_status != 0) {
print STDERR "ERROR: ImR Service returned $IMR_status\n";
return 1;
}
- if ($imr->WaitForFileTimed ($imriorfile,$imr->ProcessStartWaitInterval()) == -1) {
+ if ($imr->WaitForFileTimed ($imriorfile,
+ $imr->ProcessStartWaitInterval()) == -1) {
print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
@@ -1306,7 +2637,7 @@ sub both_ir_test
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- if ($a_srv->PutFile ($imriorfile) == -1) {
+ if ($a_srv[0]->PutFile ($imriorfile) == -1) {
print STDERR "ERROR: cannot set file <$a_srv_imriorfile>\n";
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
@@ -1319,8 +2650,8 @@ sub both_ir_test
$ACT->Arguments ("-e 16384 -o $act_actiorfile ".
"-ORBInitRef ImplRepoService=file://$act_imriorfile ".
- "$refstyle -d 2");
- $ACT_status = $ACT->Spawn ();
+ "$refstyle -d $test_debug_level");
+ my $ACT_status = $ACT->Spawn ();
if ($ACT_status != 0) {
print STDERR "ERROR: ImR Activator returned $ACT_status\n";
return 1;
@@ -1339,7 +2670,7 @@ sub both_ir_test
# No need to specify imr_initref or -orbuseimr 1 for servers spawned by activator
$TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
"add nestea_server -c \"$imr_N_SRV_cmd $refstyle\"");
- $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ my $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
if ($TI_status != 0) {
print STDERR "ERROR: tao_imr returned $TI_status\n";
$ACT->Kill (); $ACT->TimedWait (1);
@@ -1349,7 +2680,7 @@ sub both_ir_test
# No need to specify imr_initref or -orbuseimr 1 for servers spawned by activator
$TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
- "add airplane_server -c \"$imr_A_SRV_cmd $refstyle\"");
+ "add $a_srv_name[0] -c \"$imr_A_SRV_cmd[0] $refstyle -s $a_srv_name[0]\"");
$TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
if ($TI_status != 0) {
print STDERR "ERROR: tao_imr returned $TI_status\n";
@@ -1361,8 +2692,8 @@ sub both_ir_test
$N_SRV->Arguments (" -o $n_srv_nesteaiorfile -ORBUseIMR 1 ".
"-ORBInitRef ImplRepoService=file://$n_srv_imriorfile ".
"$refstyle ".
- "-ORBDebugLevel $debug_level");
- $N_SRV_status = $N_SRV->Spawn ();
+ "-ORBDebugLevel $srv_debug_level");
+ my $N_SRV_status = $N_SRV->Spawn ();
if ($N_SRV_status != 0) {
print STDERR "ERROR: Nestea Server returned $N_SRV_status\n";
$N_SRV->Kill (); $N_SRV->TimedWait (1);
@@ -1392,38 +2723,38 @@ sub both_ir_test
return 1;
}
- $A_SRV->Arguments (" -o $a_srv_airplaneiorfile -ORBUseIMR 1 ".
- "-ORBInitRef ImplRepoService=file://$n_srv_imriorfile ".
- "$refstyle ".
- "-ORBDebugLevel $debug_level");
- $A_SRV_status = $A_SRV->Spawn ();
+ $A_SRV[0]->Arguments (
+ " -o $a_srv_airplaneiorfile -ORBUseIMR 1 ".
+ "-ORBInitRef ImplRepoService=file://$n_srv_imriorfile ".
+ "$refstyle -ORBDebugLevel $srv_debug_level -s $a_srv_name[0]");
+ my $A_SRV_status = $A_SRV[0]->Spawn ();
if ($A_SRV_status != 0) {
print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ kill_then_timed_wait(\@A_SRV, 1);
$N_SRV->Kill (); $N_SRV->TimedWait (1);
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- if ($a_srv->WaitForFileTimed ($airplaneiorfile,$a_srv->ProcessStartWaitInterval()) == -1) {
+ if ($a_srv[0]->WaitForFileTimed ($airplaneiorfile[0],$a_srv[0]->ProcessStartWaitInterval()) == -1) {
print STDERR "ERROR: cannot find file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ kill_then_timed_wait(\@A_SRV, 1);
$N_SRV->Kill (); $N_SRV->TimedWait (1);
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- if ($a_srv->GetFile ($airplaneiorfile) == -1) {
+ if ($a_srv[0]->GetFile ($airplaneiorfile[0]) == -1) {
print STDERR "ERROR: cannot retrieve file <$a_srv_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ kill_then_timed_wait(\@A_SRV, 1);
$N_SRV->Kill (); $N_SRV->TimedWait (1);
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
return 1;
}
- if ($a_cli->PutFile ($airplaneiorfile) == -1) {
- print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile>\n";
- $A_SRV->Kill (); $A_SRV->TimedWait (1);
+ if ($a_cli[0]->PutFile ($airplaneiorfile[0]) == -1) {
+ print STDERR "ERROR: cannot set file <$a_cli_airplaneiorfile[$index]>\n";
+ kill_then_timed_wait(\@A_SRV, 1);
$N_SRV->Kill (); $N_SRV->TimedWait (1);
$ACT->Kill (); $ACT->TimedWait (1);
$IMR->Kill (); $IMR->TimedWait (1);
@@ -1441,7 +2772,7 @@ sub both_ir_test
print "\n## Spawning multiple simultaneous clients with both servers running.\n";
map $_->Spawn(), @a_clients;
map $_->Spawn(), @n_clients;
- map $_->WaitKill($a_cli->ProcessStopWaitInterval()), @a_clients;
+ map $_->WaitKill($a_cli[0]->ProcessStopWaitInterval()), @a_clients;
map $_->WaitKill($n_cli->ProcessStopWaitInterval()), @n_clients;
$TI->Arguments ("-ORBInitRef ImplRepoService=file://$n_srv_imriorfile ".
@@ -1453,14 +2784,14 @@ sub both_ir_test
}
$TI->Arguments ("-ORBInitRef ImplRepoService=file://$n_srv_imriorfile ".
- "shutdown airplane_server");
+ "shutdown $a_srv_name[0]");
$TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
if ($TI_status != 0) {
print STDERR "ERROR: tao_imr returned $TI_status\n";
$status = 1;
}
- $A_SRV_status = $A_SRV->WaitKill ($a_srv->ProcessStopWaitInterval());
+ $A_SRV_status = $A_SRV[0]->WaitKill ($a_srv[0]->ProcessStopWaitInterval());
if ($A_SRV_status != 0) {
print STDERR "ERROR: Airplane Server returned $A_SRV_status\n";
$status = 1;
@@ -1475,7 +2806,7 @@ sub both_ir_test
map $_->Spawn(), @a_clients;
map $_->Spawn(), @n_clients;
- map $_->WaitKill($a_cli->ProcessStopWaitInterval()), @a_clients;
+ map $_->WaitKill($a_cli[0]->ProcessStopWaitInterval()), @a_clients;
map $_->WaitKill($n_cli->ProcessStopWaitInterval()), @n_clients;
$TI->Arguments ("-ORBInitRef ImplRepoService=file://$n_srv_imriorfile ".
@@ -1487,7 +2818,7 @@ sub both_ir_test
}
$TI->Arguments ("-ORBInitRef ImplRepoService=file://$n_srv_imriorfile ".
- "shutdown airplane_server");
+ "shutdown $a_srv_name[0]");
$TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
if ($TI_status != 0) {
print STDERR "ERROR: tao_imr returned $TI_status\n";
@@ -1509,11 +2840,11 @@ sub both_ir_test
$imr->DeleteFile ($imriorfile);
$act->DeleteFile ($imriorfile);
$ti->DeleteFile ($imriorfile);
- $a_srv->DeleteFile ($imriorfile);
+ $a_srv[0]->DeleteFile ($imriorfile);
$n_srv->DeleteFile ($imriorfile);
$act->DeleteFile ($actiorfile);
- $a_srv->DeleteFile ($airplaneiorfile);
- $a_cli->DeleteFile ($airplaneiorfile);
+ $a_srv[0]->DeleteFile ($airplaneiorfile[0]);
+ $a_cli[0]->DeleteFile ($airplaneiorfile[0]);
$n_srv->DeleteFile ($nesteaiorfile);
$n_cli->DeleteFile ($nesteaiorfile);
@@ -1526,16 +2857,52 @@ sub both_ir_test
# Parse the arguments
my $ret = 0;
+my $test_num = 0;
+
+my @tests = ("airplane", "airplane_ir", "nestea", "nestea_ir",
+ "both_ir", "persistent_ir", "persistent_ir_hash",
+ "persistent_ir_shared", "persistent_ft", "failover");
+my @nt_tests = ("nt_service_ir", "persistent_ir_registry");
+
+my $i;
+if ($all_tests) {
+ push(@ARGV, @tests);
+}
-if ($#ARGV >= 0) {
-for (my $i = 0; $i <= $#ARGV; $i++) {
+if ($#ARGV == -1) {
+ $ret = both_ir_test();
+}
+
+my $append = "";
+for ($i = 0; $i <= $#ARGV; $i++) {
if ($ARGV[$i] eq "-h" || $ARGV[$i] eq "-?") {
- print "run_test test\n";
+ print "run_test [options] test\n";
print "\n";
+ print "options \n";
+ print " -debug -- set debug_level to 10\n";
+ print " -tdebug -- set the tests debug level to 10\n";
+ print " -all -- causes all tests to run (except nt_service_ir and\n";
+ print " persistent_ir_registry)\n";
+ print " -servers -- run tests with more than 1 server and client\n";
+ print " -replica -- run tests with more than 1 server and client interacting\n";
+ print " with replicated ImR Locators\n";
print "test -- Runs a specific test:\n";
- print " airplane, airplane_ir, nt_service_ir, ",
- "nestea, nestea_ir,\n";
- print " both_ir, persistent_ir\n";
+ my $indent = " ";
+ print "$indent";
+ my $count = 0;
+ my @all_tests = @tests;
+ push(@all_tests, @nt_tests);
+ foreach my $test (@all_tests) {
+ if (++$count > 1) {
+ print ",$append";
+ }
+ print "$test";
+ $append = "";
+ if ($count % 3 == 0) {
+ $append = "\n$indent";
+ }
+ }
+ print "\n";
exit 1;
}
elsif ($ARGV[$i] eq "airplane") {
@@ -1557,7 +2924,31 @@ for (my $i = 0; $i <= $#ARGV; $i++) {
$ret = both_ir_test ();
}
elsif ($ARGV[$i] eq "persistent_ir") {
- $ret = persistent_ir_test ();
+ $ret = persistent_ir_test ("-x");
+ }
+ elsif ($ARGV[$i] eq "persistent_ir_hash") {
+ $ret = persistent_ir_test ("-p");
+ }
+ elsif ($ARGV[$i] eq "persistent_ir_registry") {
+ $ret = persistent_ir_test ("-r");
+ }
+ elsif ($ARGV[$i] eq "persistent_ir_shared") {
+ $ret = persistent_ir_test ("--directory");
+ }
+ elsif ($ARGV[$i] eq "persistent_ft") {
+ $ret = persistent_ft_test ();
+ }
+ elsif ($ARGV[$i] eq "persistent_listingcorrupt") {
+ $ret = persistent_ft_test (1);
+ }
+ elsif ($ARGV[$i] eq "persistent_activatorcorrupt") {
+ $ret = persistent_ft_test (2);
+ }
+ elsif ($ARGV[$i] eq "persistent_servercorrupt") {
+ $ret = persistent_ft_test (3);
+ }
+ elsif ($ARGV[$i] eq "failover") {
+ $ret = failover_test ();
}
elsif ($ARGV[$i] eq "perclient") {
$ret = perclient();
@@ -1565,12 +2956,12 @@ for (my $i = 0; $i <= $#ARGV; $i++) {
elsif ($ARGV[$i] eq "shutdown") {
$ret = shutdown_repo();
}
- else {
+ elsif ($ARGV[$i] !~ /^-/) {
print "run_test: Unknown Option: ".$ARGV[$i]."\n";
}
-}
-} else {
- $ret = both_ir_test();
+ if ($ret != 0) {
+ last;
+ }
}
exit $ret;
diff --git a/TAO/orbsvcs/tests/Notify/Bug_1884_Regression/common.h b/TAO/orbsvcs/tests/Notify/Bug_1884_Regression/common.h
index 4ba52e0064b..4f9a251dfcd 100644
--- a/TAO/orbsvcs/tests/Notify/Bug_1884_Regression/common.h
+++ b/TAO/orbsvcs/tests/Notify/Bug_1884_Regression/common.h
@@ -61,12 +61,12 @@ get_event_channel(CORBA::ORB_ptr orb)
else {
try
{
- ec = factory->get_event_channel(channelIdSeq[0]);
+ ec = factory->get_event_channel(channelIdSeq.in()[0]);
}
catch (CosNotifyChannelAdmin::ChannelNotFound& )
{
std::cerr << "ChannelNotFound: "
- << channelIdSeq[0] << std::endl;
+ << channelIdSeq.in()[0] << std::endl;
throw;
}
diff --git a/TAO/orbsvcs/tests/Notify/Bug_1884_Regression/filter.cpp b/TAO/orbsvcs/tests/Notify/Bug_1884_Regression/filter.cpp
index 8c3ac52b03a..6612fc33e43 100644
--- a/TAO/orbsvcs/tests/Notify/Bug_1884_Regression/filter.cpp
+++ b/TAO/orbsvcs/tests/Notify/Bug_1884_Regression/filter.cpp
@@ -68,12 +68,12 @@ get_event_channel(CORBA::ORB_ptr orb)
else {
try
{
- ec = factory->get_event_channel(channelIdSeq[0]);
+ ec = factory->get_event_channel(channelIdSeq.in()[0]);
}
catch (CosNotifyChannelAdmin::ChannelNotFound&)
{
std::cerr << "ChannelNotFound: "
- << channelIdSeq[0] << std::endl;
+ << channelIdSeq.in()[0] << std::endl;
exit(1);
}
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688_Regression/common.h b/TAO/orbsvcs/tests/Notify/Bug_3688_Regression/common.h
index 4ba52e0064b..4f9a251dfcd 100755
--- a/TAO/orbsvcs/tests/Notify/Bug_3688_Regression/common.h
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688_Regression/common.h
@@ -61,12 +61,12 @@ get_event_channel(CORBA::ORB_ptr orb)
else {
try
{
- ec = factory->get_event_channel(channelIdSeq[0]);
+ ec = factory->get_event_channel(channelIdSeq.in()[0]);
}
catch (CosNotifyChannelAdmin::ChannelNotFound& )
{
std::cerr << "ChannelNotFound: "
- << channelIdSeq[0] << std::endl;
+ << channelIdSeq.in()[0] << std::endl;
throw;
}
diff --git a/TAO/orbsvcs/tests/Notify/Persistent_Filter/Filter.cpp b/TAO/orbsvcs/tests/Notify/Persistent_Filter/Filter.cpp
index 70e81593cce..548705dcfe7 100644
--- a/TAO/orbsvcs/tests/Notify/Persistent_Filter/Filter.cpp
+++ b/TAO/orbsvcs/tests/Notify/Persistent_Filter/Filter.cpp
@@ -287,7 +287,7 @@ FilterClient::get_EC ()
const int TIMEOUT = 20;
while (i < TIMEOUT)
{
- CosNotifyChannelAdmin::ChannelIDSeq_var ids
+ const CosNotifyChannelAdmin::ChannelIDSeq_var ids
= notify_factory_->get_all_channels ();
if (ids->length () > 0)
@@ -350,7 +350,7 @@ FilterClient::create_supplieradmin ()
void
FilterClient::get_supplieradmin ()
{
- CosNotifyChannelAdmin::AdminIDSeq_var ids
+ const CosNotifyChannelAdmin::AdminIDSeq_var ids
= ec_->get_all_supplieradmins();
ACE_ASSERT (ids->length () == 1);
@@ -429,7 +429,7 @@ FilterClient::create_consumeradmin ()
void
FilterClient::get_consumeradmin ()
{
- CosNotifyChannelAdmin::AdminIDSeq_var ids
+ const CosNotifyChannelAdmin::AdminIDSeq_var ids
= ec_->get_all_consumeradmins();
ACE_ASSERT (ids->length () == 2);
@@ -460,7 +460,7 @@ FilterClient::verify_filter (CosNotifyFilter::FilterAdmin_var& admin,
ACE_UNUSED_ARG (constraint_expr);
// only used to validate assert, which is
// compiled out for nondebug builds.
- CosNotifyFilter::FilterIDSeq_var ids
+ const CosNotifyFilter::FilterIDSeq_var ids
= admin->get_all_filters ();
ACE_ASSERT (ids->length () == 1);
diff --git a/TAO/orbsvcs/tests/Redundant_Naming/client.cpp b/TAO/orbsvcs/tests/Redundant_Naming/client.cpp
index f54ada2e199..483b787c224 100644
--- a/TAO/orbsvcs/tests/Redundant_Naming/client.cpp
+++ b/TAO/orbsvcs/tests/Redundant_Naming/client.cpp
@@ -16,6 +16,7 @@
#include "tao/debug.h"
#include "ace/Get_Opt.h"
#include "ace/OS_NS_stdio.h"
+#include "ace/High_Res_Timer.h"
#if defined (_MSC_VER)
# pragma warning (disable : 4250)
@@ -184,6 +185,7 @@ ACE_TMAIN(int argc, ACE_TCHAR *argv[])
level1[0].id = CORBA::string_dup ("level1_context");
CosNaming::NamingContext_var level1_context;
level1_context = root_context_1->bind_new_context (level1);
+
for (i=0; i<o_breath; i++)
{
// Instantiate a dummy object and bind it under the new context.
@@ -191,12 +193,11 @@ ACE_TMAIN(int argc, ACE_TCHAR *argv[])
Test_Object_var obj1 = impl1->_this ();
impl1->_remove_ref ();
- CosNaming::Name obj_name;
- obj_name.length (1);
+ level1.length (2);
char wide_name[16];
ACE_OS::sprintf(wide_name, "obj_%d", i);
- obj_name[0].id = CORBA::string_dup (wide_name);
- level1_context->bind (obj_name, obj1.in ());
+ level1[1].id = CORBA::string_dup (wide_name);
+ root_context_1->bind (level1, obj1.in ());
}
}
@@ -449,6 +450,94 @@ ACE_TMAIN(int argc, ACE_TCHAR *argv[])
}
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Redundancy test OK\n")));
+
+ // Test performance of binding a bunch of objects in one context
+ try
+ {
+ // Bind one context level under root.
+ CosNaming::Name level1;
+ level1.length (1);
+ level1[0].id = CORBA::string_dup ("perf_context");
+ CosNaming::NamingContext_var perf_context;
+ perf_context = root_context_1->bind_new_context (level1);
+
+ // Instantiate a dummy object and bind it under the new context.
+ My_Test_Object *impl1 = new My_Test_Object (i+1);
+ Test_Object_var obj1 = impl1->_this ();
+ impl1->_remove_ref ();
+
+ int test_runs = 100;
+ ACE_High_Res_Timer::global_scale_factor_type gsf =
+ ACE_High_Res_Timer::global_scale_factor ();
+
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+
+ // Test how long it takes to bind
+ for (i=0; i<test_runs; i++)
+ {
+ level1.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", i);
+ level1[0].id = CORBA::string_dup (wide_name);
+ perf_context->bind (level1, obj1.in ());
+ }
+
+ ACE_hrtime_t elapsed_time = ACE_OS::gethrtime () - start;
+ // convert to microseconds
+ ACE_UINT32 usecs = ACE_UINT32(elapsed_time / gsf);
+ double secs = usecs / 1000000.0;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Bound %i objects in %.2f secs\n",
+ test_runs, secs));
+
+ // Test how long it takes to resolve
+ start = ACE_OS::gethrtime ();
+ for (i=0; i<test_runs; i++)
+ {
+ level1.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", i);
+ level1[0].id = CORBA::string_dup (wide_name);
+ CORBA::Object_var result_obj_ref = perf_context->resolve (level1);
+ }
+
+ elapsed_time = ACE_OS::gethrtime () - start;
+ // convert to microseconds
+ usecs = ACE_UINT32(elapsed_time / gsf);
+ secs = ((ACE_INT32) usecs) / 1000000.0;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Resolved %i objects in %.2f secs\n",
+ test_runs, secs));
+
+ // Test how long it takes to unbind
+ start = ACE_OS::gethrtime ();
+ for (i=0; i<test_runs; i++)
+ {
+ level1.length (1);
+ char wide_name[16];
+ ACE_OS::sprintf(wide_name, "obj_%d", i);
+ level1[0].id = CORBA::string_dup (wide_name);
+ perf_context->unbind (level1);
+ }
+
+ elapsed_time = ACE_OS::gethrtime () - start;
+ // convert to microseconds
+ usecs = ACE_UINT32(elapsed_time / gsf);
+ secs = ((ACE_INT32) usecs) / 1000000.0;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Unbound %i objects in %.2f secs\n",
+ test_runs, secs));
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT ("ERROR: Exception during performance test.\n"));
+ return -1;
+ }
+
+ // All tests have passed up to this point
return 0;
}
diff --git a/TAO/orbsvcs/tests/Redundant_Naming/run_test.pl b/TAO/orbsvcs/tests/Redundant_Naming/run_test.pl
index 849a56c486c..e89dc202e66 100755
--- a/TAO/orbsvcs/tests/Redundant_Naming/run_test.pl
+++ b/TAO/orbsvcs/tests/Redundant_Naming/run_test.pl
@@ -77,12 +77,12 @@ else {
# Run two Naming Servers in redundant mode and one client. Client uses iors
# in files to find the individual copies of the Naming Servers.
-my $args = "-ORBEndPoint $ns_endpoint1 -o $test_iorfile1 -m 0 -r NameService";
+my $args = "-ORBEndPoint $ns_endpoint1 -o $iorfile1 -m 0 -r NameService";
my $prog = "$startdir/../../Naming_Service/tao_cosnaming";
$NS1 = $test->CreateProcess ("$prog", "$args");
-$test->DeleteFile ("iorfile1");
+$test->DeleteFile ($iorfile1);
$NS1->Spawn ();
@@ -98,7 +98,7 @@ $prog = "$startdir/../../Naming_Service/tao_cosnaming";
$NS2 = $test->CreateProcess ("$prog", "$args");
-$test->DeleteFile ("iorfile2");
+$test->DeleteFile ($iorfile2);
$NS2->Spawn ();
@@ -129,7 +129,7 @@ if ($client != 0) {
$NS1->Kill ();
$NS2->Kill ();
-$test->DeleteFile ("iorfile1");
-$test->DeleteFile ("iorfile2");
+$test->DeleteFile ($iorfile1);
+$test->DeleteFile ($iorfile2);
exit $status;
diff --git a/TAO/orbsvcs/tests/Simple_Naming/client.cpp b/TAO/orbsvcs/tests/Simple_Naming/client.cpp
index d8996e15ceb..f965e7607de 100644
--- a/TAO/orbsvcs/tests/Simple_Naming/client.cpp
+++ b/TAO/orbsvcs/tests/Simple_Naming/client.cpp
@@ -276,7 +276,11 @@ MT_Test::svc (void)
}
if (name_service.in () == 0)
- return -1;
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: Unable to narrow naming IOR to a NamingContext.\n"));
+ return -1;
+ }
// Bind the object.
try
@@ -344,6 +348,7 @@ MT_Test::svc (void)
{
ACE_DEBUG ((LM_DEBUG,
"Unable to unbind in thread %t\n"));
+ return -1;
}
catch (const CORBA::Exception& ex)
{
@@ -915,7 +920,9 @@ Iterator_Test::execute (TAO_Naming_Client &root_context)
|| bindings_list->length () != 1
|| bindings_list[0u].binding_type != CosNaming::nobject)
ACE_ERROR_RETURN ((LM_ERROR,
- "CosNaming::list does not function properly\n"),
+ "Iterator_Test -> CosNaming::list does not function properly. \
+Should have returned one CosNaming::nobject element in bindings_list. Length = %d, \
+Binding Type = %d\n", bindings_list->length (), bindings_list[0u].binding_type),
-1);
ACE_DEBUG ((LM_DEBUG,
"First binding: %C\n",
@@ -1214,7 +1221,7 @@ Persistent_List_Test::execute (TAO_Naming_Client &root_context)
if (CORBA::is_nil (iter.in ())
|| bindings_list->length () != 0)
ACE_ERROR_RETURN ((LM_ERROR,
- "CosNaming::list does not function properly\n"),
+ "Persistent_List_Test -> CosNaming::list does not function properly. Should have returned an iterator.\n"),
-1);
while (iter->next_one (binding.out ()))
@@ -1270,7 +1277,7 @@ Persistent_List_Test::execute (TAO_Naming_Client &root_context)
if (CORBA::is_nil (iter.in ())
|| bindings_list->length () != 0)
ACE_ERROR_RETURN ((LM_ERROR,
- "CosNaming::list does not function properly\n"),
+ "Persistent_List_Test -> CosNaming::list does not function properly. Should have returned an iterator.\n"),
-1);
while (iter->next_one (binding.out ()))
diff --git a/TAO/orbsvcs/tests/Simple_Naming/run_test_ffp.pl b/TAO/orbsvcs/tests/Simple_Naming/run_test_ffp.pl
index 5ef2c750ed4..df18c6ccee3 100755
--- a/TAO/orbsvcs/tests/Simple_Naming/run_test_ffp.pl
+++ b/TAO/orbsvcs/tests/Simple_Naming/run_test_ffp.pl
@@ -37,6 +37,7 @@ $persistent_ior_file = "pns.ior";
my $test_iorfile = $test->LocalFile ($iorfile);
my $test_persistent_ior_file = $test->LocalFile ($persistent_ior_file);
+my $prog = "../../Naming_Service/tao_cosnaming";
$test->DeleteFile($iorfile);
$test->DeleteFile($persistent_ior_file);
@@ -44,7 +45,7 @@ $test->DeleteFile($persistent_ior_file);
sub name_server
{
my $args = "-ORBNameServicePort $ns_multicast_port -o $test_iorfile -m 1 @_";
- my $prog = "../../Naming_Service/tao_cosnaming";
+
$SV = $test->CreateProcess ("$prog", "$args");
@@ -95,14 +96,50 @@ $hostname = $test->HostName ();
"Flat File Persistent Test (Part 2): \n",
"Flat File Persistent Test (Part 3): \n");
-$test_number = 0;
-$test->DeleteFile($test_persistent_ior_file);
+sub run_test
+{
+ $prog = "@_";
+
+ $test_number = 0;
+
+ $test->DeleteFile($test_persistent_ior_file);
+
+ if ( ! -d "NameService" ) {
+ mkdir (NameService, 0777);
+ }
+ else {
+ chdir "NameService";
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $test->DeleteFile ($tmp);
+ }
+ chdir "..";
+ }
+
+ # Run server and client for each of the tests. Client uses ior in a
+ # file to bootstrap to the server.
+ foreach $o (@opts) {
+ name_server ($server_opts[$test_number]);
+
+ print STDERR "\n ".$comments[$test_number];
+
+ client ($o);
+
+ $SV->Kill ();
+
+ ## For some reason, only on Windows XP, we need to
+ ## wait before starting another tao_cosnaming when
+ ## the mmap persistence option is used
+ if ($^O eq "MSWin32") {
+ sleep(1);
+ }
+
+ $test_number++;
+ }
-if ( ! -d "NameService" ) {
- mkdir (NameService, 0777);
-}
-else {
chdir "NameService";
opendir(THISDIR, ".");
@allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
@@ -111,40 +148,19 @@ else {
$test->DeleteFile ($tmp);
}
chdir "..";
-}
-
-# Run server and client for each of the tests. Client uses ior in a
-# file to bootstrap to the server.
-foreach $o (@opts) {
- name_server ($server_opts[$test_number]);
-
- print STDERR "\n ".$comments[$test_number];
+ rmdir "NameService";
- client ($o);
-
- $SV->Kill ();
-
- ## For some reason, only on Windows XP, we need to
- ## wait before starting another tao_cosnaming when
- ## the mmap persistence option is used
- if ($^O eq "MSWin32") {
- sleep(1);
- }
-
- $test_number++;
+ $test->DeleteFile($persistent_ior_file);
+ $test->DeleteFile($iorfile);
}
-chdir "NameService";
-opendir(THISDIR, ".");
-@allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
-closedir(THISDIR);
-foreach $tmp (@allfiles){
- $test->DeleteFile ($tmp);
-}
-chdir "..";
-rmdir "NameService";
+@server_exes = ("../../Naming_Service/tao_cosnaming",
+ "../../Naming_Service/tao_ft_naming");
-$test->DeleteFile($persistent_ior_file);
-$test->DeleteFile($iorfile);
+foreach $e (@server_exes) {
+ print STDERR "Testing Naming Service Executable: $e\n";
+ run_test($e);
+ print STDERR "======================================\n";
+}
exit $status;
diff --git a/TAO/orbsvcs/tests/Simple_Naming/run_test_ft.pl b/TAO/orbsvcs/tests/Simple_Naming/run_test_ft.pl
new file mode 100755
index 00000000000..37d6ec95f46
--- /dev/null
+++ b/TAO/orbsvcs/tests/Simple_Naming/run_test_ft.pl
@@ -0,0 +1,217 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+# This is a Perl script that runs some Naming Service tests
+# for the FT_Naming_Service.
+# It runs all the tests that will run with min CORBA.
+# It starts all the servers and clients as necessary.
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+use Cwd;
+
+## Save the starting directory
+$status = 0;
+$multicast = '224.9.9.2';
+$startdir = getcwd();
+
+$quiet = 0;
+
+# check for -q flag
+if ($ARGV[0] eq '-q') {
+ $quiet = 1;
+}
+
+my $test = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+
+# Variables for command-line arguments to client and server
+# executables.
+$ns_multicast_port = 10001 + $test->RandomPort(); # Can not be 10000 on Chorus 4.0
+
+$iorfile = "ns.ior";
+$persistent_ior_file = "pns.ior";
+$persistent_log_file = "test_log";
+
+$data_file = "test_run.data";
+
+## Allow the user to determine where the persistent file will be located
+## just in case the current directory is not suitable for locking.
+## We can't change the name of the persistent file because that is not
+## sufficient to work around locking problems for Tru64 when the current
+## directory is NFS mounted from a system that does not properly support
+## locking.
+foreach my $possible ($ENV{TMPDIR}, $ENV{TEMP}, $ENV{TMP}) {
+ if (defined $possible && -d $possible) {
+ if (chdir($possible)) {
+ last;
+ }
+ }
+}
+
+$test_log = $test->LocalFile ($data_file);
+$test->DeleteFile ($data_file);
+
+#Files which used by test
+my $test_iorfile = $test->LocalFile ($iorfile);
+my $test_persistent_log_file = $test->LocalFile ($persistent_log_file);
+my $test_persistent_ior_file = $test->LocalFile ($persistent_ior_file);
+
+$test->DeleteFile($persistent_ior_file);
+$test->DeleteFile($iorfile);
+$test->DeleteFile($persistent_log_file);
+
+sub name_server
+{
+ my $args = "-u NameService -ORBMulticastDiscoveryEndpoint $multicast:$ns_multicast_port -o $test_iorfile -m 1 @_";
+ my $prog = "$startdir/../../Naming_Service/tao_ft_naming";
+
+ $SV = $test->CreateProcess ("$prog", "$args");
+
+ $test->DeleteFile($iorfile);
+
+ $SV->Spawn ();
+
+ if ($test->WaitForFileTimed ($iorfile,
+ $test->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$test_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ sleep(10);
+}
+
+sub client
+{
+ my $args = "@_"." ";
+ my $prog = "$startdir/client";
+
+ $CL = $test->CreateProcess ("$prog", "$args");
+
+ $client_status = $CL->SpawnWaitKill ($test->ProcessStartWaitInterval() + 45);
+
+ if ($client_status != 0) {
+ print STDERR "ERROR: client returned $client_status\n";
+ $status = 1;
+ }
+
+}
+
+sub make_or_clean_state
+{
+ # Create a directory to hold the persistent state
+ if ( ! -d "NameService" ) {
+ mkdir (NameService, 0777);
+ }
+ else {
+ chdir "NameService";
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $test->DeleteFile ($tmp);
+ }
+ chdir "..";
+ }
+}
+
+## The options below have been reordered due to a
+## initialization problem (within the Naming_Service)
+## that has only been seen on Windows XP.
+
+# Options for all simple tests recognized by the 'client' program.
+@opts = ("-s -ORBInitRef NameService=file://$test_iorfile",
+ "-s -ORBInitRef NameService=mcast://$multicast:$ns_multicast_port\::/NameService",
+ "-t -ORBInitRef NameService=file://$test_iorfile",
+ "-i -ORBInitRef NameService=file://$test_iorfile",
+ "-e -ORBInitRef NameService=file://$test_iorfile",
+ "-y -ORBInitRef NameService=file://$test_iorfile"
+ );
+
+@server_opts = ("-t 30",
+ "",
+ "",
+ "",
+ "",
+ ""
+ );
+
+@comments = ("Simple Test: \n",
+ "Simple Test (using multicast to locate the server): \n",
+ "Tree Test: \n",
+ "Iterator Test: \n",
+ "Exceptions Test: \n",
+ "Destroy Test: \n"
+ );
+
+$test_number = 0;
+
+print "INFO: Running the test in ", getcwd(), "\n";
+
+# Run server and client for each of the tests. Client uses ior in a
+# file to bootstrap to the server.
+foreach $o (@opts) {
+
+ # Ensure that the name service is starting clean each time
+ make_or_clean_state;
+
+ print STDERR "Running Test: $comments[$test_number]\n";
+
+ name_server ($server_opts[$test_number]);
+
+ client ($o);
+
+ $SV->Kill ();
+
+ ## For some reason, only on Windows XP, we need to
+ ## wait before starting another tao_cosnaming when
+ ## the mmap persistence option is used
+ if ($^O eq "MSWin32") {
+ sleep(1);
+ }
+ $test_number++;
+}
+
+$test->DeleteFile($persistent_ior_file);
+$test->DeleteFile($persistent_log_file);
+$test->DeleteFile($iorfile);
+
+# Now run the multithreaded test, sending output to the file.
+print STDERR "\n Multithreaded Test:\n";
+$test->DeleteFile ($data_file);
+
+name_server ();
+client ("-ORBInitRef NameService=file://$test_iorfile -ORBLogFile $test_log", "-m15");
+
+$SV->Kill ();
+
+$errors = system ("perl $startdir/process-m-output.pl $test_log 15") >> 8;
+
+if ($errors > 0) {
+ $status = 1;
+
+ if (!$quiet) {
+ print STDERR "Errors Detected, printing output\n";
+ if (open (DATA, "<$test_log")) {
+ print STDERR "================================= Begin\n";
+ print STDERR <DATA>;
+ print STDERR "================================= End\n";
+ close (DATA);
+ }
+ else {
+ print STDERR "ERROR: Could not open $test_log\n";
+ }
+ $test->DeleteFile ($data_file);
+ }
+}
+
+$test->DeleteFile($iorfile);
+# Remove the persistence directory
+rmdir "NameService";
+
+
+exit $status;
diff --git a/TAO/tao/AnyTypeCode/Struct_TypeCode.cpp b/TAO/tao/AnyTypeCode/Struct_TypeCode.cpp
index b920fd9f483..0418ed99896 100644
--- a/TAO/tao/AnyTypeCode/Struct_TypeCode.cpp
+++ b/TAO/tao/AnyTypeCode/Struct_TypeCode.cpp
@@ -108,6 +108,19 @@ template <typename StringType,
typename TypeCodeType,
class FieldArrayType,
class RefCountPolicy>
+const FieldArrayType&
+TAO::TypeCode::Struct<StringType,
+ TypeCodeType,
+ FieldArrayType,
+ RefCountPolicy>::fields (void) const
+{
+ return fields_;
+}
+
+template <typename StringType,
+ typename TypeCodeType,
+ class FieldArrayType,
+ class RefCountPolicy>
CORBA::Boolean
TAO::TypeCode::Struct<StringType,
TypeCodeType,
diff --git a/TAO/tao/AnyTypeCode/Struct_TypeCode.h b/TAO/tao/AnyTypeCode/Struct_TypeCode.h
index 422b6b3fdf8..27ede78e202 100644
--- a/TAO/tao/AnyTypeCode/Struct_TypeCode.h
+++ b/TAO/tao/AnyTypeCode/Struct_TypeCode.h
@@ -78,6 +78,9 @@ namespace TAO
virtual void tao_release (void);
//@}
+ /// Accessor for fields_
+ const FieldArrayType& fields() const;
+
protected:
/**
diff --git a/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp b/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp
index 661e8414d57..6e05e19bfd1 100644
--- a/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp
+++ b/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.cpp
@@ -60,7 +60,7 @@ namespace TAO
namespace
{
- bool add_to_recursion_list (CORBA::TypeCode_ptr & tc,
+ bool add_to_tc_info_list (CORBA::TypeCode_ptr & tc,
TAO::TypeCodeFactory::TC_Info_List & infos)
{
// Since we created a new tc, add it to the list.
@@ -127,24 +127,30 @@ namespace
// Use an ACE::Value_Ptr to provide exception safety and proper
// copying semantics.
- typedef ACE::Value_Ptr<TAO::TypeCode::Case<CORBA::String_var, CORBA::TypeCode_var> > union_elem_type;
+ typedef ACE::Value_Ptr<TAO::TypeCode::Case<CORBA::String_var,
+ CORBA::TypeCode_var> > union_elem_type;
typedef ACE_Array_Base<union_elem_type> union_case_array_type;
// ------------------------------------------------------------
/// Demarshal a TypeCode.
- bool tc_demarshal (TAO_InputCDR & cdr,
- CORBA::TypeCode_ptr & tc,
- TAO::TypeCodeFactory::TC_Info_List & infos);
+ bool tc_demarshal (
+ TAO_InputCDR & cdr,
+ CORBA::TypeCode_ptr & tc,
+ TAO::TypeCodeFactory::TC_Info_List & indirect_infos,
+ TAO::TypeCodeFactory::TC_Info_List & direct_infos);
/// Demarshal an indirected TypeCode.
- bool tc_demarshal_indirection (TAO_InputCDR & cdr,
- CORBA::TypeCode_ptr & tc,
- TAO::TypeCodeFactory::TC_Info_List & infos);
-
- bool find_recursive_tc (char const * id,
- TAO::TypeCodeFactory::TC_Info_List & tcs,
- TAO::TypeCodeFactory::TC_Info_List & infos)
+ bool tc_demarshal_indirection (
+ TAO_InputCDR & cdr,
+ CORBA::TypeCode_ptr & tc,
+ TAO::TypeCodeFactory::TC_Info_List & indirect_infos,
+ TAO::TypeCodeFactory::TC_Info_List & direct_infos);
+
+ bool find_recursive_tc (
+ char const * id,
+ TAO::TypeCodeFactory::TC_Info_List & tcs,
+ TAO::TypeCodeFactory::TC_Info_List & infos)
{
// See comments above for rationale behind using an array instead
// of a map.
@@ -170,12 +176,25 @@ namespace
return (tcs.size () > 0) ;
}
+
+ // For TC_Info_List whose elements are duplicated prior to addition,
+ // clean up the list by calling release on the typecode pointers.
+ void cleanup_tc_info_list (TAO::TypeCodeFactory::TC_Info_List & infos)
+ {
+ size_t const len = infos.size ();
+
+ for (size_t i = 0; i < len; ++i)
+ {
+ CORBA::release(infos[i].type);
+ }
+ }
}
bool
TAO::TypeCodeFactory::tc_null_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_null);
@@ -187,6 +206,7 @@ bool
TAO::TypeCodeFactory::tc_void_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_void);
@@ -198,6 +218,7 @@ bool
TAO::TypeCodeFactory::tc_short_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_short);
@@ -209,6 +230,7 @@ bool
TAO::TypeCodeFactory::tc_long_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_long);
@@ -220,6 +242,7 @@ bool
TAO::TypeCodeFactory::tc_ushort_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_ushort);
@@ -231,6 +254,7 @@ bool
TAO::TypeCodeFactory::tc_ulong_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_ulong);
@@ -242,6 +266,7 @@ bool
TAO::TypeCodeFactory::tc_float_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_float);
@@ -253,6 +278,7 @@ bool
TAO::TypeCodeFactory::tc_double_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_double);
@@ -264,6 +290,7 @@ bool
TAO::TypeCodeFactory::tc_boolean_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_boolean);
@@ -275,6 +302,7 @@ bool
TAO::TypeCodeFactory::tc_char_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_char);
@@ -286,6 +314,7 @@ bool
TAO::TypeCodeFactory::tc_octet_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_octet);
@@ -297,6 +326,7 @@ bool
TAO::TypeCodeFactory::tc_any_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_any);
@@ -308,6 +338,7 @@ bool
TAO::TypeCodeFactory::tc_TypeCode_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_TypeCode);
@@ -319,6 +350,7 @@ bool
TAO::TypeCodeFactory::tc_Principal_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_Principal);
@@ -330,6 +362,7 @@ bool
TAO::TypeCodeFactory::tc_objref_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
// The remainder of a tk_objref TypeCode is encoded in a CDR
@@ -343,11 +376,14 @@ TAO::TypeCodeFactory::tc_objref_factory (CORBA::TCKind kind,
if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)))
return false;
- static char const Object_id[] = "IDL:omg.org/CORBA/Object:1.0";
- static char const CCMObject_id[] = "IDL:omg.org/CORBA/CCMObject:1.0";
- static char const CCMHome_id[] = "IDL:omg.org/CORBA/CCMHome:1.0";
+ static char const Object_id[] =
+ ACE_TEXT_ALWAYS_CHAR ("IDL:omg.org/CORBA/Object:1.0");
+ static char const CCMObject_id[] =
+ ACE_TEXT_ALWAYS_CHAR ("IDL:omg.org/CORBA/CCMObject:1.0");
+ static char const CCMHome_id[] =
+ ACE_TEXT_ALWAYS_CHAR ("IDL:omg.org/CORBA/CCMHome:1.0");
- char const * tc_constant_id = "";
+ char const * tc_constant_id = ACE_TEXT_ALWAYS_CHAR ("");
switch (kind)
{
@@ -415,7 +451,8 @@ bool
TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
ACE_ASSERT (kind == CORBA::tk_struct || kind == CORBA::tk_except);
@@ -443,7 +480,10 @@ TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
for (CORBA::ULong i = 0; i < nfields; ++i)
{
if (!(cdr >> TAO_InputCDR::to_string (fields[i].name.out (), 0)
- && tc_demarshal (cdr, fields[i].type.out (), infos)))
+ && tc_demarshal (cdr,
+ fields[i].type.out (),
+ indirect_infos,
+ direct_infos)))
return false;
}
@@ -455,7 +495,9 @@ TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
// Check if struct TypeCode is recursive.
TAO::TypeCodeFactory::TC_Info_List recursive_tc;
- if (kind == CORBA::tk_struct && find_recursive_tc (id.in (), recursive_tc, infos))
+ if (kind == CORBA::tk_struct && find_recursive_tc (id.in (),
+ recursive_tc,
+ indirect_infos))
{
// Set remaining parameters.
typedef TAO::TypeCode::Recursive_Type<typecode_type,
@@ -476,7 +518,9 @@ TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
if (!rtc)
return false; // Should never occur.
- assigned_params |= rtc->struct_parameters (name.in (), fields, nfields);
+ assigned_params |= rtc->struct_parameters (name.in (),
+ fields,
+ nfields);
}
// If no parameters were assigned then the reference in the
@@ -502,6 +546,10 @@ TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
false);
}
+ CORBA::TypeCode_ptr dup_tc = CORBA::TypeCode::_duplicate(tc);
+ if (!add_to_tc_info_list(dup_tc, direct_infos)) {
+ return false;
+ }
return true;
}
@@ -509,7 +557,8 @@ bool
TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
// The remainder of a tk_enum TypeCode is encoded in a CDR
// encapsulation.
@@ -559,7 +608,8 @@ TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
{
elem_type & member = cases[i];
- TAO::TypeCode::Case<CORBA::String_var, CORBA::TypeCode_var> * the_case = 0;
+ TAO::TypeCode::Case<CORBA::String_var, CORBA::TypeCode_var> *
+ the_case = 0;
// Ugly. *sigh*
switch (discriminant_kind)
@@ -709,7 +759,9 @@ TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
CORBA::TypeCode_var the_type;
if (!(cdr >> TAO_InputCDR::to_string (the_name.out (), 0)
- && tc_demarshal (cdr, the_type.out (), infos)))
+ && tc_demarshal (cdr, the_type.out (),
+ indirect_infos,
+ direct_infos)))
return false;
member->name (the_name.in ());
@@ -723,7 +775,7 @@ TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
// Check if we have recursive members. There could be multiple.
TAO::TypeCodeFactory::TC_Info_List recursive_tc;
- if (find_recursive_tc (id.in (), recursive_tc, infos))
+ if (find_recursive_tc (id.in (), recursive_tc, indirect_infos))
{
// Set remaining parameters.
@@ -777,6 +829,10 @@ TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
false);
}
+ CORBA::TypeCode_ptr dup_tc = CORBA::TypeCode::_duplicate(tc);
+ if (!add_to_tc_info_list(dup_tc, direct_infos)) {
+ return false;
+ }
return true;
}
@@ -784,6 +840,7 @@ bool
TAO::TypeCodeFactory::tc_enum_factory (CORBA::TCKind /* kind */,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
// The remainder of a tk_enum TypeCode is encoded in a CDR
@@ -828,6 +885,7 @@ bool
TAO::TypeCodeFactory::tc_string_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
// A tk_string/tk_wstring TypeCode has a simple parameter list,
@@ -863,7 +921,8 @@ bool
TAO::TypeCodeFactory::tc_sequence_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
ACE_ASSERT (kind == CORBA::tk_sequence || kind == CORBA::tk_array);
@@ -877,7 +936,7 @@ TAO::TypeCodeFactory::tc_sequence_factory (CORBA::TCKind kind,
CORBA::TypeCode_var content_type;
CORBA::ULong length;
- if (!(tc_demarshal (cdr, content_type.out (), infos)
+ if (!(tc_demarshal (cdr, content_type.out (), indirect_infos, direct_infos)
&& cdr >> length))
return false;
@@ -896,16 +955,18 @@ bool
TAO::TypeCodeFactory::tc_array_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_sequence_factory (kind, cdr, tc, infos);
+ return tc_sequence_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_alias_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
// The remainder of a tk_alias or tk_value_box TypeCode is encoded
// in a CDR encapsulation.
@@ -918,7 +979,10 @@ TAO::TypeCodeFactory::tc_alias_factory (CORBA::TCKind kind,
CORBA::TypeCode_var content_type;
if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)
&& cdr >> TAO_InputCDR::to_string (name.out (), 0)
- && tc_demarshal (cdr, content_type.out (), infos)))
+ && tc_demarshal (cdr,
+ content_type.out (),
+ indirect_infos,
+ direct_infos)))
{
return false;
}
@@ -941,15 +1005,17 @@ bool
TAO::TypeCodeFactory::tc_except_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_struct_factory (kind, cdr, tc, infos);
+ return tc_struct_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_longlong_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_longlong);
@@ -961,6 +1027,7 @@ bool
TAO::TypeCodeFactory::tc_ulonglong_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_ulonglong);
@@ -972,6 +1039,7 @@ bool
TAO::TypeCodeFactory::tc_longdouble_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_longdouble);
@@ -983,6 +1051,7 @@ bool
TAO::TypeCodeFactory::tc_wchar_factory (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
tc = CORBA::TypeCode::_duplicate (CORBA::_tc_wchar);
@@ -994,15 +1063,17 @@ bool
TAO::TypeCodeFactory::tc_wstring_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_string_factory (kind, cdr, tc, infos);
+ return tc_string_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_fixed_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
+ TC_Info_List &,
TC_Info_List &)
{
// A tk_fixed TypeCode has a simple parameter list, i.e. it is not
@@ -1025,7 +1096,8 @@ bool
TAO::TypeCodeFactory::tc_value_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
// The remainder of a tk_value/tk_event TypeCode is encoded in a
// CDR encapsulation
@@ -1061,7 +1133,7 @@ TAO::TypeCodeFactory::tc_value_factory (CORBA::TCKind kind,
CORBA::TypeCode_var> & field = fields[i];
if (!(cdr >> TAO_InputCDR::to_string (field.name.out (), 0)
- && tc_demarshal (cdr, field.type.out (), infos)
+ && tc_demarshal (cdr, field.type.out (), indirect_infos, direct_infos)
&& cdr >> field.visibility))
return false;
}
@@ -1074,7 +1146,7 @@ TAO::TypeCodeFactory::tc_value_factory (CORBA::TCKind kind,
// Check if valuetype/eventtype TypeCode is recursive.
TAO::TypeCodeFactory::TC_Info_List recursive_tc;
- if (find_recursive_tc (id.in (), recursive_tc, infos))
+ if (find_recursive_tc (id.in (), recursive_tc, indirect_infos))
{
// Set remaining parameters.
@@ -1127,6 +1199,10 @@ TAO::TypeCodeFactory::tc_value_factory (CORBA::TCKind kind,
false);
}
+ CORBA::TypeCode_ptr dup_tc = CORBA::TypeCode::_duplicate(tc);
+ if (!add_to_tc_info_list(dup_tc, direct_infos)) {
+ return false;
+ }
return true;
}
@@ -1134,63 +1210,74 @@ bool
TAO::TypeCodeFactory::tc_value_box_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_alias_factory (kind, cdr, tc, infos);
+ return tc_alias_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_native_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_native, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_native, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_abstract_interface_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_abstract_interface, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_abstract_interface,
+ cdr,
+ tc,
+ indirect_infos,
+ direct_infos);
}
bool
TAO::TypeCodeFactory::tc_local_interface_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_local_interface, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_local_interface, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_component_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_component, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_component, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_home_factory (CORBA::TCKind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_objref_factory (CORBA::tk_home, cdr, tc, infos);
+ return tc_objref_factory (CORBA::tk_home, cdr, tc, indirect_infos, direct_infos);
}
bool
TAO::TypeCodeFactory::tc_event_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos)
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos)
{
- return tc_value_factory (kind, cdr, tc, infos);
+ return tc_value_factory (kind, cdr, tc, indirect_infos, direct_infos);
}
// ---------------------------------------------------------------
@@ -1200,7 +1287,8 @@ namespace
bool
tc_demarshal (TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TAO::TypeCodeFactory::TC_Info_List & infos)
+ TAO::TypeCodeFactory::TC_Info_List & indirect_infos,
+ TAO::TypeCodeFactory::TC_Info_List & direct_infos)
{
// ULong since we need to detect indirected TypeCodes, too.
@@ -1210,8 +1298,9 @@ namespace
&& kind != TYPECODE_INDIRECTION))
return false;
- if (kind == TYPECODE_INDIRECTION)
- return tc_demarshal_indirection (cdr, tc, infos);
+ if (kind == TYPECODE_INDIRECTION) {
+ return tc_demarshal_indirection (cdr, tc, indirect_infos, direct_infos);
+ }
using namespace TAO::TypeCodeFactory;
@@ -1259,13 +1348,16 @@ namespace
return factory_map[kind] (static_cast<CORBA::TCKind> (kind),
cdr,
tc,
- infos);
+ indirect_infos,
+ direct_infos);
}
bool
- tc_demarshal_indirection (TAO_InputCDR & cdr,
- CORBA::TypeCode_ptr & tc,
- TAO::TypeCodeFactory::TC_Info_List & infos)
+ tc_demarshal_indirection (
+ TAO_InputCDR & cdr,
+ CORBA::TypeCode_ptr & tc,
+ TAO::TypeCodeFactory::TC_Info_List & indirect_infos,
+ TAO::TypeCodeFactory::TC_Info_List & direct_infos)
{
CORBA::Long offset;
@@ -1332,7 +1424,10 @@ namespace
CORBA::String_var name;
CORBA::TypeCode_var content_type;
if (!(indir_stream >> TAO_InputCDR::to_string (name.out (), 0)
- && tc_demarshal (indir_stream, content_type.out (), infos)))
+ && tc_demarshal (indir_stream,
+ content_type.out (),
+ indirect_infos,
+ direct_infos)))
{
return false;
}
@@ -1357,7 +1452,7 @@ namespace
// Check if we already have a tc for this RECURSIVE type, if yes, use that
TAO::TypeCodeFactory::TC_Info_List recursive_tc;
- if (find_recursive_tc (id.in (), recursive_tc, infos))
+ if (find_recursive_tc (id.in (), recursive_tc, indirect_infos))
{
tc = CORBA::TypeCode::_duplicate(recursive_tc[0].type);
}
@@ -1386,8 +1481,9 @@ namespace
id.in ()),
false);
- // Since we created a new recursive tc, add it to the "Recursive" list.
- return add_to_recursion_list (tc, infos);
+ // Since we created a new recursive tc, add it to
+ // the "Recursive" list.
+ return add_to_tc_info_list (tc, indirect_infos);
}
break;
case CORBA::tk_union:
@@ -1410,8 +1506,9 @@ namespace
id.in ()),
false);
- // Since we created a new recursive tc, add it to the "Recursive" list.
- return add_to_recursion_list (tc, infos);
+ // Since we created a new recursive tc, add it
+ // to the "Recursive" list.
+ return add_to_tc_info_list (tc, indirect_infos);
}
break;
case CORBA::tk_value:
@@ -1438,8 +1535,9 @@ namespace
id.in ()),
false);
- // Since we created a new recursive tc, add it to the "Recursive" list.
- return add_to_recursion_list (tc, infos);
+ // Since we created a new recursive tc, add it
+ // to the "Recursive" list.
+ return add_to_tc_info_list (tc, indirect_infos);
}
break;
default:
@@ -1455,9 +1553,146 @@ namespace
CORBA::Boolean
operator>> (TAO_InputCDR & cdr, CORBA::TypeCode_ptr & tc)
{
- TAO::TypeCodeFactory::TC_Info_List infos;
+ TAO::TypeCodeFactory::TC_Info_List indirect_infos;
+ TAO::TypeCodeFactory::TC_Info_List direct_infos;
+
+ if (!tc_demarshal (cdr, tc, indirect_infos, direct_infos)) {
+ cleanup_tc_info_list(direct_infos);
+ return false;
+ }
+
+ if (indirect_infos.size() == 0) {
+ cleanup_tc_info_list(direct_infos);
+ return true;
+ }
+
+ for (size_t i = 0; i < direct_infos.size(); ++i) {
+ CORBA::TypeCode_ptr& tc = direct_infos[i].type;
+
+ TAO::TypeCodeFactory::TC_Info_List recursive_tc;
+ if (find_recursive_tc(tc->id(), recursive_tc, indirect_infos)) {
+ size_t const len = recursive_tc.size ();
+ bool assigned_params = false;
+
+ switch (tc->kind()) {
+ case CORBA::tk_struct:
+ {
+ // Set remaining parameters.
+ typedef ACE_Array_Base<TAO::TypeCode::Struct_Field<CORBA::String_var,
+ CORBA::TypeCode_var> >
+ member_array_type;
+
+ typedef TAO::TypeCode::Struct<
+ CORBA::String_var,
+ CORBA::TypeCode_var,
+ member_array_type,
+ TAO::True_RefCount_Policy> typecode_type;
+
+ typedef TAO::TypeCode::Recursive_Type<typecode_type,
+ CORBA::TypeCode_var,
+ member_array_type>
+ recursive_typecode_type;
+
+ typecode_type * const tc_struct = dynamic_cast<typecode_type *>(tc);
+ for (size_t i = 0; i < len; ++i)
+ {
+ TAO::TypeCodeFactory::TC_Info & info = recursive_tc[i];
+
+ recursive_typecode_type * const rtc =
+ dynamic_cast<recursive_typecode_type *> (info.type);
+
+ if (!rtc)
+ return false; // Should never occur.
+
+ assigned_params |= rtc->struct_parameters (
+ tc_struct->name(),
+ tc_struct->fields(),
+ tc_struct->member_count());
+ }
+ }
+ break;
+ case CORBA::tk_union:
+ {
+ // Set remaining parameters.
+ typedef union_case_array_type case_array_type;
+
+ typedef TAO::TypeCode::Union<CORBA::String_var,
+ CORBA::TypeCode_var,
+ case_array_type,
+ TAO::True_RefCount_Policy>
+ typecode_type;
+
+ typedef TAO::TypeCode::Recursive_Type<typecode_type,
+ CORBA::TypeCode_var,
+ case_array_type>
+ recursive_typecode_type;
+
+ typecode_type * const tc_union = dynamic_cast<typecode_type *>(tc);
+ for (size_t i = 0; i < len; ++i)
+ {
+ TAO::TypeCodeFactory::TC_Info & info = recursive_tc[i];
+
+ recursive_typecode_type * const rtc =
+ dynamic_cast<recursive_typecode_type *> (info.type);
+
+ if (!rtc)
+ return false; // Should never occur.
+
+ assigned_params |= rtc->union_parameters (
+ tc_union->name(),
+ tc_union->discriminator_type(),
+ tc_union->cases(), // Will be copied.
+ tc_union->member_count(),
+ tc_union->default_index());
+ }
+ }
+ break;
+ case CORBA::tk_value:
+ case CORBA::tk_event:
+ {
+ // Set remaining parameters.
+ typedef ACE_Array_Base<TAO::TypeCode::Value_Field<CORBA::String_var,
+ CORBA::TypeCode_var> >
+ member_array_type;
+
+ typedef TAO::TypeCode::Value<CORBA::String_var,
+ CORBA::TypeCode_var,
+ member_array_type,
+ TAO::True_RefCount_Policy>
+ typecode_type;
+
+ typedef TAO::TypeCode::Recursive_Type<typecode_type,
+ CORBA::TypeCode_var,
+ member_array_type>
+ recursive_typecode_type;
+
+ typecode_type * const tc_value = dynamic_cast<typecode_type *>(tc);
+ for (size_t i = 0; i < len; ++i)
+ {
+ TAO::TypeCodeFactory::TC_Info & info = recursive_tc[i];
- return tc_demarshal (cdr, tc, infos);
+ recursive_typecode_type * const rtc =
+ dynamic_cast<recursive_typecode_type *> (info.type);
+
+ if (!rtc)
+ return false; // Should never occur.
+
+ assigned_params |= rtc->valuetype_parameters (
+ tc_value->name(),
+ tc_value->type_modifier(),
+ tc_value->concrete_base(),
+ tc_value->fields(), // Will be copied.
+ tc_value->member_count());
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ cleanup_tc_info_list(direct_infos);
+ return true;
}
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h b/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h
index 0e6d6015c97..3d99e69751e 100644
--- a/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h
+++ b/TAO/tao/AnyTypeCode/TypeCode_CDR_Extraction.h
@@ -39,156 +39,194 @@ namespace TAO
typedef bool (*factory) (CORBA::TCKind,
TAO_InputCDR &,
CORBA::TypeCode_ptr &,
+ TC_Info_List &,
TC_Info_List &);
bool tc_null_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_void_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_short_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_long_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_ushort_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_ulong_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_float_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_double_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_boolean_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_char_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_octet_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_any_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_TypeCode_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_Principal_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_objref_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_struct_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_union_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_enum_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_string_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_sequence_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_array_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_alias_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_except_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_longlong_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_ulonglong_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_longdouble_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_wchar_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_wstring_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_fixed_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_value_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_value_box_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_native_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_abstract_interface_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_local_interface_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_component_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_home_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
bool tc_event_factory (CORBA::TCKind kind,
TAO_InputCDR & cdr,
CORBA::TypeCode_ptr & tc,
- TC_Info_List & infos);
+ TC_Info_List & indirect_infos,
+ TC_Info_List & direct_infos);
} // End namespace TypeCodeFactory
} // End namespace TAO
diff --git a/TAO/tao/AnyTypeCode/Union_TypeCode.cpp b/TAO/tao/AnyTypeCode/Union_TypeCode.cpp
index 6e616e79366..27c7eb6a8d1 100644
--- a/TAO/tao/AnyTypeCode/Union_TypeCode.cpp
+++ b/TAO/tao/AnyTypeCode/Union_TypeCode.cpp
@@ -104,6 +104,19 @@ template <typename StringType,
typename TypeCodeType,
class CaseArrayType,
class RefCountPolicy>
+const CaseArrayType &
+TAO::TypeCode::Union<StringType,
+ TypeCodeType,
+ CaseArrayType,
+ RefCountPolicy>::cases (void) const
+{
+ return cases_;
+}
+
+template <typename StringType,
+ typename TypeCodeType,
+ class CaseArrayType,
+ class RefCountPolicy>
CORBA::Boolean
TAO::TypeCode::Union<StringType,
TypeCodeType,
diff --git a/TAO/tao/AnyTypeCode/Union_TypeCode.h b/TAO/tao/AnyTypeCode/Union_TypeCode.h
index 9757c9f9d65..abc4fe801e4 100644
--- a/TAO/tao/AnyTypeCode/Union_TypeCode.h
+++ b/TAO/tao/AnyTypeCode/Union_TypeCode.h
@@ -82,6 +82,9 @@ namespace TAO
virtual void tao_release (void);
//@}
+ /// Accessor for cases_
+ const CaseArrayType& cases(void) const;
+
protected:
/**
diff --git a/TAO/tao/AnyTypeCode/Value_TypeCode.cpp b/TAO/tao/AnyTypeCode/Value_TypeCode.cpp
index dc6aa73d6f7..8155a50d06c 100644
--- a/TAO/tao/AnyTypeCode/Value_TypeCode.cpp
+++ b/TAO/tao/AnyTypeCode/Value_TypeCode.cpp
@@ -112,6 +112,32 @@ template <typename StringType,
typename TypeCodeType,
class FieldArrayType,
class RefCountPolicy>
+const TypeCodeType&
+TAO::TypeCode::Value<StringType,
+ TypeCodeType,
+ FieldArrayType,
+ RefCountPolicy>::concrete_base (void) const
+{
+ return concrete_base_;
+}
+
+template <typename StringType,
+ typename TypeCodeType,
+ class FieldArrayType,
+ class RefCountPolicy>
+const FieldArrayType&
+TAO::TypeCode::Value<StringType,
+ TypeCodeType,
+ FieldArrayType,
+ RefCountPolicy>::fields (void) const
+{
+ return fields_;
+}
+
+template <typename StringType,
+ typename TypeCodeType,
+ class FieldArrayType,
+ class RefCountPolicy>
CORBA::Boolean
TAO::TypeCode::Value<StringType,
TypeCodeType,
diff --git a/TAO/tao/AnyTypeCode/Value_TypeCode.h b/TAO/tao/AnyTypeCode/Value_TypeCode.h
index 8f386b2e731..34abe3b7ec4 100644
--- a/TAO/tao/AnyTypeCode/Value_TypeCode.h
+++ b/TAO/tao/AnyTypeCode/Value_TypeCode.h
@@ -83,6 +83,12 @@ namespace TAO
virtual void tao_release (void);
//@}
+ /// Accessor for concrete_base_
+ const TypeCodeType& concrete_base(void) const;
+
+ /// Accessor for fields_
+ const FieldArrayType& fields() const;
+
protected:
/**
diff --git a/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp b/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp
index 62f9d46786c..5f9e5e65791 100644
--- a/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp
+++ b/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp
@@ -4,10 +4,6 @@
#include "tao/CSD_Framework/CSD_Framework_Loader.h"
#include "tao/CSD_Framework/CSD_Object_Adapter_Factory.h"
#include "tao/CSD_Framework/CSD_Strategy_Repository.h"
-#include "tao/CSD_Framework/CSD_ORBInitializer.h"
-#include "tao/PI/DLL_Resident_ORB_Initializer.h"
-#include "tao/ORBInitializer_Registry.h"
-#include "tao/ORB_Core.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -24,13 +20,12 @@ TAO_CSD_Framework_Loader::~TAO_CSD_Framework_Loader (void)
int
TAO_CSD_Framework_Loader::static_init (void)
{
- ACE_Service_Config::process_directive
- (ace_svc_desc_TAO_CSD_Object_Adapter_Factory);
-
- ACE_Service_Config::process_directive
- (ace_svc_desc_TAO_CSD_Strategy_Repository);
-
- ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_Framework_Loader);
+ ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_CSD_Object_Adapter_Factory);
+ ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_CSD_Strategy_Repository);
+ ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_CSD_Framework_Loader);
return 0;
}
@@ -46,50 +41,6 @@ TAO_CSD_Framework_Loader::init (int, ACE_TCHAR* [])
this->initialized_ = true;
- // Register the ORB initializer.
- try
- {
- PortableInterceptor::ORBInitializer_ptr temp_orb_initializer =
- PortableInterceptor::ORBInitializer::_nil ();
-
- /// Register the CSD ORBInitializer.
- ACE_NEW_THROW_EX (temp_orb_initializer,
- TAO_CSD_ORBInitializer,
- CORBA::NO_MEMORY (
- CORBA::SystemException::_tao_minor_code (
- TAO::VMCID,
- ENOMEM),
- CORBA::COMPLETED_NO));
-
- PortableInterceptor::ORBInitializer_var orb_initializer;
- orb_initializer = temp_orb_initializer;
-
- PortableInterceptor::ORBInitializer_ptr temp_dll_initializer =
- PortableInterceptor::ORBInitializer::_nil ();
-
- ACE_NEW_THROW_EX (temp_dll_initializer,
- PortableInterceptor::DLL_Resident_ORB_Initializer(
- orb_initializer.in (),
- ACE_TEXT ("TAO_CSD_ThreadPool")),
- CORBA::NO_MEMORY (
- CORBA::SystemException::_tao_minor_code (
- TAO::VMCID,
- ENOMEM),
- CORBA::COMPLETED_NO));
-
- PortableInterceptor::ORBInitializer_var dll_initializer;
- dll_initializer = temp_dll_initializer;
-
- PortableInterceptor::register_orb_initializer (dll_initializer.in ());
- }
- catch (const ::CORBA::Exception& ex)
- {
- ex._tao_print_exception (
- "Unexpected exception caught while "
- "initializing the CSD Framework");
- return 1;
- }
-
return 0;
}
diff --git a/TAO/tao/CSD_Framework/CSD_ORBInitializer.h b/TAO/tao/CSD_Framework/CSD_ORBInitializer.h
index 1b8570ca311..d82a8c5d8c6 100644
--- a/TAO/tao/CSD_Framework/CSD_ORBInitializer.h
+++ b/TAO/tao/CSD_Framework/CSD_ORBInitializer.h
@@ -36,7 +36,7 @@
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
-class TAO_CSD_ORBInitializer
+class TAO_CSD_FW_Export TAO_CSD_ORBInitializer
: public virtual PortableInterceptor::ORBInitializer
, public virtual ::CORBA::LocalObject
{
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp
index 87edf4b4c13..49603a489a6 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp
@@ -36,6 +36,7 @@ TAO::CSD::TP_Queue::put(TP_Request* request)
this->tail_->next_ = request;
this->tail_ = request;
}
+
}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h
index 9912c0e613a..3cdfdbe942c 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h
@@ -22,6 +22,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/Versioned_Namespace.h"
+#include "tao/orbconf.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -77,7 +78,6 @@ namespace TAO
/// visiting every request).
void accept_visitor(TP_Queue_Visitor& visitor);
-
private:
/// The request at the front of the queue.
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp
index a1e7be7af59..df57ecaaac7 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp
@@ -34,103 +34,90 @@ TAO::CSD::TP_Strategy_Factory::init (int argc,
initialized = 1;
TAO_CSD_Strategy_Repository *repo =
- ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance ("TAO_CSD_Strategy_Repository");
-
- if (repo != 0)
- repo->init(0,0);
+ ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
+ (ACE_TEXT ("TAO_CSD_Strategy_Repository"));
+
+ if (repo == 0)
+ {
+ TAO_CSD_ThreadPool::init ();
+ repo = ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
+ (ACE_TEXT ("TAO_CSD_Strategy_Repository"));
+ }
+
+ if (repo == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - TP_Strategy_Factory - ")
+ ACE_TEXT ("cannot initialize strategy repo\n")));
+ }
+ return -1;
+ }
+
+ repo->init(0,0);
// Parse any service configurator parameters.
for (int curarg = 0; curarg < argc; curarg++)
- if (ACE_OS::strcasecmp (argv[curarg],
- ACE_TEXT("-CSDtp")) == 0)
- {
- ACE_CString poa_name;
- unsigned long num_threads = 1;
- bool serialize_servants = true;
-
- curarg++;
- if (curarg < argc)
- {
- // Parse the parameter
- ACE_CString arg ((const char *)argv[curarg]);
- ACE_CString::size_type pos = arg.find (':');
-
- if (pos == ACE_CString::npos)
- {
- poa_name = arg;
- }
- else
- {
- poa_name = arg.substr (0, pos);
-
- ACE_CString arg_remainder =
- arg.substr (pos + 1, arg.length () - pos);
-
- ACE_CString num_thread_str;
-
- pos = arg_remainder.find (':');
-
- if (pos == ACE_CString::npos)
- {
- num_thread_str = arg_remainder;
- }
- else
- {
- num_thread_str = arg_remainder.substr (0, pos);
-
- ACE_CString off_str =
- arg_remainder.substr (pos + 1, arg.length () - pos);
-
- // Case-insensitive string comparison.
- if (ACE_OS::strcasecmp (off_str.c_str(), "OFF") == 0)
- {
- serialize_servants = false;
- }
- }
-
- num_threads = ACE_OS::strtoul (num_thread_str.c_str (), 0, 10);
-
- if (num_threads == 0)
- {
- // Minimum of 1 thread required.
- num_threads = 1;
- }
- }
-
- // Create the ThreadPool strategy for each named poa.
- TP_Strategy* strategy = 0;
- ACE_NEW_RETURN (strategy,
- TP_Strategy (num_threads, serialize_servants),
- -1);
- CSD_Framework::Strategy_var objref = strategy;
-
- TAO_CSD_Strategy_Repository *repo =
- ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
- ("TAO_CSD_Strategy_Repository");
-
- if (repo == 0)
- {
- TAO_CSD_ThreadPool::init ();
- repo = ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance (
- "TAO_CSD_Strategy_Repository"
- );
- }
-
-
- repo->add_strategy (poa_name, strategy);
- }
- }
- else
- {
- if (TAO_debug_level > 0)
- {
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT("CSD_ORB_Loader: Unknown option ")
- ACE_TEXT("<%s>.\n"),
- argv[curarg]));
- }
- }
-
+ {
+ if (ACE_OS::strcasecmp (argv[curarg],
+ ACE_TEXT("-CSDtp")) == 0)
+ {
+ ACE_CString poa_name;
+ unsigned long num_threads = 1;
+ bool serialize_servants = true;
+
+ curarg++;
+ if (curarg >= argc)
+ {
+ return -1;
+ }
+
+ // Parse the parameter
+ ACE_TCHAR *sep = ACE_OS::strchr (argv[curarg],':');
+ if (sep == 0)
+ {
+ poa_name = ACE_TEXT_ALWAYS_CHAR (argv[curarg]);
+ }
+ else
+ {
+ *sep = 0;
+ poa_name = ACE_TEXT_ALWAYS_CHAR (argv[curarg]);
+ num_threads = ACE_OS::strtol (sep + 1, &sep, 10);
+ if (*sep != 0 && *sep != ':')
+ {
+ return -1;
+ }
+ if (*sep == ':')
+ {
+ if (ACE_OS::strcasecmp (sep + 1, "OFF") == 0)
+ {
+ serialize_servants = false;
+ }
+ }
+ }
+
+ // Create the ThreadPool strategy for each named poa.
+ TP_Strategy* strategy = 0;
+ ACE_NEW_RETURN (strategy,
+ TP_Strategy (num_threads, serialize_servants),
+ -1);
+ CSD_Framework::Strategy_var objref = strategy;
+ repo->add_strategy (poa_name, strategy);
+
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT("CSD_ORB_Loader: Unknown option ")
+ ACE_TEXT("<%s>.\n"),
+ argv[curarg]));
+ }
+ return -1;
+ }
+ }
return 0;
}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp
index c96a65eccb6..80f1ac5f23a 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp
@@ -45,11 +45,11 @@ TAO::CSD::TP_Task::add_request(TP_Request* request)
int
-TAO::CSD::TP_Task::open(void* num_threads_ptr)
+TAO::CSD::TP_Task::open(void* args)
{
Thread_Counter num = 1;
- Thread_Counter* tmp = static_cast<Thread_Counter*> (num_threads_ptr);
+ Thread_Counter* tmp = static_cast<Thread_Counter*> (args);
if (tmp == 0)
{
@@ -78,7 +78,8 @@ TAO::CSD::TP_Task::open(void* num_threads_ptr)
{
ACE_ERROR_RETURN((LM_ERROR,
ACE_TEXT ("(%P|%t) TP_Task failed to open. ")
- ACE_TEXT ("num_threads (%u) is too large. Max is %d.\n"),
+ ACE_TEXT ("num_threads (%u) is too large. ")
+ ACE_TEXT ("Max is %d.\n"),
num, MAX_THREADPOOL_TASK_WORKER_THREADS),
-1);
}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h
index fea7b2ecc4e..ce5c4b705c6 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h
@@ -89,7 +89,7 @@ namespace TAO
bool add_request(TP_Request* request);
/// Activate the worker threads
- virtual int open(void* num_threads_ptr = 0);
+ virtual int open(void* args = 0);
/// The "mainline" executed by each worker thread.
virtual int svc();
diff --git a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp
index 6b83baebc12..120f88a3a73 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp
+++ b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp
@@ -6,6 +6,12 @@
#include "tao/debug.h"
#include "ace/Dynamic_Service.h"
+#include "tao/CSD_Framework/CSD_ORBInitializer.h"
+#include "tao/PI/DLL_Resident_ORB_Initializer.h"
+#include "tao/ORBInitializer_Registry.h"
+#include "tao/ORB_Core.h"
+
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
int
@@ -17,7 +23,55 @@ TAO_CSD_ThreadPool::init (void)
initialized = 1;
TAO_CSD_Framework_Loader::static_init();
- return ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_TP_Strategy_Factory);
+
+ // Register the ORB initializer.
+ try
+ {
+ PortableInterceptor::ORBInitializer_ptr temp_orb_initializer =
+ PortableInterceptor::ORBInitializer::_nil ();
+
+ /// Register the CSD ORBInitializer.
+ ACE_NEW_THROW_EX (temp_orb_initializer,
+ TAO_CSD_ORBInitializer,
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+
+ PortableInterceptor::ORBInitializer_var orb_initializer;
+ orb_initializer = temp_orb_initializer;
+
+ PortableInterceptor::ORBInitializer_ptr temp_dll_initializer =
+ PortableInterceptor::ORBInitializer::_nil ();
+
+ ACE_NEW_THROW_EX (temp_dll_initializer,
+ PortableInterceptor::DLL_Resident_ORB_Initializer(
+ orb_initializer.in (),
+ ACE_TEXT ("TAO_CSD_ThreadPool")),
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+
+ PortableInterceptor::ORBInitializer_var dll_initializer;
+ dll_initializer = temp_dll_initializer;
+
+ PortableInterceptor::register_orb_initializer (
+ dll_initializer.in ());
+ }
+ catch (const ::CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ "Unexpected exception caught while "
+ "initializing the CSD Framework");
+ return 1;
+ }
+
+
+ return ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_CSD_TP_Strategy_Factory);
}
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h
index 82a5f082ee4..8b22f1a1b2c 100644
--- a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h
+++ b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h
@@ -17,8 +17,6 @@
#include "tao/CSD_ThreadPool/CSD_TP_Export.h"
#include "tao/Versioned_Namespace.h"
-#include "ace/Service_Object.h"
-#include "ace/Service_Config.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
@@ -28,11 +26,13 @@
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
/**
- * @class TP_Strategy_Factory
+ * @class TAO_CSD_ThreadPool
*
- * @brief An ACE_Service_Object capable of creating TP_Strategy objects.
+ * @brief the static initializer for the CSD Thread Pool library
*
- * TBD - Explain in more detail.
+ * The loader appears to be born of the CSD_TP_Factory, which is the
+ * real service object. This separation seems to be necesary to ensure
+ * the CSD_Framework gets loaded prior to initializing the TP Factory.
*
*/
class TAO_CSD_TP_Export TAO_CSD_ThreadPool
diff --git a/TAO/tao/Client_Strategy_Factory.h b/TAO/tao/Client_Strategy_Factory.h
index ece676673ea..4ccdc1543f6 100644
--- a/TAO/tao/Client_Strategy_Factory.h
+++ b/TAO/tao/Client_Strategy_Factory.h
@@ -32,6 +32,11 @@ ACE_END_VERSIONED_NAMESPACE_DECL
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+namespace TAO
+{
+ struct Invocation_Retry_Params;
+}
+
class TAO_Transport_Mux_Strategy;
class TAO_Wait_Strategy;
class TAO_Transport;
@@ -84,6 +89,11 @@ public:
* Only applicable to RW wait strategy
*/
virtual bool use_cleanup_options (void) const = 0;
+
+ /// Return the parameters used to optionally retry invocation
+ /// after an exception occurs.
+ virtual const TAO::Invocation_Retry_Params &invocation_retry_params (void) const = 0;
+
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp
index e302ccaff0f..1385d2fb5e5 100644
--- a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp
+++ b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.cpp
@@ -96,8 +96,11 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
+ ACE_UNUSED_ARG (retry_state);
+
// Simple sanity check
if (this->mode_ != TAO_DII_INVOCATION ||
this->type_ != TAO_TWOWAY_INVOCATION)
@@ -216,8 +219,11 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
+ ACE_UNUSED_ARG (retry_state);
+
// Simple sanity check
if (this->mode_ != TAO_DII_DEFERRED_INVOCATION ||
this->type_ != TAO_TWOWAY_INVOCATION)
@@ -288,7 +294,8 @@ namespace TAO
TAO_Operation_Details &,
CORBA::Object_var &,
Profile_Transport_Resolver &,
- ACE_Time_Value *&)
+ ACE_Time_Value *&,
+ Invocation_Retry_State *)
{
return TAO_INVOKE_FAILURE;
}
diff --git a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.h b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.h
index 80b2c6f9274..a7586d5a71b 100644
--- a/TAO/tao/DynamicInterface/DII_Invocation_Adapter.h
+++ b/TAO/tao/DynamicInterface/DII_Invocation_Adapter.h
@@ -102,7 +102,8 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
virtual Invocation_Status invoke_collocated_i (
TAO_Stub *stub,
@@ -154,7 +155,8 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
virtual Invocation_Status invoke_collocated_i (
TAO_Stub *stub,
@@ -199,7 +201,8 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
};
#endif /* TAO_HAS_AMI */
diff --git a/TAO/tao/Dynamic_TP/DTP_Config.cpp b/TAO/tao/Dynamic_TP/DTP_Config.cpp
new file mode 100644
index 00000000000..47768ce0b99
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Config.cpp
@@ -0,0 +1,327 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_Config.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/DTP_ORBInitializer.h"
+
+#include "tao/debug.h"
+#include "ace/Dynamic_Service.h"
+#include "ace/OS_NS_strings.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_Config_Registry_Installer::TAO_DTP_Config_Registry_Installer (void)
+{
+ ACE_Service_Config::process_directive (ace_svc_desc_TAO_DTP_Config_Registry);
+}
+
+
+TAO_DTP_Config_Registry::TAO_DTP_Config_Registry (void)
+{
+}
+
+TAO_DTP_Config_Registry::~TAO_DTP_Config_Registry (void)
+{
+}
+
+int
+TAO_DTP_Config_Registry::init (int , ACE_TCHAR* [] )
+{
+ return 0;
+}
+
+bool
+TAO_DTP_Config_Registry::find (const ACE_CString& name,
+ TAO_DTP_Definition &entry)
+{
+ return registry_.find (name, entry) == 0;
+}
+
+int
+TAO_DTP_Config_Registry::bind (const ACE_CString& name,
+ TAO_DTP_Definition &entry)
+{
+ return registry_.bind (name, entry);
+}
+
+int
+TAO_DTP_Config_Registry::rebind (const ACE_CString& name,
+ TAO_DTP_Definition &entry)
+{
+ return registry_.rebind (name, entry);
+}
+
+//-------------------------------------------------------------------------
+
+TAO_DTP_Config::TAO_DTP_Config (void)
+{
+}
+
+TAO_DTP_Config::~TAO_DTP_Config (void)
+{
+}
+
+int
+TAO_DTP_Config::init (int argc, ACE_TCHAR* argv[])
+{
+ TAO_DTP_Definition entry;
+
+ ACE_TCHAR *name = 0;
+ bool overwrite = false;
+
+ int curarg = 0;
+ int r = 0;
+
+ for (curarg = 0; curarg < argc; ++curarg)
+ {
+ long val = 0;
+ if ((r = this->parse_string (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPName"),name )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ }
+ else if ((r = this->parse_bool (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPOverwrite"),
+ overwrite )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPMin"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.min_threads_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPInit"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.init_threads_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPMax"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.max_threads_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPStack"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.stack_size_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPTImeout"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.timeout_ = val;
+ }
+ else if ((r = this->parse_long (curarg,
+ argc,
+ argv,
+ ACE_TEXT("-DTPQueue"),
+ val )) != 0)
+ {
+ if (r < 0)
+ {
+ return -1;
+ }
+ entry.queue_depth_ = val;
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Config - ")
+ ACE_TEXT ("Unrecognized argv[%d], %C\n"),
+ curarg, argv[curarg]));
+ }
+ return -1;
+ }
+ }
+
+ if ((entry.max_threads_ != -1 && entry.max_threads_ < entry.init_threads_) ||
+ (entry.min_threads_ > entry.init_threads_))
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Config - ")
+ ACE_TEXT ("thread count constraint ")
+ ACE_TEXT ("violated, min: %d <= init: %d <= max: ")
+ ACE_TEXT ("%d or max = -1\n"),
+ entry.min_threads_,
+ entry.init_threads_,
+ entry.max_threads_));
+ }
+ return 0;
+ }
+
+ ACE_CString name_str = name;
+ ACE_Service_Gestalt *current = ACE_Service_Config::current();
+ TAO_DTP_Config_Registry* registry =
+ ACE_Dynamic_Service<TAO_DTP_Config_Registry>::instance
+ (current, "DTP_Config_Registry", true);
+
+ if (registry == 0)
+ {
+ current->process_directive (ace_svc_desc_TAO_DTP_Config_Registry);
+ registry = ACE_Dynamic_Service<TAO_DTP_Config_Registry>::instance
+ (current, "DTP_Config_Registry", true);
+ if (registry == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Config - ")
+ ACE_TEXT ("cannot initialize registry\n")));
+ }
+ return -1;
+ }
+ }
+
+ if (!overwrite)
+ {
+ return registry->bind(name_str, entry);
+ }
+ else
+ {
+ return registry->rebind(name_str, entry);
+ }
+ return 0;
+}
+
+int
+TAO_DTP_Config::parse_long (int &curarg,
+ int argc, ACE_TCHAR *argv[],
+ const ACE_TCHAR *match, long &value)
+{
+ ACE_TCHAR *str;
+ int result = this->parse_string (curarg, argc, argv, match, str);
+ if (result < 1)
+ return result;
+
+ ACE_TCHAR *err = 0;
+ value = ACE_OS::strtol (str, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (match, str);
+ return -1;
+ }
+ return 1;
+}
+
+int
+TAO_DTP_Config::parse_bool (int &curarg,
+ int argc, ACE_TCHAR *argv[],
+ const ACE_TCHAR *match, bool &value)
+{
+ long num;
+ int result = this->parse_long (curarg, argc, argv, match, num);
+ if (result < 1)
+ return result;
+
+ value = num != 0;
+
+ return 1;
+}
+
+int
+TAO_DTP_Config::parse_string (int &curarg,
+ int argc, ACE_TCHAR *argv[],
+ const ACE_TCHAR *match, ACE_TCHAR *&value)
+{
+ if (ACE_OS::strcasecmp (argv[curarg], match) != 0)
+ return 0;
+
+ ++curarg;
+ if (curarg >= argc)
+ {
+ this->report_option_value_error (match, ACE_TEXT("<missing>"));
+ return -1;
+ }
+
+ value = argv[curarg];
+ return 1;
+}
+
+
+void
+TAO_DTP_Config::report_option_value_error (const ACE_TCHAR* option_name,
+ const ACE_TCHAR* option_value)
+{
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Config - unknown ")
+ ACE_TEXT ("argument <%s> for <%s>\n"),
+ option_value, option_name));
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_Config_Registry)
+ACE_STATIC_SVC_DEFINE (TAO_DTP_Config_Registry,
+ ACE_TEXT ("DTP_Config_Registry"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_Config_Registry),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_Config)
+ACE_STATIC_SVC_DEFINE (TAO_DTP_Config,
+ ACE_TEXT ("DTP_Config"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_Config),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 */
+
diff --git a/TAO/tao/Dynamic_TP/DTP_Config.h b/TAO/tao/Dynamic_TP/DTP_Config.h
new file mode 100644
index 00000000000..6deddf381de
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Config.h
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file
+ *
+ * $Id$
+ *
+ * Header file for Loading DynamicTP Configurations.
+ *
+ *
+ * @author
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_CONFIG_H
+#define TAO_DYNAMIC_TP_CONFIG_H
+#include /**/ "ace/pre.h"
+
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "ace/Service_Object.h"
+#include "ace/Service_Config.h"
+#include "ace/RB_Tree.h"
+#include "ace/Synch.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+struct TAO_Dynamic_TP_Export TAO_DTP_Definition
+{
+ int min_threads_; // a default of -1 implies Lifespan of INFINITE, > 0 implies IDLE
+ int init_threads_; // default to 5
+ int max_threads_; // a default of -1 implies no limit.
+ size_t stack_size_;
+ ACE_Time_Value timeout_; // default to 60 seconds
+ int queue_depth_;
+
+ // Create explicit constructor to eliminate issues with non-initialized struct values.
+ TAO_DTP_Definition() :
+ min_threads_(-1),
+ init_threads_(5),
+ max_threads_(-1),
+ stack_size_(ACE_DEFAULT_THREAD_STACKSIZE),
+ timeout_(60,0),
+ queue_depth_(0){}
+
+};
+
+class TAO_Dynamic_TP_Export TAO_DTP_Config_Registry_Installer
+{
+ public:
+ TAO_DTP_Config_Registry_Installer (void);
+};
+
+class TAO_Dynamic_TP_Export TAO_DTP_Config_Registry : public ACE_Service_Object
+{
+public:
+ TAO_DTP_Config_Registry (void);
+ virtual ~TAO_DTP_Config_Registry (void);
+
+ virtual int init (int argc, ACE_TCHAR* []);
+
+ /// initializes the supplied set value with the configuration associated with the name, or returns false.
+ bool find (const ACE_CString& name, TAO_DTP_Definition &entry);
+
+ int bind (const ACE_CString& name, TAO_DTP_Definition &entry);
+ int rebind (const ACE_CString& name, TAO_DTP_Definition &entry);
+
+ private:
+ typedef ACE_RB_Tree<ACE_CString, TAO_DTP_Definition, ACE_Less_Than<ACE_CString>, ACE_Null_Mutex> Registry;
+ Registry registry_;
+};
+
+class TAO_Dynamic_TP_Export TAO_DTP_Config : public ACE_Service_Object
+{
+public:
+ /// Constructor.
+ TAO_DTP_Config (void);
+
+ /// Destructor.
+ virtual ~TAO_DTP_Config (void);
+
+ /// Read a definition parameter set from the supplied args.
+ /// There must be a -TPName argument, which, if replicated will cause the set to be ignored, unless -TPOverwrite is also set
+ /// constriants: min threads <= initial threads <= max_threads.
+ /// defaults: min threads = initial = max = 5
+ /// default lifespan = infinite
+ /// idle timeout is in secondes, default = 60
+ /// default stack size = 0, system defined default used.
+ /// queue depth is in number of messages, default is infinite
+ /// Init can be called multiple times,
+ virtual int init (int argc, ACE_TCHAR* []);
+
+private:
+ int parse_long (int &curarg, int argc, ACE_TCHAR* argv[], const ACE_TCHAR *match, long &value);
+ int parse_bool (int &curarg, int argc, ACE_TCHAR* argv[], const ACE_TCHAR *match, bool &value);
+ int parse_string (int &curarg, int argc, ACE_TCHAR* argv[], const ACE_TCHAR *match, ACE_TCHAR *&value);
+ void report_option_value_error (const ACE_TCHAR* option_name,
+ const ACE_TCHAR* option_value);
+
+};
+
+static TAO_DTP_Config_Registry_Installer config_installer;
+
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP, TAO_DTP_Config_Registry)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP, TAO_DTP_Config_Registry)
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP, TAO_DTP_Config)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP, TAO_DTP_Config)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+#endif /* TAO_DYNAMIC_TP_CONFIG_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp
new file mode 100644
index 00000000000..d193c3b54ea
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp
@@ -0,0 +1,132 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_ORBInitializer.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h"
+#include "tao/Dynamic_TP/DTP_Thread_Pool.h"
+#include "tao/Exception.h"
+#include "tao/ORB_Core.h"
+#include "tao/PI/ORBInitInfo.h"
+#include "tao/debug.h"
+
+#include "ace/Service_Repository.h"
+#include "ace/Svc_Conf.h"
+#include "ace/Sched_Params.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_ORBInitializer::TAO_DTP_ORBInitializer (/*const ACE_CString &tplist*/)
+{
+
+}
+
+void
+TAO_DTP_ORBInitializer::pre_init (PortableInterceptor::ORBInitInfo_ptr info)
+{
+ TAO_ORBInitInfo_var tao_info = TAO_ORBInitInfo::_narrow (info);
+
+ if (CORBA::is_nil (tao_info.in ()))
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) TAO_DTP_ORBInitializer::pre_init:\n")
+ ACE_TEXT ("(%P|%t) Unable to narrow ")
+ ACE_TEXT ("\"PortableInterceptor::ORBInitInfo_ptr\" to\n")
+ ACE_TEXT ("(%P|%t) \"TAO_ORBInitInfo *.\"\n")));
+
+ throw ::CORBA::INTERNAL ();
+ }
+
+
+ ACE_Service_Gestalt *gestalt = tao_info->orb_core ()->configuration();
+
+ ACE_Service_Object * const config_obj =
+ ACE_Dynamic_Service<ACE_Service_Object>::instance (
+ gestalt,
+ "DTP_Config",
+ true);
+ if (config_obj == 0)
+ {
+ // no config manager object loaded
+ return;
+ }
+
+ TAO_DTP_Config *config_mgr = dynamic_cast<TAO_DTP_Config *>(config_obj);
+ if (config_mgr == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) TAO_DTP_ORBInitializer::pre_init:\n")
+ ACE_TEXT ("(%P|%t) Unable to resolve DTP_Config ")
+ ACE_TEXT ("object\n")));
+
+ throw ::CORBA::INTERNAL ();
+ }
+
+ // Set the name of the thread lane resources manager to be
+ // DTP_Thread_Lane_Resources_Manager.
+ tao_info->orb_core ()->orb_params ()
+ ->thread_lane_resources_manager_factory_name (
+ "DTP_Thread_Lane_Resources_Manager_Factory");
+ ACE_Service_Config::process_directive (
+ ace_svc_desc_TAO_DTP_Thread_Lane_Resources_Manager_Factory);
+
+}
+
+void
+TAO_DTP_ORBInitializer::post_init (PortableInterceptor::ORBInitInfo_ptr info)
+{
+ TAO_ORBInitInfo_var tao_info = TAO_ORBInitInfo::_narrow (info);
+
+ TAO_Thread_Lane_Resources_Manager &tlrm =
+ tao_info->orb_core ()->thread_lane_resources_manager();
+
+ ACE_Service_Gestalt *gestalt = tao_info->orb_core ()->configuration();
+
+ const char *dtp_name =
+ tao_info->orb_core ()->orb_params ()->dynamic_thread_pool_config_name ();
+
+ if (dtp_name != 0 && dtp_name[0] != 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) TAO_DTP_ORBInitializer::post_init ")
+ ACE_TEXT ("using thread pool name %s\n"), dtp_name));
+ }
+
+ TAO_DTP_Config_Registry *config_registry =
+ dynamic_cast<TAO_DTP_Config_Registry *>
+ (ACE_Dynamic_Service<ACE_Service_Object>::instance
+ (gestalt, "DTP_Config_Registry", true));
+
+ TAO_DTP_Definition def;
+
+ if (!config_registry->find(dtp_name, def))
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) TAO_DTP_ORBInitializer::")
+ ACE_TEXT ("post_init:\n")
+ ACE_TEXT ("(%P|%t) Unable to resolve ")
+ ACE_TEXT ("DTP_Config object\n")));
+
+ throw ::CORBA::INTERNAL ();
+ }
+
+ TAO_DTP_Thread_Lane_Resources_Manager &dtp_tlrm =
+ dynamic_cast<TAO_DTP_Thread_Lane_Resources_Manager &>(tlrm);
+
+ dtp_tlrm.tp_manager().create_threadpool (def);
+ }
+
+
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_ORBInitializer.h b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.h
new file mode 100644
index 00000000000..770ac31b50d
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.h
@@ -0,0 +1,72 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_ORBInitializer.h
+ *
+ * $Id$
+ *
+ * @author Ossama Othman <ossama@uci.edu>
+ */
+//=============================================================================
+
+
+#ifndef TAO_DYNAMIC_TP_ORB_INITIALIZER_H
+#define TAO_DYNAMIC_TP_ORB_INITIALIZER_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/PI/PI.h"
+#include "tao/LocalObject.h"
+
+// This is to remove "inherits via dominance" warnings from MSVC.
+// MSVC is being a little too paranoid.
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4250)
+#endif /* _MSC_VER */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/// Dynamic_TP ORB initializer.
+class TAO_DTP_ORBInitializer
+ : public virtual PortableInterceptor::ORBInitializer
+ , public virtual ::CORBA::LocalObject
+{
+public:
+
+ TAO_DTP_ORBInitializer (void);
+
+ virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info);
+
+ virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info);
+
+private:
+
+ /// Register Dynamic_TP policy factories.
+ void register_policy_factories (PortableInterceptor::ORBInitInfo_ptr info);
+
+private:
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_DYNAMIC_TP_ORB_INITIALIZER_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_ORB_Loader.cpp b/TAO/tao/Dynamic_TP/DTP_ORB_Loader.cpp
new file mode 100644
index 00000000000..838e0a7e3d1
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_ORB_Loader.cpp
@@ -0,0 +1,113 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_ORB_Loader.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/DTP_ORBInitializer.h"
+
+#include "tao/debug.h"
+#include "tao/ORB_Constants.h"
+#include "tao/ORBInitializer_Registry.h"
+#include "tao/SystemException.h"
+#include "ace/Dynamic_Service.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/Arg_Shifter.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_ORB_Loader::TAO_DTP_ORB_Loader (void)
+ : initialized_ (false)
+{
+}
+
+TAO_DTP_ORB_Loader::~TAO_DTP_ORB_Loader (void)
+{
+}
+
+int
+TAO_DTP_ORB_Loader::init (int argc, ACE_TCHAR* argv[])
+{
+ ACE_TRACE ("TAO_DTP_ORB_Loader::init");
+
+ // Only allow initialization once.
+ if (this->initialized_)
+ return 0;
+ this->initialized_ = true;
+
+ int curarg = 0;
+ for (curarg = 0; curarg < argc; ++curarg)
+ {
+ if (ACE_OS::strcasecmp (argv[curarg], ACE_TEXT ("-DTPORB")) == 0)
+ {
+ ++curarg;
+ if (curarg >= argc)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_ORB_Loader - ")
+ ACE_TEXT ("DTPORB argument missing value\n")));
+ }
+ return -1;
+ }
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_ORB_Loader -")
+ ACE_TEXT (" Unrecognized argv[%d], %C\n"),
+ curarg, argv[curarg]));
+ }
+ return -1;
+ }
+ }
+
+ // Register the ORB initializer.
+ try
+ {
+ PortableInterceptor::ORBInitializer_ptr temp_orb_initializer =
+ PortableInterceptor::ORBInitializer::_nil ();
+
+ /// Register the DynamicTP ORBInitializer.
+ ACE_NEW_THROW_EX (temp_orb_initializer,
+ TAO_DTP_ORBInitializer (),
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+
+ PortableInterceptor::ORBInitializer_var orb_initializer;
+ orb_initializer = temp_orb_initializer;
+
+ PortableInterceptor::register_orb_initializer (orb_initializer.in ());
+ }
+ catch (const ::CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ "Unexpected exception caught while "
+ "initializing the RTORB");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_ORB_Loader)
+ACE_STATIC_SVC_DEFINE (TAO_DTP_ORB_Loader,
+ ACE_TEXT ("DTP_ORB_Loader"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_ORB_Loader),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 */
+
diff --git a/TAO/tao/Dynamic_TP/DTP_ORB_Loader.h b/TAO/tao/Dynamic_TP/DTP_ORB_Loader.h
new file mode 100644
index 00000000000..ffef32befd2
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_ORB_Loader.h
@@ -0,0 +1,63 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_ORB_Loader.h
+ *
+ * $Id$
+ *
+ * Header file for Loading DynamicTP.
+ *
+ *
+ * @author Phil Mesnier <mesnier_p@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_ORB_LOADER_H
+#define TAO_DYNAMIC_TP_ORB_LOADER_H
+#include /**/ "ace/pre.h"
+
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "ace/Service_Object.h"
+#include "ace/Service_Config.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_ORB_Core;
+
+class TAO_Dynamic_TP_Export TAO_DTP_ORB_Loader : public ACE_Service_Object
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_ORB_Loader (void);
+
+ /// Destructor.
+ virtual ~TAO_DTP_ORB_Loader (void);
+
+ /// Initialize the DynamicTP loader hooks.
+ virtual int init (int argc, ACE_TCHAR* []);
+
+private:
+ /// Set to true after init is called.
+ bool initialized_;
+};
+
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP, TAO_DTP_ORB_Loader)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP, TAO_DTP_ORB_Loader)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+#endif /* TAO_DYNAMIC_TP_ORB_LOADER_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Loader.cpp b/TAO/tao/Dynamic_TP/DTP_POA_Loader.cpp
new file mode 100644
index 00000000000..b11349f98a4
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Loader.cpp
@@ -0,0 +1,199 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_POA_Loader.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/debug.h"
+#include "tao/CSD_Framework/CSD_Framework_Loader.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/Dynamic_TP/DTP_POA_Strategy.h"
+#include "ace/OS_NS_strings.h"
+#include "tao/CSD_Framework/CSD_ORBInitializer.h"
+#include "tao/PI/DLL_Resident_ORB_Initializer.h"
+#include "tao/ORBInitializer_Registry.h"
+#include "tao/ORB_Core.h"
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_POA_Loader::TAO_DTP_POA_Loader (void)
+{
+}
+
+TAO_DTP_POA_Loader::~TAO_DTP_POA_Loader (void)
+{
+}
+
+int
+TAO_DTP_POA_Loader::init (int argc, ACE_TCHAR* argv[])
+{
+ //TAO_debug_level = 5;
+
+ ACE_TRACE ("TAO_DTP_POA_Loader::init");
+
+ // Only allow initialization once.
+ static bool initialized = false;
+ if (initialized)
+ return 0;
+ initialized = true;
+
+ TAO_CSD_Strategy_Repository * repo =
+ ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
+ ("TAO_CSD_Strategy_Repository");
+
+
+ /* Now create a POA Configuration Map Registry to look up what
+ thread pool settings are associated with each POA
+ */
+
+ if (repo == 0)
+ {
+ ACE_Service_Config::process_directive(
+ ace_svc_desc_TAO_CSD_Strategy_Repository);
+ repo = ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
+ ("TAO_CSD_Strategy_Repository");
+ }
+
+ if (repo == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Loader - ")
+ ACE_TEXT ("cannot initialize strategy repo\n")));
+ }
+ return -1;
+ }
+
+ repo->init(0,0);
+
+ for (int curarg = 0; curarg < argc; curarg++)
+ {
+
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Loader - ")
+ ACE_TEXT ("parsing args\n")));
+ }
+
+ if (ACE_OS::strcasecmp (argv[curarg], ACE_TEXT ("-DTPPOAConfigMap"))
+ == 0)
+ {
+ ++curarg;
+ if (curarg >= argc)
+ {
+ this->report_option_value_error (ACE_TEXT ("-DTPPOAConfigMap"),
+ ACE_TEXT("<missing>"));
+ return -1;
+ }
+ if ((this->load_poa_map (argv[curarg], repo)) < 0)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+
+ /*
+ If we get here then we have another map set to process and
+ add to the map registry.
+ */
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("DTP_POA_Loader: Missing option\n")
+ ACE_TEXT ("Usage: -DTPPOAConfigMap <comma-separated ")
+ ACE_TEXT ("list of POAs>:<POA Config Name>\n")
+ ACE_TEXT ("<%s>.\n"),
+ argv[curarg]));
+ }
+ }
+
+ }
+
+ return 0;
+}
+
+
+int
+TAO_DTP_POA_Loader::load_poa_map (ACE_TCHAR *map,
+ TAO_CSD_Strategy_Repository *repo)
+{
+
+ ACE_CString poa_name;
+ ACE_CString config_name;
+ TAO_DTP_POA_Strategy * strategy_container = 0;
+
+ ACE_TCHAR *sep = ACE_OS::strchr (map, ':');
+
+ if (sep == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("DTP_POA_Loader: Missing option\n")
+ ACE_TEXT ("Usage: -DTPPOAConfigMap <comma-separated ")
+ ACE_TEXT ("list of POAs>:<POA Config Name>\n<%s>.\n"),
+ map));
+ }
+ return -1;
+ }
+
+ config_name = ACE_TEXT_ALWAYS_CHAR (sep + 1);
+ *sep = 0;
+
+ // Now that we have a config name and a null strategy
+ // implementation class we can allocate a new instance of a
+ // strategy configuration container.
+
+ ACE_NEW_RETURN(strategy_container,
+ TAO_DTP_POA_Strategy(config_name,
+ false), -1);
+
+ sep = ACE_OS::strchr (map, ',');
+ while (sep != 0)
+ {
+ *sep = 0;
+ poa_name = ACE_TEXT_ALWAYS_CHAR (map);
+ repo->add_strategy (poa_name, strategy_container);
+ map = sep + 1;
+ sep = ACE_OS::strchr (map, ',');
+ }
+ poa_name = ACE_TEXT_ALWAYS_CHAR (map);
+ repo->add_strategy(poa_name, strategy_container);
+
+ return 0;
+}
+
+void
+TAO_DTP_POA_Loader::report_option_value_error (const ACE_TCHAR* name,
+ const ACE_TCHAR* value)
+{
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Loader - unknown ")
+ ACE_TEXT ("argument <%s> for <%s>\n"),
+ value, name));
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_POA_Loader)
+ACE_STATIC_SVC_DEFINE (TAO_DTP_POA_Loader,
+ ACE_TEXT ("DTP_POA_Loader"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_POA_Loader),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Loader.h b/TAO/tao/Dynamic_TP/DTP_POA_Loader.h
new file mode 100644
index 00000000000..6af4993b46c
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Loader.h
@@ -0,0 +1,62 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_POA_Loader.h
+ *
+ * $Id$
+ *
+ * Header file for Loading DynamicTP.
+ *
+ *
+ * @author Phil Mesnier <mesnier_p@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_POA_LOADER_H
+#define TAO_DYNAMIC_TP_POA_LOADER_H
+#include /**/ "ace/pre.h"
+#include "tao/orbconf.h"
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/CSD_Framework/CSD_Strategy_Repository.h"
+#include "ace/Synch.h"
+#include "ace/Service_Object.h"
+#include "ace/Service_Config.h"
+#include "ace/RB_Tree.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_Dynamic_TP_Export TAO_DTP_POA_Loader : public ACE_Service_Object
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_POA_Loader (void);
+
+ /// Destructor.
+ virtual ~TAO_DTP_POA_Loader (void);
+
+ /// Initialize the DynamicTP loader hooks.
+ virtual int init (int argc, ACE_TCHAR* []);
+
+private:
+ /// Set to true after init is called.
+ int load_poa_map (ACE_TCHAR *map_str,
+ TAO_CSD_Strategy_Repository * reg);
+
+ void report_option_value_error (const ACE_TCHAR* option_name,
+ const ACE_TCHAR* option_value);
+};
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP, TAO_DTP_POA_Loader)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP, TAO_DTP_POA_Loader)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+#endif /* TAO_DYNAMIC_TP_POA_LOADER_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Strategy.cpp b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.cpp
new file mode 100644
index 00000000000..e715319750b
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.cpp
@@ -0,0 +1,422 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_POA_Strategy.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Remote_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h"
+#include "tao/ORB_Core.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+
+#if !defined (__ACE_INLINE__)
+#include "tao/Dynamic_TP/DTP_POA_Strategy.inl"
+#endif /* ! __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+
+TAO_DTP_POA_Strategy::~TAO_DTP_POA_Strategy()
+{
+}
+
+TAO_DTP_POA_Strategy::CustomRequestOutcome
+TAO_DTP_POA_Strategy::custom_synch_request(
+ TAO::CSD::TP_Custom_Request_Operation* op)
+{
+
+ TAO::CSD::TP_Servant_State::HandleType servant_state =
+ this->get_servant_state(op->servant());
+
+ TAO::CSD::TP_Custom_Synch_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Custom_Synch_Request(op, servant_state.in ()),
+ REQUEST_REJECTED);
+
+ TAO::CSD::TP_Custom_Synch_Request_Handle request = req_ptr;
+
+ if (!this->dtp_task_.add_request (request.in ()))
+ {
+ // The request was rejected by the task.
+ return REQUEST_REJECTED;
+ }
+
+ // Now we wait until the request is handled (executed or cancelled).
+ return (request->wait ()) ? REQUEST_EXECUTED : REQUEST_CANCELLED;
+}
+
+TAO_DTP_POA_Strategy::CustomRequestOutcome
+TAO_DTP_POA_Strategy::custom_asynch_request (
+ TAO::CSD::TP_Custom_Request_Operation* op)
+{
+
+ TAO::CSD::TP_Servant_State::HandleType servant_state =
+ this->get_servant_state (op->servant ());
+
+ TAO::CSD::TP_Custom_Asynch_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Custom_Asynch_Request (op, servant_state.in ()),
+ REQUEST_REJECTED);
+
+ TAO::CSD::TP_Custom_Asynch_Request_Handle request = req_ptr;
+
+ return (this->dtp_task_.add_request (request.in ()))
+ ? REQUEST_DISPATCHED : REQUEST_REJECTED;
+}
+
+bool
+TAO_DTP_POA_Strategy::poa_activated_event_i (TAO_ORB_Core& orb_core)
+{
+
+ this->dtp_task_.thr_mgr (orb_core.thr_mgr ());
+
+ // Activates the worker threads, and waits until all have been started.
+ if (!this->config_initialized_)
+ {
+ TAO_DTP_Config_Registry * config_repo =
+ ACE_Dynamic_Service<TAO_DTP_Config_Registry>::instance
+ ("DTP_Config_Registry");
+
+ if (config_repo == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy - ")
+ ACE_TEXT ("cannot retrieve configuration repo\n")));
+ }
+ return false;
+ }
+ else
+ {
+ TAO_DTP_Definition config_entry;
+ if (!config_repo->find (this->dynamic_tp_config_name_, config_entry))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy - ")
+ ACE_TEXT ("warning: config not found...using ")
+ ACE_TEXT ("defaults!\n")));
+
+ }
+ this->set_dtp_config (config_entry);
+ //this->dtp_task_.set_init_pool_threads(config_entry.init_threads_);
+ //this->dtp_task_.set_min_pool_threads(config_entry.min_threads_);
+ //this->dtp_task_.set_max_pool_threads(config_entry.max_threads_);
+ //this->dtp_task_.set_thread_idle_time(config_entry.timeout_);
+ //this->dtp_task_.set_thread_stack_size(config_entry.stack_size_);
+ //this->dtp_task_.set_max_request_queue_depth(config_entry.queue_depth_);
+ }
+
+
+
+ }
+ return (this->dtp_task_.open () == 0);
+
+}
+
+void
+TAO_DTP_POA_Strategy::poa_deactivated_event_i ()
+{
+ // Passing in a value of 1 means that we want to shutdown the task, which
+ // equates to causing all worker threads to shutdown. The worker threads
+ // themselves will also invoke the close() method, but the passed-in value
+ // will be 0. So, a 1 means "shutdown", and a 0 means "a single worker
+ // thread is going away".
+ this->dtp_task_.close(1);
+}
+
+TAO::CSD::Strategy_Base::DispatchResult
+TAO_DTP_POA_Strategy::dispatch_remote_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant)
+{
+ TAO::CSD::TP_Servant_State::HandleType servant_state =
+ this->get_servant_state (servant);
+
+ // Now we can create the TP_Remote_Request object, and then add it to our
+ // task_'s "request queue".
+ //
+ // TBD-CSD: Need to use a Cached Allocator to "create" the
+ // TP_Remote_Request objects. For now, use the heap.
+ TAO::CSD::TP_Remote_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Remote_Request (server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in ()),
+ TAO::CSD::Strategy_Base::DISPATCH_REJECTED);
+
+ TAO::CSD::TP_Remote_Request_Handle request = req_ptr;
+
+ // Hand the request object to our task so that it can add the request
+ // to its "request queue".
+ if (!this->dtp_task_.add_request (request.in ()))
+ {
+ // Return the DISPATCH_REJECTED return code so that the caller (our
+ // base class' dispatch_request() method) knows that we did
+ // not handle the request, and that it should be rejected.
+ return TAO::CSD::Strategy_Base::DISPATCH_REJECTED;
+ }
+
+ return TAO::CSD::Strategy_Base::DISPATCH_HANDLED;
+}
+
+TAO::CSD::Strategy_Base::DispatchResult
+TAO_DTP_POA_Strategy::dispatch_collocated_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant)
+{
+
+
+ TAO::CSD::TP_Servant_State::HandleType servant_state =
+ this->get_servant_state (servant);
+
+ bool is_sync_with_server = server_request.sync_with_server ();
+ bool is_synchronous = server_request.response_expected ();
+
+ TAO::CSD::TP_Collocated_Synch_Request_Handle
+ synch_request;
+ TAO::CSD::TP_Collocated_Synch_With_Server_Request_Handle
+ synch_with_server_request;
+ TAO::CSD::TP_Request_Handle
+ request;
+
+ // Create the request object using the appropriate concrete type.
+ if (is_sync_with_server)
+ {
+ TAO::CSD::TP_Collocated_Synch_With_Server_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Collocated_Synch_With_Server_Request
+ (server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in ()),
+ DISPATCH_REJECTED);
+
+ synch_with_server_request = req_ptr;
+
+ // Give the request handle its own "copy".
+ synch_with_server_request->_add_ref ();
+ request = synch_with_server_request.in ();
+ }
+ else if (is_synchronous)
+ {
+
+ TAO::CSD::TP_Collocated_Synch_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Collocated_Synch_Request (
+ server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in ()),
+ DISPATCH_REJECTED);
+
+ synch_request = req_ptr;
+
+ // Give the request handle its own "copy".
+ synch_request->_add_ref ();
+ request = synch_request.in ();
+ }
+ else
+ {
+ TAO::CSD::TP_Collocated_Asynch_Request *req_ptr;
+ ACE_NEW_RETURN (req_ptr,
+ TAO::CSD::TP_Collocated_Asynch_Request (server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in ()),
+ DISPATCH_REJECTED);
+
+ // Just use the (base) request handle to hold the request object.
+ request = req_ptr;
+ }
+
+ // Hand the request object to our task so that it can add the request
+ // to its "request queue".
+ if (!this->dtp_task_.add_request (request.in ()))
+ {
+ // Return the DISPATCH_REJECTED return code so that the caller (our
+ // base class' dispatch_request() method) knows that we did
+ // not handle the request, and that it should be rejected.
+ return DISPATCH_REJECTED;
+ }
+
+ // We need to wait on the request object if the request type is a
+ // synchronous request.
+ if (!synch_request.is_nil ())
+ {
+ int srw = synch_request->wait ();
+ if (srw == false)
+ {
+ // Raise exception when request was cancelled.
+ throw ::CORBA::NO_IMPLEMENT ();
+ }
+ }
+ else if (!synch_with_server_request.is_nil())
+ {
+ bool swsr = synch_with_server_request->wait();
+ if (swsr == false)
+ {
+ // Raise exception when request was cancelled.
+ throw ::CORBA::NO_IMPLEMENT ();
+ }
+ }
+
+ return DISPATCH_HANDLED;
+}
+
+void
+TAO_DTP_POA_Strategy::servant_activated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId&)
+{
+ if (this->serialize_servants_)
+ {
+ // Add the servant to the servant state map.
+ this->servant_state_map_.insert (servant);
+ }
+}
+
+void
+TAO_DTP_POA_Strategy::servant_deactivated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId&)
+{
+ // Cancel all requests stuck in the queue for the specified servant.
+ this->dtp_task_.cancel_servant (servant);
+
+ if (this->serialize_servants_)
+ {
+ // Remove the servant from the servant state map.
+ this->servant_state_map_.remove (servant);
+ }
+}
+
+void
+TAO_DTP_POA_Strategy::cancel_requests (PortableServer::Servant servant)
+{
+ // Cancel all requests stuck in the queue for the specified servant.
+ this->dtp_task_.cancel_servant (servant);
+}
+
+TAO::CSD::TP_Servant_State::HandleType
+TAO_DTP_POA_Strategy::get_servant_state (PortableServer::Servant servant)
+{
+ TAO::CSD::TP_Servant_State::HandleType servant_state;
+
+ if (this->serialize_servants_)
+ {
+ servant_state = this->servant_state_map_.find (servant);
+ }
+
+ return servant_state;
+}
+
+void
+TAO_DTP_POA_Strategy::set_dtp_config (TAO_DTP_Definition &tp_config)
+{
+
+ if (tp_config.min_threads_ <= 0)
+ {
+ this->dtp_task_.set_min_pool_threads (1);
+ this->dtp_task_.set_thread_idle_time (ACE_Time_Value (0,0));
+ }
+ else
+ {
+ this->dtp_task_.set_min_pool_threads (tp_config.min_threads_);
+ this->dtp_task_.set_thread_idle_time (tp_config.timeout_);
+ }
+
+ // initial_pool_threads_
+ if ((tp_config.init_threads_ <= 0) ||
+ (tp_config.init_threads_ < tp_config.min_threads_))
+ {
+ this->dtp_task_.set_init_pool_threads (this->dtp_task_.get_min_pool_threads());
+ }
+ else
+ {
+ this->dtp_task_.set_init_pool_threads (tp_config.init_threads_);
+ }
+
+ // max_pool_threads_
+
+ if (tp_config.max_threads_ <= 0)
+ {
+ // Set to 0 so that max is unbounded.
+ this->dtp_task_.set_max_pool_threads(0);
+ }
+ else
+ if (tp_config.max_threads_ < tp_config.init_threads_)
+ {
+ this->dtp_task_.set_max_pool_threads(
+ this->dtp_task_.get_init_pool_threads ());
+ }
+ else
+ {
+ this->dtp_task_.set_max_pool_threads (tp_config.max_threads_);
+ }
+
+ // thread_stack_size_
+
+ if (tp_config.stack_size_ <= 0)
+ {
+ this->dtp_task_.set_thread_stack_size (ACE_DEFAULT_THREAD_STACKSIZE);
+ }
+ else
+ {
+ this->dtp_task_.set_thread_stack_size (tp_config.stack_size_);
+ }
+
+ // max_request_queue_depth_
+ if (tp_config.queue_depth_ < 0)
+ {
+ this->dtp_task_.set_max_request_queue_depth (0);
+ }
+ else
+ {
+ this->dtp_task_.set_max_request_queue_depth (tp_config.queue_depth_);
+ }
+
+
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy: ")
+ ACE_TEXT ("Initialized with:\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy initial_pool_threads_=")
+ ACE_TEXT ("[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy min_pool_threads_=[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy max_pool_threads_=[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy max_request_queue_depth_=")
+ ACE_TEXT ("[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy thread_stack_size_=[%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_POA_Strategy thread_idle_time_=[%d]\n"),
+ this->dtp_task_.get_init_pool_threads(),
+ this->dtp_task_.get_min_pool_threads(),
+ this->dtp_task_.get_max_pool_threads(),
+ this->dtp_task_.get_max_request_queue_depth(),
+ this->dtp_task_.get_thread_stack_size(),
+ this->dtp_task_.get_thread_idle_time()));
+ }
+}
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Strategy.h b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.h
new file mode 100644
index 00000000000..51533e334b1
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.h
@@ -0,0 +1,220 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_POA_Strategy.h
+ *
+ * $Id$
+ *
+ * @author Marc Neeley <neeleym@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_POA_STRATEGY_H
+#define TAO_DYNAMIC_TP_POA_STRATEGY_H
+
+#include /**/ "ace/pre.h"
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/Dynamic_TP/DTP_Task.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/CSD_Framework/CSD_Strategy_Base.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+#include "ace/OS_NS_strings.h"
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+
+class TAO_DTP_POA_Strategy;
+typedef TAO_Intrusive_Ref_Count_Handle<TAO_DTP_POA_Strategy>
+ TAO_DTP_POA_Strategy_Handle;
+
+namespace TAO
+{
+ namespace CSD
+ {
+ class TP_Custom_Request_Operation;
+ }
+}
+
+
+/**
+ * @class TAO_DTP_POA_Strategy
+ *
+ * @brief
+ *
+ */
+class TAO_Dynamic_TP_Export TAO_DTP_POA_Strategy:
+ public TAO::CSD::Strategy_Base
+{
+ public:
+
+ /// Constructors.
+ /// This constructor supports situations where dynamic instantiation
+ /// of a thread pool for POAs is initiated from a svc.conf file.
+ /// A configuration name is passed in such that the object can
+ /// lookup a configuration in a pre-populated repository.
+ TAO_DTP_POA_Strategy(ACE_CString tp_config_name,
+ bool serialize_servants = true);
+
+ /// This constructor supports situations where explicit instantiation
+ /// of a thread pool for POAs is initiated from an application, such as
+ /// the use of the apply_to() method.
+ TAO_DTP_POA_Strategy(TAO_DTP_Definition * tp_config,
+ bool serialize_servants = true);
+
+ /// Virtual Destructor.
+ virtual ~TAO_DTP_POA_Strategy();
+
+ /// Turn on/off serialization of servants.
+ void set_servant_serialization(bool serialize_servants);
+
+ /// Return codes for the custom dispatch_request() methods.
+ enum CustomRequestOutcome
+ {
+ /// The request was successfully put on the request queue.
+ REQUEST_DISPATCHED,
+ /// The request has been executed/completed by a worker thread.
+ REQUEST_EXECUTED,
+ /// The request was removed from the queue and cancelled.
+ REQUEST_CANCELLED,
+ /// The request queue rejected the request
+ REQUEST_REJECTED
+ };
+
+ /// Inject a synchronous, custom request into the request queue.
+ /// This will block the calling thread until the request is handled
+ /// (dispatched or cancelled) or rejected.
+ /// Will return REQUEST_EXECUTED, REQUEST_CANCELLED, or REQUEST_REJECTED.
+ CustomRequestOutcome custom_synch_request
+ (TAO::CSD::TP_Custom_Request_Operation* op);
+
+ /// Inject an asynchronous, custom request into the request queue.
+ /// This will return control to the calling thread once the request
+ /// has been placed into the queue (or rejected).
+ /// Will return REQUEST_DISPATCHED or REQUEST_REJECTED.
+ CustomRequestOutcome custom_asynch_request
+ (TAO::CSD::TP_Custom_Request_Operation* op);
+
+ /// Cancel all requests that are targeted for the provided servant.
+ /// This is requested on the user application level.
+ void cancel_requests(PortableServer::Servant servant);
+
+
+ protected:
+
+ /// Handle the dispatching of a remote request.
+ ///
+ /// This will cause a new "request" object to be created and pushed
+ /// on to a "request queue". The worker threads are responsible for
+ /// servicing the queue, and performing the actual dispatch logic.
+ virtual Strategy_Base::DispatchResult dispatch_remote_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant);
+
+ /// Handle the dispatching of a collocated request.
+ ///
+ /// This will cause a new "request" object to be created and pushed
+ /// on to a "request queue". The worker threads are responsible for
+ /// servicing the queue, and performing the actual dispatch logic.
+ virtual Strategy_Base::DispatchResult dispatch_collocated_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant);
+
+ /// Event - The POA has been activated.
+ /// This will activate the worker thread(s).
+ /// Returns true if the worker threads were activated successfully.
+ /// Otherwise, returns false.
+ virtual bool poa_activated_event_i(TAO_ORB_Core& orb_core);
+
+ /// Event - The POA has been deactivated.
+ /// This will shutdown the worker thread(s).
+ virtual void poa_deactivated_event_i();
+
+ /// Event - A servant has been activated
+ virtual void servant_activated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid);
+
+ /// Event - A servant has been deactivated
+ virtual void servant_deactivated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid);
+
+ private:
+
+
+ /**
+ * Helper method that is responsible for looking up the servant
+ * state object in the servant state map *if* the "serialize
+ * servants" flag is set to true. In the case where the
+ * "serialize servants" flag is set to false, then a "nil"
+ * servant state handle object is returned.
+ *
+ * @param servant - input - a pointer to the servant object.
+ *
+ * @returns a handle to a servant state object.
+ *
+ * @throw PortableServer::POA::ServantNotActive if the servant
+ * state cannot be determined.
+ */
+ TAO::CSD::TP_Servant_State::HandleType get_servant_state
+ (PortableServer::Servant servant);
+
+ /// The "serialize servants" flag.
+ bool serialize_servants_;
+
+ /// The map of servant state objects - only used when the
+ /// "serialize servants" flag is set to true.
+ TAO::CSD::TP_Servant_State_Map servant_state_map_;
+
+ /// This holds the name of a configuration that have been loaded
+ /// into a DTP_Config_Registry. This is the key to the RB
+ /// Tree entry.
+
+ ACE_CString dynamic_tp_config_name_;
+
+ /// This is the active object used by the worker threads.
+ /// The request queue is owned/managed by the task object.
+ /// The strategy object puts requests into the task's request
+ /// queue, and the worker threads service the queued requests
+ /// by performing the actual servant request dispatching logic.
+ TAO_DTP_Task dtp_task_;
+
+
+ /// This boolean is used to determine if the configuration has
+ /// been sent in from an application or, if false, needs to be
+ /// looked up from a Dynamic TP Config repo. It works in conjunction with
+ /// dynamic_tp_config_name_ above.
+
+ bool config_initialized_;
+
+
+ void set_dtp_config(TAO_DTP_Definition &tp_config);
+};
+
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "tao/Dynamic_TP/DTP_POA_Strategy.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_DYNAMIC_TP_POA_STRATEGY_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_POA_Strategy.inl b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.inl
new file mode 100644
index 00000000000..3ce52bb554b
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_POA_Strategy.inl
@@ -0,0 +1,35 @@
+// -*- C++ -*-
+//
+// $Id$
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_INLINE
+/// Constructor.
+TAO_DTP_POA_Strategy::TAO_DTP_POA_Strategy (ACE_CString tp_config_name,
+ bool ss)
+ : serialize_servants_ (ss),
+ config_initialized_ (false)
+{
+ this->dynamic_tp_config_name_ = tp_config_name;
+}
+
+ACE_INLINE
+TAO_DTP_POA_Strategy::TAO_DTP_POA_Strategy (TAO_DTP_Definition * tp_config,
+ bool ss)
+ : serialize_servants_ (ss),
+ config_initialized_ (true)
+{
+ this->set_dtp_config (*tp_config);
+}
+
+ACE_INLINE
+void
+TAO_DTP_POA_Strategy::set_servant_serialization (bool serialize_servants)
+{
+ // Simple Mutator.
+ this->serialize_servants_ = serialize_servants;
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Dynamic_TP/DTP_Task.cpp b/TAO/tao/Dynamic_TP/DTP_Task.cpp
new file mode 100644
index 00000000000..cc6f30c310c
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Task.cpp
@@ -0,0 +1,479 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_Task.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h"
+
+#if !defined (__ACE_INLINE__)
+# include "tao/Dynamic_TP/DTP_Task.inl"
+#endif /* ! __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_Task::TAO_DTP_Task ()
+ : aw_lock_ (),
+ queue_lock_ (),
+ work_lock_ (),
+ work_available_ (this->work_lock_),
+ active_workers_ (this->aw_lock_),
+ accepting_requests_ (false),
+ shutdown_ (false),
+ opened_ (false),
+ num_queue_requests_ ((size_t)0)
+{
+}
+
+TAO_DTP_Task::~TAO_DTP_Task()
+{
+}
+
+bool
+TAO_DTP_Task::add_request (TAO::CSD::TP_Request* request)
+{
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->queue_lock_, false);
+ ++this->num_queue_requests_;
+ if ((this->num_queue_requests_ > this->max_request_queue_depth_) &&
+ (this->max_request_queue_depth_ != 0))
+ {
+ this->accepting_requests_ = false;
+ }
+
+ if (!this->accepting_requests_)
+ {
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::add_request() ")
+ ACE_TEXT ("not accepting requests.\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::add_request() ")
+ ACE_TEXT ("num_queue_requests_ : [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::add_request() ")
+ ACE_TEXT ("max_request_queue_depth_ : [%d]\n"),
+ this->num_queue_requests_,
+ this->max_request_queue_depth_));
+ }
+ --this->num_queue_requests_;
+ return false;
+ }
+
+ // We have made the decision that the request is going to be placed upon
+ // the queue_. Inform the request that it is about to be placed into
+ // a request queue. Some requests may not need to do anything in
+ // preparation of being placed into a queue. Others, however, may need
+ // to perfom a "clone" operation on some underlying request data before
+ // the request can be properly placed into a queue.
+ request->prepare_for_queue();
+
+ this->queue_.put(request);
+ }
+
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->work_lock_, false);
+ this->work_available_.signal ();
+ if (TAO_debug_level > 4 )
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::add_request() - ")
+ ACE_TEXT ("work available\n")));
+ }
+ }
+
+ return true;
+}
+
+size_t
+TAO_DTP_Task::get_init_pool_threads ()
+{
+ return (this->init_pool_threads_);
+}
+
+size_t
+TAO_DTP_Task::get_min_pool_threads ()
+{
+ return(this->min_pool_threads_);
+}
+
+size_t TAO_DTP_Task::get_max_pool_threads ()
+{
+ return(this->max_pool_threads_);
+}
+
+size_t
+TAO_DTP_Task::get_max_request_queue_depth ()
+{
+ return(this->max_request_queue_depth_);
+}
+
+size_t
+TAO_DTP_Task::get_thread_stack_size ()
+{
+ return(this->thread_stack_size_);
+}
+
+time_t
+TAO_DTP_Task::get_thread_idle_time ()
+{
+ return(this->thread_idle_time_.sec());
+}
+
+int
+TAO_DTP_Task::open (void* /* args */)
+{
+ size_t num = 1;
+
+ // Open_Args* tmp = static_cast<Open_Args *> (args);
+
+ //if (tmp == 0)
+ // {
+ // //FUZZ: disable check_for_lack_ACE_OS
+ // ACE_ERROR_RETURN ((LM_ERROR,
+ // ACE_TEXT ("(%P|%t) DTP_Task::open() failed to open. ")
+ // ACE_TEXT ("Invalid argument type passed to open().\n")),
+ // -1);
+ // //FUZZ: enable check_for_lack_ACE_OS
+ // }
+
+ num = this->init_pool_threads_;
+
+ // Set the busy_threads_ to the number of init_threads
+ // now. When they startup they will decrement themselves
+ // as they go into a wait state.
+
+ this->busy_threads_ = 0;
+
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() initialized with:\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() init_threads_ \t\t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() min_pool_threads_ \t\t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() max_pool_threads_ \t\t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() max_request_queue_depth_ \t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() thread_stack_size_ \t\t: [%d]\n")
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::open() thread_idle_time_ \t\t: [%d]\n"),
+ this->init_pool_threads_,
+ this->min_pool_threads_,
+ this->max_pool_threads_,
+ this->max_request_queue_depth_,
+ this->thread_stack_size_,
+ this->thread_idle_time_.sec ())
+ );
+ }
+
+ // We can't activate 0 threads. Make sure this isn't the case.
+ if (num < 1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) DTP_Task::open() failed to open. ")
+ ACE_TEXT ("num_threads (%u) is less-than 1.\n"),
+ num),
+ -1);
+ }
+
+ // We need the lock acquired from here on out.
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->aw_lock_, -1);
+
+ // We can assume that we are in the proper state to handle this open()
+ // call as long as we haven't been open()'ed before.
+ if (this->opened_)
+ {
+ //FUZZ: disable check_for_lack_ACE_OS
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) DTP_Task::open() failed to open. ")
+ ACE_TEXT ("Task has previously been open()'ed.\n")),
+ -1);
+ //FUZZ: enable check_for_lack_ACE_OS
+ }
+ // Create the stack size arrays if the stack size is set > 0.
+
+ // Activate this task object with 'num' worker threads.
+ if (this->thread_stack_size_ == 0)
+ {
+ if (this->activate (THR_NEW_LWP | THR_DETACHED, num, 1) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) DTP_Task::open() failed to activate ")
+ ACE_TEXT ("(%d) worker threads.\n"),
+ num),
+ -1);
+ }
+ }
+ else
+ {
+ size_t * stack_sz_arr = new size_t[num];
+ for (size_t z = 0; z < num; z++)
+ {
+ stack_sz_arr[z] = this->thread_stack_size_;
+ }
+
+ if (this->activate (THR_NEW_LWP | THR_DETACHED,
+ num,
+ 1,
+ ACE_DEFAULT_THREAD_PRIORITY,
+ -1,
+ 0,
+ 0,
+ 0,
+ stack_sz_arr) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) DTP_Task::open() failed to activate ")
+ ACE_TEXT ("(%d) worker threads.\n"),
+ num),
+ -1);
+ }
+
+ delete[] stack_sz_arr;
+ }
+ this->opened_ = true;
+ this->accepting_requests_ = true;
+
+ return 0;
+}
+
+bool
+TAO_DTP_Task::request_ready (TAO::CSD::TP_Dispatchable_Visitor &v,
+ TAO::CSD::TP_Request_Handle &r)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->queue_lock_, false);
+ if (!this->queue_.is_empty())
+ {
+ this->queue_.accept_visitor(v);
+ r = v.request();
+ return !r.is_nil();
+ }
+ return false;
+}
+
+void
+TAO_DTP_Task::clear_request (TAO::CSD::TP_Request_Handle &r)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->queue_lock_);
+ --this->num_queue_requests_;
+ if (this->max_request_queue_depth_ > 0)
+ {
+ this->accepting_requests_ = true;
+ }
+
+ if (TAO_debug_level > 4 )
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Decrementing num_queue_requests.")
+ ACE_TEXT ("New queue depth:%d\n"),
+ this->num_queue_requests_));
+ }
+
+ r->mark_as_ready ();
+}
+
+int
+TAO_DTP_Task::svc (void)
+{
+ ++this->busy_threads_;
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("New thread created.\n")));
+ }
+
+ TAO::CSD::TP_Dispatchable_Visitor dispatchable_visitor;
+ while (!this->shutdown_)
+ {
+ TAO::CSD::TP_Request_Handle request;
+
+ while (!this->shutdown_ && request.is_nil ())
+ {
+ if (!this->request_ready (dispatchable_visitor, request))
+ {
+ --this->busy_threads_;
+
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Decrementing busy_threads_. ")
+ ACE_TEXT ("Busy thread count:%d\n"),
+ this->busy_threads_.value()));
+ }
+
+ ACE_Time_Value tmp_sec = this->thread_idle_time_.to_absolute_time();
+
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->work_lock_, false);
+ int wait_state = this->thread_idle_time_.sec () == 0
+ ? this->work_available_.wait ()
+ : this->work_available_.wait (&tmp_sec);
+
+ // Check for timeout
+ if (this->shutdown_)
+ return 0;
+ if (wait_state == -1)
+ {
+ if (errno != ETIME ||
+ (this->thr_count() > this->min_pool_threads_ &&
+ this->min_pool_threads_ > 0))
+ {
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Existing thread expiring.\n")));
+ }
+ return 0;
+ }
+ }
+ }
+
+ ++this->busy_threads_;
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Incrementing busy_threads_. ")
+ ACE_TEXT ("Busy thread count:%d\n"),
+ this->busy_threads_.value ()));
+ }
+ }
+ }
+
+ size_t count = this->thr_count ();
+ if ((this->busy_threads_ == count) &&
+ ((this->max_pool_threads_ == 0) ||
+ (count < this->max_pool_threads_)))
+ {
+ if (this->activate(THR_NEW_LWP | THR_DETACHED,
+ 1,
+ 1,
+ ACE_DEFAULT_THREAD_PRIORITY,
+ -1,
+ 0,
+ 0,
+ 0,
+ this->thread_stack_size_ == 0 ? 0 :
+ &this->thread_stack_size_) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) DTP_Task::svc() failed to grow ")
+ ACE_TEXT ("to %d worker threads.\n"), count));
+ }
+ else
+ {
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::svc() ")
+ ACE_TEXT ("Growing threadcount. ")
+ ACE_TEXT ("New thread count:%d\n"),
+ this->thr_count ()));
+ }
+ }
+ }
+
+ request->dispatch ();
+ this->clear_request (request);
+ dispatchable_visitor.reset ();
+ }
+ return 0;
+}
+
+
+int
+TAO_DTP_Task::close(u_long flag)
+{
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->aw_lock_, 0);
+ if (flag == 0)
+ {
+ this->active_workers_.signal ();
+ return 0;
+ }
+
+ if (!this->opened_)
+ {
+ return 0;
+ }
+ this->opened_ = false;
+ this->shutdown_ = true;
+ this->accepting_requests_ = false;
+ }
+
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->work_lock_, 0);
+ this->work_available_.broadcast();
+ }
+
+ size_t in_task = (this->thr_mgr ()->task () == this) ? 1 : 0;
+ if (TAO_debug_level > 4)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DTP_Task::close() ")
+ ACE_TEXT ("shutting down. in_task = %d, Count = %d \n"),
+ in_task, this->thr_count ()));
+ }
+
+ while (this->thr_count () != in_task)
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->aw_lock_, 0);
+ this->active_workers_.wait ();
+ }
+
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->queue_lock_, 0);
+ TAO::CSD::TP_Cancel_Visitor v;
+ this->queue_.accept_visitor (v);
+ }
+ return 0;
+}
+
+
+void
+TAO_DTP_Task::set_init_pool_threads (size_t thr_count)
+{
+ this->init_pool_threads_ = thr_count;
+}
+
+void
+TAO_DTP_Task::set_min_pool_threads (size_t thr_count)
+{
+ this->min_pool_threads_ = thr_count;
+}
+
+void
+TAO_DTP_Task::set_max_pool_threads (size_t thr_count)
+{
+ this->max_pool_threads_ = thr_count;
+}
+
+void
+TAO_DTP_Task::set_thread_stack_size (size_t stack_sz)
+{
+ this->thread_stack_size_ = stack_sz;
+}
+
+void
+TAO_DTP_Task::set_thread_idle_time(ACE_Time_Value thr_timeout)
+{
+ this->thread_idle_time_ = thr_timeout;
+}
+
+void
+TAO_DTP_Task::set_max_request_queue_depth (size_t queue_depth)
+{
+ this->max_request_queue_depth_ = queue_depth;
+}
+
+void
+TAO_DTP_Task::cancel_servant (PortableServer::Servant servant)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->queue_lock_);
+
+ // Cancel the requests targeted for the provided servant.
+ TAO::CSD::TP_Cancel_Visitor cancel_visitor (servant);
+ this->queue_.accept_visitor (cancel_visitor);
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Dynamic_TP/DTP_Task.h b/TAO/tao/Dynamic_TP/DTP_Task.h
new file mode 100644
index 00000000000..0b18950e75d
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Task.h
@@ -0,0 +1,199 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_Task.h
+ *
+ * $Id$
+ */
+//=============================================================================
+
+#ifndef TAO_DYNAMIC_TP_TASK_H
+#define TAO_DYNAMIC_TP_TASK_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Queue.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Request.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/Condition.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Task.h"
+#include "ace/Synch.h"
+#include "ace/Containers_T.h"
+#include "ace/Vector_T.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ /**
+ * @class TP_Task
+ *
+ * @brief Active Object managing a queue of request objects.
+ *
+ * There are two types of "users" of a TP_Task object:
+ *
+ * 1) The TP_Strategy object that "owns" this task object.
+ * 2) The worker threads that "run" this task object as an
+ * "active object".
+ *
+ * The TP_Strategy object that "owns" this task object dictates
+ * when the worker threads are activated and when they are shutdown. It
+ * also injects requests into this task's queue via calls to the
+ * add_request() method. It is also the TP_Strategy object that
+ * dictates the number of worker threads to be activated via a call to
+ * the set_num_threads() method.
+ *
+ * The active object pattern is implemented via the use of the
+ * the ACE_Task_Base base class, and each worker thread will
+ * invoke this task's svc() method, and when the svc() returns, the
+ * worker thread will invoke this task's close() method (with the
+ * flag argument equal to 0).
+ */
+ class TAO_Dynamic_TP_Export TAO_DTP_Task : public ACE_Task_Base
+ {
+ public:
+
+ /// Default Constructor.
+ TAO_DTP_Task();
+
+ /// Virtual Destructor.
+ virtual ~TAO_DTP_Task();
+
+ struct Open_Args {
+ TAO_DTP_Definition task_thread_config;
+ };
+
+
+ /// Put a request object on to the request queue.
+ /// Returns true if successful, false otherwise (it has been "rejected").
+ bool add_request(TAO::CSD::TP_Request* request);
+
+ /// Activate the worker threads
+ virtual int open(void* args = 0);
+
+ /// The "mainline" executed by each worker thread.
+ virtual int svc();
+
+ virtual int close (u_long flag = 0);
+
+ /// Set the thread and queue config.
+
+ void set_init_pool_threads(size_t thr_count);
+
+ void set_min_pool_threads(size_t thr_count);
+
+ void set_max_pool_threads(size_t thr_count);
+
+ void set_thread_stack_size(size_t stack_sz);
+
+ void set_thread_idle_time(ACE_Time_Value thr_timeout);
+
+ void set_max_request_queue_depth(size_t queue_depth);
+
+ /// Get the thread and queue config.
+
+ size_t get_init_pool_threads();
+
+ size_t get_min_pool_threads();
+
+ size_t get_max_pool_threads();
+
+ size_t get_max_request_queue_depth();
+
+ size_t get_thread_stack_size();
+
+ time_t get_thread_idle_time();
+
+ /// Cancel all requests that are targeted for the provided servant.
+ void cancel_servant (PortableServer::Servant servant);
+
+ private:
+ /// get the next available request. Return true if one available, nonblocking
+ bool request_ready (TAO::CSD::TP_Dispatchable_Visitor &v,
+ TAO::CSD::TP_Request_Handle &r);
+
+ /// release the request, reset the accepting flag if necessary
+ void clear_request (TAO::CSD::TP_Request_Handle &r);
+
+
+
+ typedef TAO_SYNCH_MUTEX LockType;
+ typedef TAO_Condition<LockType> ConditionType;
+
+ /// Lock used to synchronize the "active_workers_" condition
+ LockType aw_lock_;
+ /// Lock used to synchronize manipulation of the queue
+ LockType queue_lock_;
+ /// Lock used to synchronize the "work_available_" condition
+ LockType work_lock_;
+
+ /// Condition used to signal worker threads that they may be able to
+ /// find a request in the queue_ that needs to be dispatched to a
+ /// servant that is currently "not busy".
+ /// This condition will be signal()'ed each time a new request is
+ /// added to the queue_, and also when a servant has become "not busy".
+ ConditionType work_available_;
+
+ /// This condition will be signal()'ed each time the num_threads_
+ /// data member has its value changed. This is used to keep the
+ /// close(1) invocation (ie, a shutdown request) blocked until all
+ /// of the worker threads have stopped running.
+ ConditionType active_workers_;
+
+ /// Flag used to indicate when this task will (or will not) accept
+ /// requests via the the add_request() method.
+ bool accepting_requests_;
+
+ /// Flag used to initiate a shutdown request to all worker threads.
+ bool shutdown_;
+
+ /// Flag used to avoid multiple open() calls.
+ bool opened_;
+
+ /// The number of requests in the local queue.
+ size_t num_queue_requests_;
+
+ /// The number of currently active worker threads.
+ ACE_Atomic_Op <TAO_SYNCH_MUTEX, unsigned long> busy_threads_;
+
+ /// The queue of pending servant requests (a.k.a. the "request queue").
+ TAO::CSD::TP_Queue queue_;
+
+ /// The low water mark for dynamic threads to settle to.
+ size_t init_pool_threads_;
+
+ /// The low water mark for dynamic threads to settle to.
+ size_t min_pool_threads_;
+
+ /// The high water mark for dynamic threads to be limited to.
+ size_t max_pool_threads_;
+
+ /// If the max_pool_threads_ value has been met, then ORB requests coming in can be queued.
+ /// This is the maximum number that will be allowed.
+ size_t max_request_queue_depth_;
+
+ /// This is the memory stack size allowable for each thread.
+ size_t thread_stack_size_;
+
+ /// This is the maximum amount of time in seconds that an idle thread can
+ /// stay alive before being taken out of the pool.
+ ACE_Time_Value thread_idle_time_;
+ };
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+# include "tao/Dynamic_TP/DTP_Task.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_DYNAMIC_TP_TASK_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_Task.inl b/TAO/tao/Dynamic_TP/DTP_Task.inl
new file mode 100644
index 00000000000..5b9eaafbd7d
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Task.inl
@@ -0,0 +1,7 @@
+// -*- C++ -*-
+//
+// $Id$
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp b/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp
new file mode 100644
index 00000000000..1b70111c86b
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.cpp
@@ -0,0 +1,131 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "tao/ORB_Core.h"
+#include "tao/ORB_Core_TSS_Resources.h"
+#include "tao/Acceptor_Registry.h"
+#include "tao/Thread_Lane_Resources.h"
+#include "tao/Dynamic_TP/DTP_Thread_Pool.h"
+#include "tao/LF_Follower.h"
+#include "tao/Leader_Follower.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_Thread_Lane_Resources_Manager::TAO_DTP_Thread_Lane_Resources_Manager
+ (TAO_ORB_Core &orb_core)
+ : TAO_Thread_Lane_Resources_Manager (orb_core),
+ default_lane_resources_ (0),
+ tp_manager_ (0)
+{
+ // Create the default resources.
+ ACE_NEW (this->default_lane_resources_,
+ TAO_Thread_Lane_Resources (orb_core));
+
+ // Create the thread-pool manager.
+ ACE_NEW (this->tp_manager_,
+ TAO_DTP_Thread_Pool_Manager (orb_core));
+
+}
+
+TAO_DTP_Thread_Lane_Resources_Manager::~TAO_DTP_Thread_Lane_Resources_Manager (void)
+{
+ // Delete the default resources.
+ delete this->default_lane_resources_;
+
+ // Delete the thread-pool manager.
+ delete this->tp_manager_;
+}
+
+int
+TAO_DTP_Thread_Lane_Resources_Manager::open_default_resources (void)
+{
+ TAO_ORB_Parameters *params =
+ this->orb_core_->orb_params ();
+
+ TAO_EndpointSet endpoint_set;
+
+ params->get_endpoint_set (TAO_DEFAULT_LANE, endpoint_set);
+
+ bool ignore_address = false;
+
+ int const result =
+ this->default_lane_resources_->open_acceptor_registry (endpoint_set,
+ ignore_address);
+
+ return result;
+}
+
+void
+TAO_DTP_Thread_Lane_Resources_Manager::finalize (void)
+{
+ // Finalize default resources.
+ this->default_lane_resources_->finalize ();
+}
+
+void
+TAO_DTP_Thread_Lane_Resources_Manager::shutdown_reactor (void)
+{
+ // Shutdown default reactors.
+ this->default_lane_resources_->shutdown_reactor ();
+ // This is the only reactor in use with this thread pool
+}
+
+void
+TAO_DTP_Thread_Lane_Resources_Manager::close_all_transports (void)
+{
+ // Shutdown default reactors.
+ this->default_lane_resources_->close_all_transports ();
+}
+
+int
+TAO_DTP_Thread_Lane_Resources_Manager::is_collocated (const TAO_MProfile &mprofile)
+{
+ return this->default_lane_resources_->is_collocated (mprofile);
+}
+
+TAO_Thread_Lane_Resources &
+TAO_DTP_Thread_Lane_Resources_Manager::lane_resources (void)
+{
+ return *this->default_lane_resources_;
+}
+
+TAO_Thread_Lane_Resources &
+TAO_DTP_Thread_Lane_Resources_Manager::default_lane_resources (void)
+{
+ return *this->default_lane_resources_;
+}
+
+TAO_DTP_Thread_Pool_Manager &
+TAO_DTP_Thread_Lane_Resources_Manager::tp_manager (void)
+{
+ return *this->tp_manager_;
+}
+
+TAO_Thread_Lane_Resources_Manager *
+TAO_DTP_Thread_Lane_Resources_Manager_Factory::create_thread_lane_resources_manager (
+ TAO_ORB_Core &core)
+{
+ TAO_Thread_Lane_Resources_Manager *manager = 0;
+
+ /// Create the RT Thread Lane Resources Manager.
+ ACE_NEW_RETURN (manager,
+ TAO_DTP_Thread_Lane_Resources_Manager (core),
+ 0);
+
+ return manager;
+}
+
+ACE_STATIC_SVC_DEFINE (TAO_DTP_Thread_Lane_Resources_Manager_Factory,
+ ACE_TEXT ("DTP_Thread_Lane_Resources_Manager_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DTP_Thread_Lane_Resources_Manager_Factory),
+ ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
+ 0)
+ACE_FACTORY_DEFINE (TAO_Dynamic_TP, TAO_DTP_Thread_Lane_Resources_Manager_Factory)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h b/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h
new file mode 100644
index 00000000000..79278ec7726
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Lane_Resources_Manager.h
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_Thread_Lane_Resources_Manager.h
+ *
+ * $Id$
+ *
+ * @author Irfan Pyarali
+ */
+// ===================================================================
+
+#ifndef TAO_RT_THREAD_LANE_RESOURCES_MANAGER_H
+#define TAO_RT_THREAD_LANE_RESOURCES_MANAGER_H
+
+#include /**/ "ace/pre.h"
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Thread_Lane_Resources_Manager.h"
+#include "ace/Service_Config.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_DTP_Thread_Pool_Manager;
+
+/**
+ * @class TAO_DTP_Thread_Lane_Resources_Manager
+ *
+ * @brief Manager for thread lane resources.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_Thread_Lane_Resources_Manager :
+ public TAO_Thread_Lane_Resources_Manager
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_Thread_Lane_Resources_Manager (TAO_ORB_Core &orb_core);
+
+ /// Destructor.
+ ~TAO_DTP_Thread_Lane_Resources_Manager (void);
+
+ /// Finalize resources.
+ void finalize (void);
+
+ /// Open default resources.
+ int open_default_resources (void);
+
+ /// Shutdown reactor.
+ void shutdown_reactor (void);
+
+ /// Certain ORB policies such as dropping replies on shutdown
+ /// would need cleanup of transports to wake threads up.
+ void close_all_transports (void);
+
+ /// Does @a mprofile belong to us?
+ int is_collocated (const TAO_MProfile &mprofile);
+
+ /// @name Accessors
+ // @{
+
+ TAO_Thread_Lane_Resources &lane_resources (void);
+
+ TAO_Thread_Lane_Resources &default_lane_resources (void);
+
+ TAO_DTP_Thread_Pool_Manager &tp_manager (void);
+
+ // @}
+
+private:
+ void operator= (const TAO_DTP_Thread_Lane_Resources_Manager &);
+ TAO_DTP_Thread_Lane_Resources_Manager (const TAO_DTP_Thread_Lane_Resources_Manager &);
+
+protected:
+
+ /// Default lane resources.
+ TAO_Thread_Lane_Resources *default_lane_resources_;
+
+ /// Thread Pool Manager.
+ TAO_DTP_Thread_Pool_Manager *tp_manager_;
+};
+
+/**
+ * @class TAO_DTP_Thread_Lane_Resources_Manager_Factory
+ *
+ * @brief This class is a factory for managers of thread resources.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_Thread_Lane_Resources_Manager_Factory
+ : public TAO_Thread_Lane_Resources_Manager_Factory
+{
+public:
+
+ /// Factory method.
+ TAO_Thread_Lane_Resources_Manager *create_thread_lane_resources_manager (
+ TAO_ORB_Core &core);
+
+};
+
+
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_Dynamic_TP,
+ TAO_DTP_Thread_Lane_Resources_Manager_Factory)
+ACE_FACTORY_DECLARE (TAO_Dynamic_TP,
+ TAO_DTP_Thread_Lane_Resources_Manager_Factory)
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_RT_THREAD_LANE_RESOURCES_MANAGER_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp
new file mode 100644
index 00000000000..9d03eb8cb48
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp
@@ -0,0 +1,456 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_Thread_Pool.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#if ! defined (__ACE_INLINE__)
+#include "tao/Dynamic_TP/DTP_Thread_Pool.inl"
+#endif /* __ACE_INLINE__ */
+
+#include "tao/Exception.h"
+#include "tao/ORB_Core.h"
+#include "tao/ORB_Core_TSS_Resources.h"
+#include "tao/TSS_Resources.h"
+#include "tao/ORB.h"
+#include "tao/Acceptor_Registry.h"
+#include "tao/debug.h"
+#include "tao/LF_Follower.h"
+#include "tao/Leader_Follower.h"
+#include "ace/Auto_Ptr.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_DTP_New_Leader_Generator::TAO_DTP_New_Leader_Generator (
+ TAO_DTP_Thread_Pool &p)
+ : pool_ (p)
+{
+}
+
+void
+TAO_DTP_New_Leader_Generator::no_leaders_available (void)
+{
+ this->pool_.new_dynamic_thread ();
+}
+
+TAO_DTP_Thread_Pool_Threads::TAO_DTP_Thread_Pool_Threads (TAO_DTP_Thread_Pool &p)
+ : ACE_Task_Base (p.manager ().orb_core ().thr_mgr ()),
+ pool_ (p)
+{
+}
+
+int
+TAO_DTP_Thread_Pool_Threads::svc (void)
+{
+ TAO_ORB_Core &orb_core = this->pool_.manager ().orb_core ();
+ if (orb_core.has_shutdown ())
+ return 0;
+
+ try
+ {
+ // Do the work
+ this->run (orb_core);
+ }
+ catch (const ::CORBA::Exception& ex)
+ {
+ // No point propagating this exception. Print it out.
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("orb->run() raised exception for thread %t\n")));
+
+ ex._tao_print_exception ("");
+ }
+
+ return 0;
+}
+
+int
+TAO_DTP_Thread_Pool_Threads::run (TAO_ORB_Core &orb_core)
+{
+ CORBA::ORB_ptr orb = orb_core.orb ();
+ // A timeout is specified, run the ORB in an idle loop, if we
+ // don't handle any operations for the given timeout we just
+ // exit the loop and this thread ends itself.
+ ACE_Time_Value tv (this->pool_.dynamic_thread_time ());
+
+ while (!orb_core.has_shutdown ())
+ {
+ bool has_work = orb->work_pending (tv);
+ if (!has_work && this->pool_.above_minimum ())
+ {
+ // we've timed out, but the pool is not yet at the minimum
+ break;
+ }
+
+ // Run the ORB for the specified timeout, this prevents looping
+ // between work_pending/handle_events
+ tv = this->pool_.dynamic_thread_time ();
+ orb->run (tv);
+ // Reset the idle timeout
+ tv = this->pool_.dynamic_thread_time ();
+ }
+
+ if (TAO_debug_level > 7)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO Process %P Pool %d Thread %t\n")
+ ACE_TEXT ("Current number of dynamic threads left = %d; ")
+ ACE_TEXT ("DTP worker thread is ending!\n"),
+ this->pool_.id (),
+ this->thr_count () - 1));
+ }
+
+ return 0;
+}
+
+bool
+TAO_DTP_Thread_Pool::above_minimum (void)
+{
+ return this->definition_.min_threads_ > 0 &&
+ (int)this->threads_.thr_count () > this->definition_.min_threads_;
+}
+
+bool
+TAO_DTP_Thread_Pool::new_dynamic_thread (void)
+{
+ // Note that we are checking this condition below without the lock
+ // held.
+ if (this->definition_.max_threads_ > 0 &&
+ (int)this->threads_.thr_count () >= this->definition_.max_threads_)
+ return false;
+
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_,
+ false);
+
+ if (!this->manager_.orb_core ().has_shutdown () && !this->shutdown_ &&
+ (this->definition_.max_threads_ == -1 ||
+ (int)this->threads_.thr_count () < this->definition_.max_threads_))
+ {
+ if (TAO_debug_level > 7)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO Process %P Pool %d Thread %t\n")
+ ACE_TEXT ("Current number of threads = %d; ")
+ ACE_TEXT ("min threads = %d; max threads = %d\n")
+ ACE_TEXT ("No leaders available; DTP creating new leader!\n"),
+ this->id_,
+ this->threads_.thr_count (),
+ this->definition_.min_threads_,
+ this->definition_.max_threads_));
+
+ if (this->create_threads_i (1, THR_BOUND | THR_DETACHED))
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Pool %d Thread %t: ")
+ ACE_TEXT ("cannot create dynamic thread\n"),
+ this->id_));
+ }
+ return false;
+ }
+ }
+
+ return true;
+}
+
+CORBA::ULong
+TAO_DTP_Thread_Pool::current_threads (void) const
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_,
+ 0);
+
+ return this->threads_.thr_count ();
+}
+
+int
+TAO_DTP_Thread_Pool::create_initial_threads (void)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_,
+ 0);
+
+ // Create initial threads.
+ // first, create the minimum number of threads as static
+ // if the min threads count is -1 that means all threads are static
+
+ size_t count = (size_t)this->definition_.init_threads_;
+ size_t extra = 0;
+ if (this->definition_.min_threads_ != -1)
+ {
+ extra = count - (size_t) this->definition_.min_threads_;
+ count = (size_t) this->definition_.min_threads_;
+ }
+
+ if (TAO_debug_level > 7)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) DTP_Thread_Pool::create_initial_threads ")
+ ACE_TEXT ("Creating %d static and %d dynamic threads\n"),
+ count, extra));
+ }
+
+ int result = this->create_threads_i (count, THR_NEW_LWP | THR_JOINABLE);
+ if (result != -1 && extra > 0)
+ {
+ result = this->create_threads_i (extra, THR_BOUND | THR_DETACHED);
+ }
+ return result;
+}
+
+int
+TAO_DTP_Thread_Pool::create_dynamic_threads (size_t count)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_,
+ 0);
+
+ return this->create_threads_i (count, THR_BOUND | THR_DETACHED);
+}
+
+int
+TAO_DTP_Thread_Pool::create_threads_i (size_t count,
+ long thread_flags)
+{
+ // Overwritten parameters.
+ int force_active = 1;
+
+ // Default parameters.
+ int default_grp_id = -1;
+ ACE_Task_Base *default_task = 0;
+ ACE_hthread_t *default_thread_handles = 0;
+ void **default_stack = 0;
+
+ // Setting stack size.
+ size_t *stack_size_array = 0;
+ ACE_NEW_RETURN (stack_size_array,
+ size_t[count],
+ -1);
+ size_t index;
+ for (index = 0; index != count; ++index)
+ stack_size_array[index] =
+ this->definition_.stack_size_;
+
+ // Make sure the dynamically created stack size array is properly
+ // deleted.
+ ACE_Auto_Basic_Array_Ptr<size_t> auto_stack_size_array (stack_size_array);
+
+ TAO_ORB_Core &orb_core = manager_.orb_core ();
+
+ long flags =
+ thread_flags |
+ orb_core.orb_params ()->thread_creation_flags ();
+
+ int default_priority = 0;
+
+ // Activate the threads.
+ int result =
+ this->threads_.activate (flags,
+ count,
+ force_active,
+ default_grp_id,
+ default_priority,
+ default_task,
+ default_thread_handles,
+ default_stack,
+ stack_size_array);
+ return result;
+}
+
+TAO_DTP_Thread_Pool::TAO_DTP_Thread_Pool (TAO_DTP_Thread_Pool_Manager &manager,
+ CORBA::ULong id,
+ TAO_DTP_Definition &def)
+ : manager_ (manager),
+ id_ (id),
+ shutdown_ (false),
+ definition_ (def),
+ threads_ (*this),
+ new_thread_generator_ (*this)
+{
+ manager_.orb_core ().leader_follower ().set_new_leader_generator (
+ &new_thread_generator_);
+}
+
+void
+TAO_DTP_Thread_Pool::open (void)
+{
+ // Nothing to do for now
+}
+
+TAO_DTP_Thread_Pool::~TAO_DTP_Thread_Pool (void)
+{
+}
+
+void
+TAO_DTP_Thread_Pool::shutting_down (void)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX,
+ mon,
+ this->lock_);
+
+ // We are shutting down, this way we are not creating any more new dynamic
+ // threads
+ this->shutdown_ = true;
+}
+
+
+void
+TAO_DTP_Thread_Pool::wait (void)
+{
+ this->threads_.wait ();
+}
+
+#define TAO_THREAD_POOL_MANAGER_GUARD \
+ ACE_GUARD_THROW_EX ( \
+ TAO_SYNCH_MUTEX, \
+ mon, \
+ this->lock_, \
+ CORBA::INTERNAL ( \
+ CORBA::SystemException::_tao_minor_code ( \
+ TAO_GUARD_FAILURE, \
+ 0), \
+ CORBA::COMPLETED_NO));
+
+TAO_DTP_Thread_Pool_Manager::TAO_DTP_Thread_Pool_Manager (TAO_ORB_Core &orb_core)
+ : orb_core_ (orb_core),
+ thread_pools_ (),
+ thread_pool_id_counter_ (1),
+ lock_ ()
+{
+}
+
+TAO_DTP_Thread_Pool_Manager::~TAO_DTP_Thread_Pool_Manager (void)
+{
+ // Delete all the pools.
+ for (THREAD_POOLS::ITERATOR iterator = this->thread_pools_.begin ();
+ iterator != this->thread_pools_.end ();
+ ++iterator)
+ delete (*iterator).int_id_;
+}
+
+
+void
+TAO_DTP_Thread_Pool_Manager::wait (void)
+{
+ for (THREAD_POOLS::ITERATOR iterator = this->thread_pools_.begin ();
+ iterator != this->thread_pools_.end ();
+ ++iterator)
+ (*iterator).int_id_->wait ();
+}
+
+CORBA::ULong
+TAO_DTP_Thread_Pool_Manager::create_threadpool (TAO_DTP_Definition &def)
+{
+ TAO_THREAD_POOL_MANAGER_GUARD;
+
+ return this->create_threadpool_i (def);
+}
+
+void
+TAO_DTP_Thread_Pool_Manager::destroy_threadpool (CORBA::ULong threadpool)
+{
+ TAO_DTP_Thread_Pool *tao_thread_pool = 0;
+
+ // The guard is just for the map, don't do a wait inside the guard, because
+ // during the wait other threads can try to access the thread pool manager
+ // also, this can be one of the threads we are waiting for, which then
+ // results in a deadlock
+ {
+ TAO_THREAD_POOL_MANAGER_GUARD;
+
+ // Unbind the thread pool from the map.
+ int const result = this->thread_pools_.unbind (threadpool, tao_thread_pool);
+
+ // If the thread pool is not found in our map.
+ if (result != 0)
+ return; //throw RTCORBA::RTORB::InvalidThreadpool ();
+ }
+
+ // Mark the thread pool that we are shutting down.
+ tao_thread_pool->shutting_down ();
+
+ // Wait for the threads.
+ tao_thread_pool->wait ();
+
+ // Delete the thread pool.
+ delete tao_thread_pool;
+
+}
+
+CORBA::ULong
+TAO_DTP_Thread_Pool_Manager::create_threadpool_i (TAO_DTP_Definition &def)
+{
+ // Create the thread pool.
+ TAO_DTP_Thread_Pool *thread_pool = 0;
+
+ ACE_NEW_THROW_EX (thread_pool,
+ TAO_DTP_Thread_Pool (*this,
+ this->thread_pool_id_counter_,
+ def
+ ),
+ CORBA::NO_MEMORY ());
+
+ return this->create_threadpool_helper (thread_pool);
+}
+
+CORBA::ULong
+TAO_DTP_Thread_Pool_Manager::create_threadpool_helper (TAO_DTP_Thread_Pool *thread_pool)
+{
+ // Make sure of safe deletion in case of errors.
+ auto_ptr<TAO_DTP_Thread_Pool> safe_thread_pool (thread_pool);
+
+ // Open the pool.
+ thread_pool->open ();
+
+ // Create the static threads.
+ int result = thread_pool->create_initial_threads ();
+
+ // Throw exception in case of errors.
+ if (result != 0)
+ {
+ throw ::CORBA::INTERNAL
+ (
+ CORBA::SystemException::_tao_minor_code
+ (
+ 0, //TAO_RTCORBA_THREAD_CREATION_LOCATION_CODE,
+ errno),
+ CORBA::COMPLETED_NO);
+ }
+
+ // Bind thread to internal table.
+ result = this->thread_pools_.bind (this->thread_pool_id_counter_, thread_pool);
+
+ TAO_ORB_Core_TSS_Resources &tss =
+ *this->orb_core_.get_tss_resources ();
+ // Associate the thread pool with the ORB for later retrieval
+ tss.lane_ = thread_pool;
+
+ //
+ // Throw exception in case of errors.
+ if (result != 0)
+ throw ::CORBA::INTERNAL ();
+
+ //
+ // Success.
+ //
+
+ // No need to delete thread pool.
+ safe_thread_pool.release ();
+
+ // Return current counter and perform post-increment.
+ return this->thread_pool_id_counter_++;
+}
+
+TAO_ORB_Core &
+TAO_DTP_Thread_Pool_Manager::orb_core (void) const
+{
+ return this->orb_core_;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h
new file mode 100644
index 00000000000..6dae84f7fa4
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h
@@ -0,0 +1,249 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DTP_Thread_Pool.h
+ *
+ * $Id$
+ *
+ * @author Irfan Pyarali
+ * @author Johnny Willemsen
+ * @author Phil Mesnier
+ */
+// ===================================================================
+
+#ifndef TAO_DTP_THREAD_POOL_H
+#define TAO_DTP_THREAD_POOL_H
+
+#include /**/ "ace/pre.h"
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Hash_Map_Manager.h"
+#include "tao/Thread_Lane_Resources.h"
+#include "tao/Dynamic_TP/dynamic_tp_export.h"
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "tao/New_Leader_Generator.h"
+#include "ace/Task.h"
+#include "ace/Null_Mutex.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_ORB_Core;
+class TAO_DTP_Thread_Pool;
+class TAO_DTP_Thread_Pool_Manager;
+
+/**
+ * @class TAO_DTP_New_Leader_Generator
+ *
+ * @brief Class for creating dynamic threads.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_New_Leader_Generator
+ : public TAO_New_Leader_Generator
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_New_Leader_Generator (TAO_DTP_Thread_Pool &lane);
+
+ /// Leader/Follower class uses this method to notify the system that
+ /// we are out of leaders.
+ void no_leaders_available (void);
+
+private:
+
+ /// Pool associated with this leader generator.
+ TAO_DTP_Thread_Pool &pool_;
+};
+
+/**
+ * @class TAO_DTP_Thread_Pool_Threads
+ *
+ * @brief Class representing a static thread running in a thread lane.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_DTP_Thread_Pool_Threads : public ACE_Task_Base
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_Thread_Pool_Threads (TAO_DTP_Thread_Pool &pool);
+
+ /// Method executed when a thread is spawned.
+ int svc (void);
+
+ /// Accessor to the pool to which this thread belongs to.
+ TAO_DTP_Thread_Pool &pool (void) const;
+
+protected:
+ /// Do the real work
+ virtual int run (TAO_ORB_Core &orb_core);
+
+ /// Pool to which this thread belongs to.
+ TAO_DTP_Thread_Pool &pool_;
+};
+
+
+/**
+ * @class TAO_DTP_Thread_Pool
+ *
+ * @brief Class representing the thread pool inside a thread pool
+ * manager.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_Thread_Pool
+{
+public:
+ TAO_DTP_Thread_Pool (TAO_DTP_Thread_Pool_Manager &manager,
+ CORBA::ULong id,
+ TAO_DTP_Definition &definition);
+
+ /// Destructor.
+ ~TAO_DTP_Thread_Pool (void);
+
+ /// Open the pool.
+ void open (void);
+
+ /// Wait for threads to exit.
+ void wait (void);
+
+ /// Mark this thread pool that we are shutting down.
+ void shutting_down (void);
+
+ /// Create the initial threads - only called once.
+ int create_initial_threads (void);
+
+ /// Called by the TAO_DTP_New_Leader_Generator to request a new dynamic
+ /// thread.
+ /**
+ * It can be that no thread can be created because the number of
+ * threads is equal to the maximum we can have or the Thread Lane
+ * is shutting down.
+ * @retval true A new thread is created
+ * @retval false No thread could be created
+ */
+ bool new_dynamic_thread (void);
+
+ /// Called by the run loop to determine if to expire a thread or not
+ /// when the dynamic timeout is reached.
+ bool above_minimum (void);
+
+ /// @name Accessors
+ // @{
+
+ bool use_timeouts (void) const;
+ const ACE_Time_Value& dynamic_thread_time (void) const;
+
+ TAO_DTP_Thread_Pool_Manager &manager (void) const;
+ CORBA::ULong id (void) const;
+ CORBA::ULong current_threads (void) const;
+
+ // @}
+
+private:
+
+ int create_threads_i (size_t count, long thread_flags);
+
+ /// Create @a number_of_threads of dynamic threads. Can be called
+ /// multiple times.
+ int create_dynamic_threads (size_t count);
+
+ TAO_DTP_Thread_Pool_Manager &manager_;
+
+ CORBA::ULong id_;
+
+ /// This boolean is set when we are shutting down, then we will not create
+ /// any new dynamic threads
+ bool shutdown_;
+
+ TAO_DTP_Definition definition_;
+
+ /// Array with all threads
+ TAO_DTP_Thread_Pool_Threads threads_;
+
+ TAO_DTP_New_Leader_Generator new_thread_generator_;
+
+ /// Lock to guard all members of the pool
+ mutable TAO_SYNCH_MUTEX lock_;
+};
+
+/**
+ * @class TAO_DTP_Thread_Pool_Manager
+ *
+ * @brief Class for managing thread pools.
+ *
+ * \nosubgrouping
+ *
+ **/
+class TAO_Dynamic_TP_Export TAO_DTP_Thread_Pool_Manager
+{
+public:
+
+ /// Constructor.
+ TAO_DTP_Thread_Pool_Manager (TAO_ORB_Core &orb_core);
+
+ /// Destructor.
+ ~TAO_DTP_Thread_Pool_Manager (void);
+
+ /// Wait for threads to exit.
+ void wait (void);
+
+ /// Create a threadpool without lanes.
+ CORBA::ULong create_threadpool (TAO_DTP_Definition &def);
+
+ /// Destroy a threadpool.
+ void destroy_threadpool (CORBA::ULong threadpool);
+
+ /// Collection of thread pools.
+ typedef ACE_Hash_Map_Manager<CORBA::ULong, TAO_DTP_Thread_Pool *,
+ ACE_Null_Mutex> THREAD_POOLS;
+
+ /// @name Accessors
+ // @{
+ TAO_ORB_Core &orb_core (void) const;
+ // @}
+
+private:
+
+ /// @name Helpers
+ // @{
+
+ CORBA::ULong
+ create_threadpool_i (TAO_DTP_Definition &def);
+
+ CORBA::ULong
+ create_threadpool_helper (TAO_DTP_Thread_Pool *thread_pool);
+ // @}
+
+private:
+
+ TAO_ORB_Core &orb_core_;
+
+ THREAD_POOLS thread_pools_;
+ CORBA::ULong thread_pool_id_counter_;
+ TAO_SYNCH_MUTEX lock_;
+};
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "tao/Dynamic_TP/DTP_Thread_Pool.inl"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_THREAD_POOL_H */
diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.inl b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.inl
new file mode 100644
index 00000000000..9c28cc41e0e
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.inl
@@ -0,0 +1,43 @@
+// -*- C++ -*-
+//
+// $Id$
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_INLINE
+TAO_DTP_Thread_Pool &
+TAO_DTP_Thread_Pool_Threads::pool (void) const
+{
+ return this->pool_;
+}
+
+ACE_INLINE
+TAO_DTP_Thread_Pool_Manager &
+TAO_DTP_Thread_Pool::manager (void) const
+{
+ return this->manager_;
+}
+
+ACE_INLINE
+CORBA::ULong
+TAO_DTP_Thread_Pool::id (void) const
+{
+ return this->id_;
+}
+
+ACE_INLINE
+bool
+TAO_DTP_Thread_Pool::use_timeouts (void) const
+{
+ return this->definition_.max_threads_ > -1;
+}
+
+ACE_INLINE
+const ACE_Time_Value&
+TAO_DTP_Thread_Pool::dynamic_thread_time (void) const
+{
+ return this->definition_.timeout_;
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Dynamic_TP/Dynamic_TP.mpc b/TAO/tao/Dynamic_TP/Dynamic_TP.mpc
new file mode 100644
index 00000000000..764cc76884b
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/Dynamic_TP.mpc
@@ -0,0 +1,10 @@
+//$Id$
+
+project(Dynamic_TP) : taolib, tao_output, install, pi, csd_framework, csd_threadpool {
+ sharedname = TAO_Dynamic_TP
+ dynamicflags += TAO_DYNAMIC_TP_BUILD_DLL
+
+ specific {
+ install_dir = tao/Dynamic_TP
+ }
+}
diff --git a/TAO/tao/Dynamic_TP/dynamic_tp_export.h b/TAO/tao/Dynamic_TP/dynamic_tp_export.h
new file mode 100644
index 00000000000..3c6fd2ff524
--- /dev/null
+++ b/TAO/tao/Dynamic_TP/dynamic_tp_export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl TAO_Dynamic_TP
+// ------------------------------
+#ifndef TAO_DYNAMIC_TP_EXPORT_H
+#define TAO_DYNAMIC_TP_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (TAO_DYNAMIC_TP_HAS_DLL)
+# define TAO_DYNAMIC_TP_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && TAO_DYNAMIC_TP_HAS_DLL */
+
+#if !defined (TAO_DYNAMIC_TP_HAS_DLL)
+# define TAO_DYNAMIC_TP_HAS_DLL 1
+#endif /* ! TAO_DYNAMIC_TP_HAS_DLL */
+
+#if defined (TAO_DYNAMIC_TP_HAS_DLL) && (TAO_DYNAMIC_TP_HAS_DLL == 1)
+# if defined (TAO_DYNAMIC_TP_BUILD_DLL)
+# define TAO_Dynamic_TP_Export ACE_Proper_Export_Flag
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* TAO_DYNAMIC_TP_BUILD_DLL */
+# define TAO_Dynamic_TP_Export ACE_Proper_Import_Flag
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* TAO_DYNAMIC_TP_BUILD_DLL */
+#else /* TAO_DYNAMIC_TP_HAS_DLL == 1 */
+# define TAO_Dynamic_TP_Export
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARATION(T)
+# define TAO_DYNAMIC_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* TAO_DYNAMIC_TP_HAS_DLL == 1 */
+
+// Set TAO_DYNAMIC_TP_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (TAO_DYNAMIC_TP_NTRACE)
+# if (ACE_NTRACE == 1)
+# define TAO_DYNAMIC_TP_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define TAO_DYNAMIC_TP_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !TAO_DYNAMIC_TP_NTRACE */
+
+#if (TAO_DYNAMIC_TP_NTRACE == 1)
+# define TAO_DYNAMIC_TP_TRACE(X)
+#else /* (TAO_DYNAMIC_TP_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define TAO_DYNAMIC_TP_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (TAO_DYNAMIC_TP_NTRACE == 1) */
+
+#endif /* TAO_DYNAMIC_TP_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tao/IIOP_Profile.cpp b/TAO/tao/IIOP_Profile.cpp
index 512d80f5afe..79e01c083bc 100644
--- a/TAO/tao/IIOP_Profile.cpp
+++ b/TAO/tao/IIOP_Profile.cpp
@@ -474,7 +474,7 @@ TAO_IIOP_Profile::add_generic_endpoint (TAO_Endpoint *endp)
}
char *
-TAO_IIOP_Profile::to_string (void)
+TAO_IIOP_Profile::to_string (void) const
{
// corbaloc:iiop:1.2@host:port,iiop:1.2@host:port,.../key
diff --git a/TAO/tao/IIOP_Profile.h b/TAO/tao/IIOP_Profile.h
index ebb886e9958..1bb6fb16d10 100644
--- a/TAO/tao/IIOP_Profile.h
+++ b/TAO/tao/IIOP_Profile.h
@@ -95,7 +95,7 @@ public:
virtual char object_key_delimiter (void) const;
/// Template methods. Please see Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
/// Encode endpoints for RT profiles, using a single TAO_TAG_ENDPOINT
/// component.
diff --git a/TAO/tao/IIOP_Transport.cpp b/TAO/tao/IIOP_Transport.cpp
index 3dc71149072..c4cb2025e99 100644
--- a/TAO/tao/IIOP_Transport.cpp
+++ b/TAO/tao/IIOP_Transport.cpp
@@ -166,6 +166,8 @@ TAO_IIOP_Transport::recv (char *buf,
size_t len,
const ACE_Time_Value *max_wait_time)
{
+ this->connection_closed_on_read_ = false;
+
ssize_t const n = this->connection_handler_->peer ().recv (buf,
len,
max_wait_time);
@@ -196,6 +198,7 @@ TAO_IIOP_Transport::recv (char *buf,
// @@ What are the other error handling here??
else if (n == 0)
{
+ this->connection_closed_on_read_ = true;
return -1;
}
diff --git a/TAO/tao/IORManipulation/IORManipulation.cpp b/TAO/tao/IORManipulation/IORManipulation.cpp
index 51b83283892..cbeb0e36bec 100644
--- a/TAO/tao/IORManipulation/IORManipulation.cpp
+++ b/TAO/tao/IORManipulation/IORManipulation.cpp
@@ -27,9 +27,9 @@ TAO_IOR_Manipulation_impl::merge_iors (
{
// we need to create a new CORBA::Object which has the union of the
// two profile lists. However, if any profiles are duplicates (i.e. in
- // bott lisis) then an exception is raised.
+ // both lists) then an exception is raised.
- // Deterinine how many profiles we have
+ // Determine how many profiles we have
// Get an estimate of the size - pfile count could change since we
// neither lock nor get a copy in this loop.
CORBA::ULong i, count=0;
@@ -56,12 +56,12 @@ TAO_IOR_Manipulation_impl::merge_iors (
for (i = 1; i < iors.length () ; i++)
{
- // this gets a copy of the MProfile, hense the auto_ptr;
+ // this gets a copy of the MProfile, hence the auto_ptr;
ACE_auto_ptr_reset (tmp_pfiles,
iors[i]->_stubobj ()->make_profiles ());
- // check to see if any of the profile in tmp_pfiles are already
+ // check to see if any of the profiles in tmp_pfiles are already
// in Merged_Profiles. If so raise exception.
if (Merged_Profiles.is_equivalent (tmp_pfiles.get ()))
throw TAO_IOP::Duplicate ();
diff --git a/TAO/tao/ImR_Client/ImR_Client.cpp b/TAO/tao/ImR_Client/ImR_Client.cpp
index 010b938b876..810872ab321 100644
--- a/TAO/tao/ImR_Client/ImR_Client.cpp
+++ b/TAO/tao/ImR_Client/ImR_Client.cpp
@@ -2,6 +2,7 @@
#include "tao/ImR_Client/ImR_Client.h"
+#include "ace/Vector_T.h"
#include "tao/debug.h"
#include "tao/ORB_Core.h"
#include "tao/Stub.h"
@@ -10,9 +11,193 @@
#include "tao/PortableServer/Non_Servant_Upcall.h"
#include "tao/ImR_Client/ServerObject_i.h"
#include "tao/ImR_Client/ImplRepoC.h"
+#include "tao/IORManipulation/IORManip_Loader.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+namespace
+{
+ char* find_delimiter (char* const ior, const char delimiter)
+ {
+ // Search for "corbaloc:" alone, without the protocol. This code
+ // should be protocol neutral.
+ const char corbaloc[] = ACE_TEXT_ALWAYS_CHAR ("corbaloc:");
+ char *pos = ACE_OS::strstr (ior, corbaloc);
+ pos = ACE_OS::strchr (pos + sizeof (corbaloc), ':');
+
+ pos = ACE_OS::strchr (pos + 1, delimiter);
+
+ return pos;
+ }
+
+ CORBA::Object_ptr combine (TAO_ORB_Core& orb_core,
+ const TAO_Profile& profile,
+ const char* const key_str,
+ const char* type_id)
+ {
+ CORBA::String_var profile_str = profile.to_string ();
+
+// if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("************** IMR partial IOR =\n%C\n"),
+ profile_str.in ()));
+
+ char* const pos = find_delimiter (profile_str.inout (),
+ profile.object_key_delimiter ());
+ if (pos)
+ pos[1] = 0; // Crop the string.
+ else
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("Could not parse ImR IOR, skipping ImRification\n")));
+ return CORBA::Object::_nil();
+ }
+
+ ACE_CString ior (profile_str.in ());
+
+ // Add the key.
+ ior += key_str;
+
+// if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("************** ImR-ified IOR =\n%C\n\n"),
+ ior.c_str ()));
+
+ CORBA::Object_ptr obj = orb_core.orb ()->string_to_object (ior.c_str ());
+ obj->_stubobj()->type_id = type_id;
+ return obj;
+ }
+
+ class ImRifyProfiles
+ {
+ public:
+ ImRifyProfiles (const TAO_MProfile& base_profiles,
+ const TAO_Profile* const profile_in_use,
+ TAO_ORB_Core& orb_core,
+ const char* const key_str,
+ const char* type_id)
+ : base_profiles_ (base_profiles),
+ profile_in_use_ (profile_in_use),
+ orb_core_ (orb_core),
+ key_str_ (key_str),
+ type_id_ (type_id),
+ objs_ (base_profiles.profile_count()),
+ list_buffer_ (new CORBA::Object_ptr[base_profiles.profile_count()]),
+ ior_list_ (base_profiles.profile_count (),
+ base_profiles.profile_count (),
+ list_buffer_,
+ 0)
+ {
+ }
+
+ CORBA::Object_ptr combined_ior ()
+ {
+ const CORBA::ULong pcount = base_profiles_.profile_count ();
+ for (CORBA::ULong i = 0; i < pcount; ++i)
+ {
+ if (!combine_profile (i))
+ {
+ return default_obj (
+ ACE_TEXT_ALWAYS_CHAR ("could not resolve IORManipulation"));
+ }
+ }
+
+ CORBA::Object_var IORM = orb_core_.orb ()
+ ->resolve_initial_references (TAO_OBJID_IORMANIPULATION, 0);
+
+ if (CORBA::is_nil (IORM.in ()))
+ {
+ return default_obj (
+ ACE_TEXT_ALWAYS_CHAR ("could not resolve IORManipulation"));
+ }
+
+ TAO_IOP::TAO_IOR_Manipulation_var iorm =
+ TAO_IOP::TAO_IOR_Manipulation::_narrow (IORM.in ());
+
+ if (CORBA::is_nil (iorm.in ()))
+ {
+ return default_obj (
+ ACE_TEXT_ALWAYS_CHAR ("could not narrow IORManipulation"));
+ }
+
+ try
+ {
+ return iorm->merge_iors(ior_list_);
+ }
+ catch (const ::CORBA::Exception& )
+ {
+ return default_obj (
+ ACE_TEXT_ALWAYS_CHAR ("could not ImRify object with all profiles."));
+ }
+ }
+ private:
+ bool combine_profile(const CORBA::ULong i)
+ {
+ try
+ {
+ // store the combined profile+key
+ list_buffer_[i] = combine (orb_core_,
+ *(base_profiles_.get_profile (i)),
+ key_str_,
+ type_id_);
+ // manage the memory
+ objs_[i] = list_buffer_[i];
+
+ return true;
+ }
+ catch (const ::CORBA::Exception& )
+ {
+ return false;
+ }
+ }
+
+ CORBA::Object_ptr default_obj(const char* desc)
+ {
+ const CORBA::ULong pcount = base_profiles_.profile_count ();
+ const char* info =
+ ACE_TEXT ("because couldn't find ImR profile_in_use in profiles");
+
+ // identify the profile in use to see if we can default to
+ // that profiles partial ImR-ification
+ for (CORBA::ULong i = 0; i < pcount; ++i)
+ {
+ if (profile_in_use_ == base_profiles_.get_profile (i))
+ {
+ // if there is no object then try one last time to combine
+ // the profile
+ if (CORBA::is_nil(objs_[i].in ()) && !combine_profile (i))
+ {
+ info = ACE_TEXT ("because couldn't ImR-ify profile_in_use");
+ break;
+ }
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("ERROR: %C. ")
+ ACE_TEXT("Defaulting to ImR-ifying profile_in_use\n"),
+ desc));
+ return objs_[i]._retn ();
+ }
+ }
+
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT ("ERROR: %C, ")
+ ACE_TEXT ("but cannot default to ImR-ifying profile_in_use %C\n"),
+ desc,
+ info));
+ return CORBA::Object::_nil();
+ }
+
+ const TAO_MProfile& base_profiles_;
+ const TAO_Profile* const profile_in_use_;
+ TAO_ORB_Core& orb_core_;
+ const char* const key_str_;
+ const char* const type_id_;
+ ACE_Vector<CORBA::Object_var> objs_;
+ CORBA::Object_ptr* const list_buffer_;
+ TAO_IOP::TAO_IOR_Manipulation::IORList ior_list_;
+ };
+}
+
namespace TAO
{
namespace ImR_Client
@@ -38,7 +223,18 @@ namespace TAO
}
if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG, "Notifying ImR of startup\n"));
+ {
+ ACE_CString imr_info;
+ if (TAO_debug_level > 1)
+ {
+ CORBA::ORB_ptr orb = poa->orb_core ().orb ();
+ CORBA::String_var ior = orb->object_to_string (imr.in ());
+ imr_info = ACE_CString (", IMR IOR=") + ior.in ();
+ }
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Notifying ImR of startup%s\n"),
+ imr_info.c_str ()));
+ }
ImplementationRepository::Administration_var imr_locator;
@@ -51,7 +247,7 @@ namespace TAO
ImplementationRepository::Administration::_narrow (imr.in ());
}
- if (CORBA::is_nil(imr_locator.in ()))
+ if (CORBA::is_nil (imr_locator.in ()))
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("(%P|%t) ERROR: Narrowed IMR initial reference ")
@@ -82,7 +278,7 @@ namespace TAO
poa->server_priority (),
wait_occurred_restart_call_ignored);
- CORBA::Object_var obj = root_poa->id_to_reference_i (id.in (), false);
+ CORBA::Object_var obj = root_poa->id_to_reference_i (id.in (), false);
ImplementationRepository::ServerObject_var svr
= ImplementationRepository::ServerObject::_narrow (obj.in ());
@@ -93,24 +289,23 @@ namespace TAO
return;
}
- CORBA::String_var ior =
- svr->_stubobj ()->profile_in_use ()->to_string ();
+ CORBA::String_var full_ior = root_poa->_get_orb()->object_to_string (obj.in ());
+ TAO_Profile& profile = *(svr->_stubobj ()->profile_in_use ());
+ CORBA::String_var ior = profile.to_string();
+ ACE_DEBUG((LM_INFO,
+ "\n\nfull_ior=<%s>\n\nior=<%s>\n\n",
+ full_ior.in(),
+ ior.in()));
- // Search for "corbaloc:" alone, without the protocol. This code
- // should be protocol neutral.
- const char corbaloc[] = "corbaloc:";
- char *pos = ACE_OS::strstr (ior.inout (), corbaloc);
- pos = ACE_OS::strchr (pos + sizeof (corbaloc), ':');
+ char* const pos = find_delimiter (ior.inout (),
+ profile.object_key_delimiter ());
- pos = ACE_OS::strchr (pos + 1,
- svr->_stubobj ()->profile_in_use ()->object_key_delimiter ());
-
- ACE_CString partial_ior(ior.in (), (pos - ior.in()) + 1);
+ const ACE_CString partial_ior (ior.in (), (pos - ior.in ()) + 1);
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
- "Informing IMR that we are running at: %C\n",
- partial_ior.c_str()));
+ ACE_TEXT ("Informing IMR that we are running at: %C\n"),
+ partial_ior.c_str ()));
try
{
@@ -122,16 +317,16 @@ namespace TAO
ACE_CString name;
if (serverId.empty ())
{
- name = poa->name();
+ name = poa->name ();
}
else
{
- name = serverId + ":" + poa->name();
+ name = serverId + ":" + poa->name ();
}
imr_locator->server_is_running (name.c_str (),
- partial_ior.c_str(),
- svr.in());
+ partial_ior.c_str (),
+ svr.in ());
}
catch (const ::CORBA::SystemException&)
{
@@ -145,7 +340,8 @@ namespace TAO
}
if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG, "Successfully notified ImR of Startup\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Successfully notified ImR of Startup\n")));
}
void
@@ -165,7 +361,7 @@ namespace TAO
{
CORBA::String_var poaname = poa->the_name ();
ACE_DEBUG ((LM_DEBUG,
- "Notifying IMR of Shutdown server:%s\n",
+ ACE_TEXT ("Notifying IMR of Shutdown server:%s\n"),
poaname.in ()));
}
@@ -177,7 +373,7 @@ namespace TAO
ImplementationRepository::Administration_var imr_locator =
ImplementationRepository::Administration::_narrow (imr.in ());
- imr_locator->server_is_shutting_down (poa->name().c_str ());
+ imr_locator->server_is_shutting_down (poa->name ().c_str ());
}
catch (const ::CORBA::COMM_FAILURE&)
{
@@ -185,13 +381,17 @@ namespace TAO
// configured to drop replies during shutdown (it does by default in
// the LF model) we get a COMM_FAILURE exception which we ignore
if (TAO_debug_level > 0)
- ACE_DEBUG((LM_DEBUG, "Ignoring COMM_FAILURE while unregistering from ImR.\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Ignoring COMM_FAILURE while unregistering")
+ ACE_TEXT ("from ImR.\n")));
}
catch (const ::CORBA::TRANSIENT&)
{
// Similarly, there are cases where we could get a TRANSIENT.
if (TAO_debug_level > 0)
- ACE_DEBUG((LM_DEBUG, "Ignoring TRANSIENT while unregistering from ImR.\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Ignoring TRANSIENT while unregistering")
+ ACE_TEXT ("from ImR.\n")));
}
catch (const ::CORBA::Exception& ex)
{
@@ -202,9 +402,11 @@ namespace TAO
if (this->server_object_)
{
- PortableServer::POA_var default_poa = this->server_object_->_default_POA ();
+ PortableServer::POA_var default_poa =
+ this->server_object_->_default_POA ();
- TAO_Root_POA *root_poa = dynamic_cast <TAO_Root_POA*> (default_poa.in ());
+ TAO_Root_POA *root_poa =
+ dynamic_cast <TAO_Root_POA*> (default_poa.in ());
if (!root_poa)
{
@@ -214,7 +416,7 @@ namespace TAO
PortableServer::ObjectId_var id =
root_poa->servant_to_id_i (this->server_object_);
- root_poa->deactivate_object_i (id.in());
+ root_poa->deactivate_object_i (id.in ());
this->server_object_ = 0;
}
@@ -227,16 +429,63 @@ namespace TAO
int
ImR_Client_Adapter_Impl::Initializer (void)
{
- TAO_Root_POA::imr_client_adapter_name ("Concrete_ImR_Client_Adapter");
+ TAO_Root_POA::imr_client_adapter_name (
+ ACE_TEXT_ALWAYS_CHAR ("Concrete_ImR_Client_Adapter"));
+
+ return ACE_Service_Config::process_directive (
+ ace_svc_desc_ImR_Client_Adapter_Impl);
+ }
+
+ CORBA::Object_ptr
+ ImR_Client_Adapter_Impl::imr_key_to_object(TAO_Root_POA* poa,
+ const TAO::ObjectKey &key,
+ const char* type_id) const
+ {
+ TAO_ORB_Core& orb_core = poa->orb_core ();
+ // Check to see if we alter the IOR.
+ CORBA::Object_var imr = orb_core.implrepo_service ();
+
+ if (CORBA::is_nil (imr.in ())
+ || !imr->_stubobj ()
+ || !imr->_stubobj ()->profile_in_use ())
+ {
+ if (TAO_debug_level > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Missing ImR IOR, will not use the ImR\n")));
+ }
+ return CORBA::Object::_nil();
+ }
+
+ const TAO_MProfile& base_profiles = imr->_stubobj ()->base_profiles ();
+ CORBA::String_var key_str;
+ TAO::ObjectKey::encode_sequence_to_string (key_str.inout (), key);
+
+ // if there is only one profile, no need to use IORManipulation
+ if (base_profiles.profile_count() == 1)
+ {
+ return combine(orb_core,
+ *base_profiles.get_profile(0),
+ key_str.in(),
+ ACE_TEXT_ALWAYS_CHAR (type_id));
+ }
+
+ // need to combine each profile in the ImR with the key and
+ // then merge them all together into one ImR-ified ior
+ ImRifyProfiles imrify (base_profiles,
+ imr->_stubobj ()->profile_in_use (),
+ orb_core,
+ key_str,
+ ACE_TEXT_ALWAYS_CHAR (type_id));
- return ACE_Service_Config::process_directive (ace_svc_desc_ImR_Client_Adapter_Impl);
+ return imrify.combined_ior ();
}
}
}
ACE_STATIC_SVC_DEFINE (
ImR_Client_Adapter_Impl,
- ACE_TEXT ("Concrete_ImR_Client_Adapter"),
+ ACE_TEXT_ALWAYS_CHAR ("Concrete_ImR_Client_Adapter"),
ACE_SVC_OBJ_T,
&ACE_SVC_NAME (ImR_Client_Adapter_Impl),
ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
diff --git a/TAO/tao/ImR_Client/ImR_Client.h b/TAO/tao/ImR_Client/ImR_Client.h
index ed270a2af03..02185598e6d 100644
--- a/TAO/tao/ImR_Client/ImR_Client.h
+++ b/TAO/tao/ImR_Client/ImR_Client.h
@@ -59,6 +59,11 @@ namespace TAO
/// ImplRepo helper method, notify the ImplRepo on shutdown
virtual void imr_notify_shutdown (TAO_Root_POA* poa);
+ /// ImplRepo helper method, create an IMR-ified object for a
+ /// key with a given type
+ virtual CORBA::Object_ptr imr_key_to_object(TAO_Root_POA* poa,
+ const TAO::ObjectKey &key,
+ const char *type_id) const;
private:
/// Implementation Repository Server Object
ServerObject_i *server_object_;
diff --git a/TAO/tao/ImR_Client/ImR_Client.mpc b/TAO/tao/ImR_Client/ImR_Client.mpc
index 26d5027ea46..4350825cc33 100644
--- a/TAO/tao/ImR_Client/ImR_Client.mpc
+++ b/TAO/tao/ImR_Client/ImR_Client.mpc
@@ -24,7 +24,7 @@ project(*idl) : tao_versioning_idl_defaults, install {
}
}
-project(ImR_Client) : taolib, tao_output, install, portableserver, taoidldefaults {
+project(ImR_Client) : taolib, tao_output, install, portableserver, taoidldefaults, iormanip {
after += *idl
sharedname = TAO_ImR_Client
dynamicflags += TAO_IMR_CLIENT_BUILD_DLL
diff --git a/TAO/tao/Invocation_Adapter.cpp b/TAO/tao/Invocation_Adapter.cpp
index f85187b0172..310cec2dad1 100644
--- a/TAO/tao/Invocation_Adapter.cpp
+++ b/TAO/tao/Invocation_Adapter.cpp
@@ -15,6 +15,7 @@
#include "tao/TAOC.h"
#include "tao/SystemException.h"
#include "tao/Collocation_Resolver.h"
+#include "tao/Invocation_Retry_State.h"
#include "ace/Service_Config.h"
#if !defined (__ACE_INLINE__)
@@ -69,6 +70,8 @@ namespace TAO
max_wait_time= &tmp_wait_time;
}
+ TAO::Invocation_Retry_State retry_state (*stub);
+
while (status == TAO_INVOKE_START || status == TAO_INVOKE_RESTART)
{
// Default we go to remote
@@ -95,7 +98,8 @@ namespace TAO
this->invoke_remote_i (stub,
details,
effective_target,
- max_wait_time);
+ max_wait_time,
+ &retry_state);
}
else
{
@@ -228,7 +232,8 @@ namespace TAO
Invocation_Adapter::invoke_remote_i (TAO_Stub *stub,
TAO_Operation_Details &details,
CORBA::Object_var &effective_target,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
(void) this->set_response_flags (stub, details);
@@ -270,7 +275,8 @@ namespace TAO
return this->invoke_twoway (details,
effective_target,
resolver,
- max_wait_time);
+ max_wait_time,
+ retry_state);
}
}
@@ -281,7 +287,8 @@ namespace TAO
Invocation_Adapter::invoke_twoway (TAO_Operation_Details &details,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
// Simple sanity check
if (this->mode_ != TAO_SYNCHRONOUS_INVOCATION ||
@@ -294,7 +301,10 @@ namespace TAO
CORBA::COMPLETED_NO);
}
- TAO::Synch_Twoway_Invocation synch (this->target_, r, details);
+ TAO::Synch_Twoway_Invocation synch (this->target_, r, details,
+ true);
+
+ synch.set_retry_state (retry_state);
Invocation_Status const status = synch.remote_twoway (max_wait_time);
diff --git a/TAO/tao/Invocation_Adapter.h b/TAO/tao/Invocation_Adapter.h
index f539c28de45..b1ec5f7db19 100644
--- a/TAO/tao/Invocation_Adapter.h
+++ b/TAO/tao/Invocation_Adapter.h
@@ -47,6 +47,7 @@ namespace TAO
class Argument;
struct Exception_Data;
class Profile_Transport_Resolver;
+ class Invocation_Retry_State;
/**
* @class Invocation_Adapter
@@ -124,7 +125,9 @@ namespace TAO
* @param ex_count Number of elements in the array.
*/
virtual void invoke (TAO::Exception_Data *ex, unsigned long ex_count);
+
protected:
+
/**
* The stub pointer passed to this call has all the details about
* the object to which the invocation needs to be routed to. The
@@ -163,7 +166,8 @@ namespace TAO
TAO_Stub *stub,
TAO_Operation_Details &details,
CORBA::Object_var &effective_target,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
/// Make a collocated call.
/**
@@ -193,7 +197,8 @@ namespace TAO
TAO_Operation_Details &details,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
/// Helper method to make a one way invocation.
/**
diff --git a/TAO/tao/Invocation_Retry_Params.cpp b/TAO/tao/Invocation_Retry_Params.cpp
new file mode 100644
index 00000000000..4d966613d36
--- /dev/null
+++ b/TAO/tao/Invocation_Retry_Params.cpp
@@ -0,0 +1,20 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#include "tao/Invocation_Retry_Params.h"
+#include "tao/Invocation_Utils.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO::Invocation_Retry_Params::Invocation_Retry_Params (void)
+ : forward_on_reply_closed_limit_ (0)
+ , init_retry_delay_ (0, 100000) // Set default to 0.1 seconds
+{
+ this->forward_on_exception_limit_[FOE_OBJECT_NOT_EXIST] = 0;
+ this->forward_on_exception_limit_[FOE_COMM_FAILURE] = 0;
+ this->forward_on_exception_limit_[FOE_TRANSIENT] = 0;
+ this->forward_on_exception_limit_[FOE_INV_OBJREF] = 0;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Invocation_Retry_Params.h b/TAO/tao/Invocation_Retry_Params.h
new file mode 100644
index 00000000000..659ad4f7655
--- /dev/null
+++ b/TAO/tao/Invocation_Retry_Params.h
@@ -0,0 +1,61 @@
+/* -*- C++ -*- $Id$ */
+//=============================================================================
+/**
+ * @file Invocation_Retry_Params.h
+ *
+ * $Id$
+ *
+ * @author Byron Harris (harrisb@ociweb.com)
+ */
+//=============================================================================
+
+#ifndef TAO_INVOCATION_RETRY_PARAMS_H
+#define TAO_INVOCATION_RETRY_PARAMS_H
+
+#include "tao/orbconf.h"
+#include "ace/Array_Map.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ /**
+ * @struct Invocation_Retry_Params
+ *
+ * @brief Contains the invocation retry parameters used when encountering
+ * CORBA exceptions.
+ * The parameters can be specified using either the Client_Strategy_Factory
+ * service given in the service configuration file or through the command line.
+ * Any command line parameter overrides the corresponding option in the service
+ * configurator file.
+ */
+ struct Invocation_Retry_Params
+ {
+ Invocation_Retry_Params();
+
+ typedef ACE_Array_Map<int, int> exception_limit_map_type;
+
+ /**
+ * The maximum number of retry attempts per exception type
+ * when exceptions are encountered. The profiles are
+ * cycled through during each attempt.
+ */
+ exception_limit_map_type forward_on_exception_limit_;
+
+ /**
+ * The maximum number of times to retry a an invocation
+ * if the the connection to the server is closed when
+ * trying to get a reply.
+ */
+ int forward_on_reply_closed_limit_;
+
+ /**
+ * The delay to use between cycles of base and forward profiles.
+ */
+ ACE_Time_Value init_retry_delay_;
+ };
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_INVOCATION_RETRY_PARAMS_H*/
diff --git a/TAO/tao/Invocation_Retry_State.cpp b/TAO/tao/Invocation_Retry_State.cpp
new file mode 100644
index 00000000000..7204250846a
--- /dev/null
+++ b/TAO/tao/Invocation_Retry_State.cpp
@@ -0,0 +1,176 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#include "tao/Invocation_Retry_State.h"
+#include "tao/ORB_Core.h"
+#include "tao/Client_Strategy_Factory.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace
+{
+ void retry_limit_calc (int ex,
+ TAO::Invocation_Retry_Params &command_line_params,
+ TAO::Invocation_Retry_Params &client_factory_params,
+ TAO::Invocation_Retry_Params &result)
+ {
+ if (command_line_params.forward_on_exception_limit_[ex] !=
+ result.forward_on_exception_limit_[ex])
+ result.forward_on_exception_limit_[ex] =
+ command_line_params.forward_on_exception_limit_[ex];
+ else if (client_factory_params.forward_on_exception_limit_[ex] !=
+ result.forward_on_exception_limit_[ex])
+ result.forward_on_exception_limit_[ex] =
+ client_factory_params.forward_on_exception_limit_[ex];
+ }
+
+ /// Calculate the retry parameters by giving a command line parameter
+ /// precedence over the corresponding client strategy factory parameter.
+ /// result is assumed to be passed with default values
+ void retry_params_calc (TAO::Invocation_Retry_Params &command_line_params,
+ TAO::Invocation_Retry_Params &client_factory_params,
+ TAO::Invocation_Retry_Params &result)
+ {
+
+ // Retry delay
+ if (command_line_params.init_retry_delay_ !=
+ result.init_retry_delay_)
+ result.init_retry_delay_ = command_line_params.init_retry_delay_;
+ else if (client_factory_params.init_retry_delay_ !=
+ result.init_retry_delay_)
+ result.init_retry_delay_ = client_factory_params.init_retry_delay_;
+
+ // Retry on reply closed limit
+ if (command_line_params.forward_on_reply_closed_limit_ !=
+ result.forward_on_reply_closed_limit_)
+ result.forward_on_reply_closed_limit_ =
+ command_line_params.forward_on_reply_closed_limit_;
+ else if (client_factory_params.forward_on_reply_closed_limit_ !=
+ result.forward_on_reply_closed_limit_)
+ result.forward_on_reply_closed_limit_ =
+ client_factory_params.forward_on_reply_closed_limit_;
+
+ // Forward on exception limits
+
+ retry_limit_calc (TAO::FOE_OBJECT_NOT_EXIST,
+ command_line_params,
+ client_factory_params,
+ result);
+
+ retry_limit_calc (TAO::FOE_COMM_FAILURE,
+ command_line_params,
+ client_factory_params,
+ result);
+
+ retry_limit_calc (TAO::FOE_TRANSIENT,
+ command_line_params,
+ client_factory_params,
+ result);
+
+ retry_limit_calc (TAO::FOE_INV_OBJREF,
+ command_line_params,
+ client_factory_params,
+ result);
+
+ }
+
+}
+
+TAO::Invocation_Retry_State::Invocation_Retry_State (TAO_Stub &stub)
+ : forward_on_reply_closed_count_ (0)
+ , forward_on_exception_limit_used_ (false)
+{
+ this->ex_count_map_[FOE_OBJECT_NOT_EXIST] = 0;
+ this->ex_count_map_[FOE_COMM_FAILURE] = 0;
+ this->ex_count_map_[FOE_TRANSIENT] = 0;
+ this->ex_count_map_[FOE_INV_OBJREF] = 0;
+
+ // Cast away const to avoid tedious iterator operations on the ACE_Array_Map.
+ TAO::Invocation_Retry_Params &command_line_params =
+ const_cast<TAO::Invocation_Retry_Params &> (stub.orb_core ()
+ ->orb_params ()->invocation_retry_params ());
+ TAO::Invocation_Retry_Params &client_factory_params =
+ const_cast<TAO::Invocation_Retry_Params &> (stub.orb_core ()
+ ->client_factory ()->invocation_retry_params ());
+
+ retry_params_calc(command_line_params,
+ client_factory_params,
+ this->retry_params_);
+
+ for (Invocation_Retry_Params::exception_limit_map_type::const_iterator i =
+ this->retry_params_.forward_on_exception_limit_.begin();
+ i != this->retry_params_.forward_on_exception_limit_.end(); ++i)
+ {
+ if (i->second > 0)
+ {
+ forward_on_exception_limit_used_ = true;
+ break;
+ }
+ }
+}
+
+TAO::Invocation_Retry_State::~Invocation_Retry_State ()
+{
+}
+
+bool
+TAO::Invocation_Retry_State::forward_on_exception_limit_used () const
+{
+ return forward_on_exception_limit_used_;
+}
+
+bool
+TAO::Invocation_Retry_State::forward_on_exception_increment (const int ef)
+{
+ if (!this->forward_on_exception_limit_used_)
+ return false;
+
+ int count = this->ex_count_map_[ef];
+ Invocation_Retry_Params::exception_limit_map_type::const_iterator i =
+ this->retry_params_.forward_on_exception_limit_.find (ef);
+ int limit = i->second;
+ if (count < limit)
+ {
+ this->ex_count_map_[ef] = count + 1;
+ return true;
+ }
+
+ return false;
+}
+
+bool
+TAO::Invocation_Retry_State::forward_on_reply_closed_increment ()
+{
+ if (this->forward_on_reply_closed_count_ <
+ this->retry_params_.forward_on_reply_closed_limit_)
+ {
+ ++this->forward_on_reply_closed_count_;
+ return true;
+ }
+
+ return false;
+}
+
+void
+TAO::Invocation_Retry_State::next_profile_retry (TAO_Stub &stub) const
+{
+ stub.next_profile_retry ();
+ this->sleep_at_starting_profile (stub);
+}
+
+void
+TAO::Invocation_Retry_State::sleep_at_starting_profile (TAO_Stub &stub) const
+{
+ if (stub.at_starting_profile ())
+ this->sleep ();
+}
+
+void
+TAO::Invocation_Retry_State::sleep () const
+{
+ ACE_OS::sleep (this->retry_params_.init_retry_delay_);
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Invocation_Retry_State.h b/TAO/tao/Invocation_Retry_State.h
new file mode 100644
index 00000000000..096f32fadf8
--- /dev/null
+++ b/TAO/tao/Invocation_Retry_State.h
@@ -0,0 +1,98 @@
+/* -*- C++ -*- $Id$ */
+//=============================================================================
+/**
+ * @file Invocation_Retry_State.h
+ *
+ * $Id$
+ *
+ * @author Byron Harris (harrisb@ociweb.com)
+ *
+ */
+//=============================================================================
+
+#ifndef TAO_INVOCATION_RETRY_STATE_H
+#define TAO_INVOCATION_RETRY_STATE_H
+
+#include "tao/Stub.h"
+#include "tao/Invocation_Retry_Params.h"
+
+#include "ace/Array_Map.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ /**
+ * @class Invocation_Retry_State
+ *
+ * @brief Maintains state of invocation retries.
+ */
+ class Invocation_Retry_State
+ {
+ public:
+ Invocation_Retry_State (TAO_Stub &stub);
+
+ ~Invocation_Retry_State ();
+
+ /**
+ * Answer if any profile forward on exception limit
+ * parameter is used.
+ */
+ bool forward_on_exception_limit_used () const;
+
+ /**
+ * Attempt to increment the count of profile
+ * forwards.
+ * @return false if forward on exception is not
+ * being used or the limit has been reached.
+ */
+ bool forward_on_exception_increment (const int ef);
+
+ /**
+ * Attempt to increment the count of retries
+ * when a server connection is seen as closed
+ * during reply.
+ */
+ bool forward_on_reply_closed_increment ();
+
+ /**
+ * Increment to next profile in preparation
+ * to retry using that profile.
+ * If the next profile is the starting
+ * base profile then also call
+ * sleep ().
+ * @see TAO_Stub::next_profile_retry()
+ */
+ void next_profile_retry (TAO_Stub &stub) const;
+
+ /**
+ * Sleep if profile is the starting
+ * base profile.
+ */
+ void sleep_at_starting_profile (TAO_Stub &stub) const;
+
+ /**
+ * Sleep according to the delay value
+ * in Invocation_Retry_Params.
+ */
+ void sleep () const;
+
+ private:
+
+ typedef ACE_Array_Map<int, int> Ex_Count_Map;
+ Ex_Count_Map ex_count_map_;
+ int forward_on_reply_closed_count_;
+ Invocation_Retry_Params retry_params_;
+ bool forward_on_exception_limit_used_;
+ };
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_INVOCATION_RETRY_STATE_H*/
diff --git a/TAO/tao/Invocation_Utils.h b/TAO/tao/Invocation_Utils.h
index 54e8ec6a0c5..f17df10c510 100644
--- a/TAO/tao/Invocation_Utils.h
+++ b/TAO/tao/Invocation_Utils.h
@@ -71,7 +71,7 @@ namespace TAO
TAO_DII_ASYNCH_INVOCATION
};
- enum Forward_Once_Exception
+ enum Forward_On_Exception
{
FOE_NON = 0x0,
FOE_OBJECT_NOT_EXIST = 0x1,
diff --git a/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp b/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
index e0b8a583be7..3e189293220 100644
--- a/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
+++ b/TAO/tao/Messaging/Asynch_Invocation_Adapter.cpp
@@ -152,8 +152,11 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time)
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state)
{
+ ACE_UNUSED_ARG (retry_state);
+
// Simple sanity check
if (this->mode_ != TAO_ASYNCHRONOUS_CALLBACK_INVOCATION
|| this->type_ != TAO_TWOWAY_INVOCATION)
diff --git a/TAO/tao/Messaging/Asynch_Invocation_Adapter.h b/TAO/tao/Messaging/Asynch_Invocation_Adapter.h
index 4c78afaedae..c562f2fcba8 100644
--- a/TAO/tao/Messaging/Asynch_Invocation_Adapter.h
+++ b/TAO/tao/Messaging/Asynch_Invocation_Adapter.h
@@ -80,7 +80,8 @@ namespace TAO
TAO_Operation_Details &op,
CORBA::Object_var &effective_target,
Profile_Transport_Resolver &r,
- ACE_Time_Value *&max_wait_time);
+ ACE_Time_Value *&max_wait_time,
+ Invocation_Retry_State *retry_state = 0);
virtual Invocation_Status invoke_collocated_i (
TAO_Stub *stub,
diff --git a/TAO/tao/ORB_Core.cpp b/TAO/tao/ORB_Core.cpp
index 6fa0711bba6..cdae1455171 100644
--- a/TAO/tao/ORB_Core.cpp
+++ b/TAO/tao/ORB_Core.cpp
@@ -1102,7 +1102,54 @@ TAO_ORB_Core::init (int &argc, char *argv[] )
arg_shifter.consume_arg ();
}
else if (0 != (current_arg = arg_shifter.get_the_parameter
- (ACE_TEXT("-ORBForwardOnceOnObjectNotExist"))))
+ (ACE_TEXT("-ORBForwardOnTransientLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.forward_on_exception_limit (TAO::FOE_TRANSIENT, limit);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnCommFailureLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.forward_on_exception_limit (
+ TAO::FOE_COMM_FAILURE, limit);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnObjectNotExistLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.forward_on_exception_limit (
+ TAO::FOE_OBJECT_NOT_EXIST, limit);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnInvObjrefLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.forward_on_exception_limit (
+ TAO::FOE_INV_OBJREF, limit);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnReplyClosedLimit"))))
+ {
+ int limit = ACE_OS::atoi (current_arg);
+ this->orb_params_.invocation_retry_params ()
+ .forward_on_reply_closed_limit_ = limit;
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardDelay"))))
+ {
+ int msecs = ACE_OS::atoi (current_arg);
+ ACE_Time_Value delay(0, 1000*msecs);
+ this->orb_params_.forward_on_exception_delay (delay);
+ arg_shifter.consume_arg ();
+ }
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardOnceOnObjectNotExist"))))
{
int forward = ACE_OS::atoi (current_arg);
if (forward)
@@ -1138,12 +1185,18 @@ TAO_ORB_Core::init (int &argc, char *argv[] )
arg_shifter.consume_arg ();
}
else if (0 != (current_arg = arg_shifter.get_the_parameter
- (ACE_TEXT("-ORBAllowZIOPNoServerPolicies"))))
+ (ACE_TEXT("-ORBAllowZIOPNoServerPolicies"))))
{
// This option takes a boolean 0 (off/dissallow) or 1 (on/allow)
this->orb_params_.allow_ziop_no_server_policies (!!ACE_OS::atoi (current_arg));
arg_shifter.consume_arg ();
}
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBDynamicThreadPoolName"))))
+ {
+ this->orb_params_.dynamic_thread_pool_config_name (current_arg);
+ arg_shifter.consume_arg ();
+ }
////////////////////////////////////////////////////////////////
// catch any unknown -ORB args //
diff --git a/TAO/tao/PortableServer/ImR_Client_Adapter.h b/TAO/tao/PortableServer/ImR_Client_Adapter.h
index 70be6e3c5d2..600aaa43fe6 100644
--- a/TAO/tao/PortableServer/ImR_Client_Adapter.h
+++ b/TAO/tao/PortableServer/ImR_Client_Adapter.h
@@ -29,8 +29,16 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL
class TAO_Root_POA;
+namespace CORBA
+{
+ class Object;
+ typedef Object* Object_ptr;
+}
+
namespace TAO
{
+ class ObjectKey;
+
namespace Portable_Server
{
/**
@@ -53,6 +61,13 @@ namespace TAO
/// ImplRepo helper method, notify the ImplRepo on shutdown
virtual void imr_notify_shutdown (TAO_Root_POA* poa ) = 0;
+
+ /// ImplRepo helper method, create an IMR-ified object for a
+ /// key with a given type
+ virtual CORBA::Object_ptr imr_key_to_object(
+ TAO_Root_POA* poa,
+ const TAO::ObjectKey &key,
+ const char *type_id) const = 0;
};
}
}
diff --git a/TAO/tao/PortableServer/LifespanStrategy.h b/TAO/tao/PortableServer/LifespanStrategy.h
index 70e0c06c04d..7b562e8c801 100644
--- a/TAO/tao/PortableServer/LifespanStrategy.h
+++ b/TAO/tao/PortableServer/LifespanStrategy.h
@@ -37,9 +37,9 @@ namespace TAO
public:
LifespanStrategy (void);
- virtual void strategy_init(TAO_Root_POA *poa);
+ virtual void strategy_init (TAO_Root_POA *poa);
- virtual void strategy_cleanup(void);
+ virtual void strategy_cleanup (void);
void create (const char *name, const TAO::ObjectKey &key);
@@ -72,10 +72,14 @@ namespace TAO
/// Check the state of the POA.
virtual void check_state (void) = 0;
- virtual ::PortableServer::LifespanPolicyValue type() const = 0;
+ virtual ::PortableServer::LifespanPolicyValue type () const = 0;
virtual bool use_imr () const = 0;
+ virtual CORBA::Object_ptr imr_key_to_object (
+ const TAO::ObjectKey &key,
+ const char *type_id) const = 0;
+
protected:
TAO_Root_POA *poa_;
};
diff --git a/TAO/tao/PortableServer/LifespanStrategyPersistent.cpp b/TAO/tao/PortableServer/LifespanStrategyPersistent.cpp
index 093c7c5ef9e..0c82a670673 100644
--- a/TAO/tao/PortableServer/LifespanStrategyPersistent.cpp
+++ b/TAO/tao/PortableServer/LifespanStrategyPersistent.cpp
@@ -120,7 +120,7 @@ namespace TAO
}
}
- LifespanStrategyPersistent::LifespanStrategyPersistent() :
+ LifespanStrategyPersistent::LifespanStrategyPersistent () :
use_imr_ (true)
{
}
@@ -142,6 +142,31 @@ namespace TAO
{
return use_imr_;
}
+
+ CORBA::Object_ptr
+ LifespanStrategyPersistent::imr_key_to_object (const TAO::ObjectKey &key,
+ const char *type_id) const
+ {
+ if (!this->use_imr_)
+ {
+ // not using the imr
+ return CORBA::Object::_nil ();
+ }
+
+ // The user specified that the ImR should be used.
+ ImR_Client_Adapter *adapter =
+ ACE_Dynamic_Service<ImR_Client_Adapter>::instance (
+ TAO_Root_POA::imr_client_adapter_name ()
+ );
+ if (adapter == 0)
+ {
+ // couldn't load adapter, already reported error
+ return CORBA::Object::_nil ();
+ }
+
+ return adapter->imr_key_to_object (this->poa_, key, type_id);
+ }
+
} /* namespace Portable_Server */
} /* namespace TAO */
diff --git a/TAO/tao/PortableServer/LifespanStrategyPersistent.h b/TAO/tao/PortableServer/LifespanStrategyPersistent.h
index ce8c9a7bdd6..d379607a91b 100644
--- a/TAO/tao/PortableServer/LifespanStrategyPersistent.h
+++ b/TAO/tao/PortableServer/LifespanStrategyPersistent.h
@@ -61,6 +61,9 @@ namespace TAO
virtual bool use_imr () const;
+ virtual CORBA::Object_ptr imr_key_to_object(const TAO::ObjectKey &key,
+ const char *type_id) const;
+
private:
bool use_imr_;
};
diff --git a/TAO/tao/PortableServer/LifespanStrategyTransient.cpp b/TAO/tao/PortableServer/LifespanStrategyTransient.cpp
index eec9ca12ce0..afe60a9b338 100644
--- a/TAO/tao/PortableServer/LifespanStrategyTransient.cpp
+++ b/TAO/tao/PortableServer/LifespanStrategyTransient.cpp
@@ -104,6 +104,13 @@ namespace TAO
return false;
}
+ CORBA::Object_ptr
+ LifespanStrategyTransient::imr_key_to_object (const TAO::ObjectKey &,
+ const char *) const
+ {
+ return CORBA::Object::_nil();
+ }
+
::PortableServer::LifespanPolicyValue
LifespanStrategyTransient::type () const
{
diff --git a/TAO/tao/PortableServer/LifespanStrategyTransient.h b/TAO/tao/PortableServer/LifespanStrategyTransient.h
index 46ebb3f5a15..2a811c485c1 100644
--- a/TAO/tao/PortableServer/LifespanStrategyTransient.h
+++ b/TAO/tao/PortableServer/LifespanStrategyTransient.h
@@ -58,6 +58,9 @@ namespace TAO
virtual bool use_imr () const;
+ virtual CORBA::Object_ptr imr_key_to_object (const TAO::ObjectKey &key,
+ const char *type_id) const;
+
private:
TAO::Portable_Server::Creation_Time creation_time_;
};
diff --git a/TAO/tao/PortableServer/Root_POA.cpp b/TAO/tao/PortableServer/Root_POA.cpp
index 3de8235bf06..497ed456c83 100644
--- a/TAO/tao/PortableServer/Root_POA.cpp
+++ b/TAO/tao/PortableServer/Root_POA.cpp
@@ -1948,77 +1948,16 @@ TAO_Root_POA::key_to_object (const TAO::ObjectKey &key,
//
#if (TAO_HAS_MINIMUM_CORBA == 0)
- CORBA::Object_ptr obj = CORBA::Object::_nil ();
-
- if (indirect && this->active_policy_strategies_.lifespan_strategy()->use_imr ()
- && this->orb_core ().imr_endpoints_in_ior ())
+ if (indirect && this->orb_core ().imr_endpoints_in_ior ())
{
- // Check to see if we alter the IOR.
- CORBA::Object_var imr = this->orb_core ().implrepo_service ();
-
- if (CORBA::is_nil (imr.in ())
- || !imr->_stubobj ()
- || !imr->_stubobj ()->profile_in_use ())
+ CORBA::Object_ptr obj = this->active_policy_strategies_.
+ lifespan_strategy()->imr_key_to_object (key, type_id);
+ if (!CORBA::is_nil (obj))
{
- if (TAO_debug_level > 1)
- {
- ACE_DEBUG ((LM_DEBUG,
- "Missing ImR IOR, will not use the ImR\n"));
- }
- goto orbkey;
+ return obj;
}
-
- CORBA::String_var imr_str =
- imr->_stubobj ()->profile_in_use ()->to_string ();
-
- if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG,
- "IMR IOR =\n%C\n",
- imr_str.in ()));
-
- // Search for "corbaloc:" alone, without the protocol. This code
- // should be protocol neutral.
- const char corbaloc[] = "corbaloc:";
- char *pos = ACE_OS::strstr (imr_str.inout (), corbaloc);
- pos = ACE_OS::strchr (pos + sizeof (corbaloc), ':');
-
- pos = ACE_OS::strchr (pos + 1,
- imr->_stubobj ()->profile_in_use ()->object_key_delimiter ());
-
- if (pos)
- pos[1] = 0; // Crop the string.
- else
- {
- if (TAO_debug_level > 0)
- ACE_ERROR ((LM_ERROR,
- "Could not parse ImR IOR, skipping ImRification\n"));
- goto orbkey;
- }
-
- ACE_CString ior (imr_str.in ());
-
- // Add the key.
-
- CORBA::String_var key_str;
- TAO::ObjectKey::encode_sequence_to_string (key_str.inout (), key);
-
- ior += key_str.in ();
-
- if (TAO_debug_level > 0)
- ACE_DEBUG ((LM_DEBUG,
- "ImR-ified IOR =\n%C\n",
- ior.c_str ()));
-
- obj = this->orb_core_.orb ()->string_to_object (ior.c_str ());
-
- // type_id info is not in the corbaloc, so set it here
- obj->_stubobj()->type_id = type_id;
-
- return obj;
}
-orbkey:
-
#else
ACE_UNUSED_ARG (indirect);
#endif /* TAO_HAS_MINIMUM_CORBA */
diff --git a/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp b/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp
index d797edb925e..de26ec8ee98 100644
--- a/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp
+++ b/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.cpp
@@ -17,6 +17,10 @@
#include "tao/PortableServer/Servant_Base.h"
#include "tao/debug.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/Time_Value.h"
+#include "ace/OS_NS_sys_time.h"
+
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
namespace TAO
@@ -24,7 +28,8 @@ namespace TAO
namespace Portable_Server
{
ServantRetentionStrategyNonRetain::ServantRetentionStrategyNonRetain (void) :
- poa_ (0)
+ poa_ (0),
+ sys_id_count_ (0)
{
}
@@ -188,12 +193,29 @@ namespace TAO
PortableServer::ObjectId user_id;
// Otherwise, it is the NON_RETAIN policy. Therefore, any ol'
- // object id will do (even an empty one).
+ // object id will do (even an empty one). However, to make an
+ // object id useful for discriminating objects in applications
+ // use a simple id of a counter and a time stamp. The use of a
+ // counter by itself is not sufficient for uniqueness over time
+ // and a timestamp isn't sufficient since multiple IDs may be
+ // requested within the same time unit.
+
PortableServer::ObjectId *sys_id = 0;
ACE_NEW_THROW_EX (sys_id,
- PortableServer::ObjectId,
+ PortableServer::ObjectId (8),
CORBA::NO_MEMORY ());
+ sys_id->length(8);
+
+ long count = this->sys_id_count_++;
+ ACE_Time_Value now = ACE_OS::gettimeofday();
+
+ *reinterpret_cast<ACE_UINT32 *>(sys_id->get_buffer()) =
+ count;
+
+ *reinterpret_cast<ACE_UINT32 *>(sys_id->get_buffer() + 4) =
+ static_cast<ACE_UINT32>(now.sec());
+
system_id = sys_id;
// User id is the same as system id.
diff --git a/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h b/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h
index bc4a2e1d50b..6870c1e018c 100644
--- a/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h
+++ b/TAO/tao/PortableServer/ServantRetentionStrategyNonRetain.h
@@ -21,6 +21,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/PortableServer/Servant_Location.h"
+#include "ace/Atomic_Op.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -124,6 +125,7 @@ namespace TAO
protected:
TAO_Root_POA *poa_;
+ ACE_Atomic_Op<TAO_SYNCH_MUTEX,long> sys_id_count_;
};
}
}
diff --git a/TAO/tao/Profile.cpp b/TAO/tao/Profile.cpp
index 8cab33b26b8..4fdde3441a8 100644
--- a/TAO/tao/Profile.cpp
+++ b/TAO/tao/Profile.cpp
@@ -801,7 +801,7 @@ TAO_Unknown_Profile::object_key_delimiter (void) const
}
char *
-TAO_Unknown_Profile::to_string (void)
+TAO_Unknown_Profile::to_string (void) const
{
// @@ THROW something?
return 0;
diff --git a/TAO/tao/Profile.h b/TAO/tao/Profile.h
index 6b5570c9481..34461840ee2 100644
--- a/TAO/tao/Profile.h
+++ b/TAO/tao/Profile.h
@@ -182,7 +182,7 @@ public:
/// Return a string representation for this profile. Client must
/// deallocate memory. Only one endpoint is included into the
/// string.
- virtual char* to_string (void) = 0;
+ virtual char* to_string (void) const = 0;
/**
* Encodes this profile's endpoints into a tagged component.
@@ -430,7 +430,7 @@ public:
// = The TAO_Profile methods look above
virtual void parse_string (const char *string);
virtual char object_key_delimiter (void) const;
- virtual char* to_string (void);
+ virtual char* to_string (void) const;
virtual int decode (TAO_InputCDR& cdr);
virtual int encode (TAO_OutputCDR &stream) const;
virtual int encode_endpoints (void);
diff --git a/TAO/tao/Seq_Var_T.h b/TAO/tao/Seq_Var_T.h
index 3ec1449d834..4d91492f547 100644
--- a/TAO/tao/Seq_Var_T.h
+++ b/TAO/tao/Seq_Var_T.h
@@ -61,8 +61,10 @@ public:
_out_type out (void);
_retn_type _retn (void);
- /// TAO extension.
- _retn_type ptr (void) const;
+ /// TAO extension.
+ _retn_type ptr (void) const;
+ operator T *& ();
+
protected:
T * ptr_;
};
@@ -120,9 +122,6 @@ public:
T_elem operator[] (CORBA::ULong index);
T_const_elem operator[] (CORBA::ULong index) const;
-
- /// Variable-size base types only.
- operator T *& ();
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Seq_Var_T.inl b/TAO/tao/Seq_Var_T.inl
index b1c7c16d024..ede406b652d 100644
--- a/TAO/tao/Seq_Var_T.inl
+++ b/TAO/tao/Seq_Var_T.inl
@@ -106,6 +106,13 @@ TAO_Seq_Var_Base_T<T>::ptr (void) const
return this->ptr_;
}
+template<typename T>
+ACE_INLINE
+TAO_Seq_Var_Base_T<T>::operator T *& ()
+{
+ return this->ptr_;
+}
+
// ***************************************************************
template<typename T>
@@ -194,14 +201,6 @@ TAO_VarSeq_Var_T<T>::operator= (T * p)
return *this;
}
-// Variable-size types only.
-template<typename T>
-ACE_INLINE
-TAO_VarSeq_Var_T<T>::operator T *& ()
-{
- return this->ptr_;
-}
-
template<typename T>
ACE_INLINE
typename TAO_VarSeq_Var_T<T>::T_elem
diff --git a/TAO/tao/Storable_Base.cpp b/TAO/tao/Storable_Base.cpp
new file mode 100644
index 00000000000..dc588dd8db8
--- /dev/null
+++ b/TAO/tao/Storable_Base.cpp
@@ -0,0 +1,97 @@
+//=============================================================================
+/**
+ * @file Storable_Base.cpp
+ *
+ * $Id$
+ *
+ * @author Bruce Trask <trask_b@ociweb.com>
+ * @author Chanaka Liyanaarachchi <chanaka@ociweb.com>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "tao/Storable_Base.h"
+
+#if !defined (__ACE_INLINE__)
+#include "tao/Storable_Base.inl"
+#endif /* __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+bool TAO::Storable_Base::use_backup_default = false;
+
+void
+TAO::Storable_Base::remove (void)
+{
+ if (this->use_backup_)
+ {
+ this->remove_backup ();
+ }
+ this->do_remove ();
+}
+
+bool
+TAO::Storable_Base::use_backup ()
+{
+ return this->use_backup_;
+}
+
+ACE_CString
+TAO::Storable_Base::state_as_string (Storable_State state)
+{
+ ACE_CString state_string;
+ if (state == goodbit)
+ state_string = "goodbit";
+ else
+ {
+ if (state & badbit)
+ state_string = "badbit ";
+ if (state & eofbit)
+ state_string += "eofbit ";
+ if (state & failbit)
+ state_string += "failbit";
+ }
+ return state_string;
+}
+
+TAO::Storable_Exception::
+Storable_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name)
+ : storable_state_ (state)
+ , file_name_ (file_name)
+{
+}
+
+TAO::Storable_Exception::
+~Storable_Exception ()
+{
+}
+
+TAO::Storable_Base::Storable_State
+TAO::Storable_Exception::get_state () const
+{
+ return storable_state_;
+}
+
+const ACE_CString &
+TAO::Storable_Exception::get_file_name () const
+{
+ return file_name_;
+}
+
+TAO::Storable_Read_Exception::
+Storable_Read_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name)
+ : Storable_Exception (state, file_name)
+{
+}
+
+TAO::Storable_Write_Exception::
+Storable_Write_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name)
+ : Storable_Exception (state, file_name)
+{
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Storable_Base.h b/TAO/tao/Storable_Base.h
new file mode 100644
index 00000000000..b2fdcf7fc23
--- /dev/null
+++ b/TAO/tao/Storable_Base.h
@@ -0,0 +1,181 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Base.h
+ *
+ * $Id$
+ *
+ * @author Bruce Trask <trask_b@ociweb.com>
+ * @author Chanaka Liyanaarachchi <chanaka@ociweb.com>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_STORABLE_BASE_H
+#define TAO_STORABLE_BASE_H
+
+#include "tao/TAO_Export.h"
+#include "tao/orbconf.h"
+#include "tao/CDR.h"
+
+#include "ace/SString.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ class TAO_Export Storable_Base
+ {
+ public:
+
+ Storable_Base (bool use_backup);
+
+ virtual ~Storable_Base ();
+
+ /// The process-wide default policy
+ /// for doing a backup when close ()
+ /// is called.
+ /// The backup can then be restored if
+ /// restore_backup () is called.
+ /// The initial value for the default is false.
+ static bool use_backup_default;
+
+ bool use_backup ();
+
+ /// Remove the file that is assumed to not be open.
+ /// If backup are used, the backup will also be removed.
+ void remove();
+
+ virtual int create_backup () = 0;
+
+ virtual int exists() = 0;
+
+ virtual int open () = 0;
+
+ virtual int close () = 0;
+
+ virtual int flock (int whence, int start, int len) = 0;
+
+ virtual int funlock (int whence, int start, int len) = 0;
+
+ virtual time_t last_changed(void) = 0;
+
+ // Mimic a portion of the std::ios interface. We need to be able
+ // to indicate error states from the extraction operators below.
+ enum Storable_State { goodbit = 0,
+ badbit = 1,
+ eofbit = 2,
+ failbit = 4
+ };
+
+ void clear (Storable_State state = goodbit);
+
+ void setstate (Storable_State state);
+
+ Storable_State rdstate (void) const;
+
+ bool good (void) const;
+
+ bool bad (void) const;
+
+ bool eof (void) const;
+
+ bool fail (void) const;
+
+ static ACE_CString state_as_string (Storable_State state);
+
+ virtual void rewind (void) = 0;
+
+ virtual bool flush (void) = 0;
+
+ /// Force write of storable data to storage.
+ /// Returns 0 on success, otherwise EOF
+ virtual int sync (void) = 0;
+
+ virtual Storable_Base& operator << (const ACE_CString& str) = 0;
+
+ virtual Storable_Base& operator >> (ACE_CString& str) = 0;
+
+ virtual Storable_Base& operator << (int i) = 0;
+
+ virtual Storable_Base& operator >> (int &i) = 0;
+
+ virtual Storable_Base& operator << (unsigned int i) = 0;
+
+ virtual Storable_Base& operator >> (unsigned int &i) = 0;
+
+ virtual Storable_Base& operator << (const TAO_OutputCDR & cdr) = 0;
+
+ virtual size_t write (size_t size, const char * bytes) = 0;
+
+ virtual size_t read (size_t size, char * bytes) = 0;
+
+ virtual int restore_backup () = 0;
+
+ protected:
+
+ virtual void do_remove () = 0;
+
+ /// If a backup file exists, remove it.
+ virtual void remove_backup () = 0;
+
+ bool use_backup_;
+
+ private:
+ Storable_State state_;
+
+ };
+
+ /// Base class for exceptions thrown when encountering
+ /// errors working with persistent files.
+ class TAO_Export Storable_Exception
+ {
+ public:
+ Storable_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name);
+
+ virtual ~Storable_Exception ();
+
+ Storable_Base::Storable_State get_state () const;
+
+ const ACE_CString & get_file_name () const;
+
+ private:
+ TAO::Storable_Base::Storable_State storable_state_;
+ ACE_CString file_name_;
+ };
+
+ /// Exception thrown when an error is encountered
+ /// during reading of the persistent store.
+ class TAO_Export Storable_Read_Exception : public Storable_Exception
+ {
+ public:
+ Storable_Read_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name);
+ };
+
+ /// Exception thrown when an error is encountered
+ /// during writing to the persistent store.
+ class TAO_Export Storable_Write_Exception : public Storable_Exception
+ {
+ public:
+ Storable_Write_Exception (Storable_Base::Storable_State state,
+ const ACE_CString & file_name);
+ };
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "tao/Storable_Base.inl"
+#endif
+
+
+#endif
diff --git a/TAO/tao/Storable_Base.inl b/TAO/tao/Storable_Base.inl
new file mode 100644
index 00000000000..caddbdee3e7
--- /dev/null
+++ b/TAO/tao/Storable_Base.inl
@@ -0,0 +1,74 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Base.inl
+ *
+ * $Id$
+ *
+ * @author Bruce Trask <trask_b@ociweb.com>
+ * @author Chanaka Liyanaarachchi <chanaka@ociweb.com>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "tao/Storable_Base.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_INLINE
+TAO::Storable_Base::Storable_Base (bool use_backup)
+ : use_backup_ (use_backup)
+ , state_ (goodbit)
+{
+}
+
+ACE_INLINE
+TAO::Storable_Base::~Storable_Base ()
+{
+}
+
+ACE_INLINE void
+TAO::Storable_Base::clear (TAO::Storable_Base::Storable_State state)
+{
+ this->state_ = state;
+}
+
+ACE_INLINE void
+TAO::Storable_Base::setstate (TAO::Storable_Base::Storable_State state)
+{
+ this->clear (static_cast <TAO::Storable_Base::Storable_State> (
+ this->rdstate () | state));
+}
+
+ACE_INLINE TAO::Storable_Base::Storable_State
+TAO::Storable_Base::rdstate (void) const
+{
+ return this->state_;
+}
+
+ACE_INLINE bool
+TAO::Storable_Base::good (void) const
+{
+ return (this->state_ == goodbit);
+}
+
+ACE_INLINE bool
+TAO::Storable_Base::bad (void) const
+{
+ return (this->state_ & badbit);
+}
+
+ACE_INLINE bool
+TAO::Storable_Base::eof (void) const
+{
+ return (this->state_ & eofbit);
+}
+
+ACE_INLINE bool
+TAO::Storable_Base::fail (void) const
+{
+ return (this->state_ & failbit);
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Storable_Factory.cpp b/TAO/tao/Storable_Factory.cpp
new file mode 100644
index 00000000000..8850ac57246
--- /dev/null
+++ b/TAO/tao/Storable_Factory.cpp
@@ -0,0 +1,25 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Factory.cpp
+ *
+ * $Id$
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "tao/Storable_Factory.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO::Storable_Factory::Storable_Factory (void)
+{
+}
+
+TAO::Storable_Factory::~Storable_Factory (void)
+{
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Storable_Factory.h b/TAO/tao/Storable_Factory.h
new file mode 100644
index 00000000000..2532c774254
--- /dev/null
+++ b/TAO/tao/Storable_Factory.h
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_Factory.h
+ *
+ * $Id$
+ *
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_STORABLE_FACTORY_H
+#define TAO_STORABLE_FACTORY_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Storable_Base.h"
+
+#include "ace/SString.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ class TAO_Export Storable_Factory
+ {
+ public:
+ Storable_Factory();
+
+ virtual ~Storable_Factory();
+
+ // Factory Methods
+
+ virtual Storable_Base *create_stream(const ACE_CString & file,
+ const ACE_TCHAR * mode,
+ bool use_backup =
+ Storable_Base::use_backup_default) = 0;
+ };
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_STORABLE_FACTORY_H */
diff --git a/TAO/tao/Storable_File_Guard.cpp b/TAO/tao/Storable_File_Guard.cpp
new file mode 100644
index 00000000000..1c20d904df9
--- /dev/null
+++ b/TAO/tao/Storable_File_Guard.cpp
@@ -0,0 +1,266 @@
+//=============================================================================
+/**
+ * @file Storable_File_Guard.cpp
+ *
+ * $Id$
+ *
+ * @author Rich Seibel (seibelr@ociweb.com)
+ * @author Byron Harris (harrisb@ociweb.com)
+ */
+//=============================================================================
+
+#include "tao/Storable_File_Guard.h"
+#include "tao/Storable_Base.h"
+
+#include "tao/SystemException.h"
+
+TAO::Storable_File_Guard::
+Storable_File_Guard (bool redundant, bool use_backup)
+ : redundant_(redundant)
+ , closed_(1)
+ , use_backup_(use_backup)
+{
+}
+
+TAO::Storable_File_Guard::
+~Storable_File_Guard ()
+{
+}
+
+void
+TAO::Storable_File_Guard::init(Method_Type method_type)
+{
+
+ ACE_CString mode;
+
+ // If backup is used then always need to open with
+ // write access since if the file is corrupt then
+ // will overwrite with backup file.
+ if (this->use_backup_)
+ {
+ switch (method_type)
+ {
+ case CREATE_WITH_FILE:
+ mode = "rw";
+ break;
+ case CREATE_WITHOUT_FILE:
+ mode = "rwc";
+ break;
+ case ACCESSOR:
+ mode = "rw";
+ break;
+ case MUTATOR:
+ mode = "rw";
+ break;
+ }
+ }
+ else
+ {
+ switch (method_type)
+ {
+ case CREATE_WITH_FILE:
+ mode = "r";
+ break;
+ case CREATE_WITHOUT_FILE:
+ mode = "wc";
+ break;
+ case ACCESSOR:
+ mode = "r";
+ break;
+ case MUTATOR:
+ mode = "rw";
+ break;
+ }
+ }
+
+ // We only accept a subset of mode argument, check it
+ rwflags_ = 0;
+ for( unsigned int i = 0; i < mode.length (); i++ )
+ {
+ switch (mode[i])
+ {
+ case 'r': rwflags_ |= mode_read;
+ break;
+ case 'w': rwflags_ |= mode_write;
+ break;
+ case 'c': rwflags_ |= mode_create;
+ break;
+ default: rwflags_ = -1;
+ }
+ }
+ if( rwflags_ <= 0 )
+ {
+ errno = EINVAL;
+ throw CORBA::PERSIST_STORE();
+ }
+
+ // Create the stream
+ fl_ = this->create_stream(mode.c_str ());
+ if (redundant_)
+ {
+ if (fl_->open() != 0)
+ {
+ delete fl_;
+ throw CORBA::PERSIST_STORE();
+ }
+
+ // acquire a lock on it
+ if (fl_ -> flock(0, 0, 0) != 0)
+ {
+ fl_->close();
+ delete fl_;
+ throw CORBA::INTERNAL();
+ }
+
+ // now that the file is successfully opened and locked it must be
+ // unlocked/closed before we leave this class
+ closed_ = 0;
+
+ if ( ! (rwflags_ & mode_create) )
+ {
+ // Check if our copy is up to date
+ if (this->object_obsolete ())
+ {
+ this->mark_object_current ();
+ this->load ();
+ }
+ }
+ }
+ else if ( ! this->is_loaded_from_stream () || (rwflags_ & mode_write) )
+ {
+ bool file_has_data = fl_->exists();
+
+ if (fl_->open() != 0)
+ {
+ delete fl_;
+ throw CORBA::PERSIST_STORE();
+ }
+
+ // now that the file is successfully opened
+ // unlocked/closed before we leave this class
+ closed_ = 0;
+
+ if (file_has_data && ! this->is_loaded_from_stream ())
+ {
+ this->load ();
+ }
+ }
+ else
+ {
+ // Need to insure that fl_ gets deleted
+ delete fl_;
+ }
+}
+
+bool
+TAO::Storable_File_Guard::object_obsolete (void)
+{ // Default implementation uses time to determine
+ // if obsolete.
+ return (fl_->last_changed () > this->get_object_last_changed ());
+}
+
+void
+TAO::Storable_File_Guard::mark_object_current (void)
+{ // Default implementation is to set the last changed
+ // time to that of the file lock.
+ this->set_object_last_changed (fl_->last_changed ());
+}
+
+void
+TAO::Storable_File_Guard::release (void)
+{
+ if ( ! closed_ )
+ {
+
+ if (this->use_backup_ )
+ {
+ fl_->create_backup ();
+ }
+
+ // If we updated the disk, save the time stamp
+ if(redundant_)
+ {
+ if( rwflags_ & mode_write )
+ {
+ // This is a costly call, but necessary if
+ // we are running redundant. It ensures that
+ // the data is written to disk.
+ fl_->sync ();
+
+ this->mark_object_current ();
+ }
+
+ // Release the lock
+ fl_->funlock(0, 0, 0);
+ }
+ fl_->close();
+ delete fl_;
+ closed_ = 1;
+ }
+
+}
+
+TAO::Storable_Base &
+TAO::Storable_File_Guard::peer ()
+{
+ return *fl_;
+}
+
+void
+TAO::Storable_File_Guard::load ()
+{
+ if (!this->use_backup_)
+ {
+ this->load_from_stream ();
+ return;
+ }
+
+ try
+ {
+ this->load_from_stream ();
+ }
+ catch (const Storable_Read_Exception &ex)
+ {
+ ACE_CString state_str = Storable_Base::state_as_string (ex.get_state());
+
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: State %s ")
+ ACE_TEXT ("encountered reading persistent ")
+ ACE_TEXT ("state from file\n%s\n"),
+ state_str.c_str (), ex.get_file_name().c_str ()));
+
+ int result = this->fl_->restore_backup ();
+
+ // result of 0 means OK.
+ if (!result)
+ {
+
+ ACE_ERROR ((LM_INFO,
+ ACE_TEXT ("TAO: (%P|%t) Attempting to restore ")
+ ACE_TEXT ("from backup\n")));
+
+ try
+ {
+ this->load_from_stream ();
+ }
+ catch (const Storable_Read_Exception &ex)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: Unable to restore ")
+ ACE_TEXT ("the state from backup.\n")));
+ throw;
+ }
+ ACE_ERROR ((LM_INFO,
+ ACE_TEXT ("TAO: (%P|%t) The state was restored ")
+ ACE_TEXT ("from backup.\n")));
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: Could not read ")
+ ACE_TEXT ("backup file\n")));
+ throw;
+ }
+
+ }
+}
diff --git a/TAO/tao/Storable_File_Guard.h b/TAO/tao/Storable_File_Guard.h
new file mode 100644
index 00000000000..6b4a055be38
--- /dev/null
+++ b/TAO/tao/Storable_File_Guard.h
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_File_Guard.h
+ *
+ * $Id$
+ *
+ * @author Rich Seibel (seibelr@ociweb.com)
+ * @author Byron Harris (harrisb@ociweb.com)
+ */
+//=============================================================================
+
+#ifndef TAO_STORABLE_FILE_GUARD_H
+#define TAO_STORABLE_FILE_GUARD_H
+
+#include "tao/Storable_Base.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ /**
+ * @class Storable_File_Guard
+ * @brief Base class to use with TAO_Storable_Base to synch object state
+ * with a storable base.
+ *
+ * A guard for Storable_Base that opens a file
+ * for read/write and sets a lock on it. It then checks if the file has
+ * changed and re-reads it if it has.
+ *
+ */
+ class TAO_Export Storable_File_Guard
+ {
+ public:
+
+ Storable_File_Guard (bool redundant,
+ bool use_backup = Storable_Base::use_backup_default);
+
+ virtual ~Storable_File_Guard ();
+
+ /// Releases the lock, closes the file, and deletes the I/O stream.
+ /// Destructors of derived classes should call this this will
+ /// virtual functions are available.
+ void release (void);
+
+ /// Return when the object in memory has last changed
+ virtual time_t get_object_last_changed () = 0;
+
+ /// Get the underlying stream being used.
+ TAO::Storable_Base & peer ();
+
+ /// Indicate how the state of the object is being used.
+ /// This is used for determine the mode for accessing
+ /// the persistent store.
+ enum Method_Type
+ {
+
+ /// Construction with persistent file already existing
+ CREATE_WITH_FILE,
+
+ /// Construction with persistent file not existing
+ CREATE_WITHOUT_FILE,
+
+ /// Getting object state
+ ACCESSOR,
+
+ /// Setting object state
+ MUTATOR
+ };
+
+ protected:
+
+ /// Should be called by constructors of derived classes
+ /// since can't call the virtual functions below in constructor
+ /// of this class.
+ void init (Method_Type method_type);
+
+ /// Check if the object is current with the last update.
+ virtual bool object_obsolete (void);
+
+ /// Mark the object as up to date
+ virtual void mark_object_current (void);
+
+ /// Indicate when the object in memory has last changed
+ virtual void set_object_last_changed (const time_t & time) = 0;
+
+ /// Load object from file to memory
+ virtual void load_from_stream () = 0;
+
+ /// Answer if object has been loaded from file
+ virtual bool is_loaded_from_stream () = 0;
+
+ virtual Storable_Base * create_stream (const char * mode) = 0;
+
+ /// The pointer to the actual file I/O (bridge pattern)
+ Storable_Base *fl_;
+
+ private:
+
+ void load ();
+
+ bool redundant_;
+
+ /// A flag to keep us from trying to close things more than once.
+ int closed_;
+
+ /// The flags that we were opened with
+ int rwflags_;
+
+ /// A flag indicating if backup/restore should be performed
+ bool use_backup_;
+
+ /// Symbolic values for the flags in the above
+ enum { mode_write = 1, mode_read = 2, mode_create = 4 };
+
+ };
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif
diff --git a/TAO/tao/Storable_FlatFileStream.cpp b/TAO/tao/Storable_FlatFileStream.cpp
new file mode 100644
index 00000000000..3a5977c9dd8
--- /dev/null
+++ b/TAO/tao/Storable_FlatFileStream.cpp
@@ -0,0 +1,475 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_FlatFileStream.cpp
+ *
+ * $Id$
+ *
+ * @author Marina Spivak <marina@cs.wustl.edu>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#include "tao/Storable_FlatFileStream.h"
+
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_fcntl.h"
+#include "ace/OS_NS_sys_stat.h"
+#include "ace/Numeric_Limits.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace
+{
+ /// Avoids using fscanf to read an integer as any
+ /// whitespace following the newline will be
+ /// consumed. This could create problems if
+ /// the data that follows the newline is binary.
+ template<typename T>
+ void read_integer(const char * format, T & i,
+ TAO::Storable_Base::Storable_State & state,
+ FILE * fl)
+ {
+ char buf[BUFSIZ];
+ char * result = fgets (buf, BUFSIZ, fl);
+
+ if (result == 0)
+ {
+ if (feof (fl))
+ {
+ state = TAO::Storable_Base::eofbit;
+ return;
+ }
+ state = TAO::Storable_Base::badbit;
+ return;
+ }
+
+ /// Consume any starting newline, as fscanf would
+ /// do.
+ if (buf[0] == '\n')
+ {
+ result = fgets (buf, BUFSIZ, fl);
+ }
+
+ if (result == 0)
+ {
+ if (feof (fl))
+ {
+ state = TAO::Storable_Base::eofbit;
+ return;
+ }
+ state = TAO::Storable_Base::badbit;
+ return;
+ }
+
+ switch (sscanf (buf, format, &i))
+ {
+ case 0:
+ state = TAO::Storable_Base::badbit;
+ return;
+ case EOF:
+ state = TAO::Storable_Base::eofbit;
+ return;
+ }
+ }
+
+ int file_copy(FILE *f1, FILE *f2)
+ {
+ char buffer[BUFSIZ];
+ size_t n_read;
+
+ bool all_read = false;
+ bool some_read = false;
+
+ while (!all_read)
+ {
+ n_read =
+ ACE_OS::fread(buffer, 1, sizeof(buffer), f1);
+ if (n_read > 0)
+ {
+ if (ACE_OS::fwrite(buffer, 1, n_read, f2) != n_read)
+ return -1;
+ some_read = true;
+ }
+ else if (!some_read)
+ {
+ // Nothing was read
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: could not read from file\n")));
+
+ if (ferror (f1))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%p\n",
+ "fread error"));
+ }
+ return -1;
+ }
+ else
+ {
+ all_read = true;
+ }
+ }
+
+ return 0;
+ }
+
+}
+
+TAO::Storable_FlatFileStream::Storable_FlatFileStream (const ACE_CString & file,
+ const char * mode,
+ bool use_backup)
+ : Storable_Base(use_backup)
+ , fl_ (0)
+{
+ file_ = file;
+ mode_ = mode;
+}
+
+TAO::Storable_FlatFileStream::~Storable_FlatFileStream ()
+{
+ if ( fl_ != 0 )
+ this->close();
+}
+
+void
+TAO::Storable_FlatFileStream::do_remove ()
+{
+ ACE_OS::unlink(ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()));
+}
+
+int
+TAO::Storable_FlatFileStream::exists ()
+{
+ // We could check the mode for this file, but for now just check exists
+ return ! ACE_OS::access(file_.c_str(), F_OK);
+}
+
+int
+TAO::Storable_FlatFileStream::open()
+{
+ // For now, three flags exist "r", "w", and "c"
+ int flags = 0;
+ const char *fdmode = 0;
+ if( ACE_OS::strchr(mode_.c_str(), 'r') )
+ if( ACE_OS::strchr(mode_.c_str(), 'w') )
+ flags = O_RDWR, fdmode = "w+";
+ else
+ flags = O_RDONLY, fdmode = "r";
+ else
+ flags = O_WRONLY, fdmode = "w";
+ if( ACE_OS::strchr(mode_.c_str(), 'c') )
+ flags |= O_CREAT;
+#ifndef ACE_WIN32
+ if( ACE_OS::flock_init (&filelock_, flags, ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()), 0666) != 0 )
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open file %s for mode %s: (%d) %s\n",
+ file_.c_str(), mode_.c_str(),
+ errno, ACE_OS::strerror(errno)),
+ -1);
+#else
+ if( (filelock_.handle_= ACE_OS::open (ACE_TEXT_CHAR_TO_TCHAR(file_.c_str()), flags, 0)) == ACE_INVALID_HANDLE )
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open file %s for mode %s: (%d) %s\n",
+ file_.c_str(), mode_.c_str(),
+ ACE_ERRNO_GET, ACE_OS::strerror(ACE_ERRNO_GET)),
+ -1);
+#endif
+ this->fl_ = ACE_OS::fdopen(filelock_.handle_, ACE_TEXT_CHAR_TO_TCHAR(fdmode));
+ if (this->fl_ == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot fdopen file %s for mode %s: (%d) %s\n",
+ file_.c_str(), mode_.c_str(),
+ ACE_ERRNO_GET, ACE_OS::strerror(ACE_ERRNO_GET)),
+ -1);
+ return 0;
+}
+
+int
+TAO::Storable_FlatFileStream::close()
+{
+ ACE_OS::fflush(fl_);
+#ifndef ACE_WIN32
+ ACE_OS::flock_destroy (&filelock_, 0);
+#endif
+ ACE_OS::fclose (fl_); // even though flock_destroy closes the handle
+ // we still need to destroy the FILE*
+
+ fl_ = 0;
+ return 0;
+}
+
+int
+TAO::Storable_FlatFileStream::flock (int whence, int start, int len)
+{
+#if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+#else
+ if( ACE_OS::strcmp(mode_.c_str(), "r") == 0 )
+ ACE_OS::flock_rdlock(&filelock_, whence, start, len);
+ else
+ ACE_OS::flock_wrlock(&filelock_, whence, start, len);
+#endif
+ return 0;
+}
+
+int
+TAO::Storable_FlatFileStream::funlock (int whence, int start, int len)
+{
+#if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+#else
+ ACE_OS::flock_unlock(&filelock_, whence, start, len);
+#endif
+ return 0;
+}
+
+time_t
+TAO::Storable_FlatFileStream::last_changed(void)
+{
+ ACE_stat st;
+ ACE_OS::fstat(filelock_.handle_, &st);
+ return st.st_mtime;
+}
+
+void
+TAO::Storable_FlatFileStream::rewind (void)
+{
+ return ACE_OS::rewind(this->fl_);
+}
+
+bool
+TAO::Storable_FlatFileStream::flush (void)
+{
+ return ACE_OS::fflush(this->fl_);
+}
+
+int
+TAO::Storable_FlatFileStream::sync (void)
+{
+ return ACE_OS::fsync (this->filelock_.handle_);
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator << (const ACE_CString& str)
+{
+ int n =
+ ACE_OS::fprintf(this->fl_, ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT("\n%s\n"),
+ str.length(), str.c_str());
+ if (n < 0)
+ this->throw_on_write_error (badbit);
+
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator >> (ACE_CString& str)
+{
+ int bufSize = 0;
+ ACE_CString::size_type const max_buf_len =
+ ACE_Numeric_Limits<ACE_CString::size_type>::max ();
+ switch (fscanf(fl_, "%d\n", &bufSize))
+ {
+ case 0:
+ this->throw_on_read_error (badbit);
+ case EOF:
+ this->throw_on_read_error (eofbit);
+ }
+
+ if (bufSize < 0
+ || static_cast<ACE_CString::size_type> (bufSize) >= max_buf_len)
+ {
+ this->throw_on_read_error (badbit);
+ }
+ {
+ ACE_Auto_Basic_Array_Ptr<char> str_array (new char[bufSize + 1]);
+ str_array[0] = '\0';
+ if (ACE_OS::fgets (ACE_TEXT_CHAR_TO_TCHAR (str_array.get ()),
+ bufSize + 1,
+ this->fl_) == 0
+ && bufSize != 0)
+ {
+ this->throw_on_read_error (badbit);
+ }
+ str = ACE_CString (str_array.get (), 0, false);
+ }
+
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator << (int i)
+{
+ int n = ACE_OS::fprintf (this->fl_, "%d\n", i);
+ if (n < 0)
+ this->throw_on_write_error (badbit);
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator >> (int &i)
+{
+ Storable_State state = this->rdstate ();
+ read_integer ("%d\n", i, state, fl_);
+ this->throw_on_read_error (state);
+
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator << (unsigned int i)
+{
+ int n = ACE_OS::fprintf (this->fl_, "%u\n", i);
+ if (n < 0)
+ this->throw_on_write_error (badbit);
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator >> (unsigned int &i)
+{
+ Storable_State state = this->rdstate ();
+ read_integer ("%u\n", i, state, fl_);
+ this->throw_on_read_error (state);
+
+ return *this;
+}
+
+TAO::Storable_Base &
+TAO::Storable_FlatFileStream::operator << (const TAO_OutputCDR & cdr)
+{
+ unsigned int length = cdr.total_length ();
+ *this << length;
+ for (const ACE_Message_Block *i = cdr.begin (); i != 0; i = i->cont ())
+ {
+ const char *bytes = i->rd_ptr ();
+ size_t len = i->length ();
+ this->write (len, bytes);
+ }
+ return *this;
+}
+
+size_t
+TAO::Storable_FlatFileStream::write (size_t size, const char * bytes)
+{
+ return ACE_OS::fwrite (bytes, size, 1, fl_);
+}
+
+size_t
+TAO::Storable_FlatFileStream::read (size_t size, char * bytes)
+{
+ return ACE_OS::fread (bytes, size, 1, fl_);
+}
+
+ACE_CString
+TAO::Storable_FlatFileStream::backup_file_name ()
+{
+ return file_ + ".bak";
+}
+
+int
+TAO::Storable_FlatFileStream::create_backup ()
+{
+ FILE * backup = ACE_OS::fopen (this->backup_file_name ().c_str (), "w");
+ this->rewind();
+ int result = file_copy(this->fl_, backup);
+ if (result != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO: (%P|%t) ERROR: Unable to create backup ")
+ ACE_TEXT ("of file\n%s\n"), file_.c_str ()));
+ }
+ ACE_OS::fclose (backup);
+ return result;
+}
+
+void
+TAO::Storable_FlatFileStream::remove_backup ()
+{
+ ACE_CString backup_name = this->backup_file_name ();
+
+ if (ACE_OS::access (ACE_TEXT_CHAR_TO_TCHAR (backup_name.c_str ()), F_OK) == 0)
+ {
+ ACE_OS::unlink (ACE_TEXT_CHAR_TO_TCHAR (backup_name.c_str ()));
+ }
+}
+
+int
+TAO::Storable_FlatFileStream::restore_backup ()
+{
+ ACE_CString backup_name = this->backup_file_name ().c_str ();
+
+ if (ACE_OS::access (ACE_TEXT_CHAR_TO_TCHAR (backup_name.c_str ()), F_OK))
+ return -1;
+
+ FILE * backup = ACE_OS::fopen (ACE_TEXT_CHAR_TO_TCHAR (backup_name.c_str ()),
+ "r");
+ this->rewind();
+ int result = file_copy(backup, this->fl_);
+ ACE_OS::fclose (backup);
+ this->flush ();
+ this->clear ();
+ return result;
+}
+
+void
+TAO::Storable_FlatFileStream::throw_on_read_error (Storable_State state)
+ throw (Storable_Read_Exception)
+{
+ this->setstate (state);
+
+ if (!this->good ())
+ {
+ throw Storable_Read_Exception (this->rdstate (), this->file_);
+ }
+}
+
+void
+TAO::Storable_FlatFileStream::throw_on_write_error (Storable_State state)
+ throw (Storable_Write_Exception)
+{
+ this->setstate (state);
+
+ if (!this->good ())
+ {
+ throw Storable_Write_Exception (this->rdstate (), this->file_);
+ }
+}
+
+TAO::Storable_FlatFileFactory::Storable_FlatFileFactory(const ACE_CString & directory)
+ : Storable_Factory ()
+ , directory_(directory)
+{
+}
+
+TAO::Storable_FlatFileFactory::~Storable_FlatFileFactory()
+{
+}
+
+const ACE_CString &
+TAO::Storable_FlatFileFactory::get_directory () const
+{
+ return directory_;
+}
+
+TAO::Storable_Base *
+TAO::Storable_FlatFileFactory::create_stream (const ACE_CString & file,
+ const ACE_TCHAR * mode,
+ bool use_backup)
+{
+ TAO::Storable_Base *stream = 0;
+ ACE_CString path = this->directory_ + "/" + file;
+ ACE_NEW_RETURN (stream,
+ TAO::Storable_FlatFileStream(path,
+ ACE_TEXT_ALWAYS_CHAR (mode),
+ use_backup),
+ 0);
+ return stream;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Storable_FlatFileStream.h b/TAO/tao/Storable_FlatFileStream.h
new file mode 100644
index 00000000000..10e5a9e4425
--- /dev/null
+++ b/TAO/tao/Storable_FlatFileStream.h
@@ -0,0 +1,145 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Storable_FlatFileStream.h
+ *
+ * $Id$
+ *
+ * @author Marina Spivak <marina@cs.wustl.edu>
+ * @author Byron Harris <harrisb@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef STORABLE_FLATFILESTREAM_H
+#define STORABLE_FLATFILESTREAM_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Storable_Base.h"
+#include "tao/Storable_Factory.h"
+#include "ace/OS_NS_stdio.h"
+
+namespace TAO
+{
+
+ /**
+ * @brief A Storable_Base derived class that works with a file stream.
+ *
+ */
+ class TAO_Export Storable_FlatFileStream : public Storable_Base
+ {
+ public:
+
+ Storable_FlatFileStream(const ACE_CString & file, const char * mode,
+ bool use_backup =
+ Storable_Base::use_backup_default);
+
+ virtual ~Storable_FlatFileStream();
+
+ /// Check if a file exists on disk (file is not open)
+ virtual int exists ();
+
+ /// Open a file (the remaining methods below all require an open file)
+ virtual int open ();
+
+ /// Acquire a file lock
+ virtual int close ();
+
+ /// Acquire a file lock
+ virtual int flock (int whence, int start, int len);
+
+ /// Release a file lock
+ virtual int funlock (int whence, int start, int len);
+
+ /// Returns the last time an open file was changed
+ virtual time_t last_changed (void);
+
+ virtual void rewind (void);
+
+ virtual bool flush (void);
+
+ /// Force write of storable data to storage.
+ /// Returns 0 on success, otherwise EOF
+ virtual int sync (void);
+
+ virtual Storable_Base& operator << (const ACE_CString& str);
+
+ virtual Storable_Base& operator >> (ACE_CString& str);
+
+ virtual Storable_Base& operator << (int i);
+
+ virtual Storable_Base& operator >> (int &i);
+
+ virtual Storable_Base& operator << (unsigned int i);
+
+ virtual Storable_Base& operator >> (unsigned int &i);
+
+ virtual Storable_Base& operator << (const TAO_OutputCDR & cdr);
+
+ virtual size_t write (size_t size, const char * bytes);
+
+ virtual size_t read (size_t size, char * bytes);
+
+ virtual int restore_backup ();
+
+ protected:
+
+ virtual void do_remove ();
+
+ virtual void remove_backup ();
+
+ virtual int create_backup ();
+
+ private:
+
+ /// Throw a Storable_Read_Exception if the state
+ /// is not good due to a read error.
+ void throw_on_read_error (Storable_State state)
+ throw (Storable_Read_Exception);
+
+ /// Throw a Storable_Write_Exception if the state
+ /// is not good due to a write error.
+ void throw_on_write_error (Storable_State state)
+ throw (Storable_Write_Exception);
+
+ ACE_CString backup_file_name ();
+
+ ACE_OS::ace_flock_t filelock_;
+ FILE* fl_;
+ ACE_CString file_;
+ ACE_CString mode_;
+ };
+
+ class TAO_Export Storable_FlatFileFactory : public Storable_Factory
+ {
+ public:
+
+ /// @param directory Directory to contain file passed in
+ /// create_stream (). The directory is assumed to already exist.
+ Storable_FlatFileFactory(const ACE_CString & directory);
+
+ const ACE_CString & get_directory () const;
+
+ ~Storable_FlatFileFactory ();
+
+ // Factory Methods
+
+ /// Create the stream that can operate on a disk file
+ virtual Storable_Base *create_stream (const ACE_CString & file,
+ const ACE_TCHAR * mode,
+ bool use_backup =
+ Storable_Base::use_backup_default);
+ private:
+ ACE_CString directory_;
+
+ };
+}
+
+#include /**/ "ace/post.h"
+
+#endif /* STORABLE_FLATFILESTREAM_H */
diff --git a/TAO/tao/Strategies/COIOP_Profile.cpp b/TAO/tao/Strategies/COIOP_Profile.cpp
index ece1da6e39c..b2c075c2426 100644
--- a/TAO/tao/Strategies/COIOP_Profile.cpp
+++ b/TAO/tao/Strategies/COIOP_Profile.cpp
@@ -203,7 +203,7 @@ TAO_COIOP_Profile::add_endpoint (TAO_COIOP_Endpoint *endp)
}
char *
-TAO_COIOP_Profile::to_string (void)
+TAO_COIOP_Profile::to_string (void) const
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
diff --git a/TAO/tao/Strategies/COIOP_Profile.h b/TAO/tao/Strategies/COIOP_Profile.h
index 075a2ccdbe5..ded0bf29f4d 100644
--- a/TAO/tao/Strategies/COIOP_Profile.h
+++ b/TAO/tao/Strategies/COIOP_Profile.h
@@ -65,7 +65,7 @@ public:
~TAO_COIOP_Profile (void);
/// Template methods. Please tao/Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Strategies/DIOP_Profile.cpp b/TAO/tao/Strategies/DIOP_Profile.cpp
index b8b69911bab..2f5fc3c19b1 100644
--- a/TAO/tao/Strategies/DIOP_Profile.cpp
+++ b/TAO/tao/Strategies/DIOP_Profile.cpp
@@ -363,7 +363,7 @@ TAO_DIOP_Profile::add_endpoint (TAO_DIOP_Endpoint *endp)
}
char *
-TAO_DIOP_Profile::to_string (void)
+TAO_DIOP_Profile::to_string (void) const
{
// corbaloc:diop:1.2@host:port,diop:1.2@host:port,.../key
diff --git a/TAO/tao/Strategies/DIOP_Profile.h b/TAO/tao/Strategies/DIOP_Profile.h
index f2db5d68c01..5b4725c0418 100644
--- a/TAO/tao/Strategies/DIOP_Profile.h
+++ b/TAO/tao/Strategies/DIOP_Profile.h
@@ -77,7 +77,7 @@ public:
/// Template methods. Please tao/Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Strategies/SCIOP_Profile.cpp b/TAO/tao/Strategies/SCIOP_Profile.cpp
index 175fbe7bfd9..83899b63a7e 100644
--- a/TAO/tao/Strategies/SCIOP_Profile.cpp
+++ b/TAO/tao/Strategies/SCIOP_Profile.cpp
@@ -310,7 +310,7 @@ TAO_SCIOP_Profile::add_endpoint (TAO_SCIOP_Endpoint *endp)
}
char *
-TAO_SCIOP_Profile::to_string (void)
+TAO_SCIOP_Profile::to_string (void) const
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
diff --git a/TAO/tao/Strategies/SCIOP_Profile.h b/TAO/tao/Strategies/SCIOP_Profile.h
index 4aca872c3d7..264edc4cf57 100644
--- a/TAO/tao/Strategies/SCIOP_Profile.h
+++ b/TAO/tao/Strategies/SCIOP_Profile.h
@@ -73,7 +73,7 @@ public:
~TAO_SCIOP_Profile (void);
/// Template methods. Please see Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Strategies/SHMIOP_Profile.cpp b/TAO/tao/Strategies/SHMIOP_Profile.cpp
index 23f7c52818e..e13b03ac3c3 100644
--- a/TAO/tao/Strategies/SHMIOP_Profile.cpp
+++ b/TAO/tao/Strategies/SHMIOP_Profile.cpp
@@ -325,7 +325,7 @@ TAO_SHMIOP_Profile::add_endpoint (TAO_SHMIOP_Endpoint *endp)
}
char *
-TAO_SHMIOP_Profile::to_string (void)
+TAO_SHMIOP_Profile::to_string (void) const
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
diff --git a/TAO/tao/Strategies/SHMIOP_Profile.h b/TAO/tao/Strategies/SHMIOP_Profile.h
index 7d103435dc2..49689fb03bb 100644
--- a/TAO/tao/Strategies/SHMIOP_Profile.h
+++ b/TAO/tao/Strategies/SHMIOP_Profile.h
@@ -76,7 +76,7 @@ public:
/// Template methods, please see Profile.h for documentation.
- virtual char * to_string (void);
+ virtual char * to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Strategies/UIOP_Profile.cpp b/TAO/tao/Strategies/UIOP_Profile.cpp
index 8cf254c9d6b..e74fcd28d0b 100644
--- a/TAO/tao/Strategies/UIOP_Profile.cpp
+++ b/TAO/tao/Strategies/UIOP_Profile.cpp
@@ -239,7 +239,7 @@ TAO_UIOP_Profile::add_endpoint (TAO_UIOP_Endpoint *endp)
char *
-TAO_UIOP_Profile::to_string (void)
+TAO_UIOP_Profile::to_string (void) const
{
CORBA::String_var key;
TAO::ObjectKey::encode_sequence_to_string (key.inout(),
diff --git a/TAO/tao/Strategies/UIOP_Profile.h b/TAO/tao/Strategies/UIOP_Profile.h
index 8870fcec6e5..eb4b146989d 100644
--- a/TAO/tao/Strategies/UIOP_Profile.h
+++ b/TAO/tao/Strategies/UIOP_Profile.h
@@ -75,7 +75,7 @@ public:
~TAO_UIOP_Profile (void);
/// Template methods. Please see Profile.h for documentation.
- virtual char *to_string (void);
+ virtual char *to_string (void) const;
virtual int encode_endpoints (void);
virtual TAO_Endpoint *endpoint (void);
virtual CORBA::ULong endpoint_count (void) const;
diff --git a/TAO/tao/Stub.cpp b/TAO/tao/Stub.cpp
index 0703795d5d4..b6bdbeaea36 100644
--- a/TAO/tao/Stub.cpp
+++ b/TAO/tao/Stub.cpp
@@ -116,6 +116,13 @@ TAO_Stub::add_forward_profiles (const TAO_MProfile &mprofiles,
ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX,
guard,
this->profile_lock_));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::add_forward_profiles, ")
+ ACE_TEXT ("acquired profile lock this = 0x%x\n"),
+ this));
+ }
if (permanent_forward)
{
@@ -133,8 +140,10 @@ TAO_Stub::add_forward_profiles (const TAO_MProfile &mprofiles,
TAO_MProfile (mprofiles));
if (permanent_forward)
- // bookmark the new element at bottom of stack
- this->forward_profiles_perm_ = this->forward_profiles_;
+ {
+ // bookmark the new element at bottom of stack
+ this->forward_profiles_perm_ = this->forward_profiles_;
+ }
// forwarded profile points to the new IOR (profiles)
this->profile_in_use_->forward_to (this->forward_profiles_);
@@ -159,6 +168,14 @@ TAO_Stub::create_ior_info (IOP::IOR *&ior_info, CORBA::ULong &index)
guard,
this->profile_lock_,
-1));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::create_ior_info, acquired ")
+ ACE_TEXT ("profile lock this = 0x%x\n"),
+ this));
+ }
+
IOP::IOR *tmp_info = 0;
@@ -223,7 +240,8 @@ TAO_Stub::object_key (void) const
{
// Double-checked
// FUZZ: disable check_for_ACE_Guard
- ACE_Guard<TAO_SYNCH_MUTEX> obj (const_cast <TAO_SYNCH_MUTEX&>(this->profile_lock_));
+ ACE_Guard<TAO_SYNCH_MUTEX> obj (
+ const_cast <TAO_SYNCH_MUTEX&>(this->profile_lock_));
// FUZZ: enable check_for_ACE_Guard
if (obj.locked () != 0 && this->forward_profiles_ != 0)
@@ -520,6 +538,14 @@ TAO_Stub::marshal (TAO_OutputCDR &cdr)
guard,
this->profile_lock_,
0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::marshal, acquired ")
+ ACE_TEXT ("profile lock this = 0x%x\n"),
+ this));
+ }
+
ACE_ASSERT(this->forward_profiles_ !=0);
diff --git a/TAO/tao/Stub.h b/TAO/tao/Stub.h
index 789bc8e2e9b..a654e3931de 100644
--- a/TAO/tao/Stub.h
+++ b/TAO/tao/Stub.h
@@ -165,6 +165,11 @@ public:
*/
void reset_profiles (void);
+ /// Returns true if the profile in use is
+ /// the same as the profile in use after
+ /// reset_profiles() is called.
+ CORBA::Boolean at_starting_profile (void) const;
+
/// Returns true if a forward profile has successfully been used.
/// profile_success_ && forward_profiles_
CORBA::Boolean valid_forward_profile (void);
@@ -406,6 +411,7 @@ protected:
/// True if forwarding request upon some specific exceptions
/// (e.g. OBJECT_NOT_EXIST) already happened.
ACE_Atomic_Op<TAO_SYNCH_MUTEX, bool> forwarded_on_exception_;
+
};
// Define a TAO_Stub auto_ptr class.
diff --git a/TAO/tao/Stub.inl b/TAO/tao/Stub.inl
index d4b0ae3d8c7..714d1d736b2 100644
--- a/TAO/tao/Stub.inl
+++ b/TAO/tao/Stub.inl
@@ -3,6 +3,7 @@
// $Id$
#include "tao/ORB_Core.h"
+#include "ace/Reverse_Lock_T.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -56,6 +57,14 @@ TAO_Stub::reset_profiles (void)
ACE_MT (ACE_GUARD (TAO_SYNCH_MUTEX,
guard,
this->profile_lock_));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::reset_profiles, acquired ")
+ ACE_TEXT ("profile lock this = 0x%x\n"),
+ this));
+ }
+
this->reset_profiles_i ();
}
@@ -137,9 +146,30 @@ TAO_Stub::next_profile_i (void)
pfile_next = this->base_profiles_.get_next ();
}
- // We may have been forwarded to / from a collocated situation
- // Check for this and apply / remove optimisation if required.
- this->orb_core_->reinitialize_object (this);
+ {
+ typedef ACE_Reverse_Lock<ACE_MT_SYNCH::MUTEX> TAO_REVERSE_LOCK;
+ TAO_REVERSE_LOCK reverse (this->profile_lock_);
+ ACE_MT (ACE_GUARD_RETURN (TAO_REVERSE_LOCK, ace_mon, reverse, 0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::next_profile_i, ")
+ ACE_TEXT ("released profile lock to reinitialize ")
+ ACE_TEXT ("this = 0x%x\n"),
+ this));
+ }
+ // We may have been forwarded to / from a collocated situation
+ // Check for this and apply / remove optimisation if required.
+ this->orb_core_->reinitialize_object (this);
+ }
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::next_profile_i, ")
+ ACE_TEXT ("reacquired profile lock on object ")
+ ACE_TEXT ("this = 0x%x\n"),
+ this));
+ }
}
else
pfile_next = this->base_profiles_.get_next ();
@@ -160,6 +190,11 @@ TAO_Stub::next_profile (void)
guard,
this->profile_lock_,
0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::next_profile, acquired profile lock this = 0x%x\n"), this));
+ }
return this->next_profile_i ();
}
@@ -188,6 +223,12 @@ TAO_Stub::base_profiles (const TAO_MProfile &mprofiles)
guard,
this->profile_lock_,
0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::base_profiles, acquired profile lock this = 0x%x\n"), this));
+ }
+
// first reset things so we start from scratch!
@@ -208,6 +249,11 @@ TAO_Stub::next_profile_retry (void)
guard,
this->profile_lock_,
0));
+ if (TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Stub::next_profile_retry, acquired profile lock this = 0x%x\n"), this));
+ }
if (this->profile_success_ && this->forward_profiles_)
{
@@ -362,6 +408,13 @@ TAO_Stub::_decr_refcnt (void)
delete this;
}
+ACE_INLINE
+CORBA::Boolean
+TAO_Stub::at_starting_profile (void) const
+{
+ return profile_in_use_ == base_profiles_.get_profile(0);
+}
+
// ---------------------------------------------------------------
// Creator methods for TAO_Stub_Auto_Ptr (TAO_Stub Auto Pointer)
diff --git a/TAO/tao/Synch_Invocation.cpp b/TAO/tao/Synch_Invocation.cpp
index 40064362ca6..71ef977e300 100644
--- a/TAO/tao/Synch_Invocation.cpp
+++ b/TAO/tao/Synch_Invocation.cpp
@@ -1,6 +1,7 @@
// $Id$
#include "tao/Synch_Invocation.h"
+#include "tao/Invocation_Retry_State.h"
#include "tao/Profile_Transport_Resolver.h"
#include "tao/Profile.h"
#include "tao/Synch_Reply_Dispatcher.h"
@@ -42,9 +43,16 @@ namespace TAO
resolver,
detail,
response_expected)
+ , retry_state_ (0)
{
}
+ void
+ Synch_Twoway_Invocation::set_retry_state (Invocation_Retry_State *retry_state)
+ {
+ this->retry_state_ = retry_state;
+ }
+
Invocation_Status
Synch_Twoway_Invocation::remote_twoway (ACE_Time_Value *max_wait_time)
{
@@ -79,10 +87,25 @@ namespace TAO
if (!transport)
{
- // Way back, we failed to find a profile we could connect to.
- // We've come this far only so we reach the interception points
- // in case they can fix things. Time to bail....
- throw CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
+ if (this->retry_state_ &&
+ this->retry_state_->forward_on_exception_increment(FOE_TRANSIENT))
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("remote_twoway retrying on TRANSIENT ")
+ ACE_TEXT ("exception\n")));
+ this->retry_state_->next_profile_retry (*this->stub ());
+ return TAO_INVOKE_RESTART;
+ }
+ else
+ {
+ // Way back, we failed to find a profile we could connect to.
+ // We've come this far only so we reach the interception points
+ // in case they can fix things. Time to bail....
+ throw CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
+ }
+
}
ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon,
@@ -259,8 +282,8 @@ namespace TAO
if (TAO_debug_level > 0 && max_wait_time)
{
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply, "
- "timeout after recv is <%u> status <%d>\n",
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply, ")
+ ACE_TEXT ("timeout after recv is <%u> status <%d>\n"),
max_wait_time->msec (),
reply_error));
}
@@ -273,8 +296,9 @@ namespace TAO
if (TAO_debug_level > 3)
{
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply, "
- "recovering after an error\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("wait_for_reply, ")
+ ACE_TEXT ("recovering after an error\n")));
}
// You the smarty, don't try to moving the unbind_dispatcher
@@ -312,6 +336,19 @@ namespace TAO
(void) bd.unbind_dispatcher ();
this->resolver_.transport ()->close_connection ();
+ if (this->retry_state_ &&
+ this->resolver_.transport ()->connection_closed_on_read() &&
+ this->retry_state_->forward_on_reply_closed_increment ())
+ {
+ if (TAO_debug_level > 4)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("wait_for_reply, forward profile on ")
+ ACE_TEXT ("connection closed\n")));
+ this->retry_state_->next_profile_retry (*this->stub ());
+ return TAO_INVOKE_RESTART;
+ }
+
try
{
return
@@ -322,7 +359,11 @@ namespace TAO
}
catch (const ::CORBA::Exception&)
{
- this->resolver_.stub ()->reset_profiles ();
+ if (this->retry_state_ == 0 ||
+ !this->retry_state_->forward_on_exception_limit_used ())
+ {
+ this->resolver_.stub ()->reset_profiles ();
+ }
throw;
}
}
@@ -386,8 +427,9 @@ namespace TAO
// permanent condition not given
if (TAO_debug_level > 3)
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::"
- "check_reply_status: unexpected LOCATION_FORWARD_PERM reply\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("check_reply_status: unexpected ")
+ ACE_TEXT ("LOCATION_FORWARD_PERM reply\n")));
throw ::CORBA::INTERNAL (0, CORBA::COMPLETED_NO);
}
@@ -439,8 +481,8 @@ namespace TAO
if (TAO_debug_level > 3)
{
ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::location_forward ")
- ACE_TEXT ("being handled\n")));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("location_forward being handled\n")));
}
CORBA::Object_var fwd;
@@ -469,8 +511,8 @@ namespace TAO
if (TAO_debug_level > 3)
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::"
- "handle_user_exception\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("handle_user_exception\n")));
// Pull the exception from the stream.
CORBA::String_var buf;
@@ -513,8 +555,8 @@ namespace TAO
if (TAO_debug_level > 3)
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::"
- "handle_system_exception\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("handle_system_exception\n")));
CORBA::String_var type_id;
@@ -533,40 +575,80 @@ namespace TAO
throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
}
+ bool retry_on_exception = false;
bool do_forward = false;
- int foe_kind = this->stub ()->orb_core ()->orb_params ()->forward_once_exception();
-
- if ((CORBA::CompletionStatus) completion != CORBA::COMPLETED_YES
- && (((foe_kind & TAO::FOE_TRANSIENT) == 0
- && ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0) ||
- ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/OBJ_ADAPTER:1.0") == 0 ||
- ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/NO_RESPONSE:1.0") == 0 ||
- ((foe_kind & TAO::FOE_COMM_FAILURE) == 0
- && ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0) ||
- (this->stub ()->orb_core ()->orb_params ()->forward_invocation_on_object_not_exist ()
- && ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0) ||
- (do_forward = ! this->stub ()->forwarded_on_exception ()
- && ((((foe_kind & TAO::FOE_OBJECT_NOT_EXIST) == TAO::FOE_OBJECT_NOT_EXIST)
- && (ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0)) ||
- (((foe_kind & TAO::FOE_COMM_FAILURE) == TAO::FOE_COMM_FAILURE)
- && (ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0)) ||
- (((foe_kind & TAO::FOE_TRANSIENT) == TAO::FOE_TRANSIENT)
- && (ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0)) ||
- (((foe_kind & TAO::FOE_INV_OBJREF) == TAO::FOE_INV_OBJREF)
- && (ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/INV_OBJREF:1.0") == 0))))))
+
+ const TAO_ORB_Parameters *orb_params = this->stub ()->orb_core ()->orb_params ();
+
+ if (this->retry_state_ &&
+ this->retry_state_->forward_on_exception_limit_used () &&
+ (CORBA::CompletionStatus) completion == CORBA::COMPLETED_NO)
+ {
+ if ((ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0 &&
+ this->retry_state_->forward_on_exception_increment (TAO::FOE_TRANSIENT)) ||
+ (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0 &&
+ this->retry_state_->forward_on_exception_increment (TAO::FOE_COMM_FAILURE)) ||
+ (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0 &&
+ this->retry_state_->forward_on_exception_increment (TAO::FOE_OBJECT_NOT_EXIST)) ||
+ (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/INV_OBJREF:1.0") == 0 &&
+ this->retry_state_->forward_on_exception_increment (TAO::FOE_INV_OBJREF))
+ )
+ {
+ retry_on_exception = true;
+ this->retry_state_->sleep_at_starting_profile (*this->stub ());
+ }
+ }
+ else
+ {
+ int foe_kind = orb_params->forward_once_exception();
+
+ retry_on_exception =
+ (CORBA::CompletionStatus) completion != CORBA::COMPLETED_YES
+ && (((foe_kind & TAO::FOE_TRANSIENT) == 0
+ && ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0) ||
+ ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/OBJ_ADAPTER:1.0") == 0 ||
+ ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/NO_RESPONSE:1.0") == 0 ||
+ ((foe_kind & TAO::FOE_COMM_FAILURE) == 0
+ && ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0) ||
+ (orb_params->forward_invocation_on_object_not_exist ()
+ && ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0) ||
+ (do_forward = ! this->stub ()->forwarded_on_exception ()
+ && ((((foe_kind & TAO::FOE_OBJECT_NOT_EXIST) == TAO::FOE_OBJECT_NOT_EXIST)
+ && (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0)) ||
+ (((foe_kind & TAO::FOE_COMM_FAILURE) == TAO::FOE_COMM_FAILURE)
+ && (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0)) ||
+ (((foe_kind & TAO::FOE_TRANSIENT) == TAO::FOE_TRANSIENT)
+ && (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0)) ||
+ (((foe_kind & TAO::FOE_INV_OBJREF) == TAO::FOE_INV_OBJREF)
+ && (ACE_OS_String::strcmp (type_id.in (),
+ "IDL:omg.org/CORBA/INV_OBJREF:1.0") == 0)))));
+ }
+
+ if (retry_on_exception)
{
// If we are here then possibly we'll need a restart.
mon.set_status (TAO_INVOKE_RESTART);
+ if (TAO_debug_level > 4)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("handle_system_exception, profile forwarding ")
+ ACE_TEXT ("on exception "),
+ type_id.in (),
+ ACE_TEXT ("\n")));
+
if (do_forward)
this->stub ()->forwarded_on_exception (true);
@@ -625,8 +707,8 @@ namespace TAO
if (TAO_debug_level > 4)
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Twoway_Invocation::"
- "handle_system_exception, about to raise\n"));
+ ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::")
+ ACE_TEXT ("handle_system_exception, about to raise\n")));
mon.set_status (TAO_INVOKE_SYSTEM_EXCEPTION);
@@ -676,80 +758,98 @@ namespace TAO
if (!transport)
{
- // Way back, we failed to find a profile we could connect to.
- // We've come this far only so we reach the interception points
- // in case they can fix things. Time to bail....
- throw CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
- }
+ if (this->retry_state_ &&
+ this->retry_state_->forward_on_exception_limit_used ())
+ {
+ if (this->retry_state_->forward_on_exception_increment(FOE_TRANSIENT))
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Oneway_Invocation::")
+ ACE_TEXT ("remote_oneway retrying on TRANSIENT ")
+ ACE_TEXT ("exception\n")));
+ this->retry_state_->next_profile_retry (*this->stub ());
+ return TAO_INVOKE_RESTART;
+ }
+ }
+ else
+ {
+ // Way back, we failed to find a profile we could connect to.
+ // We've come this far only so we reach the interception points
+ // in case they can fix things. Time to bail....
+ throw CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
+ }
- {
- ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, transport->output_cdr_lock (),
- TAO_INVOKE_FAILURE);
+ }
- TAO_OutputCDR &cdr = transport->out_stream ();
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, transport->output_cdr_lock (),
+ TAO_INVOKE_FAILURE);
- cdr.message_attributes (this->details_.request_id (),
- this->resolver_.stub (),
- TAO_Message_Semantics (TAO_Message_Semantics::TAO_ONEWAY_REQUEST),
- max_wait_time);
+ TAO_OutputCDR &cdr = transport->out_stream ();
- this->write_header (cdr);
+ cdr.message_attributes (this->details_.request_id (),
+ this->resolver_.stub (),
+ TAO_Message_Semantics (TAO_Message_Semantics::TAO_ONEWAY_REQUEST),
+ max_wait_time);
- this->marshal_data (cdr);
+ this->write_header (cdr);
- countdown.update ();
+ this->marshal_data (cdr);
- if (transport->is_connected ())
- {
- // We have a connected transport so we can send the message
- s = this->send_message (cdr,
- TAO_Message_Semantics (TAO_Message_Semantics::TAO_ONEWAY_REQUEST),
- max_wait_time);
+ countdown.update ();
- if (transport->wait_strategy ()->non_blocking () == 0 &&
- transport->orb_core ()->client_factory ()->use_cleanup_options ())
- {
- if (!transport->wait_strategy ()->is_registered())
- {
- ACE_Event_Handler * const eh =
- transport->event_handler_i ();
-
- ACE_Reactor * const r =
- transport->orb_core ()->reactor ();
-
- if (r->register_handler (eh, ACE_Event_Handler::READ_MASK) == -1)
- {
- if (TAO_debug_level > 0)
- ACE_ERROR ((LM_ERROR,
- "TAO (%P|%t) - Synch_Oneway_Invocation::"
- "remote_oneway transport[%d] registration with"
- "reactor returned an error\n",
- transport->id ()));
- }
- else
- {
- // Only set this flag when registration succeeds
- transport->wait_strategy ()->is_registered(true);
- }
- }
- }
+ if (transport->is_connected ())
+ {
+ // We have a connected transport so we can send the message
+ s = this->send_message (cdr,
+ TAO_Message_Semantics (TAO_Message_Semantics::TAO_ONEWAY_REQUEST),
+ max_wait_time);
- }
- else
- {
- if (TAO_debug_level > 4)
- ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - Synch_Oneway_Invocation::"
- "remote_oneway, queueing message\n"));
+ if (transport->wait_strategy ()->non_blocking () == 0 &&
+ transport->orb_core ()->client_factory ()->use_cleanup_options ())
+ {
+ if (!transport->wait_strategy ()->is_registered())
+ {
+ ACE_Event_Handler * const eh =
+ transport->event_handler_i ();
+
+ ACE_Reactor * const r =
+ transport->orb_core ()->reactor ();
+
+ if (r->register_handler (eh, ACE_Event_Handler::READ_MASK) == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Oneway_Invocation::")
+ ACE_TEXT ("remote_oneway transport[%d] registration with")
+ ACE_TEXT ("reactor returned an error\n"),
+ transport->id ()));
+ }
+ else
+ {
+ // Only set this flag when registration succeeds
+ transport->wait_strategy ()->is_registered (true);
+ }
+ }
+ }
- if (transport->format_queue_message (cdr,
- max_wait_time,
- this->resolver_.stub()) != 0)
- {
- s = TAO_INVOKE_FAILURE;
- }
- }
- }
+ }
+ else
+ {
+ if (TAO_debug_level > 4)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Synch_Oneway_Invocation::")
+ ACE_TEXT ("remote_oneway, queueing message\n")));
+
+ if (transport->format_queue_message (cdr,
+ max_wait_time,
+ this->resolver_.stub()) != 0)
+ {
+ s = TAO_INVOKE_FAILURE;
+ }
+ }
+ }
#if TAO_HAS_INTERCEPTORS == 1
s = this->receive_other_interception ();
@@ -763,7 +863,7 @@ namespace TAO
status == PortableInterceptor::TRANSPORT_RETRY)
s = TAO_INVOKE_RESTART;
else if (status == PortableInterceptor::SYSTEM_EXCEPTION
- || status == PortableInterceptor::USER_EXCEPTION)
+ || status == PortableInterceptor::USER_EXCEPTION)
throw;
}
catch (...)
@@ -771,14 +871,14 @@ namespace TAO
// Notify interceptors of non-CORBA exception, and propagate
// that exception to the caller.
- PortableInterceptor::ReplyStatus const st =
- this->handle_all_exception ();
+ PortableInterceptor::ReplyStatus const st =
+ this->handle_all_exception ();
- if (st == PortableInterceptor::LOCATION_FORWARD ||
- st == PortableInterceptor::TRANSPORT_RETRY)
- s = TAO_INVOKE_RESTART;
- else
- throw;
+ if (st == PortableInterceptor::LOCATION_FORWARD ||
+ st == PortableInterceptor::TRANSPORT_RETRY)
+ s = TAO_INVOKE_RESTART;
+ else
+ throw;
}
#endif /* TAO_HAS_INTERCEPTORS */
diff --git a/TAO/tao/Synch_Invocation.h b/TAO/tao/Synch_Invocation.h
index ca01bafcbf4..bec82241379 100644
--- a/TAO/tao/Synch_Invocation.h
+++ b/TAO/tao/Synch_Invocation.h
@@ -36,6 +36,7 @@ class TAO_Bind_Dispatcher_Guard;
namespace TAO
{
class Profile_Transport_Resolver;
+ class Invocation_Retry_State;
/**
* @class Synch_Twoway_Invocation
@@ -82,6 +83,12 @@ namespace TAO
*/
Invocation_Status remote_twoway (ACE_Time_Value *max_wait_time);
+ /**
+ * Indicate that retry state should be tracked and controlled
+ * in the presense of exceptions.
+ */
+ void set_retry_state (Invocation_Retry_State *retry_state);
+
protected:
/**
@@ -107,6 +114,8 @@ namespace TAO
TAO_Synch_Reply_Dispatcher &rd,
TAO_Bind_Dispatcher_Guard &bd);
+ Invocation_Retry_State *retry_state_;
+
private:
/// Helper method that checks the reply status of the
@@ -115,6 +124,7 @@ namespace TAO
* This method returns an exception when there is an error.
*/
Invocation_Status check_reply_status (TAO_Synch_Reply_Dispatcher &rd);
+
};
/**
diff --git a/TAO/tao/Transport.cpp b/TAO/tao/Transport.cpp
index 25b70346428..b85f65966e1 100644
--- a/TAO/tao/Transport.cpp
+++ b/TAO/tao/Transport.cpp
@@ -143,6 +143,7 @@ TAO_Transport::TAO_Transport (CORBA::ULong tag,
, recv_buffer_size_ (0)
, sent_byte_count_ (0)
, is_connected_ (false)
+ , connection_closed_on_read_ (false)
, messaging_object_ (0)
, char_translator_ (0)
, wchar_translator_ (0)
@@ -2881,6 +2882,12 @@ TAO_Transport::using_blocking_io_for_asynch_messages (void) const
return false;
}
+bool
+TAO_Transport::connection_closed_on_read (void) const
+{
+ return connection_closed_on_read_;
+}
+
/*
* Hook to add concrete implementations from the derived class onto
* TAO's transport.
diff --git a/TAO/tao/Transport.h b/TAO/tao/Transport.h
index 914ede4db9b..84920bf9c7a 100644
--- a/TAO/tao/Transport.h
+++ b/TAO/tao/Transport.h
@@ -648,6 +648,9 @@ public:
/// Is this transport really connected
bool is_connected (void) const;
+ /// Was a connection seen as closed during a read
+ bool connection_closed_on_read (void) const;
+
/// Perform all the actions when this transport get opened
bool post_open (size_t id);
@@ -1183,6 +1186,12 @@ protected:
/// buffer the requests in this transport until the connection is ready
bool is_connected_;
+ /// Track if connection was seen as closed during a read so that
+ /// invocation can optionally be retried using a different profile.
+ /// Note that this could result in violate the "at most once" CORBA
+ /// semantics.
+ bool connection_closed_on_read_;
+
private:
/// Our messaging object.
diff --git a/TAO/tao/VarOut_T.h b/TAO/tao/VarOut_T.h
index c1608cab33a..fd3f1f4f041 100644
--- a/TAO/tao/VarOut_T.h
+++ b/TAO/tao/VarOut_T.h
@@ -54,6 +54,7 @@ public:
// TAO extension.
T * ptr (void) const;
+ operator T *& ();
protected:
T * ptr_;
@@ -113,9 +114,6 @@ public:
TAO_Var_Var_T & operator= (T *);
TAO_Var_Var_T & operator= (const TAO_Var_Var_T<T> &);
- // Variable size types only.
- operator T *& ();
-
operator const T & () const;
operator T & ();
operator T & () const;
diff --git a/TAO/tao/VarOut_T.inl b/TAO/tao/VarOut_T.inl
index d73084b4b16..7735ef6cefb 100644
--- a/TAO/tao/VarOut_T.inl
+++ b/TAO/tao/VarOut_T.inl
@@ -62,6 +62,14 @@ TAO_Var_Base_T<T>::ptr (void) const
{
return this->ptr_;
}
+
+template<typename T>
+ACE_INLINE
+TAO_Var_Base_T<T>::operator T *& ()
+{
+ return this->ptr_;
+}
+
// *************************************************************
template<typename T>
@@ -179,14 +187,6 @@ TAO_Var_Var_T<T>::operator= (T * p)
return *this;
}
-// Variable-size types only.
-template<typename T>
-ACE_INLINE
-TAO_Var_Var_T<T>::operator T *& ()
-{
- return this->ptr_;
-}
-
template<typename T>
ACE_INLINE
TAO_Var_Var_T<T>::operator const T & () const
diff --git a/TAO/tao/default_client.cpp b/TAO/tao/default_client.cpp
index ac2e0c1a57c..5e3044e9b98 100644
--- a/TAO/tao/default_client.cpp
+++ b/TAO/tao/default_client.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-// $Id: default_client.cpp 93686 2011-03-31 12:12:12Z johnnyw $
+// $Id$
#include "tao/default_client.h"
#include "tao/Wait_On_Read.h"
@@ -12,6 +12,7 @@
#include "tao/Reactive_Connect_Strategy.h"
#include "tao/LF_Connect_Strategy.h"
#include "tao/orbconf.h"
+#include "tao/Invocation_Utils.h"
#include "ace/Lock_Adapter_T.h"
#include "ace/Recursive_Thread_Mutex.h"
@@ -99,11 +100,13 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_TEXT("MT_NOUPCALL")) == 0)
this->wait_strategy_ = TAO_WAIT_ON_LF_NO_UPCALL;
else
- this->report_option_value_error (ACE_TEXT("-ORBClientConnectionHandler"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBClientConnectionHandler"), name);
}
}
else if (ACE_OS::strcasecmp (argv[curarg],
- ACE_TEXT("-ORBTransportMuxStrategy")) == 0)
+ ACE_TEXT("-ORBTransportMuxStrategy"))
+ == 0)
{
curarg++;
if (curarg < argc)
@@ -117,11 +120,13 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_TEXT("EXCLUSIVE")) == 0)
this->transport_mux_strategy_ = TAO_EXCLUSIVE_TMS;
else
- this->report_option_value_error (ACE_TEXT("-ORBTransportMuxStrategy"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBTransportMuxStrategy"), name);
}
}
else if (ACE_OS::strcasecmp (argv[curarg],
- ACE_TEXT("-ORBTransportMuxStrategyLock")) == 0)
+ ACE_TEXT("-ORBTransportMuxStrategyLock"))
+ == 0)
{
curarg++;
if (curarg < argc)
@@ -135,7 +140,8 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_TEXT("thread")) == 0)
this->muxed_strategy_lock_type_ = TAO_THREAD_LOCK;
else
- this->report_option_value_error (ACE_TEXT("-ORBTransportMuxStrategyLock"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBTransportMuxStrategyLock"), name);
}
}
else if (ACE_OS::strcasecmp (argv[curarg],
@@ -156,11 +162,14 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_TEXT("LF")) == 0)
this->connect_strategy_ = TAO_LEADER_FOLLOWER_CONNECT;
else
- this->report_option_value_error (ACE_TEXT("-ORBConnectStrategy"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBConnectStrategy"),
+ name);
}
}
else if (ACE_OS::strcasecmp (argv[curarg],
- ACE_TEXT("-ORBReplyDispatcherTableSize")) == 0)
+ ACE_TEXT("-ORBReplyDispatcherTableSize"))
+ == 0)
{
curarg++;
if (curarg < argc)
@@ -183,7 +192,118 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
ACE_OS::strcasecmp (name, ACE_TEXT("true")) == 0)
this->use_cleanup_options_ = true;
else
- this->report_option_value_error (ACE_TEXT("-ORBConnectionHandlerCleanup"), name);
+ this->report_option_value_error (
+ ACE_TEXT("-ORBConnectionHandlerCleanup"), name);
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnCommFailureLimit"))
+ == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnCommFailureLimit"),
+ name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_exception_limit_[TAO::FOE_COMM_FAILURE] =
+ limit;
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnTransientLimit")) == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnTransientLimit"),
+ name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_exception_limit_[TAO::FOE_TRANSIENT] =
+ limit;
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnObjectNotExistLimit"))
+ == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnObjectNotExistLimit"),
+ name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_exception_limit_[TAO::FOE_OBJECT_NOT_EXIST] =
+ limit;
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnInvObjrefLimit")) == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnInvObjrefLimit"), name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_exception_limit_[TAO::FOE_INV_OBJREF] =
+ limit;
+ }
+ }
+ else if (ACE_OS::strcmp (argv[curarg],
+ ACE_TEXT("-ORBForwardOnReplyClosedLimit"))
+ == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ ACE_TCHAR* name = argv[curarg];
+
+ ACE_TCHAR *err = 0;
+ long limit = ACE_OS::strtol (name, &err, 10);
+ if (err && *err != 0)
+ {
+ this->report_option_value_error (
+ ACE_TEXT("-ORBForwardOnReplyClosedLimit"), name);
+ }
+ else
+ this->invocation_retry_params_
+ .forward_on_reply_closed_limit_ = limit;
}
}
else if (ACE_OS::strncmp (argv[curarg], ACE_TEXT("-ORB"), 4) == 0)
@@ -208,7 +328,8 @@ TAO_Default_Client_Strategy_Factory::parse_args (int argc, ACE_TCHAR* argv[])
/// Create the correct client transport muxing strategy.
TAO_Transport_Mux_Strategy *
-TAO_Default_Client_Strategy_Factory::create_transport_mux_strategy (TAO_Transport *transport)
+TAO_Default_Client_Strategy_Factory::create_transport_mux_strategy (
+ TAO_Transport *transport)
{
TAO_Transport_Mux_Strategy *tms = 0;
@@ -266,13 +387,14 @@ TAO_Default_Client_Strategy_Factory::reply_dispatcher_table_size (void) const
}
TAO_Wait_Strategy *
-TAO_Default_Client_Strategy_Factory::create_wait_strategy (TAO_Transport *transport)
+TAO_Default_Client_Strategy_Factory::create_wait_strategy (
+ TAO_Transport *transport)
{
TAO_Wait_Strategy *ws = 0;
/*
- * Hook to customize the wait strategy object when the concrete wait strategy
- * object is known a priori.
+ * Hook to customize the wait strategy object when the concrete
+ * wait strategy object is known a priori.
*/
//@@ WAIT_STRATEGY_SPL_COMMENT_HOOK_START
switch (this->wait_strategy_)
@@ -318,7 +440,8 @@ TAO_Default_Client_Strategy_Factory::connect_strategy (void) const
}
TAO_Connect_Strategy *
-TAO_Default_Client_Strategy_Factory::create_connect_strategy (TAO_ORB_Core *orb_core)
+TAO_Default_Client_Strategy_Factory::create_connect_strategy (
+ TAO_ORB_Core *orb_core)
{
TAO_Connect_Strategy *cs = 0;
@@ -374,13 +497,20 @@ TAO_Default_Client_Strategy_Factory::use_cleanup_options (void) const
return this->use_cleanup_options_;
}
+const TAO::Invocation_Retry_Params &
+TAO_Default_Client_Strategy_Factory::invocation_retry_params (void) const
+{
+ return this->invocation_retry_params_;
+}
+
// ****************************************************************
ACE_STATIC_SVC_DEFINE (TAO_Default_Client_Strategy_Factory,
ACE_TEXT ("Client_Strategy_Factory"),
ACE_SVC_OBJ_T,
&ACE_SVC_NAME (TAO_Default_Client_Strategy_Factory),
- ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
0)
ACE_FACTORY_DEFINE (TAO, TAO_Default_Client_Strategy_Factory)
diff --git a/TAO/tao/default_client.h b/TAO/tao/default_client.h
index 3d7ea54f599..bd506384cec 100644
--- a/TAO/tao/default_client.h
+++ b/TAO/tao/default_client.h
@@ -22,6 +22,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "tao/Client_Strategy_Factory.h"
+#include "tao/Invocation_Retry_Params.h"
TAO_BEGIN_VERSIONED_NAMESPACE_DECL
@@ -61,6 +62,7 @@ public:
virtual TAO_Connect_Strategy *create_connect_strategy (TAO_ORB_Core *);
virtual bool use_cleanup_options (void) const;
virtual Connect_Strategy connect_strategy (void) const;
+ virtual const TAO::Invocation_Retry_Params &invocation_retry_params (void) const;
protected:
void report_option_value_error (const ACE_TCHAR* option_name,
@@ -104,6 +106,9 @@ private:
/// Cleanupoptions for RW strategy
bool use_cleanup_options_;
+
+ /// Retry options when exceptions occur
+ TAO::Invocation_Retry_Params invocation_retry_params_;
};
ACE_STATIC_SVC_DECLARE_EXPORT (TAO, TAO_Default_Client_Strategy_Factory)
diff --git a/TAO/tao/params.cpp b/TAO/tao/params.cpp
index 7adbe9e5cff..bc286c1a0e5 100644
--- a/TAO/tao/params.cpp
+++ b/TAO/tao/params.cpp
@@ -57,6 +57,7 @@ TAO_ORB_Parameters::TAO_ORB_Parameters (void)
, stub_factory_name_ ("Default_Stub_Factory")
, endpoint_selector_factory_name_ ("Default_Endpoint_Selector_Factory")
, thread_lane_resources_manager_factory_name_ ("Default_Thread_Lane_Resources_Manager_Factory")
+ , dynamic_thread_pool_config_name_ ()
, poa_factory_name_ ("TAO_Object_Adapter_Factory")
, poa_factory_directive_
(ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE("TAO_Object_Adapter_Factory",
@@ -65,7 +66,7 @@ TAO_ORB_Parameters::TAO_ORB_Parameters (void)
"_make_TAO_Object_Adapter_Factory",
""))
, forward_invocation_on_object_not_exist_ (false)
- , forward_once_exception_ (TAO::FOE_NON)
+ , forward_once_exception_ (0)
, collocation_resolver_name_ ("Default_Collocation_Resolver")
, allow_ziop_no_server_policies_ (!!TAO_ALLOW_ZIOP_NO_SERVER_POLICIES_DEFAULT)
{
@@ -365,6 +366,18 @@ TAO_ORB_Parameters::thread_lane_resources_manager_factory_name (void) const
}
void
+TAO_ORB_Parameters::dynamic_thread_pool_config_name (const char *s)
+{
+ this->dynamic_thread_pool_config_name_ = s;
+}
+
+const char *
+TAO_ORB_Parameters::dynamic_thread_pool_config_name (void) const
+{
+ return this->dynamic_thread_pool_config_name_.c_str ();
+}
+
+void
TAO_ORB_Parameters::stub_factory_name (const char *s)
{
this->stub_factory_name_ = s;
@@ -412,4 +425,28 @@ TAO_ORB_Parameters::endpoint_selector_factory_name (void) const
return this->endpoint_selector_factory_name_.c_str ();
}
+const TAO::Invocation_Retry_Params &
+TAO_ORB_Parameters::invocation_retry_params (void) const
+{
+ return this->invocation_retry_params_;
+}
+
+TAO::Invocation_Retry_Params &
+TAO_ORB_Parameters::invocation_retry_params (void)
+{
+ return this->invocation_retry_params_;
+}
+
+void
+TAO_ORB_Parameters::forward_on_exception_limit (const int ef, const int limit)
+{
+ this->invocation_retry_params_.forward_on_exception_limit_[ef] = limit;
+}
+
+void
+TAO_ORB_Parameters::forward_on_exception_delay (const ACE_Time_Value &delay)
+{
+ this->invocation_retry_params_.init_retry_delay_ = delay;
+}
+
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/params.h b/TAO/tao/params.h
index 90c5c80c4e4..b9c91ebaaa1 100644
--- a/TAO/tao/params.h
+++ b/TAO/tao/params.h
@@ -14,9 +14,11 @@
#define TAO_PARAMS_H
#include /**/ "ace/pre.h"
+#include "tao/Invocation_Retry_Params.h"
#include "ace/Unbounded_Queue.h"
#include "ace/Array_Map.h"
#include "ace/Synch.h"
+#include "ace/Time_Value.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -42,6 +44,8 @@ typedef ACE_Unbounded_Queue_Const_Iterator<ACE_CString> TAO_EndpointSetIterator;
// -------------------------------------------------------------------
+
+
/**
* @class TAO_ORB_Parameters
*
@@ -237,6 +241,9 @@ public:
void thread_lane_resources_manager_factory_name (const char *s);
const char *thread_lane_resources_manager_factory_name (void) const;
+ void dynamic_thread_pool_config_name (const char *s);
+ const char *dynamic_thread_pool_config_name (void) const;
+
void stub_factory_name (const char *s);
const char *stub_factory_name (void) const;
@@ -255,7 +262,13 @@ public:
void forward_invocation_on_object_not_exist (bool opt);
bool forward_invocation_on_object_not_exist (void) const;
- void forward_once_exception (const int);
+ void forward_on_exception_limit (const int ef, const int limit);
+ void forward_on_exception_delay (const ACE_Time_Value &delay);
+
+ TAO::Invocation_Retry_Params &invocation_retry_params (void);
+ const TAO::Invocation_Retry_Params &invocation_retry_params (void) const;
+
+ void forward_once_exception (const int ef);
int forward_once_exception () const;
void allow_ziop_no_server_policies (bool opt);
@@ -458,6 +471,13 @@ private:
ACE_CString thread_lane_resources_manager_factory_name_;
/**
+ * Name of the non-RT dynamic thread pool configuration set to load.
+ * This is only used if the Dynamic_TP library is linked. Default
+ * is an empty string.
+ */
+ ACE_CString dynamic_thread_pool_config_name_;
+
+ /**
* Name of the service object used to create the RootPOA. The
* default value is "TAO_POA". If TAO_RTCORBA is loaded, this
* will be changed to TAO_RT_POA so that a POA equipped with
@@ -478,13 +498,15 @@ private:
*/
bool forward_invocation_on_object_not_exist_;
+ TAO::Invocation_Retry_Params invocation_retry_params_;
/**
* The exceptions upon which the requests will be forwarded once.
+ * This is retained for backward compatibility of behavior.
*/
int forward_once_exception_;
- /**
+/**
* Name of the collocation resolver that needs to be instantiated.
* The default value is "Default_Collocation_Resolver". If
* TAO_RTCORBA is linked, the set_collocation_resolver will be
diff --git a/TAO/tao/tao.mpc b/TAO/tao/tao.mpc
index b26544fbf41..e2aff7dbe5c 100644
--- a/TAO/tao/tao.mpc
+++ b/TAO/tao/tao.mpc
@@ -174,6 +174,8 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
Invocation_Adapter.cpp
Invocation_Base.cpp
Invocation_Endpoint_Selectors.cpp
+ Invocation_Retry_State.cpp
+ Invocation_Retry_Params.cpp
IOPC.cpp
IOR_Parser.cpp
IORInterceptor_Adapter.cpp
@@ -274,6 +276,10 @@ project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoid
ShortSeqC.cpp
String_Alloc.cpp
StringSeqC.cpp
+ Storable_Base.cpp
+ Storable_FlatFileStream.cpp
+ Storable_Factory.cpp
+ Storable_File_Guard.cpp
Stub.cpp
Stub_Factory.cpp
Synch_Invocation.cpp
diff --git a/TAO/tests/Dynamic_TP/Config_Loader/Config_Loader.mpc b/TAO/tests/Dynamic_TP/Config_Loader/Config_Loader.mpc
new file mode 100644
index 00000000000..fff50baa1c2
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/Config_Loader/Config_Loader.mpc
@@ -0,0 +1,5 @@
+// $Id$
+
+project(*test) : dynamic_tp {
+ exename = test
+}
diff --git a/TAO/tests/Dynamic_TP/Config_Loader/Test.cpp b/TAO/tests/Dynamic_TP/Config_Loader/Test.cpp
new file mode 100644
index 00000000000..f6d274e8080
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/Config_Loader/Test.cpp
@@ -0,0 +1,80 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_Config.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/Service_Config.h"
+#include "ace/Dynamic_Service.h"
+
+void
+show_tp_config (const ACE_CString &name, const TAO_DTP_Definition &entry)
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Config set for %C:\n"), name.c_str()));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Initial threads: %d:\n"), entry.init_threads_));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Min threads: %d:\n"), entry.min_threads_));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Max threads: %d:\n"), entry.max_threads_));
+ if (entry.min_threads_ > -1)
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Idle Timeout: %d (sec)\n"), entry.timeout_.sec()));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Stack Size: %d:\n"), entry.stack_size_));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Request queue max depth: %d\n"), entry.queue_depth_));
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ ACE_Service_Config::open (argc, argv);
+
+ ACE_Service_Gestalt *current = ACE_Service_Config::current();
+ TAO_DTP_Config_Registry* registry =
+ ACE_Dynamic_Service<TAO_DTP_Config_Registry>::instance
+ (current, "DTP_Config_Registry", true);
+
+ if (registry == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Unable to load configuration\n")));
+ return -1;
+ }
+
+ TAO_DTP_Definition entry;
+
+ const ACE_TCHAR *name_list [] =
+ { ACE_TEXT ("ORB"),
+ ACE_TEXT ("bogus"),
+ ACE_TEXT ("POA1"),
+ ACE_TEXT ("defaults"),
+ ACE_TEXT ("m1"),
+ ACE_TEXT ("m2"),
+ ACE_TEXT ("m3"),
+ ACE_TEXT ("m4"),
+ ACE_TEXT ("m5"),
+ ACE_TEXT ("m6"),
+ ACE_TEXT ("m7"),
+ 0
+ };
+
+ for (int i = 0; name_list[i] != 0; i++)
+ {
+ bool found = registry->find (name_list[i], entry);
+ if (!found && (i != 1))
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Cannot find TP Config definition for %C\n"), name_list[i]));
+ return -1;
+ }
+ if (i == 1)
+ {
+ if (found)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Found TP Config definition for %C which should have failed\n"), name_list[i]));
+ return -1;
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("TP definition for %C not found as expected\n"), name_list[i]));
+ }
+ }
+ else
+ {
+ show_tp_config (name_list[i], entry);
+ }
+ }
+ return 0;
+}
diff --git a/TAO/tests/Dynamic_TP/Config_Loader/svc.conf b/TAO/tests/Dynamic_TP/Config_Loader/svc.conf
new file mode 100644
index 00000000000..4b3231a7a8b
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/Config_Loader/svc.conf
@@ -0,0 +1,16 @@
+# $Id$
+
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config()
+ "-DTPName ORB -DTPMin 5 -DTPInit 6 -DTPMax 10 -DTPTimeout 240 -DTPStack 10240 -DTPQueue 20"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPMin 2 -DTPInit 4 -DTPMax 10 -DTPQueue 10"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPOverwrite 1 -DTPMin 7 -DTPMax 14 "
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPMin 7 -DTPMax 11 -DPQueue 14"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName defaults"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m1 -DTPMin 3"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m2 -DTPMax 10"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m3 -DTPTimeout 120"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m4 -DTPMin 3 -DTPInit 7 -DTPMax 10 -DTPTimeout 120"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m5 -DTPMin 3 -DTPInit 10 -DTPTimeout 30"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m6 -DTPInit 6 -DTPMax -1"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m7 -DTPInit 7"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName bogus -DTPMin 6 -DTPInit 3"
diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/Client.cpp b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Client.cpp
new file mode 100644
index 00000000000..f2881d25d63
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Client.cpp
@@ -0,0 +1,130 @@
+// $Id$
+
+#include "TestC.h"
+#include "ace/Get_Opt.h"
+#include "ace/Task.h"
+
+class MT_Requestor : public virtual ACE_Task_Base
+{
+public:
+ MT_Requestor (Test::Sleeper_ptr s);
+
+ virtual int svc (void);
+private:
+ Test::Sleeper_var sleeper_;
+};
+
+MT_Requestor::MT_Requestor (Test::Sleeper_ptr s)
+ : sleeper_ (Test::Sleeper::_duplicate (s))
+{
+}
+
+int
+MT_Requestor::svc ()
+{
+ int retries = 5;
+ while (retries-- > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Client thread %t calling delay with %d retries\n"),
+ retries));
+ try
+ {
+ this->sleeper_->delay();
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Client thread %t delay succeeded\n")));
+ break;
+ }
+ catch (CORBA::Exception &ex)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Client thread %t caught %s\n"),
+ ex._name()));
+ }
+ }
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Client thread %t done\n")));
+ return 0;
+}
+
+const ACE_TCHAR *ior = ACE_TEXT("file://server.ior");
+bool do_shutdown = false;
+int num_threads = 1;
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:n:x"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'k':
+ ior = get_opts.opt_arg ();
+ break;
+ case 'n':
+ num_threads = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case 'x':
+ do_shutdown = true;
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-k <ior> "
+ "-n <threads> "
+ "-x "
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ CORBA::Object_var tmp =
+ orb->string_to_object(ior);
+
+ Test::Sleeper_var sleeper =
+ Test::Sleeper::_narrow(tmp.in ());
+
+ if (CORBA::is_nil (sleeper.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Nil Test::Sleeper reference <%s>\n",
+ ior),
+ 1);
+ }
+
+ MT_Requestor requestor (sleeper.in());
+ requestor.activate (THR_NEW_LWP | THR_JOINABLE, num_threads);
+ requestor.wait ();
+
+ if (do_shutdown)
+ {
+ sleeper->shutdown();
+ }
+
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Client main exception caught:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/ORB_ThreadPool.mpc b/TAO/tests/Dynamic_TP/ORB_ThreadPool/ORB_ThreadPool.mpc
new file mode 100644
index 00000000000..7fe5b08fac7
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/ORB_ThreadPool.mpc
@@ -0,0 +1,35 @@
+// -*- MPC -*-
+// $Id$
+
+project(*idl): taoidldefaults {
+ IDL_Files {
+ Test.idl
+ }
+ custom_only = 1
+}
+
+project(*Server): taoserver, dynamic_tp {
+ after += *idl
+ Source_Files {
+ Test_i.cpp
+ Server.cpp
+ TestC.cpp
+ TestS.cpp
+ }
+
+ IDL_Files {
+ }
+
+}
+
+project(*Client): taoclient {
+ after += *idl
+ Source_Files {
+ TestC.cpp
+ Client.cpp
+ }
+
+ IDL_Files {
+ }
+
+}
diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/Server.cpp b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Server.cpp
new file mode 100644
index 00000000000..fc23726e81c
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Server.cpp
@@ -0,0 +1,111 @@
+// $Id$
+
+#include "Test_i.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/Thread_Manager.h"
+
+#include "tao/ORB_Core_TSS_Resources.h"
+#include "tao/ORB_Core.h"
+#include "tao/Dynamic_TP/DTP_Thread_Pool.h"
+
+const ACE_TCHAR *ior_output_file = ACE_TEXT ("server.ior");
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:s:p:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-o <iorfile>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA");
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in ());
+
+ if (CORBA::is_nil (root_poa.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Panic: nil RootPOA\n"),
+ 1);
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager ();
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ Test_i *test_impl;
+ ACE_NEW_RETURN (test_impl, Test_i (orb.in ()), 1);
+ PortableServer::ServantBase_var owner_transfer(test_impl);
+ PortableServer::ObjectId_var id = root_poa->activate_object (test_impl);
+ CORBA::Object_var object = root_poa->id_to_reference (id.in ());
+ Test::Sleeper_var sleeper = Test::Sleeper::_narrow (object.in ());
+ CORBA::String_var ior = orb->object_to_string (sleeper.in ());
+
+ ACE_DEBUG ((LM_DEBUG,"Server calling poa_manager::activate()\n"));
+ poa_manager->activate ();
+
+ // Output the IOR to the <ior_output_file>
+ FILE *output_file= ACE_OS::fopen (ior_output_file, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file %s for writing IOR: %C",
+ ior_output_file,
+ ior.in ()),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+
+ TAO_ORB_Core_TSS_Resources &tss =
+ *orb->orb_core ()->get_tss_resources ();
+
+ // The API calls it a lane but DTP Thread Pools
+ // are always a single lane.
+ TAO_DTP_Thread_Pool *pool =
+ static_cast <TAO_DTP_Thread_Pool *> (tss.lane_);
+
+#if 0
+ ACE_DEBUG ((LM_DEBUG,"Server calling orb::run()\n"));
+ orb->run ();
+#else
+ pool->wait();
+#endif
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop finished\n"));
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/Test.idl b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Test.idl
new file mode 100644
index 00000000000..d2760fdd4be
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Test.idl
@@ -0,0 +1,19 @@
+//
+// $Id$
+//
+
+/// Put the interfaces in a module, to avoid global namespace pollution
+module Test
+{
+ /// A very simple interface
+ interface Sleeper
+ {
+ void delay ();
+
+ /// A method to shutdown the ORB
+ /**
+ * This method is used to simplify the test shutdown process
+ */
+ oneway void shutdown ();
+ };
+};
diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/Test_i.cpp b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Test_i.cpp
new file mode 100644
index 00000000000..0a5eb7f8185
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Test_i.cpp
@@ -0,0 +1,24 @@
+//
+// $Id$
+//
+#include "Test_i.h"
+#include "ace/OS_NS_unistd.h"
+
+Test_i::Test_i (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+{
+}
+
+void
+Test_i::delay(void)
+{
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Test_i::delay called\n"));
+ ACE_OS::sleep (1);
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Test_i::delay returning\n"));
+}
+
+void
+Test_i::shutdown (void)
+{
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/Test_i.h b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Test_i.h
new file mode 100644
index 00000000000..573d6c55b33
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/Test_i.h
@@ -0,0 +1,29 @@
+//
+// $Id$
+//
+
+#ifndef TEST_I_H
+#define TEST_I_H
+#include /**/ "ace/pre.h"
+
+#include "TestS.h"
+
+/// Implement the Test::Sleeper interface
+class Test_i : public virtual POA_Test::Sleeper
+{
+public:
+ /// Constructor
+ Test_i (CORBA::ORB_ptr orb);
+
+ // = The skeleton methods
+ virtual void delay (void);
+
+ virtual void shutdown (void);
+
+private:
+ CORBA::ORB_var orb_;
+
+};
+
+#include /**/ "ace/post.h"
+#endif /* TEST_I_H */
diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/client.conf b/TAO/tests/Dynamic_TP/ORB_ThreadPool/client.conf
new file mode 100644
index 00000000000..74326a5cbf4
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/client.conf
@@ -0,0 +1,4 @@
+# $Id$
+
+static Client_Strategy_Factory "-ORBTransportMuxStrategy"
+
diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/run_test.pl b/TAO/tests/Dynamic_TP/ORB_ThreadPool/run_test.pl
new file mode 100755
index 00000000000..7bce5b75574
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/run_test.pl
@@ -0,0 +1,77 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+$status = 0;
+$threads = 10;
+$sdebug = "";
+$cdebug = "";
+foreach $i (@ARGV) {
+ if ($i eq '-sdebug' || $i eq '-debug') {
+ $sdebug = "-ORBDebuglevel 10 -ORBVerboseLogging 1";
+ }
+ if ($i eq '-cdebug' || $i eq '-debug') {
+ $sdebug = "-ORBDebuglevel 10 -ORBVerboseLogging 1";
+ }
+}
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+
+my $iorbase = "server.ior";
+my $server_iorfile = $server->LocalFile ($iorbase);
+my $client_iorfile = $client->LocalFile ($iorbase);
+$server->DeleteFile($iorbase);
+$client->DeleteFile($iorbase);
+
+$SV = $server->CreateProcess ("server", "$sdebug -ORBSvcConf server.conf -ORBDynamicThreadPoolName ORBPool -o $server_iorfile");
+$CL = $client->CreateProcess ("client", "$cdebug -ORBSvcConf client.conf -k file://$client_iorfile -n $threads -x");
+$server_status = $SV->Spawn ();
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+}
+
+if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+if ($server->GetFile ($iorbase) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+if ($client->PutFile ($iorbase) == -1) {
+ print STDERR "ERROR: cannot set file <$client_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+$client_status = $CL->SpawnWaitKill ($client->ProcessStartWaitInterval() + 10);
+
+if ($client_status != 0) {
+ print STDERR "ERROR: client returned $client_status\n";
+ $status = 1;
+}
+
+$server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+}
+
+$server->DeleteFile($iorbase);
+$client->DeleteFile($iorbase);
+
+exit $status;
diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/server.conf b/TAO/tests/Dynamic_TP/ORB_ThreadPool/server.conf
new file mode 100644
index 00000000000..ec0ca59c0ed
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/server.conf
@@ -0,0 +1,4 @@
+# $Id$
+
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName ORBPool -DTPMin 3 -DTPInit 4 -DTPMax 7 -DTPTimeout 30"
+dynamic DTP_ORB_Loader Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_ORB_Loader() ""
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Dynamic_TP_POA_Test_Dynamic.mpc b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Dynamic_TP_POA_Test_Dynamic.mpc
new file mode 100644
index 00000000000..d7225b8511a
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Dynamic_TP_POA_Test_Dynamic.mpc
@@ -0,0 +1,35 @@
+// -*- MPC -*-
+// $Id$
+
+project(*idl): taoidldefaults {
+ IDL_Files {
+ Test.idl
+ }
+ custom_only = 1
+}
+
+project(Dynamic_TP_POA_Test_Dynamic_Server): taoserver, csd_framework, dynamic_tp {
+ after += *idl
+ Source_Files {
+ Hello.cpp
+ server.cpp
+ TestC.cpp
+ TestS.cpp
+ }
+
+ IDL_Files {
+ }
+
+}
+
+project(Dynamic_TP_POA_Test_Dynamic_Client): taoclient {
+ after += Dynamic_TP_POA_Test_Dynamic_Server
+ Source_Files {
+ TestC.cpp
+ client.cpp
+ }
+
+ IDL_Files {
+ }
+
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.cpp b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.cpp
new file mode 100644
index 00000000000..313393fc02c
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.cpp
@@ -0,0 +1,43 @@
+//
+// $Id$
+//
+#include "Hello.h"
+#include "ace/OS_NS_unistd.h"
+
+Hello::Hello (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb)), sleep_sec_(1)
+{
+}
+
+CORBA::Short
+Hello::sleep_sec()
+{
+ return this->sleep_sec_;
+}
+
+void
+ Hello::sleep_sec(CORBA::Short sl_sec)
+{
+ this->sleep_sec_ = sl_sec;
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Hello::sleep_sec returning\n"));
+}
+
+char *
+Hello::get_string (CORBA::Long client_num)
+{
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("TAO (%P|%t) - Server: Sleeping for client->%d....\n "),
+ client_num));
+
+ ACE_OS::sleep(this->sleep_sec_);
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("TAO (%P|%t) - Server: Returning for client->%d....\n "),
+ client_num));
+ return CORBA::string_dup ("Hello there!");
+}
+
+void
+Hello::shutdown (void)
+{
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.h b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.h
new file mode 100644
index 00000000000..93afd1f3913
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Hello.h
@@ -0,0 +1,34 @@
+//
+// $Id$
+//
+
+#ifndef HELLO_H
+#define HELLO_H
+#include /**/ "ace/pre.h"
+
+#include "TestS.h"
+
+/// Implement the Test::Hello interface
+class Hello
+ : public virtual POA_Test::Hello
+{
+public:
+ /// Constructor
+ Hello (CORBA::ORB_ptr orb);
+
+ // = The skeleton methods
+ virtual CORBA::Short sleep_sec ();
+ virtual void sleep_sec (CORBA::Short sleep_sec);
+ virtual char * get_string (CORBA::Long);
+
+ virtual void shutdown (void);
+
+private:
+ /// Use an ORB reference to convert strings to objects and shutdown
+ /// the application.
+ CORBA::ORB_var orb_;
+ CORBA::Short sleep_sec_;
+};
+
+#include /**/ "ace/post.h"
+#endif /* HELLO_H */
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Test.idl b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Test.idl
new file mode 100644
index 00000000000..0e2180b8481
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/Test.idl
@@ -0,0 +1,24 @@
+//
+// $Id$
+//
+
+/// Put the interfaces in a module, to avoid global namespace pollution
+module Test
+{
+ /// A very simple interface
+ interface Hello
+ {
+ /// Attribute to hold a sleep time in seconds
+ /// for the Hello servant
+ attribute short sleep_sec;
+
+ /// Return a simple string
+ string get_string (in long cl);
+
+ /// A method to shutdown the ORB
+ /**
+ * This method is used to simplify the test shutdown process
+ */
+ oneway void shutdown ();
+ };
+};
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/client.cpp b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/client.cpp
new file mode 100644
index 00000000000..6525413101d
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/client.cpp
@@ -0,0 +1,98 @@
+// $Id$
+
+#include "TestC.h"
+#include "ace/Get_Opt.h"
+
+const ACE_TCHAR *ior = ACE_TEXT("file://server.ior");
+int client_num = 1;
+int report_exception = 1;
+bool is_shutdown = false;
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("c:e:k:s"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'c':
+ client_num = ACE_OS::atoi(get_opts.opt_arg ());
+ break;
+ case 'e':
+ report_exception = ACE_OS::atoi(get_opts.opt_arg ());
+ break;
+ case 'k':
+ ior = get_opts.opt_arg ();
+ break;
+ case 's':
+ is_shutdown = true;
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-c <client #> "
+ "-e <0|1> "
+ "-k <ior> "
+ "-s (shutdown) "
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ CORBA::Object_var tmp =
+ orb->string_to_object(ior);
+
+ Test::Hello_var hello =
+ Test::Hello::_narrow(tmp.in ());
+
+ if (CORBA::is_nil (hello.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Nil Test::Hello reference <%s>\n",
+ ior),
+ 1);
+ }
+
+ if (is_shutdown)
+ {
+ hello->shutdown();
+ }
+ else
+ {
+ CORBA::String_var the_string =
+ hello->get_string (client_num);
+ ACE_DEBUG((LM_DEBUG,
+ "Client %d received return text of: [%C %d].\n",
+ client_num,
+ the_string.in(),
+ client_num));
+ }
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ if (report_exception)
+ ex._tao_print_exception ("Exception caught:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/run_test.pl b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/run_test.pl
new file mode 100755
index 00000000000..ff8141814bb
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/run_test.pl
@@ -0,0 +1,404 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+
+sub count_strings
+{
+ my $log_file = shift;
+ my $find_str = shift;
+ open my $fh, '<', $log_file or die $!;
+ my $cnt=0;
+ while (<$fh>)
+ {
+ $f = quotemeta($find_str);
+ $cnt += $_ =~ /$f/;
+ }
+ print STDERR "INFO: Count - [$cnt]\n";
+ close $fh;
+ return($cnt);
+}
+
+sub test_1
+{
+# Test 1:
+# This is a test for the creation of initial_pool_threads.
+# The test will start up a server with default pool values
+# and will result in 5 initial threads being started.
+
+ my $server = shift;
+ my $client = shift;
+ my $iorbase = shift;
+ my $deletelogs = shift;
+ my $status = 0;
+
+ print "\nRunning Test 1....\n";
+ $test_num=1;
+
+ my $lfname = "server_test" . $test_num . ".log";
+ my $scname = "svc" . $test_num . ".conf";
+ my $server_iorfile = $server->LocalFile ($iorbase);
+ my $client_iorfile = $client->LocalFile ($iorbase);
+ my $server_logfile = $server->LocalFile ($lfname);
+ my $svc_conf = $server->LocalFile($scname);
+
+ $server->DeleteFile($lfname);
+
+ $SV = $server->CreateProcess ("server", " -ORBDebugLevel 5 -ORBSvcConf $svc_conf -ORBLogFile $server_logfile -s 3 -o $server_iorfile");
+ $SC = $client->CreateProcess ("client", "-k file://$client_iorfile -s");
+
+ $server_status = $SV->Spawn ();
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+
+ if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ $client_status = $SC->SpawnWaitKill ($client->ProcessStopWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client $i returned $client_status\n";
+ }
+
+ # Now find the spawned threads in the log file.
+
+ $find_this="DTP_Task::svc() New thread created.";
+ $found_cnt=0;
+
+ my($found_cnt) = count_strings($server_logfile,$find_this);
+
+ if ($found_cnt != 5) {
+ print STDERR "ERROR: initial_pool_thread test failed w/$found_cnt instead of 5\n";
+ $status = 1;
+ }
+ elsif ($deletelogs) {
+ $server->DeleteFile($lfname);
+ }
+
+ $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server->DeleteFile($iorbase);
+ $client->DeleteFile($iorbase);
+
+ return($status);
+}
+
+sub test_2
+{
+ # Test 2:
+ # This is a test for showing a process maintaining a min_pool_threads after
+ # the creation of initial_pool_threads is higher. This test will also
+ # exercise the thread_idle_time (timeout).
+ # The test will start up a server with 10 init_pool_threads and 5 min_pool_threads.
+ # After 10 seconds, 5 threads should expire leaving the minimum 5 threads.
+
+
+ my $server = shift;
+ my $client = shift;
+ my $iorbase = shift;
+ my $deletelogs = shift;
+ my $status = 0;
+
+
+ print "\nRunning Test 2....\n";
+ $test_num=2;
+ my $lfname = "server_test" . $test_num . ".log";
+ my $scname = "svc" . $test_num . ".conf";
+ my $server_iorfile = $server->LocalFile ($iorbase);
+ my $client_iorfile = $client->LocalFile ($iorbase);
+ my $server_logfile = $server->LocalFile ($lfname);
+ my $svc_conf = $server->LocalFile($scname);
+
+ $server->DeleteFile($lfname);
+
+ $SV = $server->CreateProcess ("server", " -ORBDebugLevel 5 -ORBSvcConf $svc_conf -ORBLogFile $server_logfile -s 3 -o $server_iorfile");
+ $SC = $client->CreateProcess ("client", "-k file://$client_iorfile -s");
+
+ $server_status = $SV->Spawn ();
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+
+ if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ # Sleep here for more than the timeout to let the threads die off and log.
+ print STDERR "INFO: sleeping 15 seconds\n";
+ sleep(15);
+
+ $client_status = $SC->SpawnWaitKill ($client->ProcessStopWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client $i returned $client_status\n";
+ }
+ # Now find the spawned threads in the log file.
+
+ $find_this="DTP_Task::svc() Existing thread expiring.";
+ $found_cnt=0;
+
+ my($found_cnt) = count_strings($server_logfile,$find_this);
+
+ if ($found_cnt != 5) {
+ print STDERR "ERROR: min_pool_thread test failed w/$found_cnt instead of 5\n";
+ $status = 1;
+ }
+ elsif ($deletelogs) {
+ $server->DeleteFile($lfname);
+ }
+
+ $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server->DeleteFile($iorbase);
+ $client->DeleteFile($iorbase);
+
+ return($status);
+}
+
+sub test_3
+{
+ # Test 3:
+ # This is a test for showing a process maintaining a max_request_queue_depth after
+ # more clients request service than the queue allows for.
+ # The test will start up a server with a max_request_queue_depth of 10 and
+ # will issue calls from 15 clients. There should be 5 CORBA exceptions found
+ # in the log after the run.
+ #
+ my $server = shift;
+ my $client = shift;
+ my $iorbase = shift;
+ my $deletelogs = shift;
+ my $status = 0;
+
+ print "\nRunning Test 3....\n";
+ $test_num=3;
+ $num_clients=15;
+ my $lfname = "server_test" . $test_num . ".log";
+ my $scname = "svc" . $test_num . ".conf";
+ my $server_iorfile = $server->LocalFile ($iorbase);
+ my $client_iorfile = $client->LocalFile ($iorbase);
+ my $server_logfile = $server->LocalFile ($lfname);
+ my $svc_conf = $server->LocalFile($scname);
+
+ $server->DeleteFile($lfname);
+
+ $SV = $server->CreateProcess ("server", " -ORBDebugLevel 5 -ORBSvcConf $svc_conf -ORBLogFile $server_logfile -s 3 -o $server_iorfile");
+
+ $server_status = $SV->Spawn ();
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+
+ if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ for ($i = 0; $i < $num_clients; $i++) {
+ $CLS[$i] = $client->CreateProcess ("client", "-c $i -k file://$client_iorfile -e 0");
+ $CLS[$i]->Spawn ();
+ }
+
+ my $valid_num_exceptions=5;
+ my $num_exceptions=0;
+
+ for ($i = 0; $i < $num_clients; $i++) {
+
+ $client_status = $CLS[$i]->WaitKill ($client->ProcessStopWaitInterval());
+
+ if ($client_status != 0) {
+ $num_exceptions++;
+ print STDERR "STATUS: client $i returned $client_status\n";
+ }
+ }
+
+ $SC = $client->CreateProcess ("client", "-k file://$client_iorfile -s");
+ $client_status = $SC->SpawnWaitKill ($client->ProcessStopWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client $i returned $client_status\n";
+ }
+
+ if ($num_exceptions != $valid_num_exceptions)
+ {
+ print STDERR "ERROR: max_request_queue_depth test failed w/$num_exceptions instead of $valid_num_exceptions\n";
+ $status = 1;
+ }
+ elsif ($deletelogs) {
+ $server->DeleteFile($lfname);
+ }
+
+
+ $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server->DeleteFile($iorbase);
+ $client->DeleteFile($iorbase);
+
+ return($status);
+}
+
+sub test_4
+{
+
+ # Test 4:
+ # This is a test for showing a process maintaining a max_pool_threads after
+ # more clients request service than the queue allows for.
+ # The test will start up a server with a max_request_queue_depth of 10 and
+ # will issue calls from 10 clients. There should be 5 CORBA exceptions found
+ # in the log after the run.
+ #
+
+ my $server = shift;
+ my $client = shift;
+ my $iorbase = shift;
+ my $deletelogs = shift;
+ my $status = 0;
+
+ print "\nRunning Test 4....\n";
+ $test_num=4;
+ $num_clients=10;
+ my $lfname = "server_test" . $test_num . ".log";
+ my $scname = "svc" . $test_num . ".conf";
+ my $server_iorfile = $server->LocalFile ($iorbase);
+ my $client_iorfile = $client->LocalFile ($iorbase);
+ my $server_logfile = $server->LocalFile ($lfname);
+ my $svc_conf = $server->LocalFile($scname);
+
+ $server->DeleteFile($lfname);
+
+ $SV = $server->CreateProcess ("server", " -ORBDebugLevel 5 -ORBSvcConf $svc_conf -ORBLogFile $server_logfile -s 5 -o $server_iorfile");
+ $SC = $client->CreateProcess ("client", "-k file://$client_iorfile -s");
+
+ $server_status = $SV->Spawn ();
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+
+ if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ for ($i = 0; $i < $num_clients; $i++) {
+ $CLS[$i] = $client->CreateProcess ("client", "-c $i -k file://$client_iorfile");
+ $CLS[$i]->Spawn ();
+ }
+
+
+ for ($i = 0; $i < $num_clients; $i++) {
+
+ $client_status = $CLS[$i]->WaitKill ($client->ProcessStopWaitInterval());
+
+ if ($client_status != 0) {
+ print STDERR "ERROR: client $i returned $client_status\n";
+ }
+ }
+
+ $client_status = $SC->SpawnWaitKill ($client->ProcessStopWaitInterval());
+
+ # Now find the spawned threads in the log file.
+
+ $find_this="Growing threadcount.";
+ $found_cnt=0;
+ $valid_cnt=4;
+
+ my($found_cnt) = count_strings($server_logfile,$find_this);
+
+ if ($found_cnt != $valid_cnt) {
+ print STDERR "ERROR: max_pool_thread test failed w/$found_cnt instead of $valid_cnt\n";
+ $status = 1;
+ }
+ elsif ($deletelogs) {
+ $server->DeleteFile($lfname);
+ }
+
+ $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server->DeleteFile($iorbase);
+ $client->DeleteFile($iorbase);
+ return($status);
+}
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+my $iorbase = "server.ior";
+my $server_iorfile = $server->LocalFile ($iorbase);
+my $client_iorfile = $client->LocalFile ($iorbase);
+my $deletelogs = 1;
+
+$server->DeleteFile($iorbase);
+$client->DeleteFile($iorbase);
+
+my $status = 0;
+
+# Each test below will start up a server and optionally some clients.
+# When a server gets a call it will sleep some number of seconds before responding.
+# The -s parameter controls how many seconds it will sleep.
+# The order is mandatory and must not contain spaces. It is defined as follows:
+# min_pool_threads
+# initial_pool_threads
+# max_pool_threads
+# thread_stack_size
+# thread_timeout (in seconds)
+# max_queue_request_depth
+
+ while ()
+ {
+ $status = test_1($server, $client, $iorbase, $deletelogs);
+ last if ($status);
+ $status = test_2($server, $client, $iorbase, $deletelogs);
+ last if ($status);
+ $status = test_3($server, $client, $iorbase, $deletelogs);
+ last if ($status);
+ $status = test_4($server, $client, $iorbase, $deletelogs);
+ last;
+ }
+
+$server->DeleteFile($iorbase);
+$client->DeleteFile($iorbase);
+
+exit $status;
+
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/server.cpp b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/server.cpp
new file mode 100644
index 00000000000..fcdfee2efe0
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/server.cpp
@@ -0,0 +1,122 @@
+// $Id$
+
+#include "Hello.h"
+#include "tao/Dynamic_TP/DTP_POA_Strategy.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/Thread_Manager.h"
+
+const ACE_TCHAR *ior_output_file = ACE_TEXT ("server.ior");
+int sleep_sec = 1;
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:s:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+ case 's':
+ sleep_sec = ACE_OS::strtol(get_opts.opt_arg (),NULL,0);
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-o <iorfile>"
+ "-s (# sec to sleep)"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA");
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in ());
+
+ if (CORBA::is_nil (root_poa.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Panic: nil RootPOA\n"),
+ 1);
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager ();
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ Hello *hello_impl;
+ ACE_NEW_RETURN (hello_impl,
+ Hello (orb.in ()),
+ 1);
+ PortableServer::ServantBase_var owner_transfer(hello_impl);
+
+ PortableServer::ObjectId_var id =
+ root_poa->activate_object (hello_impl);
+
+ CORBA::Object_var object = root_poa->id_to_reference (id.in ());
+
+ Test::Hello_var hello =
+ Test::Hello::_narrow (object.in ());
+
+ CORBA::String_var ior =
+ orb->object_to_string (hello.in ());
+
+ // Output the IOR to the <ior_output_file>
+ FILE *output_file= ACE_OS::fopen (ior_output_file, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file %s for writing IOR: %C",
+ ior_output_file,
+ ior.in ()),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+
+ ACE_DEBUG ((LM_DEBUG,"Server calling poa_manager::activate()\n"));
+ poa_manager->activate ();
+
+
+ ACE_DEBUG ((LM_DEBUG,"Server calling hello->sleep_sec()\n"));
+ // Set the sleep time for the Hello object
+ hello->sleep_sec(sleep_sec);
+
+ ACE_DEBUG ((LM_DEBUG,"Server calling orb::run()\n"));
+ orb->run ();
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop finished\n"));
+ // Wait for all CSD task threads exit.
+ ACE_Thread_Manager::instance ()->wait ();
+
+ root_poa->destroy (1, 1);
+
+ orb->destroy ();
+
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc1.conf b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc1.conf
new file mode 100644
index 00000000000..98c7ce1492f
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc1.conf
@@ -0,0 +1,4 @@
+# $Id$
+
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPMin -1 -DTPInit 5 -DTPMax -1 -DTPTimeout 60 -DTPStack 0 -DTPQueue 0"
+dynamic DTP_POA_Loader Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_POA_Loader() "-DTPPOAConfigMap RootPOA,MyPOA2,MyPOA3:POA1"
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc2.conf b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc2.conf
new file mode 100644
index 00000000000..a0c90c7be1d
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc2.conf
@@ -0,0 +1,4 @@
+# $Id$
+
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPMin 5 -DTPInit 10 -DTPMax -1 -DTPTimeout 10 -DTPStack 0 -DTPQueue 0"
+dynamic DTP_POA_Loader Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_POA_Loader() "-DTPPOAConfigMap RootPOA,MyPOA2,MyPOA3:POA1"
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc3.conf b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc3.conf
new file mode 100644
index 00000000000..1e56b9c2599
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc3.conf
@@ -0,0 +1,4 @@
+# $Id$
+
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPMin -1 -DTPInit 15 -DTPMax -1 -DTPTimeout 10 -DTPStack 0 -DTPQueue 10"
+dynamic DTP_POA_Loader Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_POA_Loader() "-DTPPOAConfigMap RootPOA,MyPOA2,MyPOA3:POA1"
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc4.conf b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc4.conf
new file mode 100644
index 00000000000..7b8f2807899
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Dynamic/svc4.conf
@@ -0,0 +1,4 @@
+# $Id$
+
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPMin -1 -DTPInit 1 -DTPMax 5 -DTPTimeout 60 -DTPStack 0 -DTPQueue 10"
+dynamic DTP_POA_Loader Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_POA_Loader() "-DTPPOAConfigMap RootPOA,MyPOA2,MyPOA3:POA1"
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Dynamic_TP_POA_Test_Static.mpc b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Dynamic_TP_POA_Test_Static.mpc
new file mode 100644
index 00000000000..7662ee6d861
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Dynamic_TP_POA_Test_Static.mpc
@@ -0,0 +1,35 @@
+// -*- MPC -*-
+// $Id$
+
+project(Dynamic_TP_POA_Test_Static_idl): taoidldefaults {
+ IDL_Files {
+ Test.idl
+ }
+ custom_only = 1
+}
+
+project(Dynamic_TP_POA_Test_Static_Server): taoserver, csd_framework, dynamic_tp {
+ after += Dynamic_TP_POA_Test_Static_idl
+ Source_Files {
+ Hello.cpp
+ server.cpp
+ TestC.cpp
+ TestS.cpp
+ }
+
+ IDL_Files {
+ }
+
+}
+
+project(Dynamic_TP_POA_Test_Static_Client): taoclient {
+ after += Dynamic_TP_POA_Test_Static_Server
+ Source_Files {
+ TestC.cpp
+ client.cpp
+ }
+
+ IDL_Files {
+ }
+
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.cpp b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.cpp
new file mode 100644
index 00000000000..313393fc02c
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.cpp
@@ -0,0 +1,43 @@
+//
+// $Id$
+//
+#include "Hello.h"
+#include "ace/OS_NS_unistd.h"
+
+Hello::Hello (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb)), sleep_sec_(1)
+{
+}
+
+CORBA::Short
+Hello::sleep_sec()
+{
+ return this->sleep_sec_;
+}
+
+void
+ Hello::sleep_sec(CORBA::Short sl_sec)
+{
+ this->sleep_sec_ = sl_sec;
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) Hello::sleep_sec returning\n"));
+}
+
+char *
+Hello::get_string (CORBA::Long client_num)
+{
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("TAO (%P|%t) - Server: Sleeping for client->%d....\n "),
+ client_num));
+
+ ACE_OS::sleep(this->sleep_sec_);
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("TAO (%P|%t) - Server: Returning for client->%d....\n "),
+ client_num));
+ return CORBA::string_dup ("Hello there!");
+}
+
+void
+Hello::shutdown (void)
+{
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.h b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.h
new file mode 100644
index 00000000000..93afd1f3913
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Hello.h
@@ -0,0 +1,34 @@
+//
+// $Id$
+//
+
+#ifndef HELLO_H
+#define HELLO_H
+#include /**/ "ace/pre.h"
+
+#include "TestS.h"
+
+/// Implement the Test::Hello interface
+class Hello
+ : public virtual POA_Test::Hello
+{
+public:
+ /// Constructor
+ Hello (CORBA::ORB_ptr orb);
+
+ // = The skeleton methods
+ virtual CORBA::Short sleep_sec ();
+ virtual void sleep_sec (CORBA::Short sleep_sec);
+ virtual char * get_string (CORBA::Long);
+
+ virtual void shutdown (void);
+
+private:
+ /// Use an ORB reference to convert strings to objects and shutdown
+ /// the application.
+ CORBA::ORB_var orb_;
+ CORBA::Short sleep_sec_;
+};
+
+#include /**/ "ace/post.h"
+#endif /* HELLO_H */
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Test.idl b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Test.idl
new file mode 100644
index 00000000000..0e2180b8481
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/Test.idl
@@ -0,0 +1,24 @@
+//
+// $Id$
+//
+
+/// Put the interfaces in a module, to avoid global namespace pollution
+module Test
+{
+ /// A very simple interface
+ interface Hello
+ {
+ /// Attribute to hold a sleep time in seconds
+ /// for the Hello servant
+ attribute short sleep_sec;
+
+ /// Return a simple string
+ string get_string (in long cl);
+
+ /// A method to shutdown the ORB
+ /**
+ * This method is used to simplify the test shutdown process
+ */
+ oneway void shutdown ();
+ };
+};
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/client.cpp b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/client.cpp
new file mode 100644
index 00000000000..6525413101d
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/client.cpp
@@ -0,0 +1,98 @@
+// $Id$
+
+#include "TestC.h"
+#include "ace/Get_Opt.h"
+
+const ACE_TCHAR *ior = ACE_TEXT("file://server.ior");
+int client_num = 1;
+int report_exception = 1;
+bool is_shutdown = false;
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("c:e:k:s"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'c':
+ client_num = ACE_OS::atoi(get_opts.opt_arg ());
+ break;
+ case 'e':
+ report_exception = ACE_OS::atoi(get_opts.opt_arg ());
+ break;
+ case 'k':
+ ior = get_opts.opt_arg ();
+ break;
+ case 's':
+ is_shutdown = true;
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-c <client #> "
+ "-e <0|1> "
+ "-k <ior> "
+ "-s (shutdown) "
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ CORBA::Object_var tmp =
+ orb->string_to_object(ior);
+
+ Test::Hello_var hello =
+ Test::Hello::_narrow(tmp.in ());
+
+ if (CORBA::is_nil (hello.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Nil Test::Hello reference <%s>\n",
+ ior),
+ 1);
+ }
+
+ if (is_shutdown)
+ {
+ hello->shutdown();
+ }
+ else
+ {
+ CORBA::String_var the_string =
+ hello->get_string (client_num);
+ ACE_DEBUG((LM_DEBUG,
+ "Client %d received return text of: [%C %d].\n",
+ client_num,
+ the_string.in(),
+ client_num));
+ }
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ if (report_exception)
+ ex._tao_print_exception ("Exception caught:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl
new file mode 100755
index 00000000000..bc66e52623f
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/run_test.pl
@@ -0,0 +1,403 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+
+sub count_strings
+{
+ my $log_file = shift;
+ my $find_str = shift;
+ open my $fh, '<', $log_file or die $!;
+ my $cnt=0;
+ while (<$fh>)
+ {
+ $f = quotemeta($find_str);
+ $cnt += $_ =~ /$f/;
+ }
+ print STDERR "INFO: Count - [$cnt]\n";
+ close $fh;
+ return($cnt);
+}
+
+sub test_1
+{
+# Test 1:
+# This is a test for the creation of initial_pool_threads.
+# The test will start up a server with default pool values
+# and will result in 5 initial threads being started.
+
+ my $server = shift;
+ my $client = shift;
+ my $iorbase = shift;
+ my $deletelogs = shift;
+ my $status = 0;
+
+ print "\nRunning Test 1....\n";
+ $test_num=1;
+
+ my $lfname = "server_test" . $test_num . ".log";
+ my $scname = "svc" . $test_num . ".conf";
+ my $server_iorfile = $server->LocalFile ($iorbase);
+ my $client_iorfile = $client->LocalFile ($iorbase);
+ my $server_logfile = $server->LocalFile ($lfname);
+ my $svc_conf = $server->LocalFile($scname);
+
+ $server->DeleteFile($lfname);
+
+ $SV = $server->CreateProcess ("server", " -ORBDebugLevel 5 -ORBLogFile $server_logfile -s 3 -p {-1,5,-1,0,60,0} -o $server_iorfile");
+ $SC = $client->CreateProcess ("client", "-k file://$client_iorfile -s");
+
+ $server_status = $SV->Spawn ();
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+
+ if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ $client_status = $SC->SpawnWaitKill ($client->ProcessStopWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client $i returned $client_status\n";
+ }
+
+ # Now find the spawned threads in the log file.
+
+ $find_this="DTP_Task::svc() New thread created.";
+ $found_cnt=0;
+
+ my($found_cnt) = count_strings($server_logfile,$find_this);
+
+ if ($found_cnt != 5) {
+ print STDERR "ERROR: initial_pool_thread test failed w/$found_cnt instead of 5\n";
+ $status = 1;
+ }
+ elsif ($deletelogs) {
+ $server->DeleteFile($lfname);
+ }
+
+ $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server->DeleteFile($iorbase);
+ $client->DeleteFile($iorbase);
+
+ return($status);
+}
+
+sub test_2
+{
+ # Test 2:
+ # This is a test for showing a process maintaining a min_pool_threads after
+ # the creation of initial_pool_threads is higher. This test will also
+ # exercise the thread_idle_time (timeout).
+ # The test will start up a server with 10 init_pool_threads and 5 min_pool_threads.
+ # After 10 seconds, 5 threads should expire leaving the minimum 5 threads.
+
+
+ my $server = shift;
+ my $client = shift;
+ my $iorbase = shift;
+ my $deletelogs = shift;
+ my $status = 0;
+
+
+ print "\nRunning Test 2....\n";
+ $test_num=2;
+ my $lfname = "server_test" . $test_num . ".log";
+ my $scname = "svc" . $test_num . ".conf";
+ my $server_iorfile = $server->LocalFile ($iorbase);
+ my $client_iorfile = $client->LocalFile ($iorbase);
+ my $server_logfile = $server->LocalFile ($lfname);
+ my $svc_conf = $server->LocalFile($scname);
+
+ $server->DeleteFile($lfname);
+
+ $SV = $server->CreateProcess ("server", " -ORBDebugLevel 5 -ORBLogFile $server_logfile -s 3 -p {5,10,-1,0,10,0} -o $server_iorfile");
+ $SC = $client->CreateProcess ("client", "-k file://$client_iorfile -s");
+
+ $server_status = $SV->Spawn ();
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+
+ if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ # Sleep here for more than the timeout to let the threads die off and log.
+ print STDERR "INFO: sleeping 15 seconds\n";
+ sleep(15);
+
+ $client_status = $SC->SpawnWaitKill ($client->ProcessStopWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client $i returned $client_status\n";
+ }
+ # Now find the spawned threads in the log file.
+
+ $find_this="DTP_Task::svc() Existing thread expiring.";
+ $found_cnt=0;
+
+ my($found_cnt) = count_strings($server_logfile,$find_this);
+
+ if ($found_cnt != 5) {
+ print STDERR "ERROR: min_pool_thread test failed w/$found_cnt instead of 5\n";
+ $status = 1;
+ }
+ elsif ($deletelogs) {
+ $server->DeleteFile($lfname);
+ }
+
+ $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server->DeleteFile($iorbase);
+ $client->DeleteFile($iorbase);
+
+ return($status);
+}
+
+sub test_3
+{
+ # Test 3:
+ # This is a test for showing a process maintaining a max_request_queue_depth after
+ # more clients request service than the queue allows for.
+ # The test will start up a server with a max_request_queue_depth of 10 and
+ # will issue calls from 15 clients. There should be 5 CORBA exceptions found
+ # in the log after the run.
+ #
+ my $server = shift;
+ my $client = shift;
+ my $iorbase = shift;
+ my $deletelogs = shift;
+ my $status = 0;
+
+ print "\nRunning Test 3....\n";
+ $test_num=3;
+ $num_clients=15;
+ my $lfname = "server_test" . $test_num . ".log";
+ my $scname = "svc" . $test_num . ".conf";
+ my $server_iorfile = $server->LocalFile ($iorbase);
+ my $client_iorfile = $client->LocalFile ($iorbase);
+ my $server_logfile = $server->LocalFile ($lfname);
+ my $svc_conf = $server->LocalFile($scname);
+
+ $server->DeleteFile($lfname);
+
+ $SV = $server->CreateProcess ("server", " -ORBDebugLevel 5 -ORBLogFile $server_logfile -s 3 -p {-1,15,-1,0,10,10} -o $server_iorfile");
+
+ $server_status = $SV->Spawn ();
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+
+ if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ for ($i = 0; $i < $num_clients; $i++) {
+ $CLS[$i] = $client->CreateProcess ("client", "-c $i -k file://$client_iorfile -e 0");
+ $CLS[$i]->Spawn ();
+ }
+
+ my $valid_num_exceptions=5;
+ my $num_exceptions=0;
+
+ for ($i = 0; $i < $num_clients; $i++) {
+
+ $client_status = $CLS[$i]->WaitKill ($client->ProcessStopWaitInterval());
+
+ if ($client_status != 0) {
+ $num_exceptions++;
+ print STDERR "STATUS: client $i returned $client_status\n";
+ }
+ }
+
+ $SC = $client->CreateProcess ("client", "-k file://$client_iorfile -s");
+ $client_status = $SC->SpawnWaitKill ($client->ProcessStopWaitInterval());
+ if ($client_status != 0) {
+ print STDERR "ERROR: client $i returned $client_status\n";
+ }
+
+ if ($num_exceptions != $valid_num_exceptions)
+ {
+ print STDERR "ERROR: max_request_queue_depth test failed w/$num_exceptions instead of $valid_num_exceptions\n";
+ $status = 1;
+ }
+ elsif ($deletelogs) {
+ $server->DeleteFile($lfname);
+ }
+
+
+ $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server->DeleteFile($iorbase);
+ $client->DeleteFile($iorbase);
+
+ return($status);
+}
+
+sub test_4
+{
+
+ # Test 4:
+ # This is a test for showing a process maintaining a max_pool_threads after
+ # more clients request service than the queue allows for.
+ # The test will start up a server with a max_request_queue_depth of 10 and
+ # will issue calls from 10 clients. There should be 5 CORBA exceptions found
+ # in the log after the run.
+ #
+
+ my $server = shift;
+ my $client = shift;
+ my $iorbase = shift;
+ my $deletelogs = shift;
+ my $status = 0;
+
+ print "\nRunning Test 4....\n";
+ $test_num=4;
+ $num_clients=10;
+ my $lfname = "server_test" . $test_num . ".log";
+ my $scname = "svc" . $test_num . ".conf";
+ my $server_iorfile = $server->LocalFile ($iorbase);
+ my $client_iorfile = $client->LocalFile ($iorbase);
+ my $server_logfile = $server->LocalFile ($lfname);
+ my $svc_conf = $server->LocalFile($scname);
+
+ $server->DeleteFile($lfname);
+
+ $SV = $server->CreateProcess ("server", " -ORBDebugLevel 5 -ORBLogFile $server_logfile -s 5 -p {-1,1,5,0,60,10} -o $server_iorfile");
+ $SC = $client->CreateProcess ("client", "-k file://$client_iorfile -s");
+
+ $server_status = $SV->Spawn ();
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+
+ if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ for ($i = 0; $i < $num_clients; $i++) {
+ $CLS[$i] = $client->CreateProcess ("client", "-c $i -k file://$client_iorfile");
+ $CLS[$i]->Spawn ();
+ }
+
+
+ for ($i = 0; $i < $num_clients; $i++) {
+
+ $client_status = $CLS[$i]->WaitKill ($client->ProcessStopWaitInterval());
+
+ if ($client_status != 0) {
+ print STDERR "ERROR: client $i returned $client_status\n";
+ }
+ }
+
+ $client_status = $SC->SpawnWaitKill ($client->ProcessStopWaitInterval());
+
+ # Now find the spawned threads in the log file.
+
+ $find_this="Growing threadcount.";
+ $found_cnt=0;
+ $valid_cnt=4;
+
+ my($found_cnt) = count_strings($server_logfile,$find_this);
+
+ if ($found_cnt != $valid_cnt) {
+ print STDERR "ERROR: max_pool_thread test failed w/$found_cnt instead of $valid_cnt\n";
+ $status = 1;
+ }
+ elsif ($deletelogs) {
+ $server->DeleteFile($lfname);
+ }
+
+ $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+ $server->DeleteFile($iorbase);
+ $client->DeleteFile($iorbase);
+ return($status);
+}
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+my $iorbase = "server.ior";
+my $server_iorfile = $server->LocalFile ($iorbase);
+my $client_iorfile = $client->LocalFile ($iorbase);
+my $deletelogs = 1;
+
+$server->DeleteFile($iorbase);
+$client->DeleteFile($iorbase);
+
+my $status = 0;
+
+# Each test below will start up a server and optionally some clients.
+# When a server gets a call it will sleep some number of seconds before responding.
+# The -s parameter controls how many seconds it will sleep.
+# The order is mandatory and must not contain spaces. It is defined as follows:
+# min_pool_threads
+# initial_pool_threads
+# max_pool_threads
+# thread_stack_size
+# thread_timeout (in seconds)
+# max_queue_request_depth
+
+ while ()
+ {
+ $status = test_1($server, $client, $iorbase, $deletelogs);
+ last if ($status);
+ $status = test_2($server, $client, $iorbase, $deletelogs);
+ last if ($status);
+ $status = test_3($server, $client, $iorbase, $deletelogs);
+ last if ($status);
+ $status = test_4($server, $client, $iorbase, $deletelogs);
+ last;
+ }
+
+$server->DeleteFile($iorbase);
+$client->DeleteFile($iorbase);
+
+exit $status;
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/server.cpp b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/server.cpp
new file mode 100644
index 00000000000..0e6b309f82b
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Dynamic_TP_POA_Test_Static/server.cpp
@@ -0,0 +1,196 @@
+// $Id$
+
+#include "Hello.h"
+#include "tao/Dynamic_TP/DTP_POA_Strategy.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/Thread_Manager.h"
+
+const ACE_TCHAR *ior_output_file = ACE_TEXT ("server.ior");
+int sleep_sec = 1;
+
+// The parms below must be in a particular order for this test.
+// min_threads_ = -1;
+// init_threads_ = 1;
+// max_threads_ = -1;
+// stack_size_ = 0;
+// timeout_ = 60;
+// queue_depth_ = 0;
+
+const ACE_TCHAR *parms = "{-1,1,-1,0,60,0}";
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:s:p:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+ case 'p':
+ parms = get_opts.opt_arg ();
+ break;
+ case 's':
+ sleep_sec = ACE_OS::strtol(get_opts.opt_arg (),NULL,0);
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-o <iorfile>"
+ "-p (parm array)"
+ "-s (# sec to sleep)"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+void
+set_parms ( TAO_DTP_Definition * this_config)
+{
+ ACE_TCHAR *sep;
+ long val;
+
+ // Get past the brace
+ val = ACE_OS::strtol(parms,&sep,10);
+ // min_threads_ = -1;
+ this_config->min_threads_ = ACE_OS::strtol(sep+1,&sep,10);
+
+ // init_threads_ = 1;
+ this_config->init_threads_ = ACE_OS::strtol(sep+1,&sep,10);
+
+ // max_threads_ = 1;
+ this_config->max_threads_ = ACE_OS::strtol(sep+1,&sep,10);
+
+ // stack_size_ = 0;
+ this_config->stack_size_ = ACE_OS::strtol(sep+1,&sep,10);
+
+ // timeout_ = 60;
+ this_config->timeout_.set(ACE_OS::strtol(sep+1,&sep,10),0);
+
+ // queue_depth_ = 0;
+ this_config->queue_depth_ = ACE_OS::strtol(sep+1,&sep,10);
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA");
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in ());
+
+ if (CORBA::is_nil (root_poa.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Panic: nil RootPOA\n"),
+ 1);
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager ();
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+
+ TAO_DTP_Definition dtp_config;
+
+ set_parms(&dtp_config);
+
+ //dtp_config.min_threads_ = -1;
+ //dtp_config.init_threads_ = 5;
+ //dtp_config.max_threads_ = -1;
+ //dtp_config.stack_size_ = (40 * 1024);
+ //dtp_config.timeout_.set(10,0);
+ //dtp_config.queue_depth_ = 10;
+
+ ACE_DEBUG((LM_INFO,ACE_TEXT("TAO (%P|%t) - Server : min_threads_ = %d\n"),dtp_config.min_threads_));
+ ACE_DEBUG((LM_INFO,ACE_TEXT("TAO (%P|%t) - Server : init_threads_ = %d\n"),dtp_config.init_threads_));
+ ACE_DEBUG((LM_INFO,ACE_TEXT("TAO (%P|%t) - Server : max_threads_ = %d\n"),dtp_config.max_threads_));
+ ACE_DEBUG((LM_INFO,ACE_TEXT("TAO (%P|%t) - Server : stack_size_ = %d\n"),dtp_config.stack_size_));
+ ACE_DEBUG((LM_INFO,ACE_TEXT("TAO (%P|%t) - Server : timeout_ = %d\n"),dtp_config.timeout_.sec()));
+ ACE_DEBUG((LM_INFO,ACE_TEXT("TAO (%P|%t) - Server : queue_depth_ = %d\n"),dtp_config.queue_depth_));
+ ACE_DEBUG((LM_INFO,ACE_TEXT("TAO (%P|%t) - Server : sleep_sec = %d\n"),sleep_sec));
+
+ // Create the thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO_DTP_POA_Strategy> csd_strategy =
+ new TAO_DTP_POA_Strategy(&dtp_config, false);
+
+ // Tell the strategy to apply itself to the child poa.
+ if (csd_strategy->apply_to(root_poa.in()) == false)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to root poa.\n"));
+ return -1;
+ }
+
+ Hello *hello_impl;
+ ACE_NEW_RETURN (hello_impl,
+ Hello (orb.in ()),
+ 1);
+ PortableServer::ServantBase_var owner_transfer(hello_impl);
+
+ PortableServer::ObjectId_var id =
+ root_poa->activate_object (hello_impl);
+
+ CORBA::Object_var object = root_poa->id_to_reference (id.in ());
+
+ Test::Hello_var hello =
+ Test::Hello::_narrow (object.in ());
+
+ CORBA::String_var ior =
+ orb->object_to_string (hello.in ());
+
+ ACE_DEBUG ((LM_DEBUG,"Server calling poa_manager::activate()\n"));
+ poa_manager->activate ();
+
+ // Output the IOR to the <ior_output_file>
+ FILE *output_file= ACE_OS::fopen (ior_output_file, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file %s for writing IOR: %C",
+ ior_output_file,
+ ior.in ()),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+
+
+ ACE_DEBUG ((LM_DEBUG,"Server calling hello->sleep_sec()\n"));
+ // Set the sleep time for the Hello object
+ hello->sleep_sec(sleep_sec);
+
+ ACE_DEBUG ((LM_DEBUG,"Server calling orb::run()\n"));
+ orb->run ();
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop finished\n"));
+ // Wait for all CSD task threads exit.
+ ACE_Thread_Manager::instance ()->wait ();
+
+ root_poa->destroy (1, 1);
+
+ orb->destroy ();
+
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/POA_Loader.mpc b/TAO/tests/Dynamic_TP/POA_Loader/POA_Loader.mpc
new file mode 100644
index 00000000000..5ab8a83701c
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/POA_Loader.mpc
@@ -0,0 +1,5 @@
+// $Id$
+
+project(*test) : dynamic_tp,csd_framework {
+ exename = test
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/Test.cpp b/TAO/tests/Dynamic_TP/POA_Loader/Test.cpp
new file mode 100644
index 00000000000..538f19b126e
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/Test.cpp
@@ -0,0 +1,102 @@
+// $Id$
+
+#include "tao/Dynamic_TP/DTP_POA_Strategy.h"
+#include "tao/CSD_Framework/CSD_Strategy_Repository.h"
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/Service_Config.h"
+#include "ace/Dynamic_Service.h"
+#include <iostream>
+#include "tao/debug.h"
+
+void
+show_tp_config (const ACE_CString &name, const TAO_DTP_Definition &entry)
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Config set for %C:\n"), name.c_str()));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Initial threads: %d:\n"), entry.init_threads_));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Min threads: %d:\n"), entry.min_threads_));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Max threads: %d:\n"), entry.max_threads_));
+ if (entry.min_threads_ > -1)
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Idle Timeout: %d (sec)\n"), entry.timeout_.sec()));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Stack Size: %d:\n"), entry.stack_size_));
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Request queue max depth: %d\n"), entry.queue_depth_));
+}
+
+//void
+//show_poa_config (const ACE_CString &name, TAO_DTP_POA_Strategy * strat)
+//{
+ //ACE_DEBUG ((LM_INFO, ACE_TEXT ("POA [%C] has the configuration key [%C]\n"), name.c_str(),strat->get_tp_config().c_str()));
+ //ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Initial threads: %d:\n"), entry.init_threads_));
+ //ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Min threads: %d:\n"), entry.min_threads_));
+ //ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Max threads: %d:\n"), entry.max_threads_));
+ //if (entry.min_threads_ > -1)
+ // ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Idle Timeout: %d (sec)\n"), entry.timeout_));
+ //ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Stack Size: %d:\n"), entry.stack_size_));
+ //ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" Request queue max depth: %d\n"), entry.queue_depth_));
+//}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ TAO_debug_level = 1;
+
+ ACE_Service_Config::open (argc, argv);
+
+ // Dump the POA to Strategy map
+ TAO_CSD_Strategy_Repository* dtp_poa_strat_repo =
+ ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance
+ ("TAO_CSD_Strategy_Repository");
+
+ if (dtp_poa_strat_repo == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Unable to load configuration\n")));
+ return -1;
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("TAO_CSD_Strategy_Repository found\n")));
+ }
+
+
+ // Now iterate through the repository and attempt to find sample POA configurations
+
+ const ACE_TCHAR *poa_list [] =
+ { ACE_TEXT ("MyPOA"), // should find this one
+ ACE_TEXT ("POA2"), // shouldn't find this one
+ ACE_TEXT ("MyPOA3"), // should find this one
+ ACE_TEXT ("MyPOA1"), // should find this one
+ 0
+ };
+
+ TAO_DTP_POA_Strategy * mapped_strategy;
+
+ for (int i = 0; poa_list[i] != 0; i++)
+ {
+ mapped_strategy = 0;
+ ACE_DEBUG ((LM_INFO, ACE_TEXT("Config definition for %C\n"), poa_list[i]));
+ mapped_strategy = dynamic_cast <TAO_DTP_POA_Strategy*> (dtp_poa_strat_repo->find (poa_list[i]));
+ if ((mapped_strategy == 0) && (i != 1) && (i != 3))
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Cannot find TP Config definition for %C\n"), poa_list[i]));
+ continue;
+ }
+ if (i == 1 || i == 3)
+ {
+ if (mapped_strategy)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Found TP Config definition for %C which should have failed\n"), poa_list[i]));
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Config definition for %C not found as expected\n"), poa_list[i]));
+ }
+ }
+ else
+ {
+ //show_poa_config (poa_list[i], mapped_strategy);
+ }
+ }
+
+
+ return 0;
+}
diff --git a/TAO/tests/Dynamic_TP/POA_Loader/svc.conf b/TAO/tests/Dynamic_TP/POA_Loader/svc.conf
new file mode 100644
index 00000000000..664f8220087
--- /dev/null
+++ b/TAO/tests/Dynamic_TP/POA_Loader/svc.conf
@@ -0,0 +1,15 @@
+# $Id$
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName ORB -DTPMin 5 -DTPInit 6 -DTPMax 10 -DTPTimeout 240 -DTPStack 10240 -DTPQueue 20"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPMin 2 -DTPInit 4 -DTPMax 10 -DTPQueue 10"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPOverwrite 1 -DTPMin 7 -DTPMax 14 "
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName POA1 -DTPMin 7 -DTPMax 11 -DPQueue 14"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName defaults"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m1 -DTPMin 3"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m2 -DTPMax 10"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m3 -DTPTimeout 120"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m4 -DTPMin 3 -DTPInit 7 -DTPMax 10 -DTPTimeout 120"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m5 -DTPMin 3 -DTPInit 10 -DTPTimeout 30"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m6 -DTPInit 6 -DTPMax -1"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName m7 -DTPInit 7"
+dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName bogus -DTPMin 6 -DTPInit 3"
+dynamic DTP_POA_Loader Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_POA_Loader() "-DTPPOAConfigMap MyPOA,MyPOA2,MyPOA3:POA1"
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.cpp b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.cpp
new file mode 100644
index 00000000000..250ee6a55d4
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.cpp
@@ -0,0 +1,26 @@
+// $Id$
+#include "Hello.h"
+#include <iostream>
+
+Hello::Hello (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+{
+}
+
+char *
+Hello::get_string (void)
+{
+ return CORBA::string_dup ("Hello there!");
+}
+
+void
+Hello::set_string (const char * s)
+{
+ std::cout << "Call to Hello::set_string (" << s << ")" << std::endl;
+}
+
+void
+Hello::shutdown (void)
+{
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.h b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.h
new file mode 100644
index 00000000000..ad83199b24e
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Hello.h
@@ -0,0 +1,33 @@
+//
+// $Id$
+//
+
+#ifndef HELLO_H
+#define HELLO_H
+#include /**/ "ace/pre.h"
+
+#include "TestS.h"
+
+/// Implement the Test::Hello interface
+class Hello
+ : public virtual POA_Test::Hello
+{
+public:
+ /// Constructor
+ Hello (CORBA::ORB_ptr orb);
+
+ // = The skeleton methods
+ virtual char * get_string (void);
+
+ virtual void set_string (const char * s);
+
+ virtual void shutdown (void);
+
+private:
+ /// Use an ORB reference to convert strings to objects and shutdown
+ /// the application.
+ CORBA::ORB_var orb_;
+};
+
+#include /**/ "ace/post.h"
+#endif /* HELLO_H */
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/README b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/README
new file mode 100644
index 00000000000..a12accca62a
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/README
@@ -0,0 +1,14 @@
+$Id$
+
+ This tests shows that by using -ORBForwardOnTransientLimit and -ORBForwardDelay
+ options on a client, the client will retry establishing
+ a connection to a server before throwing a TRANSIENT exception.
+
+ This is done by having the client start first, wait a few seconds, and then
+ start the server.
+
+ To run the test use the run_test.pl script:
+
+$ ./run_test.pl
+
+ the script returns 0 if the test was successful.
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Retry_On_Connection_Failure.mpc b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Retry_On_Connection_Failure.mpc
new file mode 100644
index 00000000000..0b23fc42f14
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Retry_On_Connection_Failure.mpc
@@ -0,0 +1,37 @@
+// -*- MPC -*-
+// $Id$
+
+project(*idl): taoidldefaults {
+ idlflags += -Sp
+ IDL_Files {
+ Test.idl
+ }
+ custom_only = 1
+}
+
+project(*Server): taoserver, iortable {
+ after += *idl
+ Source_Files {
+ Hello.cpp
+ server.cpp
+ }
+ Source_Files {
+ TestC.cpp
+ TestS.cpp
+ }
+ IDL_Files {
+ }
+}
+
+project(*Client): taoclient {
+ after += *idl
+ Source_Files {
+ client.cpp
+ }
+ Source_Files {
+ TestC.cpp
+ }
+ IDL_Files {
+ }
+}
+
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Test.idl b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Test.idl
new file mode 100644
index 00000000000..c546c828670
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/Test.idl
@@ -0,0 +1,22 @@
+//
+// $Id$
+//
+
+/// Put the interfaces in a module, to avoid global namespace pollution
+module Test
+{
+ /// A very simple interface
+ interface Hello
+ {
+ /// Return a simple string
+ string get_string ();
+
+ /// A oneway operation takes a
+ /// different path to get to a TRANSIENT
+ /// exception.
+ oneway void set_string (in string s);
+
+ /// Shutdown the ORB
+ oneway void shutdown ();
+ };
+};
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/client.cpp b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/client.cpp
new file mode 100644
index 00000000000..c2fa3ae7849
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/client.cpp
@@ -0,0 +1,87 @@
+// $Id$
+
+#include "TestC.h"
+#include "ace/Get_Opt.h"
+
+const ACE_TCHAR *ior = ACE_TEXT ("file://test.ior");
+bool oneway_call = false;
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:o:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'k':
+ ior = get_opts.opt_arg ();
+ break;
+
+ case 'o':
+ oneway_call = ACE_OS::atoi (get_opts.opt_arg ()) != 0;
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-k <ior> "
+ "-o <oneway flag> "
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ CORBA::Object_var tmp = orb->string_to_object(ior);
+
+ Test::Hello_var hello = Test::Hello::_narrow(tmp.in ());
+
+ if (CORBA::is_nil (hello.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Nil Test::Hello reference <%s>\n",
+ ior),
+ 1);
+ }
+
+ if (oneway_call)
+ {
+ CORBA::String_var the_string = CORBA::string_dup( "Test" );
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) - Client sending string <%C> oneway\n",
+ the_string.in ()));
+ hello->set_string (the_string);
+ }
+ else
+ {
+ CORBA::String_var the_string = hello->get_string ();
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) - Client getting string <%C>\n",
+ the_string.in ()));
+ }
+
+ hello->shutdown ();
+
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/run_test.pl b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/run_test.pl
new file mode 100755
index 00000000000..7436a6abe30
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/run_test.pl
@@ -0,0 +1,104 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+$status = 0;
+$debug_level = '0';
+$cdebug_level = '0';
+$oneway_call = 0;
+foreach $i (@ARGV) {
+ if ($i eq '-oneway') {
+ $oneway_call = 1;
+ }
+ if ($i eq '-debug') {
+ $debug_level = '10';
+ }
+ if ($i eq '-cdebug') {
+ $cdebug_level = '10';
+ }
+}
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+
+my $iorbase = "server.ior";
+my $host = $server->HostName();
+my $port = $server->RandomPort();
+my $endpoint = $host . ":" . $port;
+my $server_iorfile = $server->LocalFile ($iorbase);
+my $client_iorfile = $client->LocalFile ($iorbase);
+$server->DeleteFile($iorbase);
+$client->DeleteFile($iorbase);
+
+$SV = $server->CreateProcess ("server", "-ORBdebuglevel $debug_level " .
+ "-o $server_iorfile " .
+ "-ORBEndpoint iiop://$endpoint");
+
+$CL = $client->CreateProcess ("client", "-ORBdebuglevel $debug_level " .
+ "-o $oneway_call " .
+ "-ORBForwardOnTransientLimit 20 " .
+ "-ORBForwardDelay 500 " .
+ "-k corbaloc::$endpoint/Simple_Server");
+
+print STDERR $CL->CommandLine () . "\n";
+$client_status = $CL->Spawn ();
+
+if ($client_status != 0) {
+ print STDERR "ERROR: client returned $client_status\n";
+ $status = 1;
+}
+
+print "Waiting to start server\n";
+
+sleep(2);
+
+print STDERR $SV->CommandLine () . "\n";
+$server_status = $SV->Spawn ();
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+}
+
+if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+if ($server->GetFile ($iorbase) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+if ($client->PutFile ($iorbase) == -1) {
+ print STDERR "ERROR: cannot set file <$client_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+$server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+}
+
+$client_status = $CL->WaitKill ($client->ProcessStopWaitInterval());
+
+if ($client_status != 0) {
+ print STDERR "ERROR: client returned $client_status\n";
+ $status = 1;
+}
+
+$server->DeleteFile($iorbase);
+$client->DeleteFile($iorbase);
+
+exit $status;
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/server.cpp b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/server.cpp
new file mode 100644
index 00000000000..c08c71cb744
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Connection_Failure/server.cpp
@@ -0,0 +1,115 @@
+// $Id$
+
+#include "Hello.h"
+#include "tao/IORTable/IORTable.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+
+const ACE_TCHAR *ior_output_file = ACE_TEXT ("test.ior");
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-o <iorfile>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA");
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in ());
+
+ if (CORBA::is_nil (root_poa.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Panic: nil RootPOA\n"),
+ 1);
+
+ PortableServer::POAManager_var poa_manager = root_poa->the_POAManager ();
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ Hello *hello_impl = 0;
+ ACE_NEW_RETURN (hello_impl,
+ Hello (orb.in ()),
+ 1);
+ PortableServer::ServantBase_var owner_transfer(hello_impl);
+
+ PortableServer::ObjectId_var id =
+ root_poa->activate_object (hello_impl);
+
+ CORBA::Object_var object = root_poa->id_to_reference (id.in ());
+
+ Test::Hello_var hello = Test::Hello::_narrow (object.in ());
+
+ CORBA::String_var ior = orb->object_to_string (hello.in ());
+
+ CORBA::Object_var table_object =
+ orb->resolve_initial_references("IORTable");
+
+ IORTable::Table_var table =
+ IORTable::Table::_narrow (table_object.in ());
+ if (CORBA::is_nil (table.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Unable to initialize the IORTable.\n"),
+ 1);
+ table->bind ("Simple_Server", ior.in ());
+
+ // Output the IOR to the <ior_output_file>
+ FILE *output_file= ACE_OS::fopen (ior_output_file, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file for writing IOR: %s\n",
+ ior_output_file),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+
+ poa_manager->activate ();
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop starting\n"));
+
+ orb->run ();
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop finished\n"));
+
+ root_poa->destroy (1, 1);
+
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/README b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/README
new file mode 100755
index 00000000000..b24ca308f8c
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/README
@@ -0,0 +1,23 @@
+/**
+
+$Id$
+
+@page Retry_On_Reply_Failure Test README File
+
+ This is test for the invocation retry feature when a client
+ receives OBJECT_NOT_EXIST, COMM_FAILURE, TRANSIENT or INV_OBJREF
+ exceptions from server as a reply to a request.
+ This feature can be enabled and disabled by -ORBForwardOnObjectNotExistLimit
+ -ORBForwardOnCommFailureLimit, -ORBForwardOnOnTransientLimit and
+ -ORBForwardOnInvObjLimit options with value 0(disable) and 1(enable).
+
+ The starting point for this test implementation was the
+ ForwardOnceUponException test.
+
+ To execute the test simply run:
+
+$ ./run_test.pl
+
+ the script returns 0 on success and non-zero on failures.
+
+*/
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/Retry_On_Reply_Failure.mpc b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/Retry_On_Reply_Failure.mpc
new file mode 100755
index 00000000000..ee705f01845
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/Retry_On_Reply_Failure.mpc
@@ -0,0 +1,35 @@
+// -*- MPC -*-
+// $Id$
+
+project(*idl): taoidldefaults {
+ IDL_Files {
+ test.idl
+ }
+ custom_only = 1
+}
+
+project(*Server): taoserver, iortable {
+ after += *idl
+ Source_Files {
+ test_i.cpp
+ server.cpp
+ }
+ Source_Files {
+ testC.cpp
+ testS.cpp
+ }
+ IDL_Files {
+ }
+}
+
+project(*Client): taoclient, anytypecode {
+ after += *idl
+ Source_Files {
+ client.cpp
+ }
+ Source_Files {
+ testC.cpp
+ }
+ IDL_Files {
+ }
+}
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/client.cpp b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/client.cpp
new file mode 100755
index 00000000000..ecd2d0df42d
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/client.cpp
@@ -0,0 +1,278 @@
+// $Id$
+
+#include "testC.h"
+#include "ace/Get_Opt.h"
+#include "ace/Task.h"
+#include "ace/streams.h"
+#include "tao/Invocation_Utils.h"
+#include "ace/OS_NS_unistd.h"
+
+const ACE_TCHAR *ior = ACE_TEXT("file://test.ior");
+int nthreads = 1;
+static const ACE_TCHAR corbaloc_prefix[] = ACE_TEXT("corbaloc:");
+int expect_ex_kind = TAO::FOE_NON;
+int num_requests = 1;
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:e:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'k':
+ ior = get_opts.opt_arg ();
+ break;
+
+ case 'e':
+ expect_ex_kind = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-k <ior>"
+ "-e <expected exception kind> "
+ "\n",
+ argv [0]),
+ -1);
+ }
+
+ if (ACE_OS::strncmp (ior,
+ corbaloc_prefix,
+ ACE_OS::strlen(corbaloc_prefix)) != 0)
+ return 1;
+
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+class Worker : public ACE_Task_Base
+{
+public:
+ Worker (CORBA::ORB_ptr orb);
+ // Constructor
+
+ // = The Task_Base methods
+ virtual int svc (void);
+
+ // Caught any exception ?
+ int received_ex_kind () const;
+
+ // Return number of received exceptions.
+ int num_received_ex () const;
+
+ // Indicate if the invocation completed.
+ bool invocation_completed () const;
+
+ // Is test done ?
+ void done ();
+
+private:
+
+ // The ORB reference
+ CORBA::ORB_var orb_;
+ // The exceptions caught.
+ int received_ex_kind_;
+ // The number of received exceptions.
+ int num_received_ex_;
+ // Flag indicating that the invocation was completed.
+ bool invocation_completed_;
+ // Flag for test completion. The result is
+ // collected before done.
+ bool done_;
+};
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ Worker worker (orb.in ());
+
+ if (worker.activate (THR_NEW_LWP | THR_JOINABLE,
+ nthreads) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Cannot activate worker threads\n"),
+ 1);
+
+ int timeout = 30;
+ int now = 0;
+ while (now < timeout &&
+ ((expect_ex_kind == 0 && !worker.invocation_completed ()) ||
+ (expect_ex_kind != 0 && expect_ex_kind != worker.received_ex_kind ()))
+ )
+ {
+ std::cout << "." << std::flush;
+ now += 1;
+ ACE_Time_Value tv (1, 0);
+ orb->run (tv);
+ }
+ ACE_ASSERT (now != 0);
+
+
+ std::cout << std::endl;
+
+ worker.done ();
+
+ CORBA::Object_var object =
+ orb->string_to_object (ior);
+
+ Simple_Server_var server =
+ Simple_Server::_narrow (object.in ());
+
+ server->shutdown ();
+
+ ACE_OS::sleep (1);
+
+ orb->destroy ();
+
+ worker.thr_mgr ()->wait ();
+
+
+ bool expect_no_ex =
+ expect_ex_kind == TAO::FOE_NON && worker.num_received_ex () == 0 && worker.invocation_completed ();
+ bool expect_ex_received =
+ expect_ex_kind == worker.received_ex_kind () && worker.num_received_ex () > 0 && !worker.invocation_completed ();
+ if (expect_no_ex || expect_ex_received)
+ {
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)client: test passed.\n"));
+ return 0;
+ }
+ else
+ {
+ ACE_DEBUG ((LM_ERROR, "(%P|%t)client: test failed.\n"));
+ return 1;
+ }
+ }
+
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught in main:");
+ return 1;
+ }
+
+ return 0;
+}
+
+// ****************************************************************
+
+Worker::Worker (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb)),
+ received_ex_kind_ (TAO::FOE_NON),
+ num_received_ex_ (0),
+ invocation_completed_ (false),
+ done_ (false)
+{
+}
+
+int
+Worker::svc (void)
+{
+ try
+ {
+ CORBA::Object_var object =
+ this->orb_->string_to_object (ior);
+
+ Simple_Server_var server =
+ Simple_Server::_narrow (object.in ());
+
+ if (CORBA::is_nil (server.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Object reference <%s> is nil.\n",
+ ior));
+ return 0;
+ }
+
+ try {
+ CORBA::Boolean r =
+ server->test_is_a ("IDL:Foo:1.0");
+
+ this->invocation_completed_ = true;
+
+ if (r != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) unexpected result = %d\n",
+ r));
+
+ }
+ catch (const CORBA::OBJECT_NOT_EXIST &)
+ {
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)received OBJECT_NOT_EXIST \n"));
+ if (!this->done_)
+ {
+ ++ this->num_received_ex_;
+ received_ex_kind_ |= TAO::FOE_OBJECT_NOT_EXIST;
+ }
+ }
+ catch (const CORBA::COMM_FAILURE &)
+ {
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)received COMM_FAILURE \n"));
+ if (!this->done_)
+ {
+ ++ this->num_received_ex_;
+ received_ex_kind_ |= TAO::FOE_COMM_FAILURE;
+ }
+ }
+ catch (const CORBA::TRANSIENT &)
+ {
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)received TRANSIENT \n"));
+ if (!this->done_)
+ {
+ ++ this->num_received_ex_;
+ received_ex_kind_ |= TAO::FOE_TRANSIENT;
+ }
+ }
+ catch (const CORBA::INV_OBJREF &)
+ {
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)received INV_OBJREF \n"));
+ if (!this->done_)
+ {
+ ++ this->num_received_ex_;
+ received_ex_kind_ |= TAO::FOE_INV_OBJREF;
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Unexpected exception caught");
+ }
+
+ return 0;
+}
+
+
+int
+Worker::received_ex_kind () const
+{
+ return received_ex_kind_;
+}
+
+int
+Worker::num_received_ex () const
+{
+ return num_received_ex_;
+}
+
+bool
+Worker::invocation_completed () const
+{
+ return invocation_completed_;
+}
+
+void
+Worker::done ()
+{
+ done_ = true;
+}
+
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl
new file mode 100755
index 00000000000..4f779484bd7
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/run_test.pl
@@ -0,0 +1,152 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+$status = 0;
+$debug_level = '0';
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $debug_level = '10';
+ }
+}
+
+# Current supported forward once exceptions:
+# EF_OBJECT_NOT_EXIST = 0x1,
+# EF_COMM_FAILURE = 0x2,
+# EF_TRANSIENT = 0x4,
+# EF_INV_OBJREF = 0x8,
+@configurations = ({
+ description => "case 1: retry on OBJECT_NOT_EXIST exceptions until no failure",
+ orb_invocation_retry_opts => "-ORBForwardOnObjectNotExistLimit 10 -ORBForwardDelay 50",
+ client_expect_ex_kind => "0",
+ server_raise_ex_kind => "1",
+ num_exceptions_to_throw => 2,
+ },{
+ description => "case 2: retry on OBJECT_NOT_EXIST exceptions and give up",
+ orb_invocation_retry_opts => "-ORBForwardOnObjectNotExistLimit 1 -ORBForwardDelay 50",
+ client_expect_ex_kind => "1",
+ server_raise_ex_kind => "1",
+ num_exceptions_to_throw => 2,
+ },{
+ description => "case 3: retry on COMM_FAILURE exceptions until no failure",
+ orb_invocation_retry_opts => "-ORBForwardOnCommFailureLimit 10 -ORBForwardDelay 50",
+ client_expect_ex_kind => "0",
+ server_raise_ex_kind => "2",
+ num_exceptions_to_throw => 2,
+ },{
+ description => "case 4: retry on COMM_FAILURE exceptions and give up",
+ orb_invocation_retry_opts => "-ORBForwardOnCommFailureLimit 1 -ORBForwardDelay 50",
+ client_expect_ex_kind => "2",
+ server_raise_ex_kind => "2",
+ num_exceptions_to_throw => 2,
+ },{
+ description => "case 5: retry on TRANSIENT exceptions until no failure",
+ orb_invocation_retry_opts => "-ORBForwardOnTransientLimit 10 -ORBForwardDelay 50",
+ client_expect_ex_kind => "0",
+ server_raise_ex_kind => "4",
+ num_exceptions_to_throw => 2,
+ },{
+ description => "case 6: retry on TRANSIENT exceptions and give up",
+ orb_invocation_retry_opts => "-ORBForwardOnTransientLimit 1 -ORBForwardDelay 50",
+ client_expect_ex_kind => "4",
+ server_raise_ex_kind => "4",
+ num_exceptions_to_throw => 2,
+ },{
+ description => "case 7: retry on INV_OBJREF exceptions until no failure",
+ orb_invocation_retry_opts => "-ORBForwardOnInvObjrefLimit 10 -ORBForwardDelay 50",
+ client_expect_ex_kind => "0",
+ server_raise_ex_kind => "8",
+ num_exceptions_to_throw => 2,
+ },{
+ description => "case 8: retry on INV_OBJREF exceptions and give up",
+ orb_invocation_retry_opts => "-ORBForwardOnInvObjrefLimit 1 -ORBForwardDelay 50",
+ client_expect_ex_kind => "8",
+ server_raise_ex_kind => "8",
+ num_exceptions_to_throw => 2,
+ },
+
+
+
+ );
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+
+my $iorbase = "test.ior";
+my $host = $server->HostName();
+my $server_iorfile = $server->LocalFile ($iorbase);
+my $client_iorfile = $client->LocalFile ($iorbase);
+
+for $test (@configurations) {
+ print STDERR "\n==== Running $test->{description} \n\n";
+
+ my $port = $server->RandomPort();
+ $server->DeleteFile($iorbase);
+ $client->DeleteFile($iorbase);
+
+ $SV = $server->CreateProcess ("server", "-ORBdebuglevel $debug_level ".
+ "-o $server_iorfile ".
+ "-ORBEndpoint iiop://$host:$port ".
+ "-e $test->{server_raise_ex_kind} ".
+ "-n $test->{num_exceptions_to_throw}");
+
+ $CL = $client->CreateProcess ("client", "-k corbaloc::$host:$port/Simple_Server ".
+ "-e $test->{client_expect_ex_kind} ".
+ "$test->{orb_invocation_retry_opts}");
+
+ print STDERR $SV->CommandLine () . "\n";
+ print STDERR $CL->CommandLine () . "\n";
+
+ $server_status = $SV->Spawn ();
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+ }
+
+ if ($server->WaitForFileTimed ($iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ if ($server->GetFile ($iorbase) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$server_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ if ($client->PutFile ($iorbase) == -1) {
+ print STDERR "ERROR: cannot set file <$client_iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+
+ $client_status = $CL->SpawnWaitKill ($client->ProcessStartWaitInterval() + 45);
+
+ if ($client_status != 0) {
+ print STDERR "ERROR: client returned $client_status\n";
+ $status = 1;
+ }
+
+ $server_status = $SV->WaitKill ($server->ProcessStopWaitInterval());
+
+ if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+ }
+
+}
+
+$server->DeleteFile($iorbase);
+$client->DeleteFile($iorbase);
+
+exit $status;
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/server.cpp b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/server.cpp
new file mode 100755
index 00000000000..295e3bd018d
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/server.cpp
@@ -0,0 +1,121 @@
+// $Id$
+
+#include "test_i.h"
+#include "tao/IORTable/IORTable.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+#include "tao/Invocation_Utils.h"
+
+const ACE_TCHAR *ior_output_file = ACE_TEXT("test.ior");
+int num_exceptions_to_throw = 0;
+int raise_exception = TAO::FOE_NON;
+int num_requests = 1;
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:e:n:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+ case 'e':
+ raise_exception = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case 'n':
+ num_exceptions_to_throw = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-o <iorfile> -e <raise_exception> -n <num_exceptions_to_throw>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv);
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA");
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in ());
+ if (CORBA::is_nil (root_poa.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Unable to initialize the POA.\n"),
+ 1);
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager ();
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ Simple_Server_i server_impl (orb.in (), num_exceptions_to_throw);
+
+ PortableServer::ObjectId_var id =
+ root_poa->activate_object (&server_impl);
+
+ CORBA::Object_var object = root_poa->id_to_reference (id.in ());
+
+ Simple_Server_var server =
+ Simple_Server::_narrow (object.in ());
+
+ CORBA::String_var ior =
+ orb->object_to_string (server.in ());
+
+ CORBA::Object_var table_object =
+ orb->resolve_initial_references("IORTable");
+
+ IORTable::Table_var table =
+ IORTable::Table::_narrow (table_object.in ());
+ if (CORBA::is_nil (table.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Unable to initialize the IORTable.\n"),
+ 1);
+ table->bind ("Simple_Server", ior.in ());
+
+ //ACE_DEBUG ((LM_DEBUG, "Activated as <%C>\n", ior.in ()));
+
+ FILE *output_file= ACE_OS::fopen (ior_output_file, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file for writing IOR: %s",
+ ior_output_file),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+
+ poa_manager->activate ();
+
+ orb->run ();
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)server: event loop finished\n"));
+
+ root_poa->destroy (1, 1);
+
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught in server:");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test.idl b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test.idl
new file mode 100755
index 00000000000..b9aa7108ed3
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test.idl
@@ -0,0 +1,8 @@
+// $Id$
+
+interface Simple_Server
+{
+ boolean test_is_a (in string type);
+
+ oneway void shutdown ();
+};
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.cpp b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.cpp
new file mode 100755
index 00000000000..042b552b16d
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.cpp
@@ -0,0 +1,58 @@
+// $Id$
+
+#include "test_i.h"
+#include "tao/Invocation_Utils.h"
+
+extern int raise_exception;
+
+Simple_Server_i::Simple_Server_i (CORBA::ORB_ptr orb, int num_exceptions_to_throw)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+ , num_exceptions_to_throw_(num_exceptions_to_throw)
+ , num_exceptions_thrown_(0)
+ , raise_exception_ (TAO::FOE_NON)
+{
+}
+
+CORBA::Boolean
+Simple_Server_i::test_is_a (const char * /* type */)
+{
+ if (this->num_exceptions_thrown_ ==
+ this->num_exceptions_to_throw_)
+ return 0;
+
+ if ((raise_exception & TAO::FOE_OBJECT_NOT_EXIST) == TAO::FOE_OBJECT_NOT_EXIST)
+ {
+ //ACE_DEBUG ((LM_DEBUG, "(%P|%t) test_is_a called and raise OBJECT_NOT_EXIST\n"));
+ ++this->num_exceptions_thrown_;
+ throw ::CORBA::OBJECT_NOT_EXIST (CORBA::OMGVMCID | 1, CORBA::COMPLETED_NO);
+ }
+
+ if ((raise_exception & TAO::FOE_COMM_FAILURE) == TAO::FOE_COMM_FAILURE)
+ {
+ //ACE_DEBUG ((LM_DEBUG, "(%P|%t) test_is_a called and raise COMM_FAILURE\n"));
+ ++this->num_exceptions_thrown_;
+ throw ::CORBA::COMM_FAILURE (CORBA::OMGVMCID | 1, CORBA::COMPLETED_NO);
+ }
+
+ if ((raise_exception & TAO::FOE_TRANSIENT) == TAO::FOE_TRANSIENT)
+ {
+ //ACE_DEBUG ((LM_DEBUG, "(%P|%t) \t called and raise TRANSIENT\n"));
+ ++this->num_exceptions_thrown_;
+ throw ::CORBA::TRANSIENT (CORBA::OMGVMCID | 1, CORBA::COMPLETED_NO);
+ }
+
+ if ((raise_exception & TAO::FOE_INV_OBJREF) == TAO::FOE_INV_OBJREF)
+ {
+ //ACE_DEBUG ((LM_DEBUG, "(%P|%t) test_is_a called %d and raise INV_OBJREF\n", ncalls_));
+ ++this->num_exceptions_thrown_;
+ throw ::CORBA::INV_OBJREF (CORBA::OMGVMCID | 1, CORBA::COMPLETED_NO);
+ }
+
+ return 0;
+}
+
+void
+Simple_Server_i::shutdown (void)
+{
+ this->orb_->shutdown (0);
+}
diff --git a/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.h b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.h
new file mode 100755
index 00000000000..8bc654aab28
--- /dev/null
+++ b/TAO/tests/Multiple_Retry_Tests/Retry_On_Reply_Failure/test_i.h
@@ -0,0 +1,46 @@
+
+//=============================================================================
+/**
+ * @file test_i.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+//=============================================================================
+
+
+#ifndef TAO_RETRY_ON_REPLY_FAILURE_I_H
+#define TAO_RETRY_ON_REPLY_FAILURE_I_H
+
+#include "testS.h"
+
+/**
+ * @class Simple_Server_i
+ *
+ * @brief Simpler Server implementation
+ *
+ * Implements the Simple_Server interface in test.idl
+ */
+class Simple_Server_i : public POA_Simple_Server
+{
+public:
+ /// ctor
+ Simple_Server_i (CORBA::ORB_ptr orb, int num_exceptions_to_throw);
+
+ // = The Simple_Server methods.
+ CORBA::Boolean test_is_a (const char * type);
+
+ void shutdown (void);
+
+private:
+ /// The ORB
+ CORBA::ORB_var orb_;
+
+ int num_exceptions_to_throw_;
+ int num_exceptions_thrown_;
+
+ int raise_exception_;
+};
+
+#endif /* TAO_RETRY_ON_REPLY_FAILURE_I_H */
diff --git a/TAO/tests/POA/Non_Retain_System_Id/Non_Retain_System_Id.mpc b/TAO/tests/POA/Non_Retain_System_Id/Non_Retain_System_Id.mpc
new file mode 100644
index 00000000000..f4e31f3dfd0
--- /dev/null
+++ b/TAO/tests/POA/Non_Retain_System_Id/Non_Retain_System_Id.mpc
@@ -0,0 +1,6 @@
+// -*- MPC -*-
+// $Id$
+
+project(POA*): taoserver, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro {
+ exename = test
+}
diff --git a/TAO/tests/POA/Non_Retain_System_Id/run_test.pl b/TAO/tests/POA/Non_Retain_System_Id/run_test.pl
new file mode 100755
index 00000000000..18bd124e73a
--- /dev/null
+++ b/TAO/tests/POA/Non_Retain_System_Id/run_test.pl
@@ -0,0 +1,22 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+
+$SV = $server->CreateProcess ("test");
+
+$test = $SV->SpawnWaitKill ($server->ProcessStartWaitInterval());
+
+if ($test != 0) {
+ print STDERR "ERROR: test returned $test\n";
+ exit 1;
+}
+
+exit 0;
diff --git a/TAO/tests/POA/Non_Retain_System_Id/test.cpp b/TAO/tests/POA/Non_Retain_System_Id/test.cpp
new file mode 100644
index 00000000000..95b5a5614ff
--- /dev/null
+++ b/TAO/tests/POA/Non_Retain_System_Id/test.cpp
@@ -0,0 +1,215 @@
+
+//=============================================================================
+/**
+ * @file test.cpp
+ *
+ * $Id$
+ *
+ * This program verifies that a POA using the NON_RETAIN policy creates
+ * unique system IDs, also that objects created with a USER id policy is
+ * not given a bo
+ *
+ * @author Phil Mesnier
+ */
+//=============================================================================
+
+
+#include "testS.h"
+#include "ace/SString.h"
+#include "tao/PortableServer/POA_Current.h"
+
+class ID_Check_i : public POA_ID_Check
+{
+public:
+ ID_Check_i (int num);
+ ~ID_Check_i (void);
+
+ void set_id (int index, PortableServer::ObjectId_var oid);
+
+ CORBA::Boolean check_servant_id (CORBA::Short index);
+
+private:
+ int count_;
+ PortableServer::ObjectId_var * oids_;
+ PortableServer::Current_var current_;
+};
+
+ID_Check_i::ID_Check_i (int num)
+ : count_ (num),
+ oids_ (0),
+ current_ ()
+{
+ int argc = 0;
+ char **argv = 0;
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
+ CORBA::Object_var obj = orb->resolve_initial_references ("POACurrent");
+ current_ = PortableServer::Current::_narrow (obj.in());
+
+ oids_ = new PortableServer::ObjectId_var[num];
+}
+
+ID_Check_i::~ID_Check_i (void)
+{
+ delete [] oids_;
+}
+
+void
+ID_Check_i::set_id (int index, PortableServer::ObjectId_var oid)
+{
+ this->oids_[index] = oid;
+}
+
+CORBA::Boolean
+ID_Check_i::check_servant_id (CORBA::Short index)
+{
+ if (index < 0 || index >= this->count_)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("check_servant_id: requested index outside of range\n")));
+ return false;
+ }
+ PortableServer::ObjectId_var oid = this->current_->get_object_id();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("check_servant_id: index = %d current objectid ")
+ ACE_TEXT ("len %d octets: "),
+ index, oid->length()));
+ for (size_t i = 0; i < oid->length () && i < 16; i++)
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT("%02x "), oid[i]));
+ ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("\n")));
+
+ if (oid->length() != this->oids_[index]->length())
+ return false;
+ for (size_t i = 0; i < oid->length(); i++)
+ {
+ if (oid[i] != this->oids_[index][i])
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("check_servant_id: id[%d] mismatch at position %d, ")
+ ACE_TEXT ("got %d, expected %d\n"),
+ index, i, oid[i], this->oids_[index][i]));
+ return false;
+ }
+ }
+ return true;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ // Initialize the ORB.
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
+
+ // Obtain the RootPOA.
+ CORBA::Object_var object =
+ orb->resolve_initial_references ("RootPOA");
+
+ // Narrow to POA.
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (object.in ());
+
+ // Get the POAManager of the RootPOA.
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager ();
+
+ // Policies for the new POA.
+ CORBA::PolicyList policies (4);
+ policies.length (3);
+
+ // Request Processing Policy.
+ policies[0] =
+ root_poa->create_request_processing_policy (PortableServer::USE_DEFAULT_SERVANT);
+
+ // Id Uniqueness Policy.
+ policies[1] =
+ root_poa->create_id_uniqueness_policy (PortableServer::MULTIPLE_ID);
+
+ // Servant Retention Policy.
+ policies[2] =
+ root_poa->create_servant_retention_policy (PortableServer::NON_RETAIN);
+
+ // Create POA to host default servant.
+ ACE_CString name = "System IDs";
+ PortableServer::POA_var sys_id_poa =
+ root_poa->create_POA (name.c_str (),
+ poa_manager.in (),
+ policies);
+
+ policies.length (4);
+ policies[3] =
+ root_poa->create_id_assignment_policy (PortableServer::USER_ID);
+
+ name = "User IDs";
+ PortableServer::POA_var user_id_poa =
+ root_poa->create_POA (name.c_str (),
+ poa_manager.in (),
+ policies);
+
+ // Destroy policies.
+ for (CORBA::ULong i = 0; i < policies.length (); ++i)
+ {
+ CORBA::Policy_ptr policy = policies[i];
+ policy->destroy ();
+ }
+
+ int objcount = 30;
+
+ ID_Check_i *servant = new ID_Check_i (objcount);
+ sys_id_poa->set_servant (servant);
+ user_id_poa->set_servant (servant);
+
+ // Activate POA manager.
+ poa_manager->activate ();
+
+ // Create object array.
+ ID_Check_var *refs = new ID_Check_var[objcount];
+ PortableServer::ObjectId_var obj_id;
+ char *user_id_str = new char[10];
+
+ for (int i = 0; i < objcount; i++)
+ {
+ if (i < objcount / 2)
+ {
+ object = sys_id_poa->create_reference ("IDL:ID_Check:1.0");
+ refs[i] = ID_Check::_narrow (object.in());
+ obj_id = sys_id_poa->reference_to_id (object);
+ servant->set_id (i, obj_id);
+ }
+ else
+ {
+ ACE_OS::sprintf (user_id_str, "id %d", i);
+ obj_id = PortableServer::string_to_ObjectId (user_id_str);
+ object = user_id_poa->create_reference_with_id (obj_id.in(),
+ "IDL:ID_Check:1.0");
+ refs[i] = ID_Check::_narrow (object.in());
+ servant->set_id (i, obj_id);
+ }
+ }
+
+ int successes = 0;
+ for (int i = 0; i < objcount; i++)
+ {
+ successes += refs[i]->check_servant_id (i) ? 1 : 0;
+ }
+
+ orb->destroy ();
+
+ if (successes != objcount)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("FAILURE: only got %d ids correct out of %d\n"),
+ successes, objcount));
+ return -1;
+ }
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Success: All ids match\n")));
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/POA/Non_Retain_System_Id/test.idl b/TAO/tests/POA/Non_Retain_System_Id/test.idl
new file mode 100644
index 00000000000..8fb4acbb8ee
--- /dev/null
+++ b/TAO/tests/POA/Non_Retain_System_Id/test.idl
@@ -0,0 +1,6 @@
+// $Id$
+
+interface ID_Check
+{
+ boolean check_servant_id (in short index);
+};
diff --git a/TAO/tests/Storable/README b/TAO/tests/Storable/README
new file mode 100644
index 00000000000..b5086ded191
--- /dev/null
+++ b/TAO/tests/Storable/README
@@ -0,0 +1,14 @@
+$Id$
+
+This test verifies that TAO::Storable_FlatFileStream along
+with TAO::Storable_File_Guard can be used to save/restore
+the state of an object (an instance of Savable) to the
+file system. To verifing Storable_File_Guard's file locking,
+two processes that read/write from the persistent store run
+in parallel.
+
+Note that this test does not explicitly validate the code in
+Storable_File_Guard that deals with the persistent store
+being obsolete.
+
+
diff --git a/TAO/tests/Storable/Savable.cpp b/TAO/tests/Storable/Savable.cpp
new file mode 100644
index 00000000000..6ec1318a6ae
--- /dev/null
+++ b/TAO/tests/Storable/Savable.cpp
@@ -0,0 +1,228 @@
+// $Id$
+
+#include "Savable.h"
+#include "tao/Storable_Base.h"
+#include "tao/Storable_Factory.h"
+#include "tao/Storable_File_Guard.h"
+
+const int Savable::bytes_size_max = 128;
+
+class Savable_File_Guard: public TAO::Storable_File_Guard
+{
+public:
+
+ Savable_File_Guard (Savable & savable, Method_Type method_type);
+
+ ~Savable_File_Guard ();
+
+ virtual void set_object_last_changed (const time_t & time);
+
+ virtual time_t get_object_last_changed ();
+
+ virtual void load_from_stream ();
+
+ virtual bool is_loaded_from_stream ();
+
+ virtual TAO::Storable_Base * create_stream (const char * mode);
+
+private:
+ Savable & savable_;
+};
+
+Savable_File_Guard::Savable_File_Guard (Savable & savable,
+ Method_Type method_type)
+ : TAO::Storable_File_Guard(false)
+ , savable_(savable)
+{
+ try
+ {
+ this->init(method_type);
+ }
+ catch (TAO::Storable_Read_Exception &)
+ {
+ throw Savable_Exception();
+ }
+}
+
+Savable_File_Guard::~Savable_File_Guard ()
+{
+ this->release ();
+}
+
+void
+Savable_File_Guard::set_object_last_changed (const time_t & time)
+{
+ savable_.last_changed_ = time;
+}
+
+time_t
+Savable_File_Guard::get_object_last_changed ()
+{
+ return savable_.last_changed_;
+}
+
+void
+Savable_File_Guard::load_from_stream ()
+{
+ savable_.read (this->peer ());
+ savable_.loaded_from_stream_ = true;
+ this->peer ().rewind ();
+}
+
+bool
+Savable_File_Guard::is_loaded_from_stream ()
+{
+ return savable_.loaded_from_stream_;
+}
+
+TAO::Storable_Base *
+Savable_File_Guard::create_stream (const char * mode)
+{
+ return savable_.storable_factory_.create_stream ("test.dat", mode);
+}
+
+typedef TAO::Storable_File_Guard SFG;
+
+Savable::Savable (TAO::Storable_Factory & storable_factory)
+ : storable_factory_(storable_factory)
+ , loaded_from_stream_ (false)
+{
+
+ for (int index = 0; index < 2; ++index)
+ {
+ this->i_[index] = 0;
+ this->ui_[index] = 0;
+ this->bytes_size_[index] = 0;
+ this->bytes_[index] = new char [this->bytes_size_max];
+ for (int i = 0; i < this->bytes_size_max; ++i)
+ {
+ this->bytes_[index][i] = ACE_CHAR_MAX;
+ }
+ }
+
+ ACE_Auto_Ptr<TAO::Storable_Base>
+ stream (storable_factory_.create_stream("test.dat", "r"));
+ if (stream->exists ())
+ {
+ Savable_File_Guard fg(*this, SFG::CREATE_WITH_FILE);
+ }
+ else
+ {
+ Savable_File_Guard fg(*this, SFG::CREATE_WITHOUT_FILE);
+ this->write (fg.peer ());
+ }
+}
+
+Savable::~Savable ()
+{
+ for (int index = 0; index < 2; ++index)
+ {
+ delete []this->bytes_[index];
+ }
+}
+
+bool
+Savable::is_loaded_from_stream ()
+{
+ return this->loaded_from_stream_;
+}
+
+void
+Savable::read (TAO::Storable_Base & stream)
+{
+ stream.rewind ();
+
+ for (int index = 0; index < 2; ++index)
+ {
+ stream >> this->string_[index];
+ stream >> this->i_[index];
+ stream >> this->ui_[index];
+ stream >> this->bytes_size_[index];
+ stream.read (this->bytes_size_[index], this->bytes_[index]);
+ }
+}
+
+void
+Savable::write (TAO::Storable_Base & stream)
+{
+ stream.rewind ();
+
+ for (int index = 0; index < 2; ++index)
+ {
+ stream << this->string_[index];
+ stream << this->i_[index];
+ stream << this->ui_[index];
+ stream << this->bytes_size_[index];
+ stream.write (this->bytes_size_[index], this->bytes_[index]);
+ }
+
+ stream.flush ();
+}
+
+void
+Savable::string_set (int index, const ACE_CString &s)
+{
+ Savable_File_Guard fg(*this, SFG::MUTATOR);
+ this->string_[index] = s;
+ this->write (fg.peer ());
+}
+
+const ACE_CString &
+Savable::string_get (int index)
+{
+ Savable_File_Guard fg(*this, SFG::ACCESSOR);
+ return this->string_[index];
+}
+
+void
+Savable::int_set (int index, int i)
+{
+ Savable_File_Guard fg(*this, SFG::MUTATOR);
+ this->i_[index] = i;
+ this->write (fg.peer ());
+}
+
+int
+Savable::int_get (int index)
+{
+ Savable_File_Guard fg(*this, SFG::ACCESSOR);
+ return this->i_[index];
+}
+
+void
+Savable::unsigned_int_set (int index, unsigned int ui)
+{
+ Savable_File_Guard fg(*this, SFG::MUTATOR);
+ this->ui_[index] = ui;
+ this->write (fg.peer ());
+}
+
+unsigned int
+Savable::unsigned_int_get (int index)
+{
+ Savable_File_Guard fg(*this, SFG::ACCESSOR);
+ return this->ui_[index];
+}
+
+void
+Savable::bytes_set (int index, int size, char * bytes)
+{
+ Savable_File_Guard fg(*this, SFG::MUTATOR);
+ this->bytes_size_[index] = size;
+ for (int i = 0; i < this->bytes_size_[index]; ++i)
+ {
+ this->bytes_[index][i] = bytes[i];
+ }
+ this->write (fg.peer ());
+}
+
+int
+Savable::bytes_get (int index, char * bytes)
+{
+ Savable_File_Guard fg(*this, SFG::ACCESSOR);
+ for (int i = 0; i < this->bytes_size_[index]; ++i)
+ {
+ bytes[i] = this->bytes_[index][i];
+ }
+ return this->bytes_size_[index];
+}
diff --git a/TAO/tests/Storable/Savable.h b/TAO/tests/Storable/Savable.h
new file mode 100644
index 00000000000..c227e90639e
--- /dev/null
+++ b/TAO/tests/Storable/Savable.h
@@ -0,0 +1,61 @@
+// $Id$
+
+#include "tao/Storable_Base.h"
+
+#include "ace/SString.h"
+
+namespace TAO
+{
+ class Storable_Factory;
+}
+
+class Savable_Exception
+{
+};
+
+/// A simple class to use for testing whose contents
+/// are to be persisted. It has attributes for each basic
+/// type that can be saved.
+/// There are two attributes for each type so that
+/// one process can write one attribute of the same
+/// type while another process reads another attribute
+/// of the same type.
+class Savable
+{
+ public:
+ Savable (TAO::Storable_Factory & storable_factory);
+
+ ~Savable ();
+
+ void string_set (int index, const ACE_CString &s);
+ const ACE_CString & string_get (int index);
+
+ void int_set (int index, int i);
+ int int_get (int index);
+
+ void unsigned_int_set (int index, unsigned int ui);
+ unsigned int unsigned_int_get (int index);
+
+ void bytes_set (int index, int size, char * bytes);
+ int bytes_get (int index, char * bytes);
+
+ bool is_loaded_from_stream ();
+
+ private:
+ TAO::Storable_Factory & storable_factory_;
+ bool loaded_from_stream_;
+ time_t last_changed_;
+ void read (TAO::Storable_Base & stream);
+ void write (TAO::Storable_Base & stream);
+
+ ACE_CString string_[2];
+ int i_[2];
+ unsigned int ui_[2];
+
+ static const int bytes_size_max;
+ int bytes_size_[2];
+ char * bytes_[2];
+
+ friend class Savable_File_Guard;
+};
+
diff --git a/TAO/tests/Storable/Storable.mpc b/TAO/tests/Storable/Storable.mpc
new file mode 100644
index 00000000000..8dc0de72161
--- /dev/null
+++ b/TAO/tests/Storable/Storable.mpc
@@ -0,0 +1,6 @@
+// -*- MPC -*-
+// $Id$
+
+project : taoclient {
+ exename = test
+}
diff --git a/TAO/tests/Storable/data_files/bad_binary.dat b/TAO/tests/Storable/data_files/bad_binary.dat
new file mode 100644
index 00000000000..eda0d4e6b50
--- /dev/null
+++ b/TAO/tests/Storable/data_files/bad_binary.dat
@@ -0,0 +1,6 @@
+11
+test_string
+-100
+100
+8
+  \ No newline at end of file
diff --git a/TAO/tests/Storable/data_files/bad_int.dat b/TAO/tests/Storable/data_files/bad_int.dat
new file mode 100644
index 00000000000..19e69d4a464
--- /dev/null
+++ b/TAO/tests/Storable/data_files/bad_int.dat
@@ -0,0 +1,3 @@
+11
+test_string
+-10 \ No newline at end of file
diff --git a/TAO/tests/Storable/data_files/bad_string.dat b/TAO/tests/Storable/data_files/bad_string.dat
new file mode 100644
index 00000000000..0519db270cc
--- /dev/null
+++ b/TAO/tests/Storable/data_files/bad_string.dat
@@ -0,0 +1,2 @@
+11
+test_st \ No newline at end of file
diff --git a/TAO/tests/Storable/data_files/bad_unsigned_int.dat b/TAO/tests/Storable/data_files/bad_unsigned_int.dat
new file mode 100644
index 00000000000..c3dcc1cdc45
--- /dev/null
+++ b/TAO/tests/Storable/data_files/bad_unsigned_int.dat
@@ -0,0 +1,4 @@
+11
+test_string
+-100
+10 \ No newline at end of file
diff --git a/TAO/tests/Storable/data_files/good.dat b/TAO/tests/Storable/data_files/good.dat
new file mode 100644
index 00000000000..a34d7bdac3e
--- /dev/null
+++ b/TAO/tests/Storable/data_files/good.dat
@@ -0,0 +1,11 @@
+11
+test_string
+-100
+100
+8
+ 11
+test_string
+-100
+100
+8
+  \ No newline at end of file
diff --git a/TAO/tests/Storable/run_test.pl b/TAO/tests/Storable/run_test.pl
new file mode 100755
index 00000000000..10d340d34e6
--- /dev/null
+++ b/TAO/tests/Storable/run_test.pl
@@ -0,0 +1,156 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+use File::Copy;
+
+my $status = 0;
+
+my $test1 = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+
+my $stdout_file = "test.out";
+my $stderr_file = "test.err";
+my $test_stdout_file = $test1->LocalFile ($stdout_file);
+my $test_stderr_file = $test1->LocalFile ($stderr_file);
+
+sub cat_file($)
+{
+ my $file_name = shift;
+ if (-s $file_name ) # size of file is greater than zero
+ {
+ open TESTFILE, $file_name or die "Couldn't open file: $!";
+ my @teststring = <TESTFILE>; # read in all of the file
+ print STDERR "\n@teststring\n";
+ close TESTFILE;
+ }
+}
+
+sub redirect_output()
+{
+ open (OLDOUT, ">&", \*STDOUT) or die "Can't dup STDOUT: $!";
+ open (OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!";
+ open STDERR, '>', $test_stderr_file;
+ open STDOUT, '>', $test_stdout_file;
+}
+
+sub restore_output()
+{
+ open (STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!";
+ open (STDOUT, ">&OLDOUT") or die "Can't dup OLDOUT: $!";
+}
+
+
+my $persistent_file = "test.dat";
+$test1->DeleteFile ($persistent_file);
+
+my $num_loops = 5;
+my $loop_sleep_msec = 200;
+
+if ($#ARGV >= 0) {
+ for (my $i = 0; $i <= $#ARGV; $i++) {
+ if ($ARGV[$i] eq '-num_loops') {
+ $i++;
+ $num_loops = $ARGV[$i];
+ }
+ elsif ($ARGV[$i] eq "-loop_sleep") {
+ $i++;
+ $loop_sleep_msec = $ARGV[$i];
+ }
+ else {
+ print "Usage: run_test.pl ".
+ "[-num_loops <num=$num_loops>] ".
+ "[-loop_sleep <msec=$loop_sleep_msec>]\n";
+ exit 1;
+ }
+ }
+}
+
+$T1 = $test1->CreateProcess ("test", "-i 0 -n $num_loops");
+
+my $test2 = PerlACE::TestTarget::create_target (2) || die "Create target 1 failed\n";
+
+$T2 = $test2->CreateProcess ("test", "-i 1 -n $num_loops -s $loop_sleep_msec");
+
+$test1_status = $T1->Spawn ();
+
+if ($test1_status != 0) {
+ print STDERR "ERROR: test 1 returned $test1_status\n";
+ $status = 1;
+}
+
+$test2_status = $T2->SpawnWaitKill ($test2->ProcessStartWaitInterval());
+
+if ($test2_status != 0) {
+ print STDERR "ERROR: test 2 returned $test2_status\n";
+ $status = 1;
+}
+
+$test1_status = $T1->WaitKill ($test1->ProcessStopWaitInterval());
+
+if ($test1_status != 0) {
+ print STDERR "ERROR: test 1 returned $test1_status\n";
+ $status = 1;
+}
+
+$test1->DeleteFile ($persistent_file);
+
+sub test_backup_recovery($)
+{
+ my $bad_file = shift;
+
+ my $status = 0;
+
+ print STDERR "Testing recovery of backup file for $bad_file.\n";
+
+ my $backup_file = "test.dat.bak";
+ copy($bad_file, "test.dat") or die "Copy failed: $!";
+ copy("data_files/good.dat", $backup_file) or die "Copy failed: $!";
+
+ $T = $test1->CreateProcess ("test", "-b");
+ # Redirect output so that expected error messages are not interpreted as
+ # test failure and rely instead of return status.
+ redirect_output();
+ my $test_status = $T->SpawnWaitKill ($test1->ProcessStartWaitInterval());
+ restore_output();
+ if ($test_status != 0) {
+ $status = 1;
+ print STDERR "ERROR: Backup recovery test using $bad_file failed\n";
+ cat_file($test_stderr_file);
+ cat_file($test_stdout_file);
+ }
+ else {
+ print STDERR "Recovery successful\n";
+ }
+
+ if (-e $backup_file) {
+ $test1->DeleteFile ($backup_file);
+ }
+ else {
+ $status = 1;
+ print STDERR "ERROR: Backup file was not created\n";
+ }
+ $test1->DeleteFile ($persistent_file);
+ $test1->DeleteFile ($stdout_file);
+ $test1->DeleteFile ($stderr_file);
+ return $status;
+}
+
+@bad_files = (
+ "data_files/bad_binary.dat",
+ "data_files/bad_int.dat",
+ "data_files/bad_string.dat",
+ "data_files/bad_unsigned_int.dat"
+ );
+
+foreach $bad_file (@bad_files) {
+ if (test_backup_recovery ($bad_file) != 0) {
+ $status = 1;
+ }
+}
+
+exit $status
diff --git a/TAO/tests/Storable/test.cpp b/TAO/tests/Storable/test.cpp
new file mode 100644
index 00000000000..d9f74cb7763
--- /dev/null
+++ b/TAO/tests/Storable/test.cpp
@@ -0,0 +1,188 @@
+// $Id$
+
+// Assumed to be one of two processes that
+// writes/reads from persistent store.
+// Each process writes one group of attributes
+// and reads from the group written by the
+// other process. After reading a check is
+// made that expected values are read.
+// A sleep is done at the end of the loop
+// to account for limitation in resolution
+// of timestamp on file used to determine
+// if the file is stale.
+
+#include "Savable.h"
+
+#include "tao/Storable_FlatFileStream.h"
+
+#include "ace/Get_Opt.h"
+
+#include "ace/OS_NS_unistd.h"
+
+#include <iostream>
+
+const ACE_TCHAR *persistence_file = ACE_TEXT("test.dat");
+
+int num_loops = 1;
+int sleep_msecs = 100;
+int write_index = 0;
+bool use_backup = false;
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("n:s:i:b"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'n':
+ num_loops = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+
+ case 's':
+ sleep_msecs = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+
+ case 'i':
+ write_index = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+
+ case 'b':
+ use_backup = true;
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT("usage: %s ")
+ ACE_TEXT("-n <number-of-loops> ")
+ ACE_TEXT("-s <milliseconds-to-sleep-in-loop> ")
+ ACE_TEXT("-i <index-used-for-writing> ")
+ ACE_TEXT("-b (use backup) ")
+ ACE_TEXT("\n"),
+ argv [0]),
+ -1);
+ }
+
+ if (write_index != 0 && write_index != 1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT("Error: Value passed to -i should be ")
+ ACE_TEXT("0 or 1.")),
+ -1);
+ }
+
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ int exit_status = 0;
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ int read_index = write_index ? 0 : 1;
+
+ TAO::Storable_Base::use_backup_default = use_backup;
+
+ TAO::Storable_FlatFileFactory factory ("./");
+
+ ACE_CString str_write_value = "test_string";
+ int int_write_value = -100;
+ unsigned int unsigned_int_write_value = 100;
+
+ const int bytes_size = 8;
+ char bytes_write_value[bytes_size];
+ char bytes_read[bytes_size];
+ // Set 1st byte to 32 (ASCII space) to
+ // make sure fscanf doesn't consume it
+ // when reading the size.
+ bytes_write_value[0] = 32;
+ for (int i = 1; i < bytes_size; ++i)
+ {
+ bytes_write_value[i] = i;
+ }
+
+ ACE_Time_Value sleep_time (0, 1000*sleep_msecs);
+
+ try
+ {
+ for (int j = 0; j < num_loops; ++j)
+ {
+
+ // Constructor called num_loops times.
+ // Each time state read from persistent store.
+ Savable savable(factory);
+
+ // If the file was read, verify what was
+ // written from other process is correct.
+ if (savable.is_loaded_from_stream ())
+ {
+
+ int int_read = savable.int_get(read_index);
+ // If value read is not 0 then the other
+ // process has written to persistent store.
+ // If not, it's too soon to test.
+ if (int_read != 0)
+ {
+ ACE_ASSERT (int_read == int_write_value);
+
+ const ACE_CString & str_read = savable.string_get(read_index);
+ ACE_ASSERT (str_read == str_write_value);
+
+ unsigned int unsigned_int_read =
+ savable.unsigned_int_get (read_index);
+ ACE_ASSERT (unsigned_int_read == unsigned_int_write_value);
+
+ int bytes_read_size =
+ savable.bytes_get (read_index, bytes_read);
+ ACE_ASSERT (bytes_read_size == bytes_size);
+ for (int k = 0; k < bytes_size; ++k)
+ {
+ ACE_ASSERT (bytes_read[k] == bytes_write_value[k]);
+ }
+ }
+ }
+
+ // Write out state
+ savable.string_set(write_index, str_write_value);
+ savable.int_set(write_index, int_write_value);
+ savable.unsigned_int_set(write_index, unsigned_int_write_value);
+ savable.bytes_set(write_index, bytes_size, bytes_write_value);
+ int bytes_size = savable.bytes_get (write_index, bytes_read);
+ for (int k = 0; k < bytes_size; ++k)
+ {
+ ACE_ASSERT (bytes_read[k] == bytes_write_value[k]);
+ }
+
+ ACE_OS::sleep (sleep_time);
+ }
+ }
+
+ catch (Savable_Exception &)
+ {
+ std::cout << "Savable_Exception thrown" << std::endl;
+ exit_status = 1;
+ }
+
+ catch (TAO::Storable_Read_Exception &ex)
+ {
+ std::cout << "TAO::Storable_Read_Exception thrown with state " <<
+ ex.get_state () << std::endl;
+ exit_status = 1;
+ }
+
+ catch (TAO::Storable_Write_Exception &ex)
+ {
+ std::cout << "TAO::Storable_Write_Exception thrown with state " <<
+ ex.get_state () << std::endl;
+ exit_status = 1;
+ }
+
+ return exit_status;
+}
diff --git a/TAO/tests/Var_Deref/README.txt b/TAO/tests/Var_Deref/README.txt
new file mode 100644
index 00000000000..2f6afd2fc07
--- /dev/null
+++ b/TAO/tests/Var_Deref/README.txt
@@ -0,0 +1,8 @@
+$Id$
+
+This test is intended to demonstrate that Var types can be
+dereferenced to the pointer type using a casting operation.
+
+This behavior is dangerous in that the reference count is not
+increased by extracting the pointer, thus using for anything more than
+simple status testing should not be done.
diff --git a/TAO/tests/Var_Deref/Test.idl b/TAO/tests/Var_Deref/Test.idl
new file mode 100644
index 00000000000..b395b3a0711
--- /dev/null
+++ b/TAO/tests/Var_Deref/Test.idl
@@ -0,0 +1,19 @@
+// $Id$
+
+module Test
+{
+
+ struct FixedStruct
+ {
+ long l;
+ };
+
+ struct VarStruct
+ {
+ string st;
+ };
+
+ typedef sequence <FixedStruct> FixedSeq;
+ typedef sequence <VarStruct> VarSeq;
+
+};
diff --git a/TAO/tests/Var_Deref/Var_Deref.mpc b/TAO/tests/Var_Deref/Var_Deref.mpc
new file mode 100644
index 00000000000..05811812315
--- /dev/null
+++ b/TAO/tests/Var_Deref/Var_Deref.mpc
@@ -0,0 +1,23 @@
+// -*- MPC -*-
+// $Id$
+
+project(*idl): taoidldefaults {
+ idlflags += -Sp
+ IDL_Files {
+ Test.idl
+ }
+ custom_only = 1
+}
+
+project(*exe): taoclient {
+ exename = var_deref
+ after += *idl
+ Source_Files {
+ var_deref.cpp
+ }
+ Source_Files {
+ TestC.cpp
+ }
+ IDL_Files {
+ }
+}
diff --git a/TAO/tests/Var_Deref/var_deref.cpp b/TAO/tests/Var_Deref/var_deref.cpp
new file mode 100644
index 00000000000..d48bba980c3
--- /dev/null
+++ b/TAO/tests/Var_Deref/var_deref.cpp
@@ -0,0 +1,83 @@
+// $Id$
+
+#include "TestC.h"
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ int errors = 0;
+ Test::FixedStruct *ft = 0;
+ Test::FixedStruct_var ftvar ( new Test::FixedStruct );
+ Test::FixedStruct_var nftvar (0);
+
+ Test::FixedSeq *fs = 0;
+ Test::FixedSeq_var fsvar ( new Test::FixedSeq (0) );
+ Test::FixedSeq_var nfsvar (0);
+
+ Test::VarStruct *vt = 0;
+ Test::VarStruct_var vtvar ( new Test::VarStruct );
+ Test::VarStruct_var nvtvar (0);
+
+ Test::VarSeq *vs = 0;
+ Test::VarSeq_var vsvar (new Test::VarSeq (0) );
+ Test::VarSeq_var nvsvar (0);
+
+ ft = ftvar;
+ if (ft == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Expected a non-null FixedStruct ref, got null\n"));
+ ++errors;
+ }
+ ft = nftvar;
+ if (ft != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Expected a null FixedStruct ref, got non-null\n"));
+ ++errors;
+ }
+
+ fs = fsvar;
+ if (fs == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Expected a non-null FixedSeq ref, got null\n"));
+ ++errors;
+ }
+ fs = nfsvar;
+ if (fs != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Expected a null FixedSeq ref, got non-null\n"));
+ ++errors;
+ }
+
+ vt = vtvar;
+ if (vt == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Expected a non-null VarStruct rev, got null\n"));
+ ++errors;
+ }
+ vt = nvtvar;
+ if (vt != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Expected a null VarStruct rev, got non-null\n"));
+ ++errors;
+ }
+
+ vs = vsvar;
+ if (vs == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Expected a non-null VarSeq rev, got null\n"));
+ ++errors;
+ }
+ vs = nvsvar;
+ if (vs != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Expected a null VarSeq rev, got non-null\n"));
+ ++errors;
+ }
+
+ if (errors == 0)
+ ACE_DEBUG ((LM_DEBUG, "Success: all dereferences worked as expected\n"));
+ else
+ ACE_DEBUG ((LM_DEBUG, "Failure: %d dereferences didn't work\n", errors));
+
+ return errors;
+}
diff --git a/TAO/utils/logWalker/GIOP_Buffer.cpp b/TAO/utils/logWalker/GIOP_Buffer.cpp
new file mode 100644
index 00000000000..48f5df26530
--- /dev/null
+++ b/TAO/utils/logWalker/GIOP_Buffer.cpp
@@ -0,0 +1,597 @@
+// $Id$
+
+#include "GIOP_Buffer.h"
+#include "ace/OS_NS_string.h"
+
+static const char *size_leadin_1_5 = "GIOP v1."; //"x msg, ";
+static size_t leadin_len_1_5 = 15;
+static const char *size_leadin_1_6 = "GIOP message v1."; //2, ";
+static size_t leadin_len_1_6 = 19;
+
+
+const char *GIOP_Buffer::size_leadin = 0;
+size_t GIOP_Buffer::leadin_len = 0;
+const size_t GIOP_Buffer::giop_header_len = 12;
+
+void
+GIOP_Buffer::init_leadin (int version)
+{
+ if (size_leadin == 0)
+ {
+ if (version == 150)
+ {
+ size_leadin = size_leadin_1_5;
+ leadin_len = leadin_len_1_5;
+ }
+ else
+ {
+ size_leadin = size_leadin_1_6;
+ leadin_len = leadin_len_1_6;
+ }
+ }
+}
+
+// GIOP 1.2 header: 12 bytes
+// Magic: 4
+// ver: 2
+// flags: 1 // bo
+// type: 1 // req/repl/lf/excp
+// len: 4
+//
+// Request 1.2 header:
+// req_id: 4
+// flags: 1
+// RESVD: 3
+// Address disposition: 4
+// target: <4 len, + len> [0-3 pad]
+// opname: <4 len, + len>
+
+// GIOP 1.0 header: 12 bytes
+// Magic: 4
+// ver: 2
+// byte_order: 1
+// type: 1 // req/repl/lf/excp
+// len: 4
+//
+// Request 1.0 header:
+/*
+struct RequestHeader_1_0 { // Renamed from RequestHeader
+ IOP::ServiceContextList service_context;
+ unsigned long request_id;
+ boolean response_expected;
+ sequence <octet> object_key;
+ string operation;
+ CORBA::OctetSeq requesting_principal;
+};
+*/
+// service_context: 4(count)+contexts.
+// context id: 4
+// content blob: 4(len) + len octets + (0-3)pad
+// request_id: 4
+// respexp: 1
+// RESVD: 3
+// Address disposition: 4
+// target: <4 len, + len> [0-3 pad]
+// opname: <4 len, + len>
+
+/*
+struct ReplyHeader_1_0 { // Renamed from ReplyHeader
+ IOP::ServiceContextList service_context;
+ unsigned long request_id;
+ ReplyStatusType_1_0 reply_status;
+ };
+ // GIOP 1.1
+ typedef ReplyHeader_1_0 ReplyHeader_1_1;
+ // Same Header contents for 1.0 and 1.1
+#else
+ // GIOP 1.2, 1.3
+ enum ReplyStatusType_1_2 {
+ NO_EXCEPTION,
+ USER_EXCEPTION,
+ SYSTEM_EXCEPTION,
+ LOCATION_FORWARD,
+ LOCATION_FORWARD_PERM,// new value for 1.2
+ NEEDS_ADDRESSING_MODE // new value for 1.2
+ };
+ struct ReplyHeader_1_2 {
+ unsigned long request_id;
+ ReplyStatusType_1_2 reply_status;
+ IOP::ServiceContextList service_context;
+ };
+
+ */
+
+
+
+static const size_t target_offset_12 = GIOP_Buffer::giop_header_len + 12;
+
+// 12 = req_id + flags + RESVD + addr disp.
+
+GIOP_Buffer::GIOP_Buffer(void)
+ : cdr_ (0),
+ preamble_(),
+ log_offset_(0),
+ thr_(0),
+ time_(0),
+ expected_req_id_(0),
+ expected_size_(0),
+ expected_type_(0),
+ buffer_size_(0),
+ wr_pos_ (0),
+ octets_ (0),
+ owner_ (0),
+ buffer_lost_ (false),
+ sending_(false),
+ oid_ (0),
+ oid_len_ (0),
+ opname_ (0),
+ req_id_ (0),
+ resp_exp_ (0),
+ reply_status_ (0),
+ ver_minor_ (0),
+ msg_size_ (0),
+ num_contexts_ (0),
+ header_parsed_ (false),
+ payload_start_ (0)
+{
+}
+
+GIOP_Buffer::GIOP_Buffer(const char *text,
+ size_t offset,
+ Thread *thread,
+ Invocation *owner)
+ : cdr_ (0),
+ preamble_(text),
+ log_offset_(offset),
+ thr_(thread),
+ time_(0),
+ expected_req_id_(0),
+ expected_size_(0),
+ expected_type_(0),
+ buffer_size_(0),
+ wr_pos_ (0),
+ octets_ (0),
+ owner_ (owner),
+ buffer_lost_ (false),
+ sending_(false),
+ oid_ (0),
+ oid_len_ (0),
+ opname_ (0),
+ req_id_ (0),
+ resp_exp_ (0),
+ reply_status_ (0),
+ ver_minor_ (0),
+ msg_size_ (0),
+ num_contexts_ (0),
+ header_parsed_ (false),
+ payload_start_ (0)
+{
+ const char *size_str = ACE_OS::strstr(text, size_leadin) + leadin_len;
+ const char *id = size_str == 0 ? 0 : ACE_OS::strchr(size_str, '[') + 1;
+ this->sending_ = ACE_OS::strstr(text,"send") ? 0 : 1;
+ this->expected_type_ = ACE_OS::strstr(text,"Request") ? 0 : 1;
+ this->expected_size_ = ACE_OS::strtol(size_str, 0,10);
+ this->expected_req_id_ = ACE_OS::strtol(id, 0, 10);
+ const char *time_tok = ACE_OS::strchr (text,'@');
+ if (time_tok != 0)
+ {
+ char timebuf[30];
+ ACE_OS::strncpy(timebuf, text, (time_tok - text));
+ timebuf[time_tok - text] = 0;
+ char *hms = ACE_OS::strchr (timebuf,' ');
+ if (hms != 0)
+ {
+ int hr, min, sec, msec;
+ ::sscanf (hms+1,"%d:%d:%d.%d", &hr, &min, &sec, &msec);
+ this->time_ = (hr * 3600 + min *60 + sec) * 1000 + msec;
+ }
+ }
+}
+
+void
+GIOP_Buffer::owner (Invocation *owner)
+{
+ this->owner_ = owner;
+}
+
+Invocation *
+GIOP_Buffer::owner (void)
+{
+ return this->owner_;
+}
+
+void
+GIOP_Buffer::init_buf (const char *text, size_t offset)
+{
+ // GIOP message - HEXDUMP
+ this->log_offset_ = offset;
+ const char * size_str = ACE_OS::strstr (text,"HEXDUMP ") + 8;
+ this->buffer_size_ = ACE_OS::strtol (size_str, 0, 10);
+ size_str = ACE_OS::strstr (text,"showing first ");
+ if (size_str != 0)
+ {
+ size_str += 14;
+ this->buffer_size_ = ACE_OS::strtol (size_str, 0, 10);
+ }
+ if (this->octets_ != 0)
+ {
+ delete [] this->octets_;
+ }
+ this->octets_ = new char [this->buffer_size_];
+ ACE_OS::memset (this->octets_, 0, this->buffer_size_);
+ this->wr_pos_ = this->octets_;
+}
+
+GIOP_Buffer::~GIOP_Buffer(void)
+{
+ delete [] this->octets_;
+}
+
+int
+GIOP_Buffer::add_octets (const char *text, size_t offset)
+{
+ if (this->octets_ == 0)
+ {
+ this->init_buf(text, offset);
+ return 0;
+ }
+
+ const char *c = text;
+ char *err;
+ for (int count = 0;
+ count < 16 && this->cur_size() < this->buffer_size_;
+ count++)
+ {
+ if (count == 8)
+ ++c;
+ int o = ::strtol(c, &err, 16);
+ if (err == c || *err == 0)
+ return -1;
+ *this->wr_pos_++ = o;
+ c = err+1;
+ }
+ size_t cs = this->cur_size();
+ int rtn = 0;
+ if (!this->header_parsed_)
+ {
+ this->header_parsed_ = this->parse_header();
+ if (this->header_parsed_ )
+ rtn = 1;
+ }
+ if (cs == this->buffer_size_)
+ {
+ char vmaj = this->octets_[4];
+ char order = this->octets_[6];
+
+ delete this->cdr_;
+ this->cdr_ = new ACE_InputCDR (this->octets_,
+ this->cur_size(),
+ order, vmaj, this->ver_minor_);
+ this->cdr_->skip_bytes (this->payload_start_ - this->octets_);
+ rtn = -1;
+ }
+ return rtn;
+}
+
+bool
+GIOP_Buffer::sending (void) const
+{
+ return this->sending_;
+}
+
+bool
+GIOP_Buffer::is_full (void) const
+{
+ return this->buffer_size_ > 0 && this->cur_size() == this->buffer_size_;
+}
+
+char
+GIOP_Buffer::type (void) const
+{
+ if (this->octets_ == 0)
+ return 127;
+ return this->octets_[7];
+}
+
+char
+GIOP_Buffer::expected_type (void) const
+{
+ return this->expected_type_;
+}
+
+char
+GIOP_Buffer::minor_version (void) const
+{
+ return this->ver_minor_;
+}
+
+size_t
+GIOP_Buffer::reply_status (void) const
+{
+ return this->reply_status_;
+}
+
+size_t
+GIOP_Buffer::num_contexts (void) const
+{
+ return this->num_contexts_;
+}
+
+bool
+GIOP_Buffer::is_oneway (void)
+{
+ if (this->octets_ == 0)
+ {
+ return false;
+ }
+
+ if (!this->header_parsed_)
+ this->header_parsed_ = this->parse_header();
+
+ return (resp_exp_ &1) == 0;
+}
+
+size_t
+GIOP_Buffer::log_posn (void) const
+{
+ return this->log_offset_;
+}
+
+Thread *
+GIOP_Buffer::thread (void)
+{
+ return this->thr_;
+}
+
+time_t
+GIOP_Buffer::time (void) const
+{
+ return this->time_;
+}
+
+const ACE_CString &
+GIOP_Buffer::preamble (void) const
+{
+ return this->preamble_;
+}
+
+size_t
+GIOP_Buffer::expected_size (void) const
+{
+ return this->expected_size_;
+}
+
+size_t
+GIOP_Buffer::msg_size (void)
+{
+ if (this->cur_size() < 12)
+ return 0;
+ if (!this->header_parsed_)
+ this->header_parsed_ = this->parse_header();
+ return this->msg_size_;
+}
+
+size_t
+GIOP_Buffer::expected_req_id (void) const
+{
+ return this->expected_req_id_;
+}
+
+size_t
+GIOP_Buffer::actual_req_id (void)
+{
+ if (this->octets_ == 0)
+ return 0;
+
+ if (!this->header_parsed_)
+ this->header_parsed_ = this->parse_header();
+
+ return this->req_id_;
+}
+
+size_t
+GIOP_Buffer::cur_size (void) const
+{
+ return this->wr_pos_ - this->octets_;
+}
+
+bool
+GIOP_Buffer::parse_svc_contexts (void)
+{
+ ACE_CDR::ULong temp;
+ ACE_CDR::ULong num_svc_cont;
+ if ( !(*this->cdr_ >> num_svc_cont))
+ return false;
+ this->num_contexts_ = static_cast<size_t>(num_svc_cont);
+ while (num_svc_cont > 0)
+ {
+ if (!(*this->cdr_ >> temp)) // tag really
+ return false;
+ if (!(*this->cdr_ >> temp))
+ return false;
+ if (!this->cdr_->skip_bytes(temp))
+ return false;
+ --num_svc_cont;
+ }
+ return true;
+}
+
+bool
+GIOP_Buffer::parse_header (void)
+{
+ if (this->octets_ == 0 || this->cur_size() < 12)
+ {
+ return false;
+ }
+
+ char vmaj = this->octets_[4];
+ this->ver_minor_ = this->octets_[5];
+ char order = this->octets_[6];
+
+ char mtype = this->octets_[7];
+ if (mtype > 1) // not a request or reply
+ return false;
+
+ delete this->cdr_;
+ this->cdr_ = new ACE_InputCDR (this->octets_,
+ this->cur_size(),
+ order, vmaj, this->ver_minor_);
+ this->cdr_->skip_bytes (8);
+ this->payload_start_ = this->cdr_->rd_ptr();
+ ACE_CDR::ULong len_ulong;
+ if (!(*this->cdr_ >> len_ulong))
+ return false;
+ this->msg_size_ = len_ulong;
+
+ if (this->ver_minor_ < 2)
+ {
+ if (!this->parse_svc_contexts())
+ return false;
+ }
+
+ if (!(*this->cdr_ >> len_ulong))
+ return false;
+ this->req_id_ = static_cast<size_t>(len_ulong);
+
+ switch (mtype) {
+ case 0: //Request
+ if (!(*this->cdr_ >> this->resp_exp_))
+ return false;
+ if (this->ver_minor_ > 1 &&
+ !(*this->cdr_ >> len_ulong)) // address disposition
+ return false;
+ if (!(*this->cdr_ >> len_ulong))
+ return false;
+ this->oid_len_ = static_cast<size_t>(len_ulong);
+ this->oid_ = this->cdr_->rd_ptr();
+ if (!this->cdr_->skip_bytes(len_ulong))
+ return false;
+
+ if (!(*this->cdr_ >> len_ulong))
+ return false;
+ this->opname_ = this->cdr_->rd_ptr();
+ if (!this->cdr_->skip_bytes(len_ulong))
+ return false;
+ break;
+ case 1: //Reply
+ if (!(*this->cdr_ >> len_ulong))
+ return false;
+ this->reply_status_ = static_cast<size_t>(len_ulong);
+ break;
+ default:
+ return true;
+ }
+ if (this->ver_minor_ > 1)
+ {
+ if (!this->parse_svc_contexts())
+ return false;
+ }
+ this->cdr_->align_read_ptr (8);
+ this->payload_start_ = this->cdr_->rd_ptr();
+ return true;
+}
+
+const char *
+GIOP_Buffer::target_oid (size_t &len)
+{
+ if (this->octets_ == 0)
+ {
+ return 0;
+ }
+
+ if (!this->header_parsed_)
+ this->header_parsed_ = this->parse_header();
+
+ if (this->oid_ == 0)
+ return 0;
+
+ len = this->oid_len_;
+ return this->oid_;
+}
+
+const char *
+GIOP_Buffer::operation (void)
+{
+ if (octets_ == 0)
+ return 0;
+
+ if (!this->header_parsed_)
+ this->header_parsed_ = this->parse_header();
+
+ return this->opname_;
+}
+
+ACE_InputCDR &
+GIOP_Buffer::payload (void)
+{
+ if (octets_ != 0 && !this->header_parsed_)
+ this->header_parsed_ = this->parse_header();
+ return *this->cdr_;
+}
+
+bool
+GIOP_Buffer::has_octets (void) const
+{
+ return (octets_ != 0);
+}
+
+bool
+GIOP_Buffer::validate (void)
+{
+ return
+ this->expected_req_id_ == this->actual_req_id() &&
+ this->expected_type_ == this->type() &&
+ this->expected_size_ == this->msg_size();
+}
+
+bool
+GIOP_Buffer::matches (GIOP_Buffer *other) const
+{
+ if (other->header_parsed_)
+ return this->expected_req_id_ == other->actual_req_id() &&
+ this->expected_type_ == other->type() &&
+ this->expected_size_ == other->msg_size();
+ else
+ return this->expected_req_id_ == other->expected_req_id() &&
+ this->expected_type_ == other->expected_type() &&
+ this->sending_ == other->sending() &&
+ this->expected_size_ == other->expected_size();
+}
+
+void
+GIOP_Buffer::reset (void)
+{
+ this->octets_ = 0;
+ this->wr_pos_ = 0;
+ this->buffer_size_ = 0;
+ this->buffer_lost_ = true;
+ this->header_parsed_ = false;
+ this->opname_ = 0;
+}
+
+void
+GIOP_Buffer::transfer_from (GIOP_Buffer *other)
+{
+ delete this->octets_;
+ this->octets_ = other->octets_;
+ this->wr_pos_ = other->wr_pos_;
+ this->buffer_size_ = other->buffer_size_;
+ this->header_parsed_ = false;
+ other->reset();
+}
+
+void
+GIOP_Buffer::swap (GIOP_Buffer *other)
+{
+ char *tmp_octets = this->octets_;
+ char *tmp_wr_pos = this->wr_pos_;
+ size_t tmp_size = this->buffer_size_;
+
+ this->octets_ = other->octets_;
+ this->wr_pos_ = other->wr_pos_;
+ this->buffer_size_ = other->buffer_size_;
+
+ other->octets_ = tmp_octets;
+ other->wr_pos_ = tmp_wr_pos;
+ other->buffer_size_ = tmp_size;
+}
diff --git a/TAO/utils/logWalker/GIOP_Buffer.h b/TAO/utils/logWalker/GIOP_Buffer.h
new file mode 100644
index 00000000000..1e1386374c5
--- /dev/null
+++ b/TAO/utils/logWalker/GIOP_Buffer.h
@@ -0,0 +1,117 @@
+// -*- C++ -*-
+
+// $Id$
+//
+
+#ifndef LOG_WALKER_GIOP_BUFFER_H
+#define LOG_WALKER_GIOP_BUFFER_H
+
+#include "ace/SString.h"
+#include "ace/CDR_Stream.h"
+
+class Invocation;
+class Thread;
+
+// Invocation holds the buffer contents for a request/response pair.
+// This could be originating in this process, or in the peer process.
+//
+// The trigger for finding a new outgoing invocation is "Muxed_TMS[%d]"
+// following that the process/thread will perform a dump_msg.
+//
+// The trigger for finding a new incoming invocation is
+// "Transport[%d]::process_parsed_messages, entering (missing data == 0)"
+// which could indicate a new request or reply, depending on the context
+// in which the peer connection is made.
+//
+// It is possible that two or more threads may call dump_msg
+// concurrently and thus have the preamble and body printed out of
+// order. The HEXDUMP always reports a buffer size including the 12
+// byte GIOP header. Also, the first line of the text contains header
+// data which can be compared to the expected request ID.
+
+class GIOP_Buffer
+{
+public:
+
+ static const char *size_leadin;
+ static size_t leadin_len;
+ static const size_t giop_header_len;
+ static void init_leadin (int version);
+
+ GIOP_Buffer (const char *text,
+ size_t offset,
+ Thread *thread,
+ Invocation *owner = 0);
+ GIOP_Buffer (void);
+ ~GIOP_Buffer (void);
+
+ void owner (Invocation *);
+ Invocation *owner (void);
+
+ void init_buf (const char *text, size_t offset);
+ int add_octets(const char *text, size_t offset);
+ char type (void) const;
+ char expected_type (void) const;
+ bool sending (void) const;
+ char minor_version (void) const;
+ size_t reply_status (void) const;
+ size_t num_contexts (void) const;
+ bool is_oneway (void);
+ bool is_full (void) const;
+ size_t log_posn (void) const;
+ Thread *thread (void);
+ time_t time (void) const;
+
+ const ACE_CString &preamble(void) const;
+ size_t expected_req_id(void) const;
+ size_t actual_req_id(void);
+
+ size_t expected_size (void) const;
+ size_t buf_size (void) const;
+ size_t cur_size(void) const;
+ size_t msg_size (void);
+
+ const char * target_oid (size_t &len);
+ const char * operation (void);
+ ACE_InputCDR &payload (void);
+
+ bool has_octets (void) const;
+ bool validate (void);
+ bool matches (GIOP_Buffer *other) const;
+
+ void reset (void);
+ void transfer_from (GIOP_Buffer *other);
+ void swap (GIOP_Buffer *other);
+
+private:
+ bool parse_svc_contexts (void);
+ bool parse_header (void);
+
+ ACE_InputCDR *cdr_;
+ ACE_CString preamble_;
+ size_t log_offset_;
+ Thread *thr_;
+ time_t time_;
+ size_t expected_req_id_;
+ size_t expected_size_;
+ char expected_type_;
+ size_t buffer_size_;
+ char * wr_pos_;
+ char * octets_;
+ Invocation *owner_;
+ bool buffer_lost_;
+ bool sending_;
+ char * oid_;
+ size_t oid_len_;
+ char * opname_;
+ size_t req_id_;
+ char resp_exp_;
+ size_t reply_status_;
+ char ver_minor_;
+ size_t msg_size_;
+ size_t num_contexts_;
+ bool header_parsed_;
+ char * payload_start_;
+};
+
+#endif // LOG_WALKER_GIOP_BUFFER_H
diff --git a/TAO/utils/logWalker/HostProcess.cpp b/TAO/utils/logWalker/HostProcess.cpp
index d68d518bfd8..6f9988c163b 100644
--- a/TAO/utils/logWalker/HostProcess.cpp
+++ b/TAO/utils/logWalker/HostProcess.cpp
@@ -9,16 +9,10 @@
PeerNode::PeerNode (long h, PeerProcess *p)
:handle_ (h),
- peer_ (p),
- closed_ (false)
+ peer_ (p)
{
}
-PeerNode::~PeerNode (void)
-{
- delete peer_;
-}
-
HostProcess::HostProcess (const ACE_CString &src, long pid)
: pid_(pid),
logfile_name_(src)
@@ -39,24 +33,15 @@ HostProcess::~HostProcess (void)
{
delete reinterpret_cast<Thread *>(i.next()->item_);
}
-
- for (PeerArray::ITERATOR i(this->by_handle_); !i.done(); i++)
+#if 0
+ for (PeerProcs::ITERATOR i = by_addr_.begin(); i != servers_.end(); i++)
{
- ACE_DLList_Node *entry;
+ PeerProcs::ENTRY *entry;
if (i.next(entry) == 0)
break;
- //i.remove ();
-
- PeerNode *node = reinterpret_cast<PeerNode*>(entry->item_);
- PeerProcess *pp = node->peer_;
- const ACE_CString &addr = pp->is_server() ?
- pp->server_addr() : pp->last_client_addr();
- this->by_addr_.unbind (addr);
- delete node;
+ delete entry->item();
}
-
- this->by_addr_.close();
-
+#endif
}
void
@@ -72,7 +57,7 @@ HostProcess::proc_name (void) const
}
Thread *
-HostProcess::find_thread (long tid)
+HostProcess::find_thread (long tid, size_t offset)
{
Thread *thr = 0;
for (ACE_DLList_Iterator<Thread> i(threads_);
@@ -86,12 +71,31 @@ HostProcess::find_thread (long tid)
char alias[20];
ACE_OS::sprintf (alias,"Thread[" ACE_SIZE_T_FORMAT_SPECIFIER_ASCII "]",
this->threads_.size() + 1);
- thr = new Thread (tid, alias);
+ thr = new Thread (tid, alias, offset);
threads_.insert_tail (thr);
return thr;
}
Thread *
+HostProcess::find_thread_for_peer (const ACE_CString &addr, Session &session)
+{
+ Thread *thr = 0;
+ for (ACE_DLList_Iterator<Thread> i(threads_);
+ !i.done();
+ i.advance())
+ {
+ i.next(thr);
+ PeerProcess *pp = thr->pending_peer();
+ if (pp == 0)
+ continue;
+
+ if (pp->match_server_addr(addr, session))
+ return thr;
+ }
+ return 0;
+}
+
+Thread *
HostProcess::find_thread_for_handle (long h)
{
Thread *thr = 0;
@@ -115,8 +119,8 @@ HostProcess::find_peer (const ACE_CString &addr)
return pp;
}
-PeerNode *
-HostProcess::find_peer_i (long h)
+PeerProcess *
+HostProcess::find_peer (long h)
{
if (this->by_handle_.size() == 0)
return 0;
@@ -126,19 +130,8 @@ HostProcess::find_peer_i (long h)
{
PeerNode *node = reinterpret_cast<PeerNode *>(i.next()->item_);
if (node->handle_ == h)
- return node;
+ return node->peer_;
}
-
- return 0;
-}
-
-
-PeerProcess *
-HostProcess::find_peer (long h, bool ignore_closed)
-{
- PeerNode *node = this->find_peer_i (h);
- if (node != 0 && !(ignore_closed && node->closed_) )
- return node->peer_;
return 0;
}
@@ -181,8 +174,8 @@ void
HostProcess::add_peer(long handle, PeerProcess *peer)
{
peer->set_owner (this);
- PeerNode *node = this->find_peer_i(handle);
- if (node != 0 && !node->closed_ )
+ PeerProcess *existing = this->find_peer(handle);
+ if (existing != 0)
{
ACE_DEBUG ((LM_DEBUG,
"add_peer, found existing for %d\n",
@@ -190,29 +183,16 @@ HostProcess::add_peer(long handle, PeerProcess *peer)
}
const ACE_CString &addr = peer->is_server() ?
peer->server_addr() : peer->last_client_addr();
- errno = 0;
-
int result = this->by_addr_.bind (addr,peer);
- if (result == -1)
- {
- ACE_ERROR ((LM_ERROR,"add_peer, cannot bind handle %d to addr %s %p\n",
- handle, addr.c_str(), "by_addr_.bind"));
- }
+ if (result < 0)
+ ACE_ERROR ((LM_ERROR,"add_peer, cannot bind to addr %s result = %d, %p\n", addr.c_str(), result, "by_addr_.bind"));
- if (node == 0)
- {
- node = new PeerNode (handle,peer);
- this->by_handle_.insert_tail(node);
- }
- else
- {
- node->closed_ = false;
- node->peer_ = peer;
- }
+ PeerNode *node = new PeerNode (handle,peer);
+ this->by_handle_.insert_tail(node);
}
void
-HostProcess::close_peer(long h)
+HostProcess::remove_peer(long h)
{
if (this->by_handle_.size() == 0)
return;
@@ -223,7 +203,7 @@ HostProcess::close_peer(long h)
PeerNode *node = reinterpret_cast<PeerNode *>(i.next()->item_);
if (node->handle_ == h)
{
- node->closed_ = true;
+ this->by_handle_.remove(i.next());
return;
}
}
@@ -273,7 +253,11 @@ HostProcess::dump_ident (ostream &strm, const char *message)
void
HostProcess::dump_thread_detail (ostream &strm)
{
- this->dump_ident (strm, " thread details:");
+ this->dump_ident (strm, "thread details:");
+ long total_sent = 0;
+ long total_recv = 0;
+ size_t total_bytes_sent = 0;
+ size_t total_bytes_recv = 0;
for (ACE_DLList_Iterator <Thread> t_iter (this->threads_);
!t_iter.done();
t_iter.advance())
@@ -281,13 +265,16 @@ HostProcess::dump_thread_detail (ostream &strm)
Thread *thr = 0;
t_iter.next(thr);
thr->dump_detail (strm);
+ thr->get_summary (total_recv, total_sent, total_bytes_recv, total_bytes_sent);
}
+ strm << "Total requests sent: " << total_sent << " received: " << total_recv << endl;
+ strm << "Total requests bytes sent: " << total_bytes_sent << " received: " << total_bytes_recv << endl;
}
void
HostProcess::dump_thread_invocations (ostream &strm)
{
- this->dump_ident (strm, " invocations by thread:");
+ this->dump_ident (strm, "invocations by thread:");
for (ACE_DLList_Iterator <Thread> t_iter (this->threads_);
!t_iter.done();
t_iter.advance())
@@ -345,7 +332,7 @@ HostProcess::iterate_peers (int group,
void
HostProcess::dump_peer_detail (ostream &strm)
{
- this->dump_ident (strm, " peer processes:");
+ this->dump_ident (strm, "peer processes:");
size_t num_servers = 0;
size_t num_clients = 0;
strm << " total peers: " << this->by_addr_.current_size() << endl;
@@ -372,16 +359,16 @@ HostProcess::dump_peer_detail (ostream &strm)
void
HostProcess::dump_object_detail (ostream &strm)
{
- this->dump_ident (strm, " peer objects: ");
+ this->dump_ident (strm, "peer objects: ");
this->iterate_peers (3, 1, &strm);
}
void
HostProcess::dump_invocation_detail(ostream &strm)
{
- this->dump_ident (strm, " invocations: ");
+ this->dump_ident (strm, "invocations: ");
this->iterate_peers (3, 2, &strm);
- this->dump_ident (strm, " end invocation report");
+ this->dump_ident (strm, "end invocation report");
}
void
diff --git a/TAO/utils/logWalker/HostProcess.h b/TAO/utils/logWalker/HostProcess.h
index d92e9dd2630..5cd9f65b8a4 100644
--- a/TAO/utils/logWalker/HostProcess.h
+++ b/TAO/utils/logWalker/HostProcess.h
@@ -27,10 +27,8 @@ class Thread;
struct PeerNode
{
PeerNode (long h, PeerProcess *p);
- ~PeerNode (void);
long handle_;
PeerProcess *peer_;
- bool closed_;
};
typedef ACE_DLList<Thread> ThreadList;
@@ -57,7 +55,10 @@ public:
// Returns a thread instance based on thread id. Will create an instance
// as needed.
- Thread * find_thread (long tid);
+ Thread * find_thread (long tid, size_t offset);
+
+ // Returns a thread that has a pending peer with the supplied address
+ Thread * find_thread_for_peer (const ACE_CString& addr, Session &session);
// Returns a thread that had previously worked with handle h. May return
// a null pointer.
@@ -85,9 +86,12 @@ public:
// locate a peer process by handle or address
PeerProcess *find_peer (const ACE_CString& addr);
- PeerProcess *find_peer (long handle, bool ignore_closed);
+ PeerProcess *find_peer (long handle);
+
+ void remove_peer (long handle);
- void close_peer (long handle);
+ // remove a peer by handle, noting the line.
+ void close_peer (long handle, size_t offset);
// various output methods
void dump_ident (ostream &strm, const char *extra);
@@ -103,8 +107,6 @@ public:
void reconcile_peers (Session *session);
private:
- PeerNode *find_peer_i (long handle);
-
void iterate_peers (int group,
int operation,
ostream *strm = 0,
diff --git a/TAO/utils/logWalker/Invocation.cpp b/TAO/utils/logWalker/Invocation.cpp
index 7e8dc980154..27ed20d7da8 100644
--- a/TAO/utils/logWalker/Invocation.cpp
+++ b/TAO/utils/logWalker/Invocation.cpp
@@ -1,6 +1,7 @@
// $Id$
#include "Invocation.h"
+#include "GIOP_Buffer.h"
#include "PeerProcess.h"
#include "PeerObject.h"
#include "Session.h"
@@ -8,518 +9,19 @@
#include "Thread.h"
#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_stdio.h"
#include "ace/Log_Msg.h"
-#include <stdio.h>
-
-static const char *size_leadin_1_5 = "GIOP v1."; //"x msg, ";
-static size_t leadin_len_1_5 = 15;
-static const char *size_leadin_1_6 = "GIOP message v1."; //2, ";
-static size_t leadin_len_1_6 = 19;
-
-
-static const char *size_leadin = 0;
-static size_t leadin_len = 0;
-static const size_t giop_header_len = 12;
-
-static const int date_format = 2;
-
-// GIOP 1.2 header: 12 bytes
-// Magic: 4
-// ver: 2
-// flags: 1 // bo
-// type: 1 // req/repl/lf/excp
-// len: 4
-//
-// Request 1.2 header:
-// req_id: 4
-// flags: 1
-// RESVD: 3
-// Address disposition: 4
-// target: <4 len, + len> [0-3 pad]
-// opname: <4 len, + len>
-
-// GIOP 1.0 header: 12 bytes
-// Magic: 4
-// ver: 2
-// byte_order: 1
-// type: 1 // req/repl/lf/excp
-// len: 4
-//
-// Request 1.0 header:
-/*
-struct RequestHeader_1_0 { // Renamed from RequestHeader
- IOP::ServiceContextList service_context;
- unsigned long request_id;
- boolean response_expected;
- sequence <octet> object_key;
- string operation;
- CORBA::OctetSeq requesting_principal;
-};
-*/
-// service_context: 4(count)+contexts.
-// context id: 4
-// content blob: 4(len) + len octets + (0-3)pad
-// request_id: 4
-// respexp: 1
-// RESVD: 3
-// Address disposition: 4
-// target: <4 len, + len> [0-3 pad]
-// opname: <4 len, + len>
-
-/*
-struct ReplyHeader_1_0 { // Renamed from ReplyHeader
- IOP::ServiceContextList service_context;
- unsigned long request_id;
- ReplyStatusType_1_0 reply_status;
- };
- // GIOP 1.1
- typedef ReplyHeader_1_0 ReplyHeader_1_1;
- // Same Header contents for 1.0 and 1.1
-#else
- // GIOP 1.2, 1.3
- enum ReplyStatusType_1_2 {
- NO_EXCEPTION,
- USER_EXCEPTION,
- SYSTEM_EXCEPTION,
- LOCATION_FORWARD,
- LOCATION_FORWARD_PERM,// new value for 1.2
- NEEDS_ADDRESSING_MODE // new value for 1.2
- };
- struct ReplyHeader_1_2 {
- unsigned long request_id;
- ReplyStatusType_1_2 reply_status;
- IOP::ServiceContextList service_context;
- };
-
- */
-
-
-
-static const size_t target_offset_12 = giop_header_len + 12;
-
-// 12 = req_id + flags + RESVD + addr disp.
-
-Invocation::GIOP_Buffer::GIOP_Buffer(const char *text,
- size_t offset,
- Thread *thread,
- Invocation *owner)
- : preamble_(text),
- log_offset_(offset),
- thr_(thread),
- time_(0),
- expected_req_id_(0),
- expected_size_(0),
- expected_type_(0),
- size_(0),
- wr_pos_ (0),
- octets_ (0),
- owner_ (owner),
- buffer_lost_ (false),
- sending_(false),
- oid_ (0),
- oid_len_ (0),
- opname_ (0),
- req_id_ (0),
- resp_exp_ (0),
- reply_status_ (0),
- ver_minor_ (0),
- num_contexts_ (0),
- header_parsed_ (false)
-{
- const char *size_str = ACE_OS::strstr(text, size_leadin) + leadin_len;
- const char *id = size_str == 0 ? 0 : ACE_OS::strchr(size_str, '[') + 1;
- this->sending_ = ACE_OS::strstr(text,"send") ? 0 : 1;
- this->expected_type_ = ACE_OS::strstr(text,"Request") ? 0 : 1;
- this->expected_size_ = ACE_OS::strtol(size_str, 0,10) + giop_header_len;
- this->expected_req_id_ = ACE_OS::strtol(id, 0, 10);
- const char *time_tok = ACE_OS::strchr (text,'@');
- if (time_tok != 0)
- {
- char timebuf[30];
- ACE_OS::strncpy(timebuf, text, (time_tok - text));
- timebuf[time_tok - text] = 0;
- char *hms = ACE_OS::strchr (timebuf,' ');
- if (Session::date_format() == 2) // MMM DD hh:mm:ss.msec YYYY
- {
- if (hms != 0)
- hms = ACE_OS::strchr (hms+1,' ');
- }
-
- if (hms != 0)
- {
- int hr, min, sec, msec;
- ::sscanf (hms+1,"%d:%d:%d.%d", &hr, &min, &sec, &msec);
- this->time_ = (hr * 3600 + min *60 + sec) * 1000 + msec;
- }
- }
-}
-
-void
-Invocation::GIOP_Buffer::owner (Invocation *owner)
-{
- this->owner_ = owner;
-}
-
-Invocation *
-Invocation::GIOP_Buffer::owner (void)
-{
- return this->owner_;
-}
-
-void
-Invocation::GIOP_Buffer::init_buf (const char *text)
-{
- // GIOP message - HEXDUMP
- const char * size_str = ACE_OS::strstr(text,"HEXDUMP ") + 8;
- this->size_ = ACE_OS::strtol(size_str, 0,10);
- size_str = ACE_OS::strstr(text,"showing first ");
- if (size_str != 0)
- {
- size_str += 14;
- this->size_ = ACE_OS::strtol(size_str, 0, 10);
- }
- this->octets_ = new char [this->size_];
- ACE_OS::memset(this->octets_,0,this->size_);
- this->wr_pos_ = this->octets_;
-}
-
-Invocation::GIOP_Buffer::~GIOP_Buffer(void)
-{
- delete [] this->octets_;
-}
-
-int
-Invocation::GIOP_Buffer::add_octets(const char *text)
-{
- if (this->octets_ == 0)
- {
- this->init_buf(text);
- return 0;
- }
-
- const char *c = text;
- char *err;
- for (int count = 0; count < 16 && this->cur_size() < this->size_; count++)
- {
- if (count == 8)
- ++c;
- int o = ::strtol(c, &err, 16);
- if (err == c || *err == 0)
- return -1;
- *this->wr_pos_++ = o;
- c = err+1;
- }
- size_t cs = this->cur_size();
- if (cs == this->size_)
- return -1;
- else
- if (!this->header_parsed_)
- {
- this->header_parsed_ = this->parse_header();
- if (this->header_parsed_ )
- return 1;
- }
- return 0;
-}
-
-bool
-Invocation::GIOP_Buffer::sending (void) const
-{
- return this->sending_;
-}
-
-bool
-Invocation::GIOP_Buffer::is_full(void) const
-{
- return this->size_ > 0 && this->cur_size() == this->size_;
-}
-
-char
-Invocation::GIOP_Buffer::type (void) const
-{
- if (this->octets_ == 0)
- return 127;
- return this->octets_[7];
-}
-
-char
-Invocation::GIOP_Buffer::expected_type (void) const
-{
- return this->expected_type_;
-}
-
-char
-Invocation::GIOP_Buffer::minor_version (void) const
-{
- return this->ver_minor_;
-}
-
-char
-Invocation::GIOP_Buffer::reply_status (void) const
-{
- return this->reply_status_;
-}
-
-size_t
-Invocation::GIOP_Buffer::num_contexts (void) const
-{
- return this->num_contexts_;
-}
-
-bool
-Invocation::GIOP_Buffer::is_oneway(void)
-{
- if (this->octets_ == 0)
- {
- return false;
- }
-
- if (!this->header_parsed_)
- this->header_parsed_ = this->parse_header();
-
- return (resp_exp_ &1) == 0;
-}
-
-size_t
-Invocation::GIOP_Buffer::log_posn (void) const
-{
- return this->log_offset_;
-}
-
-Thread *
-Invocation::GIOP_Buffer::thread (void)
-{
- return this->thr_;
-}
-
-time_t
-Invocation::GIOP_Buffer::time (void) const
-{
- return this->time_;
-}
-
-const ACE_CString &
-Invocation::GIOP_Buffer::preamble(void) const
-{
- return this->preamble_;
-}
-
-size_t
-Invocation::GIOP_Buffer::expected_size (void) const
-{
- return this->expected_size_;
-}
-
-size_t
-Invocation::GIOP_Buffer::size(void) const
-{
- return this->size_;
-}
-
-size_t
-Invocation::GIOP_Buffer::expected_req_id(void) const
-{
- return this->expected_req_id_;
-}
-
-size_t
-Invocation::GIOP_Buffer::actual_req_id(void)
-{
- if (this->octets_ == 0)
- return 0;
-
- if (!this->header_parsed_)
- this->header_parsed_ = this->parse_header();
-
- return this->req_id_;
-}
-
-size_t
-Invocation::GIOP_Buffer::cur_size(void) const
-{
- return this->wr_pos_ - this->octets_;
-}
-
-bool
-Invocation::GIOP_Buffer::parse_svc_contexts (ACE_InputCDR &cdr)
-{
- ACE_CDR::ULong temp;
- ACE_CDR::ULong num_svc_cont;
- if ( !(cdr >> num_svc_cont))
- return false;
- this->num_contexts_ = static_cast<size_t>(num_svc_cont);
- while (num_svc_cont > 0)
- {
- if (!(cdr >> temp)) // tag really
- return false;
- if (!(cdr >> temp))
- return false;
- if (!cdr.skip_bytes(temp))
- return false;
- --num_svc_cont;
- }
- return true;
-}
-
-bool
-Invocation::GIOP_Buffer::parse_header (void)
-{
- if (this->octets_ == 0)
- {
- return false;
- }
-
- char vmaj = this->octets_[4];
- this->ver_minor_ = this->octets_[5];
- char bo = this->octets_[6];
-
- char mtype = this->octets_[7];
- if (mtype > 1) // not a request or reply
- return false;
-
- ACE_InputCDR cdr(this->octets_ + giop_header_len,
- this->cur_size() - giop_header_len,
- bo, vmaj, this->ver_minor_);
-
- ACE_CDR::ULong len_ulong;
-
- if (this->ver_minor_ < 2)
- {
- if (!this->parse_svc_contexts(cdr))
- return false;
- }
-
- if (!(cdr >> len_ulong))
- return false;
- this->req_id_ = static_cast<size_t>(len_ulong);
-
- switch (mtype) {
- case 0: //Request
- if (!(cdr >> this->resp_exp_))
- return false;
- if (this->ver_minor_ > 1 &&
- !(cdr >> len_ulong)) // address disposition
- return false;
- if (!(cdr >> len_ulong))
- return false;
- this->oid_len_ = static_cast<size_t>(len_ulong);
- this->oid_ = cdr.rd_ptr();
- if (!cdr.skip_bytes(len_ulong))
- return false;
-
- if (!(cdr >> len_ulong))
- return false;
- this->opname_ = cdr.rd_ptr();
- if (!cdr.skip_bytes(len_ulong))
- return false;
- break;
- case 1: //Reply
- if (!(cdr >> len_ulong))
- return false;
- this->reply_status_ = static_cast<size_t>(len_ulong);
- break;
- default:
- return false;
- }
- if (this->ver_minor_ > 1)
- {
- if (!this->parse_svc_contexts(cdr))
- return false;
- }
-
- return true;
-}
-
-const char *
-Invocation::GIOP_Buffer::target_oid(size_t &len)
-{
- if (this->octets_ == 0)
- {
- return 0;
- }
-
- if (!this->header_parsed_)
- this->header_parsed_ = this->parse_header();
-
- if (this->oid_ == 0)
- return 0;
-
- len = this->oid_len_;
- return this->oid_;
-}
-
-const char *
-Invocation::GIOP_Buffer::operation(void)
-{
- if (octets_ == 0)
- return 0;
-
- if (!this->header_parsed_)
- this->header_parsed_ = this->parse_header();
-
- return this->opname_;
-}
-
-bool
-Invocation::GIOP_Buffer::validate (void)
-{
- return this->expected_req_id_ == this->actual_req_id() &&
- this->expected_type_ == this->type();
-}
-
-bool
-Invocation::GIOP_Buffer::matches (Invocation::GIOP_Buffer *other) const
-{
- return this->expected_req_id_ == other->actual_req_id() &&
- this->expected_type_ == other->type() &&
- this->expected_size_ == other->size();
-}
-
-void
-Invocation::GIOP_Buffer::reset (void)
-{
- this->octets_ = 0;
- this->wr_pos_ = 0;
- this->size_ = 0;
- this->buffer_lost_ = true;
-}
-
-void
-Invocation::GIOP_Buffer::transfer_from (GIOP_Buffer *other)
-{
- delete this->octets_;
- this->octets_ = other->octets_;
- this->wr_pos_ = other->wr_pos_;
- this->size_ = other->size_;
- other->reset();
-}
-
-
-//----------------------------------------------------------------------------
-
-
-Invocation::Invocation (PeerProcess *peer, long handle, size_t rid)
+Invocation::Invocation (PeerProcess *peer, Thread *thr, size_t rid)
:req_octets_(0),
repl_octets_(0),
+ waiter_ (thr),
+ notify_incidents_ (),
peer_(peer),
req_id_(rid),
target_(0),
- handle_(handle)
+ handle_(thr->active_handle())
{
- if (size_leadin == 0)
- {
- if (Session::tao_version() == 150)
- {
- size_leadin = size_leadin_1_5;
- leadin_len = leadin_len_1_5;
- }
- else
- {
- size_leadin = size_leadin_1_6;
- leadin_len = leadin_len_1_6;
- }
- }
}
Invocation::~Invocation (void)
@@ -531,7 +33,9 @@ Invocation::~Invocation (void)
bool
Invocation::init (const char * text, size_t offset, Thread *thread)
{
- const char *size_str = ACE_OS::strstr(text, size_leadin);
+ if (GIOP_Buffer::size_leadin == 0)
+ GIOP_Buffer::init_leadin (Session::tao_version());
+ const char *size_str = ACE_OS::strstr(text, GIOP_Buffer::size_leadin);
const char *id = size_str == 0 ? 0 : ACE_OS::strchr(size_str, '[');
if (size_str == 0 || id == 0)
{
@@ -549,6 +53,12 @@ Invocation::init (const char * text, size_t offset, Thread *thread)
return true;
}
+void
+Invocation::add_notify_incident (const ACE_CString &text, size_t /* offset */)
+{
+ this->notify_incidents_.enqueue_tail (text);
+}
+
bool
Invocation::is_oneway(void) const
{
@@ -584,13 +94,13 @@ Invocation::message_complete (void)
return true;
}
-Invocation::GIOP_Buffer *
+GIOP_Buffer *
Invocation::octets (bool request)
{
return request ? this->req_octets_ : this->repl_octets_ ;
}
-Invocation::GIOP_Buffer *
+GIOP_Buffer *
Invocation::give_octets (bool request)
{
GIOP_Buffer *result = request ? this->req_octets_ : this->repl_octets_ ;
@@ -624,6 +134,16 @@ Invocation::set_octets (bool request, GIOP_Buffer *octets)
octets->owner(this);
}
+bool
+Invocation::sent_request (void) const
+{
+ if (this->req_octets_)
+ return this->req_octets_->sending();
+ if (this->repl_octets_)
+ return !this->repl_octets_->sending();
+ return false;
+}
+
size_t
Invocation::request_id (void) const
{
@@ -638,6 +158,18 @@ Invocation::expected_size (void) const
return req_octets_->expected_size();
}
+size_t
+Invocation::request_bytes (void) const
+{
+ return req_octets_ != 0 ? req_octets_->expected_size() : 0;
+}
+
+Thread *
+Invocation::waiter (void) const
+{
+ return this->waiter_;
+}
+
long
Invocation::handle (void) const
{
@@ -661,10 +193,13 @@ Invocation::req_line (void)
}
void
-Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_handle)
+Invocation::dump_detail (ostream &strm,
+ int indent,
+ Dump_Mode mode,
+ bool show_handle)
{
const char *opname = "";
- const char *dir_1 = "to ";
+ const char *dir_1 = "sent to ";
const char *dir_2 = " in ";
if (this->req_octets_ != 0)
@@ -672,7 +207,7 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha
opname = this->req_octets_->operation();
if (this->req_octets_->sending())
{
- dir_1 = "for ";
+ dir_1 = "recv for ";
dir_2 = " from ";
}
}
@@ -697,14 +232,15 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha
strm << " [" << opname << "]\t";
time_t req_time = 0;
time_t rep_time = 0;
- long delta = 0;
+ size_t delta = 0;
if (!this->is_oneway() && this->req_octets_ != 0)
{
req_time = this->req_octets_->time();
if (this->repl_octets_ != 0)
{
rep_time = this->repl_octets_->time();
- delta = this->repl_octets_->log_posn() - this->req_octets_->log_posn();
+ delta = this->repl_octets_->log_posn() -
+ this->req_octets_->log_posn();
}
}
if (req_time != 0 && rep_time != 0)
@@ -715,6 +251,7 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha
strm << " Request, ";
if (this->req_octets_->num_contexts() > 0)
strm << "with " << this->req_octets_->num_contexts() << " contexts, ";
+ strm << "size " << this->req_octets_->expected_size() << " ";
strm << "line " << this->req_octets_->log_posn();
if (mode == Dump_Thread || mode == Dump_Both)
strm << " " << this->req_octets_->thread()->alias();
@@ -729,27 +266,21 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha
{
strm << " Reply, ";
if (this->repl_octets_->num_contexts() > 0)
- strm << "with " << this->repl_octets_->num_contexts() << " contexts, ";
+ strm << "with " << this->repl_octets_->num_contexts()
+ << " contexts, ";
+ strm << "size " << this->repl_octets_->expected_size() << " ";
strm << "line " << this->repl_octets_->log_posn();
#if defined (SHOW_THREAD_ID)
strm << " " << this->repl_octets_->thread()->alias();
#endif
char rstat = this->repl_octets_->reply_status();
- switch (rstat)
+ if (rstat == 1 || rstat == 2)
+ {
+ strm << (rstat == 1 ? " User" : " System") << " Exception";
+ }
+ else if (rstat == 3)
{
- case 0:
- break;
- case 1:
- strm << " User Exception";
- break;
- case 2:
- strm << " System Exception";
- break;
- case 3:
strm << " Location Forward";
- break;
- default:
- strm << " status = " << static_cast<short>(rstat);
}
}
else
@@ -757,5 +288,143 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha
}
if (delta > 0)
strm << " log span = " << delta;
+ if (this->req_octets_ != 0 && this->req_octets_->has_octets() &&
+ this->repl_octets_ != 0 && this->repl_octets_->has_octets())
+ this->dump_special_details (strm, opname);
strm << endl;
+ if (this->notify_incidents_.size() > 0)
+ {
+ for (NotifyIncidents::ITERATOR i = this->notify_incidents_.begin();
+ !(i.done()); i.advance())
+ {
+ ACE_CString *note;
+ i.next(note);
+ strm << " " << *note << endl;
+ }
+ }
+}
+
+void
+Invocation::dump_special_details (ostream &strm, const char *opname)
+{
+ char rstat = this->repl_octets_->reply_status();
+ int opid = 0;
+ if (ACE_OS::strcmp (opname, "_is_a") == 0)
+ {
+ opid = 1;
+ ACE_InputCDR &giop_cdr = this->req_octets_->payload();
+ ACE_InputCDR cdr (giop_cdr.rd_ptr(),
+ giop_cdr.length(),
+ giop_cdr.byte_order());
+ ACE_CDR::ULong len;
+ if (cdr >> len)
+ strm << "\n expected type ( len = " << len << ") "
+ << cdr.rd_ptr();
+ }
+ else if (ACE_OS::strcmp (opname, "_get_MyID") == 0)
+ {
+ opid = 2;
+ }
+ else if (ACE_OS::strcmp (opname, "resolve_str") == 0)
+ {
+ opid = 3;
+ ACE_InputCDR &giop_cdr = this->req_octets_->payload();
+ ACE_InputCDR cdr (giop_cdr.rd_ptr(),
+ giop_cdr.length(),
+ giop_cdr.byte_order());
+ ACE_CDR::ULong len;
+ if (cdr >> len)
+ strm << "\n name len = " << len << ") " << cdr.rd_ptr();
+ }
+ else if (ACE_OS::strcmp (opname, "resolve") == 0 ||
+ ACE_OS::strcmp (opname, "bind") == 0 ||
+ ACE_OS::strcmp (opname, "rebind") == 0 ||
+ ACE_OS::strcmp (opname, "bind_new_context") == 0
+ )
+ {
+ opid = 3;
+ ACE_InputCDR &giop_cdr = this->req_octets_->payload();
+ ACE_InputCDR cdr (giop_cdr.rd_ptr(),
+ giop_cdr.length(),
+ giop_cdr.byte_order());
+ ACE_CDR::ULong count;
+ if (cdr >> count)
+ {
+ strm << "\n name_seq.lengh = " << count << " ";
+ while (count-- > 0)
+ {
+ ACE_CDR::ULong len;
+ if (!(cdr >> len))
+ break;
+ strm << cdr.rd_ptr();
+ if (!cdr.skip_bytes (len))
+ break;
+ if (!(cdr >> len))
+ break;
+ if (len > 1)
+ {
+ strm << "." << cdr.rd_ptr();
+ }
+ if (!cdr.skip_bytes (len))
+ break;
+ if (count > 0)
+ {
+ strm << "/";
+ }
+ }
+ if (static_cast<ACE_CDR::Long>(count) > 0)
+ {
+ strm << " [name truncated]";
+ }
+ }
+ }
+
+
+ ACE_InputCDR &giop_cdr = this->repl_octets_->payload();
+ ACE_InputCDR cdr (giop_cdr.rd_ptr(),
+ giop_cdr.length(),
+ giop_cdr.byte_order());
+
+ if (rstat == 0)
+ {
+ switch (opid)
+ {
+ case 1:
+ {
+ ACE_CDR::Boolean x;
+ if (cdr >> ACE_InputCDR::to_boolean (x))
+ strm << " reply: " << (x ? "yes" : "no");
+ break;
+ }
+ case 2:
+ {
+ ACE_CDR::Long x;
+ if (cdr >> x)
+ strm << " \n MyID reply: " << x;
+ break;
+ }
+ default:;
+ }
+ }
+ else
+ {
+ if (opid == 0)
+ {
+ strm << "\n ";
+ }
+ if (rstat == 1 || rstat == 2)
+ {
+ strm << " Exception ";
+ }
+ else
+ {
+ strm << " Redirect to ";
+ }
+ ACE_CDR::ULong len;
+ if (cdr >> len)
+ {
+ strm << cdr.rd_ptr();
+ }
+ }
+
}
diff --git a/TAO/utils/logWalker/Invocation.h b/TAO/utils/logWalker/Invocation.h
index 0594a79665f..107a513652d 100644
--- a/TAO/utils/logWalker/Invocation.h
+++ b/TAO/utils/logWalker/Invocation.h
@@ -8,10 +8,14 @@
#include "ace/SString.h"
#include "ace/CDR_Stream.h"
+#include "ace/Unbounded_Queue.h"
class PeerProcess;
class PeerObject;
class Thread;
+class GIOP_Buffer;
+
+typedef ACE_Unbounded_Queue<ACE_CString> NotifyIncidents;
// Invocation holds the buffer contents for a request/response pair.
// This could be originating in this process, or in the peer process.
@@ -33,68 +37,6 @@ class Thread;
class Invocation
{
public:
- class GIOP_Buffer
- {
- public:
- GIOP_Buffer (const char *text, size_t offset, Thread *thread, Invocation *owner = 0);
- ~GIOP_Buffer (void);
- void owner (Invocation *);
- Invocation *owner (void);
- void init_buf (const char *text);
- int add_octets(const char *text);
- char type (void) const;
- char expected_type (void) const;
- bool sending (void) const;
- char minor_version (void) const;
- char reply_status (void) const;
- size_t num_contexts (void) const;
- bool is_oneway (void);
- bool is_full (void) const;
- size_t log_posn (void) const;
- Thread *thread (void);
- time_t time (void) const;
-
- const ACE_CString &preamble(void) const;
- size_t expected_req_id(void) const;
- size_t actual_req_id(void);
- size_t expected_size (void) const;
- size_t size (void) const;
- size_t cur_size(void) const;
- const char * target_oid (size_t &len);
- const char * operation (void);
- bool validate (void);
- bool matches (GIOP_Buffer *other) const;
- void reset (void);
- void transfer_from (GIOP_Buffer *other);
-
- private:
- bool parse_svc_contexts (ACE_InputCDR& cdr);
- bool parse_header (void);
-
- ACE_CString preamble_;
- size_t log_offset_;
- Thread *thr_;
- time_t time_;
- size_t expected_req_id_;
- size_t expected_size_;
- char expected_type_;
- size_t size_;
- char * wr_pos_;
- char * octets_;
- Invocation *owner_;
- bool buffer_lost_;
- bool sending_;
- char * oid_;
- size_t oid_len_;
- char * opname_;
- size_t req_id_;
- char resp_exp_;
- size_t reply_status_;
- char ver_minor_;
- size_t num_contexts_;
- bool header_parsed_;
- };
-
enum Dump_Mode {
Dump_Proc,
Dump_Thread,
@@ -102,15 +44,13 @@ public:
};
// initialize a new instance, with the initial request text line and offeset
- Invocation (PeerProcess *peer, long handle, size_t req_id = 0);
+ Invocation (PeerProcess *peer, Thread *thr, size_t req_id = 0);
bool init ( const char * text, size_t offset, Thread *thr);
~Invocation (void);
// return true if the invocation was a oneway
bool is_oneway(void) const;
- void set_target (const char *oid, size_t oid_len);
-
// return true if the request is a oneway and has all its octets, or
// if it also has all its reply octets. The side-effect of this call
// is to obtain the target reference from the request buffer and associate
@@ -119,10 +59,17 @@ public:
size_t request_id (void) const;
+ // returns true if this request was sent by the host process.
+ bool sent_request (void) const;
+
// returns the size parsed from either the request or reply preamble
// which can be used to match a HEXDUMP b
size_t expected_size (void) const;
+ size_t request_bytes (void) const;
+
+ void set_target (const char *oid, size_t oid_len);
+
void set_octets (bool request, GIOP_Buffer *octets);
GIOP_Buffer *octets (bool request);
GIOP_Buffer *give_octets (bool request);
@@ -130,14 +77,19 @@ public:
bool contains (size_t line);
size_t req_line (void);
+ void add_notify_incident (const ACE_CString &text, size_t offset);
+ Thread *waiter (void) const;
long handle (void) const;
void dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_handle);
+ void dump_special_details (ostream &strm, const char *opname);
private:
GIOP_Buffer *req_octets_;
GIOP_Buffer *repl_octets_;
+ Thread *waiter_;
+ NotifyIncidents notify_incidents_;
PeerProcess *peer_;
size_t req_id_;
PeerObject *target_;
diff --git a/TAO/utils/logWalker/Log.cpp b/TAO/utils/logWalker/Log.cpp
index 0f2ebfa7889..b54e4e22301 100644
--- a/TAO/utils/logWalker/Log.cpp
+++ b/TAO/utils/logWalker/Log.cpp
@@ -11,8 +11,15 @@
#include "ace/Mem_Map.h"
Log::Log (Session &session)
- : session_(session),
- dump_target_(0)
+ : session_ (session),
+ dump_target_ (0),
+ history_ (),
+ timestamp_ (),
+ line_ (0),
+ info_ (0),
+ offset_ (0),
+ hostproc_ (0),
+ thr_ (0)
{
}
@@ -21,7 +28,7 @@ Log::~Log (void)
}
bool
-Log::init (const ACE_TCHAR *filename, const char *alias)
+Log::process_file (const ACE_TCHAR *filename, const char *alias)
{
ACE_DEBUG ((LM_DEBUG,"Processing log file %C\n",
filename));
@@ -43,13 +50,13 @@ Log::init (const ACE_TCHAR *filename, const char *alias)
size_t remainder = mapsize;
size_t linelen = 0;
- char *line;
+ char *text;
size_t maxline = 1000;
char *buffer = new char[maxline];
- size_t line_pos = 1;
- while ((line = ACE_OS::strchr(base,'\n')) != 0)
+ this->offset_ = 1;
+ while ((text = ACE_OS::strchr(base,'\n')) != 0)
{
- linelen = line - base;
+ linelen = text - base;
if (linelen >= maxline)
{
delete [] buffer;
@@ -59,9 +66,11 @@ Log::init (const ACE_TCHAR *filename, const char *alias)
}
ACE_OS::strncpy(buffer,base,linelen);
buffer[linelen] = 0;
- this->parse_line (buffer, line_pos);
- base = line+1;
- ++line_pos;
+ this->line_ = buffer;
+ if (linelen > 0)
+ this->parse_line ();
+ base = text+1;
+ ++this->offset_;
remainder -= linelen;
if (remainder < 1)
break;
@@ -74,115 +83,116 @@ Log::init (const ACE_TCHAR *filename, const char *alias)
return true;
}
-bool
-Log::get_pid_tid (long &pid, long &tid, char *line)
+void
+Log::get_preamble ()
{
- const char * p = ACE_OS::strstr (line, "TAO (");
+ char * p = ACE_OS::strstr (this->line_, "(");
char * t = 0;
+
+ this->info_ = this->line_;
+
if (p == 0)
- return false;
+ return;
- pid = ACE_OS::strtol(p+5,&t,10);
- tid = ACE_OS::strtol(t+1,0,10);
- return true;
-}
+ if (p != this->line_)
+ {
+ char * x = ACE_OS::strstr (this->line_, "TAO (");
+ if (x+4 != p)
+ {
+ x = ACE_OS::strstr (this->line_, "@(");
+ if (x + 1 != p)
+ return;
+ }
+ }
-HostProcess *
-Log::get_host (long pid)
-{
- HostProcess *hp = 0;
+
+ long pid = ACE_OS::strtol(p + 1, &t, 10);
if (pid == 0)
- return 0;
+ return;
+
+ long tid = 0;
+ if ( *t == '|' )
+ tid = ACE_OS::strtol(t + 1, 0, 10);
+ else if ( *t != ')')
+ return; // not either (pid) or (pid|tid)
+
+ this->info_ = ACE_OS::strstr (p, ")") + 1;
+ this->hostproc_ = 0;
for (ACE_DLList_Iterator<HostProcess> i (this->procs_);
!i.done();
i.advance())
{
- i.next(hp);
- if (hp->pid() == pid)
- return hp;
+ i.next(this->hostproc_);
+ if (this->hostproc_->pid() == pid)
+ {
+ break;
+ }
+ this->hostproc_ = 0;
}
- hp = this->session_.find_process(pid);
- if (hp != 0)
- return hp;
- size_t numprocs = this->procs_.size();
- hp = new HostProcess (this->origin_,pid);
- this->procs_.insert_tail(hp);
- ACE_CString &procname = this->alias_.length() > 0 ?
- this->alias_ : this->origin_;
- switch (numprocs)
+ if (this->hostproc_ == 0)
+ this->hostproc_ = this->session_.find_process(pid);
+
+ if (this->hostproc_ == 0)
{
- case 0:
- hp->proc_name(procname);
- break;
- case 1:
- {
- ACE_CString a2 = procname + "_1";
- HostProcess *first;
- if (this->procs_.get(first) == 0)
- first->proc_name(a2);
- }
- //fallthru
- default:
- {
- char ext[10];
- ACE_OS::sprintf(ext,"_" ACE_SIZE_T_FORMAT_SPECIFIER_ASCII,numprocs+1);
- ACE_CString a2 = procname + ext;
- hp->proc_name(a2);
- }
- }
-
- this->session_.add_process(hp);
- return hp;
+ size_t numprocs = this->procs_.size();
+ this->hostproc_ = new HostProcess (this->origin_,pid);
+ this->procs_.insert_tail(this->hostproc_);
+ ACE_CString &procname = this->alias_.length() > 0 ?
+ this->alias_ : this->origin_;
+ switch (numprocs)
+ {
+ case 0:
+ this->hostproc_->proc_name(procname);
+ break;
+ case 1:
+ {
+ ACE_CString a2 = procname + "_1";
+ HostProcess *first;
+ if (this->procs_.get(first) == 0)
+ first->proc_name(a2);
+ }
+ //fallthru
+ default:
+ {
+ char ext[10];
+ ACE_OS::sprintf(ext,"_" ACE_SIZE_T_FORMAT_SPECIFIER_ASCII,numprocs+1);
+ ACE_CString a2 = procname + ext;
+ this->hostproc_->proc_name(a2);
+ }
+ }
+
+ this->session_.add_process(this->hostproc_);
+ }
+ this->thr_ = this->hostproc_->find_thread (tid, this->offset_);
+ return;
}
void
-Log::handle_msg_dump (char *line, size_t offset)
+Log::handle_msg_octets ()
{
- int pos = this->dump_target_->add_octets(line);
- if (pos > 0) // need to validate target
+ int pos = this->dump_target_->add_octets(this->line_, this->offset_);
+ if (this->dump_target_ == &this->unknown_msg_)
{
- if (!this->dump_target_->validate())
- {
- for (ACE_DLList_Iterator<Thread> t_iter(this->giop_waiters_);
- !t_iter.done();
- t_iter.advance())
- {
- Thread *th = 0;
- t_iter.next(th);
- Invocation::GIOP_Buffer *new_target = th->giop_target();
- if (new_target == 0 || new_target == this->dump_target_)
- continue;
- if (new_target->matches (this->dump_target_))
- {
- Thread *tmp_thr = this->dump_target_->thread();
- new_target->transfer_from (this->dump_target_);
- this->dump_target_ = new_target;
- t_iter.remove();
- this->giop_waiters_.insert_tail (tmp_thr);
- break;
- }
- }
- }
- else
+ for (ACE_DLList_Iterator<Thread> t_iter(this->giop_waiters_);
+ !t_iter.done();
+ t_iter.advance())
{
- for (ACE_DLList_Iterator<Thread> t_iter(this->giop_waiters_);
- !t_iter.done();
- t_iter.advance())
+ Thread *th = 0;
+ t_iter.next(th);
+ GIOP_Buffer *waiter = th->giop_target();
+ if (waiter == 0)
+ continue;
+ if (waiter->matches (this->dump_target_))
{
- Thread *th = 0;
- t_iter.next(th);
- if (this->dump_target_ == th->giop_target())
- {
- PeerProcess *pp = th->incoming();
- th->exit_wait(pp, offset);
- t_iter.remove();
- break;
- }
+ waiter->transfer_from (this->dump_target_);
+ this->dump_target_ = waiter;
+ t_iter.remove();
+ break;
}
}
}
- else if (pos == -1) // done
+ if (pos == -1) // done
{
Invocation *inv = this->dump_target_->owner();
if (inv != 0)
@@ -192,338 +202,289 @@ Log::handle_msg_dump (char *line, size_t offset)
if (oid != 0)
inv->set_target (oid, len);
}
+ else
+ {
+ if (this->dump_target_ == &this->unknown_msg_)
+ ACE_ERROR ((LM_ERROR, "%d dump ended with no target owner\n", this->offset_));
+ }
this->dump_target_ = 0;
+ this->unknown_msg_.reset();
}
}
void
-Log::parse_HEXDUMP (Log *this_, char *line, size_t offset)
+Log::parse_HEXDUMP_i (void)
{
- Thread *thr = 0;
-
- char *pos = ACE_OS::strstr (line,"HEXDUMP");
+ char *pos = ACE_OS::strstr (this->line_,"HEXDUMP");
pos += 8;
- size_t len = ACE_OS::strtol (pos, 0, 10);
- for (ACE_DLList_Reverse_Iterator<Thread> t_iter(this_->giop_waiters_);
- !t_iter.done();
- t_iter.advance())
- {
- t_iter.next(thr);
- Invocation::GIOP_Buffer *target = thr->giop_target();
- if (target == 0 || target->expected_size() != len || target->size() > 0)
- continue;
- this_->dump_target_ = target;
- t_iter.remove();
- break;
- }
- if (this_->dump_target_ == 0)
+
+ if (this->dump_target_ != 0)
{
ACE_ERROR ((LM_ERROR,
- "%d: Could not find a giop waiter for size %d\n",
- offset, len));
+ "%d: Parse HEXDUMP in the middle of an existing dump\n",
+ this->offset_));
}
else
- this_->dump_target_->init_buf (line);
+ {
+ this->unknown_msg_.init_buf (this->line_, this->offset_);
+ this->dump_target_ = &this->unknown_msg_;
+ }
}
void
-Log::parse_dump_msg (Log *this_, char *line, size_t offset)
+Log::parse_dump_giop_msg_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
+ int sending = ACE_OS::strstr (this->info_,"send") != 0 ? 0 : 1;
+ int type = ACE_OS::strstr (this->info_,"Request") != 0 ? 0 : 1;
+ int mode = sending + type * 2;
- int mode = ACE_OS::strstr (line,"send") != 0 ? 0 : 1;
- mode += ACE_OS::strstr (line,"Request") != 0 ? 0 : 2;
- char *pos = strrchr (line,'[');
+ char *pos = strrchr (this->info_,'[');
long rid = ACE_OS::strtol(pos+1, 0, 10);
- PeerProcess *pp = thr->incoming();
+ PeerProcess *pp = this->thr_->incoming();
if (pp == 0)
{
ACE_ERROR((LM_ERROR,
"%d: dump_msg, could not find pp for incoming, text = %s\n",
- offset, line));
+ this->offset_, this->info_));
return;
}
- Invocation::GIOP_Buffer *target = 0;
+ GIOP_Buffer *target = 0;
switch (mode)
{
case 1: { // receiving request
- thr->handle_request();
- Invocation *inv = pp->new_invocation (rid,thr);
+ this->thr_->handle_request();
+ Invocation *inv = pp->new_invocation (rid, this->thr_);
if (inv == 0)
{
ACE_ERROR ((LM_ERROR,
"%d: process %s already has invocation %d\n",
- offset, pp->id(), rid));
+ this->offset_, pp->id(), rid));
break;
}
- inv->init (line, offset, thr);
+ inv->init (this->line_, this->offset_, this->thr_);
+ this->thr_->push_invocation (inv);
target = inv->octets(true);
+ if (target == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "%d: no target octets for new recv reqeust, id = %d\n",
+ this->offset_, rid));
+ return;
+ }
break;
}
case 0: // sending request
- thr->enter_wait(pp);
+ this->thr_->enter_wait(pp);
+ this->thr_->push_invocation (0);
// fall through.
case 3: { // receiving reply
- Invocation *inv = pp->find_invocation(rid, thr->active_handle());
+ Invocation *inv = pp->find_invocation(rid, this->thr_->active_handle());
if (inv == 0)
{
ACE_ERROR ((LM_ERROR,
"%d: could not find existing invocation for req_id %d\n",
- offset, rid));
- inv = pp->new_invocation (rid,thr);
+ this->offset_, rid));
+ inv = pp->new_invocation (rid,this->thr_);
}
- inv->init (line, offset, thr);
+ inv->init (this->line_, this->offset_, this->thr_);
target = inv->octets(mode == 0);
if (target == 0 && mode == 3)
{
ACE_ERROR ((LM_ERROR,
"%d: could not map invocation to target for req_id %d\n",
- offset, rid));
+ this->offset_, rid));
return;
}
// if (mode == 3)
-// thr->exit_wait(pp, offset);
+// this->thr_->exit_wait(pp, this->offset_);
break;
}
case 2: { // sending reply
- target = new Invocation::GIOP_Buffer(line,offset, thr);
+ target = new GIOP_Buffer(this->line_, this->offset_, this->thr_);
+ this->thr_->pop_invocation ();
break;
}
default:;
}
- thr->set_giop_target (target);
- this_->giop_waiters_.insert_tail(thr);
- if (this_->giop_waiters_.size() > 1 && (mode == 1 || mode == 3))
+ this->thr_->set_giop_target (target);
+ if (this->giop_waiters_.size() > 0)
{
- size_t prev_size = 0;
- for (ACE_DLList_Reverse_Iterator<Thread> t_iter(this_->giop_waiters_);
+ Thread *other_thr = 0;
+ for (ACE_DLList_Iterator<Thread> t_iter(this->giop_waiters_);
!t_iter.done();
t_iter.advance())
{
- if (prev_size == 0)
- prev_size = target->expected_size();
+ t_iter.next(other_thr);
+ GIOP_Buffer *tgt = other_thr->giop_target();
+ if (target == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "%d: parse_dump_giop_msg_i, target is null, mode = %d, reqid = %d\n",
+ this->offset_, mode, rid));
+ return;
+ }
+ if (tgt != 0 && this->thr_ != other_thr && target->matches (tgt))
+ {
+ this->thr_->set_dup (other_thr, true);
+ }
}
}
+ this->giop_waiters_.insert_tail(this->thr_);
}
void
-Log::parse_open_listener (Log *this_, char *line, size_t )
+Log::parse_open_listener_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- char *addr = ACE_OS::strchr(line,'<') +1;
+ char *addr = ACE_OS::strchr(this->info_,'<') +1;
char *c = ACE_OS::strchr(addr,'>');
*c = '\0';
ACE_CString server_addr(addr);
- hp->add_listen_endpoint(server_addr);
+ this->hostproc_->add_listen_endpoint(server_addr);
}
void
-Log::parse_got_existing (Log *this_, char *line, size_t offset)
+Log::parse_got_existing_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
-
- char *hpos = ACE_OS::strchr(line,'[');
+ char *hpos = ACE_OS::strchr(this->info_,'[');
long handle = ACE_OS::strtol(hpos+1,0,10);
- PeerProcess *pp = hp->find_peer(handle, true);
+ PeerProcess *pp = this->hostproc_->find_peer(handle);
if (pp == 0)
{
ACE_ERROR ((LM_ERROR,
"%d: Error parsing %C, can't find peer "
"for handle %d, text = %s\n",
- offset, this_->origin_.c_str(), handle, line));
+ this->offset_, this->origin_.c_str(), handle, this->info_));
return;
}
- thr->active_handle (handle);
+ this->thr_->active_handle (handle);
}
void
-Log::parse_muxed_tms (Log *this_, char *line, size_t offset)
+Log::parse_muxed_tms_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
-
- char *hpos = ACE_OS::strchr(line,'[');
+ char *hpos = ACE_OS::strchr(this->info_,'[');
long handle = ACE_OS::strtol(hpos+1,0,10);
hpos = ACE_OS::strchr(hpos, '<');
long req_id = ACE_OS::strtol(hpos+1,0,10);
- PeerProcess *pp = hp->find_peer(handle, true);
+ PeerProcess *pp = this->hostproc_->find_peer(handle);
if (pp == 0)
{
ACE_ERROR ((LM_ERROR,
"%d: Error parsing %C, can't find peer "
"for handle %d, text = %s\n",
- offset, this_->origin_.c_str(), handle, line));
+ this->offset_, this->origin_.c_str(), handle, this->info_));
return;
}
- thr->active_handle (handle);
+ this->thr_->active_handle (handle);
- Invocation *inv = pp->new_invocation(req_id, thr);
+ Invocation *inv = pp->new_invocation(req_id, this->thr_);
if (inv == 0)
ACE_DEBUG ((LM_DEBUG,"%d: peer %s already has invocation id %d\n",
- offset, pp->id(), req_id));
- thr->incoming_from (pp);
+ this->offset_, pp->id(), req_id));
+ this->thr_->incoming_from (pp);
}
void
-Log::parse_exclusive_tms (Log *this_, char *line, size_t offset)
+Log::parse_exclusive_tms_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
-
- long handle = thr->active_handle();
- PeerProcess *pp = hp->find_peer(handle, true);
+ long handle = this->thr_->active_handle();
+ PeerProcess *pp = this->hostproc_->find_peer(handle);
if (pp == 0)
{
ACE_ERROR ((LM_ERROR,
"%d: Error parsing %C, can't find peer "
"for handle %d, text = %s\n",
- offset, this_->origin_.c_str(), handle, line));
+ this->offset_, this->origin_.c_str(), handle, this->info_));
return;
}
- char *rpos = ACE_OS::strchr(line, '<');
+ char *rpos = ACE_OS::strchr(this->info_, '<');
long req_id = ACE_OS::strtol(rpos+1,0,10);
- Invocation *inv = pp->new_invocation(req_id, thr);
+ Invocation *inv = pp->new_invocation(req_id, this->thr_);
if (inv == 0)
ACE_DEBUG ((LM_DEBUG,"%d: peer %s already has invocation id %d\n",
- offset, pp->id(), req_id));
- thr->incoming_from (pp);
+ this->offset_, pp->id(), req_id));
+ this->thr_->incoming_from (pp);
}
void
-Log::parse_process_parsed_msgs (Log *this_, char *line, size_t offset)
+Log::parse_process_parsed_msgs_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
-
- char *hpos = ACE_OS::strchr(line,'[');
- long handle = ACE_OS::strtol(hpos+1,0,10);
+ char *hpos = ACE_OS::strchr(this->info_, '[');
+ long handle = ACE_OS::strtol(hpos+1, 0, 10);
- PeerProcess *pp = hp->find_peer(handle, true);
+ PeerProcess *pp = this->hostproc_->find_peer(handle);
if (pp == 0)
{
ACE_ERROR ((LM_ERROR,
"%d: Error parsing %C, can't find peer "
"for handle %d, text = %s\n",
- offset, this_->origin_.c_str(), handle, line));
- pp = new PeerProcess (offset,true);
- Transport *t = new Transport ("<unknown>",false, offset);
+ this->offset_, this->origin_.c_str(), handle, this->info_));
+ pp = new PeerProcess (this->offset_, true);
+ Transport *t = new Transport ("<unknown>", false, this->offset_);
t->handle_ = handle;
pp->add_transport(t);
- hp->add_peer (handle,pp);
+ this->hostproc_->add_peer (handle,pp);
return;
}
- thr->active_handle(handle);
- thr->incoming_from (pp);
+ this->thr_->active_handle(handle);
+ this->thr_->incoming_from (pp);
}
void
-Log::parse_wait_for_event (Log *this_, char *line, size_t offset)
+Log::parse_wait_for_event_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
+// char *pos = ACE_OS::strchr (this->info_,'[');
+// long rid = ACE_OS::strtol(pos+1, 0, 10);
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
+ bool done = (ACE_OS::strstr (this->info_,"done (follower)") != 0) ||
+ (ACE_OS::strstr(this->info_,"(leader) exit") != 0);
- PeerProcess *pp = thr->incoming();
+ PeerProcess *pp = this->thr_->incoming();
if (pp == 0)
+ pp = this->thr_->pending_peer();
+ if (pp != 0 && done)
{
- ACE_ERROR((LM_ERROR,
- "%d: wait_for_event, could not find peer process for incoming, text = %s\n",
- offset, line));
- return;
+ this->thr_->exit_wait(pp, this->offset_);
}
-
- bool done = (ACE_OS::strstr (line,"done (follower)") != 0) ||
- (ACE_OS::strstr(line,"(leader) exit") != 0);
-
-
- if (done)
- thr->exit_wait(pp, offset);
-// else
-// thr->enter_wait(pp);
}
void
-Log::parse_wait_on_read (Log *this_, char *line, size_t offset)
+Log::parse_wait_on_read_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
- PeerProcess *pp = thr->incoming();
-
- thr->exit_wait (pp, offset);
+ PeerProcess *pp = this->thr_->incoming();
+ this->thr_->exit_wait (pp, this->offset_);
}
void
-Log::parse_cleanup_queue (Log *this_, char *line, size_t offset)
+Log::parse_cleanup_queue_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
-
- char *hpos = ACE_OS::strchr(line,'[');
+ char *hpos = ACE_OS::strchr(this->info_,'[');
long handle = ACE_OS::strtol(hpos+1,0,10);
- PeerProcess *pp = hp->find_peer(handle, false);
- if (pp == 0)
- {
- ACE_ERROR ((LM_ERROR,
- "%d: cleanup queue, could not find peer for handle %d\n",
- offset, handle));
- return;
- }
+ PeerProcess *pp = this->hostproc_->find_peer(handle);
- Thread *original_thr = thr;
- Invocation::GIOP_Buffer *target = original_thr->giop_target();
+ Thread *original_thr = this->thr_;
+ GIOP_Buffer *target = original_thr->giop_target();
if (target == 0 || target->owner() != 0)
{
- original_thr = hp->find_thread_for_handle (handle);
+ original_thr = this->hostproc_->find_thread_for_handle (handle);
if (original_thr == 0)
{
ACE_ERROR ((LM_ERROR,
"%d: cleanup queue, no original "
"thread found, handle %d\n",
- offset, handle));
+ this->offset_, handle));
return;
}
target = original_thr->giop_target();
}
+ if (target != 0 && target->cur_size() == 0 && original_thr->has_dup())
+ {
+ ACE_ERROR ((LM_ERROR, "%d: cleanup queue, swapping targets for thread %d\n",
+ this->offset_, original_thr->id()));
+ original_thr->swap_target();
+ }
original_thr->set_giop_target(0);
original_thr->active_handle (0);
@@ -536,18 +497,18 @@ Log::parse_cleanup_queue (Log *this_, char *line, size_t offset)
{
ACE_ERROR ((LM_ERROR,
"%d: Cleanup queue detected, "
- "could not find invocation for rid = %d\n",
- offset, rid));
+ "could not find invocation for rid = %d on thread %d\n",
+ this->offset_, rid, original_thr->id()));
rid = target->expected_req_id();
inv = pp->find_invocation (rid, handle);
if (inv == 0)
{
ACE_ERROR ((LM_ERROR,
- "%d, Cleanup queue still failed to find rid %d\n",
- offset, rid));
+ "%d, Cleanup queue still failed to find rid %d, on thread %d\n",
+ this->offset_, rid, original_thr->id()));
return;
}
- original_thr->exit_wait(pp, offset);
+ original_thr->exit_wait(pp, this->offset_);
mtype = target->expected_type();
}
inv->set_octets (mtype == 0, target);
@@ -560,48 +521,76 @@ Log::parse_cleanup_queue (Log *this_, char *line, size_t offset)
}
void
-Log::parse_close_connection (Log *this_, char *line, size_t offset)
+Log::parse_close_connection_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
-
- char *hpos = ACE_OS::strchr(line,'[');
+ char *hpos = ACE_OS::strchr(this->info_,'[');
long handle = ACE_OS::strtol(hpos+1,0,10);
- PeerProcess *pp = hp->find_peer(handle, false);
+ PeerProcess *pp = this->hostproc_->find_peer(handle);
if (pp != 0)
{
Transport *t = pp->find_transport (handle);
if (t != 0)
- t->close_offset_ = offset;
+ t->close_offset_ = this->offset_;
}
- hp->close_peer(handle);
+ this->hostproc_->remove_peer(handle);
}
void
-Log::parse_handler_open (Log *this_, char *line, size_t offset)
+Log::parse_handler_open_i (bool is_ssl)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
-
- char *addr = ACE_OS::strchr(line,'<') +1;
+ char *addr = ACE_OS::strrchr(this->info_,'<') +1;
char *c = ACE_OS::strchr(addr,'>');
*c = '\0';
c = ACE_OS::strstr(c+1,"on ");
- long handle = ACE_OS::strtol(c + 3,0,10);
- PeerProcess *pp = thr->pending_peer();
+ c += 3;
+ if (*c == '[')
+ c++;
+ long handle = ACE_OS::strtol(c,0,10);
+ PeerProcess *pp = 0;
+ if (this->conn_waiters_.size() > 0)
+ {
+ for (ACE_DLList_Iterator<PeerProcess> c_iter (this->conn_waiters_);
+ !c_iter.done();
+ c_iter.advance())
+ {
+ PeerProcess *waiter = 0;
+ c_iter.next(waiter);
+ if (waiter != 0 && waiter->match_server_addr (addr, session_))
+ {
+ pp = waiter;
+ c_iter.remove();
+ break;
+ }
+ }
+ }
+ else
+ {
+ pp = this->thr_->pending_peer();
+ }
if (pp == 0)
+ {
+ ACE_ERROR ((LM_ERROR,"%d: no pending peer for addr %s\n",
+ this->offset_, addr));
+ return;
+ }
+
+ pp->ssl (is_ssl);
+
+ const ACE_CString &local_addr = this->thr_->pending_local_addr();
+ if (local_addr.length() > 0 )
{
- ACE_ERROR ((LM_ERROR,"%d: no pending peer for file %s\n",
- offset, this_->origin_.c_str()));
- return;
+ if (pp->is_server())
+ {
+ Transport *t = new Transport (addr, true, this->offset_);
+ pp->add_transport (t);
+ this->hostproc_->add_client_endpoint (t->client_endpoint_);
+ }
+ else
+ {
+ pp->set_server_addr (local_addr);
+ }
+ this->thr_->pending_local_addr ("");
}
Transport *trans = 0;
@@ -613,209 +602,378 @@ Log::parse_handler_open (Log *this_, char *line, size_t offset)
ACE_ERROR ((LM_ERROR,
"%d: Pending peer exists, but no last transport "
"set, file %s\n",
- offset, this_->origin_.c_str()));
+ this->offset_, this->origin_.c_str()));
return;
}
// trans->client_endpoint_ = addr;
}
else
{
- trans = new Transport (addr,false,offset);
+ trans = new Transport (addr, false, this->offset_);
pp->add_transport(trans);
}
trans->handle_ = handle;
- thr->pending_peer(0);
- hp->add_peer(handle,pp);
+ this->thr_->pending_peer(0);
+ this->hostproc_->add_peer (handle,pp);
}
void
-Log::parse_SSLIOP_from_client (Log *this_, char *line, size_t offset)
+Log::parse_begin_connection_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
-
- char *addr = ACE_OS::strchr(line,'<') +1;
+ char *addr = ACE_OS::strchr(this->info_,'<') +1;
char *c = ACE_OS::strchr(addr,'>');
*c = '\0';
- c = ACE_OS::strstr(c+1,"on [");
-
- PeerProcess *pp = thr->pending_peer();
+ PeerProcess *pp = this->hostproc_->find_peer(addr);
if (pp == 0)
{
- pp = new PeerProcess (offset, false);
- thr->pending_peer (pp);
+ pp = new PeerProcess(this->offset_, true);
+ pp->set_server_addr (addr);
}
-
- pp->set_server_addr(addr);
+ this->conn_waiters_.insert_tail (pp);
+ this->thr_->pending_peer (pp);
}
+
void
-Log::parse_SSLIOP_from_server (Log *this_, char *line, size_t offset)
+Log::parse_local_addr_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
-
- char *addr = ACE_OS::strchr(line,'<') +1;
+ char *addr = ACE_OS::strchr(this->info_,'<') +1;
char *c = ACE_OS::strchr(addr,'>');
*c = '\0';
- c = ACE_OS::strstr(c+1,"on [");
- long handle = ACE_OS::strtol(c + 4,0,10);
- PeerProcess *pp = thr->pending_peer();
- if (pp == 0)
+
+ PeerProcess *peer = this->thr_->pending_peer();
+ if (peer == 0)
{
- ACE_ERROR ((LM_ERROR,"%d: no pending peer for file %s\n",
- offset, this_->origin_.c_str()));
- return;
+ this->thr_->pending_local_addr (addr);
+ return;
}
- Transport *trans = new Transport (addr,false,offset);
- pp->add_transport(trans);
- trans->handle_ = handle;
- thr->pending_peer(0);
- hp->add_peer(handle,pp);
+ if (peer->is_server())
+ {
+ Transport *t = new Transport (addr, true, this->offset_);
+ peer->add_transport (t);
+ this->hostproc_->add_client_endpoint (t->client_endpoint_);
+ }
+ else
+ {
+ peer->set_server_addr (addr);
+ }
}
void
-Log::parse_begin_connection (Log *this_, char *line, size_t offset)
+Log::parse_connection_not_complete_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
+ this->thr_->pending_peer (0);
+}
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
+void
+Log::parse_open_as_server_i (void)
+{
+ this->thr_->pending_peer (new PeerProcess(this->offset_, false));
+}
- char *addr = ACE_OS::strchr(line,'<') +1;
- char *c = ACE_OS::strchr(addr,'>');
- *c = '\0';
- PeerProcess *pp = hp->find_peer(addr);
+void
+Log::parse_iiop_connection_handler_ctor_i (void)
+{
+ PeerProcess *pp = this->thr_->pending_peer();
if (pp == 0)
{
- pp = new PeerProcess(offset,true);
- pp->set_server_addr (addr);
+ ACE_ERROR ((LM_ERROR, "%d: parse_iiop_connection_handler_ctor_i: no pending peer on thread\n", this->offset_));
+ return;
}
- thr->pending_peer (pp);
+
+#if 0
+ char *pos = ACE_OS::strchr (this->info_,'[') + 1;
+ long tmp_handle = ACE_OS::strtol (pos, 0, 10);
+ // pp->set_handle (tmp_handle);
+#endif
}
void
-Log::parse_SSLIOP_begin_connection (Log *this_, char *line, size_t offset)
+Log::parse_wait_for_connection_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
+ ACE_ERROR ((LM_ERROR,"%d: parse_wait_for_connection, line = %s\n", this->offset_, this->line_));
+ if (ACE_OS::strstr (this->info_,"Connection not complete") == 0)
+ {
+ return;
+ }
+ else if (ACE_OS::strstr (this->info_,"wait done result =") == 0)
+ {
+ char *pos = ACE_OS::strchr (this->info_, '=') + 2;
+ int result = ACE_OS::strtol (pos, 0, 10);
+ if (result == 1)
+ return;
+ pos = ACE_OS::strchr (this->info_, '[') + 1;
+ long handle = ACE_OS::strtol (pos, 0, 10);
+ PeerProcess *pp = 0;
+
+ ACE_DEBUG ((LM_DEBUG, "%d: parse_wait_for_connection: wait done, result = %d, purging handle = %d\n", this->offset_, result, handle));
+
+ if (this->conn_waiters_.size() > 0)
+ {
+ for (ACE_DLList_Iterator<PeerProcess> c_iter (this->conn_waiters_);
+ !c_iter.done();
+ c_iter.advance())
+ {
+ PeerProcess *waiter = 0;
+ c_iter.next(waiter);
+ if (waiter != 0)
+ {
+ Transport *t = waiter->find_transport (handle);
+ if (t != 0)
+ {
+ pp = waiter;
+ c_iter.remove();
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ pp = this->thr_->pending_peer();
+ Transport *t = pp->find_transport (handle);
+ if (t == 0)
+ {
+ pp = 0;
+ }
+ else
+ {
+ this->thr_->pending_peer (0);
+ }
+ }
+ if (pp == 0)
+ {
+ ACE_ERROR ((LM_ERROR,"%d: no pending peer for handle %s\n",
+ this->offset_, handle));
+ return;
+ }
+ delete pp;
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
+ }
+}
- PeerProcess *pp = new PeerProcess(offset,true);
- thr->pending_peer (pp);
+void
+Log::parse_post_open_i (void)
+{
+ // ACE_ERROR ((LM_ERROR,"%d: parse_post_open, line = %s\n", this->offset_, this->line_));
}
void
-Log::parse_local_addr (Log *this_, char *line, size_t offset)
+Log::parse_notify_poa_helper_i (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
+ Invocation *inv = this->thr_->current_invocation ();
+ if (inv == 0)
+ {
+ ACE_ERROR ((LM_ERROR,"%d: parse_notify_poa_helper line = %s, no current invocation on thread\n", this->offset_, this->info_));
+ return;
+ }
+ bool activate = ACE_OS::strstr (this->info_, "Activating") != 0;
+ char *idpos = ACE_OS::strstr (this->info_, "id = ");
+ long objid = ACE_OS::strtol (idpos + 5, 0, 10);
+ idpos = ACE_OS::strstr (idpos + 5, "in POA : ");
+ long poaid = ACE_OS::strtol (idpos + 10, 0, 10);
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
+ char buffer[100];
+ ACE_OS::sprintf (buffer,"Notify object %s, object id %ld, POA %ld on line %ld",
+ (activate ? "activation" : "deactivation"), objid, poaid,
+ (unsigned long)this->offset_);
+ ACE_CString text (buffer);
- PeerProcess *peer = thr->pending_peer();
- if (peer == 0)
+ inv->add_notify_incident (text, this->offset_);
+}
+
+void
+Log::parse_notify_object_i (void)
+{
+ Invocation *inv = this->thr_->current_invocation ();
+ if (inv == 0)
{
- ACE_ERROR((LM_ERROR, "%d: file %s, no pending client or server\n",
- offset, this_->origin_.c_str()));
- return;
+ // ACE_ERROR ((LM_ERROR,"%d: parse_notify_object line = %s, no current invocation on thread\n", this->offset_, this->info_));
}
- char *addr = ACE_OS::strchr(line,'<') +1;
- char *c = ACE_OS::strchr(addr,'>');
- *c = '\0';
- if (peer->is_server())
+ char *ptr = ACE_OS::strstr (this->info_, "object:") + 7;
+ u_long objid = ACE_OS::strtol (ptr, &ptr, 16);
+ char note[100];
+ note[0] = 0;
+ if (ACE_OS::strstr (ptr, "created") != 0)
{
- Transport *t = new Transport (addr, true, offset);
- peer->add_transport (t);
- hp->add_client_endpoint (t->client_endpoint_);
+ ::sprintf (note, "Created notify object %lx",objid);
+#if 0
+ NotifyObject notobj = new NotifyObject (objid, this->offset_, this->timestamp_);
+ this->hostproc_->add_notify_obj (notobj);
+#endif
}
- else
+ else if (ACE_OS::strstr (ptr, "destroyed") != 0)
{
- peer->set_server_addr (addr);
+ ::sprintf (note, "Destroyed notify object %lx",objid);
+#if 0
+ NotifyObject notobj = this->hostproc_->find_notify_obj (objid);
+ if (notobj == 0)
+ {
+ ACE_ERROR ((LM_ERROR, "%d: could not find notify object %lx\n", this->offset_, objid));
+ }
+ else
+ {
+ notobj->destroyed (this->offset_, this->timestamp_);
+ }
+#endif
+ }
+ else if (ACE_OS::strstr (ptr, "incr ") != 0)
+ {
+ ptr = ACE_OS::strchr (ptr, '=');
+ int count = ACE_OS::strtol (ptr + 2, 0, 10);
+ ::sprintf (note, "increment reference notify object %lx, count now %d",objid, count);
+#if 0
+ NotifyObject notobj = this->hostproc_->find_notify_obj (objid);
+ if (notobj == 0)
+ {
+ notobj = new NotifyObject (objid, this->offset_, this->timestamp_);
+ this->hostproc_->add_notify_obj (notobj);
+ }
+ notobj->incr (this->offset_, this->timestamp_);
+#endif
+ }
+ else if (ACE_OS::strstr (ptr, "decr ") != 0)
+ {
+ ptr = ACE_OS::strchr (ptr, '=');
+ int count = ACE_OS::strtol (ptr + 2, 0, 10);
+ ::sprintf (note, "decrement reference notify object %lx, count now %d",objid, count);
+#if 0
+ NotifyObject notobj = this->hostproc_->find_notify_obj (objid);
+ if (notobj == 0)
+ {
+ ACE_ERROR ((LM_ERROR, "%d: could not find notify object %x\n", this->offset_, objid));
+ }
+ else
+ {
+ notobj->decr (this->offset_, this->timestamp_);
+ }
+#endif
}
+
+ ACE_CString text (note);
+ if (inv)
+ inv->add_notify_incident (text, this->offset_);
}
void
-Log::parse_open_as_server (Log *this_, char *line, size_t offset)
+Log::get_timestamp (void)
{
- long pid = 0;
- long tid = 0;
- this_->get_pid_tid(pid,tid,line);
-
- HostProcess *hp = this_->get_host(pid);
- Thread *thr = hp == 0 ? 0 : hp->find_thread (tid);
-
- thr->pending_peer (new PeerProcess(offset, false));
-
+ const char *time_tok = ACE_OS::strchr (this->line_,'@');
+ size_t len = (size_t)(time_tok - this->line_);
+ if (time_tok != 0 && len < 30)
+ {
+ this->timestamp_ = ACE_CString (this->line_, len);
+#if 0
+ int year, mon, day;
+ int hr, min, sec, msec;
+ ::sscanf (hms+1,"%d-%d-%d %d:%d:%d.%d", &year, &mon, &day, &hr, &min, &sec, &msec);
+ time = (hr * 3600 + min *60 + sec) * 1000 + msec;
+ if (this->time_ > time)
+ time += 24 * 3600 * 1000;
+#endif
+ }
}
void
-Log::parse_line (char *line, size_t offset)
+Log::parse_line (void)
{
- // first, is it a client connection to a new peer?
- // next is it a server connection to a new peer?
- // is it a new request or reply?
- // a GIOP hex dump?
-
- static parse_key exprs[] =
- {
- { "Handler::open, IIOP connection to peer", parse_handler_open },
- { "GIOP_Message_Base::dump_msg,", parse_dump_msg },
- { "GIOP message - HEXDUMP", parse_HEXDUMP },
- { "open_i, listening on:", parse_open_listener },
- { "open_i - listening on:", parse_open_listener },
- { "Muxed_TMS[", parse_muxed_tms },
- { "Exclusive_TMS::request_id", parse_exclusive_tms },
- { "process_parsed_messages", parse_process_parsed_msgs },
- { "wait_for_event", parse_wait_for_event },
- { "Wait_On_Read", parse_wait_on_read },
- { "::cleanup_queue, byte_count", parse_cleanup_queue },
- { "close_connection_eh", parse_close_connection },
- { "ssliop_connect, making a new ", parse_SSLIOP_begin_connection },
- { "SSLIOP connection from client", parse_SSLIOP_from_client },
- { "SSLIOP connection accepted from server", parse_SSLIOP_from_server },
- { "IIOP_Connector::begin_connection, to ", parse_begin_connection },
- { "IIOP_Connection_Handler::open, The local addr is", parse_local_addr },
- { "opened as TAO_SERVER_ROLE", parse_open_as_server },
- { "Transport_Connector::connect, got an existing connected", parse_got_existing },
- { 0,0 }
- };
-
if (this->dump_target_ != 0)
{
- this->handle_msg_dump (line, offset);
+ this->handle_msg_octets ();
return;
}
- for (int i = 0; exprs[i].text != 0; i++)
+ this->get_preamble();
+ this->get_timestamp();
+
+ if (ACE_OS::strstr (this->info_, "Handler::open, IIOP connection to peer") != 0)
{
- if (ACE_OS::strstr(line, exprs[i].text) != 0)
- {
- (*exprs[i].op)(this, line, offset);
- return;
- }
+ this->parse_handler_open_i(false);
+ }
+ else if (ACE_OS::strstr (this->info_, "GIOP_Message_Base::dump_msg,") != 0)
+ {
+ this->parse_dump_giop_msg_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "GIOP message - HEXDUMP") != 0)
+ {
+ this->parse_HEXDUMP_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "open_i, listening on:") != 0)
+ {
+ this->parse_open_listener_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "Muxed_TMS[") != 0)
+ {
+ this->parse_muxed_tms_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "Exclusive_TMS::request_id") != 0)
+ {
+ this->parse_exclusive_tms_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "process_parsed_messages") != 0)
+ {
+ this->parse_process_parsed_msgs_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "wait_for_event") != 0)
+ {
+ this->parse_wait_for_event_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "Wait_On_Read") != 0)
+ {
+ this->parse_wait_on_read_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "::cleanup_queue, byte_count") != 0)
+ {
+ this->parse_cleanup_queue_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "close_connection_eh") != 0)
+ {
+ this->parse_close_connection_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "IIOP_Connector::begin_connection, to ") != 0)
+ {
+ this->parse_begin_connection_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "IIOP_Connection_Handler::open, The local addr is") != 0)
+ {
+ this->parse_local_addr_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "Connection not complete.") != 0)
+ {
+ this->parse_connection_not_complete_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "opened as TAO_SERVER_ROLE") != 0)
+ {
+ this->parse_open_as_server_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "Transport_Connector::connect, got an existing connected") != 0)
+ {
+ this->parse_got_existing_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "Transport_Connector::wait_for_connection_competion") != 0)
+ {
+ this->parse_wait_for_connection_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "Transport::post_open, tport") != 0)
+ {
+ this->parse_post_open_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "SSLIOP connection from client") != 0)
+ {
+ this->parse_handler_open_i(true);
+ }
+ else if (ACE_OS::strstr (this->info_, "SSLIOP connection accepted from server") != 0)
+ {
+ this->parse_local_addr_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "POA_Helper") != 0)
+ {
+ this->parse_notify_poa_helper_i();
+ }
+ else if (ACE_OS::strstr (this->info_, "object:") != 0)
+ {
+ this->parse_notify_object_i ();
}
return;
}
-
-void
-Log::summarize (void)
-{
- // todo
-}
diff --git a/TAO/utils/logWalker/Log.h b/TAO/utils/logWalker/Log.h
index 3aaffa8853d..682f7a21bb6 100644
--- a/TAO/utils/logWalker/Log.h
+++ b/TAO/utils/logWalker/Log.h
@@ -9,68 +9,87 @@
#include "ace/Containers.h"
#include "ace/Synch.h"
#include "ace/SString.h"
+#include "ace/Time_Value.h"
#include "PeerProcess.h"
#include "HostProcess.h"
+#include "GIOP_Buffer.h"
class Session;
class HostProcess;
+class Invocation;
typedef ACE_DLList<HostProcess> HostProcesses;
+class Incident
+{
+public:
+ ACE_CString timestamp_;
+ size_t offset_;
+ int thread_;
+ ACE_CString annotation_;
+ Invocation *invocation_;
+};
+
+typedef ACE_Unbounded_Queue<Incident> IncidentList;
+
+
class Log
{
public:
Log (Session &s);
- ~Log();
-
- bool init (const ACE_TCHAR *filename, const char *alias = "");
-
- void summarize(void);
-
- void dump (ostream &strm);
-
-private:
- typedef void (* parser_func)(Log *this_, char *line, size_t offset);
-
- struct parse_key
- {
- const char *text;
- parser_func op;
- };
-
- bool get_pid_tid (long &pid, long &tid, char *line);
- HostProcess *get_host (long pid);
- void handle_msg_dump (char *line, size_t offset);
- void parse_line (char* line, size_t offset);
-
- static void parse_handler_open (Log *this_, char *line, size_t offset);
- static void parse_SSLIOP_handler_open (Log *this_, char *line, size_t offset);
- static void parse_dump_msg (Log *this_, char *line, size_t offset);
- static void parse_HEXDUMP (Log *this_, char *line, size_t offset);
- static void parse_open_listener (Log *this_, char *line, size_t offset);
- static void parse_got_existing (Log *this_, char *line, size_t offset);
- static void parse_muxed_tms (Log *this_, char *line, size_t offset);
- static void parse_exclusive_tms (Log *this_, char *line, size_t offset);
- static void parse_process_parsed_msgs (Log *this_, char *line, size_t offset);
- static void parse_wait_for_event (Log *this_, char *line, size_t offset);
- static void parse_wait_on_read (Log *this_, char *line, size_t offset);
- static void parse_cleanup_queue (Log *this_, char *line, size_t offset);
- static void parse_close_connection (Log *this_, char *line, size_t offset);
- static void parse_begin_connection (Log *this_, char *line, size_t offset);
- static void parse_SSLIOP_begin_connection (Log *this_, char *line, size_t offset);
- static void parse_SSLIOP_from_client (Log *this_, char *line, size_t offset);
- static void parse_SSLIOP_from_server (Log *this_, char *line, size_t offset);
- static void parse_local_addr (Log *this_, char *line, size_t offset);
- static void parse_open_as_server (Log *this_, char *line, size_t offset);
+ virtual ~Log(void);
+
+ bool process_file (const ACE_TCHAR *filename, const char *alias = "");
+
+protected:
+
+ virtual void parse_line (void);
+
+ void get_preamble (void);
+ void get_timestamp (void);
+ void handle_msg_octets (void);
+ bool match_target(void);
+
+ void parse_handler_open_i (bool is_ssl);
+ void parse_dump_giop_msg_i (void);
+ void parse_HEXDUMP_i (void);
+ void parse_open_listener_i (void);
+ void parse_got_existing_i (void);
+ void parse_muxed_tms_i (void);
+ void parse_exclusive_tms_i (void);
+ void parse_process_parsed_msgs_i (void);
+ void parse_wait_for_event_i (void);
+ void parse_wait_on_read_i (void);
+ void parse_cleanup_queue_i (void);
+ void parse_close_connection_i (void);
+ void parse_begin_connection_i (void);
+ void parse_local_addr_i (void);
+ void parse_connection_not_complete_i (void);
+ void parse_open_as_server_i (void);
+ void parse_iiop_connection_handler_ctor_i (void);
+ void parse_wait_for_connection_i (void);
+ void parse_post_open_i (void);
+ void parse_notify_poa_helper_i (void);
+ void parse_notify_object_i (void);
ACE_CString origin_;
ACE_CString alias_;
Session &session_;
HostProcesses procs_;
- Invocation::GIOP_Buffer* dump_target_;
+ GIOP_Buffer unknown_msg_;
+ GIOP_Buffer* dump_target_;
ThreadList giop_waiters_;
-
+ ACE_DLList<PeerProcess> conn_waiters_;
+ IncidentList history_;
+
+ // parsed for every line
+ ACE_CString timestamp_;
+ char *line_;
+ char *info_;
+ size_t offset_;
+ HostProcess *hostproc_;
+ Thread *thr_;
};
#endif // LOG_WALKER_LOG_H
diff --git a/TAO/utils/logWalker/PeerObject.cpp b/TAO/utils/logWalker/PeerObject.cpp
index 3cf504bcb5e..00ec6e7f9c9 100644
--- a/TAO/utils/logWalker/PeerObject.cpp
+++ b/TAO/utils/logWalker/PeerObject.cpp
@@ -41,7 +41,10 @@ PeerObject::num_invocations (void)
void
PeerObject::dump_detail (ostream &strm)
{
- strm << this->ident_ << " has "
- << this->invocations_.size() << " invocations" << endl;
+ size_t s = this->invocations_.size();
+ strm << " " << this->name_ << " has "
+ << s << " invocation"
+ << (s > 1 ? "s" : "")
+ << endl;
}
diff --git a/TAO/utils/logWalker/PeerProcess.cpp b/TAO/utils/logWalker/PeerProcess.cpp
index 10669845dda..00e51c68d77 100644
--- a/TAO/utils/logWalker/PeerProcess.cpp
+++ b/TAO/utils/logWalker/PeerProcess.cpp
@@ -3,6 +3,7 @@
#include "PeerProcess.h"
#include "PeerObject.h"
#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_string.h"
#include "ace/ACE.h"
#include "Invocation.h"
#include "HostProcess.h"
@@ -20,23 +21,27 @@ Transport::Transport (const char *addr, bool is_client, size_t offset)
}
char *
-PeerProcess::nextIdent(void)
+PeerProcess::nextIdent(bool is_server)
{
static int count = 0;
char *ident = new char[15];
- ACE_OS::sprintf (ident,"proc_%d", count++);
+ ACE_OS::sprintf (ident,"%s_%d", (is_server ? "server" : "client"), count++);
return ident;
}
PeerProcess::PeerProcess (size_t offset, bool is_server)
: owner_ (0),
remote_ (0),
- server_addr_(),
+ server_port_(),
+ server_host_(),
server_(is_server),
+ ssl_(false),
+ localhost_(false),
origin_offset_ (offset),
- objects_ ()
+ objects_ (),
+ object_by_index_ ()
{
- this->ident_ = PeerProcess::nextIdent();
+ this->ident_ = PeerProcess::nextIdent(is_server);
}
PeerProcess::~PeerProcess (void)
@@ -54,26 +59,43 @@ PeerProcess::~PeerProcess (void)
break;
delete entry->item();
}
- for (TransportList::ITERATOR i(this->transports_); !i.done(); i++)
- {
- ACE_DLList_Node *entry;
- if (i.next(entry) == 0)
- break;
- //i.remove ();
- delete reinterpret_cast<Transport*>(entry->item_);
- }
}
void
-PeerProcess::set_server_addr (const char *addr)
+PeerProcess::set_server_addr (const ACE_CString &addr)
{
- this->server_addr_ = addr;
+ size_t p = addr.rfind (':');
+ this->server_port_ = addr.substring(p);
+ this->server_host_ = addr.substring(0,p);
+
+ this->localhost_ = this->server_host_ == "localhost" ||
+ this->server_host_ == "127.0.0.1" || this->server_host_ == "[::1]";
}
-const ACE_CString&
+bool
+PeerProcess::match_server_addr (const ACE_CString &addr, Session &session) const
+{
+ size_t p = addr.rfind (':');
+ ACE_CString port = addr.substring (p);
+ ACE_CString host = addr.substring (0,p);
+ if (port != this->server_port_)
+ return false;
+
+ if (this->localhost_)
+ {
+ return host == "localhost" || host == "127.0.0.1" || host == "[::1]";
+ }
+
+ if (this->server_host_ == host)
+ return true;
+
+ return session.is_equivalent (this->server_host_, host);
+}
+
+ACE_CString
PeerProcess::server_addr (void) const
{
- return this->server_addr_;
+ return this->server_host_ + this->server_port_;
}
const ACE_CString&
@@ -89,6 +111,12 @@ PeerProcess::is_server (void) const
}
void
+PeerProcess::ssl (bool is_ssl)
+{
+ this->ssl_ = is_ssl;
+}
+
+void
PeerProcess::add_transport (Transport *t)
{
this->last_transport_ = t;
@@ -118,7 +146,6 @@ PeerProcess::find_transport (long handle)
return 0;
}
-
void
PeerProcess::match_hosts (Session *session)
{
@@ -127,7 +154,7 @@ PeerProcess::match_hosts (Session *session)
// then this wants to find the remote based on the Transport
// instance
if (this->server_)
- this->remote_ = session->find_host(this->server_addr_, true);
+ this->remote_ = session->find_host(this->server_host_, true);
else
{
Transport *t = 0;
@@ -161,8 +188,9 @@ PeerProcess::object_for (const char *oid, size_t len)
long index = static_cast<long>(objects_.current_size());
char alias[20];
ACE_OS::sprintf (alias, "obj_%ld", index);
- po = new PeerObject(index,alias, this);
+ po = new PeerObject(index, alias, this);
objects_.bind(key, po);
+ object_by_index_.bind (index, po);
}
return po;
}
@@ -172,7 +200,7 @@ PeerProcess::new_invocation (size_t req_id, Thread *thr)
{
if (this->find_invocation (req_id, thr->active_handle()) != 0)
return 0;
- Invocation *inv = new Invocation (this, thr->active_handle(), req_id);
+ Invocation *inv = new Invocation (this, thr, req_id);
this->invocations_.insert_tail(inv);
thr->add_invocation (inv);
return inv;
@@ -236,11 +264,13 @@ PeerProcess::dump_summary (ostream &strm)
else
strm << " peer process " << this->ident_;
strm << " is a ";
+ if (this->ssl_)
+ strm << "secure ";
if (this->server_)
strm << "server at ";
else
strm << "client to ";
- strm << this->server_addr_;
+ strm << this->server_host_ << this->server_port_;
strm << " with " << num_transports << " connections, ";
strm << " referenced " << this->objects_.current_size()
<< " objects in " << this->invocations_.size() << " invocations";
@@ -252,7 +282,7 @@ PeerProcess::dump_summary (ostream &strm)
Transport *tran = 0;
i.next(tran);
strm << " connection[" << tran->handle_ << "] ";
- strm << (tran->local_is_client_ ? "from " : "to ");
+ strm << (tran->local_is_client_ ? "to " : "from ");
strm << tran->client_endpoint_;
strm << " created line " << tran->open_offset_;
if (tran->close_offset_)
@@ -265,18 +295,22 @@ void
PeerProcess::dump_object_detail (ostream &strm)
{
strm << this->objects_.current_size()
- << " Objects referenced in ";
+ << " Objects referenced";
+ if (this->server_)
+ strm << " in ";
+ else
+ strm << " by ";
if (this->remote_)
strm << remote_->proc_name();
else
- strm << " peer process " << this->ident_;
+ strm << "peer process " << this->ident_;
strm << ":" << endl;
size_t count_inv = 0;
- for (PeerObjectTable::ITERATOR i = this->objects_.begin();
- i != this->objects_.end();
- i++)
+ for (ObjectByIndex::ITERATOR i = this->object_by_index_.begin();
+ !i.done();
+ i.advance())
{
- PeerObjectTable::ENTRY *entry = 0;
+ ObjectByIndex::ENTRY *entry = 0;
i.next (entry);
PeerObject *obj = entry->item();
obj->dump_detail (strm);
@@ -288,7 +322,8 @@ PeerProcess::dump_object_detail (ostream &strm)
void
PeerProcess::dump_invocation_detail (ostream &strm)
{
- strm << "\n " << this->invocations_.size() << " Invocations with ";
+ strm << "\n " << this->invocations_.size() << " Invocations ";
+ strm << (this->server_ ? "to " : "from ");
if (this->remote_)
strm << remote_->proc_name();
else
diff --git a/TAO/utils/logWalker/PeerProcess.h b/TAO/utils/logWalker/PeerProcess.h
index 76205ba19ad..59ebacbcd64 100644
--- a/TAO/utils/logWalker/PeerProcess.h
+++ b/TAO/utils/logWalker/PeerProcess.h
@@ -32,13 +32,14 @@ public:
typedef ACE_RB_Tree<u_long, PeerObject*, ACE_Less_Than<u_long>, ACE_Null_Mutex> PeerObjectTable;
+typedef ACE_RB_Tree<long, PeerObject*, ACE_Less_Than<long>, ACE_Null_Mutex> ObjectByIndex;
typedef ACE_DLList<Invocation> InvocationList;
typedef ACE_DLList<Transport> TransportList;
class PeerProcess
{
public:
- static char *nextIdent(void);
+ static char *nextIdent(bool is_server);
PeerProcess (size_t offset, bool is_server);
virtual ~PeerProcess (void);
@@ -49,16 +50,18 @@ public:
HostProcess *owner (void);
void match_hosts (Session *session);
- void set_server_addr (const char *addr);
- const ACE_CString &server_addr (void) const;
+ void set_server_addr (const ACE_CString &addr);
+ ACE_CString server_addr (void) const;
const ACE_CString &last_client_addr (void) const;
bool is_server (void) const;
+ void ssl (bool is_ssl);
void add_transport (Transport *t);
Transport *last_transport (void);
Transport *find_transport (long handle);
bool match_local (const char *addr) const;
+ bool match_server_addr (const ACE_CString &addr, Session &session) const;
Invocation *new_invocation (size_t req_id, Thread *thr);
Invocation *find_invocation (size_t req_id, long handle);
@@ -72,15 +75,20 @@ public:
private:
char *ident_;
+ char *origin_;
HostProcess *owner_;
HostProcess *remote_;
- ACE_CString server_addr_;
+ ACE_CString server_port_;
+ ACE_CString server_host_;
TransportList transports_;
Transport *last_transport_;
bool server_;
+ bool ssl_;
+ bool localhost_;
size_t origin_offset_;
PeerObjectTable objects_;
InvocationList invocations_;
+ ObjectByIndex object_by_index_;
};
diff --git a/TAO/utils/logWalker/Session.cpp b/TAO/utils/logWalker/Session.cpp
index ad497703eb9..8f194415417 100644
--- a/TAO/utils/logWalker/Session.cpp
+++ b/TAO/utils/logWalker/Session.cpp
@@ -9,8 +9,6 @@
long
Session::tao_version_ = 200;
-int
-Session::date_format_ = 1;
Session::Session (void)
{
@@ -53,24 +51,6 @@ Session::tao_version (void)
return tao_version_;
}
-bool
-Session::set_date_format (ACE_TCHAR *str)
-{
- if (ACE_OS::strncmp(str, ACE_TEXT("1"), 1)== 0)
- date_format_ = 1;
- else if (ACE_OS::strncmp (str, ACE_TEXT("2"), 1) == 0)
- date_format_ = 2;
- else
- return false;
- return true;
-}
-
-int
-Session::date_format (void)
-{
- return date_format_;
-}
-
void
Session::add_process (HostProcess *proc)
{
@@ -95,6 +75,19 @@ Session::alternate_address (const char *addrspec)
this->alt_addrs_.bind(name,value);
}
+bool
+Session::is_equivalent (const ACE_CString &primary,
+ const ACE_CString &alternate)
+{
+ ACE_CString test(primary);
+ ACE_CString alt;
+ if (this->alt_addrs_.find(test,alt) == 0)
+ {
+ return alt == alternate;
+ }
+ return false;
+}
+
void
Session::default_service (const char *addrspec)
{
diff --git a/TAO/utils/logWalker/Session.h b/TAO/utils/logWalker/Session.h
index 7e944fc5701..2f4bfb0c85d 100644
--- a/TAO/utils/logWalker/Session.h
+++ b/TAO/utils/logWalker/Session.h
@@ -17,7 +17,7 @@ class HostProcess;
typedef ACE_RB_Tree<long, HostProcess *, ACE_Less_Than<long>, ACE_Null_Mutex> Processes;
typedef ACE_RB_Tree<ACE_CString, HostProcess *, ACE_Less_Than<ACE_CString>, ACE_Null_Mutex> Procs_By_Name;
-typedef ACE_Hash_Map_Manager<ACE_CString, ACE_CString, ACE_Null_Mutex> AltAddresses;
+typedef ACE_Hash_Map_Manager<const ACE_CString, ACE_CString, ACE_Null_Mutex> AltAddresses;
class Session
{
@@ -33,10 +33,9 @@ public:
static bool set_tao_version (ACE_TCHAR *str);
static long tao_version (void);
- static int date_format (void);
- static bool set_date_format (ACE_TCHAR *ser);
-
void alternate_address (const char *string);
+ bool is_equivalent (const ACE_CString &primary,
+ const ACE_CString &alternate);
void default_service (const char *string);
void make_dir (const char * );
@@ -56,7 +55,6 @@ private:
ACE_CString base_dir_;
ACE_CString outfile_;
static long tao_version_;
- static int date_format_;
};
#endif // LOG_WALKER_SESSION_H
diff --git a/TAO/utils/logWalker/Thread.cpp b/TAO/utils/logWalker/Thread.cpp
index 57345a22447..a9e2f2394cb 100644
--- a/TAO/utils/logWalker/Thread.cpp
+++ b/TAO/utils/logWalker/Thread.cpp
@@ -3,21 +3,25 @@
#include "Thread.h"
#include "Invocation.h"
#include "PeerProcess.h"
+#include "GIOP_Buffer.h"
#include "ace/OS_NS_stdio.h"
-
#include <stack>
-Thread::Thread (long tid, const char *alias)
+Thread::Thread (long tid, const char *alias, size_t offset)
: id_(tid),
alias_ (alias),
max_depth_ (0),
- encounters_ (0),
+ client_encounters_ (0),
+ server_encounters_ (0),
nested_ (0),
pending_(),
incoming_(0),
new_connection_(0),
giop_target_(0),
- active_handle_ (0)
+ target_dup_(0),
+ current_invocation_ (),
+ active_handle_ (0),
+ first_line_ (offset)
{
}
@@ -34,9 +38,21 @@ Thread::pending_peer (void) const
}
void
+Thread::pending_local_addr (const ACE_CString &addr)
+{
+ this->pending_local_addr_ = addr;
+}
+
+const ACE_CString &
+Thread::pending_local_addr (void) const
+{
+ return this->pending_local_addr_;
+}
+
+void
Thread::handle_request (void)
{
- this->encounters_++;
+ this->server_encounters_++;
if (this->pending_.size() > 1)
this->nested_++;
}
@@ -45,7 +61,7 @@ void
Thread::enter_wait (PeerProcess *pp)
{
this->pending_.push (pp);
- this->encounters_++;
+ this->client_encounters_++;
if (this->pending_.size() > this->max_depth_)
this->max_depth_ = this->pending_.size();
if (this->pending_.size() > 1)
@@ -72,13 +88,7 @@ Thread::exit_wait (PeerProcess *pp, size_t linenum)
long
Thread::max_depth (void) const
{
- return this->max_depth_;
-}
-
-long
-Thread::encounters (void) const
-{
- return this->encounters_;
+ return static_cast<long> (this->max_depth_);
}
long
@@ -117,16 +127,61 @@ Thread::active_handle (void) const
return this->active_handle_;
}
-Invocation::GIOP_Buffer *
+void
+Thread::set_dup (Thread *other, bool set_other)
+{
+ this->target_dup_ = other;
+ if (set_other)
+ {
+ other->set_dup (this, false);
+ }
+}
+
+void
+Thread::clear_dup (void)
+{
+ this->target_dup_ = 0;
+}
+
+bool
+Thread::has_dup (void)
+{
+ return this->target_dup_ != 0;
+}
+
+void
+Thread::swap_target (void)
+{
+ if (target_dup_ != 0 && target_dup_->giop_target() != 0)
+ {
+ this->giop_target_->swap (target_dup_->giop_target());
+ this->target_dup_->clear_dup ();
+ this->target_dup_ = 0;
+ }
+ else
+ {
+ if (target_dup_ == 0)
+ ACE_ERROR ((LM_ERROR, "Thread::swap_target, target_dup_ == 0\n"));
+ else
+ ACE_ERROR ((LM_ERROR, "Thread::swap_target, target_dup_.id = %d, giop_target == 0\n", target_dup_->id()));
+ }
+}
+
+GIOP_Buffer *
Thread::giop_target (void)
{
return this->giop_target_;
}
void
-Thread::set_giop_target (Invocation::GIOP_Buffer *buffer)
+Thread::set_giop_target (GIOP_Buffer *buffer)
{
this->giop_target_ = buffer;
+ if (this->target_dup_ != 0)
+ {
+ this->target_dup_->clear_dup();
+ this->target_dup_ = 0;
+ }
}
void
@@ -136,10 +191,34 @@ Thread::add_invocation (Invocation *inv)
}
void
-Thread::dump_detail (ostream &strm)
+Thread::push_invocation (Invocation *inv)
+{
+ this->current_invocation_.push(inv);
+}
+
+void
+Thread::pop_invocation (void)
{
- strm << " " << this->alias_ << " tid = " << this->id_
- << "\t" << this->encounters_ << " encounters";
+ Invocation *inv;
+ this->current_invocation_.pop (inv);
+}
+
+Invocation *
+Thread::current_invocation (void) const
+{
+ Invocation *inv = 0;
+ if (this->current_invocation_.size() > 0)
+ this->current_invocation_.top(inv);
+ return inv;
+}
+
+void
+Thread::dump_detail (ostream &strm) const
+{
+ strm << " " << this->alias_ << " tid = 0x" << hex << this->id_
+ << "\tfirst line " << dec << this->first_line_ << "\t"
+ << this->server_encounters_ << " requests sent "
+ << this->client_encounters_ << " requests received";
if (nested_ > 0)
strm <<", with " << this->nested_ << " nested upcalls, max depth "
<< this->max_depth_;
@@ -147,21 +226,48 @@ Thread::dump_detail (ostream &strm)
}
void
+Thread::get_summary (long &sent_reqs,
+ long &recv_reqs,
+ size_t &sent_size,
+ size_t &recv_size)
+{
+ for (ACE_DLList_Iterator <Invocation> i(this->invocations_);
+ !i.done();
+ i.advance())
+ {
+ Invocation *inv;
+ i.next(inv);
+ if (inv->sent_request())
+ {
+ ++sent_reqs;
+ sent_size += inv->request_bytes();
+ }
+ else
+ {
+ ++recv_reqs;
+ recv_size += inv->request_bytes();
+ }
+ }
+}
+
+void
Thread::dump_invocations (ostream &strm)
{
- strm << " " << this->alias_ << " handled " << this->invocations_.size() << " invocations" << endl;
+ size_t total_request_bytes = 0;
+ strm << " " << this->alias_ << " handled " << this->invocations_.size()
+ << " invocations" << endl;
std::stack<Invocation *> nested;
- for (ACE_DLList_Iterator <Invocation> i(this->invocations_);
+ for (ACE_DLList_Iterator <Invocation> i (this->invocations_);
!i.done();
i.advance())
{
Invocation *inv;
i.next(inv);
- int level = 0;
- while (!nested.empty())
+ size_t level = 0;
+ while (!nested.empty ())
{
- if (nested.top()->contains(inv->req_line()))
+ if (nested.top()->contains (inv->req_line ()))
{
level = nested.size();
break;
@@ -171,5 +277,7 @@ Thread::dump_invocations (ostream &strm)
nested.push(inv);
inv->dump_detail (strm, level, Invocation::Dump_Proc, false);
+ total_request_bytes += inv->request_bytes();
}
+ strm << "total request octet count: " << total_request_bytes;
}
diff --git a/TAO/utils/logWalker/Thread.h b/TAO/utils/logWalker/Thread.h
index 4660d34a0c1..d6bf5f5d7b1 100644
--- a/TAO/utils/logWalker/Thread.h
+++ b/TAO/utils/logWalker/Thread.h
@@ -14,44 +14,60 @@
#include "PeerProcess.h"
typedef ACE_Unbounded_Stack<PeerProcess *> UpcallStack;
+typedef ACE_Unbounded_Stack<Invocation *> InvocationStack;
class Thread
{
public:
- Thread (long tid, const char *alias);
+ Thread (long tid, const char *alias, size_t offset);
long max_depth (void) const;
- long encounters (void) const;
+ long client_encounters (void) const;
+ long server_encounters (void) const;
long id (void) const;
const ACE_CString &alias (void) const;
void incoming_from (PeerProcess *);
void add_invocation (Invocation *);
+ void push_invocation (Invocation *);
+ void pop_invocation (void);
+ Invocation *current_invocation (void) const;
PeerProcess *incoming (void) const;
void handle_request (void);
void enter_wait (PeerProcess *);
void exit_wait (PeerProcess *, size_t linenum);
- Invocation::GIOP_Buffer *giop_target (void);
- void set_giop_target (Invocation::GIOP_Buffer *buffer);
- void dump_detail (ostream &strm);
+ GIOP_Buffer *giop_target (void);
+ void set_giop_target (GIOP_Buffer *buffer);
+ void dump_detail (ostream &strm) const;
void dump_invocations (ostream &strm);
+ void get_summary (long &sent_reqs, long &recv_reqs, size_t &sent_size, size_t &recv_size);
PeerProcess *pending_peer (void) const;
void pending_peer (PeerProcess *pp);
-
+ void pending_local_addr (const ACE_CString &addr);
+ const ACE_CString& pending_local_addr (void) const;
void active_handle (long handle);
long active_handle (void) const;
+ void set_dup (Thread *other, bool set_other);
+ void clear_dup (void);
+ void swap_target (void);
+ bool has_dup (void);
private:
long id_;
ACE_CString alias_;
size_t max_depth_;
- long encounters_;
+ long client_encounters_;
+ long server_encounters_;
long nested_;
UpcallStack pending_;
PeerProcess *incoming_;
PeerProcess *new_connection_;
- Invocation::GIOP_Buffer *giop_target_;
+ ACE_CString pending_local_addr_;
+ GIOP_Buffer *giop_target_;
+ Thread *target_dup_;
InvocationList invocations_;
+ InvocationStack current_invocation_;
long active_handle_;
+ size_t first_line_;
};
#endif // LOG_WALKER_THREAD_H
diff --git a/TAO/utils/logWalker/logWalker.cpp b/TAO/utils/logWalker/logWalker.cpp
index cbd0c7375c3..b669c89c1d3 100644
--- a/TAO/utils/logWalker/logWalker.cpp
+++ b/TAO/utils/logWalker/logWalker.cpp
@@ -30,7 +30,7 @@ parse_filename (Session &session, char * buffer)
Log log(session);
if (ACE_OS::strchr(buffer,'=') == 0)
{
- log.init(ACE_TEXT_CHAR_TO_TCHAR(buffer));
+ log.process_file (ACE_TEXT_CHAR_TO_TCHAR(buffer));
}
else
{
@@ -38,7 +38,7 @@ parse_filename (Session &session, char * buffer)
tokens.delimiter_replace('=', 0);
char *alias = tokens.next();
ACE_TString filename = ACE_TEXT_CHAR_TO_TCHAR(tokens.next());
- log.init(filename.c_str(), alias);
+ log.process_file (filename.c_str(), alias);
}
}
@@ -111,13 +111,12 @@ void
print_help (void)
{
ACE_DEBUG ((LM_DEBUG, "tao_logWalker recongizes the following arguments\n"));
- ACE_DEBUG ((LM_DEBUG, "-outfile <filename> - write all output to specified file\n"));
- ACE_DEBUG ((LM_DEBUG, "-dir <directory> - create separate output files, one per log, and put them in specified directory.\n Either -outfile or -dir may be set but not both. Default output to stdout.\n"));
- ACE_DEBUG ((LM_DEBUG, "-manifest <manifest> - Take inputs from named manifest file\n"));
- ACE_DEBUG ((LM_DEBUG, "-tao <1.5 .. 2.0> - set source TAO version, default 2.0\n"));
- ACE_DEBUG ((LM_DEBUG, "-date <1|2> - interpret dates as 1) YYYY-MM-DD hh:mm:ss.sss, or 2) MMM DD hh:mm:ss.sss YYYY\n"));
- ACE_DEBUG ((LM_DEBUG, "-alias <name=address> - bind an alias to a host address.\n Repeat as many times as necessary.\n"));
- ACE_DEBUG ((LM_DEBUG, "-proc <service=address> - bind a service such as Naming to a specific endpoint address\n"));
+ ACE_DEBUG ((LM_DEBUG, "-o <filename> - write all output to specified file\n"));
+ ACE_DEBUG ((LM_DEBUG, "-d <directory> - create separate output files, one per log, and put them in specified directory.\n Either -o or -d may be set but not both. Default output to stdout.\n"));
+ ACE_DEBUG ((LM_DEBUG, "-m <manifest> - Take inputs from named manifest file\n"));
+ ACE_DEBUG ((LM_DEBUG, "-t <1.5 .. 2.0> - set source TAO version, default 2.0\n"));
+ ACE_DEBUG ((LM_DEBUG, "-a <name=address> - bind an alias to a host address.\n Repeat as many times as necessary.\n"));
+ ACE_DEBUG ((LM_DEBUG, "-p <service=address> - bind a service such as Naming to a specific endpoint address\n"));
}
int
@@ -132,8 +131,7 @@ ACE_TMAIN (int argc, ACE_TCHAR **argv)
Session session;
for (int i = 1; i < argc; i++)
{
- if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-outfile")) == 0 ||
- ACE_OS::strcasecmp (argv[i], ACE_TEXT("-o")) == 0)
+ if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-o")) == 0)
{
if (session.has_dir())
ACE_ERROR_RETURN ((LM_ERROR,
@@ -142,8 +140,7 @@ ACE_TMAIN (int argc, ACE_TCHAR **argv)
session.outfile(ACE_TEXT_ALWAYS_CHAR(argv[++i]));
continue;
}
- if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-dir")) == 0 ||
- ACE_OS::strcasecmp (argv[i], ACE_TEXT("-d")) == 0)
+ if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-d")) == 0)
{
if (session.has_outfile())
ACE_ERROR_RETURN ((LM_ERROR,
@@ -152,14 +149,12 @@ ACE_TMAIN (int argc, ACE_TCHAR **argv)
session.make_dir (ACE_TEXT_ALWAYS_CHAR(argv[++i]));
continue;
}
- if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-manifest")) == 0 ||
- ACE_OS::strcasecmp (argv[i], ACE_TEXT("-m")) == 0)
+ if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-m")) == 0)
{
parse_manifest (session, argv[++i]);
continue;
}
- if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-tao")) == 0 ||
- ACE_OS::strcasecmp (argv[i], ACE_TEXT("-t")) == 0)
+ if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-t")) == 0)
{
if (Session::set_tao_version (argv[++i]))
continue;
@@ -167,23 +162,12 @@ ACE_TMAIN (int argc, ACE_TCHAR **argv)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT("TAO version must be 1.5, 1.6, 1.7, 1.8, or 2.0 \n")), 0);
}
- if (ACE_OS::strcasecmp (argv[i], ACE_TEXT ("-date")) == 0)
- {
- if (Session::set_date_format (argv[++i]))
- continue;
- else
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_TEXT("Date format option must be 1 or 2\n")), 0);
- }
-
- if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-alias")) == 0 ||
- ACE_OS::strcasecmp (argv[i], ACE_TEXT("-a")) == 0)
+ if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-a")) == 0)
{
session.alternate_address (ACE_TEXT_ALWAYS_CHAR (argv[++i]));
continue;
}
- if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-proc")) == 0 ||
- ACE_OS::strcasecmp (argv[i], ACE_TEXT("-p")) == 0)
+ if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-p")) == 0)
{
session.default_service (ACE_TEXT_ALWAYS_CHAR (argv[++i]));
continue;
diff --git a/TAO/utils/nsgroup/README.nsgroup b/TAO/utils/nsgroup/README.nsgroup
new file mode 100644
index 00000000000..4dc243dbad1
--- /dev/null
+++ b/TAO/utils/nsgroup/README.nsgroup
@@ -0,0 +1,156 @@
+$Id$
+
+This utility provides a command line interface for the tao_ft_naming service.
+tao_ft_naming service supports the NameService and NamingManager interfaces.
+
+Here is a summary of the commands and options:
+
+tao_nsgroup group_create -group <group> -policy <round | rand | least>
+tao_nsgroup group_remove -group <group>
+tao_nsgroup group_bind -group <group> -name <name>
+tao_nsgroup group_unbind -name <name>
+tao_nsgroup group_modify -group <group> -policy <round | rand | least>
+tao_nsgroup group_list
+tao_nsgroup member_add -group <group> -location <location> -ior <ior>
+tao_nsgroup member_remove -group <group> -location <location>
+tao_nsgroup member_show -group <group> -location <location>
+tao_nsgroup member_list -group <group>
+tao_nsgroup -help
+
+tao_nsgroup group_create -group <group> -policy <round | rand | least>
+
+ Adds the object group to to the load balancing naming manager service with the
+ specified selection policy. On Creation, an object group contains no member
+ objects. Returns error if <group> is not unique.
+
+ Returns Success(0), Error(1)
+
+ Example:
+ $ACE_ROOT/bin/tao_nsgroup group_create -group ieee -policy round \
+ -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior
+
+tao_nsgroup group_remove -group <group>
+
+ Removes the specified object group from the load balancing naming manager
+ service.
+
+ Returns Success(0), Error(1)
+
+ Example:
+ $ACE_ROOT/bin/tao_nsgroup group_remove -group ieee \
+ -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior
+
+ Note: If the object group is bound with group_bind, you must also unbind it
+ with group_unbind.
+
+tao_nsgroup group_bind -group <group> -name <name>
+
+ Binds the specified object group to the specified stringified name in the
+ naming service. When clients resolve that name, they tranparently obtain a
+ member of the specified object group from the load balancing naming manager
+ service.
+
+ Returns Success(0), Error(1)
+
+ Example:
+
+ $ACE_ROOT/bin/tao_nsgroup group_bind -group ieee -name iso/ieee \
+ -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior
+
+ Note: The iso context used in this example must be created before calling
+ group_bind.
+
+tao_nsgroup group_unbind -name <name>
+
+ Unbinds the specified stringified name from the naming service, but does not
+ remove the object group.
+
+ Returns Success(0), Error(1)
+
+ Example:
+
+ $ACE_ROOT/bin/tao_nsgroup group_unbind -name iso/ieee \
+ -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior
+
+tao_nsgroup group_modify -group <group> -policy <round | rand | least>
+
+ Changes the selection algorithm for the specified object group. An object
+ group's selection algorithm determines how the load balancing naming manager
+ service directs client requests to object group members.
+
+ Returns Success(0), Error(1)
+
+ Example:
+ $ACE_ROOT/bin/tao_nsgroup group_modify -group ieee -policy rand \
+ -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior
+
+tao_nsgroup group_list
+
+ Displays all object groups that currently exist in the load balancing naming
+ manager service by selection policy.
+
+ Returns Success(0), Error(1)
+
+ Example:
+ $ACE_ROOT/bin/tao_nsgroup group_list \
+ -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior
+
+ Round Robin Load Balancing Groups:
+ ieee
+
+ Random Load Balancing Groups:
+ ieed
+
+ Least Load Balancing Groups:
+ No Least Load Balancing Groups Registered
+
+
+tao_nsgroup member_add -group <group> -location <location> -ior <ior>
+
+ Adds an member object to the specified object group. After being added, the
+ member object is available for selection. Returns error if the ior is not
+ unique for the specified object group.
+
+ Returns Success(0), Error(1)
+
+ Example:
+ $ACE_ROOT/bin/tao_nsgroup member_add -group ieee -location 127.0.0.1 \
+ -ior file://mo.ior -ORBInitRef NameService=file://ns.ior \
+ -ORBInitRef NamingManager=file://nm.ior
+
+tao_nsgroup member_remove -group <group> -location <location>
+
+ Removes the specified member object location from the specified object group.
+
+ Returns Success(0), Error(1)
+
+ Example:
+ $ACE_ROOT/bin/tao_nsgroup member_remove -group ieee -location 127.0.0.1 \
+ -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior
+
+tao_nsgroup member_list -group <group>
+
+ Lists the member locations of the specified object group.
+
+ Returns Success(0), Error(1)
+
+ Example:
+ $ACE_ROOT/bin/tao_nsgroup member_list -group ieee \
+ -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior
+ 127.0.0.1
+
+
+tao_nsgroup member_show -group <group> -location <location>
+
+ Displays the object reference that cooresponds to the specified member location
+ of an object group.
+
+ Returns Success(0), Error(1)
+
+ Example:
+
+ $ACE_ROOT/bin/tao_nsgroup member_show -group ieee -location 127.0.0.1 \
+ -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior
+ IOR:010000002100000049444c3a6f6d672e6f72672f46542f4e616d696e674d616e616765723a312e300000000001000000000000006c000000010102000e00000031302e3230312e3230302e363400e1841b00000014010f005253541571a65076c60a000000000001000000010000000002000000000000000800000001000000004f41540100000018000000010000000100010001000000010001050901010000000000
+
+
diff --git a/TAO/utils/nsgroup/nsgroup.cpp b/TAO/utils/nsgroup/nsgroup.cpp
new file mode 100644
index 00000000000..da59a31f561
--- /dev/null
+++ b/TAO/utils/nsgroup/nsgroup.cpp
@@ -0,0 +1,519 @@
+//==========================================================================
+/**
+ * @file nsgroup.cpp
+ *
+ * $Id$
+ *
+ * @author Phillip LaBanca <labancap@ociweb.com>
+ */
+//==========================================================================
+
+
+#include "orbsvcs/Naming/FaultTolerant/nsgroup_svc.h"
+#include "ace/Get_Opt.h"
+
+//============================================================================
+bool
+show_help(int argc, ACE_TCHAR *argv[])
+{
+ static const ACE_TCHAR options[] = ACE_TEXT("h");
+ static const int skip_args = 1;
+ static const int report_errors = 0;
+ static const int ordering = ACE_Get_Opt::RETURN_IN_ORDER;
+ static const int long_only = 0;
+
+ // Not enough arguments indicates help is required
+ if( argc < 2 )
+ {
+ return true;
+ }
+
+ // Did they ask for help ?
+ ACE_Get_Opt get_opts (
+ argc,
+ argv,
+ options,
+ skip_args,
+ report_errors,
+ ordering,
+ long_only
+ );
+
+ if (get_opts.long_option (ACE_TEXT ("help"),'h') != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT (" Unable to add long option 'H'\n")),
+ true);
+ }
+
+ int c;
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'h': // help
+
+ return true;
+ break;
+ }
+ }
+ return false;
+}
+
+/**
+ * @class nsgroup
+ *
+ * @brief Encapsulate the NS group command line operations in a class.
+ *
+ *
+ */
+
+class NSGROUP
+{
+public:
+
+ enum NSGROUP_COMMAND {
+ NSGROUP_NONE,
+ NSGROUP_HELP,
+ NSGROUP_GROUP_CREATE,
+ NSGROUP_GROUP_BIND,
+ NSGROUP_GROUP_UNBIND,
+ NSGROUP_GROUP_MODIFY,
+ NSGROUP_GROUP_LIST,
+ NSGROUP_GROUP_REMOVE,
+ NSGROUP_MEMBER_LIST,
+ NSGROUP_MEMBER_ADD,
+ NSGROUP_MEMBER_REMOVE,
+ NSGROUP_MEMBER_SHOW
+ };
+
+ /// Constructor
+ NSGROUP (int argc, ACE_TCHAR **argv);
+
+ /// start the ORB.
+ int start_orb (void);
+
+ /// parse command line, validate arguments and run the command
+ int run_cmd (void);
+
+ /// Display command line interface usage
+ int show_usage( void );
+
+ const char * group_arg(void) const { return group_arg_; }
+ const char * policy_arg(void) const { return policy_arg_; }
+ const char * location_arg(void) const { return location_arg_; }
+ const char * ior_arg(void) const { return ior_arg_; }
+ const char * namepath_arg(void) const { return namepath_arg_; }
+
+private:
+
+ /// parse command line arguments
+ NSGROUP_COMMAND parse_command_line (void);
+
+private:
+
+ NS_group_svc svc_;
+
+ int argc_;
+ ACE_TCHAR **argv_;
+
+ /// parsed command result
+ NSGROUP_COMMAND nsgroup_cmd_;
+
+ /// parsed command line arguments
+ const char *group_arg_;
+ const char *policy_arg_;
+ const char *typeid_arg_;
+ const char *location_arg_;
+ const char *ior_arg_;
+ const char *namepath_arg_;
+};
+
+
+ NSGROUP::NSGROUP (int argc, ACE_TCHAR **argv)
+ : argc_ (argc),
+ argv_ (argv),
+ nsgroup_cmd_(NSGROUP::NSGROUP_NONE)
+{
+}
+
+int
+NSGROUP::start_orb (void)
+{
+ const int RC_SUCCESS = 0;
+ const int RC_ERROR = -1;
+
+ try
+ {
+
+#if 0
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("start_orb::argc(%u)\n"), this->argc_));
+ for( int i = 0; i < this->argc_; ++i){
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("start_orb::argv(%u:%s)\n"),
+ i,
+ this->argv_[i]));
+ }
+#endif //
+
+ // Initialise the ORB.
+
+ CORBA::ORB_var orb_ = CORBA::ORB_init (this->argc_, this->argv_);
+
+ if (RC_SUCCESS != svc_.set_orb (orb_))
+ {
+
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT (" (%P|%t) Unable to initialize the ORB.\n")),
+ RC_ERROR);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ //
+ //////////////////////////////////////////////////////////////////////////
+ CORBA::Object_var naming_manager_object =
+ orb_->resolve_initial_references (ACE_TEXT_ALWAYS_CHAR ("NamingManager"));
+
+ FT_Naming::NamingManager_var naming_manager_ =
+ FT_Naming::NamingManager::_narrow (naming_manager_object.in ());
+
+ if (RC_SUCCESS != svc_.set_naming_manager (naming_manager_))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT (" (%P|%t) Unable to get Naming ")
+ ACE_TEXT ("Manager Reference\n")),
+ RC_ERROR);
+ }
+ //////////////////////////////////////////////////////////////////////////
+ //
+ //////////////////////////////////////////////////////////////////////////
+ CORBA::Object_var naming_object =
+ orb_->resolve_initial_references(ACE_TEXT_ALWAYS_CHAR ("NameService"));
+
+ CosNaming::NamingContextExt_var name_service_ =
+ CosNaming::NamingContextExt::_narrow (naming_object.in ());
+
+ if (RC_SUCCESS != svc_.set_name_context (name_service_))
+ {
+ ACE_ERROR_RETURN (( LM_ERROR,
+ ACE_TEXT (" (%P|%t) Unable to get Name Service ")
+ ACE_TEXT ("Reference\n")),
+ RC_ERROR);
+ }
+ //////////////////////////////////////////////////////////////////////////
+ //
+ //////////////////////////////////////////////////////////////////////////
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (ACE_TEXT("\nException raised initialising ORB\n"));
+ return RC_ERROR;
+ }
+
+ return RC_SUCCESS;
+
+}
+
+int
+NSGROUP::run_cmd(void)
+{
+ const int RC_ERROR = -1;
+ const int RC_BADARG = -2;
+
+ int rc = RC_ERROR;
+
+ switch( parse_command_line () )
+ {
+
+ case NSGROUP_HELP:
+ return show_usage ();
+ break;
+
+ case NSGROUP_GROUP_CREATE:
+ rc = svc_.group_create ( group_arg(), policy_arg() );
+ break;
+
+ case NSGROUP_GROUP_BIND:
+ rc = svc_.group_bind ( group_arg(), namepath_arg() );
+ break;
+
+ case NSGROUP_GROUP_UNBIND:
+ rc = svc_.group_unbind ( namepath_arg() );
+ break;
+
+ case NSGROUP_GROUP_MODIFY:
+ rc = svc_.group_modify ( group_arg(), policy_arg() );
+ break;
+
+ case NSGROUP_GROUP_LIST:
+ rc = svc_.group_list ();
+ break;
+
+ case NSGROUP_GROUP_REMOVE:
+ rc = svc_.group_remove ( group_arg() );
+ break;
+
+ case NSGROUP_MEMBER_LIST:
+ rc = svc_.member_list ( group_arg() );
+ break;
+
+ case NSGROUP_MEMBER_ADD:
+ rc = svc_.member_add ( group_arg(), location_arg(), ior_arg() );
+ break;
+
+ case NSGROUP_MEMBER_REMOVE:
+ rc = svc_.member_remove ( group_arg(), location_arg() );
+ break;
+
+ case NSGROUP_MEMBER_SHOW:
+ rc = svc_.member_show ( group_arg(), location_arg() );
+ break;
+
+ default:
+ show_usage ();
+ return rc;
+ break;
+ }
+
+ if (rc == RC_BADARG)
+ {
+ show_usage ();
+ }
+
+ return rc;
+}
+
+NSGROUP::NSGROUP_COMMAND
+NSGROUP::parse_command_line (void)
+{
+ #if 0
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("parse_command_line::argc(%u)\n"),
+ this->argc_));
+ for( int i = 0; i < this->argc_; ++i){
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("parse_command_line::argv(%u:%s)\n"),
+ i,
+ this->argv_[i]));
+ }
+ #endif
+
+ static const ACE_TCHAR options[] = ACE_TEXT("g:p:t:l:i:n:h");
+ static const int skip_args = 1;
+ static const int report_errors = 0;
+ static const int ordering = ACE_Get_Opt::PERMUTE_ARGS;
+ static const int long_only = 1;
+
+ ACE_Get_Opt get_opts (
+ this->argc_,
+ this->argv_,
+ options,
+ skip_args,
+ report_errors,
+ ordering,
+ long_only
+ );
+
+ this->group_arg_ = 0;
+ if (get_opts.long_option (ACE_TEXT ("group"),
+ 'g',
+ ACE_Get_Opt::ARG_REQUIRED) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to add long option 'g'\n")),
+ NSGROUP_NONE);
+
+ this->policy_arg_ = 0;
+ if (get_opts.long_option (ACE_TEXT ("policy"),
+ 'p',
+ ACE_Get_Opt::ARG_REQUIRED) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to add long option 'p'\n")),
+ NSGROUP_NONE);
+
+ this->location_arg_ = 0;
+ if (get_opts.long_option (ACE_TEXT ("location"),
+ 'l',
+ ACE_Get_Opt::ARG_REQUIRED) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to add long option 'l'\n")),
+ NSGROUP_NONE);
+
+ this->ior_arg_ = 0;
+ if (get_opts.long_option (ACE_TEXT ("ior"),
+ 'i',
+ ACE_Get_Opt::ARG_REQUIRED) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to add long option 'i'\n")),
+ NSGROUP_NONE);
+
+ this->namepath_arg_ = 0;
+ if (get_opts.long_option (ACE_TEXT ("name"),
+ 'n',
+ ACE_Get_Opt::ARG_REQUIRED) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to add long option 'n'\n")),
+ NSGROUP_NONE);
+
+ if (get_opts.long_option (ACE_TEXT ("help"), 'h') != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to add long option 'h'\n")),
+ NSGROUP_NONE);
+
+ int c;
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'g': // group
+ this->group_arg_ = get_opts.opt_arg ();
+ break;
+ case 'p': // policy
+ this->policy_arg_ = get_opts.opt_arg ();
+ break;
+ case 'l': // location
+ this->location_arg_ = get_opts.opt_arg ();
+ break;
+ case 'i': // ior
+ this->ior_arg_ = get_opts.opt_arg ();
+ break;
+ case 'n': // name
+ this->namepath_arg_ = get_opts.opt_arg ();
+ break;
+ case 'h':
+ return NSGROUP_HELP;
+ }
+
+ // handle non-option arguments
+ int non_option_arg_count = 0;
+ for( int i = get_opts.opt_ind (); i < this->argc_; ++i)
+ {
+
+ non_option_arg_count++;
+
+
+ if( ACE_OS::strncmp (this->argv_[i],ACE_TEXT("group_create"),
+ ACE_OS::strlen (ACE_TEXT("group_create"))) == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_GROUP_CREATE;
+ }
+ else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_bind"),
+ ACE_OS::strlen (ACE_TEXT("group_bind"))) == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_GROUP_BIND;
+ }
+ else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_unbind"),
+ ACE_OS::strlen (ACE_TEXT("group_unbind")))
+ == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_GROUP_UNBIND;
+ }
+ else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_modify"),
+ ACE_OS::strlen (ACE_TEXT("group_modify"))) == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_GROUP_MODIFY;
+ }
+ else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_list"),
+ ACE_OS::strlen (ACE_TEXT("group_list"))) == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_GROUP_LIST;
+ }
+ else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_remove"),
+ ACE_OS::strlen (ACE_TEXT("group_remove"))) == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_GROUP_REMOVE;
+ }
+ else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("member_list"),
+ ACE_OS::strlen (ACE_TEXT("member_list"))) == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_MEMBER_LIST;
+ }
+ else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("member_add"),
+ ACE_OS::strlen (ACE_TEXT("member_add"))) == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_MEMBER_ADD;
+ }
+ else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("member_remove"),
+ ACE_OS::strlen (ACE_TEXT("member_remove"))) == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_MEMBER_REMOVE;
+
+ }
+ else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("member_show"),
+ ACE_OS::strlen (ACE_TEXT("member_show"))) == 0 )
+ {
+ nsgroup_cmd_ = NSGROUP_MEMBER_SHOW;
+ }
+ else
+ {
+ nsgroup_cmd_ = NSGROUP_NONE;
+ }
+ }
+
+ // The command should be the only non option argument
+ if ( non_option_arg_count > 1 ) {
+ nsgroup_cmd_ = NSGROUP_NONE;
+ }
+
+ return nsgroup_cmd_;
+}
+
+
+int
+NSGROUP::show_usage ( void )
+{
+ const int RC_SUCCESS = 0;
+
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Usage:\n")
+ ACE_TEXT (" %s\n")
+ ACE_TEXT (" group_create -group <group> -policy <round | rand | least> \n")
+ ACE_TEXT (" group_bind -group <group> -name <name>\n")
+ ACE_TEXT (" group_unbind -name <name>\n")
+ ACE_TEXT (" group_modify -group <group> -policy <round | rand | least> \n")
+ ACE_TEXT (" group_list\n")
+ ACE_TEXT (" group_remove -group <group>\n")
+ ACE_TEXT (" member_list -group <group>\n")
+ ACE_TEXT (" member_add -group <group> -location <location> -ior <IOR>\n")
+ ACE_TEXT (" member_remove -group <group> -location <location>\n")
+ ACE_TEXT (" member_show -group <group> -location <location>\n")
+ ACE_TEXT (" -help\n")
+ ACE_TEXT ("\n"),
+ this->argv_[0]));
+ return RC_SUCCESS;
+}
+
+
+//============================================================================
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ const int RC_ERROR = -1;
+ const int RC_SUCCESS = 0;
+
+ int rc = RC_ERROR;
+
+ try
+ {
+
+ NSGROUP ns_group (argc, argv);
+
+ if ( show_help (argc, argv) )
+ {
+ rc = ns_group.show_usage ();
+ }
+ else if ( RC_SUCCESS == ns_group.start_orb ())
+ {
+ rc = ns_group.run_cmd ();
+ }
+
+ }
+ catch (const CORBA::Exception&)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("Unable to run %C\n"),
+ argv[0]),
+ 1);
+ }
+
+ return (rc == RC_SUCCESS) ? 0 : 1;
+}
diff --git a/TAO/utils/nsgroup/nsgroup.mpc b/TAO/utils/nsgroup/nsgroup.mpc
new file mode 100644
index 00000000000..490334f5247
--- /dev/null
+++ b/TAO/utils/nsgroup/nsgroup.mpc
@@ -0,0 +1,9 @@
+// $Id$
+
+project(nsgroup): orbsvcsexe, ftnaming, naming, install, svc_utils {
+ install = $(ACE_ROOT)/bin
+ exename = tao_nsgroup
+ Source_Files {
+ nsgroup.cpp
+ }
+}
diff --git a/TAO/utils/nsgroup/run_test.pl b/TAO/utils/nsgroup/run_test.pl
new file mode 100755
index 00000000000..bd8818e5ffa
--- /dev/null
+++ b/TAO/utils/nsgroup/run_test.pl
@@ -0,0 +1,443 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::TestTarget;
+
+my $status = 0;
+my $debug_level = 0;
+my $redirection_enabled = 0;
+
+
+foreach $i (@ARGV) {
+ if ($i eq '-debug') {
+ $debug_level = '10';
+ }
+}
+
+#$ENV{ACE_TEST_VERBOSE} = "1";
+
+my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n";
+my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n";
+
+## The LoadManager needs to register signals with the ORB's reactor (on
+## Windows only) and thus can not use the TP Reactor since it doesn't
+## support that kind of thing. So, we swith to the Select MT Reactor.
+my $NM_conf = $server->LocalFile ("windows" . $PerlACE::svcconf_ext);
+
+my $name_mgr_iorbase = "nm.ior";
+my $name_srv_iorbase = "ns.ior";
+my $stdout_file = "test.out";
+my $stderr_file = "test.err";
+
+my $server_hostname = $server->HostName ();
+my $name_mgr_iorfile = $server->LocalFile ($name_mgr_iorbase);
+my $name_server_iorfile = $server->LocalFile ($name_srv_iorbase);
+
+my $naming_mgr_client_iorfile = $client->LocalFile ($name_mgr_iorbase);
+my $name_srv_client_iorfile = $client->LocalFile ($name_srv_iorbase);
+my $client_stdout_file = $client->LocalFile ($stdout_file);
+my $client_stderr_file = $client->LocalFile ($stderr_file);
+
+$server->DeleteFile($name_mgr_iorbase);
+$server->DeleteFile($name_srv_iorbase);
+$client->DeleteFile($name_mgr_iorbase);
+$client->DeleteFile($name_srv_iorbase);
+$client->DeleteFile($stdout_file);
+$client->DeleteFile($stderr_file);
+
+my $DEBUG_LEVEL = "-ORBDebugLevel $debug_level";
+my $hostname = $server->HostName ();
+my $ns_orb_port1 = 10001 + $server->RandomPort ();
+my $ns_endpoint1 = "iiop://$hostname:$ns_orb_port1";
+
+my $DEF_REF = "-ORBDefaultInitRef corbaloc:iiop:$hostname:$ns_orb_port1";
+#my $NM_REF = "-ORBInitRef NameService=file://$name_srv_client_iorfile";
+#my $RM_REF = "-ORBInitRef NamingManager=file://$naming_mgr_client_iorfile";
+my $NS_REF = "--ns file://$name_srv_client_iorfile";
+my $LOAD_ARG = "$DEF_REF $DEBUG_LEVEL";
+
+my $tao_ft_naming = "$ENV{TAO_ROOT}/orbsvcs/Naming_Service/tao_ft_naming";
+my $name_dir = "NameService";
+my $group_dir = "Groups";
+my $ns_args = "$DEBUG_LEVEL " .
+ "-ORBListenEndPoints $ns_endpoint1 " .
+ "-h $name_mgr_iorbase " .
+ "-o $name_srv_iorbase " .
+ "-v $group_dir " .
+ "-u $name_dir " .
+ ($^O eq 'MSWin32' ? "-ORBSvcConf $NM_conf" : '');
+
+my $NM = $server->CreateProcess ($tao_ft_naming, $ns_args);
+my $NSGROUP = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsgroup");
+my $NSLIST = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nslist");
+my $NSADD = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsadd");
+my $NSDEL = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsdel");
+
+my $POSITIVE_TEST_RESULT = 0;
+my $NEGATIVE_TEST_RESULT = 1;
+
+sub clean_persistence_dir($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ chdir $directory_name;
+ opendir(THISDIR, ".");
+ @allfiles = grep(!/^\.\.?$/, readdir(THISDIR));
+ closedir(THISDIR);
+ foreach $tmp (@allfiles){
+ $target->DeleteFile ($tmp);
+ }
+ chdir "..";
+}
+
+# Make sure that the directory to use to hold the persistence data
+# exists and is cleaned out.
+sub init_persistence_directory($$)
+{
+ my $target = shift;
+ my $directory_name = shift;
+
+ if ( ! -d $directory_name ) {
+ mkdir ($directory_name, 0777);
+ } else {
+ clean_persistence_dir ($target, $directory_name);
+ }
+}
+
+sub cat_file($)
+{
+ my $file_name = shift;
+ if (-s $file_name ) # size of file is greater than zero
+ {
+ open TESTFILE, $file_name or die "Couldn't open file: $!";
+ my @teststring = <TESTFILE>; # read in all of the file
+ print STDERR "\n@teststring\n";
+ close TESTFILE;
+ }
+}
+
+sub redirect_output()
+{
+ open(OLDOUT, ">&", \*STDOUT) or die "Can't dup STDOUT: $!";
+ open(OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!";
+ open STDERR, '>', $client_stderr_file;
+ open STDOUT, '>', $client_stdout_file;
+}
+
+sub restore_output()
+{
+ open(STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!";
+ open(STDOUT, ">&OLDOUT") or die "Can't dup OLDOUT: $!";
+}
+
+sub run_client ($$)
+{
+ my $args = shift;
+ my $expected_test_result = shift;
+
+ my $arglist = "$LOAD_ARG $args";
+
+ if ($expected_test_result != $POSITIVE_TEST_RESULT ) {
+ print STDERR "\n\n======== Running Negative Test ================\n";
+ } else {
+ print STDERR "\n\n======== Running Positive Test ================\n";
+ }
+ print STDERR "$args\n";
+
+ $NSGROUP->Arguments ($arglist);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ my $client_status = $NSGROUP->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+
+ if ($client_status != $expected_test_result) {
+ my $time = localtime;
+ print STDERR "ERROR: client returned $client_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ cat_file($client_stdout_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nsadd($)
+{
+ print STDERR "\n\n======== Running tao_nsadd ================\n";
+ my $args = shift;
+ $NSADD->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nsadd --ns file://ns.ior --name iso --ctx
+ my $client_status = $NSADD->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($client_status != $0) {
+ my $time = localtime;
+ print STDERR "ERROR: nsadd returned $client_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nsdel($)
+{
+ print STDERR "\n\n======== Running tao_nsdel ================\n";
+ my $args = shift;
+ $NSDEL->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nsdel --ns file://ns.ior --name iso --destroy
+ my $client_status = $NSDEL->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($client_status != $0) {
+ my $time = localtime;
+ print STDERR "ERROR: nsdel returned $client_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_nslist($)
+{
+ print STDERR "\n\n======== Running tao_nslist ================\n";
+ my $args = shift;
+ $NSLIST->Arguments ($args);
+
+ if ($redirection_enabled) {
+ redirect_output();
+ }
+
+ #tao_nslist --ns file://ns.ior
+ my $client_status = $NSLIST->SpawnWaitKill ($client->ProcessStartWaitInterval());
+
+ if ($redirection_enabled) {
+ restore_output();
+ }
+
+ if ($client_status != $0) {
+ my $time = localtime;
+ print STDERR "ERROR: nslist returned $client_status at $time\n";
+ if ($redirection_enabled) {
+ cat_file($client_stderr_file);
+ }
+ $status = 1;
+ }
+}
+
+sub run_clients ()
+{
+ run_client (
+ "group_list",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "group_create -group ieee -policy round",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "group_create -group ieed -policy rand",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "group_create -group ieee -policy round",
+ $NEGATIVE_TEST_RESULT);
+
+ run_client (
+ "group_list",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "member_list -group ieee",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "member_add -group ieee -location $server_hostname -ior file://$naming_mgr_client_iorfile",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "member_list -group ieee",
+ $POSITIVE_TEST_RESULT);
+
+ run_nsadd("$DEF_REF"." --name iso --ctx");
+
+ run_nslist("$NS_REF");
+
+ run_client (
+ "group_unbind -name iso/ieee",
+ $NEGATIVE_TEST_RESULT);
+
+ run_nslist("$NS_REF");
+
+ run_client (
+ "group_bind -group ieee -name iso/ieee",
+ $POSITIVE_TEST_RESULT);
+
+ run_nslist("$NS_REF");
+
+ run_client (
+ "group_modify -group ieee -policy rand",
+ $POSITIVE_TEST_RESULT);
+
+ # Change the policy back to a supported one before
+ # doing the nslist to avoid the error message.
+ run_client (
+ "group_modify -group ieee -policy round",
+ $POSITIVE_TEST_RESULT);
+
+ run_nslist("$NS_REF");
+
+ run_client (
+ "member_add -group ieee -location $server_hostname -ior file://$naming_mgr_client_iorfile",
+ $NEGATIVE_TEST_RESULT);
+
+ run_client (
+ "member_list -group ieee",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "member_show -group ieee -location $server_hostname",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "member_remove -group ieee -location $server_hostname",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "member_list -group ieee",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "group_remove -group ieee",
+ $POSITIVE_TEST_RESULT);
+
+ run_client (
+ "group_unbind -name iso/ieee",
+ $POSITIVE_TEST_RESULT);
+
+ run_nslist("$NS_REF");
+
+ run_client (
+ "group_list",
+ $POSITIVE_TEST_RESULT);
+
+ run_nsdel("$DEF_REF"." --name iso --destroy");
+
+ # Verify we can handle a non-existent ior to add to the list
+ run_nsadd("$DEF_REF --name does_not_exist --ior file://thisfiledoesnotexist");
+ run_nslist("$NS_REF");
+ run_nsdel("$DEF_REF"." --name does_not_exist");
+ run_nslist("$NS_REF");
+
+
+ run_client (
+ "-help",
+ $POSITIVE_TEST_RESULT);
+}
+
+print STDERR "\n\n======== Running tao_nsgroup Test================\n";
+print STDERR "\n";
+
+print STDERR "This test will check the methods of the tao_nsgroup\n";
+print STDERR "\n";
+
+init_persistence_directory ($server, $name_dir );
+init_persistence_directory ($server, $group_dir );
+
+################################################################################
+# setup END block to cleanup after exit call
+################################################################################
+END
+{
+ $server->DeleteFile($name_mgr_iorbase);
+ $server->DeleteFile($name_srv_iorbase);
+ $client->DeleteFile($name_mgr_iorbase);
+ $client->DeleteFile($name_srv_iorbase);
+ $client->DeleteFile($stdout_file);
+ $client->DeleteFile($stderr_file);
+
+ if ( -d $name_dir ) {
+ clean_persistence_dir ($server, $name_dir);
+ rmdir ($name_dir);
+ }
+
+ if ( -d $group_dir ) {
+ clean_persistence_dir ($server, $group_dir);
+ rmdir ($group_dir);
+ }
+}
+
+################################################################################
+## Start tao_ft_naming Service
+################################################################################
+
+$server_status = $NM->Spawn ();
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ exit 1;
+}
+
+if ($server->WaitForFileTimed ($name_mgr_iorbase,
+ $server->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$name_mgr_iorbase>\n";
+ $NM->Kill (); $NM->TimedWait (1);
+ exit 1;
+}
+
+print STDERR "Waiting for $name_mgr_iorbase\n";
+if ($server->GetFile ($name_mgr_iorbase) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$name_mgr_iorbase>\n";
+ $NM->Kill (); $NM->TimedWait (1);
+ exit 1;
+}
+
+if ($client->PutFile ($name_mgr_iorbase) == -1) {
+ print STDERR "ERROR: cannot set file <$naming_mgr_client_iorfile>\n";
+ $NM->Kill (); $NM->TimedWait (1);
+ exit 1;
+}
+
+run_clients();
+
+print STDERR "\n\n====================================================\n";
+print STDERR "\n";
+$server_status = $NM->TerminateWaitKill ($server->ProcessStopWaitInterval());
+
+if ($server_status != 0) {
+ print STDERR "ERROR: server returned $server_status\n";
+ $status = 1;
+}
+
+
+exit $status;
diff --git a/TAO/utils/nsgroup/windows.conf b/TAO/utils/nsgroup/windows.conf
new file mode 100644
index 00000000000..e02d5089fce
--- /dev/null
+++ b/TAO/utils/nsgroup/windows.conf
@@ -0,0 +1,3 @@
+# $Id$
+
+dynamic Advanced_Resource_Factory Service_Object* TAO_Strategies:_make_TAO_Advanced_Resource_Factory () "-ORBReactorType select_mt"
diff --git a/TAO/utils/nsgroup/windows.conf.xml b/TAO/utils/nsgroup/windows.conf.xml
new file mode 100644
index 00000000000..37af1733d3b
--- /dev/null
+++ b/TAO/utils/nsgroup/windows.conf.xml
@@ -0,0 +1,10 @@
+<?xml version='1.0'?>
+<!-- Converted from windows.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- -->
+ <!-- $Id$ -->
+ <!-- -->
+ <dynamic id="Advanced_Resource_Factory" type="Service_Object">
+ <initializer path="TAO_Strategies" init="_make_TAO_Advanced_Resource_Factory" params="-ORBReactorType select_mt"/>
+ </dynamic>
+</ACE_Svc_Conf>
diff --git a/TAO/utils/nslist/nslist.cpp b/TAO/utils/nslist/nslist.cpp
index 6ac49370a10..1633680618d 100644
--- a/TAO/utils/nslist/nslist.cpp
+++ b/TAO/utils/nslist/nslist.cpp
@@ -41,15 +41,19 @@ namespace
const char
*myTree = "|", // Default string to draw tree "tram-lines"
*myNode = "+"; // Default string to draw tree node end-points
- int
- sizeMyTree, // Initialised by main to strlen (myTree)
- sizeMyNode, // Initialised by main to strlen (myNode)
- maxDepth= 0; // Limit to display depth (default unlimited)
+ int sizeMyTree; // Initialised by main to strlen (myTree)
+ int sizeMyNode; // Initialised by main to strlen (myNode)
+ int maxDepth= 0; // Limit to display depth (default unlimited)
ACE_Time_Value
rtt = ACE_Time_Value::zero; // relative roundtrip timeout for ctx
+ const CORBA::ULong MAX_COUNT_DEFAULT = 100;
+ CORBA::ULong max_count = MAX_COUNT_DEFAULT;
+
void list_context (const CosNaming::NamingContext_ptr,
- int level);
+ int level,
+ CORBA::ULong max_count);
+
CORBA::Object_ptr set_rtt(CORBA::Object_ptr obj);
//==========================================================================
@@ -271,7 +275,7 @@ namespace
ACE_DEBUG ((LM_DEBUG, "\n"));
if (xc.in ())
{
- list_context (xc.in (), level + 1);
+ list_context (xc.in (), level + 1, max_count);
}
}
else
@@ -301,14 +305,15 @@ namespace
//==========================================================================
void
- list_context (const CosNaming::NamingContext_ptr nc, int level)
+ list_context (const CosNaming::NamingContext_ptr nc,
+ int level,
+ CORBA::ULong max_count)
{
CosNaming::BindingIterator_var it;
CosNaming::BindingList_var bl;
- CORBA::ULong const CHUNK = 100;
NestedNamingContexts::add (nc);
- nc->list (CHUNK, bl, it);
+ nc->list (max_count, bl, it);
show_chunk (nc, bl.in (), level);
@@ -318,7 +323,7 @@ namespace
do
{
- more = it->next_n (CHUNK, bl);
+ more = it->next_n (max_count, bl);
show_chunk (nc, bl.in (), level);
} while (more);
@@ -567,14 +572,15 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[])
else if (1 != ACE_OS::strlen(*(++argv)))
{
ACE_DEBUG ((LM_DEBUG,
- "Error: --kindsep takes a single character (not %s)\n", *argv));
+ ACE_TEXT ("Error: --kindsep takes a single ")
+ ACE_TEXT ("character (not %s)\n"), *argv));
failed = true;
}
else if (showNSonly)
{
ACE_DEBUG ((LM_DEBUG,
- "Error: --nsior and --kindsep are "
- "both specified\n"));
+ ACE_TEXT ("Error: --nsior and --kindsep are ")
+ ACE_TEXT ("both specified\n")));
failed = true;
}
else
@@ -591,14 +597,14 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[])
else if (!--argc || !ACE_OS::ace_isdigit (ACE_TEXT_ALWAYS_CHAR (*(++argv))[0]))
{
ACE_DEBUG ((LM_DEBUG,
- "Error: --max requires a number\n"));
+ ACE_TEXT ("Error: --max requires a number\n")));
failed = true;
}
else if (showNSonly)
{
ACE_DEBUG ((LM_DEBUG,
- "Error: --nsior and --max are "
- "both specified\n"));
+ ACE_TEXT ("Error: --nsior and --max are ")
+ ACE_TEXT ("both specified\n")));
failed = true;
}
else
@@ -609,22 +615,53 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[])
if (rtt != ACE_Time_Value::zero)
{
ACE_DEBUG ((LM_DEBUG,
- "Error: --rtt given more than once\n"));
+ ACE_TEXT ("Error: --rtt given more than once\n")));
+ failed = true;
+ }
+ else if (!--argc || !ACE_OS::ace_isdigit (ACE_TEXT_ALWAYS_CHAR (*(++argv))[0]))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Error: --rtt requires a number\n")));
+ failed = true;
+ }
+ else
+ rtt.set (ACE_OS::atoi (*argv), 0);
+ }
+ else if (0 == ACE_OS::strcmp(*argv, ACE_TEXT ("--count")))
+ {
+ if (max_count != MAX_COUNT_DEFAULT)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Error: --count given more than once\n")));
failed = true;
}
else if (!--argc || !ACE_OS::ace_isdigit (ACE_TEXT_ALWAYS_CHAR (*(++argv))[0]))
{
ACE_DEBUG ((LM_DEBUG,
- "Error: --rtt requires a number\n"));
+ ACE_TEXT ("Error: --count requires a number\n")));
failed = true;
}
else
- rtt.set(ACE_OS::atoi (*argv), 0);
+ {
+ CORBA::ULong count = ACE_OS::strtoul (ACE_TEXT_ALWAYS_CHAR (*argv), 0, 10);
+ if (count > 0)
+ {
+ max_count = count;
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Error: --count requires a number")
+ ACE_TEXT (" greater than 0\n")));
+ failed = true;
+ }
+ }
}
else
{
ACE_DEBUG ((LM_DEBUG,
- "Unknown option %s\n", *argv));
+ ACE_TEXT ("Unknown option %s\n"),
+ *argv));
failed = true;
}
}
@@ -632,20 +669,22 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[])
if (failed)
{
- ACE_DEBUG ((LM_DEBUG, "\n%s options:\n"
- " --nsior {Display the naming service IOR and exit}\n"
- "or:\n"
- " --ns <ior> {Defaults to standard NameService}\n"
- " --ior {Display ior for end points}\n"
- " --ctxior {Display ior for naming contexts}\n"
- " --tree \"xx\" {Defaults to | for drawing tramlines}\n"
- " --node \"xx\" {Defaults to + for drawing nodes}\n"
- " --noloops {Inhibit drawing of naming context loops}\n"
- " --name <name> {Lists sub-set, defaults to root}\n"
- " --ctxsep <character> {<name> Context separation character, default /}\n"
- " --kindsep <character> {<name> ID/Kind separation character, default .}\n"
- " --max <number> {If given, limits displayed sub-context depth}\n",
- " --rtt <seconds> {If given, sets the relative round trip timeout policy}\n",
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n%s options:\n")
+ ACE_TEXT (" --nsior {Display the naming service IOR and exit}\n")
+ ACE_TEXT ("or:\n")
+ ACE_TEXT (" --ns <ior> {Defaults to standard NameService}\n")
+ ACE_TEXT (" --ior {Display ior for end points}\n")
+ ACE_TEXT (" --ctxior {Display ior for naming contexts}\n")
+ ACE_TEXT (" --tree \"xx\" {Defaults to | for drawing tramlines}\n")
+ ACE_TEXT (" --node \"xx\" {Defaults to + for drawing nodes}\n")
+ ACE_TEXT (" --noloops {Inhibit drawing of naming context loops}\n")
+ ACE_TEXT (" --name <name> {Lists sub-set, defaults to root}\n")
+ ACE_TEXT (" --ctxsep <character> {<name> Context separation character, default /}\n")
+ ACE_TEXT (" --kindsep <character> {<name> ID/Kind separation character, default .}\n")
+ ACE_TEXT (" --max <number> {If given, limits displayed sub-context depth}\n")
+ ACE_TEXT (" --rtt <seconds> {If given, sets the relative round trip timeout policy}\n")
+ ACE_TEXT (" --count <number> {If given, sets the maximum ")
+ ACE_TEXT ("number of entries per request from the NameService}\n"),
pname));
orb->destroy ();
return 1;
@@ -718,7 +757,7 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[])
ACE_DEBUG ((LM_DEBUG,
"Naming Service: %C\n---------------\n",
((showCtxIOR)? str.in () : "")));
- list_context (root_nc.in (), 1);
+ list_context (root_nc.in (), 1, max_count);
}
}
catch (const CORBA::Exception& ex)
diff --git a/TAO/utils/utils.mwc b/TAO/utils/utils.mwc
index eb8edb1783e..e6c25693aa5 100644
--- a/TAO/utils/utils.mwc
+++ b/TAO/utils/utils.mwc
@@ -10,4 +10,6 @@ workspace {
// must have mfc=1 in $ACE_ROOT/bin/MakeProjectCreator/config/default.features to generate Makefile for wxNamingViewer
NamingViewer
+
+ nsgroup
}