summaryrefslogtreecommitdiff
path: root/TAO
diff options
context:
space:
mode:
authordai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2005-10-19 00:27:51 +0000
committerdai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2005-10-19 00:27:51 +0000
commitb29e5800752ecefbe4e9317ac908e40d9c6eded0 (patch)
tree3bdec835860a692ca76bdcd5baa5f069645bf248 /TAO
parent189f1baf20ea719b1724adef186b8699706eb065 (diff)
downloadATCD-b29e5800752ecefbe4e9317ac908e40d9c6eded0.tar.gz
Tue Oct 18 17:24:26 MST 2005 Yan Dai <dai_y@ociweb.com>
Diffstat (limited to 'TAO')
-rw-r--r--TAO/ChangeLog460
-rw-r--r--TAO/examples/CSD_Strategy/README20
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/CSD_Test_ThreadPool.mpc24
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/ClientApp.cpp143
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/ClientApp.h29
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/Foo.idl29
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/Foo_i.cpp112
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/Foo_i.h49
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/OrbShutdownTask.cpp77
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/OrbShutdownTask.h41
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/README57
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/ServerApp.cpp237
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/ServerApp.h30
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/client_main.cpp45
-rwxr-xr-xTAO/examples/CSD_Strategy/ThreadPool/run_test.pl55
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool/server_main.cpp43
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/CSD_Test_ThreadPool2.mpc25
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/ClientApp.cpp143
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/ClientApp.h30
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/Foo.idl29
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/FooServantList.cpp99
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/FooServantList.h42
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/Foo_i.cpp86
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/Foo_i.h53
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.cpp77
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.h41
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/README61
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/ServerApp.cpp229
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/ServerApp.h30
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/client_main.cpp44
-rwxr-xr-xTAO/examples/CSD_Strategy/ThreadPool2/run_test.pl77
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool2/server_main.cpp44
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/CSD_Test_ThreadPool3.mpc25
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/ClientApp.cpp142
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/ClientApp.h30
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/Foo.idl29
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/Foo_i.cpp72
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/Foo_i.h40
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.cpp77
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.h41
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/OrbTask.cpp98
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/OrbTask.h37
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/README58
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/ServerApp.cpp269
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/ServerApp.h31
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/client_main.cpp44
-rwxr-xr-xTAO/examples/CSD_Strategy/ThreadPool3/run_test.pl56
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool3/server_main.cpp42
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/CSD_Test_ThreadPool4.mpc15
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/Callback.idl11
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/Callback_i.cpp26
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/Callback_i.h27
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/ClientTask.cpp213
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/ClientTask.h38
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/Foo.idl73
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/Foo_i.cpp301
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/Foo_i.h158
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.cpp77
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.h41
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/README23
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/ServerApp.cpp357
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/ServerApp.h44
-rwxr-xr-xTAO/examples/CSD_Strategy/ThreadPool4/run_test.pl39
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool4/server_main.cpp43
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/CSD_Test_ThreadPool5.mpc36
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/Callback.idl11
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/Callback_i.cpp26
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/Callback_i.h26
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/ClientApp.cpp226
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/ClientApp.h31
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/ClientTask.cpp263
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/ClientTask.h44
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/Foo.idl73
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp226
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.h63
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/Foo_i.cpp312
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/Foo_i.h166
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.cpp77
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.h41
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/OrbTask.cpp98
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/OrbTask.h37
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/README47
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/ServerApp.cpp354
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/ServerApp.h34
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/client_main.cpp45
-rwxr-xr-xTAO/examples/CSD_Strategy/ThreadPool5/run_test.pl126
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/server_main.cpp45
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/CSD_Test_ThreadPool6.mpc25
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/ClientApp.cpp143
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/ClientApp.h30
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/Foo.idl29
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/Foo_i.cpp113
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/Foo_i.h48
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.cpp77
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.h41
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/README14
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/ServerApp.cpp240
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/ServerApp.h30
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/client_main.cpp45
-rwxr-xr-xTAO/examples/CSD_Strategy/ThreadPool6/run_test.pl55
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool6/server_main.cpp45
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestApps/ClientApp.cpp200
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestApps/ClientApp.h63
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestApps/README64
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestApps/ServerApp.cpp421
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestApps/ServerApp.h95
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestApps/client_main.cpp7
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestApps/csd_pt_testapps.mpc21
-rwxr-xr-xTAO/performance-tests/CSD_Strategy/TestApps/run_test.pl227
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestApps/server_main.cpp5
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/AppHelper.cpp102
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/AppHelper.h114
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/AppShutdown.cpp84
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/AppShutdown.h42
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/CSD_PT_TestInf_Export.h58
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/CancelledException.idl7
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/ClientEngine.cpp12
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/ClientEngine.h39
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/ClientTask.cpp117
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/ClientTask.h53
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/CustomException.idl7
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/FooException.idl7
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/OrbRunner.cpp57
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/OrbRunner.h24
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.cpp75
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.h40
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/OrbTask.cpp98
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/OrbTask.h39
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/README13
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/ServantList_T.cpp102
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/ServantList_T.h67
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/TestAppBase.cpp30
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/TestAppBase.h36
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/TestAppException.idl7
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/TestAppMain.h49
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestInf/csd_pt_testinf.mpc38
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/CSD_PT_TestServant_Export.h58
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/Foo.idl29
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.cpp88
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.h41
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/Foo_Statistics.cpp75
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/Foo_Statistics.h33
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/Foo_i.cpp83
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/Foo_i.h46
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/README10
-rw-r--r--TAO/performance-tests/CSD_Strategy/TestServant/csd_pt_testservant.mpc20
-rw-r--r--TAO/tao/CSD_Framework.mpc34
-rw-r--r--TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.cpp56
-rw-r--r--TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h49
-rw-r--r--TAO/tao/CSD_Framework/CSD_FW_Export.h58
-rw-r--r--TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp462
-rw-r--r--TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h127
-rw-r--r--TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl42
-rw-r--r--TAO/tao/CSD_Framework/CSD_Framework.pidl75
-rw-r--r--TAO/tao/CSD_Framework/CSD_FrameworkA.cpp73
-rw-r--r--TAO/tao/CSD_Framework/CSD_FrameworkA.h64
-rw-r--r--TAO/tao/CSD_Framework/CSD_FrameworkC.cpp293
-rw-r--r--TAO/tao/CSD_Framework/CSD_FrameworkC.h312
-rw-r--r--TAO/tao/CSD_Framework/CSD_FrameworkC.inl27
-rw-r--r--TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp26
-rw-r--r--TAO/tao/CSD_Framework/CSD_Framework_Loader.h41
-rw-r--r--TAO/tao/CSD_Framework/CSD_ORBInitializer.cpp33
-rw-r--r--TAO/tao/CSD_Framework/CSD_ORBInitializer.h66
-rw-r--r--TAO/tao/CSD_Framework/CSD_Object_Adapter.cpp42
-rw-r--r--TAO/tao/CSD_Framework/CSD_Object_Adapter.h54
-rw-r--r--TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.cpp93
-rw-r--r--TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.h46
-rw-r--r--TAO/tao/CSD_Framework/CSD_POA.cpp131
-rw-r--r--TAO/tao/CSD_Framework/CSD_POA.h108
-rw-r--r--TAO/tao/CSD_Framework/CSD_POA.inl11
-rw-r--r--TAO/tao/CSD_Framework/CSD_Strategy_Base.cpp133
-rw-r--r--TAO/tao/CSD_Framework/CSD_Strategy_Base.h172
-rw-r--r--TAO/tao/CSD_Framework/CSD_Strategy_Base.inl138
-rw-r--r--TAO/tao/CSD_Framework/CSD_Strategy_Proxy.cpp47
-rw-r--r--TAO/tao/CSD_Framework/CSD_Strategy_Proxy.h110
-rw-r--r--TAO/tao/CSD_Framework/CSD_Strategy_Proxy.inl104
-rw-r--r--TAO/tao/CSD_Framework/CSD_Strategy_Repository.cpp114
-rw-r--r--TAO/tao/CSD_Framework/CSD_Strategy_Repository.h75
-rw-r--r--TAO/tao/CSD_Framework/diffs/CSD_Framework.diff38
-rw-r--r--TAO/tao/CSD_ThreadPool.mpc34
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.cpp44
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h85
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.inl28
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.cpp57
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h87
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.inl20
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.cpp55
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h106
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.inl52
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.cpp71
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h107
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.inl27
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.cpp16
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.h100
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.inl42
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.cpp50
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h76
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.inl11
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.cpp16
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.h78
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.inl44
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.cpp16
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h96
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.inl47
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.cpp32
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h89
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.inl18
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.cpp50
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h91
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.inl26
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Export.h58
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp124
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h96
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue.inl23
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.cpp16
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.h74
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.inl7
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.cpp57
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.h99
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.inl20
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Request.cpp24
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Request.h133
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Request.inl92
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.cpp16
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.h89
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.inl24
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.cpp11
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h92
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.inl66
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.cpp270
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.h180
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.inl17
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp108
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.h61
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.cpp11
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.h107
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.inl50
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp310
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Task.h158
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_TP_Task.inl17
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp19
-rw-r--r--TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h60
-rw-r--r--TAO/tao/Intrusive_Ref_Count_Base_T.cpp21
-rw-r--r--TAO/tao/Intrusive_Ref_Count_Base_T.h75
-rw-r--r--TAO/tao/Intrusive_Ref_Count_Base_T.inl32
-rw-r--r--TAO/tao/Intrusive_Ref_Count_Handle_T.cpp16
-rw-r--r--TAO/tao/Intrusive_Ref_Count_Handle_T.h152
-rw-r--r--TAO/tao/Intrusive_Ref_Count_Handle_T.inl155
-rw-r--r--TAO/tao/PortableServer/Object_Adapter.cpp15
-rw-r--r--TAO/tao/PortableServer/Object_Adapter.h4
-rw-r--r--TAO/tao/PortableServer/POAManager.cpp13
-rw-r--r--TAO/tao/PortableServer/Root_POA.cpp36
-rw-r--r--TAO/tao/PortableServer/Root_POA.h19
-rw-r--r--TAO/tao/PortableServer/ServantRetentionStrategyRetain.cpp40
-rw-r--r--TAO/tao/PortableServer/get_arg.h2
-rw-r--r--TAO/tao/Service_Context.h13
-rw-r--r--TAO/tao/TAO_Server_Request.h16
-rw-r--r--TAO/tao/Tagged_Profile.h14
-rw-r--r--TAO/tao/operation_details.h13
-rw-r--r--TAO/tests/CSD_Strategy_Tests/Broken/CSD_TP_Broken.mpc21
-rw-r--r--TAO/tests/CSD_Strategy_Tests/Broken/ClientApp.cpp318
-rw-r--r--TAO/tests/CSD_Strategy_Tests/Broken/ClientApp.h78
-rw-r--r--TAO/tests/CSD_Strategy_Tests/Broken/ServerApp.cpp417
-rw-r--r--TAO/tests/CSD_Strategy_Tests/Broken/ServerApp.h85
-rw-r--r--TAO/tests/CSD_Strategy_Tests/Broken/client_main.cpp7
-rwxr-xr-xTAO/tests/CSD_Strategy_Tests/Broken/run_test.pl172
-rw-r--r--TAO/tests/CSD_Strategy_Tests/Broken/server_main.cpp5
-rw-r--r--TAO/tests/CSD_Strategy_Tests/README117
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/AppHelper.cpp102
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/AppHelper.h114
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/AppShutdown.cpp85
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/AppShutdown.h42
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Export.h58
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Lib.mpc39
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/CancelledException.idl7
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/ClientEngine.cpp12
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/ClientEngine.h38
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/ClientTask.cpp116
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/ClientTask.h51
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/CustomException.idl7
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/FooException.idl7
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/OrbRunner.cpp58
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/OrbRunner.h24
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.cpp75
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.h40
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/OrbTask.cpp99
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/OrbTask.h38
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/ServantList_T.cpp135
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/ServantList_T.h68
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.cpp35
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.h24
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppBase.cpp30
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppBase.h36
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppException.idl7
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppMain.h49
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_A/CSD_TP_Foo_A_Export.h58
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A.idl29
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.cpp94
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.h40
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.cpp88
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.h34
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.cpp82
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.h44
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_A/csd_tp_foo_a_lib.mpc20
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/CSD_TP_Foo_B_Export.h58
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback.idl11
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.cpp28
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.h32
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B.idl70
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.cpp206
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.h47
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.cpp83
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.h47
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.cpp187
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.h54
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.cpp283
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.h93
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_B/csd_tp_foo_b_lib.mpc25
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/CSD_TP_Foo_C_Export.h58
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C.idl29
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.cpp92
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.h40
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.cpp136
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.h42
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.cpp153
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.h52
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.cpp111
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.h35
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.cpp65
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.h45
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.cpp66
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.h50
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.cpp69
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.h51
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.cpp52
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.h47
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.cpp81
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.h50
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.cpp148
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.h54
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Foo_C/csd_tp_foo_c_lib.mpc27
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_1/CSD_TP_Test_1.mpc21
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.cpp84
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.h28
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.cpp188
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.h30
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_1/client_main.cpp5
-rwxr-xr-xTAO/tests/CSD_Strategy_Tests/TP_Test_1/run_test.pl55
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_1/server_main.cpp5
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_2/CSD_TP_Test_2.mpc21
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.cpp196
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.h51
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.cpp368
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.h79
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_2/client_main.cpp7
-rwxr-xr-xTAO/tests/CSD_Strategy_Tests/TP_Test_2/run_test.pl173
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_2/server_main.cpp7
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_3/CSD_TP_Test_3.mpc21
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.cpp318
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.h78
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.cpp408
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.h85
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_3/client_main.cpp7
-rwxr-xr-xTAO/tests/CSD_Strategy_Tests/TP_Test_3/run_test.pl170
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_3/server_main.cpp5
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_4/CSD_TP_Test_4.mpc21
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.cpp199
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.h52
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_4/README337
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.cpp383
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.h79
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_4/client_main.cpp7
-rwxr-xr-xTAO/tests/CSD_Strategy_Tests/TP_Test_4/run_test.pl177
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_4/server_main.cpp5
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/CSD_TP_Test_Dynamic.mpc20
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.cpp25
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.h45
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/README37
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Test.idl20
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/client.cpp86
-rwxr-xr-xTAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/run_test.pl43
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/server.cpp115
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/svc.conf1
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Static/CSD_TP_Test_Static.mpc21
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.cpp86
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.h28
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Static/README38
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ServerApp.cpp171
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ServerApp.h30
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Static/client_main.cpp5
-rwxr-xr-xTAO/tests/CSD_Strategy_Tests/TP_Test_Static/run_test.pl55
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Static/server_main.cpp5
-rw-r--r--TAO/tests/CSD_Strategy_Tests/TP_Test_Static/svc.conf1
393 files changed, 29812 insertions, 5 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 8aa7ab4702f..12ac174a5c5 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,463 @@
+Tue Oct 18 17:24:26 MST 2005 Yan Dai <dai_y@ociweb.com>
+
+ Merged in the CSD (Custom Servant Dispatching) feature from OCI.
+
+ The main changes to existing code are:
+
+ - Four hooks are added to TAO_Root_POA to notify the CSD when poa
+ is activated/deactivated and servant is activated/deactivated.
+ Some areas of the code were instrumented to call these hooks to
+ notify the CSD Strategy object of POA activation and deactivation
+ "events". Likewise, code was added to notify the CSD Strategy object
+ of servant activation and deactivation "events".
+ - A virtual method do_dispatch() is added to the TAO_Object_Adapter so
+ the CSD object adpater can override the default implementation to
+ dispatch the requests to the CSD strategy.
+ - The remote requests and the collocated oneway requests are cloned when
+ they are dispatched to the CSD strategy. To support the TAO_ServerRequest
+ clone in the CSD library, the friendship is added to the TAO_ServerRequest
+ class and it's data member classes such as TAO_Service_Context class,
+ TAO_Operation_Details class and TAO_Tagged_Profile class.
+
+ * tao/PortableServer/Root_POA.cpp:
+ * tao/PortableServer/Root_POA.h:
+
+ Added four hooks.
+
+ * tao/PortableServer/Object_Adapter.cpp:
+ * tao/PortableServer/Object_Adapter.h:
+ * tao/PortableServer/POAManager.cpp:
+ * tao/PortableServer/ServantRetentionStrategyRetain.cpp:
+
+ Instrumented to call the hooks.
+
+ * tao/operation_details.h:
+ * tao/Service_Context.h:
+ * tao/Tagged_Profile.h:
+
+ Added friendship with CSD_FW_Server_Request_Wrapper to support
+ the TAO_ServerRequest clone in CSD library.
+
+ * tao/TAO_Server_Request.h:
+
+ - Changed the operation_details_ to be pointer to const
+ TAO_Operation_Details object instead of const pointer to const
+ TAO_Operation_Details object. This change is made to accommodate
+ the change of TAO_ServerRequest clone in the CSD library.
+ - Added friendship with CSD_FW_Server_Request_Wrapper to support
+ the TAO_ServerRequest clone in CSD library.
+
+ * tao/PortableServer/get_arg.h:
+
+ Made the get_in_arg template function check whether the
+ detail argument is nil. If the detail is not nil and the
+ argument list in detail is nil(collocated oneway case) then it
+ will demarshall the input CDR stream and get arguments. This
+ change is made to accommodate the changes in TAO_Operation_Details
+ clone that writes the argument list to the input CDR of the
+ TAO_ServerRequest object.
+
+ * tao/Intrusive_Ref_Count_Base_T.cpp:
+ * tao/Intrusive_Ref_Count_Base_T.h:
+ * tao/Intrusive_Ref_Count_Base_T.inl:
+ * tao/Intrusive_Ref_Count_Handle_T.cpp:
+ * tao/Intrusive_Ref_Count_Handle_T.h:
+ * tao/Intrusive_Ref_Count_Handle_T.inl:
+
+ These are two new classes that provide infrastructure-level support
+ for classes that need an "intrusive" reference counting mechanism.
+
+ * tao/CSD_Framework.mpc:
+ * tao/CSD_Framework/CSD_Default_Servant_Dispatcher.cpp:
+ * tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h:
+ * tao/CSD_Framework/CSD_Framework.pidl:
+ * tao/CSD_Framework/CSD_Framework_Loader.cpp:
+ * tao/CSD_Framework/CSD_Framework_Loader.h:
+ * tao/CSD_Framework/CSD_FrameworkA.cpp:
+ * tao/CSD_Framework/CSD_FrameworkA.h:
+ * tao/CSD_Framework/CSD_FrameworkC.cpp:
+ * tao/CSD_Framework/CSD_FrameworkC.h:
+ * tao/CSD_Framework/CSD_FrameworkC.inl:
+ * tao/CSD_Framework/CSD_FW_Export.h:
+ * tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp:
+ * tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h:
+ * tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl:
+ * tao/CSD_Framework/CSD_Object_Adapter.cpp:
+ * tao/CSD_Framework/CSD_Object_Adapter.h:
+ * tao/CSD_Framework/CSD_Object_Adapter_Factory.cpp:
+ * tao/CSD_Framework/CSD_Object_Adapter_Factory.h:
+ * tao/CSD_Framework/CSD_ORBInitializer.cpp:
+ * tao/CSD_Framework/CSD_ORBInitializer.h:
+ * tao/CSD_Framework/CSD_POA.cpp:
+ * tao/CSD_Framework/CSD_POA.h:
+ * tao/CSD_Framework/CSD_POA.inl:
+ * tao/CSD_Framework/CSD_Strategy_Base.cpp:
+ * tao/CSD_Framework/CSD_Strategy_Base.h:
+ * tao/CSD_Framework/CSD_Strategy_Base.inl:
+ * tao/CSD_Framework/CSD_Strategy_Proxy.cpp:
+ * tao/CSD_Framework/CSD_Strategy_Proxy.h:
+ * tao/CSD_Framework/CSD_Strategy_Proxy.inl:
+ * tao/CSD_Framework/CSD_Strategy_Repository.cpp:
+ * tao/CSD_Framework/CSD_Strategy_Repository.h:
+ * tao/CSD_Framework/diffs/CSD_Framework.diff:
+
+ All of the files listed above are brand new and are used to build
+ the new CSD Framework library. This framework implements the base
+ classes for the concrete strategy implementation and implements
+ the service objects for CSD strategy static and dynamic loading
+ via the service configuration file.
+
+ * tao/CSD_ThreadPool.mpc:
+ * tao/CSD_ThreadPool/CSD_ThreadPool.cpp:
+ * tao/CSD_ThreadPool/CSD_ThreadPool.h:
+ * tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h:
+ * tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h:
+ * tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h:
+ * tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h:
+ * tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Corba_Request.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Corba_Request.h:
+ * tao/CSD_ThreadPool/CSD_TP_Corba_Request.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Request.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Request.h:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Request.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h:
+ * tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h:
+ * tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Export.h:
+ * tao/CSD_ThreadPool/CSD_TP_Queue.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Queue.h:
+ * tao/CSD_ThreadPool/CSD_TP_Queue.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.h:
+ * tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Remote_Request.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Remote_Request.h:
+ * tao/CSD_ThreadPool/CSD_TP_Remote_Request.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Request.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Request.h:
+ * tao/CSD_ThreadPool/CSD_TP_Request.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Servant_State.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Servant_State.h:
+ * tao/CSD_ThreadPool/CSD_TP_Servant_State.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h:
+ * tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Strategy.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Strategy.h:
+ * tao/CSD_ThreadPool/CSD_TP_Strategy.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.h:
+ * tao/CSD_ThreadPool/CSD_TP_Synch_Helper.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Synch_Helper.h:
+ * tao/CSD_ThreadPool/CSD_TP_Synch_Helper.inl:
+ * tao/CSD_ThreadPool/CSD_TP_Task.cpp:
+ * tao/CSD_ThreadPool/CSD_TP_Task.h:
+ * tao/CSD_ThreadPool/CSD_TP_Task.inl:
+
+ All of the files listed above are brand new and are used to build
+ the new CSD ThreadPool library. Collectively, these classes
+ represent the reference-implementation for the CSD Strategy feature.
+
+ * examples/CSD_Strategy/README:
+ * examples/CSD_Strategy/ThreadPool/client_main.cpp:
+ * examples/CSD_Strategy/ThreadPool/ClientApp.cpp:
+ * examples/CSD_Strategy/ThreadPool/ClientApp.h:
+ * examples/CSD_Strategy/ThreadPool/CSD_Test_ThreadPool.mpc:
+ * examples/CSD_Strategy/ThreadPool/Foo.idl:
+ * examples/CSD_Strategy/ThreadPool/Foo_i.cpp:
+ * examples/CSD_Strategy/ThreadPool/Foo_i.h:
+ * examples/CSD_Strategy/ThreadPool/OrbShutdownTask.cpp:
+ * examples/CSD_Strategy/ThreadPool/OrbShutdownTask.h:
+ * examples/CSD_Strategy/ThreadPool/README:
+ * examples/CSD_Strategy/ThreadPool/run_test.pl:
+ * examples/CSD_Strategy/ThreadPool/server_main.cpp:
+ * examples/CSD_Strategy/ThreadPool/ServerApp.cpp:
+ * examples/CSD_Strategy/ThreadPool/ServerApp.h:
+ * examples/CSD_Strategy/ThreadPool2/client_main.cpp:
+ * examples/CSD_Strategy/ThreadPool2/ClientApp.cpp:
+ * examples/CSD_Strategy/ThreadPool2/ClientApp.h:
+ * examples/CSD_Strategy/ThreadPool2/CSD_Test_ThreadPool2.mpc:
+ * examples/CSD_Strategy/ThreadPool2/Foo.idl:
+ * examples/CSD_Strategy/ThreadPool2/Foo_i.cpp:
+ * examples/CSD_Strategy/ThreadPool2/Foo_i.h:
+ * examples/CSD_Strategy/ThreadPool2/FooServantList.cpp:
+ * examples/CSD_Strategy/ThreadPool2/FooServantList.h:
+ * examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.cpp:
+ * examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.h:
+ * examples/CSD_Strategy/ThreadPool2/README:
+ * examples/CSD_Strategy/ThreadPool2/run_test.pl:
+ * examples/CSD_Strategy/ThreadPool2/server_main.cpp:
+ * examples/CSD_Strategy/ThreadPool2/ServerApp.cpp:
+ * examples/CSD_Strategy/ThreadPool2/ServerApp.h:
+ * examples/CSD_Strategy/ThreadPool3/client_main.cpp:
+ * examples/CSD_Strategy/ThreadPool3/ClientApp.cpp:
+ * examples/CSD_Strategy/ThreadPool3/ClientApp.h:
+ * examples/CSD_Strategy/ThreadPool3/CSD_Test_ThreadPool3.mpc:
+ * examples/CSD_Strategy/ThreadPool3/Foo.idl:
+ * examples/CSD_Strategy/ThreadPool3/Foo_i.cpp:
+ * examples/CSD_Strategy/ThreadPool3/Foo_i.h:
+ * examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.cpp:
+ * examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.h:
+ * examples/CSD_Strategy/ThreadPool3/OrbTask.cpp:
+ * examples/CSD_Strategy/ThreadPool3/OrbTask.h:
+ * examples/CSD_Strategy/ThreadPool3/README:
+ * examples/CSD_Strategy/ThreadPool3/run_test.pl:
+ * examples/CSD_Strategy/ThreadPool3/server_main.cpp:
+ * examples/CSD_Strategy/ThreadPool3/ServerApp.cpp:
+ * examples/CSD_Strategy/ThreadPool3/ServerApp.h:
+ * examples/CSD_Strategy/ThreadPool4/Callback.idl:
+ * examples/CSD_Strategy/ThreadPool4/Callback_i.cpp:
+ * examples/CSD_Strategy/ThreadPool4/Callback_i.h:
+ * examples/CSD_Strategy/ThreadPool4/ClientTask.cpp:
+ * examples/CSD_Strategy/ThreadPool4/ClientTask.h:
+ * examples/CSD_Strategy/ThreadPool4/CSD_Test_ThreadPool4.mpc:
+ * examples/CSD_Strategy/ThreadPool4/Foo.idl:
+ * examples/CSD_Strategy/ThreadPool4/Foo_i.cpp:
+ * examples/CSD_Strategy/ThreadPool4/Foo_i.h:
+ * examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.cpp:
+ * examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.h:
+ * examples/CSD_Strategy/ThreadPool4/README:
+ * examples/CSD_Strategy/ThreadPool4/run_test.pl:
+ * examples/CSD_Strategy/ThreadPool4/server_main.cpp:
+ * examples/CSD_Strategy/ThreadPool4/ServerApp.cpp:
+ * examples/CSD_Strategy/ThreadPool4/ServerApp.h:
+ * examples/CSD_Strategy/ThreadPool5/Callback.idl:
+ * examples/CSD_Strategy/ThreadPool5/Callback_i.cpp:
+ * examples/CSD_Strategy/ThreadPool5/Callback_i.h:
+ * examples/CSD_Strategy/ThreadPool5/client_main.cpp:
+ * examples/CSD_Strategy/ThreadPool5/ClientApp.cpp:
+ * examples/CSD_Strategy/ThreadPool5/ClientApp.h:
+ * examples/CSD_Strategy/ThreadPool5/ClientTask.cpp:
+ * examples/CSD_Strategy/ThreadPool5/ClientTask.h:
+ * examples/CSD_Strategy/ThreadPool5/CSD_Test_ThreadPool5.mpc:
+ * examples/CSD_Strategy/ThreadPool5/Foo.idl:
+ * examples/CSD_Strategy/ThreadPool5/Foo_i.cpp:
+ * examples/CSD_Strategy/ThreadPool5/Foo_i.h:
+ * examples/CSD_Strategy/ThreadPool5/FooServantList.cpp:
+ * examples/CSD_Strategy/ThreadPool5/FooServantList.h:
+ * examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.cpp:
+ * examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.h:
+ * examples/CSD_Strategy/ThreadPool5/OrbTask.cpp:
+ * examples/CSD_Strategy/ThreadPool5/OrbTask.h:
+ * examples/CSD_Strategy/ThreadPool5/README:
+ * examples/CSD_Strategy/ThreadPool5/run_test.pl:
+ * examples/CSD_Strategy/ThreadPool5/server_main.cpp:
+ * examples/CSD_Strategy/ThreadPool5/ServerApp.cpp:
+ * examples/CSD_Strategy/ThreadPool5/ServerApp.h:
+ * examples/CSD_Strategy/ThreadPool6/client_main.cpp:
+ * examples/CSD_Strategy/ThreadPool6/ClientApp.cpp:
+ * examples/CSD_Strategy/ThreadPool6/ClientApp.h:
+ * examples/CSD_Strategy/ThreadPool6/CSD_Test_ThreadPool6.mpc:
+ * examples/CSD_Strategy/ThreadPool6/Foo.idl:
+ * examples/CSD_Strategy/ThreadPool6/Foo_i.cpp:
+ * examples/CSD_Strategy/ThreadPool6/Foo_i.h:
+ * examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.cpp:
+ * examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.h:
+ * examples/CSD_Strategy/ThreadPool6/README:
+ * examples/CSD_Strategy/ThreadPool6/run_test.pl:
+ * examples/CSD_Strategy/ThreadPool6/server_main.cpp:
+ * examples/CSD_Strategy/ThreadPool6/ServerApp.cpp:
+ * examples/CSD_Strategy/ThreadPool6/ServerApp.h:
+ * performance-tests/CSD_Strategy/TestApps/client_main.cpp:
+ * performance-tests/CSD_Strategy/TestApps/ClientApp.cpp:
+ * performance-tests/CSD_Strategy/TestApps/ClientApp.h:
+ * performance-tests/CSD_Strategy/TestApps/csd_pt_testapps.mpc:
+ * performance-tests/CSD_Strategy/TestApps/run_test.pl:
+ * performance-tests/CSD_Strategy/TestApps/server_main.cpp:
+ * performance-tests/CSD_Strategy/TestApps/ServerApp.cpp:
+ * performance-tests/CSD_Strategy/TestApps/ServerApp.h:
+ * performance-tests/CSD_Strategy/TestApps/README:
+ * performance-tests/CSD_Strategy/TestInf/AppHelper.cpp:
+ * performance-tests/CSD_Strategy/TestInf/AppHelper.h:
+ * performance-tests/CSD_Strategy/TestInf/AppShutdown.cpp:
+ * performance-tests/CSD_Strategy/TestInf/AppShutdown.h:
+ * performance-tests/CSD_Strategy/TestInf/CancelledException.idl:
+ * performance-tests/CSD_Strategy/TestInf/ClientEngine.cpp:
+ * performance-tests/CSD_Strategy/TestInf/ClientEngine.h:
+ * performance-tests/CSD_Strategy/TestInf/ClientTask.cpp:
+ * performance-tests/CSD_Strategy/TestInf/ClientTask.h:
+ * performance-tests/CSD_Strategy/TestInf/csd_pt_testinf.mpc:
+ * performance-tests/CSD_Strategy/TestInf/CSD_PT_TestInf_Export.h:
+ * performance-tests/CSD_Strategy/TestInf/CustomException.idl:
+ * performance-tests/CSD_Strategy/TestInf/FooException.idl:
+ * performance-tests/CSD_Strategy/TestInf/OrbRunner.cpp:
+ * performance-tests/CSD_Strategy/TestInf/OrbRunner.h:
+ * performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.cpp:
+ * performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.h:
+ * performance-tests/CSD_Strategy/TestInf/OrbTask.cpp:
+ * performance-tests/CSD_Strategy/TestInf/OrbTask.h:
+ * performance-tests/CSD_Strategy/TestInf/ServantList_T.cpp:
+ * performance-tests/CSD_Strategy/TestInf/ServantList_T.h:
+ * performance-tests/CSD_Strategy/TestInf/TestAppBase.cpp:
+ * performance-tests/CSD_Strategy/TestInf/TestAppBase.h:
+ * performance-tests/CSD_Strategy/TestInf/TestAppException.idl:
+ * performance-tests/CSD_Strategy/TestInf/TestAppMain.h:
+ * performance-tests/CSD_Strategy/TestInf/README:
+ * performance-tests/CSD_Strategy/TestServant/csd_pt_testservant.mpc:
+ * performance-tests/CSD_Strategy/TestServant/CSD_PT_TestServant_Export.h:
+ * performance-tests/CSD_Strategy/TestServant/Foo.idl:
+ * performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.cpp:
+ * performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.h:
+ * performance-tests/CSD_Strategy/TestServant/Foo_i.cpp:
+ * performance-tests/CSD_Strategy/TestServant/Foo_i.h:
+ * performance-tests/CSD_Strategy/TestServant/Foo_Statistics.cpp:
+ * performance-tests/CSD_Strategy/TestServant/Foo_Statistics.h:
+ * performance-tests/CSD_Strategy/TestServant/README:
+ * tests/CSD_Strategy_Tests/README:
+ * tests/CSD_Strategy_Tests/Broken/client_main.cpp:
+ * tests/CSD_Strategy_Tests/Broken/ClientApp.cpp:
+ * tests/CSD_Strategy_Tests/Broken/ClientApp.h:
+ * tests/CSD_Strategy_Tests/Broken/CSD_TP_Broken.mpc:
+ * tests/CSD_Strategy_Tests/Broken/run_test.pl:
+ * tests/CSD_Strategy_Tests/Broken/server_main.cpp:
+ * tests/CSD_Strategy_Tests/Broken/ServerApp.cpp:
+ * tests/CSD_Strategy_Tests/Broken/ServerApp.h:
+ * tests/CSD_Strategy_Tests/TP_Common/AppHelper.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/AppHelper.h:
+ * tests/CSD_Strategy_Tests/TP_Common/AppShutdown.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/AppShutdown.h:
+ * tests/CSD_Strategy_Tests/TP_Common/CancelledException.idl:
+ * tests/CSD_Strategy_Tests/TP_Common/ClientEngine.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/ClientEngine.h:
+ * tests/CSD_Strategy_Tests/TP_Common/ClientTask.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/ClientTask.h:
+ * tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Export.h:
+ * tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Lib.mpc:
+ * tests/CSD_Strategy_Tests/TP_Common/CustomException.idl:
+ * tests/CSD_Strategy_Tests/TP_Common/FooException.idl:
+ * tests/CSD_Strategy_Tests/TP_Common/OrbRunner.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/OrbRunner.h:
+ * tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.h:
+ * tests/CSD_Strategy_Tests/TP_Common/OrbTask.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/OrbTask.h:
+ * tests/CSD_Strategy_Tests/TP_Common/ServantList_T.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/ServantList_T.h:
+ * tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.h:
+ * tests/CSD_Strategy_Tests/TP_Common/TestAppBase.cpp:
+ * tests/CSD_Strategy_Tests/TP_Common/TestAppBase.h:
+ * tests/CSD_Strategy_Tests/TP_Common/TestAppException.idl:
+ * tests/CSD_Strategy_Tests/TP_Common/TestAppMain.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_A/CSD_TP_Foo_A_Export.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_A/csd_tp_foo_a_lib.mpc:
+ * tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A.idl:
+ * tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Callback.idl:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/CSD_TP_Foo_B_Export.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/csd_tp_foo_b_lib.mpc:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B.idl:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/CSD_TP_Foo_C_Export.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/csd_tp_foo_c_lib.mpc:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C.idl:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.h:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.cpp:
+ * tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.h:
+ * tests/CSD_Strategy_Tests/TP_Test_1/client_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_1/CSD_TP_Test_1.mpc:
+ * tests/CSD_Strategy_Tests/TP_Test_1/run_test.pl:
+ * tests/CSD_Strategy_Tests/TP_Test_1/server_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_2/client_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_2/CSD_TP_Test_2.mpc:
+ * tests/CSD_Strategy_Tests/TP_Test_2/run_test.pl:
+ * tests/CSD_Strategy_Tests/TP_Test_2/server_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_3/client_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_3/CSD_TP_Test_3.mpc:
+ * tests/CSD_Strategy_Tests/TP_Test_3/run_test.pl:
+ * tests/CSD_Strategy_Tests/TP_Test_3/server_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_4/client_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_4/CSD_TP_Test_4.mpc:
+ * tests/CSD_Strategy_Tests/TP_Test_4/README:
+ * tests/CSD_Strategy_Tests/TP_Test_4/run_test.pl:
+ * tests/CSD_Strategy_Tests/TP_Test_4/server_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_Dynamic/client.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_Dynamic/CSD_TP_Test_Dynamic.mpc:
+ * tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.h:
+ * tests/CSD_Strategy_Tests/TP_Test_Dynamic/README:
+ * tests/CSD_Strategy_Tests/TP_Test_Dynamic/run_test.pl:
+ * tests/CSD_Strategy_Tests/TP_Test_Dynamic/server.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_Dynamic/svc.conf:
+ * tests/CSD_Strategy_Tests/TP_Test_Dynamic/Test.idl:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/client_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/CSD_TP_Test_Static.mpc:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/README:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/run_test.pl:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/server_main.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/ServerApp.cpp:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/ServerApp.h:
+ * tests/CSD_Strategy_Tests/TP_Test_Static/svc.conf:
+
+ All of the files above are part of the examples, tests and performance
+ tests added for the CSD feature.
+
Tue Oct 18 13:23:21 2005 Chris Cleeland <cleeland_c@ociweb.com>
* docs/ec_options.html: Finally updated documentation to
diff --git a/TAO/examples/CSD_Strategy/README b/TAO/examples/CSD_Strategy/README
new file mode 100644
index 00000000000..05a14e7af7e
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/README
@@ -0,0 +1,20 @@
+The example ThreadPool, ThreadPool2 and ThreadPool3 use the same idl file which
+defines some twoway calls and a simple oneway call and they are different just
+because of their configurations such as the number of servants, the number of
+ORB threads and the number of csd threads.
+
+ThreadPool - 1 servant, 1 ORB theread (main thread), 1 csd thread.
+ThreadPool2 - multiple servants, 1 ORB theread (main thread), multiple
+csd threads.
+ThreadPool3 - 1 servant, multiple ORB thereads (main thread), multiple
+csd threads.
+
+The example 6 is simply a copy of the threadpool example, the only difference
+is it uses the TIE approach.
+
+The example ThreadPool4 and ThreadPool5 use the same idl file which includes
+the operations defined in example ThreadPool, ThreadPool2 and ThreadPool3 in
+addition of callbacks and the oneway "IN" argument test. The ThreadPool4 is
+a collocated test. The ThreadPool5 combines all other test cases together except
+the ThreadPool6 example.
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/CSD_Test_ThreadPool.mpc b/TAO/examples/CSD_Strategy/ThreadPool/CSD_Test_ThreadPool.mpc
new file mode 100644
index 00000000000..33b7e1a515b
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/CSD_Test_ThreadPool.mpc
@@ -0,0 +1,24 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server) : csd_threadpool, taoexe, portableserver {
+ exename = server_main
+
+ Source_Files {
+ Foo_i.cpp
+ ServerApp.cpp
+ server_main.cpp
+ OrbShutdownTask.cpp
+ }
+}
+
+project(*Client): taoexe, anytypecode {
+ exename = client_main
+
+ Source_Files {
+ FooC.cpp
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/ClientApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool/ClientApp.cpp
new file mode 100644
index 00000000000..a81a617566c
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/ClientApp.cpp
@@ -0,0 +1,143 @@
+// $Id$
+#include "ClientApp.h"
+#include "FooC.h"
+#include "ace/Get_Opt.h"
+#include "ace/Log_Msg.h"
+
+
+ClientApp::ClientApp()
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb
+ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ CORBA::Object_var obj
+ = orb->string_to_object(this->ior_.c_str() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to convert IOR string to obj ref.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ Foo_var foo = Foo::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(foo.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to Foo interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ for (CORBA::Long i = 1; i <= 100; i++)
+ {
+ foo->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ foo->op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ CORBA::Long value = foo->op3(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Value retrieved from op3() == %d\n",
+ value));
+
+ for (CORBA::Long j = 1; j <= 5; j++)
+ {
+ foo->op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ foo->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Caught FooException - as expected.\n"));
+
+ }
+ ACE_ENDTRY;
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Tell server that we are done().\n"));
+
+ foo->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Back from done().\n"));
+
+ return 0;
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/ClientApp.h b/TAO/examples/CSD_Strategy/ThreadPool/ClientApp.h
new file mode 100644
index 00000000000..1c706005563
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/ClientApp.h
@@ -0,0 +1,29 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+class ClientApp
+{
+ public:
+
+ ClientApp();
+ ~ClientApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString ior_;
+
+ ACE_CString exe_name_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/Foo.idl b/TAO/examples/CSD_Strategy/ThreadPool/Foo.idl
new file mode 100644
index 00000000000..f4a756a31b1
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/Foo.idl
@@ -0,0 +1,29 @@
+// $Id$
+#ifndef FOO_IDL
+#define FOO_IDL
+
+exception FooException {};
+exception TestException {};
+
+interface Foo
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, no arguments
+ long op3();
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Client calls this last. It will shutdown the server.
+ void done();
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/Foo_i.cpp b/TAO/examples/CSD_Strategy/ThreadPool/Foo_i.cpp
new file mode 100644
index 00000000000..66e424d8781
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/Foo_i.cpp
@@ -0,0 +1,112 @@
+// $Id$
+#include "Foo_i.h"
+#include "OrbShutdownTask.h"
+#include "ace/OS.h"
+
+Foo_i::Foo_i(unsigned num_clients)
+ : value_(0),
+ num_clients_(num_clients),
+ count_op1_(0),
+ count_op2_(0),
+ count_op3_(0),
+ count_op4_(0),
+ count_op5_(0)
+{
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) Number of clients for Foo_i servant: %d\n",
+ num_clients));
+}
+
+
+Foo_i::~Foo_i()
+{
+}
+
+
+void
+Foo_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op1_;
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op2_;
+ this->value_ = value;
+}
+
+
+CORBA::Long
+Foo_i::op3(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op3_;
+ return this->value_;
+}
+
+
+void
+Foo_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op4_;
+ this->value_ = value;
+
+ if (this->count_op4_ % 500 == 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) op4() has been called %d times now. value == %d\n",
+ this->count_op4_, this->value_));
+ }
+
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ ++this->count_op5_;
+ ACE_THROW_SPEC (FooException());
+}
+
+
+void
+Foo_i::done(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ unsigned num_left = --this->num_clients_;
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) A client has reported that it is done(). "
+ "There are %d clients left.\n", num_left));
+
+ if (num_left == 0)
+ {
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) Stats:\n"
+ "op1() count: %d\n"
+ "op2() count: %d\n"
+ "op3() count: %d\n"
+ "op4() count: %d\n"
+ "op5() count: %d\n",
+ this->count_op1_,
+ this->count_op2_,
+ this->count_op3_,
+ this->count_op4_,
+ this->count_op5_));
+
+ if (TheOrbShutdownTask::instance()->open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_i::done: failed to create orb "\
+ "shutdown thread.\n"));
+ }
+ }
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/Foo_i.h b/TAO/examples/CSD_Strategy/ThreadPool/Foo_i.h
new file mode 100644
index 00000000000..cf1ee0968e1
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/Foo_i.h
@@ -0,0 +1,49 @@
+// $Id$
+#ifndef FOO_I_H
+#define FOO_I_H
+
+#include "FooS.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+
+class Foo_i : public virtual POA_Foo,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Foo_i(unsigned num_clients);
+ virtual ~Foo_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+
+ private:
+
+ CORBA::Long value_;
+ unsigned num_clients_;
+
+ unsigned count_op1_;
+ unsigned count_op2_;
+ unsigned count_op3_;
+ unsigned count_op4_;
+ unsigned count_op5_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/OrbShutdownTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool/OrbShutdownTask.cpp
new file mode 100644
index 00000000000..f9d551e8aee
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/OrbShutdownTask.cpp
@@ -0,0 +1,77 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbShutdownTask.h"
+#include "ace/CORBA_macros.h"
+#include "ace/OS_NS_unistd.h"
+
+
+OrbShutdownTask::OrbShutdownTask()
+{
+}
+
+
+OrbShutdownTask::~OrbShutdownTask()
+{
+}
+
+
+void
+OrbShutdownTask::orb(CORBA::ORB_ptr orb)
+{
+ this->orb_ = CORBA::ORB::_duplicate (orb);
+}
+
+
+int
+OrbShutdownTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbShutdownTask failed to open().\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::svc()
+{
+ ACE_OS::sleep (2);
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)OrbShutdownTask::svc shutdown orb \n"));
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->shutdown(0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::shutdown() call "
+ "in OrbShutdownTask::svc().\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/OrbShutdownTask.h b/TAO/examples/CSD_Strategy/ThreadPool/OrbShutdownTask.h
new file mode 100644
index 00000000000..3795d12c3c9
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/OrbShutdownTask.h
@@ -0,0 +1,41 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_SHUTDOWN_TASK_H
+#define ORB_SHUTDOWN_TASK_H
+
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+
+class OrbShutdownTask : public ACE_Task_Base
+{
+ public:
+
+ OrbShutdownTask();
+ virtual ~OrbShutdownTask();
+
+ void orb(CORBA::ORB_ptr orb);
+
+ virtual int open(void*);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+};
+
+typedef ACE_Singleton<OrbShutdownTask, ACE_Thread_Mutex> TheOrbShutdownTask;
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/README b/TAO/examples/CSD_Strategy/ThreadPool/README
new file mode 100644
index 00000000000..76a46ba103f
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/README
@@ -0,0 +1,57 @@
+# $Id$
+
+Description:
+
+This is the simplest example shows the use of a Custom Servant Dispatching (CSD)
+Strategy. This test uses the reference implementation, known as the Thread Pool
+CSD Strategy. This tests some simple remote two-way CORBA requests and a simple
+remote one-way request.
+
+The server application creates one servant object, runs the ORB event
+loop using the main thread, and uses one worker thread for the
+Thread Pool CSD Strategy.
+
+The client application invokes simple two-way calls on the object
+reference. There is also a simple one-way call that is also made on
+the object reference.
+
+The run_test.pl script will launch 1 sever process, and 40 client processes.
+Each client process will make invocations on the single object reference
+provided by the (single) server process.
+
+Executables:
+
+ * client_main
+
+ This is the client test executable.
+
+ Command-line arguments:
+
+ -? : Prints the executable's available command-line options, and
+ then exits.
+
+ -i <ior string> : Provide the IOR to the client (ie, file://some.ior).
+
+ * server_main
+
+ This is the server test executable.
+
+ Command-line arguments:
+
+ -? : Prints the executable's available command-line options, and
+ then exits.
+
+ -o <ior filename> : Name of file to which the IOR will be written.
+
+ -n <num_clients> : The number of clients that will use the server.
+
+ * run_test.pl
+
+ This perl script will run an automated test using 40 client processes
+ and 1 server process. The script returns 0 if the test was successful.
+
+ No command-line options are supported. Simply execute the perl script
+ as follows:
+
+ $ ./run_test.pl
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/ServerApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool/ServerApp.cpp
new file mode 100644
index 00000000000..b036b9ff205
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/ServerApp.cpp
@@ -0,0 +1,237 @@
+// $Id$
+#include "ServerApp.h"
+#include "Foo_i.h"
+#include "OrbShutdownTask.h"
+#include "ace/Get_Opt.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+
+ServerApp::ServerApp()
+: num_clients_ (1)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheOrbShutdownTask::instance()->orb (orb.in ());
+
+ CORBA::Object_var obj
+ = orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to resolve initial ref for 'RootPOA'.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POA_var root_poa
+ = PortableServer::POA::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(root_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to POA interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager( ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the child POA.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ PortableServer::POA_var child_poa
+ = root_poa->create_POA("ChildPoa",
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(child_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to create the child POA.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // Create the thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO::CSD::TP_Strategy> csd_tp_strategy =
+ new TAO::CSD::TP_Strategy();
+
+ // Tell the strategy to apply itself to the child poa.
+ if (csd_tp_strategy->apply_to(child_poa.in() ACE_ENV_ARG_PARAMETER) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to apply custom dispatching strategy to child poa.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+ ACE_CHECK_RETURN (-1);
+
+ // Create the servant object.
+ Foo_i* servant = new Foo_i(this->num_clients_);
+
+ // local smart pointer variable to deal with releasing the reference
+ // to the servant object when the smart pointer object falls out of scope.
+ PortableServer::ServantBase_var owner_transfer(servant);
+
+ // Activate the servant using the Child POA.
+ PortableServer::ObjectId_var oid
+ = child_poa->activate_object(servant
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Obtain the object reference.
+ obj = child_poa->servant_to_reference(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (Foo_i).\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // Stringify the object reference
+ CORBA::String_var ior
+ = orb->object_to_string(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Write the stringified object reference to the ior file.
+ FILE* ior_file = ACE_OS::fopen(this->ior_filename_.c_str(), "w");
+
+ if (ior_file == 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Cannot open output file for writing IOR: %s",
+ this->ior_filename_.c_str()));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ ACE_OS::fprintf(ior_file, "%s", ior.in ());
+ ACE_OS::fclose(ior_file);
+
+ // Activate the POA Manager
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is ready. Running the ORB event loop.\n"));
+
+ // Run the ORB event loop.
+ orb->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp ORB has stopped running. "
+ "Stop the CSD strategy.\n"));
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is waiting for OrbShutdownTask.\n"));
+ TheOrbShutdownTask::instance()->wait ();
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the Root POA.\n"));
+
+ // Sleep for 2 second to let the done() two-way call complete
+ // before cleanup.
+ ACE_OS::sleep (2);
+
+ // Tear-down the root poa and orb.
+ root_poa->destroy(1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the ORB.\n"));
+
+ orb->destroy( ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp has completed running successfully.\n"));
+
+ return 0;
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "o:n:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'o':
+ this->ior_filename_ = get_opts.opt_arg();
+ break;
+
+ case 'n':
+ {
+ int tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ this->usage_statement();
+ return -1;
+ }
+
+ this->num_clients_ = tmp;
+ }
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-o <ior_filename>]\n"
+ "\t[-n <num_clients>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/ServerApp.h b/TAO/examples/CSD_Strategy/ThreadPool/ServerApp.h
new file mode 100644
index 00000000000..ad89b43c972
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/ServerApp.h
@@ -0,0 +1,30 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+
+class ServerApp
+{
+ public:
+
+ ServerApp();
+ ~ServerApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString exe_name_;
+ ACE_CString ior_filename_;
+ unsigned num_clients_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/client_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool/client_main.cpp
new file mode 100644
index 00000000000..1f9c337ae54
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/client_main.cpp
@@ -0,0 +1,45 @@
+// $Id$
+#include "ClientApp.h"
+#include "ace/Log_Msg.h"
+#include "ace/SString.h"
+#include "tao/Exception.h"
+
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+
+ ClientApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ClientApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/run_test.pl b/TAO/examples/CSD_Strategy/ThreadPool/run_test.pl
new file mode 100755
index 00000000000..e15decb6a63
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/run_test.pl
@@ -0,0 +1,55 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+$iorfile = PerlACE::LocalFile ("server.ior");
+unlink $iorfile;
+$status = 0;
+
+$num_clients=40;
+
+$SV = new PerlACE::Process ("server_main", "-o $iorfile -n $num_clients");
+
+$SV->Spawn ();
+
+if (PerlACE::waitforfile_timed ($iorfile,
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ @CLS[$i] = new PerlACE::Process ("client_main", " -i file://$iorfile");
+
+ @CLS[$i]->Spawn ();
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ $client = @CLS[$i]->WaitKill (60);
+
+ if ($client != 0) {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill (60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+unlink $iorfile;
+
+exit $status;
diff --git a/TAO/examples/CSD_Strategy/ThreadPool/server_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool/server_main.cpp
new file mode 100644
index 00000000000..8c3c4b192a0
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool/server_main.cpp
@@ -0,0 +1,43 @@
+// $Id$
+#include "ServerApp.h"
+#include "ace/Log_Msg.h"
+#include "tao/Exception.h"
+
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+ ServerApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception in main() for ServerApp");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ServerApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/CSD_Test_ThreadPool2.mpc b/TAO/examples/CSD_Strategy/ThreadPool2/CSD_Test_ThreadPool2.mpc
new file mode 100644
index 00000000000..c14935e056d
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/CSD_Test_ThreadPool2.mpc
@@ -0,0 +1,25 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_threadpool, taoexe, portableserver {
+ exename = server_main
+
+ Source_Files {
+ Foo_i.cpp
+ FooServantList.cpp
+ ServerApp.cpp
+ server_main.cpp
+ OrbShutdownTask.cpp
+ }
+}
+
+project(*Client): taoexe, anytypecode {
+ exename = client_main
+
+ Source_Files {
+ FooC.cpp
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/ClientApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool2/ClientApp.cpp
new file mode 100644
index 00000000000..14e52e52804
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/ClientApp.cpp
@@ -0,0 +1,143 @@
+// $Id$
+#include "ClientApp.h"
+#include "FooC.h"
+#include "ace/Get_Opt.h"
+#include "ace/Log_Msg.h"
+
+
+ClientApp::ClientApp()
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb
+ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ CORBA::Object_var obj
+ = orb->string_to_object(this->ior_.c_str() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to convert IOR string to obj ref.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ Foo_var foo = Foo::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(foo.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to Foo interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ for (CORBA::Long i = 1; i <= 100; i++)
+ {
+ foo->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ foo->op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ CORBA::Long value = foo->op3(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Value retrieved from op3() == %d\n",
+ value));
+
+ for (CORBA::Long j = 1; j <= 5; j++)
+ {
+ foo->op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ foo->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Caught FooException - as expected.\n"));
+
+ }
+ ACE_ENDTRY;
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Tell server that we are done().\n"));
+
+ foo->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Back from done().\n"));
+
+ return 0;
+}
+
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/ClientApp.h b/TAO/examples/CSD_Strategy/ThreadPool2/ClientApp.h
new file mode 100644
index 00000000000..7dc57bb78dc
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/ClientApp.h
@@ -0,0 +1,30 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+
+class ClientApp
+{
+ public:
+
+ ClientApp();
+ ~ClientApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString ior_;
+
+ ACE_CString exe_name_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/Foo.idl b/TAO/examples/CSD_Strategy/ThreadPool2/Foo.idl
new file mode 100644
index 00000000000..f4a756a31b1
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/Foo.idl
@@ -0,0 +1,29 @@
+// $Id$
+#ifndef FOO_IDL
+#define FOO_IDL
+
+exception FooException {};
+exception TestException {};
+
+interface Foo
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, no arguments
+ long op3();
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Client calls this last. It will shutdown the server.
+ void done();
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/FooServantList.cpp b/TAO/examples/CSD_Strategy/ThreadPool2/FooServantList.cpp
new file mode 100644
index 00000000000..1c1fc13eaf6
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/FooServantList.cpp
@@ -0,0 +1,99 @@
+// $Id$
+#include "FooServantList.h"
+#include "Foo_i.h"
+#include "OrbShutdownTask.h"
+#include "ace/OS.h"
+
+
+FooServantList::FooServantList(const char* prefix,
+ unsigned num_servants,
+ unsigned num_clients,
+ CORBA::ORB_ptr orb)
+ : prefix_(prefix),
+ num_servants_(num_servants),
+ num_clients_(num_clients),
+ orb_ (CORBA::ORB::_duplicate(orb))
+{
+ this->servants_ = new PortableServer::ServantBase_var[num_servants];
+}
+
+
+FooServantList::~FooServantList()
+{
+ delete [] this->servants_;
+}
+
+
+void
+FooServantList::create_and_activate(PortableServer::POA_ptr poa
+ ACE_ENV_ARG_DECL)
+{
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ char buf[32];
+ ACE_OS::sprintf(buf, "%02d", i + 1);
+ ACE_CString servant_name = this->prefix_ + "_" + buf;
+
+ this->servants_[i] = new Foo_i(servant_name.c_str(),this);
+
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId(servant_name.c_str());
+
+ poa->activate_object_with_id(id.in(),
+ this->servants_[i].in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CORBA::Object_var obj = poa->id_to_reference(id.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (%s).\n",
+ servant_name.c_str()));
+ ACE_THROW (TestException());
+ }
+
+ CORBA::String_var ior
+ = this->orb_->object_to_string(obj.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_CString filename = servant_name + ".ior";
+ FILE* ior_file = ACE_OS::fopen(filename.c_str(), "w");
+
+ if (ior_file == 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Cannot open output file (%s) for writing IOR.",
+ filename.c_str()));
+ ACE_THROW (TestException());
+ }
+
+ ACE_OS::fprintf(ior_file, "%s", ior.in());
+ ACE_OS::fclose(ior_file);
+ }
+}
+
+
+void
+FooServantList::client_done(ACE_ENV_SINGLE_ARG_DECL)
+{
+ unsigned num_left;
+
+ {
+ GuardType guard(this->num_clients_lock_);
+ num_left = --this->num_clients_;
+ }
+
+ if (num_left == 0)
+ {
+ if (TheOrbShutdownTask::instance()->open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)FooServantList::client_done: "
+ "failed to create orb shutdown thread.\n"));
+ }
+ }
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/FooServantList.h b/TAO/examples/CSD_Strategy/ThreadPool2/FooServantList.h
new file mode 100644
index 00000000000..d6e35ff894a
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/FooServantList.h
@@ -0,0 +1,42 @@
+// $Id$
+#ifndef FOOSERVANTLIST_H
+#define FOOSERVANTLIST_H
+
+#include "tao/ORB.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/Servant_Base.h"
+#include "ace/SString.h"
+
+
+class FooServantList
+{
+ public:
+
+ FooServantList(const char* prefix,
+ unsigned num_servants,
+ unsigned num_clients,
+ CORBA::ORB_ptr orb);
+ ~FooServantList();
+
+ void create_and_activate(PortableServer::POA_ptr poa
+ ACE_ENV_ARG_DECL);
+
+ void client_done(ACE_ENV_SINGLE_ARG_DECL);
+
+
+ private:
+
+ typedef ACE_SYNCH_MUTEX LockType;
+ typedef ACE_Guard<LockType> GuardType;
+
+ PortableServer::ServantBase_var* servants_;
+ ACE_CString prefix_;
+ unsigned num_servants_;
+
+ LockType num_clients_lock_;
+ unsigned num_clients_;
+
+ CORBA::ORB_var orb_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/Foo_i.cpp b/TAO/examples/CSD_Strategy/ThreadPool2/Foo_i.cpp
new file mode 100644
index 00000000000..5923bb5b022
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/Foo_i.cpp
@@ -0,0 +1,86 @@
+// $Id$
+#include "Foo_i.h"
+#include "FooServantList.h"
+#include "ace/OS.h"
+
+Foo_i::Foo_i(const char* servant_name,FooServantList* mgr)
+ : value_(0),
+ count_op1_(0),
+ count_op2_(0),
+ count_op3_(0),
+ count_op4_(0),
+ count_op5_(0),
+ servant_name_(servant_name),
+ mgr_(mgr)
+{
+}
+
+
+Foo_i::~Foo_i()
+{
+}
+
+
+void
+Foo_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op1_;
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op2_;
+ this->value_ = value;
+}
+
+
+CORBA::Long
+Foo_i::op3(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op3_;
+ return this->value_;
+}
+
+
+void
+Foo_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op4_;
+ this->value_ = value;
+
+ if (this->count_op4_ % 100 == 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) op4() has been called %d times now. value == %d\n",
+ this->count_op4_, this->value_));
+ }
+
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ ++this->count_op5_;
+ ACE_THROW_SPEC (FooException());
+}
+
+
+void
+Foo_i::done(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->mgr_->client_done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/Foo_i.h b/TAO/examples/CSD_Strategy/ThreadPool2/Foo_i.h
new file mode 100644
index 00000000000..5cc2a45e467
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/Foo_i.h
@@ -0,0 +1,53 @@
+// $Id$
+#ifndef FOO_I_H
+#define FOO_I_H
+
+#include "FooS.h"
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+class FooServantList;
+
+class Foo_i : public virtual POA_Foo,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Foo_i(const char* servant_name, FooServantList* mgr);
+ virtual ~Foo_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+
+ private:
+
+ CORBA::Long value_;
+
+ unsigned count_op1_;
+ unsigned count_op2_;
+ unsigned count_op3_;
+ unsigned count_op4_;
+ unsigned count_op5_;
+
+ ACE_CString servant_name_;
+ FooServantList* mgr_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.cpp
new file mode 100644
index 00000000000..f9d551e8aee
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.cpp
@@ -0,0 +1,77 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbShutdownTask.h"
+#include "ace/CORBA_macros.h"
+#include "ace/OS_NS_unistd.h"
+
+
+OrbShutdownTask::OrbShutdownTask()
+{
+}
+
+
+OrbShutdownTask::~OrbShutdownTask()
+{
+}
+
+
+void
+OrbShutdownTask::orb(CORBA::ORB_ptr orb)
+{
+ this->orb_ = CORBA::ORB::_duplicate (orb);
+}
+
+
+int
+OrbShutdownTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbShutdownTask failed to open().\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::svc()
+{
+ ACE_OS::sleep (2);
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)OrbShutdownTask::svc shutdown orb \n"));
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->shutdown(0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::shutdown() call "
+ "in OrbShutdownTask::svc().\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.h b/TAO/examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.h
new file mode 100644
index 00000000000..3795d12c3c9
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/OrbShutdownTask.h
@@ -0,0 +1,41 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_SHUTDOWN_TASK_H
+#define ORB_SHUTDOWN_TASK_H
+
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+
+class OrbShutdownTask : public ACE_Task_Base
+{
+ public:
+
+ OrbShutdownTask();
+ virtual ~OrbShutdownTask();
+
+ void orb(CORBA::ORB_ptr orb);
+
+ virtual int open(void*);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+};
+
+typedef ACE_Singleton<OrbShutdownTask, ACE_Thread_Mutex> TheOrbShutdownTask;
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/README b/TAO/examples/CSD_Strategy/ThreadPool2/README
new file mode 100644
index 00000000000..4c770475642
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/README
@@ -0,0 +1,61 @@
+# $Id$
+
+Description:
+
+This is another test showing the use of a Custom Servant Dispatching
+(CSD) Strategy. This test uses the reference implementation, known as the
+Thread Pool CSD Strategy. This tests some simple remote two-way CORBA
+requests and a simple remote one-way request.
+
+The server application creates 10 servant object, runs the ORB event
+loop using the main thread, and uses 10 worker thread for the
+Thread Pool CSD Strategy.
+
+The client application invokes simple two-way calls on the object
+reference. There is also a simple one-way call that is also made on
+the object reference.
+
+The run_test.pl script will launch 1 sever process, and 40 client processes.
+Since the server process contains 10 distinct servants, the clients are
+evenly divided such that each servant "serves" 4 distinct clients.
+
+
+Executables:
+
+ * client_main
+
+ This is the client test executable.
+
+ Command-line arguments:
+
+ -? : Prints the executable's available command-line options, and
+ then exits.
+
+ -i <ior string> : Provide the IOR to the client (ie, file://some.ior).
+
+ * server_main
+
+ This is the server test executable.
+
+ Command-line arguments:
+
+ -? : Prints the executable's available command-line options, and
+ then exits.
+
+ -p <ior filename prefix> : Common prefix used in all ior filenames
+ that are output.
+
+ -s <num servants> : The number of servant objects in the server.
+
+ -c <num clients> : The number of clients that will use the server.
+
+ * run_test.pl
+
+ This perl script will run an automated test using 40 client processes
+ and 1 server process. The script returns 0 if the test was successful.
+
+ No command-line options are supported. Simply execute the perl script
+ as follows:
+
+ $ ./run_test.pl
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/ServerApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool2/ServerApp.cpp
new file mode 100644
index 00000000000..a9986df9ec5
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/ServerApp.cpp
@@ -0,0 +1,229 @@
+// $Id$
+#include "ServerApp.h"
+#include "FooServantList.h"
+#include "FooC.h"
+#include "OrbShutdownTask.h"
+#include "ace/Get_Opt.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+
+ServerApp::ServerApp()
+ : ior_filename_("foo"),
+ num_servants_(1),
+ num_clients_(1)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheOrbShutdownTask::instance()->orb (orb.in ());
+
+ CORBA::Object_var obj
+ = orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to resolve initial ref for 'RootPOA'.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POA_var root_poa
+ = PortableServer::POA::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(root_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to POA interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the child POA.
+ CORBA::PolicyList policies(1);
+ policies.length(1);
+
+ policies[0] = root_poa->create_id_assignment_policy(PortableServer::USER_ID
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ PortableServer::POA_var child_poa
+ = root_poa->create_POA("ChildPoa",
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(child_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to create the child POA.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ policies[0]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO::CSD::TP_Strategy> csd_tp_strategy =
+ new TAO::CSD::TP_Strategy();
+
+ csd_tp_strategy->set_num_threads(this->num_servants_);
+
+ // Tell the strategy to apply itself to the child poa.
+ if (csd_tp_strategy->apply_to(child_poa.in() ACE_ENV_ARG_PARAMETER) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to apply custom dispatching strategy to child poa.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+ ACE_CHECK_RETURN (-1);
+
+ FooServantList servants(this->ior_filename_.c_str(),
+ this->num_servants_,
+ this->num_clients_,
+ orb.in());
+
+ servants.create_and_activate(child_poa.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Activate the POA Manager
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is ready. Running the ORB event loop.\n"));
+
+ // Run the ORB event loop.
+ orb->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp ORB has stopped running. "
+ "Stop the CSD strategy.\n"));
+
+ // Sleep for 2 second to let the done() two-way call complete
+ // before cleanup.
+ ACE_OS::sleep (2);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is waiting for OrbShutdownTask.\n"));
+ TheOrbShutdownTask::instance()->wait ();
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the Root POA.\n"));
+
+ // Tear-down the root poa and orb.
+ root_poa->destroy(1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the ORB.\n"));
+
+ orb->destroy(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp has completed running successfully.\n"));
+
+ return 0;
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "p:s:c:");
+
+ int c;
+ int tmp;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'p':
+ this->ior_filename_ = get_opts.opt_arg();
+ break;
+
+ case 's':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ this->usage_statement();
+ return -1;
+ }
+
+ this->num_servants_ = tmp;
+ break;
+
+ case 'c':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ this->usage_statement();
+ return -1;
+ }
+
+ this->num_clients_ = tmp;
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-p <ior_filename_prefix>]\n"
+ "\t[-s <num_servants>]\n"
+ "\t[-c <num_clients>]\n"
+ "\t[-?]\n",
+ "Default ior_filename_prefix is 'foo'.\n"
+ "Default num_servants is 1.\n"
+ "Default num_clients is 1.\n\n",
+ this->exe_name_.c_str()));
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/ServerApp.h b/TAO/examples/CSD_Strategy/ThreadPool2/ServerApp.h
new file mode 100644
index 00000000000..7556826f1e2
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/ServerApp.h
@@ -0,0 +1,30 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+class ServerApp
+{
+ public:
+
+ ServerApp();
+ ~ServerApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString exe_name_;
+ ACE_CString ior_filename_;
+ unsigned num_servants_;
+ unsigned num_clients_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/client_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool2/client_main.cpp
new file mode 100644
index 00000000000..545d6b52a9a
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/client_main.cpp
@@ -0,0 +1,44 @@
+// $Id$
+#include "ClientApp.h"
+#include "ace/Log_Msg.h"
+#include "ace/SString.h"
+#include "tao/Exception.h"
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+
+ ClientApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ClientApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/run_test.pl b/TAO/examples/CSD_Strategy/ThreadPool2/run_test.pl
new file mode 100755
index 00000000000..60be2077f11
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/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 '../../../../bin';
+use PerlACE::Run_Test;
+
+$status = 0;
+
+$iorfname_prefix = "server";
+$num_servants=10;
+$num_clients_per_servant=4;
+$num_clients=$num_servants * $num_clients_per_servant;
+
+#Delete old ior files.
+for (my $i = 0; $i < $num_servants; $i++) {
+ $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+
+ unlink $iorfile[$i];
+}
+
+$SV = new PerlACE::Process ("server_main", "-p $iorfname_prefix -s $num_servants -c $num_clients");
+
+$SV->Spawn ();
+
+# Wait for the servant ior files created by server.
+for (my $i = 0; $i < $num_servants; $i++) {
+ $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+
+ if (PerlACE::waitforfile_timed ($iorfile[$i],
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile[$i]>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+}
+
+$count = 0;
+
+for (my $i = 0; $i < $num_servants; $i++) {
+ for ($j = 0; $j < $num_clients_per_servant; $j++) {
+ $CLS[$count] = new PerlACE::Process ("client_main", " -i file://$iorfile[$i]");
+ $CLS[$count]->Spawn ();
+ $count ++;
+ }
+}
+
+for (my $i = 0; $i < $num_clients; $i++) {
+ $client = $CLS[$i]->WaitKill (60);
+
+ if ($client != 0) {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+$server = $SV->WaitKill (60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+#Delete ior files generated by this run.
+for (my $i = 0; $i < $num_servants; $i++) {
+ $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+
+ unlink $iorfile[$i];
+}
+
+exit $status;
diff --git a/TAO/examples/CSD_Strategy/ThreadPool2/server_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool2/server_main.cpp
new file mode 100644
index 00000000000..bb14220d3c7
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool2/server_main.cpp
@@ -0,0 +1,44 @@
+// $Id$
+#include "ServerApp.h"
+#include "ace/Log_Msg.h"
+#include "tao/Exception.h"
+#include "tao/Environment.h"
+
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+ ServerApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ServerApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/CSD_Test_ThreadPool3.mpc b/TAO/examples/CSD_Strategy/ThreadPool3/CSD_Test_ThreadPool3.mpc
new file mode 100644
index 00000000000..04902011dd3
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/CSD_Test_ThreadPool3.mpc
@@ -0,0 +1,25 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_threadpool, taoexe, portableserver {
+ exename = server_main
+
+ Source_Files {
+ Foo_i.cpp
+ OrbTask.cpp
+ ServerApp.cpp
+ server_main.cpp
+ OrbShutdownTask.cpp
+ }
+}
+
+project(*Client): taoexe, anytypecode {
+ exename = client_main
+
+ Source_Files {
+ FooC.cpp
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/ClientApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool3/ClientApp.cpp
new file mode 100644
index 00000000000..b55bdff6842
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/ClientApp.cpp
@@ -0,0 +1,142 @@
+// $Id$
+#include "ClientApp.h"
+#include "FooC.h"
+#include "ace/Get_Opt.h"
+#include "ace/Log_Msg.h"
+
+
+ClientApp::ClientApp()
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb
+ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ CORBA::Object_var obj
+ = orb->string_to_object(this->ior_.c_str() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to convert IOR string to obj ref.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ Foo_var foo = Foo::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(foo.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to Foo interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ for (CORBA::Long i = 1; i <= 100; i++)
+ {
+ foo->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ foo->op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ CORBA::Long value = foo->op3(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Value retrieved from op3() == %d\n",
+ value));
+
+ for (CORBA::Long j = 1; j <= 5; j++)
+ {
+ foo->op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ foo->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Caught FooException - as expected.\n"));
+
+ }
+ ACE_ENDTRY;
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Tell server that we are done().\n"));
+
+ foo->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Back from done().\n"));
+
+ return 0;
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/ClientApp.h b/TAO/examples/CSD_Strategy/ThreadPool3/ClientApp.h
new file mode 100644
index 00000000000..7dc57bb78dc
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/ClientApp.h
@@ -0,0 +1,30 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+
+class ClientApp
+{
+ public:
+
+ ClientApp();
+ ~ClientApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString ior_;
+
+ ACE_CString exe_name_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/Foo.idl b/TAO/examples/CSD_Strategy/ThreadPool3/Foo.idl
new file mode 100644
index 00000000000..f4a756a31b1
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/Foo.idl
@@ -0,0 +1,29 @@
+// $Id$
+#ifndef FOO_IDL
+#define FOO_IDL
+
+exception FooException {};
+exception TestException {};
+
+interface Foo
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, no arguments
+ long op3();
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Client calls this last. It will shutdown the server.
+ void done();
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/Foo_i.cpp b/TAO/examples/CSD_Strategy/ThreadPool3/Foo_i.cpp
new file mode 100644
index 00000000000..39a83de2507
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/Foo_i.cpp
@@ -0,0 +1,72 @@
+// $Id$
+#include "Foo_i.h"
+#include "OrbShutdownTask.h"
+
+
+Foo_i::Foo_i(unsigned num_clients)
+ : value_(0),
+ num_clients_(num_clients)
+{
+}
+
+
+Foo_i::~Foo_i()
+{
+}
+
+
+void
+Foo_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+}
+
+
+void
+Foo_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->value_ = value;
+}
+
+
+CORBA::Long
+Foo_i::op3(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ return this->value_;
+}
+
+
+
+void
+Foo_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->value_ = value;
+}
+
+
+void
+Foo_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ ACE_THROW (FooException());
+}
+
+
+void
+Foo_i::done(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ unsigned num_left = --this->num_clients_;
+
+ if (num_left == 0)
+ {
+ if (TheOrbShutdownTask::instance()->open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_i::done: "
+ "failed to create orb shutdown thread.\n"));
+ }
+ }
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/Foo_i.h b/TAO/examples/CSD_Strategy/ThreadPool3/Foo_i.h
new file mode 100644
index 00000000000..0d897194358
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/Foo_i.h
@@ -0,0 +1,40 @@
+// $Id$
+#ifndef FOO_I_H
+#define FOO_I_H
+
+#include "FooS.h"
+
+
+class Foo_i : public virtual POA_Foo,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Foo_i(unsigned num_clients);
+ virtual ~Foo_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ private:
+
+ CORBA::Long value_;
+ unsigned num_clients_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.cpp
new file mode 100644
index 00000000000..f9d551e8aee
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.cpp
@@ -0,0 +1,77 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbShutdownTask.h"
+#include "ace/CORBA_macros.h"
+#include "ace/OS_NS_unistd.h"
+
+
+OrbShutdownTask::OrbShutdownTask()
+{
+}
+
+
+OrbShutdownTask::~OrbShutdownTask()
+{
+}
+
+
+void
+OrbShutdownTask::orb(CORBA::ORB_ptr orb)
+{
+ this->orb_ = CORBA::ORB::_duplicate (orb);
+}
+
+
+int
+OrbShutdownTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbShutdownTask failed to open().\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::svc()
+{
+ ACE_OS::sleep (2);
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)OrbShutdownTask::svc shutdown orb \n"));
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->shutdown(0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::shutdown() call "
+ "in OrbShutdownTask::svc().\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.h b/TAO/examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.h
new file mode 100644
index 00000000000..3795d12c3c9
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/OrbShutdownTask.h
@@ -0,0 +1,41 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_SHUTDOWN_TASK_H
+#define ORB_SHUTDOWN_TASK_H
+
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+
+class OrbShutdownTask : public ACE_Task_Base
+{
+ public:
+
+ OrbShutdownTask();
+ virtual ~OrbShutdownTask();
+
+ void orb(CORBA::ORB_ptr orb);
+
+ virtual int open(void*);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+};
+
+typedef ACE_Singleton<OrbShutdownTask, ACE_Thread_Mutex> TheOrbShutdownTask;
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/OrbTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool3/OrbTask.cpp
new file mode 100644
index 00000000000..390bbe8a317
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/OrbTask.cpp
@@ -0,0 +1,98 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbTask.h"
+
+namespace { enum { MAX_ORB_TASK_WORKER_THREADS = 20 }; }
+
+
+OrbTask::OrbTask(CORBA::ORB_ptr orb, unsigned num_threads)
+ : orb_ (CORBA::ORB::_duplicate(orb)),
+ num_threads_(num_threads)
+{
+}
+
+
+OrbTask::~OrbTask()
+{
+}
+
+
+int
+OrbTask::open(void*)
+{
+ if (this->num_threads_ < 1)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "num_threads_ (%d) is less-than 1.\n",
+ this->num_threads_),
+ -1);
+ }
+
+ if (this->num_threads_ > MAX_ORB_TASK_WORKER_THREADS)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "num_threads_ (%d) is too large. Max is %d.\n",
+ this->num_threads_, MAX_ORB_TASK_WORKER_THREADS),
+ -1);
+ }
+
+ if (CORBA::is_nil(this->orb_.in()))
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "ORB object reference is nil.\n"),
+ -1);
+ }
+
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, this->num_threads_) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to activate "
+ "(%d) worker threads.\n",
+ this->num_threads_),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbTask::svc()
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::run() method. "
+ "OrbTask is stopping.\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/OrbTask.h b/TAO/examples/CSD_Strategy/ThreadPool3/OrbTask.h
new file mode 100644
index 00000000000..dde50d15f66
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/OrbTask.h
@@ -0,0 +1,37 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_TASK_H
+#define ORB_TASK_H
+
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+class OrbTask : public ACE_Task_Base
+{
+ public:
+
+ OrbTask(CORBA::ORB_ptr orb, unsigned num_threads = 1);
+ virtual ~OrbTask();
+
+ virtual int open(void* x = 0);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+ unsigned num_threads_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/README b/TAO/examples/CSD_Strategy/ThreadPool3/README
new file mode 100644
index 00000000000..ebad7aba505
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/README
@@ -0,0 +1,58 @@
+# $Id$
+
+Description:
+
+This is another test showing the use of a Custom Servant Dispatching
+(CSD) Strategy. This test uses the reference implementation, known as the
+Thread Pool CSD Strategy. This tests some simple remote two-way CORBA
+requests and a simple remote one-way request.
+
+The server application creates 1 servant object, runs the ORB event
+loop using 4 threads (one being the main thread), and uses 10 worker
+threads for the Thread Pool CSD Strategy.
+
+The client application invokes simple two-way calls on the object
+reference. There is also a simple one-way call that is also made on
+the object reference.
+
+The run_test.pl script will launch 1 sever process, and 40 client processes.
+
+
+Executables:
+
+ * client_main
+
+ This is the client test executable.
+
+ Command-line arguments:
+
+ -? : Prints the executable's available command-line options, and
+ then exits.
+
+ -i <ior string> : Provide the IOR to the client (ie, file://some.ior).
+
+ * server_main
+
+ This is the server test executable.
+
+ Command-line arguments:
+
+ -? : Prints the executable's available command-line options, and
+ then exits.
+
+ -o <ior filename> : Name of file to which IOR will be written.
+
+ -n <num clients> : The number of clients that will use the server.
+
+ -t <num ORB threads> : Number of threads running the ORB event loop.
+
+ * run_test.pl
+
+ This perl script will run an automated test using 40 client processes
+ and 1 server process. The script returns 0 if the test was successful.
+
+ No command-line options are supported. Simply execute the perl script
+ as follows:
+
+ $ ./run_test.pl
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/ServerApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool3/ServerApp.cpp
new file mode 100644
index 00000000000..0625e2baf67
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/ServerApp.cpp
@@ -0,0 +1,269 @@
+// $Id$
+#include "ServerApp.h"
+#include "Foo_i.h"
+#include "OrbTask.h"
+#include "OrbShutdownTask.h"
+#include "ace/Get_Opt.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+
+ServerApp::ServerApp()
+ : ior_filename_("ServerApp.default.ior"),
+ num_clients_(1),
+ num_orb_threads_(1)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheOrbShutdownTask::instance()->orb (orb.in ());
+
+ CORBA::Object_var obj
+ = orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to resolve initial ref for 'RootPOA'.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POA_var root_poa
+ = PortableServer::POA::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(root_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to POA interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the child POA.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ PortableServer::POA_var child_poa
+ = root_poa->create_POA("ChildPoa",
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(child_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to create the child POA.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // Create the thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO::CSD::TP_Strategy> csd_tp_strategy =
+ new TAO::CSD::TP_Strategy();
+
+ // Tell the strategy to apply itself to the child poa.
+ if (csd_tp_strategy->apply_to(child_poa.in() ACE_ENV_ARG_PARAMETER) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to apply custom dispatching strategy to child poa.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+ ACE_CHECK_RETURN (-1);
+
+ // Create the servant object.
+ Foo_i* servant = new Foo_i(this->num_clients_);
+
+ // local smart pointer variable to deal with releasing the reference
+ // to the servant object when the smart pointer object falls out of scope.
+ PortableServer::ServantBase_var owner_transfer(servant);
+
+ // Activate the servant using the Child POA.
+ PortableServer::ObjectId_var oid
+ = child_poa->activate_object(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Obtain the object reference.
+ obj = child_poa->servant_to_reference(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (Foo_i).\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // Stringify the object reference
+ CORBA::String_var ior
+ = orb->object_to_string(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Write the stringified object reference to the ior file.
+ FILE* ior_file = ACE_OS::fopen(this->ior_filename_.c_str(), "w");
+
+ if (ior_file == 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Cannot open output file for writing IOR: %s",
+ this->ior_filename_.c_str()));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ ACE_OS::fprintf(ior_file, "%s", ior.in ());
+ ACE_OS::fclose(ior_file);
+
+ // Activate the POA Manager
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is ready.\n"));
+
+ // If the num_orb_threads_ is exactly one, then just use the current
+ // (mainline) thread to run the ORB event loop.
+ if (this->num_orb_threads_ == 1)
+ {
+ // Since the num_orb_threads_ is exactly one, we just use the current
+ // (mainline) thread to run the ORB event loop.
+ orb->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ }
+ else
+ {
+ // The num_orb_threads_ is greater than 1, so we will use an OrbTask
+ // (active object) to run the ORB event loop in (num_orb_threads_ - 1)
+ // threads. We use the current (mainline) thread as the other thread
+ // running the ORB event loop.
+ OrbTask orb_task(orb.in(), this->num_orb_threads_ - 1);
+
+ // Activate the OrbTask worker threads
+ if (orb_task.open() != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to open the OrbTask.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // This will use the current (mainline) thread to run the ORB event loop.
+ orb->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Now that the current thread has unblocked from running the orb,
+ // make sure to wait for all of the worker threads to complete.
+ orb_task.wait();
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is waiting for OrbShutdownTask.\n"));
+ TheOrbShutdownTask::instance()->wait ();
+
+ // Sleep for 2 second to let the done() two-way call complete
+ // before cleanup.
+ ACE_OS::sleep (2);
+
+ // Tear-down the root poa and orb.
+ root_poa->destroy(1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ orb->destroy(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ return 0;
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "o:n:t:");
+
+ int c;
+ int tmp;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'o':
+ this->ior_filename_ = get_opts.opt_arg();
+ break;
+
+ case 'n':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ this->usage_statement();
+ return -1;
+ }
+
+ this->num_clients_ = tmp;
+ break;
+
+ case 't':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ this->usage_statement();
+ return -1;
+ }
+
+ this->num_orb_threads_ = tmp;
+ break;
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-o <ior_filename>]\n"
+ "\t[-n <num_clients>]\n"
+ "\t[-t <num_orb_threads>]\n"
+ "\t[-?]\n",
+ "Default ior_filename_prefix is 'foo'.\n"
+ "Default num_servants is 1.\n"
+ "Default num_clients is 1.\n\n",
+ this->exe_name_.c_str()));
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/ServerApp.h b/TAO/examples/CSD_Strategy/ThreadPool3/ServerApp.h
new file mode 100644
index 00000000000..9ffd10f0507
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/ServerApp.h
@@ -0,0 +1,31 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+
+class ServerApp
+{
+ public:
+
+ ServerApp();
+ ~ServerApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString exe_name_;
+ ACE_CString ior_filename_;
+ unsigned num_clients_;
+ unsigned num_orb_threads_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/client_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool3/client_main.cpp
new file mode 100644
index 00000000000..f1b0c4cb08a
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/client_main.cpp
@@ -0,0 +1,44 @@
+// $Id$
+#include "ClientApp.h"
+#include "ace/Log_Msg.h"
+#include "tao/Exception.h"
+
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+
+ ClientApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ClientApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/run_test.pl b/TAO/examples/CSD_Strategy/ThreadPool3/run_test.pl
new file mode 100755
index 00000000000..b0c25a6456b
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/run_test.pl
@@ -0,0 +1,56 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+$iorfile = PerlACE::LocalFile ("server.ior");
+unlink $iorfile;
+$status = 0;
+
+$num_clients=40;
+$num_orb_threads=4;
+
+$SV = new PerlACE::Process ("server_main", "-o $iorfile -n $num_clients -t $num_orb_threads");
+
+$SV->Spawn ();
+
+if (PerlACE::waitforfile_timed ($iorfile,
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ @CLS[$i] = new PerlACE::Process ("client_main", " -i file://$iorfile");
+
+ @CLS[$i]->Spawn ();
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ $client = @CLS[$i]->WaitKill (60);
+
+ if ($client != 0) {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill (60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+unlink $iorfile;
+
+exit $status;
diff --git a/TAO/examples/CSD_Strategy/ThreadPool3/server_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool3/server_main.cpp
new file mode 100644
index 00000000000..cad2b8e119d
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool3/server_main.cpp
@@ -0,0 +1,42 @@
+// $Id$
+#include "ServerApp.h"
+#include "ace/Log_Msg.h"
+#include "tao/Exception.h"
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+ ServerApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ServerApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/CSD_Test_ThreadPool4.mpc b/TAO/examples/CSD_Strategy/ThreadPool4/CSD_Test_ThreadPool4.mpc
new file mode 100644
index 00000000000..386d4964863
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/CSD_Test_ThreadPool4.mpc
@@ -0,0 +1,15 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_threadpool, messaging, taoexe, portableserver {
+ exename = server_main
+
+ Source_Files {
+ Foo_i.cpp
+ Callback_i.cpp
+ ServerApp.cpp
+ server_main.cpp
+ ClientTask.cpp
+ OrbShutdownTask.cpp
+ }
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/Callback.idl b/TAO/examples/CSD_Strategy/ThreadPool4/Callback.idl
new file mode 100644
index 00000000000..49be42260cb
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/Callback.idl
@@ -0,0 +1,11 @@
+// $Id$
+#ifndef CALLBACK_IDL
+#define CALLBACK_IDL
+
+interface Callback
+{
+ void test_method();
+};
+
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/Callback_i.cpp b/TAO/examples/CSD_Strategy/ThreadPool4/Callback_i.cpp
new file mode 100644
index 00000000000..c243461dcaa
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/Callback_i.cpp
@@ -0,0 +1,26 @@
+// $Id$
+#include "Callback_i.h"
+
+
+Callback_i::Callback_i()
+{
+}
+
+
+Callback_i::~Callback_i ()
+{
+}
+
+
+void
+Callback_i::test_method (
+ ACE_ENV_SINGLE_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, "(%P|%t)Callback_i::test_method called \n"));
+
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/Callback_i.h b/TAO/examples/CSD_Strategy/ThreadPool4/Callback_i.h
new file mode 100644
index 00000000000..c66fe818f94
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/Callback_i.h
@@ -0,0 +1,27 @@
+// $Id$
+#ifndef CALLBACK_I_H
+#define CALLBACK_I_H
+
+#include "CallbackS.h"
+
+
+class Callback_i : public virtual POA_Callback,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Callback_i();
+
+ virtual ~Callback_i();
+
+ virtual void test_method (
+ ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+};
+
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/ClientTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool4/ClientTask.cpp
new file mode 100644
index 00000000000..93aadcf0e78
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/ClientTask.cpp
@@ -0,0 +1,213 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ClientTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "ClientTask.h"
+#include "ace/SString.h"
+#include "ace/OS.h"
+
+
+ClientTask::ClientTask(Foo_ptr foo,
+ Callback_ptr callback)
+: foo_(Foo::_duplicate(foo)),
+ callback_(Callback::_duplicate(callback))
+{
+}
+
+
+ClientTask::~ClientTask()
+{
+}
+
+
+int
+ClientTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) ClientTask failed to activate "
+ "the client thread.\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+ClientTask::svc()
+{
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::svc start\n"));
+
+ ACE_TRY_NEW_ENV
+ {
+ for (CORBA::Long i = 1; i <= 100; i++)
+ {
+ // Simple Two-way calls.
+ this->foo_->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->foo_->op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ CORBA::Long value = this->foo_->op3(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Value retrieved from op3() == %d\n",
+ value));
+
+ for (CORBA::Long j = 1; j <= 5; j++)
+ {
+ this->foo_->op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ ACE_TRY_EX (op5)
+ {
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) ===> Invoke op5()\n"));
+ this->foo_->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK_EX (op5);
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) ===> No exception raised from op5(). :-(\n"));
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Caught FooException - as expected.\n"));
+
+ }
+ ACE_ENDTRY;
+
+ // Two-Way calls with inout parameters.
+ CORBA::String_var message = CORBA::string_dup( "Hello! " );
+ CORBA::Boolean result
+ = this->foo_->op6( "TAO User", message.inout() ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (result)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Message from op6() == %s\n",
+ message.in ()));
+ }
+ else
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> op6() returned false.\n"));
+ }
+
+ // Callback test.
+ this->foo_->callback_object (this->callback_.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->foo_->test_callback (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // One-Way calls with various arguments.
+ CORBA::String_var ub_string = CORBA::string_dup( "UNBOUNDED STRING" );
+ this->foo_->test_unbounded_string_arg (ub_string.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::String_var bd_string = CORBA::string_dup( "BOUNDED STRING" );
+ this->foo_->test_bounded_string_arg (bd_string.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Fixed_Array fixed_array;
+
+ for (CORBA::ULong m = 0; m < 20; m ++)
+ {
+ fixed_array[m] = i + m;
+ }
+
+ this->foo_->test_fixed_array_arg (fixed_array ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Var_Array var_array;
+ var_array[0] = CORBA::string_dup( "STRING 1" );
+ var_array[1] = CORBA::string_dup( "STRING 2" );
+ var_array[2] = CORBA::string_dup( "STRING 3" );
+ this->foo_->test_var_array_arg (var_array ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Bounded_Var_Size_var bd_var_size_string = new Bounded_Var_Size();
+ const char* buffer1 = "BOUNDED VAR SIZE CHAR";
+ bd_var_size_string->replace (bd_var_size_string->maximum (),
+ ACE_OS::strlen (buffer1) + 1,
+ (CORBA::Char*)buffer1);
+ this->foo_->test_bounded_var_size_arg (bd_var_size_string.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ const char* buffer2 = "UNBOUNDED VAR SIZE CHAR";
+ Unbounded_Var_Size_var ub_var_size_string = new Unbounded_Var_Size(100);
+ ub_var_size_string->replace (ub_var_size_string->maximum (),
+ ACE_OS::strlen (buffer2) + 1,
+ (CORBA::Char*)buffer2);
+ this->foo_->test_unbounded_var_size_arg (ub_var_size_string.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ TimeOfDay t;
+ t.hour = 12;
+ t.minute = 30;
+ t.second = 10;
+ this->foo_->test_fixed_size_arg (t ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->foo_->test_fixed_size_arg_two_way (t ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::Boolean special_value = 1;
+ this->foo_->test_special_basic_arg (special_value ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->foo_->test_objref_arg (this->callback_.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::svc - Invoke foo->done()\n"));
+
+ this->foo_->done (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::svc - Back from foo->done()\n"));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception in ClientTask::svc():");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in ClientTask::svc()\n"));
+ }
+ ACE_ENDTRY;
+
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::svc end\n"));
+
+ return 0;
+}
+
+
+int
+ClientTask::close(u_long)
+{
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::close() - enter/exit\n"));
+ return 0;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/ClientTask.h b/TAO/examples/CSD_Strategy/ThreadPool4/ClientTask.h
new file mode 100644
index 00000000000..2f0aa572f8a
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/ClientTask.h
@@ -0,0 +1,38 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ClientTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef CLIENT_TASK_H
+#define CLIENT_TASK_H
+
+#include "FooC.h"
+#include "CallbackC.h"
+#include "ace/Task.h"
+
+class ClientTask : public ACE_Task_Base
+{
+ public:
+
+ ClientTask(Foo_ptr foo,
+ Callback_ptr callback);
+
+ virtual ~ClientTask();
+
+ virtual int open(void* x = 0);
+ virtual int svc();
+ virtual int close(u_long);
+
+ private:
+ Foo_var foo_;
+ Callback_var callback_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/Foo.idl b/TAO/examples/CSD_Strategy/ThreadPool4/Foo.idl
new file mode 100644
index 00000000000..715dd264d41
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/Foo.idl
@@ -0,0 +1,73 @@
+// $Id$
+#ifndef FOO_IDL
+#define FOO_IDL
+
+#include "Callback.idl"
+
+exception FooException {};
+exception TestException {};
+
+typedef sequence<char, 32> Bounded_Var_Size;
+typedef sequence<char> Unbounded_Var_Size;
+typedef long Fixed_Array[20];
+typedef string Var_Array [3];
+
+struct TimeOfDay {
+ short hour; // 0 - 23
+ short minute; // 0 - 59
+ short second; // 0 - 59
+};
+interface Foo
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, no arguments
+ long op3();
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Operation with the inout parameter.
+ boolean op6(in string user_name,
+ inout string message);
+
+ oneway void test_unbounded_string_arg(in string message);
+
+ oneway void test_bounded_string_arg(in string<20> message);
+
+ oneway void test_fixed_array_arg(in Fixed_Array message);
+
+ oneway void test_var_array_arg(in Var_Array messages);
+
+ oneway void test_bounded_var_size_arg(in Bounded_Var_Size message);
+
+ oneway void test_unbounded_var_size_arg(in Unbounded_Var_Size message);
+
+ oneway void test_fixed_size_arg (in TimeOfDay t);
+
+ oneway void test_special_basic_arg(in boolean value);
+
+ oneway void test_objref_arg (in Callback cb);
+
+ void test_fixed_size_arg_two_way (in TimeOfDay t);
+
+ /// Operation with the object reference parameter.
+ void callback_object (in Callback cb);
+
+ /// Operation that invoke remote operation on
+ // callback object.
+ void test_callback ();
+
+ /// Client calls this last. It will shutdown the server.
+ void done();
+};
+
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/Foo_i.cpp b/TAO/examples/CSD_Strategy/ThreadPool4/Foo_i.cpp
new file mode 100644
index 00000000000..e94e00c0226
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/Foo_i.cpp
@@ -0,0 +1,301 @@
+// $Id$
+#include "Foo_i.h"
+#include "OrbShutdownTask.h"
+#include "ace/OS.h"
+
+Foo_i::Foo_i(const char* servant_name)
+: value_(0),
+ count_op1_(0),
+ count_op2_(0),
+ count_op3_(0),
+ count_op4_(0),
+ count_op5_(0),
+ servant_name_(servant_name)
+{
+}
+
+
+Foo_i::~Foo_i()
+{
+}
+
+
+void
+Foo_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op1_;
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op2_;
+ this->value_ = value;
+}
+
+
+CORBA::Long
+Foo_i::op3(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op3_;
+ return this->value_;
+}
+
+
+void
+Foo_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op4_;
+ this->value_ = value;
+
+ if (this->count_op4_ % 1 == 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) op4() has been called %d times now. value == %d\n",
+ this->count_op4_, this->value_));
+ }
+
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) Foo_i::op5() - ENTER\n"));
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) Foo_i::op5() - Increment counter.\n"));
+ unsigned newcount = ++this->count_op5_;
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) Foo_i::op5() - Counter is now %d.\n", newcount));
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) Foo_i::op5() - EXIT - Raise a FooException.\n"));
+ ACE_THROW_SPEC (FooException());
+}
+
+
+CORBA::Boolean
+Foo_i::op6 (
+ const char * user_name,
+ char *& message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_CString str(message);
+ str += user_name;
+ message = CORBA::string_dup (str.c_str ());
+ return 1;
+}
+
+
+void
+Foo_i::test_unbounded_string_arg (
+ const char * message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_unbounded_string_arg ")
+ ACE_TEXT("got unbounded string %s\n"),
+ message));
+}
+
+
+void
+Foo_i::test_bounded_string_arg (
+ const char * message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_bounded_string_arg ")
+ ACE_TEXT("got bounded string %s\n"),
+ message));
+}
+
+
+void
+Foo_i::test_fixed_array_arg (
+ const ::Fixed_Array message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ for (CORBA::ULong i = 0; i < 20; i++)
+ {
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_fixed_array_arg ")
+ ACE_TEXT("got fixed_array[i] = %d\n"),
+ i, message[i]));
+ }
+}
+
+
+void
+Foo_i::test_bounded_var_size_arg (
+ const ::Bounded_Var_Size & message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_bounded_var_size_arg ")
+ ACE_TEXT("got var array chars %s\n"),
+ message.get_buffer ()));
+}
+
+
+void
+Foo_i::test_unbounded_var_size_arg (
+ const ::Unbounded_Var_Size & message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_unbounded_var_size_arg ")
+ ACE_TEXT("got var array chars %s\n"),
+ message.get_buffer ()));
+}
+
+
+void
+Foo_i::test_fixed_size_arg (
+ const ::TimeOfDay & t
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_fixed_size_arg ")
+ ACE_TEXT("got timeofday %d:%d:%d\n"),
+ t.hour, t.minute, t.second));
+}
+
+void
+Foo_i::test_fixed_size_arg_two_way (
+ const ::TimeOfDay & t
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_fixed_size_arg_two_way ")
+ ACE_TEXT("got timeofday %d:%d:%d\n"),
+ t.hour, t.minute, t.second));
+}
+
+void
+Foo_i::test_var_array_arg (
+ const ::Var_Array messages
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_var_array_arg ")
+ ACE_TEXT(" %s \n"), messages[0].in ()));
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_var_array_arg ")
+ ACE_TEXT(" %s \n"), messages[1].in ()));
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_var_array_arg ")
+ ACE_TEXT(" %s \n"), messages[2].in ()));
+}
+
+
+void
+Foo_i::test_special_basic_arg (
+ ::CORBA::Boolean value
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_special_basic_arg ")
+ ACE_TEXT(" got special basic arg: %d \n"), value));
+}
+
+
+void
+Foo_i::test_objref_arg (
+ ::Callback_ptr cb
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ this->callback_ = Callback::_duplicate (cb);
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_objref_arg ")
+ ACE_TEXT(" got callback object. \n")));
+}
+
+
+void
+Foo_i::callback_object (
+ ::Callback_ptr cb
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ this->callback_ = Callback::_duplicate (cb);
+}
+
+void
+Foo_i::test_callback (
+ ACE_ENV_SINGLE_ARG_DECL
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ if (CORBA::is_nil (this->callback_.in ()))
+ {
+ ACE_THROW_SPEC (TestException ());
+ }
+ else
+ {
+ this->callback_->test_method (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+
+void
+Foo_i::done(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ static ACE_Atomic_Op <ACE_SYNCH_MUTEX, unsigned> num_clients = 2;
+
+ num_clients --;
+
+ if (num_clients == 0)
+ {
+ if (TheOrbShutdownTask::instance()->open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_i::done: "
+ "failed to create orb shutdown thread.\n"));
+ }
+ }
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/Foo_i.h b/TAO/examples/CSD_Strategy/ThreadPool4/Foo_i.h
new file mode 100644
index 00000000000..82c115ecbe6
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/Foo_i.h
@@ -0,0 +1,158 @@
+// $Id$
+#ifndef FOO_I_H
+#define FOO_I_H
+
+#include "FooS.h"
+#include "CallbackC.h"
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+class FooServantList;
+
+class Foo_i : public virtual POA_Foo,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Foo_i(const char* servant_name);
+ virtual ~Foo_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException));
+
+ virtual CORBA::Boolean op6 (
+ const char * user_name,
+ char *& message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_unbounded_string_arg (
+ const char * message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_bounded_string_arg (
+ const char * message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_fixed_array_arg (
+ const ::Fixed_Array message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_var_array_arg (
+ const ::Var_Array messages
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_bounded_var_size_arg (
+ const ::Bounded_Var_Size & message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_unbounded_var_size_arg (
+ const ::Unbounded_Var_Size & message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_fixed_size_arg (
+ const ::TimeOfDay & t
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_fixed_size_arg_two_way (
+ const ::TimeOfDay & t
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_special_basic_arg (
+ ::CORBA::Boolean value
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_objref_arg (
+ ::Callback_ptr cb
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void callback_object (
+ ::Callback_ptr cb
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_callback (
+ ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+
+ private:
+
+ CORBA::Long value_;
+
+ unsigned count_op1_;
+ unsigned count_op2_;
+ unsigned count_op3_;
+ unsigned count_op4_;
+ unsigned count_op5_;
+
+ ACE_CString servant_name_;
+ Callback_var callback_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.cpp
new file mode 100644
index 00000000000..f9d551e8aee
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.cpp
@@ -0,0 +1,77 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbShutdownTask.h"
+#include "ace/CORBA_macros.h"
+#include "ace/OS_NS_unistd.h"
+
+
+OrbShutdownTask::OrbShutdownTask()
+{
+}
+
+
+OrbShutdownTask::~OrbShutdownTask()
+{
+}
+
+
+void
+OrbShutdownTask::orb(CORBA::ORB_ptr orb)
+{
+ this->orb_ = CORBA::ORB::_duplicate (orb);
+}
+
+
+int
+OrbShutdownTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbShutdownTask failed to open().\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::svc()
+{
+ ACE_OS::sleep (2);
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)OrbShutdownTask::svc shutdown orb \n"));
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->shutdown(0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::shutdown() call "
+ "in OrbShutdownTask::svc().\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.h b/TAO/examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.h
new file mode 100644
index 00000000000..3795d12c3c9
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/OrbShutdownTask.h
@@ -0,0 +1,41 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_SHUTDOWN_TASK_H
+#define ORB_SHUTDOWN_TASK_H
+
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+
+class OrbShutdownTask : public ACE_Task_Base
+{
+ public:
+
+ OrbShutdownTask();
+ virtual ~OrbShutdownTask();
+
+ void orb(CORBA::ORB_ptr orb);
+
+ virtual int open(void*);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+};
+
+typedef ACE_Singleton<OrbShutdownTask, ACE_Thread_Mutex> TheOrbShutdownTask;
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/README b/TAO/examples/CSD_Strategy/ThreadPool4/README
new file mode 100644
index 00000000000..923174c8d78
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/README
@@ -0,0 +1,23 @@
+# $Id$
+
+Description:
+
+This is another test showing the use of a Custom Servant Dispatching
+(CSD) Strategy. This test uses the reference implementation, known as the
+Thread Pool CSD Strategy. This tests collocated requests.
+
+The server application creates two servants, each with a different child
+POA. One of the POAs has a CSD Strategy applied to it, and the other does
+not. Also created are two collocated callback servants to test the
+passing of object references as arguments in collocated requests.
+
+The server activates a new thread for each of the two collocated "clients".
+
+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/examples/CSD_Strategy/ThreadPool4/ServerApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool4/ServerApp.cpp
new file mode 100644
index 00000000000..9db3f5c7785
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/ServerApp.cpp
@@ -0,0 +1,357 @@
+// $Id$
+#include "ServerApp.h"
+#include "Foo_i.h"
+#include "Callback_i.h"
+#include "ClientTask.h"
+#include "OrbShutdownTask.h"
+#include "ace/Get_Opt.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+#include "tao/Messaging/Messaging.h"
+#include "tao/AnyTypeCode/Any.h"
+
+
+ServerApp::ServerApp()
+: synch_with_server_ (0)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheOrbShutdownTask::instance()->orb (this->orb_.in ());
+
+ if (synch_with_server_)
+ {
+ CORBA::Object_var manager_object =
+ orb_->resolve_initial_references("ORBPolicyManager"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ CORBA::PolicyManager_var policy_manager
+ = CORBA::PolicyManager::_narrow(manager_object.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil (policy_manager.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ " (%P|%t) Panic: nil PolicyManager\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ CORBA::Any policy_value;
+ policy_value <<= Messaging::SYNC_WITH_SERVER;
+ CORBA::PolicyList policies(1);
+ policies.length(1);
+
+ policies[0] =
+ orb_->create_policy (Messaging::SYNC_SCOPE_POLICY_TYPE,
+ policy_value
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ policy_manager->set_policy_overrides (policies,
+ CORBA::ADD_OVERRIDE
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ policies[0]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ }
+
+ CORBA::Object_var obj
+ = orb_->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to resolve initial ref for 'RootPOA'.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POA_var root_poa
+ = PortableServer::POA::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(root_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to POA interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the child POA.
+ CORBA::PolicyList policies(1);
+ policies.length(1);
+
+ policies[0] = root_poa->create_id_assignment_policy(PortableServer::USER_ID
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ PortableServer::POA_var child_poa_1 = root_poa->create_POA("ChildPoa_1",
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(child_poa_1.in()))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to create the ChildPoa_1.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POA_var child_poa_2 = root_poa->create_POA("ChildPoa_2",
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(child_poa_2.in()))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to create the ChildPoa_2.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ policies[0]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO::CSD::TP_Strategy> csd_tp_strategy =
+ new TAO::CSD::TP_Strategy();
+
+ // We need create multiple working threads otherwise it would deadlock
+ // with the callback test.
+ csd_tp_strategy->set_num_threads(2);
+
+ // Tell the strategy to apply itself to the child poa.
+ if (csd_tp_strategy->apply_to(child_poa_1.in() ACE_ENV_ARG_PARAMETER) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to apply custom dispatching strategy to child poa 1.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+ ACE_CHECK_RETURN (-1);
+
+ Foo_var foo1 = this->create_foo(child_poa_1.in(),
+ "foo_applied_strategy"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ Foo_var foo2 = this->create_foo(child_poa_2.in(),
+ "foo_not_applied_strategy"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ Callback_var callback1
+ = this->create_callback(child_poa_1.in(),
+ "callback_applied_strategy"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ Callback_var callback2
+ = this->create_callback(child_poa_2.in(),
+ "callback_not_applied_strategy"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Activate the POA Manager
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is ready. Running the ORB event loop.\n"));
+
+ // Wait for the custom stretegy launch the dispatching threads.
+ ACE_OS::sleep (2);
+
+ ClientTask client1 (foo1.in (), callback1.in ());
+ if (client1.open() != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to open the collocated client1.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ ClientTask client2 (foo2.in (), callback2.in ());
+ if (client2.open() != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to open the collocated client2.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // Run the ORB event loop.
+ orb_->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp ORB has stopped running.\n"));
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) Wait for the OrbShutdownTask.\n"));
+
+ TheOrbShutdownTask::instance()->wait ();
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) Wait for the collocated client task.\n"));
+
+ client1.wait ();
+ client2.wait ();
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) Stop the CSD strategy.\n"));
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the Root POA.\n"));
+
+ // Tear-down the root poa and orb_.
+ root_poa->destroy(1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the ORB.\n"));
+
+ orb_->destroy(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp has completed running successfully.\n"));
+
+ return 0;
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "s");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 's':
+ this->synch_with_server_ = 1;
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+Foo_ptr
+ServerApp::create_foo (
+ PortableServer::POA_ptr poa,
+ const char* servant_name
+ ACE_ENV_ARG_DECL)
+{
+ PortableServer::ServantBase_var servant
+ = new Foo_i(servant_name);
+
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId(servant_name);
+
+ poa->activate_object_with_id(id.in(), servant.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (Foo::_nil ());
+
+ CORBA::Object_var obj = poa->id_to_reference(id.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (Foo::_nil ());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (%s).\n",
+ servant_name));
+ ACE_THROW_RETURN (TestException(), Foo::_nil ());
+ }
+
+ Foo_var foo = Foo::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (Foo::_nil ());
+
+ return foo._retn ();
+}
+
+Callback_ptr
+ServerApp::create_callback(
+ PortableServer::POA_ptr poa,
+ const char* servant_name
+ ACE_ENV_ARG_DECL)
+{
+ PortableServer::ServantBase_var servant
+ = new Callback_i();
+
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId("callback");
+
+ poa->activate_object_with_id(id.in(), servant.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (Callback::_nil ());
+
+ CORBA::Object_var obj = poa->id_to_reference(id.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (Callback::_nil ());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (%s).\n",
+ servant_name));
+ ACE_THROW_RETURN (TestException(), Callback::_nil ());
+ }
+
+ Callback_var callback = Callback::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (Callback::_nil ());
+
+ return callback._retn ();
+}
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-s <synch_with_server>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/ServerApp.h b/TAO/examples/CSD_Strategy/ThreadPool4/ServerApp.h
new file mode 100644
index 00000000000..0c10f8341d0
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/ServerApp.h
@@ -0,0 +1,44 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "FooC.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "ace/SString.h"
+
+class ServerApp
+{
+ public:
+
+ ServerApp();
+ ~ServerApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ Foo_ptr
+ create_foo(
+ PortableServer::POA_ptr poa,
+ const char* servant_name
+ ACE_ENV_ARG_DECL);
+
+ Callback_ptr
+ create_callback(
+ PortableServer::POA_ptr poa,
+ const char* servant_name
+ ACE_ENV_ARG_DECL);
+
+
+ ACE_CString exe_name_;
+
+ CORBA::ORB_var orb_;
+
+ int synch_with_server_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/run_test.pl b/TAO/examples/CSD_Strategy/ThreadPool4/run_test.pl
new file mode 100755
index 00000000000..1a39bd75ae2
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/run_test.pl
@@ -0,0 +1,39 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+$status = 0;
+
+$synch_with_server_option = "";
+
+if ($ARGV[0] eq 'synch_with_server') {
+ $synch_with_server_option = "-s";
+}
+elsif ($ARGV[0] eq '') {
+ #synch with transport
+}
+else {
+ print STDERR "ERROR: invalid parameter $ARGV[0] \n";
+ exit 1;
+}
+
+$SV = new PerlACE::Process ("server_main", "$synch_with_server_option");
+
+$SV->Spawn ();
+
+
+$server = $SV->WaitKill (60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+
+exit $status;
diff --git a/TAO/examples/CSD_Strategy/ThreadPool4/server_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool4/server_main.cpp
new file mode 100644
index 00000000000..d0884b4aeb4
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool4/server_main.cpp
@@ -0,0 +1,43 @@
+// $Id$
+#include "ServerApp.h"
+#include "ace/Log_Msg.h"
+#include "tao/Exception.h"
+
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+ ServerApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ServerApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/CSD_Test_ThreadPool5.mpc b/TAO/examples/CSD_Strategy/ThreadPool5/CSD_Test_ThreadPool5.mpc
new file mode 100644
index 00000000000..a5c323adc01
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/CSD_Test_ThreadPool5.mpc
@@ -0,0 +1,36 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_threadpool, taoexe, portableserver {
+ exename = server_main
+
+ Source_Files {
+ server_main.cpp
+ Foo_i.cpp
+ FooC.cpp
+ FooS.cpp
+ Callback_i.cpp
+ CallbackC.cpp
+ CallbackS.cpp
+ ServerApp.cpp
+ ClientTask.cpp
+ FooServantList.cpp
+ OrbTask.cpp
+ OrbShutdownTask.cpp
+ }
+}
+
+project(*Client): csd_threadpool, taoexe, portableserver {
+ exename = client_main
+
+ Source_Files {
+ client_main.cpp
+ Callback_i.cpp
+ CallbackC.cpp
+ CallbackS.cpp
+ FooC.cpp
+ ClientTask.cpp
+ ClientApp.cpp
+ }
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/Callback.idl b/TAO/examples/CSD_Strategy/ThreadPool5/Callback.idl
new file mode 100644
index 00000000000..49be42260cb
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/Callback.idl
@@ -0,0 +1,11 @@
+// $Id$
+#ifndef CALLBACK_IDL
+#define CALLBACK_IDL
+
+interface Callback
+{
+ void test_method();
+};
+
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/Callback_i.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/Callback_i.cpp
new file mode 100644
index 00000000000..c243461dcaa
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/Callback_i.cpp
@@ -0,0 +1,26 @@
+// $Id$
+#include "Callback_i.h"
+
+
+Callback_i::Callback_i()
+{
+}
+
+
+Callback_i::~Callback_i ()
+{
+}
+
+
+void
+Callback_i::test_method (
+ ACE_ENV_SINGLE_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, "(%P|%t)Callback_i::test_method called \n"));
+
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/Callback_i.h b/TAO/examples/CSD_Strategy/ThreadPool5/Callback_i.h
new file mode 100644
index 00000000000..0837c30df81
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/Callback_i.h
@@ -0,0 +1,26 @@
+// $Id$
+#ifndef CALLBACK_I_H
+#define CALLBACK_I_H
+
+#include "CallbackS.h"
+
+
+class Callback_i : public virtual POA_Callback,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Callback_i();
+
+ virtual ~Callback_i();
+
+ virtual void test_method (
+ ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+};
+
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/ClientApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/ClientApp.cpp
new file mode 100644
index 00000000000..02db9e8a2f2
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/ClientApp.cpp
@@ -0,0 +1,226 @@
+// $Id$
+#include "ClientApp.h"
+#include "Callback_i.h"
+#include "ClientTask.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+#include "ace/Get_Opt.h"
+#include "ace/Log_Msg.h"
+
+
+ClientApp::ClientApp()
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb
+ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ CORBA::Object_var obj
+ = orb->string_to_object(this->ior_.c_str() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to convert IOR string to obj ref.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ Foo_var foo = Foo::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(foo.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to Foo interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // Create the callback object using the child poa with the custom
+ // strategy.
+ obj = orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to resolve initial ref for 'RootPOA'.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POA_var root_poa
+ = PortableServer::POA::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(root_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to POA interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the child POA.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ PortableServer::POA_var child_poa
+ = root_poa->create_POA("ChildPoa",
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(child_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to create the child POA.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // Create the thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO::CSD::TP_Strategy> csd_tp_strategy =
+ new TAO::CSD::TP_Strategy();
+
+ csd_tp_strategy->set_num_threads(1);
+
+ // Tell the strategy to apply itself to the child poa.
+ if (csd_tp_strategy->apply_to(child_poa.in() ACE_ENV_ARG_PARAMETER) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to apply custom dispatching strategy to child poa.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+ ACE_CHECK_RETURN (-1);
+
+ // Create the servant object.
+ Callback_i* servant = new Callback_i ();
+
+ // local smart pointer variable to deal with releasing the reference
+ // to the servant object when the smart pointer object falls out of scope.
+ PortableServer::ServantBase_var owner_transfer(servant);
+
+ // Activate the servant using the Child POA.
+ PortableServer::ObjectId_var oid
+ = child_poa->activate_object(servant
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Obtain the object reference.
+ obj = child_poa->servant_to_reference(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (Callback_i).\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ Callback_var callback = Callback::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ClientTask client_task(orb.in (), foo.in (), callback.in ());
+
+ if (client_task.open () != 0)
+ {
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // Activate the POA Manager
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientApp is ready.\n"));
+
+ orb->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ client_task.wait ();
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientApp is destroying the Root POA.\n"));
+
+ // Tear-down the root poa and orb.
+ root_poa->destroy(1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientApp is destroying the ORB.\n"));
+
+ orb->destroy(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientApp has completed running successfully.\n"));
+
+ return 0;
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/ClientApp.h b/TAO/examples/CSD_Strategy/ThreadPool5/ClientApp.h
new file mode 100644
index 00000000000..4bb06ef0cac
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/ClientApp.h
@@ -0,0 +1,31 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+class ClientTask;
+
+class ClientApp
+{
+ public:
+
+ ClientApp();
+ ~ClientApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString ior_;
+
+ ACE_CString exe_name_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/ClientTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/ClientTask.cpp
new file mode 100644
index 00000000000..db9ed7c43f1
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/ClientTask.cpp
@@ -0,0 +1,263 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ClientTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "ClientTask.h"
+#include "ace/SString.h"
+#include "ace/OS.h"
+
+
+ClientTask::ClientTask(CORBA::ORB_ptr orb,
+ Foo_ptr foo,
+ Callback_ptr callback,
+ bool collocated)
+: orb_ (CORBA::ORB::_duplicate (orb)),
+ foo_(Foo::_duplicate(foo)),
+ callback_(Callback::_duplicate(callback)),
+ collocated_ (collocated)
+{
+}
+
+
+ClientTask::~ClientTask()
+{
+}
+
+
+int
+ClientTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) ClientTask failed to activate "
+ "the client thread.\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+ClientTask::svc()
+{
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::svc start\n"));
+
+ ACE_TRY_NEW_ENV
+ {
+ // Make sure the connection is established before making
+ // remote invocations.
+ if (this->validate_connection () == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)ClientTask::svc " \
+ "client connect failed.\n"));
+ return -1;
+ }
+
+ for (CORBA::Long i = 1; i <= 100; i++)
+ {
+ // Simple Two-way calls.
+ this->foo_->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->foo_->op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::Long value = this->foo_->op3(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Value retrieved from op3() == %d\n",
+ value));
+
+ for (CORBA::ULong j = 1; j <= 5; j++)
+ {
+ this->foo_->op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ ACE_TRY_EX (op5)
+ {
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) ===> Invoke op5()\n"));
+ this->foo_->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK_EX (op5);
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) ===> No exception raised from op5(). :-(\n"));
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Caught FooException - as expected.\n"));
+
+ }
+ ACE_ENDTRY;
+
+ // Two-Way calls with inout parameters.
+ CORBA::String_var message = CORBA::string_dup( "Hello! " );
+ CORBA::Boolean result
+ = this->foo_->op6( "TAO User", message.inout() ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (result)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Message from op6() == %s\n",
+ message.in ()));
+ }
+ else
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> op6() returned false.\n"));
+ }
+
+ // Callback test.
+ this->foo_->callback_object (this->callback_.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->foo_->test_callback (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // One-Way calls with various arguments.
+ CORBA::String_var ub_string = CORBA::string_dup( "UNBOUNDED STRING" );
+ this->foo_->test_unbounded_string_arg (ub_string.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::String_var bd_string = CORBA::string_dup( "BOUNDED STRING" );
+ this->foo_->test_bounded_string_arg (bd_string.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Fixed_Array fixed_array;
+
+ for (CORBA::ULong m = 0; m < 20; m ++)
+ {
+ fixed_array[m] = i + m;
+ }
+
+ this->foo_->test_fixed_array_arg (fixed_array ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Var_Array var_array;
+ var_array[0] = CORBA::string_dup( "STRING 1" );
+ var_array[1] = CORBA::string_dup( "STRING 2" );
+ var_array[2] = CORBA::string_dup( "STRING 3" );
+ this->foo_->test_var_array_arg (var_array ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Bounded_Var_Size_var bd_var_size_string = new Bounded_Var_Size();
+ const char* buffer1 = "BOUNDED VAR SIZE CHAR";
+ bd_var_size_string->replace (bd_var_size_string->maximum (),
+ ACE_OS::strlen (buffer1) + 1,
+ (CORBA::Char*)buffer1);
+ this->foo_->test_bounded_var_size_arg (bd_var_size_string.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ const char* buffer2 = "UNBOUNDED VAR SIZE CHAR";
+ Unbounded_Var_Size_var ub_var_size_string = new Unbounded_Var_Size(100);
+ ub_var_size_string->replace (ub_var_size_string->maximum (),
+ ACE_OS::strlen (buffer2) + 1,
+ (CORBA::Char*)buffer2);
+ this->foo_->test_unbounded_var_size_arg (ub_var_size_string.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ TimeOfDay t;
+ t.hour = 12;
+ t.minute = 30;
+ t.second = 10;
+ this->foo_->test_fixed_size_arg (t ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->foo_->test_fixed_size_arg_two_way (t ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::Boolean special_value = 1;
+ this->foo_->test_special_basic_arg (special_value ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->foo_->test_objref_arg (this->callback_.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::svc - Invoke foo->done()\n"));
+
+ this->foo_->done (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::svc - Back from foo->done()\n"));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception in ClientTask::svc:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in ClientTask::svc()\n"));
+ }
+ ACE_ENDTRY;
+
+ if (! collocated_)
+ {
+ ACE_OS::sleep (2);
+ this->orb_->shutdown(0);
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::svc end\n"));
+
+ return 0;
+}
+
+
+int
+ClientTask::close(u_long)
+{
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ClientTask::close() - enter/exit\n"));
+ return 0;
+}
+
+
+bool
+ClientTask::validate_connection ()
+{
+ for (CORBA::ULong j = 0; j != 1000; ++j)
+ {
+ ACE_TRY_NEW_ENV
+ {
+#if (TAO_HAS_CORBA_MESSAGING == 1)
+ CORBA::PolicyList_var unused;
+ this->foo_->_validate_connection (unused
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#else
+ this->foo_->_is_a ("Not_An_IDL_Type"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#endif /* TAO_HAS_MESSAGING == 1 */
+ return true;
+ }
+ ACE_CATCHANY
+ {
+ }
+ ACE_ENDTRY;
+ }
+
+ return false;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/ClientTask.h b/TAO/examples/CSD_Strategy/ThreadPool5/ClientTask.h
new file mode 100644
index 00000000000..aec109d9ed6
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/ClientTask.h
@@ -0,0 +1,44 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ClientTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef CLIENT_TASK_H
+#define CLIENT_TASK_H
+
+#include "FooC.h"
+#include "CallbackC.h"
+#include "ace/Task.h"
+
+class ClientTask : public ACE_Task_Base
+{
+ public:
+
+ ClientTask(CORBA::ORB_ptr orb,
+ Foo_ptr foo,
+ Callback_ptr callback,
+ bool collocated = false);
+
+ virtual ~ClientTask();
+
+ virtual int open(void* x = 0);
+ virtual int svc();
+ virtual int close(u_long);
+
+ private:
+ bool validate_connection ();
+
+ CORBA::ORB_var orb_;
+ Foo_var foo_;
+ Callback_var callback_;
+ bool collocated_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/Foo.idl b/TAO/examples/CSD_Strategy/ThreadPool5/Foo.idl
new file mode 100644
index 00000000000..ad4f1cc77cb
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/Foo.idl
@@ -0,0 +1,73 @@
+// $Id$
+#ifndef FOO_IDL
+#define FOO_IDL
+
+#include "Callback.idl"
+
+exception FooException {};
+exception TestException {};
+
+typedef sequence<char, 32> Bounded_Var_Size;
+typedef sequence<char> Unbounded_Var_Size;
+typedef long Fixed_Array[20];
+typedef string Var_Array [3];
+
+struct TimeOfDay {
+ short hour; // 0 - 23
+ short minute; // 0 - 59
+ short second; // 0 - 59
+};
+interface Foo
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, no arguments
+ long op3();
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Operation with the inout parameter.
+ boolean op6(in string user_name,
+ inout string message);
+
+ oneway void test_unbounded_string_arg(in string message);
+
+ oneway void test_bounded_string_arg(in string<20> message);
+
+ oneway void test_fixed_array_arg(in Fixed_Array message);
+
+ oneway void test_var_array_arg(in Var_Array messages);
+
+ oneway void test_bounded_var_size_arg(in Bounded_Var_Size message);
+
+ oneway void test_unbounded_var_size_arg(in Unbounded_Var_Size message);
+
+ oneway void test_fixed_size_arg (in TimeOfDay t);
+
+ oneway void test_special_basic_arg(in boolean value);
+
+ oneway void test_objref_arg (in Callback cb);
+
+ void test_fixed_size_arg_two_way (in TimeOfDay t);
+
+ /// Operation with the object reference parameter.
+ void callback_object (in Callback cb);
+
+ /// Operation that invoke remote operation on
+ // callback object.
+ void test_callback ();
+
+ /// Client calls this last. It will shutdown the server.
+ void done();
+};
+
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp
new file mode 100644
index 00000000000..4f2bddc3ab8
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp
@@ -0,0 +1,226 @@
+// $Id$
+#include "FooServantList.h"
+#include "Foo_i.h"
+#include "Callback_i.h"
+#include "ClientTask.h"
+#include "OrbShutdownTask.h"
+#include "ace/OS.h"
+
+
+FooServantList::FooServantList(const char* prefix,
+ unsigned num_servants,
+ unsigned num_clients,
+ int collocated_test,
+ int servant_to_deactivate,
+ CORBA::ORB_ptr orb)
+ : prefix_(prefix),
+ num_servants_(num_servants),
+ num_clients_(num_clients),
+ init_num_clients_ (num_clients_),
+ collocated_test_(collocated_test),
+ servant_to_deactivate_ (servant_to_deactivate),
+ collocated_client_ (0),
+ orb_ (CORBA::ORB::_duplicate(orb))
+{
+ this->servants_ = new Foo_i* [num_servants];
+ this->safe_servants_ = new PortableServer::ServantBase_var[num_servants];
+}
+
+
+FooServantList::~FooServantList()
+{
+ delete [] this->safe_servants_;
+ delete [] this->servants_;
+ delete collocated_client_;
+}
+
+
+void
+FooServantList::create_and_activate(CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa
+ ACE_ENV_ARG_DECL)
+{
+ poa_ = PortableServer::POA::_duplicate (poa);
+
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ char buf[32];
+ ACE_OS::sprintf(buf, "%02d", i + 1);
+ ACE_CString servant_name = this->prefix_ + "_" + buf;
+
+ this->servants_[i] = new Foo_i(servant_name.c_str(),this);
+ this->safe_servants_[i] = this->servants_[i];
+
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId(servant_name.c_str());
+
+ poa->activate_object_with_id(id.in(),
+ this->safe_servants_[i].in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CORBA::Object_var obj = poa->id_to_reference(id.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (%s).\n",
+ servant_name.c_str()));
+ ACE_THROW (TestException());
+ }
+
+ // create the collocated object reference.
+ if (this->collocated_test_ && i == 0)
+ {
+ Foo_var collocated = Foo::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Create the servant object.
+ Callback_i* servant = new Callback_i ();
+
+ // local smart pointer variable to deal with releasing the reference
+ // to the servant object when the smart pointer object falls out of scope.
+ PortableServer::ServantBase_var safe_servant(servant);
+
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId("callback");
+
+ poa->activate_object_with_id(id.in(), safe_servant.in());
+
+ CORBA::Object_var obj = poa->id_to_reference(id.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (%s).\n",
+ servant_name.c_str()));
+ ACE_THROW (TestException());
+ }
+
+ Callback_var callback
+ = Callback::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ collocated_client_
+ = new ClientTask(orb, collocated.in (), callback.in (), true);
+ if (collocated_client_->open() != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to open the collocated client.\n"));
+ ACE_THROW (TestException());
+ }
+ }
+
+ CORBA::String_var ior
+ = this->orb_->object_to_string(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_CString filename = servant_name + ".ior";
+ FILE* ior_file = ACE_OS::fopen(filename.c_str(), "w");
+
+ if (ior_file == 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Cannot open output file (%s) for writing IOR.",
+ filename.c_str()));
+ ACE_THROW (TestException());
+ }
+ else
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) writing IOR to file %s\n",
+ filename.c_str()));
+ }
+ ACE_OS::fprintf(ior_file, "%s", ior.in());
+ ACE_OS::fclose(ior_file);
+ }
+}
+
+
+void
+FooServantList::client_done(ACE_ENV_SINGLE_ARG_DECL)
+{
+ unsigned num_left;
+
+ {
+ GuardType guard(this->num_clients_lock_);
+ num_left = --this->num_clients_;
+ }
+
+ if (num_left == 0)
+ {
+ if (TheOrbShutdownTask::instance()->open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)FooServantList::client_done: "
+ "failed to create orb shutdown thread.\n"));
+ }
+ }
+}
+
+
+ClientTask*
+FooServantList::collocated_client () const
+{
+ return collocated_client_;
+}
+
+
+void
+FooServantList::deactivate_servant (ACE_ENV_SINGLE_ARG_DECL)
+{
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ // To eliminate compiler warning about comparison of signed vs unsigned.
+ int signed_i = i;
+
+ if ((servant_to_deactivate_ == 0 ) ||
+ ((servant_to_deactivate_ > 0) &&
+ (signed_i == servant_to_deactivate_ - 1)))
+ {
+ if (servants_[i]->active())
+ {
+ servants_[i]->active(false);
+ ACE_DEBUG((LM_DEBUG, "(%P|%t)FooServantList::deactivate_servant "
+ "deactivate %dth servant \n", i+1));
+
+ PortableServer::ObjectId_var id =
+ poa_->servant_to_id (safe_servants_[i].in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ poa_->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->num_servants_ == 1)
+ {
+ // If there is only one servant and we deactivate it then
+ // all clients will catch exception and we need a way to
+ // shutdown the orb.
+ // Wait for 5 seconds so we can see the requests queued
+ // will be cancelled by deactivate servant.
+ ACE_OS::sleep (5);
+ ACE_DEBUG((LM_DEBUG, "(%P|%t)shutdown ORB\n"));
+ if (TheOrbShutdownTask::instance()->open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)FooServantList::deactivate_servant: "
+ "failed to create orb shutdown thread.\n"));
+ }
+ }
+ else
+ {
+ GuardType guard(this->num_clients_lock_);
+ // The clients that requests this deactivated servant
+ // will catch exception due to the deactivated servant.
+ // We need descrease the num_clients so the alived
+ // servant can be called to shutdown the orb.
+ this->num_clients_ -= this->init_num_clients_/num_servants_;
+ }
+ }
+ }
+ }
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.h b/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.h
new file mode 100644
index 00000000000..fb40809e62e
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.h
@@ -0,0 +1,63 @@
+// $Id$
+#ifndef FOOSERVANTLIST_H
+#define FOOSERVANTLIST_H
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/Servant_Base.h"
+#include "ace/SString.h"
+
+
+class ClientTask;
+class Foo_i;
+
+class FooServantList
+{
+ public:
+
+ FooServantList(const char* prefix,
+ unsigned num_servants,
+ unsigned num_clients,
+ int collocated_test,
+ int servant_to_deactivate,
+ CORBA::ORB_ptr orb);
+ ~FooServantList();
+
+ void create_and_activate(CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa
+ ACE_ENV_ARG_DECL);
+
+ void client_done(ACE_ENV_SINGLE_ARG_DECL);
+
+ ClientTask* collocated_client () const;
+
+ void deactivate_servant (ACE_ENV_SINGLE_ARG_DECL);
+
+ private:
+
+ typedef ACE_SYNCH_MUTEX LockType;
+ typedef ACE_Guard<LockType> GuardType;
+
+ Foo_i** servants_;
+ PortableServer::ServantBase_var* safe_servants_;
+ ACE_CString prefix_;
+ unsigned num_servants_;
+
+ LockType num_clients_lock_;
+ unsigned num_clients_;
+ unsigned init_num_clients_;
+ int collocated_test_;
+ // The servant_to_be_deactivate_ should be an integer greater than -2.
+ // -1 => defatult value, DONT deactivate servant.
+ // 0 => deactivate all servants.
+ // > 0 => the index of the servant to be deactivated.
+ int servant_to_deactivate_;
+
+ ClientTask* collocated_client_;
+
+ /// The poa to activate and deactivate servant.
+ PortableServer::POA_var poa_;
+
+ CORBA::ORB_var orb_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/Foo_i.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/Foo_i.cpp
new file mode 100644
index 00000000000..073c0d85283
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/Foo_i.cpp
@@ -0,0 +1,312 @@
+// $Id$
+#include "Foo_i.h"
+#include "FooServantList.h"
+#include "ace/OS.h"
+
+Foo_i::Foo_i(const char* servant_name,FooServantList* mgr)
+ : value_(0),
+ count_op1_(0),
+ count_op2_(0),
+ count_op3_(0),
+ count_op4_(0),
+ count_op5_(0),
+ servant_name_(servant_name),
+ mgr_(mgr),
+ active_ (true)
+{
+}
+
+
+Foo_i::~Foo_i()
+{
+}
+
+
+void
+Foo_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op1_;
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op2_;
+ this->value_ = value;
+}
+
+
+CORBA::Long
+Foo_i::op3(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op3_;
+
+ if (this->count_op3_ == 30)
+ {
+ this->mgr_->deactivate_servant (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+ }
+
+ return this->value_.value ();
+}
+
+
+void
+Foo_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op4_;
+ this->value_ = value;
+
+ if (this->count_op4_.value () % 1 == 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) op4() has been called %d times now. value == %d\n",
+ this->count_op4_.value (), this->value_.value ()));
+ }
+
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ ++this->count_op5_;
+ ACE_THROW (FooException());
+}
+
+
+CORBA::Boolean
+Foo_i::op6 (
+ const char * user_name,
+ char *& message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_CString str(message);
+ str += user_name;
+ message = CORBA::string_dup (str.c_str ());
+ return 1;
+}
+
+
+void
+Foo_i::test_unbounded_string_arg (
+ const char * message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_unbounded_string_arg ")
+ ACE_TEXT("got unbounded string %s\n"),
+ message));
+}
+
+
+void
+Foo_i::test_bounded_string_arg (
+ const char * message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_bounded_string_arg ")
+ ACE_TEXT("got bounded string %s\n"),
+ message));
+}
+
+
+void
+Foo_i::test_fixed_array_arg (
+ const ::Fixed_Array message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ for (CORBA::ULong i = 0; i < 20; i++)
+ {
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_fixed_array_arg ")
+ ACE_TEXT("got fixed_array[i] = %d\n"),
+ i, message[i]));
+ }
+}
+
+
+void
+Foo_i::test_bounded_var_size_arg (
+ const ::Bounded_Var_Size & message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_bounded_var_size_arg ")
+ ACE_TEXT("got var array chars %s\n"),
+ message.get_buffer ()));
+}
+
+
+void
+Foo_i::test_unbounded_var_size_arg (
+ const ::Unbounded_Var_Size & message
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_unbounded_var_size_arg ")
+ ACE_TEXT("got var array chars %s\n"),
+ message.get_buffer ()));
+}
+
+
+void
+Foo_i::test_fixed_size_arg (
+ const ::TimeOfDay & t
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_fixed_size_arg ")
+ ACE_TEXT("got timeofday %d:%d:%d\n"),
+ t.hour, t.minute, t.second));
+}
+
+void
+Foo_i::test_fixed_size_arg_two_way (
+ const ::TimeOfDay & t
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_fixed_size_arg_two_way ")
+ ACE_TEXT("got timeofday %d:%d:%d\n"),
+ t.hour, t.minute, t.second));
+}
+
+void
+Foo_i::test_var_array_arg (
+ const ::Var_Array messages
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_var_array_arg ")
+ ACE_TEXT(" %s \n"), messages[0].in ()));
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_var_array_arg ")
+ ACE_TEXT(" %s \n"), messages[1].in ()));
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_var_array_arg ")
+ ACE_TEXT(" %s \n"), messages[2].in ()));
+}
+
+
+void
+Foo_i::test_special_basic_arg (
+ ::CORBA::Boolean value
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_special_basic_arg ")
+ ACE_TEXT(" got special basic arg: %d \n"), value));
+}
+
+
+void
+Foo_i::test_objref_arg (
+ ::Callback_ptr cb
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ this->callback_ = Callback::_duplicate (cb);
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_i::test_objref_arg ")
+ ACE_TEXT(" got callback object. \n")));
+}
+
+
+void
+Foo_i::callback_object (
+ ::Callback_ptr cb
+ ACE_ENV_ARG_DECL_NOT_USED
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ this->callback_ = Callback::_duplicate (cb);
+}
+
+void
+Foo_i::test_callback (
+ ACE_ENV_SINGLE_ARG_DECL
+)
+ACE_THROW_SPEC ((
+ CORBA::SystemException
+))
+{
+ if (CORBA::is_nil (this->callback_.in ()))
+ {
+ ACE_THROW_SPEC (TestException ());
+ }
+ else
+ {
+ this->callback_->test_method (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+
+void
+Foo_i::done(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->mgr_->client_done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+Foo_i::active (bool flag)
+{
+ active_ = flag;
+}
+
+
+bool
+Foo_i::active ()
+{
+ return active_.value ();
+}
+
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/Foo_i.h b/TAO/examples/CSD_Strategy/ThreadPool5/Foo_i.h
new file mode 100644
index 00000000000..f28d9aeeacc
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/Foo_i.h
@@ -0,0 +1,166 @@
+// $Id$
+#ifndef FOO_I_H
+#define FOO_I_H
+
+#include "FooS.h"
+#include "CallbackC.h"
+#include "ace/SString.h"
+
+class FooServantList;
+
+
+class Foo_i : public virtual POA_Foo,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Foo_i(const char* servant_name, FooServantList* mgr);
+ virtual ~Foo_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException));
+
+ virtual CORBA::Boolean op6 (
+ const char * user_name,
+ char *& message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_unbounded_string_arg (
+ const char * message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_bounded_string_arg (
+ const char * message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_fixed_array_arg (
+ const ::Fixed_Array message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_var_array_arg (
+ const ::Var_Array messages
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_bounded_var_size_arg (
+ const ::Bounded_Var_Size & message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_unbounded_var_size_arg (
+ const ::Unbounded_Var_Size & message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_fixed_size_arg (
+ const ::TimeOfDay & t
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_fixed_size_arg_two_way (
+ const ::TimeOfDay & t
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_special_basic_arg (
+ ::CORBA::Boolean value
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_objref_arg (
+ ::Callback_ptr cb
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void callback_object (
+ ::Callback_ptr cb
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void test_callback (
+ ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ void active (bool flag);
+
+ bool active ();
+
+ private:
+
+ typedef ACE_Atomic_Op <ACE_SYNCH_MUTEX, CORBA::Long> AtomicLong;
+ typedef ACE_Atomic_Op <ACE_SYNCH_MUTEX, unsigned> AtomicUnsigned;
+ typedef ACE_Atomic_Op <ACE_SYNCH_MUTEX, bool> AtomicBool;
+
+ AtomicLong value_;
+ AtomicUnsigned count_op1_;
+ AtomicUnsigned count_op2_;
+ AtomicUnsigned count_op3_;
+ AtomicUnsigned count_op4_;
+ AtomicUnsigned count_op5_;
+
+ ACE_CString servant_name_;
+ FooServantList* mgr_;
+ AtomicBool active_;
+ Callback_var callback_;
+};
+
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.cpp
new file mode 100644
index 00000000000..f9d551e8aee
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.cpp
@@ -0,0 +1,77 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbShutdownTask.h"
+#include "ace/CORBA_macros.h"
+#include "ace/OS_NS_unistd.h"
+
+
+OrbShutdownTask::OrbShutdownTask()
+{
+}
+
+
+OrbShutdownTask::~OrbShutdownTask()
+{
+}
+
+
+void
+OrbShutdownTask::orb(CORBA::ORB_ptr orb)
+{
+ this->orb_ = CORBA::ORB::_duplicate (orb);
+}
+
+
+int
+OrbShutdownTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbShutdownTask failed to open().\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::svc()
+{
+ ACE_OS::sleep (2);
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)OrbShutdownTask::svc shutdown orb \n"));
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->shutdown(0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::shutdown() call "
+ "in OrbShutdownTask::svc().\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.h b/TAO/examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.h
new file mode 100644
index 00000000000..3795d12c3c9
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/OrbShutdownTask.h
@@ -0,0 +1,41 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_SHUTDOWN_TASK_H
+#define ORB_SHUTDOWN_TASK_H
+
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+
+class OrbShutdownTask : public ACE_Task_Base
+{
+ public:
+
+ OrbShutdownTask();
+ virtual ~OrbShutdownTask();
+
+ void orb(CORBA::ORB_ptr orb);
+
+ virtual int open(void*);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+};
+
+typedef ACE_Singleton<OrbShutdownTask, ACE_Thread_Mutex> TheOrbShutdownTask;
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/OrbTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/OrbTask.cpp
new file mode 100644
index 00000000000..fcfb7c919ac
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/OrbTask.cpp
@@ -0,0 +1,98 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbTask.h"
+
+namespace { enum { MAX_ORB_TASK_WORKER_THREADS = 20 }; }
+
+
+OrbTask::OrbTask(CORBA::ORB_ptr orb, unsigned num_threads)
+ : num_threads_(num_threads)
+{
+ this->orb_ = CORBA::ORB::_duplicate(orb);
+}
+
+
+OrbTask::~OrbTask()
+{
+}
+
+
+int
+OrbTask::open(void*)
+{
+ if (this->num_threads_ < 1)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "num_threads_ (%d) is less-than 1.\n",
+ this->num_threads_),
+ -1);
+ }
+
+ if (this->num_threads_ > MAX_ORB_TASK_WORKER_THREADS)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "num_threads_ (%d) is too large. Max is %d.\n",
+ this->num_threads_, MAX_ORB_TASK_WORKER_THREADS),
+ -1);
+ }
+
+ if (CORBA::is_nil(this->orb_.in()))
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "ORB object reference is nil.\n"),
+ -1);
+ }
+
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, this->num_threads_) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to activate "
+ "(%d) worker threads.\n",
+ this->num_threads_),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbTask::svc()
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::run() method. "
+ "OrbTask is stopping.\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/OrbTask.h b/TAO/examples/CSD_Strategy/ThreadPool5/OrbTask.h
new file mode 100644
index 00000000000..dde50d15f66
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/OrbTask.h
@@ -0,0 +1,37 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_TASK_H
+#define ORB_TASK_H
+
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+class OrbTask : public ACE_Task_Base
+{
+ public:
+
+ OrbTask(CORBA::ORB_ptr orb, unsigned num_threads = 1);
+ virtual ~OrbTask();
+
+ virtual int open(void* x = 0);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+ unsigned num_threads_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/README b/TAO/examples/CSD_Strategy/ThreadPool5/README
new file mode 100644
index 00000000000..29b72f8a861
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/README
@@ -0,0 +1,47 @@
+# $Id$
+
+Description:
+
+This test is a combination of other tests and has also added some
+other test cases such as cancel_servant. It uses the command
+line options for the number of orb threads, number of servants,
+collocated test options, etc.
+
+The client application acts as a server too because of the callback
+test. The client application also uses a custom dispatching strategy.
+
+To run the test use the run_test.pl script:
+
+$ ./run_test.pl
+
+ This test is similar to the "ThreadPool" test.
+
+$ ./run_test.pl collocated
+
+ This runs the collocated test.
+
+ The server application creates one servant, runs one orb
+ thread, runs two custom dispatching threads and one client
+ thread to invoke the operations.
+
+ Running two custom dispatching threads instead of one is
+ required to avoid deadlock.
+
+$ ./run_test.pl multiple_servants
+
+ This test is similar to the "ThreadPool2" test.
+
+$ ./run_test.pl multiple_orb_threads
+
+ This test is similar to the "ThreadPool3" test.
+
+$ ./run_test.pl cancel_servant
+
+ This test shows that requests stuck in the request queue are
+ cancelled when a servant is deactivated.
+
+ The client invokes multiple two-way operations and catches the
+ OBJECT_NOT_EXIST or NO_IMPLEMENTATION exception after the servant
+ is deactivated - this is what it is supposed to do - the exceptions
+ are expected.
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/ServerApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/ServerApp.cpp
new file mode 100644
index 00000000000..2e996f83e15
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/ServerApp.cpp
@@ -0,0 +1,354 @@
+// $Id$
+#include "ServerApp.h"
+#include "OrbTask.h"
+#include "FooServantList.h"
+#include "ClientTask.h"
+#include "OrbShutdownTask.h"
+#include "ace/Get_Opt.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+
+ServerApp::ServerApp()
+ : ior_filename_("foo"),
+ num_servants_(1),
+ num_csd_threads_ (1),
+ num_clients_(1),
+ num_orb_threads_ (1),
+ collocated_test_ (0),
+ servant_to_deactivate_ (-1)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheOrbShutdownTask::instance()->orb (orb.in ());
+
+ CORBA::Object_var obj
+ = orb->resolve_initial_references("RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to resolve initial ref for 'RootPOA'.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POA_var root_poa
+ = PortableServer::POA::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(root_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to POA interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the child POA.
+ CORBA::PolicyList policies(1);
+ policies.length(1);
+
+ policies[0]
+ = root_poa->create_id_assignment_policy(PortableServer::USER_ID
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ PortableServer::POA_var child_poa
+ = root_poa->create_POA("ChildPoa",
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(child_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to create the child POA.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ policies[0]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO::CSD::TP_Strategy> csd_tp_strategy =
+ new TAO::CSD::TP_Strategy();
+
+ csd_tp_strategy->set_num_threads(this->num_csd_threads_);
+
+ // Tell the strategy to apply itself to the child poa.
+ if (csd_tp_strategy->apply_to(child_poa.in() ACE_ENV_ARG_PARAMETER) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to apply custom dispatching strategy to child poa.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+ ACE_CHECK_RETURN (-1);
+
+ FooServantList servants(this->ior_filename_.c_str(),
+ this->num_servants_,
+ this->num_clients_,
+ this->collocated_test_,
+ this->servant_to_deactivate_,
+ orb.in());
+
+ // Activate the POA Manager before start the ClientTask thread so that
+ // we do not need coordinate the ClientTask and main thread for the
+ // collocated test.
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ servants.create_and_activate(orb.in (),
+ child_poa.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is ready.\n"));
+
+ // If the num_orb_threads_ is exactly one, then just use the current
+ // (mainline) thread to run the ORB event loop.
+ if (this->num_orb_threads_ == 1)
+ {
+ // Since the num_orb_threads_ is exactly one, we just use the current
+ // (mainline) thread to run the ORB event loop.
+ orb->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ }
+ else
+ {
+ // The num_orb_threads_ is greater than 1, so we will use an OrbTask
+ // (active object) to run the ORB event loop in (num_orb_threads_ - 1)
+ // threads. We use the current (mainline) thread as the other thread
+ // running the ORB event loop.
+ OrbTask orb_task(orb.in(), this->num_orb_threads_ - 1);
+
+ // Activate the OrbTask worker threads
+ if (orb_task.open() != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to open the OrbTask.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ // This will use the current (mainline) thread to run the ORB event loop.
+ orb->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Now that the current thread has unblocked from running the orb,
+ // make sure to wait for all of the worker threads to complete.
+ orb_task.wait();
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is waiting for OrbShutdownTask.\n"));
+ TheOrbShutdownTask::instance()->wait ();
+
+ // Sleep for 2 second to let the done() two-way call complete
+ // before cleanup.
+ ACE_OS::sleep (2);
+
+ if (collocated_test_)
+ {
+ servants.collocated_client ()->wait ();
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the Root POA.\n"));
+
+ // Tear-down the root poa and orb.
+ root_poa->destroy(1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the ORB.\n"));
+
+ orb->destroy(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp has completed running successfully.\n"));
+
+ return 0;
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "p:s:c:t:l:d:n:");
+
+ int c;
+ int tmp;
+
+ while ((c = get_opts()) != -1)
+ {
+ int parse_error = 0;
+
+ switch (c)
+ {
+ case 'p':
+ this->ior_filename_ = get_opts.opt_arg();
+ break;
+
+ case 's':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Error. -s must be followed by an integer "
+ "value greater than 0.\n"));
+ parse_error = 1;
+ }
+
+ this->num_servants_ = tmp;
+ break;
+
+ case 'c':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Error. -c must be followed by an integer "
+ "value greater than 0.\n"));
+ parse_error = 1;
+ }
+
+ this->num_clients_ = tmp;
+ break;
+
+ case 't':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Error. -t must be followed by an integer "
+ "value greater than 0.\n"));
+ parse_error = 1;
+ }
+
+ this->num_orb_threads_ = tmp;
+ break;
+
+ case 'n':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Error. -n must be followed by an integer "
+ "value greater than 0.\n"));
+ parse_error = 1;
+ }
+
+ this->num_csd_threads_ = tmp;
+ break;
+
+ case 'l':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Error. -l must be followed by an integer "
+ "value greater than -1.\n"));
+ parse_error = 1;
+ }
+
+ this->collocated_test_ = tmp;
+ break;
+
+ case 'd':
+ tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Error. -d must be followed by an integer "
+ "value >= 0.\n"));
+ parse_error = 1;
+ }
+
+ this->servant_to_deactivate_ = tmp;
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (parse_error != 0)
+ {
+ this->usage_statement();
+ return parse_error;
+ }
+ }
+
+ // The deadlock will happen with the collocated callback test
+ // when we have one working thread, so create at least one more
+ // working thread would resolve the deadlock.
+ if (this->collocated_test_ == 1 && this->num_csd_threads_ == 1)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Error. The num_csd_threads_ should be "
+ ">= 1.\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) usage: %s \n"
+ "\t[-p <ior_filename_prefix>] \n"
+ "\t[-s <num_servants>] \n"
+ "\t[-c <num_clients>] \n"
+ "\t[-n <num_csd_threads>] \n"
+ "\t[-t <num_orb_threads>] \n"
+ "\t[-l <collocation_test>] \n"
+ "\t[-d <servant_to_deactivate>] \n"
+ "Default ior_filename_prefix is 'foo'.\n"
+ "Default num_servants is 1.\n"
+ "Default num_clients is 1.\n"
+ "Default num_orb_threads is 1.\n"
+ "Default collocation_test flag is 0.\n"
+ "Default servant_to_deactivate is -1 means not deactivate servant.\n"
+ " 0 means deactivate all servant. \n"
+ " >0 means the index (servant_to_deactivate-1) of the servant in the servant list.\n",
+ this->exe_name_.c_str ()));
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/ServerApp.h b/TAO/examples/CSD_Strategy/ThreadPool5/ServerApp.h
new file mode 100644
index 00000000000..8b461a3e299
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/ServerApp.h
@@ -0,0 +1,34 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+class ServerApp
+{
+ public:
+
+ ServerApp();
+ ~ServerApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString exe_name_;
+ ACE_CString ior_filename_;
+ unsigned num_servants_;
+ unsigned num_csd_threads_;
+ unsigned num_clients_;
+ unsigned num_orb_threads_;
+ int collocated_test_;
+ int servant_to_deactivate_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/client_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/client_main.cpp
new file mode 100644
index 00000000000..1f9c337ae54
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/client_main.cpp
@@ -0,0 +1,45 @@
+// $Id$
+#include "ClientApp.h"
+#include "ace/Log_Msg.h"
+#include "ace/SString.h"
+#include "tao/Exception.h"
+
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+
+ ClientApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ClientApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/run_test.pl b/TAO/examples/CSD_Strategy/ThreadPool5/run_test.pl
new file mode 100755
index 00000000000..4ea3513ac50
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/run_test.pl
@@ -0,0 +1,126 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+$status = 0;
+
+
+$iorfname_prefix = "server";
+$num_servants=1;
+$num_clients_per_servant=40;
+$num_orb_threads=1;
+$num_csd_threads=1;
+$collocated_test=0;
+$servant_cancellation_option="";
+
+if ($ARGV[0] eq 'collocated') {
+ # 1 servant, 1 collocated client, 1 orb thread, 2 strategy working threads
+ $num_clients_per_servant=1;
+ $collocated_test=1;
+ $num_csd_threads=2;
+}
+elsif ($ARGV[0] eq 'multiple_servants') {
+ # multiple servants and single orb thread.
+ # 10 servant, 40 client, 1 orb thread, 10 strategy working threads
+ $num_servants=10;
+ $num_csd_threads=10;
+ $num_clients_per_servant=4;
+}
+elsif ($ARGV[0] eq 'multiple_orb_threads') {
+ # multiple servants and multiple orb threads.
+ # 10 servant, 40 client, 4 orb thread, 10 strategy working threads
+ $num_servants=10;
+ $num_csd_threads=10;
+ $num_clients_per_servant=4;
+ $num_orb_threads=4;
+}
+elsif ($ARGV[0] eq 'cancel_servant') {
+ # Cancel one servant and leave the other alive.
+ # 2 servant, 10 client, 5 orb thread, 1 strategy working threads
+ $num_clients_per_servant=5;
+ $num_servants=2;
+ $num_csd_threads=2;
+ $num_orb_threads=5;
+ $servant_cancellation_option = " -d 1 ";
+}
+elsif ($ARGV[0] eq '') {
+ # default test - 1 servant, 40 clients , 1 orb thread, 1 csd thread
+}
+else {
+ print STDERR "ERROR: invalid parameter $ARGV[0] \n";
+ exit 1;
+}
+
+$num_clients=$num_servants * $num_clients_per_servant;
+
+#Delete old ior files.
+for (my $i = 0; $i < $num_servants; $i++) {
+ $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+
+ unlink $iorfile[$i];
+}
+
+$SV = new PerlACE::Process ("server_main",
+ "-p $iorfname_prefix -s $num_servants "
+ . "-c $num_clients -t $num_orb_threads -n $num_csd_threads "
+ . "-l $collocated_test $servant_cancellation_option");
+
+$SV->Spawn ();
+
+# Wait for the servant ior files created by server.
+for (my $i = 0; $i < $num_servants; $i++) {
+ $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+
+ if (PerlACE::waitforfile_timed ($iorfile[$i],
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile[$i]>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+ }
+}
+
+$count = 0;
+
+if ($collocated_test == 0) {
+ for (my $i = 0; $i < $num_servants; $i++) {
+ for ($j = 0; $j < $num_clients_per_servant; $j++) {
+ $CLS[$count] = new PerlACE::Process ("client_main", " -i file://$iorfile[$i]");
+ $CLS[$count]->Spawn ();
+ $count ++;
+ }
+ }
+
+ for (my $i = 0; $i < $num_clients; $i++) {
+ $client = $CLS[$i]->WaitKill (60);
+
+ if ($client != 0) {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+ }
+}
+
+$server = $SV->WaitKill (60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+#Delete ior files generated by this run.
+for (my $i = 0; $i < $num_servants; $i++) {
+ $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+
+ unlink $iorfile[$i];
+}
+
+exit $status;
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/server_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/server_main.cpp
new file mode 100644
index 00000000000..ba16e928f63
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/server_main.cpp
@@ -0,0 +1,45 @@
+// $Id$
+#include "ServerApp.h"
+#include "ace/Log_Msg.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+#include "tao/Exception.h"
+
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+ ServerApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ServerApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/CSD_Test_ThreadPool6.mpc b/TAO/examples/CSD_Strategy/ThreadPool6/CSD_Test_ThreadPool6.mpc
new file mode 100644
index 00000000000..fc53a3a81c2
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/CSD_Test_ThreadPool6.mpc
@@ -0,0 +1,25 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_threadpool, taoexe, portableserver, minimum_corba {
+ exename = server_main
+ idlflags -= -Sc
+
+ Source_Files {
+ Foo_i.cpp
+ ServerApp.cpp
+ server_main.cpp
+ OrbShutdownTask.cpp
+ }
+}
+
+project(*Client): taoexe, anytypecode {
+ exename = client_main
+
+ Source_Files {
+ FooC.cpp
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/ClientApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool6/ClientApp.cpp
new file mode 100644
index 00000000000..74e97209295
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/ClientApp.cpp
@@ -0,0 +1,143 @@
+// $Id$
+#include "ClientApp.h"
+#include "FooC.h"
+#include "ace/Get_Opt.h"
+#include "ace/Log_Msg.h"
+
+
+ClientApp::ClientApp()
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb
+ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ CORBA::Object_var obj
+ = orb->string_to_object(this->ior_.c_str() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to convert IOR string to obj ref.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+ Foo_var foo = Foo::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(foo.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to Foo interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);
+ }
+
+
+ for (CORBA::Long i = 1; i <= 100; i++)
+ {
+ foo->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ foo->op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ CORBA::Long value = foo->op3(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Value retrieved from op3() == %d\n",
+ value));
+
+ for (CORBA::Long j = 1; j <= 5; j++)
+ {
+ foo->op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ foo->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Caught FooException - as expected.\n"));
+
+ }
+ ACE_ENDTRY;
+ }
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Tell server that we are done().\n"));
+
+ foo->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ===> Back from done().\n"));
+
+ return 0;
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/ClientApp.h b/TAO/examples/CSD_Strategy/ThreadPool6/ClientApp.h
new file mode 100644
index 00000000000..7dc57bb78dc
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/ClientApp.h
@@ -0,0 +1,30 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+
+class ClientApp
+{
+ public:
+
+ ClientApp();
+ ~ClientApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString ior_;
+
+ ACE_CString exe_name_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/Foo.idl b/TAO/examples/CSD_Strategy/ThreadPool6/Foo.idl
new file mode 100644
index 00000000000..f4a756a31b1
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/Foo.idl
@@ -0,0 +1,29 @@
+// $Id$
+#ifndef FOO_IDL
+#define FOO_IDL
+
+exception FooException {};
+exception TestException {};
+
+interface Foo
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, no arguments
+ long op3();
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Client calls this last. It will shutdown the server.
+ void done();
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/Foo_i.cpp b/TAO/examples/CSD_Strategy/ThreadPool6/Foo_i.cpp
new file mode 100644
index 00000000000..8201c889f88
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/Foo_i.cpp
@@ -0,0 +1,113 @@
+// $Id$
+#include "Foo_i.h"
+#include "OrbShutdownTask.h"
+#include "ace/OS.h"
+
+Foo_i::Foo_i(unsigned num_clients)
+ : value_(0),
+ num_clients_(num_clients),
+ count_op1_(0),
+ count_op2_(0),
+ count_op3_(0),
+ count_op4_(0),
+ count_op5_(0)
+
+{
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) Number of clients for Foo_i servant: %d\n",
+ num_clients));
+}
+
+
+Foo_i::~Foo_i()
+{
+}
+
+
+void
+Foo_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op1_;
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op2_;
+ this->value_ = value;
+}
+
+
+CORBA::Long
+Foo_i::op3(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op3_;
+ return this->value_;
+}
+
+
+void
+Foo_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_op4_;
+ this->value_ = value;
+
+ if (this->count_op4_ % 500 == 0)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) op4() has been called %d times now. value == %d\n",
+ this->count_op4_, this->value_));
+ }
+
+ // Sleep for 10 milliseconds (10,000 microseconds)
+ //ACE_OS::sleep(ACE_Time_Value(0,10000));
+}
+
+
+void
+Foo_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ ++this->count_op5_;
+ ACE_THROW (FooException());
+}
+
+
+void
+Foo_i::done(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ unsigned num_left = --this->num_clients_;
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) A client has reported that it is done(). "
+ "There are %d clients left.\n", num_left));
+
+ if (num_left == 0)
+ {
+ ACE_DEBUG((LM_DEBUG, "(%P|%t) Stats:\n"
+ "op1() count: %d\n"
+ "op2() count: %d\n"
+ "op3() count: %d\n"
+ "op4() count: %d\n"
+ "op5() count: %d\n",
+ this->count_op1_,
+ this->count_op2_,
+ this->count_op3_,
+ this->count_op4_,
+ this->count_op5_));
+
+ if (TheOrbShutdownTask::instance()->open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_i::done: "
+ "failed to create orb shutdown thread.\n"));
+ }
+ }
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/Foo_i.h b/TAO/examples/CSD_Strategy/ThreadPool6/Foo_i.h
new file mode 100644
index 00000000000..ab50cc5589a
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/Foo_i.h
@@ -0,0 +1,48 @@
+// $Id$
+#ifndef FOO_I_H
+#define FOO_I_H
+
+#include "FooS.h"
+
+
+class Foo_i
+{
+ public:
+
+ Foo_i(unsigned num_clients);
+ virtual ~Foo_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+
+ private:
+
+ CORBA::Long value_;
+ unsigned num_clients_;
+
+ CORBA::ORB_var orb_;
+
+ unsigned count_op1_;
+ unsigned count_op2_;
+ unsigned count_op3_;
+ unsigned count_op4_;
+ unsigned count_op5_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.cpp b/TAO/examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.cpp
new file mode 100644
index 00000000000..f9d551e8aee
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.cpp
@@ -0,0 +1,77 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbShutdownTask.h"
+#include "ace/CORBA_macros.h"
+#include "ace/OS_NS_unistd.h"
+
+
+OrbShutdownTask::OrbShutdownTask()
+{
+}
+
+
+OrbShutdownTask::~OrbShutdownTask()
+{
+}
+
+
+void
+OrbShutdownTask::orb(CORBA::ORB_ptr orb)
+{
+ this->orb_ = CORBA::ORB::_duplicate (orb);
+}
+
+
+int
+OrbShutdownTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbShutdownTask failed to open().\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::svc()
+{
+ ACE_OS::sleep (2);
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)OrbShutdownTask::svc shutdown orb \n"));
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->shutdown(0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::shutdown() call "
+ "in OrbShutdownTask::svc().\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.h b/TAO/examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.h
new file mode 100644
index 00000000000..3795d12c3c9
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/OrbShutdownTask.h
@@ -0,0 +1,41 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_SHUTDOWN_TASK_H
+#define ORB_SHUTDOWN_TASK_H
+
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+
+class OrbShutdownTask : public ACE_Task_Base
+{
+ public:
+
+ OrbShutdownTask();
+ virtual ~OrbShutdownTask();
+
+ void orb(CORBA::ORB_ptr orb);
+
+ virtual int open(void*);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+};
+
+typedef ACE_Singleton<OrbShutdownTask, ACE_Thread_Mutex> TheOrbShutdownTask;
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/README b/TAO/examples/CSD_Strategy/ThreadPool6/README
new file mode 100644
index 00000000000..5c90da80c6b
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/README
@@ -0,0 +1,14 @@
+# $Id$
+
+Description:
+
+This is the simple "ThreadPool" test modified to use the TIE approach.
+
+
+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/examples/CSD_Strategy/ThreadPool6/ServerApp.cpp b/TAO/examples/CSD_Strategy/ThreadPool6/ServerApp.cpp
new file mode 100644
index 00000000000..08584619c8a
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/ServerApp.cpp
@@ -0,0 +1,240 @@
+// $Id$
+#include "ServerApp.h"
+#include "Foo_i.h"
+#include "FooS_T.h"
+#include "OrbShutdownTask.h"
+#include "ace/Get_Opt.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+
+ServerApp::ServerApp()
+: ior_filename_ ("server.ior")
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheOrbShutdownTask::instance()->orb (orb.in ());
+
+ CORBA::Object_var obj
+ = orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to resolve initial ref for 'RootPOA'.\n"));
+ ACE_THROW_RETURN (TestException(), -1);;
+ }
+
+ PortableServer::POA_var root_poa
+ = PortableServer::POA::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(root_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to POA interface.\n"));
+ ACE_THROW_RETURN (TestException(), -1);;
+ }
+
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the child POA.
+ CORBA::PolicyList policies(1);
+ policies.length(1);
+
+ policies[0] =
+ root_poa->create_implicit_activation_policy (PortableServer::IMPLICIT_ACTIVATION
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ PortableServer::POA_var child_poa
+ = root_poa->create_POA("ChildPoa",
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(child_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to create the child POA.\n"));
+ ACE_THROW_RETURN (TestException(), -1);;
+ }
+
+ policies[0]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO::CSD::TP_Strategy> csd_tp_strategy =
+ new TAO::CSD::TP_Strategy();
+
+ // Tell the strategy to apply itself to the child poa.
+ if (csd_tp_strategy->apply_to(child_poa.in() ACE_ENV_ARG_PARAMETER) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
+ "Failed to apply custom dispatching strategy to child poa.\n"));
+ ACE_THROW_RETURN (TestException(), -1);;
+ }
+ ACE_CHECK_RETURN (-1);
+
+ // Create the Foo_i object.
+ Foo_i foo_i (this->num_clients_);
+
+ // Create tie object with the Foo_i object.
+ POA_Foo_tie<Foo_i> foo_tie_i (foo_i, child_poa.in ());
+
+ // Get Object Reference for the foo_tie_i object.
+ Foo_var foo = foo_tie_i._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ if (CORBA::is_nil(foo.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant foo_tie_i.\n"));
+ ACE_THROW_RETURN (TestException(), -1);;
+ }
+
+ // Stringify the object reference
+ CORBA::String_var ior
+ = orb->object_to_string(foo.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Write the stringified object reference to the ior file.
+ FILE* ior_file = ACE_OS::fopen(this->ior_filename_.c_str(), "w");
+
+ if (ior_file == 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Cannot open output file for writing IOR: %s",
+ this->ior_filename_.c_str()));
+ ACE_THROW_RETURN (TestException(), -1);;
+ }
+
+ ACE_OS::fprintf(ior_file, "%s", ior.in ());
+ ACE_OS::fclose(ior_file);
+
+ // Activate the POA Manager
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is ready. Running the ORB event loop.\n"));
+
+ // Run the ORB event loop.
+ orb->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp ORB has stopped running. "
+ "Stop the CSD strategy.\n"));
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is waiting for OrbShutdownTask.\n"));
+ TheOrbShutdownTask::instance()->wait ();
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the Root POA.\n"));
+
+ // Sleep for 2 second to let the done() two-way call complete
+ // before cleanup.
+ ACE_OS::sleep (2);
+
+ // Tear-down the root poa and orb.
+ root_poa->destroy(1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the ORB.\n"));
+
+ orb->destroy(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp has completed running successfully.\n"));
+
+ return 0;
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "o:n:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'o':
+ this->ior_filename_ = get_opts.opt_arg();
+ break;
+
+ case 'n':
+ {
+ int tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ this->usage_statement ();
+ return -1;
+ }
+
+ this->num_clients_ = tmp;
+ }
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-o <ior_filename>]\n"
+ "\t[-n <num_clients>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/ServerApp.h b/TAO/examples/CSD_Strategy/ThreadPool6/ServerApp.h
new file mode 100644
index 00000000000..ad89b43c972
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/ServerApp.h
@@ -0,0 +1,30 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "ace/SString.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+
+
+class ServerApp
+{
+ public:
+
+ ServerApp();
+ ~ServerApp();
+
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+ void usage_statement();
+
+ ACE_CString exe_name_;
+ ACE_CString ior_filename_;
+ unsigned num_clients_;
+};
+
+#endif
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/client_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool6/client_main.cpp
new file mode 100644
index 00000000000..1f9c337ae54
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/client_main.cpp
@@ -0,0 +1,45 @@
+// $Id$
+#include "ClientApp.h"
+#include "ace/Log_Msg.h"
+#include "ace/SString.h"
+#include "tao/Exception.h"
+
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+
+ ClientApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ClientApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/run_test.pl b/TAO/examples/CSD_Strategy/ThreadPool6/run_test.pl
new file mode 100755
index 00000000000..ded41bfc848
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/run_test.pl
@@ -0,0 +1,55 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+$iorfile = PerlACE::LocalFile ("server.ior");
+unlink $iorfile;
+$status = 0;
+
+$num_clients=1;
+
+$SV = new PerlACE::Process ("server_main", "-o $iorfile -n $num_clients");
+
+$SV->Spawn ();
+
+if (PerlACE::waitforfile_timed ($iorfile,
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ @CLS[$i] = new PerlACE::Process ("client_main", " -i file://$iorfile");
+
+ @CLS[$i]->Spawn ();
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ $client = @CLS[$i]->WaitKill (60);
+
+ if ($client != 0) {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill (60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+unlink $iorfile;
+
+exit $status;
diff --git a/TAO/examples/CSD_Strategy/ThreadPool6/server_main.cpp b/TAO/examples/CSD_Strategy/ThreadPool6/server_main.cpp
new file mode 100644
index 00000000000..ba16e928f63
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool6/server_main.cpp
@@ -0,0 +1,45 @@
+// $Id$
+#include "ServerApp.h"
+#include "ace/Log_Msg.h"
+#include "ace/CORBA_macros.h"
+#include "tao/Environment.h"
+#include "tao/Exception.h"
+
+
+int
+main(int argc, char* argv[])
+{
+ ACE_LOG_MSG->priority_mask(LM_TRACE |
+ LM_DEBUG |
+ LM_INFO |
+ LM_NOTICE |
+ LM_WARNING |
+ LM_ERROR |
+ LM_CRITICAL |
+ LM_ALERT |
+ LM_EMERGENCY,
+ ACE_Log_Msg::PROCESS);
+
+ ServerApp app;
+
+ ACE_TRY_NEW_ENV
+ {
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ return ret == 1 ? 0 : ret;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Caught exception:");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Unknown (...) exception caught in main() "
+ "for ServerApp\n"));
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestApps/ClientApp.cpp b/TAO/performance-tests/CSD_Strategy/TestApps/ClientApp.cpp
new file mode 100644
index 00000000000..f01b5c7570d
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestApps/ClientApp.cpp
@@ -0,0 +1,200 @@
+// $Id$
+#include "ClientApp.h"
+#include "TestInf/AppHelper.h"
+#include "TestInf/TestAppExceptionC.h"
+#include "TestServant/Foo_ClientEngine.h"
+#include "ace/Get_Opt.h"
+
+
+ClientApp::ClientApp()
+ : TestAppBase("CSD_PT_ClientApp"),
+ ior_("Not Set"),
+ client_id_(0),
+ num_loops_(1)
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ this->client_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ result = this->run_engine(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ this->cleanup();
+ return result;
+}
+
+
+int
+ClientApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Returns -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ return this->parse_args(argc, argv);
+}
+
+
+void
+ClientApp::client_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Turn the ior_ into a Foo obj ref.
+ Foo_var foo = RefHelper<Foo>::string_to_ref(this->orb_.in(),
+ this->ior_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Create the ClientEngine object, and give it the Foo obj ref.
+ this->engine_ = new Foo_ClientEngine(foo.in(), this->client_id_);
+}
+
+
+int
+ClientApp::run_engine(ACE_ENV_SINGLE_ARG_DECL)
+{
+ bool result = this->engine_->execute(this->num_loops_
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ return result ? 0 : -1;
+}
+
+
+void
+ClientApp::cleanup()
+{
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:n:l:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case 'n':
+ result = this->set_arg(this->client_id_,
+ get_opts.opt_arg(),
+ c,
+ "client_id",
+ 1);
+ break;
+
+ case 'l':
+ result = this->set_arg(this->num_loops_,
+ get_opts.opt_arg(),
+ c,
+ "num_loops",
+ 1);
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-n <client_id>]\n"
+ "\t[-l <num_loops>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ClientApp::arg_dependency_checks()
+{
+ if (this->ior_ == "Not Set")
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Missing required command-line option (-i <ior>).\n"));
+ this->usage_statement();
+ return -1;
+ }
+
+ if (this->client_id_ <= 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Required command-line option (-n <client id>).\n"
+ " The client id should be positive integer. \n"));
+ this->usage_statement();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+ClientApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+ return 0;
+}
+
+
diff --git a/TAO/performance-tests/CSD_Strategy/TestApps/ClientApp.h b/TAO/performance-tests/CSD_Strategy/TestApps/ClientApp.h
new file mode 100644
index 00000000000..9136ff9d27e
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestApps/ClientApp.h
@@ -0,0 +1,63 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ClientApp.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "TestInf/TestAppBase.h"
+#include "TestInf/ClientEngine.h"
+#include "tao/ORB.h"
+#include "ace/SString.h"
+
+
+class ClientApp : public TestAppBase
+{
+ public:
+
+ ClientApp();
+ virtual ~ClientApp();
+
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void client_setup(ACE_ENV_SINGLE_ARG_DECL);
+ int run_engine(ACE_ENV_SINGLE_ARG_DECL);
+ void cleanup();
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+
+ CORBA::ORB_var orb_;
+ ACE_CString exe_name_;
+ ACE_CString ior_;
+ ClientEngine_Handle engine_;
+ unsigned client_id_;
+ unsigned num_loops_;
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestApps/README b/TAO/performance-tests/CSD_Strategy/TestApps/README
new file mode 100644
index 00000000000..61ddc725de5
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestApps/README
@@ -0,0 +1,64 @@
+/**
+
+@page CSD_Strategy TestApp README File
+
+ This directory contains the test applications. This test tries to
+estimate how fast the CSD strategy can handle requests.
+
+ To run the test use the run_test.pl script as below. The number
+parameter is the trail id for the server used to identify the test
+results when running same test multiple times using single script.
+The id should be positive integer.
+
+
+$ ./run_test.pl 1
+
+ 1 remote client, 1 servant, 1 orb thread (main thread), 1 csd strategy thread
+
+$ ./run_test.pl remote 1
+
+ 40 remote clients, 1 servant, 1 orb thread (main thread), 1 csd strategy thread
+
+$ ./run_test.pl collocated 1
+
+ 10 collocated clients, 1 servant, 1 orb thread (main thread), 1 csd strategy thread
+
+$ ./run_test.pl remote_orbthreads 1
+
+ 40 remote clients, 1 servant, 5 orb threads, 1 csd strategy thread
+
+$ ./run_test.pl remote_servants 1
+
+ 40 remote clients, 5 servants, 5 orb threads, 1 csd strategy thread
+
+$ ./run_test.pl remote_csdthreads 1
+
+ 40 remote clients, 5 servants, 1 orb thread (main thread), 5 csd strategy threads
+
+$ ./run_test.pl remote_big 1
+
+ 40 remote clients, 10 servants, 4 orb threads, 5 csd strategy threads
+
+$ ./run_test.pl collocated_big 1
+
+ 40 collocated clients, 10 servants, 1 orb thread (main thread), 5 csd strategy threads
+
+$ ./run_test.pl big 1
+
+ 40 remote clients, 40 collocated clients, 10 servants, 4 orb threads, 5 csd strategy threads
+
+$ ./run_test.pl remote_huge 1
+
+ 400 remote clients, 10 servants, 4 orb threads, 5 csd strategy threads
+
+$ ./run_test.pl collocated_huge 1
+
+ 40 collocated clients, 10 servants, 1 orb thread (main thread), 20 csd strategy threads
+
+
+ The script returns 0 if the test was successful, and prints
+out the number of requests, the total time to dispatch these requests
+and the average number of requests the CSD strategy dispatched
+per millisecond.
+
+*/
diff --git a/TAO/performance-tests/CSD_Strategy/TestApps/ServerApp.cpp b/TAO/performance-tests/CSD_Strategy/TestApps/ServerApp.cpp
new file mode 100644
index 00000000000..2a01df0f410
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestApps/ServerApp.cpp
@@ -0,0 +1,421 @@
+// $Id$
+#include "ServerApp.h"
+#include "TestInf/AppHelper.h"
+#include "TestInf/OrbRunner.h"
+#include "TestInf/AppShutdown.h"
+#include "TestInf/TestAppExceptionC.h"
+#include "TestServant/Foo_ClientEngine.h"
+#include "ace/OS.h"
+#include "ace/Get_Opt.h"
+#include "ace/Time_Value.h"
+#include "ace/High_Res_Timer.h"
+
+
+ServerApp::ServerApp()
+ : TestAppBase("CSD_PT_ServerApp"),
+ ior_filename_prefix_("foo"),
+ num_servants_(1),
+ num_csd_threads_(1),
+ num_orb_threads_(1),
+ num_remote_clients_(1),
+ num_collocated_clients_(0),
+ num_loops_(1),
+ use_csd_(1),
+ scenario_id_("UnknownScenarioId"),
+ trial_id_(0)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ this->poa_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->csd_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->servant_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->collocated_setup();
+ this->poa_activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_High_Res_Timer timer;
+ timer.start();
+
+ this->run_collocated_clients(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_orb_event_loop(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+
+ timer.stop();
+
+ ACE_Time_Value tv;
+ timer.elapsed_time(tv);
+
+ unsigned num_operations = this->stats_.total();
+
+ double ops_per_msec = (1.0 * num_operations) / tv.msec();
+
+ ACE_DEBUG((LM_DEBUG, "%s,%d,%d,%d,%.2f\n",
+ this->scenario_id_.c_str(),
+ this->trial_id_,
+ num_operations,
+ tv.msec(),
+ ops_per_msec));
+
+ this->cleanup();
+ return this->check_results () ? 0 : -1;
+}
+
+
+int
+ServerApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheAppShutdown->init(this->orb_.in(),
+ this->num_remote_clients_ +
+ this->num_collocated_clients_
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ return 0;
+}
+
+
+void
+ServerApp::poa_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->poa_ = this->create_poa(this->orb_.in(),
+ "ChildPoa"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::csd_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->tp_strategy_ = new TAO::CSD::TP_Strategy(this->num_csd_threads_);
+
+ if (this->use_csd_ > 0)
+ {
+ if (!this->tp_strategy_->apply_to(this->poa_.in() ACE_ENV_ARG_PARAMETER))
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to poa.\n"));
+ ACE_THROW(TestAppException());
+ }
+ ACE_CHECK;
+ }
+}
+
+
+void
+ServerApp::servant_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->servants_.create_and_activate(this->num_servants_,
+ this->orb_.in (),
+ this->poa_.in (),
+ this->ior_filename_prefix_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::collocated_setup()
+{
+ int client_id = this->num_remote_clients_;
+
+ for (unsigned i = 0; i < this->num_collocated_clients_; i++)
+ {
+ ++client_id;
+
+ // Dole out the servant object references in a round-robin fashion.
+ unsigned servant_index = i % this->num_servants_;
+
+ ServantListType::T_stub_var obj = this->servants_.objref(servant_index);
+
+ ClientEngine_Handle engine = new Foo_ClientEngine(obj.in(), client_id);
+
+ this->collocated_client_task_.add_engine(engine.in());
+ }
+
+ this->collocated_client_task_.num_loops(this->num_loops_);
+}
+
+
+void
+ServerApp::poa_activate(ACE_ENV_SINGLE_ARG_DECL)
+{
+ PortableServer::POAManager_var poa_manager
+ = this->poa_->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->num_collocated_clients_ > 0)
+ {
+ if (this->collocated_client_task_.open() == -1)
+ {
+ ACE_THROW (TestAppException ());
+ }
+ }
+}
+
+
+void
+ServerApp::run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL)
+{
+ OrbRunner orb_runner(this->orb_.in(), this->num_orb_threads_);
+ orb_runner.run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ TheAppShutdown->wait ();
+}
+
+
+void
+ServerApp::cleanup()
+{
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "p:s:n:t:r:c:l:u:x:z:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'p':
+ this->ior_filename_prefix_ = get_opts.opt_arg();
+ break;
+
+ case 's':
+ result = this->set_arg(this->num_servants_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 'n':
+ result = this->set_arg(this->num_csd_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 't':
+ result = this->set_arg(this->num_orb_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_orb_threads",
+ 1);
+ break;
+
+ case 'r':
+ result = this->set_arg(this->num_remote_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_remote_clients");
+ break;
+
+ case 'c':
+ result = this->set_arg(this->num_collocated_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_collocated_clients");
+ break;
+
+ case 'l':
+ result = this->set_arg(this->num_loops_,
+ get_opts.opt_arg(),
+ c,
+ "num_loops",
+ 1);
+ break;
+
+ case 'u':
+ result = this->set_arg(this->use_csd_,
+ get_opts.opt_arg(),
+ c,
+ "use_csd_flag");
+ break;
+
+ case 'x':
+ this->scenario_id_ = get_opts.opt_arg();
+ break;
+
+ case 'z':
+ result = this->set_arg(this->trial_id_,
+ get_opts.opt_arg(),
+ c,
+ "trial_id_number",
+ 1);
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-p <ior_filename_prefix>]\n"
+ "\t[-s <num_servants>]\n"
+ "\t[-n <num_csd_threads>]\n"
+ "\t[-t <num_orb_threads>]\n"
+ "\t[-r <num_remote_clients>]\n"
+ "\t[-c <num_collocated_clients>]\n"
+ "\t[-l <num_loops>]\n"
+ "\t[-u <use_csd_flag>]\n"
+ "\t[-x <scenario_id_string>]\n"
+ "\t[-z <trial_id_number>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ServerApp::arg_dependency_checks()
+{
+ return (this->num_remote_clients_
+ + this->num_collocated_clients_) > 0 ? 0 : -1;
+}
+
+
+int
+ServerApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+ return 0;
+}
+
+
+PortableServer::POA_ptr
+ServerApp::create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL)
+{
+ // Get the Root POA.
+ PortableServer::POA_var root_poa
+ = RefHelper<PortableServer::POA>::resolve_initial_ref(orb,
+ "RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Get the POAManager from the Root POA.
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Create the child POA Policies.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ // Create the child POA
+ PortableServer::POA_var poa = AppHelper::create_poa(poa_name,
+ root_poa.in(),
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Give away the child POA_ptr from the POA_var variable.
+ return poa._retn();
+}
+
+
+bool
+ServerApp::check_results()
+{
+
+ this->stats_.init(this->num_remote_clients_ +
+ this->num_collocated_clients_,
+ this->num_loops_);
+
+ Foo_ClientEngine::expected_results(this->stats_);
+
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ this->servants_.servant(i)->gather_stats(this->stats_);
+ }
+
+ this->stats_.actual_vs_expected();
+
+ return true;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestApps/ServerApp.h b/TAO/performance-tests/CSD_Strategy/TestApps/ServerApp.h
new file mode 100644
index 00000000000..a9029d65703
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestApps/ServerApp.h
@@ -0,0 +1,95 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ServerApp.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "TestInf/TestAppBase.h"
+#include "TestInf/ServantList_T.h"
+#include "TestInf/ClientTask.h"
+#include "TestServant/Foo_i.h"
+#include "TestServant/Foo_Statistics.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "ace/SString.h"
+
+
+class ServerApp : public TestAppBase
+{
+ public:
+
+ ServerApp();
+ virtual ~ServerApp();
+
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void poa_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void csd_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void servant_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void collocated_setup();
+ void poa_activate(ACE_ENV_SINGLE_ARG_DECL);
+ void run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL);
+ void run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL);
+ bool check_results();
+ void cleanup();
+
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+
+ PortableServer::POA_ptr create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL);
+
+ typedef ServantList<Foo_i> ServantListType;
+
+ CORBA::ORB_var orb_;
+ PortableServer::POA_var poa_;
+ TAO::CSD::TP_Strategy_Handle tp_strategy_;
+
+ ServantListType servants_;
+
+ ClientTask collocated_client_task_;
+
+ ACE_CString exe_name_;
+ ACE_CString ior_filename_prefix_;
+ unsigned num_servants_;
+ unsigned num_csd_threads_;
+ unsigned num_orb_threads_;
+ unsigned num_remote_clients_;
+ unsigned num_collocated_clients_;
+ unsigned num_loops_;
+ unsigned use_csd_;
+
+ ACE_CString scenario_id_;
+ unsigned trial_id_;
+
+ Foo_Statistics stats_;
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestApps/client_main.cpp b/TAO/performance-tests/CSD_Strategy/TestApps/client_main.cpp
new file mode 100644
index 00000000000..3481f7068f7
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestApps/client_main.cpp
@@ -0,0 +1,7 @@
+// $Id$
+#include "TestInf/TestAppMain.h"
+#include "ClientApp.h"
+
+TEST_APP_MAIN(ClientApp)
+
+
diff --git a/TAO/performance-tests/CSD_Strategy/TestApps/csd_pt_testapps.mpc b/TAO/performance-tests/CSD_Strategy/TestApps/csd_pt_testapps.mpc
new file mode 100644
index 00000000000..330fcd4afc5
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestApps/csd_pt_testapps.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project(csd_test_server): csd_pt_test_exe {
+ exename=server_main
+
+ Source_Files {
+ ServerApp.cpp
+ server_main.cpp
+ }
+}
+
+project(csd_test_client): csd_pt_test_exe {
+ exename=client_main
+
+ Source_Files {
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/performance-tests/CSD_Strategy/TestApps/run_test.pl b/TAO/performance-tests/CSD_Strategy/TestApps/run_test.pl
new file mode 100755
index 00000000000..42469543ce0
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestApps/run_test.pl
@@ -0,0 +1,227 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+# 5 Minute server timeout.
+my $server_timeout_secs = 300;
+
+my $status = 0;
+
+my $iorfname_prefix = "servant";
+my $num_servants = 1;
+my $num_orb_threads = 1;
+my $num_remote_clients = 1;
+my $num_csd_threads = 1;
+my $num_collocated_clients = 0;
+my $num_loops = 100;
+my $use_csd = 1;
+my $scenario_id = "UnsetScenarioId";
+my $trial_id = 1;
+
+my $i;
+my $j;
+my @iorfile;
+
+my $ARGC = @ARGV;
+
+if ($ARGC > 0)
+{
+ if ($ARGC > 3)
+ {
+ print STDERR "ERROR: Too many command-line arguments for $0.\n";
+ exit 1;
+ }
+
+ if ($ARGC < 2)
+ {
+ print STDERR "ERROR: Too few command-line arguments for $0.\n";
+ exit 1;
+ }
+
+ if ($ARGC > 2)
+ {
+ $num_loops = $ARGV[2];
+ }
+
+ $scenario_id = $ARGV[0];
+ $trial_id = $ARGV[1];
+
+ my $subtest = $scenario_id;
+
+ if ($subtest =~ /^x_(.+)$/)
+ {
+ $subtest = $1;
+ $use_csd = 0;
+ }
+
+ if ($subtest eq 'remote')
+ {
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'collocated')
+ {
+ $num_remote_clients = 0;
+ $num_collocated_clients = 10;
+ }
+ elsif ($subtest eq 'remote_orbthreads')
+ {
+ $num_orb_threads = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_servants')
+ {
+ $num_servants = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_csdthreads')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'collocated_big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_remote_clients = 0;
+ $num_collocated_clients = 40;
+ }
+ elsif ($subtest eq 'big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ $num_collocated_clients = 40;
+ }
+ elsif ($subtest eq 'remote_huge')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 400;
+ $num_loops = $num_loops / 10;
+ # 15 minute server timeout
+ $server_timeout_secs = 1800;
+ }
+ elsif ($subtest eq 'collocated_huge')
+ {
+ $num_csd_threads = 20;
+ $num_servants = 10;
+ $num_remote_clients = 0;
+ $num_collocated_clients = 40;
+ }
+ elsif ($subtest eq 'usage')
+ {
+ print STDOUT "Usage: $0 [<subtest>]\n" .
+ "\n" .
+ "Supported <subtest> values:\n" .
+ "\n" .
+ "\tremote\n" .
+ "\tcollocated\n" .
+ "\tremote_orbthreads\n" .
+ "\tremote_servants\n" .
+ "\tremote_csdthreads\n" .
+ "\tremote_big\n" .
+ "\tcollocated_big\n" .
+ "\tbig\n" .
+ "\tremote_huge\n" .
+ "\tusage\n" .
+ "\n";
+ exit 0;
+ }
+ else
+ {
+ print STDERR "ERROR: invalid subtest argument for $0: $subtest\n";
+ exit 1;
+ }
+}
+
+#Delete old ior files.
+for ($i = 0; $i < $num_servants; $i++) {
+ my $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+ unlink $iorfile[$i];
+}
+
+$SV = new PerlACE::Process("server_main",
+ "-p $iorfname_prefix " .
+ "-s $num_servants " .
+ "-n $num_csd_threads " .
+ "-t $num_orb_threads " .
+ "-r $num_remote_clients " .
+ "-c $num_collocated_clients " .
+ "-l $num_loops " .
+ "-u $use_csd " .
+ "-x $scenario_id " .
+ "-z $trial_id");
+
+$SV->Spawn();
+
+# Wait for the servant ior files created by server.
+for ($i = 0; $i < $num_servants; $i++) {
+ if (PerlACE::waitforfile_timed
+ ($iorfile[$i],
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile[$i]>\n";
+ $SV->Kill();
+ $SV->TimedWait(1);
+ exit 1;
+ }
+}
+
+my $count = 0;
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+ $client_id = $i+1;
+
+ # Round-robin assignment of servants to clients.
+ $j = $i % $num_servants;
+
+ $CLS[$i] = new PerlACE::Process("client_main",
+ "-i file://$iorfile[$j] ".
+ "-n $client_id " .
+ "-l $num_loops");
+
+ $CLS[$i]->Spawn();
+}
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+ $client = $CLS[$i]->WaitKill(600);
+
+ if ($client != 0)
+ {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill(600);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+#Delete ior files generated by this run.
+for ($i = 0; $i < $num_servants; $i++) {
+ unlink $iorfile[$i];
+}
+
+exit $status;
diff --git a/TAO/performance-tests/CSD_Strategy/TestApps/server_main.cpp b/TAO/performance-tests/CSD_Strategy/TestApps/server_main.cpp
new file mode 100644
index 00000000000..d0d2aa30fff
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestApps/server_main.cpp
@@ -0,0 +1,5 @@
+// $Id$
+#include "TestInf/TestAppMain.h"
+#include "ServerApp.h"
+
+TEST_APP_MAIN(ServerApp)
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/AppHelper.cpp b/TAO/performance-tests/CSD_Strategy/TestInf/AppHelper.cpp
new file mode 100644
index 00000000000..0f60191a9bd
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/AppHelper.cpp
@@ -0,0 +1,102 @@
+// $Id$
+#include "AppHelper.h"
+
+void
+AppHelper::ref_to_file(CORBA::ORB_ptr orb,
+ CORBA::Object_ptr obj,
+ const char* filename
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::String_var ior = orb->object_to_string(obj);
+
+ FILE* ior_file = ACE_OS::fopen(filename, "w");
+
+ if (ior_file == 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Cannot open output file [%s] to write IOR.",
+ filename));
+ ACE_THROW (TestAppException());
+ }
+
+ ACE_OS::fprintf(ior_file, "%s", ior.in());
+ ACE_OS::fclose(ior_file);
+}
+
+
+PortableServer::POA_ptr
+AppHelper::create_poa(const char* name,
+ PortableServer::POA_ptr root_poa,
+ PortableServer::POAManager_ptr mgr,
+ CORBA::PolicyList& policies
+ ACE_ENV_ARG_DECL)
+{
+ PortableServer::POA_var child_poa = root_poa->create_POA(name,
+ mgr,
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ if (CORBA::is_nil(child_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to create child POA: %s.\n", name));
+ ACE_THROW_RETURN (TestAppException(), PortableServer::POA::_nil ());
+ }
+
+ return child_poa._retn();
+}
+
+
+CORBA::Object_ptr
+AppHelper::activate_servant(PortableServer::POA_ptr poa,
+ PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ // Activate the servant using the Child POA.
+ PortableServer::ObjectId_var oid
+ = poa->activate_object(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ CORBA::Object_var obj
+ = poa->servant_to_reference(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to convert servant_to_ref.\n"));
+ ACE_THROW_RETURN (TestAppException(), CORBA::Object::_nil ());
+ }
+
+ return obj._retn();
+}
+
+
+bool
+AppHelper::validate_connection (CORBA::Object_ptr obj)
+{
+ for (CORBA::ULong j = 0; j != 100; ++j)
+ {
+ ACE_TRY_NEW_ENV
+ {
+#if (TAO_HAS_CORBA_MESSAGING == 1)
+ CORBA::PolicyList_var unused;
+ obj->_validate_connection (unused
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#else
+ obj->_is_a ("Not_An_IDL_Type"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#endif /* TAO_HAS_MESSAGING == 1 */
+ return true;
+ }
+ ACE_CATCHANY
+ {
+ }
+ ACE_ENDTRY;
+ }
+
+ return false;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/AppHelper.h b/TAO/performance-tests/CSD_Strategy/TestInf/AppHelper.h
new file mode 100644
index 00000000000..bdc6c2ab5b3
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/AppHelper.h
@@ -0,0 +1,114 @@
+// $Id$
+#ifndef APPHELPER_H
+#define APPHELPER_H
+
+#include "CSD_PT_TestInf_Export.h"
+#include "TestAppExceptionC.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/ORB.h"
+#include "ace/OS.h"
+#include "ace/Log_Msg.h"
+
+
+template <typename T>
+struct RefHelper
+{
+ typedef typename T::_ptr_type T_ptr;
+ typedef typename T::_var_type T_var;
+
+ static T_ptr string_to_ref(CORBA::ORB_ptr orb,
+ const char* ior
+ ACE_ENV_ARG_DECL)
+ {
+ CORBA::Object_var obj = orb->string_to_object(ior ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN(T::_nil ());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to convert IOR string to obj ref.\n"));
+ ACE_THROW_RETURN (TestAppException(), T::_nil ());
+ }
+
+ T_var t_obj = T::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN(T::_nil ());
+
+ if (CORBA::is_nil(t_obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to T interface.\n"));
+ ACE_THROW_RETURN (TestAppException(), T::_nil ());
+ }
+
+ return t_obj._retn();
+ }
+
+ static T_ptr resolve_initial_ref(CORBA::ORB_ptr orb,
+ const char* name
+ ACE_ENV_ARG_DECL)
+ {
+ CORBA::Object_var obj
+ = orb->resolve_initial_references(name ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (T::_nil ());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to resolve initial ref for '%s'.\n",
+ name));
+ ACE_THROW_RETURN (TestAppException(), T::_nil ());
+ }
+
+ T_var t_obj = T::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (T::_nil ());
+
+
+ if (CORBA::is_nil(t_obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow resolved initial ref '%s'.\n",
+ name));
+ ACE_THROW_RETURN (TestAppException(), T::_nil ());
+ }
+
+ return t_obj._retn();
+ }
+
+};
+
+struct CSD_PT_TestInf_Export AppHelper
+{
+
+ static void ref_to_file(CORBA::ORB_ptr orb,
+ CORBA::Object_ptr obj,
+ const char* filename
+ ACE_ENV_ARG_DECL);
+
+ static PortableServer::POA_ptr create_poa
+ (const char* name,
+ PortableServer::POA_ptr root_poa,
+ PortableServer::POAManager_ptr mgr,
+ CORBA::PolicyList& policies
+ ACE_ENV_ARG_DECL);
+
+ static CORBA::Object_ptr activate_servant(PortableServer::POA_ptr poa,
+ PortableServer::Servant servant
+ ACE_ENV_ARG_DECL);
+
+ // This helper method is used because there is a chance that the
+ // initial CORBA request made to the target ORB will fail during
+ // connection establishment with a TRANSIENT CORBA SystemException.
+ // This occurs for some platforms (ie, windows) when several clients
+ // make their initial CORBA request to the same ORB at the same time,
+ // causing the ORB to attempt to handle several connection establishments
+ // at one time. Apparently, under certain conditions, it will throw the
+ // TRANSIENT exception to tell the client application to "try again later".
+ // The analogy is making a phone call. Sometimes you get a busy tone.
+ // This means "try again later".
+ // This helper function will retry until the connection establishment
+ // works - or until it decides that enough is enough.
+ static bool validate_connection (CORBA::Object_ptr obj);
+};
+
+#endif
+
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/AppShutdown.cpp b/TAO/performance-tests/CSD_Strategy/TestInf/AppShutdown.cpp
new file mode 100644
index 00000000000..79d7f28c0d9
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/AppShutdown.cpp
@@ -0,0 +1,84 @@
+// $Id$
+#include "AppShutdown.h"
+#include "TestAppExceptionC.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_unistd.h"
+
+AppShutdown::AppShutdown()
+ : num_clients_(0),
+ num_clients_shutdown_(0)
+{
+}
+
+
+AppShutdown::~AppShutdown()
+{
+}
+
+
+void
+AppShutdown::init(CORBA::ORB_ptr orb,
+ unsigned num_clients
+ ACE_ENV_ARG_DECL)
+{
+ if ((!CORBA::is_nil(this->orb_.in())) ||
+ (CORBA::is_nil(orb)) ||
+ (num_clients == 0))
+ {
+ // Already init()'ed, or bad argument values.
+ ACE_THROW(TestAppException());
+ }
+ else
+ {
+ this->orb_ = CORBA::ORB::_duplicate(orb);
+ this->num_clients_ = num_clients;
+ this->num_clients_shutdown_ = 0;
+ }
+}
+
+
+void
+AppShutdown::wait ()
+{
+ this->orb_shutdown_task_.wait();
+}
+
+
+void
+AppShutdown::client_done()
+{
+ if ((this->num_clients_ == 0) || (CORBA::is_nil(this->orb_.in())))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) AppShutdown was never initialized.\n"));
+ return;
+ }
+
+ unsigned cur_shutdown;
+
+ {
+ GuardType guard(this->lock_);
+ cur_shutdown = ++this->num_clients_shutdown_;
+ }
+
+ if (cur_shutdown == this->num_clients_)
+ {
+ // Sleep for one second before shutting down the ORB. This
+ // is a poor-man version of "wait until the CSD request queue drains".
+ ACE_OS::sleep(1);
+ this->orb_shutdown_task_.orb(this->orb_.in());
+ if (this->orb_shutdown_task_.open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) AppShutdown failed to create orb "\
+ "shutdown thread.\n"));
+ return;
+ }
+ }
+}
+
+
+AppShutdown*
+AppShutdown::instance ()
+{
+ static AppShutdown app_shutdown;
+ return &app_shutdown;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/AppShutdown.h b/TAO/performance-tests/CSD_Strategy/TestInf/AppShutdown.h
new file mode 100644
index 00000000000..481659d734e
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/AppShutdown.h
@@ -0,0 +1,42 @@
+// $Id$
+#ifndef APP_SHUTDOWN_H
+#define APP_SHUTDOWN_H
+
+#include "CSD_PT_TestInf_Export.h"
+#include "OrbShutdownTask.h"
+#include "tao/ORB.h"
+
+class CSD_PT_TestInf_Export AppShutdown
+{
+ public:
+
+ AppShutdown();
+ virtual ~AppShutdown();
+
+ void init(CORBA::ORB_ptr orb,
+ unsigned num_clients
+ ACE_ENV_ARG_DECL);
+
+ void wait ();
+
+ void client_done();
+
+ static AppShutdown* instance ();
+
+ private:
+
+ typedef ACE_SYNCH_MUTEX LockType;
+ typedef ACE_Guard<LockType> GuardType;
+
+ LockType lock_;
+ CORBA::ORB_var orb_;
+ unsigned num_clients_;
+ unsigned num_clients_shutdown_;
+
+ OrbShutdownTask orb_shutdown_task_;
+};
+
+
+#define TheAppShutdown AppShutdown::instance()
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/CSD_PT_TestInf_Export.h b/TAO/performance-tests/CSD_Strategy/TestInf/CSD_PT_TestInf_Export.h
new file mode 100644
index 00000000000..91f36276272
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/CSD_PT_TestInf_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s CSD_PT_TestInf
+// ------------------------------
+#ifndef CSD_PT_TESTINF_EXPORT_H
+#define CSD_PT_TESTINF_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (CSD_PT_TESTINF_HAS_DLL)
+# define CSD_PT_TESTINF_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && CSD_PT_TESTINF_HAS_DLL */
+
+#if !defined (CSD_PT_TESTINF_HAS_DLL)
+# define CSD_PT_TESTINF_HAS_DLL 1
+#endif /* ! CSD_PT_TESTINF_HAS_DLL */
+
+#if defined (CSD_PT_TESTINF_HAS_DLL) && (CSD_PT_TESTINF_HAS_DLL == 1)
+# if defined (CSD_PT_TESTINF_BUILD_DLL)
+# define CSD_PT_TestInf_Export ACE_Proper_Export_Flag
+# define CSD_PT_TESTINF_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define CSD_PT_TESTINF_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* CSD_PT_TESTINF_BUILD_DLL */
+# define CSD_PT_TestInf_Export ACE_Proper_Import_Flag
+# define CSD_PT_TESTINF_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define CSD_PT_TESTINF_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* CSD_PT_TESTINF_BUILD_DLL */
+#else /* CSD_PT_TESTINF_HAS_DLL == 1 */
+# define CSD_PT_TestInf_Export
+# define CSD_PT_TESTINF_SINGLETON_DECLARATION(T)
+# define CSD_PT_TESTINF_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* CSD_PT_TESTINF_HAS_DLL == 1 */
+
+// Set CSD_PT_TESTINF_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (CSD_PT_TESTINF_NTRACE)
+# if (ACE_NTRACE == 1)
+# define CSD_PT_TESTINF_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define CSD_PT_TESTINF_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !CSD_PT_TESTINF_NTRACE */
+
+#if (CSD_PT_TESTINF_NTRACE == 1)
+# define CSD_PT_TESTINF_TRACE(X)
+#else /* (CSD_PT_TESTINF_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define CSD_PT_TESTINF_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (CSD_PT_TESTINF_NTRACE == 1) */
+
+#endif /* CSD_PT_TESTINF_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/CancelledException.idl b/TAO/performance-tests/CSD_Strategy/TestInf/CancelledException.idl
new file mode 100644
index 00000000000..8f9afcf68de
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/CancelledException.idl
@@ -0,0 +1,7 @@
+// $Id$
+#ifndef CANCELAPPXCEPTION_IDL
+#define CANCELAPPXCEPTION_IDL
+
+exception CancelledException {};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/ClientEngine.cpp b/TAO/performance-tests/CSD_Strategy/TestInf/ClientEngine.cpp
new file mode 100644
index 00000000000..361bb3cd465
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/ClientEngine.cpp
@@ -0,0 +1,12 @@
+// $Id$
+#include "ClientEngine.h"
+
+
+ClientEngine::ClientEngine()
+{
+}
+
+
+ClientEngine::~ClientEngine()
+{
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/ClientEngine.h b/TAO/performance-tests/CSD_Strategy/TestInf/ClientEngine.h
new file mode 100644
index 00000000000..93acb571cdc
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/ClientEngine.h
@@ -0,0 +1,39 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ClientEngine.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef CLIENT_ENGINE_H
+#define CLIENT_ENGINE_H
+
+#include "CSD_PT_TestInf_Export.h"
+#include "tao/Intrusive_Ref_Count_Base_T.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+#include "tao/Environment.h"
+#include "ace/Synch.h"
+#include "ace/CORBA_macros.h"
+
+
+class ClientEngine;
+typedef TAO_Intrusive_Ref_Count_Handle<ClientEngine> ClientEngine_Handle;
+
+
+class CSD_PT_TestInf_Export ClientEngine : public TAO_Intrusive_Ref_Count_Base<ACE_SYNCH_MUTEX>
+{
+ public:
+
+ ClientEngine();
+ virtual ~ClientEngine();
+
+ virtual bool execute(unsigned num_loops
+ ACE_ENV_ARG_DECL) = 0;
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/ClientTask.cpp b/TAO/performance-tests/CSD_Strategy/TestInf/ClientTask.cpp
new file mode 100644
index 00000000000..9b5ad8bc3cd
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/ClientTask.cpp
@@ -0,0 +1,117 @@
+// $Id$
+// This may look like C, but it's really -*- C++ -*-
+#include "ClientTask.h"
+#include "tao/Exception.h"
+#include "ace/SString.h"
+
+
+ClientTask::ClientTask()
+ : failure_count_(0),
+ num_loops_(1)
+{
+}
+
+
+ClientTask::~ClientTask()
+{
+}
+
+
+void
+ClientTask::add_engine(ClientEngine* engine)
+{
+ // Pass in false so that _add_ref() is called.
+ ClientEngine_Handle engine_handle(engine,false);
+ this->engines_.push_back(engine_handle);
+}
+
+
+void
+ClientTask::num_loops(unsigned num_loops)
+{
+ this->num_loops_ = num_loops;
+}
+
+
+int
+ClientTask::open(void*)
+{
+ unsigned num_threads = this->engines_.size();
+
+ if (num_threads == 0)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) ClientTask cannot activate 0 threads.\n"),
+ -1);
+ }
+
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, num_threads) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) ClientTask failed to activate "
+ "the %d client threads.\n", num_threads),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+ClientTask::svc()
+{
+ ClientEngine_Handle engine;
+ unsigned num_loops;
+
+ {
+ GuardType guard(this->lock_);
+ this->engines_.get(engine, this->engines_.size() - 1);
+ this->engines_.pop_back();
+ num_loops = this->num_loops_;
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ if (engine->execute(num_loops ACE_ENV_ARG_PARAMETER) == false)
+ {
+ GuardType guard(this->lock_);
+ this->failure_count_++;
+ }
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "ClientTask::svc Caught exception from execute():");
+
+ GuardType guard(this->lock_);
+ this->failure_count_ ++;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) ClientTask::svc caught unknown (...) exception "\
+ "in execute() " ));
+ GuardType guard(this->lock_);
+ this->failure_count_++;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+ClientTask::close(u_long)
+{
+ return 0;
+}
+
+
+unsigned
+ClientTask::failure_count() const
+{
+ return this->failure_count_;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/ClientTask.h b/TAO/performance-tests/CSD_Strategy/TestInf/ClientTask.h
new file mode 100644
index 00000000000..a99ccc6ad43
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/ClientTask.h
@@ -0,0 +1,53 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ClientTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef CLIENT_TASK_H
+#define CLIENT_TASK_H
+
+#include "CSD_PT_TestInf_Export.h"
+#include "ClientEngine.h"
+#include "ace/Task.h"
+#include "ace/Vector_T.h"
+#include "ace/Synch.h"
+
+
+class CSD_PT_TestInf_Export ClientTask : public ACE_Task_Base
+{
+ public:
+
+ ClientTask();
+ virtual ~ClientTask();
+
+ void add_engine(ClientEngine* engine);
+ void num_loops(unsigned num_loops);
+
+ virtual int open(void* arg = 0);
+ virtual int svc();
+ virtual int close(u_long);
+
+ unsigned failure_count() const;
+
+
+ private:
+
+ typedef ACE_SYNCH_MUTEX LockType;
+ typedef ACE_Guard<LockType> GuardType;
+
+ typedef ACE_Vector<ClientEngine_Handle> EngineVector;
+
+ LockType lock_;
+ EngineVector engines_;
+ unsigned failure_count_;
+ unsigned num_loops_;
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/CustomException.idl b/TAO/performance-tests/CSD_Strategy/TestInf/CustomException.idl
new file mode 100644
index 00000000000..794900c41ce
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/CustomException.idl
@@ -0,0 +1,7 @@
+// $Id$
+#ifndef CUSTOMEXCEPTION_IDL
+#define CUSTOMEXCEPTION_IDL
+
+exception CustomException {};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/FooException.idl b/TAO/performance-tests/CSD_Strategy/TestInf/FooException.idl
new file mode 100644
index 00000000000..4f76953e24c
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/FooException.idl
@@ -0,0 +1,7 @@
+// $Id$
+#ifndef FOOEXCEPTION_IDL
+#define FOOEXCEPTION_IDL
+
+exception FooException {};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/OrbRunner.cpp b/TAO/performance-tests/CSD_Strategy/TestInf/OrbRunner.cpp
new file mode 100644
index 00000000000..fc2ddbdec04
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/OrbRunner.cpp
@@ -0,0 +1,57 @@
+// $Id$
+#include "OrbRunner.h"
+#include "OrbTask.h"
+#include "TestAppExceptionC.h"
+
+
+OrbRunner::OrbRunner(CORBA::ORB_ptr orb, unsigned num_orb_threads)
+ : orb_(CORBA::ORB::_duplicate(orb)),
+ num_orb_threads_(num_orb_threads)
+{
+}
+
+
+OrbRunner::~OrbRunner()
+{
+}
+
+
+void
+OrbRunner::run(ACE_ENV_SINGLE_ARG_DECL)
+{
+ ACE_ASSERT(this->num_orb_threads_ > 0);
+
+ // If the num_orb_threads_ is exactly one, then just use the current
+ // (mainline) thread to run the ORB event loop.
+ if (this->num_orb_threads_ == 1)
+ {
+ // Since the num_orb_threads_ is exactly one, we just use the current
+ // (mainline) thread to run the ORB event loop.
+ this->orb_->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ else
+ {
+ // The num_orb_threads_ is greater than 1, so we will use an OrbTask
+ // (active object) to run the ORB event loop in (num_orb_threads_ - 1)
+ // threads. We use the current (mainline) thread as the other thread
+ // running the ORB event loop.
+ OrbTask orb_task(this->orb_.in(), this->num_orb_threads_ - 1);
+
+ // Activate the OrbTask worker threads
+ if (orb_task.open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to open the OrbTask.\n"));
+ ACE_THROW(TestAppException());
+ }
+
+ // This will use the current (mainline) thread to run the ORB event loop.
+ this->orb_->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Now that the current thread has unblocked from running the orb,
+ // make sure to wait for all of the worker threads to complete.
+ orb_task.wait();
+ }
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/OrbRunner.h b/TAO/performance-tests/CSD_Strategy/TestInf/OrbRunner.h
new file mode 100644
index 00000000000..cdbbcfea222
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/OrbRunner.h
@@ -0,0 +1,24 @@
+// $Id$
+#ifndef ORB_RUNNER_H
+#define ORB_RUNNER_H
+
+#include "CSD_PT_TestInf_Export.h"
+#include "tao/ORB.h"
+
+class CSD_PT_TestInf_Export OrbRunner
+{
+ public:
+
+ OrbRunner(CORBA::ORB_ptr orb, unsigned num_orb_threads = 1);
+ virtual ~OrbRunner();
+
+ void run(ACE_ENV_SINGLE_ARG_DECL);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+ unsigned num_orb_threads_;
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.cpp b/TAO/performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.cpp
new file mode 100644
index 00000000000..79ba1ba3f5e
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.cpp
@@ -0,0 +1,75 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbShutdownTask.h"
+#include "ace/CORBA_macros.h"
+#include "ace/OS_NS_unistd.h"
+
+
+OrbShutdownTask::OrbShutdownTask()
+{
+}
+
+
+OrbShutdownTask::~OrbShutdownTask()
+{
+}
+
+
+void
+OrbShutdownTask::orb(CORBA::ORB_ptr orb)
+{
+ this->orb_ = CORBA::ORB::_duplicate(orb);
+}
+
+
+int
+OrbShutdownTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbShutdownTask failed to open().\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::svc()
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->shutdown(0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::shutdown() call "
+ "in OrbShutdownTask::svc().\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.h b/TAO/performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.h
new file mode 100644
index 00000000000..11f2bbd341a
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/OrbShutdownTask.h
@@ -0,0 +1,40 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_SHUTDOWN_TASK_H
+#define ORB_SHUTDOWN_TASK_H
+
+#include "CSD_PT_TestInf_Export.h"
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+
+class CSD_PT_TestInf_Export OrbShutdownTask : public ACE_Task_Base
+{
+ public:
+
+ OrbShutdownTask();
+ virtual ~OrbShutdownTask();
+
+ void orb(CORBA::ORB_ptr orb);
+
+ virtual int open(void*);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/OrbTask.cpp b/TAO/performance-tests/CSD_Strategy/TestInf/OrbTask.cpp
new file mode 100644
index 00000000000..bca9d522e94
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/OrbTask.cpp
@@ -0,0 +1,98 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbTask.h"
+
+namespace { enum { MAX_ORB_TASK_WORKER_THREADS = 20 }; }
+
+
+OrbTask::OrbTask(CORBA::ORB_ptr orb, unsigned num_threads)
+ : orb_(CORBA::ORB::_duplicate(orb)),
+ num_threads_(num_threads)
+{
+}
+
+
+OrbTask::~OrbTask()
+{
+}
+
+
+int
+OrbTask::open(void*)
+{
+ if (this->num_threads_ < 1)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "num_threads_ (%d) is less-than 1.\n",
+ this->num_threads_),
+ -1);
+ }
+
+ if (this->num_threads_ > MAX_ORB_TASK_WORKER_THREADS)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "num_threads_ (%d) is too large. Max is %d.\n",
+ this->num_threads_, MAX_ORB_TASK_WORKER_THREADS),
+ -1);
+ }
+
+ if (CORBA::is_nil(this->orb_.in()))
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "ORB object reference is nil.\n"),
+ -1);
+ }
+
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, this->num_threads_) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to activate "
+ "(%d) worker threads.\n",
+ this->num_threads_),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbTask::svc()
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::run() method. "
+ "OrbTask is stopping.\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/OrbTask.h b/TAO/performance-tests/CSD_Strategy/TestInf/OrbTask.h
new file mode 100644
index 00000000000..3631273c548
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/OrbTask.h
@@ -0,0 +1,39 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_TASK_H
+#define ORB_TASK_H
+
+#include "CSD_PT_TestInf_Export.h"
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+
+class CSD_PT_TestInf_Export OrbTask : public ACE_Task_Base
+{
+ public:
+
+ OrbTask(CORBA::ORB_ptr orb, unsigned num_threads = 1);
+ virtual ~OrbTask();
+
+ virtual int open(void*);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+ unsigned num_threads_;
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/README b/TAO/performance-tests/CSD_Strategy/TestInf/README
new file mode 100644
index 00000000000..1d7f59a5c47
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/README
@@ -0,0 +1,13 @@
+/**
+
+@page CSD_Strategy TestInf README File
+
+ This is the test infrastructure library. It contains the common shared
+code such as test exception idl files, the helper functions that wrap multiple
+TAO operations and the classes provide the basic test functionalities. Adding
+this library is to simplify the development of the new tests.
+
+*/
+
+
+
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/ServantList_T.cpp b/TAO/performance-tests/CSD_Strategy/TestInf/ServantList_T.cpp
new file mode 100644
index 00000000000..22133fa9868
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/ServantList_T.cpp
@@ -0,0 +1,102 @@
+// $Id$
+#include "ServantList_T.h"
+#include "AppHelper.h"
+#include "TestAppExceptionC.h"
+
+
+template <typename T>
+ServantList<T>::ServantList()
+{
+}
+
+
+template <typename T>
+ServantList<T>::~ServantList()
+{
+}
+
+
+template <typename T>
+void
+ServantList<T>::create_and_activate(unsigned num_servants,
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char* ior_fname_prefix
+ ACE_ENV_ARG_DECL)
+{
+ for (unsigned i = 0; i < num_servants; i++)
+ {
+ char buf[32];
+ ACE_OS::sprintf(buf, "%02d", i + 1);
+ ACE_CString filename = ACE_CString(ior_fname_prefix) + "_" + buf + ".ior";
+ ServantRecord record;
+ record.servant_ = new T();
+ record.safe_servant_ = record.servant_;
+
+ CORBA::Object_var obj
+ = AppHelper::activate_servant(poa,
+ record.safe_servant_.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ AppHelper::ref_to_file(orb, obj.in(), filename.c_str() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ record.obj_ = T_stub::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil(record.obj_.in()))
+ {
+ ACE_THROW (TestAppException());
+ }
+
+ this->servant_records_.push_back(record);
+ }
+}
+
+
+template <typename T>
+void
+ServantList<T>::create_and_activate(unsigned num_servants,
+ PortableServer::POA_ptr poa
+ ACE_ENV_ARG_DECL)
+{
+ for (unsigned i = 0; i < num_servants; i++)
+ {
+ ServantRecord record;
+ record.servant_ = new T();
+ record.safe_servant_ = record.servant_;
+
+ CORBA::Object_var obj
+ = AppHelper::activate_servant(poa,
+ record.safe_servant_.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ record.obj_ = T_stub::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil(record.obj_.in()))
+ {
+ ACE_THROW (TestAppException());
+ }
+
+ this->servant_records_.push_back(record);
+ }
+}
+
+
+template <typename T>
+typename ServantList<T>::T_stub_ptr
+ServantList<T>::objref(unsigned index)
+{
+ return T_stub::_duplicate(this->servant_records_[index].obj_.in());
+}
+
+
+template <typename T>
+T*
+ServantList<T>::servant(unsigned index)
+{
+ return this->servant_records_[index].servant_;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/ServantList_T.h b/TAO/performance-tests/CSD_Strategy/TestInf/ServantList_T.h
new file mode 100644
index 00000000000..57143d889c1
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/ServantList_T.h
@@ -0,0 +1,67 @@
+// $Id$
+#ifndef SERVANTLIST_T_H
+#define SERVANTLIST_T_H
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/Servant_Base.h"
+#include "ace/Vector_T.h"
+
+
+// The T type is a concrete servant type.
+template <class T>
+class ServantList
+{
+ public:
+
+ typedef typename T::_stub_type T_stub;
+ typedef typename T::_stub_ptr_type T_stub_ptr;
+ typedef typename T::_stub_var_type T_stub_var;
+
+ ServantList();
+ ~ServantList();
+
+ /// Activate servant and output ior to a file.
+ void create_and_activate(unsigned num_servants,
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char* ior_fname_prefix
+ ACE_ENV_ARG_DECL);
+
+ /// Activate servant and not output ior to a file.
+ void create_and_activate(unsigned num_servants,
+ PortableServer::POA_ptr poa
+ ACE_ENV_ARG_DECL);
+
+
+ /// Get a (copy) of one of the object references (for a specific servant).
+ T_stub_ptr objref(unsigned index);
+
+ /// This doesn't return a copy.
+ T* servant(unsigned index);
+
+
+ private:
+
+ struct ServantRecord
+ {
+ T* servant_;
+ PortableServer::ServantBase_var safe_servant_;
+ T_stub_var obj_;
+ };
+
+ typedef ACE_Vector<ServantRecord> ServantRecordVector;
+
+ ServantRecordVector servant_records_;
+};
+
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ServantList_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("ServantList_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#endif /* SERVANTLIST_T_H */
+
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/TestAppBase.cpp b/TAO/performance-tests/CSD_Strategy/TestInf/TestAppBase.cpp
new file mode 100644
index 00000000000..f2a2e97b7a2
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/TestAppBase.cpp
@@ -0,0 +1,30 @@
+// $Id$
+#include "TestAppBase.h"
+
+TestAppBase::TestAppBase(const char* name)
+ : name_(name)
+{
+}
+
+
+TestAppBase::~TestAppBase()
+{
+}
+
+
+const char*
+TestAppBase::name() const
+{
+ return this->name_.c_str();
+}
+
+
+int
+TestAppBase::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int rc = this->run_i(argc, argv ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Convert 1 to 0. Leave 0 and -1 as they are.
+ return (rc == 1) ? 0 : rc;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/TestAppBase.h b/TAO/performance-tests/CSD_Strategy/TestInf/TestAppBase.h
new file mode 100644
index 00000000000..b14436b623c
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/TestAppBase.h
@@ -0,0 +1,36 @@
+// $Id$
+#ifndef TESTAPPBASE_H
+#define TESTAPPBASE_H
+
+#include "CSD_PT_TestInf_Export.h"
+#include "ace/SString.h"
+#include "tao/Environment.h"
+#include "ace/CORBA_macros.h"
+
+
+class CSD_PT_TestInf_Export TestAppBase
+{
+ public:
+
+ virtual ~TestAppBase();
+
+ // Returns 0 for success, and -1 for failure.
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+ const char* name() const;
+
+
+ protected:
+
+ TestAppBase(const char* name);
+
+ // Returns -1 for failure, 0 for success
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL) = 0;
+
+
+ private:
+
+ ACE_CString name_;
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/TestAppException.idl b/TAO/performance-tests/CSD_Strategy/TestInf/TestAppException.idl
new file mode 100644
index 00000000000..2ac53939b77
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/TestAppException.idl
@@ -0,0 +1,7 @@
+// $Id$
+#ifndef TESTAPPXCEPTION_IDL
+#define TESTAPPXCEPTION_IDL
+
+exception TestAppException {};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/TestAppMain.h b/TAO/performance-tests/CSD_Strategy/TestInf/TestAppMain.h
new file mode 100644
index 00000000000..062b6fc0c8e
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/TestAppMain.h
@@ -0,0 +1,49 @@
+// $Id$
+#ifndef TESTAPPMAIN_H
+#define TESTAPPMAIN_H
+
+#include "ace/Log_Msg.h"
+#include "ace/SString.h"
+#include "tao/Exception.h"
+#include "tao/Environment.h"
+
+#define TEST_APP_MAIN(APP_TYPE) \
+int \
+main(int argc, char* argv[]) \
+{ \
+ ACE_LOG_MSG->priority_mask(LM_TRACE | \
+ LM_DEBUG | \
+ LM_INFO | \
+ LM_NOTICE | \
+ LM_WARNING | \
+ LM_ERROR | \
+ LM_CRITICAL | \
+ LM_ALERT | \
+ LM_EMERGENCY, \
+ ACE_Log_Msg::PROCESS); \
+\
+ APP_TYPE app; \
+\
+ ACE_TRY_NEW_ENV \
+ { \
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER); \
+ ACE_TRY_CHECK; \
+ return ret; \
+ } \
+ ACE_CATCHANY \
+ { \
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, \
+ "Caught exception:"); \
+ } \
+ ACE_CATCHALL \
+ { \
+ ACE_ERROR((LM_ERROR, \
+ "(%P|%t) Unknown (...) exception caught in main() " \
+ "for App [%d].\n", app.name())); \
+ } \
+ ACE_ENDTRY; \
+ \
+ return 1; \
+}
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestInf/csd_pt_testinf.mpc b/TAO/performance-tests/CSD_Strategy/TestInf/csd_pt_testinf.mpc
new file mode 100644
index 00000000000..39bea8a0c18
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestInf/csd_pt_testinf.mpc
@@ -0,0 +1,38 @@
+//$Id$
+project : taolib_with_idl, csd_threadpool {
+ sharedname = CSD_PT_TestInf
+ dynamicflags = CSD_PT_TESTINF_BUILD_DLL
+ idlflags += -Wb,export_macro=CSD_PT_TestInf_Export -Wb,export_include=CSD_PT_TestInf_Export.h
+ includes += $(TAO_ROOT)/tao
+
+ IDL_Files {
+ FooException.idl
+ TestAppException.idl
+ CancelledException.idl
+ CustomException.idl
+ }
+
+ Source_Files {
+ AppHelper.cpp
+ AppShutdown.cpp
+ ClientEngine.cpp
+ ClientTask.cpp
+ OrbRunner.cpp
+ OrbShutdownTask.cpp
+ OrbTask.cpp
+ TestAppBase.cpp
+ FooExceptionC.cpp
+ FooExceptionS.cpp
+ TestAppExceptionC.cpp
+ TestAppExceptionS.cpp
+ CancelledExceptionC.cpp
+ CancelledExceptionS.cpp
+ CustomExceptionC.cpp
+ CustomExceptionS.cpp
+ }
+
+ Template_Files {
+ ServantList_T.cpp
+ }
+
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/CSD_PT_TestServant_Export.h b/TAO/performance-tests/CSD_Strategy/TestServant/CSD_PT_TestServant_Export.h
new file mode 100644
index 00000000000..6d33bdbe291
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/CSD_PT_TestServant_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s CSD_PT_TestServant
+// ------------------------------
+#ifndef CSD_PT_TESTSERVANT_EXPORT_H
+#define CSD_PT_TESTSERVANT_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (CSD_PT_TESTSERVANT_HAS_DLL)
+# define CSD_PT_TESTSERVANT_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && CSD_PT_TESTSERVANT_HAS_DLL */
+
+#if !defined (CSD_PT_TESTSERVANT_HAS_DLL)
+# define CSD_PT_TESTSERVANT_HAS_DLL 1
+#endif /* ! CSD_PT_TESTSERVANT_HAS_DLL */
+
+#if defined (CSD_PT_TESTSERVANT_HAS_DLL) && (CSD_PT_TESTSERVANT_HAS_DLL == 1)
+# if defined (CSD_PT_TESTSERVANT_BUILD_DLL)
+# define CSD_PT_TestServant_Export ACE_Proper_Export_Flag
+# define CSD_PT_TESTSERVANT_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define CSD_PT_TESTSERVANT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* CSD_PT_TESTSERVANT_BUILD_DLL */
+# define CSD_PT_TestServant_Export ACE_Proper_Import_Flag
+# define CSD_PT_TESTSERVANT_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define CSD_PT_TESTSERVANT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* CSD_PT_TESTSERVANT_BUILD_DLL */
+#else /* CSD_PT_TESTSERVANT_HAS_DLL == 1 */
+# define CSD_PT_TestServant_Export
+# define CSD_PT_TESTSERVANT_SINGLETON_DECLARATION(T)
+# define CSD_PT_TESTSERVANT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* CSD_PT_TESTSERVANT_HAS_DLL == 1 */
+
+// Set CSD_PT_TESTSERVANT_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (CSD_PT_TESTSERVANT_NTRACE)
+# if (ACE_NTRACE == 1)
+# define CSD_PT_TESTSERVANT_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define CSD_PT_TESTSERVANT_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !CSD_PT_TESTSERVANT_NTRACE */
+
+#if (CSD_PT_TESTSERVANT_NTRACE == 1)
+# define CSD_PT_TESTSERVANT_TRACE(X)
+#else /* (CSD_PT_TESTSERVANT_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define CSD_PT_TESTSERVANT_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (CSD_PT_TESTSERVANT_NTRACE == 1) */
+
+#endif /* CSD_PT_TESTSERVANT_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/Foo.idl b/TAO/performance-tests/CSD_Strategy/TestServant/Foo.idl
new file mode 100644
index 00000000000..41663869082
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/Foo.idl
@@ -0,0 +1,29 @@
+// $Id$
+#ifndef FOO_IDL
+#define FOO_IDL
+
+#include "TestInf/FooException.idl"
+
+interface Foo
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, 1 "in" argument
+ long op3(in long value);
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Client calls this last. The last client to claim that it is
+ /// done will cause the server to shutdown.
+ void done();
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.cpp b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.cpp
new file mode 100644
index 00000000000..a5f4212e47e
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.cpp
@@ -0,0 +1,88 @@
+// $Id$
+#include "Foo_ClientEngine.h"
+#include "Foo_Statistics.h"
+#include "TestInf/TestAppExceptionC.h"
+#include "TestInf/AppHelper.h"
+#include "ace/Log_Msg.h"
+
+
+Foo_ClientEngine::Foo_ClientEngine(Foo_ptr obj, unsigned client_id)
+ : obj_(Foo::_duplicate(obj)),
+ client_id_(client_id)
+{
+}
+
+
+Foo_ClientEngine::~Foo_ClientEngine()
+{
+}
+
+
+bool
+Foo_ClientEngine::execute(unsigned num_loops ACE_ENV_ARG_DECL)
+{
+ // Make sure the connection is established before making
+ // remote invocations.
+ if (AppHelper::validate_connection(this->obj_.in()) == false)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t)Foo_ClientEngine::execute - "
+ "client %d connect failed.\n", this->client_id_));
+ return false;
+ }
+
+ // Verify the return values and return the results.
+ bool success = true;
+
+ for (unsigned loop = 0; loop < num_loops; loop++)
+ {
+ CORBA::Long i = this->client_id_;
+
+ this->obj_->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ this->obj_->op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ CORBA::Long value = this->obj_->op3(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ success = (value != i) ? false : success;
+
+ for (CORBA::Long j = 1; j <= 5; j++)
+ {
+ this->obj_->op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ }
+
+ bool caught_exception = false;
+
+ ACE_TRY_NEW_ENV
+ {
+ this->obj_->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ // Expected
+ caught_exception = true;
+ }
+ ACE_ENDTRY;
+
+ success = (!caught_exception) ? false : success;
+ }
+
+ this->obj_->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ return success;
+}
+
+
+void
+Foo_ClientEngine::expected_results(Foo_Statistics& stats)
+{
+ stats.expected(1, 1);
+ stats.expected(2, 1);
+ stats.expected(3, 1);
+ stats.expected(4, 0);
+ stats.expected(4, 5);
+ stats.expected(5, 1);
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.h b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.h
new file mode 100644
index 00000000000..c704a9a65cb
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_ClientEngine.h
@@ -0,0 +1,41 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_ClientEngine.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_CLIENT_ENGINE_H
+#define FOO_CLIENT_ENGINE_H
+
+#include "CSD_PT_TestServant_Export.h"
+#include "TestInf/ClientEngine.h"
+#include "FooC.h"
+
+class Foo_Statistics;
+
+
+class CSD_PT_TestServant_Export Foo_ClientEngine : public ClientEngine
+{
+ public:
+
+ Foo_ClientEngine(Foo_ptr obj, unsigned client_id = 0);
+ virtual ~Foo_ClientEngine();
+
+ virtual bool execute(unsigned num_loops ACE_ENV_ARG_DECL);
+
+ static void expected_results(Foo_Statistics& stats);
+
+
+ private:
+
+ Foo_var obj_;
+ unsigned client_id_;
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/Foo_Statistics.cpp b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_Statistics.cpp
new file mode 100644
index 00000000000..6fe6e95fcff
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_Statistics.cpp
@@ -0,0 +1,75 @@
+// $Id$
+#include "Foo_Statistics.h"
+#include "Foo_ClientEngine.h"
+
+
+Foo_Statistics::Foo_Statistics()
+ : num_clients_(0),
+ num_loops_(0)
+{
+ for (unsigned i = 0; i < 5; i++)
+ {
+ this->expected_[i] = 0;
+ this->actual_[i] = 0;
+ }
+}
+
+
+Foo_Statistics::~Foo_Statistics()
+{
+}
+
+
+void
+Foo_Statistics::init(unsigned num_clients, unsigned num_loops)
+{
+ this->num_clients_ = num_clients;
+ this->num_loops_ = num_loops;
+}
+
+
+void
+Foo_Statistics::expected(unsigned op_num, unsigned count)
+{
+ this->expected_[op_num-1] = count * this->num_clients_ * this->num_loops_;
+}
+
+
+void
+Foo_Statistics::actual(unsigned op_num, unsigned count)
+{
+ this->actual_[op_num-1] += count;
+}
+
+
+bool
+Foo_Statistics::actual_vs_expected()
+{
+ for (unsigned i = 0; i < 5; i++)
+ {
+ if (this->expected_[i] != this->actual_[i])
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "Actual vs. Expected Results Failure: "
+ "op%d() expected: %d, got: %d\n",
+ i, this->expected_[i], this->actual_[i]));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+unsigned
+Foo_Statistics::total() const
+{
+ unsigned t = 0;
+
+ for (unsigned i = 0 ; i < 5; i++)
+ {
+ t += this->expected_[i];
+ }
+
+ return t;
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/Foo_Statistics.h b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_Statistics.h
new file mode 100644
index 00000000000..e864489f9b3
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_Statistics.h
@@ -0,0 +1,33 @@
+// $Id$
+#ifndef FOO_STATISTICS_H
+#define FOO_STATISTICS_H
+
+#include "CSD_PT_TestServant_Export.h"
+
+
+class CSD_PT_TestServant_Export Foo_Statistics
+{
+ public:
+
+ Foo_Statistics();
+ virtual ~Foo_Statistics();
+
+ void init(unsigned num_clients, unsigned num_loops);
+
+ void expected(unsigned op_num, unsigned count);
+ void actual(unsigned op_num, unsigned count);
+
+ bool actual_vs_expected();
+
+ unsigned total() const;
+
+
+ private:
+
+ unsigned num_clients_;
+ unsigned num_loops_;
+ unsigned expected_[5];
+ unsigned actual_[5];
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/Foo_i.cpp b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_i.cpp
new file mode 100644
index 00000000000..cbe2721a94d
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_i.cpp
@@ -0,0 +1,83 @@
+// $Id$
+#include "Foo_i.h"
+#include "TestInf/AppShutdown.h"
+#include "ace/OS.h"
+#include "ace/Time_Value.h"
+
+
+
+
+Foo_i::Foo_i()
+{
+ for (unsigned i = 0; i < 5; i++)
+ {
+ this->op_count_[i] = 0;
+ }
+}
+
+
+Foo_i::~Foo_i()
+{
+}
+
+
+void
+Foo_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[0]++;
+}
+
+
+void
+Foo_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ACE_UNUSED_ARG(value);
+ this->op_count_[1]++;
+}
+
+
+CORBA::Long
+Foo_i::op3(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[2]++;
+ return value;
+}
+
+
+void
+Foo_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ACE_UNUSED_ARG(value);
+ this->op_count_[3]++;
+}
+
+
+void
+Foo_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ this->op_count_[4]++;
+ ACE_THROW (FooException());
+}
+
+
+void
+Foo_i::done(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ TheAppShutdown->client_done();
+}
+
+
+void
+Foo_i::gather_stats(Foo_Statistics& stats)
+{
+ for (unsigned i = 0; i < 5; i++)
+ {
+ stats.actual(i + 1, this->op_count_[i]);
+ }
+}
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/Foo_i.h b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_i.h
new file mode 100644
index 00000000000..b6270ecf0e3
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/Foo_i.h
@@ -0,0 +1,46 @@
+// $Id$
+#ifndef FOO_I_H
+#define FOO_I_H
+
+#include "CSD_PT_TestServant_Export.h"
+#include "FooS.h"
+#include "Foo_Statistics.h"
+
+
+class CSD_PT_TestServant_Export Foo_i : public virtual POA_Foo,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Foo_i();
+ virtual ~Foo_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException,
+ FooException));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+
+ void gather_stats(Foo_Statistics& stats);
+
+
+ private:
+
+ unsigned op_count_[5];
+};
+
+#endif
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/README b/TAO/performance-tests/CSD_Strategy/TestServant/README
new file mode 100644
index 00000000000..b8ccf09aaf1
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/README
@@ -0,0 +1,10 @@
+/**
+
+@page CSD_Strategy TestServant README File
+
+ This is a library for the specific test. It contains test idl files, the
+servant implementaions, test statistics and the client task with sequence
+of remote invocations. Adding this library is to simplify the tests with
+multiple clients or collocated tests.
+
+*/
diff --git a/TAO/performance-tests/CSD_Strategy/TestServant/csd_pt_testservant.mpc b/TAO/performance-tests/CSD_Strategy/TestServant/csd_pt_testservant.mpc
new file mode 100644
index 00000000000..543180258f2
--- /dev/null
+++ b/TAO/performance-tests/CSD_Strategy/TestServant/csd_pt_testservant.mpc
@@ -0,0 +1,20 @@
+//$Id$
+project : csd_pt_testinf_lib {
+ sharedname = CSD_PT_TestServant
+ dynamicflags = CSD_PT_TESTSERVANT_BUILD_DLL
+ idlflags += -Wb,export_macro=CSD_PT_TestServant_Export -Wb,export_include=CSD_PT_TestServant_Export.h
+ includes += $(TAO_ROOT)/tao
+
+ IDL_Files {
+ Foo.idl
+ }
+
+ Source_Files {
+ FooC.cpp
+ FooS.cpp
+ Foo_ClientEngine.cpp
+ Foo_i.cpp
+ Foo_Statistics.cpp
+ }
+
+}
diff --git a/TAO/tao/CSD_Framework.mpc b/TAO/tao/CSD_Framework.mpc
new file mode 100644
index 00000000000..d80d59483e5
--- /dev/null
+++ b/TAO/tao/CSD_Framework.mpc
@@ -0,0 +1,34 @@
+//$Id$
+project : taolib, portableserver, core, pi {
+ sharedname = TAO_CSD_Framework
+ dynamicflags = TAO_CSD_FW_BUILD_DLL
+ includes += $(TAO_ROOT)/tao
+
+ Source_Files {
+ CSD_Framework
+ }
+
+ Header_Files {
+ CSD_Framework
+ }
+
+ Inline_Files {
+ CSD_Framework
+ }
+
+ Template_Files {
+ CSD_Framework
+ }
+
+ Resource_Files {
+ CSD_Framework
+ }
+
+ IDL_Files {
+ CSD_Framework
+ }
+
+ PIDL_Files {
+ CSD_Framework
+ }
+}
diff --git a/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.cpp b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.cpp
new file mode 100644
index 00000000000..63513ba304d
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.cpp
@@ -0,0 +1,56 @@
+// @(#) $Id$
+
+#include "CSD_Default_Servant_Dispatcher.h"
+#include "CSD_POA.h"
+#include "CSD_Strategy_Repository.h"
+#include "ace/Dynamic_Service.h"
+
+ACE_RCSID(CSD_Framework,
+ CSD_Default_Servant_Dispatcher,
+ "$Id$")
+
+
+TAO_CSD_Default_Servant_Dispatcher::~TAO_CSD_Default_Servant_Dispatcher (void)
+{
+}
+
+
+TAO_Root_POA *
+TAO_CSD_Default_Servant_Dispatcher::create_Root_POA (const ACE_CString &name,
+ TAO_POA_Manager &poa_manager,
+ const TAO_POA_Policy_Set &policies,
+ ACE_Lock &lock,
+ TAO_SYNCH_MUTEX &thread_lock,
+ TAO_ORB_Core &orb_core,
+ TAO_Object_Adapter *object_adapter
+ ACE_ENV_ARG_DECL)
+{
+ TAO_CSD_POA *poa = 0;
+
+ ACE_NEW_THROW_EX (poa,
+ TAO_CSD_POA (name,
+ poa_manager,
+ policies,
+ 0,
+ lock,
+ thread_lock,
+ orb_core,
+ object_adapter
+ ACE_ENV_ARG_PARAMETER),
+ CORBA::NO_MEMORY ());
+ ACE_CHECK_RETURN (0);
+
+
+ TAO_CSD_Strategy_Repository *repo =
+ ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance ("TAO_CSD_Strategy_Repository");
+
+ CSD_Framework::Strategy_var strategy = repo->find (name);
+
+ if (! CORBA::is_nil (strategy.in ()))
+ {
+ poa->set_csd_strategy (strategy.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+ }
+
+ return poa;
+}
diff --git a/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h
new file mode 100644
index 00000000000..120630c123b
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h
@@ -0,0 +1,49 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file CSD_Default_Servant_Dispatcher.h
+ *
+ * $Id$
+ *
+ * @author Yan Dai (dai_y@ociweb.com)
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_DEFAULT_SERVANT_DISPATCHER_H
+#define TAO_CSD_DEFAULT_SERVANT_DISPATCHER_H
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/PortableServer/Default_Servant_Dispatcher.h"
+
+/**
+ * @class TAO_CSD_Default_Servant_Dispatcher
+ *
+ * @brief Interface for CSD_POA servant dispatching strategies.
+ */
+class TAO_CSD_FW_Export TAO_CSD_Default_Servant_Dispatcher
+ : public virtual TAO_Default_Servant_Dispatcher
+{
+public:
+ virtual ~TAO_CSD_Default_Servant_Dispatcher (void);
+
+
+ /// Factory method for creating new CSD Root POA.
+ virtual TAO_Root_POA *create_Root_POA (const ACE_CString &name,
+ TAO_POA_Manager &poa_manager,
+ const TAO_POA_Policy_Set &policies,
+ ACE_Lock &lock,
+ TAO_SYNCH_MUTEX &thread_lock,
+ TAO_ORB_Core &orb_core,
+ TAO_Object_Adapter *object_adapter
+ ACE_ENV_ARG_DECL);
+};
+
+#include /**/ "ace/post.h"
+#endif /* TAO_CSD_DEFAULT_SERVANT_DISPATCHER_H */
diff --git a/TAO/tao/CSD_Framework/CSD_FW_Export.h b/TAO/tao/CSD_Framework/CSD_FW_Export.h
new file mode 100644
index 00000000000..edeb9119dc4
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_FW_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s TAO_CSD_FW
+// ------------------------------
+#ifndef TAO_CSD_FW_EXPORT_H
+#define TAO_CSD_FW_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (TAO_CSD_FW_HAS_DLL)
+# define TAO_CSD_FW_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && TAO_CSD_FW_HAS_DLL */
+
+#if !defined (TAO_CSD_FW_HAS_DLL)
+# define TAO_CSD_FW_HAS_DLL 1
+#endif /* ! TAO_CSD_FW_HAS_DLL */
+
+#if defined (TAO_CSD_FW_HAS_DLL) && (TAO_CSD_FW_HAS_DLL == 1)
+# if defined (TAO_CSD_FW_BUILD_DLL)
+# define TAO_CSD_FW_Export ACE_Proper_Export_Flag
+# define TAO_CSD_FW_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define TAO_CSD_FW_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* TAO_CSD_FW_BUILD_DLL */
+# define TAO_CSD_FW_Export ACE_Proper_Import_Flag
+# define TAO_CSD_FW_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define TAO_CSD_FW_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* TAO_CSD_FW_BUILD_DLL */
+#else /* TAO_CSD_FW_HAS_DLL == 1 */
+# define TAO_CSD_FW_Export
+# define TAO_CSD_FW_SINGLETON_DECLARATION(T)
+# define TAO_CSD_FW_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* TAO_CSD_FW_HAS_DLL == 1 */
+
+// Set TAO_CSD_FW_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (TAO_CSD_FW_NTRACE)
+# if (ACE_NTRACE == 1)
+# define TAO_CSD_FW_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define TAO_CSD_FW_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !TAO_CSD_FW_NTRACE */
+
+#if (TAO_CSD_FW_NTRACE == 1)
+# define TAO_CSD_FW_TRACE(X)
+#else /* (TAO_CSD_FW_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define TAO_CSD_FW_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (TAO_CSD_FW_NTRACE == 1) */
+
+#endif /* TAO_CSD_FW_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp
new file mode 100644
index 00000000000..94d71cb86af
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp
@@ -0,0 +1,462 @@
+// $Id$
+#include "CSD_FW_Server_Request_Wrapper.h"
+#include "tao/debug.h"
+#include "tao/ORB_Constants.h"
+#include "ORB_Core.h"
+#include "tao/Transport.h"
+#include "tao/CDR.h"
+
+
+ACE_RCSID (CSD_Framework,
+ FW_Server_Request_Wrapper,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_FW_Server_Request_Wrapper.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::FW_Server_Request_Wrapper::~FW_Server_Request_Wrapper()
+{
+ // Only delete the request if we cloned it.
+ if (this->is_clone_)
+ {
+ // Since this TAO_ServerRequest object is a clone, it
+ // "owns" the input and output CDR objects held by the
+ // incoming_ and outgoing_ data members, respectfully.
+ // Thus, for the clone case, the TAO_ServerRequest dtor
+ // needs to release (aka, delete) the CDR objects.
+ delete this->request_->incoming_;
+
+ // Get the start message block that reference to the data allocated
+ // on the heap.
+ if (this->request_->outgoing_ != 0)
+ {
+ char* buffer = this->request_->outgoing_->begin ()->base ();
+ delete [] buffer;
+ delete this->request_->outgoing_;
+ }
+ if (this->request_->operation_details_ != 0)
+ {
+ char* opname = (char*)this->request_->operation_details_->opname_;
+ delete [] opname;
+ }
+ delete this->request_;
+ }
+}
+
+
+// Assumes that the servant argument is not a NULL pointer.
+void
+TAO::CSD::FW_Server_Request_Wrapper::dispatch
+ (PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ ACE_TRY
+ {
+ servant->_dispatch(*this->request_, 0 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ // Only CORBA exceptions are caught here.
+ ACE_CATCHANY
+ {
+ if (this->request_->collocated())
+ {
+ // For collocated requests, we re-throw the exception.
+ ACE_RE_THROW;
+ }
+ else if (!this->request_->sync_with_server() &&
+ this->request_->response_expected() &&
+ !this->request_->deferred_reply())
+ {
+ // The request is a remote request that is expecting a reply.
+ this->request_->tao_send_reply_exception(ACE_ANY_EXCEPTION);
+ }
+ else if (TAO_debug_level > 0)
+ {
+ // It is unfortunate that an exception (probably a system
+ // exception) was thrown by the dispatch code (even by the
+ // user) when the client was not expecting a response.
+ // However, in this case, we cannot close the connection
+ // down, since it really isn't the client's fault.
+
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) exception thrown ")
+ ACE_TEXT ("but client is not waiting a response\n")));
+
+ ACE_PRINT_EXCEPTION (
+ ACE_ANY_EXCEPTION,
+ "FW_Server_Request_Wrapper::dispatch ()");
+ }
+ }
+#if defined (TAO_HAS_EXCEPTIONS)
+ ACE_CATCHALL
+ {
+ // @@ TODO some c++ exception or another, but what do we do with
+ // it?
+ // We are supposed to map it into a CORBA::UNKNOWN exception.
+ // BTW, this cannot be detected if using the <env> mapping. If
+ // we have native exceptions but no support for them in the ORB
+ // we should still be able to catch it. If we don't have native
+ // exceptions it couldn't have been raised in the first place!
+ CORBA::UNKNOWN exception (CORBA::SystemException::_tao_minor_code
+ (TAO_UNHANDLED_SERVER_CXX_EXCEPTION, 0),
+ CORBA::COMPLETED_MAYBE);
+
+ if (this->request_->collocated())
+ {
+ // For collocated requests, we re-throw the exception.
+ ACE_RE_THROW;
+ }
+ else if (!this->request_->sync_with_server() &&
+ this->request_->response_expected() &&
+ !this->request_->deferred_reply())
+ {
+ // The request is a remote request that is expecting a reply.
+ this->request_->tao_send_reply_exception(exception);
+ }
+ else if (TAO_debug_level > 0)
+ {
+ // It is unfortunate that an exception (probably a system
+ // exception) was thrown by the dispatch code (even by the
+ // user) when the client was not expecting a response.
+ // However, in this case, we cannot close the connection
+ // down, since it really isn't the client's fault.
+
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) exception thrown ")
+ ACE_TEXT ("but client is not waiting a response\n")));
+
+ ACE_PRINT_EXCEPTION (
+ exception,
+ "FW_Server_Request_Wrapper::dispatch ()");
+ }
+ }
+#endif /* TAO_HAS_EXCEPTIONS */
+
+ ACE_ENDTRY;
+}
+
+
+TAO_ServerRequest*
+TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_ServerRequest*& request)
+{
+ // TBD-CSD: Ultimately add an argument for an allocator.
+ TAO_ServerRequest* clone_obj = this->create_new_request ();
+
+ if (clone_obj == 0)
+ {
+ return 0;
+ }
+
+ // TYPE: TAO_Pluggable_Messaging*
+ // ACTION: Assuming that a shallow-copy is ok here.
+ clone_obj->mesg_base_ = request->mesg_base_;
+
+ // TYPE: ACE_CString
+ // ACTION: Assignment performs deep-copy of string contents.
+ clone_obj->operation_ = request->operation_;
+
+ // TYPE: CORBA::Object_var
+ // ACTION: Assignment performs reference-counted copy of object ref.
+ clone_obj->forward_location_ = request->forward_location_;
+
+ // TYPE: TAO_InputCDR*
+ // ACTION: This *must* be "cloned".
+ if (request->incoming_ != 0)
+ {
+ clone_obj->incoming_ = this->clone (request->incoming_);
+ }
+
+ // TYPE: TAO_OutputCDR*
+ // ACTION: This *must* be "cloned".
+ if (request->outgoing_ != 0)
+ {
+ clone_obj->outgoing_ = this->create_new_output_cdr ();
+ }
+
+ // TYPE: TAO_Transport*
+ // ACTION: Assuming that a shallow-copy is ok here.
+ clone_obj->transport_ = request->transport_;
+
+ // TYPE: CORBA::Boolean
+ // ACTION: Primitive data type assignment.
+ clone_obj->response_expected_ = request->response_expected_;
+
+ // TYPE: CORBA::Boolean
+ // ACTION: Primitive data type assignment.
+ clone_obj->deferred_reply_ = request->deferred_reply_;
+
+ // TYPE: CORBA::Boolean
+ // ACTION: Primitive data type assignment.
+ clone_obj->sync_with_server_ = request->sync_with_server_;
+
+ // TYPE: CORBA::Boolean
+ // ACTION: Primitive data type assignment.
+ clone_obj->is_dsi_ = request->is_dsi_;
+
+ // TYPE: CORBA::ULong
+ // ACTION: Primitive data type assignment.
+ clone_obj->exception_type_ = request->exception_type_;
+
+ // TYPE: TAO_ORB_Core*
+ // ACTION: Assuming that a shallow-copy is ok here.
+ clone_obj->orb_core_ = request->orb_core_;
+
+ // TYPE: TAO_Service_Context
+ // ACTION: No copy/assignment operator, so adding/using a clone operation.
+ this->clone (request->request_service_context_, clone_obj->request_service_context_);
+
+ // TYPE: TAO_Service_Context
+ // ACTION: No copy/assignment operator, so adding/using a clone operation.
+ this->clone (request->reply_service_context_, clone_obj->reply_service_context_);
+
+ // TYPE: CORBA::ULong
+ // ACTION: Primitive data type assignment.
+ clone_obj->request_id_ = request->request_id_;
+
+ // TYPE: TAO_Tagged_Profile
+ // ACTION: No copy/assignment operator, so adding/using a clone operation.
+ this->clone (request->profile_, clone_obj->profile_);
+
+ // TYPE: CORBA::OctetSeq_var
+ // ACTION: Assignment performs reference-counted copy of sequence.
+ clone_obj->requesting_principal_ = request->requesting_principal_;
+
+ // TYPE: ptrdiff_t
+ // ACTION: Primitive data type assignment (unsigned integral type).
+ clone_obj->dsi_nvlist_align_ = request->dsi_nvlist_align_;
+
+ // TYPE: TAO_Operation_Details const * const
+ // ACTION: Need to clone this.
+ if (request->operation_details_ != 0)
+ {
+ ACE_ASSERT (request->incoming_ == 0);
+ if (this->clone (request->operation_details_,
+ clone_obj->operation_details_,
+ clone_obj->incoming_) == false)
+ {
+ return 0;
+ }
+ }
+
+ // TYPE: CORBA::Boolean
+ // ACTION: Primitive data type assignment.
+ clone_obj->argument_flag_ = request->argument_flag_;
+
+#if TAO_HAS_INTERCEPTORS == 1
+ // TYPE: size_t
+ // ACTION: Primitive data type assignment.
+ // Just leave this alone for a clone.
+ //
+ //clone_obj->interceptor_count_ = request->interceptor_count_;
+
+ // TYPE: TAO::PICurrent_Impl
+ // ACTION: Copy/assignment operator disabled on purpose.
+ // Just leave this alone for a clone.
+ //
+ // clone_obj->rs_pi_current_
+
+ // TYPE: TAO::PICurrent_Copy_Callback
+ // ACTION: No copy/assignment operator.
+ // Just leave this alone for a clone.
+ //
+ // clone_obj->pi_current_copy_callback_
+
+ // TYPE: CORBA::OctetSeq_var
+ // ACTION: Assignment performs reference-counted copy of sequence.
+ // Assuming that this is ok.
+ // Just leave this alone for a clone.
+ //
+ //clone_obj->result_seq_ = request->result_seq_;
+#endif /* TAO_HAS_INTERCEPTORS == 1 */
+
+ if (clone_obj->transport_ != 0)
+ {
+ clone_obj->transport_->assign_translators(clone_obj->incoming_,
+ clone_obj->outgoing_);
+ }
+ return clone_obj;
+}
+
+
+TAO_InputCDR*
+TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_InputCDR*& from)
+{
+ TAO_InputCDR* clone_ptr = 0;
+ ACE_NEW_RETURN (clone_ptr,
+ TAO_InputCDR(*from),
+ 0);
+ return clone_ptr;
+}
+
+
+bool
+TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Operation_Details const *& from,
+ TAO_Operation_Details const *& to,
+ TAO_InputCDR*& cdr)
+{
+ TAO_Operation_Details* from_non_const
+ = const_cast <TAO_Operation_Details *>(from);
+
+ char* cloned_op_name = new char[from_non_const->opname_len_ + 1];
+ ACE_OS::strncpy(cloned_op_name, from_non_const->opname_, from_non_const->opname_len_);
+ cloned_op_name[from_non_const->opname_len_] = '\0';
+
+ TAO_OutputCDR outcdr;
+
+ if (! from_non_const->marshal_args (outcdr))
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT("(%P|%T) TAO::CSD::FW_Server_Request_Wrapper::")
+ ACE_TEXT("clone TAO_Operation_Details failed\n")));
+ return false;
+ }
+
+ ACE_NEW_RETURN (cdr,
+ TAO_InputCDR (outcdr),
+ false);
+
+
+ // CSD-TBD: Eventually need to use allocators.
+
+ // CSD-TBD: Assert that this->ex_data_ and this->ex_count_ are both == 0
+ TAO_Operation_Details* to_non_const;
+ ACE_NEW_RETURN (to_non_const,
+ TAO_Operation_Details(cloned_op_name,
+ from_non_const->opname_len_,
+ from_non_const->argument_flag_,
+ 0,
+ 0,
+ 0,
+ 0),
+ false);
+
+
+ // DATA MEMBER: const char *opname_;
+ // DATA MEMBER: CORBA::ULong opname_len_;
+ // DATA MEMBER: CORBA::Boolean argument_flag_;
+ // DATA MEMBER: TAO::Argument **args_;
+ // DATA MEMBER: CORBA::ULong num_args_;
+ // DATA MEMBER: TAO::Exception_Data *ex_data_;
+ // DATA MEMBER: CORBA::ULong ex_count_;
+ //
+ // ACTION: None - handled in ctor
+ //
+
+ // DATA MEMBER: CORBA::ULong request_id_;
+ // DATA MEMBER: CORBA::Octet response_flags_;
+ // DATA MEMBER: TAO_Target_Specification::TAO_Target_Address addressing_mode_;
+ // DATA MEMBER: TAO_Service_Context request_service_info_;
+ // DATA MEMBER: TAO_Service_Context reply_service_info_;
+ //
+ // ACTION: Use assignment op to copy from "this" object to the clone.
+ //
+ to_non_const->request_id_ = from->request_id_;
+ to_non_const->response_flags_ = from->response_flags_;
+ to_non_const->addressing_mode_ = from->addressing_mode_;
+
+ // DATA MEMBER: TAO_Service_Context request_service_info_;
+ // DATA MEMBER: TAO_Service_Context reply_service_info_;
+ //
+ // ACTION: Use the TAO_Service_Context clone() method.
+ //
+ this->clone (from_non_const->request_service_info_, to_non_const->request_service_info_);
+ this->clone (from_non_const->reply_service_info_, to_non_const->reply_service_info_);
+
+ to = to_non_const;
+
+ return true;
+}
+
+
+void
+TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Tagged_Profile& from,
+ TAO_Tagged_Profile& to)
+{
+ to.orb_core_ = from.orb_core_;
+ to.discriminator_ = from.discriminator_;
+ to.object_key_extracted_ = from.object_key_extracted_;
+ to.object_key_ = from.object_key_;
+ to.profile_ = from.profile_;
+ to.profile_index_ = from.profile_index_;
+ to.type_id_ = from.type_id_;
+}
+
+
+void
+TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Service_Context& from,
+ TAO_Service_Context& to)
+{
+ to.service_context_ = from.service_context_;
+}
+
+TAO_ServerRequest*
+TAO::CSD::FW_Server_Request_Wrapper::create_new_request ()
+{
+ // Use one of constructor to create the TAO_ServerRequest object then
+ // reset the data members. This reduces the footprint due to a default
+ // TAO_ServerRequest constructor.
+ //
+ //TAO_ServerRequest (TAO_Pluggable_Messaging *mesg_base,
+ // TAO_InputCDR &input,
+ // TAO_OutputCDR &output,
+ // TAO_Transport *transport,
+ // TAO_ORB_Core *orb_core);
+
+ TAO_ServerRequest* request = 0;
+
+ TAO_InputCDR dummy_input ((ACE_Message_Block *)0); // empty input cdr stream
+ TAO_OutputCDR dummy_output ((char *)0, (size_t) 0); // empty output cdr stream
+ ACE_NEW_RETURN (request,
+ TAO_ServerRequest (0,
+ dummy_input,
+ dummy_output,
+ 0,
+ 0),
+ 0);
+
+ request->incoming_ = 0;
+ request->outgoing_ = 0;
+
+ return request;
+}
+
+
+TAO_OutputCDR*
+TAO::CSD::FW_Server_Request_Wrapper::create_new_output_cdr ()
+{
+ TAO_OutputCDR* cdr = 0;
+
+ // A buffer that we will use to initialise the CDR stream
+ char* repbuf = new char[ACE_CDR::DEFAULT_BUFSIZE];
+
+ ACE_CDR::Octet major;
+ ACE_CDR::Octet minor;
+ this->request_->outgoing_->get_version (major, minor);
+
+ // Initialze an output CDR on the stack
+ // NOTE: Don't jump to a conclusion as to why we are using the
+ // input_cdr and hence the global pool here. These pools will move
+ // to the lanes anyway at some point of time. Further, it would have
+ // been awesome to have this in TSS. But for some reason the cloning
+ // that happens when the ORB gets flow controlled while writing a
+ // reply is messing things up. We crash horribly. Doing this adds a
+ // lock, we need to set things like this -- put stuff in TSS here
+ // and transfer to global memory when we get flow controlled. We
+ // need to work on the message block to get it right!
+ ACE_NEW_RETURN (cdr,
+ TAO_OutputCDR (repbuf,
+ ACE_CDR::DEFAULT_BUFSIZE,
+ TAO_ENCAP_BYTE_ORDER,
+ this->request_->orb_core_->input_cdr_buffer_allocator (),
+ this->request_->orb_core_->input_cdr_dblock_allocator (),
+ this->request_->orb_core_->input_cdr_msgblock_allocator (),
+ this->request_->orb_core_->orb_params ()->cdr_memcpy_tradeoff (),
+ major,
+ minor),
+ 0);
+
+ return cdr;
+}
+
diff --git a/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h
new file mode 100644
index 00000000000..945a921ca99
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h
@@ -0,0 +1,127 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file CSD_FW_Server_Request_Wrapper.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_FW_SERVER_REQUEST_WRAPPER_H
+#define TAO_CSD_FW_SERVER_REQUEST_WRAPPER_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/TAO_Server_Request.h"
+#include "tao/operation_details.h"
+#include "tao/PortableServer/Servant_Base.h"
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ /**
+ * @class FW_Server_Request_Wrapper
+ *
+ * @brief Wrapper around a TAO_Server_Request that will be cloned
+ * at the proper time.
+ *
+ * This CSD Framework class is used to provide an interface to a
+ * TAO_ServerRequest object such that it can be used for CSD strategies
+ * that need to clone TAO_Server_Requests (ie, so that they may be
+ * placed on a queue to be dispatched by another thread).
+ *
+ * There are several purposes for this class, with the main thing being
+ * that the TAO_ServerRequest object is not used directly by the
+ * CSD Strategies since it is, after all, an internal TAO class that was
+ * never meant to be exposed. Future changes to TAO's internal design
+ * may cause disruption in the TAO_ServerRequest class. These changes
+ * would only need to be accounted for here in this
+ * FW_Server_Request_Wrapper class' implementation, and all CSD
+ * Strategies will work again. It's a maintenance issue.
+ *
+ * @note: The CSD namespace is inside of TAO namespace in current
+ * implementation. This can be changed but, at least for now, it's
+ * already been delivered to some customs, we leave it as-is. If it
+ * needs to change, we will make this change.
+ */
+ class TAO_CSD_FW_Export FW_Server_Request_Wrapper
+ {
+ public:
+
+ /// Constructor.
+ FW_Server_Request_Wrapper(TAO_ServerRequest& server_request);
+
+ /// Destructor.
+ ~FW_Server_Request_Wrapper();
+
+ /// Perform the clone operation.
+ void clone();
+
+ /// Dispatch the request to the servant.
+ void dispatch(PortableServer::Servant servant ACE_ENV_ARG_DECL);
+
+ /// Cancel the request.
+ void cancel();
+
+
+ private:
+
+ /// Create a deep copy of the request_ object.
+ /// The other clone methods are used to support the TAO_ServerRequest clone.
+ TAO_ServerRequest* clone (TAO_ServerRequest*& from);
+
+ /// Clone an input cdr stream.
+ TAO_InputCDR* clone (TAO_InputCDR*& from);
+
+ /// Create a deep copy of a TAO_Operation_Details object and marshall
+ /// the arguments into a TAO_InputCDR stream. The cloned TAO_Operation_Details
+ /// object is created without any arguments. This would help the skeleton
+ /// code to determine whether the arguments are in the operation_details_
+ /// object or should be demarshalled from the incoming_ stream in the request_
+ /// object.
+ bool clone (TAO_Operation_Details const *& from,
+ TAO_Operation_Details const *& to,
+ TAO_InputCDR* & cdr);
+
+ /// Clone the TAO_Tagged_Profile object.
+ void clone (TAO_Tagged_Profile& from, TAO_Tagged_Profile& to);
+
+ /// Clone the TAO_Service_Context object.
+ void clone (TAO_Service_Context& from, TAO_Service_Context& to);
+
+ /// Create a new TAO_ServerRequest with default initial values.
+ TAO_ServerRequest* create_new_request ();
+
+ /// Create a TAO_OutputCDR stream initialized with a heap allocated
+ /// buffer.
+ TAO_OutputCDR* create_new_output_cdr ();
+
+ /// A flag that indicates that the TAO_ServerRequest object
+ /// is already cloned.
+ bool is_clone_;
+
+ /// Pointer to the underlying TAO_ServerRequest object.
+ TAO_ServerRequest* request_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_FW_Server_Request_Wrapper.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_FW_SERVER_REQUEST_WRAPPER_H */
diff --git a/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl
new file mode 100644
index 00000000000..a259de116ab
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl
@@ -0,0 +1,42 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::FW_Server_Request_Wrapper::FW_Server_Request_Wrapper
+ (TAO_ServerRequest& server_request)
+ : is_clone_(false),
+ request_(&server_request)
+{
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::FW_Server_Request_Wrapper::clone()
+{
+ // Only clone the TAO_Server_Request object if we have not performed the
+ // clone already. This really should only be called once, but this code
+ // makes sure that we do not introduce a leak.
+ if (!this->is_clone_)
+ {
+ this->request_ = this->clone (this->request_);
+ this->is_clone_ = true;
+ }
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::FW_Server_Request_Wrapper::cancel()
+{
+ // We only need to handle remote requests that are expecting a reply.
+ if (!this->request_->collocated() &&
+ !this->request_->sync_with_server() &&
+ this->request_->response_expected() &&
+ !this->request_->deferred_reply())
+ {
+ CORBA::NO_IMPLEMENT ex;
+ this->request_->tao_send_reply_exception(ex);
+ }
+}
+
diff --git a/TAO/tao/CSD_Framework/CSD_Framework.pidl b/TAO/tao/CSD_Framework/CSD_Framework.pidl
new file mode 100644
index 00000000000..ba1940df02e
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Framework.pidl
@@ -0,0 +1,75 @@
+// -*- IDL -*-
+/**
+ * @file CSD_Framework.pidl
+ *
+ * $Id$
+ *
+ * @brief Pre-compiled IDL source for the CSD_Framework module.
+ *
+ * This file was used to generate the code in
+ * CSD_FrameworkC.{h,inl,cpp}, using the following command:
+ *
+ $ACE_ROOT/bin/tao_idl \
+ -o orig -Gp -Gd -Ge 1 -Gt -Sc -GA -I$TAO_ROOT \
+ -Wb,export_macro=TAO_CSD_FW_Export \
+ -Wb,export_include="CSD_FW_Export.h" \
+ -Wb,pre_include="ace/pre.h" \
+ -Wb,post_include="ace/post.h" \
+ CSD_Framework.pidl
+ *
+ * After the file is generated a patch from the diffs directory must
+ * be applied. The patch:
+ *
+ * - Disables parts of the code under certain configurations.
+ *
+ * - Eliminates cycles in the include dependencies.
+ *
+ * - Adds non-idl components of CSD_Framework to the namespace.
+ * This includes (a) Servant (b) ServantBase (c) RefCountServantBase
+ * (d) Cookie (e) ObjectId_to_string (f) string_to_ObjectId (g)
+ * ObjectId_to_wstring (h) wstring_to_ObjectId (i) ServantBase_var
+ * (j) DynamicImplementation (k) LocalServantBase
+ *
+ * Apply patches using the following command:
+ *
+ * patch < diffs/CSD_Framework.diff
+ *
+ * Note: The diffs were generated using:
+ *
+ * rm diffs/CSD_Framework.diff
+ * for i in CSD_FrameworkC.{h,i,cpp}; do
+ * diff -wub orig/$i $i >> diffs/CSD_Framework.diff
+ * done
+ */
+
+#ifndef _CSD_FRAMEWORK_IDL_
+#define _CSD_FRAMEWORK_IDL_
+
+#include <tao/PortableServer/PortableServer.pidl>
+
+module CSD_Framework {
+
+ //# pragma version CSD_Framework 2.3
+
+ // This is a common base interface for all CSD strategy
+ // implementations
+ local interface Strategy {
+
+ //# pragma version Strategy 2.3
+
+ // This is support for a legacy method of supplying a strategy to a
+ // POA.
+ boolean apply_to(in PortableServer::POA p);
+ };
+
+ // Specialized POA providing a method to supply a strategy object to
+ // the POA.
+ local interface POA : PortableServer::POA {
+
+ //# pragma version POA 2.3
+
+ void set_csd_strategy (in Strategy s);
+ };
+};
+
+#endif //_CSD_FRAMEWORK_IDL_
diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkA.cpp b/TAO/tao/CSD_Framework/CSD_FrameworkA.cpp
new file mode 100644
index 00000000000..9045084e4bc
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_FrameworkA.cpp
@@ -0,0 +1,73 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// **** Code generated by the The ACE ORB (TAO) IDL Compiler ****
+// TAO and the TAO IDL Compiler have been developed by:
+// Center for Distributed Object Computing
+// Washington University
+// St. Louis, MO
+// USA
+// http://www.cs.wustl.edu/~schmidt/doc-center.html
+// and
+// Distributed Object Computing Laboratory
+// University of California at Irvine
+// Irvine, CA
+// USA
+// http://doc.ece.uci.edu/
+// and
+// Institute for Software Integrated Systems
+// Vanderbilt University
+// Nashville, TN
+// USA
+// http://www.isis.vanderbilt.edu/
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
+#include "CSD_FrameworkA.h"
+#include "tao/AnyTypeCode/Null_RefCount_Policy.h"
+#include "tao/AnyTypeCode/TypeCode_Constants.h"
+#include "tao/AnyTypeCode/Alias_TypeCode_Static.h"
+#include "tao/AnyTypeCode/Objref_TypeCode_Static.h"
+#include "tao/AnyTypeCode/String_TypeCode_Static.h"
+#include "tao/AnyTypeCode/Any.h"
+#include "tao/CDR.h"
+#include "tao/AnyTypeCode/Any.h"
+#include "tao/AnyTypeCode/Any_Impl_T.h"
+
+// TAO_IDL - Generated from
+// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_typecode/objref_typecode.cpp:76
+
+static TAO::TypeCode::Objref<char const *,
+ TAO::Null_RefCount_Policy>
+ _tao_tc_CSD_Framework_Strategy (
+ ::CORBA::tk_local_interface,
+ "IDL:CSD_Framework/Strategy:1.0",
+ "Strategy");
+
+namespace CSD_Framework
+{
+ ::CORBA::TypeCode_ptr const _tc_Strategy =
+ &_tao_tc_CSD_Framework_Strategy;
+}
+
+
+
+// TAO_IDL - Generated from
+// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_typecode/objref_typecode.cpp:76
+
+static TAO::TypeCode::Objref<char const *,
+ TAO::Null_RefCount_Policy>
+ _tao_tc_CSD_Framework_POA (
+ ::CORBA::tk_local_interface,
+ "IDL:CSD_Framework/POA:1.0",
+ "POA");
+
+namespace CSD_Framework
+{
+ ::CORBA::TypeCode_ptr const _tc_POA =
+ &_tao_tc_CSD_Framework_POA;
+}
+
+
diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkA.h b/TAO/tao/CSD_Framework/CSD_FrameworkA.h
new file mode 100644
index 00000000000..db88e7a79d6
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_FrameworkA.h
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// **** Code generated by the The ACE ORB (TAO) IDL Compiler ****
+// TAO and the TAO IDL Compiler have been developed by:
+// Center for Distributed Object Computing
+// Washington University
+// St. Louis, MO
+// USA
+// http://www.cs.wustl.edu/~schmidt/doc-center.html
+// and
+// Distributed Object Computing Laboratory
+// University of California at Irvine
+// Irvine, CA
+// USA
+// http://doc.ece.uci.edu/
+// and
+// Institute for Software Integrated Systems
+// Vanderbilt University
+// Nashville, TN
+// USA
+// http://www.isis.vanderbilt.edu/
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
+// TAO_IDL - Generated from
+// .\be\be_codegen.cpp:754
+
+#ifndef _TAO_IDL_ORIG_CSD_FRAMEWORKA_H_
+#define _TAO_IDL_ORIG_CSD_FRAMEWORKA_H_
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+#include "CSD_FrameworkC.h"
+//#include "tao/PortableServer/PortableServerA.h"
+
+
+// TAO_IDL - Generated from
+// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_module/module_ch.cpp:59
+
+namespace CSD_Framework
+{
+
+ // TAO_IDL - Generated from
+ // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_typecode/typecode_decl.cpp:49
+
+ extern TAO_CSD_FW_Export ::CORBA::TypeCode_ptr const _tc_Strategy;
+
+ // TAO_IDL - Generated from
+ // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_typecode/typecode_decl.cpp:49
+
+ extern TAO_CSD_FW_Export ::CORBA::TypeCode_ptr const _tc_POA;
+
+// TAO_IDL - Generated from
+// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_module/module_ch.cpp:86
+
+} // module CSD_Framework
+
+#include /**/ "ace/post.h"
+
+#endif /* ifndef */
diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkC.cpp b/TAO/tao/CSD_Framework/CSD_FrameworkC.cpp
new file mode 100644
index 00000000000..12b91dd79cc
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_FrameworkC.cpp
@@ -0,0 +1,293 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// **** Code generated by the The ACE ORB (TAO) IDL Compiler ****
+// TAO and the TAO IDL Compiler have been developed by:
+// Center for Distributed Object Computing
+// Washington University
+// St. Louis, MO
+// USA
+// http://www.cs.wustl.edu/~schmidt/doc-center.html
+// and
+// Distributed Object Computing Laboratory
+// University of California at Irvine
+// Irvine, CA
+// USA
+// http://doc.ece.uci.edu/
+// and
+// Institute for Software Integrated Systems
+// Vanderbilt University
+// Nashville, TN
+// USA
+// http://www.isis.vanderbilt.edu/
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
+// TAO_IDL - Generated from
+// .\be\be_codegen.cpp:277
+
+
+#include "CSD_FrameworkC.h"
+#include "tao/CDR.h"
+#include "ace/OS_NS_string.h"
+
+#if !defined (__ACE_INLINE__)
+#include "CSD_FrameworkC.inl"
+#endif /* !defined INLINE */
+
+// TAO_IDL - Generated from
+// .\be\be_visitor_arg_traits.cpp:70
+
+// Arg traits specializations.
+namespace TAO
+{
+}
+
+
+// TAO_IDL - Generated from
+// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_cs.cpp:60
+
+// Traits specializations for CSD_Framework::Strategy.
+
+CSD_Framework::Strategy_ptr
+TAO::Objref_Traits<CSD_Framework::Strategy>::duplicate (
+ CSD_Framework::Strategy_ptr p
+ )
+{
+ return CSD_Framework::Strategy::_duplicate (p);
+}
+
+void
+TAO::Objref_Traits<CSD_Framework::Strategy>::release (
+ CSD_Framework::Strategy_ptr p
+ )
+{
+ CORBA::release (p);
+}
+
+CSD_Framework::Strategy_ptr
+TAO::Objref_Traits<CSD_Framework::Strategy>::nil (void)
+{
+ return CSD_Framework::Strategy::_nil ();
+}
+
+::CORBA::Boolean
+TAO::Objref_Traits<CSD_Framework::Strategy>::marshal (
+ CSD_Framework::Strategy_ptr p,
+ TAO_OutputCDR & cdr
+ )
+{
+ return ::CORBA::Object::marshal (p, cdr);
+}
+
+CSD_Framework::Strategy::Strategy (void)
+{}
+
+CSD_Framework::Strategy::~Strategy (void)
+{}
+
+CSD_Framework::Strategy_ptr
+CSD_Framework::Strategy::_narrow (
+ ::CORBA::Object_ptr _tao_objref
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ return Strategy::_duplicate (
+ dynamic_cast<Strategy_ptr> (_tao_objref)
+ );
+}
+
+CSD_Framework::Strategy_ptr
+CSD_Framework::Strategy::_unchecked_narrow (
+ ::CORBA::Object_ptr _tao_objref
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ return Strategy::_duplicate (
+ dynamic_cast<Strategy_ptr> (_tao_objref)
+ );
+}
+
+CSD_Framework::Strategy_ptr
+CSD_Framework::Strategy::_duplicate (Strategy_ptr obj)
+{
+ if (! CORBA::is_nil (obj))
+ {
+ obj->_add_ref ();
+ }
+
+ return obj;
+}
+
+void
+CSD_Framework::Strategy::_tao_release (Strategy_ptr obj)
+{
+ CORBA::release (obj);
+}
+
+::CORBA::Boolean
+CSD_Framework::Strategy::_is_a (
+ const char *value
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ if (
+ !ACE_OS::strcmp (
+ value,
+ "IDL:CSD_Framework/Strategy:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/CORBA/LocalObject:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/CORBA/Object:1.0"
+ )
+ )
+ {
+ return true; // success using local knowledge
+ }
+ else
+ {
+ return false;
+ }
+}
+
+const char* CSD_Framework::Strategy::_interface_repository_id (void) const
+{
+ return "IDL:CSD_Framework/Strategy:1.0";
+}
+
+::CORBA::Boolean
+CSD_Framework::Strategy::marshal (TAO_OutputCDR &)
+{
+ return false;
+}
+
+// TAO_IDL - Generated from
+// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_cs.cpp:60
+
+// Traits specializations for CSD_Framework::POA.
+
+CSD_Framework::POA_ptr
+TAO::Objref_Traits<CSD_Framework::POA>::duplicate (
+ CSD_Framework::POA_ptr p
+ )
+{
+ return CSD_Framework::POA::_duplicate (p);
+}
+
+void
+TAO::Objref_Traits<CSD_Framework::POA>::release (
+ CSD_Framework::POA_ptr p
+ )
+{
+ CORBA::release (p);
+}
+
+CSD_Framework::POA_ptr
+TAO::Objref_Traits<CSD_Framework::POA>::nil (void)
+{
+ return CSD_Framework::POA::_nil ();
+}
+
+::CORBA::Boolean
+TAO::Objref_Traits<CSD_Framework::POA>::marshal (
+ CSD_Framework::POA_ptr p,
+ TAO_OutputCDR & cdr
+ )
+{
+ return ::CORBA::Object::marshal (p, cdr);
+}
+
+CSD_Framework::POA::POA (void)
+{}
+
+CSD_Framework::POA::~POA (void)
+{}
+
+CSD_Framework::POA_ptr
+CSD_Framework::POA::_narrow (
+ ::CORBA::Object_ptr _tao_objref
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ return POA::_duplicate (
+ dynamic_cast<POA_ptr> (_tao_objref)
+ );
+}
+
+CSD_Framework::POA_ptr
+CSD_Framework::POA::_unchecked_narrow (
+ ::CORBA::Object_ptr _tao_objref
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ return POA::_duplicate (
+ dynamic_cast<POA_ptr> (_tao_objref)
+ );
+}
+
+CSD_Framework::POA_ptr
+CSD_Framework::POA::_duplicate (POA_ptr obj)
+{
+ if (! CORBA::is_nil (obj))
+ {
+ obj->_add_ref ();
+ }
+
+ return obj;
+}
+
+void
+CSD_Framework::POA::_tao_release (POA_ptr obj)
+{
+ CORBA::release (obj);
+}
+
+::CORBA::Boolean
+CSD_Framework::POA::_is_a (
+ const char *value
+ ACE_ENV_ARG_DECL_NOT_USED
+ )
+{
+ if (
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/PortableServer/POA:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:CSD_Framework/POA:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/CORBA/LocalObject:1.0"
+ ) ||
+ !ACE_OS::strcmp (
+ value,
+ "IDL:omg.org/CORBA/Object:1.0"
+ )
+ )
+ {
+ return true; // success using local knowledge
+ }
+ else
+ {
+ return false;
+ }
+}
+
+const char* CSD_Framework::POA::_interface_repository_id (void) const
+{
+ return "IDL:CSD_Framework/POA:1.0";
+}
+
+::CORBA::Boolean
+CSD_Framework::POA::marshal (TAO_OutputCDR &)
+{
+ return false;
+}
diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkC.h b/TAO/tao/CSD_Framework/CSD_FrameworkC.h
new file mode 100644
index 00000000000..832eae8ffe0
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_FrameworkC.h
@@ -0,0 +1,312 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// **** Code generated by the The ACE ORB (TAO) IDL Compiler ****
+// TAO and the TAO IDL Compiler have been developed by:
+// Center for Distributed Object Computing
+// Washington University
+// St. Louis, MO
+// USA
+// http://www.cs.wustl.edu/~schmidt/doc-center.html
+// and
+// Distributed Object Computing Laboratory
+// University of California at Irvine
+// Irvine, CA
+// USA
+// http://doc.ece.uci.edu/
+// and
+// Institute for Software Integrated Systems
+// Vanderbilt University
+// Nashville, TN
+// USA
+// http://www.isis.vanderbilt.edu/
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
+// TAO_IDL - Generated from
+// .\be\be_codegen.cpp:154
+
+#ifndef _TAO_IDL_ORIG_CSD_FRAMEWORKC_H_
+#define _TAO_IDL_ORIG_CSD_FRAMEWORKC_H_
+
+#include /**/ "ace/pre.h"
+
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_FW_Export.h"
+#include "tao/ORB.h"
+#include "tao/SystemException.h"
+#include "tao/Environment.h"
+#include "tao/Object.h"
+#include "tao/Objref_VarOut_T.h"
+
+#include "tao/PortableServer/PortableServer.h"
+
+#if defined (TAO_EXPORT_MACRO)
+#undef TAO_EXPORT_MACRO
+#endif
+#define TAO_EXPORT_MACRO TAO_CSD_FW_Export
+
+// TAO_IDL - Generated from
+// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_module/module_ch.cpp:49
+
+namespace CSD_Framework
+{
+
+ // TAO_IDL - Generated from
+ // .\be\be_interface.cpp:646
+
+#if !defined (_CSD_FRAMEWORK_STRATEGY__VAR_OUT_CH_)
+#define _CSD_FRAMEWORK_STRATEGY__VAR_OUT_CH_
+
+ class Strategy;
+ typedef Strategy *Strategy_ptr;
+
+ typedef
+ TAO_Objref_Var_T<
+ Strategy
+ >
+ Strategy_var;
+
+ typedef
+ TAO_Objref_Out_T<
+ Strategy
+ >
+ Strategy_out;
+
+#endif /* end #if !defined */
+
+ // TAO_IDL - Generated from
+ // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_ch.cpp:54
+
+#if !defined (_CSD_FRAMEWORK_STRATEGY_CH_)
+#define _CSD_FRAMEWORK_STRATEGY_CH_
+
+ class TAO_CSD_FW_Export Strategy
+ : public virtual ::CORBA::Object
+ {
+ public:
+ typedef Strategy_ptr _ptr_type;
+ typedef Strategy_var _var_type;
+
+ // The static operations.
+ static Strategy_ptr _duplicate (Strategy_ptr obj);
+
+ static void _tao_release (Strategy_ptr obj);
+
+ static Strategy_ptr _narrow (
+ ::CORBA::Object_ptr obj
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ static Strategy_ptr _unchecked_narrow (
+ ::CORBA::Object_ptr obj
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ static Strategy_ptr _nil (void)
+ {
+ return static_cast<Strategy_ptr> (0);
+ }
+
+
+
+ // TAO_IDL - Generated from
+ // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_operation/operation_ch.cpp:46
+
+ virtual ::CORBA::Boolean apply_to (
+ ::PortableServer::POA_ptr p
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ ::CORBA::SystemException
+ )) = 0;
+
+ // TAO_IDL - Generated from
+ // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_ch.cpp:210
+
+ virtual ::CORBA::Boolean _is_a (
+ const char *type_id
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ virtual const char* _interface_repository_id (void) const;
+ virtual ::CORBA::Boolean marshal (TAO_OutputCDR &cdr);
+
+ protected:
+ // Abstract or local interface only.
+ Strategy (void);
+
+ virtual ~Strategy (void);
+
+ private:
+ // Private and unimplemented for concrete interfaces.
+ Strategy (const Strategy &);
+
+ void operator= (const Strategy &);
+ };
+
+#endif /* end #if !defined */
+
+ // TAO_IDL - Generated from
+ // .\be\be_interface.cpp:646
+
+#if !defined (_CSD_FRAMEWORK_POA__VAR_OUT_CH_)
+#define _CSD_FRAMEWORK_POA__VAR_OUT_CH_
+
+ class POA;
+ typedef POA *POA_ptr;
+
+ typedef
+ TAO_Objref_Var_T<
+ POA
+ >
+ POA_var;
+
+ typedef
+ TAO_Objref_Out_T<
+ POA
+ >
+ POA_out;
+
+#endif /* end #if !defined */
+
+ // TAO_IDL - Generated from
+ // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_ch.cpp:54
+
+#if !defined (_CSD_FRAMEWORK_POA_CH_)
+#define _CSD_FRAMEWORK_POA_CH_
+
+ class TAO_CSD_FW_Export POA
+ : public virtual ::PortableServer::POA
+ {
+ public:
+ typedef POA_ptr _ptr_type;
+ typedef POA_var _var_type;
+
+ // The static operations.
+ static POA_ptr _duplicate (POA_ptr obj);
+
+ static void _tao_release (POA_ptr obj);
+
+ static POA_ptr _narrow (
+ ::CORBA::Object_ptr obj
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ static POA_ptr _unchecked_narrow (
+ ::CORBA::Object_ptr obj
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ static POA_ptr _nil (void)
+ {
+ return static_cast<POA_ptr> (0);
+ }
+
+
+
+ // TAO_IDL - Generated from
+ // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_operation/operation_ch.cpp:46
+
+ virtual void set_csd_strategy (
+ ::CSD_Framework::Strategy_ptr s
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((
+ ::CORBA::SystemException
+ )) = 0;
+
+ // TAO_IDL - Generated from
+ // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_ch.cpp:210
+
+ virtual ::CORBA::Boolean _is_a (
+ const char *type_id
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ );
+
+ virtual const char* _interface_repository_id (void) const;
+ virtual ::CORBA::Boolean marshal (TAO_OutputCDR &cdr);
+
+ protected:
+ // Abstract or local interface only.
+ POA (void);
+
+ virtual ~POA (void);
+
+ private:
+ // Private and unimplemented for concrete interfaces.
+ POA (const POA &);
+
+ void operator= (const POA &);
+ };
+
+#endif /* end #if !defined */
+
+// TAO_IDL - Generated from
+// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_module/module_ch.cpp:78
+
+} // module CSD_Framework
+
+// TAO_IDL - Generated from
+// .\be\be_visitor_traits.cpp:61
+
+// Traits specializations.
+namespace TAO
+{
+
+#if !defined (_CSD_FRAMEWORK_STRATEGY__TRAITS_)
+#define _CSD_FRAMEWORK_STRATEGY__TRAITS_
+
+ template<>
+ struct TAO_CSD_FW_Export Objref_Traits< ::CSD_Framework::Strategy>
+ {
+ static ::CSD_Framework::Strategy_ptr duplicate (
+ ::CSD_Framework::Strategy_ptr
+ );
+ static void release (
+ ::CSD_Framework::Strategy_ptr
+ );
+ static ::CSD_Framework::Strategy_ptr nil (void);
+ static ::CORBA::Boolean marshal (
+ ::CSD_Framework::Strategy_ptr p,
+ TAO_OutputCDR & cdr
+ );
+ };
+
+#endif /* end #if !defined */
+
+#if !defined (_CSD_FRAMEWORK_POA__TRAITS_)
+#define _CSD_FRAMEWORK_POA__TRAITS_
+
+ template<>
+ struct TAO_CSD_FW_Export Objref_Traits< ::CSD_Framework::POA>
+ {
+ static ::CSD_Framework::POA_ptr duplicate (
+ ::CSD_Framework::POA_ptr
+ );
+ static void release (
+ ::CSD_Framework::POA_ptr
+ );
+ static ::CSD_Framework::POA_ptr nil (void);
+ static ::CORBA::Boolean marshal (
+ ::CSD_Framework::POA_ptr p,
+ TAO_OutputCDR & cdr
+ );
+ };
+
+#endif /* end #if !defined */
+}
+
+#include /**/ "ace/post.h"
+
+#endif /* ifndef */
+
+
diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkC.inl b/TAO/tao/CSD_Framework/CSD_FrameworkC.inl
new file mode 100644
index 00000000000..c944d806c1f
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_FrameworkC.inl
@@ -0,0 +1,27 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// **** Code generated by the The ACE ORB (TAO) IDL Compiler ****
+// TAO and the TAO IDL Compiler have been developed by:
+// Center for Distributed Object Computing
+// Washington University
+// St. Louis, MO
+// USA
+// http://www.cs.wustl.edu/~schmidt/doc-center.html
+// and
+// Distributed Object Computing Laboratory
+// University of California at Irvine
+// Irvine, CA
+// USA
+// http://doc.ece.uci.edu/
+// and
+// Institute for Software Integrated Systems
+// Vanderbilt University
+// Nashville, TN
+// USA
+// http://www.isis.vanderbilt.edu/
+//
+// Information about TAO is available at:
+// http://www.cs.wustl.edu/~schmidt/TAO.html
+
diff --git a/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp b/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp
new file mode 100644
index 00000000000..9163e6995dc
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp
@@ -0,0 +1,26 @@
+// $Id$
+
+#include "CSD_Framework_Loader.h"
+#include "CSD_Object_Adapter_Factory.h"
+#include "CSD_Strategy_Repository.h"
+#include "ace/Dynamic_Service.h"
+
+ACE_RCSID (CSD_Framework,
+ CSD_Framework_Loader,
+ "$Id$")
+
+#include "tao/ORB_Core.h"
+
+int
+TAO_CSD_Framework_Loader::init (void)
+{
+ ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_Object_Adapter_Factory);
+
+ TAO_ORB_Core::set_poa_factory ("TAO_CSD_Object_Adapter_Factory",
+ "dynamic TAO_CSD_Object_Adapter_Factory Service_Object * _make_TAO_CSD_Object_Adapter_Factory()");
+
+
+ ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_Strategy_Repository);
+
+ return 0;
+}
diff --git a/TAO/tao/CSD_Framework/CSD_Framework_Loader.h b/TAO/tao/CSD_Framework/CSD_Framework_Loader.h
new file mode 100644
index 00000000000..5a13ed5f13f
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Framework_Loader.h
@@ -0,0 +1,41 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file CSD_Framework_Loader.h
+ *
+ * $Id$
+ *
+ * Header file for loading CSD framework service objects.
+ *
+ * @author Yan Dai (dai_y@ociweb.com)
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_FRAMEWORK_LOADER_H
+#define TAO_CSD_FRAMEWORK_LOADER_H
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class TAO_CSD_Framework_Loader
+ *
+ * @brief TAO_CSD_Framework_Loader.
+ *
+ * This class acts as a facade for the CSD_Framework library to the
+ * ORB.
+ */
+class TAO_CSD_FW_Export TAO_CSD_Framework_Loader
+{
+ public:
+ /// Used to force the initialization of the ORB code.
+ static int init (void);
+};
+
+#include /**/ "ace/post.h"
+#endif /* TAO_CSD_FRAMEWORK_LOADER_H */
diff --git a/TAO/tao/CSD_Framework/CSD_ORBInitializer.cpp b/TAO/tao/CSD_Framework/CSD_ORBInitializer.cpp
new file mode 100644
index 00000000000..56a46b61c18
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_ORBInitializer.cpp
@@ -0,0 +1,33 @@
+// $Id$
+#include "CSD_ORBInitializer.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+ACE_RCSID (CSD_Framework,
+ CSD_ORBInitializer,
+ "$Id$")
+
+#include "CSD_Object_Adapter_Factory.h"
+
+TAO_CSD_ORBInitializer::TAO_CSD_ORBInitializer ()
+{
+}
+
+void
+TAO_CSD_ORBInitializer::pre_init (
+ PortableInterceptor::ORBInitInfo_ptr
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+void
+TAO_CSD_ORBInitializer::post_init (
+ PortableInterceptor::ORBInitInfo_ptr
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+
+#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
diff --git a/TAO/tao/CSD_Framework/CSD_ORBInitializer.h b/TAO/tao/CSD_Framework/CSD_ORBInitializer.h
new file mode 100644
index 00000000000..0b661e2dd7c
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_ORBInitializer.h
@@ -0,0 +1,66 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file CSD_ORBInitializer.h
+ *
+ * $Id$
+ *
+ * @author Yan Dai (dai_y@ociweb.com)
+ */
+//=============================================================================
+
+
+#ifndef TAO_CSD_ORB_INITIALIZER_H
+#define TAO_CSD_ORB_INITIALIZER_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/orbconf.h"
+
+#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
+
+#include "CSD_FW_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+//#include "tao/PortableInterceptorC.h"
+#include "tao/LocalObject.h"
+#include "tao/PI/ORBInitializerC.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 */
+
+/// CSD ORB initializer.
+class TAO_CSD_FW_Export TAO_CSD_ORBInitializer :
+ public virtual PortableInterceptor::ORBInitializer,
+ public virtual TAO_Local_RefCounted_Object
+{
+public:
+
+ TAO_CSD_ORBInitializer ();
+
+ virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+};
+
+#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_CSD_ORB_INITIALIZER_H */
diff --git a/TAO/tao/CSD_Framework/CSD_Object_Adapter.cpp b/TAO/tao/CSD_Framework/CSD_Object_Adapter.cpp
new file mode 100644
index 00000000000..cd599fd37e2
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter.cpp
@@ -0,0 +1,42 @@
+// $Id$
+
+#include "CSD_Object_Adapter.h"
+#include "CSD_Strategy_Proxy.h"
+#include "CSD_POA.h"
+
+ACE_RCSID (CSD_Framework,
+ CSD_Object_Adapter,
+ "$Id$")
+
+TAO_CSD_Object_Adapter::TAO_CSD_Object_Adapter (
+ const TAO_Server_Strategy_Factory::Active_Object_Map_Creation_Parameters &creation_parameters,
+ TAO_ORB_Core &orb_core)
+ : TAO_Object_Adapter (creation_parameters, orb_core)
+{
+
+}
+
+TAO_CSD_Object_Adapter::~TAO_CSD_Object_Adapter ()
+{
+}
+
+void
+TAO_CSD_Object_Adapter::do_dispatch (
+ TAO_ServerRequest& req,
+ TAO::Portable_Server::Servant_Upcall& upcall
+ ACE_ENV_ARG_DECL)
+{
+ TAO_Root_POA& poa = upcall.poa ();
+ TAO_CSD_POA* csd_poa = dynamic_cast<TAO_CSD_POA*> (&poa);
+
+ if (csd_poa == 0)
+ {
+ ACE_THROW (CORBA::BAD_PARAM ());
+ }
+
+ TAO::CSD::Strategy_Proxy& proxy
+ = csd_poa->servant_dispatching_strategy_proxy ();
+ proxy.dispatch_request (req, upcall ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
diff --git a/TAO/tao/CSD_Framework/CSD_Object_Adapter.h b/TAO/tao/CSD_Framework/CSD_Object_Adapter.h
new file mode 100644
index 00000000000..83deb3c96b6
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter.h
@@ -0,0 +1,54 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file CSD_Object_Adapter.h
+ *
+ * $Id$
+ *
+ * @author Yan Dai (dai_y@ociweb.com)
+ */
+//=============================================================================
+
+
+#ifndef TAO_CSD_OBJECT_ADAPTER_H
+#define TAO_CSD_OBJECT_ADAPTER_H
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/PortableServer/Object_Adapter.h"
+
+/**
+ * @class TAO_CSD_Object_Adapter
+ *
+ * @brief Defines the CSD version Object Adapter which overrides
+ * default dispatch implementation.
+ *
+ * This class will be used as a facade for the CSD POAs in a server
+ */
+class TAO_CSD_FW_Export TAO_CSD_Object_Adapter : public TAO_Object_Adapter
+{
+public:
+
+ /// Constructor
+ TAO_CSD_Object_Adapter (const TAO_Server_Strategy_Factory::Active_Object_Map_Creation_Parameters &creation_parameters,
+ TAO_ORB_Core &orb_core);
+
+ /// Destructor
+ virtual ~TAO_CSD_Object_Adapter (void);
+
+ /// Hand the request to the Service_Dispatching_Strategy_Proxy for
+ /// dispatching.
+ virtual void do_dispatch (TAO_ServerRequest& req,
+ TAO::Portable_Server::Servant_Upcall& upcall
+ ACE_ENV_ARG_DECL);
+};
+
+
+#include /**/ "ace/post.h"
+#endif /* TAO_CSD_OBJECT_ADAPTER_H */
diff --git a/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.cpp b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.cpp
new file mode 100644
index 00000000000..7943eda6a5d
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.cpp
@@ -0,0 +1,93 @@
+// $Id$
+
+#include "CSD_Object_Adapter_Factory.h"
+#include "CSD_Strategy_Repository.h"
+#include "CSD_Object_Adapter.h"
+#include "CSD_ORBInitializer.h"
+#include "CSD_Default_Servant_Dispatcher.h"
+#include "tao/ORB_Core.h"
+#include "tao/ORBInitializer_Registry.h"
+#include "ace/Dynamic_Service.h"
+
+ACE_RCSID (CSD_Framework,
+ CSD_Object_Adapter_Factory,
+ "$Id$")
+
+
+TAO_CSD_Object_Adapter_Factory::TAO_CSD_Object_Adapter_Factory (void)
+{
+}
+
+TAO_Adapter*
+TAO_CSD_Object_Adapter_Factory::create (TAO_ORB_Core *oc)
+{
+ // Create the CSD object adapter.
+ TAO_CSD_Object_Adapter *object_adapter = 0;
+ ACE_NEW_RETURN (object_adapter,
+ TAO_CSD_Object_Adapter (oc->server_factory ()->
+ active_object_map_creation_parameters (),
+ *oc),
+ 0);
+
+ // Create and register the CSD servant dispatcher.
+ TAO_CSD_Default_Servant_Dispatcher * csd_servant_dispatcher = 0;
+ ACE_NEW_RETURN (csd_servant_dispatcher,
+ TAO_CSD_Default_Servant_Dispatcher,
+ 0);
+ object_adapter->servant_dispatcher (csd_servant_dispatcher);
+
+ return object_adapter;
+}
+
+int
+TAO_CSD_Object_Adapter_Factory::init (int /* argc */,
+ ACE_TCHAR* /* argv */ [])
+{
+ 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_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ /// Register the Messaging ORBInitializer.
+ PortableInterceptor::ORBInitializer_ptr temp_orb_initializer =
+ PortableInterceptor::ORBInitializer::_nil ();
+
+ ACE_NEW_THROW_EX (temp_orb_initializer,
+ TAO_CSD_ORBInitializer,
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO::VMCID,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+ ACE_TRY_CHECK;
+
+ PortableInterceptor::ORBInitializer_var orb_initializer =
+ temp_orb_initializer;
+
+ PortableInterceptor::register_orb_initializer (orb_initializer.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "(%P | %t) Caught exception:");
+ return -1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+ACE_FACTORY_DEFINE (TAO_CSD_FW, TAO_CSD_Object_Adapter_Factory)
+ACE_STATIC_SVC_DEFINE (TAO_CSD_Object_Adapter_Factory,
+ ACE_TEXT ("TAO_CSD_Object_Adapter_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_CSD_Object_Adapter_Factory),
+ ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
+ 0)
diff --git a/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.h b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.h
new file mode 100644
index 00000000000..9deab152daf
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.h
@@ -0,0 +1,46 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file CSD_Object_Adapter_Factory.h
+ *
+ * $Id$
+ *
+ * @author Yan Dai (dai_y@ociweb.com)
+ */
+//=============================================================================
+
+
+#ifndef TAO_CSD_OBJECT_ADAPTER_FACTORY_H
+#define TAO_CSD_OBJECT_ADAPTER_FACTORY_H
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Adapter_Factory.h"
+#include "ace/Service_Config.h"
+
+
+class TAO_CSD_FW_Export TAO_CSD_Object_Adapter_Factory : public TAO_Adapter_Factory
+{
+public:
+ /// Constructor
+ TAO_CSD_Object_Adapter_Factory (void);
+
+ // = The TAO_Adapter_Factory methods, please read tao/Adapter.h for
+ // details.
+ virtual TAO_Adapter *create (TAO_ORB_Core *orb_core);
+
+ virtual int init (int argc,
+ ACE_TCHAR* argv[]);
+};
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_CSD_FW, TAO_CSD_Object_Adapter_Factory)
+ACE_FACTORY_DECLARE (TAO_CSD_FW, TAO_CSD_Object_Adapter_Factory)
+
+#include /**/ "ace/post.h"
+#endif /* TAO_CSD_OBJECT_ADAPTER_FACTORY_H */
diff --git a/TAO/tao/CSD_Framework/CSD_POA.cpp b/TAO/tao/CSD_Framework/CSD_POA.cpp
new file mode 100644
index 00000000000..98ec63d864e
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_POA.cpp
@@ -0,0 +1,131 @@
+// $Id$
+
+
+#include "CSD_POA.h"
+#include "CSD_Strategy_Repository.h"
+#include "CSD_Strategy_Base.h"
+
+#include "ace/Dynamic_Service.h"
+
+ACE_RCSID (CSD_Framework,
+ CSD_POA,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_POA.inl"
+#endif /* ! __ACE_INLINE__ */
+
+// Implementation skeleton constructor
+TAO_CSD_POA::TAO_CSD_POA (const String &name,
+ TAO_POA_Manager &poa_manager,
+ const TAO_POA_Policy_Set &policies,
+ TAO_Root_POA *parent,
+ ACE_Lock &lock,
+ TAO_SYNCH_MUTEX &thread_lock,
+ TAO_ORB_Core &orb_core,
+ TAO_Object_Adapter *object_adapter
+ ACE_ENV_ARG_DECL)
+: TAO_Regular_POA (name,
+ poa_manager,
+ policies,
+ parent,
+ lock,
+ thread_lock,
+ orb_core,
+ object_adapter
+ ACE_ENV_ARG_PARAMETER)
+{
+ ACE_NEW_THROW_EX (this->sds_proxy_,
+ TAO::CSD::Strategy_Proxy (),
+ CORBA::NO_MEMORY ());
+ ACE_CHECK;
+}
+
+
+// Implementation skeleton destructor
+TAO_CSD_POA::~TAO_CSD_POA (void)
+{
+ delete this->sds_proxy_;
+}
+
+void TAO_CSD_POA::set_csd_strategy (
+ ::CSD_Framework::Strategy_ptr strategy
+ ACE_ENV_ARG_DECL
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ))
+{
+ if (CORBA::is_nil (strategy))
+ {
+ ACE_THROW (CORBA::BAD_PARAM ());
+ }
+ this->sds_proxy_->custom_strategy (strategy);
+}
+
+TAO_Root_POA *
+TAO_CSD_POA::new_POA (const String &name,
+ TAO_POA_Manager &poa_manager,
+ const TAO_POA_Policy_Set &policies,
+ TAO_Root_POA *parent,
+ ACE_Lock &lock,
+ TAO_SYNCH_MUTEX &thread_lock,
+ TAO_ORB_Core &orb_core,
+ TAO_Object_Adapter *object_adapter
+ ACE_ENV_ARG_DECL)
+{
+ TAO_CSD_POA *poa = 0;
+
+ ACE_NEW_THROW_EX (poa,
+ TAO_CSD_POA (name,
+ poa_manager,
+ policies,
+ parent,
+ lock,
+ thread_lock,
+ orb_core,
+ object_adapter
+ ACE_ENV_ARG_PARAMETER),
+ CORBA::NO_MEMORY ());
+ ACE_CHECK_RETURN (0);
+
+ TAO_CSD_Strategy_Repository *repo =
+ ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance ("TAO_CSD_Strategy_Repository");
+
+
+ CSD_Framework::Strategy_var strategy = repo->find (name);
+
+ if (! CORBA::is_nil (strategy.in ()))
+ {
+ poa->set_csd_strategy (strategy.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+ }
+
+ return poa;
+}
+
+void TAO_CSD_POA::poa_activated_hook ()
+{
+ this->sds_proxy_->poa_activated_event ();
+}
+
+void TAO_CSD_POA::poa_deactivated_hook ()
+{
+ this->sds_proxy_->poa_deactivated_event ();
+}
+
+void TAO_CSD_POA::servant_activated_hook (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ this->sds_proxy_->servant_activated_event (servant, oid ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void TAO_CSD_POA::servant_deactivated_hook (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ this->sds_proxy_->servant_deactivated_event (servant, oid ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
diff --git a/TAO/tao/CSD_Framework/CSD_POA.h b/TAO/tao/CSD_Framework/CSD_POA.h
new file mode 100644
index 00000000000..8038537b45d
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_POA.h
@@ -0,0 +1,108 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file CSD_POA.h
+ *
+ * $Id$
+ *
+ * @author Yan Dai (dai_y@ociweb.com)
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_POA_H
+#define TAO_CSD_POA_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/PortableServer/Regular_POA.h"
+#include "CSD_Strategy_Proxy.h"
+
+
+/**
+ * @class TAO_CSD_POA
+ *
+ * @brief Implementation of the CSD_Framework::POA interface.
+ *
+ * Implementation of the CSD_Framework::POA interface.
+ */
+class TAO_CSD_FW_Export TAO_CSD_POA
+ : public virtual CSD_Framework::POA,
+ public virtual TAO_Regular_POA
+{
+public:
+ //Constructor
+ TAO_CSD_POA (const String &name,
+ TAO_POA_Manager &poa_manager,
+ const TAO_POA_Policy_Set &policies,
+ TAO_Root_POA *parent,
+ ACE_Lock &lock,
+ TAO_SYNCH_MUTEX &thread_lock,
+ TAO_ORB_Core &orb_core,
+ TAO_Object_Adapter *object_adapter
+ ACE_ENV_ARG_DECL);
+
+ //Destructor
+ virtual ~TAO_CSD_POA (void);
+
+ /// Pass the Strategy object reference to the CSD poa.
+ virtual
+ void set_csd_strategy (
+ ::CSD_Framework::Strategy_ptr s
+ ACE_ENV_ARG_DECL
+ )
+ ACE_THROW_SPEC ((
+ CORBA::SystemException
+ ));
+
+ /// Hook - The POA has been (or is being) activated.
+ virtual void poa_activated_hook ();
+
+ /// Hook - The POA has been deactivated.
+ virtual void poa_deactivated_hook ();
+
+ /// Hook - A servant has been activated.
+ virtual void servant_activated_hook (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+ /// Hook - A servant has been deactivated.
+ virtual void servant_deactivated_hook (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+ ///Method for creating new CSD POA.
+ TAO_Root_POA * new_POA (const String &name,
+ TAO_POA_Manager &poa_manager,
+ const TAO_POA_Policy_Set &policies,
+ TAO_Root_POA *parent,
+ ACE_Lock &lock,
+ TAO_SYNCH_MUTEX &thread_lock,
+ TAO_ORB_Core &orb_core,
+ TAO_Object_Adapter *object_adapter
+ ACE_ENV_ARG_DECL);
+
+ /// Servant Dispatching Strategy proxy accessor.
+ TAO::CSD::Strategy_Proxy&
+ servant_dispatching_strategy_proxy (void) const;
+
+private:
+
+ TAO::CSD::Strategy_Proxy* sds_proxy_;
+};
+
+
+#if defined (__ACE_INLINE__)
+# include "CSD_POA.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_POA_H */
+
diff --git a/TAO/tao/CSD_Framework/CSD_POA.inl b/TAO/tao/CSD_Framework/CSD_POA.inl
new file mode 100644
index 00000000000..7a9aef6f63a
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_POA.inl
@@ -0,0 +1,11 @@
+// $Id$
+
+
+
+ACE_INLINE
+TAO::CSD::Strategy_Proxy&
+TAO_CSD_POA::servant_dispatching_strategy_proxy (void) const
+{
+ return *sds_proxy_;
+}
+
diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Base.cpp b/TAO/tao/CSD_Framework/CSD_Strategy_Base.cpp
new file mode 100644
index 00000000000..de6524c3b04
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Strategy_Base.cpp
@@ -0,0 +1,133 @@
+// $Id$
+
+#include "CSD_Strategy_Base.h"
+#include "CSD_POA.h"
+#include "CSD_Strategy_Proxy.h"
+#include "tao/PortableServer/Root_POA.h"
+#include "tao/PortableServer/POAManager.h"
+#include "tao/PortableServer/Servant_Base.h"
+#include "tao/TAO_Server_Request.h"
+
+ACE_RCSID (CSD_Framework,
+ CSD_Strategy_Base,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_Strategy_Base.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::Strategy_Base::~Strategy_Base()
+{
+}
+
+CORBA::Boolean
+TAO::CSD::Strategy_Base::apply_to (PortableServer::POA_ptr poa
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (CORBA::is_nil(poa))
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("(%P|%t) CSD Strategy cannot ")
+ ACE_TEXT("be applied to a nil POA.\n")));
+ return false;
+ }
+
+ if (!CORBA::is_nil(this->poa_.in()))
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("(%P|%t) CSD Strategy already ")
+ ACE_TEXT("applied to a POA.\n")));
+ return false;
+ }
+
+ // The POA is a local interface (IDL terminology), and thus we know that
+ // we can downcast the POA_ptr to its (TAO) implementation type.
+ TAO_CSD_POA* poa_impl = dynamic_cast<TAO_CSD_POA*>(poa);
+
+ if (poa_impl == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("(%P|%t) CSD Strategy cannot ")
+ ACE_TEXT("be applied to a non CSD POA.\n")));
+ return false;
+ }
+
+ // We need to check to see if the POA is already "active". If this is
+ // the case, then we need to handle the poa_activated_event() right now.
+ // If the POA is not already "active", then we can just wait until it
+ // does get activated, and we (the strategy) will be informed of the
+ // poa_activated_event() at that time.
+ if (poa_impl->tao_poa_manager().get_state() ==
+ PortableServer::POAManager::ACTIVE)
+ {
+ // The POA is already "active" (since its POAManager is active).
+ // We need to "raise" the poa_activated_event() now. Otherwise,
+ // the event will be raised when the POAManager does become active.
+ if (!this->poa_activated_event())
+ {
+ // An error has been already been reported to the log with
+ // the detailed reason for the failure to handle the event.
+ return false;
+ }
+ }
+
+ // Set the CSD Strategy_Base on the strategy proxy object owned by the POA.
+ bool strategy_set = false;
+ ACE_TRY_NEW_ENV
+ {
+ poa_impl->set_csd_strategy (this ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ strategy_set = true;
+ }
+ ACE_CATCHANY
+ {
+ }
+ ACE_ENDTRY;
+
+ if (! strategy_set)
+ {
+ // We need to make sure that we raise a poa_deactivated_event() if
+ // we earlier raised a poa_activated_event().
+ this->poa_deactivated_event();
+
+ // An error has been already been reported to the log with
+ // the detailed reason why the proxy will not accept the
+ // custom strategy.
+ return false;
+ }
+
+ // Save a duplicate of the poa into our data member.
+ this->poa_ = PortableServer::POA::_duplicate (poa);
+
+ // Success
+ return true;
+}
+
+
+void
+TAO::CSD::Strategy_Base::servant_activated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ ACE_UNUSED_ARG(servant);
+ ACE_UNUSED_ARG(oid);
+ // do nothing.
+}
+
+
+void
+TAO::CSD::Strategy_Base::servant_deactivated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ ACE_UNUSED_ARG(servant);
+ ACE_UNUSED_ARG(oid);
+ // do nothing.
+}
diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Base.h b/TAO/tao/CSD_Framework/CSD_Strategy_Base.h
new file mode 100644
index 00000000000..9650a914a45
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Strategy_Base.h
@@ -0,0 +1,172 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Custom_Servant_Dispatching_Strategy.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_FW_CUSTOM_SERVANT_DISPATCHING_STRATEGY_H
+#define TAO_CSD_FW_CUSTOM_SERVANT_DISPATCHING_STRATEGY_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/Servant_Upcall.h"
+#include "tao/PortableServer/Servant_Base.h"
+#include "tao/TAO_Server_Request.h"
+#include "tao/LocalObject.h"
+
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_FrameworkC.h"
+
+class TAO_Root_POA;
+namespace PortableServer
+{
+ class POAManager;
+};
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+ /**
+ * @class Strategy_Base
+ *
+ * @brief Base class for all Custom Servant Dispatching Strategies.
+ *
+ * This class serves as the base class for all "custom" strategies that
+ * perform servant dispatching. An instance of (a subclass of) this class
+ * can be applied to a POA object. Any servant requests for the POA will
+ * be "dispatched" to this strategy object.
+ *
+ */
+ class TAO_CSD_FW_Export Strategy_Base
+ : public CSD_Framework::Strategy,
+ public TAO_Local_RefCounted_Object
+ {
+ public:
+
+ /// Result Type for dispatching method(s).
+ enum DispatchResult
+ {
+ // The request dispatching has been handled.
+ DISPATCH_HANDLED,
+
+ // The request dispatching has been rejected.
+ DISPATCH_REJECTED,
+
+ // Defer to "default" dispatching strategy (use the caller's thread).
+ DISPATCH_DEFERRED
+ };
+
+ /// Virtual Destructor.
+ virtual ~Strategy_Base();
+
+ /// This method is invoked to "attach" this strategy object to
+ /// the supplied POA. Returns true for success, and false for failure.
+ CORBA::Boolean apply_to(PortableServer::POA_ptr poa ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ protected:
+ /// Default Constructor.
+ Strategy_Base();
+
+ /// Subclass provides implementation to dispatch a remote request.
+ virtual DispatchResult dispatch_remote_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant
+ ACE_ENV_ARG_DECL) = 0;
+
+ /// Subclass provides implementation to dispatch a collocated request.
+ virtual DispatchResult dispatch_collocated_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant
+ ACE_ENV_ARG_DECL) = 0;
+
+ /// Event - The POA has been activated.
+ virtual bool poa_activated_event_i() = 0;
+
+ /// Event - The POA has been deactivated.
+ virtual void poa_deactivated_event_i() = 0;
+
+ /// Event - A servant has been activated.
+ virtual void servant_activated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+ /// Event - A servant has been deactivated.
+ virtual void servant_deactivated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+ private:
+
+ /// Only our friend, the proxy, is allowed to invoke our private operations.
+ /// This allows us to not pollute the public interface of the CSD Strategy_Base
+ /// subclasses with methods that should never be called (except by the
+ /// proxy, of course).
+ friend class Strategy_Proxy;
+
+ /// This CSD Strategy_Base has been asked to dispatch a (collocated or remote)
+ /// request.
+ void dispatch_request(TAO_ServerRequest& server_request,
+ ::TAO::Portable_Server::Servant_Upcall& upcall
+ ACE_ENV_ARG_DECL);
+
+ /// Event - The POA has been activated. This happens when the POA_Manager
+ /// is activated.
+ bool poa_activated_event();
+
+ /// Event - The POA has been deactivated. This happens when the
+ /// POAManager is deactivated, or when the POA is destroyed.
+ void poa_deactivated_event();
+
+ /// Event - A servant has been activated.
+ void servant_activated_event(PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+ /// Event - A servant has been deactivated. This also occurs when
+ /// the POA is destroyed.
+ void servant_deactivated_event(PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+ /// The POA to which this strategy has been applied.
+ ::PortableServer::POA_var poa_;
+
+ /// This flag indicates that the POA is currently active (true) or
+ /// currently inactive (false).
+ bool poa_activated_;
+ };
+ }
+}
+
+
+#if defined (__ACE_INLINE__)
+# include "CSD_Strategy_Base.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_FW_CUSTOM_SERVANT_DISPATCHING_STRATEGY_H */
diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Base.inl b/TAO/tao/CSD_Framework/CSD_Strategy_Base.inl
new file mode 100644
index 00000000000..1f31a6cdcf4
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Strategy_Base.inl
@@ -0,0 +1,138 @@
+// -*- C++ -*-
+// $Id$
+#include "tao/debug.h"
+
+ACE_INLINE
+TAO::CSD::Strategy_Base::Strategy_Base()
+ : poa_activated_(false)
+{
+}
+
+ACE_INLINE
+void
+TAO::CSD::Strategy_Base::dispatch_request
+ (TAO_ServerRequest& server_request,
+ TAO::Portable_Server::Servant_Upcall& upcall
+ ACE_ENV_ARG_DECL)
+{
+ DispatchResult result;
+
+ if (server_request.collocated())
+ {
+ result = this->dispatch_collocated_request_i(server_request,
+ upcall.user_id(),
+ this->poa_.in(),
+ server_request.operation(),
+ upcall.servant()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ else
+ {
+ result = this->dispatch_remote_request_i(server_request,
+ upcall.user_id(),
+ this->poa_.in(),
+ server_request.operation(),
+ upcall.servant()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ switch (result)
+ {
+ case DISPATCH_HANDLED:
+ // Do nothing. Everything has been handled.
+ break;
+
+ case DISPATCH_REJECTED:
+ if (server_request.collocated ())
+ {
+ CORBA::NO_IMPLEMENT ex;
+ ex._raise ();
+ }
+ else
+ {
+ // Raise an appropriate SystemException if the request is expecting
+ // a reply.
+ if (!server_request.sync_with_server() &&
+ server_request.response_expected() &&
+ !server_request.deferred_reply())
+ {
+ CORBA::NO_IMPLEMENT ex;
+ server_request.tao_send_reply_exception(ex);
+ }
+ }
+ break;
+
+ case DISPATCH_DEFERRED:
+ // Perform the "default" dispatching strategy logic for this request
+ // right now, using the current thread.
+ upcall.servant()->_dispatch(server_request,
+ (void*)&upcall
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ break;
+
+ default:
+ if (TAO_debug_level > 0)
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("(%P|%t) Unknown result (%d) from call to ")
+ ACE_TEXT("dispatch_remote_request_i().\n"), result));
+ // Since we do not know what to do here, just do the minimum, which
+ // treats this case just like the DISPATCH_HANDLED case, for better
+ // or worse. Hitting this default case means a coding error.
+ break;
+ }
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::Strategy_Base::poa_activated_event()
+{
+ // Notify the subclass of the event, saving the result.
+ this->poa_activated_ = this->poa_activated_event_i();
+
+ // Return the result
+ return this->poa_activated_;
+}
+
+ACE_INLINE
+void
+TAO::CSD::Strategy_Base::poa_deactivated_event()
+{
+ if (this->poa_activated_)
+ {
+ this->poa_activated_ = false;
+
+ // Notify the subclass of the event.
+ this->poa_deactivated_event_i();
+
+ // Reset the poa to nil to decrement the reference count.
+ // This will break the circular dependency of the deletion
+ // of the CSD POA.
+ this->poa_ = 0;
+ }
+}
+
+ACE_INLINE
+void
+TAO::CSD::Strategy_Base::servant_activated_event
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ this->servant_activated_event_i(servant, oid ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+ACE_INLINE
+void
+TAO::CSD::Strategy_Base::servant_deactivated_event
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ this->servant_deactivated_event_i(servant, oid ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.cpp b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.cpp
new file mode 100644
index 00000000000..063ec14f9aa
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.cpp
@@ -0,0 +1,47 @@
+// $Id$
+
+#include "CSD_Strategy_Proxy.h"
+#include "tao/TAO_Server_Request.h"
+#include "tao/debug.h"
+
+ACE_RCSID (CSD_Framework,
+ CSD_Strategy_Base,
+ "$Id$")
+
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_Strategy_Proxy.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+bool
+TAO::CSD::Strategy_Proxy::custom_strategy
+ (CSD_Framework::Strategy_ptr strategy)
+{
+ if (this->strategy_impl_)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("(%P|%t) Error - TAO::CSD::Strategy_Proxy ")
+ ACE_TEXT("object already has a custom strategy.\n")));
+
+ return false;
+ }
+
+ if (CORBA::is_nil(strategy))
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR((LM_ERROR,
+ ACE_TEXT("(%P|%t) Error - TAO::CSD::Strategy_Proxy ")
+ ACE_TEXT("supplied with a NIL custom strategy.\n")));
+
+ return false;
+ }
+
+ // We need to bump up the reference count of the strategy before saving
+ // it off into our handle (smart pointer) data member.
+ this->strategy_ = CSD_Framework::Strategy::_duplicate(strategy);
+ this->strategy_impl_ = dynamic_cast <TAO::CSD::Strategy_Base*> (strategy);
+
+ return true;
+}
diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.h b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.h
new file mode 100644
index 00000000000..78ffea92778
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.h
@@ -0,0 +1,110 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_Strategy_Proxy.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_SERVANT_DISPATCHING_STRATEGY_PROXY_H
+#define TAO_SERVANT_DISPATCHING_STRATEGY_PROXY_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/Servant_Upcall.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_Strategy_Base.h"
+
+class TAO_ServerRequest;
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+ /**
+ * @class Strategy_Proxy
+ *
+ * @brief Proxy class for the Custom Servant Dispatching Strategy.
+ *
+ * If no custom servant dispatching strategy is provided to the proxy,
+ * then the "default servant dispatching strategy" logic is used.
+ */
+ class TAO_CSD_FW_Export Strategy_Proxy
+ {
+ public:
+
+ /// Default Constructor.
+ Strategy_Proxy();
+
+ /// Destructor.
+ ~Strategy_Proxy();
+
+ /// Mutator to provide the proxy with a CSD Strategy object.
+ /// A return value of true indicates success, and false indicates
+ /// failure to set the custom strategy on the proxy object.
+ bool custom_strategy(CSD_Framework::Strategy_ptr strategy);
+
+ /// Invoked by the Object_Adapter using an ORB thread.
+ ///
+ /// If the proxy object holds a custom strategy object, then this method
+ /// will simply delegate to the custom strategy object. Otherwise,
+ /// this method will perform the "default servant dispatching strategy"
+ /// logic, preserving the original logic path as it was prior to the
+ /// introduction of the Custom Servant Dispatching feature.
+ ///
+ /// This method will be inlined (if inlining is turned on during the build).
+ ///
+ /// The added cost to the original logic path will be this method
+ /// invocation + one conditional (an is_nil() call/comparison for truth on
+ /// the smart pointer to the custom dispatching strategy object).
+ void dispatch_request(TAO_ServerRequest& server_request,
+ TAO::Portable_Server::Servant_Upcall& upcall
+ ACE_ENV_ARG_DECL);
+
+
+ /// Event - The POA has been (or is being) activated.
+ bool poa_activated_event();
+
+ /// Event - The POA has been deactivated.
+ void poa_deactivated_event();
+
+ /// Event - A servant has been activated.
+ void servant_activated_event(PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+ /// Event - A servant has been deactivated.
+ void servant_deactivated_event(PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+ private:
+
+ /// Smart Pointer to a custom servant dispatching strategy object.
+ /// This smart pointer will be in the "nil" state when the "default"
+ /// strategy is to be applied.
+ CSD_Framework::Strategy_var strategy_;
+ TAO::CSD::Strategy_Base *strategy_impl_;
+ };
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_Strategy_Proxy.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif
diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.inl b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.inl
new file mode 100644
index 00000000000..320fd6dca8f
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.inl
@@ -0,0 +1,104 @@
+// -*- C++ -*-
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::Strategy_Proxy::Strategy_Proxy()
+ : strategy_impl_(0)
+{
+}
+
+
+ACE_INLINE
+TAO::CSD::Strategy_Proxy::~Strategy_Proxy()
+{
+ strategy_impl_ = 0; // don't delete it! The var will do it for us.
+}
+
+ACE_INLINE
+void
+TAO::CSD::Strategy_Proxy::dispatch_request
+ (TAO_ServerRequest& server_request,
+ TAO::Portable_Server::Servant_Upcall& upcall
+ ACE_ENV_ARG_DECL)
+{
+
+ if (this->strategy_impl_ == 0)
+ {
+ // This is the "default" strategy implementation.
+ upcall.servant()->_dispatch(server_request,
+ (void*)&upcall
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ else
+ {
+ // Delegate to the custom strategy object.
+ this->strategy_impl_->dispatch_request(server_request,
+ upcall
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::Strategy_Proxy::poa_activated_event()
+{
+ // Delegate to the custom strategy object (or return true if this proxy
+ // is not holding a custom strategy).
+ return (this->strategy_impl_ == 0) ? true
+ : this->strategy_impl_->poa_activated_event();
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::Strategy_Proxy::poa_deactivated_event()
+{
+ // We only need to do something if this proxy holds a custom strategy.
+ if (this->strategy_impl_)
+ {
+ // Delegate to the custom strategy object.
+ this->strategy_impl_->poa_deactivated_event();
+ }
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::Strategy_Proxy::servant_activated_event
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ // We only need to do something if this proxy holds a custom strategy.
+ if (this->strategy_impl_)
+ {
+ // Delegate to the custom strategy object.
+ this->strategy_impl_->servant_activated_event(servant,
+ oid
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::Strategy_Proxy::servant_deactivated_event
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ // We only need to do something if this proxy holds a custom strategy.
+ if (this->strategy_impl_)
+ {
+ // Delegate to the custom strategy object.
+ this->strategy_impl_->servant_deactivated_event(servant,
+ oid
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Repository.cpp b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.cpp
new file mode 100644
index 00000000000..2a98495e301
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.cpp
@@ -0,0 +1,114 @@
+// $Id$
+
+#include "CSD_Strategy_Repository.h"
+#include "tao/debug.h"
+
+ACE_RCSID (CSD_Framework,
+ CSD_Strategy_Factory,
+ "$Id$")
+
+
+TAO_CSD_Strategy_Repository::TAO_CSD_Strategy_Repository()
+{
+}
+
+
+TAO_CSD_Strategy_Repository::~TAO_CSD_Strategy_Repository()
+{
+ delete this->strategy_list_head_;
+}
+
+int
+TAO_CSD_Strategy_Repository::init(int, ACE_TCHAR **)
+{
+
+ static int initialized = 0;
+
+ // Only allow initialization once.
+ if (initialized)
+ return 0;
+
+ initialized = 1;
+ this->strategy_list_head_ = 0;
+ return 0;
+}
+
+CSD_Framework::Strategy_ptr
+TAO_CSD_Strategy_Repository::find (const ACE_CString& name)
+{
+
+ if (this->strategy_list_head_ != 0)
+ {
+ Strategy_Node *node = this->strategy_list_head_->find(name);
+ if (node != 0)
+ return CSD_Framework::Strategy::_duplicate (node->strategy_.in());
+ }
+
+ return CSD_Framework::Strategy::_nil();
+}
+
+
+int
+TAO_CSD_Strategy_Repository::add_strategy (const ACE_CString& name,
+ CSD_Framework::Strategy_ptr strat)
+{
+ Strategy_Node *node = 0;
+ ACE_NEW_RETURN (node, Strategy_Node(name,strat),-1);
+ if (this->strategy_list_head_ == 0)
+ this->strategy_list_head_ = node;
+ else
+ this->strategy_list_head_->add_node(node);
+
+ if (TAO_debug_level > 3)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("Strategy_Repository::add_strategy for %s \n"),
+ name.c_str ()));
+ }
+ return 0;
+}
+
+TAO_CSD_Strategy_Repository::Strategy_Node::Strategy_Node (const ACE_CString& name,
+ CSD_Framework::Strategy_ptr strat)
+ : poa_name_(name),
+ strategy_(CSD_Framework::Strategy::_duplicate(strat)),
+ next_(0)
+{
+}
+
+TAO_CSD_Strategy_Repository::Strategy_Node::~Strategy_Node ()
+{
+ if (this->next_)
+ delete this->next_;
+}
+
+void
+TAO_CSD_Strategy_Repository::Strategy_Node::add_node(Strategy_Node *node)
+{
+ if (this->next_)
+ this->next_->add_node(node);
+ else
+ this->next_ = node;
+}
+
+TAO_CSD_Strategy_Repository::Strategy_Node *
+TAO_CSD_Strategy_Repository::Strategy_Node::find(const ACE_CString &name)
+{
+ if (this->poa_name_ == name)
+ return this;
+ if (this->next_)
+ return this->next_->find(name);
+ return 0;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+
+ACE_FACTORY_DEFINE (TAO_CSD_FW, TAO_CSD_Strategy_Repository)
+ACE_STATIC_SVC_DEFINE (TAO_CSD_Strategy_Repository,
+ ACE_TEXT ("TAO_CSD_Strategy_Repository"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_CSD_Strategy_Repository),
+ ACE_Service_Type::DELETE_THIS
+ | ACE_Service_Type::DELETE_OBJ,
+ 0)
diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Repository.h b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.h
new file mode 100644
index 00000000000..d9b1ef773d0
--- /dev/null
+++ b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.h
@@ -0,0 +1,75 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_Strategy_Repository.h
+ *
+ * $Id$
+ *
+ * @author Yan Dai <dai_y@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_STRATEGY_FACTORY_H
+#define TAO_CSD_STRATEGY_FACTORY_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_FW_Export.h"
+#include "CSD_FrameworkC.h"
+#include "ace/Service_Object.h"
+#include "ace/Service_Config.h"
+#include "ace/Synch.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+/**
+ * @class TAO_CSD_Strategy_Factory
+ *
+ * @brief An ACE_Service_Object capable of creating TP_Strategy objects.
+ *
+ * TBD - Explain in more detail.
+ *
+ */
+class TAO_CSD_FW_Export TAO_CSD_Strategy_Repository : public ACE_Service_Object
+{
+public:
+
+ /// Constructor.
+ TAO_CSD_Strategy_Repository();
+
+ /// Virtual Destructor.
+ virtual ~TAO_CSD_Strategy_Repository();
+
+ int init (int argc, ACE_TCHAR ** argv);
+
+ /// Factory method used to create a CSD_Strategy object.
+ CSD_Framework::Strategy_ptr find (const ACE_CString& poa_name);
+
+ int add_strategy (const ACE_CString& poa_name,
+ CSD_Framework::Strategy_ptr strategy);
+
+private:
+ struct Strategy_Node {
+ Strategy_Node(const ACE_CString& poa_name,
+ CSD_Framework::Strategy_ptr strategy);
+ ~Strategy_Node();
+ void add_node (Strategy_Node *);
+ Strategy_Node *find(const ACE_CString& name);
+
+ ACE_CString poa_name_;
+ CSD_Framework::Strategy_var strategy_;
+ Strategy_Node * next_;
+ };
+ Strategy_Node * strategy_list_head_;
+};
+
+ACE_STATIC_SVC_DECLARE_EXPORT (TAO_CSD_FW, TAO_CSD_Strategy_Repository)
+ACE_FACTORY_DECLARE (TAO_CSD_FW, TAO_CSD_Strategy_Repository)
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_STRATEGY_FACTORY_H */
diff --git a/TAO/tao/CSD_Framework/diffs/CSD_Framework.diff b/TAO/tao/CSD_Framework/diffs/CSD_Framework.diff
new file mode 100644
index 00000000000..4d5e2989f73
--- /dev/null
+++ b/TAO/tao/CSD_Framework/diffs/CSD_Framework.diff
@@ -0,0 +1,38 @@
+--- CSD_FrameworkA.h 2005-10-03 16:07:54.484375000 -0700
++++ orig/CSD_FrameworkA.h 2005-10-03 13:11:38.312500000 -0700
+@@ -34,8 +34,8 @@
+ #include /**/ "ace/pre.h"
+
+ #include "CSD_FW_Export.h"
+-#include "CSD_FrameworkC.h"
+-//#include "tao/PortableServer/PortableServerA.h"
++#include "tao/orig/CSD_FrameworkC.h"
++#include "tao/PortableServer/PortableServerA.h"
+
+
+ // TAO_IDL - Generated from
+--- CSD_FrameworkC.h 2005-10-03 16:08:02.500000000 -0700
++++ orig/CSD_FrameworkC.h 2005-10-03 13:11:38.312500000 -0700
+@@ -47,7 +47,7 @@
+ #include "tao/Object.h"
+ #include "tao/Objref_VarOut_T.h"
+
+-#include "tao/PortableServer/PortableServer.h"
++#include "tao/PortableServer/PortableServerC.h"
+
+ #if defined (TAO_EXPORT_MACRO)
+ #undef TAO_EXPORT_MACRO
+@@ -305,6 +305,13 @@
+ #endif /* end #if !defined */
+ }
+
++// TAO_IDL - Generated from
++// .\be\be_codegen.cpp:1040
++
++#if defined (__ACE_INLINE__)
++#include "CSD_FrameworkC.inl"
++#endif /* defined INLINE */
++
+ #include /**/ "ace/post.h"
+
+ #endif /* ifndef */
diff --git a/TAO/tao/CSD_ThreadPool.mpc b/TAO/tao/CSD_ThreadPool.mpc
new file mode 100644
index 00000000000..54a6dffc681
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool.mpc
@@ -0,0 +1,34 @@
+//$Id$
+project : csd_framework {
+ sharedname = TAO_CSD_ThreadPool
+ dynamicflags = TAO_CSD_TP_BUILD_DLL
+ includes += $(TAO_ROOT)/tao
+
+ Source_Files {
+ CSD_ThreadPool
+ }
+
+ Header_Files {
+ CSD_ThreadPool
+ }
+
+ Inline_Files {
+ CSD_ThreadPool
+ }
+
+ Template_Files {
+ CSD_ThreadPool
+ }
+
+ Resource_Files {
+ CSD_ThreadPool
+ }
+
+ IDL_Files {
+ CSD_ThreadPool
+ }
+
+ PIDL_Files {
+ CSD_ThreadPool
+ }
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.cpp
new file mode 100644
index 00000000000..9117ad0b690
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.cpp
@@ -0,0 +1,44 @@
+// $Id$
+
+#include "CSD_TP_Cancel_Visitor.h"
+#include "CSD_TP_Request.h"
+
+ACE_RCSID (CSD_TP,
+ Cancel_Visitor,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Cancel_Visitor.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Cancel_Visitor::~TP_Cancel_Visitor()
+{
+}
+
+
+bool
+TAO::CSD::TP_Cancel_Visitor::visit_request(TP_Request* request,
+ bool& remove_flag)
+{
+ // If our servant_ data member is in the 'nil' state, then
+ // we are supposed to cancel *ALL* requests that we visit.
+ //
+ // Otherwise, if our servant_ data member is not in the 'nil' state,
+ // we are supposed to cancel only requests that target our specific
+ // servant_.
+
+ if ((this->servant_.in() == 0) || (request->is_target(this->servant_.in())))
+ {
+ // Set the remove_flag to true so that this request is removed
+ // (and released) from the queue when we finish our visit.
+ remove_flag = true;
+
+ // Cancel the request
+ request->cancel();
+ }
+
+ // Since we are either cancelling requests to any servant or a
+ // specific servant, always continue visitation.
+ return true;
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h
new file mode 100644
index 00000000000..538f6899979
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h
@@ -0,0 +1,85 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Cancel_Visitor.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_CANCEL_VISITOR_H
+#define TAO_CSD_TP_CANCEL_VISITOR_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+#include "tao/PortableServer/Servant_Base.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Queue_Visitor.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ /**
+ * @class TP_Cancel_Visitor
+ *
+ * @brief Used to extract/cancel request(s) from the queue.
+ *
+ * This visitor is used to cancel certain requests in the queue
+ * as they are visited.
+ *
+ * Note that this is currently implemented to cancel *all*
+ * requests in the queue, or requests that are targeted for a specific
+ * servant. This could be extended in the future to perhaps
+ * cancel all requests that have the same operation name, or something
+ * else.
+ *
+ */
+ class TAO_CSD_TP_Export TP_Cancel_Visitor : public TP_Queue_Visitor
+ {
+ public:
+
+ /// Default Constructor - cancel *all* requests.
+ TP_Cancel_Visitor();
+
+ /// Constructor with provided servant - cancel requests that
+ /// target the supplied servant.
+ TP_Cancel_Visitor(PortableServer::Servant servant);
+
+ /// Virtual Destructor.
+ virtual ~TP_Cancel_Visitor();
+
+ /// Returns true to continue visitation. Returns false to stop
+ /// visitation. Sets the remove_flag to true if the request should
+ /// be removed from the queue as a result of the visit. Leaves the
+ /// remove_flag alone otherwise.
+ virtual bool visit_request(TP_Request* request, bool& remove_flag);
+
+
+ private:
+
+ /// Left as nil if we are to cancel all requests, or set to a specific
+ /// servant if only requests targeting that servant should be cancelled.
+ PortableServer::ServantBase_var servant_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Cancel_Visitor.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_DISPATCHABLE_VISITOR_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.inl
new file mode 100644
index 00000000000..b5d698f1f7a
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.inl
@@ -0,0 +1,28 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Cancel_Visitor::TP_Cancel_Visitor()
+{
+}
+
+
+ACE_INLINE
+TAO::CSD::TP_Cancel_Visitor::TP_Cancel_Visitor(PortableServer::Servant servant)
+ : servant_(servant)
+{
+ // This try-catch block is not really necessary for current implementation
+ // since the _add_ref does not throw exception, but we have to add it to
+ // satisfy the non-exception builds. If _add_ref really throws an exception
+ // then this constructor needs deal with the exception.
+ ACE_TRY_NEW_ENV
+ {
+ this->servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.cpp
new file mode 100644
index 00000000000..b43ec670d51
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.cpp
@@ -0,0 +1,57 @@
+// $Id$
+
+#include "CSD_TP_Collocated_Asynch_Request.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Collocated_Asynch_Request,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Collocated_Asynch_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Collocated_Asynch_Request::~TP_Collocated_Asynch_Request()
+{
+}
+
+
+void
+TAO::CSD::TP_Collocated_Asynch_Request::prepare_for_queue_i()
+{
+ this->do_clone();
+}
+
+
+void
+TAO::CSD::TP_Collocated_Asynch_Request::dispatch_i()
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->do_dispatch(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ // Eat these. We probably should log these, but since we have already
+ // unblocked the requesting thread there is no point in saving it or
+ // doing anything with it.
+ }
+#if defined (TAO_HAS_EXCEPTIONS)
+ ACE_CATCHALL
+ {
+ // Eat these. We probably should log these, but since we have already
+ // unblocked the requesting thread there is no point in saving it or
+ // doing anything with it.
+ }
+#endif
+ ACE_ENDTRY;
+}
+
+
+void
+TAO::CSD::TP_Collocated_Asynch_Request::cancel_i()
+{
+ this->do_cancel();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h
new file mode 100644
index 00000000000..bf7b2a17b37
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h
@@ -0,0 +1,87 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Collocated_Asynch_Request.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_COLLOCATED_ASYNCH_REQUEST_H
+#define TAO_CSD_TP_COLLOCATED_ASYNCH_REQUEST_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Corba_Request.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Collocated_Asynch_Request;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Collocated_Asynch_Request>
+ TP_Collocated_Asynch_Request_Handle;
+
+ /**
+ * @class TP_Collocated_Asynch_Request
+ *
+ * @brief Represents a "queue-able", collocated, asynchronous,
+ * CORBA request.
+ *
+ * This kind request is one-way collocated request with the default
+ * SYNC_SCOPE policy (SYNC_WITH_TRANSPORT) applied. It is cloned
+ * before enqueuing and the "enqueuing" thread never blocks.
+ */
+ class TAO_CSD_TP_Export TP_Collocated_Asynch_Request
+ : public TP_Corba_Request
+ {
+ public:
+
+ /// Constructor.
+ TP_Collocated_Asynch_Request
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state);
+
+ /// Virtual Destructor.
+ virtual ~TP_Collocated_Asynch_Request();
+
+
+ protected:
+
+ /// Prepare this TP_Collocated_Asynch_Request object to be placed
+ /// into the request queue. This will cause the underlying
+ /// TAO_ServerRequest object to be cloned.
+ virtual void prepare_for_queue_i();
+
+ /// Dispatch the request to the servant.
+ virtual void dispatch_i();
+
+ /// Cancel the request.
+ virtual void cancel_i();
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Collocated_Asynch_Request.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_COLLOCATED_ASYNCH_REQUEST_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.inl
new file mode 100644
index 00000000000..94a7238bd46
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.inl
@@ -0,0 +1,20 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Collocated_Asynch_Request::TP_Collocated_Asynch_Request
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state)
+ : TP_Corba_Request(object_id,
+ poa,
+ operation,
+ servant,
+ servant_state,
+ server_request)
+{
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.cpp
new file mode 100644
index 00000000000..58e868c835a
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.cpp
@@ -0,0 +1,55 @@
+// $Id$
+
+#include "CSD_TP_Collocated_Synch_Request.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Collocated_Synch_Request,
+ "$Id$")
+
+#include "tao/ORB_Core.h"
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Collocated_Synch_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Collocated_Synch_Request::~TP_Collocated_Synch_Request()
+{
+}
+
+
+void
+TAO::CSD::TP_Collocated_Synch_Request::dispatch_i()
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->do_dispatch(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ // We need to save off a copy of the exception.
+ this->exception_ = ACE_ANY_EXCEPTION._tao_duplicate();
+ }
+#if defined (TAO_HAS_EXCEPTIONS)
+ ACE_CATCHALL
+ {
+ this->exception_
+ = new CORBA::UNKNOWN (CORBA::SystemException::_tao_minor_code
+ (TAO_UNHANDLED_SERVER_CXX_EXCEPTION, 0),
+ CORBA::COMPLETED_MAYBE);
+ }
+#endif
+ ACE_ENDTRY;
+
+ this->synch_helper_.dispatched();
+}
+
+
+void
+TAO::CSD::TP_Collocated_Synch_Request::cancel_i()
+{
+ this->synch_helper_.cancelled();
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h
new file mode 100644
index 00000000000..732158e3c02
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h
@@ -0,0 +1,106 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Collocated_Synch_Request.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_COLLOCATED_SYNCH_REQUEST_H
+#define TAO_CSD_TP_COLLOCATED_SYNCH_REQUEST_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Corba_Request.h"
+#include "CSD_TP_Synch_Helper.h"
+#include "tao/Exception.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Collocated_Synch_Request;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Collocated_Synch_Request>
+ TP_Collocated_Synch_Request_Handle;
+
+ /**
+ * @class TP_Collocated_Synch_Request
+ *
+ * @brief Represents a "queue-able", synchronous, collocated,
+ * CORBA request.
+ *
+ * This kind request is the two-way or oneway(with SYNC_WITH_TARGET
+ * policy applied) collocated request. It is NOT cloned before
+ * enqueuing and the "enqueuing" thread will block until the request
+ * is dispatched/handled or cancelled.
+ */
+ class TAO_CSD_TP_Export TP_Collocated_Synch_Request
+ : public TP_Corba_Request
+ {
+ public:
+
+ /// Constructor.
+ TP_Collocated_Synch_Request
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state);
+
+ /// Virtual Destructor.
+ virtual ~TP_Collocated_Synch_Request();
+
+ /// Wait until the request has been dispatched (and completed), or
+ /// until it has been cancelled.
+ /// Returns true if the request has been dispatched, and returns
+ /// false if the request has been cancelled.
+ bool wait(ACE_ENV_SINGLE_ARG_DECL);
+
+
+ protected:
+
+ /// Note that we do not override our base class implementation of
+ /// prepare_for_queue_i() (which does nothing), because we don't
+ /// need to clone the Server Request object.
+
+ /// Dispatch the request to the servant.
+ virtual void dispatch_i();
+
+ /// Cancel the request.
+ virtual void cancel_i();
+
+
+ private:
+
+ /// Helper used to block and unblock the thread that invokes our
+ /// wait() method.
+ TP_Synch_Helper synch_helper_;
+
+ /// Set to NULL initially, and will only be set thereafter if an
+ /// exception is raised from the dispatch() call on the server_request_.
+ CORBA::Exception* exception_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Collocated_Synch_Request.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_COLLOCATED_SYNCH_REQUEST_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.inl
new file mode 100644
index 00000000000..4481a463c1e
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.inl
@@ -0,0 +1,52 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Collocated_Synch_Request::TP_Collocated_Synch_Request
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state)
+ : TP_Corba_Request(object_id,
+ poa,
+ operation,
+ servant,
+ servant_state,
+ server_request),
+ exception_(0)
+{
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::TP_Collocated_Synch_Request::wait(ACE_ENV_SINGLE_ARG_DECL)
+{
+ bool dispatched = this->synch_helper_.wait_while_pending();
+
+ if (dispatched)
+ {
+ // Check to see if the dispatching caused an exception to be raised.
+ if (this->exception_ != 0)
+ {
+ // An exception was raised during the actual dispatching to
+ // the servant. We need to raise the exception to our caller,
+ // which is the thread that made the collocated request in the
+ // first place.
+ CORBA::Exception* ex = this->exception_;
+ this->exception_ = 0;
+
+#if defined (TAO_HAS_EXCEPTIONS)
+ ACE_Auto_Basic_Ptr<CORBA::Exception> ex_holder(ex);
+ ex->_raise ();
+#else
+ ACE_TRY_ENV.exception (ex);
+#endif /* ACE_HAS_EXCEPTIONS */
+ }
+ }
+
+ return dispatched;
+
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.cpp
new file mode 100644
index 00000000000..657cac81be0
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.cpp
@@ -0,0 +1,71 @@
+// $Id$
+
+#include "CSD_TP_Collocated_Synch_With_Server_Request.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Collocated_Synch_With_Server_Request,
+ "$Id$")
+
+#include "tao/Exception.h"
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Collocated_Synch_With_Server_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Collocated_Synch_With_Server_Request::~TP_Collocated_Synch_With_Server_Request()
+{
+}
+
+
+void
+TAO::CSD::TP_Collocated_Synch_With_Server_Request::prepare_for_queue_i()
+{
+ // NOTE: We *NEED* clone the TAO_ServerRequest for a collocated,
+ // one-way SYNC_WITH_SERVER request. This is because the
+ // calling thread is signalled just *before* the request is
+ // dispatched. It's (very) possible that the calling thread
+ // will destroy the underlying TAO_ServerRequest object while
+ // the request is dispatching to servant. This is why we make
+ // a clone - so that we have our own copy that won't be destroyed
+ // while we are using it.
+ this->do_clone();
+}
+
+
+void
+TAO::CSD::TP_Collocated_Synch_With_Server_Request::dispatch_i()
+{
+ // This is done *before* we do_dispatch().
+ this->synch_helper_.dispatched();
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->do_dispatch(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ // Eat these. We probably should log these, but since we have already
+ // unblocked the requesting thread there is no point in saving it or
+ // doing anything with it.
+ }
+#if defined (TAO_HAS_EXCEPTIONS)
+ ACE_CATCHALL
+ {
+ // Eat these. We probably should log these, but since we have already
+ // unblocked the requesting thread there is no point in saving it or
+ // doing anything with it.
+ }
+#endif
+ ACE_ENDTRY;
+}
+
+
+void
+TAO::CSD::TP_Collocated_Synch_With_Server_Request::cancel_i()
+{
+ this->synch_helper_.cancelled();
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h
new file mode 100644
index 00000000000..39748db1853
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h
@@ -0,0 +1,107 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Collocated_Synch_With_Server_Request.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_COLLOCATED_SYNCH_WITH_SERVER_REQUEST_H
+#define TAO_CSD_TP_COLLOCATED_SYNCH_WITH_SERVER_REQUEST_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Corba_Request.h"
+#include "CSD_TP_Synch_Helper.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Collocated_Synch_With_Server_Request;
+ typedef TAO_Intrusive_Ref_Count_Handle
+ <TP_Collocated_Synch_With_Server_Request>
+ TP_Collocated_Synch_With_Server_Request_Handle;
+
+ /**
+ * @class TP_Collocated_Synch_With_Server_Request
+ *
+ * @brief Represents a "queue-able", one-way, collocated, CORBA
+ * request with a "Synch Scope" policy of SYNC_WITH_SERVER.
+ *
+ * This kind of request is one-way request with the SYNC_WITH_SERVER
+ * policy applied. It is cloned before enqueuing and the "enqueuing"
+ * thread will block until it is signalled by the TP_Task thread that
+ * will happen just before the request is dispatched or the request
+ * is cancelled.
+ */
+ class TAO_CSD_TP_Export TP_Collocated_Synch_With_Server_Request
+ : public TP_Corba_Request
+ {
+ public:
+
+ /// Constructor.
+ TP_Collocated_Synch_With_Server_Request
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state);
+
+ /// Virtual Destructor.
+ virtual ~TP_Collocated_Synch_With_Server_Request();
+
+ /// Wait until the request has been dispatched (but not completed), or
+ /// until it has been cancelled. Note that this will wait until just
+ /// *before* the request is dispatched by a worker thread. This is
+ /// different than the TP_Collocated_Synch_Request which waits until
+ /// just *after* the request is dispatched by a worker thread.
+ /// Returns true if the request has been dispatched, and returns
+ /// false if the request has been cancelled.
+ bool wait(ACE_ENV_SINGLE_ARG_DECL);
+
+
+ protected:
+
+ /// Prepare this TP_Collocated_Synch_With_Server_Request object to be
+ /// placed into the request queue. This will cause the underlying
+ /// TAO_ServerRequest object to be cloned.
+ virtual void prepare_for_queue_i();
+
+ /// Dispatch the request to the servant.
+ virtual void dispatch_i();
+
+ /// Cancel the request.
+ virtual void cancel_i();
+
+
+ private:
+
+ /// Helper used to block and unblock the thread that invokes our
+ /// wait() method.
+ TP_Synch_Helper synch_helper_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Collocated_Synch_With_Server_Request.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_COLLOCATED_SYNCH_WITH_SERVER_REQUEST_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.inl
new file mode 100644
index 00000000000..08dc5141fae
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.inl
@@ -0,0 +1,27 @@
+// $Id$
+
+ACE_INLINE
+TAO::CSD::TP_Collocated_Synch_With_Server_Request::TP_Collocated_Synch_With_Server_Request
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state)
+ : TP_Corba_Request(object_id,
+ poa,
+ operation,
+ servant,
+ servant_state,
+ server_request)
+{
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::TP_Collocated_Synch_With_Server_Request::wait(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+{
+ return this->synch_helper_.wait_while_pending();
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.cpp
new file mode 100644
index 00000000000..a4a40ba6091
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.cpp
@@ -0,0 +1,16 @@
+// $Id$
+
+#include "CSD_TP_Corba_Request.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Corba_Request,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Corba_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Corba_Request::~TP_Corba_Request()
+{
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.h
new file mode 100644
index 00000000000..d6343e20935
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.h
@@ -0,0 +1,100 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Corba_Request.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_CORBA_REQUEST_H
+#define TAO_CSD_TP_CORBA_REQUEST_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Request.h"
+#include "tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/Servant_Base.h"
+#include "ace/SString.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Corba_Request;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Corba_Request>
+ TP_Corba_Request_Handle;
+
+ /**
+ * @class TP_Corba_Request
+ *
+ * @brief Base class for "queue-able" CORBA requests.
+ *
+ * TBD - Add description
+ *
+ */
+ class TAO_CSD_TP_Export TP_Corba_Request : public TP_Request
+ {
+ public:
+
+ /// Virtual Destructor.
+ virtual ~TP_Corba_Request();
+
+
+ protected:
+
+ /// Constructor.
+ TP_Corba_Request(const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state,
+ TAO_ServerRequest& server_request);
+
+ /// Delegate to the FW_Server_Request_Wrapper clone() method.
+ void do_clone();
+
+ /// Delegate to the FW_Server_Request_Wrapper dispatch() method.
+ void do_dispatch(ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Delegate to the FW_Server_Request_Wrapper cancel() method.
+ void do_cancel();
+
+
+ private:
+
+ /// The ObjectId for the target servant.
+ PortableServer::ObjectId object_id_;
+
+ /// The POA.
+ PortableServer::POA_var poa_;
+
+ /// The name of the IDL operation.
+ ACE_CString operation_;
+
+ /// The TAO_ServerRequest object wrapper.
+ FW_Server_Request_Wrapper server_request_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Corba_Request.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_CORBA_REQUEST_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.inl
new file mode 100644
index 00000000000..2047ad845d3
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.inl
@@ -0,0 +1,42 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Corba_Request::TP_Corba_Request
+ (const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state,
+ TAO_ServerRequest& server_request)
+ : TP_Request(servant,servant_state),
+ object_id_(object_id),
+ operation_(operation),
+ server_request_(server_request)
+{
+ this->poa_ = PortableServer::POA::_duplicate(poa);
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Corba_Request::do_clone()
+{
+ this->server_request_.clone();
+}
+
+ACE_INLINE
+void
+TAO::CSD::TP_Corba_Request::do_dispatch(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->server_request_.dispatch(this->servant() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Corba_Request::do_cancel()
+{
+ this->server_request_.cancel();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.cpp
new file mode 100644
index 00000000000..4ac59c6f1fa
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.cpp
@@ -0,0 +1,50 @@
+// $Id$
+
+#include "CSD_TP_Custom_Asynch_Request.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Custom_Asynch_Request,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Custom_Asynch_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Custom_Asynch_Request::~TP_Custom_Asynch_Request()
+{
+}
+
+
+void
+TAO::CSD::TP_Custom_Asynch_Request::dispatch_i()
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->execute_op();
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ // Eat these. We probably should log these, but since we have already
+ // unblocked the requesting thread there is no point in saving it or
+ // doing anything with it.
+ }
+#if defined (TAO_HAS_EXCEPTIONS)
+ ACE_CATCHALL
+ {
+ // Eat these. We probably should log these, but since we have already
+ // unblocked the requesting thread there is no point in saving it or
+ // doing anything with it.
+ }
+#endif
+ ACE_ENDTRY;
+}
+
+
+void
+TAO::CSD::TP_Custom_Asynch_Request::cancel_i()
+{
+ this->cancel_op();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h
new file mode 100644
index 00000000000..ee3479c2e9c
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h
@@ -0,0 +1,76 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Custom_Asynch_Request.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_CUSTOM_ASYNCH_REQUEST_H
+#define TAO_CSD_TP_CUSTOM_ASYNCH_REQUEST_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Custom_Request.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Custom_Asynch_Request;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Custom_Asynch_Request>
+ TP_Custom_Asynch_Request_Handle;
+
+ /**
+ * @class TP_Custom_Asynch_Request
+ *
+ * @brief Base class for "queue-able", Custom (non-CORBA),
+ * Synchronous requests.
+ *
+ * TBD - Add description
+ *
+ */
+ class TAO_CSD_TP_Export TP_Custom_Asynch_Request
+ : public TP_Custom_Request
+ {
+ public:
+
+ /// Constructor.
+ TP_Custom_Asynch_Request(TP_Custom_Request_Operation* op,
+ TP_Servant_State* servant_state);
+
+ /// Virtual Destructor.
+ virtual ~TP_Custom_Asynch_Request();
+
+
+ protected:
+
+ /// Dispatch the request to the servant.
+ virtual void dispatch_i();
+
+ /// Cancel the request.
+ virtual void cancel_i();
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Custom_Asynch_Request.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_CUSTOM_ASYNCH_REQUEST_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.inl
new file mode 100644
index 00000000000..7281af45b9a
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.inl
@@ -0,0 +1,11 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Custom_Asynch_Request::TP_Custom_Asynch_Request
+ (TP_Custom_Request_Operation* op,
+ TP_Servant_State* servant_state)
+ : TP_Custom_Request(op,servant_state)
+{
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.cpp
new file mode 100644
index 00000000000..810858cca79
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.cpp
@@ -0,0 +1,16 @@
+// $Id$
+
+#include "CSD_TP_Custom_Request.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Custom_Request,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Custom_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Custom_Request::~TP_Custom_Request()
+{
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.h
new file mode 100644
index 00000000000..e4d89f40e15
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.h
@@ -0,0 +1,78 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Custom_Request.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_CUSTOM_REQUEST_H
+#define TAO_CSD_TP_CUSTOM_REQUEST_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Request.h"
+#include "CSD_TP_Custom_Request_Operation.h"
+#include "tao/PortableServer/Servant_Base.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Custom_Request;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Custom_Request>
+ TP_Custom_Request_Handle;
+
+ /**
+ * @class TP_Custom_Request
+ *
+ * @brief Base class for "queue-able" Custom (non-CORBA) requests.
+ *
+ * TBD - Add description
+ *
+ */
+ class TAO_CSD_TP_Export TP_Custom_Request : public TP_Request
+ {
+ public:
+
+ /// Virtual Destructor.
+ virtual ~TP_Custom_Request();
+
+
+ protected:
+
+ /// Constructor.
+ TP_Custom_Request(TP_Custom_Request_Operation* op,
+ TP_Servant_State* servant_state);
+
+ void execute_op();
+ void cancel_op();
+
+
+ private:
+
+ TP_Custom_Request_Operation_Handle op_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Custom_Request.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_CUSTOM_REQUEST_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.inl
new file mode 100644
index 00000000000..6b53f3cbf78
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.inl
@@ -0,0 +1,44 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Custom_Request::TP_Custom_Request
+ (TP_Custom_Request_Operation* op,
+ TP_Servant_State* servant_state)
+ : TP_Request(op->servant(),servant_state),
+ op_(op, false)
+{
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Custom_Request::execute_op()
+{
+ this->op_->execute();
+
+ // Now drop the reference to the custom operation object.
+ // This is necessary so that custom operation objects can be created
+ // on the stack for synchronous custom requests. If we do not do this,
+ // then there is a race condition which could result in the stack-created
+ // custom operation object having a reference count of 2 when it falls
+ // out of scope (and destructs). Our op_ data member would be the one
+ // that held the other reference, and when our op_ data member destructs,
+ // it attempts to perform a _remove_ref() on the underlying operation
+ // object - which has already been destructed! Thus, we reset the op_
+ // data member here to the 'nil' state - causing the _remove_ref() to
+ // be performed now.
+ this->op_ = 0;
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Custom_Request::cancel_op()
+{
+ this->op_->cancel();
+
+ // See comments in the execute_op() method.
+ this->op_ = 0;
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.cpp
new file mode 100644
index 00000000000..49617f39ea3
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.cpp
@@ -0,0 +1,16 @@
+// $Id$
+
+#include "CSD_TP_Custom_Request_Operation.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Custom_Request_Operation,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Custom_Request_Operation.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Custom_Request_Operation::~TP_Custom_Request_Operation()
+{
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h
new file mode 100644
index 00000000000..50673612536
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h
@@ -0,0 +1,96 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Custom_Request_Operation.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_CUSTOM_REQUEST_OPERATION_H
+#define TAO_CSD_TP_CUSTOM_REQUEST_OPERATION_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Intrusive_Ref_Count_Base_T.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+#include "tao/PortableServer/Servant_Base.h"
+#include "ace/Synch.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Custom_Request_Operation;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Custom_Request_Operation>
+ TP_Custom_Request_Operation_Handle;
+
+
+ /**
+ * @class TP_Custom_Request_Operation
+ *
+ * @brief Base class for all custom request operations.
+ *
+ * @note The caller that creates a new TP_Custom_Request_Operation
+ * object needs call _add_ref () on the servant before
+ * constructing it and the TP_Custom_Request_Operation object
+ * is responsible to decrement the reference count.
+ *
+ * TBD - Add description
+ */
+ class TAO_CSD_TP_Export TP_Custom_Request_Operation
+ : public TAO_Intrusive_Ref_Count_Base<ACE_SYNCH_MUTEX>
+ {
+ public:
+
+ /// Virtual Destructor.
+ virtual ~TP_Custom_Request_Operation();
+
+ /// Invoked by a worker thread to perform the operation.
+ void execute();
+
+ /// Invoked when the request has been cancelled.
+ void cancel();
+
+ /// Used by the TP_Strategy to obtain the target servant in order
+ /// to construct the custom request object. Returns the servant as
+ /// an "in" argument (the caller does not get a new 'copy'). This
+ /// is useful for chaining.
+ PortableServer::Servant servant();
+
+
+ protected:
+
+ /// Constructor.
+ TP_Custom_Request_Operation(PortableServer::Servant servant);
+
+ virtual void execute_i() = 0;
+ virtual void cancel_i() = 0;
+
+
+ private:
+
+ PortableServer::ServantBase_var servant_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Custom_Request_Operation.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_CUSTOM_REQUEST_OPERATION_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.inl
new file mode 100644
index 00000000000..cfdcc74f1c6
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.inl
@@ -0,0 +1,47 @@
+// -*- C++ -*-
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Custom_Request_Operation::TP_Custom_Request_Operation
+ (PortableServer::Servant servant)
+: servant_ (servant)
+{
+ // This try-catch block is not really necessary for current implementation
+ // since the _add_ref does not throw exception, but we have to add it to
+ // satisfy the non-exception builds. If _add_ref really throws an exception
+ // then this constructor needs deal with the exception.
+ ACE_TRY_NEW_ENV
+ {
+ this->servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Custom_Request_Operation::execute()
+{
+ this->execute_i();
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Custom_Request_Operation::cancel()
+{
+ this->cancel_i();
+}
+
+
+ACE_INLINE
+PortableServer::Servant
+TAO::CSD::TP_Custom_Request_Operation::servant()
+{
+ return this->servant_.in();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.cpp
new file mode 100644
index 00000000000..dd9162bea02
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.cpp
@@ -0,0 +1,32 @@
+// $Id$
+
+#include "CSD_TP_Custom_Synch_Request.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Custom_Synch_Request,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Custom_Synch_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Custom_Synch_Request::~TP_Custom_Synch_Request()
+{
+}
+
+
+void
+TAO::CSD::TP_Custom_Synch_Request::dispatch_i()
+{
+ this->execute_op();
+ this->synch_helper_.dispatched();
+}
+
+
+void
+TAO::CSD::TP_Custom_Synch_Request::cancel_i()
+{
+ this->cancel_op();
+ this->synch_helper_.cancelled();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h
new file mode 100644
index 00000000000..a4c5e059e40
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h
@@ -0,0 +1,89 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Custom_Synch_Request.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_CUSTOM_SYNCH_REQUEST_H
+#define TAO_CSD_TP_CUSTOM_SYNCH_REQUEST_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Custom_Request.h"
+#include "CSD_TP_Synch_Helper.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Custom_Synch_Request;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Custom_Synch_Request>
+ TP_Custom_Synch_Request_Handle;
+
+ /**
+ * @class TP_Custom_Synch_Request
+ *
+ * @brief Base class for "queue-able", Custom (non-CORBA),
+ * Synchronous requests.
+ *
+ * TBD - Add description
+ *
+ */
+ class TAO_CSD_TP_Export TP_Custom_Synch_Request : public TP_Custom_Request
+ {
+ public:
+
+ /// Constructor.
+ TP_Custom_Synch_Request(TP_Custom_Request_Operation* op,
+ TP_Servant_State* servant_state);
+
+ /// Virtual Destructor.
+ virtual ~TP_Custom_Synch_Request();
+
+ /// Wait until the request has been executed (and completes), or
+ /// until it has been cancelled. Returns true if the request has
+ /// been executed/completed, and returns false if the request has
+ /// been cancelled.
+ bool wait();
+
+
+ protected:
+
+ /// Dispatch the request to the servant.
+ virtual void dispatch_i();
+
+ /// Cancel the request.
+ virtual void cancel_i();
+
+
+ private:
+
+ /// Helper used to block and unblock the thread that invokes our
+ /// wait() method.
+ TP_Synch_Helper synch_helper_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Custom_Synch_Request.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_CUSTOM_SYNCH_REQUEST_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.inl
new file mode 100644
index 00000000000..18cb942160c
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.inl
@@ -0,0 +1,18 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Custom_Synch_Request::TP_Custom_Synch_Request
+ (TP_Custom_Request_Operation* op,
+ TP_Servant_State* servant_state)
+ : TP_Custom_Request(op,servant_state)
+{
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::TP_Custom_Synch_Request::wait()
+{
+ return this->synch_helper_.wait_while_pending();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.cpp
new file mode 100644
index 00000000000..c10b11aa53b
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.cpp
@@ -0,0 +1,50 @@
+// $Id$
+
+#include "CSD_TP_Dispatchable_Visitor.h"
+
+ACE_RCSID (CSD_TP,
+ Dispatchable_Visitor,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Dispatchable_Visitor.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Dispatchable_Visitor::~TP_Dispatchable_Visitor()
+{
+}
+
+
+bool
+TAO::CSD::TP_Dispatchable_Visitor::visit_request(TP_Request* request,
+ bool& remove_flag)
+{
+ // Ask the request object if the target servant is "ready" to accept
+ // a request being dispatched to it.
+ if (request->is_ready())
+ {
+ // Ok. This request is a "dispatchable" request. It is what we were
+ // hoping to find.
+
+ // Save a copy of the request in our handle data member.
+ request->_add_ref();
+ this->request_ = request;
+
+ // Make sure that the queue will extract the request from the queue
+ // upon our return.
+ remove_flag = true;
+
+ // Mark the target servant as being "busy".
+ request->mark_as_busy();
+
+ // Stop the visitation by returning false.
+ return false;
+ }
+
+ // The target servant object of the request isn't ready, so the request
+ // is not considered to be a "dispatchable" request.
+
+ // Return true to visit the next request in the queue (if there is one).
+ return true;
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h
new file mode 100644
index 00000000000..9f639a5e8a9
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h
@@ -0,0 +1,91 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Dispatchable_Visitor.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_DISPATCHABLE_VISITOR_H
+#define TAO_CSD_TP_DISPATCHABLE_VISITOR_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Queue_Visitor.h"
+#include "CSD_TP_Request.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ /**
+ * @class TP_Dispatchable_Visitor
+ *
+ * @brief Used to extract the first "dispatchable" request from the queue.
+ *
+ * An instance of this visitor class is used by one of the worker
+ * threads to locate the first "dispatchable" request in the queue. If
+ * such a request is visited, then this visitor will save a "copy" of
+ * the request, indicate that the request should be removed from the
+ * queue, and indicate that visitation should stop.
+ *
+ * An method is provided to retrieve a "copy" of the "dispatchable"
+ * request that was saved off during visitation. A nil reference
+ * (ie, a NULL pointer) will be returned if no dispatchable request
+ * was found.
+ *
+ */
+ class TAO_CSD_TP_Export TP_Dispatchable_Visitor : public TP_Queue_Visitor
+ {
+ public:
+
+ /// Default Constructor.
+ TP_Dispatchable_Visitor();
+
+ /// Virtual Destructor.
+ virtual ~TP_Dispatchable_Visitor();
+
+ /// Reset this visitor object in order to re-use it for another
+ /// visitation of the request queue. This sets the vistor's "result"
+ /// (the TP_Request* data member) to its default value (a nil handle).
+ void reset();
+
+ /// Returns true to continue visitation. Returns false to stop
+ /// visitation. Sets the remove_flag to true if the request should
+ /// be removed from the queue as a result of the visit. Leaves the
+ /// remove_flag alone otherwise.
+ virtual bool visit_request(TP_Request* request, bool& remove_flag);
+
+ /// This returns a "copy" of the located request, or 0 if no request
+ /// was located.
+ TP_Request* request();
+
+
+ private:
+
+ /// A handle to the located request.
+ TP_Request_Handle request_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Dispatchable_Visitor.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_DISPATCHABLE_VISITOR_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.inl
new file mode 100644
index 00000000000..ac66587e2a7
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.inl
@@ -0,0 +1,26 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Dispatchable_Visitor::TP_Dispatchable_Visitor()
+{
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Dispatchable_Visitor::reset()
+{
+ // Set the handle to 0 to have it release any request it may currently
+ // be referencing.
+ this->request_ = 0;
+}
+
+
+ACE_INLINE
+TAO::CSD::TP_Request*
+TAO::CSD::TP_Dispatchable_Visitor::request()
+{
+ TP_Request_Handle handle(this->request_.in(), false);
+ return handle._retn();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Export.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Export.h
new file mode 100644
index 00000000000..1eeb556e4f8
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s TAO_CSD_TP
+// ------------------------------
+#ifndef TAO_CSD_TP_EXPORT_H
+#define TAO_CSD_TP_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (TAO_CSD_TP_HAS_DLL)
+# define TAO_CSD_TP_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && TAO_CSD_TP_HAS_DLL */
+
+#if !defined (TAO_CSD_TP_HAS_DLL)
+# define TAO_CSD_TP_HAS_DLL 1
+#endif /* ! TAO_CSD_TP_HAS_DLL */
+
+#if defined (TAO_CSD_TP_HAS_DLL) && (TAO_CSD_TP_HAS_DLL == 1)
+# if defined (TAO_CSD_TP_BUILD_DLL)
+# define TAO_CSD_TP_Export ACE_Proper_Export_Flag
+# define TAO_CSD_TP_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define TAO_CSD_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* TAO_CSD_TP_BUILD_DLL */
+# define TAO_CSD_TP_Export ACE_Proper_Import_Flag
+# define TAO_CSD_TP_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define TAO_CSD_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* TAO_CSD_TP_BUILD_DLL */
+#else /* TAO_CSD_TP_HAS_DLL == 1 */
+# define TAO_CSD_TP_Export
+# define TAO_CSD_TP_SINGLETON_DECLARATION(T)
+# define TAO_CSD_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* TAO_CSD_TP_HAS_DLL == 1 */
+
+// Set TAO_CSD_TP_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (TAO_CSD_TP_NTRACE)
+# if (ACE_NTRACE == 1)
+# define TAO_CSD_TP_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define TAO_CSD_TP_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !TAO_CSD_TP_NTRACE */
+
+#if (TAO_CSD_TP_NTRACE == 1)
+# define TAO_CSD_TP_TRACE(X)
+#else /* (TAO_CSD_TP_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define TAO_CSD_TP_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (TAO_CSD_TP_NTRACE == 1) */
+
+#endif /* TAO_CSD_TP_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp
new file mode 100644
index 00000000000..7253794cf0b
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp
@@ -0,0 +1,124 @@
+// $Id$
+
+#include "CSD_TP_Queue.h"
+#include "CSD_TP_Request.h"
+#include "CSD_TP_Queue_Visitor.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Queue,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Queue.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+void
+TAO::CSD::TP_Queue::put(TP_Request* request)
+{
+ // The request is passed in as an "in" argument, and we would like to
+ // hold on to a "copy" within the queue (the linked list). We will
+ // perform an _add_ref() on the request now to make the queue's "copy".
+ request->_add_ref();
+
+ if (this->tail_ == 0)
+ {
+ // The tail_ is a NULL pointer only when the queue is empty.
+ // Make the request be the only element in the queue.
+ this->head_ = this->tail_ = request;
+
+ // Make sure the request's prev_ and next_ pointers are set to NULL.
+ request->prev_ = request->next_ = 0;
+ }
+ else
+ {
+ // There is at least one request already in the queue. "Append" the
+ // supplied request object to the end of the queue.
+ request->prev_ = this->tail_;
+ request->next_ = 0;
+ this->tail_->next_ = request;
+ this->tail_ = request;
+ }
+}
+
+
+void
+TAO::CSD::TP_Queue::accept_visitor(TP_Queue_Visitor& visitor)
+{
+ TP_Request* cur = this->head_;
+
+ while (cur != 0)
+ {
+ TP_Request* prev = cur->prev_;
+ TP_Request* next = cur->next_;
+
+ // Pass the current request to the visitor. Also pass-in a reference
+ // to the remove_from_queue flag. The visitor may decide that it
+ // wants to keep the current request for itself, and desires that the
+ // request be (surgically) removed from the queue. The visitor also
+ // gets to decide, via its return value, whether or not visitation
+ // should continue (or cease to continue).
+ bool remove_from_queue = false;
+
+ bool continue_visitation = visitor.visit_request(cur,remove_from_queue);
+
+ if (remove_from_queue)
+ {
+ // Create a local handle to release the current request once
+ // the handle falls out of scope. We need to do this because the
+ // queue "owns" a "copy" of each request in the queue.
+ TP_Request_Handle handle = cur;
+
+ if (this->head_ == cur)
+ {
+ // The current request is at the front (the head_) of the queue.
+
+ // Move the head_ to the next request in the queue.
+ this->head_ = next;
+
+ if (this->head_ == 0)
+ {
+ // Not only was the current request at the front of the
+ // queue - it was the *only* request in the queue.
+ // Update the tail_ pointer now that the queue is empty.
+ this->tail_ = 0;
+ }
+ else
+ {
+ // Set the (new) head_ request's prev_ pointer to be NULL.
+ this->head_->prev_ = 0;
+ }
+ }
+ else if (this->tail_ == cur)
+ {
+ // The current request is not at the front of the queue,
+ // but it is at the back of the queue. This implies that
+ // the queue currently contains at least two requests -
+ // the current request (cur), and the previous request (prev).
+ // The point is that we can now assume that the 'prev' pointer
+ // is never NULL in this case.
+ this->tail_ = prev;
+ this->tail_->next_ = 0;
+ }
+ else
+ {
+ // The current request is not at the front or at the back.
+ // This implies that there are at least three requests in
+ // the queue. We can assume that the 'next' and 'prev'
+ // pointers are never NULL in this case.
+ prev->next_ = next;
+ next->prev_ = prev;
+ }
+ }
+
+ if (!continue_visitation)
+ {
+ // The visitor doesn't want to procede with any further visitation.
+ // Break out of the visitation loop now.
+ break;
+ }
+
+ // Move on to the next request in the queue.
+ cur = next;
+ }
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h
new file mode 100644
index 00000000000..7b42cfeda59
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h
@@ -0,0 +1,96 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Queue.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_QUEUE_H
+#define TAO_CSD_TP_QUEUE_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Request;
+ class TP_Queue_Visitor;
+
+ /**
+ * @class TP_Queue
+ *
+ * @brief Queue of servant requests that need to be dispatched.
+ *
+ * This is the queue of pending servant requests that is "owned"
+ * by a TP_Strategy object. When an ORB thread dispatches
+ * a servant request to the strategy object, it will create the
+ * appropriate (subclass of) TP_Request object to "wrap"
+ * the servant request in a "queue-friendly" wrapper. The ORB thread
+ * will then place the TP_Request object on to the queue. Note that
+ * this scenario pertains to what are being called "remote requests".
+ * There are other scenarios in which other types of requests can
+ * get added to this queue.
+ *
+ * The strategy object will employ a set of worker threads that are
+ * responsible for "servicing" the servant requests in the queue.
+ *
+ * Note: In the future, support will be added to allow the client
+ * application inject "custom" TP_Request objects into
+ * a TP_Strategy object, causing them to be placed in
+ * the queue.
+ */
+ class TAO_CSD_TP_Export TP_Queue
+ {
+ public:
+
+ /// Default Constructor.
+ TP_Queue();
+
+ /// Destructor.
+ ~TP_Queue();
+
+ /// Place a request at the end of the queue.
+ void put(TP_Request* request);
+
+ /// Returns true if the queue is empty. Returns false otherwise.
+ bool is_empty() const;
+
+ /// Visitors will visit each request in the queue, from front to back,
+ /// and have the ability to stop visiting at any time (ie, before
+ /// visiting every request).
+ void accept_visitor(TP_Queue_Visitor& visitor);
+
+
+ private:
+
+ /// The request at the front of the queue.
+ TP_Request* head_;
+
+ /// The request at the end of the queue.
+ TP_Request* tail_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Queue.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_QUEUE_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.inl
new file mode 100644
index 00000000000..58adcec4744
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.inl
@@ -0,0 +1,23 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Queue::TP_Queue()
+ : head_(0),
+ tail_(0)
+{
+}
+
+
+ACE_INLINE
+TAO::CSD::TP_Queue::~TP_Queue()
+{
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::TP_Queue::is_empty() const
+{
+ return (this->head_ == 0);
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.cpp
new file mode 100644
index 00000000000..95d3c39f750
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.cpp
@@ -0,0 +1,16 @@
+// $Id$
+
+#include "CSD_TP_Queue_Visitor.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Queue_Visitor,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Queue_Visitor.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Queue_Visitor::~TP_Queue_Visitor()
+{
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.h
new file mode 100644
index 00000000000..cece3e7ffbc
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.h
@@ -0,0 +1,74 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Queue_Visitor.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_QUEUE_VISITOR_H
+#define TAO_CSD_TP_QUEUE_VISITOR_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Request;
+
+
+ /**
+ * @class TP_Queue_Visitor
+ *
+ * @brief Base class for vistors of the elements in the TP_Queue.
+ *
+ * Provides a way to perform thread-safe iteration over the
+ * TP_Request objects contained within a TP_Queue object.
+ *
+ * This also provides a means to encapsulate each distinct algorithm
+ * within a distinct subclass of TP_Queue_Visitor.
+ *
+ */
+ class TAO_CSD_TP_Export TP_Queue_Visitor
+ {
+ public:
+
+ /// Virtual Destructor.
+ virtual ~TP_Queue_Visitor();
+
+ /// Returns true to continue visitation. Return false to stop
+ /// visitation. Sets the remove_flag to true if the request should
+ /// be removed from the queue as a result of the visit. Leaves the
+ /// remove_flag alone otherwise.
+ virtual bool visit_request(TP_Request* request, bool& remove_flag) = 0;
+
+
+ protected:
+
+ /// Default Constructor.
+ TP_Queue_Visitor();
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Queue_Visitor.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_QUEUE_VISITOR_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.inl
new file mode 100644
index 00000000000..77567843234
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.inl
@@ -0,0 +1,7 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Queue_Visitor::TP_Queue_Visitor()
+{
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.cpp
new file mode 100644
index 00000000000..cf7f2642505
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.cpp
@@ -0,0 +1,57 @@
+// $Id$
+
+#include "CSD_TP_Remote_Request.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Remote_Request,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Remote_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Remote_Request::~TP_Remote_Request()
+{
+}
+
+
+void
+TAO::CSD::TP_Remote_Request::prepare_for_queue_i()
+{
+ this->do_clone();
+}
+
+
+void
+TAO::CSD::TP_Remote_Request::dispatch_i()
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->do_dispatch(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ // Eat these. We probably should log these, but since we have already
+ // unblocked the requesting thread there is no point in saving it or
+ // doing anything with it.
+ }
+#if defined (TAO_HAS_EXCEPTIONS)
+ ACE_CATCHALL
+ {
+ // Eat these. We probably should log these, but since we have already
+ // unblocked the requesting thread there is no point in saving it or
+ // doing anything with it.
+ }
+#endif
+ ACE_ENDTRY;
+}
+
+
+void
+TAO::CSD::TP_Remote_Request::cancel_i()
+{
+ this->do_cancel();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.h
new file mode 100644
index 00000000000..c80dec5c992
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.h
@@ -0,0 +1,99 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Remote_Request.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_REMOTE_REQUEST_H
+#define TAO_CSD_TP_REMOTE_REQUEST_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Corba_Request.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Remote_Request;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Remote_Request>
+ TP_Remote_Request_Handle;
+
+ /**
+ * @class TP_Remote_Request
+ *
+ * @brief Represents a "queue-able", remote, CORBA request.
+ * Both syncronous and asynchronous remote CORBA requests
+ * are represented by the class.
+ *
+ * TBD - Go over the following comments and clean up.
+ *
+ * Since this class derives from the TP_Request class, it can be
+ * added to a TP_Queue (ie, it is a "queueable" request). It
+ * represents a servant request that has been made by a remote
+ * CORBA client (as opposed to a collocated CORBA client). The
+ * term "CORBA client" is being used here to distinguish CORBA
+ * servant requests (those made thru a CORBA object reference), and
+ * "Custom" servant requests that can be "dispatched" to the strategy
+ * directly by the client application code (ie, not thru a CORBA
+ * object reference). Thus, there are "CORBA clients" and
+ * "Direct clients".
+ *
+ * In summary, this class represents a servant request made when a
+ * remote client invokes a method on a CORBA object reference.
+ *
+ */
+ class TAO_CSD_TP_Export TP_Remote_Request : public TP_Corba_Request
+ {
+ public:
+
+ /// Constructor.
+ TP_Remote_Request(TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state);
+
+ /// Virtual Destructor.
+ virtual ~TP_Remote_Request();
+
+
+ protected:
+
+ /// Prepare this TP_Remote_Request object to be placed into the
+ /// request queue. This will cause the underlying TAO_ServerRequest
+ /// object to be cloned.
+ virtual void prepare_for_queue_i();
+
+ /// Dispatch the request to the servant.
+ virtual void dispatch_i();
+
+ /// Cancel the request.
+ virtual void cancel_i();
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Remote_Request.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_REMOTE_REQUEST_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.inl
new file mode 100644
index 00000000000..baa56a9ea08
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.inl
@@ -0,0 +1,20 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Remote_Request::TP_Remote_Request
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant,
+ TP_Servant_State* servant_state)
+ : TP_Corba_Request(object_id,
+ poa,
+ operation,
+ servant,
+ servant_state,
+ server_request)
+{
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.cpp
new file mode 100644
index 00000000000..a01d18f19dd
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.cpp
@@ -0,0 +1,24 @@
+// $Id$
+
+#include "CSD_TP_Request.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Request,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Request::~TP_Request()
+{
+}
+
+
+void
+TAO::CSD::TP_Request::prepare_for_queue_i()
+{
+ // Default implementation is to do nothing. Subclasses can provide
+ // their own implementation if needed.
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.h
new file mode 100644
index 00000000000..4e7c61e9b09
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.h
@@ -0,0 +1,133 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Request.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_REQUEST_H
+#define TAO_CSD_TP_REQUEST_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Servant_State.h"
+#include "tao/PortableServer/Servant_Base.h"
+#include "tao/Intrusive_Ref_Count_Base_T.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Request;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Request> TP_Request_Handle;
+
+ class TP_Queue;
+
+
+ /**
+ * @class TP_Request
+ *
+ * @brief Base class for "queue-able" requests.
+ *
+ * This class serves as the abstract base class for all types of
+ * "servant requests" that can be inserted into a TP_Queue
+ * object.
+ */
+ class TAO_CSD_TP_Export TP_Request
+ : public TAO_Intrusive_Ref_Count_Base<ACE_SYNCH_MUTEX>
+ {
+ public:
+
+ /// Virtual Destructor.
+ virtual ~TP_Request();
+
+ /// Prepare the request to be placed into the request queue.
+ void prepare_for_queue();
+
+ /// Invoked to dispatch the request to the servant.
+ void dispatch();
+
+ /// Invoked to cancel the request.
+ void cancel();
+
+ /// Is the target servant ready to accept a request?
+ bool is_ready() const;
+
+ /// Mark the target servant as being busy.
+ void mark_as_busy();
+
+ /// Mark the target servant as being ready (ie, not busy).
+ void mark_as_ready();
+
+ /// This method returns true if this request targets the supplied
+ /// servant object.
+ bool is_target(PortableServer::Servant servant);
+
+
+ protected:
+
+ /// Constructor.
+ TP_Request(PortableServer::Servant servant,
+ TP_Servant_State* servant_state);
+
+ /// Accessor for the servant. Does not return a new (ref counted)
+ /// reference! This is used for chaining.
+ PortableServer::Servant servant();
+
+ /// The subclass knows if it needs to do anything in preparation
+ /// of being placed into the request queue. The default implementation
+ /// does nothing, so only subclasses that have something to do
+ /// need to provide their own implementation.
+ virtual void prepare_for_queue_i();
+
+ /// The subclass knows how to carry out its own way of dispatching
+ /// the request to the servant.
+ virtual void dispatch_i() = 0;
+
+ /// Ask the subclass to perform its duties to carry out the cancellation.
+ virtual void cancel_i() = 0;
+
+
+ private:
+
+ /// The TP_Queue class is our friend since it needs access to
+ /// the prev_ and next_ (private) data members.
+ friend class TP_Queue;
+
+ /// The previous TP_Request object (in the queue).
+ TP_Request* prev_;
+
+ /// The next TP_Request object (in the queue).
+ TP_Request* next_;
+
+ /// Reference to the servant object.
+ PortableServer::ServantBase_var servant_;
+
+ /// Reference to the servant "state" object (contains the busy flag).
+ TP_Servant_State::HandleType servant_state_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Request.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_REQUEST_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.inl
new file mode 100644
index 00000000000..7181678ecde
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.inl
@@ -0,0 +1,92 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Request::TP_Request(PortableServer::Servant servant,
+ TP_Servant_State* servant_state)
+ : prev_(0),
+ next_(0),
+ servant_ (servant),
+ servant_state_(servant_state, false)
+{
+ // This try-catch block is not really necessary for current implementation
+ // since the _add_ref does not throw exception, but we have to add it to
+ // satisfy the non-exception builds. If _add_ref really throws an exception
+ // then this constructor needs deal with the exception.
+ ACE_TRY_NEW_ENV
+ {
+ this->servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Request::prepare_for_queue()
+{
+ this->prepare_for_queue_i();
+}
+
+
+ACE_INLINE
+PortableServer::Servant
+TAO::CSD::TP_Request::servant()
+{
+ // Used for chaining so we do not return a new "copy".
+ return this->servant_.in();
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::TP_Request::is_ready() const
+{
+ return !this->servant_state_->busy_flag();
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Request::mark_as_busy()
+{
+ this->servant_state_->busy_flag(true);
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Request::mark_as_ready()
+{
+ this->servant_state_->busy_flag(false);
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::TP_Request::is_target(PortableServer::Servant servant)
+{
+ // Compare pointers. Return true only if these are the exact same object.
+ return (servant == this->servant_.in());
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Request::dispatch()
+{
+ this->dispatch_i();
+
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Request::cancel()
+{
+ this->cancel_i();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.cpp
new file mode 100644
index 00000000000..bd7413d3fd2
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.cpp
@@ -0,0 +1,16 @@
+// $Id$
+
+#include "CSD_TP_Servant_State.h"
+
+ACE_RCSID (CSD_TP,
+ Servant_State,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Servant_State.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Servant_State::~TP_Servant_State()
+{
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.h
new file mode 100644
index 00000000000..fca7d321f1d
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.h
@@ -0,0 +1,89 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Servant_State.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_SERVANT_STATE_H
+#define TAO_CSD_TP_SERVANT_STATE_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Intrusive_Ref_Count_Base_T.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+#include "ace/Synch.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ /**
+ * @class TP_Servant_State
+ *
+ * @brief Maintains state information for a particular servant.
+ *
+ * This TP_Servant_State class is an intrusively reference-counted
+ * class. This allows it to be held in a "smart pointer" (aka, handle)
+ * object that will manage the reference-counting automagically.
+ *
+ * One TP_Servant_State object is created for each servant object for
+ * which a request is to be dispatched. The servant state objects are
+ * held (via smart pointers) in a TP_Servant_State_Map object. In turn,
+ * the TP_Servant_State_Map object is a data member of the TP_Stategy
+ * class. Each request placed on to the request queue will hold a
+ * reference (via a smart pointer) to the servant state object.
+ *
+ * Currently, the only "state" info held in this TP_Servant_State class
+ * is the servant's busy flag.
+ *
+ */
+ class TAO_CSD_TP_Export TP_Servant_State
+ : public TAO_Intrusive_Ref_Count_Base<ACE_SYNCH_MUTEX>
+ {
+ public:
+
+ /// Handle Type (aka, Smart Pointer Type).
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Servant_State> HandleType;
+
+ /// Default Constructor.
+ TP_Servant_State();
+
+ /// Virtual Destructor.
+ virtual ~TP_Servant_State();
+
+ /// Accessor for the servant busy flag.
+ bool busy_flag() const;
+
+ /// Mutator for the servant busy flag.
+ void busy_flag(bool new_value);
+
+ private:
+
+ /// The servant's current "busy" state (true == busy, false == not busy)
+ bool busy_flag_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Servant_State.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_SERVANT_STATE_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.inl
new file mode 100644
index 00000000000..ba67f809131
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.inl
@@ -0,0 +1,24 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Servant_State::TP_Servant_State()
+ : busy_flag_(false)
+{
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::TP_Servant_State::busy_flag() const
+{
+ return this->busy_flag_;
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Servant_State::busy_flag(bool new_value)
+{
+ this->busy_flag_ = new_value;
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.cpp
new file mode 100644
index 00000000000..d6d34c6c6c2
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.cpp
@@ -0,0 +1,11 @@
+// $Id$
+
+#include "CSD_TP_Servant_State_Map.h"
+
+ACE_RCSID (CSD_TP,
+ Servant_State_Map,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Servant_State_Map.inl"
+#endif /* ! __ACE_INLINE__ */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h
new file mode 100644
index 00000000000..667b836006c
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h
@@ -0,0 +1,92 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Servant_State_Map.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_SERVANT_STATE_MAP_H
+#define TAO_CSD_TP_SERVANT_STATE_MAP_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "CSD_TP_Servant_State.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "ace/Hash_Map_Manager.h"
+#include "ace/Synch.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ /**
+ * @class TP_Servant_State_Map
+ *
+ * @brief Map of Servant_State objects - one per servant.
+ *
+ * A TP_Stategy object holds an instance of a TP_Servant_State_Map object
+ * as a (held-by-value) data member. The strategy uses this map to
+ * find or create the TP_Servant_State object for a particular servant
+ * object.
+ *
+ */
+ class TAO_CSD_TP_Export TP_Servant_State_Map
+ {
+ public:
+
+ /// Default Constructor.
+ TP_Servant_State_Map();
+
+ /// Destructor.
+ ~TP_Servant_State_Map();
+
+ /// Accessor for the servant busy flag.
+ TP_Servant_State* find(PortableServer::Servant servant
+ ACE_ENV_ARG_DECL);
+
+ /// Insert the servant to map.
+ void insert(PortableServer::Servant servant
+ ACE_ENV_ARG_DECL);
+
+ /// Remove the servant from map.
+ void remove(PortableServer::Servant servant
+ ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ /// Underlying Map Type - Hash-Based -
+ /// Key Type: void*, Value Type: TP_Servant_State::HandleType
+ typedef ACE_Hash_Map_Manager_Ex<void*,
+ TP_Servant_State::HandleType,
+ ACE_Hash<void*>,
+ ACE_Equal_To<void*>,
+ ACE_SYNCH_MUTEX> MapType;
+
+ /// The underlying map of servant state objects.
+ MapType map_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Servant_State_Map.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_SERVANT_STATE_MAP_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.inl
new file mode 100644
index 00000000000..0d0e40f54f3
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.inl
@@ -0,0 +1,66 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Servant_State_Map::TP_Servant_State_Map()
+{
+}
+
+
+ACE_INLINE
+TAO::CSD::TP_Servant_State_Map::~TP_Servant_State_Map()
+{
+}
+
+
+ACE_INLINE
+TAO::CSD::TP_Servant_State*
+TAO::CSD::TP_Servant_State_Map::find(PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ void* key = servant;
+
+ TP_Servant_State::HandleType value;
+
+ if (this->map_.find(key, value) != 0)
+ {
+ ACE_THROW_RETURN (PortableServer::POA::ServantNotActive (), 0);
+ }
+
+ return value._retn();
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Servant_State_Map::insert(PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ void* key = servant;
+
+ TP_Servant_State::HandleType value = new TP_Servant_State ();
+
+ int result = this->map_.bind(key, value);
+
+ if (result == 1)
+ {
+ ACE_THROW (PortableServer::POA::ServantAlreadyActive ());
+ }
+
+ ACE_ASSERT (result == 0);
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Servant_State_Map::remove(PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ void* key = servant;
+
+ if (this->map_.unbind(key) == -1)
+ {
+ ACE_THROW (PortableServer::POA::ServantNotActive ());
+ }
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.cpp
new file mode 100644
index 00000000000..6968234d673
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.cpp
@@ -0,0 +1,270 @@
+// $Id$
+
+#include "CSD_TP_Strategy.h"
+#include "CSD_TP_Remote_Request.h"
+#include "CSD_TP_Collocated_Synch_Request.h"
+#include "CSD_TP_Collocated_Asynch_Request.h"
+#include "CSD_TP_Custom_Synch_Request.h"
+#include "CSD_TP_Custom_Asynch_Request.h"
+#include "CSD_TP_Collocated_Synch_With_Server_Request.h"
+#include "ace/Trace.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Strategy,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Strategy.inl"
+#endif /* ! __ACE_INLINE__ */
+
+
+TAO::CSD::TP_Strategy::~TP_Strategy()
+{
+}
+
+
+
+TAO::CSD::TP_Strategy::CustomRequestOutcome
+TAO::CSD::TP_Strategy::custom_synch_request(TP_Custom_Request_Operation* op
+ ACE_ENV_ARG_DECL)
+{
+ TP_Servant_State::HandleType servant_state
+ = this->servant_state_map_.find(op->servant() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (REQUEST_REJECTED);
+
+ TP_Custom_Synch_Request_Handle request = new
+ TP_Custom_Synch_Request(op, servant_state.in());
+
+ if (!this->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::CSD::TP_Strategy::CustomRequestOutcome
+TAO::CSD::TP_Strategy::custom_asynch_request(TP_Custom_Request_Operation* op
+ ACE_ENV_ARG_DECL)
+{
+ TP_Servant_State::HandleType servant_state
+ = this->servant_state_map_.find(op->servant() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (REQUEST_REJECTED);
+
+ TP_Custom_Asynch_Request_Handle request = new
+ TP_Custom_Asynch_Request(op, servant_state.in());
+
+ return (this->task_.add_request(request.in()))
+ ? REQUEST_DISPATCHED : REQUEST_REJECTED;
+}
+
+
+bool
+TAO::CSD::TP_Strategy::poa_activated_event_i()
+{
+ // Activates the worker threads, and waits until all have been started.
+ return (this->task_.open(&(this->num_threads_)) == 0);
+}
+
+
+void
+TAO::CSD::TP_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->task_.close(1);
+}
+
+
+TAO::CSD::Strategy_Base::DispatchResult
+TAO::CSD::TP_Strategy::dispatch_remote_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ // Obtain the TP_Servant_State object associated with the servant object.
+ // The find() either return a non nil handle or already thrown
+ // ServantNotActive exception.
+
+ TP_Servant_State::HandleType servant_state
+ = this->servant_state_map_.find(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (DISPATCH_REJECTED);
+
+ // 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.
+ TP_Remote_Request_Handle request =
+ new TP_Remote_Request(server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in());
+
+ // Hand the request object to our task so that it can add the request
+ // to its "request queue".
+ if (!this->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::CSD::TP_Strategy::dispatch_collocated_request_i
+ (TAO_ServerRequest& server_request,
+ const PortableServer::ObjectId& object_id,
+ PortableServer::POA_ptr poa,
+ const char* operation,
+ PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ // Obtain the TP_Servant_State object associated with the servant object.
+ // The find() either return a non nil handle or already thrown
+ // ServantNotActive exception.
+
+ TP_Servant_State::HandleType servant_state
+ = this->servant_state_map_.find(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (DISPATCH_REJECTED);
+
+ bool is_sync_with_server = server_request.sync_with_server();
+ bool is_synchronous = server_request.response_expected();
+
+ TP_Collocated_Synch_Request_Handle synch_request;
+ TP_Collocated_Synch_With_Server_Request_Handle synch_with_server_request;
+ TP_Request_Handle request;
+
+ // Create the request object using the appropriate concrete type.
+ if (is_sync_with_server)
+ {
+ synch_with_server_request =
+ new TP_Collocated_Synch_With_Server_Request
+ (server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in());
+
+ // Give the request handle its own "copy".
+ synch_with_server_request->_add_ref();
+ request = synch_with_server_request.in();
+ }
+ else if (is_synchronous)
+ {
+ synch_request = new TP_Collocated_Synch_Request(server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in());
+
+ // Give the request handle its own "copy".
+ synch_request->_add_ref();
+ request = synch_request.in();
+ }
+ else
+ {
+ // Just use the (base) request handle to hold the request object.
+ request = new TP_Collocated_Asynch_Request(server_request,
+ object_id,
+ poa,
+ operation,
+ servant,
+ servant_state.in());
+ }
+
+ // Hand the request object to our task so that it can add the request
+ // to its "request queue".
+ if (!this->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(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (DISPATCH_REJECTED);
+ if (srw == false)
+ {
+ // Raise exception when request was cancelled.
+ ACE_THROW_RETURN(CORBA::NO_IMPLEMENT(), DISPATCH_REJECTED);
+ }
+ }
+ else if (!synch_with_server_request.is_nil())
+ {
+ bool swsr = synch_with_server_request->wait(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (DISPATCH_REJECTED);
+ if (swsr == false)
+ {
+ // Raise exception when request was cancelled.
+ ACE_THROW_RETURN(CORBA::NO_IMPLEMENT(), DISPATCH_REJECTED);
+ }
+ }
+
+ return DISPATCH_HANDLED;
+}
+
+
+void
+TAO::CSD::TP_Strategy::servant_activated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ ACE_UNUSED_ARG(oid);
+
+ // Add the servant to the servant state map.
+ this->servant_state_map_.insert(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+TAO::CSD::TP_Strategy::servant_deactivated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ ACE_UNUSED_ARG(oid);
+
+ // Cancel all requests stuck in the queue for the specified servant.
+ this->task_.cancel_servant(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Remove the servant from the servant state map.
+ this->servant_state_map_.remove(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+TAO::CSD::TP_Strategy::cancel_requests(PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ // Cancel all requests stuck in the queue for the specified servant.
+ this->task_.cancel_servant(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.h
new file mode 100644
index 00000000000..ff96daa2788
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.h
@@ -0,0 +1,180 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Strategy.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_STRATEGY_H
+#define TAO_CSD_TP_STRATEGY_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#include "CSD_TP_Task.h"
+#include "CSD_TP_Servant_State_Map.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"
+
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ class TP_Strategy;
+ typedef TAO_Intrusive_Ref_Count_Handle<TP_Strategy> TP_Strategy_Handle;
+
+ class TP_Custom_Request_Operation;
+
+ /**
+ * @class TP_Strategy
+ *
+ * @brief A simple custom Thread-Pool servant dispatching strategy class.
+ *
+ * This class represents a concrete implementation of a "Custom
+ * Servant Dispatching Strategy". This implementation is being called
+ * the "Thread Pool Strategy" reference implementation.
+ *
+ * A custom servant dispatching strategy object can be applied to a
+ * POA object in order to carry out the servant dispatching duties
+ * for that POA.
+ *
+ */
+ class TAO_CSD_TP_Export TP_Strategy
+ : public Strategy_Base
+ {
+ public:
+
+ /// Constructor.
+ TP_Strategy(unsigned num_threads = 1);
+
+ /// Virtual Destructor.
+ virtual ~TP_Strategy();
+
+ /// Set the number of threads in the pool (must be > 0).
+ void set_num_threads(unsigned num_threads);
+
+ /// 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
+ (TP_Custom_Request_Operation* op
+ ACE_ENV_ARG_DECL);
+
+ /// 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
+ (TP_Custom_Request_Operation* op
+ ACE_ENV_ARG_DECL);
+
+ /// Cancel all requests that are targeted for the provided servant.
+ /// This is requested on the user application level.
+ void cancel_requests(PortableServer::Servant servant
+ ACE_ENV_ARG_DECL);
+
+ 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
+ ACE_ENV_ARG_DECL);
+
+ /// 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
+ ACE_ENV_ARG_DECL);
+
+ /// 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();
+
+ /// 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
+ ACE_ENV_ARG_DECL);
+
+ /// Event - A servant has been deactivated
+ virtual void servant_deactivated_event_i
+ (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ /// 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.
+ TP_Task task_;
+
+ /// The number of worker threads to use for the task.
+ unsigned num_threads_;
+
+ /// The map of servant state objects.
+ TP_Servant_State_Map servant_state_map_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Strategy.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_STRATEGY_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.inl
new file mode 100644
index 00000000000..ac2f95e3586
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.inl
@@ -0,0 +1,17 @@
+// $Id$
+
+ACE_INLINE
+TAO::CSD::TP_Strategy::TP_Strategy(unsigned num_threads)
+ : num_threads_(num_threads)
+{
+ // Assumes that num_threads > 0.
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Strategy::set_num_threads(unsigned num_threads)
+{
+ // Simple Mutator. Assumes that num_threads > 0.
+ this->num_threads_ = num_threads;
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp
new file mode 100644
index 00000000000..0ec186f2f6d
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp
@@ -0,0 +1,108 @@
+// $Id$
+
+#include "CSD_TP_Strategy_Factory.h"
+#include "CSD_TP_Strategy.h"
+#include "CSD_ThreadPool.h"
+#include "tao/CSD_Framework/CSD_Strategy_Repository.h"
+#include "tao/debug.h"
+#include "ace/Dynamic_Service.h"
+#include "ace/OS_NS_strings.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Strategy_Factory,
+ "$Id$")
+
+
+TAO::CSD::TP_Strategy_Factory::TP_Strategy_Factory()
+{
+}
+
+
+TAO::CSD::TP_Strategy_Factory::~TP_Strategy_Factory()
+{
+}
+
+
+int
+TAO::CSD::TP_Strategy_Factory::init (int argc,
+ ACE_TCHAR* argv[])
+{
+ ACE_TRACE ("TAO::CSD::TP_Strategy_Factory::init");
+
+ static int initialized = 0;
+
+ // Only allow initialization once.
+ if (initialized)
+ return 0;
+
+ 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_CString poa_name;
+ unsigned num_threads = 1;
+
+ // Parse any service configurator parameters.
+ for (int curarg = 0; curarg < argc; curarg++)
+ if (ACE_OS::strcasecmp (argv[curarg],
+ ACE_TEXT("-CSDtp")) == 0)
+ {
+ curarg++;
+ if (curarg < argc)
+ {
+ // Parse the parameter
+ ACE_CString arg ((const char *)argv[curarg]);
+ ssize_t pos = arg.find (':');
+ poa_name = arg.substr (0, pos);
+ ACE_CString num_thread_str = arg.substr (pos + 1, arg.length () - pos);
+ num_threads = ACE_OS::strtoul (num_thread_str.c_str (), 0, 10);
+
+ // Create the ThreadPool strategy for each named poa.
+ TP_Strategy* strategy = 0;
+ ACE_NEW_RETURN (strategy, TP_Strategy (num_threads), -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_DEBUG ((LM_ERROR,
+ ACE_TEXT("CSD_ORB_Loader: Unknown option ")
+ ACE_TEXT("<%s>.\n"),
+ argv[curarg]));
+ }
+ }
+
+
+ return 0;
+}
+
+ACE_FACTORY_NAMESPACE_DEFINE(TAO_CSD_TP,
+ TAO_CSD_TP_Strategy_Factory,
+ TAO::CSD::TP_Strategy_Factory)
+
+ACE_STATIC_SVC_DEFINE(TAO_CSD_TP_Strategy_Factory,
+ ACE_TEXT("TAO_CSD_TP_Strategy_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME(TAO_CSD_TP_Strategy_Factory),
+ ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
+ 0)
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.h
new file mode 100644
index 00000000000..e51346befbf
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.h
@@ -0,0 +1,61 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Strategy_Factory.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_STRATEGY_FACTORY_H
+#define TAO_CSD_TP_STRATEGY_FACTORY_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_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 */
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ /**
+ * @class TP_Strategy_Factory
+ *
+ * @brief An ACE_Service_Object capable of creating TP_Strategy objects.
+ *
+ * TBD - Explain in more detail.
+ *
+ */
+ class TAO_CSD_TP_Export TP_Strategy_Factory : public ACE_Service_Object
+ {
+ public:
+
+ /// Constructor.
+ TP_Strategy_Factory();
+
+ /// Virtual Destructor.
+ virtual ~TP_Strategy_Factory();
+
+ int init (int argc, ACE_TCHAR* argv[]);
+ };
+ }
+}
+
+ACE_STATIC_SVC_DECLARE_EXPORT(TAO_CSD_TP, TAO_CSD_TP_Strategy_Factory)
+ACE_FACTORY_DECLARE(TAO_CSD_TP, TAO_CSD_TP_Strategy_Factory)
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_STRATEGY_FACTORY_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.cpp
new file mode 100644
index 00000000000..b3b241ec8f8
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.cpp
@@ -0,0 +1,11 @@
+// $Id$
+
+#include "CSD_TP_Synch_Helper.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Synch_Helper,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Synch_Helper.inl"
+#endif /* ! __ACE_INLINE__ */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.h
new file mode 100644
index 00000000000..80c8aaff2ec
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.h
@@ -0,0 +1,107 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Synch_Helper.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_SYNCH_HELPER_H
+#define TAO_CSD_TP_SYNCH_HELPER_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+#include "tao/Condition.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Synch.h"
+
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ /**
+ * @class TP_Synch_Helper
+ *
+ * @brief Helper class for synchronous requests to block the requesting
+ * thread until the appropriate time (when it will be un-blocked).
+ *
+ * TBD - Description here
+ *
+ */
+ class TAO_CSD_TP_Export TP_Synch_Helper
+ {
+ public:
+
+ /// Constructor. Sets initial state to PENDING.
+ TP_Synch_Helper();
+
+ /// Destructor.
+ ~TP_Synch_Helper();
+
+ /// Returns true if the helper state is DISPATCHED, and false if
+ /// the helper state is CANCELLED. However, if the helper state
+ /// is PENDING, then this method will block the calling thread
+ /// until the state changes to something other than PENDING
+ /// (ie, DISPATCHED or CANCELLED).
+ bool wait_while_pending();
+
+ /// Change the state of this helper to DISPATCHED, which will cause
+ /// wait_while_pending() to unblock.
+ void dispatched();
+
+ /// Change the state of this helper to CANCELLED, which will cause
+ /// wait_while_pending() to unblock.
+ void cancelled();
+
+
+ private:
+
+ /// Enumeration Type for all possible states of this helper object.
+ enum HelperState
+ {
+ PENDING,
+ DISPATCHED,
+ CANCELLED
+ };
+
+ /// Thread lock type
+ typedef ACE_SYNCH_MUTEX LockType;
+
+ /// Thread guard type
+ typedef ACE_Guard<LockType> GuardType;
+
+ /// Thread condition type
+ typedef TAO_Condition<LockType> ConditionType;
+
+ /// Lock used to protect the state and condition.
+ LockType lock_;
+
+ /// Used to denote the state of the request dispatching.
+ HelperState state_;
+
+ /// The condition used to block the calling thread until the
+ /// state is something other than the PENDING state.
+ ConditionType condition_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Synch_Helper.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_SYNCH_HELPER_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.inl
new file mode 100644
index 00000000000..8a54320afb4
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.inl
@@ -0,0 +1,50 @@
+// $Id$
+
+
+ACE_INLINE
+TAO::CSD::TP_Synch_Helper::TP_Synch_Helper()
+ : state_(PENDING),
+ condition_(this->lock_)
+{
+}
+
+
+ACE_INLINE
+TAO::CSD::TP_Synch_Helper::~TP_Synch_Helper()
+{
+}
+
+
+ACE_INLINE
+bool
+TAO::CSD::TP_Synch_Helper::wait_while_pending()
+{
+ GuardType guard(this->lock_);
+
+ while (this->state_ == PENDING)
+ {
+ this->condition_.wait();
+ }
+
+ return (this->state_ == DISPATCHED);
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Synch_Helper::dispatched()
+{
+ GuardType guard(this->lock_);
+ this->state_ = DISPATCHED;
+ this->condition_.signal();
+}
+
+
+ACE_INLINE
+void
+TAO::CSD::TP_Synch_Helper::cancelled()
+{
+ GuardType guard(this->lock_);
+ this->state_ = CANCELLED;
+ this->condition_.signal();
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp
new file mode 100644
index 00000000000..4a3874a4b82
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp
@@ -0,0 +1,310 @@
+// $Id$
+
+#include "CSD_TP_Task.h"
+#include "CSD_TP_Request.h"
+#include "CSD_TP_Dispatchable_Visitor.h"
+#include "CSD_TP_Cancel_Visitor.h"
+
+ACE_RCSID (CSD_ThreadPool,
+ TP_Task,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "CSD_TP_Task.inl"
+#endif /* ! __ACE_INLINE__ */
+
+TAO::CSD::TP_Task::~TP_Task()
+{
+}
+
+
+bool
+TAO::CSD::TP_Task::add_request(TP_Request* request)
+{
+ GuardType guard(this->lock_);
+
+ if (!this->accepting_requests_)
+ {
+ ACE_DEBUG((LM_DEBUG,"(%P|%t) TP_Task::add_request() - "
+ "not accepting requests\n"));
+ 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);
+
+ this->work_available_.signal();
+
+ return true;
+}
+
+
+int
+TAO::CSD::TP_Task::open(void* num_threads_ptr)
+{
+ unsigned num = 1;
+
+ if (num_threads_ptr != 0)
+ {
+ unsigned* tmp = ACE_static_cast(unsigned*, num_threads_ptr);
+
+ if (tmp == 0)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) TP_Task failed to open. "
+ "Invalid argument type passed to open().\n"),
+ -1);
+ }
+
+ num = *tmp;
+ }
+
+ // We can't activate 0 threads. Make sure this isn't the case.
+ if (num < 1)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) TP_Task failed to open. "
+ "num_threads_ (%u) is less-than 1.\n",
+ num),
+ -1);
+ }
+
+ // Likewise, we can't activate too many. Make sure this isn't the case.
+ if (num > MAX_THREADPOOL_TASK_WORKER_THREADS)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) TP_Task failed to open. "
+ "num_threads_ (%u) is too large. Max is %d.\n",
+ num, MAX_THREADPOOL_TASK_WORKER_THREADS),
+ -1);
+ }
+
+ // We need the lock acquired from here on out.
+ GuardType guard(this->lock_);
+
+ // 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_)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) TP_Task failed to open. "
+ "Task has previously been open()'ed.\n"),
+ -1);
+ }
+
+ // Activate this task object with 'num' worker threads.
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, num) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) TP_Task failed to activate "
+ "(%d) worker threads.\n",
+ num),
+ -1);
+ }
+
+ // Now we have past the point where we can say we've been open()'ed before.
+ this->opened_ = true;
+
+ // Now we wait until all of the threads have started.
+ while (this->num_threads_ != num)
+ {
+ this->active_workers_.wait();
+ }
+
+ // We can now accept requests (via our add_request() method).
+ this->accepting_requests_ = true;
+
+ return 0;
+}
+
+
+int
+TAO::CSD::TP_Task::svc()
+{
+ // Account for this current worker thread having started the
+ // execution of this svc() method.
+ {
+ GuardType guard(this->lock_);
+ // Put the thread id into a collection which is used to check whether
+ // the orb shutdown is called by one of the threads in the pool.
+ ACE_thread_t thr_id = ACE_OS::thr_self ();
+ if (this->activated_threads_.set(thr_id, this->num_threads_) == -1)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ ACE_TEXT("(%P|%t)TP_Task::svc: number of threads is out of range \n")),
+ 0);
+ }
+ ++this->num_threads_;
+ this->active_workers_.signal();
+ }
+
+ // This visitor object will be re-used over and over again as part of
+ // the "GetWork" logic below.
+ TP_Dispatchable_Visitor dispatchable_visitor;
+
+ // Start the "GetWork-And-PerformWork" loop for the current worker thread.
+ while (1)
+ {
+ TP_Request_Handle request;
+
+ // Do the "GetWork" step.
+ {
+ // Acquire the lock until just before we decide to "PerformWork".
+ GuardType guard(this->lock_);
+
+ // Start the "GetWork" loop.
+ while (request.is_nil())
+ {
+ if (this->shutdown_initiated_)
+ {
+ // This breaks us out of all loops with one fell swoop.
+ return 0;
+ }
+
+ // There is no need to visit the queue if it is empty.
+ if (!this->queue_.is_empty())
+ {
+ // Reset the visitor since we use it over and over. This
+ // will cause the visitor to drop any reference to
+ // a request that it may still be holding from a prior
+ // call to accept_visitor().
+ dispatchable_visitor.reset();
+
+ // Visit the requests in the queue in hopes of
+ // locating the first "dispatchable" (ie, not busy) request.
+ // If a dispatchable request is located, it is extracted
+ // from the queue and saved in a handle data member in the
+ // visitor object.
+ this->queue_.accept_visitor(dispatchable_visitor);
+
+ // If a dispatchable request is located, it is extracted
+ // from the queue and saved in a handle data member in the
+ // visitor object. Let's get a "copy" (or a NULL pointer
+ // if the visitor didn't locate/extract one).
+ request = dispatchable_visitor.request();
+ }
+
+ // Either the queue is empty or we couldn't find any dispatchable
+ // requests in the queue at this time.
+ if (request.is_nil())
+ {
+ // Let's wait until we hear about the possibility of
+ // work before we go look again.
+ this->work_available_.wait();
+ }
+ }
+
+ // We have dropped out of the "while (request.is_nil())" loop.
+ // We only get here is we located/extracted a dispatchable request
+ // from the queue. Note that the visitor will have already
+ // marked the target servant as now being busy (because of us).
+ // We can now safely release the lock.
+ }
+
+ // Do the "PerformWork" step. We don't need the lock_ to do this.
+ request->dispatch();
+
+ // Now that the request has been dispatched, we need to mark the target
+ // servant as no longer being busy, and we need to signal any wait()'ing
+ // worker threads that there may be some dispatchable requests in the
+ // queue now for this not-busy servant. We need the lock_ to do this.
+ {
+ GuardType guard(this->lock_);
+ request->mark_as_ready();
+ this->work_available_.signal();
+ }
+
+ // Note that the request will be "released" here when the request
+ // handle falls out of scope and its destructor performs the
+ // _remove_ref() call on the underlying TP_Request object.
+ }
+
+ // This will never get executed.
+ return 0;
+}
+
+
+int
+TAO::CSD::TP_Task::close(u_long flag)
+{
+ GuardType guard(this->lock_);
+
+ if (flag == 0)
+ {
+ // Worker thread is closing.
+ --this->num_threads_;
+ this->active_workers_.signal();
+ }
+ else
+ {
+ // Strategy object is shutting down the task.
+
+ // Do nothing if this task has never been open()'ed.
+ if (!this->opened_)
+ {
+ return 0;
+ }
+
+ // Set the shutdown flag to true.
+ this->shutdown_initiated_ = true;
+
+ // Stop accepting requests.
+ this->accepting_requests_ = false;
+
+ // Signal all worker threads waiting on the work_available_ condition.
+ this->work_available_.broadcast();
+
+ size_t num_waiting_threads = 0;
+
+ ACE_thread_t my_thr_id = ACE_OS::thr_self ();
+
+ // Check whether the calling thread(calling orb shutdown) is one of the
+ // threads in the pool. If it is then it should not wait itself.
+ size_t size = this->activated_threads_.size ();
+
+ for (size_t i = 0; i < size; i ++)
+ {
+ ACE_thread_t thr_id = 0;
+ if (activated_threads_.get (thr_id, i) == 0 && thr_id == my_thr_id)
+ {
+ num_waiting_threads = 1;
+ break;
+ }
+ }
+
+ // Wait until all worker threads have shutdown.
+ while (this->num_threads_ != num_waiting_threads)
+ {
+ this->active_workers_.wait();
+ }
+
+ // Cancel all requests.
+ TP_Cancel_Visitor cancel_visitor;
+ this->queue_.accept_visitor(cancel_visitor);
+ }
+
+ return 0;
+}
+
+
+
+void
+TAO::CSD::TP_Task::cancel_servant (PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ GuardType guard(this->lock_);
+
+ // Cancel the requests targeted for the provided servant.
+ TP_Cancel_Visitor cancel_visitor(servant);
+ this->queue_.accept_visitor(cancel_visitor);
+}
+
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h
new file mode 100644
index 00000000000..25fa02f2fda
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h
@@ -0,0 +1,158 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_TP_Task.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_TP_TASK_H
+#define TAO_CSD_TP_TASK_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_TP_Export.h"
+
+#include "CSD_TP_Queue.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"
+
+namespace TAO
+{
+ namespace CSD
+ {
+
+ /**
+ * @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).
+ *
+ * @note I just wanted to document an idea... When the pool consists
+ * of only one worker thread, we could care less about checking
+ * if target servant objects are busy or not. The simple fact
+ * that only one thread will be dispatching all requests means
+ * that servant objects will never be busy when the thread
+ * tests to see if a request is "ready_for_dispatch()". I'm
+ * just wondering if this knowledge can be applied to the
+ * implementation such that the "pool with one worker thread" case
+ * performs more efficiently. This is STP vs SSTP.
+ *
+ */
+ class TAO_CSD_TP_Export TP_Task : public ACE_Task_Base
+ {
+ public:
+
+ /// Default Constructor.
+ TP_Task();
+
+ /// Virtual Destructor.
+ virtual ~TP_Task();
+
+ /// Put a request object on to the request queue.
+ /// Returns true if successful, false otherwise (it has been "rejected").
+ bool add_request(TP_Request* request);
+
+ /// Activate the worker threads
+ virtual int open(void* num_threads_ptr = 0);
+
+ /// The "mainline" executed by each worker thread.
+ virtual int svc();
+
+ /// Multi-purpose: argument value is used to differentiate purpose.
+ ///
+ /// 0) Invoked by each worker thread after its invocation of the
+ /// svc() method has completed (ie, returned).
+ /// 1) Invoked by the strategy object to shutdown all worker threads.
+ virtual int close(u_long flag = 0);
+
+ /// Cancel all requests that are targeted for the provided servant.
+ void cancel_servant (PortableServer::Servant servant
+ ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ typedef TAO_SYNCH_MUTEX LockType;
+ typedef ACE_Guard<LockType> GuardType;
+ typedef TAO_Condition<LockType> ConditionType;
+
+
+ /// Lock to protect the "state" (all of the data members) of this object.
+ LockType 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_initiated_;
+
+ /// Flag used to avoid multiple open() calls.
+ bool opened_;
+
+ /// The number of currently active worker threads.
+ unsigned num_threads_;
+
+ /// The queue of pending servant requests (a.k.a. the "request queue").
+ TP_Queue queue_;
+
+ typedef ACE_Array <ACE_thread_t> Thread_Ids;
+
+ /// The list of ids for the threads launched by this task.
+ Thread_Ids activated_threads_;
+ };
+
+ }
+}
+
+#if defined (__ACE_INLINE__)
+# include "CSD_TP_Task.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_TP_TASK_H */
diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.inl
new file mode 100644
index 00000000000..5d9744d2afb
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.inl
@@ -0,0 +1,17 @@
+// $Id$
+
+namespace { enum { MAX_THREADPOOL_TASK_WORKER_THREADS = 50 }; }
+namespace { const ACE_thread_t default_thread_id = 0; }
+
+
+ACE_INLINE
+TAO::CSD::TP_Task::TP_Task()
+ : work_available_(this->lock_),
+ active_workers_(this->lock_),
+ accepting_requests_(false),
+ shutdown_initiated_(false),
+ opened_(false),
+ num_threads_(0),
+ activated_threads_ ((size_t)MAX_THREADPOOL_TASK_WORKER_THREADS, default_thread_id)
+{
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp
new file mode 100644
index 00000000000..6797bd315e9
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp
@@ -0,0 +1,19 @@
+// $Id$
+
+#include "CSD_ThreadPool.h"
+#include "CSD_TP_Strategy_Factory.h"
+#include "tao/CSD_Framework/CSD_Framework_Loader.h"
+#include "tao/debug.h"
+#include "ace/Dynamic_Service.h"
+
+int
+TAO_CSD_ThreadPool::init (void)
+{
+ static int initialized = 0;
+ if (initialized == 1)
+ return 0;
+ initialized = 1;
+
+ TAO_CSD_Framework_Loader::init();
+ return ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_TP_Strategy_Factory);
+}
diff --git a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h
new file mode 100644
index 00000000000..e227bce3023
--- /dev/null
+++ b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h
@@ -0,0 +1,60 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file CSD_Threadpool.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_CSD_THREADPOOL_H
+#define TAO_CSD_THREADPOOL_H
+
+#include /**/ "ace/pre.h"
+
+#include "CSD_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 */
+
+/**
+ * @class TP_Strategy_Factory
+ *
+ * @brief An ACE_Service_Object capable of creating TP_Strategy objects.
+ *
+ * TBD - Explain in more detail.
+ *
+ */
+class TAO_CSD_TP_Export TAO_CSD_ThreadPool
+{
+ public:
+ /// Used to force the initialization of the ORB code.
+ static int init (void);
+};
+
+#if defined(ACE_HAS_BROKEN_STATIC_CONSTRUCTORS)
+
+typedef int (*TAO_CSD_Threadpool) (void);
+
+static TAO_CSD_Threadpool
+TAO_Requires_CSD_Threadpool =
+ &TAO_CSD_ThreadPool::init;
+
+#else
+
+static int
+TAO_Requires_CSD_Threadpool =
+ TAO_CSD_ThreadPool::init ();
+
+#endif /* ACE_HAS_BROKEN_STATIC_CONSTRUCTORS */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_CSD_THREADPOOL_H */
diff --git a/TAO/tao/Intrusive_Ref_Count_Base_T.cpp b/TAO/tao/Intrusive_Ref_Count_Base_T.cpp
new file mode 100644
index 00000000000..e7776d3fd91
--- /dev/null
+++ b/TAO/tao/Intrusive_Ref_Count_Base_T.cpp
@@ -0,0 +1,21 @@
+// $Id$
+
+#ifndef TAO_INTRUSIVE_REF_COUNT_BASE_T_C
+#define TAO_INTRUSIVE_REF_COUNT_BASE_T_C
+
+#include "Intrusive_Ref_Count_Base_T.h"
+
+#if !defined (__ACE_INLINE__)
+#include "tao/Intrusive_Ref_Count_Base_T.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID (tao,
+ Intrusive_Ref_Count_Base_T,
+ "$Id$")
+
+template <typename T>
+TAO_Intrusive_Ref_Count_Base<T>::~TAO_Intrusive_Ref_Count_Base()
+{
+}
+
+#endif /* TAO_INTRUSIVE_REF_COUNT_BASE_T_C */
diff --git a/TAO/tao/Intrusive_Ref_Count_Base_T.h b/TAO/tao/Intrusive_Ref_Count_Base_T.h
new file mode 100644
index 00000000000..f37041bd02c
--- /dev/null
+++ b/TAO/tao/Intrusive_Ref_Count_Base_T.h
@@ -0,0 +1,75 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Intrusive_Ref_Count_Base_T.h
+ *
+ * $Id$
+ *
+ * @authors Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_INTRUSIVE_REF_COUNT_BASE_T_H
+#define TAO_INTRUSIVE_REF_COUNT_BASE_T_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Atomic_Op.h"
+
+
+/**
+ * @class TAO_Intrusive_Ref_Count_Base<ACE_LOCK>
+ *
+ * @brief Template base class to provide intrusive reference-counting
+ * to subclasses. This makes the subclass capable of using a
+ * TAO_Intrusive_Ref_Count_Handle<X> class as a smart-pointer
+ * to an X object. In this case, X is a sub-class of this class,
+ * TAO_Intrusive_Ref_Count_Base<ACE_LOCK>. The ACE_LOCK type is
+ * used to protect the atomic reference count data member.
+ *
+ */
+template <class ACE_LOCK>
+class TAO_Intrusive_Ref_Count_Base
+{
+public:
+
+ virtual ~TAO_Intrusive_Ref_Count_Base();
+
+ void _add_ref();
+ void _remove_ref();
+
+
+protected:
+
+ TAO_Intrusive_Ref_Count_Base();
+
+
+private:
+
+ ACE_Atomic_Op<ACE_LOCK, long> ref_count_;
+
+ // Not implemented.
+ TAO_Intrusive_Ref_Count_Base(const TAO_Intrusive_Ref_Count_Base&);
+ TAO_Intrusive_Ref_Count_Base& operator=(const TAO_Intrusive_Ref_Count_Base&);
+};
+
+#if defined (__ACE_INLINE__)
+#include "Intrusive_Ref_Count_Base_T.inl"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "Intrusive_Ref_Count_Base_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Intrusive_Ref_Count_Base_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_INTRUSIVE_REF_COUNT_BASE_T_H */
diff --git a/TAO/tao/Intrusive_Ref_Count_Base_T.inl b/TAO/tao/Intrusive_Ref_Count_Base_T.inl
new file mode 100644
index 00000000000..448763b6c74
--- /dev/null
+++ b/TAO/tao/Intrusive_Ref_Count_Base_T.inl
@@ -0,0 +1,32 @@
+// $Id$
+
+template <typename T>
+ACE_INLINE
+TAO_Intrusive_Ref_Count_Base<T>::TAO_Intrusive_Ref_Count_Base ()
+ : ref_count_(1)
+{}
+
+
+template <typename T>
+ACE_INLINE
+void
+TAO_Intrusive_Ref_Count_Base<T>::_add_ref()
+{
+ ++this->ref_count_;
+}
+
+
+template <typename T>
+ACE_INLINE
+void
+TAO_Intrusive_Ref_Count_Base<T>::_remove_ref()
+{
+ long new_count = --this->ref_count_;
+
+ if (new_count != 0)
+ {
+ return;
+ }
+
+ delete this;
+}
diff --git a/TAO/tao/Intrusive_Ref_Count_Handle_T.cpp b/TAO/tao/Intrusive_Ref_Count_Handle_T.cpp
new file mode 100644
index 00000000000..f66b1177c48
--- /dev/null
+++ b/TAO/tao/Intrusive_Ref_Count_Handle_T.cpp
@@ -0,0 +1,16 @@
+// $Id$
+
+#ifndef TAO_INTRUSIVE_REF_COUNT_HANDLE_T_C
+#define TAO_INTRUSIVE_REF_COUNT_HANDLE_T_C
+
+#include "Intrusive_Ref_Count_Handle_T.h"
+
+#if !defined (__ACE_INLINE__)
+#include "tao/Intrusive_Ref_Count_Handle_T.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID (tao,
+ Intrusive_Ref_Count_Handle_T,
+ "$Id$")
+
+#endif /* TAO_INTRUSIVE_REF_COUNT_HANDLE_T_C */
diff --git a/TAO/tao/Intrusive_Ref_Count_Handle_T.h b/TAO/tao/Intrusive_Ref_Count_Handle_T.h
new file mode 100644
index 00000000000..ce9a64dc694
--- /dev/null
+++ b/TAO/tao/Intrusive_Ref_Count_Handle_T.h
@@ -0,0 +1,152 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Intrusive_Ref_Count_Handle_T.h
+ *
+ * $Id$
+ *
+ * @authors Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef TAO_INTRUSIVE_REF_COUNT_HANDLE_T_H
+#define TAO_INTRUSIVE_REF_COUNT_HANDLE_T_H
+
+#include /**/ "ace/pre.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+/**
+ * @class TAO_Intrusive_Ref_Count_Handle<T>
+ *
+ * @brief Template class for smart-pointer to (intrusively) ref-counted object.
+ *
+ * This class behaves just like a xxx_var type behaves. The only significant
+ * difference is that this class provides a "bool is_nil() const" method,
+ * and xxx_var types don't (they use the "bool CORBA::is_nil(xxx_ptr ptr)"
+ * method instead). For example,
+ *
+ * typedef TAO_Intrusive_Ref_Count_Handle<PortableServer::ServantBase>
+ * MyServantBase_var;
+ *
+ * The MyServantBase_var and the PortableServer::ServantBase_var are
+ * nearly idenitical. The only difference is that the MyServantBase_var
+ * has a "isNil()" method that indicates whether or not the smart pointer
+ * is in the 'nil' state or not.
+ *
+ * This class can be used to "safely" deal with an instance of a servant.
+ * For example, we can use a single variable
+ * TAO_Intrusive_Ref_Count_Handle<Foo_i>
+ *
+ * typedef TAO_Intrusive_Ref_Count_Handle<Foo_i> Foo_i_var;
+ * Foo_i_var servant_;
+ *
+ * instead of using two variables
+ *
+ * PortableServer::ServantBase_var servant_holder_;
+ * Foo_i* servant_;
+
+ * to deal with the servant memory.
+ *
+ * The Foo_i_var type does everything that the PortableServer::ServantBase_var
+ * type does. In addition, the Foo_i_var type can provide access to the servant
+ * as derived class via the arrow operator.
+ */
+template <typename T>
+class TAO_Intrusive_Ref_Count_Handle
+{
+public:
+
+ /// Default Ctor - enters the "nil" state.
+ TAO_Intrusive_Ref_Count_Handle();
+
+ /// Ctor - By default, takes ownership of passed-in "copy" of reference
+ /// to T. But the second argument (bool) can be changed from
+ /// the default value of 'true' to the non-default value of 'false'.
+ /// The second argument dictates whether or not this handle object
+ /// should take ownership of the passed-in pointer to the T object.
+ /// By default, it takes ownership, leaving the reference counter
+ /// of the T object unchanged. When it is instructed to not take
+ /// ownership (false value for second arg), then the reference
+ /// counter of the T object will be incremented so that this
+ /// handle object has its own "copy".
+ TAO_Intrusive_Ref_Count_Handle(T* p, bool take_ownership = true);
+
+ /// Copy Ctor - claims a "copy" of rhs object's reference to T.
+ TAO_Intrusive_Ref_Count_Handle(const TAO_Intrusive_Ref_Count_Handle& b);
+
+ /// Dtor
+ ~TAO_Intrusive_Ref_Count_Handle();
+
+ /// Assignment Operator with T* argument.
+ /// Takes ownership of passed-in "copy" of reference to T.
+ TAO_Intrusive_Ref_Count_Handle& operator=(T* p);
+
+ /// Assignment Operator with const TAO_Smart_Ptr<T>& argument.
+ /// Claims a "copy" of rhs object's reference to T.
+ TAO_Intrusive_Ref_Count_Handle& operator=
+ (const TAO_Intrusive_Ref_Count_Handle& b);
+
+ /// Const Accessor to underlying pointer (T*) using arrow (->) operator.
+ T* operator->() const;
+
+ /// Returns true if underlying pointer is NULL (0).
+ /// Returns false otherwise.
+ bool is_nil() const;
+
+ /// Used to pass the underlying pointer as an "IN" argument to a method.
+ T* in() const;
+
+ /// Used to pass the underlying pointer as an "IN/OUT" argument to a method.
+ T*& inout();
+
+ /// Used to pass the underlying pointer as an "OUT" argument to a method.
+ T*& out();
+
+ /// Used to take-away the underlying pointer from this smart pointer object.
+ /// Caller becomes responsibe for the returned "copy" to the reference.
+ /// Always leaves the smart pointer in the "nil" state upon return.
+ T* _retn();
+
+
+private:
+
+ /// Claim a "copy" of the reference-counted object by adding
+ /// one to its reference counter. Do nothing if this smart pointer
+ /// object is currently in the "nil" state.
+ void claim();
+
+ /// Drop our "copy" of the reference-counted object by removing
+ /// one from its reference counter. Do nothing if this smart pointer
+ /// object is currently in the "nil" state.
+ /// Note that this method will always leave this smart pointer
+ /// in the "nil" state upon its return.
+ void drop();
+
+
+ /// The underlying pointer to the (intrusively) reference-counted object.
+ /// Set to 0 when this smart pointer is in the "nil" state. Otherwise,
+ /// this smart pointer always owns a (reference-counted) "copy" of the
+ /// object pointed to by the ptr_ data member.
+ T* ptr_;
+};
+
+#if defined (__ACE_INLINE__)
+#include "Intrusive_Ref_Count_Handle_T.inl"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "Intrusive_Ref_Count_Handle_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Intrusive_Ref_Count_Handle_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_INTRUSIVE_REF_COUNT_HANDLE_T_H */
diff --git a/TAO/tao/Intrusive_Ref_Count_Handle_T.inl b/TAO/tao/Intrusive_Ref_Count_Handle_T.inl
new file mode 100644
index 00000000000..9c3a1fbe48b
--- /dev/null
+++ b/TAO/tao/Intrusive_Ref_Count_Handle_T.inl
@@ -0,0 +1,155 @@
+// $Id$
+
+
+template <typename T>
+ACE_INLINE
+TAO_Intrusive_Ref_Count_Handle<T>::TAO_Intrusive_Ref_Count_Handle()
+ : ptr_(0)
+{
+}
+
+
+template <typename T>
+ACE_INLINE
+TAO_Intrusive_Ref_Count_Handle<T>::TAO_Intrusive_Ref_Count_Handle
+ (T* p,
+ bool take_ownership)
+ : ptr_(p)
+{
+ if (!take_ownership)
+ {
+ this->claim();
+ }
+}
+
+
+template <typename T>
+ACE_INLINE
+TAO_Intrusive_Ref_Count_Handle<T>::TAO_Intrusive_Ref_Count_Handle
+ (const TAO_Intrusive_Ref_Count_Handle<T>& b)
+ : ptr_(b.ptr_)
+{
+ this->claim();
+}
+
+
+template <typename T>
+ACE_INLINE
+TAO_Intrusive_Ref_Count_Handle<T>::~TAO_Intrusive_Ref_Count_Handle()
+{
+ this->drop();
+}
+
+
+template <typename T>
+ACE_INLINE
+TAO_Intrusive_Ref_Count_Handle<T>&
+TAO_Intrusive_Ref_Count_Handle<T>::operator=(T* p)
+{
+ if (this->ptr_ != p)
+ {
+ this->drop();
+ this->ptr_ = p;
+ }
+
+ return *this;
+}
+
+
+template <typename T>
+ACE_INLINE
+TAO_Intrusive_Ref_Count_Handle<T>&
+TAO_Intrusive_Ref_Count_Handle<T>::operator=
+ (const TAO_Intrusive_Ref_Count_Handle<T>& b)
+{
+ if (this->ptr_ != b.ptr_)
+ {
+ this->drop();
+ this->ptr_ = b.ptr_;
+ this->claim();
+ }
+
+ return *this;
+}
+
+
+template <typename T>
+ACE_INLINE
+T*
+TAO_Intrusive_Ref_Count_Handle<T>::operator->() const
+{
+ return this->ptr_;
+}
+
+
+template <typename T>
+ACE_INLINE
+bool
+TAO_Intrusive_Ref_Count_Handle<T>::is_nil() const
+{
+ return this->ptr_ == 0;
+}
+
+
+template <typename T>
+ACE_INLINE
+T*
+TAO_Intrusive_Ref_Count_Handle<T>::in() const
+{
+ return this->ptr_;
+}
+
+
+template <typename T>
+ACE_INLINE
+T*&
+TAO_Intrusive_Ref_Count_Handle<T>::inout()
+{
+ return this->ptr_;
+}
+
+
+template <typename T>
+ACE_INLINE
+T*&
+TAO_Intrusive_Ref_Count_Handle<T>::out()
+{
+ this->drop();
+ return this->ptr_;
+}
+
+
+template <typename T>
+ACE_INLINE
+T*
+TAO_Intrusive_Ref_Count_Handle<T>::_retn()
+{
+ T* retval = this->ptr_;
+ this->ptr_ = 0;
+ return retval;
+}
+
+
+template <typename T>
+ACE_INLINE
+void
+TAO_Intrusive_Ref_Count_Handle<T>::claim()
+{
+ if (this->ptr_ != 0)
+ {
+ this->ptr_->_add_ref();
+ }
+}
+
+
+template <typename T>
+ACE_INLINE
+void
+TAO_Intrusive_Ref_Count_Handle<T>::drop()
+{
+ if (this->ptr_ != 0)
+ {
+ this->ptr_->_remove_ref();
+ this->ptr_ = 0;
+ }
+}
diff --git a/TAO/tao/PortableServer/Object_Adapter.cpp b/TAO/tao/PortableServer/Object_Adapter.cpp
index 6ad3cc7ad62..c1a6c27d759 100644
--- a/TAO/tao/PortableServer/Object_Adapter.cpp
+++ b/TAO/tao/PortableServer/Object_Adapter.cpp
@@ -355,9 +355,7 @@ TAO_Object_Adapter::dispatch_servant (const TAO::ObjectKey &key,
{
ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_DISPATCH_START);
- servant_upcall.servant ()->_dispatch (req,
- &servant_upcall
- ACE_ENV_ARG_PARAMETER);
+ do_dispatch (req, servant_upcall ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (result);
}
@@ -1242,3 +1240,14 @@ TAO_Object_Adapter::servant_dispatcher (TAO_Servant_Dispatcher *dispatcher)
this->servant_dispatcher_ = dispatcher;
}
+void
+TAO_Object_Adapter::do_dispatch (TAO_ServerRequest& req,
+ TAO::Portable_Server::Servant_Upcall& upcall
+ ACE_ENV_ARG_DECL)
+{
+ upcall.servant ()->_dispatch(req,
+ &upcall
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
diff --git a/TAO/tao/PortableServer/Object_Adapter.h b/TAO/tao/PortableServer/Object_Adapter.h
index a3605dc2f11..85587c99c0f 100644
--- a/TAO/tao/PortableServer/Object_Adapter.h
+++ b/TAO/tao/PortableServer/Object_Adapter.h
@@ -217,6 +217,10 @@ protected:
static ACE_Lock *create_lock (int enable_locking,
TAO_SYNCH_MUTEX &thread_lock);
+ virtual void do_dispatch (TAO_ServerRequest& req,
+ TAO::Portable_Server::Servant_Upcall& upcall
+ ACE_ENV_ARG_DECL);
+
public:
/**
diff --git a/TAO/tao/PortableServer/POAManager.cpp b/TAO/tao/PortableServer/POAManager.cpp
index 539f5d0cd9d..186b51c9163 100644
--- a/TAO/tao/PortableServer/POAManager.cpp
+++ b/TAO/tao/PortableServer/POAManager.cpp
@@ -51,6 +51,15 @@ TAO_POA_Manager::activate_i (ACE_ENV_SINGLE_ARG_DECL)
else
{
this->state_ = PortableServer::POAManager::ACTIVE;
+ // Find the poas that applied the custom servant dispatching
+ // strategy to launch the dispatching threads.
+
+ for (POA_COLLECTION::iterator iterator = this->poa_collection_.begin ();
+ iterator != this->poa_collection_.end ();
+ ++iterator)
+ {
+ (*iterator)->poa_activated_hook ();
+ }
}
this->adapter_manager_state_changed (this->state_
@@ -117,6 +126,10 @@ TAO_POA_Manager::deactivate_i (CORBA::Boolean etherealize_objects,
++iterator)
{
TAO_Root_POA *poa = *iterator;
+ // Notify the poas that applied the custom servant dispatching
+ // strategy to stop the dispatching threads.
+ poa->poa_deactivated_hook ();
+
poa->deactivate_all_objects_i (etherealize_objects,
wait_for_completion
ACE_ENV_ARG_PARAMETER);
diff --git a/TAO/tao/PortableServer/Root_POA.cpp b/TAO/tao/PortableServer/Root_POA.cpp
index 4a132bd1766..4d51829d9e4 100644
--- a/TAO/tao/PortableServer/Root_POA.cpp
+++ b/TAO/tao/PortableServer/Root_POA.cpp
@@ -822,6 +822,10 @@ TAO_Root_POA::destroy_i (CORBA::Boolean etherealize_objects,
this->cleanup_in_progress_ = 1;
+ // Inform the custom servant dispatching strategy to stop the working
+ // threads when the poa is destroyed.
+ this->poa_deactivated_hook ();
+
// This operation destroys the POA and all descendant POAs. The POA
// so destroyed (that is, the POA with its name) may be re-created
// later in the same process. (This differs from the
@@ -2892,3 +2896,35 @@ TAO_POA_Static_Resources::TAO_POA_Static_Resources (void)
{
}
+void
+TAO_Root_POA::poa_activated_hook ()
+{
+ //no-ops
+}
+
+void
+TAO_Root_POA::poa_deactivated_hook ()
+{
+ //no-ops
+}
+
+void
+TAO_Root_POA::servant_activated_hook (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ //no-ops
+ ACE_UNUSED_ARG (servant);
+ ACE_UNUSED_ARG (oid);
+}
+
+void
+TAO_Root_POA::servant_deactivated_hook (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL)
+{
+ //no-ops
+ ACE_UNUSED_ARG (servant);
+ ACE_UNUSED_ARG (oid);
+}
+
diff --git a/TAO/tao/PortableServer/Root_POA.h b/TAO/tao/PortableServer/Root_POA.h
index 7fcd071f9f7..313bd5bb093 100644
--- a/TAO/tao/PortableServer/Root_POA.h
+++ b/TAO/tao/PortableServer/Root_POA.h
@@ -561,6 +561,25 @@ public:
ACE_ENV_SINGLE_ARG_DECL
);
+ /// These hooks are needed by the CSD strategy to override
+ /// and no-ops by default.
+
+ /// Hook - The POA has been (or is being) activated.
+ virtual void poa_activated_hook ();
+
+ /// Hook - The POA has been deactivated.
+ virtual void poa_deactivated_hook ();
+
+ /// Hook - A servant has been activated.
+ virtual void servant_activated_hook (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
+ /// Hook - A servant has been deactivated.
+ virtual void servant_deactivated_hook (PortableServer::Servant servant,
+ const PortableServer::ObjectId& oid
+ ACE_ENV_ARG_DECL);
+
protected:
#if (TAO_HAS_MINIMUM_POA == 0)
diff --git a/TAO/tao/PortableServer/ServantRetentionStrategyRetain.cpp b/TAO/tao/PortableServer/ServantRetentionStrategyRetain.cpp
index 87cf5b4defe..3e054666f24 100644
--- a/TAO/tao/PortableServer/ServantRetentionStrategyRetain.cpp
+++ b/TAO/tao/PortableServer/ServantRetentionStrategyRetain.cpp
@@ -105,6 +105,18 @@ namespace TAO
// Decrement the reference count.
CORBA::UShort new_count = --active_object_map_entry->reference_count_;
+ // Inform the custom servant dispatching (CSD) strategy that the
+ // servant is deactivated. This would be called just once when the
+ // servant is deactivated the first time.
+ if (active_object_map_entry->deactivated_ == 0)
+ {
+ this->poa_->servant_deactivated_hook (
+ active_object_map_entry->servant_,
+ active_object_map_entry->user_id_
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
if (new_count == 0)
{
this->poa_->cleanup_servant (active_object_map_entry->servant_,
@@ -557,6 +569,13 @@ namespace TAO
// Everything is finally ok
//
+ // Inform the custom servant dispatching (CSD) strategy that the
+ // sevant is activated.
+ this->poa_->servant_activated_hook (servant,
+ user_id.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
// ATTENTION: Trick locking here, see class header for details
Non_Servant_Upcall non_servant_upcall (*this->poa_);
ACE_UNUSED_ARG (non_servant_upcall);
@@ -635,6 +654,13 @@ namespace TAO
// Everything is finally ok
//
+ // Inform the custom servant dispatching (CSD) strategy that the
+ // sevant is activated.
+ this->poa_->servant_activated_hook (servant,
+ system_id.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
// ATTENTION: Trick locking here, see class header for details
Non_Servant_Upcall non_servant_upcall (*this->poa_);
ACE_UNUSED_ARG (non_servant_upcall);
@@ -758,6 +784,13 @@ namespace TAO
// Everything is finally ok
//
+ // Inform the custom servant dispatching (CSD) strategy that the
+ // sevant is activated.
+ this->poa_->servant_activated_hook (servant,
+ user_id.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
// ATTENTION: Trick locking here, see class header for details
Non_Servant_Upcall non_servant_upcall (*this->poa_);
ACE_UNUSED_ARG (non_servant_upcall);
@@ -865,6 +898,13 @@ namespace TAO
// Everything is finally ok
//
+ // Inform the custom servant dispatching (CSD) strategy that the
+ // sevant is activated.
+ this->poa_->servant_activated_hook (servant,
+ id
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
// ATTENTION: Trick locking here, see class header for details
Non_Servant_Upcall non_servant_upcall (*this->poa_);
ACE_UNUSED_ARG (non_servant_upcall);
diff --git a/TAO/tao/PortableServer/get_arg.h b/TAO/tao/PortableServer/get_arg.h
index bf7a2fc892f..498035b3ed8 100644
--- a/TAO/tao/PortableServer/get_arg.h
+++ b/TAO/tao/PortableServer/get_arg.h
@@ -79,7 +79,7 @@ namespace TAO
size_t i)
{
return
- details
+ (details != 0 && details->args () != 0)
? static_cast<typename TAO::Arg_Traits<T>::in_arg_val *> (
details->args ()[i])->arg ()
: static_cast<typename TAO::SArg_Traits<T>::in_arg_val *> (
diff --git a/TAO/tao/Service_Context.h b/TAO/tao/Service_Context.h
index 348bec7c061..b5ac3727b15 100644
--- a/TAO/tao/Service_Context.h
+++ b/TAO/tao/Service_Context.h
@@ -23,6 +23,14 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+namespace TAO
+{
+ namespace CSD
+ {
+ class FW_Server_Request_Wrapper;
+ }
+}
+
/**
* @class TAO_Service_Context
*
@@ -52,6 +60,11 @@
class TAO_Export TAO_Service_Context
{
public:
+ /// Declare FW_Server_Request_Wrapper a friend
+ /// This friendship makes the FW_Server_Request_Wrapper be able to
+ /// clone the TAO_Service_Context data member in TAO_ServerRequest.
+ friend class TAO::CSD::FW_Server_Request_Wrapper;
+
/// Constructor
TAO_Service_Context (void);
diff --git a/TAO/tao/TAO_Server_Request.h b/TAO/tao/TAO_Server_Request.h
index 288fd4a2723..29b11e2503a 100644
--- a/TAO/tao/TAO_Server_Request.h
+++ b/TAO/tao/TAO_Server_Request.h
@@ -52,6 +52,14 @@ namespace CORBA
class Exception;
}
+namespace TAO
+{
+ namespace CSD
+ {
+ class FW_Server_Request_Wrapper;
+ }
+}
+
class TAO_Operation_Details;
/**
@@ -65,6 +73,12 @@ class TAO_Operation_Details;
class TAO_Export TAO_ServerRequest
{
public:
+
+ /// Declare FW_Server_Request_Wrapper a friend
+ /// This friendship makes the FW_Server_Request_Wrapper be able to
+ /// clone the TAO_ServerRequest.
+ friend class TAO::CSD::FW_Server_Request_Wrapper;
+
/// Declare TAO_AMH_Response_Handler a friend
/**
* The TAO_AMH_Response_Handler class needs to copy part of the
@@ -319,7 +333,7 @@ private:
/// Used to pad CDR stream if we have used DSI.
ptrdiff_t dsi_nvlist_align_;
- TAO_Operation_Details const * const operation_details_;
+ TAO_Operation_Details const * operation_details_;
/**
* An argument flag to indicate whether there is any data that is
diff --git a/TAO/tao/Tagged_Profile.h b/TAO/tao/Tagged_Profile.h
index 5e9e10f8348..b7706dca0c7 100644
--- a/TAO/tao/Tagged_Profile.h
+++ b/TAO/tao/Tagged_Profile.h
@@ -24,6 +24,14 @@
#include "tao/Object_KeyC.h"
#include "ace/SString.h"
+namespace TAO
+{
+ namespace CSD
+ {
+ class FW_Server_Request_Wrapper;
+ }
+}
+
/**
* @class TAO_Tagged_Profile
*
@@ -34,6 +42,12 @@
class TAO_Export TAO_Tagged_Profile
{
public:
+
+ /// Declare FW_Server_Request_Wrapper a friend
+ /// This friendship makes the FW_Server_Request_Wrapper be able to
+ /// clone the TAO_Tagged_Profile data member in TAO_ServerRequest.
+ friend class TAO::CSD::FW_Server_Request_Wrapper;
+
/// Ctor
TAO_Tagged_Profile (TAO_ORB_Core *orb_core);
diff --git a/TAO/tao/operation_details.h b/TAO/tao/operation_details.h
index 8748d0f6147..55df7ee8328 100644
--- a/TAO/tao/operation_details.h
+++ b/TAO/tao/operation_details.h
@@ -37,6 +37,14 @@ namespace TAO
struct Exception_Data;
}
+namespace TAO
+{
+ namespace CSD
+ {
+ class FW_Server_Request_Wrapper;
+ }
+}
+
/**
* @class TAO_Operation_Details
*
@@ -53,6 +61,11 @@ class TAO_Export TAO_Operation_Details
{
public:
+ /// Declare FW_Server_Request_Wrapper a friend
+ /// This friendship makes the FW_Server_Request_Wrapper be able to
+ /// clone the TAO_Operation_Details data member in TAO_ServerRequest.
+ friend class TAO::CSD::FW_Server_Request_Wrapper;
+
/// Constructor
TAO_Operation_Details (const char *name,
CORBA::ULong len,
diff --git a/TAO/tests/CSD_Strategy_Tests/Broken/CSD_TP_Broken.mpc b/TAO/tests/CSD_Strategy_Tests/Broken/CSD_TP_Broken.mpc
new file mode 100644
index 00000000000..016caef75ef
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/Broken/CSD_TP_Broken.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_tp_test_exe_b {
+ exename=server_main
+
+ Source_Files {
+ ServerApp.cpp
+ server_main.cpp
+ }
+}
+
+project(*Client): csd_tp_test_exe_b {
+ exename=client_main
+
+ Source_Files {
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/Broken/ClientApp.cpp b/TAO/tests/CSD_Strategy_Tests/Broken/ClientApp.cpp
new file mode 100644
index 00000000000..f9d264a5ed7
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/Broken/ClientApp.cpp
@@ -0,0 +1,318 @@
+// $Id$
+#include "ClientApp.h"
+#include "AppHelper.h"
+#include "OrbRunner.h"
+#include "AppShutdown.h"
+#include "TestAppExceptionC.h"
+#include "Foo_B_ClientEngine.h"
+#include "ace/Get_Opt.h"
+
+
+ClientApp::ClientApp()
+: TestAppBase("TP_Test_3_Client"),
+ client_task_ (true), // shutdown orb after client is done.
+ num_servants_ (1),
+ num_csd_threads_ (1),
+ num_orb_threads_ (1),
+ ior_("Not Set"),
+ client_kind_(0),
+ client_id_(0)
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ if (result != 0)
+ {
+ return result;
+ }
+ ACE_CHECK_RETURN (-1);
+
+ this->poa_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->csd_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->client_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->poa_activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_clients(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_orb_event_loop(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->cleanup();
+
+ return this->check_validity () ? 0 : -1;
+}
+
+
+int
+ClientApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheAppShutdown->init(this->orb_.in(), num_servants_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ return 0;
+}
+
+
+void
+ClientApp::poa_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->poa_ = this->create_poa(this->orb_.in(),
+ "ChildPoa"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ClientApp::csd_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->tp_strategy_ = new TAO::CSD::TP_Strategy(this->num_csd_threads_);
+
+ if (!this->tp_strategy_->apply_to(this->poa_.in() ACE_ENV_ARG_PARAMETER))
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to poa.\n"));
+ ACE_THROW(TestAppException());
+ }
+ ACE_CHECK;
+}
+
+
+void
+ClientApp::client_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Turn the ior_ into a Foo_B obj ref.
+ Foo_B_var foo = RefHelper<Foo_B>::string_to_ref(this->orb_.in(),
+ this->ior_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->servants_.create_and_activate(1, // number of callback servants
+ this->poa_.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ ServantListType::T_stub_var cb = this->servants_.objref(0);
+
+ // Create the ClientEngine object, and give it the Foo_B and Callback object
+ // references.
+ ClientEngine_Handle engine
+ = new Foo_B_ClientEngine(foo.in(), cb.in (), this->client_id_);
+ this->client_task_.add_engine(engine.in());
+}
+
+
+void
+ClientApp::poa_activate(ACE_ENV_SINGLE_ARG_DECL)
+{
+ PortableServer::POAManager_var poa_manager
+ = this->poa_->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ClientApp::run_clients(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->client_task_.open() != 0)
+ {
+ ACE_THROW (TestAppException ());
+ }
+}
+
+
+void
+ClientApp::run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL)
+{
+ OrbRunner orb_runner(this->orb_.in(), this->num_orb_threads_);
+ orb_runner.run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ TheAppShutdown->wait ();
+}
+
+
+PortableServer::POA_ptr
+ClientApp::create_poa(CORBA::ORB_ptr orb, const char* poa_name ACE_ENV_ARG_DECL)
+{
+ // Get the Root POA.
+ PortableServer::POA_var root_poa
+ = RefHelper<PortableServer::POA>::resolve_initial_ref(orb,
+ "RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Get the POAManager from the Root POA.
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Create the child POA Policies.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ // Create the child POA
+ PortableServer::POA_var poa = AppHelper::create_poa(poa_name,
+ root_poa.in(),
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Give away the child POA_ptr from the POA_var variable.
+ return poa._retn();
+}
+
+
+void
+ClientApp::cleanup()
+{
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:k:n:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case 'k':
+ result = set_arg(this->client_kind_,
+ get_opts.opt_arg(),
+ c,
+ "client_kind");
+ break;
+
+ case 'n':
+ result = set_arg(this->client_id_,
+ get_opts.opt_arg(),
+ c,
+ "client_id");
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-k <client_kind>]\n"
+ "\t[-n <client_id>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ClientApp::arg_dependency_checks()
+{
+ if (this->ior_ == "Not Set")
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Missing required command-line option (-i <ior>).\n"));
+ this->usage_statement();
+ return -1;
+ }
+ if (this->client_id_ <= 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Invalid command-line option (-n <client id>). \n"
+ " The client id should be positive integer. \n"));
+ this->usage_statement();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+ClientApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+ return 0;
+}
+
+
+bool
+ClientApp::check_validity ()
+{
+ // Check whether the clients return any errors.
+ if (this->client_task_.failure_count () > 0)
+ {
+ return false;
+ }
+
+ return true;
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/Broken/ClientApp.h b/TAO/tests/CSD_Strategy_Tests/Broken/ClientApp.h
new file mode 100644
index 00000000000..846384224f5
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/Broken/ClientApp.h
@@ -0,0 +1,78 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "TestAppBase.h"
+#include "ClientEngine.h"
+#include "ServantList_T.h"
+#include "Callback_i.h"
+#include "ClientTask.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/ORB.h"
+#include "ace/SString.h"
+
+
+class ClientApp : public TestAppBase
+{
+ public:
+
+ ClientApp();
+ virtual ~ClientApp();
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void poa_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void csd_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void client_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void poa_activate(ACE_ENV_SINGLE_ARG_DECL);
+ void run_clients(ACE_ENV_SINGLE_ARG_DECL);
+ void run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL);
+ bool check_validity ();
+ void cleanup();
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+ PortableServer::POA_ptr create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL);
+
+
+ typedef ServantList<Callback_i> ServantListType;
+
+ CORBA::ORB_var orb_;
+ PortableServer::POA_var poa_;
+ TAO::CSD::TP_Strategy_Handle tp_strategy_;
+
+ ServantListType servants_;
+
+ ClientTask client_task_;
+
+ ACE_CString exe_name_;
+
+ unsigned num_servants_;
+ unsigned num_csd_threads_;
+ unsigned num_orb_threads_;
+
+ ACE_CString ior_;
+ unsigned client_kind_;
+ unsigned client_id_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/Broken/ServerApp.cpp b/TAO/tests/CSD_Strategy_Tests/Broken/ServerApp.cpp
new file mode 100644
index 00000000000..e84221c8a35
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/Broken/ServerApp.cpp
@@ -0,0 +1,417 @@
+// $Id$
+#include "ServerApp.h"
+#include "AppHelper.h"
+#include "OrbRunner.h"
+#include "AppShutdown.h"
+#include "TestAppExceptionC.h"
+#include "Foo_B_SimpleClientEngine.h"
+#include "Callback_i.h"
+#include "ace/OS.h"
+#include "ace/Get_Opt.h"
+
+
+ServerApp::ServerApp()
+ : TestAppBase("TP_Test_3_Server"),
+ ior_filename_prefix_("foo"),
+ num_servants_(1),
+ num_csd_threads_(1),
+ num_orb_threads_(1),
+ num_remote_clients_(1),
+ num_collocated_clients_(0),
+ collocated_client_kind_(0)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ if (result != 0)
+ {
+ return result;
+ }
+ ACE_CHECK_RETURN (-1);
+
+ this->poa_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->csd_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->servant_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->collocated_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->poa_activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_collocated_clients(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_orb_event_loop(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->cleanup();
+ return this->check_validity () ? 0 : -1;
+}
+
+
+int
+ServerApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ unsigned num_clients = this->num_remote_clients_ +
+ this->num_collocated_clients_;
+
+ TheAppShutdown->init(this->orb_.in(), num_clients ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ return 0;
+}
+
+
+void
+ServerApp::poa_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->poa_ = this->create_poa(this->orb_.in(),
+ "ChildPoa"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->num_collocated_clients_ > 0)
+ {
+ this->cb_poa_ = this->create_poa(this->orb_.in(),
+ "CallbackPoa"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+void
+ServerApp::csd_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->tp_strategy_ = new TAO::CSD::TP_Strategy(this->num_csd_threads_);
+
+// We don't apply the strategy for this test to show that the bug isn't
+// part of the CSD ThreadPool Strategy code.
+#if 0
+ if (!this->tp_strategy_->apply_to(this->poa_.in() ACE_ENV_ARG_PARAMETER))
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to poa.\n"));
+ ACE_THROW(TestAppException());
+ }
+ ACE_CHECK;
+#endif
+
+ // Use another poa and strategy for callbacks. This would resolve
+ // the deadlock situation that happens when having number of csd
+ // threads less than number of collocated clients.
+ if (this->num_collocated_clients_ > 0)
+ {
+ this->cb_tp_strategy_ = new TAO::CSD::TP_Strategy();
+// We don't apply the strategy for this test to show that the bug isn't
+// part of the CSD ThreadPool Strategy code.
+#if 0
+ if (!this->cb_tp_strategy_->apply_to(this->cb_poa_.in() ACE_ENV_ARG_PARAMETER))
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to callback poa.\n"));
+ ACE_THROW(TestAppException());
+ }
+ ACE_CHECK;
+#endif
+ }
+}
+
+
+void
+ServerApp::servant_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->foo_servants_.create_and_activate(this->num_servants_,
+ this->orb_.in (),
+ this->poa_.in (),
+ this->ior_filename_prefix_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::collocated_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->num_collocated_clients_ == 0)
+ return;
+
+ this->cb_servants_.create_and_activate(1, // number of callback servants
+ this->cb_poa_.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CallbackServantListType::T_stub_var cb = this->cb_servants_.objref(0);
+
+ unsigned client_id = this->num_remote_clients_;
+
+ for (unsigned i = 0; i < this->num_collocated_clients_; i++)
+ {
+ client_id ++;
+ // Dole out the servant object references in a round-robin fashion.
+ unsigned servant_index = i % this->num_servants_;
+
+ FooServantListType::T_stub_var foo
+ = this->foo_servants_.objref(servant_index);
+ ClientEngine_Handle engine
+ = new Foo_B_SimpleClientEngine(foo.in(), cb.in (), client_id, true);
+ this->collocated_client_task_.add_engine(engine.in());
+ }
+}
+
+
+void
+ServerApp::poa_activate(ACE_ENV_SINGLE_ARG_DECL)
+{
+ PortableServer::POAManager_var poa_manager
+ = this->poa_->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->num_collocated_clients_ > 0)
+ {
+ if (this->collocated_client_task_.open() == -1)
+ {
+ ACE_THROW (TestAppException ());
+ }
+ }
+}
+
+
+void
+ServerApp::run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL)
+{
+ OrbRunner orb_runner(this->orb_.in(), this->num_orb_threads_);
+ orb_runner.run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ TheAppShutdown->wait ();
+}
+
+
+void
+ServerApp::cleanup()
+{
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "p:s:n:t:r:c:k:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'p':
+ this->ior_filename_prefix_ = get_opts.opt_arg();
+ break;
+
+ case 's':
+ result = set_arg(this->num_servants_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 'n':
+ result = set_arg(this->num_csd_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 't':
+ result = set_arg(this->num_orb_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_orb_threads",
+ 1);
+ break;
+
+ case 'r':
+ result = set_arg(this->num_remote_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_remote_clients");
+ break;
+
+ case 'c':
+ result = set_arg(this->num_collocated_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_collocated_clients");
+ break;
+
+ case 'k':
+ result = set_arg(this->collocated_client_kind_,
+ get_opts.opt_arg(),
+ c,
+ "collocated_client_kind");
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-p <ior_filename_prefix>]\n"
+ "\t[-s <num_servants>]\n"
+ "\t[-n <num_csd_threads>]\n"
+ "\t[-t <num_orb_threads>]\n"
+ "\t[-r <num_remote_clients>]\n"
+ "\t[-c <num_collocated_clients>]\n"
+ "\t[-k <collocated_client_kind>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ServerApp::arg_dependency_checks()
+{
+ return (this->num_remote_clients_
+ + this->num_collocated_clients_) > 0 ? 0 : -1;
+}
+
+
+int
+ServerApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+ return 0;
+}
+
+
+PortableServer::POA_ptr
+ServerApp::create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL)
+{
+ // Get the Root POA.
+ PortableServer::POA_var root_poa
+ = RefHelper<PortableServer::POA>::resolve_initial_ref(orb,
+ "RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Get the POAManager from the Root POA.
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Create the child POA Policies.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ // Create the child POA
+ PortableServer::POA_var poa = AppHelper::create_poa(poa_name,
+ root_poa.in(),
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Give away the child POA_ptr from the POA_var variable.
+ return poa._retn();
+}
+
+
+bool
+ServerApp::check_validity ()
+{
+ return true;
+#if 0
+ // Check whether the clients return any errors.
+ if (this->num_collocated_clients_ > 0
+ && this->collocated_client_task_.failure_count () > 0)
+ {
+ return false;
+ }
+
+ Foo_B_Statistics stats (this->num_remote_clients_,
+ this->num_collocated_clients_);
+
+ Foo_B_SimpleClientEngine::expected_results (stats);
+
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ this->foo_servants_.servant(i)->gather_stats (stats);
+ }
+
+ if (this->num_collocated_clients_ > 0)
+ {
+ this->cb_servants_.servant (0)->gather_stats (stats);
+ }
+
+ return stats.actual_vs_expected ();
+#endif
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/Broken/ServerApp.h b/TAO/tests/CSD_Strategy_Tests/Broken/ServerApp.h
new file mode 100644
index 00000000000..c90b7671534
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/Broken/ServerApp.h
@@ -0,0 +1,85 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "TestAppBase.h"
+#include "ServantList_T.h"
+#include "ClientTask.h"
+#include "Foo_B_i.h"
+#include "Callback_i.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "ace/SString.h"
+
+
+class ServerApp : public TestAppBase
+{
+ public:
+
+ ServerApp();
+ virtual ~ServerApp();
+
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void poa_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void csd_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void servant_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void collocated_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void poa_activate(ACE_ENV_SINGLE_ARG_DECL);
+ void run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL);
+ void run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL);
+ bool check_validity ();
+ void cleanup();
+
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+
+ PortableServer::POA_ptr create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL);
+
+ typedef ServantList<Foo_B_i> FooServantListType;
+ typedef ServantList<Callback_i> CallbackServantListType;
+
+ CORBA::ORB_var orb_;
+ PortableServer::POA_var poa_;
+ TAO::CSD::TP_Strategy_Handle tp_strategy_;
+
+ PortableServer::POA_var cb_poa_;
+ TAO::CSD::TP_Strategy_Handle cb_tp_strategy_;
+
+ FooServantListType foo_servants_;
+ CallbackServantListType cb_servants_;
+
+ ClientTask collocated_client_task_;
+
+ ACE_CString exe_name_;
+
+ ACE_CString ior_filename_prefix_;
+ unsigned num_servants_;
+ unsigned num_csd_threads_;
+ unsigned num_orb_threads_;
+ unsigned num_remote_clients_;
+ unsigned num_collocated_clients_;
+ unsigned collocated_client_kind_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/Broken/client_main.cpp b/TAO/tests/CSD_Strategy_Tests/Broken/client_main.cpp
new file mode 100644
index 00000000000..3814bef5ff9
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/Broken/client_main.cpp
@@ -0,0 +1,7 @@
+// $Id$
+#include "ClientApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ClientApp)
+
+
diff --git a/TAO/tests/CSD_Strategy_Tests/Broken/run_test.pl b/TAO/tests/CSD_Strategy_Tests/Broken/run_test.pl
new file mode 100755
index 00000000000..3000ac7a43c
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/Broken/run_test.pl
@@ -0,0 +1,172 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+my $status = 0;
+
+my $iorfname_prefix = "servant";
+my $num_servants = 1;
+my $num_orb_threads = 1;
+my $num_remote_clients = 1;
+my $num_csd_threads = 1;
+my $num_collocated_clients = 0;
+my $collocated_client_kind = 0;
+my $client_kind = 0;
+
+my $i;
+my $j;
+my @iorfile;
+
+my $ARGC = @ARGV;
+
+if ($ARGC > 0)
+{
+ if ($ARGC > 1)
+ {
+ print STDERR "ERROR: Too many command-line arguments for $0.\n";
+ exit 1;
+ }
+
+ my $subtest = $ARGV[0];
+
+ if ($subtest eq 'remote')
+ {
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'collocated')
+ {
+ $num_remote_clients = 0;
+ $num_collocated_clients = 1;
+ $num_csd_threads=1;
+ }
+ elsif ($subtest eq 'remote_orbthreads')
+ {
+ $num_orb_threads = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_servants')
+ {
+ $num_servants = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_csdthreads')
+ {
+ $num_csd_threads = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ $num_collocated_clients = 40;
+ }
+ elsif ($subtest eq 'usage')
+ {
+ print STDOUT "Usage: $0 [<subtest>]\n" .
+ "\n" .
+ "Supported <subtest> values:\n" .
+ "\n" .
+ "\tremote\n" .
+ "\tcollocated\n" .
+ "\tremote_orbthreads\n" .
+ "\tremote_servants\n" .
+ "\tremote_csdthreads\n" .
+ "\tremote_big\n" .
+ "\tusage\n" .
+ "\n";
+ exit 0;
+ }
+ else
+ {
+ print STDERR "ERROR: invalid subtest argument for $0: $subtest\n";
+ exit 1;
+ }
+}
+
+#Delete old ior files.
+for ($i = 0; $i < $num_servants; $i++) {
+ my $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+ unlink $iorfile[$i];
+}
+
+$SV = new PerlACE::Process("server_main",
+# "-ORBNegotiateCodesets 0 " .
+ "-p $iorfname_prefix " .
+ "-s $num_servants " .
+ "-n $num_csd_threads " .
+ "-t $num_orb_threads " .
+ "-r $num_remote_clients " .
+ "-c $num_collocated_clients " .
+ "-k $collocated_client_kind");
+
+
+$SV->Spawn();
+
+# Wait for the servant ior files created by server.
+for ($i = 0; $i < $num_servants; $i++) {
+ if (PerlACE::waitforfile_timed
+ ($iorfile[$i],
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile[$i]>\n";
+ $SV->Kill();
+ $SV->TimedWait(1);
+ exit 1;
+ }
+}
+
+my $count = 0;
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+ $client_id = $i + 1;
+
+ $j = $i % $num_servants;
+
+ $CLS[$i] = new PerlACE::Process("client_main",
+ "-i file://$iorfile[$j] ".
+ "-k $client_kind ".
+ "-n $client_id");
+ $CLS[$i]->Spawn();
+}
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+ $client = $CLS[$i]->WaitKill(60);
+
+ if ($client != 0)
+ {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill(60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+#Delete ior files generated by this run.
+for ($i = 0; $i < $num_servants; $i++) {
+ unlink $iorfile[$i];
+}
+
+exit $status;
diff --git a/TAO/tests/CSD_Strategy_Tests/Broken/server_main.cpp b/TAO/tests/CSD_Strategy_Tests/Broken/server_main.cpp
new file mode 100644
index 00000000000..82e987f6d41
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/Broken/server_main.cpp
@@ -0,0 +1,5 @@
+// $Id$
+#include "ServerApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ServerApp)
diff --git a/TAO/tests/CSD_Strategy_Tests/README b/TAO/tests/CSD_Strategy_Tests/README
new file mode 100644
index 00000000000..4ab0940d42b
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/README
@@ -0,0 +1,117 @@
+This directory contains tests for the Custom Servant Dispatching (CSD)
+feature implemented within TAO. Specifically, these tests use the reference
+implementation CSD Strategy, called the Thread Pool (TP) CSD Strategy.
+
+Each sub-directory should contain its own README file which describes the
+contents of the particular sub-directory in more detail. The following
+is a list of sub-directories located here under the
+$TAO_ROOT/tests/CSD_Strategy_Tests directory:
+
+TP_Test_Lib
+-----------
+
+ This sub-directory contains source code used to build the
+ "CSD_TP_Test" library (ie, libCSD_TP_Test.so). This library contains
+ infrastructure code used by all of the CSD test applications. The
+ purpose of this library is code re-use and ease of maintenance (ie,
+ change/fix something in this library, and all applications using it
+ will gain the benefit.)
+
+
+TP_Foo_A
+--------
+
+ This sub-directory contains source code used to build the
+ "CSD_TP_Foo_A" library (ie, libCSD_TP_Foo_A.so). This library contains
+ one IDL file which declares the "Foo_A" interface. All of the other
+ source code in this library is used to support client and/or server
+ applications that will use the Foo_A interface.
+
+
+TP_Foo_B
+--------
+
+ This sub-directory contains source code used to build the
+ "CSD_TP_Foo_B" library (ie, libCSD_TP_Foo_B.so). This library contains
+ one IDL file which declares the "Foo_B" interface. All of the other
+ source code in this library is used to support client and/or server
+ applications that will use the Foo_B interface.
+
+
+TP_Foo_C
+--------
+
+ This sub-directory contains source code used to build the
+ "CSD_TP_Foo_C" library (ie, libCSD_TP_Foo_C.so). This library contains
+ one IDL file which declares the "Foo_C" interface. All of the other
+ source code in this library is used to support client and/or server
+ applications that will use the Foo_C interface.
+
+
+TP_Test_1
+---------
+
+ This sub-directory contains source code that is used to build a
+ client application and a server application. These applications
+ make use of the Foo_A interface (see the TP_Foo_A directory).
+ This particular pair of applications do not use all of the infrastructure
+ types made available to them by the TP_Test_Lib.
+
+ The TP_Test_1 application code is really more of an example than a test.
+ Other test applications (ie, TP_Test_2) do the same thing as TP_Test_1,
+ except that the other test applications take advantage of the
+ infrastructure types provided by the TP_Test_Lib. Another big difference
+ is that the TP_Test_1 does not perform any "actual" vs. "expected"
+ results checking - and the other TP tests do perform these checks.
+
+
+TP_Test_2
+---------
+
+ This sub-directory contains source code that is used to build a
+ client application and a server application. These applications
+ make use of the Foo_A interface (see the TP_Foo_A directory).
+
+ The Foo_A interface is a simple interface with just a few simple
+ operations (both one-way and two-way).
+
+ Each launched client application (ie, client process) represents a
+ "remote" client of a Foo_A servant object that lives in a server
+ process. The server application can be instructed, upon start up,
+ to use any number of "collocated clients". Each collocated client is
+ essentially a new thread in the server process that will perform the
+ same logic that is performed by the remote client application.
+
+
+TP_Test_3
+---------
+
+ This sub-directory contains source code that is used to build a
+ client application and a server application. These applications
+ make use of the Foo_B interface (see the TP_Foo_B directory).
+
+ The Foo_B interface has a rich set of operations, using a wide variety
+ of argument types.
+
+ The TP_Test_3 applications are nearly identical to their TP_Test_2
+ counterparts, except for the fact that Foo_B is the interface type
+ used in TP_Test_3, and Foo_A is the interface type used in TP_Test_2.
+
+
+TP_Test_4
+---------
+
+ This sub-directory contains source code that is used to build a
+ client application and a server application. These applications
+ make use of the Foo_C interface (see the TP_Foo_C directory).
+
+ The Foo_C interface is a simple interface with just a few simple
+ operations (both one-way and two-way). It is nearly (if not exactly)
+ identical to the Foo_A interface.
+
+ The TP_Test_4 applications are nearly identical to the TP_Test_2
+ applications with one significant difference: the TP_Test_4 server
+ application makes use of the "custom requests" feature provided by
+ the CSD Thread Pool Strategy. These custom requests are performed
+ by the collocated client code within the server application.
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/AppHelper.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/AppHelper.cpp
new file mode 100644
index 00000000000..db2d1ec202e
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/AppHelper.cpp
@@ -0,0 +1,102 @@
+// $Id$
+#include "AppHelper.h"
+
+void
+AppHelper::ref_to_file(CORBA::ORB_ptr orb,
+ CORBA::Object_ptr obj,
+ const char* filename
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::String_var ior = orb->object_to_string(obj);
+
+ FILE* ior_file = ACE_OS::fopen(filename, (const ACE_TCHAR *)("w"));
+
+ if (ior_file == 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Cannot open output file [%s] to write IOR.",
+ filename));
+ ACE_THROW (TestAppException());
+ }
+
+ ACE_OS::fprintf(ior_file, "%s", ior.in());
+ ACE_OS::fclose(ior_file);
+}
+
+
+PortableServer::POA_ptr
+AppHelper::create_poa(const char* name,
+ PortableServer::POA_ptr root_poa,
+ PortableServer::POAManager_ptr mgr,
+ CORBA::PolicyList& policies
+ ACE_ENV_ARG_DECL)
+{
+ PortableServer::POA_var child_poa = root_poa->create_POA(name,
+ mgr,
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ if (CORBA::is_nil(child_poa.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to create child POA: %s.\n", name));
+ ACE_THROW_RETURN (TestAppException(), PortableServer::POA::_nil ());
+ }
+
+ return child_poa._retn();
+}
+
+
+CORBA::Object_ptr
+AppHelper::activate_servant(PortableServer::POA_ptr poa,
+ PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ // Activate the servant using the Child POA.
+ PortableServer::ObjectId_var oid
+ = poa->activate_object(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ CORBA::Object_var obj
+ = poa->servant_to_reference(servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to convert servant_to_ref.\n"));
+ ACE_THROW_RETURN (TestAppException(), CORBA::Object::_nil ());
+ }
+
+ return obj._retn();
+}
+
+
+bool
+AppHelper::validate_connection (CORBA::Object_ptr obj)
+{
+ for (CORBA::ULong j = 0; j != 100; ++j)
+ {
+ ACE_TRY_NEW_ENV
+ {
+#if (TAO_HAS_CORBA_MESSAGING == 1)
+ CORBA::PolicyList_var unused;
+ obj->_validate_connection (unused
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#else
+ obj->_is_a ("Not_An_IDL_Type"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#endif /* TAO_HAS_MESSAGING == 1 */
+ return true;
+ }
+ ACE_CATCHANY
+ {
+ }
+ ACE_ENDTRY;
+ }
+
+ return false;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/AppHelper.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/AppHelper.h
new file mode 100644
index 00000000000..06a6ac721a2
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/AppHelper.h
@@ -0,0 +1,114 @@
+// $Id$
+#ifndef APPHELPER_H
+#define APPHELPER_H
+
+#include "CSD_TP_Test_Export.h"
+#include "TestAppExceptionC.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/ORB.h"
+#include "ace/OS.h"
+#include "ace/Log_Msg.h"
+
+
+template <typename T>
+struct RefHelper
+{
+ typedef typename T::_ptr_type T_ptr;
+ typedef typename T::_var_type T_var;
+
+ static T_ptr string_to_ref(CORBA::ORB_ptr orb,
+ const char* ior
+ ACE_ENV_ARG_DECL)
+ {
+ CORBA::Object_var obj = orb->string_to_object(ior ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN(T::_nil ());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to convert IOR string to obj ref.\n"));
+ ACE_THROW_RETURN (TestAppException(), T::_nil ());
+ }
+
+ T_var t_obj = T::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN(T::_nil ());
+
+ if (CORBA::is_nil(t_obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow obj ref to T interface.\n"));
+ ACE_THROW_RETURN (TestAppException(), T::_nil ());
+ }
+
+ return t_obj._retn();
+ }
+
+ static T_ptr resolve_initial_ref(CORBA::ORB_ptr orb,
+ const char* name
+ ACE_ENV_ARG_DECL)
+ {
+ CORBA::Object_var obj
+ = orb->resolve_initial_references(name ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (T::_nil ());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to resolve initial ref for '%s'.\n",
+ name));
+ ACE_THROW_RETURN (TestAppException(), T::_nil ());
+ }
+
+ T_var t_obj = T::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (T::_nil ());
+
+
+ if (CORBA::is_nil(t_obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to narrow resolved initial ref '%s'.\n",
+ name));
+ ACE_THROW_RETURN (TestAppException(), T::_nil ());
+ }
+
+ return t_obj._retn();
+ }
+
+};
+
+struct CSD_TP_Test_Export AppHelper
+{
+
+ static void ref_to_file(CORBA::ORB_ptr orb,
+ CORBA::Object_ptr obj,
+ const char* filename
+ ACE_ENV_ARG_DECL);
+
+ static PortableServer::POA_ptr create_poa
+ (const char* name,
+ PortableServer::POA_ptr root_poa,
+ PortableServer::POAManager_ptr mgr,
+ CORBA::PolicyList& policies
+ ACE_ENV_ARG_DECL);
+
+ static CORBA::Object_ptr activate_servant(PortableServer::POA_ptr poa,
+ PortableServer::Servant servant
+ ACE_ENV_ARG_DECL);
+
+ // This helper method is used because there is a chance that the
+ // initial CORBA request made to the target ORB will fail during
+ // connection establishment with a TRANSIENT CORBA SystemException.
+ // This occurs for some platforms (ie, windows) when several clients
+ // make their initial CORBA request to the same ORB at the same time,
+ // causing the ORB to attempt to handle several connection establishments
+ // at one time. Apparently, under certain conditions, it will throw the
+ // TRANSIENT exception to tell the client application to "try again later".
+ // The analogy is making a phone call. Sometimes you get a busy tone.
+ // This means "try again later".
+ // This helper function will retry until the connection establishment
+ // works - or until it decides that enough is enough.
+ static bool validate_connection (CORBA::Object_ptr obj);
+};
+
+#endif
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/AppShutdown.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/AppShutdown.cpp
new file mode 100644
index 00000000000..53dec90290a
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/AppShutdown.cpp
@@ -0,0 +1,85 @@
+// $Id$
+#include "AppShutdown.h"
+#include "TestAppExceptionC.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_unistd.h"
+
+
+AppShutdown::AppShutdown()
+ : num_clients_(0),
+ num_clients_shutdown_(0)
+{
+}
+
+
+AppShutdown::~AppShutdown()
+{
+}
+
+
+void
+AppShutdown::init(CORBA::ORB_ptr orb,
+ unsigned num_clients
+ ACE_ENV_ARG_DECL)
+{
+ if ((!CORBA::is_nil(this->orb_.in())) ||
+ (CORBA::is_nil(orb)) ||
+ (num_clients == 0))
+ {
+ // Already init()'ed, or bad argument values.
+ ACE_THROW(TestAppException());
+ }
+ else
+ {
+ this->orb_ = CORBA::ORB::_duplicate(orb);
+ this->num_clients_ = num_clients;
+ this->num_clients_shutdown_ = 0;
+ }
+}
+
+
+void
+AppShutdown::wait ()
+{
+ this->orb_shutdown_task_.wait();
+}
+
+
+void
+AppShutdown::client_done()
+{
+ if ((this->num_clients_ == 0) || (CORBA::is_nil(this->orb_.in())))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) AppShutdown was never initialized.\n"));
+ return;
+ }
+
+ unsigned cur_shutdown;
+
+ {
+ GuardType guard(this->lock_);
+ cur_shutdown = ++this->num_clients_shutdown_;
+ }
+
+ if (cur_shutdown == this->num_clients_)
+ {
+ // Sleep for one second before shutting down the ORB. This
+ // is a poor-man version of "wait until the CSD request queue drains".
+ ACE_OS::sleep(1);
+ this->orb_shutdown_task_.orb(this->orb_.in());
+ if (this->orb_shutdown_task_.open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t) AppShutdown failed to create orb "\
+ "shutdown thread.\n"));
+ return;
+ }
+ }
+}
+
+
+AppShutdown*
+AppShutdown::instance ()
+{
+ static AppShutdown app_shutdown;
+ return &app_shutdown;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/AppShutdown.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/AppShutdown.h
new file mode 100644
index 00000000000..d79c2aababf
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/AppShutdown.h
@@ -0,0 +1,42 @@
+// $Id$
+#ifndef APP_SHUTDOWN_H
+#define APP_SHUTDOWN_H
+
+#include "CSD_TP_Test_Export.h"
+#include "OrbShutdownTask.h"
+#include "tao/ORB.h"
+
+class CSD_TP_Test_Export AppShutdown
+{
+ public:
+
+ AppShutdown();
+ virtual ~AppShutdown();
+
+ void init(CORBA::ORB_ptr orb,
+ unsigned num_clients
+ ACE_ENV_ARG_DECL);
+
+ void wait ();
+
+ void client_done();
+
+ static AppShutdown* instance ();
+
+ private:
+
+ typedef ACE_SYNCH_MUTEX LockType;
+ typedef ACE_Guard<LockType> GuardType;
+
+ LockType lock_;
+ CORBA::ORB_var orb_;
+ unsigned num_clients_;
+ unsigned num_clients_shutdown_;
+
+ OrbShutdownTask orb_shutdown_task_;
+};
+
+
+#define TheAppShutdown AppShutdown::instance()
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Export.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Export.h
new file mode 100644
index 00000000000..9ebd7dc8f34
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s CSD_TP_Test
+// ------------------------------
+#ifndef CSD_TP_TEST_EXPORT_H
+#define CSD_TP_TEST_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (CSD_TP_TEST_HAS_DLL)
+# define CSD_TP_TEST_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && CSD_TP_TEST_HAS_DLL */
+
+#if !defined (CSD_TP_TEST_HAS_DLL)
+# define CSD_TP_TEST_HAS_DLL 1
+#endif /* ! CSD_TP_TEST_HAS_DLL */
+
+#if defined (CSD_TP_TEST_HAS_DLL) && (CSD_TP_TEST_HAS_DLL == 1)
+# if defined (CSD_TP_TEST_BUILD_DLL)
+# define CSD_TP_Test_Export ACE_Proper_Export_Flag
+# define CSD_TP_TEST_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define CSD_TP_TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* CSD_TP_TEST_BUILD_DLL */
+# define CSD_TP_Test_Export ACE_Proper_Import_Flag
+# define CSD_TP_TEST_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define CSD_TP_TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* CSD_TP_TEST_BUILD_DLL */
+#else /* CSD_TP_TEST_HAS_DLL == 1 */
+# define CSD_TP_Test_Export
+# define CSD_TP_TEST_SINGLETON_DECLARATION(T)
+# define CSD_TP_TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* CSD_TP_TEST_HAS_DLL == 1 */
+
+// Set CSD_TP_TEST_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (CSD_TP_TEST_NTRACE)
+# if (ACE_NTRACE == 1)
+# define CSD_TP_TEST_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define CSD_TP_TEST_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !CSD_TP_TEST_NTRACE */
+
+#if (CSD_TP_TEST_NTRACE == 1)
+# define CSD_TP_TEST_TRACE(X)
+#else /* (CSD_TP_TEST_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define CSD_TP_TEST_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (CSD_TP_TEST_NTRACE == 1) */
+
+#endif /* CSD_TP_TEST_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Lib.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Lib.mpc
new file mode 100644
index 00000000000..c7f6e20a3f5
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/CSD_TP_Test_Lib.mpc
@@ -0,0 +1,39 @@
+//$Id$
+project : taolib_with_idl, csd_threadpool {
+ sharedname = CSD_TP_Test
+ dynamicflags = CSD_TP_TEST_BUILD_DLL
+ idlflags += -Wb,export_macro=CSD_TP_Test_Export -Wb,export_include=CSD_TP_Test_Export.h
+ includes += $(TAO_ROOT)/tao
+
+ IDL_Files {
+ FooException.idl
+ TestAppException.idl
+ CancelledException.idl
+ CustomException.idl
+ }
+
+ Source_Files {
+ AppHelper.cpp
+ AppShutdown.cpp
+ ClientEngine.cpp
+ ClientTask.cpp
+ OrbRunner.cpp
+ OrbTask.cpp
+ TestAppBase.cpp
+ StatisticsHelper.cpp
+ OrbShutdownTask.cpp
+ FooExceptionC.cpp
+ FooExceptionS.cpp
+ TestAppExceptionC.cpp
+ TestAppExceptionS.cpp
+ CancelledExceptionC.cpp
+ CancelledExceptionS.cpp
+ CustomExceptionC.cpp
+ CustomExceptionS.cpp
+ }
+
+ Template_Files {
+ ServantList_T.cpp
+ }
+
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/CancelledException.idl b/TAO/tests/CSD_Strategy_Tests/TP_Common/CancelledException.idl
new file mode 100644
index 00000000000..8f9afcf68de
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/CancelledException.idl
@@ -0,0 +1,7 @@
+// $Id$
+#ifndef CANCELAPPXCEPTION_IDL
+#define CANCELAPPXCEPTION_IDL
+
+exception CancelledException {};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientEngine.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientEngine.cpp
new file mode 100644
index 00000000000..361bb3cd465
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientEngine.cpp
@@ -0,0 +1,12 @@
+// $Id$
+#include "ClientEngine.h"
+
+
+ClientEngine::ClientEngine()
+{
+}
+
+
+ClientEngine::~ClientEngine()
+{
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientEngine.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientEngine.h
new file mode 100644
index 00000000000..3fdd3efd233
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientEngine.h
@@ -0,0 +1,38 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ClientEngine.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef CLIENT_ENGINE_H
+#define CLIENT_ENGINE_H
+
+#include "CSD_TP_Test_Export.h"
+#include "tao/Intrusive_Ref_Count_Base_T.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+#include "tao/Environment.h"
+#include "ace/Synch.h"
+#include "ace/CORBA_macros.h"
+
+
+class ClientEngine;
+typedef TAO_Intrusive_Ref_Count_Handle<ClientEngine> ClientEngine_Handle;
+
+
+class CSD_TP_Test_Export ClientEngine : public TAO_Intrusive_Ref_Count_Base<ACE_SYNCH_MUTEX>
+{
+ public:
+
+ ClientEngine();
+ virtual ~ClientEngine();
+
+ virtual bool execute(ACE_ENV_SINGLE_ARG_DECL) = 0;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientTask.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientTask.cpp
new file mode 100644
index 00000000000..5ac8d25f408
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientTask.cpp
@@ -0,0 +1,116 @@
+// $Id$
+#include "ClientTask.h"
+#include "ClientEngine.h"
+#include "AppShutdown.h"
+#include "ace/SString.h"
+
+
+ClientTask::ClientTask(bool shutdown_after_done)
+: shutdown_after_done_(shutdown_after_done),
+ failure_count_(0)
+{
+}
+
+
+ClientTask::~ClientTask()
+{
+}
+
+
+void
+ClientTask::add_engine(ClientEngine* engine)
+{
+ // Pass in false so that _add_ref() is called.
+ ClientEngine_Handle engine_handle(engine,false);
+ this->engines_.push_back(engine_handle);
+}
+
+
+int
+ClientTask::open(void*)
+{
+ unsigned num_threads = this->engines_.size();
+
+ if (num_threads == 0)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) ClientTask cannot activate 0 threads.\n"),
+ -1);
+ }
+
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, num_threads) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) ClientTask failed to activate "
+ "the %d client threads.\n", num_threads),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+ClientTask::svc()
+{
+ ClientEngine_Handle engine;
+
+ {
+ GuardType guard(this->lock_);
+ this->engines_.get(engine, this->engines_.size() - 1);
+ this->engines_.pop_back();
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ bool exec_ret = engine->execute(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (exec_ret == false)
+ {
+ GuardType guard(this->lock_);
+ this->failure_count_ ++;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "ClientTask::svc Caught exception from execute():");
+
+ GuardType guard(this->lock_);
+ this->failure_count_ ++;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) ClientTask::svc caught unknown (...) exception "\
+ "in execute() " ));
+ GuardType guard(this->lock_);
+ this->failure_count_ ++;
+ }
+ ACE_ENDTRY;
+
+ if(this->shutdown_after_done_)
+ {
+ // This is used to shutdown orb for a client application
+ // with an orb running.
+ TheAppShutdown->client_done ();
+ }
+
+ return 0;
+}
+
+
+int
+ClientTask::close(u_long)
+{
+ return 0;
+}
+
+
+unsigned
+ClientTask::failure_count () const
+{
+ return this->failure_count_;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientTask.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientTask.h
new file mode 100644
index 00000000000..cc3de7ec8a2
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/ClientTask.h
@@ -0,0 +1,51 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ClientTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef CLIENT_TASK_H
+#define CLIENT_TASK_H
+
+#include "CSD_TP_Test_Export.h"
+#include "ClientEngine.h"
+#include "ace/Task.h"
+#include "ace/Vector_T.h"
+#include "ace/Synch.h"
+
+
+class CSD_TP_Test_Export ClientTask : public ACE_Task_Base
+{
+ public:
+
+ ClientTask(bool shutdown_after_done = false);
+ virtual ~ClientTask();
+
+ void add_engine(ClientEngine* engine);
+
+ virtual int open(void* arg = 0);
+ virtual int svc();
+ virtual int close(u_long);
+
+ unsigned failure_count () const;
+
+ private:
+
+ typedef ACE_SYNCH_MUTEX LockType;
+ typedef ACE_Guard<LockType> GuardType;
+
+ typedef ACE_Vector<ClientEngine_Handle> EngineVector;
+
+ LockType lock_;
+ EngineVector engines_;
+ bool shutdown_after_done_;
+ unsigned failure_count_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/CustomException.idl b/TAO/tests/CSD_Strategy_Tests/TP_Common/CustomException.idl
new file mode 100644
index 00000000000..794900c41ce
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/CustomException.idl
@@ -0,0 +1,7 @@
+// $Id$
+#ifndef CUSTOMEXCEPTION_IDL
+#define CUSTOMEXCEPTION_IDL
+
+exception CustomException {};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/FooException.idl b/TAO/tests/CSD_Strategy_Tests/TP_Common/FooException.idl
new file mode 100644
index 00000000000..4f76953e24c
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/FooException.idl
@@ -0,0 +1,7 @@
+// $Id$
+#ifndef FOOEXCEPTION_IDL
+#define FOOEXCEPTION_IDL
+
+exception FooException {};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbRunner.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbRunner.cpp
new file mode 100644
index 00000000000..0cc9c9bd5ad
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbRunner.cpp
@@ -0,0 +1,58 @@
+// $Id$
+#include "OrbRunner.h"
+#include "OrbTask.h"
+#include "TestAppExceptionC.h"
+
+
+OrbRunner::OrbRunner(CORBA::ORB_ptr orb, unsigned num_orb_threads)
+ : orb_(CORBA::ORB::_duplicate(orb)),
+ num_orb_threads_(num_orb_threads)
+{
+}
+
+
+OrbRunner::~OrbRunner()
+{
+}
+
+
+void
+OrbRunner::run(ACE_ENV_SINGLE_ARG_DECL)
+{
+ ACE_ASSERT(this->num_orb_threads_ > 0);
+
+ // If the num_orb_threads_ is exactly one, then just use the current
+ // (mainline) thread to run the ORB event loop.
+ if (this->num_orb_threads_ == 1)
+ {
+ // Since the num_orb_threads_ is exactly one, we just use the current
+ // (mainline) thread to run the ORB event loop.
+ this->orb_->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ else
+ {
+ // The num_orb_threads_ is greater than 1, so we will use an OrbTask
+ // (active object) to run the ORB event loop in (num_orb_threads_ - 1)
+ // threads. We use the current (mainline) thread as the other thread
+ // running the ORB event loop.
+ OrbTask orb_task(this->orb_.in(), this->num_orb_threads_ - 1);
+
+ // Activate the OrbTask worker threads
+ if (orb_task.open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to open the OrbTask.\n"));
+ ACE_THROW(TestAppException());
+ }
+
+ // This will use the current (mainline) thread to run the ORB event loop.
+ this->orb_->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Now that the current thread has unblocked from running the orb,
+ // make sure to wait for all of the worker threads to complete.
+ orb_task.wait();
+ }
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbRunner.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbRunner.h
new file mode 100644
index 00000000000..71c7c4e358c
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbRunner.h
@@ -0,0 +1,24 @@
+// $Id$
+#ifndef ORB_RUNNER_H
+#define ORB_RUNNER_H
+
+#include "CSD_TP_Test_Export.h"
+#include "tao/ORB.h"
+
+class CSD_TP_Test_Export OrbRunner
+{
+ public:
+
+ OrbRunner(CORBA::ORB_ptr orb, unsigned num_orb_threads = 1);
+ virtual ~OrbRunner();
+
+ void run(ACE_ENV_SINGLE_ARG_DECL);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+ unsigned num_orb_threads_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.cpp
new file mode 100644
index 00000000000..79ba1ba3f5e
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.cpp
@@ -0,0 +1,75 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbShutdownTask.h"
+#include "ace/CORBA_macros.h"
+#include "ace/OS_NS_unistd.h"
+
+
+OrbShutdownTask::OrbShutdownTask()
+{
+}
+
+
+OrbShutdownTask::~OrbShutdownTask()
+{
+}
+
+
+void
+OrbShutdownTask::orb(CORBA::ORB_ptr orb)
+{
+ this->orb_ = CORBA::ORB::_duplicate(orb);
+}
+
+
+int
+OrbShutdownTask::open(void*)
+{
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, 1) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbShutdownTask failed to open().\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::svc()
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->shutdown(0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::shutdown() call "
+ "in OrbShutdownTask::svc().\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbShutdownTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.h
new file mode 100644
index 00000000000..221251a7d3f
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbShutdownTask.h
@@ -0,0 +1,40 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbShutdownTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_SHUTDOWN_TASK_H
+#define ORB_SHUTDOWN_TASK_H
+
+#include "CSD_TP_Test_Export.h"
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+
+class CSD_TP_Test_Export OrbShutdownTask : public ACE_Task_Base
+{
+ public:
+
+ OrbShutdownTask();
+ virtual ~OrbShutdownTask();
+
+ void orb(CORBA::ORB_ptr orb);
+
+ virtual int open(void*);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbTask.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbTask.cpp
new file mode 100644
index 00000000000..ff6ad717898
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbTask.cpp
@@ -0,0 +1,99 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbTask.cpp
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#include "OrbTask.h"
+#include "ace/CORBA_macros.h"
+
+namespace { enum { MAX_ORB_TASK_WORKER_THREADS = 20 }; }
+
+
+OrbTask::OrbTask(CORBA::ORB_ptr orb, unsigned num_threads)
+ : orb_(CORBA::ORB::_duplicate(orb)),
+ num_threads_(num_threads)
+{
+}
+
+
+OrbTask::~OrbTask()
+{
+}
+
+
+int
+OrbTask::open(void*)
+{
+ if (this->num_threads_ < 1)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "num_threads_ (%d) is less-than 1.\n",
+ this->num_threads_),
+ -1);
+ }
+
+ if (this->num_threads_ > MAX_ORB_TASK_WORKER_THREADS)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "num_threads_ (%d) is too large. Max is %d.\n",
+ this->num_threads_, MAX_ORB_TASK_WORKER_THREADS),
+ -1);
+ }
+
+ if (CORBA::is_nil(this->orb_.in()))
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to open. "
+ "ORB object reference is nil.\n"),
+ -1);
+ }
+
+ if (this->activate(THR_NEW_LWP | THR_JOINABLE, this->num_threads_) != 0)
+ {
+ // Assumes that when activate returns non-zero return code that
+ // no threads were activated.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "(%P|%t) OrbTask failed to activate "
+ "(%d) worker threads.\n",
+ this->num_threads_),
+ -1);
+ }
+
+ return 0;
+}
+
+
+int
+OrbTask::svc()
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Exception raised by ORB::run() method. "
+ "OrbTask is stopping.\n"));
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+int
+OrbTask::close(u_long)
+{
+ return 0;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbTask.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbTask.h
new file mode 100644
index 00000000000..dc01e3ca191
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/OrbTask.h
@@ -0,0 +1,38 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OrbTask.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef ORB_TASK_H
+#define ORB_TASK_H
+
+#include "CSD_TP_Test_Export.h"
+#include "ace/Task.h"
+#include "tao/ORB.h"
+
+class CSD_TP_Test_Export OrbTask : public ACE_Task_Base
+{
+ public:
+
+ OrbTask(CORBA::ORB_ptr orb, unsigned num_threads = 1);
+ virtual ~OrbTask();
+
+ virtual int open(void* x = 0);
+ virtual int svc();
+ virtual int close(u_long);
+
+
+ private:
+
+ CORBA::ORB_var orb_;
+ unsigned num_threads_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/ServantList_T.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/ServantList_T.cpp
new file mode 100644
index 00000000000..2727c975253
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/ServantList_T.cpp
@@ -0,0 +1,135 @@
+// $Id$
+#include "ServantList_T.h"
+#include "AppHelper.h"
+#include "TestAppExceptionC.h"
+
+
+template <typename T>
+ServantList<T>::ServantList()
+{
+}
+
+
+template <typename T>
+ServantList<T>::~ServantList()
+{
+}
+
+
+template <typename T>
+void
+ServantList<T>::create_and_activate(unsigned num_servants,
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char* ior_fname_prefix
+ ACE_ENV_ARG_DECL)
+{
+ for (unsigned i = 0; i < num_servants; i++)
+ {
+ char buf[32];
+ ACE_OS::sprintf(buf, "%02d", i + 1);
+ ACE_CString filename = ACE_CString(ior_fname_prefix) + "_" + buf + ".ior";
+ ServantRecord record;
+ record.servant_ = new T();
+ record.safe_servant_ = record.servant_;
+
+ CORBA::Object_var obj
+ = AppHelper::activate_servant(poa,
+ record.safe_servant_.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ AppHelper::ref_to_file(orb, obj.in(), filename.c_str() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ record.obj_ = T_stub::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil(record.obj_.in()))
+ {
+ ACE_THROW (TestAppException());
+ }
+
+ this->servant_records_.push_back(record);
+ }
+}
+
+
+template <typename T>
+void
+ServantList<T>::create_and_activate(unsigned num_servants,
+ PortableServer::POA_ptr poa
+ ACE_ENV_ARG_DECL)
+{
+ for (unsigned i = 0; i < num_servants; i++)
+ {
+ ServantRecord record;
+ record.servant_ = new T();
+ record.safe_servant_ = record.servant_;
+
+ CORBA::Object_var obj
+ = AppHelper::activate_servant(poa,
+ record.safe_servant_.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ record.obj_ = T_stub::_narrow(obj.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil(record.obj_.in()))
+ {
+ ACE_THROW (TestAppException());
+ }
+
+ this->servant_records_.push_back(record);
+ }
+}
+
+
+// Code for reference - doesn't work right now
+#if 0
+template <typename T>
+void
+ServantList<T>::deactivate(PortableServer::POA_ptr poa)
+{
+ ServantRecord record;
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ PortableServer::ObjectId_var id =
+ poa->servant_to_id(record.safe_servant_.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ poa->deactivate_object(id.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "ServantList_T::deactivate_servant ()");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)ServantList_T::deactivate_servant "
+ "Caught unknown exception \n"));
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+}
+#endif
+
+
+template <typename T>
+typename ServantList<T>::T_stub_ptr
+ServantList<T>::objref(unsigned index)
+{
+ return T_stub::_duplicate(this->servant_records_[index].obj_.in());
+}
+
+
+template <typename T>
+T*
+ServantList<T>::servant(unsigned index)
+{
+ return this->servant_records_[index].servant_;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/ServantList_T.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/ServantList_T.h
new file mode 100644
index 00000000000..3cc61e42905
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/ServantList_T.h
@@ -0,0 +1,68 @@
+// $Id$
+#ifndef SERVANTLIST_T_H
+#define SERVANTLIST_T_H
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/Servant_Base.h"
+#include "ace/Vector_T.h"
+
+
+// The T type is a concrete servant type.
+template <class T>
+class ServantList
+{
+ public:
+
+ typedef typename T::_stub_type T_stub;
+ typedef typename T::_stub_ptr_type T_stub_ptr;
+ typedef typename T::_stub_var_type T_stub_var;
+
+ ServantList();
+ ~ServantList();
+
+ /// Activate servant and output ior to a file.
+ void create_and_activate(unsigned num_servants,
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa,
+ const char* ior_fname_prefix
+ ACE_ENV_ARG_DECL);
+
+ /// Activate servant and not output ior to a file.
+ void create_and_activate(unsigned num_servants,
+ PortableServer::POA_ptr poa
+ ACE_ENV_ARG_DECL);
+
+ // Code not used and not working right now - possible future addition.
+ //void deactivate(PortableServer::POA_ptr poa);
+
+ /// Get a (copy) of one of the object references (for a specific servant).
+ T_stub_ptr objref(unsigned index);
+ /// This doesn't return a copy.
+ T* servant(unsigned index);
+
+
+ private:
+
+ struct ServantRecord
+ {
+ T* servant_;
+ PortableServer::ServantBase_var safe_servant_;
+ T_stub_var obj_;
+ };
+
+ typedef ACE_Vector<ServantRecord> ServantRecordVector;
+
+ ServantRecordVector servant_records_;
+};
+
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ServantList_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("ServantList_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#endif /* SERVANTLIST_T_H */
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.cpp
new file mode 100644
index 00000000000..456d7025478
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.cpp
@@ -0,0 +1,35 @@
+// $Id$
+#include "StatisticsHelper.h"
+
+// swap function for integers
+void swap ( CORBA::Long& x, CORBA::Long& y )
+{
+ CORBA::Long temp;
+ temp = x;
+ x = y;
+ y = temp;
+}
+
+
+void sort ( LongVector & vector )
+{
+ unsigned size = vector.size ();
+
+ if (size > 0)
+ {
+ unsigned indexOfMin;
+ unsigned pass;
+ unsigned j;
+
+ for ( pass = 0; pass < size - 1; pass++ )
+ {
+ indexOfMin = pass;
+
+ for ( j = pass + 1; j < size; j++ )
+ if ( vector[j] < vector[indexOfMin] )
+ indexOfMin = j;
+
+ swap ( vector[pass], vector[indexOfMin] );
+ }
+ }
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.h
new file mode 100644
index 00000000000..7f26a4ae165
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/StatisticsHelper.h
@@ -0,0 +1,24 @@
+// $Id$
+#ifndef STATISTICS_HELPER_H
+#define STATISTICS_HELPER_H
+
+#include "CSD_TP_Test_Export.h"
+#include "tao/Basic_Types.h"
+#include "ace/Array.h"
+#include "ace/Vector_T.h"
+#include "ace/SString.h"
+
+
+typedef ACE_Vector< CORBA::Long, 1000 > LongVector;
+typedef ACE_Vector< ACE_CString, 1000 > StringVector;
+typedef ACE_Array< CORBA::Long > LongArray;
+
+
+extern CSD_TP_Test_Export
+void swap ( CORBA::Long& x, CORBA::Long& y );
+
+extern CSD_TP_Test_Export
+void sort ( LongVector & vector );
+
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppBase.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppBase.cpp
new file mode 100644
index 00000000000..f2a2e97b7a2
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppBase.cpp
@@ -0,0 +1,30 @@
+// $Id$
+#include "TestAppBase.h"
+
+TestAppBase::TestAppBase(const char* name)
+ : name_(name)
+{
+}
+
+
+TestAppBase::~TestAppBase()
+{
+}
+
+
+const char*
+TestAppBase::name() const
+{
+ return this->name_.c_str();
+}
+
+
+int
+TestAppBase::run(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int rc = this->run_i(argc, argv ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Convert 1 to 0. Leave 0 and -1 as they are.
+ return (rc == 1) ? 0 : rc;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppBase.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppBase.h
new file mode 100644
index 00000000000..5138ffbf84c
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppBase.h
@@ -0,0 +1,36 @@
+// $Id$
+#ifndef TESTAPPBASE_H
+#define TESTAPPBASE_H
+
+#include "CSD_TP_Test_Export.h"
+#include "ace/SString.h"
+#include "tao/Environment.h"
+#include "ace/CORBA_macros.h"
+
+
+class CSD_TP_Test_Export TestAppBase
+{
+ public:
+
+ virtual ~TestAppBase();
+
+ // Returns 0 for success, and -1 for failure.
+ int run(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+ const char* name() const;
+
+
+ protected:
+
+ TestAppBase(const char* name);
+
+ // Returns -1 for failure, 0 for success
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL) = 0;
+
+
+ private:
+
+ ACE_CString name_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppException.idl b/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppException.idl
new file mode 100644
index 00000000000..2ac53939b77
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppException.idl
@@ -0,0 +1,7 @@
+// $Id$
+#ifndef TESTAPPXCEPTION_IDL
+#define TESTAPPXCEPTION_IDL
+
+exception TestAppException {};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppMain.h b/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppMain.h
new file mode 100644
index 00000000000..062b6fc0c8e
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Common/TestAppMain.h
@@ -0,0 +1,49 @@
+// $Id$
+#ifndef TESTAPPMAIN_H
+#define TESTAPPMAIN_H
+
+#include "ace/Log_Msg.h"
+#include "ace/SString.h"
+#include "tao/Exception.h"
+#include "tao/Environment.h"
+
+#define TEST_APP_MAIN(APP_TYPE) \
+int \
+main(int argc, char* argv[]) \
+{ \
+ ACE_LOG_MSG->priority_mask(LM_TRACE | \
+ LM_DEBUG | \
+ LM_INFO | \
+ LM_NOTICE | \
+ LM_WARNING | \
+ LM_ERROR | \
+ LM_CRITICAL | \
+ LM_ALERT | \
+ LM_EMERGENCY, \
+ ACE_Log_Msg::PROCESS); \
+\
+ APP_TYPE app; \
+\
+ ACE_TRY_NEW_ENV \
+ { \
+ int ret = app.run(argc,argv ACE_ENV_ARG_PARAMETER); \
+ ACE_TRY_CHECK; \
+ return ret; \
+ } \
+ ACE_CATCHANY \
+ { \
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, \
+ "Caught exception:"); \
+ } \
+ ACE_CATCHALL \
+ { \
+ ACE_ERROR((LM_ERROR, \
+ "(%P|%t) Unknown (...) exception caught in main() " \
+ "for App [%d].\n", app.name())); \
+ } \
+ ACE_ENDTRY; \
+ \
+ return 1; \
+}
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/CSD_TP_Foo_A_Export.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/CSD_TP_Foo_A_Export.h
new file mode 100644
index 00000000000..9b855c486d8
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/CSD_TP_Foo_A_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s CSD_TP_Foo_A
+// ------------------------------
+#ifndef CSD_TP_FOO_A_EXPORT_H
+#define CSD_TP_FOO_A_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (CSD_TP_FOO_A_HAS_DLL)
+# define CSD_TP_FOO_A_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && CSD_TP_FOO_A_HAS_DLL */
+
+#if !defined (CSD_TP_FOO_A_HAS_DLL)
+# define CSD_TP_FOO_A_HAS_DLL 1
+#endif /* ! CSD_TP_FOO_A_HAS_DLL */
+
+#if defined (CSD_TP_FOO_A_HAS_DLL) && (CSD_TP_FOO_A_HAS_DLL == 1)
+# if defined (CSD_TP_FOO_A_BUILD_DLL)
+# define CSD_TP_Foo_A_Export ACE_Proper_Export_Flag
+# define CSD_TP_FOO_A_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define CSD_TP_FOO_A_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* CSD_TP_FOO_A_BUILD_DLL */
+# define CSD_TP_Foo_A_Export ACE_Proper_Import_Flag
+# define CSD_TP_FOO_A_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define CSD_TP_FOO_A_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* CSD_TP_FOO_A_BUILD_DLL */
+#else /* CSD_TP_FOO_A_HAS_DLL == 1 */
+# define CSD_TP_Foo_A_Export
+# define CSD_TP_FOO_A_SINGLETON_DECLARATION(T)
+# define CSD_TP_FOO_A_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* CSD_TP_FOO_A_HAS_DLL == 1 */
+
+// Set CSD_TP_FOO_A_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (CSD_TP_FOO_A_NTRACE)
+# if (ACE_NTRACE == 1)
+# define CSD_TP_FOO_A_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define CSD_TP_FOO_A_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !CSD_TP_FOO_A_NTRACE */
+
+#if (CSD_TP_FOO_A_NTRACE == 1)
+# define CSD_TP_FOO_A_TRACE(X)
+#else /* (CSD_TP_FOO_A_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define CSD_TP_FOO_A_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (CSD_TP_FOO_A_NTRACE == 1) */
+
+#endif /* CSD_TP_FOO_A_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A.idl b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A.idl
new file mode 100644
index 00000000000..e9f3b0345f8
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A.idl
@@ -0,0 +1,29 @@
+// $Id$
+#ifndef FOO_A_IDL
+#define FOO_A_IDL
+
+#include "FooException.idl"
+
+interface Foo_A
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, 1 "in" argument
+ long op3(in long value);
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Client calls this last. The last client to claim that it is
+ /// done will cause the server to shutdown.
+ void done();
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.cpp
new file mode 100644
index 00000000000..bb0d1cf1bf7
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.cpp
@@ -0,0 +1,94 @@
+// $Id$
+#include "Foo_A_ClientEngine.h"
+#include "Foo_A_Statistics.h"
+#include "TestAppExceptionC.h"
+#include "AppHelper.h"
+#include "ace/Log_Msg.h"
+
+Foo_A_ClientEngine::Foo_A_ClientEngine(Foo_A_ptr obj,
+ unsigned client_id,
+ bool collocated)
+ : obj_(Foo_A::_duplicate(obj)),
+ client_id_ (client_id),
+ collocated_ (collocated)
+{
+}
+
+
+Foo_A_ClientEngine::~Foo_A_ClientEngine()
+{
+}
+
+
+bool
+Foo_A_ClientEngine::execute(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Make sure the connection is established before making
+ // remote invocations.
+ if (AppHelper::validate_connection (this->obj_.in ()) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_A_ClientEngine::execute " \
+ "client %d connect failed.\n", this->client_id_));
+ return false;
+ }
+
+ // Verify the return values and return the results.
+ bool check_validity = true;
+
+ CORBA::Long i = this->client_id_;
+
+ this->obj_->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ this->obj_->op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ CORBA::Long value = this->obj_->op3(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ if (value != i)
+ {
+ check_validity = false;
+ }
+
+ for (CORBA::Long j = 1; j <= 5; j++)
+ {
+ this->obj_->op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ }
+
+ bool caught_exception = false;
+
+ ACE_TRY
+ {
+ this->obj_->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ // Expected
+ caught_exception = true;
+ }
+ ACE_ENDTRY;
+
+ if (! caught_exception)
+ {
+ check_validity = false;
+ }
+
+ this->obj_->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ return check_validity;
+}
+
+
+void
+Foo_A_ClientEngine::expected_results(Foo_A_Statistics& stats)
+{
+ stats.expected(1, 1);
+ stats.expected(2, 1);
+ stats.expected(3, 1);
+ stats.expected(4, 5);
+ stats.expected(5, 1);
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.h
new file mode 100644
index 00000000000..4f49888f34f
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_ClientEngine.h
@@ -0,0 +1,40 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_A_ClientEngine.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_A_CLIENT_ENGINE_H
+#define FOO_A_CLIENT_ENGINE_H
+
+#include "CSD_TP_Foo_A_Export.h"
+#include "ClientEngine.h"
+#include "Foo_AC.h"
+
+class Foo_A_Statistics;
+
+class CSD_TP_Foo_A_Export Foo_A_ClientEngine : public ClientEngine
+{
+ public:
+
+ Foo_A_ClientEngine(Foo_A_ptr obj, unsigned client_id = 0, bool collocated = false);
+ virtual ~Foo_A_ClientEngine();
+
+ virtual bool execute(ACE_ENV_SINGLE_ARG_DECL);
+
+ static void expected_results(Foo_A_Statistics& stats);
+
+ private:
+
+ Foo_A_var obj_;
+ unsigned client_id_;
+ bool collocated_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.cpp
new file mode 100644
index 00000000000..1ef8ce83cd7
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.cpp
@@ -0,0 +1,88 @@
+// $Id$
+#include "Foo_A_Statistics.h"
+#include "Foo_A_ClientEngine.h"
+
+Foo_A_Statistics::Foo_A_Statistics(unsigned num_clients)
+: num_clients_ (num_clients)
+{
+ for (unsigned i = 0; i < 5; i++)
+ {
+ this->expected_[i] = 0;
+ this->actual_[i] = 0;
+ }
+}
+
+
+Foo_A_Statistics::~Foo_A_Statistics()
+{
+}
+
+
+void
+Foo_A_Statistics::expected(unsigned op_num, unsigned count)
+{
+ this->expected_[op_num-1] = count * this->num_clients_;
+}
+
+
+void
+Foo_A_Statistics::actual(unsigned op_num, unsigned count)
+{
+ this->actual_[op_num-1] += count;
+}
+
+
+void
+Foo_A_Statistics::actual_in_values(unsigned op_num, LongVector lv)
+{
+ size_t sz = lv.size();
+ for (size_t i = 0; i < sz; i++)
+ {
+ this->actual_in_values_[op_num-1].push_back (lv[i]);
+ }
+}
+
+
+bool
+Foo_A_Statistics::actual_vs_expected()
+{
+ Foo_A_Statistics stats (1);
+ Foo_A_ClientEngine::expected_results (stats);
+
+ for (unsigned i = 0; i < 5; i++)
+ {
+ if (this->expected_[i] != this->actual_[i])
+ {
+ return false;
+ }
+
+ // Verify the "in" values.
+ // Skip op1/op5 since they do not have any "in" values.
+ if (i % 5 == 0 || i % 5 == 4)
+ {
+ continue;
+ }
+
+ unsigned actual_size
+ = this->actual_in_values_[i].size ();
+ unsigned expected_size
+ = this->num_clients_ * stats.expected_[i];
+ if (actual_size != expected_size)
+ {
+ return false;
+ }
+ sort (this->actual_in_values_[i]);
+
+ for (unsigned j = 0; j < actual_size - 1; j++)
+ {
+ if (this->actual_in_values_[i][j] != this->actual_in_values_[i][j + 1] - 1)
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.h
new file mode 100644
index 00000000000..d5bf9ea2c71
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_Statistics.h
@@ -0,0 +1,34 @@
+// $Id$
+#ifndef STATISTICS_A_H
+#define STATISTICS_A_H
+
+#include "CSD_TP_Foo_A_Export.h"
+#include "StatisticsHelper.h"
+
+
+class CSD_TP_Foo_A_Export Foo_A_Statistics
+{
+ public:
+
+ Foo_A_Statistics(unsigned num_clients);
+
+ virtual ~Foo_A_Statistics();
+
+ void expected(unsigned op_num, unsigned count);
+ void actual(unsigned op_num, unsigned count);
+ void actual_in_values(unsigned op_num, LongVector lv);
+
+ bool actual_vs_expected();
+
+
+ private:
+
+ unsigned num_clients_;
+
+ unsigned expected_[5];
+ unsigned actual_[5];
+
+ LongVector actual_in_values_ [5];
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.cpp
new file mode 100644
index 00000000000..a3bab7748aa
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.cpp
@@ -0,0 +1,82 @@
+// $Id$
+#include "Foo_A_i.h"
+#include "AppShutdown.h"
+
+
+Foo_A_i::Foo_A_i()
+{
+ for (unsigned i = 0; i < 5; i++)
+ {
+ this->op_count_[i] = 0;
+ }
+}
+
+
+Foo_A_i::~Foo_A_i()
+{
+}
+
+
+void
+Foo_A_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[0] ++;
+}
+
+
+void
+Foo_A_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->in_values_[1].push_back (value);
+ this->op_count_[1] ++;
+}
+
+
+CORBA::Long
+Foo_A_i::op3(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->in_values_[2].push_back (value);
+ this->op_count_[2] ++;
+ return value;
+}
+
+
+void
+Foo_A_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->in_values_[3].push_back (value);
+ this->op_count_[3] ++;
+}
+
+
+void
+Foo_A_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ this->op_count_[4] ++;
+ ACE_THROW (FooException());
+}
+
+
+void
+Foo_A_i::done(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ TheAppShutdown->client_done();
+}
+
+
+void
+Foo_A_i::gather_stats(Foo_A_Statistics& stats)
+{
+ for (unsigned i = 0; i < 5; i++)
+ {
+ stats.actual (i + 1, this->op_count_[i]);
+ stats.actual_in_values (i + 1, this->in_values_[i]);
+ }
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.h
new file mode 100644
index 00000000000..094def1fb06
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/Foo_A_i.h
@@ -0,0 +1,44 @@
+// $Id$
+#ifndef FOO_A_I_H
+#define FOO_A_I_H
+
+#include "CSD_TP_Foo_A_Export.h"
+#include "Foo_AS.h"
+#include "Foo_A_Statistics.h"
+
+
+class CSD_TP_Foo_A_Export Foo_A_i : public virtual POA_Foo_A,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Foo_A_i();
+ virtual ~Foo_A_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ void gather_stats (Foo_A_Statistics& stats) ;
+
+ private:
+
+ LongVector in_values_ [5];
+ unsigned op_count_ [5];
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/csd_tp_foo_a_lib.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/csd_tp_foo_a_lib.mpc
new file mode 100644
index 00000000000..7f2027a9f5d
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_A/csd_tp_foo_a_lib.mpc
@@ -0,0 +1,20 @@
+//$Id$
+project : csd_tp_test_lib {
+ sharedname = CSD_TP_Foo_A
+ dynamicflags = CSD_TP_FOO_A_BUILD_DLL
+ idlflags += -Wb,export_macro=CSD_TP_Foo_A_Export -Wb,export_include=CSD_TP_Foo_A_Export.h
+ includes += $(TAO_ROOT)/tao
+
+ IDL_Files {
+ Foo_A.idl
+ }
+
+ Source_Files {
+ Foo_AC.cpp
+ Foo_AS.cpp
+ Foo_A_ClientEngine.cpp
+ Foo_A_i.cpp
+ Foo_A_Statistics.cpp
+ }
+
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/CSD_TP_Foo_B_Export.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/CSD_TP_Foo_B_Export.h
new file mode 100644
index 00000000000..c6e2f4cd967
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/CSD_TP_Foo_B_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s CSD_TP_Foo_B
+// ------------------------------
+#ifndef CSD_TP_FOO_B_EXPORT_H
+#define CSD_TP_FOO_B_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (CSD_TP_FOO_B_HAS_DLL)
+# define CSD_TP_FOO_B_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && CSD_TP_FOO_B_HAS_DLL */
+
+#if !defined (CSD_TP_FOO_B_HAS_DLL)
+# define CSD_TP_FOO_B_HAS_DLL 1
+#endif /* ! CSD_TP_FOO_B_HAS_DLL */
+
+#if defined (CSD_TP_FOO_B_HAS_DLL) && (CSD_TP_FOO_B_HAS_DLL == 1)
+# if defined (CSD_TP_FOO_B_BUILD_DLL)
+# define CSD_TP_Foo_B_Export ACE_Proper_Export_Flag
+# define CSD_TP_FOO_B_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define CSD_TP_FOO_B_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* CSD_TP_FOO_B_BUILD_DLL */
+# define CSD_TP_Foo_B_Export ACE_Proper_Import_Flag
+# define CSD_TP_FOO_B_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define CSD_TP_FOO_B_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* CSD_TP_FOO_B_BUILD_DLL */
+#else /* CSD_TP_FOO_B_HAS_DLL == 1 */
+# define CSD_TP_Foo_B_Export
+# define CSD_TP_FOO_B_SINGLETON_DECLARATION(T)
+# define CSD_TP_FOO_B_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* CSD_TP_FOO_B_HAS_DLL == 1 */
+
+// Set CSD_TP_FOO_B_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (CSD_TP_FOO_B_NTRACE)
+# if (ACE_NTRACE == 1)
+# define CSD_TP_FOO_B_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define CSD_TP_FOO_B_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !CSD_TP_FOO_B_NTRACE */
+
+#if (CSD_TP_FOO_B_NTRACE == 1)
+# define CSD_TP_FOO_B_TRACE(X)
+#else /* (CSD_TP_FOO_B_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define CSD_TP_FOO_B_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (CSD_TP_FOO_B_NTRACE == 1) */
+
+#endif /* CSD_TP_FOO_B_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback.idl b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback.idl
new file mode 100644
index 00000000000..49be42260cb
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback.idl
@@ -0,0 +1,11 @@
+// $Id$
+#ifndef CALLBACK_IDL
+#define CALLBACK_IDL
+
+interface Callback
+{
+ void test_method();
+};
+
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.cpp
new file mode 100644
index 00000000000..d4158bf5324
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.cpp
@@ -0,0 +1,28 @@
+// $Id$
+#include "Callback_i.h"
+
+Callback_i::Callback_i()
+ : num_callbacks_(0)
+{
+}
+
+
+Callback_i::~Callback_i ()
+{
+}
+
+
+void
+Callback_i::test_method(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->num_callbacks_ ++;
+}
+
+
+void
+Callback_i::gather_stats(Foo_B_Statistics& stats)
+{
+ stats.actual_callbacks(this->num_callbacks_.value ());
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.h
new file mode 100644
index 00000000000..8404d72e382
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Callback_i.h
@@ -0,0 +1,32 @@
+// $Id$
+#ifndef CALLBACK_I_H
+#define CALLBACK_I_H
+
+#include "CSD_TP_Foo_B_Export.h"
+#include "CallbackS.h"
+#include "Foo_B_Statistics.h"
+
+
+class CSD_TP_Foo_B_Export Callback_i
+ : public virtual POA_Callback,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Callback_i();
+
+ virtual ~Callback_i();
+
+ virtual void test_method(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ void gather_stats(Foo_B_Statistics& stats);
+
+
+ private:
+
+ ACE_Atomic_Op <ACE_SYNCH_MUTEX, unsigned> num_callbacks_;
+};
+
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B.idl b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B.idl
new file mode 100644
index 00000000000..2b6b7382fab
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B.idl
@@ -0,0 +1,70 @@
+// $Id$
+#ifndef FOO_B_IDL
+#define FOO_B_IDL
+
+#include "FooException.idl"
+#include "Callback.idl"
+
+
+typedef sequence<char, 32> Bounded_Var_Size;
+typedef sequence<char> Unbounded_Var_Size;
+typedef long Fixed_Array[20];
+typedef string Var_Array [3];
+
+struct TimeOfDay {
+ short hour; // 0 - 23
+ short minute; // 0 - 59
+ short second; // 0 - 59
+};
+interface Foo_B
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, 1 "in" argument
+ long op3(in long value);
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Test fixed size "in" argument and the "inout" parameter.
+ boolean op6(in TimeOfDay t,
+ inout string message);
+
+ /// Callback test.
+
+ /// Pass the callback object and the server invoke operation on
+ /// the callback object reference.
+ void op7 (in Callback cb) raises (FooException);
+
+ oneway void test_unbounded_string_arg(in string message);
+
+ oneway void test_bounded_string_arg(in string<20> message);
+
+ oneway void test_fixed_array_arg(in Fixed_Array message);
+
+ oneway void test_var_array_arg(in Var_Array messages);
+
+ oneway void test_bounded_var_size_arg(in Bounded_Var_Size message);
+
+ oneway void test_unbounded_var_size_arg(in Unbounded_Var_Size message);
+
+ oneway void test_fixed_size_arg (in TimeOfDay t);
+
+ oneway void test_special_basic_arg(in boolean value, in long client_id);
+
+ oneway void test_objref_arg (in Callback cb);
+
+ /// Client calls this last. The last client to claim that it is
+ /// done will cause the server to shutdown.
+ void done();
+};
+
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.cpp
new file mode 100644
index 00000000000..2769f5ad9cf
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.cpp
@@ -0,0 +1,206 @@
+// $Id$
+#include "Foo_B_ClientEngine.h"
+#include "Callback_i.h"
+#include "Foo_B_Statistics.h"
+#include "TestAppExceptionC.h"
+#include "AppHelper.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS.h"
+
+const char* ONEWAY_ARG_TEST_STR = "TEST";
+
+Foo_B_ClientEngine::Foo_B_ClientEngine(Foo_B_ptr obj,
+ Callback_ptr callback,
+ unsigned client_id,
+ bool collocated)
+ : obj_(Foo_B::_duplicate(obj)),
+ callback_(Callback::_duplicate(callback)),
+ client_id_(client_id),
+ collocated_(collocated)
+{
+}
+
+
+Foo_B_ClientEngine::~Foo_B_ClientEngine()
+{
+}
+
+
+bool
+Foo_B_ClientEngine::execute(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Make sure the connection is established before making
+ // remote invocations.
+ if (AppHelper::validate_connection (this->obj_.in ()) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_A_ClientEngine::execute " \
+ "client %d connect failed.\n", this->client_id_));
+ return false;
+ }
+
+ // Verify the return values and return the results.
+ bool check_validity = true;
+
+ this->obj_->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ this->obj_->op2(this->client_id_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ CORBA::Long value = this->obj_->op3(this->client_id_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ if (value != static_cast<CORBA::Long>(this->client_id_))
+ {
+ check_validity = false;
+ }
+
+ for (CORBA::ULong j = 1; j <= 5; j++)
+ {
+ this->obj_->op4(495 + (this->client_id_ * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ }
+
+ bool caught_exception = false;
+
+ ACE_TRY
+ {
+ this->obj_->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ // Expected
+ caught_exception = true;
+ }
+ ACE_ENDTRY;
+
+ if (! caught_exception)
+ {
+ check_validity = false;
+ }
+
+ TimeOfDay t;
+ t.hour = 12;
+ t.minute = 30;
+ t.second = 10;
+
+ char test_str [20];
+ ACE_OS::sprintf (test_str, "%d %s", this->client_id_, ONEWAY_ARG_TEST_STR);
+
+ char buffer [20];
+
+ // Two-Way calls with "inout" and fixed size "in" arguments.
+ CORBA::String_var message = CORBA::string_dup(test_str);
+
+ CORBA::Boolean result = this->obj_->op6( t, message.inout() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ ACE_UNUSED_ARG(result);
+
+ ACE_OS::sprintf (buffer, "%d %s %d:%d:%d", this->client_id_, ONEWAY_ARG_TEST_STR,
+ t.hour, t.minute, t.second);
+
+ if (ACE_OS::strncmp (message.in (), buffer, ACE_OS::strlen (buffer)) != 0)
+ {
+ check_validity = false;
+ }
+
+ // Callback test.
+ this->obj_->op7 (this->callback_.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ // One-Way calls with various arguments.
+ CORBA::String_var ub_string = CORBA::string_dup( test_str );
+ this->obj_->test_unbounded_string_arg (ub_string.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ CORBA::String_var bd_string = CORBA::string_dup( test_str );
+ this->obj_->test_bounded_string_arg (bd_string.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ Fixed_Array fixed_array;
+
+ for (CORBA::ULong m = 0 ; m < 20; m ++)
+ {
+ fixed_array[m] = this->client_id_ + m;
+ }
+
+ this->obj_->test_fixed_array_arg (fixed_array ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ Var_Array var_array;
+
+ for (CORBA::ULong k = 0; k < 3; k++)
+ {
+ ACE_OS::sprintf (buffer, "%d %s %d",
+ this->client_id_, ONEWAY_ARG_TEST_STR, k);
+ var_array[k] = CORBA::string_dup(buffer);
+ }
+
+ this->obj_->test_var_array_arg (var_array ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ Bounded_Var_Size_var bd_var_size_string = new Bounded_Var_Size();
+
+ bd_var_size_string->replace (bd_var_size_string->maximum (),
+ ACE_OS::strlen (test_str) + 1,
+ test_str);
+ this->obj_->test_bounded_var_size_arg (bd_var_size_string.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ Unbounded_Var_Size_var ub_var_size_string = new Unbounded_Var_Size(100);
+ ub_var_size_string->replace (ub_var_size_string->maximum (),
+ ACE_OS::strlen (test_str) + 1,
+ test_str);
+ this->obj_->test_unbounded_var_size_arg (ub_var_size_string.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ this->obj_->test_fixed_size_arg (t ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ this->obj_->test_special_basic_arg (this->client_id_ % 2,
+ this->client_id_
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ this->obj_->test_objref_arg (this->callback_.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ this->obj_->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ return check_validity;
+}
+
+
+void
+Foo_B_ClientEngine::expected_results(Foo_B_Statistics& stats)
+{
+ stats.expected(1, 1, Foo_B_Statistics::FOO_B_STAT_NONE);
+ stats.expected(2, 1, Foo_B_Statistics::FOO_B_STAT_LONG);
+ stats.expected(3, 1, Foo_B_Statistics::FOO_B_STAT_LONG);
+ stats.expected(4, 5, Foo_B_Statistics::FOO_B_STAT_LONG);
+ stats.expected(5, 1, Foo_B_Statistics::FOO_B_STAT_NONE);
+ stats.expected(6, 1, Foo_B_Statistics::FOO_B_STAT_NONE);
+ stats.expected(7, 1, Foo_B_Statistics::FOO_B_STAT_NONE);
+ stats.expected(8, 1, Foo_B_Statistics::FOO_B_STAT_STRING);
+ stats.expected(9, 1, Foo_B_Statistics::FOO_B_STAT_STRING);
+ stats.expected(10, 1, Foo_B_Statistics::FOO_B_STAT_LONG);
+ stats.expected(11, 1, Foo_B_Statistics::FOO_B_STAT_STRING);
+ stats.expected(12, 1, Foo_B_Statistics::FOO_B_STAT_STRING);
+ stats.expected(13, 1, Foo_B_Statistics::FOO_B_STAT_NONE);
+ stats.expected(14, 1, Foo_B_Statistics::FOO_B_STAT_STRING);
+ stats.expected(15, 1, Foo_B_Statistics::FOO_B_STAT_NONE);
+ stats.expected(16, 1, Foo_B_Statistics::FOO_B_STAT_NONE);
+ stats.expected_callbacks (1);
+}
+
+
+unsigned
+Foo_B_ClientEngine::expected_callbacks ()
+{
+ return 1;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.h
new file mode 100644
index 00000000000..a6e8e51667b
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_ClientEngine.h
@@ -0,0 +1,47 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_B_ClientEngine.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_B_CLIENT_ENGINE_H
+#define FOO_B_CLIENT_ENGINE_H
+
+#include "CSD_TP_Foo_B_Export.h"
+#include "ClientEngine.h"
+#include "Foo_BC.h"
+
+class Foo_B_Statistics;
+class Callback_i;
+
+class CSD_TP_Foo_B_Export Foo_B_ClientEngine : public ClientEngine
+{
+ public:
+
+ Foo_B_ClientEngine(Foo_B_ptr obj,
+ Callback_ptr callback,
+ unsigned client_id = 0,
+ bool collocated = false);
+
+ virtual ~Foo_B_ClientEngine();
+
+ virtual bool execute(ACE_ENV_SINGLE_ARG_DECL);
+
+ static void expected_results(Foo_B_Statistics& stats);
+ static unsigned expected_callbacks ();
+
+ private:
+
+ Foo_B_var obj_;
+ Callback_var callback_;
+ unsigned client_id_;
+ bool collocated_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.cpp
new file mode 100644
index 00000000000..ec2d97c6bdf
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.cpp
@@ -0,0 +1,83 @@
+// $Id$
+#include "Foo_B_SimpleClientEngine.h"
+#include "Callback_i.h"
+#include "Foo_B_Statistics.h"
+#include "TestAppExceptionC.h"
+#include "AppHelper.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS.h"
+
+extern const char* ONEWAY_ARG_TEST_STR;
+
+Foo_B_SimpleClientEngine::Foo_B_SimpleClientEngine(Foo_B_ptr obj,
+ Callback_ptr callback,
+ unsigned client_id,
+ bool collocated)
+ : obj_(Foo_B::_duplicate(obj)),
+ callback_(Callback::_duplicate(callback)),
+ client_id_(client_id),
+ collocated_(collocated)
+{
+}
+
+
+Foo_B_SimpleClientEngine::~Foo_B_SimpleClientEngine()
+{
+}
+
+
+bool
+Foo_B_SimpleClientEngine::execute(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Make sure the connection is established before making
+ // remote invocations.
+ if (AppHelper::validate_connection (this->obj_.in ()) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_A_SimpleClientEngine::execute " \
+ "client %d connect failed.\n", this->client_id_));
+ return false;
+ }
+
+ // Verify the return values and return the results.
+ bool check_validity = true;
+
+ // Callback test.
+ ACE_TRY
+ {
+ if (CORBA::is_nil(this->callback_.in()))
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_A_SimpleClientEngine::execute " \
+ "The callback_ objref is nil before op7() call!\n"));
+ }
+
+ this->obj_->op7 (this->callback_.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_A_SimpleClientEngine::execute " \
+ "FooException raised by op7() call.\n"));
+ check_validity = false;
+ }
+ ACE_ENDTRY;
+
+ // Tell the servant that this client is done.
+ this->obj_->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ return check_validity;
+}
+
+
+void
+Foo_B_SimpleClientEngine::expected_results(Foo_B_Statistics& stats)
+{
+ stats.expected(7, 1, Foo_B_Statistics::FOO_B_STAT_NONE);
+}
+
+
+unsigned
+Foo_B_SimpleClientEngine::expected_callbacks ()
+{
+ return 1;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.h
new file mode 100644
index 00000000000..38ef6a09bcf
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_SimpleClientEngine.h
@@ -0,0 +1,47 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_B_SimpleClientEngine.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_B_SIMPLE_CLIENT_ENGINE_H
+#define FOO_B_SIMPLE_CLIENT_ENGINE_H
+
+#include "CSD_TP_Foo_B_Export.h"
+#include "ClientEngine.h"
+#include "Foo_BC.h"
+
+class Foo_B_Statistics;
+class Callback_i;
+
+class CSD_TP_Foo_B_Export Foo_B_SimpleClientEngine : public ClientEngine
+{
+ public:
+
+ Foo_B_SimpleClientEngine(Foo_B_ptr obj,
+ Callback_ptr callback,
+ unsigned client_id = 0,
+ bool collocated = false);
+
+ virtual ~Foo_B_SimpleClientEngine();
+
+ virtual bool execute(ACE_ENV_SINGLE_ARG_DECL);
+
+ static void expected_results(Foo_B_Statistics& stats);
+ static unsigned expected_callbacks ();
+
+ private:
+
+ Foo_B_var obj_;
+ Callback_var callback_;
+ unsigned client_id_;
+ bool collocated_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.cpp
new file mode 100644
index 00000000000..d282c058b8e
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.cpp
@@ -0,0 +1,187 @@
+// $Id$
+#include "Foo_B_Statistics.h"
+#include "Foo_B_ClientEngine.h"
+
+extern const char* ONEWAY_ARG_TEST_STR;
+extern CORBA::Boolean special_value;
+
+Foo_B_Statistics::Foo_B_Statistics(unsigned num_remote_clients,
+ unsigned num_collcated_clients)
+: num_clients_ (num_remote_clients + num_collcated_clients),
+ num_collcated_clients_ (num_collcated_clients),
+ expected_callbacks_ (0),
+ actual_callbacks_ (0),
+ servant_error_count_ (0)
+{
+ for (unsigned i = 0; i < 16; i++)
+ {
+ this->expected_op_count_[i] = 0;
+ this->actual_op_count_[i] = 0;
+ }
+}
+
+
+Foo_B_Statistics::~Foo_B_Statistics()
+{
+}
+
+
+void
+Foo_B_Statistics::expected(unsigned op_num, unsigned count, In_Value_Type type)
+{
+ this->expected_op_count_[op_num-1] = count * this->num_clients_;
+ this->expected_in_value_type_[op_num-1] = type;
+}
+
+
+void
+Foo_B_Statistics::actual(unsigned op_num, unsigned count)
+{
+ this->actual_op_count_[op_num-1] += count;
+}
+
+
+void
+Foo_B_Statistics::actual(unsigned op_num, LongVector lv)
+{
+ unsigned sz = lv.size();
+ for (unsigned i = 0; i < sz; i++)
+ {
+ this->actual_in_long_[op_num-1].push_back (lv[i]);
+ }
+}
+
+
+void
+Foo_B_Statistics::actual(unsigned op_num, StringVector sv)
+{
+ unsigned sz = sv.size();
+ for (unsigned i = 0; i < sz; i++)
+ {
+ this->actual_in_string_[op_num-1].push_back (sv[i]);
+ }
+}
+
+
+void
+Foo_B_Statistics::expected_callbacks (unsigned num_cbs)
+{
+ expected_callbacks_ = num_cbs * this->num_collcated_clients_;
+}
+
+
+void
+Foo_B_Statistics::actual_callbacks (unsigned num_cbs)
+{
+ actual_callbacks_ += num_cbs;
+}
+
+
+void
+Foo_B_Statistics::servant_error_count (unsigned error_count)
+{
+ this->servant_error_count_ += error_count;
+}
+
+
+bool
+Foo_B_Statistics::actual_vs_expected()
+{
+ // Verify the checking results in servant operation code.
+ if (this->servant_error_count_ > 0)
+ {
+ return false;
+ }
+
+ // Verify the number of callbacks received for the collocated
+ // client.
+ if (actual_callbacks_ != expected_callbacks_)
+ {
+ return false;
+ }
+
+ // Verify the number of operations server received.
+ for (unsigned int z = 0; z < 16; z++)
+ {
+ if (this->expected_op_count_[z] != this->actual_op_count_[z])
+ {
+ return false;
+ }
+ }
+
+ Foo_B_Statistics stats (1, 0);
+ Foo_B_ClientEngine::expected_results (stats);
+
+ for (unsigned i = 0; i < 16; i++)
+ {
+ switch (expected_in_value_type_[i])
+ {
+ case FOO_B_STAT_LONG:
+ {
+ unsigned actual_size
+ = this->actual_in_long_[i].size ();
+ unsigned expected_size
+ = this->num_clients_ * stats.expected_op_count_[i];
+ if (actual_size != expected_size)
+ {
+ return false;
+ }
+ sort (this->actual_in_long_[i]);
+
+ for (unsigned j = 0; j < actual_size - 1; j++)
+ {
+ if (this->actual_in_long_[i][j] != this->actual_in_long_[i][j + 1] - 1)
+ {
+ return false;
+ }
+ }
+ }
+ break;
+
+ case FOO_B_STAT_STRING:
+ {
+ unsigned actual_size
+ = this->actual_in_string_[i].size ();
+ unsigned expected_size
+ = this->num_clients_ * stats.expected_op_count_[i];
+ if (actual_size != expected_size)
+ {
+ return false;
+ }
+
+ LongVector lvec;
+ char buffer[50];
+
+ for (unsigned k = 0; k < actual_size; k++)
+ {
+ unsigned client_id;
+ sscanf (this->actual_in_string_[i][k].c_str(), "%d %s", &client_id, buffer);
+ if (ACE_OS::strcmp (buffer, ONEWAY_ARG_TEST_STR) != 0)
+ {
+ return false;
+ }
+ lvec.push_back (client_id);
+ }
+
+ sort (lvec);
+
+ for (unsigned j = 0; j < actual_size - 1; j++)
+ {
+ if (lvec[j] != lvec[j + 1] - 1)
+ {
+ return false;
+ }
+ }
+ }
+ break;
+
+ case FOO_B_STAT_NONE:
+ default:
+ break;
+ }
+
+ }
+
+ return true;
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.h
new file mode 100644
index 00000000000..cf21382c549
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_Statistics.h
@@ -0,0 +1,54 @@
+// $Id$
+#ifndef STATISTICS_B_H
+#define STATISTICS_B_H
+
+#include "CSD_TP_Foo_B_Export.h"
+#include "StatisticsHelper.h"
+
+
+class CSD_TP_Foo_B_Export Foo_B_Statistics
+{
+ public:
+
+ enum In_Value_Type
+ {
+ FOO_B_STAT_NONE,
+ FOO_B_STAT_STRING,
+ FOO_B_STAT_LONG
+ };
+
+ Foo_B_Statistics(unsigned num_remote_clients,
+ unsigned num_collcated_clients);
+
+ virtual ~Foo_B_Statistics();
+
+ void expected(unsigned op_num, unsigned count, In_Value_Type type);
+ void actual(unsigned op_num, unsigned count);
+ void actual(unsigned op_num, LongVector lv);
+ void actual(unsigned op_num, StringVector sv);
+ void servant_error_count(unsigned error_count);
+
+ void expected_callbacks (unsigned num_cbs);
+ void actual_callbacks (unsigned num_cbs);
+
+ bool actual_vs_expected();
+
+private:
+
+ unsigned num_clients_;
+ unsigned num_collcated_clients_;
+
+ LongVector actual_in_long_ [16];
+ StringVector actual_in_string_ [16];
+
+ unsigned expected_op_count_[16];
+ unsigned actual_op_count_[16];
+ unsigned expected_in_value_type_[16];
+
+ unsigned expected_callbacks_;
+ unsigned actual_callbacks_;
+
+ unsigned servant_error_count_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.cpp
new file mode 100644
index 00000000000..73105ff1713
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.cpp
@@ -0,0 +1,283 @@
+// $Id$
+#include "Foo_B_i.h"
+#include "AppShutdown.h"
+#include "TestAppExceptionC.h"
+#include "ace/OS.h"
+#include "ace/SString.h"
+
+
+Foo_B_i::Foo_B_i()
+: error_count_ (0)
+{
+ for (unsigned i = 0; i < 16; i++)
+ {
+ op_count_[i] = 0;
+ }
+}
+
+
+Foo_B_i::~Foo_B_i()
+{
+}
+
+
+void
+Foo_B_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[0] ++;
+}
+
+
+void
+Foo_B_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[1] ++;
+ this->in_long_[1].push_back (value);
+}
+
+
+CORBA::Long
+Foo_B_i::op3(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[2] ++;
+ this->in_long_[2].push_back (value);
+ return value;
+}
+
+
+void
+Foo_B_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[3] ++;
+ this->in_long_[3].push_back (value);
+}
+
+
+void
+Foo_B_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ this->op_count_[4] ++;
+ ACE_THROW (FooException());
+}
+
+
+CORBA::Boolean
+Foo_B_i::op6(const TimeOfDay& t,
+ char*& message
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[5] ++;
+ char buf [20];
+ ACE_OS::sprintf (buf, "%s %d:%d:%d", message, t.hour, t.minute, t.second);
+ message = CORBA::string_dup (buf);
+
+ return 1;
+}
+
+
+void
+Foo_B_i::op7(Callback_ptr cb
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException,
+ FooException))
+{
+ this->op_count_[6] ++;
+
+ if (CORBA::is_nil (cb))
+ {
+ error_count_ ++;
+ ACE_THROW (FooException ());
+ }
+ else
+ {
+ cb->test_method (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+
+void
+Foo_B_i::test_unbounded_string_arg(const char* message
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[7] ++;
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_unbounded_string_arg ")
+ // ACE_TEXT("got unbounded string %s\n"),
+ // message));
+ this->in_string_[7].push_back (message);
+}
+
+
+void
+Foo_B_i::test_bounded_string_arg(const char* message
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[8] ++;
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_bounded_string_arg ")
+ // ACE_TEXT("got bounded string %s\n"),
+ // message));
+ this->in_string_[8].push_back (message);
+}
+
+
+void
+Foo_B_i::test_fixed_array_arg(const Fixed_Array message
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[9] ++;
+
+ for (unsigned i = 0; i < 19; i++)
+ {
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_fixed_array_arg ")
+ // ACE_TEXT("got fixed array[i] = %d\n"),
+ // i, message[i]));
+
+ if (message[i] != message[i + 1] -1)
+ {
+ error_count_ ++;
+ break;
+ }
+ }
+
+
+ this->in_long_[9].push_back (message[0]);
+}
+
+
+void
+Foo_B_i::test_bounded_var_size_arg(const Bounded_Var_Size& message
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[10] ++;
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_bounded_var_size_arg ")
+ // ACE_TEXT("got var array chars %s\n"),
+ // message.get_buffer ()));
+ this->in_string_[10].push_back (message.get_buffer ());
+}
+
+
+void
+Foo_B_i::test_unbounded_var_size_arg(const Unbounded_Var_Size& message
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[11] ++;
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_unbounded_var_size_arg ")
+ // ACE_TEXT("got var array chars %s\n"),
+ // message.get_buffer ()));
+ this->in_string_[11].push_back (message.get_buffer ());
+}
+
+
+void
+Foo_B_i::test_fixed_size_arg(const TimeOfDay& t
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_UNUSED_ARG(t);
+
+ this->op_count_[12] ++;
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_fixed_size_arg ")
+ // ACE_TEXT("got timeofday %d:%d:%d\n"),
+ // t.hour, t.minute, t.second));
+}
+
+
+void
+Foo_B_i::test_var_array_arg(const Var_Array messages
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[13] ++;
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_var_array_arg ")
+ // ACE_TEXT(" %s \n"), messages[0].in ()));
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_var_array_arg ")
+ // ACE_TEXT(" %s \n"), messages[1].in ()));
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_var_array_arg ")
+ // ACE_TEXT(" %s \n"), messages[2].in ()));
+ unsigned cur_client_id = 0;
+
+ for (unsigned i = 0 ; i < 3; i ++)
+ {
+ unsigned client_id = 0;
+ unsigned str_id = 0;
+ char test_str[20];
+ sscanf (messages[i].in (), "%d %s %d", &client_id, test_str, &str_id);
+
+ if (str_id != i)
+ {
+ error_count_ ++;
+ }
+
+ if (i == 0)
+ {
+ cur_client_id = client_id;
+ }
+ else if (client_id != cur_client_id)
+ {
+ error_count_ ++;
+ }
+ }
+ this->in_string_[13].push_back (messages[0].in ());
+}
+
+
+void
+Foo_B_i::test_special_basic_arg(CORBA::Boolean value,
+ CORBA::Long client_id
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->op_count_[14] ++;
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_special_basic_arg ")
+ // ACE_TEXT(" got special basic arg: %d \n"), value));
+
+ CORBA::Boolean expected_special_value = client_id % 2;
+ if (expected_special_value != value)
+ {
+ error_count_ ++;
+ }
+}
+
+
+void
+Foo_B_i::test_objref_arg(Callback_ptr cb
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_UNUSED_ARG(cb);
+ this->op_count_[15] ++;
+ //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t)Foo_B_i::test_objref_arg ")
+ // ACE_TEXT(" got callback object. \n")));
+}
+
+
+void
+Foo_B_i::done(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ TheAppShutdown->client_done();
+}
+
+
+void
+Foo_B_i::gather_stats (Foo_B_Statistics& stats)
+{
+ for (unsigned i = 0; i < 16; i++)
+ {
+ stats.actual (i+1, this->op_count_[i]);
+ stats.actual (i+1, this->in_string_[i]);
+ stats.actual (i+1, this->in_long_[i]);
+ stats.servant_error_count (this->error_count_);
+ }
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.h
new file mode 100644
index 00000000000..c6838db5776
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/Foo_B_i.h
@@ -0,0 +1,93 @@
+// $Id$
+#ifndef FOO_B_I_H
+#define FOO_B_I_H
+
+#include "CSD_TP_Foo_B_Export.h"
+#include "Foo_BS.h"
+#include "Foo_B_Statistics.h"
+
+
+class CSD_TP_Foo_B_Export Foo_B_i : public virtual POA_Foo_B,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Foo_B_i();
+ virtual ~Foo_B_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException));
+
+ virtual CORBA::Boolean op6(const TimeOfDay& t,
+ char*& message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op7(Callback_ptr cb
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException,
+ FooException));
+
+ virtual void test_unbounded_string_arg(const char* message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void test_bounded_string_arg(const char* message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void test_fixed_array_arg(const Fixed_Array message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void test_var_array_arg(const Var_Array messages
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void test_bounded_var_size_arg(const Bounded_Var_Size& message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void test_unbounded_var_size_arg(const Unbounded_Var_Size& message
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void test_fixed_size_arg(const TimeOfDay& t
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void test_special_basic_arg(CORBA::Boolean value,
+ CORBA::Long client_id
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void test_objref_arg(Callback_ptr cb
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ void gather_stats (Foo_B_Statistics& stats);
+
+ private:
+
+ LongVector in_long_ [16];
+ StringVector in_string_ [16];
+ unsigned op_count_ [16];
+ unsigned error_count_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/csd_tp_foo_b_lib.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/csd_tp_foo_b_lib.mpc
new file mode 100644
index 00000000000..a9503d73c5a
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_B/csd_tp_foo_b_lib.mpc
@@ -0,0 +1,25 @@
+//$Id$
+project : csd_tp_test_lib {
+ sharedname = CSD_TP_Foo_B
+ dynamicflags = CSD_TP_FOO_B_BUILD_DLL
+ idlflags += -Wb,export_macro=CSD_TP_Foo_B_Export -Wb,export_include=CSD_TP_Foo_B_Export.h
+ includes += $(TAO_ROOT)/tao
+
+ IDL_Files {
+ Foo_B.idl
+ Callback.idl
+ }
+
+ Source_Files {
+ Foo_BC.cpp
+ Foo_BS.cpp
+ Foo_B_ClientEngine.cpp
+ Foo_B_SimpleClientEngine.cpp
+ Foo_B_i.cpp
+ Foo_B_Statistics.cpp
+ Callback_i.cpp
+ CallbackC.cpp
+ CallbackS.cpp
+ }
+
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/CSD_TP_Foo_C_Export.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/CSD_TP_Foo_C_Export.h
new file mode 100644
index 00000000000..ef1996b0a26
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/CSD_TP_Foo_C_Export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s CSD_TP_Foo_C
+// ------------------------------
+#ifndef CSD_TP_FOO_C_EXPORT_H
+#define CSD_TP_FOO_C_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (CSD_TP_FOO_C_HAS_DLL)
+# define CSD_TP_FOO_C_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && CSD_TP_FOO_C_HAS_DLL */
+
+#if !defined (CSD_TP_FOO_C_HAS_DLL)
+# define CSD_TP_FOO_C_HAS_DLL 1
+#endif /* ! CSD_TP_FOO_C_HAS_DLL */
+
+#if defined (CSD_TP_FOO_C_HAS_DLL) && (CSD_TP_FOO_C_HAS_DLL == 1)
+# if defined (CSD_TP_FOO_C_BUILD_DLL)
+# define CSD_TP_Foo_C_Export ACE_Proper_Export_Flag
+# define CSD_TP_FOO_C_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define CSD_TP_FOO_C_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* CSD_TP_FOO_C_BUILD_DLL */
+# define CSD_TP_Foo_C_Export ACE_Proper_Import_Flag
+# define CSD_TP_FOO_C_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define CSD_TP_FOO_C_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* CSD_TP_FOO_C_BUILD_DLL */
+#else /* CSD_TP_FOO_C_HAS_DLL == 1 */
+# define CSD_TP_Foo_C_Export
+# define CSD_TP_FOO_C_SINGLETON_DECLARATION(T)
+# define CSD_TP_FOO_C_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* CSD_TP_FOO_C_HAS_DLL == 1 */
+
+// Set CSD_TP_FOO_C_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (CSD_TP_FOO_C_NTRACE)
+# if (ACE_NTRACE == 1)
+# define CSD_TP_FOO_C_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define CSD_TP_FOO_C_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !CSD_TP_FOO_C_NTRACE */
+
+#if (CSD_TP_FOO_C_NTRACE == 1)
+# define CSD_TP_FOO_C_TRACE(X)
+#else /* (CSD_TP_FOO_C_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define CSD_TP_FOO_C_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (CSD_TP_FOO_C_NTRACE == 1) */
+
+#endif /* CSD_TP_FOO_C_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C.idl b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C.idl
new file mode 100644
index 00000000000..b7eeea96f33
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C.idl
@@ -0,0 +1,29 @@
+// $Id$
+#ifndef FOO_C_IDL
+#define FOO_C_IDL
+
+#include "FooException.idl"
+
+interface Foo_C
+{
+ /// void return-type, no arguments
+ void op1();
+
+ /// void return-type, 1 "in" argument
+ void op2(in long value);
+
+ /// long return-type, 1 "in" argument
+ long op3(in long value);
+
+ /// one-way version of op2
+ oneway void op4(in long value);
+
+ /// Operation that always raises an exception.
+ void op5() raises (FooException);
+
+ /// Client calls this last. The last client to claim that it is
+ /// done will cause the server to shutdown.
+ void done();
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.cpp
new file mode 100644
index 00000000000..fdd8b4e2671
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.cpp
@@ -0,0 +1,92 @@
+// $Id$
+#include "Foo_C_ClientEngine.h"
+#include "AppHelper.h"
+#include "ace/Log_Msg.h"
+
+
+Foo_C_ClientEngine::Foo_C_ClientEngine(Foo_C_ptr obj,
+ unsigned client_id)
+ : obj_(Foo_C::_duplicate(obj)),
+ client_id_ (client_id)
+{
+}
+
+
+Foo_C_ClientEngine::~Foo_C_ClientEngine()
+{
+}
+
+
+bool
+Foo_C_ClientEngine::execute(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Verify the return values and return the results.
+ bool check_validity = true;
+
+ // Make sure the connection is established before making
+ // remote invocations.
+ if (AppHelper::validate_connection (this->obj_.in ()) == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_A_ClientEngine::execute " \
+ "client %d connect failed.\n", this->client_id_));
+ return false;
+ }
+
+ CORBA::Long i = this->client_id_;
+
+ this->obj_->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ this->obj_->op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ CORBA::Long value = this->obj_->op3(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ if (value != i)
+ {
+ check_validity = false;
+ }
+
+ for (CORBA::Long j = 1; j <= 5; j++)
+ {
+ this->obj_->op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ }
+
+ bool caught_exception = false;
+
+ ACE_TRY
+ {
+ this->obj_->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ // Expected
+ caught_exception = true;
+ }
+ ACE_ENDTRY;
+
+ if (! caught_exception)
+ {
+ check_validity = false;
+ }
+
+ this->obj_->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ return check_validity;
+}
+
+
+void
+Foo_C_ClientEngine::expected_results(Foo_C_Statistics& stats)
+{
+ // This ClientEngine is used by remote clients.
+ stats.expected(1, 1, true);
+ stats.expected(2, 1, true);
+ stats.expected(3, 1, true);
+ stats.expected(4, 5, true);
+ stats.expected(5, 1, true);
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.h
new file mode 100644
index 00000000000..54247223f04
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_ClientEngine.h
@@ -0,0 +1,40 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_C_ClientEngine.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_C_CLIENT_ENGINE_H
+#define FOO_C_CLIENT_ENGINE_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "ClientEngine.h"
+#include "Foo_CC.h"
+#include "Foo_C_Statistics.h"
+
+
+class CSD_TP_Foo_C_Export Foo_C_ClientEngine : public ClientEngine
+{
+ public:
+
+ Foo_C_ClientEngine(Foo_C_ptr obj,
+ unsigned client_id);
+ virtual ~Foo_C_ClientEngine();
+
+ virtual bool execute(ACE_ENV_SINGLE_ARG_DECL);
+
+ static void expected_results(Foo_C_Statistics& stats);
+
+ private:
+
+ Foo_C_var obj_;
+ unsigned client_id_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.cpp
new file mode 100644
index 00000000000..da6b44f7c71
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.cpp
@@ -0,0 +1,136 @@
+// $Id$
+#include "Foo_C_Custom_ClientEngine.h"
+#include "CustomExceptionC.h"
+#include "ace/Log_Msg.h"
+
+
+Foo_C_Custom_ClientEngine::Foo_C_Custom_ClientEngine
+ (Foo_C_i* servant,
+ Foo_C_ptr objref,
+ TAO::CSD::TP_Strategy* strategy,
+ unsigned client_id)
+ : proxy_(servant,objref,strategy),
+ client_id_(client_id)
+{
+}
+
+
+Foo_C_Custom_ClientEngine::~Foo_C_Custom_ClientEngine()
+{
+}
+
+
+bool
+Foo_C_Custom_ClientEngine::execute(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Make sure the connection is established before making
+ // remote invocations.
+ if (this->proxy_.validate_connection () == false)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)Foo_A_ClientEngine::execute " \
+ "client %d connect failed.\n", this->client_id_));
+ return false;
+ }
+
+ bool check_validity = true;
+ CORBA::Long i = this->client_id_;
+
+ this->proxy_.op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ this->proxy_.op2(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ CORBA::Long value = this->proxy_.op3(i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ if (value != i)
+ {
+ check_validity = false;
+ }
+
+
+ for (CORBA::Long j = 1; j <= 5; j++)
+ {
+ this->proxy_.op4(495 + (i * 5) + j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ }
+
+ bool caught_exception = false;
+ ACE_TRY_EX (op5)
+ {
+ this->proxy_.op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK_EX (op5);
+ }
+ ACE_CATCH (FooException, ex)
+ {
+ // Expected
+ caught_exception = true;
+ }
+ ACE_ENDTRY;
+
+ if (! caught_exception)
+ {
+ check_validity = false;
+ }
+
+ long cust_i = this->client_id_;
+
+ this->proxy_.cust_op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ this->proxy_.cust_op2(cust_i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ long cust_value = this->proxy_.cust_op3(cust_i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ if (cust_value != i)
+ {
+ check_validity = false;
+ }
+
+ for (long cust_j = 1; cust_j <= 5; cust_j++)
+ {
+ this->proxy_.cust_op4(495 + (cust_i * 5) + cust_j ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+ }
+
+ caught_exception = false;
+
+ ACE_TRY_EX (cust_op5)
+ {
+ this->proxy_.cust_op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK_EX (cust_op5)
+ }
+ ACE_CATCHANY //(CustomException, ex)
+ {
+ // Expected
+ caught_exception = true;
+ }
+ ACE_ENDTRY;
+
+ if (! caught_exception)
+ {
+ check_validity = false;
+ }
+
+ this->proxy_.done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (false);
+
+ return check_validity;
+}
+
+
+void
+Foo_C_Custom_ClientEngine::expected_results(Foo_C_Statistics& stats)
+{
+ // This ClientEngine is used by collocated clients.
+ stats.expected(1, 1, false);
+ stats.expected(2, 1, false);
+ stats.expected(3, 1, false);
+ stats.expected(4, 5, false);
+ stats.expected(5, 1, false);
+ stats.expected(6, 1, false);
+ stats.expected(7, 1, false);
+ stats.expected(8, 1, false);
+ stats.expected(9, 5, false);
+ stats.expected(10, 1, false);
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.h
new file mode 100644
index 00000000000..d797927c042
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_ClientEngine.h
@@ -0,0 +1,42 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_C_ClientEngine.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_C_CUSTOM_CLIENT_ENGINE_H
+#define FOO_C_CUSTOM_CLIENT_ENGINE_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "ClientEngine.h"
+#include "Foo_C_Custom_Proxy.h"
+
+
+class CSD_TP_Foo_C_Export Foo_C_Custom_ClientEngine : public ClientEngine
+{
+ public:
+
+ Foo_C_Custom_ClientEngine(Foo_C_i* servant,
+ Foo_C_ptr objref,
+ TAO::CSD::TP_Strategy* strategy,
+ unsigned client_id);
+ virtual ~Foo_C_Custom_ClientEngine();
+
+ virtual bool execute(ACE_ENV_SINGLE_ARG_DECL);
+
+ static void expected_results(Foo_C_Statistics& stats);
+
+
+ private:
+
+ Foo_C_Custom_Proxy proxy_;
+ unsigned client_id_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.cpp
new file mode 100644
index 00000000000..0fc2e22471a
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.cpp
@@ -0,0 +1,153 @@
+// $Id$
+#include "Foo_C_Custom_Proxy.h"
+#include "Foo_C_cust_op1.h"
+#include "Foo_C_cust_op2.h"
+#include "Foo_C_cust_op3.h"
+#include "Foo_C_cust_op4.h"
+#include "Foo_C_cust_op5.h"
+#include "AppHelper.h"
+
+
+Foo_C_Custom_Proxy::Foo_C_Custom_Proxy(Foo_C_i* servant,
+ Foo_C_ptr objref,
+ TAO::CSD::TP_Strategy* strategy)
+ : servant_(servant),
+ objref_(Foo_C::_duplicate(objref)),
+ strategy_(strategy, false)
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+Foo_C_Custom_Proxy::~Foo_C_Custom_Proxy()
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+bool
+Foo_C_Custom_Proxy::validate_connection ()
+{
+ return AppHelper::validate_connection (this->objref_.in ());
+}
+
+
+void
+Foo_C_Custom_Proxy::op1(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->objref_->op1(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+Foo_C_Custom_Proxy::op2(CORBA::Long x ACE_ENV_ARG_DECL)
+{
+ this->objref_->op2(x ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+CORBA::Long
+Foo_C_Custom_Proxy::op3(CORBA::Long x ACE_ENV_ARG_DECL)
+{
+ CORBA::Long result = this->objref_->op3(x ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+ return result;
+}
+
+
+void
+Foo_C_Custom_Proxy::op4(CORBA::Long x ACE_ENV_ARG_DECL)
+{
+ this->objref_->op4(x ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+Foo_C_Custom_Proxy::op5(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->objref_->op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+Foo_C_Custom_Proxy::done(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->objref_->done(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+Foo_C_Custom_Proxy::cust_op1(ACE_ENV_SINGLE_ARG_DECL)
+{
+ Foo_C_cust_op1_Handle op = new Foo_C_cust_op1(this->servant_);
+ this->strategy_->custom_synch_request(op.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+Foo_C_Custom_Proxy::cust_op2(long x ACE_ENV_ARG_DECL)
+{
+ Foo_C_cust_op2_Handle op = new Foo_C_cust_op2(this->servant_, x);
+ this->strategy_->custom_synch_request(op.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+long
+Foo_C_Custom_Proxy::cust_op3(long x ACE_ENV_ARG_DECL)
+{
+ Foo_C_cust_op3_Handle op = new Foo_C_cust_op3(this->servant_, x);
+ this->strategy_->custom_synch_request(op.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+ int ret = op->result(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+ return ret;
+}
+
+
+void
+Foo_C_Custom_Proxy::cust_op4(long x ACE_ENV_ARG_DECL)
+{
+ Foo_C_cust_op4_Handle op = new Foo_C_cust_op4(this->servant_,x);
+ this->strategy_->custom_asynch_request(op.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+Foo_C_Custom_Proxy::cust_op5(ACE_ENV_SINGLE_ARG_DECL)
+{
+ Foo_C_cust_op5_Handle op = new Foo_C_cust_op5(this->servant_);
+ this->strategy_->custom_synch_request(op.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ op->result(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.h
new file mode 100644
index 00000000000..5cd7eeae55a
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Custom_Proxy.h
@@ -0,0 +1,52 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_C_Custom_Proxy.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_C_CUSTOM_PROXY_H
+#define FOO_C_CUSTOM_PROXY_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "ClientEngine.h"
+#include "Foo_C_i.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+
+
+class CSD_TP_Foo_C_Export Foo_C_Custom_Proxy
+{
+public:
+
+ Foo_C_Custom_Proxy(Foo_C_i* servant,
+ Foo_C_ptr objref,
+ TAO::CSD::TP_Strategy* strategy);
+ ~Foo_C_Custom_Proxy();
+
+ bool validate_connection ();
+
+ void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+ void op2(CORBA::Long x ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+ CORBA::Long op3(CORBA::Long x ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+ void op4(CORBA::Long x ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+ void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+ void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+
+ void cust_op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+ void cust_op2(long x ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+ long cust_op3(long x ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+ void cust_op4(long x ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+ void cust_op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+
+private:
+ Foo_C_i* servant_;
+ Foo_C_var objref_;
+ TAO::CSD::TP_Strategy_Handle strategy_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.cpp
new file mode 100644
index 00000000000..b832e29d9a1
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.cpp
@@ -0,0 +1,111 @@
+// $Id$
+#include "Foo_C_Statistics.h"
+#include "Foo_C_ClientEngine.h"
+#include "Foo_C_Custom_ClientEngine.h"
+
+Foo_C_Statistics::Foo_C_Statistics(unsigned num_remote_clients,
+ unsigned num_collocated_clients)
+: num_remote_clients_ (num_remote_clients),
+ num_collocated_clients_ (num_collocated_clients)
+{
+ for (unsigned i = 0; i < 10; i++)
+ {
+ this->expected_[i] = 0;
+ this->actual_[i] = 0;
+ }
+}
+
+
+Foo_C_Statistics::~Foo_C_Statistics()
+{
+}
+
+
+void
+Foo_C_Statistics::expected(unsigned op_num, unsigned count, bool remote_client)
+{
+ if (remote_client)
+ {
+ this->expected_[op_num-1] += count * this->num_remote_clients_;
+ }
+ else
+ {
+ this->expected_[op_num-1] += count * this->num_collocated_clients_;
+ }
+}
+
+
+void
+Foo_C_Statistics::actual(unsigned op_num, unsigned count)
+{
+ this->actual_[op_num-1] += count;
+}
+
+
+void
+Foo_C_Statistics::actual_in_values(unsigned op_num, LongVector lv)
+{
+ size_t sz = lv.size();
+ for (size_t i = 0; i < sz; i++)
+ {
+ this->actual_in_values_[op_num-1].push_back (lv[i]);
+ }
+}
+
+
+bool
+Foo_C_Statistics::actual_vs_expected()
+{
+ // Get the expected statistics for a single remote client.
+ Foo_C_Statistics remote_client_stats (1, 0);
+ Foo_C_ClientEngine::expected_results (remote_client_stats);
+ // Get the expected statistics for a single collocated client.
+ Foo_C_Statistics collocated_client_stats (0, 1);
+ Foo_C_Custom_ClientEngine::expected_results (collocated_client_stats);
+
+ for (unsigned i = 0; i < 10; i++)
+ {
+ if (this->expected_[i] != this->actual_[i])
+ {
+ return false;
+ }
+
+ // Verify the "in" values.
+ // Skip op1/op5 and cust_op1/cust_op5 since they do not have
+ // any "in" values.
+ if (i % 5 == 0 || i % 5 == 4)
+ {
+ continue;
+ }
+
+ unsigned actual_size
+ = this->actual_in_values_[i].size ();
+ unsigned expected_size
+ = this->num_remote_clients_ * remote_client_stats.expected_[i]
+ + this->num_collocated_clients_ * collocated_client_stats.expected_[i];
+
+ if (actual_size == 0 && expected_size == 0)
+ {
+ continue;
+ }
+
+ if (actual_size != expected_size)
+ {
+ return false;
+ }
+
+ sort (this->actual_in_values_[i]);
+
+ for (unsigned j = 0; j < actual_size - 1; j++)
+ {
+ if (this->actual_in_values_[i][j] != this->actual_in_values_[i][j + 1] - 1)
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.h
new file mode 100644
index 00000000000..4d7dcff1df9
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_Statistics.h
@@ -0,0 +1,35 @@
+// $Id$
+#ifndef STATISTICS_C_H
+#define STATISTICS_C_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "StatisticsHelper.h"
+
+
+class CSD_TP_Foo_C_Export Foo_C_Statistics
+{
+ public:
+
+ Foo_C_Statistics(unsigned num_remote_clients,
+ unsigned num_collocated_clients);
+
+ virtual ~Foo_C_Statistics();
+
+ void expected(unsigned op_num, unsigned count, bool remote_client);
+ void actual(unsigned op_num, unsigned count);
+ void actual_in_values(unsigned op_num, LongVector lv);
+
+ bool actual_vs_expected();
+
+
+ private:
+
+ unsigned num_remote_clients_;
+ unsigned num_collocated_clients_;
+ unsigned expected_[10];
+ unsigned actual_[10];
+
+ LongVector actual_in_values_ [10];
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.cpp
new file mode 100644
index 00000000000..3ca92e4af2e
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.cpp
@@ -0,0 +1,65 @@
+// $Id$
+#include "Foo_C_cust_op1.h"
+#include "Foo_C_i.h"
+#include "CancelledExceptionC.h"
+
+
+Foo_C_cust_op1::Foo_C_cust_op1(Foo_C_i* servant)
+ : TAO::CSD::TP_Custom_Request_Operation(servant),
+ cancelled_(false),
+ servant_(servant)
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+Foo_C_cust_op1::~Foo_C_cust_op1()
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+void
+Foo_C_cust_op1::result(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->cancelled_)
+ {
+ ACE_THROW (CancelledException());
+ }
+}
+
+
+void
+Foo_C_cust_op1::execute_i()
+{
+ this->servant_->cust_op1();
+}
+
+
+void
+Foo_C_cust_op1::cancel_i()
+{
+ this->cancelled_ = true;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.h
new file mode 100644
index 00000000000..553cb27a6d8
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op1.h
@@ -0,0 +1,45 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_C_cust_op1.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_C_CUST_OP1_H
+#define FOO_C_CUST_OP1_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+class Foo_C_i;
+
+class Foo_C_cust_op1;
+typedef TAO_Intrusive_Ref_Count_Handle<Foo_C_cust_op1> Foo_C_cust_op1_Handle;
+
+
+class CSD_TP_Foo_C_Export Foo_C_cust_op1 : public TAO::CSD::TP_Custom_Request_Operation
+{
+ public:
+
+ Foo_C_cust_op1(Foo_C_i* servant);
+ virtual ~Foo_C_cust_op1();
+
+ void result(ACE_ENV_SINGLE_ARG_DECL);
+
+
+ protected:
+ virtual void execute_i();
+ virtual void cancel_i();
+
+ private:
+ bool cancelled_;
+ Foo_C_i* servant_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.cpp
new file mode 100644
index 00000000000..c0bc62fb2f0
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.cpp
@@ -0,0 +1,66 @@
+// $Id$
+#include "Foo_C_cust_op2.h"
+#include "Foo_C_i.h"
+#include "CancelledExceptionC.h"
+
+
+Foo_C_cust_op2::Foo_C_cust_op2(Foo_C_i* servant, long arg)
+ : TAO::CSD::TP_Custom_Request_Operation(servant),
+ arg_(arg),
+ cancelled_(false),
+ servant_(servant)
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+Foo_C_cust_op2::~Foo_C_cust_op2()
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+void
+Foo_C_cust_op2::result(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->cancelled_)
+ {
+ ACE_THROW (CancelledException());
+ }
+}
+
+
+void
+Foo_C_cust_op2::execute_i()
+{
+ this->servant_->cust_op2(this->arg_);
+}
+
+
+void
+Foo_C_cust_op2::cancel_i()
+{
+ this->cancelled_ = true;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.h
new file mode 100644
index 00000000000..8a319e3b50a
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op2.h
@@ -0,0 +1,50 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_C_cust_op2.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_C_CUST_OP2_H
+#define FOO_C_CUST_OP2_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+class Foo_C_i;
+
+class Foo_C_cust_op2;
+typedef TAO_Intrusive_Ref_Count_Handle<Foo_C_cust_op2> Foo_C_cust_op2_Handle;
+
+
+class CSD_TP_Foo_C_Export Foo_C_cust_op2 : public TAO::CSD::TP_Custom_Request_Operation
+{
+ public:
+
+ Foo_C_cust_op2(Foo_C_i* servant, long arg);
+ virtual ~Foo_C_cust_op2();
+
+ void result(ACE_ENV_SINGLE_ARG_DECL);
+
+
+ protected:
+
+ virtual void execute_i();
+ virtual void cancel_i();
+
+
+ private:
+
+ long arg_;
+ bool cancelled_;
+
+ Foo_C_i* servant_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.cpp
new file mode 100644
index 00000000000..b6bfad9dc67
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.cpp
@@ -0,0 +1,69 @@
+// $Id$
+#include "Foo_C_cust_op3.h"
+#include "Foo_C_i.h"
+#include "CancelledExceptionC.h"
+
+
+Foo_C_cust_op3::Foo_C_cust_op3(Foo_C_i* servant, long arg)
+ : TAO::CSD::TP_Custom_Request_Operation(servant),
+ arg_(arg),
+ result_(0),
+ cancelled_(false),
+ servant_(servant)
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+Foo_C_cust_op3::~Foo_C_cust_op3()
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+long
+Foo_C_cust_op3::result(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->cancelled_)
+ {
+ ACE_THROW_RETURN (CancelledException(), -1);
+ }
+
+ return this->result_;
+}
+
+
+void
+Foo_C_cust_op3::execute_i()
+{
+ this->result_ = this->servant_->cust_op3(this->arg_);
+}
+
+
+void
+Foo_C_cust_op3::cancel_i()
+{
+ this->cancelled_ = true;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.h
new file mode 100644
index 00000000000..7e86e3c8a53
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op3.h
@@ -0,0 +1,51 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_C_cust_op3.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_C_CUST_OP3_H
+#define FOO_C_CUST_OP3_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+class Foo_C_i;
+
+class Foo_C_cust_op3;
+typedef TAO_Intrusive_Ref_Count_Handle<Foo_C_cust_op3> Foo_C_cust_op3_Handle;
+
+
+class CSD_TP_Foo_C_Export Foo_C_cust_op3 : public TAO::CSD::TP_Custom_Request_Operation
+{
+ public:
+
+ Foo_C_cust_op3(Foo_C_i* servant, long arg);
+ virtual ~Foo_C_cust_op3();
+
+ long result(ACE_ENV_SINGLE_ARG_DECL);
+
+
+ protected:
+
+ virtual void execute_i();
+ virtual void cancel_i();
+
+
+ private:
+
+ long arg_;
+ long result_;
+ bool cancelled_;
+
+ Foo_C_i* servant_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.cpp
new file mode 100644
index 00000000000..828e841990f
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.cpp
@@ -0,0 +1,52 @@
+// $Id$
+#include "Foo_C_cust_op4.h"
+#include "Foo_C_i.h"
+
+
+Foo_C_cust_op4::Foo_C_cust_op4(Foo_C_i* servant, long arg)
+ : TAO::CSD::TP_Custom_Request_Operation(servant),
+ arg_(arg),
+ servant_(servant)
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+Foo_C_cust_op4::~Foo_C_cust_op4()
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+void
+Foo_C_cust_op4::execute_i()
+{
+ this->servant_->cust_op4(this->arg_);
+}
+
+
+void
+Foo_C_cust_op4::cancel_i()
+{
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.h
new file mode 100644
index 00000000000..1f8e5eeb5db
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op4.h
@@ -0,0 +1,47 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_C_cust_op4.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_C_CUST_OP4_H
+#define FOO_C_CUST_OP4_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+class Foo_C_i;
+
+class Foo_C_cust_op4;
+typedef TAO_Intrusive_Ref_Count_Handle<Foo_C_cust_op4> Foo_C_cust_op4_Handle;
+
+
+class CSD_TP_Foo_C_Export Foo_C_cust_op4 : public TAO::CSD::TP_Custom_Request_Operation
+{
+ public:
+
+ Foo_C_cust_op4(Foo_C_i* servant, long arg);
+ virtual ~Foo_C_cust_op4();
+
+
+ protected:
+
+ virtual void execute_i();
+ virtual void cancel_i();
+
+
+ private:
+
+ long arg_;
+
+ Foo_C_i* servant_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.cpp
new file mode 100644
index 00000000000..6f5b6756dda
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.cpp
@@ -0,0 +1,81 @@
+// $Id$
+#include "Foo_C_cust_op5.h"
+#include "Foo_C_i.h"
+#include "CancelledExceptionC.h"
+#include "CustomExceptionC.h"
+
+
+Foo_C_cust_op5::Foo_C_cust_op5(Foo_C_i* servant)
+ : TAO::CSD::TP_Custom_Request_Operation(servant),
+ exception_(false),
+ cancelled_(false),
+ servant_(servant)
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+Foo_C_cust_op5::~Foo_C_cust_op5()
+{
+ // This try-catch block is not really necessary, but we have to add it to
+ // satisfy the non-exception builds. Since there is actually no exception
+ // raised from _add_ref, we just ignore the exception here.
+ ACE_TRY_NEW_ENV
+ {
+ servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ }
+ ACE_ENDTRY;
+}
+
+
+void
+Foo_C_cust_op5::result(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->cancelled_)
+ {
+ ACE_THROW (CancelledException());
+ }
+
+ if (this->exception_)
+ {
+ ACE_THROW (CustomException());
+ }
+}
+
+
+void
+Foo_C_cust_op5::execute_i()
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->servant_->cust_op5(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (CustomException, ex)
+ {
+ this->exception_ = true;
+ }
+ ACE_ENDTRY;
+}
+
+
+void
+Foo_C_cust_op5::cancel_i()
+{
+ this->cancelled_ = true;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.h
new file mode 100644
index 00000000000..d6963d31bbe
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_cust_op5.h
@@ -0,0 +1,50 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Foo_C_cust_op5.h
+ *
+ * $Id$
+ *
+ * @author Tim Bradley <bradley_t@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef FOO_C_CUST_OP5_H
+#define FOO_C_CUST_OP5_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+
+class Foo_C_i;
+
+class Foo_C_cust_op5;
+typedef TAO_Intrusive_Ref_Count_Handle<Foo_C_cust_op5> Foo_C_cust_op5_Handle;
+
+
+class CSD_TP_Foo_C_Export Foo_C_cust_op5 : public TAO::CSD::TP_Custom_Request_Operation
+{
+ public:
+
+ Foo_C_cust_op5(Foo_C_i* servant);
+ virtual ~Foo_C_cust_op5();
+
+ void result(ACE_ENV_SINGLE_ARG_DECL);
+
+
+ protected:
+
+ virtual void execute_i();
+ virtual void cancel_i();
+
+
+ private:
+
+ bool exception_;
+ bool cancelled_;
+
+ Foo_C_i* servant_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.cpp
new file mode 100644
index 00000000000..25fadd9deef
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.cpp
@@ -0,0 +1,148 @@
+// $Id$
+#include "Foo_C_i.h"
+#include "AppShutdown.h"
+#include "CustomExceptionC.h"
+
+
+Foo_C_i::Foo_C_i()
+{
+ for (unsigned i = 0; i < 10; i++)
+ {
+ this->count_[i] = 0;
+ }
+}
+
+
+Foo_C_i::~Foo_C_i()
+{
+}
+
+
+void
+Foo_C_i::op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ ++this->count_[0];
+}
+
+
+void
+Foo_C_i::op2(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->in_values_[1].push_back (value);
+ ++this->count_[1];
+}
+
+
+CORBA::Long
+Foo_C_i::op3(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->in_values_[2].push_back (value);
+ ++this->count_[2];
+ return value;
+}
+
+
+void
+Foo_C_i::op4(CORBA::Long value ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->in_values_[3].push_back (value);
+ ++this->count_[3];
+}
+
+
+void
+Foo_C_i::op5(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException, FooException))
+{
+ ++this->count_[4];
+ ACE_THROW (FooException());
+}
+
+
+void
+Foo_C_i::done(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ TheAppShutdown->client_done();
+}
+
+
+void
+Foo_C_i::cust_op1(ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+{
+ ++this->count_[5];
+}
+
+
+void
+Foo_C_i::cust_op2(long value ACE_ENV_ARG_DECL_NOT_USED)
+{
+ this->in_values_[6].push_back (value);
+ ++this->count_[6];
+}
+
+
+long
+Foo_C_i::cust_op3(long value ACE_ENV_ARG_DECL_NOT_USED)
+{
+ this->in_values_[7].push_back (value);
+ ++this->count_[7];
+ return value;
+}
+
+
+void
+Foo_C_i::cust_op4(long value ACE_ENV_ARG_DECL_NOT_USED)
+{
+ this->in_values_[8].push_back (value);
+ ++this->count_[8];
+}
+
+
+void
+Foo_C_i::cust_op5(ACE_ENV_SINGLE_ARG_DECL)
+{
+ ++this->count_[9];
+ ACE_THROW (CustomException());
+}
+
+
+void
+Foo_C_i::gather_stats(Foo_C_Statistics& stats)
+{
+ for (unsigned i = 0; i < 10; i++)
+ {
+ stats.actual (i + 1, this->count_[i]);
+ stats.actual_in_values (i + 1, this->in_values_[i]);
+ }
+}
+
+
+void
+Foo_C_i::dump()
+{
+ static unsigned id = 0;
+
+ ++id;
+
+ ACE_DEBUG((LM_DEBUG, "Servant %d Stats:\n", id));
+ ACE_DEBUG((LM_DEBUG, "------------------\n"));
+
+ unsigned i;
+
+ for (i = 0; i < 5; i++)
+ {
+ ACE_DEBUG((LM_DEBUG, "op%d : %d\n", i+1, this->count_[i]));
+ }
+
+ for (i = 5; i < 10; i++)
+ {
+ ACE_DEBUG((LM_DEBUG, "cust_op%d: %d\n", i+1, this->count_[i]));
+ }
+
+ ACE_DEBUG((LM_DEBUG, "------------------\n"));
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.h b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.h
new file mode 100644
index 00000000000..f5de38ef1ce
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/Foo_C_i.h
@@ -0,0 +1,54 @@
+// $Id$
+#ifndef FOO_C_I_H
+#define FOO_C_I_H
+
+#include "CSD_TP_Foo_C_Export.h"
+#include "Foo_CS.h"
+#include "Foo_C_Statistics.h"
+
+
+class CSD_TP_Foo_C_Export Foo_C_i : public virtual POA_Foo_C,
+ public virtual PortableServer::RefCountServantBase
+{
+ public:
+
+ Foo_C_i();
+ virtual ~Foo_C_i();
+
+ virtual void op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op2(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual CORBA::Long op3(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op4(CORBA::Long value ACE_ENV_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ virtual void op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException,
+ FooException));
+
+ virtual void done(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ void cust_op1(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+ void cust_op2(long value ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+ long cust_op3(long value ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+ void cust_op4(long value ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+ void cust_op5(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+
+ void gather_stats(Foo_C_Statistics& stats);
+
+ void dump();
+
+
+ private:
+
+ LongVector in_values_ [10];
+ unsigned count_[10];
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/csd_tp_foo_c_lib.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/csd_tp_foo_c_lib.mpc
new file mode 100644
index 00000000000..bc014925ccf
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Foo_C/csd_tp_foo_c_lib.mpc
@@ -0,0 +1,27 @@
+//$Id$
+project : csd_tp_test_lib {
+ sharedname = CSD_TP_Foo_C
+ dynamicflags = CSD_TP_FOO_C_BUILD_DLL
+ idlflags += -Wb,export_macro=CSD_TP_Foo_C_Export -Wb,export_include=CSD_TP_Foo_C_Export.h
+ includes += $(TAO_ROOT)/tao
+
+ IDL_Files {
+ Foo_C.idl
+ }
+
+ Source_Files {
+ Foo_CC.cpp
+ Foo_CS.cpp
+ Foo_C_ClientEngine.cpp
+ Foo_C_Custom_ClientEngine.cpp
+ Foo_C_Custom_Proxy.cpp
+ Foo_C_cust_op1.cpp
+ Foo_C_cust_op2.cpp
+ Foo_C_cust_op3.cpp
+ Foo_C_cust_op4.cpp
+ Foo_C_cust_op5.cpp
+ Foo_C_i.cpp
+ Foo_C_Statistics.cpp
+ }
+
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_1/CSD_TP_Test_1.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/CSD_TP_Test_1.mpc
new file mode 100644
index 00000000000..02cac4dc7da
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/CSD_TP_Test_1.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_tp_test_exe_a {
+ exename=server_main
+
+ Source_Files {
+ ServerApp.cpp
+ server_main.cpp
+ }
+}
+
+project(*Client): csd_tp_test_exe_a {
+ exename=client_main
+
+ Source_Files {
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.cpp
new file mode 100644
index 00000000000..d51dfbda1b1
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.cpp
@@ -0,0 +1,84 @@
+// $Id$
+#include "ClientApp.h"
+#include "Foo_A_ClientEngine.h"
+#include "AppHelper.h"
+#include "TestAppExceptionC.h"
+#include "ace/Get_Opt.h"
+#include "ace/Log_Msg.h"
+
+
+ClientApp::ClientApp()
+ : TestAppBase("TP_Test_1_Client")
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ // Initialize the ORB before parsing our own args.
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Returns -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+ // Convert the IOR string to a Foo_A object reference.
+ Foo_A_var foo = RefHelper<Foo_A>::string_to_ref(orb.in(),
+ this->ior_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the appropriate client "engine" object.
+ Foo_A_ClientEngine engine(foo.in());
+
+ // Execute the client algorithm
+ result = engine.execute(ACE_ENV_SINGLE_ARG_PARAMETER) ? 0 : -1;
+ ACE_CHECK_RETURN (-1);
+
+ return result;
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ ACE_Get_Opt get_opts(argc, argv, "i:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case '?':
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) usage: %s -i <ior_string>\n",
+ argv[0]));
+ return 1;
+
+ default:
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) usage: %s -i <ior_string>\n",
+ argv[0]));
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.h
new file mode 100644
index 00000000000..1af2e9ff6a6
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ClientApp.h
@@ -0,0 +1,28 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "TestAppBase.h"
+#include "ace/SString.h"
+
+
+class ClientApp : public TestAppBase
+{
+ public:
+
+ ClientApp();
+ virtual ~ClientApp();
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+
+ ACE_CString ior_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.cpp
new file mode 100644
index 00000000000..a386c21d049
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.cpp
@@ -0,0 +1,188 @@
+// $Id$
+#include "ServerApp.h"
+#include "Foo_A_i.h"
+#include "AppHelper.h"
+#include "TestAppExceptionC.h"
+#include "AppShutdown.h"
+#include "ace/Get_Opt.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/Intrusive_Ref_Count_Handle_T.h"
+// To force static load the service.
+#include "tao/CSD_ThreadPool/CSD_ThreadPool.h"
+
+ServerApp::ServerApp()
+ : TestAppBase("TP_Test_1_Server"),
+ num_clients_ (1)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ // Initialize the ORB before parsing our own args.
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Returns -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheAppShutdown->init(orb.in(), num_clients_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Get the Root POA
+ PortableServer::POA_var root_poa =
+ RefHelper<PortableServer::POA>::resolve_initial_ref(orb.in(),
+ "RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Get the POAManager from the Root POA.
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the child POA Policies.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ // Create the child POA
+ PortableServer::POA_var child_poa =
+ AppHelper::create_poa("ChildPoa",
+ root_poa.in(),
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+
+ // Create the thread pool servant dispatching strategy object, and
+ // hold it in a (local) smart pointer variable.
+ TAO_Intrusive_Ref_Count_Handle<TAO::CSD::TP_Strategy> csd_strategy =
+ new TAO::CSD::TP_Strategy();
+
+ // Tell the strategy to apply itself to the child poa.
+ if (csd_strategy->apply_to(child_poa.in() ACE_ENV_ARG_PARAMETER) == false)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to child poa.\n"));
+ return -1;
+ }
+ ACE_CHECK_RETURN (-1);
+
+ // Create the servant object.
+ Foo_A_i* servant = new Foo_A_i();
+
+ // Local smart pointer variable to deal with releasing the reference
+ // to the servant object when the variable falls out of scope.
+ PortableServer::ServantBase_var servant_owner(servant);
+
+ // Obtain the object reference using the servant
+ CORBA::Object_var obj = AppHelper::activate_servant(child_poa.in(),
+ servant
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Stringify and save the object reference to a file
+ AppHelper::ref_to_file(orb.in(),
+ obj.in(),
+ this->ior_filename_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Activate the POA Manager
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is ready. Running the ORB event loop.\n"));
+
+ // Run the ORB event loop.
+ orb->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp ORB event loop has completed.\n"));
+
+ TheAppShutdown->wait ();
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the Root POA.\n"));
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the Root POA.\n"));
+
+ root_poa->destroy(1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the ORB.\n"));
+
+ orb->destroy(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp has completed running successfully.\n"));
+
+ return 0;
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ ACE_Get_Opt get_opts(argc, argv, "o:n:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'o':
+ this->ior_filename_ = get_opts.opt_arg();
+ break;
+
+ case 'n':
+ {
+ int tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Error. -n must be followed by an integer "
+ "value greater than 0.\n"));
+ return -1;
+ }
+
+ this->num_clients_ = tmp;
+ }
+ break;
+
+ case '?':
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) usage: %s -o <ior_filename> -n <num_clients>\n",
+ argv[0]));
+ return 1;
+
+ default:
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) usage: %s -o <ior_filename> -n <num_clients>\n",
+ argv[0]));
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.h
new file mode 100644
index 00000000000..3bfe10e6f0a
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/ServerApp.h
@@ -0,0 +1,30 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "TestAppBase.h"
+#include "ace/SString.h"
+
+
+class ServerApp : public TestAppBase
+{
+ public:
+
+ ServerApp();
+ virtual ~ServerApp();
+
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+
+ ACE_CString ior_filename_;
+ unsigned num_clients_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_1/client_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/client_main.cpp
new file mode 100644
index 00000000000..ae98ca0f6ac
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/client_main.cpp
@@ -0,0 +1,5 @@
+// $Id$
+#include "ClientApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ClientApp)
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_1/run_test.pl b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/run_test.pl
new file mode 100755
index 00000000000..e15decb6a63
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/run_test.pl
@@ -0,0 +1,55 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+$iorfile = PerlACE::LocalFile ("server.ior");
+unlink $iorfile;
+$status = 0;
+
+$num_clients=40;
+
+$SV = new PerlACE::Process ("server_main", "-o $iorfile -n $num_clients");
+
+$SV->Spawn ();
+
+if (PerlACE::waitforfile_timed ($iorfile,
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ @CLS[$i] = new PerlACE::Process ("client_main", " -i file://$iorfile");
+
+ @CLS[$i]->Spawn ();
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ $client = @CLS[$i]->WaitKill (60);
+
+ if ($client != 0) {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill (60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+unlink $iorfile;
+
+exit $status;
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_1/server_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/server_main.cpp
new file mode 100644
index 00000000000..82e987f6d41
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_1/server_main.cpp
@@ -0,0 +1,5 @@
+// $Id$
+#include "ServerApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ServerApp)
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_2/CSD_TP_Test_2.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/CSD_TP_Test_2.mpc
new file mode 100644
index 00000000000..02cac4dc7da
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/CSD_TP_Test_2.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_tp_test_exe_a {
+ exename=server_main
+
+ Source_Files {
+ ServerApp.cpp
+ server_main.cpp
+ }
+}
+
+project(*Client): csd_tp_test_exe_a {
+ exename=client_main
+
+ Source_Files {
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.cpp
new file mode 100644
index 00000000000..531dba15f17
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.cpp
@@ -0,0 +1,196 @@
+// $Id$
+#include "ClientApp.h"
+#include "AppHelper.h"
+#include "TestAppExceptionC.h"
+#include "Foo_A_ClientEngine.h"
+#include "ace/Get_Opt.h"
+
+
+ClientApp::ClientApp()
+ : TestAppBase("TP_Test_2_Client"),
+ ior_("Not Set"),
+ client_kind_(0),
+ client_id_(0)
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ this->client_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ result = this->run_engine(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->cleanup();
+ return result;
+}
+
+
+int
+ClientApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ return this->parse_args(argc, argv);
+}
+
+
+void
+ClientApp::client_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Turn the ior_ into a Foo_A obj ref.
+ Foo_A_var foo = RefHelper<Foo_A>::string_to_ref(this->orb_.in(),
+ this->ior_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Create the ClientEngine object, and give it the Foo_A obj ref.
+ this->engine_ = new Foo_A_ClientEngine(foo.in(), this->client_id_);
+}
+
+
+int
+ClientApp::run_engine(ACE_ENV_SINGLE_ARG_DECL)
+{
+ bool result = this->engine_->execute(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ return result ? 0 : -1;
+}
+
+
+void
+ClientApp::cleanup()
+{
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:k:n:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case 'k':
+ result = set_arg(this->client_kind_,
+ get_opts.opt_arg(),
+ c,
+ "client_kind");
+ break;
+
+ case 'n':
+ result = set_arg(this->client_id_,
+ get_opts.opt_arg(),
+ c,
+ "client_id");
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-k <client_kind>]\n"
+ "\t[-n <client_id>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ClientApp::arg_dependency_checks()
+{
+ if (this->ior_ == "Not Set")
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Missing required command-line option (-i <ior>).\n"));
+ this->usage_statement();
+ return -1;
+ }
+
+ if (this->client_id_ <= 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Invalid command-line option (-n <client id>). \n"
+ " The client id should be positive integer. \n"));
+ this->usage_statement();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+ClientApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+ return 0;
+}
+
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.h
new file mode 100644
index 00000000000..d5bb80cf800
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ClientApp.h
@@ -0,0 +1,51 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "TestAppBase.h"
+#include "ClientEngine.h"
+#include "tao/ORB.h"
+#include "ace/SString.h"
+
+
+class ClientApp : public TestAppBase
+{
+ public:
+
+ ClientApp();
+ virtual ~ClientApp();
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void client_setup(ACE_ENV_SINGLE_ARG_DECL);
+ int run_engine(ACE_ENV_SINGLE_ARG_DECL);
+ void cleanup();
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+
+ CORBA::ORB_var orb_;
+ ACE_CString exe_name_;
+ ACE_CString ior_;
+ unsigned client_kind_;
+ ClientEngine_Handle engine_;
+ unsigned client_id_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.cpp
new file mode 100644
index 00000000000..8219f7bf2f1
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.cpp
@@ -0,0 +1,368 @@
+// $Id$
+#include "ServerApp.h"
+#include "AppHelper.h"
+#include "OrbRunner.h"
+#include "AppShutdown.h"
+#include "TestAppExceptionC.h"
+#include "Foo_A_ClientEngine.h"
+#include "ace/OS.h"
+#include "ace/Get_Opt.h"
+// To force static load the service.
+#include "tao/CSD_ThreadPool/CSD_ThreadPool.h"
+
+ServerApp::ServerApp()
+ : TestAppBase("TP_Test_2_Server"),
+ ior_filename_prefix_("foo"),
+ num_servants_(1),
+ num_csd_threads_(1),
+ num_orb_threads_(1),
+ num_remote_clients_(1),
+ num_collocated_clients_(0),
+ collocated_client_kind_(0)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ this->poa_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->csd_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->servant_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->collocated_setup();
+ this->poa_activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_collocated_clients(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_orb_event_loop(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ this->cleanup();
+ return this->check_validity () ? 0 : -1;
+}
+
+
+int
+ServerApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+
+ if (result != 0)
+ {
+ return result;
+ }
+
+ unsigned num_clients = this->num_remote_clients_ +
+ this->num_collocated_clients_;
+
+ TheAppShutdown->init (this->orb_.in (), num_clients ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ return 0;
+}
+
+
+void
+ServerApp::poa_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->poa_ = this->create_poa(this->orb_.in(),
+ "ChildPoa"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::csd_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->tp_strategy_ = new TAO::CSD::TP_Strategy(this->num_csd_threads_);
+
+ if (!this->tp_strategy_->apply_to(this->poa_.in() ACE_ENV_ARG_PARAMETER))
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to poa.\n"));
+ ACE_THROW(TestAppException());
+ }
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::servant_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->servants_.create_and_activate(this->num_servants_,
+ this->orb_.in (),
+ this->poa_.in (),
+ this->ior_filename_prefix_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::collocated_setup()
+{
+ int client_id_start = this->num_remote_clients_;
+ for (unsigned i = 0; i < this->num_collocated_clients_; i++)
+ {
+ // Dole out the servant object references in a round-robin fashion.
+ unsigned servant_index = i % this->num_servants_;
+
+ ServantListType::T_stub_var obj = this->servants_.objref(servant_index);
+ ClientEngine_Handle engine = new Foo_A_ClientEngine(obj.in(), ++client_id_start, true);
+ this->collocated_client_task_.add_engine(engine.in());
+ }
+}
+
+
+void
+ServerApp::poa_activate(ACE_ENV_SINGLE_ARG_DECL)
+{
+ PortableServer::POAManager_var poa_manager
+ = this->poa_->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->num_collocated_clients_ > 0)
+ {
+ if (this->collocated_client_task_.open() == -1)
+ {
+ ACE_THROW (TestAppException ());
+ }
+ }
+}
+
+
+void
+ServerApp::run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL)
+{
+ OrbRunner orb_runner(this->orb_.in(), this->num_orb_threads_);
+ orb_runner.run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ TheAppShutdown->wait ();
+}
+
+
+void
+ServerApp::cleanup()
+{
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "p:s:n:t:r:c:k:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'p':
+ this->ior_filename_prefix_ = get_opts.opt_arg();
+ break;
+
+ case 's':
+ result = this->set_arg(this->num_servants_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 'n':
+ result = this->set_arg(this->num_csd_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 't':
+ result = this->set_arg(this->num_orb_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_orb_threads",
+ 1);
+ break;
+
+ case 'r':
+ result = this->set_arg(this->num_remote_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_remote_clients");
+ break;
+
+ case 'c':
+ result = this->set_arg(this->num_collocated_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_collocated_clients");
+ break;
+
+ case 'k':
+ result = this->set_arg(this->collocated_client_kind_,
+ get_opts.opt_arg(),
+ c,
+ "collocated_client_kind");
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-p <ior_filename_prefix>]\n"
+ "\t[-s <num_servants>]\n"
+ "\t[-n <num_csd_threads>]\n"
+ "\t[-t <num_orb_threads>]\n"
+ "\t[-r <num_remote_clients>]\n"
+ "\t[-c <num_collocated_clients>]\n"
+ "\t[-k <collocated_client_kind>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ServerApp::arg_dependency_checks()
+{
+ return (this->num_remote_clients_
+ + this->num_collocated_clients_) > 0 ? 0 : -1;
+}
+
+
+int
+ServerApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+ return 0;
+}
+
+
+PortableServer::POA_ptr
+ServerApp::create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL)
+{
+ // Get the Root POA.
+ PortableServer::POA_var root_poa
+ = RefHelper<PortableServer::POA>::resolve_initial_ref(orb,
+ "RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Get the POAManager from the Root POA.
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Create the child POA Policies.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ // Create the child POA
+ PortableServer::POA_var poa = AppHelper::create_poa(poa_name,
+ root_poa.in(),
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Give away the child POA_ptr from the POA_var variable.
+ return poa._retn();
+}
+
+
+bool
+ServerApp::check_validity ()
+{
+ // Check whether the clients return any errors.
+ if (this->num_collocated_clients_ > 0
+ && this->collocated_client_task_.failure_count () > 0)
+ {
+ return false;
+ }
+
+ unsigned num_clients = this->num_remote_clients_ +
+ this->num_collocated_clients_;
+
+ Foo_A_Statistics stats (num_clients);
+
+ Foo_A_ClientEngine::expected_results (stats);
+
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ this->servants_.servant(i)->gather_stats(stats);
+ }
+
+ return stats.actual_vs_expected ();
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.h
new file mode 100644
index 00000000000..73b5ccbbd94
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/ServerApp.h
@@ -0,0 +1,79 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "TestAppBase.h"
+#include "Foo_A_i.h"
+#include "ServantList_T.h"
+#include "ClientTask.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "ace/SString.h"
+
+
+class ServerApp : public TestAppBase
+{
+ public:
+
+ ServerApp();
+ virtual ~ServerApp();
+
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void poa_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void csd_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void servant_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void collocated_setup();
+ void poa_activate(ACE_ENV_SINGLE_ARG_DECL);
+ void run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL);
+ void run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL);
+ bool check_validity ();
+ void cleanup();
+
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+
+ PortableServer::POA_ptr create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL);
+
+ typedef ServantList<Foo_A_i> ServantListType;
+
+ CORBA::ORB_var orb_;
+ PortableServer::POA_var poa_;
+ TAO::CSD::TP_Strategy_Handle tp_strategy_;
+
+ ServantListType servants_;
+
+ ClientTask collocated_client_task_;
+
+ ACE_CString exe_name_;
+
+ ACE_CString ior_filename_prefix_;
+ unsigned num_servants_;
+ unsigned num_csd_threads_;
+ unsigned num_orb_threads_;
+ unsigned num_remote_clients_;
+ unsigned num_collocated_clients_;
+ unsigned collocated_client_kind_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_2/client_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/client_main.cpp
new file mode 100644
index 00000000000..3814bef5ff9
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/client_main.cpp
@@ -0,0 +1,7 @@
+// $Id$
+#include "ClientApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ClientApp)
+
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_2/run_test.pl b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/run_test.pl
new file mode 100755
index 00000000000..a0daa50592b
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/run_test.pl
@@ -0,0 +1,173 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+my $status = 0;
+
+my $iorfname_prefix = "servant";
+my $num_servants = 1;
+my $num_orb_threads = 1;
+my $num_remote_clients = 1;
+my $num_csd_threads = 1;
+my $num_collocated_clients = 0;
+my $collocated_client_kind = 0;
+my $client_kind = 0;
+
+my $i;
+my $j;
+my @iorfile;
+
+my $ARGC = @ARGV;
+
+if ($ARGC > 0)
+{
+ if ($ARGC > 1)
+ {
+ print STDERR "ERROR: Too many command-line arguments for $0.\n";
+ exit 1;
+ }
+
+ my $subtest = $ARGV[0];
+
+ if ($subtest eq 'remote')
+ {
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'collocated')
+ {
+ $num_remote_clients = 0;
+ $num_collocated_clients = 1;
+ }
+ elsif ($subtest eq 'remote_orbthreads')
+ {
+ $num_orb_threads = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_servants')
+ {
+ $num_servants = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_csdthreads')
+ {
+ $num_csd_threads = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ $num_collocated_clients = 40;
+ }
+ elsif ($subtest eq 'usage')
+ {
+ print STDOUT "Usage: $0 [<subtest>]\n" .
+ "\n" .
+ "Supported <subtest> values:\n" .
+ "\n" .
+ "\tremote\n" .
+ "\tcollocated\n" .
+ "\tremote_orbthreads\n" .
+ "\tremote_servants\n" .
+ "\tremote_csdthreads\n" .
+ "\tremote_big\n" .
+ "\tusage\n" .
+ "\n";
+ exit 0;
+ }
+ else
+ {
+ print STDERR "ERROR: invalid subtest argument for $0: $subtest\n";
+ exit 1;
+ }
+}
+
+#Delete old ior files.
+for ($i = 0; $i < $num_servants; $i++) {
+ my $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+ unlink $iorfile[$i];
+}
+
+$SV = new PerlACE::Process("server_main",
+ "-p $iorfname_prefix " .
+ "-s $num_servants " .
+ "-n $num_csd_threads " .
+ "-t $num_orb_threads " .
+ "-r $num_remote_clients " .
+ "-c $num_collocated_clients " .
+ "-k $collocated_client_kind");
+
+$SV->Spawn();
+
+
+# Wait for the servant ior files created by server.
+for ($i = 0; $i < $num_servants; $i++) {
+ if (PerlACE::waitforfile_timed
+ ($iorfile[$i],
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile[$i]>\n";
+ $SV->Kill();
+ $SV->TimedWait(1);
+ exit 1;
+ }
+}
+
+
+my $count = 0;
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+
+ $client_id = $i+1;
+
+ $j = $i % $num_servants;
+
+ $CLS[$i] = new PerlACE::Process("client_main",
+ "-i file://$iorfile[$j] ".
+ "-k $client_kind ".
+ "-n $client_id");
+
+ $CLS[$i]->Spawn();
+}
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+ $client = $CLS[$i]->WaitKill(60);
+
+ if ($client != 0)
+ {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill(60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+#Delete ior files generated by this run.
+for ($i = 0; $i < $num_servants; $i++) {
+ unlink $iorfile[$i];
+}
+
+exit $status;
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_2/server_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/server_main.cpp
new file mode 100644
index 00000000000..0be257accae
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_2/server_main.cpp
@@ -0,0 +1,7 @@
+// $Id$
+#include "ServerApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ServerApp)
+
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_3/CSD_TP_Test_3.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/CSD_TP_Test_3.mpc
new file mode 100644
index 00000000000..016caef75ef
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/CSD_TP_Test_3.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_tp_test_exe_b {
+ exename=server_main
+
+ Source_Files {
+ ServerApp.cpp
+ server_main.cpp
+ }
+}
+
+project(*Client): csd_tp_test_exe_b {
+ exename=client_main
+
+ Source_Files {
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.cpp
new file mode 100644
index 00000000000..85ddc34bb47
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.cpp
@@ -0,0 +1,318 @@
+// $Id$
+#include "ClientApp.h"
+#include "AppHelper.h"
+#include "OrbRunner.h"
+#include "AppShutdown.h"
+#include "TestAppExceptionC.h"
+#include "Foo_B_ClientEngine.h"
+#include "ace/Get_Opt.h"
+// To force static load the service.
+#include "tao/CSD_ThreadPool/CSD_ThreadPool.h"
+
+ClientApp::ClientApp()
+: TestAppBase("TP_Test_3_Client"),
+ client_task_ (true), // shutdown orb after client is done.
+ num_servants_ (1),
+ num_csd_threads_ (1),
+ num_orb_threads_ (1),
+ ior_("Not Set"),
+ client_kind_(0),
+ client_id_(0)
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ if (result != 0)
+ {
+ return result;
+ }
+ ACE_CHECK_RETURN (-1);
+
+ this->poa_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->csd_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->client_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->poa_activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_clients();
+ this->run_orb_event_loop(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ result = this->check_validity () ? 0 : -1;
+ this->cleanup();
+
+ return result;
+}
+
+
+int
+ClientApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheAppShutdown->init(this->orb_.in(), num_servants_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ return 0;
+}
+
+
+void
+ClientApp::poa_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->poa_ = this->create_poa(this->orb_.in(),
+ "ChildPoa"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ClientApp::csd_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->tp_strategy_ = new TAO::CSD::TP_Strategy(this->num_csd_threads_);
+
+ if (!this->tp_strategy_->apply_to(this->poa_.in() ACE_ENV_ARG_PARAMETER))
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to poa.\n"));
+ ACE_THROW(TestAppException());
+ }
+ ACE_CHECK;
+}
+
+
+void
+ClientApp::client_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Turn the ior_ into a Foo_B obj ref.
+ Foo_B_var foo = RefHelper<Foo_B>::string_to_ref(this->orb_.in(),
+ this->ior_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->servants_.create_and_activate(1, // number of callback servants
+ this->poa_.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ ServantListType::T_stub_var cb = this->servants_.objref(0);
+
+ // Create the ClientEngine object, and give it the Foo_B and Callback object
+ // references.
+ ClientEngine_Handle engine
+ = new Foo_B_ClientEngine(foo.in(), cb.in (), this->client_id_);
+ this->client_task_.add_engine(engine.in());
+}
+
+
+void
+ClientApp::poa_activate(ACE_ENV_SINGLE_ARG_DECL)
+{
+ PortableServer::POAManager_var poa_manager
+ = this->poa_->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ClientApp::run_clients()
+{
+ this->client_task_.open();
+}
+
+
+void
+ClientApp::run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL)
+{
+ OrbRunner orb_runner(this->orb_.in(), this->num_orb_threads_);
+ orb_runner.run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ TheAppShutdown->wait ();
+}
+
+
+PortableServer::POA_ptr
+ClientApp::create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL)
+{
+ // Get the Root POA.
+ PortableServer::POA_var root_poa
+ = RefHelper<PortableServer::POA>::resolve_initial_ref(orb,
+ "RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Get the POAManager from the Root POA.
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Create the child POA Policies.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ // Create the child POA
+ PortableServer::POA_var poa = AppHelper::create_poa(poa_name,
+ root_poa.in(),
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Give away the child POA_ptr from the POA_var variable.
+ return poa._retn();
+}
+
+
+void
+ClientApp::cleanup()
+{
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:k:n:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case 'k':
+ result = set_arg(this->client_kind_,
+ get_opts.opt_arg(),
+ c,
+ "client_kind");
+ break;
+
+ case 'n':
+ result = set_arg(this->client_id_,
+ get_opts.opt_arg(),
+ c,
+ "client_id");
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-k <client_kind>]\n"
+ "\t[-n <client_id>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ClientApp::arg_dependency_checks()
+{
+ if (this->ior_ == "Not Set")
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Missing required command-line option (-i <ior>).\n"));
+ this->usage_statement();
+ return -1;
+ }
+ if (this->client_id_ <= 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Invalid command-line option (-n <client id>). \n"
+ " The client id should be positive integer. \n"));
+ this->usage_statement();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+ClientApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+ return 0;
+}
+
+
+bool
+ClientApp::check_validity ()
+{
+ // Check whether the clients return any errors.
+ if (this->client_task_.failure_count () > 0)
+ {
+ return false;
+ }
+
+ return true;
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.h
new file mode 100644
index 00000000000..2eb6f23bd39
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ClientApp.h
@@ -0,0 +1,78 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "TestAppBase.h"
+#include "ClientEngine.h"
+#include "ServantList_T.h"
+#include "Callback_i.h"
+#include "ClientTask.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "tao/ORB.h"
+#include "ace/SString.h"
+
+
+class ClientApp : public TestAppBase
+{
+ public:
+
+ ClientApp();
+ virtual ~ClientApp();
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void poa_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void csd_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void client_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void poa_activate(ACE_ENV_SINGLE_ARG_DECL);
+ void run_clients();
+ void run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL);
+ bool check_validity ();
+ void cleanup();
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+ PortableServer::POA_ptr create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL);
+
+
+ typedef ServantList<Callback_i> ServantListType;
+
+ CORBA::ORB_var orb_;
+ PortableServer::POA_var poa_;
+ TAO::CSD::TP_Strategy_Handle tp_strategy_;
+
+ ServantListType servants_;
+
+ ClientTask client_task_;
+
+ ACE_CString exe_name_;
+
+ unsigned num_servants_;
+ unsigned num_csd_threads_;
+ unsigned num_orb_threads_;
+
+ ACE_CString ior_;
+ unsigned client_kind_;
+ unsigned client_id_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.cpp
new file mode 100644
index 00000000000..3366a6abd73
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.cpp
@@ -0,0 +1,408 @@
+// $Id$
+#include "ServerApp.h"
+#include "AppHelper.h"
+#include "OrbRunner.h"
+#include "AppShutdown.h"
+#include "TestAppExceptionC.h"
+#include "Foo_B_ClientEngine.h"
+#include "Foo_B_ClientEngine.h"
+#include "Callback_i.h"
+#include "ace/OS.h"
+#include "ace/Get_Opt.h"
+// To force static load the service.
+#include "tao/CSD_ThreadPool/CSD_ThreadPool.h"
+
+ServerApp::ServerApp()
+ : TestAppBase("TP_Test_3_Server"),
+ ior_filename_prefix_("foo"),
+ num_servants_(1),
+ num_csd_threads_(1),
+ num_orb_threads_(1),
+ num_remote_clients_(1),
+ num_collocated_clients_(0),
+ collocated_client_kind_(0)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ if (result != 0)
+ {
+ return result;
+ }
+ ACE_CHECK_RETURN (-1);
+
+ this->poa_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->csd_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->servant_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->collocated_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->poa_activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_collocated_clients(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_orb_event_loop(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->cleanup();
+ return this->check_validity () ? 0 : -1;
+}
+
+
+int
+ServerApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ unsigned num_clients = this->num_remote_clients_ +
+ this->num_collocated_clients_;
+
+ TheAppShutdown->init(this->orb_.in(), num_clients ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ return 0;
+}
+
+
+void
+ServerApp::poa_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->poa_ = this->create_poa(this->orb_.in(),
+ "ChildPoa"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->num_collocated_clients_ > 0)
+ {
+ this->cb_poa_ = this->create_poa(this->orb_.in(),
+ "CallbackPoa"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+void
+ServerApp::csd_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->tp_strategy_ = new TAO::CSD::TP_Strategy(this->num_csd_threads_);
+
+ if (!this->tp_strategy_->apply_to(this->poa_.in() ACE_ENV_ARG_PARAMETER))
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to poa.\n"));
+ ACE_THROW(TestAppException());
+ }
+ ACE_CHECK;
+
+ // Use another poa and strategy for callbacks. This would resolve
+ // the deadlock situation that happens when having number of csd
+ // threads less than number of collocated clients.
+ if (this->num_collocated_clients_ > 0)
+ {
+ this->cb_tp_strategy_ = new TAO::CSD::TP_Strategy();
+ if (!this->cb_tp_strategy_->apply_to(this->cb_poa_.in() ACE_ENV_ARG_PARAMETER))
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to callback poa.\n"));
+ ACE_THROW(TestAppException());
+ }
+ ACE_CHECK;
+ }
+}
+
+
+void
+ServerApp::servant_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->foo_servants_.create_and_activate(this->num_servants_,
+ this->orb_.in (),
+ this->poa_.in (),
+ this->ior_filename_prefix_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::collocated_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->num_collocated_clients_ == 0)
+ return;
+
+ this->cb_servants_.create_and_activate(1, // number of callback servants
+ this->cb_poa_.in()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CallbackServantListType::T_stub_var cb = this->cb_servants_.objref(0);
+
+ unsigned client_id = this->num_remote_clients_;
+
+ for (unsigned i = 0; i < this->num_collocated_clients_; i++)
+ {
+ client_id ++;
+ // Dole out the servant object references in a round-robin fashion.
+ unsigned servant_index = i % this->num_servants_;
+
+ FooServantListType::T_stub_var foo
+ = this->foo_servants_.objref(servant_index);
+ ClientEngine_Handle engine
+ = new Foo_B_ClientEngine(foo.in(), cb.in (), client_id, true);
+ this->collocated_client_task_.add_engine(engine.in());
+ }
+}
+
+
+void
+ServerApp::poa_activate(ACE_ENV_SINGLE_ARG_DECL)
+{
+ PortableServer::POAManager_var poa_manager
+ = this->poa_->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->num_collocated_clients_ > 0)
+ {
+ if (this->collocated_client_task_.open() == -1)
+ {
+ ACE_THROW (TestAppException ());
+ }
+ }
+}
+
+
+void
+ServerApp::run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL)
+{
+ OrbRunner orb_runner(this->orb_.in(), this->num_orb_threads_);
+ orb_runner.run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ TheAppShutdown->wait ();
+}
+
+
+void
+ServerApp::cleanup()
+{
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "p:s:n:t:r:c:k:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'p':
+ this->ior_filename_prefix_ = get_opts.opt_arg();
+ break;
+
+ case 's':
+ result = set_arg(this->num_servants_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 'n':
+ result = set_arg(this->num_csd_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 't':
+ result = set_arg(this->num_orb_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_orb_threads",
+ 1);
+ break;
+
+ case 'r':
+ result = set_arg(this->num_remote_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_remote_clients");
+ break;
+
+ case 'c':
+ result = set_arg(this->num_collocated_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_collocated_clients");
+ break;
+
+ case 'k':
+ result = set_arg(this->collocated_client_kind_,
+ get_opts.opt_arg(),
+ c,
+ "collocated_client_kind");
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-p <ior_filename_prefix>]\n"
+ "\t[-s <num_servants>]\n"
+ "\t[-n <num_csd_threads>]\n"
+ "\t[-t <num_orb_threads>]\n"
+ "\t[-r <num_remote_clients>]\n"
+ "\t[-c <num_collocated_clients>]\n"
+ "\t[-k <collocated_client_kind>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ServerApp::arg_dependency_checks()
+{
+ return (this->num_remote_clients_
+ + this->num_collocated_clients_) > 0 ? 0 : -1;
+}
+
+
+int
+ServerApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+ return 0;
+}
+
+
+PortableServer::POA_ptr
+ServerApp::create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL)
+{
+ // Get the Root POA.
+ PortableServer::POA_var root_poa
+ = RefHelper<PortableServer::POA>::resolve_initial_ref(orb,
+ "RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Get the POAManager from the Root POA.
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Create the child POA Policies.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ // Create the child POA
+ PortableServer::POA_var poa = AppHelper::create_poa(poa_name,
+ root_poa.in(),
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Give away the child POA_ptr from the POA_var variable.
+ return poa._retn();
+}
+
+
+bool
+ServerApp::check_validity ()
+{
+ // Check whether the clients return any errors.
+ if (this->num_collocated_clients_ > 0
+ && this->collocated_client_task_.failure_count () > 0)
+ {
+ return false;
+ }
+
+ Foo_B_Statistics stats (this->num_remote_clients_,
+ this->num_collocated_clients_);
+
+ Foo_B_ClientEngine::expected_results (stats);
+
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ this->foo_servants_.servant(i)->gather_stats (stats);
+ }
+
+ if (this->num_collocated_clients_ > 0)
+ {
+ this->cb_servants_.servant (0)->gather_stats (stats);
+ }
+
+ return stats.actual_vs_expected ();
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.h
new file mode 100644
index 00000000000..12af1ec455b
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/ServerApp.h
@@ -0,0 +1,85 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "TestAppBase.h"
+#include "ServantList_T.h"
+#include "ClientTask.h"
+#include "Foo_B_i.h"
+#include "Callback_i.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "ace/SString.h"
+
+
+class ServerApp : public TestAppBase
+{
+ public:
+
+ ServerApp();
+ virtual ~ServerApp();
+
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void poa_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void csd_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void servant_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void collocated_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void poa_activate(ACE_ENV_SINGLE_ARG_DECL);
+ void run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL);
+ void run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL);
+ bool check_validity ();
+ void cleanup();
+
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+
+ PortableServer::POA_ptr create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL);
+
+ typedef ServantList<Foo_B_i> FooServantListType;
+ typedef ServantList<Callback_i> CallbackServantListType;
+
+ CORBA::ORB_var orb_;
+ PortableServer::POA_var poa_;
+ TAO::CSD::TP_Strategy_Handle tp_strategy_;
+
+ PortableServer::POA_var cb_poa_;
+ TAO::CSD::TP_Strategy_Handle cb_tp_strategy_;
+
+ FooServantListType foo_servants_;
+ CallbackServantListType cb_servants_;
+
+ ClientTask collocated_client_task_;
+
+ ACE_CString exe_name_;
+
+ ACE_CString ior_filename_prefix_;
+ unsigned num_servants_;
+ unsigned num_csd_threads_;
+ unsigned num_orb_threads_;
+ unsigned num_remote_clients_;
+ unsigned num_collocated_clients_;
+ unsigned collocated_client_kind_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_3/client_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/client_main.cpp
new file mode 100644
index 00000000000..3814bef5ff9
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/client_main.cpp
@@ -0,0 +1,7 @@
+// $Id$
+#include "ClientApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ClientApp)
+
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_3/run_test.pl b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/run_test.pl
new file mode 100755
index 00000000000..1fdb29e8cc5
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/run_test.pl
@@ -0,0 +1,170 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+my $status = 0;
+
+my $iorfname_prefix = "servant";
+my $num_servants = 1;
+my $num_orb_threads = 1;
+my $num_remote_clients = 1;
+my $num_csd_threads = 1;
+my $num_collocated_clients = 0;
+my $collocated_client_kind = 0;
+my $client_kind = 0;
+
+my $i;
+my $j;
+my @iorfile;
+
+my $ARGC = @ARGV;
+
+if ($ARGC > 0)
+{
+ if ($ARGC > 1)
+ {
+ print STDERR "ERROR: Too many command-line arguments for $0.\n";
+ exit 1;
+ }
+
+ my $subtest = $ARGV[0];
+
+ if ($subtest eq 'remote')
+ {
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'collocated')
+ {
+ $num_remote_clients = 0;
+ $num_collocated_clients = 1;
+ $num_csd_threads=1;
+ }
+ elsif ($subtest eq 'remote_orbthreads')
+ {
+ $num_orb_threads = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_servants')
+ {
+ $num_servants = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_csdthreads')
+ {
+ $num_csd_threads = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ $num_collocated_clients = 40;
+ }
+ elsif ($subtest eq 'usage')
+ {
+ print STDOUT "Usage: $0 [<subtest>]\n" .
+ "\n" .
+ "Supported <subtest> values:\n" .
+ "\n" .
+ "\tremote\n" .
+ "\tcollocated\n" .
+ "\tremote_orbthreads\n" .
+ "\tremote_servants\n" .
+ "\tremote_csdthreads\n" .
+ "\tremote_big\n" .
+ "\tusage\n" .
+ "\n";
+ exit 0;
+ }
+ else
+ {
+ print STDERR "ERROR: invalid subtest argument for $0: $subtest\n";
+ exit 1;
+ }
+}
+
+#Delete old ior files.
+for ($i = 0; $i < $num_servants; $i++) {
+ my $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+ unlink $iorfile[$i];
+}
+
+$SV = new PerlACE::Process("server_main",
+ "-p $iorfname_prefix " .
+ "-s $num_servants " .
+ "-n $num_csd_threads " .
+ "-t $num_orb_threads " .
+ "-r $num_remote_clients " .
+ "-c $num_collocated_clients " .
+ "-k $collocated_client_kind");
+
+$SV->Spawn();
+
+# Wait for the servant ior files created by server.
+for ($i = 0; $i < $num_servants; $i++) {
+ if (PerlACE::waitforfile_timed
+ ($iorfile[$i],
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile[$i]>\n";
+ $SV->Kill();
+ $SV->TimedWait(1);
+ exit 1;
+ }
+}
+
+my $count = 0;
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+ $client_id = $i + 1;
+
+ $j = $i % $num_servants;
+
+ $CLS[$i] = new PerlACE::Process("client_main",
+ "-i file://$iorfile[$j] ".
+ "-k $client_kind ".
+ "-n $client_id");
+ $CLS[$i]->Spawn();
+}
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+ $client = $CLS[$i]->WaitKill(60);
+
+ if ($client != 0)
+ {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill(60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+#Delete ior files generated by this run.
+for ($i = 0; $i < $num_servants; $i++) {
+ unlink $iorfile[$i];
+}
+
+exit $status;
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_3/server_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/server_main.cpp
new file mode 100644
index 00000000000..82e987f6d41
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_3/server_main.cpp
@@ -0,0 +1,5 @@
+// $Id$
+#include "ServerApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ServerApp)
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_4/CSD_TP_Test_4.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/CSD_TP_Test_4.mpc
new file mode 100644
index 00000000000..ca9f92ac607
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/CSD_TP_Test_4.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_tp_test_exe_c {
+ exename=server_main
+
+ Source_Files {
+ ServerApp.cpp
+ server_main.cpp
+ }
+}
+
+project(*Client): csd_tp_test_exe_c {
+ exename=client_main
+
+ Source_Files {
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.cpp
new file mode 100644
index 00000000000..57520df303c
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.cpp
@@ -0,0 +1,199 @@
+// $Id$
+#include "ClientApp.h"
+#include "AppHelper.h"
+#include "TestAppExceptionC.h"
+#include "Foo_C_ClientEngine.h"
+#include "ace/Get_Opt.h"
+
+
+ClientApp::ClientApp()
+ : TestAppBase("TP_Test_4_Client"),
+ ior_("Not Set"),
+ client_kind_(0),
+ client_id_(0)
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ if (result != 0)
+ {
+ return result;
+ }
+ ACE_CHECK_RETURN (-1);
+
+ this->client_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ result = this->run_engine(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ this->cleanup();
+
+ return result;
+}
+
+
+int
+ClientApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ return this->parse_args(argc, argv);
+}
+
+
+void
+ClientApp::client_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Turn the ior_ into a Foo_C obj ref.
+ Foo_C_var foo = RefHelper<Foo_C>::string_to_ref(this->orb_.in(),
+ this->ior_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Create the ClientEngine object, and give it the Foo_C obj ref.
+ this->engine_ = new Foo_C_ClientEngine(foo.in(), this->client_id_);
+}
+
+
+int
+ClientApp::run_engine(ACE_ENV_SINGLE_ARG_DECL)
+{
+ bool result = this->engine_->execute(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ return result ? 0 : -1;
+}
+
+
+void
+ClientApp::cleanup()
+{
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "i:k:n:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case 'k':
+ result = set_arg(this->client_kind_,
+ get_opts.opt_arg(),
+ c,
+ "client_kind");
+ break;
+
+ case 'n':
+ result = set_arg(this->client_id_,
+ get_opts.opt_arg(),
+ c,
+ "client_id");
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ClientApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-i <ior>]\n"
+ "\t[-k <client_kind>]\n"
+ "\t[-n <client_id>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ClientApp::arg_dependency_checks()
+{
+ if (this->ior_ == "Not Set")
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Missing required command-line option (-i <ior>).\n"));
+ this->usage_statement();
+ return -1;
+ }
+
+ if (this->client_id_ <= 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: Invalid command-line option (-n <client id>). \n"
+ " The client id should be positive integer. \n"));
+ this->usage_statement();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+ClientApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+
+ return 0;
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.h
new file mode 100644
index 00000000000..e2f7bf6fc06
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ClientApp.h
@@ -0,0 +1,52 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "TestAppBase.h"
+#include "ClientEngine.h"
+#include "tao/ORB.h"
+#include "ace/SString.h"
+
+
+class ClientApp : public TestAppBase
+{
+ public:
+
+ ClientApp();
+ virtual ~ClientApp();
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void client_setup(ACE_ENV_SINGLE_ARG_DECL);
+ int run_engine(ACE_ENV_SINGLE_ARG_DECL);
+ void cleanup();
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+
+ CORBA::ORB_var orb_;
+ ACE_CString exe_name_;
+ ACE_CString ior_;
+ unsigned client_kind_;
+ ClientEngine_Handle engine_;
+ unsigned client_id_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_4/README b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/README
new file mode 100644
index 00000000000..100428e0103
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/README
@@ -0,0 +1,337 @@
+// $Id$
+===========================================================================
+Directory: $TAO_ROOT/tests/CSD_Strategy_Tests/TP_Test_4
+
+Uses Libs: $TAO_ROOT/tests/CSD_Strategy_Tests/TP_Test_Lib
+ $TAO_ROOT/tests/CSD_Strategy_Tests/TP_Foo_C
+
+===========================================================================
+Executable: server_main
+
+Description: The test server application.
+
+Command-Line:
+
+ % server_main [options]
+
+ where, [options] includes the following:
+
+ -p <ior_filename_prefix>
+ -s <num_servants>
+ -n <num_csd_threads>
+ -t <num_orb_threads>
+ -r <num_remote_clients>
+ -c <num_collocated_clients>
+ -k <collocated_client_kind>
+ -?
+
+Command-Line Arguments:
+
+ -p <ior_filename_prefix>
+
+ If not specified, the <ior_filename_prefix> defaults to "foo".
+ This value is used as the prefix for the filename(s) to which
+ the server application will write stringified object reference(s).
+ Each "IOR file" contains the (stringified) object reference
+ associated with a distinct servant object within the server
+ application. These files are the way that the client application(s)
+ are able to "locate" the object reference(s) upon which they will
+ invoke (CORBA) operations. In essence, the filesystem is used
+ as a "poor-man" Naming Service.
+
+ The filenames are of the form, "prefix_%02d.ior", using a unique
+ integer "id" for each file - starting with an "id" of 1. Thus,
+ if the server application was told to create 3 servants (via the
+ -s <num_servants> option), and the <ior_filename_prefix> is "foo",
+ then three files will be written by the server application:
+
+ foo_01.ior
+ foo_02.ior
+ foo_03.ior
+
+
+ -s <num_servants>
+
+ The <num_servants> must be an integer value greater than 0.
+
+ If not specified, the <num_servants> defaults to 1. This is used
+ to inform the server application of the number of distinct servant
+ objects that it should create.
+
+
+ -n <num_csd_threads>
+
+ The <num_csd_threads> must be an integer value greater than 0.
+
+ If not specified, the <num_csd_threads> defaults to 1. This is
+ used to inform the server application of the number of worker
+ threads that should be activated by the Thread Pool CSD Strategy.
+ The worker threads are responsible for servicing the strategy's
+ request queue. This can also be called the "size of the thread
+ pool".
+
+
+ -t <num_orb_threads>
+
+ The <num_orb_threads> must be an integer value greater than 0.
+
+ If not specified, the <num_orb_threads> defaults to 1. This option
+ is used to tell the server application how many distinct threads
+ should be used to run the ORB event loop. The "mainline thread"
+ will always run the ORB event loop itself, so that accounts for
+ one of the num_orb_threads. If num_orb_threads is greater than 1,
+ then (num_orb_threads - 1) threads will be activated by the server
+ application, and each of these threads will run the ORB event loop.
+ The end result is that there will be <num_orb_threads> distinct
+ threads (including the mainline thread) running the ORB event loop.
+
+
+ -r <num_remote_clients>
+
+ The <num_remote_clients> must be an integer value greater than,
+ or equal to, 0. In addition, the sum of the <num_remote_clients>
+ and the <num_collocated_clients> (see the -c option) must be
+ greater than 0. Both cannot be 0, since the server application
+ would interpret this to mean that no clients will ever use it,
+ and that's kind of pointless.
+
+ If not specified, the <num_remote_clients> defaults to 1. This
+ option informs the server application how many remote clients it
+ can expect to "hear" from over the course of its lifetime. Each
+ distinct test client, remote or collocated, is required to invoke
+ the done() operation on one of the servant objects. The server
+ application decides to shut itself down gracefully when it has
+ received one done() invocation for each remote client and for
+ each collocated client. Once all of the expected done() calls
+ have been made, the server application assumes that no more clients
+ will need its services, and thus it shuts itself down. This is
+ used to support the automated test scenarios implemented within
+ the run_test.pl script. It provides a way for a test scenario to
+ automate the graceful shutdown of the server by telling the server
+ how many clients to expect (remote + collocated).
+
+
+ -c <num_collocated_clients>
+
+ The <num_collocated_clients> must be an integer value greater than,
+ or equal to, 0. In addition, the sum of the <num_collocated_clients>
+ and the <num_remote_clients> (see the -r option) must be
+ greater than 0. Both cannot be 0, since the server application
+ would interpret this to mean that no clients will ever use it,
+ and that's kind of pointless.
+
+ If not specified, the <num_collocated_clients> defaults to 0. This
+ option informs the server application how many collocated clients
+ should "live", collocated, within the server application. Each
+ collocated client will execute its logic in a distinct thread
+ within the server application. As an example, if the server
+ application was told to use a <num_collocated_clients> value of 40,
+ then the server application will activate 40 threads - each
+ carrying out the logic of one "client". This client "logic" is
+ identical to the logic carried out by a single remote client
+ application (client_main) process. As with remote clients,
+ each collocated client will invoke the done() operation on
+ one of the servants (via an object ref) when the client logic
+ has been completed. See the "-r <num_remote_clients>" option
+ for more information about the done() operation, and its purpose.
+
+ For this particular server application (TP_Test_4), each
+ collocated client will perform the normal client logic as well
+ as carry out a set of "custom" requests on the collocated servant.
+ Custom operations not defined in IDL.
+
+
+ -k <collocated_client_kind>
+
+ This is reserved for future use. It currently doesn't get used
+ for anything.
+
+
+ -?
+
+ This is used to request the "Usage Statement" for the Server
+ Application (ie, "server_main -?" prints the usage statement).
+
+
+===========================================================================
+Executable: client_main
+
+Description: The test client application.
+
+Command-Line:
+
+ % client_main [options]
+
+ where, [options] includes the following:
+
+ -i <ior>
+ -n <client_id>
+ -k <collocated_client_kind>
+ -?
+
+
+Command-Line Arguments:
+
+ -i <ior>
+
+ The <ior> is required, and must be a valid IOR. In our case, where
+ the server application saves stringified object references to files,
+ we supply the client application with an <ior> in the following
+ form: "file://foo_01.ior". See the server application's description
+ of its "-p <ior_filename_prefix>" option for more information.
+
+ The client application will use the <ior> to obtain an object
+ reference using the CORBA::ORB::string_to_object() method. This
+ is the object reference upon which the client logic will invoke
+ operations. The object reference will be associated with a
+ distinct servant object within the server application.
+
+
+ -n <client_id>
+
+ The <client_id> is required, and must be an integer value greater
+ than 0.
+
+ As part of the logic used to check actual vs. expected results,
+ each client is assigned a unique id. As a side-note, each
+ collocated client within the server application (if there are
+ any) will also be assigned a unique client_id. For any given
+ test scenario run by the run_test.pl script, each client (remote
+ and/or collocated) will be assigned a unique client_id.
+
+ The server application assigns client_ids to its collocated clients
+ based upon its knowledge of how many remote clients will be used
+ in the test scenario (see the "-r <num_remote_clients>" option
+ for the server application). The server application assumes that
+ the run_test.pl will assign client_ids to remote clients starting
+ with 1, and up to the <num_remote_clients>. Thus, the server
+ application assigns client_ids to collocated clients starting
+ with (<num_remote_clients> + 1), and incrementing by 1 for each
+ additional collocated client_id.
+
+
+ -k <collocated_client_kind>
+
+ This is reserved for future use. It currently doesn't get used
+ for anything.
+
+
+ -?
+
+ This is used to request the "Usage Statement" for the Client
+ Application (ie, "client_main -?" prints the usage statement).
+
+
+===========================================================================
+Executable: run_test.pl (PERL script).
+
+Description: Script used to run a specific test scenario. This includes
+ the launching of a server application process and client
+ applications processes as called for by the specific scenario.
+
+Command-Line:
+
+ % run_test.pl <scenario>
+
+ where, <scenario> can be one of the following values:
+
+ "big"
+ "a"
+ "b"
+
+ If a <scenario> is not specified on the run_test.pl command-line,
+ then a default scenario is used.
+
+
+Scenarios:
+
+ -----------------------------------------------------------------------
+ Default: (when no <scenario> is specified on the command-line)
+
+ $iorfname_prefix = "servant";
+ $num_servants = 1;
+ $num_orb_threads = 1;
+ $num_remote_clients = 1;
+ $num_csd_threads = 1;
+ $num_collocated_clients = 0;
+
+ -----------------------------------------------------------------------
+ "remote":
+
+ Uses the Default values, with the following overrides:
+
+ $num_remote_clients = 40;
+
+ -----------------------------------------------------------------------
+ "collocated":
+
+ Uses the Default values, with the following overrides:
+
+ $num_remote_clients = 0;
+ $num_collocated_clients = 1;
+
+ -----------------------------------------------------------------------
+ "collocated_big":
+
+ Uses the Default values, with the following overrides:
+
+ $num_remote_clients = 0;
+ $num_csd_threads = 5;
+ $num_collocated_clients = 40;
+
+ -----------------------------------------------------------------------
+ "remote_orbthreads":
+
+ Uses the Default values, with the following overrides:
+
+ $num_orb_threads = 5;
+ $num_remote_clients = 40;
+
+ -----------------------------------------------------------------------
+ "remote_servants":
+
+ Uses the Default values, with the following overrides:
+
+ $num_servants = 5;
+ $num_remote_clients = 40;
+
+ -----------------------------------------------------------------------
+ "remote_csdthreads":
+
+ Uses the Default values, with the following overrides:
+
+ $num_csd_threads = 5;
+ $num_remote_clients = 40;
+
+ -----------------------------------------------------------------------
+ "remote_big":
+
+ Uses the Default values, with the following overrides:
+
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+
+ -----------------------------------------------------------------------
+ "big":
+
+ Uses the Default values, with the following overrides:
+
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ $num_collocated_clients = 40;
+
+ -----------------------------------------------------------------------
+ "usage":
+
+ This is not really a test scenario, but it will cause the
+ run_test.pl script to print a "Usage Statement", which includes
+ a list of the supported <scenario> values.
+
+ -----------------------------------------------------------------------
+
+
+===========================================================================
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.cpp
new file mode 100644
index 00000000000..93c4ba59b53
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.cpp
@@ -0,0 +1,383 @@
+// $Id$
+#include "ServerApp.h"
+#include "AppHelper.h"
+#include "OrbRunner.h"
+#include "AppShutdown.h"
+#include "TestAppExceptionC.h"
+#include "Foo_C_Custom_ClientEngine.h"
+#include "Foo_C_ClientEngine.h"
+#include "Foo_C_Statistics.h"
+#include "ace/OS.h"
+#include "ace/Get_Opt.h"
+// To force static load the service.
+#include "tao/CSD_ThreadPool/CSD_ThreadPool.h"
+
+ServerApp::ServerApp()
+ : TestAppBase("TP_Test_4_Server"),
+ ior_filename_prefix_("foo"),
+ num_servants_(1),
+ num_csd_threads_(1),
+ num_orb_threads_(1),
+ num_remote_clients_(1),
+ num_collocated_clients_(0),
+ collocated_client_kind_(0)
+{
+}
+
+
+ServerApp::~ServerApp()
+{
+}
+
+
+int
+ServerApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ int result = this->init(argc, argv ACE_ENV_ARG_PARAMETER);
+ if (result != 0)
+ {
+ return result;
+ }
+ ACE_CHECK_RETURN (-1);
+
+ this->poa_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->csd_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->servant_setup(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->collocated_setup();
+ this->poa_activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_collocated_clients(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->run_orb_event_loop(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->cleanup();
+ return this->check_validity () ? 0 : -1;
+}
+
+
+int
+ServerApp::init(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Raises -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ unsigned num_clients = this->num_remote_clients_ +
+ this->num_collocated_clients_;
+
+ TheAppShutdown->init(this->orb_.in(), num_clients ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ return 0;
+}
+
+
+void
+ServerApp::poa_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->poa_ = this->create_poa(this->orb_.in(),
+ "ChildPoa"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::csd_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->tp_strategy_ = new TAO::CSD::TP_Strategy(this->num_csd_threads_);
+
+ if (!this->tp_strategy_->apply_to(this->poa_.in() ACE_ENV_ARG_PARAMETER))
+ {
+ ACE_ERROR((LM_ERROR,
+ "Failed to apply CSD strategy to poa.\n"));
+ ACE_THROW(TestAppException());
+ }
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::servant_setup(ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->servants_.create_and_activate(this->num_servants_,
+ this->orb_.in (),
+ this->poa_.in (),
+ this->ior_filename_prefix_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::collocated_setup()
+{
+ int custom_client_id_start = this->num_remote_clients_;
+
+ unsigned servant_index = 0;
+
+ for (unsigned i = 0; i < this->num_collocated_clients_; i++)
+ {
+ if (i > 0)
+ {
+ // Dole out the servant object references in a round-robin fashion.
+ servant_index = (servant_index + 1) % this->num_servants_;
+ }
+
+ ServantListType::T_stub_var obj = this->servants_.objref(servant_index);
+
+ ClientEngine_Handle engine =
+ new Foo_C_Custom_ClientEngine(this->servants_.servant(servant_index),
+ obj.in(),
+ this->tp_strategy_.in(),
+ ++ custom_client_id_start);
+ this->collocated_client_task_.add_engine(engine.in());
+ }
+}
+
+
+void
+ServerApp::poa_activate(ACE_ENV_SINGLE_ARG_DECL)
+{
+ PortableServer::POAManager_var poa_manager
+ = this->poa_->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+void
+ServerApp::run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->num_collocated_clients_ > 0)
+ {
+ if (this->collocated_client_task_.open() == -1)
+ {
+ ACE_THROW (TestAppException ());
+ }
+ }
+}
+
+
+void
+ServerApp::run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL)
+{
+ OrbRunner orb_runner(this->orb_.in(), this->num_orb_threads_);
+ orb_runner.run(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ TheAppShutdown->wait ();
+}
+
+
+void
+ServerApp::cleanup()
+{
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ this->servants_.servant(i)->dump();
+ }
+
+ // Wait for all of the collocated client task threads to finish.
+ if (this->num_collocated_clients_ > 0)
+ {
+ this->collocated_client_task_.wait();
+ }
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ this->exe_name_ = argv[0];
+
+ ACE_Get_Opt get_opts(argc, argv, "p:s:n:t:r:c:k:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ int result = 0;
+ switch (c)
+ {
+ case 'p':
+ this->ior_filename_prefix_ = get_opts.opt_arg();
+ break;
+
+ case 's':
+ result = this->set_arg(this->num_servants_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 'n':
+ result = this->set_arg(this->num_csd_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_servants",
+ 1);
+ break;
+
+ case 't':
+ result = this->set_arg(this->num_orb_threads_,
+ get_opts.opt_arg(),
+ c,
+ "num_orb_threads",
+ 1);
+ break;
+
+ case 'r':
+ result = this->set_arg(this->num_remote_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_remote_clients");
+ break;
+
+ case 'c':
+ result = this->set_arg(this->num_collocated_clients_,
+ get_opts.opt_arg(),
+ c,
+ "num_collocated_clients");
+ break;
+
+ case 'k':
+ result = this->set_arg(this->collocated_client_kind_,
+ get_opts.opt_arg(),
+ c,
+ "collocated_client_kind");
+ break;
+
+ case '?':
+ this->usage_statement();
+ return 1;
+
+ default:
+ this->usage_statement();
+ return -1;
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ return this->arg_dependency_checks();
+}
+
+void
+ServerApp::usage_statement()
+{
+ ACE_ERROR((LM_ERROR,
+ "Usage: %s [options]\n\n"
+ "OPTIONS:\n\n"
+ "\t[-p <ior_filename_prefix>]\n"
+ "\t[-s <num_servants>]\n"
+ "\t[-n <num_csd_threads>]\n"
+ "\t[-t <num_orb_threads>]\n"
+ "\t[-r <num_remote_clients>]\n"
+ "\t[-c <num_collocated_clients>]\n"
+ "\t[-k <collocated_client_kind>]\n"
+ "\t[-?]\n\n",
+ this->exe_name_.c_str()));
+}
+
+
+int
+ServerApp::arg_dependency_checks()
+{
+ return (this->num_remote_clients_
+ + this->num_collocated_clients_) > 0 ? 0 : -1;
+}
+
+
+int
+ServerApp::set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min)
+{
+ int tmp = ACE_OS::atoi(arg);
+
+ if (tmp < min)
+ {
+ ACE_ERROR((LM_ERROR,
+ "Error: -%c <%s> must be integer type with a value of, "
+ "at least, %d.\n", opt, name, min));
+ this->usage_statement();
+ return -1;
+ }
+
+ value = tmp;
+
+ return 0;
+}
+
+
+PortableServer::POA_ptr
+ServerApp::create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL)
+{
+ // Get the Root POA.
+ PortableServer::POA_var root_poa
+ = RefHelper<PortableServer::POA>::resolve_initial_ref(orb,
+ "RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Get the POAManager from the Root POA.
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Create the child POA Policies.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ // Create the child POA
+ PortableServer::POA_var poa
+ = AppHelper::create_poa(poa_name,
+ root_poa.in(),
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ // Give away the child POA_ptr from the POA_var variable.
+ return poa._retn();
+}
+
+
+bool
+ServerApp::check_validity ()
+{
+ Foo_C_Statistics stats (this->num_remote_clients_,
+ this->num_collocated_clients_);
+
+ Foo_C_ClientEngine::expected_results (stats);
+ Foo_C_Custom_ClientEngine::expected_results (stats);
+
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ this->servants_.servant(i)->gather_stats(stats);
+ }
+
+ return stats.actual_vs_expected ();
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.h
new file mode 100644
index 00000000000..99f0af758b5
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/ServerApp.h
@@ -0,0 +1,79 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "TestAppBase.h"
+#include "Foo_C_i.h"
+#include "ServantList_T.h"
+#include "ClientTask.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
+#include "ace/SString.h"
+
+
+class ServerApp : public TestAppBase
+{
+ public:
+
+ ServerApp();
+ virtual ~ServerApp();
+
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ // These are all called, in order, by the run_i() method.
+ int init(int argc, char* argv[] ACE_ENV_ARG_DECL);
+ void poa_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void csd_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void servant_setup(ACE_ENV_SINGLE_ARG_DECL);
+ void collocated_setup();
+ void poa_activate(ACE_ENV_SINGLE_ARG_DECL);
+ void run_collocated_clients(ACE_ENV_SINGLE_ARG_DECL);
+ void run_orb_event_loop(ACE_ENV_SINGLE_ARG_DECL);
+ bool check_validity ();
+ void cleanup();
+
+
+ // Helper methods used by the methods above.
+ int parse_args(int argc, char* argv[]);
+
+ int set_arg(unsigned& value,
+ const char* arg,
+ char opt,
+ const char* name,
+ int min = 0);
+
+ void usage_statement();
+ int arg_dependency_checks();
+
+
+ PortableServer::POA_ptr create_poa(CORBA::ORB_ptr orb,
+ const char* poa_name
+ ACE_ENV_ARG_DECL);
+
+ typedef ServantList<Foo_C_i> ServantListType;
+
+ CORBA::ORB_var orb_;
+ PortableServer::POA_var poa_;
+ TAO::CSD::TP_Strategy_Handle tp_strategy_;
+
+ ServantListType servants_;
+
+ ClientTask collocated_client_task_;
+
+ ACE_CString exe_name_;
+
+ ACE_CString ior_filename_prefix_;
+ unsigned num_servants_;
+ unsigned num_csd_threads_;
+ unsigned num_orb_threads_;
+ unsigned num_remote_clients_;
+ unsigned num_collocated_clients_;
+ unsigned collocated_client_kind_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_4/client_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/client_main.cpp
new file mode 100644
index 00000000000..3814bef5ff9
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/client_main.cpp
@@ -0,0 +1,7 @@
+// $Id$
+#include "ClientApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ClientApp)
+
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_4/run_test.pl b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/run_test.pl
new file mode 100755
index 00000000000..5b93da07b74
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/run_test.pl
@@ -0,0 +1,177 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+my $status = 0;
+
+my $iorfname_prefix = "servant";
+my $num_servants = 1;
+my $num_orb_threads = 1;
+my $num_remote_clients = 1;
+my $num_csd_threads = 1;
+my $num_collocated_clients = 0;
+my $collocated_client_kind = 0;
+my $client_kind = 0;
+
+my $i;
+my $j;
+my @iorfile;
+
+my $ARGC = @ARGV;
+
+if ($ARGC > 0)
+{
+ if ($ARGC > 1)
+ {
+ print STDERR "ERROR: Too many command-line arguments for $0.\n";
+ exit 1;
+ }
+
+ my $subtest = $ARGV[0];
+
+ if ($subtest eq 'remote')
+ {
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'collocated')
+ {
+ $num_remote_clients = 0;
+ $num_collocated_clients = 1;
+ }
+ elsif ($subtest eq 'collocated_big')
+ {
+ $num_remote_clients = 0;
+ $num_csd_threads = 5;
+ $num_collocated_clients = 40;
+ }
+ elsif ($subtest eq 'remote_orbthreads')
+ {
+ $num_orb_threads = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_servants')
+ {
+ $num_servants = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_csdthreads')
+ {
+ $num_csd_threads = 5;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'remote_big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ }
+ elsif ($subtest eq 'big')
+ {
+ $num_csd_threads = 5;
+ $num_servants = 10;
+ $num_orb_threads = 4;
+ $num_remote_clients = 40;
+ $num_collocated_clients = 40;
+ }
+ elsif ($subtest eq 'usage')
+ {
+ print STDOUT "Usage: $0 [<subtest>]\n" .
+ "\n" .
+ "Supported <subtest> values:\n" .
+ "\n" .
+ "\tremote\n" .
+ "\tcollocated\n" .
+ "\tremote_orbthreads\n" .
+ "\tremote_servants\n" .
+ "\tremote_csdthreads\n" .
+ "\tremote_big\n" .
+ "\tusage\n" .
+ "\n";
+ exit 0;
+ }
+ else
+ {
+ print STDERR "ERROR: invalid subtest argument for $0: $subtest\n";
+ exit 1;
+ }
+}
+
+#Delete old ior files.
+for ($i = 0; $i < $num_servants; $i++) {
+ my $servant_id = sprintf("%02d", ($i + 1));
+ $iorfile[$i] = PerlACE::LocalFile($iorfname_prefix . "_$servant_id.ior");
+ unlink $iorfile[$i];
+}
+
+$SV = new PerlACE::Process("server_main",
+ "-p $iorfname_prefix " .
+ "-s $num_servants " .
+ "-n $num_csd_threads " .
+ "-t $num_orb_threads " .
+ "-r $num_remote_clients " .
+ "-c $num_collocated_clients " .
+ "-k $collocated_client_kind");
+
+$SV->Spawn();
+
+# Wait for the servant ior files created by server.
+for ($i = 0; $i < $num_servants; $i++) {
+ if (PerlACE::waitforfile_timed
+ ($iorfile[$i],
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile[$i]>\n";
+ $SV->Kill();
+ $SV->TimedWait(1);
+ exit 1;
+ }
+}
+
+my $count = 0;
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+
+ $client_id = $i+1;
+
+ $j = $i % $num_servants;
+
+ $CLS[$i] = new PerlACE::Process("client_main",
+ "-i file://$iorfile[$j] ".
+ "-k $client_kind ".
+ "-n $client_id");
+
+ $CLS[$i]->Spawn();
+}
+
+for ($i = 0; $i < $num_remote_clients; $i++)
+{
+ $client = $CLS[$i]->WaitKill(60);
+
+ if ($client != 0)
+ {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill(60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+#Delete ior files generated by this run.
+for ($i = 0; $i < $num_servants; $i++) {
+ unlink $iorfile[$i];
+}
+
+exit $status;
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_4/server_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/server_main.cpp
new file mode 100644
index 00000000000..82e987f6d41
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_4/server_main.cpp
@@ -0,0 +1,5 @@
+// $Id$
+#include "ServerApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ServerApp)
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/CSD_TP_Test_Dynamic.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/CSD_TP_Test_Dynamic.mpc
new file mode 100644
index 00000000000..5b90572b45d
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/CSD_TP_Test_Dynamic.mpc
@@ -0,0 +1,20 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): taoserver {
+ idlflags += -Sa -St
+ Source_Files {
+ Hello.cpp
+ server.cpp
+ }
+}
+
+project(*Client): taoclient {
+ Source_Files {
+ TestC.cpp
+ client.cpp
+ }
+}
+
+
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.cpp
new file mode 100644
index 00000000000..70af3ea8a11
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.cpp
@@ -0,0 +1,25 @@
+//
+// $Id$
+//
+#include "Hello.h"
+
+ACE_RCSID(Hello, Hello, "$Id$")
+
+Hello::Hello (CORBA::ORB_ptr orb)
+ : orb_ (CORBA::ORB::_duplicate (orb))
+{
+}
+
+char *
+Hello::get_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ return CORBA::string_dup ("Hello there!");
+}
+
+void
+Hello::shutdown (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER);
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.h
new file mode 100644
index 00000000000..9097ddddbb4
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Hello.h
@@ -0,0 +1,45 @@
+//
+// $Id$
+//
+
+#ifndef HELLO_H
+#define HELLO_H
+#include /**/ "ace/pre.h"
+
+#include "TestS.h"
+
+#if defined (_MSC_VER)
+# if (_MSC_VER >= 1200)
+# pragma warning(push)
+# endif /* _MSC_VER >= 1200 */
+# pragma warning (disable:4250)
+#endif /* _MSC_VER */
+
+/// Implement the Test::Hello interface
+class Hello
+ : public virtual POA_Test::Hello
+ , public virtual PortableServer::RefCountServantBase
+{
+public:
+ /// Constructor
+ Hello (CORBA::ORB_ptr orb);
+
+ // = The skeleton methods
+ virtual char * get_string (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+private:
+ /// Use an ORB reference to conver strings to objects and shutdown
+ /// the application.
+ CORBA::ORB_var orb_;
+};
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma warning(pop)
+#endif /* _MSC_VER */
+
+#include /**/ "ace/post.h"
+#endif /* HELLO_H */
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/README b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/README
new file mode 100644
index 00000000000..a4e3fbcdc2a
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/README
@@ -0,0 +1,37 @@
+// $Id$
+===========================================================================
+Directory: $TAO_ROOT/tests/CSD_Strategy_Tests/TP_Test_5
+
+===========================================================================
+
+===========================================================================
+Directory: $TAO_ROOT/tests/CSD_Strategy_Tests/TP_Test_Static
+
+===========================================================================
+This test shows the ThreadPool strategy can automatically apply to the poa
+via service configuration file dynamic directive.
+
+This simple test is a copy of $TAO_ROOT/tests/Hello test. The difference is
+this test contains the svc.conf file to configure the CSD strategies and the
+poas that apply the CSD strategy.
+
+A new TP_Strategy object is created during the initialization of the
+TP_Strategy_Factory service object and it will be automatically applied to
+a poa.
+
+The service configuration file specifies the number of threads that
+the ThreadPool strategy have and also specify which poa the strategy should
+apply to. We can specify multiple ThreadPool strategies and the poas via -CSDtp
+option.
+
+e.g
+dynamic TAO_CSD_TP_Strategy_Factory Service_Object *
+TAO_CSD_ThreadPool:_make_TAO_CSD_TP_Strategy_Factory() "-CSDtp RootPOA:2 -CSDtp childpoa:4"
+
+
+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/CSD_Strategy_Tests/TP_Test_Dynamic/Test.idl b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Test.idl
new file mode 100644
index 00000000000..3c0976e106d
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/Test.idl
@@ -0,0 +1,20 @@
+//
+// $Id$
+//
+
+/// Put the interfaces in a module, to avoid global namespace pollution
+module Test
+{
+ /// A very simple interface
+ interface Hello
+ {
+ /// Return a simple string
+ string get_string ();
+
+ /// A method to shutdown the ORB
+ /**
+ * This method is used to simplify the test shutdown process
+ */
+ oneway void shutdown ();
+ };
+};
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/client.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/client.cpp
new file mode 100644
index 00000000000..f85722246b5
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/client.cpp
@@ -0,0 +1,86 @@
+// $Id$
+
+#include "TestC.h"
+#include "ace/Get_Opt.h"
+
+ACE_RCSID(Hello, client, "$Id$")
+
+const char *ior = "file://test.ior";
+
+int
+parse_args (int argc, char *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "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 sucessful parsing of the command line
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ ACE_TRY_NEW_ENV
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ CORBA::Object_var tmp =
+ orb->string_to_object(ior ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Test::Hello_var hello =
+ Test::Hello::_narrow(tmp.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (hello.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Nil Test::Hello reference <%s>\n",
+ ior),
+ 1);
+ }
+
+ CORBA::String_var the_string =
+ hello->get_string (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) - string returned <%s>\n",
+ the_string.in ()));
+
+ hello->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Exception caught:");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/run_test.pl b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/run_test.pl
new file mode 100755
index 00000000000..02041ea0c25
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/run_test.pl
@@ -0,0 +1,43 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+$iorfile = PerlACE::LocalFile ("server.ior");
+unlink $iorfile;
+$status = 0;
+
+$SV = new PerlACE::Process ("server", "-o $iorfile");
+$CL = new PerlACE::Process ("client", " -k file://$iorfile");
+
+$SV->Spawn ();
+
+if (PerlACE::waitforfile_timed ($iorfile,
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+$client = $CL->SpawnWaitKill (300);
+
+if ($client != 0) {
+ print STDERR "ERROR: client returned $client\n";
+ $status = 1;
+}
+
+$server = $SV->WaitKill (10);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+unlink $iorfile;
+
+exit $status;
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/server.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/server.cpp
new file mode 100644
index 00000000000..177aad4d1d8
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/server.cpp
@@ -0,0 +1,115 @@
+// $Id$
+
+#include "Hello.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_stdio.h"
+
+ACE_RCSID (Hello,
+ server,
+ "$Id$")
+
+const char *ior_output_file = "test.ior";
+
+int
+parse_args (int argc, char *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "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 sucessful parsing of the command line
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ ACE_TRY_NEW_ENV
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (root_poa.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Panic: nil RootPOA\n"),
+ 1);
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ Hello *hello_impl;
+ ACE_NEW_RETURN (hello_impl,
+ Hello (orb.in ()),
+ 1);
+ PortableServer::ServantBase_var owner_transfer(hello_impl);
+
+ Test::Hello_var hello =
+ hello_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::String_var ior =
+ orb->object_to_string (hello.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Output the IOR to the <ior_output_file>
+ FILE *output_file= ACE_OS::fopen (ior_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 (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop finished\n"));
+
+ root_poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Exception caught:");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/svc.conf b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/svc.conf
new file mode 100644
index 00000000000..e59fb4ac94c
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Dynamic/svc.conf
@@ -0,0 +1 @@
+dynamic TAO_CSD_TP_Strategy_Factory Service_Object * TAO_CSD_ThreadPool:_make_TAO_CSD_TP_Strategy_Factory() "-CSDtp RootPOA:2"
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/CSD_TP_Test_Static.mpc b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/CSD_TP_Test_Static.mpc
new file mode 100644
index 00000000000..02cac4dc7da
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/CSD_TP_Test_Static.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Server): csd_tp_test_exe_a {
+ exename=server_main
+
+ Source_Files {
+ ServerApp.cpp
+ server_main.cpp
+ }
+}
+
+project(*Client): csd_tp_test_exe_a {
+ exename=client_main
+
+ Source_Files {
+ ClientApp.cpp
+ client_main.cpp
+ }
+}
+
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.cpp
new file mode 100644
index 00000000000..4fc25f46c1c
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.cpp
@@ -0,0 +1,86 @@
+// $Id$
+#include "ClientApp.h"
+#include "Foo_A_ClientEngine.h"
+#include "AppHelper.h"
+#include "TestAppExceptionC.h"
+#include "ace/Get_Opt.h"
+#include "ace/Log_Msg.h"
+// To force static load the service.
+#include "tao/CSD_ThreadPool/CSD_ThreadPool.h"
+
+ClientApp::ClientApp()
+ : TestAppBase("TP_Test_1_Client"),
+ ior_ ("file://test.ior")
+{
+}
+
+
+ClientApp::~ClientApp()
+{
+}
+
+
+int
+ClientApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ // Initialize the ORB before parsing our own args.
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Returns -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+ // Convert the IOR string to a Foo_A object reference.
+ Foo_A_var foo = RefHelper<Foo_A>::string_to_ref(orb.in(),
+ this->ior_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the appropriate client "engine" object.
+ Foo_A_ClientEngine engine(foo.in());
+
+ // Execute the client algorithm
+ result = engine.execute(ACE_ENV_SINGLE_ARG_PARAMETER) ? 0 : -1;
+ ACE_CHECK_RETURN (-1);
+
+ return result;
+}
+
+
+int
+ClientApp::parse_args(int argc, char* argv[])
+{
+ ACE_Get_Opt get_opts(argc, argv, "i:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'i':
+ this->ior_ = get_opts.opt_arg();
+ break;
+
+ case '?':
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) usage: %s -i <ior_string>\n",
+ argv[0]));
+ return 1;
+
+ default:
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) usage: %s -i <ior_string>\n",
+ argv[0]));
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.h
new file mode 100644
index 00000000000..1af2e9ff6a6
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ClientApp.h
@@ -0,0 +1,28 @@
+// $Id$
+#ifndef CLIENTAPP_H
+#define CLIENTAPP_H
+
+#include "TestAppBase.h"
+#include "ace/SString.h"
+
+
+class ClientApp : public TestAppBase
+{
+ public:
+
+ ClientApp();
+ virtual ~ClientApp();
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+
+ ACE_CString ior_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/README b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/README
new file mode 100644
index 00000000000..8090bdb87ce
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/README
@@ -0,0 +1,38 @@
+// $Id$
+===========================================================================
+Directory: $TAO_ROOT/tests/CSD_Strategy_Tests/TP_Test_Static
+
+===========================================================================
+This test shows the ThreadPool strategy can automatically apply to the poa
+via service configuration file static directive.
+
+This simple test is a copy of TP_Test_1. The difference is the test
+application does not need to create the TP_Strategy object and apply to the
+poa. A new TP_Strategy object is created during the initialization of the
+TP_Strategy_Factory service object and it will be automatically applied to
+a poa.
+
+The application needs to include the following two files to force the
+TAO_CSD_ORB_Loader and TAO_CSD_TP_Strategy_Factory service objects register
+with the service repository before initializing the services specified in
+.conf file.
+
+#include "tao/CSD_Framework/CSD_ORB_Loader.h"
+#include "tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.h"
+
+
+The service configuration file specifies the number of threads that
+the ThreadPool strategy have and also specify which poa the strategy should
+apply to. We can specify multiple ThreadPool strategies and the poas via -CSDtp
+option.
+
+e.g
+static TAO_CSD_TP_Strategy_Factory "-CSDtp RootPOA:2 -CSDtp ChildPoa:3"
+
+
+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/CSD_Strategy_Tests/TP_Test_Static/ServerApp.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ServerApp.cpp
new file mode 100644
index 00000000000..348e7987ba8
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ServerApp.cpp
@@ -0,0 +1,171 @@
+// $Id$
+#include "ServerApp.h"
+#include "Foo_A_i.h"
+#include "AppHelper.h"
+#include "TestAppExceptionC.h"
+#include "AppShutdown.h"
+#include "ace/Get_Opt.h"
+// To force static load the service.
+#include "tao/CSD_ThreadPool/CSD_ThreadPool.h"
+
+
+ServerApp::ServerApp()
+ : TestAppBase("TP_Test_1_Server"),
+ ior_filename_ ("test.ior"),
+ num_clients_ (1)
+{
+}
+
+ServerApp::~ServerApp()
+{
+}
+
+int
+ServerApp::run_i(int argc, char* argv[] ACE_ENV_ARG_DECL)
+{
+ // Initialize the ORB before parsing our own args.
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Parse the command-line args for this application.
+ // * Returns -1 if problems are encountered.
+ // * Returns 1 if the usage statement was explicitly requested.
+ // * Returns 0 otherwise.
+ int result = this->parse_args(argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ TheAppShutdown->init(orb.in(), num_clients_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Get the Root POA
+ PortableServer::POA_var root_poa =
+ RefHelper<PortableServer::POA>::resolve_initial_ref(orb.in(),
+ "RootPOA"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Get the POAManager from the Root POA.
+ PortableServer::POAManager_var poa_manager
+ = root_poa->the_POAManager(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the child POA Policies.
+ CORBA::PolicyList policies(0);
+ policies.length(0);
+
+ // Create the child POA
+ PortableServer::POA_var child_poa =
+ AppHelper::create_poa("ChildPoa",
+ root_poa.in(),
+ poa_manager.in(),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Create the servant object.
+ Foo_A_i* servant = new Foo_A_i();
+
+ // Local smart pointer variable to deal with releasing the reference
+ // to the servant object when the variable falls out of scope.
+ PortableServer::ServantBase_var servant_owner(servant);
+
+ // Obtain the object reference using the servant
+ CORBA::Object_var obj = AppHelper::activate_servant(child_poa.in(),
+ servant
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Stringify and save the object reference to a file
+ AppHelper::ref_to_file(orb.in(),
+ obj.in(),
+ this->ior_filename_.c_str()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Activate the POA Manager
+ poa_manager->activate(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is ready. Running the ORB event loop.\n"));
+
+ // Run the ORB event loop.
+ orb->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp ORB event loop has completed.\n"));
+
+ TheAppShutdown->wait ();
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the Root POA.\n"));
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the Root POA.\n"));
+
+ root_poa->destroy(1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp is destroying the ORB.\n"));
+
+ orb->destroy(ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) ServerApp has completed running successfully.\n"));
+
+ return 0;
+}
+
+
+int
+ServerApp::parse_args(int argc, char* argv[])
+{
+ ACE_Get_Opt get_opts(argc, argv, "o:n:");
+
+ int c;
+
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'o':
+ this->ior_filename_ = get_opts.opt_arg();
+ break;
+
+ case 'n':
+ {
+ int tmp = ACE_OS::atoi(get_opts.opt_arg());
+ if (tmp < 1)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Error. -n must be followed by an integer "
+ "value greater than 0.\n"));
+ return -1;
+ }
+
+ this->num_clients_ = tmp;
+ }
+ break;
+
+ case '?':
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) usage: %s -o <ior_filename> -n <num_clients>\n",
+ argv[0]));
+ return 1;
+
+ default:
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) usage: %s -o <ior_filename> -n <num_clients>\n",
+ argv[0]));
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ServerApp.h b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ServerApp.h
new file mode 100644
index 00000000000..3bfe10e6f0a
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/ServerApp.h
@@ -0,0 +1,30 @@
+// $Id$
+#ifndef SERVERAPP_H
+#define SERVERAPP_H
+
+#include "TestAppBase.h"
+#include "ace/SString.h"
+
+
+class ServerApp : public TestAppBase
+{
+ public:
+
+ ServerApp();
+ virtual ~ServerApp();
+
+
+ protected:
+
+ virtual int run_i(int argc, char* argv[] ACE_ENV_ARG_DECL);
+
+
+ private:
+
+ int parse_args(int argc, char* argv[]);
+
+ ACE_CString ior_filename_;
+ unsigned num_clients_;
+};
+
+#endif
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/client_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/client_main.cpp
new file mode 100644
index 00000000000..ae98ca0f6ac
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/client_main.cpp
@@ -0,0 +1,5 @@
+// $Id$
+#include "ClientApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ClientApp)
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/run_test.pl b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/run_test.pl
new file mode 100755
index 00000000000..e15decb6a63
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/run_test.pl
@@ -0,0 +1,55 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use lib '../../../../bin';
+use PerlACE::Run_Test;
+
+$iorfile = PerlACE::LocalFile ("server.ior");
+unlink $iorfile;
+$status = 0;
+
+$num_clients=40;
+
+$SV = new PerlACE::Process ("server_main", "-o $iorfile -n $num_clients");
+
+$SV->Spawn ();
+
+if (PerlACE::waitforfile_timed ($iorfile,
+ $PerlACE::wait_interval_for_process_creation) == -1) {
+ print STDERR "ERROR: cannot find file <$iorfile>\n";
+ $SV->Kill (); $SV->TimedWait (1);
+ exit 1;
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ @CLS[$i] = new PerlACE::Process ("client_main", " -i file://$iorfile");
+
+ @CLS[$i]->Spawn ();
+}
+
+for ($i = 0; $i < $num_clients; $i++) {
+
+ $client = @CLS[$i]->WaitKill (60);
+
+ if ($client != 0) {
+ print STDERR "ERROR: client $i returned $client\n";
+ $status = 1;
+ }
+}
+
+
+$server = $SV->WaitKill (60);
+
+if ($server != 0) {
+ print STDERR "ERROR: server returned $server\n";
+ $status = 1;
+}
+
+unlink $iorfile;
+
+exit $status;
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/server_main.cpp b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/server_main.cpp
new file mode 100644
index 00000000000..82e987f6d41
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/server_main.cpp
@@ -0,0 +1,5 @@
+// $Id$
+#include "ServerApp.h"
+#include "TestAppMain.h"
+
+TEST_APP_MAIN(ServerApp)
diff --git a/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/svc.conf b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/svc.conf
new file mode 100644
index 00000000000..a274350e4ac
--- /dev/null
+++ b/TAO/tests/CSD_Strategy_Tests/TP_Test_Static/svc.conf
@@ -0,0 +1 @@
+static TAO_CSD_TP_Strategy_Factory "-CSDtp ChildPoa:2"