diff options
author | john_c <john_c@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2004-11-19 22:14:54 +0000 |
---|---|---|
committer | john_c <john_c@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2004-11-19 22:14:54 +0000 |
commit | adaaf3a4108d172f5fe517da3836e5625f819759 (patch) | |
tree | eede6298a1baa4cbfe0b8d96d1c3e5efa0b767e3 /TAO | |
parent | ff8a8def6d0c5e3fae7b3512bb7e80ab82697783 (diff) | |
download | ATCD-adaaf3a4108d172f5fe517da3836e5625f819759.tar.gz |
Thu Nov 18 12:39:59 2004 Ciju John <john_c@ociweb.com>
Fri Oct 29 10:53:56 2004 Dale Wilson <wilson_d@ociweb.com>
Wed Oct 27 11:59:01 2004 Dale Wilson <wilson_d@ociweb.com>
Mon Oct 25 20:41:00 2004 Dale Wilson <wilson_d@ociweb.com>
Mon Oct 25 14:51:09 2004 Dale Wilson <wilson_d@ociweb.com>
Wed Oct 20 11:38:11 2004 Dale Wilson <wilson_d@ociweb.com>
Tue Oct 19 10:43:28 2004 Dale Wilson <wilson_d@ociweb.com>
Mon Oct 18 15:21:49 2004 Dale Wilson <wilson_d@ociweb.com>
Mon Oct 18 10:29:48 2004 Dale Wilson <wilson_d@ociweb.com>
Mon Oct 18 10:11:47 2004 Dale Wilson <wilson_d@ociweb.com>
Tue Oct 12 14:10:43 2004 Dale Wilson <wilson_d@ociweb.com>
Mon Oct 11 14:39:15 2004 Dale Wilson <wilson_d@ociweb.com>
Thu Oct 7 09:40:51 2004 Dale Wilson <wilson_d@ociweb.com>
Mon Oct 18 13:02:11 2004 Dale Wilson <wilson_d@ociweb.com>
ed Oct 13 15:44:58 2004 Dale Wilson <wilson_d@ociweb.com>
Diffstat (limited to 'TAO')
235 files changed, 18993 insertions, 1992 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 5aeed30a0c8..c55d999aec3 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,729 @@ +Thu Nov 18 12:39:59 2004 Ciju John <john_c@ociweb.com> + + * TAO-INSTALL.html: + Fixed a older cvs conflict entry. + + * tao/UTF16_BOM_Factory.cpp + * tao/Messaging/Asynch_Invocation.cpp + Fixed explict template initiation compile failures. + + * MakeProjectCreator/config/notify.mpb + * MakeProjectCreator/config/notify_serv.mpb + Notification modules rename updates. + + * orbsvcs/tests/Notify/Reconnecting + * orbsvcs/tests/Notify/XML_Persistence + * orbsvcs/tests/Notify/ThreadPool + * orbsvcs/tests/Notify/Lanes + New Notification tests being added. + +Fri Oct 29 10:53:56 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/Notify_Service/Notify_Service.cpp: + Don't write IOR file until Notification Service + is *really* ready to run. + + * orbsvcs/orbsvcs/Notify/Admin.cpp: + * orbsvcs/orbsvcs/Notify/Builder.cpp: + * orbsvcs/orbsvcs/Notify/Consumer.cpp: + * orbsvcs/orbsvcs/Notify/Delivery_Request.h: + * orbsvcs/orbsvcs/Notify/Delivery_Request.inl: + * orbsvcs/orbsvcs/Notify/EventChannelFactory.h: + * orbsvcs/orbsvcs/Notify/EventChannelFactory.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup.cpp: + * orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.h: + * orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.cpp: + * orbsvcs/orbsvcs/Notify/ProxyConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Random_File.cpp: + * orbsvcs/orbsvcs/Notify/Reconnection_Registry.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.cpp: + + * orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp: + + Add Event reloading and restarting. Passes Reconnection test. + There is a lot of debug output still turned on so some housecleaning + is definately in order. + + + * orbsvcs/tests/Notify/Reconnecting/Consumer.cpp: + * orbsvcs/tests/Notify/Reconnecting/Supplier.cpp: + Add additional diagnostic information to track down problems + revealed by test. + + +Wed Oct 27 11:59:01 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/orbsvcs/CosNotification.mpc: + + * orbsvcs/orbsvcs/Notify/Admin.h: + * orbsvcs/orbsvcs/Notify/Admin.inl: + * orbsvcs/orbsvcs/Notify/Admin.cpp: + * orbsvcs/orbsvcs/Notify/Bit_Vector.h: + * orbsvcs/orbsvcs/Notify/Bit_Vector.cpp: + * orbsvcs/orbsvcs/Notify/Consumer.cpp: + * orbsvcs/orbsvcs/Notify/ConsumerAdmin.h: + * orbsvcs/orbsvcs/Notify/ConsumerAdmin.cpp: + * orbsvcs/orbsvcs/Notify/Delivery_Request.h: + * orbsvcs/orbsvcs/Notify/Delivery_Request.inl: + * orbsvcs/orbsvcs/Notify/Delivery_Request.cpp: + * orbsvcs/orbsvcs/Notify/Event.h: + * orbsvcs/orbsvcs/Notify/Event.inl: + * orbsvcs/orbsvcs/Notify/EventChannel.h: + * orbsvcs/orbsvcs/Notify/EventChannel.cpp: + * orbsvcs/orbsvcs/Notify/EventChannelFactory.h: + * orbsvcs/orbsvcs/Notify/EventChannelFactory.cpp: + * orbsvcs/orbsvcs/Notify/EventType.h: + * orbsvcs/orbsvcs/Notify/EventType.cpp: + * orbsvcs/orbsvcs/Notify/EventTypeSeq.h: + * orbsvcs/orbsvcs/Notify/EventTypeSeq.cpp: + * orbsvcs/orbsvcs/Notify/Event_Persistence_Factory.h: + * orbsvcs/orbsvcs/Notify/Event_Persistence_Strategy.h: + * orbsvcs/orbsvcs/Notify/FilterAdmin.h: + * orbsvcs/orbsvcs/Notify/FilterAdmin.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request.h: + * orbsvcs/orbsvcs/Notify/Method_Request.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Event.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Event.inl: + * orbsvcs/orbsvcs/Notify/Method_Request_Event.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup.cpp: + * orbsvcs/orbsvcs/Notify/Name_Value_Pair.h: + * orbsvcs/orbsvcs/Notify/Name_Value_Pair.cpp: + * orbsvcs/orbsvcs/Notify/Object.h: + * orbsvcs/orbsvcs/Notify/Object.cpp: + * orbsvcs/orbsvcs/Notify/POA_Helper.h: + * orbsvcs/orbsvcs/Notify/POA_Helper.cpp: + * orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.h: + * orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.cpp: + * orbsvcs/orbsvcs/Notify/Proxy.h: + * orbsvcs/orbsvcs/Notify/Proxy.cpp: + * orbsvcs/orbsvcs/Notify/ProxyConsumer.h: + * orbsvcs/orbsvcs/Notify/ProxyConsumer.cpp: + * orbsvcs/orbsvcs/Notify/ProxySupplier.cpp: + * orbsvcs/orbsvcs/Notify/Random_File.h: + * orbsvcs/orbsvcs/Notify/Random_File.cpp: + * orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.h: + * orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.cpp: + * orbsvcs/orbsvcs/Notify/Reconnection_Registry.h: + * orbsvcs/orbsvcs/Notify/Reconnection_Registry.cpp: + * orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.inl: + * orbsvcs/orbsvcs/Notify/Routing_Slip.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip.inl: + * orbsvcs/orbsvcs/Notify/Routing_Slip.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.inl: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.cpp: + * orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.h: + * orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.cpp: + * orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.h: + * orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.cpp: + * orbsvcs/orbsvcs/Notify/SupplierAdmin.h: + * orbsvcs/orbsvcs/Notify/SupplierAdmin.cpp: + * orbsvcs/orbsvcs/Notify/Topology_Factory.h: + * orbsvcs/orbsvcs/Notify/Topology_Loader.h: + * orbsvcs/orbsvcs/Notify/Topology_Loader.cpp: + * orbsvcs/orbsvcs/Notify/Topology_Object.h: + * orbsvcs/orbsvcs/Notify/Topology_Object.inl: + * orbsvcs/orbsvcs/Notify/Topology_Object.cpp: + * orbsvcs/orbsvcs/Notify/Topology_Saver.h: + * orbsvcs/orbsvcs/Notify/Topology_Saver.cpp: + * orbsvcs/orbsvcs/Notify/XML_Loader.h: + * orbsvcs/orbsvcs/Notify/XML_Loader.cpp: + * orbsvcs/orbsvcs/Notify/XML_Saver.h: + * orbsvcs/orbsvcs/Notify/XML_Saver.cpp: + * orbsvcs/orbsvcs/Notify/XML_Topology_Factory.h: + * orbsvcs/orbsvcs/Notify/XML_Topology_Factory.cpp: + + * orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp: + + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp: + + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp: + + * orbsvcs/tests/Notify/PluggableTopology/Test_Saver.h: + * orbsvcs/tests/Notify/PluggableTopology/Test_Saver.cpp: + * orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.h: + * orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.cpp: + + * orbsvcs/tests/Notify/Reconnecting/Consumer.cpp: + * orbsvcs/tests/Notify/Reconnecting/Supplier.cpp: + * orbsvcs/tests/Notify/Reconnecting/event.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_mt.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_mt_both.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_mt_topo.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_st.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_st_both.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_st_topo.conf: + + * orbsvcs/tests/Notify/Unit/TestBasicTypes.cpp: + + Rename namespace used in OCI reliable notification service work + from TAO_NOTIFY to TAO_Notify (note case). + Integrate event reliability. + Status: Normal event delivery still works. + Reliable event delivery being tested. + Reload events after failure, not merged yet. + + +Mon Oct 25 20:41:00 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/orbsvcs/CosNotification.mpc: + * orbsvcs/orbsvcs/Notify/Any/AnyEvent.h: + * orbsvcs/orbsvcs/Notify/Any/AnyEvent.cpp: + * orbsvcs/orbsvcs/Notify/Buffering_Strategy.h: + * orbsvcs/orbsvcs/Notify/Buffering_Strategy.cpp: + * orbsvcs/orbsvcs/Notify/Consumer.h: + * orbsvcs/orbsvcs/Notify/Consumer.cpp: + * orbsvcs/orbsvcs/Notify/Event.h: + * orbsvcs/orbsvcs/Notify/Event.inl: + * orbsvcs/orbsvcs/Notify/Method_Request.h: + * orbsvcs/orbsvcs/Notify/Method_Request.inl: + * orbsvcs/orbsvcs/Notify/Method_Request.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.inl: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Event.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Event.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Updates.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Updates.cpp: + * orbsvcs/orbsvcs/Notify/ProxySupplier.h: + * orbsvcs/orbsvcs/Notify/ProxySupplier.cpp: + * orbsvcs/orbsvcs/Notify/Reactive_Task.h: + * orbsvcs/orbsvcs/Notify/Reactive_Task.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip.cpp: + * orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.cpp: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.cpp: + * orbsvcs/orbsvcs/Notify/ThreadPool_Task.h: + * orbsvcs/orbsvcs/Notify/ThreadPool_Task.cpp: + * orbsvcs/orbsvcs/Notify/Worker_Task.h: + Rename Method_Request classes for consistency and self-documentation. + Naming convention: + Base classes have no suffix (i.e. TAO_Notify_Method_Request) + Uncopied classes (on stack) keep their No_Copy suffix. + Copied classes (on heap) have a _Queueable suffix. + + + + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_Base.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_Base.inl: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_Base.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_Base.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_Base.inl: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_Base.cpp: + Removed these files. + +Mon Oct 25 14:51:09 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/orbsvcs/CosNotification.mpc: + CosNotification_Serv: Add dependancy on svc_utils + CosNotification_Serv: Add Method_Dispatch_Base and Method_Lookup_Base + + * orbsvcs/orbsvcs/Notify/Admin.cpp: + * orbsvcs/orbsvcs/Notify/ConsumerAdmin.cpp: + * orbsvcs/orbsvcs/Notify/EventChannel.cpp: + * orbsvcs/orbsvcs/Notify/EventChannelFactory.cpp: + * orbsvcs/orbsvcs/Notify/EventTypeSeq.cpp: + * orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.cpp: + * orbsvcs/orbsvcs/Notify/Random_File.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.cpp: + * orbsvcs/orbsvcs/Notify/XML_Loader.cpp: + Use "DEBUG_LEVEL" to enable "local debug messages" consistently. + + * orbsvcs/orbsvcs/Notify/Name_Value_Pair.h: + * orbsvcs/orbsvcs/Notify/Topology_Saver.h: + Change export library name. + + * orbsvcs/orbsvcs/Notify/Consumer.h: + * orbsvcs/orbsvcs/Notify/Consumer.inl: + * orbsvcs/orbsvcs/Notify/Consumer.cpp: + * orbsvcs/orbsvcs/Notify/Delivery_Request.cpp: + * orbsvcs/orbsvcs/Notify/Event.h: + * orbsvcs/orbsvcs/Notify/Event.inl: + * orbsvcs/orbsvcs/Notify/Event.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request.h: + * orbsvcs/orbsvcs/Notify/Method_Request.inl: + * orbsvcs/orbsvcs/Notify/Method_Request.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_Base.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_Base.inl: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_Base.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Event.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Event.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_Base.cpp: + * orbsvcs/orbsvcs/Notify/ProxySupplier.h: + * orbsvcs/orbsvcs/Notify/ProxySupplier.cpp: + * orbsvcs/orbsvcs/Notify/Reactive_Task.h: + * orbsvcs/orbsvcs/Notify/Reactive_Task.cpp: + * orbsvcs/orbsvcs/Notify/SupplierAdmin.cpp: + * orbsvcs/orbsvcs/Notify/ThreadPool_Task.h: + * orbsvcs/orbsvcs/Notify/ThreadPool_Task.cpp: + * orbsvcs/orbsvcs/Notify/Worker_Task.h: + * orbsvcs/orbsvcs/Notify/Any/AnyEvent.h: + * orbsvcs/orbsvcs/Notify/Any/AnyEvent.cpp: + * orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Any/PushConsumer.h: + * orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Any/PushSupplier.h: + * orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h: + * orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.h: + Create a common base class for Method_Requests that deal with events. + Use it instead of the *Dispatch_T and *Lookup_T templates. + Use inheritance and virtual methods rather than function overloading + to distinguish copied events from uncopied events. This allowed a lot + of duplicate code to be removed (not to mention the duplicate template + expansions) and avoided the need to do everything twice in the routing slip + family of objects. + + The event now "knows" whether it's been copied to the heap. The copy_on_heap + method is supported by all events and returns a pointer to the copied event. + As a side effect this eliminates the possibility that multiple heap copies + of the event will be created (the TAO_Notify_Method_Request_No_Copy_Ex may + have avoided multiple copies but it was hard to tell.) + Because the ACE Refcounted_Auto_Ptr is not very smart, I switched to using + TAO_Notify_Refcount_Guard_T which is smarter, but strangely named. I also beefed + up *Refcount_Guard" to allow null construction (for inclusion in collections) and + semantically correct copies. The result is that there is no need for all the refcount + pointers an event to be aware of each other. It is safe to create a new refcount pointer + given only a pointer to the heap-copy of the event. + + Change the event delivery logic in the consumer so that a delivery failure can + cause an event to be kept on a queue for the consumer rather than discarding the + event and deleting the consumer. This will be needed to support persistent events. + An unfortunate side effect is I used a simple queue rather than a Buffering_Strategy + to hold these events pending delivery. As a result there are cases in which the + delivery policy specified by QoS parameters may not work exactly right. This can + be fixed in the future by adding the missing functionality to Buffering Strategy. + + Status as of this checkin: The notification service and the RT notification service + build without warnings (with or without simulated exceptions) All tests passed by + the DOC group head branch also pass with these changes. + + * orbsvcs/tests/Notify/Basic/MultiTypes.cpp: + It was spinning waiting for incoming messages. I made it wait instead. + I also added a comment about a potential timing problem that showed up + during debugging. This will not happen in a "real" test so I didn't fix it. + + * orbsvcs/tests/Notify/Blocking/notify.conf: + Fix trailing 'x' (also done in head branch) + +Wed Oct 20 11:38:11 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.h: + * orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.inl: + Add copy constructor and operator =. + +Tue Oct 19 10:43:28 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.inl: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.inl: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.cpp: + Removed these files. + Replacing template-based with inheritence-based copy managament. + The problem with a template based approach (other than the + obscurity of overloading methods based on raw vs smart + pointer (some comments would have been nice!)) is the + source code explosion. Because the distinction + between Event * and Event_var is meaningful, every stage of the + process has to provide (at least) two methods to preserve this + distinction even when this stage doesn't care. + This became a problem in adding event persistence because it + meant that the event persistence stuff would also have to preserve + this "state-by-pointer-type" info. + + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_Base.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_Base.inl: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_Base.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_Base.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_Base.inl: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup_Base.cpp: + Added these files. + + + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.cpp: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup.h: + * orbsvcs/orbsvcs/Notify/Method_Request_Lookup.cpp: + Now derived from *_Base rather than _T<x,x,x,x> + + + * orbsvcs/orbsvcs/Notify/Any/AnyEvent.h: + * orbsvcs/orbsvcs/Notify/Any/AnyEvent.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.cpp: + * orbsvcs/orbsvcs/Notify/Event.h: + * orbsvcs/orbsvcs/Notify/Event.inl: + * orbsvcs/orbsvcs/Notify/Event.cpp: + The distinction that the templates were attempting to preserve + was whether or not the event had been copied to the heap. + The goal was to keep the event on the stack as long as possible, + but make a copy on the heap when it became necessary to queue the + event for later processing or for another thread. + + This is now handled by providing a virtual "Event::copy_on_heap" method. + A event on the stack makes a copy and returns a pointer to it. + A event on the heap just returns a pointer to itself. + + * orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.h: + * orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.inl: + The pointer to events was based on Refcountable_Auto_Ptr which is + not smart enough to have two pointers to the same object unless one + was created from the other. Event was changed to be a Refcountable + object and Refcountable_Guard was extended to allow null pointers, + thereby allowing it to be contained in a collection. Asserts protect + null Refcountable_Guards from misuse. + + * orbsvcs/orbsvcs/Notify/Consumer.h: + * orbsvcs/orbsvcs/Notify/Consumer.inl: + * orbsvcs/orbsvcs/Notify/Consumer.cpp: + * orbsvcs/orbsvcs/Notify/Proxy.h: + * orbsvcs/orbsvcs/Notify/Proxy.inl: + * orbsvcs/orbsvcs/Notify/ProxySupplier.h: + * orbsvcs/orbsvcs/Notify/ProxySupplier.cpp: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp: + Eliminate overridden-by-pointer-type methods that are + no longer needed. Use copy_on_heap when necessary. + + +Mon Oct 18 15:21:49 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/orbsvcs/Notify/Buffering_Strategy.h: + * orbsvcs/orbsvcs/Notify/Builder.h: + * orbsvcs/orbsvcs/Notify/EventChannel.h: + Build issues. + +Mon Oct 18 10:29:48 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/orbsvcs/Notify/Any/AnyEvent.inl: + * orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.inl: + * orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.inl: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.inl: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.inl: + * orbsvcs/orbsvcs/Notify/Any/PushConsumer.inl: + * orbsvcs/orbsvcs/Notify/Any/PushSupplier.inl: + * orbsvcs/orbsvcs/Notify/RT_Builder.inl: + * orbsvcs/orbsvcs/Notify/RT_Factory.inl: + * orbsvcs/orbsvcs/Notify/RT_Notify_Service.inl: + * orbsvcs/orbsvcs/Notify/RT_POA_Helper.inl: + * orbsvcs/orbsvcs/Notify/RT_Properties.inl: + * orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.inl: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.inl: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.inl: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.inl: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.inl: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.inl: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.inl: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.inl: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.inl: + .inl's should not include their own .h + +Mon Oct 18 10:11:47 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/orbsvcs/Notify/Bit_Vector.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.h: + * orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.h: + * orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.cpp: + Change export library name + + * orbsvcs/orbsvcs/Notify/Delivery_Request.h: + * orbsvcs/orbsvcs/Notify/Delivery_Request.cpp: + Change export library name + Use 1.4 naming convention for pointers. + + + * orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.h: + Change export library name + Use renamed Random_File. + + + * orbsvcs/orbsvcs/Notify/Find_Worker_T.h: + * orbsvcs/orbsvcs/Notify/Find_Worker_T.cpp: + Make it const correct. + + * orbsvcs/orbsvcs/Notify/Topology_Object.h: + * orbsvcs/orbsvcs/Notify/Topology_Object.cpp: + Use V1.4 naming convention for object id. + + + + * orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.inl: + * orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.inl: + .inl's should not include their own .h + + +Tue Oct 12 14:10:43 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/orbsvcs/Notify/Delivery_Request.inl: + * orbsvcs/orbsvcs/Notify/Routing_Slip.inl: + Pick up Event Persistence files missed during + previous merge. + + * orbsvcs/orbsvcs/Notify/Random_File.h: + * orbsvcs/orbsvcs/Notify/Random_File.cpp: + Rename Persistent_File->Random_File + + * orbsvcs/orbsvcs/Notify/Delivery_Method.h: + * orbsvcs/orbsvcs/Notify/Delivery_Method.cpp: + * orbsvcs/orbsvcs/Notify/Delivery_Method_Dispatch.h: + * orbsvcs/orbsvcs/Notify/Delivery_Method_Dispatch.cpp: + * orbsvcs/orbsvcs/Notify/Delivery_Method_Lookup.h: + * orbsvcs/orbsvcs/Notify/Delivery_Method_Lookup.cpp: + * orbsvcs/orbsvcs/Notify/Persistent_File.h: + * orbsvcs/orbsvcs/Notify/Persistent_File.cpp: + + Removed these files. + + +Mon Oct 11 14:39:15 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/tests/Notify/Unit/Notify_Unit.mpc: + * orbsvcs/tests/Notify/Unit/TestBasic.h: + * orbsvcs/tests/Notify/Unit/TestBasic.cpp: + * orbsvcs/tests/Notify/Unit/TestBasicTypes.h: + * orbsvcs/tests/Notify/Unit/TestBasicTypes.cpp: + * orbsvcs/tests/Notify/Unit/TestBuilder.h: + * orbsvcs/tests/Notify/Unit/TestBuilder.cpp: + * orbsvcs/tests/Notify/Unit/TestQoS.h: + * orbsvcs/tests/Notify/Unit/TestQoS.cpp: + * orbsvcs/tests/Notify/Unit/UnitTester.h: + * orbsvcs/tests/Notify/Unit/main.cpp: + * orbsvcs/tests/Notify/Unit/readme: + * orbsvcs/tests/Notify/Unit/run_test.pl: + * orbsvcs/tests/Notify/Unit/start_ns.pl: + Copy Unit test from OCI branch. Needs work. +Thu Oct 7 09:40:51 2004 Dale Wilson <wilson_d@ociweb.com> + + * ChangeLog_pnotify: + + * docs/notification/reliability.html: + + * orbsvcs/orbsvcs/CosNotification.mpc: + * orbsvcs/orbsvcs/Notify/Admin.h: + * orbsvcs/orbsvcs/Notify/Admin.inl: + * orbsvcs/orbsvcs/Notify/Admin.cpp: + * orbsvcs/orbsvcs/Notify/AdminProperties.h: + * orbsvcs/orbsvcs/Notify/AdminProperties.inl: + * orbsvcs/orbsvcs/Notify/AdminProperties.cpp: + * orbsvcs/orbsvcs/Notify/AllocTracker.h: + * orbsvcs/orbsvcs/Notify/Bit_Vector.h: + * orbsvcs/orbsvcs/Notify/Bit_Vector.cpp: + * orbsvcs/orbsvcs/Notify/Builder.h: + * orbsvcs/orbsvcs/Notify/Builder.cpp: + * orbsvcs/orbsvcs/Notify/ConsumerAdmin.h: + * orbsvcs/orbsvcs/Notify/ConsumerAdmin.cpp: + * orbsvcs/orbsvcs/Notify/CosNotify_Service.cpp: + * orbsvcs/orbsvcs/Notify/Delivery_Method.h: + * orbsvcs/orbsvcs/Notify/Delivery_Method.cpp: + * orbsvcs/orbsvcs/Notify/Delivery_Method_Dispatch.h: + * orbsvcs/orbsvcs/Notify/Delivery_Method_Dispatch.cpp: + * orbsvcs/orbsvcs/Notify/Delivery_Method_Lookup.h: + * orbsvcs/orbsvcs/Notify/Delivery_Method_Lookup.cpp: + * orbsvcs/orbsvcs/Notify/Delivery_Request.h: + * orbsvcs/orbsvcs/Notify/Delivery_Request.cpp: + * orbsvcs/orbsvcs/Notify/EventChannel.h: + * orbsvcs/orbsvcs/Notify/EventChannel.cpp: + * orbsvcs/orbsvcs/Notify/EventChannelFactory.h: + * orbsvcs/orbsvcs/Notify/EventChannelFactory.cpp: + * orbsvcs/orbsvcs/Notify/EventType.h: + * orbsvcs/orbsvcs/Notify/EventType.cpp: + * orbsvcs/orbsvcs/Notify/EventTypeSeq.h: + * orbsvcs/orbsvcs/Notify/EventTypeSeq.cpp: + * orbsvcs/orbsvcs/Notify/Event_Manager.cpp: + * orbsvcs/orbsvcs/Notify/Event_Persistence_Factory.h: + * orbsvcs/orbsvcs/Notify/Event_Persistence_Strategy.h: + * orbsvcs/orbsvcs/Notify/FilterAdmin.h: + * orbsvcs/orbsvcs/Notify/FilterAdmin.cpp: + * orbsvcs/orbsvcs/Notify/ID_Factory.h: + * orbsvcs/orbsvcs/Notify/ID_Factory.inl: + * orbsvcs/orbsvcs/Notify/ID_Factory.cpp: + * orbsvcs/orbsvcs/Notify/Name_Value_Pair.h: + * orbsvcs/orbsvcs/Notify/Name_Value_Pair.inl: + * orbsvcs/orbsvcs/Notify/Name_Value_Pair.cpp: + * orbsvcs/orbsvcs/Notify/Object.h: + * orbsvcs/orbsvcs/Notify/Object.inl: + * orbsvcs/orbsvcs/Notify/Object.cpp: + * orbsvcs/orbsvcs/Notify/POA_Helper.h: + * orbsvcs/orbsvcs/Notify/POA_Helper.cpp: + * orbsvcs/orbsvcs/Notify/Peer.h: + * orbsvcs/orbsvcs/Notify/Persistent_File.h: + * orbsvcs/orbsvcs/Notify/Persistent_File.cpp: + * orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.h: + * orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.cpp: + * orbsvcs/orbsvcs/Notify/Properties.h: + * orbsvcs/orbsvcs/Notify/Properties.inl: + * orbsvcs/orbsvcs/Notify/PropertySeq.h: + * orbsvcs/orbsvcs/Notify/PropertySeq.inl: + * orbsvcs/orbsvcs/Notify/PropertySeq.cpp: + * orbsvcs/orbsvcs/Notify/Property_Boolean.h: + * orbsvcs/orbsvcs/Notify/Property_Boolean.inl: + * orbsvcs/orbsvcs/Notify/Property_T.h: + * orbsvcs/orbsvcs/Notify/Property_T.inl: + * orbsvcs/orbsvcs/Notify/Proxy.h: + * orbsvcs/orbsvcs/Notify/Proxy.cpp: + * orbsvcs/orbsvcs/Notify/ProxyConsumer.cpp: + * orbsvcs/orbsvcs/Notify/ProxySupplier.h: + * orbsvcs/orbsvcs/Notify/ProxySupplier.cpp: + * orbsvcs/orbsvcs/Notify/ProxySupplier_T.cpp: + * orbsvcs/orbsvcs/Notify/Proxy_T.cpp: + * orbsvcs/orbsvcs/Notify/QoSProperties.h: + * orbsvcs/orbsvcs/Notify/QoSProperties.inl: + * orbsvcs/orbsvcs/Notify/QoSProperties.cpp: + * orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.h: + * orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.cpp: + * orbsvcs/orbsvcs/Notify/Reconnection_Registry.h: + * orbsvcs/orbsvcs/Notify/Reconnection_Registry.inl: + * orbsvcs/orbsvcs/Notify/Reconnection_Registry.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.cpp: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.h: + * orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.cpp: + * orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.h: + * orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.cpp: + * orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.h: + * orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.cpp: + + * orbsvcs/orbsvcs/Notify/SupplierAdmin.h: + * orbsvcs/orbsvcs/Notify/SupplierAdmin.cpp: + * orbsvcs/orbsvcs/Notify/Topology_Factory.h: + * orbsvcs/orbsvcs/Notify/Topology_Loader.h: + * orbsvcs/orbsvcs/Notify/Topology_Loader.cpp: + * orbsvcs/orbsvcs/Notify/Topology_Object.h: + * orbsvcs/orbsvcs/Notify/Topology_Object.inl: + * orbsvcs/orbsvcs/Notify/Topology_Object.cpp: + * orbsvcs/orbsvcs/Notify/Topology_Saver.h: + * orbsvcs/orbsvcs/Notify/Topology_Saver.cpp: + * orbsvcs/orbsvcs/Notify/XML_Loader.h: + * orbsvcs/orbsvcs/Notify/XML_Loader.cpp: + * orbsvcs/orbsvcs/Notify/XML_Saver.h: + * orbsvcs/orbsvcs/Notify/XML_Saver.cpp: + * orbsvcs/orbsvcs/Notify/XML_Topology_Factory.h: + * orbsvcs/orbsvcs/Notify/XML_Topology_Factory.cpp: + * orbsvcs/orbsvcs/Notify/notify_persist_export.h: + * orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.cpp: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp: + * orbsvcs/orbsvcs/Notify/Any/PushConsumer.h: + * orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Any/PushSupplier.h: + * orbsvcs/orbsvcs/Notify/Any/PushSupplier.cpp: + + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h: + * orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.cpp: + + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.h: + * orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.cpp: + + * orbsvcs/orbsvcs/NotifyExt.idl: + + * orbsvcs/tests/Notify/PluggableTopology/PlugTop.mpc: + * orbsvcs/tests/Notify/PluggableTopology/Test_Saver.h: + * orbsvcs/tests/Notify/PluggableTopology/Test_Saver.cpp: + * orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.h: + * orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.cpp: + * orbsvcs/tests/Notify/PluggableTopology/main.cpp: + * orbsvcs/tests/Notify/PluggableTopology/plugtop_export.h: + * orbsvcs/tests/Notify/PluggableTopology/plugtop_ns.conf: + + * orbsvcs/tests/Notify/Reconnecting/Consumer.h: + * orbsvcs/tests/Notify/Reconnecting/Consumer.cpp: + * orbsvcs/tests/Notify/Reconnecting/README: + * orbsvcs/tests/Notify/Reconnecting/Reconnecting.mpc: + * orbsvcs/tests/Notify/Reconnecting/Supplier.h: + * orbsvcs/tests/Notify/Reconnecting/Supplier.cpp: + * orbsvcs/tests/Notify/Reconnecting/event.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_mt.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_mt_both.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_mt_topo.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_st.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_st_both.conf: + * orbsvcs/tests/Notify/Reconnecting/ns_st_topo.conf: + * orbsvcs/tests/Notify/Reconnecting/run_test.pl: + + * orbsvcs/tests/Notify/XML_Persistence/XML_Persistence.mpc: + * orbsvcs/tests/Notify/XML_Persistence/main.cpp: + * orbsvcs/tests/Notify/XML_Persistence/run_test.pl: + * orbsvcs/tests/Notify/XML_Persistence/svc.conf: + + * orbsvcs/tests/Notify/lib/Periodic_Consumer.cpp: + + Merge OCI's Notification Service Changes into DOC group. + Connectivity (i.e. topology) persistence is working + Event persistence is not, yet. + Fri Nov 19 12:46:00 2004 Gary Maxey <gary.maxey@hp.com> * tests/CodeSets/simple/run_test.pl diff --git a/TAO/TAO-INSTALL.html b/TAO/TAO-INSTALL.html index 41f004eeaee..d0fa73d7836 100644 --- a/TAO/TAO-INSTALL.html +++ b/TAO/TAO-INSTALL.html @@ -60,7 +60,7 @@ TAO. If you have <A HREF="../docs/ACE-porting.html">porting questions</A> or have a problem compiling the TAO along with ACE wrappers on the platforms shown above please send email to either the -<A HREF="news:comp.soft-sys.ace">Newsgroup</A> or to the <A +<A HREF="news:comp.soft-sys.ace">Newsgroup</A> or to the <A HREF="mailto:ace-users@cs.wustl.edu">TAO mailing list</A> and we'll try to help you fix the problems. You can also submit bug reports and enhancement requests in our @@ -74,7 +74,7 @@ with the <A HREF="http://www.dre.vanderbilt.edu/ACE"> ACE </A> release. You'll always need the most recent version of ACE because TAO tracks and influences changes to ACE. Always use the ACE+TAO release -bundle as a single piece instead of trying to mix and match things up.<P> +bundle as a single piece instead of trying to mix and match things up.<P> <HR><P> <H3>On UNIX platforms</H3> @@ -123,7 +123,7 @@ bundle as a single piece instead of trying to mix and match things up.<P> <P>If you wish to compile the ORB services distributed with TAO, including the <CODE>Naming_Service</CODE> you must include <CODE>$TAO_ROOT/orbsvcs</CODE> to the list - above. Please see the + above. Please see the <A HREF="docs/configurations.html#orbsvcs">TAO configuration documentation</a> for a discussion on how to create a subset configuration of specific TAO ORB servcies. @@ -160,7 +160,7 @@ etc.<p> GNU Make can be obtained from various places in source and binary form. Please see <a href="../ACE-INSTALL.html"> ACE-INSTALL.html </a> -for details from where they can be obtained.<P> +for details from where they can be obtained.<P> <HR><P> @@ -290,7 +290,7 @@ $ echo 'include $(ACE_ROOT)/include/makeinclude/platform_TARGET.GNU' \ <a href="../ACE-INSTALL.html#vxworks">../ACE-INSTALL.html</a>, and <a href="../ACE-INSTALL.html#VxWorks/NT">Building ACE on - Tornado/NT hosts for VxWorks targets</a> + Tornado/NT hosts for VxWorks targets</a> </P> <P>Please note that dynamic loading of libraries is not supported @@ -301,7 +301,7 @@ $ echo 'include $(ACE_ROOT)/include/makeinclude/platform_TARGET.GNU' \ <P>If using perfect hashing, TAO_IDL needs gperf to be built on the host. That's the default on many platforms. First, build <code>gperf</code> in the - <code>ACE_wrappers/apps/gperf/src/</code> directory. + <code>ACE_wrappers/apps/gperf/src/</code> directory. </P> <H4>Which one is right for me?</H4> @@ -376,15 +376,8 @@ project </a> file.</P> files that loads the projects ACE, ACEXML, Kokyu, TAO, TAO_IDL (the compiler), gperf, the orb services libraries, and the standalone executables (such as Naming Service, etc.). It can be used to build -all the files needed to build/run TAO applications.</P> - -<<<<<<< TAO-INSTALL.html -<H4>Visual C++ 7.1</H4> The DOC group doesn't support TAO on VC++ 7.0 -since the libraries that were shipped with VC++ 7.0 did not work -well. The DOC group supports only VC++ 7.1, which is used by their -sponsors. The following points are relevant to users who are trying to -use TAO with VC++ 7.1. -======= +all the files needed to build/run TAO applications.</P> + <H4>Visual C++ 7.1</H4> The DOC group doesn't support TAO on VC++ 7.0 since the libraries that were shipped with VC++ 7.0 did not work well. The DOC group supports @@ -393,7 +386,6 @@ points are also relevant to users who are trying to use TAO with VC++ 7.1. Additionally, all required options are set for the generated .sln files. If something is missing then it is probably a bug with MPC. Please report such bugs to the tao-users newsgroups. ->>>>>>> 1.86 <H4>Borland C++ Builder</H4> <P> @@ -434,7 +426,7 @@ creating static libraries and linking with them. <P>First, follow the build instructions in the <A HREF="../ACE-INSTALL.html#mingw">ACE installation notes.</A> When building with MinGW and Cygwin you are using the GNU make under Windows. -When you use make from the commandline, make sure that <code>TAO_ROOT</code> is +When you use make from the commandline, make sure that <code>TAO_ROOT</code> is set to a full path or to <code>%ACE_ROOT%/TAO</code>, which will also result in setting a full path. Setting it with the Unix style to <code>$ACE_ROOT/TAO</code> will not work, setting it using the make style to <code>$(ACE_ROOT)/TAO</code> looks @@ -499,27 +491,27 @@ GNUmakefiles, and project files for building on various platforms will not be available. Users from anon cvs are expected to generate them using <a href="../MPC/README">MPC</a> before building ACE, TAO or CIAO. We point out some suggestions below to get bootstrapped -quickly. +quickly. <UL> <LI> Please see <a href="#MPC"> instructions </a> above to download - MPC from anon cvs repository <p> + MPC from anon cvs repository <p> <LI>Please make sure that you have <a href="http://www.perl.org"> - perl</a> installed, preferably perl - 5.8 or higher. Users on Win32 based platforms are recommended to use + perl</a> installed, preferably perl + 5.8 or higher. Users on Win32 based platforms are recommended to use <a href="http://www.activestate.com/Products/ActivePerl/"> Active State Perl </a>. We use active state perl without problems. We have ran into problems trying to use the cygwin version of perl on Win32 based platforms. <p> <LI>If you just want to build TAO and associated tests, examples, and associated utility libraries, we recommend the following - alternatives: + alternatives: <UL> <LI> Build ACE and TAO seperately. ACE needs to be built first and instructins for building ACE are available at <a href="../ACE-INSTALL.html#MPC">ACE-INSTALL</a>. GNUmakefiles and project files for TAO can be generated by using the following - commands:<p> + commands:<p> <CODE> $ACE_ROOT/bin/mwc.pl TAO.mwc </CODE> <p> from <CODE> $TAO_ROOT </CODE> to generate GNUmakefiles. Use <CODE> -type vc6 </CODE> or <CODE>-type vc71</CODE> to generate VC6 and @@ -539,9 +531,9 @@ quickly. <LI>If you want to build CIAO and its associated libraries please see <a href="CIAO/CIAO-INSTALL.html"> CIAO-INSTALL <a> for details. - - </UL> - + + </UL> + <HR><P> Back to the <A HREF="http://www.cs.wustl.edu/~schmidt/TAO.html">TAO</A> home page. diff --git a/TAO/docs/notification/reliability.html b/TAO/docs/notification/reliability.html new file mode 100644 index 00000000000..44c9c198035 --- /dev/null +++ b/TAO/docs/notification/reliability.html @@ -0,0 +1,346 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> + <head> + <title>Using the Reliable Notification Service</title> + <meta content="False" name="vs_snapToGrid"> + <meta content="False" name="vs_showGrid"> + <!-- $Id$ --> + </head> + <body> + <h1>Using the Reliable Notification Service</h1> + <h2>Background</h2> + <p>There are two CORBA services defined by the OMG to support the + Supplier/Consumer design pattern. This pattern allows messages (known as + Events in this context) to be generated by one or more suppliers and delivered + to one or more consumers without requiring that the suppliers and consumers + have any knowledge of each other. </p> + <P>The Event Service provides a basic implementation of this pattern, and the + Notification service extends this basic service to support a rich variety of + optional features.</P> + <h2>Reliability and Persistence</h2> + <p>One of the optional features of the Notification service is Reliability. + By default the Event Service and the Notification service provide a <EM>best-effort</EM> + support for event delivery. If things go wrong -- program crashes, + communications failures, etc. events may be lost without notice.</p> + <P>There are some circumstances in which losing events is not + acceptable. The Notification service may be used for these situations if + it is configured for reliable operation. Reliable operation is not + available in the Event Service. Reliable operation means information is + saved persistently (usually on a disk file) and used to recover from the + various failures that might otherwise lead to loss of data.</P> + <P>There are two separate, but related, issues that need to be addressed to + provide reliable event delivery: topology persistence an event + persistence.</P> + <P>To provide topology persistence, sometimes called connection persistence, the + Notification service must keep track of what clients (Suppliers and Consumers) + have connected to the Notification service and what options have been specified + to contol the delivery of events.</P> + <P>To provide event persistence the Notification service tracks each event in + persistent storage to be sure it is delivered to every consumer that should + receive it. + </P> + <P>There may be situations in which topology persistence is all that is necessary + -- it may be acceptable to lose events during a failure as long as + the system is restored to normal operation afterward. Event persistence + on the other hand can only be supported if topology persistence is also being + used. It doesn't help to keep track of events if the system is unable to + find the consumers to which the events should be delivered.</P> + <P>Two separate issues must be addressed as part of setting up the Notifcation + for reliable operation. At the system administration level the + Notification service must be configured for topology persistence and + possibly for event persistence. At the application level, programs + that operate as consumers and suppliers must set the appropriate parameters to + enable reliable operation, and must cooperate with the reconnection process + that occurs during topology recovery.</P> + <h2>Configuring Notification Service Reliability.</h2> + <h3>Service Configurator Changes</h3> + <P>Runtime configuration of the Notification Service is supported through the + service configurator file. This file is normally named svc.conf; however the + -ORBSvcConf command line option allows an alternate service configuration file + to be specified. + </P> + <P> + Service configuration changes to support Notification Service reliability + include a new option on the existing <code>Notify_Default_Event_Manager_Objects_Factory</code> + service configuration command, and two new service configuration commands. + </P> + <H4>Notify_Default_Event_Manager_Objects_Factory option: -AllowReconnect</H4> + <p>Certain recovery cases require that a Consumer be able to reconnect to an + existing proxy object in the Notification Service in order to receive all + events delivered by that proxy object. This behavior is a departure from the + OMG Specification which mandates that the Notification Service should throw an + "Already Connected" exception when a consumer attempts to connect to a proxy + that was previously used by another Consumer. + </p> + <p>A new option, -AllowReconnect, is available for the existing <code>Notify_Default_Event_Manager_Objects_Factory + </code>command to support this requirement. As an example of its use, the + following line configures the Notification Service for multi-threaded operation + supporting reconnection.</p> + <code>static Notify_Default_Event_Manager_Objects_Factory "-DispatchingThreads 2 + -SourceThreads 2 -AllowReconnect" </code> + <H3>Configuring Connection (Topologogy) Reliability</H3> + <p>The support for persistent topology is actually a configurable strategy. + TAO includes an XML Topology Persistence Strategy that uses an XML file for + persistent storage, but it it is designed to allow other strategies to be + developed. For example if topology information should be stored in a + relational database file, it is possible to develop a persistent topology + strategy to do so. The details of doing this are beyond the scope of this + document. + </p> + <P>This document describes how to configure the XML topology persistence included + with TAO.</P> + <P>An example of the service configuration command to configure the XML + strategy is: + </P> + <p><code>dynamic Topology_Factory Service_Object* + TAO_CosNotification_persist:_make_XML_Topology_Factory() "-base_path ./reconnect_test" </code> + </p> + <p>The first part of this line: <code>dynamic Topology_Factory Service_Object* + TAO_CosNotification_persist:_make_XML_Topology_Factory()</code>should be given + exactly as shown. For details on this syntax, see chapter 17 of the TAO + Developer's Guide. + </p> + <P>The quoted string at the end of the line contain arguments for the configured + strategy. The arguments recognized by the XML topology strategy implemented in + this project are: + </P> + <ul> + <li> + -v + <li> + -base_path <EM>file_path</EM> + <li> + -backup_count <EM>count</EM> + <li> + -save_base_path <EM>file_path</EM> + <li> + -load_base_path <EM>file_path</EM> + <li> + <H4>-no_timestamp + </H4> + </li> + </ul> + <H4>Topology_Factory Option: -v</H4> + To help diagnose and/or document svc.conf settings, the "-v" will cause the + options for the Topology_Factory to be displayed as they are interpreted + <H4>Topology_Factory Option: -base_path file_path + </H4> + <P>The argument for this option is a fully qualified path name without an + extension for the xml file in which topology information is saved. Three + extensions will be appended to this name: .new, .xml, and .000 + </P> + <P>Saved topology information will be written to <EM>file_path</EM>.new file. + Information with a .new extension is not necessarily complete and will not be + used to restore the topology. + </P> + <P>When the .new file is complete, the previous <EM>file_path</EM>.000 (if any) + will be deleted, the previous <EM>file_path</EM>.xml (if any) will be renamed + as <EM>file_path</EM>.000 and the <EM>file_path</EM>.new file will be renamed + as file_path.xml. The assumption is that a file system rename operation is + atomic. If this assumption holds than at any time the file <EM>file_path</EM>.xml + (if it exists) contains the most recent complete save. If <EM>file_path</EM>.xml + does not exist then <EM>file_path</EM>.000 contains the most recent complete + save. If neither of these files exist the saved topology information is not + available. + </P> + <H4>Topology_Factory Option: -backup_count count</H4> + <P>This option modifies the behavior described in the preceeding section to allow + additional backup copies of the topology file to be retained. The default + value, 1, means that only the <EM>file_path</EM>.000 file will be kept. If a + higher number is specified, then older versions will be kept. Rather than + deleting <EM>file_path</EM>.000, the system will rename it to be <EM>file_path.</EM>001. + Older versions will be named <EM>file_path</EM>.002, <EM>file_path</EM>.002 and + so on. + </P> + <P>Under normal circumstances only one backup file is required -- in fact these + additional backup files will not be used to restore the topoogy. However + setting this number to a larger value lets the system keep a brief history of + topology changes. Since the XML files are roughly human-readable this can be + used as a diagnostic tool for problems related to Notification Service + topology. + </P> + <H4>Topology_Factory Options: -save_base_path file_path and -load_base_path + file_path + </H4> + <P>These options are alternatives to the -base_path option. They allow the file + from which topology information is loaded at Notification Service startup time + to be different from the file to which this information is saved as the system + runs. + </P> + <P>This option is mostly used for developer testing, a system administrator may + find an interesting use for this option -- possibly involving script files that + rename the XML files during recovery from a Notification Service failure. + </P> + <H4>Topology_Factory Option: -no_timestamp</H4> + <P>The XML files include a timestamp to indicate when the information was saved. + The timestamp is for information only and is not needed for correct functioning + of the topology persistence. This option suppresses that timestamp. Doing so + makes it possible to compare XML files using a program like diff to see if the + files represent the same topology. + </P> + <P>This option is intended primarily for testing the persistent topology + implementation. + </P> + <h3>Configuring Event Reliability</h3> + <p>A service configuraton new object, "Event_Persistence", can be configured in + the service configuration file to enable and configure the Event Reliability. + An example of the line needed to configure the Event_Persistence object is: + </p> + <p><code>dynamic Event_Persistence Service_Object* + TAO_CosNotification_persist:_make_Standard_Event_Persistence() "-v -file_path + ./event_persist.db" </code> + </p> + <p><CODE></CODE>If this line does not appear in svc.conf, then event reliability + will not be supported. QoS parameters for reliable event delivery will be + silently ignored when Event Reliability is not configured. Event reliability + also requires topology reliability, so if this line appears there must also be + a "Topology_Factory" line in the file. If not, the Notification Service will + fail to start up. + </p> + <P>The beginning of this line, up to and including the parentheses, should appear + exactly as shown. For details on this syntax, see chapter 17 of the TAO + Developer's Guide. The quoted string at the end of the line contains options + for Event_Persistence. + </P> + <h4>Event_Persistence Option: -v</h4> + <p>This option and any option that appears after this option will be written to + the log (normally the console) as it is processed. This is intended to help + diagnose and document the Event Persistence settings. The default is to + configure Event Persistence silently. + </p> + <h4>Event_Persistence Option: -file_path path + </h4> + <p>This option gives the completely qualified name for the file in which + persistent event information will be stored. The file should be configured on a + reliable device that supports synchronized writes (i.e. flushing the operating + system's write cache.) A device that is suitable for storing a reliable + database would be appropriate for storing this file. The file will be subject + to a relatively high number of small (single block) write requests, but very + few, if any, read requests. If the file does not exist, then a new file will be + created. If the file does exist, and if topology is successfully loaded, the + events from this file will be reloaded and redelivered automatically. This is a + required option. There is no default value. + </p> + <h4>Event_Persistence Option: -block_size n + </h4> + <p>This option gives the block size in bytes for the device on which the event + reliability file is stored. For both performance and reliability reasons it is + important that the value matches the physical characteristics of the device. + The default value is 512. + </p> + <h2>Application Programming Changes to Support Reliability</h2> + <p> + When it is configured as described above, the Notification service + supports reliable connectivity and/or event delivery. + Actually achieving such reliability, however, requires cooperation from the + Notification service clients (Suppliers and Consumers). + <P> + There are a number of failure possibilities and different recovery techniques + are needed to handle them. The simplest case is when a client + fails and is restarted. + <P> + The Notification service will have maintained the connection points (Supplier + and Consumer Admins, Proxy Consumers, Proxy Admins, etc.) As each of these + connections was established, an ID returned by the notification + service. An application that wishes to be reconnected after a failure + should save a persistent copy of these IDs. For example, it could write + the IDs to a file, then read them back from the file after restarting. + Using these ID's the application can reconnect to the existing connection + points in the Notification service. The reconnection to the Proxy objects + will only work if the Notification service has been configured with the + -AllowReconnection option described above, but otherwise this process is fairly + straightforward. + <P> + As soon as a supplier has reconnected, it can resume sending events. As + soon as a consumer has reconnected, persistent events (if any) and new events + will start to arrive. + <P> + Notice that the identity of a consumer or supplier is determined by these saved + IDs. This is true even if the restarted client is running on a completely + different machine from the original client. + <P> + The case of the Notification service itself failing then being restarted on the + same or a different machine is somewhat more complicated. The + Notification service wasn't designed to initiate a connection to a + client. It must wait for the client to reconnect before it can start + accepting or delivering events. The difficulty is in having the client + know when to initiatie the reconnection, and to where the Notification service + is running in case it was necessary to move it to a new machine due to the + failure + <H3>Reconnection Registry</H3> + <p>The reconnection registry provides an answer to the question of how the client + knows where and when to reconnect to the Notification service. This + TAO-specific interface is implemented by the EventChannelFactory in the + reliable Notification Service. Clients can narrow the EventChannelFactory + object reference to a Reconnection Registery interface, then register a + Reconnection Callback object that will be notified when the Notification + service has restarted and is ready for reconections. The + EventChannelFactory passes its own object reference to the Reconnection + Callback object to inform the client where the Notification service is now + running.</p> + <P>The interfaces involved are defined in the NotifyExt.idl file (in + $TAO_ROOT/orbsvcs/orbsvcs) and are shown here:</P> + <pre> + /** * \brief An interface which gets registered with a + ReconnectionRegistry. + * * A supplier or consumer must implement this interface in order + to * allow the Notification Service to attempt to reconnect to it + after * a failure. The supplier or consumer must register its instance + of * this interface with the + ReconnectionRegistry. + */ interface + ReconnectionCallback + { /// Perform operations to reconnect to the Notification + Service /// after a + failure. void reconnect (in Object + + new_connection); /// Check to see if the ReconnectionCallback is alive + boolean is_alive (); + }; + + /** + * \brief An interface that handles registration of suppliers and consumers. + * + * This registry should be implemented by an EventChannelFactory and + * will call the appropriate reconnect methods for all ReconnectionCallback + * objects registered with it. + */ + interface ReconnectionRegistry + { + typedef unsigned long ReconnectionID; + ReconnectionID register_callback(in ReconnectionCallback reconection); + + void unregister_callback (in ReconnectionID id); + + /// Check to see if the ReconnectionRegistry is alive + boolean is_alive (); + }; + </pre> + <H3>Using Event Reliability</H3> + <P>Configuring the Notification service for reliable event delivery is necessary, + but not sufficient to enable reliable handling of events. The application + code in either the client or the server must configure the EventChannel through + which the events are delivered to operate in the reliable mode. This is + done by setting the QoSProperties named "ConnectionReliabilty" and + "EventReliability" to the value "persistent" -- either at the time the channel + is created or at a later time useing the set_qos method.</P> + <P>Once an channel has been configured for reliable operation, persistence can be + disabled on an event by event basis using QoSProperties of the event + itself. This could be none, for examlpe, to avoid the overhead of + persistently storing events for which reliability is not needed.</P> + <P>The supplier sends events to the EventChannel using a push() method. For + persistent events, this call will not return to the supplier until the + Notification service is prepared to guarantee event delivery. + </P> + <P>Application code in the Consumer should be written with the knowledge that + events are guaranteed to be delivered, but during recovery from a failure there + is a possiblity that an event may arrive more than once. This could + happen, for example if the event was in the process of being delivered at the + time the failure occurred and the failure prevents the Notfication service from + determining if the delivery completed successfully. To meet its + committment that every event will be delivered, the Notification service will + retry the delivery in this canse which may result in a duplicate event.</P> + <P>As long as this situation is understood at the time the application is + designed, it should be possible for the application to handle this situation.</P> + </body> +</html> diff --git a/TAO/orbsvcs/Notify_Service/Notify_Service.cpp b/TAO/orbsvcs/Notify_Service/Notify_Service.cpp index 0e1eaf79ed2..12f7fdd7ea7 100644 --- a/TAO/orbsvcs/Notify_Service/Notify_Service.cpp +++ b/TAO/orbsvcs/Notify_Service/Notify_Service.cpp @@ -10,7 +10,7 @@ #include "ace/Argv_Type_Converter.h" #include "tao/ORB_Core.h" #include "ace/Dynamic_Service.h" -#include "../orbsvcs/Notify/Service.h" +#include "orbsvcs/orbsvcs/Notify/Service.h" TAO_Notify_Service_Driver::TAO_Notify_Service_Driver (void) : notify_service_ (0), @@ -90,7 +90,7 @@ TAO_Notify_Service_Driver::init (int argc, ACE_TCHAR *argv[] if (this->notify_service_ == 0) { - ACE_DEBUG ((LM_DEBUG, "Service not found! check conf. file\n")); + ACE_DEBUG ((LM_DEBUG, "Service not found! check conf.file\n")); return -1; } @@ -139,24 +139,6 @@ TAO_Notify_Service_Driver::init (int argc, ACE_TCHAR *argv[] ACE_ASSERT (!CORBA::is_nil (this->notify_factory_.in ())); - // Write IOR to a file, if asked. - CORBA::String_var str = - this->orb_->object_to_string (this->notify_factory_.in () ACE_ENV_ARG_PARAMETER); - ACE_CHECK_RETURN (-1); - - if (this->ior_output_file_) - { - ACE_OS::fprintf (this->ior_output_file_, - "%s", - str.in ()); - ACE_OS::fclose (this->ior_output_file_); - this->ior_output_file_ = 0; - } - else if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, - "The Notification Event Channel Factory IOR is <%s>\n", - str.in ())); - // Make it bootstrappable, if asked. if (this->bootstrap_) { @@ -184,84 +166,103 @@ TAO_Notify_Service_Driver::init (int argc, ACE_TCHAR *argv[] } } + // Register with the Name service, if asked if (this->use_name_svc_) - { - // Register the Factory - ACE_ASSERT (!CORBA::is_nil (this->naming_.in ())); + { + // Register the Factory + ACE_ASSERT (!CORBA::is_nil (this->naming_.in ())); #if defined (TAO_NOTIFY_USE_NAMING_CONTEXT) - CosNaming::Name name (1); - name.length (1); - name[0].id = - CORBA::string_dup (this->notify_factory_name_.c_str ()); + CosNaming::Name name (1); + name.length (1); + name[0].id = + CORBA::string_dup (this->notify_factory_name_.c_str ()); #else - CosNaming::Name_var name = - this->naming_->to_name (this->notify_factory_name_.c_str () - ACE_ENV_ARG_PARAMETER); + CosNaming::Name_var name = + this->naming_->to_name (this->notify_factory_name_.c_str () + ACE_ENV_ARG_PARAMETER); #endif /* TAO_NOTIFY_USE_NAMING_CONTEXT */ - ACE_CHECK_RETURN (-1); + ACE_CHECK_RETURN (-1); #if defined (TAO_NOTIFY_USE_NAMING_CONTEXT) - this->naming_->rebind (name, - this->notify_factory_.in () - ACE_ENV_ARG_PARAMETER); + this->naming_->rebind (name, + this->notify_factory_.in () + ACE_ENV_ARG_PARAMETER); #else - this->naming_->rebind (name.in (), - this->notify_factory_.in () - ACE_ENV_ARG_PARAMETER); + this->naming_->rebind (name.in (), + this->notify_factory_.in () + ACE_ENV_ARG_PARAMETER); #endif /* TAO_NOTIFY_USE_NAMING_CONTEXT */ - ACE_CHECK_RETURN (-1); + ACE_CHECK_RETURN (-1); - ACE_DEBUG ((LM_DEBUG, - "Registered with the naming service as: %s\n", - this->notify_factory_name_.c_str())); - - if (this->register_event_channel_ == 1) - { - // create an event channel - CosNotifyChannelAdmin::ChannelID id; - - CosNotification::QoSProperties initial_qos; - CosNotification::AdminProperties initial_admin; - - CosNotifyChannelAdmin::EventChannel_var ec = - this->notify_factory_->create_channel (initial_qos, - initial_admin, - id - ACE_ENV_ARG_PARAMETER); + ACE_DEBUG ((LM_DEBUG, + "Registered with the naming service as: %s\n", + this->notify_factory_name_.c_str())); + + if (this->register_event_channel_ == 1) + { + // create an event channel + CosNotifyChannelAdmin::ChannelID id; + + CosNotification::QoSProperties initial_qos; + CosNotification::AdminProperties initial_admin; + + CosNotifyChannelAdmin::EventChannel_var ec = + this->notify_factory_->create_channel (initial_qos, + initial_admin, + id + ACE_ENV_ARG_PARAMETER); #if defined (TAO_NOTIFY_USE_NAMING_CONTEXT) - name[0].id = - CORBA::string_dup (this->notify_channel_name_.c_str ()); + name[0].id = + CORBA::string_dup (this->notify_channel_name_.c_str ()); #else - name = this->naming_->to_name ( - this->notify_channel_name_.c_str () - ACE_ENV_ARG_PARAMETER); + name = this->naming_->to_name ( + this->notify_channel_name_.c_str () + ACE_ENV_ARG_PARAMETER); #endif /* TAO_NOTIFY_USE_NAMING_CONTEXT */ - ACE_CHECK_RETURN (-1); - + ACE_CHECK_RETURN (-1); #if defined (TAO_NOTIFY_USE_NAMING_CONTEXT) - this->naming_->rebind (name, - ec.in () - ACE_ENV_ARG_PARAMETER); + this->naming_->rebind (name, + ec.in () + ACE_ENV_ARG_PARAMETER); #else - this->naming_->rebind (name.in (), - ec.in () - ACE_ENV_ARG_PARAMETER); + this->naming_->rebind (name.in (), + ec.in () + ACE_ENV_ARG_PARAMETER); #endif /* TAO_NOTIFY_USE_NAMING_CONTEXT */ - ACE_CHECK_RETURN (-1); + ACE_CHECK_RETURN (-1); + + ACE_DEBUG ((LM_DEBUG, + "Registered an Event Channel with the naming service as: %s\n", + this->notify_channel_name_.c_str())); + + } + } - ACE_DEBUG ((LM_DEBUG, - "Registered an Event Channel with the naming service as: %s\n", - this->notify_channel_name_.c_str())); + // Write IOR to a file, if asked. + // Note: do this last to ensure that we're up and running before the file is written + CORBA::String_var str = + this->orb_->object_to_string (this->notify_factory_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); - } + if (this->ior_output_file_) + { + ACE_OS::fprintf (this->ior_output_file_, + "%s", + str.in ()); + ACE_OS::fclose (this->ior_output_file_); + this->ior_output_file_ = 0; } + else if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "The Notification Event Channel Factory IOR is <%s>\n", + str.in ())); return 0; } diff --git a/TAO/orbsvcs/orbsvcs/CosNotification.mpc b/TAO/orbsvcs/orbsvcs/CosNotification.mpc index 8d659c06e9c..1d35acea011 100644 --- a/TAO/orbsvcs/orbsvcs/CosNotification.mpc +++ b/TAO/orbsvcs/orbsvcs/CosNotification.mpc @@ -48,8 +48,7 @@ project(CosNotification) : orbsvcslib, core, event { Template_Files { } - - // explicit Resource_Files to avoid including _Skel & _Serv rc files. + Resource_Files{ CosNotification.rc } @@ -116,7 +115,7 @@ project(CosNotification_Skel) : orbsvcslib, core, notification, event_skel, port } } -project(CosNotification_Serv) : orbsvcslib, core, notification_skel, dynamicany, etcl { +project(CosNotification_Serv) : orbsvcslib, svc_utils, core, notification_skel, dynamicany, etcl{ sharedname = TAO_CosNotification_Serv dynamicflags = TAO_NOTIFY_SERV_BUILD_DLL tagchecks += Notify @@ -131,6 +130,7 @@ project(CosNotification_Serv) : orbsvcslib, core, notification_skel, dynamicany, Notify { Notify/Admin.cpp Notify/AdminProperties.cpp + Notify/Bit_Vector.cpp Notify/Buffering_Strategy.cpp Notify/Builder.cpp Notify/Consumer.cpp @@ -138,6 +138,7 @@ project(CosNotification_Serv) : orbsvcslib, core, notification_skel, dynamicany, Notify/CosNotify_Initializer.cpp Notify/CosNotify_Service.cpp Notify/Default_Factory.cpp + Notify/Delivery_Request.cpp Notify/ETCL_Filter.cpp Notify/ETCL_FilterFactory.cpp Notify/Event.cpp @@ -154,6 +155,7 @@ project(CosNotification_Serv) : orbsvcslib, core, notification_skel, dynamicany, Notify/Method_Request_Lookup.cpp Notify/Method_Request_Shutdown.cpp Notify/Method_Request_Updates.cpp + Notify/Name_Value_Pair.cpp Notify/Notify_Constraint_Interpreter.cpp Notify/Notify_Constraint_Visitors.cpp Notify/Notify_Default_Collection_Factory.cpp @@ -163,6 +165,7 @@ project(CosNotification_Serv) : orbsvcslib, core, notification_skel, dynamicany, Notify/Notify_EventChannelFactory_i.cpp Notify/Object.cpp Notify/Peer.cpp + Notify/Persistent_File_Allocator.cpp Notify/POA_Helper.cpp Notify/Properties.cpp Notify/PropertySeq.cpp @@ -171,14 +174,23 @@ project(CosNotification_Serv) : orbsvcslib, core, notification_skel, dynamicany, Notify/ProxyConsumer.cpp Notify/ProxySupplier.cpp Notify/QoSProperties.cpp + Notify/Random_File.cpp Notify/Reactive_Task.cpp Notify/Refcountable.cpp + Notify/Reconnection_Registry.cpp + Notify/Routing_Slip.cpp + Notify/Routing_Slip_Persistence_Manager.cpp + Notify/Routing_Slip_Queue.cpp Notify/Subscription_Change_Worker.cpp Notify/Supplier.cpp Notify/SupplierAdmin.cpp + Notify/Standard_Event_Persistence.cpp Notify/ThreadPool_Task.cpp Notify/Timer_Queue.cpp Notify/Timer_Reactor.cpp + Notify/Topology_Loader.cpp + Notify/Topology_Object.cpp + Notify/Topology_Saver.cpp Notify/Worker_Task.cpp Notify/Any/AnyEvent.cpp Notify/Any/CosEC_ProxyPushConsumer.cpp @@ -203,3 +215,20 @@ project(CosNotification_Serv) : orbsvcslib, core, notification_skel, dynamicany, Template_Files { } } + +//project(CosNotification_Persist) : orbsvcslib, core, notification, event_skel, portableserver, acexml { +project(CosNotification_Persist) : notification_serv, acexml { + sharedname = TAO_CosNotification_Persist + dynamicflags = TAO_NOTIFY_PERSIST_BUILD_DLL + + IDL_Files { + } + Source_Files { + Notify/XML_Loader.cpp + Notify/XML_Saver.cpp + Notify/XML_Topology_Factory.cpp + } + + Template_Files { + } +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Admin.cpp b/TAO/orbsvcs/orbsvcs/Notify/Admin.cpp index c01902fea7e..c262a7bb1c7 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Admin.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Admin.cpp @@ -14,11 +14,20 @@ ACE_RCSID (Notify, #include "Container_T.h" #include "Proxy.h" #include "EventChannel.h" - -TAO_Notify_Admin::TAO_Notify_Admin (void) +#include "Topology_Saver.h" +#include "Save_Persist_Worker_T.h" +#include "Reconnect_Worker_T.h" +#include "tao/debug.h" +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + +TAO_Notify_Admin::TAO_Notify_Admin () : ec_ (0) , proxy_container_ (0) , filter_operator_ (CosNotifyChannelAdmin::OR_OP) + , is_default_ (false) { // Initialize all Admin objects to initially be subscribed for all events. // This is a reasonable default and is required to allow Cos Event consumers/suppliers to send/receive events, @@ -37,7 +46,7 @@ TAO_Notify_Admin::init (TAO_Notify_EventChannel *ec ACE_ENV_ARG_DECL) this->ec_->_incr_refcnt (); - this->TAO_Notify_Object::init (ec); + this->TAO_Notify::Topology_Object::init (ec); ACE_NEW_THROW_EX (this->proxy_container_, TAO_Notify_Proxy_Container (), @@ -91,6 +100,105 @@ TAO_Notify_Admin::insert (TAO_Notify_Proxy* proxy ACE_ENV_ARG_DECL) this->proxy_container_->insert (proxy ACE_ENV_ARG_PARAMETER); } +void +TAO_Notify_Admin::save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL) +{ + bool changed = this->children_changed_; + this->children_changed_ = false; + this->self_changed_ = false; + + if (is_persistent ()) + { + TAO_Notify::NVPList attrs; + this->save_attrs(attrs); + + const char* type = this->get_admin_type_name(); + + bool want_all_children = + saver.begin_object(this->id(), type, attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (want_all_children || this->filter_admin_.is_changed ()) + { + this->filter_admin_.save_persistent(saver ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + if (want_all_children || this->subscribed_types_.is_changed ()) + { + this->subscribed_types_.save_persistent(saver ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + TAO_Notify::Save_Persist_Worker<TAO_Notify_Proxy> wrk(saver, want_all_children); + this->proxy_container_->collection()->for_each(&wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + saver.end_object(this->id(), type ACE_ENV_ARG_PARAMETER); + } +} + +void +TAO_Notify_Admin::save_attrs (TAO_Notify::NVPList& attrs) +{ + TAO_Notify_Object::save_attrs(attrs); + attrs.push_back(TAO_Notify::NVP("InterFilterGroupOperator", this->filter_operator_)); + if (this->is_default_) + { + attrs.push_back (TAO_Notify::NVP ("default", "yes")); + } +} + +void +TAO_Notify_Admin::load_attrs(const TAO_Notify::NVPList& attrs) +{ + TAO_Notify_Object::load_attrs (attrs); + const char * value = 0; + if (attrs.find ("InterFilterGroupOperator", value)) + { + this->filter_operator_ = static_cast <CosNotifyChannelAdmin::InterFilterGroupOperator> (ACE_OS::atoi (value)); + } + if (attrs.find ("default", value)) + { + this->is_default_ = (ACE_OS::strcmp (value, "yes") == 0); + } +} + +TAO_Notify::Topology_Object* +TAO_Notify_Admin::load_child (const ACE_CString &type, + CORBA::Long id, const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL) +{ + ACE_UNUSED_ARG (attrs); + TAO_Notify::Topology_Object* result = this; + if (type == "subscriptions") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Admin reload subscription %d\n") + , ACE_static_cast (int, id) + )); + // since we initialized our subscribed types to everything + // in the constructor. we have to clear it out first. + this->subscribed_types_.reset(); + result = &this->subscribed_types_; + } + else if (type == "filter_admin") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Admin reload filter_admin %d\n") + , ACE_static_cast (int, id) + )); + result = & this->filter_admin_; + } + return result; +} + +void +TAO_Notify_Admin::reconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_Notify::Reconnect_Worker<TAO_Notify_Proxy> wrk; + this->proxy_container_->collection()->for_each(&wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class TAO_ESF_Shutdown_Proxy<TAO_Notify_Proxy>; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Admin.h b/TAO/orbsvcs/orbsvcs/Notify/Admin.h index c2c384df821..ea1029d8cc1 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Admin.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Admin.h @@ -22,7 +22,7 @@ #include "FilterAdmin.h" #include "EventTypeSeq.h" -#include "Object.h" +#include "Topology_Object.h" class TAO_Notify_Proxy; class TAO_Notify_EventChannel; @@ -35,7 +35,7 @@ template <class TYPE> class TAO_Notify_Container_T; * */ -class TAO_Notify_Serv_Export TAO_Notify_Admin : public virtual TAO_Notify_Object +class TAO_Notify_Serv_Export TAO_Notify_Admin : public TAO_Notify::Topology_Parent { friend class TAO_Notify_Builder; public: @@ -43,7 +43,7 @@ public: typedef CosNotifyChannelAdmin::AdminIDSeq_var SEQ_VAR; /// Constuctor - TAO_Notify_Admin (void); + TAO_Notify_Admin (); /// Destructor ~TAO_Notify_Admin (); @@ -69,14 +69,28 @@ public: CosNotifyChannelAdmin::InterFilterGroupOperator filter_operator (void); /// Obtain the Admin's subscribed types. - void subscribed_types (TAO_Notify_EventTypeSeq& subscribed_types + void subscribed_types (TAO_Notify_EventTypeSeq& subscribed_types ACE_ENV_ARG_DECL); + TAO_Notify_EventChannel * event_channel () const; /// Shutdown virtual int shutdown (ACE_ENV_SINGLE_ARG_DECL); + virtual void save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL); + virtual TAO_Notify::Topology_Object* load_child (const ACE_CString &type, + CORBA::Long id, const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL); + virtual void reconnect (ACE_ENV_SINGLE_ARG_DECL); + + void set_default (bool is_default); + bool is_default () const; + virtual void load_attrs(const TAO_Notify::NVPList& attrs); + protected: - typedef TAO_Notify_Container_T <TAO_Notify_Proxy> + void save_attrs (TAO_Notify::NVPList& attrs); + virtual const char * get_admin_type_name (void) const = 0; + +protected: + typedef TAO_Notify_Container_T <TAO_Notify_Proxy> TAO_Notify_Proxy_Container; /// = Data Members @@ -95,6 +109,8 @@ protected: /// Filter operator CosNotifyChannelAdmin::InterFilterGroupOperator filter_operator_; + + bool is_default_; }; #if defined (__ACE_INLINE__) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Admin.inl b/TAO/orbsvcs/orbsvcs/Notify/Admin.inl index 8b6d8641eeb..f675842ad8c 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Admin.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Admin.inl @@ -1,5 +1,13 @@ // $Id$ +ACE_INLINE +TAO_Notify_EventChannel * +TAO_Notify_Admin::event_channel () const +{ + return this->ec_; +} + + ACE_INLINE TAO_Notify_FilterAdmin& TAO_Notify_Admin::filter_admin (void) { @@ -17,3 +25,17 @@ TAO_Notify_Admin::filter_operator (void) { return this->filter_operator_; } + +ACE_INLINE +void +TAO_Notify_Admin::set_default (bool is_default) +{ + this->is_default_ = is_default; +} + +ACE_INLINE +bool +TAO_Notify_Admin::is_default (void) const +{ + return this->is_default_; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.cpp b/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.cpp index 1d373b8eac8..1c90b0e5248 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.cpp @@ -6,8 +6,8 @@ #include "AdminProperties.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID (Notify, - TAO_Notify_AdminProperties, +ACE_RCSID (Notify, + TAO_Notify_AdminProperties, "$Id$") #include "orbsvcs/CosNotificationC.h" @@ -43,6 +43,38 @@ TAO_Notify_AdminProperties::init (const CosNotification::PropertySeq& prop_seq) return 0; } +void +TAO_Notify_AdminProperties::init () +{ + // This method should only be called once, (during topo load) + ACE_ASSERT(this->size() == 0); + + if (this->max_global_queue_length_.is_valid()) + { + CORBA::Any a; + a <<= this->max_global_queue_length_.value(); + this->add(this->max_global_queue_length_.name(), a); + } + if (this->max_consumers_.is_valid()) + { + CORBA::Any a; + a <<= this->max_consumers_.value(); + this->add(this->max_consumers_.name(), a); + } + if (this->max_suppliers_.is_valid()) + { + CORBA::Any a; + a <<= this->max_suppliers_.value(); + this->add(this->max_suppliers_.name(), a); + } + if (this->reject_new_events_.is_valid()) + { + CORBA::Any a; + a <<= CORBA::Any::from_boolean(this->reject_new_events_.value()); + this->add(this->reject_new_events_.name(), a); + } +} + CORBA::Boolean TAO_Notify_AdminProperties::queue_full (void) { diff --git a/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.h b/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.h index e7f51ebc5a0..5594add39b6 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.h +++ b/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.h @@ -37,7 +37,7 @@ * @brief The AdminProperties per EventChannel. * */ -class TAO_Notify_Serv_Export TAO_Notify_AdminProperties +class TAO_Notify_Serv_Export TAO_Notify_AdminProperties : public TAO_Notify_PropertySeq { public: @@ -50,12 +50,21 @@ public: // Init int init (const CosNotification::PropertySeq& prop_seq); - // = Accessors + // finish initialization after values are set by topology load + void init (); + + // = Const Accessors const TAO_Notify_Property_Long& max_global_queue_length (void) const; const TAO_Notify_Property_Long& max_consumers (void) const; const TAO_Notify_Property_Long& max_suppliers (void) const; const TAO_Notify_Property_Boolean& reject_new_events (void) const; + // = Non-const accessors + TAO_Notify_Property_Long & max_global_queue_length (void); + TAO_Notify_Property_Long & max_consumers (void); + TAO_Notify_Property_Long & max_suppliers (void); + TAO_Notify_Property_Boolean & reject_new_events (void); + CORBA::Long& global_queue_length (void); TAO_SYNCH_MUTEX& global_queue_lock (void); TAO_SYNCH_CONDITION& global_queue_not_full_condition (void); @@ -109,8 +118,8 @@ protected: TAO_Notify_Atomic_Property_Long suppliers_; }; -typedef ACE_Refcounted_Auto_Ptr<TAO_Notify_AdminProperties, - TAO_SYNCH_MUTEX> +typedef ACE_Refcounted_Auto_Ptr<TAO_Notify_AdminProperties, + TAO_SYNCH_MUTEX> TAO_Notify_AdminProperties_var; #if defined (__ACE_INLINE__) diff --git a/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.inl b/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.inl index 0eea011af97..36743cc9dc1 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/AdminProperties.inl @@ -6,24 +6,48 @@ TAO_Notify_AdminProperties::max_global_queue_length (void) const return this->max_global_queue_length_; } +ACE_INLINE TAO_Notify_Property_Long& +TAO_Notify_AdminProperties::max_global_queue_length (void) +{ + return this->max_global_queue_length_; +} + ACE_INLINE const TAO_Notify_Property_Long& TAO_Notify_AdminProperties::max_consumers (void) const { return this->max_consumers_; } +ACE_INLINE TAO_Notify_Property_Long& +TAO_Notify_AdminProperties::max_consumers (void) +{ + return this->max_consumers_; +} + ACE_INLINE const TAO_Notify_Property_Long& TAO_Notify_AdminProperties::max_suppliers (void) const { return this->max_suppliers_; } +ACE_INLINE TAO_Notify_Property_Long& +TAO_Notify_AdminProperties::max_suppliers (void) +{ + return this->max_suppliers_; +} + ACE_INLINE const TAO_Notify_Property_Boolean& TAO_Notify_AdminProperties::reject_new_events (void) const { return this->reject_new_events_; } +ACE_INLINE TAO_Notify_Property_Boolean& +TAO_Notify_AdminProperties::reject_new_events (void) +{ + return this->reject_new_events_; +} + ACE_INLINE CORBA::Long& TAO_Notify_AdminProperties::global_queue_length (void) { diff --git a/TAO/orbsvcs/orbsvcs/Notify/AllocTracker.h b/TAO/orbsvcs/orbsvcs/Notify/AllocTracker.h new file mode 100644 index 00000000000..5568ce5e720 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/AllocTracker.h @@ -0,0 +1,81 @@ +// $Id$ +#ifndef ALLOC_TRACKER_H +#define ALLOC_TRACKER_H +#include /**/"ace/pre.h" + +#include "notify_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +//#define DEBUG_MEMORY_USE +#if defined(_MSC_VER) && defined (_DEBUG) && defined (DEBUG_MEMORY_USE) +namespace CRT{ + +/// \brief dump heap allocation stats +/// +/// This works only on microsoft/windows compilers +/// but it's handy to diagnose memory allocation problems. +/// To use, add the following macro in the scope where you +/// want to check memory usage. +/// ACE_WIN32_HEAP_MONITOR(name); +/// where name is a quoted string to label the stats. +/// When the object created by this macro goes out of scope +/// it will write a log message like: +/// (10056|6396) name: New heap blocks: 39; bytes: 19550 +/// +/// For non-debug, or non-vc builds, the macro expands to nothing +class CrtHeapDumper +{ +public: + CrtHeapDumper(const char * name, bool verbose = false) + : name_ (name) + , verbose_ (verbose) + { + _CrtMemCheckpoint (&before_); + } + + ~CrtHeapDumper() + { + dump(); + } + void dump() + { + _CrtMemState after; + _CrtMemCheckpoint (&after); + _CrtMemState diff; + _CrtMemDifference (&diff, &before_, &after); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) %s: New heap blocks: %d; bytes: %d\n"), + name_.c_str (), + ACE_static_cast (int, diff.lCounts[_NORMAL_BLOCK]), + ACE_static_cast (int, diff.lSizes[_NORMAL_BLOCK]) + )); + if (this->verbose_) + { + _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); + _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT ); + _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE ); + _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT ); + _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE ); + _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT ); + _CrtMemDumpAllObjectsSince (&this->before_); + } + } + +private: + ACE_CString name_; + bool verbose_; + _CrtMemState before_; +}; +} //namespace +#define ACE_WIN32_HEAP_MONITOR(name) \ + CrtHeapDumper heap_check___(name); \ + ACE_UNUSED_ARG (heap_check___) +#else // _MSC_VER etc + #define ACE_WIN32_HEAP_MONITOR(name) +#endif // _MSC_VER etc +#include /**/"ace/post.h" +#endif // ALLOC_TRACKER_H diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.cpp index c8c2464998c..a6c7015080a 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.cpp @@ -11,6 +11,11 @@ ACE_RCSID (Notify, TAO_Notify_AnyEvent, "$Id$") #include "../Consumer.h" #include "tao/debug.h" +//#define DEBUG_LEVEL 10 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + TAO_Notify_EventType TAO_Notify_AnyEvent_No_Copy::event_type_; TAO_Notify_AnyEvent_No_Copy::TAO_Notify_AnyEvent_No_Copy (const CORBA::Any &event) @@ -22,18 +27,6 @@ TAO_Notify_AnyEvent_No_Copy::~TAO_Notify_AnyEvent_No_Copy () { } -TAO_Notify_Event* -TAO_Notify_AnyEvent_No_Copy::copy (ACE_ENV_SINGLE_ARG_DECL) const -{ - TAO_Notify_Event* copy; - - ACE_NEW_THROW_EX (copy, - TAO_Notify_AnyEvent (*this->event_), - CORBA::NO_MEMORY ()); - - return copy; -} - const TAO_Notify_EventType& TAO_Notify_AnyEvent_No_Copy::type (void) const { @@ -49,7 +42,7 @@ TAO_Notify_AnyEvent_No_Copy::convert (CosNotification::StructuredEvent& notifica CORBA::Boolean TAO_Notify_AnyEvent_No_Copy::do_match (CosNotifyFilter::Filter_ptr filter ACE_ENV_ARG_DECL) const { - if (TAO_debug_level > 0) + if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, "Notify (%P|%t) - " "TAO_Notify_AnyEvent::do_match ()\n")); @@ -59,7 +52,7 @@ TAO_Notify_AnyEvent_No_Copy::do_match (CosNotifyFilter::Filter_ptr filter ACE_EN void TAO_Notify_AnyEvent_No_Copy::push (TAO_Notify_Consumer* consumer ACE_ENV_ARG_DECL) const { - if (TAO_debug_level > 0) + if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, "Notify (%P|%t) - " "TAO_Notify_AnyEvent::push \n")); @@ -98,6 +91,39 @@ TAO_Notify_AnyEvent_No_Copy::push_no_filtering (Event_Forwarder::ProxyPushSuppli forwarder->forward_any_no_filtering (*this->event_ ACE_ENV_ARG_PARAMETER); } +void +TAO_Notify_AnyEvent_No_Copy::marshal (TAO_OutputCDR & cdr) const +{ + static const ACE_CDR::Octet ANY_CODE = MARSHAL_ANY; + cdr.write_octet (ANY_CODE); + cdr << (*this->event_); +} + +//static +TAO_Notify_AnyEvent * +TAO_Notify_AnyEvent_No_Copy::unmarshal (TAO_InputCDR & cdr) +{ + TAO_Notify_AnyEvent * event = 0; + CORBA::Any body; + if (cdr >> body) + { + event = new TAO_Notify_AnyEvent (body); + } + return event; +} + +TAO_Notify_Event * +TAO_Notify_AnyEvent_No_Copy::copy (ACE_ENV_SINGLE_ARG_DECL) const +{ + TAO_Notify_Event * new_event; + ACE_NEW_THROW_EX (new_event, + TAO_Notify_AnyEvent (*this->event_), + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (0); + return new_event; +} + + /*****************************************************************************************************/ TAO_Notify_AnyEvent::TAO_Notify_AnyEvent (const CORBA::Any &event) @@ -110,3 +136,10 @@ TAO_Notify_AnyEvent::TAO_Notify_AnyEvent (const CORBA::Any &event) TAO_Notify_AnyEvent::~TAO_Notify_AnyEvent () { } + +const TAO_Notify_Event * +TAO_Notify_AnyEvent::queueable_copy (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this; +} + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.h b/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.h index d97e7bc2b7e..9ea70ded141 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.h @@ -14,7 +14,7 @@ #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -26,7 +26,7 @@ #include "orbsvcs/CosNotificationC.h" class TAO_Notify_Consumer; - +class TAO_Notify_AnyEvent; /** * @class TAO_Notify_AnyEvent * @@ -43,9 +43,6 @@ public: /// Destructor ~TAO_Notify_AnyEvent_No_Copy (); - /// Copy the event. - virtual TAO_Notify_Event* copy (ACE_ENV_SINGLE_ARG_DECL) const; - /// Get the event type. virtual const TAO_Notify_EventType& type (void) const; @@ -69,7 +66,21 @@ public: /// Push event to the Event_Forwarder interface virtual void push_no_filtering (Event_Forwarder::ProxyPushSupplier_ptr forwarder ACE_ENV_ARG_DECL) const; + /// marshal this event into a CDR buffer (for persistence) + virtual void marshal (TAO_OutputCDR & cdr) const; + + /// unmarshal this event from a CDR buffer (for persistence) + /// \param code a code indicating what type of event to create. + /// \param cdr a CDR stream containing the marshalled data for the event. + /// \return the new event, or NULL if this is the wrong type of event. + static TAO_Notify_AnyEvent * unmarshal (TAO_InputCDR & cdr); + protected: + /// returns a copy of this event allocated from the heap + virtual TAO_Notify_Event * copy (ACE_ENV_SINGLE_ARG_DECL) const; + +protected: + /// Any Event const CORBA::Any* event_; @@ -94,6 +105,9 @@ public: /// Destructor ~TAO_Notify_AnyEvent (); + /// return this + virtual const TAO_Notify_Event * queueable_copy (ACE_ENV_SINGLE_ARG_DECL)const; + protected: /// Copy of the Event. CORBA::Any any_copy_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.inl b/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.inl index 4920e03d422..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/AnyEvent.inl @@ -1,3 +1,2 @@ // $Id$ -#include "AnyEvent.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp index 0a613a94fed..f12b4a6d210 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp @@ -31,13 +31,6 @@ TAO_Notify_CosEC_ProxyPushConsumer::release (void) } void -TAO_Notify_CosEC_ProxyPushConsumer::push (TAO_Notify_Event_var &/*event*/) -{ - // This should never be called. - ACE_ASSERT (1); -} - -void TAO_Notify_CosEC_ProxyPushConsumer::push (const CORBA::Any& any ACE_ENV_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException @@ -80,10 +73,17 @@ TAO_Notify_CosEC_ProxyPushConsumer::connect_push_supplier (CosEventComm::PushSup this->connect (supplier ACE_ENV_ARG_PARAMETER); } -void TAO_Notify_CosEC_ProxyPushConsumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) +void +TAO_Notify_CosEC_ProxyPushConsumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); } + +const char * +TAO_Notify_CosEC_ProxyPushConsumer::get_proxy_type_name (void) const +{ + return "ec_proxy_push_consumer"; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h index 7cb9b02f115..8221afc10fe 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h @@ -14,7 +14,7 @@ #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -51,6 +51,8 @@ public: /// Release virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + protected: ///= CosNotifyChannelAdmin::ProxyPushConsumer methods @@ -72,7 +74,8 @@ protected: )); private: // Overloaded TAO_Notify_ProxyConsumer::push to get around Borland compiler warnings. - virtual void push (TAO_Notify_Event_var &event); + // I don't think this is necessary any more -- Dale. +// virtual void push (TAO_Notify_Event_var &event); }; #if defined(_MSC_VER) && (_MSC_VER >= 1200) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.inl b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.inl index e787ced2266..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.inl @@ -1,3 +1,2 @@ // $Id$ -#include "CosEC_ProxyPushConsumer.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.cpp index e1cafd280c9..76caa3c43b5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.cpp @@ -57,3 +57,9 @@ TAO_Notify_CosEC_ProxyPushSupplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); } + +const char * +TAO_Notify_CosEC_ProxyPushSupplier::get_proxy_type_name (void) const +{ + return "ec_proxy_push_supplier"; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h index 69acbdcdacc..143232fe6d8 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h @@ -14,7 +14,7 @@ #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -56,6 +56,8 @@ public: /// Release virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + // = Interface methods virtual void connect_push_consumer ( CosEventComm::PushConsumer_ptr push_consumer diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.inl b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.inl index c6551c656c4..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.inl @@ -1,3 +1,2 @@ // $Id$ -#include "CosEC_ProxyPushSupplier.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp index aecb8951e81..0b93c980ee3 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp @@ -10,8 +10,7 @@ ACE_RCSID (Notify, TAO_Notify_ProxyPushConsumer, "$Id$") #include "tao/debug.h" #include "../AdminProperties.h" -#include "../Method_Request_Lookup.h" -#include "../Worker_Task.h" +#include "../Properties.h" #include "AnyEvent.h" #include "PushSupplier.h" @@ -43,13 +42,6 @@ TAO_Notify_ProxyPushConsumer::MyType (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) } void -TAO_Notify_ProxyPushConsumer::push (TAO_Notify_Event_var &/*event*/) -{ - // This should never be called. - ACE_ASSERT (1); -} - -void TAO_Notify_ProxyPushConsumer::push (const CORBA::Any& any ACE_ENV_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException @@ -67,10 +59,7 @@ TAO_Notify_ProxyPushConsumer::push (const CORBA::Any& any ACE_ENV_ARG_DECL) } TAO_Notify_AnyEvent_No_Copy event (any); - - TAO_Notify_Method_Request_Lookup_No_Copy request (&event, this); - - this->worker_task ()->execute (request ACE_ENV_ARG_PARAMETER); + this->push_i (&event ACE_ENV_ARG_PARAMETER); } void @@ -90,6 +79,8 @@ TAO_Notify_ProxyPushConsumer::connect_any_push_supplier (CosEventComm::PushSuppl ACE_CHECK; this->connect (supplier ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void TAO_Notify_ProxyPushConsumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) @@ -98,4 +89,43 @@ void TAO_Notify_ProxyPushConsumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_ )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +const char * +TAO_Notify_ProxyPushConsumer::get_proxy_type_name (void) const +{ + return "proxy_push_consumer"; +} + +void +TAO_Notify_ProxyPushConsumer::load_attrs (const TAO_Notify::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::PushSupplier_var ps = + CosNotifyComm::PushSupplier::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + // minor hack: suppress generating subscription updates during reload. + bool save_updates = this->updates_off_; + this->updates_off_ = true; + this->connect_any_push_supplier(ps.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->updates_off_ = save_updates; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + } } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h index 6c732c772ad..ef66f3ec7b9 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h @@ -14,7 +14,7 @@ #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -41,6 +41,7 @@ class TAO_Notify_Serv_Export TAO_Notify_ProxyPushConsumer POA_CosNotifyChannelAdmin::ProxyPushConsumer > { + typedef TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::ProxyPushConsumer> SuperClass; friend class TAO_Notify_Builder; public: /// Constuctor @@ -52,6 +53,11 @@ public: /// Release virtual void release (void); +// virtual void save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL); + virtual const char * get_proxy_type_name (void) const; + + virtual void load_attrs (const TAO_Notify::NVPList& attrs); + protected: ///= CosNotifyChannelAdmin::ProxyPushConsumer methods @@ -79,7 +85,8 @@ protected: private: // Overloaded TAO_Notify_ProxyConsumer::push to get around Borland compiler warnings. - virtual void push (TAO_Notify_Event_var &event); + // I don't think this is necessary any more -- Dale. +// virtual void push (TAO_Notify_Event_var &event); }; #if defined(_MSC_VER) && (_MSC_VER >= 1200) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.inl b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.inl index 32c8ecf4355..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.inl @@ -1,3 +1,2 @@ // $Id$ -#include "ProxyPushConsumer.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp index c5e280e9b75..acb9df825dd 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp @@ -10,6 +10,7 @@ ACE_RCSID (Notify, TAO_Notify_ProxyPushSupplier, "$Id$") #include "tao/debug.h" #include "PushConsumer.h" +#include "../Properties.h" TAO_Notify_ProxyPushSupplier::TAO_Notify_ProxyPushSupplier (void) { @@ -48,6 +49,8 @@ TAO_Notify_ProxyPushSupplier::connect_any_push_consumer (CosEventComm::PushConsu ACE_CHECK; this->connect (consumer ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -57,6 +60,8 @@ TAO_Notify_ProxyPushSupplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } CosNotifyChannelAdmin::ProxyType @@ -67,3 +72,36 @@ TAO_Notify_ProxyPushSupplier::MyType (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) { return CosNotifyChannelAdmin::PUSH_ANY; } + +const char * +TAO_Notify_ProxyPushSupplier::get_proxy_type_name (void) const +{ + return "proxy_push_supplier"; +} + +void +TAO_Notify_ProxyPushSupplier::load_attrs (const TAO_Notify::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::PushConsumer_var pc = + CosNotifyComm::PushConsumer::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->connect_any_push_consumer(pc.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // if we can't reconnect, tough... + } + ACE_ENDTRY; + } +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h index c24668ef7e8..158292d9f86 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h @@ -14,7 +14,7 @@ #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -46,6 +46,7 @@ TAO_Notify_ProxySupplier_T<POA_Event_Forwarder::ProxyPushSupplier>; class TAO_Notify_Serv_Export TAO_Notify_ProxyPushSupplier : public virtual TAO_Notify_ProxySupplier_T <POA_Event_Forwarder::ProxyPushSupplier> { + typedef TAO_Notify_ProxySupplier_T <POA_Event_Forwarder::ProxyPushSupplier> SuperClass; friend class TAO_Notify_Builder; public: /// Constuctor @@ -57,6 +58,10 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + + virtual void load_attrs (const TAO_Notify::NVPList& attrs); + // = Interface methods virtual CosNotifyChannelAdmin::ProxyType MyType (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.inl b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.inl index dda279acbfc..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.inl @@ -1,3 +1,2 @@ // $Id$ -#include "ProxyPushSupplier.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp index d26302a2cee..e6958fdb4aa 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp @@ -6,13 +6,14 @@ #include "PushConsumer.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID (Notify, - TAO_Notify_PushConsumer, +ACE_RCSID (Notify, + TAO_Notify_PushConsumer, "$Id$") #include "ace/Refcounted_Auto_Ptr.h" #include "orbsvcs/CosEventCommC.h" #include "../Event.h" +#include "../Properties.h" TAO_Notify_PushConsumer::TAO_Notify_PushConsumer (TAO_Notify_ProxySupplier* proxy) :TAO_Notify_Consumer (proxy) @@ -48,18 +49,6 @@ TAO_Notify_PushConsumer::release (void) } void -TAO_Notify_PushConsumer::push_i (const TAO_Notify_Event* event ACE_ENV_ARG_DECL) -{ - event->push (this ACE_ENV_ARG_PARAMETER); -} - -void -TAO_Notify_PushConsumer::push_i (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL) -{ - event->push (this ACE_ENV_ARG_PARAMETER); -} - -void TAO_Notify_PushConsumer::push (const CORBA::Any& payload ACE_ENV_ARG_DECL) { this->push_consumer_->push (payload ACE_ENV_ARG_PARAMETER); @@ -74,3 +63,46 @@ TAO_Notify_PushConsumer::push (const CosNotification::StructuredEvent& event ACE this->push_consumer_->push (any ACE_ENV_ARG_PARAMETER); } + +/// Push a batch of events to this consumer. +void +TAO_Notify_PushConsumer::push (const CosNotification::EventBatch& event ACE_ENV_ARG_DECL_NOT_USED) +{ + ACE_ASSERT(false); + ACE_UNUSED_ARG (event); + // TODO exception? +} + + + +bool +TAO_Notify_PushConsumer::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_consumer_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} + +void +TAO_Notify_PushConsumer::reconnect_from_consumer (TAO_Notify_Consumer* old_consumer + ACE_ENV_ARG_DECL) +{ + TAO_Notify_PushConsumer* tmp = ACE_dynamic_cast(TAO_Notify_PushConsumer*, old_consumer); + ACE_ASSERT(tmp != 0); + this->init(tmp->push_consumer_.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->schedule_timer(false); +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.h index f5ca3aa8af9..69bc1d9bc35 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.h @@ -13,7 +13,7 @@ #define TAO_Notify_PUSHCONSUMER_H #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -44,10 +44,7 @@ public: virtual void release (void); /// Push <event> to this consumer. - virtual void push_i (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); - - /// Push <event> to this consumer. - virtual void push_i (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL); +// virtual void push_i (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); /// Push <event> to this consumer. virtual void push (const CORBA::Any& event ACE_ENV_ARG_DECL); @@ -55,6 +52,18 @@ public: /// Push <event> to this consumer. virtual void push (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL); + /// Push a batch of events to this consumer. + virtual void push (const CosNotification::EventBatch& event ACE_ENV_ARG_DECL); + + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + + /// on reconnect we need to move events from the old consumer + /// to the new one + virtual void reconnect_from_consumer ( + TAO_Notify_Consumer* old_consumer + ACE_ENV_ARG_DECL); + protected: /// The Consumer CosEventComm::PushConsumer_var push_consumer_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.inl b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.inl index e557d6a7eda..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.inl @@ -1,3 +1,2 @@ // $Id$ -#include "PushConsumer.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.cpp index c6d2ae4c48a..948ed38f936 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.cpp @@ -7,6 +7,7 @@ #endif /* __ACE_INLINE__ */ ACE_RCSID (Notify, TAO_Notify_PushSupplier, "$Id$") +#include "../Properties.h" TAO_Notify_PushSupplier::TAO_Notify_PushSupplier (TAO_Notify_ProxyConsumer* proxy) :TAO_Notify_Supplier (proxy) @@ -40,3 +41,23 @@ TAO_Notify_PushSupplier::release (void) delete this; //@@ inform factory } +bool +TAO_Notify_PushSupplier::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_supplier_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.h index 9f9ab07131e..1a108bad3ba 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.h @@ -13,7 +13,7 @@ #define TAO_Notify_PUSHSUPPLIER_H #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -46,6 +46,9 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + protected: /// The Supplier CosEventComm::PushSupplier_var push_supplier_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.inl b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.inl index 9f9bf75ff2f..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.inl @@ -1,3 +1,2 @@ // $Id$ -#include "PushSupplier.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Bit_Vector.cpp b/TAO/orbsvcs/orbsvcs/Notify/Bit_Vector.cpp new file mode 100644 index 00000000000..65fc33cde83 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Bit_Vector.cpp @@ -0,0 +1,118 @@ +// $Id$ + +#include "Bit_Vector.h" + +namespace TAO_Notify +{ + +Bit_Vector::Bit_Vector() + : size_(0) + , first_set_bit_(0) + , first_cleared_bit_(0) +{ +} + +Bit_Vector::~Bit_Vector() +{ +} + +bool +Bit_Vector::is_set(const size_t location) const +{ + bool result = false; + if (location < this->size_) + { + result = (0 != (this->bitvec_[location >> BPW_LOG_2] & (1 << (location % BITS_PER_WORD)))); + } + return result; +} + +void +Bit_Vector::set_bit(const size_t location, bool set) +{ + if (location >= this->size_) + { + if ((location >> BPW_LOG_2) >= (this->size_ >> BPW_LOG_2)) + { + size_t need = (location >> BPW_LOG_2) - (this->size_ >> BPW_LOG_2); + this->bitvec_.resize(this->bitvec_.size() + need + 1, 0); + } + this->size_ = location + 1; + } + if (set) + { + this->bitvec_[location >> BPW_LOG_2] |= (1 << (location % BITS_PER_WORD)); + } + else + { + this->bitvec_[location >> BPW_LOG_2] &= ~(1 << (location % BITS_PER_WORD)); + } + this->evaluate_firsts(location, set); +} + +size_t +Bit_Vector::find_first_bit(bool set) const +{ + size_t result = 0; + if (set) + { + result = this->first_set_bit_; + } + else + { + result = this->first_cleared_bit_; + } + return result; +} + +void +Bit_Vector::evaluate_firsts(const size_t location, bool set) +{ + if (set) + { + if (this->first_cleared_bit_ == location) + { + this->first_cleared_bit_ = this->find_first_bit_of(location, false); + } + if (this->first_set_bit_ > location) + { + this->first_set_bit_ = location; + } + } + else if (!set) + { + if (this->first_set_bit_ == location) + { + this->first_set_bit_ = this->find_first_bit_of(location, true); + } + if (this->first_cleared_bit_ > location) + { + this->first_cleared_bit_ = location; + } + } +} + +size_t +Bit_Vector::find_first_bit_of(const size_t location, bool set) +{ + size_t newloc = 0; + size_t idx = 0; + for (idx = location; (newloc == 0) && (idx < this->size_ + 1); idx++) + { + if (is_set(idx) == set) + { + newloc = idx; + } + } + return newloc; +} + +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Vector<ACE_UINT32>; +template class ACE_Array_Base<ACE_UINT32>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Vector<ACE_UINT32> +#pragma instantiate ACE_Array_Base<ACE_UINT32> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Bit_Vector.h b/TAO/orbsvcs/orbsvcs/Notify/Bit_Vector.h new file mode 100644 index 00000000000..b9f090dac6d --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Bit_Vector.h @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Bit_Vector.h + * + * $Id$ + * + * This is a basic bit vector class. + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef BIT_VECTOR_H +#define BIT_VECTOR_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "notify_serv_export.h" + +#include "ace/Vector_T.h" +#include "ace/Basic_Types.h" + +namespace TAO_Notify +{ + +/// \brief Simple bit vector. +/// +/// Written to support block allocation from persistent storage. +/// Should be promoted to the ACE level to make it generally usable. +class TAO_Notify_Serv_Export Bit_Vector +{ + typedef ACE_UINT32 BASIC_UINT_TYPE; + typedef ACE_Vector<BASIC_UINT_TYPE> VECTOR_TYPE; + enum { + BITS_PER_WORD = 32, + BPW_LOG_2 = 5 + }; +public: + + /// The constructor. + Bit_Vector(); + /// The destructor. + ~Bit_Vector(); + + /// \brief Determine if a bit at location is set. + bool is_set(const size_t location) const; + /// \brief Set or unset a bit at location, growing the vector as needed. + void set_bit(const size_t location, bool set); + + /// \brief Find the first bit that is either set or unset in an O(1). + size_t find_first_bit(bool set) const; + +private: + /// Update our first set and unset bits. + void evaluate_firsts(const size_t location, bool set); + /// Iterate from location to the end, finding the first bit that + /// matches the requested set or unset value. + size_t find_first_bit_of(const size_t location, bool set); + +private: + VECTOR_TYPE bitvec_; + size_t size_; + size_t first_set_bit_; + size_t first_cleared_bit_; +}; + +} + +#include /**/ "ace/post.h" +#endif /* BIT_VECTOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Buffering_Strategy.cpp b/TAO/orbsvcs/orbsvcs/Notify/Buffering_Strategy.cpp index 55acfa6f5dc..a2de6771ef9 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Buffering_Strategy.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Buffering_Strategy.cpp @@ -87,7 +87,7 @@ TAO_Notify_Buffering_Strategy::shutdown (void) } int -TAO_Notify_Buffering_Strategy::enqueue (TAO_Notify_Method_Request& method_request) +TAO_Notify_Buffering_Strategy::enqueue (TAO_Notify_Method_Request_Queueable& method_request) { ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->global_queue_lock_, -1); @@ -174,7 +174,7 @@ TAO_Notify_Buffering_Strategy::enqueue (TAO_Notify_Method_Request& method_reques } int -TAO_Notify_Buffering_Strategy::dequeue (TAO_Notify_Method_Request* &method_request, const ACE_Time_Value *abstime) +TAO_Notify_Buffering_Strategy::dequeue (TAO_Notify_Method_Request_Queueable* &method_request, const ACE_Time_Value *abstime) { ACE_Message_Block *mb; @@ -194,7 +194,7 @@ TAO_Notify_Buffering_Strategy::dequeue (TAO_Notify_Method_Request* &method_reque if (this->msg_queue_.dequeue (mb) == -1) return -1; - method_request = ACE_dynamic_cast (TAO_Notify_Method_Request*, mb); + method_request = ACE_dynamic_cast (TAO_Notify_Method_Request_Queueable*, mb); if (method_request == 0) return -1; @@ -210,7 +210,7 @@ TAO_Notify_Buffering_Strategy::dequeue (TAO_Notify_Method_Request* &method_reque } int -TAO_Notify_Buffering_Strategy::queue (TAO_Notify_Method_Request& method_request) +TAO_Notify_Buffering_Strategy::queue (TAO_Notify_Method_Request_Queueable& method_request) { int result; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Buffering_Strategy.h b/TAO/orbsvcs/orbsvcs/Notify/Buffering_Strategy.h index fb2bdc4627c..36f48e27cc9 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Buffering_Strategy.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Buffering_Strategy.h @@ -23,13 +23,13 @@ #include "ace/Null_Condition.h" #include "ace/Message_Queue.h" -#include "orbsvcs/TimeBaseC.h" +#include "orbsvcs/orbsvcs/TimeBaseC.h" #include "Property.h" #include "Property_T.h" #include "AdminProperties.h" -class TAO_Notify_Method_Request; +class TAO_Notify_Method_Request_Queueable; class TAO_Notify_QoSProperties; typedef ACE_Message_Queue<ACE_NULL_SYNCH> TAO_Notify_Message_Queue; @@ -62,11 +62,11 @@ public: /// Enqueue according the enqueing strategy. /// Return -1 on error else the number of items in the queue. - int enqueue (TAO_Notify_Method_Request& method_request); + int enqueue (TAO_Notify_Method_Request_Queueable& method_request); /// Dequeue batch. This method will block for @a abstime if non-zero or else blocks till an item is available. /// Return -1 on error or if nothing is available, else the number of items actually dequeued (1). - int dequeue (TAO_Notify_Method_Request* &method_request, + int dequeue (TAO_Notify_Method_Request_Queueable* &method_request, const ACE_Time_Value *abstime); /// Shutdown @@ -83,7 +83,7 @@ public: protected: /// Apply the Order Policy and queue. return -1 on error. - int queue (TAO_Notify_Method_Request& method_request); + int queue (TAO_Notify_Method_Request_Queueable& method_request); /// Discard as per the Discard Policy. int discard (void); diff --git a/TAO/orbsvcs/orbsvcs/Notify/Builder.cpp b/TAO/orbsvcs/orbsvcs/Notify/Builder.cpp index be7c6fafeba..5aa8b9c2390 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Builder.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Builder.cpp @@ -5,8 +5,8 @@ #include "Builder.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID (Notify, - Builder, +ACE_RCSID (Notify, + Builder, "$Id$") #include "ace/Dynamic_Service.h" @@ -41,10 +41,10 @@ ACE_RCSID (Notify, #include "ETCL_FilterFactory.h" #include "Container_T.h" -template <class PROXY_IMPL, - class PROXY, - class PROXY_PTR, - class PROXY_VAR, +template <class PROXY_IMPL, + class PROXY, + class PROXY_PTR, + class PROXY_VAR, class PARENT> class TAO_Notify_Proxy_Builder_T { @@ -83,6 +83,32 @@ public: return proxy_ret._retn (); } + + PROXY_IMPL* + build (PARENT *parent, const CosNotifyChannelAdmin::ProxyID proxy_id + ACE_ENV_ARG_DECL) + { + TAO_Notify_Factory* factory = TAO_Notify_PROPERTIES::instance ()->factory (); + + PROXY_IMPL* proxy = 0; + factory->create (proxy ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + PortableServer::ServantBase_var servant (proxy); + + proxy->init (parent ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + proxy->activate (proxy, proxy_id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + // insert proxy in admin container. + parent->insert (proxy ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return proxy; + } + }; // define the ProxyConsumer Builders. @@ -183,21 +209,22 @@ TAO_Notify_Builder::build_event_channel_factory (PortableServer::POA_ptr poa ACE factory->create (ecf ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (ecf_ret._retn ()); - PortableServer::ServantBase_var servant_var (ecf); +// PortableServer::ServantBase_var servant_var (ecf); - ecf->TAO_Notify_EventChannelFactory::init (poa ACE_ENV_ARG_PARAMETER); - - CORBA::Object_var obj = ecf->activate (ecf ACE_ENV_ARG_PARAMETER); + ecf->init (poa ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (ecf_ret._retn ()); - - ecf_ret = CosNotifyChannelAdmin::EventChannelFactory::_narrow (obj.in() ACE_ENV_ARG_PARAMETER); + ecf_ret = ecf->activate_self (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (ecf_ret._retn ()); return (ecf_ret._retn ()); } CosNotifyChannelAdmin::EventChannel_ptr -TAO_Notify_Builder::build_event_channel (TAO_Notify_EventChannelFactory* ecf, const CosNotification::QoSProperties & initial_qos, const CosNotification::AdminProperties & initial_admin, CosNotifyChannelAdmin::ChannelID_out id ACE_ENV_ARG_DECL) +TAO_Notify_Builder::build_event_channel ( + TAO_Notify_EventChannelFactory* ecf, + const CosNotification::QoSProperties & initial_qos, + const CosNotification::AdminProperties & initial_admin, + CosNotifyChannelAdmin::ChannelID_out id ACE_ENV_ARG_DECL) { CosNotifyChannelAdmin::EventChannel_var ec_ret; @@ -207,7 +234,7 @@ TAO_Notify_Builder::build_event_channel (TAO_Notify_EventChannelFactory* ecf, co factory->create (ec ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (ec_ret._retn ()); - PortableServer::ServantBase_var servant_var (ec); +// PortableServer::ServantBase_var servant_var (ec); ec->init (ecf, initial_qos, initial_admin ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (ec_ret._retn ()); @@ -228,8 +255,35 @@ TAO_Notify_Builder::build_event_channel (TAO_Notify_EventChannelFactory* ecf, co return ec_ret._retn (); } +TAO_Notify_EventChannel * +TAO_Notify_Builder::build_event_channel ( + TAO_Notify_EventChannelFactory* ecf, + const CosNotifyChannelAdmin::ChannelID id ACE_ENV_ARG_DECL) +{ + TAO_Notify_Factory* factory = TAO_Notify_PROPERTIES::instance ()->factory (); + + TAO_Notify_EventChannel* ec = 0; + factory->create (ec ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + ec->init (ecf ACE_ENV_ARG_PARAMETER); //, initial_qos, initial_admin + ACE_CHECK_RETURN (0); + + // insert ec in ec container. + ecf->ec_container_->insert (ec ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + ec->activate (ec, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return ec; +} + CosNotifyChannelAdmin::ConsumerAdmin_ptr -TAO_Notify_Builder::build_consumer_admin (TAO_Notify_EventChannel* ec, CosNotifyChannelAdmin::InterFilterGroupOperator op, CosNotifyChannelAdmin::AdminID_out id ACE_ENV_ARG_DECL) +TAO_Notify_Builder::build_consumer_admin ( + TAO_Notify_EventChannel* ec, + CosNotifyChannelAdmin::InterFilterGroupOperator op, + CosNotifyChannelAdmin::AdminID_out id ACE_ENV_ARG_DECL) { CosNotifyChannelAdmin::ConsumerAdmin_var ca_ret; @@ -239,7 +293,7 @@ TAO_Notify_Builder::build_consumer_admin (TAO_Notify_EventChannel* ec, CosNotify factory->create (ca ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (ca_ret._retn ()); - PortableServer::ServantBase_var servant_var (ca); +// PortableServer::ServantBase_var servant_var (ca); ca->init (ec ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (ca_ret._retn ()); @@ -261,6 +315,31 @@ TAO_Notify_Builder::build_consumer_admin (TAO_Notify_EventChannel* ec, CosNotify return ca_ret._retn (); } +TAO_Notify_ConsumerAdmin * +TAO_Notify_Builder::build_consumer_admin ( + TAO_Notify_EventChannel* ec, + const CosNotifyChannelAdmin::ChannelID id + ACE_ENV_ARG_DECL) +{ + TAO_Notify_Factory* factory = TAO_Notify_PROPERTIES::instance ()->factory (); + TAO_Notify_ConsumerAdmin * ca = 0; + factory->create (ca ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + +// PortableServer::ServantBase_var servant_var (ca); + + ca->init (ec ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Object_var obj = ca->activate (ca, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + // insert admin in CA container. + ec->ca_container_->insert (ca ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + return ca; +} + CosNotifyChannelAdmin::SupplierAdmin_ptr TAO_Notify_Builder::build_supplier_admin (TAO_Notify_EventChannel* ec, CosNotifyChannelAdmin::InterFilterGroupOperator op, CosNotifyChannelAdmin::AdminID_out id ACE_ENV_ARG_DECL) { @@ -272,7 +351,7 @@ TAO_Notify_Builder::build_supplier_admin (TAO_Notify_EventChannel* ec, CosNotify factory->create (sa ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (sa_ret._retn ()); - PortableServer::ServantBase_var servant_var (sa); +// PortableServer::ServantBase_var servant_var (sa); sa->init (ec ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (sa_ret._retn ()); @@ -294,6 +373,32 @@ TAO_Notify_Builder::build_supplier_admin (TAO_Notify_EventChannel* ec, CosNotify return sa_ret._retn (); } +TAO_Notify_SupplierAdmin * +TAO_Notify_Builder::build_supplier_admin ( + TAO_Notify_EventChannel* ec, + const CosNotifyChannelAdmin::ChannelID id + ACE_ENV_ARG_DECL) +{ + TAO_Notify_Factory* factory = TAO_Notify_PROPERTIES::instance ()->factory (); + TAO_Notify_SupplierAdmin * sa = 0; + factory->create (sa ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + +// PortableServer::ServantBase_var servant_var (ca); + + sa->init (ec ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Object_var obj = sa->activate (sa, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + // insert admin in CA container. + ec->sa_container_->insert (sa ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return sa; +} + CosNotifyChannelAdmin::ProxyConsumer_ptr TAO_Notify_Builder::build_proxy(TAO_Notify_SupplierAdmin* sa , CosNotifyChannelAdmin::ClientType ctype @@ -366,6 +471,76 @@ TAO_Notify_Builder::build_proxy(TAO_Notify_ConsumerAdmin* ca } } +TAO_Notify_ProxyConsumer * +TAO_Notify_Builder::build_proxy(TAO_Notify_SupplierAdmin* sa + , CosNotifyChannelAdmin::ClientType ctype + , const CosNotifyChannelAdmin::ProxyID proxy_id + ACE_ENV_ARG_DECL) +{ + switch (ctype) + { + case CosNotifyChannelAdmin::ANY_EVENT: + { + TAO_Notify_ProxyPushConsumer_Builder pb; + return pb.build (sa, proxy_id ACE_ENV_ARG_PARAMETER); + } + break; + + case CosNotifyChannelAdmin::STRUCTURED_EVENT: + { + TAO_Notify_StructuredProxyPushConsumer_Builder pb; + return pb.build (sa, proxy_id ACE_ENV_ARG_PARAMETER); + } + break; + + case CosNotifyChannelAdmin::SEQUENCE_EVENT: + { + TAO_Notify_SequenceProxyPushConsumer_Builder pb; + return pb.build (sa, proxy_id ACE_ENV_ARG_PARAMETER); + } + break; + + default: + ACE_THROW_RETURN (CORBA::BAD_PARAM (), + 0); + } +} + +TAO_Notify_ProxySupplier * +TAO_Notify_Builder::build_proxy(TAO_Notify_ConsumerAdmin* ca + , CosNotifyChannelAdmin::ClientType ctype + , const CosNotifyChannelAdmin::ProxyID proxy_id + ACE_ENV_ARG_DECL) +{ + switch (ctype) + { + case CosNotifyChannelAdmin::ANY_EVENT: + { + TAO_Notify_ProxyPushSupplier_Builder pb; + return pb.build (ca, proxy_id ACE_ENV_ARG_PARAMETER); + } + break; + + case CosNotifyChannelAdmin::STRUCTURED_EVENT: + { + TAO_Notify_StructuredProxyPushSupplier_Builder pb; + return pb.build (ca, proxy_id ACE_ENV_ARG_PARAMETER); + } + break; + + case CosNotifyChannelAdmin::SEQUENCE_EVENT: + { + TAO_Notify_SequenceProxyPushSupplier_Builder pb; + return pb.build (ca, proxy_id ACE_ENV_ARG_PARAMETER); + } + break; + + default: + ACE_THROW_RETURN (CORBA::BAD_PARAM (), + 0); + } +} + CosEventChannelAdmin::ProxyPushSupplier_ptr TAO_Notify_Builder::build_proxy (TAO_Notify_ConsumerAdmin* ca ACE_ENV_ARG_DECL) { diff --git a/TAO/orbsvcs/orbsvcs/Notify/Builder.h b/TAO/orbsvcs/orbsvcs/Notify/Builder.h index bcf5abd6bec..4be050d60e9 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Builder.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Builder.h @@ -26,11 +26,14 @@ #include "orbsvcs/NotifyExtC.h" #include "AdminProperties.h" +#include "Topology_Object.h" class TAO_Notify_EventChannelFactory; class TAO_Notify_EventChannel; class TAO_Notify_SupplierAdmin; class TAO_Notify_ConsumerAdmin; +class TAO_Notify_ProxyConsumer; +class TAO_Notify_ProxySupplier; class TAO_Notify_FilterFactory; class TAO_Notify_Object; @@ -66,6 +69,13 @@ public: , CosNotifyChannelAdmin::ChannelID_out id ACE_ENV_ARG_DECL); + + virtual TAO_Notify_EventChannel * + build_event_channel (TAO_Notify_EventChannelFactory* ecf + , const CosNotifyChannelAdmin::ChannelID id + ACE_ENV_ARG_DECL); + + /// Build ConsumerAdmin virtual CosNotifyChannelAdmin::ConsumerAdmin_ptr build_consumer_admin (TAO_Notify_EventChannel* ec @@ -73,13 +83,31 @@ public: , CosNotifyChannelAdmin::AdminID_out id ACE_ENV_ARG_DECL); + /// Build ConsumerAdmin during topology restore + /// TODO: this returns a reference to the actual type + /// to accomodate loadable builder/factory there should + /// be an appropriate base class for it to return. + virtual TAO_Notify_ConsumerAdmin * + build_consumer_admin (TAO_Notify_EventChannel* ec + , const CosNotifyChannelAdmin::AdminID id //CORBA::Long id // note: an in parameter! + ACE_ENV_ARG_DECL); + /// Build SupplierAdmin virtual CosNotifyChannelAdmin::SupplierAdmin_ptr - build_supplier_admin (TAO_Notify_EventChannel* ec + build_supplier_admin (TAO_Notify_EventChannel * ec , CosNotifyChannelAdmin::InterFilterGroupOperator op , CosNotifyChannelAdmin::AdminID_out id ACE_ENV_ARG_DECL); + /// Build ConsumerAdmin during topology restore + /// TODO: this returns a reference to the actual type + /// to accomodate loadable builder/factory there should + /// be an appropriate base class for it to return. + virtual TAO_Notify_SupplierAdmin * + build_supplier_admin (TAO_Notify_EventChannel * ec + , const CosNotifyChannelAdmin::AdminID id //CORBA::Long id // note: an in parameter! + ACE_ENV_ARG_DECL); + /// Build ProxyConsumer virtual CosNotifyChannelAdmin::ProxyConsumer_ptr build_proxy (TAO_Notify_SupplierAdmin* sa @@ -88,6 +116,13 @@ public: , const CosNotification::QoSProperties & initial_qos ACE_ENV_ARG_DECL); + /// Reload ProxyConsumer + virtual TAO_Notify_ProxyConsumer * + build_proxy (TAO_Notify_SupplierAdmin* sa + , CosNotifyChannelAdmin::ClientType ctype + , const CosNotifyChannelAdmin::ProxyID proxy_id + ACE_ENV_ARG_DECL); + /// Build ProxySupplier. virtual CosNotifyChannelAdmin::ProxySupplier_ptr build_proxy (TAO_Notify_ConsumerAdmin* ca @@ -96,6 +131,13 @@ public: , const CosNotification::QoSProperties & initial_qos ACE_ENV_ARG_DECL); + /// Reload ProxySupplier. + virtual TAO_Notify_ProxySupplier * + build_proxy (TAO_Notify_ConsumerAdmin* ca + , CosNotifyChannelAdmin::ClientType ctype + , const CosNotifyChannelAdmin::ProxyID proxy_id + ACE_ENV_ARG_DECL); + /// Build CosEC style ProxySupplier. virtual CosEventChannelAdmin::ProxyPushSupplier_ptr build_proxy (TAO_Notify_ConsumerAdmin* ca ACE_ENV_ARG_DECL); @@ -111,15 +153,15 @@ public: /// Apply Thread Pools. virtual void apply_thread_pool_concurrency ( - TAO_Notify_Object& object, - const NotifyExt::ThreadPoolParams& tp_params + TAO_Notify_Object& object, + const NotifyExt::ThreadPoolParams& tp_params ACE_ENV_ARG_DECL ); /// Apply Thread Pools with Lanes. virtual void apply_lane_concurrency ( - TAO_Notify_Object& object, - const NotifyExt::ThreadPoolLanesParams& tpl_params + TAO_Notify_Object& object, + const NotifyExt::ThreadPoolLanesParams& tpl_params ACE_ENV_ARG_DECL ); }; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Consumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Consumer.cpp index 84506c169de..3a34d828dcc 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Consumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Consumer.cpp @@ -6,21 +6,50 @@ #include "Consumer.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID(RT_Notify, TAO_Notify_Consumer, "$Id$") +ACE_RCSID (RT_Notify, TAO_Notify_Consumer, "$Id$") +#include "Timer.h" +#include "orbsvcs/orbsvcs/Time_Utilities.h" #include "ace/Refcounted_Auto_Ptr.h" #include "ace/Unbounded_Queue.h" #include "tao/debug.h" +#include "Method_Request_Event.h" + +//#define DEBUG_LEVEL 10 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + +static const int DEFAULT_RETRY_TIMEOUT = 10;//120; // Note : This should be a config param or qos setting TAO_Notify_Consumer::TAO_Notify_Consumer (TAO_Notify_ProxySupplier* proxy) - :proxy_ (proxy), event_collection_ (0), is_suspended_ (0) + : proxy_ (proxy) + , pending_events_ (0) + , is_suspended_ (0) + , pacing_ (proxy->qos_properties_.pacing_interval ()) + , max_batch_size_ (CosNotification::MaximumBatchSize, 0) + , timer_id_ (-1) +// , buffering_strategy_ (0) + , timer_ (0) { - this->event_collection_ = new TAO_Notify_Event_Collection (); + ACE_NEW ( + this->pending_events_ , + TAO_Notify_Consumer::Request_Queue () + ); + + this->timer_ = this->proxy ()->timer (); } TAO_Notify_Consumer::~TAO_Notify_Consumer () { - delete this->event_collection_; + delete this->pending_events_; +// delete this->buffering_strategy_; + if (this->timer_ == 0) + { + this->cancel_timer (); + this->timer_->_decr_refcnt (); + this->timer_ = 0; + } } TAO_Notify_Proxy* @@ -30,41 +59,506 @@ TAO_Notify_Consumer::proxy (void) } void -TAO_Notify_Consumer::dispatch_pending (ACE_ENV_SINGLE_ARG_DECL) +TAO_Notify_Consumer::qos_changed (const TAO_Notify_QoSProperties& qos_properties) +{ + this->max_batch_size_ = qos_properties.maximum_batch_size (); + +/* +//@@ todo: consider buffering strategy + if (this->max_batch_size_.is_valid ()) + {// set the max batch size. + this->buffering_strategy_->batch_size (this->max_batch_size_.value ()); + } +*/ + + // Inform the buffering strategy of qos change. +/* + this->buffering_strategy_->update_qos_properties (qos_properties); +*/ +} + +void +TAO_Notify_Consumer::resume (ACE_ENV_SINGLE_ARG_DECL) +{ + this->is_suspended_ = 0; + + this->dispatch_pending (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +TAO_Notify_Consumer::enqueue_request ( + TAO_Notify_Method_Request_Event * request + ACE_ENV_ARG_DECL) { + TAO_Notify_Event_var event_var; + request->event ()->queueable_copy (event_var ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + TAO_Notify_Method_Request_Event_Queueable * queue_entry; + ACE_NEW_THROW_EX (queue_entry, + TAO_Notify_Method_Request_Event_Queueable (*request, event_var), + CORBA::NO_MEMORY ()); + ACE_CHECK; + + if (DEBUG_LEVEL > 3) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("Consumer %d: enqueue_request (%d) @%@.\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence (), + request + )); + ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, *this->proxy_lock ()); + this->pending_events_->enqueue_tail (queue_entry); +} + +bool +TAO_Notify_Consumer::enqueue_if_necessary (TAO_Notify_Method_Request_Event * request ACE_ENV_ARG_DECL) +{ + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, *this->proxy_lock (), false); + if (! this->pending_events_->is_empty ()) + { + if (DEBUG_LEVEL > 3)ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("Consumer %d: enqueuing another event. %d\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence () + )); + TAO_Notify_Event_var event_var; + request->event ()->queueable_copy (event_var ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (false); + TAO_Notify_Method_Request_Event_Queueable * queue_entry; + ACE_NEW_THROW_EX (queue_entry, + TAO_Notify_Method_Request_Event_Queueable (*request, event_var), + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (false); + this->pending_events_->enqueue_tail (queue_entry); + this->schedule_timer (false); + return true; + } if (this->is_suspended_ == 1) - return; // Do nothing if we're suspended. + { + if (DEBUG_LEVEL > 3) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("Suspended Consumer %d enqueing event. %d\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence () + )); + TAO_Notify_Event_var event_var; + request->event ()->queueable_copy (event_var ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (false); + TAO_Notify_Method_Request_Event_Queueable * queue_entry; + ACE_NEW_THROW_EX (queue_entry, + TAO_Notify_Method_Request_Event_Queueable (*request, event_var), + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (false); + this->pending_events_->enqueue_tail (queue_entry); + this->schedule_timer (false); + return true; + } + return false; +} + +void +TAO_Notify_Consumer::deliver (TAO_Notify_Method_Request_Event * request ACE_ENV_ARG_DECL) +{ + // Increment reference counts (safely) to prevent this object and its proxy + // from being deleted while the push is in progress. + TAO_Notify_Refcountable_Guard_T<TAO_Notify_Proxy> proxy_guard (this->proxy ()); + TAO_Notify_Refcountable_Guard_T<TAO_Notify_Consumer> this_guard (this); + bool queued = enqueue_if_necessary (request ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + if (!queued) + { + DispatchStatus status = this->dispatch_request (request); + switch (status) + { + case DISPATCH_SUCCESS: + { + request->complete (); + break; + } + case DISPATCH_RETRY: + { + if (DEBUG_LEVEL > 1) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("Consumer %d enqueing event %d due to failed dispatch.\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence ())); + this->enqueue_request (request ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->schedule_timer (true); + break; + } + case DISPATCH_DISCARD: + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer %d: Error during direct dispatch. Discarding event:%d.\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence () + )); + request->complete (); + break; + } + case DISPATCH_FAIL: + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer %d: Failed during direct dispatch :%d. Discarding event.\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence () + )); + request->complete (); + ACE_TRY_NEW_ENV + { + this->proxy_supplier ()->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // todo is there something meaningful we can do here? + ; + } + ACE_ENDTRY; + break; + } + } + } +} + +TAO_Notify_Consumer::DispatchStatus +TAO_Notify_Consumer::dispatch_request (TAO_Notify_Method_Request_Event * request) +{ + DispatchStatus result = DISPATCH_SUCCESS; + ACE_TRY_NEW_ENV + { + request->event ()->push (this ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (DEBUG_LEVEL > 8) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("Consumer %d dispatched single event %d.\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence () + )); + } + ACE_CATCH (CORBA::OBJECT_NOT_EXIST, ex) + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Consumer %d::push (request) OBJECT_NOT_EXIST %s\n"), + ACE_static_cast (int, this->proxy ()->id ()), + ex._info ().c_str () + )); + result = DISPATCH_FAIL; + } + ACE_CATCH (CORBA::TRANSIENT, ex) + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Consumer %d::push (request) Transient (minor=%d) %s\n"), + ACE_static_cast (int, this->proxy ()->id ()), + ex.minor (), + ex._info ().c_str () + )); + const CORBA::ULong BITS_5_THRU_12_MASK = 0x00000f80u; + switch (ex.minor () & 0xfffff000u) + { + case CORBA::OMGVMCID: + switch (ex.minor () & 0x00000fffu) + { + case 2: // No usable profile + case 3: // Request cancelled + case 4: // POA destroyed + result = DISPATCH_FAIL; + break; + default: + result = DISPATCH_DISCARD; + } + break; + + case TAO_DEFAULT_MINOR_CODE: + default: + switch (ex.minor () & BITS_5_THRU_12_MASK) + { + case TAO_INVOCATION_SEND_REQUEST_MINOR_CODE: + result = DISPATCH_FAIL; + break; + case TAO_POA_DISCARDING: + case TAO_POA_HOLDING: + default: + result = DISPATCH_RETRY; + } break; + } + + } + ACE_CATCH (CORBA::SystemException, ex) + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Consumer %d::push (request) SystemException %s\n"), + ACE_static_cast (int, this->proxy ()->id ()), + ex._info ().c_str () + )); + result = DISPATCH_DISCARD; + } + ACE_CATCHANY + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Consumer %d::push (request) Caught unexpected exception pushing event to consumer.\n"), + ACE_static_cast (int, this->proxy ()->id ()) + )); + result = DISPATCH_DISCARD; + } + ACE_ENDTRY; + + // for persistent events that haven't timed out + // convert "FAIL" & "DISCARD" to "RETRY" + // for transient events, convert RETRY to DISCARD (hey, best_effort.) + if (result == DISPATCH_FAIL || result == DISPATCH_DISCARD) + { + if (request->should_retry ()) + { + result = DISPATCH_RETRY; + } + } + else if (result == DISPATCH_RETRY) + { + if (! request->should_retry ()) + { + result = DISPATCH_DISCARD; + } + } - TAO_Notify_Event_Collection event_collection_copy; + return result; +} +TAO_Notify_Consumer::DispatchStatus +TAO_Notify_Consumer::dispatch_batch (const CosNotification::EventBatch& batch) +{ + ACE_TRY_NEW_ENV { - ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, *this->proxy_lock ()); - event_collection_copy = *this->event_collection_; // Payload is never copied, this is a collection of _vars. - this->event_collection_->reset (); + this->push (batch ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; } + ACE_CATCH (CORBA::OBJECT_NOT_EXIST, not_exist) + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Consumer %d::dispatch_batch OBJECT_NOT_EXIST %s\n"), + ACE_static_cast (int, this->proxy ()->id ()), + not_exist._info ().c_str () + )); + return DISPATCH_FAIL; + } + ACE_CATCH (CORBA::SystemException, ex) + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Consumer %d::dispatch_batch SystemException %s\n"), + ACE_static_cast (int, this->proxy ()->id ()), + ex._info ().c_str () + )); + // @@todo what to return here? + return DISPATCH_RETRY; + } + ACE_CATCHANY + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("(%P|%t) Consumer %d: Caught unexpected exception pushing EventBatch to consumer.\n"), + ACE_static_cast (int, this->proxy ()->id ()) + )); + return DISPATCH_FAIL; + } + ACE_ENDTRY; + return DISPATCH_SUCCESS; +} + +void +TAO_Notify_Consumer::dispatch_pending (ACE_ENV_SINGLE_ARG_DECL) +{ + if (DEBUG_LEVEL > 5) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("Consumer %d dispatching pending events. Queue size: %d\n"), + ACE_static_cast (int, this->proxy ()->id ()), + this->pending_events_->size () + )); - TAO_Notify_ProxySupplier* proxy_supplier = this->proxy_supplier (); + // lock ourselves in memory for the duration + TAO_Notify_Refcountable_Guard_T<TAO_Notify_Consumer> self_grd (this); + + // dispatch events until: 1) the queue is empty; 2) the proxy shuts down, or 3) the dispatch fails + ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, *this->proxy_lock ()); + bool ok = true; + while (ok && !this->proxy_supplier ()->has_shutdown () && !this->pending_events_->is_empty ()) + { + if (! dispatch_from_queue (*this->pending_events_, ace_mon)) + { + this->schedule_timer (true); + ok = false; + } + } +} - TAO_Notify_Event_var event; - while (!event_collection_copy.is_empty ()) +// virtual: this is the default, overridden for SequencePushConsumer +bool +TAO_Notify_Consumer::dispatch_from_queue (Request_Queue & requests, ACE_Guard <TAO_SYNCH_MUTEX> & ace_mon) +{ + bool result = true; + TAO_Notify_Method_Request_Event_Queueable * request; + if (requests.dequeue_head (request) == 0) + { + ace_mon.release (); + DispatchStatus status = this->dispatch_request (request); + switch (status) { - if (event_collection_copy.dequeue_head (event) == 0) + case DISPATCH_SUCCESS: + { + request->complete (); + request->release (); + result = true; + ace_mon.acquire (); + break; + } + case DISPATCH_RETRY: + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer %d: Will retry %d\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence () + )); + ace_mon.acquire (); + requests.enqueue_head (request); // put the failed event back where it was + result = false; + break; + } + case DISPATCH_DISCARD: + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer %d: Error during dispatch. Discarding event:%d.\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence () + )); + request->complete (); + ace_mon.acquire (); + result = true; + break; + } + case DISPATCH_FAIL: + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer %d: Failed. Discarding event %d.\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence () + )); + request->complete (); + ace_mon.acquire (); + while (requests.dequeue_head (request) == 0) + { + ace_mon.release (); + request->complete (); + ace_mon.acquire (); + } + ace_mon.release (); + ACE_TRY_NEW_ENV { - proxy_supplier->push_no_filtering (event ACE_ENV_ARG_PARAMETER); + this->proxy_supplier ()->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; } + ACE_CATCHANY + { + // todo is there something reasonable to do here? + } + ACE_ENDTRY; + ace_mon.acquire (); + result = true; + break; + } } + } + return result; } +//@@todo: rather than is_error, use pacing interval so it will be configurable +//@@todo: find some way to use batch buffering stratgy for sequence consumers. void -TAO_Notify_Consumer::resume (ACE_ENV_SINGLE_ARG_DECL) +TAO_Notify_Consumer::schedule_timer (bool is_error) { - this->is_suspended_ = 0; + if (this->timer_id_ != -1) + { + return; // We only want a single timeout scheduled. + } + // don't schedule timer if there's nothing that can be done + if (this->is_suspended ()) + { + return; + } - this->dispatch_pending (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_ASSERT (this->timer_ != 0); + + // If we're scheduling the timer due to an error then we want to + // use the retry timeout, otherwise we'll assume that the pacing + // interval is sufficient for now. + ACE_Time_Value tv (DEFAULT_RETRY_TIMEOUT); + + if (! is_error) + { + if (this->pacing_.is_valid ()) + { + tv = ORBSVCS_Time::to_Time_Value (this->pacing_.value ()); + } + } + + if (DEBUG_LEVEL > 5) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("Consumer %d: scheduling pacing/retry for %dms.\n"), + ACE_static_cast (int, this->proxy ()->id ()), + tv.msec ())); + + this->timer_id_ = this->timer_->schedule_timer ( + this, + tv, + ACE_Time_Value::zero); + if (this->timer_id_ == -1) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("TAO_Notify_Consumer %d::schedule_timer () Error scheduling timer.\n"), + ACE_static_cast (int, this->proxy ()->id ()) + )); + } } void +TAO_Notify_Consumer::cancel_timer (void) +{ + if (this->timer_ != 0 && this->timer_id_ != -1) + { + if (DEBUG_LEVEL > 5) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("Consumer %d canceling dispatch timer.\n"), + static_cast<int> (this->proxy ()->id ()) + )); + + this->timer_->cancel_timer (timer_id_); + } + this->timer_id_ = -1; +} + +int +TAO_Notify_Consumer::handle_timeout (const ACE_Time_Value&, const void*) +{ + TAO_Notify_Refcountable_Guard_T<TAO_Notify_Consumer> grd (this); + this->timer_id_ = -1; // This must come first, because dispatch_pending may try to resched + ACE_TRY_NEW_ENV + { + this->dispatch_pending (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + + return 0; +} + +void +TAO_Notify_Consumer::shutdown (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + if (this->timer_ == 0) + { + this->cancel_timer (); + this->timer_->_decr_refcnt (); + this->timer_ = 0; + } +} + + +void TAO_Notify_Consumer::dispatch_updates_i (const CosNotification::EventTypeSeq& added, const CosNotification::EventTypeSeq& removed ACE_ENV_ARG_DECL) { diff --git a/TAO/orbsvcs/orbsvcs/Notify/Consumer.h b/TAO/orbsvcs/orbsvcs/Notify/Consumer.h index bac8a0cbded..1dea726c618 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Consumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Consumer.h @@ -9,8 +9,8 @@ * */ -#ifndef TAO_Notify_CONSUMER_H -#define TAO_Notify_CONSUMER_H +#ifndef TAO_NOTIFY_CONSUMER_H +#define TAO_NOTIFY_CONSUMER_H #include /**/ "ace/pre.h" @@ -25,18 +25,33 @@ #include "Peer.h" #include "Event.h" +#include "ace/Event_Handler.h" class TAO_Notify_ProxySupplier; class TAO_Notify_Proxy; - +class TAO_Notify_Method_Request_Event_Queueable; +class TAO_Notify_Method_Request_Event; /** * @class TAO_Notify_Consumer * * @brief Astract Base class for wrapping consumer objects that connect to the EventChannel * */ -class TAO_Notify_Serv_Export TAO_Notify_Consumer : public TAO_Notify_Peer +class TAO_Notify_Serv_Export TAO_Notify_Consumer + : public TAO_Notify_Peer + , public ACE_Event_Handler // to support timer { + +public: + /// Status returned from dispatch attempts + enum DispatchStatus { + DISPATCH_SUCCESS, + DISPATCH_RETRY, // retry this message + DISPATCH_DISCARD, // discard this message + DISPATCH_FAIL}; // discard all messages and disconnect consumer + + typedef ACE_Unbounded_Queue<TAO_Notify_Method_Request_Event_Queueable *> Request_Queue; + public: /// Constuctor TAO_Notify_Consumer (TAO_Notify_ProxySupplier* proxy); @@ -50,11 +65,8 @@ public: /// Access Base Proxy. virtual TAO_Notify_Proxy* proxy (void); - /// Push <event> to this consumer. - void push (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); - - /// Push <event> to this consumer. - void push (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL); + /// Dispatch Event to consumer + void deliver (TAO_Notify_Method_Request_Event * request ACE_ENV_ARG_DECL); /// Push <event> to this consumer. virtual void push (const CORBA::Any& event ACE_ENV_ARG_DECL) = 0; @@ -62,6 +74,12 @@ public: /// Push <event> to this consumer. virtual void push (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL) = 0; + /// Push a batch of events to this consumer. + virtual void push (const CosNotification::EventBatch& event ACE_ENV_ARG_DECL) = 0; + + /// Dispatch the batch of events to the attached consumer + DispatchStatus dispatch_batch (const CosNotification::EventBatch& batch); + /// Dispatch the pending events void dispatch_pending (ACE_ENV_SINGLE_ARG_DECL); @@ -74,32 +92,92 @@ public: /// Resume Connection void resume (ACE_ENV_SINGLE_ARG_DECL); + /// Shutdown the consumer + virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL); + + /// on reconnect we need to move events from the old consumer + /// to the new one + virtual void reconnect_from_consumer ( + TAO_Notify_Consumer* old_consumer + ACE_ENV_ARG_DECL) = 0; + + /// Override, Peer::qos_changed + virtual void qos_changed (const TAO_Notify_QoSProperties& qos_properties); + protected: + DispatchStatus dispatch_request (TAO_Notify_Method_Request_Event * request); + + /** + * \brief Attempt to dispatch event from a queue. + * + * Called by dispatch_pending. Deliver one or more events to the Consumer. + * If delivery fails, events are left in the queue (or discarded depending + * on QoS parameters.) + * Undelivered, undiscarded requests are left at the front of the queue. + * Overridden in sequence consumer to dispatch as an EventBatch. + * \return false if delivery failed and the request(s) cannot be discarded. + */ + virtual bool dispatch_from_queue ( + Request_Queue & requests, + ACE_Guard <TAO_SYNCH_MUTEX> & ace_mon); + + void enqueue_request(TAO_Notify_Method_Request_Event * request ACE_ENV_ARG_DECL); + + /// Add request to a queue if necessary. + /// Overridden by sequence consumer to "always" put incoming events into the queue. + /// @returns true the request has been enqueued; false the request should be handled now. + virtual bool enqueue_if_necessary( + TAO_Notify_Method_Request_Event * request + ACE_ENV_ARG_DECL); + // Dispatch updates virtual void dispatch_updates_i (const CosNotification::EventTypeSeq& added, const CosNotification::EventTypeSeq& removed ACE_ENV_ARG_DECL); - /// Push Implementation. - virtual void push_i (const TAO_Notify_Event* event ACE_ENV_ARG_DECL) = 0; - - /// Push Implementation. - virtual void push_i (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL) = 0; - /// Get the shared Proxy Lock TAO_SYNCH_MUTEX* proxy_lock (void); +protected: + virtual int handle_timeout (const ACE_Time_Value& current_time, + const void* act = 0); + + + /// Schedule timer + void schedule_timer (bool is_error = false); + + /// Cancel timer + void cancel_timer (void); + + ///= Protected Data Members +protected: /// The Proxy that we associate with. TAO_Notify_ProxySupplier* proxy_; /// Events pending to be delivered. - TAO_Notify_Event_Collection* event_collection_; + Request_Queue * pending_events_; /// Suspended Flag. CORBA::Boolean is_suspended_; /// Interface that accepts offer_changes CosNotifyComm::NotifyPublish_var publish_; + + /// The Pacing Interval + const TAO_Notify_Property_Time & pacing_; + + /// Max. batch size. + TAO_Notify_Property_Long max_batch_size_; + + /// Timer Id. + long timer_id_; + +// todo find some way to use this rather than Request_Queue +// /// The Buffering Strategy +// TAO_Notify_Batch_Buffering_Strategy* buffering_strategy_; +// + /// The Timer Manager that we use. + TAO_Notify_Timer* timer_; }; #if defined (__ACE_INLINE__) @@ -108,4 +186,4 @@ protected: #include /**/ "ace/post.h" -#endif /* TAO_Notify_CONSUMER_H */ +#endif /* TAO_NOTIFY_CONSUMER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Consumer.inl b/TAO/orbsvcs/orbsvcs/Notify/Consumer.inl index 77a5f12c554..5bbdbc22dff 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Consumer.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Consumer.inl @@ -1,6 +1,8 @@ // $Id$ #include "ProxySupplier.h" +//#include "Method_Request.h" +#include "Method_Request_Dispatch.h" ACE_INLINE TAO_SYNCH_MUTEX* TAO_Notify_Consumer::proxy_lock (void) @@ -25,72 +27,3 @@ TAO_Notify_Consumer::suspend (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) { this->is_suspended_ = 1; } - -ACE_INLINE void -TAO_Notify_Consumer::push (const TAO_Notify_Event_var &event ACE_ENV_ARG_DECL) -{ - if (this->is_suspended_ == 1) // If we're suspended, queue for later delivery. - { - ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, *this->proxy_lock ()); - - this->event_collection_->enqueue_head (event); - - return; - } - - ACE_TRY - { - this->push_i (event ACE_ENV_ARG_PARAMETER); - ACE_TRY_CHECK; - } - ACE_CATCH (CORBA::OBJECT_NOT_EXIST, not_exist) - { - this->handle_dispatch_exception (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_TRY_CHECK; - } - ACE_CATCH (CORBA::SystemException, sysex) - { - this->handle_dispatch_exception (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_TRY_CHECK; - } - ACE_CATCHANY - { - } - ACE_ENDTRY; -} - -ACE_INLINE void -TAO_Notify_Consumer::push (const TAO_Notify_Event* event ACE_ENV_ARG_DECL) -{ - if (this->is_suspended_ == 1) // If we're suspended, queue for later delivery. - { - ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, *this->proxy_lock ()); - - TAO_Notify_Event* event_copy = event->copy (ACE_ENV_SINGLE_ARG_PARAMETER); - TAO_Notify_Event_Copy_var event_var (event_copy); - - this->event_collection_->enqueue_head (event_var); - - return; - } - - ACE_TRY - { - this->push_i (event ACE_ENV_ARG_PARAMETER); - ACE_TRY_CHECK; - } - ACE_CATCH (CORBA::OBJECT_NOT_EXIST, not_exist) - { - this->handle_dispatch_exception (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_TRY_CHECK; - } - ACE_CATCH (CORBA::SystemException, sysex) - { - this->handle_dispatch_exception (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_TRY_CHECK; - } - ACE_CATCHANY - { - } - ACE_ENDTRY; -} diff --git a/TAO/orbsvcs/orbsvcs/Notify/ConsumerAdmin.cpp b/TAO/orbsvcs/orbsvcs/Notify/ConsumerAdmin.cpp index 5552b0df58b..09a89927501 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ConsumerAdmin.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/ConsumerAdmin.cpp @@ -6,8 +6,8 @@ #include "ConsumerAdmin.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID (RT_Notify, - TAO_Notify_ConsumerAdmin, +ACE_RCSID (RT_Notify, + TAO_Notify_ConsumerAdmin, "$Id$") #include "ace/Auto_Ptr.h" @@ -20,6 +20,13 @@ ACE_RCSID (RT_Notify, #include "Builder.h" #include "Find_Worker_T.h" #include "Seq_Worker_T.h" +#include "ProxySupplier.h" + +#include "tao/debug.h" +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL typedef TAO_Notify_Find_Worker_T<TAO_Notify_Proxy , CosNotifyChannelAdmin::ProxySupplier @@ -30,9 +37,18 @@ TAO_Notify_ProxySupplier_Find_Worker; typedef TAO_Notify_Seq_Worker_T<TAO_Notify_Proxy> TAO_Notify_Proxy_Seq_Worker; TAO_Notify_ConsumerAdmin::TAO_Notify_ConsumerAdmin (void) + : TAO_Notify_Admin () +{ +} + +const char * +TAO_Notify_ConsumerAdmin::get_admin_type_name () const { + return "consumer_admin"; } + + TAO_Notify_ConsumerAdmin::~TAO_Notify_ConsumerAdmin () { } @@ -83,6 +99,76 @@ TAO_Notify_ConsumerAdmin::destroy (ACE_ENV_SINGLE_ARG_DECL) ACE_CHECK; } + +TAO_Notify::Topology_Object* +TAO_Notify_ConsumerAdmin::load_child (const ACE_CString &type, + CORBA::Long id, const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL) +{ + TAO_Notify::Topology_Object* result = this; + if (type == "proxy_push_supplier") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Admin reload proxy %d\n") + , ACE_static_cast (int, id) + )); + result = this->load_proxy(id, CosNotifyChannelAdmin::ANY_EVENT, attrs ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + else if (type == "structured_proxy_push_supplier") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Admin reload proxy %d\n") + , ACE_static_cast (int, id) + )); + result = this->load_proxy(id, CosNotifyChannelAdmin::STRUCTURED_EVENT, attrs ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + else if (type == "sequence_proxy_push_supplier") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Admin reload proxy %d\n") + , ACE_static_cast (int, id) + )); + result = this->load_proxy(id, CosNotifyChannelAdmin::SEQUENCE_EVENT, attrs ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } +#if 0 + else if (type == "ec_proxy_push_supplier") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Admin reload proxy %d\n") + , ACE_static_cast (int, id) + )); + result = this->load_proxy(id, attrs ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } +#endif + else + { + result = TAO_Notify_Admin::load_child (type, id, attrs ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + return result; +} + +TAO_Notify::Topology_Object* +TAO_Notify_ConsumerAdmin::load_proxy ( + CORBA::Long id, + CosNotifyChannelAdmin::ClientType ctype, + const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL) +{ + TAO_Notify_Builder* bld = TAO_Notify_PROPERTIES::instance()->builder(); + TAO_Notify_ProxySupplier * proxy = + bld->build_proxy (this + , ctype + , id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + ACE_ASSERT(proxy != 0); + proxy->load_attrs (attrs); + return proxy; +} + CosNotifyChannelAdmin::ProxySupplier_ptr TAO_Notify_ConsumerAdmin::obtain_notification_push_supplier (CosNotifyChannelAdmin::ClientType ctype, CosNotifyChannelAdmin::ProxyID_out proxy_id @@ -95,11 +181,16 @@ TAO_Notify_ConsumerAdmin::obtain_notification_push_supplier (CosNotifyChannelAdm { CosNotification::QoSProperties initial_qos; - return TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this + CosNotifyChannelAdmin::ProxySupplier_var proxy = + TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this , ctype , proxy_id - , initial_qos + , initial_qos ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + return proxy._retn (); } CosNotifyChannelAdmin::ProxySupplier_ptr @@ -114,11 +205,16 @@ TAO_Notify_ConsumerAdmin::obtain_notification_push_supplier_with_qos (CosNotifyC , CosNotification::UnsupportedQoS )) { - return TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this + CosNotifyChannelAdmin::ProxySupplier_var proxy = + TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this , ctype , proxy_id , initial_qos ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + return proxy._retn (); } CosEventChannelAdmin::ProxyPushSupplier_ptr @@ -127,7 +223,12 @@ TAO_Notify_ConsumerAdmin::obtain_push_supplier (ACE_ENV_SINGLE_ARG_DECL) CORBA::SystemException )) { - return TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this ACE_ENV_ARG_PARAMETER); + CosEventChannelAdmin::ProxyPushSupplier_var proxy = + TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + return proxy._retn (); } CosNotifyChannelAdmin::AdminID @@ -223,6 +324,7 @@ TAO_Notify_ConsumerAdmin::subscription_change (const CosNotification::EventTypeS this->proxy_container_->collection()->for_each (&worker ACE_ENV_ARG_PARAMETER); } + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } CosNotifyFilter::FilterID @@ -231,7 +333,12 @@ TAO_Notify_ConsumerAdmin::add_filter (CosNotifyFilter::Filter_ptr new_filter ACE CORBA::SystemException )) { - return this->filter_admin_.add_filter (new_filter ACE_ENV_ARG_PARAMETER); + CosNotifyFilter::FilterID fid = + this->filter_admin_.add_filter (new_filter ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (fid); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (fid); + return fid; } void @@ -356,6 +463,24 @@ TAO_Notify_ConsumerAdmin::obtain_pull_supplier (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), CosEventChannelAdmin::ProxyPullSupplier::_nil ()); } +TAO_Notify_ProxySupplier * +TAO_Notify_ConsumerAdmin::find_proxy_supplier ( + TAO_Notify::IdVec & id_path, + size_t position + ACE_ENV_ARG_DECL) +{ + TAO_Notify_ProxySupplier * result = 0; + size_t path_size = id_path.size (); + if (position < path_size) + { + TAO_Notify_ProxySupplier_Find_Worker find_worker; + TAO_Notify_Proxy * proxy = find_worker.find (id_path[position], *this->proxy_container_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + result = dynamic_cast <TAO_Notify_ProxySupplier *> (proxy); + } + return result; +} + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class TAO_Notify_Find_Worker_T<TAO_Notify_Proxy diff --git a/TAO/orbsvcs/orbsvcs/Notify/ConsumerAdmin.h b/TAO/orbsvcs/orbsvcs/Notify/ConsumerAdmin.h index 99964a7cd11..2f4632fba01 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ConsumerAdmin.h +++ b/TAO/orbsvcs/orbsvcs/Notify/ConsumerAdmin.h @@ -23,6 +23,7 @@ #include "orbsvcs/NotifyExtS.h" #include "Admin.h" +class TAO_Notify_ProxySupplier; #if defined(_MSC_VER) #if (_MSC_VER >= 1200) @@ -57,7 +58,25 @@ public: /// Release this object. virtual void release (void); + virtual const char * get_admin_type_name () const; + + virtual TAO_Notify::Topology_Object* load_child ( + const ACE_CString &type, + CORBA::Long id, + const TAO_Notify::NVPList& attrs + ACE_ENV_ARG_DECL); + + TAO_Notify_ProxySupplier * find_proxy_supplier ( + TAO_Notify::IdVec & id_path, + size_t position + ACE_ENV_ARG_DECL); + protected: + TAO_Notify::Topology_Object *load_proxy ( + CORBA::Long id, + CosNotifyChannelAdmin::ClientType ctype, + const TAO_Notify::NVPList& attrs + ACE_ENV_ARG_DECL); /// = NotifyExt::ConsumerAdmin methods virtual CosNotifyChannelAdmin::ProxySupplier_ptr diff --git a/TAO/orbsvcs/orbsvcs/Notify/CosNotify_Service.cpp b/TAO/orbsvcs/orbsvcs/Notify/CosNotify_Service.cpp index 4fcfbe8081e..da6c7459da9 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/CosNotify_Service.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/CosNotify_Service.cpp @@ -104,6 +104,11 @@ TAO_CosNotify_Service::init (int argc, char *argv[]) task_per_proxy = 1; arg_shifter.consume_arg (); } + else if (arg_shifter.cur_arg_strncasecmp (ACE_LIB_TEXT("-AllowReconnect")) == 0) + { + arg_shifter.consume_arg (); + TAO_Notify_PROPERTIES::instance()->allow_reconnect (true); + } } // Init the EC QoS diff --git a/TAO/orbsvcs/orbsvcs/Notify/Delivery_Request.cpp b/TAO/orbsvcs/orbsvcs/Notify/Delivery_Request.cpp new file mode 100644 index 00000000000..b78ff6882d2 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Delivery_Request.cpp @@ -0,0 +1,108 @@ +// $Id$ + +#include "Delivery_Request.h" + +#if ! defined (__ACE_INLINE__) +#include "Delivery_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include "tao/debug.h" + +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + +namespace TAO_Notify +{ + +/////////////////// +// Delivery_Request +Delivery_Request::Delivery_Request (const Routing_Slip_Ptr & routing_slip, size_t request_id) + : routing_slip_ (routing_slip) + , request_id_ (request_id) + , delivery_type_ (0) +{ + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Delivery_Request:: constructor\n") + )); +} + +Delivery_Request::~Delivery_Request () +{ + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Delivery_Request:: destructor\n") + )); +} + +// DO NOT INLINE THIS. It uses the Routing_Slip_Ptr which cannot be declared at +// the time Delivery_Request.inl is compiled. +void +Delivery_Request::complete () +{ + routing_slip_->delivery_request_complete (this->request_id_); +} + +// DO NOT INLINE THIS. It uses the Routing_Slip_Ptr which cannot be declared at +// the time Delivery_Request.inl is compiled. +const TAO_Notify_Event_var & +Delivery_Request::event () const +{ + return this->routing_slip_->event (); +} + +void +Delivery_Request::marshal (TAO_OutputCDR & cdr) +{ + if (this->delivery_type_ != 0) + { + cdr.write_octet (this->delivery_type_); + size_t dest_count = this->destination_id_.size (); + cdr.write_ulong (dest_count); + for (size_t ndest = 0; ndest < dest_count; ++ ndest) + { + cdr.write_ulong (this->destination_id_ [ndest]); + } + } +} + +unsigned long +Delivery_Request::sequence () const +{ + return this->routing_slip_->sequence (); +} + + +bool +Delivery_Request::should_retry () const +{ + return this->routing_slip_->should_retry (); +} + +void +Delivery_Request::dispatch ( + TAO_Notify_ProxySupplier * proxy_supplier, + bool filter ACE_ENV_ARG_DECL) +{ + this->routing_slip_->dispatch (proxy_supplier, filter ACE_ENV_ARG_PARAMETER); +} +} // namespace + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +//template class ACE_Auto_Basic_Ptr<TAO_Notify::Routing_Slip>; +//template class ACE_Strong_Bound_Ptr<TAO_Notify::Routing_Slip, TAO_SYNCH_MUTEX>; +//template class ACE_Auto_Basic_Ptr<TAO_Notify::Delivery_Request>; +//template class ACE_Strong_Bound_Ptr<TAO_Notify::Delivery_Request,TAO_SYNCH_MUTEX>; +// Duplicated in Routing_Slip.cpp +//template class ACE_Vector <TAO_Notify::Delivery_Request_Ptr>; +//template class ACE_Array_Base<ACE_Strong_Bound_Ptr<TAO_Notify::Delivery_Request,TAO_SYNCH_MUTEX> >; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +//#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Notify::Routing_Slip> +//#pragma instantiate ACE_Strong_Bound_Ptr<TAO_Notify::Routing_Slip,TAO_SYNCH_MUTEX> +//#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Notify::Delivery_Request> +//#pragma instantiate ACE_Strong_Bound_Ptr<TAO_Notify::Delivery_Request,TAO_SYNCH_MUTEX> +// Duplicated in Routing_Slip.cpp +//#pragma instantiate ACE_Vector <TAO_Notify::Delivery_Request_Ptr> +//#pragma instantiate ACE_Array_Base<ACE_Strong_Bound_Ptr<TAO_Notify::Delivery_Request,TAO_SYNCH_MUTEX> > +#endif /*ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Delivery_Request.h b/TAO/orbsvcs/orbsvcs/Notify/Delivery_Request.h new file mode 100644 index 00000000000..235a5a68f85 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Delivery_Request.h @@ -0,0 +1,132 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef TAO_NOTIFY_DELIVERY_REQUEST_H +#define TAO_NOTIFY_DELIVERY_REQUEST_H +#include /**/ "ace/pre.h" + +#include "notify_serv_export.h" +#include "Topology_Object.h" +#include "Event.h" +#include <ace/Vector_T.h> +#include <ace/Bound_Ptr.h> +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +// Forward declarations of referenced classes +class TAO_Notify_EventChannelFactory; +class TAO_Notify_ProxySupplier; + +namespace TAO_Notify +{ + +// Forward declarations of TAO_Notify classes/pointers/collections declared +// in this header +class Delivery_Request; +/// A reference-counted smart pointer to a Delivery_Request. +typedef ACE_Strong_Bound_Ptr<Delivery_Request, TAO_SYNCH_MUTEX> Delivery_Request_Ptr; + +typedef ACE_Unbounded_Queue<Delivery_Request_Ptr> Delivery_Request_Queue; + +// Forward declarations of TAO_Notify classes/pointers/collections referenced +// in this header + +class Routing_Slip; +typedef ACE_Strong_Bound_Ptr<Routing_Slip, TAO_SYNCH_MUTEX> Routing_Slip_Ptr; + +/// \brief Represents a request to deliver an event to a particular destination. +/// +/// A Routing Slip contains a collection of Delivery Requests. +/// A Delivery Request is associated with a Delivery Method. Delivery Methods +/// should be lightweight objects because they are copied, queued, and otherwise +/// passed around while they are waiting to be executed. The Delivery Request is +/// more stable. +class TAO_Notify_Serv_Export Delivery_Request +{ +public: + /// Normal constructor + /// \param routing_slip the routing slip that owns this Delivery Request. + /// \param request_id an id that identifies this Delivery Request to the Routing Slip. + Delivery_Request (const Routing_Slip_Ptr & routing_slip, size_t request_id); + + /// \brief A static "factory" method for use during restart. + /// + /// \param routing_slip. The routing slip to which the new Delivery Request should be attached. + /// \param request_id The id used to identify this Delivery Request to the Routing Slip. + /// \param ecf The EventChannelFactory responsible for reloading this Delivery Method. + /// \param cdr A CDR stream from which the peristent information for this Delivery Requect can be retrieved. + /// \return a pointer to the newly-allocated Delivery Request + static Delivery_Request_Ptr create ( + const Routing_Slip_Ptr & routing_slip, + size_t request_id, + TAO_Notify_EventChannelFactory & ecf, + TAO_InputCDR & cdr); + + /// a normal destructor. + ~Delivery_Request (); + + /// \brief A method to indicate the delivery is complete. + /// + /// To be called by the delivery method associated with this delivery request. + void complete (); + + /// \brief An accessor method for the event associated with the Routing Slip that owns this Delivery request. + const TAO_Notify_Event_var & event () const; + + /// \brief An accessor method for the routing slip that owns this request. + const Routing_Slip_Ptr & routing_slip ()const; + + /// \brief Capture Delivery Type for the Delivery Method + /// + /// Called by the delivery method to capture information that should be persisted. + void set_delivery_type (ACE_CDR::Octet type); + + /// \brief Capture destination ID for the Delivery Request. + /// + /// Called by the delivery method to capture information that should be persisted. + void set_destination_id (IdVec & destination_id); + + /// \brief Marshal peristent information for this delivery request and its delivery methods into a CDR stream. + /// + /// Called during persistent event storage. + void marshal (TAO_OutputCDR & cdr); + + /// expose routing slip method + unsigned long sequence () const; + + /// expose routing slip method + bool should_retry () const; + + /// expose routing slip method + void dispatch (TAO_Notify_ProxySupplier * proxy_supplier, bool filter ACE_ENV_ARG_DECL); + + // Meaningless, but needed by ACE_Vector on some platforms (gcc2.x LynxOS) + bool operator == (const Delivery_Request & rhs) const; + // Meaningless, but needed by ACE_Vector on some platforms + bool operator != (const Delivery_Request & rhs) const; + +private: + /// No null constructor. + Delivery_Request (); + /// No copy constructor. + Delivery_Request (const Delivery_Request & rhs); + /// no assignment operator + Delivery_Request & operator = (const Delivery_Request & rhs); + +private: + Routing_Slip_Ptr routing_slip_; + size_t request_id_; + ACE_CDR::Octet delivery_type_; + IdVec destination_id_; +}; + +} // namespace + +#if defined (__ACE_INLINE__) +#include "Delivery_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* TAO_NOTIFY_DELIVERY_REQUEST_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Delivery_Request.inl b/TAO/orbsvcs/orbsvcs/Notify/Delivery_Request.inl new file mode 100644 index 00000000000..a63fcc9a6aa --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Delivery_Request.inl @@ -0,0 +1,31 @@ +/* -*- C++ -*- */ +// $Id$ +#include "Routing_Slip.h" + +namespace TAO_Notify +{ + +ACE_INLINE +const Routing_Slip_Ptr & +Delivery_Request::routing_slip () const +{ + return this->routing_slip_; +} + +ACE_INLINE +void +Delivery_Request::set_delivery_type (ACE_CDR::Octet type) +{ + this->delivery_type_ = type; +} + +ACE_INLINE +void +Delivery_Request::set_destination_id (IdVec & destination_id) +{ + this->destination_id_ = destination_id; +} + +} // namespace TAO_Notify + + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Event.cpp b/TAO/orbsvcs/orbsvcs/Notify/Event.cpp index b731ccf5f4d..b9c21374693 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Event.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Event.cpp @@ -6,16 +6,22 @@ #include "Event.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID (Notify, - TAO_Notify_Event, +ACE_RCSID (Notify, + TAO_Notify_Event, "$Id$") #include "tao/debug.h" +#include "tao/CDR.h" #include "orbsvcs/CosNotificationC.h" +// NOTE: unfortunately we must know about derived types to implement unmarshal +#include "Any/AnyEvent.h" +#include "Structured/StructuredEvent.h" TAO_Notify_Event::TAO_Notify_Event (void) :priority_ (CosNotification::Priority, CosNotification::DefaultPriority), - timeout_ (CosNotification::Timeout) + timeout_ (CosNotification::Timeout), + reliable_ (false), + event_on_heap_ (0) { // if (TAO_debug_level > 0) // ACE_DEBUG ((LM_DEBUG,"event:%x created\n", this )); @@ -26,6 +32,11 @@ TAO_Notify_Event::~TAO_Notify_Event () // if (TAO_debug_level > 1) // ACE_DEBUG ((LM_DEBUG,"event:%x destroyed\n", this )); } +void +TAO_Notify_Event::release (void) +{ + delete this; +} void TAO_Notify_Event::translate (const CORBA::Any& any, CosNotification::StructuredEvent& notification) @@ -40,11 +51,37 @@ TAO_Notify_Event::translate (const CosNotification::StructuredEvent& notificatio { any <<= notification; // is the typecode set by this operation or do we need to set it explicity. } +/// Unmarshal an event from a CDR. (for persistence) +//static +TAO_Notify_Event * +TAO_Notify_Event::unmarshal (TAO_InputCDR & cdr) +{ + TAO_Notify_Event * result = 0; + ACE_CDR::Octet code = 0; + if (cdr.read_octet (code)) + { + switch (code) + { + case MARSHAL_ANY: + result = TAO_Notify_AnyEvent::unmarshal (cdr); + break; + case MARSHAL_STRUCTURED: + result = TAO_Notify_StructuredEvent::unmarshal (cdr); + break; + default: + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Event::unmarshal: unknown event code %d\n"), + code)); + break; + } + } + return result; +} #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Auto_Basic_Ptr<TAO_Notify_Event>; -template class ACE_Refcounted_Auto_Ptr<const TAO_Notify_Event, TAO_SYNCH_MUTEX>; +template class TAO_Notify_Refcountable_Guard_T<TAO_Notify_Event>; template class ACE_Unbounded_Queue<TAO_Notify_Event_var>; template class ACE_Node<TAO_Notify_Event_var>; template class ACE_Unbounded_Queue_Iterator<TAO_Notify_Event_var>; @@ -52,7 +89,7 @@ template class ACE_Unbounded_Queue_Iterator<TAO_Notify_Event_var>; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate ACE_Auto_Basic_Ptr<TAO_Notify_Event> -#pragma instantiate ACE_Refcounted_Auto_Ptr<const TAO_Notify_Event, TAO_SYNCH_MUTEX> +#pragma instantiate TAO_Notify_Refcountable_Guard_T<TAO_Notify_Event>; #pragma instantiate ACE_Unbounded_Queue<TAO_Notify_Event_var> #pragma instantiate ACE_Node<TAO_Notify_Event_var> #pragma instantiate ACE_Unbounded_Queue_Iterator<TAO_Notify_Event_var> diff --git a/TAO/orbsvcs/orbsvcs/Notify/Event.h b/TAO/orbsvcs/orbsvcs/Notify/Event.h index 66a8c40bff3..3bc2296490f 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Event.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Event.h @@ -9,8 +9,8 @@ * */ -#ifndef TAO_Notify_EVENT_H -#define TAO_Notify_EVENT_H +#ifndef TAO_NOTIFY_EVENT_H +#define TAO_NOTIFY_EVENT_H #include /**/ "ace/pre.h" @@ -21,17 +21,56 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Copy_Disabled.h" -#include "ace/Refcounted_Auto_Ptr.h" + +#include "Refcountable.h" +#include "Refcountable_Guard_T.h" #include "orbsvcs/Event_ForwarderS.h" #include "orbsvcs/CosNotifyFilterC.h" #include "orbsvcs/CosNotificationC.h" #include "Property.h" +#include "Property_Boolean.h" #include "Property_T.h" class TAO_Notify_Consumer; class TAO_Notify_EventType; +class TAO_Notify_Event; + +typedef TAO_Notify_Refcountable_Guard_T<TAO_Notify_Event> TAO_Notify_Event_var_Base; + +/** + * @class TAO_Notify_Event_var + * + * @brief A Non-Copy version of the smart pointer that hides the constructors. + * + */ +class TAO_Notify_Event_var : public TAO_Notify_Event_var_Base +{ +public: + /// Default Constructor + TAO_Notify_Event_var (void); + +protected: + /// Constructor + TAO_Notify_Event_var (const TAO_Notify_Event* event); +}; + +/** + * @class TAO_Notify_Event + * + * @brief A smart pointer that allows construction from a TAO_Notify_Event + * + */ +class TAO_Notify_Event_Copy_var : public TAO_Notify_Event_var +{ +public: + /// Default Constructor + TAO_Notify_Event_Copy_var (void); + + /// Constructor + TAO_Notify_Event_Copy_var (const TAO_Notify_Event* event); +}; /** * @class TAO_Notify_Event @@ -39,17 +78,20 @@ class TAO_Notify_EventType; * @brief Base class abstraction for Events flowing through the EventChannel. * */ -class TAO_Notify_Serv_Export TAO_Notify_Event : private ACE_Copy_Disabled +class TAO_Notify_Serv_Export TAO_Notify_Event + : public TAO_Notify_Refcountable + , private ACE_Copy_Disabled { public: + // Codes to distinguish marshaled events in persistent storage + enum {MARSHAL_ANY=1,MARSHAL_STRUCTURED=2}; /// Constuctor TAO_Notify_Event (void); /// Destructor virtual ~TAO_Notify_Event (); - /// Copy the event. - virtual TAO_Notify_Event* copy (ACE_ENV_SINGLE_ARG_DECL) const = 0; + virtual void release (void); /// Translate Any to Structured static void translate (const CORBA::Any& any, CosNotification::StructuredEvent& notification); @@ -81,6 +123,15 @@ public: /// Push event to the Event_Forwarder interface virtual void push_no_filtering (Event_Forwarder::ProxyPushSupplier_ptr forwarder ACE_ENV_ARG_DECL) const = 0; + /// Return a pointer to a copy of this event on the heap + void queueable_copy (TAO_Notify_Event_var & ptr ACE_ENV_ARG_DECL) const; + + /// marshal this event into a CDR buffer (for persistence) + virtual void marshal (TAO_OutputCDR & cdr) const = 0; + + /// Unmarshal an event from a CDR. (for persistence) + static TAO_Notify_Event * unmarshal (TAO_InputCDR & cdr); + ///= Accessors /// Priority const TAO_Notify_Property_Short& priority (void) const; @@ -88,7 +139,14 @@ public: /// Timeout const TAO_Notify_Property_Time& timeout (void) const; + /// Reliable + const TAO_Notify_Property_Boolean& reliable(void) const; + protected: + + /// Return a pointer to a copy of this event on the heap + virtual TAO_Notify_Event * copy (ACE_ENV_SINGLE_ARG_DECL) const = 0; + /// = QoS properties /// Priority. @@ -96,49 +154,17 @@ protected: /// Timeout. TAO_Notify_Property_Time timeout_; -}; -typedef ACE_Refcounted_Auto_Ptr<const TAO_Notify_Event, TAO_SYNCH_MUTEX> TAO_Notify_Event_var_Base; + /// Reliability + TAO_Notify_Property_Boolean reliable_; -/** - * @class TAO_Notify_Event_var - * - * @brief A Non-Copy version of the ACE_Refcounted_Auto_Ptr that hides the constructors. - * - */ -class TAO_Notify_Event_var : public TAO_Notify_Event_var_Base -{ -public: - /// Default Constructor - TAO_Notify_Event_var (void); - -protected: - /// Constructor - TAO_Notify_Event_var (TAO_Notify_Event* event); -}; - -/** - * @class TAO_Notify_Event - * - * @brief A version of the ACE_Refcounted_Auto_Ptr that allows construction from a TAO_Notify_Event - * - */ -class TAO_Notify_Event_Copy_var : public TAO_Notify_Event_var -{ -public: - /// Default Constructor - TAO_Notify_Event_Copy_var (void); - - /// Constructor - TAO_Notify_Event_Copy_var (TAO_Notify_Event* event); + TAO_Notify_Event * event_on_heap_; }; -typedef ACE_Unbounded_Queue<TAO_Notify_Event_var> TAO_Notify_Event_Collection; - #if defined (__ACE_INLINE__) #include "Event.inl" #endif /* __ACE_INLINE__ */ #include /**/ "ace/post.h" -#endif /* TAO_Notify_EVENT_H */ +#endif /* TAO_NOTIFY_EVENT_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Event.inl b/TAO/orbsvcs/orbsvcs/Notify/Event.inl index 02006440911..b51106e8276 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Event.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Event.inl @@ -12,6 +12,12 @@ TAO_Notify_Event::timeout (void) const return this->timeout_; } +ACE_INLINE const TAO_Notify_Property_Boolean& +TAO_Notify_Event::reliable (void) const +{ + return this->reliable_; +} + /**********************************************************/ ACE_INLINE @@ -21,8 +27,8 @@ TAO_Notify_Event_var::TAO_Notify_Event_var (void) } ACE_INLINE -TAO_Notify_Event_var::TAO_Notify_Event_var (TAO_Notify_Event* event) - : TAO_Notify_Event_var_Base (event) +TAO_Notify_Event_var::TAO_Notify_Event_var (const TAO_Notify_Event* event) + : TAO_Notify_Event_var_Base (const_cast <TAO_Notify_Event *>(event)) { } @@ -35,7 +41,23 @@ TAO_Notify_Event_Copy_var::TAO_Notify_Event_Copy_var (void) } ACE_INLINE -TAO_Notify_Event_Copy_var::TAO_Notify_Event_Copy_var (TAO_Notify_Event* event) +TAO_Notify_Event_Copy_var::TAO_Notify_Event_Copy_var (const TAO_Notify_Event* event) : TAO_Notify_Event_var (event) { } + +ACE_INLINE +void //const TAO_Notify_Event * +TAO_Notify_Event::queueable_copy (TAO_Notify_Event_var & ptr ACE_ENV_ARG_DECL) const +{ + if (this->event_on_heap_ == 0) + { + TAO_Notify_Event * copied = + this->copy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + const_cast <TAO_Notify_Event *> (this)->event_on_heap_ = copied; + copied->event_on_heap_ = copied; + } + ptr = TAO_Notify_Event_Copy_var (this->event_on_heap_); +} + diff --git a/TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp b/TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp index 3985ef9d899..f4b63f44419 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp @@ -16,6 +16,15 @@ #include "Builder.h" #include "Find_Worker_T.h" #include "Seq_Worker_T.h" +#include "Topology_Saver.h" +#include "Save_Persist_Worker_T.h" +#include "Reconnect_Worker_T.h" + +#include "tao/debug.h" +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL ACE_RCSID(Notify, TAO_Notify_EventChannel, "$Id$") @@ -54,7 +63,7 @@ TAO_Notify_EventChannel::init (TAO_Notify_EventChannelFactory* ecf , const CosNotification::AdminProperties & initial_admin ACE_ENV_ARG_DECL) { - this->TAO_Notify_Object::init (ecf); + this->TAO_Notify::Topology_Object::init (ecf); this->ecf_ = ecf; @@ -109,16 +118,69 @@ TAO_Notify_EventChannel::init (TAO_Notify_EventChannelFactory* ecf this->set_admin (initial_admin ACE_ENV_ARG_PARAMETER); ACE_CHECK; - CosNotifyChannelAdmin::AdminID id; + // Note originally default admins were allocated here, bt this caused problems + // attempting to save the topology changes before the Event Channel was completely + // constructed and linked to the ECF. + // Lazy evaluation also avoids creating unneded admins. +} + + +void +TAO_Notify_EventChannel::init (TAO_Notify_EventChannelFactory* ecf + ACE_ENV_ARG_DECL) +{ + this->TAO_Notify::Topology_Object::init (ecf); + + this->ecf_ = ecf; + + this->ecf_->_incr_refcnt (); + + // Init ca_container_ + ACE_NEW_THROW_EX (this->ca_container_, + TAO_Notify_ConsumerAdmin_Container (), + CORBA::INTERNAL ()); + ACE_CHECK; + + this->ca_container_->init (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Init ca_container_ + ACE_NEW_THROW_EX (this->sa_container_, + TAO_Notify_SupplierAdmin_Container (), + CORBA::INTERNAL ()); + ACE_CHECK; + + this->sa_container_->init (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + TAO_Notify_AdminProperties* admin_properties = 0; + + // Set the admin properties. + ACE_NEW_THROW_EX (admin_properties, + TAO_Notify_AdminProperties (), + CORBA::NO_MEMORY ()); + ACE_CHECK; + + this->admin_properties_ = admin_properties; + + // create the event manager. @@ use factory + ACE_NEW_THROW_EX (this->event_manager_, + TAO_Notify_Event_Manager (), + CORBA::INTERNAL ()); + ACE_CHECK; + + this->event_manager_->init (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + const CosNotification::QoSProperties &default_ec_qos = + TAO_Notify_PROPERTIES::instance ()->default_event_channel_qos_properties (); - // Set the default ConsumerAdmin. - this->default_consumer_admin_ = this->new_for_consumers (CosNotifyChannelAdmin::OR_OP, id ACE_ENV_ARG_PARAMETER); + this->set_qos (default_ec_qos ACE_ENV_ARG_PARAMETER); ACE_CHECK; - // Set the default SupplierAdmin. - this->default_supplier_admin_ = this->new_for_suppliers (CosNotifyChannelAdmin::OR_OP, id ACE_ENV_ARG_PARAMETER); } + void TAO_Notify_EventChannel::_add_ref (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) { @@ -214,20 +276,63 @@ TAO_Notify_EventChannel::MyFactory (ACE_ENV_SINGLE_ARG_DECL) } CosNotifyChannelAdmin::ConsumerAdmin_ptr -TAO_Notify_EventChannel::default_consumer_admin (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +TAO_Notify_EventChannel::default_consumer_admin (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { + if (CORBA::is_nil (default_consumer_admin_.in ())) + { + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->default_admin_mutex_, CosNotifyChannelAdmin::ConsumerAdmin::_nil()); + if (CORBA::is_nil (default_consumer_admin_.in ())) + { + CosNotifyChannelAdmin::AdminID id; + this->default_consumer_admin_ = this->new_for_consumers (CosNotifyChannelAdmin::OR_OP, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CosNotifyChannelAdmin::ConsumerAdmin::_nil()); + // Wish there was a better way to do this! + PortableServer::ServantBase * admin_servant = + this->poa_->reference_to_servant ( + this->default_consumer_admin_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CosNotifyChannelAdmin::ConsumerAdmin::_nil()); + TAO_Notify_Admin * pAdmin = dynamic_cast <TAO_Notify_Admin *> (admin_servant); + ACE_ASSERT (pAdmin != 0); // if this assert triggers, we have mixed implementations? + if (pAdmin != 0) + { + pAdmin->set_default (true); + } + } + } return CosNotifyChannelAdmin::ConsumerAdmin::_duplicate (this->default_consumer_admin_.in ()); } CosNotifyChannelAdmin::SupplierAdmin_ptr -TAO_Notify_EventChannel::default_supplier_admin (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +TAO_Notify_EventChannel::default_supplier_admin (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { + if (CORBA::is_nil (default_supplier_admin_.in ())) + { + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->default_admin_mutex_, CosNotifyChannelAdmin::SupplierAdmin::_nil()); + if (CORBA::is_nil (default_supplier_admin_.in ())) + { + CosNotifyChannelAdmin::AdminID id; + this->default_supplier_admin_ = this->new_for_suppliers (CosNotifyChannelAdmin::OR_OP, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CosNotifyChannelAdmin::SupplierAdmin::_nil()); + PortableServer::ServantBase * admin_servant = + this->poa_->poa()->reference_to_servant ( + this->default_supplier_admin_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + TAO_Notify_Admin * pAdmin = dynamic_cast <TAO_Notify_Admin *> (admin_servant); + ACE_ASSERT (pAdmin != 0); // if this assert triggers, we have mixed implementations? + if (pAdmin != 0) + { + pAdmin->set_default (true); + } + } + } return CosNotifyChannelAdmin::SupplierAdmin::_duplicate (this->default_supplier_admin_.in ()); } @@ -248,7 +353,12 @@ TAO_Notify_EventChannel::new_for_consumers (CosNotifyChannelAdmin::InterFilterGr )) { - return TAO_Notify_PROPERTIES::instance()->builder()->build_consumer_admin (this, op, id ACE_ENV_ARG_PARAMETER); + ::CosNotifyChannelAdmin::ConsumerAdmin_var ca = + TAO_Notify_PROPERTIES::instance()->builder()->build_consumer_admin (this, op, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ca._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (ca._retn ()); + return ca._retn (); } ::CosNotifyChannelAdmin::SupplierAdmin_ptr @@ -260,7 +370,12 @@ TAO_Notify_EventChannel::new_for_suppliers (CosNotifyChannelAdmin::InterFilterGr CORBA::SystemException )) { - return TAO_Notify_PROPERTIES::instance()->builder()->build_supplier_admin (this, op, id ACE_ENV_ARG_PARAMETER); + ::CosNotifyChannelAdmin::SupplierAdmin_var sa = + TAO_Notify_PROPERTIES::instance()->builder()->build_supplier_admin (this, op, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (sa._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (sa._retn ()); + return sa._retn (); } CosNotifyChannelAdmin::ConsumerAdmin_ptr @@ -337,21 +452,21 @@ TAO_Notify_EventChannel::get_admin (ACE_ENV_SINGLE_ARG_DECL) } CosEventChannelAdmin::ConsumerAdmin_ptr -TAO_Notify_EventChannel::for_consumers (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +TAO_Notify_EventChannel::for_consumers (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { - return CosEventChannelAdmin::ConsumerAdmin::_duplicate (this->default_consumer_admin_.in ()); + return this->default_consumer_admin(ACE_ENV_SINGLE_ARG_PARAMETER); } CosEventChannelAdmin::SupplierAdmin_ptr -TAO_Notify_EventChannel::for_suppliers (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +TAO_Notify_EventChannel::for_suppliers (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { - return CosEventChannelAdmin::SupplierAdmin::_duplicate (this->default_supplier_admin_.in ()); + return this->default_supplier_admin (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -367,6 +482,196 @@ TAO_Notify_EventChannel::validate_qos (const CosNotification::QoSProperties & /* ACE_THROW (CORBA::NO_IMPLEMENT ()); } +void +TAO_Notify_EventChannel::save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL) +{ + bool changed = this->self_changed_; + this->self_changed_ = false; + this->children_changed_ = false; + + if (is_persistent ()) + { + TAO_Notify::NVPList attrs; + this->save_attrs(attrs); + + bool want_all_children = saver.begin_object( + this->id(), "channel", attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + TAO_Notify::Save_Persist_Worker<TAO_Notify_ConsumerAdmin> ca_wrk(saver, want_all_children); + + ACE_ASSERT(this->ca_container_ != 0); + this->ca_container_->collection()->for_each(&ca_wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + TAO_Notify::Save_Persist_Worker<TAO_Notify_SupplierAdmin> sa_wrk(saver, want_all_children); + ACE_ASSERT(this->sa_container_ != 0); + this->sa_container_->collection()->for_each(&sa_wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + saver.end_object(this->id(), "channel" ACE_ENV_ARG_PARAMETER); + } +} + +namespace { + template<class T> + void add_attr(TAO_Notify::NVPList& attrs, const T& prop) { + if (prop.is_valid()) + { + attrs.push_back(TAO_Notify::NVP (prop)); + } + } +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template void add_attr<TAO_Notify_Property_Boolean>(TAO_Notify::NVPList&, + const TAO_Notify_Property_Boolean&); +template void add_attr<TAO_Notify_Property_T<int> >(TAO_Notify::NVPList&, + const TAO_Notify_Property_T<int>&); +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate void add_attr<TAO_Notify_Property_Boolean>(\ + TAO_Notify::NVPList&, const TAO_Notify_Property_Boolean&) +#pragma instantiate void add_attr<TAO_Notify_Property_T<int> >(\ + TAO_Notify::NVPList&, const TAO_Notify_Property_T<int>&) +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ +} + +void +TAO_Notify_EventChannel::save_attrs(TAO_Notify::NVPList& attrs) +{ + TAO_Notify_Object::save_attrs(attrs); + add_attr(attrs, this->admin_properties_->max_global_queue_length()); + add_attr(attrs, this->admin_properties_->max_consumers()); + add_attr(attrs, this->admin_properties_->max_suppliers()); + add_attr(attrs, this->admin_properties_->reject_new_events()); +} + +void +TAO_Notify_EventChannel::load_attrs(const TAO_Notify::NVPList& attrs) +{ + TAO_Notify_Object::load_attrs(attrs); + attrs.load(this->admin_properties_->max_global_queue_length()); + attrs.load(this->admin_properties_->max_consumers()); + attrs.load(this->admin_properties_->max_suppliers()); + attrs.load(this->admin_properties_->reject_new_events()); + this->admin_properties_->init(); +} + +TAO_Notify::Topology_Object * +TAO_Notify_EventChannel::load_child (const ACE_CString &type, + CORBA::Long id, + const TAO_Notify::NVPList& attrs + ACE_ENV_ARG_DECL) +{ + TAO_Notify::Topology_Object* result = this; + if (type == "consumer_admin") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) EventChannel reload consumer_admin %d\n") + , ACE_static_cast (int, id) + )); + + // call special builder method to reload + TAO_Notify_Builder* bld = TAO_Notify_PROPERTIES::instance()->builder(); + TAO_Notify_ConsumerAdmin * ca = bld->build_consumer_admin ( + this, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + ca->load_attrs (attrs); + if (ca->is_default ()) + { + CORBA::Object_var caob = this->poa_->servant_to_reference (ca ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + this->default_consumer_admin_ = + CosNotifyChannelAdmin::ConsumerAdmin::_narrow ( + caob.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + result = ca; + } + else if (type == "supplier_admin") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) EventChannel reload supplier_admin %d\n") + , ACE_static_cast (int, id) + )); + TAO_Notify_Builder* bld = TAO_Notify_PROPERTIES::instance()->builder(); + + TAO_Notify_SupplierAdmin * sa = bld->build_supplier_admin ( + this, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + sa->load_attrs (attrs); + if (sa->is_default ()) + { + CORBA::Object_var saob = this->poa_->servant_to_reference (sa ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + this->default_supplier_admin_ = + CosNotifyChannelAdmin::SupplierAdmin::_narrow ( + saob.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + result = sa; + } + return result; +} +TAO_Notify_ProxyConsumer * +TAO_Notify_EventChannel::find_proxy_consumer (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL) +{ + TAO_Notify_ProxyConsumer * result = 0; + size_t path_size = id_path.size (); + if (position < path_size) + { + TAO_Notify_SupplierAdmin_Find_Worker find_worker; + TAO_Notify_SupplierAdmin * admin = find_worker.find (id_path[position], *this->sa_container_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + ++position; + if (admin != 0) + { + result = admin->find_proxy_consumer (id_path, position + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + } + return result; +} + +TAO_Notify_ProxySupplier * +TAO_Notify_EventChannel::find_proxy_supplier (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL) +{ + TAO_Notify_ProxySupplier * result = 0; + size_t path_size = id_path.size (); + if (position < path_size) + { + TAO_Notify_ConsumerAdmin_Find_Worker find_worker; + TAO_Notify_ConsumerAdmin * admin = find_worker.find (id_path[position], *this->ca_container_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + ++position; + if (admin != 0) + { + result = admin->find_proxy_supplier (id_path, position + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + } + return result; +} + + +void +TAO_Notify_EventChannel::reconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_Notify::Reconnect_Worker<TAO_Notify_ConsumerAdmin> ca_wrk; + ACE_ASSERT(this->ca_container_ != 0); + this->ca_container_->collection()->for_each(&ca_wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + TAO_Notify::Reconnect_Worker<TAO_Notify_SupplierAdmin> sa_wrk; + ACE_ASSERT(this->sa_container_ != 0); + this->sa_container_->collection()->for_each(&sa_wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class TAO_Notify_Find_Worker_T<TAO_Notify_ConsumerAdmin @@ -387,6 +692,11 @@ template class TAO_Notify_Container_T <TAO_Notify_SupplierAdmin>; template class TAO_ESF_Shutdown_Proxy<TAO_Notify_ConsumerAdmin>; template class TAO_ESF_Shutdown_Proxy<TAO_Notify_SupplierAdmin>; +template class TAO_Notify::Save_Persist_Worker<TAO_Notify_ConsumerAdmin>; +template class TAO_Notify::Save_Persist_Worker<TAO_Notify_SupplierAdmin>; +template class TAO_Notify::Reconnect_Worker<TAO_Notify_ConsumerAdmin>; +template class TAO_Notify::Reconnect_Worker<TAO_Notify_SupplierAdmin>; + #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate TAO_Notify_Find_Worker_T<TAO_Notify_ConsumerAdmin @@ -407,4 +717,9 @@ template class TAO_ESF_Shutdown_Proxy<TAO_Notify_SupplierAdmin>; #pragma instantiate TAO_ESF_Shutdown_Proxy<TAO_Notify_ConsumerAdmin> #pragma instantiate TAO_ESF_Shutdown_Proxy<TAO_Notify_SupplierAdmin> +#pragma instantiate Save_Persist_Worker<TAO_Notify_ConsumerAdmin> +#pragma instantiate Save_Persist_Worker<TAO_Notify_SupplierAdmin> +#pragma instantiate TAO_Notify::Reconnect_Worker<TAO_Notify_ConsumerAdmin> +#pragma instantiate TAO_Notify::Reconnect_Worker<TAO_Notify_SupplierAdmin> + #endif /*ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/EventChannel.h b/TAO/orbsvcs/orbsvcs/Notify/EventChannel.h index e334a2f03e5..c52843ac570 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/EventChannel.h +++ b/TAO/orbsvcs/orbsvcs/Notify/EventChannel.h @@ -21,16 +21,18 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "orbsvcs/CosNotifyChannelAdminS.h" - +#include "Topology_Object.h" #include "Object.h" class TAO_Notify_ConsumerAdmin; class TAO_Notify_SupplierAdmin; class TAO_Notify_EventChannelFactory; +class TAO_Notify_ProxyConsumer; +class TAO_Notify_ProxySupplier; template <class TYPE> class TAO_Notify_Container_T; #if defined(_MSC_VER) -#if (_MSC_VER >= 1200) + #if (_MSC_VER >= 1200) #pragma warning(push) #endif /* _MSC_VER >= 1200 */ #pragma warning(disable:4250) @@ -42,9 +44,9 @@ template <class TYPE> class TAO_Notify_Container_T; * @brief Implementation of CosNotifyChannelAdmin::EventChannel * */ -class TAO_Notify_Serv_Export TAO_Notify_EventChannel - : public POA_CosNotifyChannelAdmin::EventChannel, - public virtual TAO_Notify_Object +class TAO_Notify_Serv_Export TAO_Notify_EventChannel + : public POA_CosNotifyChannelAdmin::EventChannel, + public TAO_Notify::Topology_Parent { friend class TAO_Notify_Builder; @@ -64,6 +66,10 @@ public: , const CosNotification::AdminProperties & initial_admin ACE_ENV_ARG_DECL); + /// Init (for reload) + void init (TAO_Notify_EventChannelFactory* ecf + ACE_ENV_ARG_DECL); + /// Remove ConsumerAdmin from its container. void remove (TAO_Notify_ConsumerAdmin* consumer_admin ACE_ENV_ARG_DECL); @@ -74,11 +80,30 @@ public: virtual void _add_ref (ACE_ENV_SINGLE_ARG_DECL); virtual void _remove_ref (ACE_ENV_SINGLE_ARG_DECL); + // TAO_Notify::Topology_Parent + + virtual void save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL); + virtual TAO_Notify::Topology_Object* load_child (const ACE_CString &type, + CORBA::Long id, + const TAO_Notify::NVPList& attrs + ACE_ENV_ARG_DECL); + virtual void reconnect (ACE_ENV_SINGLE_ARG_DECL); + + virtual TAO_Notify_Object::ID get_id () const {return id();} + + TAO_Notify_ProxyConsumer * find_proxy_consumer (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL); + TAO_Notify_ProxySupplier * find_proxy_supplier (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL); + /// Release virtual void release (void); /// Shutdown virtual int shutdown (ACE_ENV_SINGLE_ARG_DECL); + virtual void load_attrs(const TAO_Notify::NVPList& attrs); + + +protected: + virtual void save_attrs(TAO_Notify::NVPList& attrs); protected: typedef TAO_Notify_Container_T <TAO_Notify_ConsumerAdmin> TAO_Notify_ConsumerAdmin_Container; @@ -94,6 +119,8 @@ protected: /// SupplierAdmin Container. TAO_Notify_SupplierAdmin_Container *sa_container_; + TAO_SYNCH_MUTEX default_admin_mutex_; + // Default Consumer Admin CosNotifyChannelAdmin::ConsumerAdmin_var default_consumer_admin_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/EventChannelFactory.cpp b/TAO/orbsvcs/orbsvcs/Notify/EventChannelFactory.cpp index debe138d960..14f84bb280e 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/EventChannelFactory.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/EventChannelFactory.cpp @@ -12,11 +12,24 @@ ACE_RCSID(Notify, TAO_Notify_EventChannelFactory, "$Id$") #include "Properties.h" #include "Factory.h" #include "Builder.h" +#include "Topology_Saver.h" +#include "Topology_Loader.h" +#include "Save_Persist_Worker_T.h" +#include "Reconnect_Worker_T.h" +#include "Event_Persistence_Strategy.h" +#include "Routing_Slip_Persistence_Manager.h" + #include "EventChannel.h" #include "Container_T.h" #include "Find_Worker_T.h" #include "Seq_Worker_T.h" +#include "tao/debug.h" +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + typedef TAO_Notify_Find_Worker_T<TAO_Notify_EventChannel , CosNotifyChannelAdmin::EventChannel , CosNotifyChannelAdmin::EventChannel_ptr @@ -26,7 +39,12 @@ TAO_Notify_EventChannel_Find_Worker; typedef TAO_Notify_Seq_Worker_T<TAO_Notify_EventChannel> TAO_Notify_EventChannel_Seq_Worker; TAO_Notify_EventChannelFactory::TAO_Notify_EventChannelFactory (void) - :ec_container_ (0) + : ec_container_ (0) + , topology_save_seq_ (0) + , topology_factory_(0) + , reconnect_registry_(*this) + , loading_topology_ (false) + { } @@ -95,6 +113,17 @@ TAO_Notify_EventChannelFactory::init (PortableServer::POA_ptr poa ACE_ENV_ARG_DE // Make the Proxys acivate in this same POA. this->proxy_poa_ = this->object_poa_; + + // Note topology factory is configured separately from the "builder" mediated + // objects since it is independant of the "style" of Notification Service. + this->topology_factory_ = + ACE_Dynamic_Service <TAO_Notify::Topology_Factory>::instance ("Topology_Factory"); + + this->load_topology (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->load_event_persistence (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; } void @@ -121,6 +150,7 @@ TAO_Notify_EventChannelFactory::remove (TAO_Notify_EventChannel* event_channel A { this->ec_container_->remove (event_channel ACE_ENV_ARG_PARAMETER); ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } int @@ -152,11 +182,16 @@ TAO_Notify_EventChannelFactory::get_default_filter_factory (ACE_ENV_SINGLE_ARG_D , CosNotification::UnsupportedAdmin )) { - return TAO_Notify_PROPERTIES::instance()->builder()->build_event_channel (this + CosNotifyChannelAdmin::EventChannel_var ec = + TAO_Notify_PROPERTIES::instance()->builder()->build_event_channel (this , initial_qos , initial_admin , id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ec._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (ec._retn ()); + return ec._retn (); } CosNotifyChannelAdmin::ChannelIDSeq* @@ -182,6 +217,337 @@ TAO_Notify_EventChannelFactory::get_event_channel (CosNotifyChannelAdmin::Channe return find_worker.resolve (id, *this->ec_container_ ACE_ENV_ARG_PARAMETER); } +void +TAO_Notify_EventChannelFactory::set_topology_factory(TAO_Notify::Topology_Factory* f) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Debug Topology_Factory installed in EventChannelFactory.\n") + )); + // If the above meessage appears when you don't expect it + // use svc.conf to install the topology factory rather + // than calling this method. + this->topology_factory_ = f; +} + +void +TAO_Notify_EventChannelFactory::load_topology (ACE_ENV_SINGLE_ARG_DECL) +{ + this->loading_topology_ = true; + if (this->topology_factory_ != 0) + { + auto_ptr<TAO_Notify::Topology_Loader> tl(this->topology_factory_->create_loader()); + if (tl.get () != 0) + { + tl->load (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + } + else + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Topology persistence disabled.\n"))); + } + this->loading_topology_ = false; +} +bool +TAO_Notify_EventChannelFactory::is_persistent () const +{ + return true; +} + +void +TAO_Notify_EventChannelFactory::save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL) +{ + bool changed = this->self_changed_; + this->self_changed_ = false; + this->children_changed_ = false; + + TAO_Notify::NVPList attrs; // ECF has no attributes + + bool want_all_children = + saver.begin_object(0, "channel_factory", attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // for each deleted child + // delete_child // if the child has persistence. + + TAO_Notify::Save_Persist_Worker<TAO_Notify_EventChannel> wrk(saver, want_all_children); + + ACE_ASSERT(this->ec_container_ != 0); + this->ec_container_->collection()->for_each(&wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (want_all_children || this->reconnect_registry_.is_changed ()) + { + this->reconnect_registry_.save_persistent(saver ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + saver.end_object(0, "channel_factory" ACE_ENV_ARG_PARAMETER); +} + +void +TAO_Notify_EventChannelFactory::load_event_persistence (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_Notify::Event_Persistence_Strategy * strategy = + ACE_Dynamic_Service <TAO_Notify::Event_Persistence_Strategy>::instance ("Event_Persistence"); + if (strategy != 0) + { + if (this->topology_factory_ != 0) + { + TAO_Notify::Event_Persistence_Factory * factory = strategy->get_factory (); + if (factory != 0) + { + for ( + TAO_Notify::Routing_Slip_Persistence_Manager * rspm = factory->first_reload_manager(); + rspm != 0; + rspm = rspm->load_next ()) + { + TAO_Notify::Routing_Slip_Ptr routing_slip = TAO_Notify::Routing_Slip::create (*this, rspm); + if (!routing_slip.null ()) + { + this->routing_slip_restart_set_.insert (routing_slip); + } + else + { + //@@todo: tell the rspm it's an orphan, but we can't during reload + // we need collect these and come back later to remove them + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Reload persistent event failed.\n") + )); + } + } + } + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Notify Service: Configuration error. Event Persistence requires Topology Persistence.\n") + )); + ACE_THROW (CORBA::PERSIST_STORE()); + ACE_CHECK; + } + } +} + +bool +TAO_Notify_EventChannelFactory::change_to_parent (ACE_ENV_SINGLE_ARG_DECL) +{ + bool saving = false; + if (! this->loading_topology_) + { + // A null pointer means that saving of topology is disabled. + if (this->topology_factory_ != 0) + { + saving = true; + // seq is used to check save-in-progress + // if it changes while we're waiting for the lock + // then our change may have already been saved, so + // just return. Caller will signal change again if necessary. + short seq = this->topology_save_seq_; + ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->topology_save_lock_, CORBA::INTERNAL ()); + ACE_CHECK_RETURN(false); + if (seq == this->topology_save_seq_) + { + auto_ptr<TAO_Notify::Topology_Saver> saver(this->topology_factory_->create_saver()); + if (saver.get() != 0) + { + this->save_persistent(*saver ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(false); + saver->close (ACE_ENV_SINGLE_ARG_PARAMETER); + } + this->topology_save_seq_ += 1; + } + } + } + return saving; +} + +TAO_Notify::Topology_Object* +TAO_Notify_EventChannelFactory::load_child (const ACE_CString& type, + CORBA::Long id, + const TAO_Notify:: + NVPList& attrs + ACE_ENV_ARG_DECL) +{ + // ignore anything but our valid children (ie channel) + TAO_Notify::Topology_Object * result = this; + if (type == "channel") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) EventChannelFactory reload channel %d\n") + , ACE_static_cast (int, id) + )); + + TAO_Notify_Builder* bld = TAO_Notify_PROPERTIES::instance()->builder(); + TAO_Notify_EventChannel * ec = bld->build_event_channel( + this , + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + + ec->load_attrs (attrs); + + result = ec; + } + else if (type == TAO_Notify::REGISTRY_TYPE) + { + result = & this->reconnect_registry_; + } + return result; +} + +void +TAO_Notify_EventChannelFactory::reconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + // Reconnect all children first + TAO_Notify::Reconnect_Worker<TAO_Notify_EventChannel> wrk; + + this->ec_container_->collection()->for_each(&wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Then send reconnection announcement to registered clients + ACE_ASSERT (!CORBA::is_nil (this->channel_factory_.in ())); + this->reconnect_registry_.send_reconnect (this->channel_factory_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // reactivate events in-progress + Routing_Slip_Set::CONST_ITERATOR iter (this->routing_slip_restart_set_); + TAO_Notify::Routing_Slip_Ptr * routing_slip; + for (iter.first(); iter.next(routing_slip); iter.advance()) + { + (*routing_slip)->reconnect(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } + this->routing_slip_restart_set_.reset (); +} + +NotifyExt::ReconnectionRegistry::ReconnectionID +TAO_Notify_EventChannelFactory::register_callback ( + NotifyExt::ReconnectionCallback_ptr reconnection + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return this->reconnect_registry_.register_callback ( + reconnection + ACE_ENV_ARG_PARAMETER); +} + +void +TAO_Notify_EventChannelFactory::unregister_callback ( + NotifyExt::ReconnectionRegistry::ReconnectionID id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->reconnect_registry_.unregister_callback ( + id + ACE_ENV_ARG_PARAMETER); +} + +CORBA::Boolean +TAO_Notify_EventChannelFactory::is_alive (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::Boolean (1); +} + +void +TAO_Notify_EventChannelFactory::save_topology (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +TAO_Notify_ProxyConsumer * +TAO_Notify_EventChannelFactory::find_proxy_consumer (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL) +{ + TAO_Notify_ProxyConsumer * result = 0; + size_t path_size = id_path.size (); + + // EventChannelFactory only: The first id is proably for the ECF itself + // if so, silently consume it. + if (position < path_size && id_path[position] == this->id_) + { + ++position; + } + if (position < path_size) + { + TAO_Notify_EventChannel_Find_Worker find_worker; + + TAO_Notify_EventChannel * ec = find_worker.find (id_path[position], *this->ec_container_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + ++position; + if (ec != 0) + { + result = ec->find_proxy_consumer (id_path, position + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + } + return result; +} + +TAO_Notify_ProxySupplier * +TAO_Notify_EventChannelFactory::find_proxy_supplier (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL) +{ + TAO_Notify_ProxySupplier * result = 0; + size_t path_size = id_path.size (); + + // EventChannelFactory only: The first id is proably for the ECF itself + // if so, silently consume it. + if (position < path_size && id_path[position] == this->id_) + { + ++position; + } + if (position < path_size) + { + TAO_Notify_EventChannel_Find_Worker find_worker; + TAO_Notify_EventChannel * ec = find_worker.find (id_path[position], *this->ec_container_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + ++position; + if (ec != 0) + { + result = ec->find_proxy_supplier (id_path, position + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + } + return result; +} + +CosNotifyChannelAdmin::EventChannelFactory_ptr +TAO_Notify_EventChannelFactory::activate_self (ACE_ENV_SINGLE_ARG_DECL) +{ + CORBA::Object_var obj = this->activate (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CosNotifyChannelAdmin::EventChannelFactory::_nil ()); + this->channel_factory_ + = CosNotifyChannelAdmin::EventChannelFactory::_narrow (obj.in() ACE_ENV_ARG_PARAMETER); + CosNotifyChannelAdmin::EventChannelFactory::_narrow (obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_NEW_ENV + { + if (DEBUG_LEVEL > 9) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) TAO_Notify_EventChannelFactory::activate_self") )); + } + this->reconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // ignore for now + } + ACE_ENDTRY; + return this->channel_factory_._retn(); +} + + +TAO_Notify_Object::ID +TAO_Notify_EventChannelFactory::get_id () const +{ + return id(); +} + + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class TAO_Notify_Find_Worker_T<TAO_Notify_EventChannel diff --git a/TAO/orbsvcs/orbsvcs/Notify/EventChannelFactory.h b/TAO/orbsvcs/orbsvcs/Notify/EventChannelFactory.h index c93fffd92a2..41af5f203bc 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/EventChannelFactory.h +++ b/TAO/orbsvcs/orbsvcs/Notify/EventChannelFactory.h @@ -22,8 +22,10 @@ #include "orbsvcs/CosNotifyChannelAdminS.h" #include "orbsvcs/NotifyExtS.h" - -#include "Object.h" +#include "Topology_Object.h" +#include "Topology_Factory.h" +#include "Reconnection_Registry.h" +#include "Routing_Slip.h" class TAO_Notify_EventChannel; template <class TYPE> class TAO_Notify_Container_T; @@ -41,11 +43,13 @@ template <class TYPE> class TAO_Notify_Container_T; * @brief Implementation of CosNotifyChannelAdmin::EventChannelFactory * */ -class TAO_Notify_Serv_Export TAO_Notify_EventChannelFactory - : public virtual POA_NotifyExt::EventChannelFactory, - public virtual TAO_Notify_Object +class TAO_Notify_Serv_Export TAO_Notify_EventChannelFactory + : public virtual POA_NotifyExt::EventChannelFactory + , public TAO_Notify::Topology_Parent + { friend class TAO_Notify_Builder; + typedef ACE_Unbounded_Set <TAO_Notify::Routing_Slip_Ptr> Routing_Slip_Set; public: /// Constuctor @@ -72,11 +76,49 @@ public: ACE_ENV_SINGLE_ARG_DECL ); - /// shutdown - virtual int shutdown (ACE_ENV_SINGLE_ARG_DECL); + + ////////////////////////// + // The following methods are for + // unit testing and debugging + + /// Use the registered Topology_Factory to create a loader, and + /// load the topology. If no Topology_Factory is registered + /// then nothing will be loaded. + void load_topology (ACE_ENV_SINGLE_ARG_DECL); + + /// Use the passed in saver factory to generate topology saver objects. + /// Does not take ownership. + void set_topology_factory(TAO_Notify::Topology_Factory* sf); + + //-- Topology_Parent + + virtual bool is_persistent () const; + + virtual void save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL); + virtual bool change_to_parent (ACE_ENV_SINGLE_ARG_DECL); + virtual TAO_Notify::Topology_Object* load_child (const ACE_CString &type, + CORBA::Long id, + const TAO_Notify::NVPList& attrs + ACE_ENV_ARG_DECL); + CosNotifyChannelAdmin::EventChannelFactory_ptr activate_self (ACE_ENV_SINGLE_ARG_DECL); + virtual void reconnect (ACE_ENV_SINGLE_ARG_DECL); + + /// handle change notifications + bool handle_change (ACE_ENV_SINGLE_ARG_DECL); + + void load_event_persistence (ACE_ENV_SINGLE_ARG_DECL); + + virtual void save_topology (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + TAO_Notify_ProxyConsumer * find_proxy_consumer (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL); + TAO_Notify_ProxySupplier * find_proxy_supplier (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL); + TAO_Notify_Object * follow_id_path (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL); + virtual TAO_Notify_Object::ID get_id () const; + protected: - typedef TAO_Notify_Container_T<TAO_Notify_EventChannel> + typedef TAO_Notify_Container_T<TAO_Notify_EventChannel> TAO_Notify_EventChannel_Container; /// = Data Members @@ -86,21 +128,38 @@ public: /// The default filter factory. CosNotifyFilter::FilterFactory_var default_filter_factory_; - /// = NotifyExt method + /// = NotifyExt methods virtual void destroy (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )); + /// shutdown + virtual int shutdown (ACE_ENV_SINGLE_ARG_DECL); + + virtual + NotifyExt::ReconnectionRegistry::ReconnectionID register_callback ( + NotifyExt::ReconnectionCallback_ptr reconnection + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void unregister_callback ( + NotifyExt::ReconnectionRegistry::ReconnectionID id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + /// = CosNotifyChannelAdmin Methods virtual ::CosNotifyChannelAdmin::EventChannel_ptr create_channel ( const CosNotification::QoSProperties & initial_qos, const CosNotification::AdminProperties & initial_admin, - CosNotifyChannelAdmin::ChannelID_out id + CosNotifyChannelAdmin::ChannelID_out id ACE_ENV_ARG_DECL ) - ACE_THROW_SPEC ((CORBA::SystemException, + ACE_THROW_SPEC ((CORBA::SystemException, CosNotification::UnsupportedQoS, CosNotification::UnsupportedAdmin)); @@ -115,6 +174,20 @@ public: ) ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyChannelAdmin::ChannelNotFound)); + +private: + TAO_SYNCH_MUTEX topology_save_lock_; + + CosNotifyChannelAdmin::EventChannelFactory_var channel_factory_; + + /// change-in-progress detector to avoid duplicates + short topology_save_seq_; + TAO_Notify::Topology_Factory* topology_factory_; + TAO_Notify::Reconnection_Registry reconnect_registry_; + bool loading_topology_; + + Routing_Slip_Set routing_slip_restart_set_; + }; #if defined(_MSC_VER) && (_MSC_VER >= 1200) diff --git a/TAO/orbsvcs/orbsvcs/Notify/EventType.cpp b/TAO/orbsvcs/orbsvcs/Notify/EventType.cpp index bcfae54e616..1b2e0a3a1ef 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/EventType.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/EventType.cpp @@ -10,6 +10,8 @@ #include "EventType.inl" #endif /* __ACE_INLINE__ */ +#include "Topology_Saver.h" + ACE_RCSID (Notify, TAO_Notify_EventType, "$Id$") @@ -139,3 +141,36 @@ TAO_Notify_EventType::dump (void) const this->event_type_.domain_name.in (), this->event_type_.type_name.in ())); } + +/// Initialize from an NVPList, return false on failure +bool TAO_Notify_EventType::init(const TAO_Notify::NVPList& attrs) +{ + bool result = false; + + ACE_CString domain; + ACE_CString type; + if (attrs.load("Domain", domain) && attrs.load("Type", type)) + { + this->init_i(domain.c_str(), type.c_str()); + result = true; + } + return result; + +} + + // TAO_Notify::Topology_Object + +void +TAO_Notify_EventType::save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL) +{ + TAO_Notify::NVPList attrs; + bool changed = true; + + attrs.push_back(TAO_Notify::NVP("Domain", this->event_type_.domain_name.in())); + attrs.push_back(TAO_Notify::NVP("Type", this->event_type_.type_name.in())); + saver.begin_object(0, "subscription", attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + saver.end_object(0, "subscription" ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/EventType.h b/TAO/orbsvcs/orbsvcs/Notify/EventType.h index 3fcd875060d..2378fe6ba80 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/EventType.h +++ b/TAO/orbsvcs/orbsvcs/Notify/EventType.h @@ -21,6 +21,7 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "orbsvcs/CosNotificationC.h" +#include "Topology_Object.h" /** * @class TAO_Notify_EventType @@ -31,7 +32,7 @@ * It is used by the Event Manager as a key to find subscription lists. * */ -class TAO_Notify_Serv_Export TAO_Notify_EventType +class TAO_Notify_Serv_Export TAO_Notify_EventType : public TAO_Notify::Topology_Savable { public: /// Constuctor @@ -41,7 +42,7 @@ public: // Constuctor /// Destructor - ~TAO_Notify_EventType (); + virtual ~TAO_Notify_EventType (); /// hash value u_long hash (void) const; @@ -70,6 +71,13 @@ public: /// Helper to print contents. void dump (void) const; + /// Initialize from an NVPList, return false on failure + bool init(const TAO_Notify::NVPList& attrs); + + // TAO_Notify::Topology_Object + + virtual void save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL); + protected: /// Init this object. void init_i (const char* domain_name, const char* type_name); diff --git a/TAO/orbsvcs/orbsvcs/Notify/EventTypeSeq.cpp b/TAO/orbsvcs/orbsvcs/Notify/EventTypeSeq.cpp index 5161da17add..a02e2901cfb 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/EventTypeSeq.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/EventTypeSeq.cpp @@ -6,6 +6,14 @@ #include "EventTypeSeq.inl" #endif /* __ACE_INLINE__ */ +#include "Topology_Saver.h" + +#include "tao/debug.h" +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + ACE_RCSID(Notify, TAO_Notify_EventTypeSeq, "$Id$") TAO_Notify_EventTypeSeq::TAO_Notify_EventTypeSeq (void) @@ -17,6 +25,19 @@ TAO_Notify_EventTypeSeq::TAO_Notify_EventTypeSeq (const CosNotification::EventTy this->insert_seq (event_type_seq); } +TAO_Notify_EventTypeSeq & +TAO_Notify_EventTypeSeq::operator = (const TAO_Notify_EventTypeSeq & rhs) +{ + ACE_Unbounded_Set <TAO_Notify_EventType>::operator = (rhs); + return *this; +} + +TAO_Notify_EventTypeSeq::TAO_Notify_EventTypeSeq (const TAO_Notify_EventTypeSeq & rhs) + : ACE_Unbounded_Set <TAO_Notify_EventType> (rhs) + , TAO_Notify::Topology_Object () +{ +} + void TAO_Notify_EventTypeSeq::populate (CosNotification::EventTypeSeq& event_type_seq) const { @@ -238,3 +259,58 @@ TAO_Notify_EventTypeSeq::dump (void) const ACE_DEBUG ((LM_DEBUG, ", ")); } } + + // TAO_Notify::Topology_Object +void +TAO_Notify_EventTypeSeq::save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL) +{ + bool changed = this->self_changed_; + this->self_changed_ = false; + this->children_changed_ = false; + TAO_Notify::NVPList attrs; + + TAO_Notify_EventTypeSeq::ITERATOR iter (*this); + TAO_Notify_EventType* event_type; + + if (this->size() != 0) + { + saver.begin_object(0, "subscriptions", attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + for (iter.first (); iter.next (event_type) != 0; iter.advance ()) + { + event_type->save_persistent(saver ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +// todo: +// for all deleted children +// { +// saver.delete_child(child_type, child_id); +// } + saver.end_object(0, "subscriptions" ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +} + +TAO_Notify::Topology_Object* +TAO_Notify_EventTypeSeq::load_child (const ACE_CString &type, CORBA::Long id, + const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL) +{ + ACE_UNUSED_ARG (id); + TAO_Notify::Topology_Object *result = this; + TAO_Notify_EventType et; + + if ((type == "subscription") && et.init(attrs)) + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Event_Type reload subscription\n") + )); + inherited::insert(et); + } + return result; +} + +void +TAO_Notify_EventTypeSeq::release (void) +{ + delete this; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/EventTypeSeq.h b/TAO/orbsvcs/orbsvcs/Notify/EventTypeSeq.h index 9f492e605e7..fb6966a939a 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/EventTypeSeq.h +++ b/TAO/orbsvcs/orbsvcs/Notify/EventTypeSeq.h @@ -28,7 +28,9 @@ * @brief Allows operations using the CosNotification::EventTypeSeq type. * */ -class TAO_Notify_Serv_Export TAO_Notify_EventTypeSeq : public ACE_Unbounded_Set <TAO_Notify_EventType> +class TAO_Notify_Serv_Export TAO_Notify_EventTypeSeq + : public ACE_Unbounded_Set <TAO_Notify_EventType> + , public TAO_Notify::Topology_Object { typedef ACE_Unbounded_Set <TAO_Notify_EventType> inherited; @@ -36,6 +38,8 @@ public: /// Constructor TAO_Notify_EventTypeSeq (void); TAO_Notify_EventTypeSeq (const CosNotification::EventTypeSeq& event_type_seq); + TAO_Notify_EventTypeSeq (const TAO_Notify_EventTypeSeq & rhs); + TAO_Notify_EventTypeSeq & operator = (const TAO_Notify_EventTypeSeq & rhs); /// Preprocess the types added and removed. void init (TAO_Notify_EventTypeSeq& added, TAO_Notify_EventTypeSeq& removed); @@ -64,6 +68,14 @@ public: /// Print the contents. void dump (void) const; + + // TAO_Notify::Topology_Object + + virtual void save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL); + virtual TAO_Notify::Topology_Object* load_child (const ACE_CString &type, CORBA::Long id, + const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL); + virtual void release (void); + }; #if defined (__ACE_INLINE__) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Event_Manager.cpp b/TAO/orbsvcs/orbsvcs/Notify/Event_Manager.cpp index 9a03b6c3c96..ef8c778aa9d 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Event_Manager.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Event_Manager.cpp @@ -76,7 +76,7 @@ void TAO_Notify_Event_Manager::connect (TAO_Notify_ProxyConsumer* proxy_consumer ACE_ENV_ARG_DECL) { this->supplier_map_->connect (proxy_consumer ACE_ENV_ARG_PARAMETER); - + ACE_CHECK; // Inform about subscription types. TAO_Notify_EventTypeSeq removed; proxy_consumer->types_changed (this->subscription_types (), removed ACE_ENV_ARG_PARAMETER); diff --git a/TAO/orbsvcs/orbsvcs/Notify/Event_Persistence_Factory.h b/TAO/orbsvcs/orbsvcs/Notify/Event_Persistence_Factory.h new file mode 100644 index 00000000000..3d9ac08b43e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Event_Persistence_Factory.h @@ -0,0 +1,47 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Event_Persistence_Factory.h + * + * $Id$ + * + * A factory class that creates a Routing_Slip_Persistence_Manager. + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef EVENT_PERSISTENCE_FACTORY_H +#define EVENT_PERSISTENCE_FACTORY_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "notify_serv_export.h" + +namespace TAO_Notify +{ + class Routing_Slip_Persistence_Manager; + class Persistent_Callback; + + /// interface to be implemented by specific Event_Persistence_Factories + class TAO_Notify_Serv_Export Event_Persistence_Factory + { + public: + /// Create a Persistence Manager + virtual Routing_Slip_Persistence_Manager * + create_routing_slip_persistence_manager (Persistent_Callback * callback) = 0; + + /// Begin the reload process by returning the first Routing_Slip_Persistence_Manager + /// to continue call Routing_Slip_Persistence_Manager::load_next () + virtual Routing_Slip_Persistence_Manager * first_reload_manager () = 0; + + }; +} // namespace TAO_Notify + +#include /**/ "ace/post.h" +#endif /* EVENT_PERSISTENCE_FACTORY_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Event_Persistence_Strategy.h b/TAO/orbsvcs/orbsvcs/Notify/Event_Persistence_Strategy.h new file mode 100644 index 00000000000..3ff9990b326 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Event_Persistence_Strategy.h @@ -0,0 +1,47 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Event_Persistence_Strategy.h + * + * $Id$ + * + * A factory class that creates a Routing_Slip_Persistence_Manager. + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef EVENT_PERSISTENCE_STRATEGY_H +#define EVENT_PERSISTENCE_STRATEGY_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "notify_serv_export.h" + +#include "ace/Service_Object.h" + +namespace TAO_Notify +{ + class Event_Persistence_Factory; + + /// Interface to be implemented by specific strategies + class TAO_Notify_Serv_Export Event_Persistence_Strategy: public ACE_Service_Object + { + public: + + // get the current factory, creating it if necessary + virtual Event_Persistence_Factory * get_factory () = 0; + + // release the current factory so a new one can be created + virtual void reset () = 0; + }; + +} // namespace TAO_Notify + +#include /**/ "ace/post.h" +#endif /* EVENT_PERSISTENCE_STRATEGY_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/FilterAdmin.cpp b/TAO/orbsvcs/orbsvcs/Notify/FilterAdmin.cpp index d6b64275843..138b9e17ba6 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/FilterAdmin.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/FilterAdmin.cpp @@ -8,6 +8,8 @@ ACE_RCSID(Notify, FilterAdmin, "$Id$") +#include "Topology_Saver.h" +#include "Properties.h" #include "ace/Refcounted_Auto_Ptr.h" // Implementation skeleton constructor @@ -128,6 +130,76 @@ TAO_Notify_FilterAdmin::remove_all_filters (ACE_ENV_SINGLE_ARG_DECL) this->filter_list_.unbind_all (); } +void +TAO_Notify_FilterAdmin::save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL) +{ + if (this->filter_list_.current_size() == 0) + return; + + bool changed = true; + + TAO_Notify::NVPList attrs; + bool want_children = saver.begin_object(0, "filter_admin", attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + if (want_children) + { + FILTER_LIST::ITERATOR iter (this->filter_list_); + FILTER_LIST::ENTRY* entry; + + TAO_Notify_Properties* properties = TAO_Notify_PROPERTIES::instance(); + CORBA::ORB_var orb = properties->orb(); + ACE_ASSERT(! CORBA::is_nil(orb.in())); + + for (; iter.next(entry) != 0; iter.advance()) + { + TAO_Notify::NVPList fattrs; + CORBA::Long id = entry->ext_id_; + CORBA::String_var ior = orb->object_to_string(entry->int_id_.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + fattrs.push_back(TAO_Notify::NVP("IOR", ior.in())); + saver.begin_object(id, "filter", fattrs, changed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + saver.end_object(id, "filter" ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + } + + saver.end_object(0, "filter_admin" ACE_ENV_ARG_PARAMETER); +} + +TAO_Notify::Topology_Object* +TAO_Notify_FilterAdmin::load_child (const ACE_CString &type, CORBA::Long id, + const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL) +{ + if (type == "filter") + { + TAO_Notify_Properties* properties = TAO_Notify_PROPERTIES::instance(); + CORBA::ORB_var orb = properties->orb(); + ACE_ASSERT(! CORBA::is_nil(orb.in())); + ACE_CString ior; + attrs.load("IOR", ior); + + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + CosNotifyFilter::Filter_var filter = CosNotifyFilter::Filter::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + if (! CORBA::is_nil(filter.in())) + { + this->filter_ids_.set_last_used(id); + if (this->filter_list_.bind (id, filter) != 0) + ACE_THROW_RETURN (CORBA::INTERNAL (), 0); + } + } + return this; +} + +void +TAO_Notify_FilterAdmin::release (void) +{ + delete this; +} + + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Hash_Map_Entry<CosNotifyFilter::FilterID,CosNotifyFilter::Filter_var>; template class ACE_Hash_Map_Manager<CosNotifyFilter::FilterID,CosNotifyFilter::Filter_var,ACE_Null_Mutex>; diff --git a/TAO/orbsvcs/orbsvcs/Notify/FilterAdmin.h b/TAO/orbsvcs/orbsvcs/Notify/FilterAdmin.h index 4e40b0b5ac9..d6e20116940 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/FilterAdmin.h +++ b/TAO/orbsvcs/orbsvcs/Notify/FilterAdmin.h @@ -22,6 +22,7 @@ #include "ID_Factory.h" #include "Event.h" #include "notify_serv_export.h" +#include "Topology_Object.h" /** * @class TAO_Notify_FilterAdmin @@ -30,6 +31,7 @@ * */ class TAO_Notify_Serv_Export TAO_Notify_FilterAdmin + : public TAO_Notify::Topology_Object { public: @@ -80,6 +82,13 @@ class TAO_Notify_Serv_Export TAO_Notify_FilterAdmin CORBA::SystemException )); + + // TAO_Notify::Topology_Object + + virtual void save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL); + virtual TAO_Notify::Topology_Object* load_child (const ACE_CString &type, CORBA::Long id, + const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL); + virtual void release (void); private: typedef ACE_Hash_Map_Manager <CosNotifyFilter::FilterID, CosNotifyFilter::Filter_var, ACE_SYNCH_NULL_MUTEX> FILTER_LIST; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Find_Worker_T.cpp b/TAO/orbsvcs/orbsvcs/Notify/Find_Worker_T.cpp index 3adfc211d53..43110f20672 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Find_Worker_T.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Find_Worker_T.cpp @@ -18,7 +18,7 @@ TAO_Notify_Find_Worker_T<TYPE,INTERFACE,INTERFACE_PTR,EXCEPTION>::TAO_Notify_Fin } template<class TYPE, class INTERFACE, class INTERFACE_PTR, class EXCEPTION> TYPE* -TAO_Notify_Find_Worker_T<TYPE,INTERFACE,INTERFACE_PTR,EXCEPTION>::find (TAO_Notify_Object::ID id, CONTAINER& container ACE_ENV_ARG_DECL) +TAO_Notify_Find_Worker_T<TYPE,INTERFACE,INTERFACE_PTR,EXCEPTION>::find (const TAO_Notify_Object::ID id, CONTAINER& container ACE_ENV_ARG_DECL) { this->id_ = id; @@ -29,7 +29,7 @@ TAO_Notify_Find_Worker_T<TYPE,INTERFACE,INTERFACE_PTR,EXCEPTION>::find (TAO_Noti } template<class TYPE, class INTERFACE, class INTERFACE_PTR, class EXCEPTION> INTERFACE_PTR -TAO_Notify_Find_Worker_T<TYPE,INTERFACE,INTERFACE_PTR,EXCEPTION>::resolve (TAO_Notify_Object::ID id, CONTAINER& container ACE_ENV_ARG_DECL) +TAO_Notify_Find_Worker_T<TYPE,INTERFACE,INTERFACE_PTR,EXCEPTION>::resolve (const TAO_Notify_Object::ID id, CONTAINER& container ACE_ENV_ARG_DECL) { this->find (id, container ACE_ENV_ARG_PARAMETER); diff --git a/TAO/orbsvcs/orbsvcs/Notify/Find_Worker_T.h b/TAO/orbsvcs/orbsvcs/Notify/Find_Worker_T.h index 554a52395a7..abc1533da56 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Find_Worker_T.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Find_Worker_T.h @@ -41,10 +41,10 @@ public: TAO_Notify_Find_Worker_T (void); /// Find the Type. - TYPE* find (TAO_Notify_Object::ID id, CONTAINER& container ACE_ENV_ARG_DECL); + TYPE* find (const TAO_Notify_Object::ID id, CONTAINER& container ACE_ENV_ARG_DECL); /// Find and resolve to the Interface. - INTERFACE_PTR resolve (TAO_Notify_Object::ID id, CONTAINER& container ACE_ENV_ARG_DECL); + INTERFACE_PTR resolve (const TAO_Notify_Object::ID id, CONTAINER& container ACE_ENV_ARG_DECL); protected: ///= TAO_ESF_Worker method diff --git a/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.cpp b/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.cpp index 8e021520caf..b8bec81f68c 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.cpp @@ -9,6 +9,7 @@ ACE_RCSID(Notify, TAO_Notify_ID_Factory, "$Id$") TAO_Notify_ID_Factory::TAO_Notify_ID_Factory (void) + : seed_ (0) { } diff --git a/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.h b/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.h index f3f6e3127b0..b9f0bd8aef5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.h +++ b/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.h @@ -41,8 +41,12 @@ public: TAO_Notify_Object::ID id (void); + void set_last_used (const TAO_Notify_Object::ID id); + private: - ACE_Atomic_Op<TAO_SYNCH_MUTEX, TAO_Notify_Object::ID> seed_; + // Can't use atomic op, because we added the set_last_used() method. + TAO_Notify_Object::ID seed_; + TAO_SYNCH_MUTEX mtx_; }; diff --git a/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.inl b/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.inl index 74a2d8582d6..f9fb1f5e89b 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/ID_Factory.inl @@ -3,5 +3,16 @@ ACE_INLINE TAO_Notify_Object::ID TAO_Notify_ID_Factory::id (void) { + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->mtx_, 0); return ++seed_; } + +ACE_INLINE void +TAO_Notify_ID_Factory::set_last_used (const TAO_Notify_Object::ID id) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mtx_); + if (this->seed_ < id) + { + this->seed_ = id; + } +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request.cpp b/TAO/orbsvcs/orbsvcs/Notify/Method_Request.cpp index 56fd8d589e7..50e22647519 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request.cpp @@ -6,4 +6,19 @@ #include "Method_Request.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID(Notify, TAO_Notify_Method_Request, "$Id$") +ACE_RCSID(Notify, TAO_Notify_Method_Request_Queueable, "$Id$") + +TAO_Notify_Method_Request_Queueable * +TAO_Notify_Method_Request_Queueable::copy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + return this; +} + +TAO_Notify_Method_Request_Queueable::TAO_Notify_Method_Request_Queueable() +{ +} + +TAO_Notify_Method_Request_Queueable::TAO_Notify_Method_Request_Queueable(const TAO_Notify_Event * event) +{ + this->init (event); +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request.h b/TAO/orbsvcs/orbsvcs/Notify/Method_Request.h index 6134050823d..248708a0eae 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request.h @@ -5,8 +5,6 @@ * $Id$ * * @author Pradeep Gore <pradeep@oomworks.com> - * - * */ #ifndef TAO_Notify_METHOD_REQUEST_H @@ -26,41 +24,42 @@ #include "Event.h" -class TAO_Notify_Method_Request; +class TAO_Notify_Method_Request_Queueable; /** - * @class TAO_Notify_Method_Request_No_Copy + * @class TAO_Notify_Method_Request * - * @brief Base class for Method Requests that do not copy the event. + * @brief Base class for Method Requests * */ -class TAO_Notify_Serv_Export TAO_Notify_Method_Request_No_Copy +class TAO_Notify_Serv_Export TAO_Notify_Method_Request { public: /// Execute the Request virtual int execute (ACE_ENV_SINGLE_ARG_DECL) = 0; - - /// Create a copy of this object. - virtual TAO_Notify_Method_Request* copy (ACE_ENV_SINGLE_ARG_DECL) = 0; + virtual TAO_Notify_Method_Request_Queueable* copy (ACE_ENV_SINGLE_ARG_DECL) = 0; }; /***********************************************************************/ /** - * @class TAO_Notify_Method_Request + * @class TAO_Notify_Method_Request_Queueable * * @brief Interface for NS method Requests * */ -class TAO_Notify_Serv_Export TAO_Notify_Method_Request : public ACE_Message_Block +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Queueable + : public ACE_Message_Block + , public TAO_Notify_Method_Request { public: enum {PRIORITY_BASE = 32768}; - void init (const TAO_Notify_Event_var& event); + TAO_Notify_Method_Request_Queueable(); + TAO_Notify_Method_Request_Queueable(const TAO_Notify_Event * event); - /// Execute the Request - virtual int execute (ACE_ENV_SINGLE_ARG_DECL) = 0; + virtual TAO_Notify_Method_Request_Queueable* copy (ACE_ENV_SINGLE_ARG_DECL); + void init (const TAO_Notify_Event * event); }; #if defined (__ACE_INLINE__) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request.inl b/TAO/orbsvcs/orbsvcs/Notify/Method_Request.inl index 66c35ce83d6..c3f8250333d 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request.inl @@ -3,7 +3,7 @@ #include "ace/OS_NS_sys_time.h" ACE_INLINE void -TAO_Notify_Method_Request::init (const TAO_Notify_Event_var& event) +TAO_Notify_Method_Request_Queueable::init (const TAO_Notify_Event * event) { // Set the parameters that affect queuing in the message queue. // The ACE_Message_Block priorities go from 0 (lowest) to ULONG_MAX diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.cpp b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.cpp index 4322dbc6f29..fce23cb5d14 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.cpp @@ -13,120 +13,293 @@ ACE_RCSID(Notify, TAO_Notify_Method_Request_Dispatch, "$Id$") #include "Consumer.h" #include "Admin.h" #include "ConsumerAdmin.h" - -TAO_Notify_Method_Request_Dispatch::TAO_Notify_Method_Request_Dispatch (const TAO_Notify_Event_var& event, TAO_Notify_ProxySupplier* proxy_supplier, CORBA::Boolean filtering) - : TAO_Notify_Method_Request_Dispatch_Base (event, proxy_supplier, filtering) +#include "EventChannelFactory.h" +#include "ace/OS_NS_stdio.h" +//#define DEBUG_LEVEL 10 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + +// Constuct from event +TAO_Notify_Method_Request_Dispatch::TAO_Notify_Method_Request_Dispatch ( + const TAO_Notify_Event * event, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering) + : TAO_Notify_Method_Request_Event (event) + , proxy_supplier_ (proxy_supplier) + , filtering_ (filtering) { - this->init (event); } -TAO_Notify_Method_Request_Dispatch::~TAO_Notify_Method_Request_Dispatch () +// Construct from a delivery rquest +TAO_Notify_Method_Request_Dispatch::TAO_Notify_Method_Request_Dispatch ( + const TAO_Notify::Delivery_Request_Ptr & delivery, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering) + : TAO_Notify_Method_Request_Event (delivery) + , proxy_supplier_ (proxy_supplier) + , filtering_ (filtering) { } -int -TAO_Notify_Method_Request_Dispatch::execute (ACE_ENV_SINGLE_ARG_DECL) +// Constuct construct from another method request+event +// event is passed separately because we may be using a copy +// of the one in the previous method request +TAO_Notify_Method_Request_Dispatch::TAO_Notify_Method_Request_Dispatch ( + const TAO_Notify_Method_Request_Event & request, + const TAO_Notify_Event * event, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering) + : TAO_Notify_Method_Request_Event (request, event) + , proxy_supplier_ (proxy_supplier) + , filtering_ (filtering) { - return this->execute_i (ACE_ENV_SINGLE_ARG_PARAMETER); } -/*********************************************************************************************************/ - -TAO_Notify_Method_Request_Dispatch_No_Copy::TAO_Notify_Method_Request_Dispatch_No_Copy (const TAO_Notify_Event* event, TAO_Notify_ProxySupplier* proxy_supplier, CORBA::Boolean filtering) - : TAO_Notify_Method_Request_Dispatch_No_Copy_Base (event, proxy_supplier, filtering) +TAO_Notify_Method_Request_Dispatch::~TAO_Notify_Method_Request_Dispatch () { +#if 0 + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Destroy TAO_Notify_Method_Request_Dispatch @%@\n"), + this)); +#endif } -TAO_Notify_Method_Request_Dispatch_No_Copy:: ~TAO_Notify_Method_Request_Dispatch_No_Copy () +int TAO_Notify_Method_Request_Dispatch::execute_i (ACE_ENV_SINGLE_ARG_DECL) { + if (this->proxy_supplier_->has_shutdown ()) + return 0; // If we were shutdown while waiting in the queue, return with no action. + + if (this->filtering_ == 1) + { + TAO_Notify_Admin* parent = this->proxy_supplier_->consumer_admin (); + CORBA::Boolean val = this->proxy_supplier_->check_filters (this->event_, + parent->filter_admin (), + parent->filter_operator () + ACE_ENV_ARG_PARAMETER); + + if (TAO_debug_level > 1) + ACE_DEBUG ((LM_DEBUG, "Proxysupplier %x filter eval result = %d",&this->proxy_supplier_ , val)); + + // Filter failed - do nothing. + if (val == 0) + return 0; + } + + ACE_TRY + { + TAO_Notify_Consumer* consumer = this->proxy_supplier_->consumer (); + + if (consumer != 0) + { + consumer->deliver (this ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + } + ACE_CATCHANY + { + if (TAO_debug_level > 0) + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("TAO_Notify_Method_Request_Dispatch::: error sending event.\n ") + ); + } + ACE_ENDTRY; + + return 0; } -int -TAO_Notify_Method_Request_Dispatch_No_Copy::execute (ACE_ENV_SINGLE_ARG_DECL) +/// Static method used to reconstruct a Method Request Dispatch +TAO_Notify_Method_Request_Dispatch_Queueable * +TAO_Notify_Method_Request_Dispatch::unmarshal ( + TAO_Notify::Delivery_Request_Ptr & delivery_request, + TAO_Notify_EventChannelFactory &ecf, + TAO_InputCDR & cdr + ACE_ENV_ARG_DECL) { - return this->execute_i (ACE_ENV_SINGLE_ARG_PARAMETER); + bool ok = true; + TAO_Notify_Method_Request_Dispatch_Queueable * result = 0; + ACE_CString textpath; + CORBA::ULong count; + if (cdr.read_ulong (count)) + { + TAO_Notify::IdVec id_path (count); + for (size_t nid = 0; ok && nid < count; ++nid) + { + TAO_Notify_Object::ID id = 0; + if ( cdr.read_long (id)) + { + id_path.push_back (id); + char idbuf[20]; + ACE_OS::snprintf (idbuf, sizeof(idbuf)-1, "/%d", ACE_static_cast (int, id)); + textpath += idbuf; + } + else + { + ok = false; + } + } + + if (ok) + { + TAO_Notify_ProxySupplier* proxy_supplier = ecf.find_proxy_supplier (id_path, + 0 ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + if (proxy_supplier != 0) + { + if (DEBUG_LEVEL > 6) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) TAO_Notify_Method_Request_Dispatch reload event for %s\n") + , textpath.c_str() + )); + ACE_NEW_NORETURN (result, + TAO_Notify_Method_Request_Dispatch_Queueable (delivery_request, proxy_supplier, true)); + } + else + { + TAO_Notify_ProxyConsumer * proxy_consumer = ecf.find_proxy_consumer (id_path, 0 ACE_ENV_ARG_PARAMETER); //@@todo + if (proxy_consumer == 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Method_Request_Dispatch::unmarshal: unknown proxy id %s\n") + , textpath.c_str() + )); + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Method_Request_Dispatch::unmarshal: wrong type of proxy id %s\n") + , textpath.c_str() + )); + } + } + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Method_Request_Dispatch::unmarshal: Cant read proxy id path\n") + )); + } + } + return result; } -TAO_Notify_Method_Request* -TAO_Notify_Method_Request_Dispatch_No_Copy::copy (ACE_ENV_SINGLE_ARG_DECL) -{ - TAO_Notify_Method_Request* request; +/////////////////////////////////////////////////////////////////////////////// - TAO_Notify_Event* event_copy = this->event_->copy (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_CHECK_RETURN (0); - TAO_Notify_Event_Copy_var event_var (event_copy); +/*******************************************************************/ - ACE_NEW_THROW_EX (request, - TAO_Notify_Method_Request_Dispatch (event_var, this->proxy_supplier_, this->filtering_), - CORBA::INTERNAL ()); +// Constuct construct from another method request+event +// event is passed separately because we may be using a copy +// of the one in the previous method request +TAO_Notify_Method_Request_Dispatch_Queueable::TAO_Notify_Method_Request_Dispatch_Queueable ( + const TAO_Notify_Method_Request_Event & request, + TAO_Notify_Event_var & event, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering) + : TAO_Notify_Method_Request_Dispatch (request, event.get (), proxy_supplier, filtering) + , TAO_Notify_Method_Request_Queueable (event.get ()) +{ +#if 0 + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Construct Method_Request_Dispatch @%@\n"), + this)); +#endif +} - return request; + /// Constuct construct from Delivery Request + /// should ONLY be used by unmarshall +TAO_Notify_Method_Request_Dispatch_Queueable::TAO_Notify_Method_Request_Dispatch_Queueable ( + const TAO_Notify::Delivery_Request_Ptr & request, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering) + : TAO_Notify_Method_Request_Dispatch (request, request->event ().get (), proxy_supplier, filtering) + , TAO_Notify_Method_Request_Queueable (request->event ().get ()) +{ +#if 0 + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Construct unmarshalled Method_Request_Dispatch_Queueable @%@\n"), + this)); +#endif +} + +TAO_Notify_Method_Request_Dispatch_Queueable::~TAO_Notify_Method_Request_Dispatch_Queueable () +{ +#if 0 + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Destroy TAO_Notify_Method_Request_Dispatch_Queueable @%@\n"), + this)); +#endif +} + +int +TAO_Notify_Method_Request_Dispatch_Queueable::execute (ACE_ENV_SINGLE_ARG_DECL) +{ + return this->execute_i (ACE_ENV_SINGLE_ARG_PARAMETER); } /*********************************************************************************************************/ -TAO_Notify_Method_Request_Dispatch_No_Copy_Ex::TAO_Notify_Method_Request_Dispatch_No_Copy_Ex (const TAO_Notify_Event_var& event, TAO_Notify_ProxySupplier* proxy_supplier, CORBA::Boolean filtering) - : TAO_Notify_Method_Request_Dispatch_No_Copy_Ex_Base (event, proxy_supplier, filtering) +TAO_Notify_Method_Request_Dispatch_No_Copy::TAO_Notify_Method_Request_Dispatch_No_Copy ( + const TAO_Notify_Event* event, + TAO_Notify_ProxySupplier* proxy_supplier, + CORBA::Boolean filtering) + : TAO_Notify_Method_Request_Dispatch (event, proxy_supplier, filtering) { +#if 0 + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Construct Method_Request_Dispatch_No_Copy @%@\n"), + this)); +#endif +} + /// Constuct construct from another method request +TAO_Notify_Method_Request_Dispatch_No_Copy::TAO_Notify_Method_Request_Dispatch_No_Copy ( + const TAO_Notify_Method_Request_Event & request, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering) + : TAO_Notify_Method_Request_Dispatch (request, request.event (), proxy_supplier, filtering) +{ +#if 0 + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Construct Method_Request_Dispatch_No_Copy @%@\n"), + this)); +#endif } -TAO_Notify_Method_Request_Dispatch_No_Copy_Ex:: ~TAO_Notify_Method_Request_Dispatch_No_Copy_Ex () +TAO_Notify_Method_Request_Dispatch_No_Copy:: ~TAO_Notify_Method_Request_Dispatch_No_Copy () { +#if 0 + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Destroy Method_Request_Dispatch_No_Copy @%@\n"), + this)); +#endif } int -TAO_Notify_Method_Request_Dispatch_No_Copy_Ex::execute (ACE_ENV_SINGLE_ARG_DECL) +TAO_Notify_Method_Request_Dispatch_No_Copy::execute (ACE_ENV_SINGLE_ARG_DECL) { return this->execute_i (ACE_ENV_SINGLE_ARG_PARAMETER); } -TAO_Notify_Method_Request* -TAO_Notify_Method_Request_Dispatch_No_Copy_Ex::copy (ACE_ENV_SINGLE_ARG_DECL) +TAO_Notify_Method_Request_Queueable* +TAO_Notify_Method_Request_Dispatch_No_Copy::copy (ACE_ENV_SINGLE_ARG_DECL) { - TAO_Notify_Method_Request* request; + TAO_Notify_Method_Request_Queueable* request; + + TAO_Notify_Event_var event_var; + this->event_->queueable_copy (event_var ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); ACE_NEW_THROW_EX (request, - TAO_Notify_Method_Request_Dispatch (this->event_, this->proxy_supplier_, this->filtering_), + TAO_Notify_Method_Request_Dispatch_Queueable (*this, event_var, this->proxy_supplier_.get(), this->filtering_), + //TAO_Notify_Method_Request_Dispatch_Queueable (*this, event_var, this->proxy_supplier_, this->filtering_), CORBA::INTERNAL ()); return request; } - +/*********************************************************************************************************/ #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class TAO_Notify_Method_Request_Dispatch_T<const TAO_Notify_Event_var -, TAO_Notify_ProxySupplier_Guard -, const TAO_Notify_Event_var& -, TAO_Notify_ProxySupplier*>; - -template class TAO_Notify_Method_Request_Dispatch_T<const TAO_Notify_Event* -, TAO_Notify_ProxySupplier* -, const TAO_Notify_Event* -, TAO_Notify_ProxySupplier*>; - -template class TAO_Notify_Method_Request_Dispatch_T<const TAO_Notify_Event_var& -, TAO_Notify_ProxySupplier* -, const TAO_Notify_Event_var& -, TAO_Notify_ProxySupplier*>; - #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate TAO_Notify_Method_Request_Dispatch_T<const TAO_Notify_Event_var -, TAO_Notify_ProxySupplier_Guard -, const TAO_Notify_Event_var& -, TAO_Notify_ProxySupplier*> - -#pragma instantiate TAO_Notify_Method_Request_Dispatch_T<const TAO_Notify_Event* -, TAO_Notify_ProxySupplier* -, const TAO_Notify_Event* -, TAO_Notify_ProxySupplier*> - -#pragma instantiate TAO_Notify_Method_Request_Dispatch_T<const TAO_Notify_Event_var& -, TAO_Notify_ProxySupplier* -, const TAO_Notify_Event_var& -, TAO_Notify_ProxySupplier*> - #endif /*ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.h b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.h index 156dadf13e9..41b9682c6fb 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.h @@ -21,97 +21,149 @@ #include "Method_Request.h" #include "Refcountable.h" -#include "Method_Request_Dispatch_T.h" +#include "Method_Request_Event.h" #include "ProxySupplier.h" +#include "Delivery_Request.h" + +class TAO_Notify_EventChannelFactory; +class TAO_InputCDR; +class TAO_Notify_Method_Request_Dispatch_Queueable; /** * @class TAO_Notify_Method_Request_Dispatch * - * @brief Dispatchs an event to a proxy supplier. + * @brief * */ - -typedef TAO_Notify_Method_Request_Dispatch_T<const TAO_Notify_Event_var - , TAO_Notify_ProxySupplier_Guard - , const TAO_Notify_Event_var& - , TAO_Notify_ProxySupplier*> TAO_Notify_Method_Request_Dispatch_Base; - -class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Dispatch : public TAO_Notify_Method_Request_Dispatch_Base - , public TAO_Notify_Method_Request +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Dispatch + : public TAO_Notify_Method_Request_Event { public: - /// Constuctor - TAO_Notify_Method_Request_Dispatch (const TAO_Notify_Event_var& event, TAO_Notify_ProxySupplier* proxy_supplier, CORBA::Boolean filtering); + /// an arbitrary code (Octet) to identify this delivery method type in persistent storage + enum {persistence_code = 1}; + + /// Constuct from event + TAO_Notify_Method_Request_Dispatch ( + const TAO_Notify_Event * event, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering); + + /// Construct from a delivery rquest + TAO_Notify_Method_Request_Dispatch ( + const TAO_Notify::Delivery_Request_Ptr & delivery, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering); + + /// Constuct construct from another method request+event + /// event is passed separately because we may be using a copy + /// of the one in the previous method request + TAO_Notify_Method_Request_Dispatch ( + const TAO_Notify_Method_Request_Event & request, + const TAO_Notify_Event * event, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering); +public: /// Destructor - ~TAO_Notify_Method_Request_Dispatch (); + virtual ~TAO_Notify_Method_Request_Dispatch (); - /// Execute the Request - virtual int execute (ACE_ENV_SINGLE_ARG_DECL); -}; + /// Static method used to reconstruct a Method Request Dispatch + static TAO_Notify_Method_Request_Dispatch_Queueable * unmarshal ( + TAO_Notify::Delivery_Request_Ptr & delivery_request, + TAO_Notify_EventChannelFactory &ecf, + TAO_InputCDR & cdr + ACE_ENV_ARG_DECL); -/*******************************************************************************************************/ + +protected: + /// Execute the dispatch operation. + int execute_i (ACE_ENV_SINGLE_ARG_DECL); + +protected: + /// The Proxy + TAO_Notify_ProxySupplier_Guard proxy_supplier_; + //TAO_Notify_ProxySupplier* proxy_supplier_; + + /// Flag is true if we want to do filtering else false. + bool filtering_; +}; /** - * @class TAO_Notify_Method_Request_Dispatch_No_Copy + * @class TAO_Notify_Method_Request_Dispatch_Queueable * * @brief Dispatchs an event to a proxy supplier. * */ -typedef TAO_Notify_Method_Request_Dispatch_T<const TAO_Notify_Event* - , TAO_Notify_ProxySupplier* - , const TAO_Notify_Event* - , TAO_Notify_ProxySupplier*> TAO_Notify_Method_Request_Dispatch_No_Copy_Base; - -class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Dispatch_No_Copy : public TAO_Notify_Method_Request_Dispatch_No_Copy_Base - , public TAO_Notify_Method_Request_No_Copy +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Dispatch_Queueable + : public TAO_Notify_Method_Request_Dispatch + , public TAO_Notify_Method_Request_Queueable { public: - /// Constuctor - TAO_Notify_Method_Request_Dispatch_No_Copy (const TAO_Notify_Event* event, TAO_Notify_ProxySupplier* proxy_supplier, CORBA::Boolean filtering); + /// Construct construct from another method request+event + /// event is passed separately because we may be using a copy + /// of the one in the previous method request + TAO_Notify_Method_Request_Dispatch_Queueable ( + const TAO_Notify_Method_Request_Event & request, + TAO_Notify_Event_var & event, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering); + + /// Constuct construct from Delivery Request + /// should ONLY be used by unmarshall + TAO_Notify_Method_Request_Dispatch_Queueable ( + const TAO_Notify::Delivery_Request_Ptr & request, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering); /// Destructor - ~TAO_Notify_Method_Request_Dispatch_No_Copy (); + ~TAO_Notify_Method_Request_Dispatch_Queueable (); /// Execute the Request virtual int execute (ACE_ENV_SINGLE_ARG_DECL); - /// Create a copy of this object. - virtual TAO_Notify_Method_Request* copy (ACE_ENV_SINGLE_ARG_DECL); +private: + const TAO_Notify_Event_var event_var_; + TAO_Notify_ProxySupplier_Guard proxy_guard_; }; /*******************************************************************************************************/ /** - * @class TAO_Notify_Method_Request_Dispatch_No_Copy_Ex + * @class TAO_Notify_Method_Request_Dispatch_No_Copy * * @brief Dispatchs an event to a proxy supplier. * */ - -typedef TAO_Notify_Method_Request_Dispatch_T<const TAO_Notify_Event_var& - , TAO_Notify_ProxySupplier* - , const TAO_Notify_Event_var& - , TAO_Notify_ProxySupplier*> TAO_Notify_Method_Request_Dispatch_No_Copy_Ex_Base; - -class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Dispatch_No_Copy_Ex : public TAO_Notify_Method_Request_Dispatch_No_Copy_Ex_Base - , public TAO_Notify_Method_Request_No_Copy +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Dispatch_No_Copy + : public TAO_Notify_Method_Request_Dispatch + , public TAO_Notify_Method_Request { public: - /// Constuctor - TAO_Notify_Method_Request_Dispatch_No_Copy_Ex (const TAO_Notify_Event_var& event, TAO_Notify_ProxySupplier* proxy_supplier, CORBA::Boolean filtering); + /// Constuct from event + TAO_Notify_Method_Request_Dispatch_No_Copy ( + const TAO_Notify_Event * event, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering); + + /// Constuct construct from another method request + TAO_Notify_Method_Request_Dispatch_No_Copy ( + const TAO_Notify_Method_Request_Event & request, + TAO_Notify_ProxySupplier* proxy_supplier, + bool filtering); /// Destructor - ~TAO_Notify_Method_Request_Dispatch_No_Copy_Ex (); + ~TAO_Notify_Method_Request_Dispatch_No_Copy (); /// Execute the Request virtual int execute (ACE_ENV_SINGLE_ARG_DECL); - /// Create a copy of this object. - virtual TAO_Notify_Method_Request* copy (ACE_ENV_SINGLE_ARG_DECL); + /// Create a copy of this method request + virtual TAO_Notify_Method_Request_Queueable* copy (ACE_ENV_SINGLE_ARG_DECL); }; +/*******************************************************************************************************/ + #if defined (__ACE_INLINE__) #include "Method_Request_Dispatch.inl" #endif /* __ACE_INLINE__ */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.inl b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.inl index cfa1da318d3..a694a8e0731 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch.inl @@ -1 +1,8 @@ // $Id$ +ACE_INLINE +const TAO_Notify_Event * +TAO_Notify_Method_Request_Event::event() const +{ + return this->event_; +} + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.cpp b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.cpp deleted file mode 100644 index 4fc841ccc78..00000000000 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// $Id$ -#ifndef TAO_Notify_Method_Request_Dispatch_T_CPP -#define TAO_Notify_Method_Request_Dispatch_T_CPP - -#include "Method_Request_Dispatch_T.h" - -#if ! defined (__ACE_INLINE__) -#include "Method_Request_Dispatch_T.inl" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID (Notify, - TAO_Notify_Method_Request_Dispatch_T, - "$Id$") - - -template <class EVENT, class PROXY, class EVENT_PARAM, class PROXY_PARAM> -TAO_Notify_Method_Request_Dispatch_T<EVENT, PROXY, EVENT_PARAM, PROXY_PARAM>::TAO_Notify_Method_Request_Dispatch_T (EVENT_PARAM event, PROXY_PARAM proxy_supplier, CORBA::Boolean filtering) - :event_ (event), proxy_supplier_ (proxy_supplier), filtering_ (filtering) -{ -} - -template <class EVENT, class PROXY, class EVENT_PARAM, class PROXY_PARAM> -TAO_Notify_Method_Request_Dispatch_T<EVENT, PROXY, EVENT_PARAM, PROXY_PARAM>::~TAO_Notify_Method_Request_Dispatch_T () -{ -} - -#endif /* TAO_Notify_Method_Request_Dispatch_T_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.h b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.h deleted file mode 100644 index 961db8c576b..00000000000 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- C++ -*- */ -/** - * @file Method_Request_Dispatch_T.h - * - * $Id$ - * - * @author Pradeep Gore <pradeep@oomworks.com> - * - * - */ - -#ifndef TAO_Notify_METHOD_REQUEST_DISPATCH_T_H -#define TAO_Notify_METHOD_REQUEST_DISPATCH_T_H - -#include /**/ "ace/pre.h" - -#include "notify_serv_export.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "tao/Basic_Types.h" - -#include "ace/CORBA_macros.h" - -/** - * @class TAO_Notify_Method_Request_Dispatch_T - * - * @brief - * - */ -template <class EVENT, class PROXY, class EVENT_PARAM, class PROXY_PARAM> -class TAO_Notify_Method_Request_Dispatch_T -{ -public: - /// Constuctor - TAO_Notify_Method_Request_Dispatch_T (EVENT_PARAM event, - PROXY_PARAM proxy, - CORBA::Boolean filtering); - - /// Destructor - virtual ~TAO_Notify_Method_Request_Dispatch_T (); - - /// Execute the dispatch operation. - int execute_i (ACE_ENV_SINGLE_ARG_DECL); - -protected: - /// The Event - EVENT event_; - - /// The Proxy - PROXY proxy_supplier_; - - /// Flag is true if we want to do fintering else false. - CORBA::Boolean filtering_; -}; - -#if defined (__ACE_INLINE__) -#include "Method_Request_Dispatch_T.inl" -#endif /* __ACE_INLINE__ */ - -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "Method_Request_Dispatch_T.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation ("Method_Request_Dispatch_T.cpp") -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ - -#include /**/ "ace/post.h" - -#endif /* TAO_Notify_METHOD_REQUEST_DISPATCH_T_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.inl b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.inl deleted file mode 100644 index 948d2595e1a..00000000000 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Dispatch_T.inl +++ /dev/null @@ -1,48 +0,0 @@ -// $Id$ - -#include "Admin.h" -#include "Consumer.h" -#include "tao/debug.h" - -template <class EVENT, class PROXY, class EVENT_PARAM, class PROXY_PARAM> ACE_INLINE int -TAO_Notify_Method_Request_Dispatch_T<EVENT, PROXY, EVENT_PARAM, PROXY_PARAM>::execute_i (ACE_ENV_SINGLE_ARG_DECL) -{ - if (this->proxy_supplier_->has_shutdown ()) - return 0; // If we were shutdown while waiting in the queue, return with no action. - - if (this->filtering_ == 1) - { - TAO_Notify_Admin* parent = this->proxy_supplier_->consumer_admin (); - - CORBA::Boolean val = this->proxy_supplier_->check_filters (this->event_, - parent->filter_admin (), - parent->filter_operator () - ACE_ENV_ARG_PARAMETER); - - if (TAO_debug_level > 1) - ACE_DEBUG ((LM_DEBUG, "Proxysupplier %x filter eval result = %d",&this->proxy_supplier_ , val)); - - // Filter failed - do nothing. - if (val == 0) - return 0; - } - - ACE_TRY - { - TAO_Notify_Consumer* consumer = this->proxy_supplier_->consumer (); - - if (consumer != 0) - { - consumer->push (this->event_ ACE_ENV_ARG_PARAMETER); - ACE_TRY_CHECK; - } - } - ACE_CATCHANY - { - if (TAO_debug_level > 0) - ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "TAO_Notify_Method_Request_Dispatch::: error sending event. \n "); - } - ACE_ENDTRY; - - return 0; -} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.cpp b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.cpp index 011b566cc2b..1bf474a8c12 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.cpp @@ -6,25 +6,98 @@ #include "Method_Request_Event.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID (Notify, TAO_Notify_Method_Request_Event, "$Id$") +#include "Delivery_Request.h" -TAO_Notify_Method_Request_Event::TAO_Notify_Method_Request_Event (const TAO_Notify_Event_var& event) - :event_ (event) +ACE_RCSID (Notify, TAO_Notify_Method_Request_Event_Queueable, "$Id$") + +TAO_Notify_Method_Request_Event::TAO_Notify_Method_Request_Event ( + const TAO_Notify_Event * event) + : event_ (event) { - this->init (event); } -TAO_Notify_Method_Request_Event::~TAO_Notify_Method_Request_Event () +TAO_Notify_Method_Request_Event::TAO_Notify_Method_Request_Event ( + const TAO_Notify::Delivery_Request_Ptr & request) + : event_ (request->event ().get ()) + , delivery_request_ (request) { } -int -TAO_Notify_Method_Request_Event::execute (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + +TAO_Notify_Method_Request_Event::TAO_Notify_Method_Request_Event ( + const TAO_Notify_Method_Request_Event & rhs, + const TAO_Notify_Event * event) + : event_ (event) + , delivery_request_ (rhs.delivery_request_) { - return -1; } -const TAO_Notify_Event_var& -TAO_Notify_Method_Request_Event::event (void) +TAO_Notify_Method_Request_Event::~TAO_Notify_Method_Request_Event() +{ +} + +const TAO_Notify_Event * TAO_Notify_Method_Request_Event::event() const +{ + return event_; +} + +void +TAO_Notify_Method_Request_Event::complete () +{ + if (this->delivery_request_.get () != 0) + { + this->delivery_request_->complete (); + } +} + + +unsigned long +TAO_Notify_Method_Request_Event::sequence () +{ + if (this->delivery_request_.get () != 0) + { + return this->delivery_request_->sequence (); + } + return 0; +} + +bool +TAO_Notify_Method_Request_Event::should_retry () { - return this->event_; + if (this->delivery_request_.get () != 0) + { + return this->delivery_request_->should_retry (); + } + return false; } + +/**********************************************************/ + + +TAO_Notify_Method_Request_Event_Queueable::TAO_Notify_Method_Request_Event_Queueable ( + const TAO_Notify_Method_Request_Event & prev_request, + const TAO_Notify_Event_var & event_var) + : TAO_Notify_Method_Request_Queueable (event_var.get ()) + , TAO_Notify_Method_Request_Event (prev_request, event_var.get ()) + , event_var_ (event_var) +{ +} + +TAO_Notify_Method_Request_Event_Queueable::TAO_Notify_Method_Request_Event_Queueable ( + TAO_Notify::Delivery_Request_Ptr & request) + : TAO_Notify_Method_Request_Queueable (request->event ().get ()) + , TAO_Notify_Method_Request_Event (request, request->event ().get ()) + , event_var_ (request->event ()) +{ +} + +TAO_Notify_Method_Request_Event_Queueable::~TAO_Notify_Method_Request_Event_Queueable () +{ +} + +int +TAO_Notify_Method_Request_Event_Queueable::execute (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + ACE_ASSERT (false); + return -1; +} + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.h b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.h index 2703fef2955..13707a77e72 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.h @@ -20,31 +20,81 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "Method_Request.h" +#include "Event.h" +#include "ProxySupplier.h" +#include "tao/Basic_Types.h" +#include "ace/CORBA_macros.h" +#include "Delivery_Request.h" /** * @class TAO_Notify_Method_Request_Event * - * @brief A method request for storing events. + * @brief A base class for all Method Requests that are associated with events. * */ -class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Event : public TAO_Notify_Method_Request +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Event { public: - /// Constuctor - TAO_Notify_Method_Request_Event (const TAO_Notify_Event_var& event); + /// Construct from event + TAO_Notify_Method_Request_Event (const TAO_Notify_Event *); + + /// Construct from a delivery request + TAO_Notify_Method_Request_Event ( + const TAO_Notify::Delivery_Request_Ptr & delivery_request); + + /// Construct from another Method Request + /// Event is passed separately because it may be a copy of the one in request. + TAO_Notify_Method_Request_Event (const TAO_Notify_Method_Request_Event & rhs, + const TAO_Notify_Event * event); +public: /// Destructor virtual ~TAO_Notify_Method_Request_Event (); - /// Execute the Request - virtual int execute (ACE_ENV_SINGLE_ARG_DECL); - - /// Obtain the event. - const TAO_Notify_Event_var& event (void); + const TAO_Notify_Event * event() const; + void complete (); + unsigned long sequence (); + bool should_retry (); protected: - /// The event. - const TAO_Notify_Event_var event_; + + /// The Event + const TAO_Notify_Event * event_; + + /// Pointer to the routing slip's delivery request (if any) + TAO_Notify::Delivery_Request_Ptr delivery_request_; +}; + +/***************************************************************/ + +/** + * @class TAO_Notify_Method_Request_Event_Queueable + * + * @brief A method request for storing events. + * + */ +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Event_Queueable + : public TAO_Notify_Method_Request_Queueable + , public TAO_Notify_Method_Request_Event +{ +public: + /// Constuctor + /// Not the event_var is passed as a separate parameter to avoid throwing + /// exceptions from the constructor if it's necessary to copy the event. + TAO_Notify_Method_Request_Event_Queueable ( + const TAO_Notify_Method_Request_Event & prev_request, + const TAO_Notify_Event_var & event_var); + + TAO_Notify_Method_Request_Event_Queueable ( + TAO_Notify::Delivery_Request_Ptr & request); + + /// Destructor + virtual ~TAO_Notify_Method_Request_Event_Queueable (); + + /// satisfy the pure virtual method. Should never be called. + virtual int execute (ACE_ENV_SINGLE_ARG_DECL); +private: + TAO_Notify_Event_var event_var_; }; #if defined (__ACE_INLINE__) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.inl b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.inl index 594304747ec..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Event.inl @@ -1,3 +1,2 @@ // $Id$ -#include "Method_Request_Event.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup.cpp b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup.cpp index a99adabdb47..b038d2d84f4 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup.cpp @@ -15,27 +15,182 @@ ACE_RCSID(Notify, TAO_Notify_Method_Request_Lookup, "$Id$") #include "Proxy.h" #include "Admin.h" #include "SupplierAdmin.h" - -TAO_Notify_Method_Request_Lookup::TAO_Notify_Method_Request_Lookup (const TAO_Notify_Event_var& event, TAO_Notify_ProxyConsumer* proxy_consumer) - : TAO_Notify_Method_Request_Lookup_Base (event, proxy_consumer) +#include "Event_Manager.h" +#include "Method_Request_Dispatch.h" +#include "Delivery_Request.h" +#include "EventChannelFactory.h" + +TAO_Notify_Method_Request_Lookup::TAO_Notify_Method_Request_Lookup ( + const TAO_Notify_Event * event, + TAO_Notify_ProxyConsumer * proxy) + : TAO_Notify_Method_Request_Event (event) + , proxy_consumer_ (proxy) { - this->init (event); } TAO_Notify_Method_Request_Lookup::~TAO_Notify_Method_Request_Lookup () { } +void +TAO_Notify_Method_Request_Lookup::work ( + TAO_Notify_ProxySupplier* proxy_supplier + ACE_ENV_ARG_DECL) +{ + if (delivery_request_.get () == 0) + { + TAO_Notify_Method_Request_Dispatch_No_Copy request (*this, proxy_supplier, true); + proxy_supplier->deliver (request ACE_ENV_ARG_PARAMETER); + } + else + { + delivery_request_->dispatch (proxy_supplier, true ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +} + +int TAO_Notify_Method_Request_Lookup::execute_i (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->proxy_consumer_->has_shutdown ()) + return 0; // If we were shutdown while waiting in the queue, return with no action. + + TAO_Notify_SupplierAdmin* parent = this->proxy_consumer_->supplier_admin (); + + CORBA::Boolean val = this->proxy_consumer_->check_filters (this->event_, + parent->filter_admin (), + parent->filter_operator () + ACE_ENV_ARG_PARAMETER); + + if (TAO_debug_level > 1) + ACE_DEBUG ((LM_DEBUG, "Proxyconsumer %x filter eval result = %d",&this->proxy_consumer_ , val)); + + // Filter failed - do nothing. + if (val == 0) + return 0; + + // The map of subscriptions. + TAO_Notify_Consumer_Map* map = this->proxy_consumer_->event_manager ()->consumer_map (); + + TAO_Notify_Consumer_Map::ENTRY* entry = map->find (this->event_->type () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + TAO_Notify_ProxySupplier_Collection* consumers = 0; + + if (entry != 0) + { + consumers = entry->collection (); + + if (consumers != 0) + consumers->for_each (this ACE_ENV_ARG_PARAMETER); + + map->release (entry); + } + + // Get the default consumers + consumers = map->broadcast_collection (); + + if (consumers != 0) + consumers->for_each (this ACE_ENV_ARG_PARAMETER); + this->complete (); + return 0; +} + +/// Static method used to reconstruct a Method Request Dispatch +TAO_Notify_Method_Request_Lookup_Queueable * +TAO_Notify_Method_Request_Lookup::unmarshal ( + TAO_Notify::Delivery_Request_Ptr & delivery_request, + TAO_Notify_EventChannelFactory &ecf, + TAO_InputCDR & cdr + ACE_ENV_ARG_DECL) +{ + bool ok = true; + TAO_Notify_Method_Request_Lookup_Queueable * result = 0; + CORBA::ULong count; + if (cdr.read_ulong (count)) + { + TAO_Notify::IdVec id_path (count); + for (size_t nid = 0; ok && nid < count; ++nid) + { + TAO_Notify_Object::ID id = 0; + if ( cdr.read_long (id)) + { + id_path.push_back (id); + } + else + { + ok = false; + } + } + + if (ok) + { + TAO_Notify_ProxyConsumer * proxy_consumer = ecf.find_proxy_consumer ( + id_path, + 0 ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + if (proxy_consumer != 0) + { + ACE_NEW_NORETURN (result, + TAO_Notify_Method_Request_Lookup_Queueable (delivery_request, proxy_consumer)); + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Method_Request_Lookup_No_Copy::unmarshal: unknown proxy id\n") + )); + } + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) TAO_Notify_Method_Request_Lookup_No_Copy::unmarshal: Cant read proxy id path\n") + )); + } + } + return result; + +} + + +/****************************************************************/ + +TAO_Notify_Method_Request_Lookup_Queueable::TAO_Notify_Method_Request_Lookup_Queueable ( + const TAO_Notify_Event_var& event, + TAO_Notify_ProxyConsumer* proxy_consumer) + : TAO_Notify_Method_Request_Lookup (event.get (), proxy_consumer) + , TAO_Notify_Method_Request_Queueable (event.get ()) + , event_var_ (event) + , proxy_guard_ (proxy_consumer) +{ +} + +TAO_Notify_Method_Request_Lookup_Queueable::TAO_Notify_Method_Request_Lookup_Queueable ( + TAO_Notify::Delivery_Request_Ptr & request, + TAO_Notify_ProxyConsumer * proxy_consumer) + : TAO_Notify_Method_Request_Lookup (request->event ().get (), proxy_consumer) + , TAO_Notify_Method_Request_Queueable (request->event ().get ()) + , event_var_ (request->event ()) + , proxy_guard_ (proxy_consumer) +{ +} + + +TAO_Notify_Method_Request_Lookup_Queueable::~TAO_Notify_Method_Request_Lookup_Queueable () +{ +} + int -TAO_Notify_Method_Request_Lookup::execute (ACE_ENV_SINGLE_ARG_DECL) +TAO_Notify_Method_Request_Lookup_Queueable::execute (ACE_ENV_SINGLE_ARG_DECL) { return this->execute_i (ACE_ENV_SINGLE_ARG_PARAMETER); } /******************************************************************************************************/ -TAO_Notify_Method_Request_Lookup_No_Copy::TAO_Notify_Method_Request_Lookup_No_Copy (const TAO_Notify_Event* event, TAO_Notify_ProxyConsumer* proxy_consumer) - : TAO_Notify_Method_Request_Lookup_No_Copy_Base (event, proxy_consumer) +TAO_Notify_Method_Request_Lookup_No_Copy::TAO_Notify_Method_Request_Lookup_No_Copy ( + const TAO_Notify_Event* event, + TAO_Notify_ProxyConsumer* proxy_consumer) + : TAO_Notify_Method_Request_Lookup (event, proxy_consumer) { } @@ -49,23 +204,22 @@ TAO_Notify_Method_Request_Lookup_No_Copy::execute (ACE_ENV_SINGLE_ARG_DECL) return this->execute_i (ACE_ENV_SINGLE_ARG_PARAMETER); } -TAO_Notify_Method_Request* +TAO_Notify_Method_Request_Queueable* TAO_Notify_Method_Request_Lookup_No_Copy::copy (ACE_ENV_SINGLE_ARG_DECL) { - TAO_Notify_Method_Request* request; + TAO_Notify_Method_Request_Queueable* request; - TAO_Notify_Event* event_copy = this->event_->copy (ACE_ENV_SINGLE_ARG_PARAMETER); + TAO_Notify_Event_var event_var; + this->event_->queueable_copy (event_var ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - TAO_Notify_Event_Copy_var event_var (event_copy); - ACE_NEW_THROW_EX (request, - TAO_Notify_Method_Request_Lookup (event_var, this->proxy_consumer_), + TAO_Notify_Method_Request_Lookup_Queueable (event_var, this->proxy_consumer_), CORBA::INTERNAL ()); return request; } - +#if 0 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class TAO_Notify_Method_Request_Lookup_T<const TAO_Notify_Event_var @@ -89,5 +243,5 @@ template class TAO_Notify_Method_Request_Lookup_T<const TAO_Notify_Event* , TAO_Notify_ProxyConsumer* , const TAO_Notify_Event* , TAO_Notify_ProxyConsumer*> - +#endif #endif /*ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup.h b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup.h index 42bb57b38e7..89d9b8f6c1b 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup.h @@ -20,57 +20,107 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "orbsvcs/ESF/ESF_Worker.h" -#include "Method_Request.h" +#include "Method_Request_Event.h" +#include "ProxySupplier.h" #include "ProxyConsumer.h" #include "Consumer_Map.h" -#include "Method_Request_Lookup_T.h" +#include "Delivery_Request.h" -class TAO_Notify_ProxyConsumer; - -typedef TAO_Notify_Method_Request_Lookup_T<const TAO_Notify_Event_var - , TAO_Notify_ProxyConsumer_Guard - , const TAO_Notify_Event_var& - , TAO_Notify_ProxyConsumer*> TAO_Notify_Method_Request_Lookup_Base; +class TAO_Notify_Method_Request_Lookup_Queueable; +class TAO_Notify_Event; /** * @class TAO_Notify_Method_Request_Lookup * - * @brief Lookup command object looks up the event type of the given event in the consumer map and send the event to each proxysupplier. + * @brief * */ -class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Lookup : public TAO_Notify_Method_Request_Lookup_Base - , public TAO_Notify_Method_Request +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Lookup + : public TAO_ESF_Worker<TAO_Notify_ProxySupplier> + , public TAO_Notify_Method_Request_Event { public: + + /// an arbitrary code (Octet) to identify this type of request in persistent storage + enum {persistence_code = 2}; + + /// Destructor + virtual ~TAO_Notify_Method_Request_Lookup (); + + /// Static method used to reconstruct a Method Request Dispatch + static TAO_Notify_Method_Request_Lookup_Queueable * unmarshal ( + TAO_Notify::Delivery_Request_Ptr & delivery_request, + TAO_Notify_EventChannelFactory &ecf, + TAO_InputCDR & cdr + ACE_ENV_ARG_DECL); + +protected: /// Constuctor - TAO_Notify_Method_Request_Lookup (const TAO_Notify_Event_var& event, TAO_Notify_ProxyConsumer* proxy_consumer); + TAO_Notify_Method_Request_Lookup (const TAO_Notify_Event * event, TAO_Notify_ProxyConsumer * proxy); + + /// Execute the dispatch operation. + int execute_i (ACE_ENV_SINGLE_ARG_DECL); + + ///= TAO_ESF_Worker method + virtual void work (TAO_Notify_ProxySupplier* proxy_supplier ACE_ENV_ARG_DECL); + +protected: + + /// The Proxy + TAO_Notify_ProxyConsumer* proxy_consumer_; +}; + +/***************************************************************/ + +/** + * @class TAO_Notify_Method_Request_Lookup_Queueable + * + * @brief Lookup command object looks up the event type of the given event in the consumer map and send the event to each proxysupplier. + * + */ +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Lookup_Queueable + : public TAO_Notify_Method_Request_Lookup + , public TAO_Notify_Method_Request_Queueable +{ +public: + /// Constuctor from event + TAO_Notify_Method_Request_Lookup_Queueable ( + const TAO_Notify_Event_var& event, + TAO_Notify_ProxyConsumer * proxy_consumer); + + /// Constuctor from delivery request + TAO_Notify_Method_Request_Lookup_Queueable ( + TAO_Notify::Delivery_Request_Ptr & request, + TAO_Notify_ProxyConsumer * proxy_consumer); /// Destructor - ~TAO_Notify_Method_Request_Lookup (); + ~TAO_Notify_Method_Request_Lookup_Queueable (); /// Execute the Request virtual int execute (ACE_ENV_SINGLE_ARG_DECL); + +private: + const TAO_Notify_Event_var event_var_; + TAO_Notify_ProxyConsumer_Guard proxy_guard_; }; /*****************************************************************************************************************************/ -typedef TAO_Notify_Method_Request_Lookup_T<const TAO_Notify_Event* - , TAO_Notify_ProxyConsumer* - , const TAO_Notify_Event* - , TAO_Notify_ProxyConsumer*> TAO_Notify_Method_Request_Lookup_No_Copy_Base; - /** * @class TAO_Notify_Method_Request_Lookup_No_Copy * * @brief Lookup command object looks up the event type of the given event in the consumer map and send the event to each proxysupplier. * */ -class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Lookup_No_Copy : public TAO_Notify_Method_Request_Lookup_No_Copy_Base - , public TAO_Notify_Method_Request_No_Copy +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Lookup_No_Copy + : public TAO_Notify_Method_Request_Lookup + , public TAO_Notify_Method_Request { public: /// Constuctor - TAO_Notify_Method_Request_Lookup_No_Copy (const TAO_Notify_Event* event, TAO_Notify_ProxyConsumer* proxy_consumer); + TAO_Notify_Method_Request_Lookup_No_Copy ( + const TAO_Notify_Event* event, + TAO_Notify_ProxyConsumer* proxy_consumer); /// Destructor ~TAO_Notify_Method_Request_Lookup_No_Copy (); @@ -79,7 +129,7 @@ public: virtual int execute (ACE_ENV_SINGLE_ARG_DECL); /// Create a copy of this object. - virtual TAO_Notify_Method_Request* copy (ACE_ENV_SINGLE_ARG_DECL); + virtual TAO_Notify_Method_Request_Queueable* copy (ACE_ENV_SINGLE_ARG_DECL); }; #if defined (__ACE_INLINE__) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.cpp b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.cpp deleted file mode 100644 index 9492aba6155..00000000000 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// $Id$ -#ifndef TAO_Notify_Method_Request_Lookup_T_CPP -#define TAO_Notify_Method_Request_Lookup_T_CPP - -#include "Method_Request_Lookup_T.h" - -#if ! defined (__ACE_INLINE__) -#include "Method_Request_Lookup_T.inl" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID (Notify, TAO_Notify_Method_Request_Lookup_T, "$Id$") - -template <class EVENT, class PROXY, class EVENT_PARAM, class PROXY_PARAM> -TAO_Notify_Method_Request_Lookup_T<EVENT, PROXY, EVENT_PARAM, PROXY_PARAM>::TAO_Notify_Method_Request_Lookup_T (EVENT_PARAM event, PROXY_PARAM proxy_consumer) - :event_ (event), proxy_consumer_ (proxy_consumer) -{ -} - -template <class EVENT, class PROXY, class EVENT_PARAM, class PROXY_PARAM> -TAO_Notify_Method_Request_Lookup_T<EVENT, PROXY, EVENT_PARAM, PROXY_PARAM>::~TAO_Notify_Method_Request_Lookup_T () -{ -} - - -template <class EVENT, class PROXY, class EVENT_PARAM, class PROXY_PARAM> void -TAO_Notify_Method_Request_Lookup_T<EVENT, PROXY, EVENT_PARAM, PROXY_PARAM>::work (TAO_Notify_ProxySupplier* proxy_supplier ACE_ENV_ARG_DECL) -{ - proxy_supplier->push (this->event_ ACE_ENV_ARG_PARAMETER); -} - -#endif /* TAO_Notify_Method_Request_Lookup_T_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.h b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.h deleted file mode 100644 index f9f830b5d3e..00000000000 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- C++ -*- */ -/** - * @file Method_Request_Lookup_T.h - * - * $Id$ - * - * @author Pradeep Gore <pradeep@oomworks.com> - * - * - */ - -#ifndef TAO_Notify_METHOD_REQUEST_LOOKUP_T_H -#define TAO_Notify_METHOD_REQUEST_LOOKUP_T_H -#include /**/ "ace/pre.h" - -#include "notify_serv_export.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "orbsvcs/ESF/ESF_Worker.h" -#include "ProxySupplier.h" - -/** - * @class TAO_Notify_Method_Request_Lookup_T - * - * @brief - * - */ -template <class EVENT, class PROXY, class EVENT_PARAM, class PROXY_PARAM> -class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Lookup_T : public TAO_ESF_Worker<TAO_Notify_ProxySupplier> -{ -public: - /// Constuctor - TAO_Notify_Method_Request_Lookup_T (EVENT_PARAM event, PROXY_PARAM proxy); - - /// Destructor - virtual ~TAO_Notify_Method_Request_Lookup_T (); - - /// Execute the dispatch operation. - int execute_i (ACE_ENV_SINGLE_ARG_DECL); - -protected: - ///= TAO_ESF_Worker method - virtual void work (TAO_Notify_ProxySupplier* proxy_supplier ACE_ENV_ARG_DECL); - - /// The Event - EVENT event_; - - /// The Proxy - PROXY proxy_consumer_; -}; - -#if defined (__ACE_INLINE__) -#include "Method_Request_Lookup_T.inl" -#endif /* __ACE_INLINE__ */ - -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "Method_Request_Lookup_T.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation ("Method_Request_Lookup_T.cpp") -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ - -#include /**/ "ace/post.h" -#endif /* TAO_Notify_METHOD_REQUEST_LOOKUP_T_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.inl b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.inl deleted file mode 100644 index 4367a6ca8e8..00000000000 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Lookup_T.inl +++ /dev/null @@ -1,51 +0,0 @@ -// $Id$ - -#include "tao/debug.h" -#include "Event_Manager.h" - -template <class EVENT, class PROXY, class EVENT_PARAM, class PROXY_PARAM> ACE_INLINE int -TAO_Notify_Method_Request_Lookup_T<EVENT, PROXY, EVENT_PARAM, PROXY_PARAM>::execute_i (ACE_ENV_SINGLE_ARG_DECL) -{ - if (this->proxy_consumer_->has_shutdown ()) - return 0; // If we were shutdown while waiting in the queue, return with no action. - - TAO_Notify_Admin* parent = this->proxy_consumer_->supplier_admin (); - - CORBA::Boolean val = this->proxy_consumer_->check_filters (this->event_, - parent->filter_admin (), - parent->filter_operator () - ACE_ENV_ARG_PARAMETER); - - if (TAO_debug_level > 1) - ACE_DEBUG ((LM_DEBUG, "Proxyconsumer %x filter eval result = %d",&this->proxy_consumer_ , val)); - - // Filter failed - do nothing. - if (val == 0) - return 0; - - // The map of subscriptions. - TAO_Notify_Consumer_Map* map = this->proxy_consumer_->event_manager ()->consumer_map (); - - TAO_Notify_Consumer_Map::ENTRY* entry = map->find (this->event_->type () ACE_ENV_ARG_PARAMETER); - ACE_CHECK_RETURN (0); - - TAO_Notify_ProxySupplier_Collection* consumers = 0; - - if (entry != 0) - { - consumers = entry->collection (); - - if (consumers != 0) - consumers->for_each (this ACE_ENV_ARG_PARAMETER); - - map->release (entry); - } - - // Get the default consumers - consumers = map->broadcast_collection (); - - if (consumers != 0) - consumers->for_each (this ACE_ENV_ARG_PARAMETER); - - return 0; -} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.cpp b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.cpp index f0d82aee866..5fb9c39aca9 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.cpp @@ -18,7 +18,7 @@ TAO_Notify_Method_Request_Shutdown::~TAO_Notify_Method_Request_Shutdown () { } -TAO_Notify_Method_Request* +TAO_Notify_Method_Request_Queueable* TAO_Notify_Method_Request_Shutdown::copy (void) { return new TAO_Notify_Method_Request_Shutdown (this->task_); diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.h b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.h index 2491f9c2862..0144d188451 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Shutdown.h @@ -29,7 +29,7 @@ class TAO_Notify_ThreadPool_Task; * @brief Shutdown message for the ThreadPool_Task * */ -class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Shutdown : public TAO_Notify_Method_Request +class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Shutdown : public TAO_Notify_Method_Request_Queueable { public: /// Constuctor @@ -39,7 +39,7 @@ public: ~TAO_Notify_Method_Request_Shutdown (); /// Create a copy of this object. - TAO_Notify_Method_Request* copy (void); + TAO_Notify_Method_Request_Queueable* copy (void); /// Execute the Request virtual int execute (ACE_ENV_SINGLE_ARG_DECL); diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Updates.cpp b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Updates.cpp index 231af05e8d2..48b5c3fe4ea 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Updates.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Updates.cpp @@ -39,10 +39,10 @@ TAO_Notify_Method_Request_Updates_No_Copy::~TAO_Notify_Method_Request_Updates_No { } -TAO_Notify_Method_Request* +TAO_Notify_Method_Request_Queueable* TAO_Notify_Method_Request_Updates_No_Copy::copy (ACE_ENV_SINGLE_ARG_DECL) { - TAO_Notify_Method_Request* request; + TAO_Notify_Method_Request_Queueable* request; ACE_NEW_THROW_EX (request, TAO_Notify_Method_Request_Updates (this->added_, this->removed_, this->proxy_), diff --git a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Updates.h b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Updates.h index 25943a091de..def6c4efdaf 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Updates.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Method_Request_Updates.h @@ -37,7 +37,7 @@ typedef TAO_Notify_Method_Request_Updates_T<const TAO_Notify_EventTypeSeq * */ class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Updates : public TAO_Notify_Method_Request_Updates_Base - ,public TAO_Notify_Method_Request + ,public TAO_Notify_Method_Request_Queueable { public: /// Constuctor @@ -65,7 +65,7 @@ typedef TAO_Notify_Method_Request_Updates_T<const TAO_Notify_EventTypeSeq& * */ class TAO_Notify_Serv_Export TAO_Notify_Method_Request_Updates_No_Copy : public TAO_Notify_Method_Request_Updates_No_Copy_Base - ,public TAO_Notify_Method_Request_No_Copy + ,public TAO_Notify_Method_Request { public: /// Constuctor @@ -75,7 +75,7 @@ public: ~TAO_Notify_Method_Request_Updates_No_Copy (); /// Create a copy of this object. - virtual TAO_Notify_Method_Request* copy (ACE_ENV_SINGLE_ARG_DECL); + virtual TAO_Notify_Method_Request_Queueable* copy (ACE_ENV_SINGLE_ARG_DECL); /// Execute the Request virtual int execute (ACE_ENV_SINGLE_ARG_DECL); diff --git a/TAO/orbsvcs/orbsvcs/Notify/Name_Value_Pair.cpp b/TAO/orbsvcs/orbsvcs/Notify/Name_Value_Pair.cpp new file mode 100644 index 00000000000..0fd7509d890 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Name_Value_Pair.cpp @@ -0,0 +1,227 @@ +// $Id$ + +#include "Name_Value_Pair.h" + +#if ! defined (__ACE_INLINE__) +#include "Name_Value_Pair.inl" +#endif /* __ACE_INLINE__ */ + +#include "Property_T.h" +#include "ace/OS_String.h" +#include "ace/OS_NS_stdio.h" + +namespace +{ + ACE_UINT64 string_to_uint64(const char * s) + { + size_t len = ACE_OS::strlen (s); + if (len == 0) + return 0; + if (! isdigit(s[0])) + return 0; + + ACE_UINT64 t = 0; + for (size_t i = 0; i < len; ++i) + { + if (isdigit(s[i]) == 0) + { + break; + } + t *= 10; + t += (s[i] - '0'); + } + return t; + } +} + +namespace TAO_Notify +{ + NVP::NVP() + { + } + + NVP::NVP(const TAO_Notify_Property_Short& p) + : name(p.name()) + { + char buf[64]; + ACE_OS::sprintf (buf, "%d", p.value ()); + value = buf; + } + + NVP::NVP(const TAO_Notify_Property_Long& p) + : name(p.name()) + { + char buf[64]; + long temp = ACE_static_cast (long, p.value ()); + ACE_OS::sprintf (buf, "%ld", temp); + value = buf; + } + + NVP::NVP(const TAO_Notify_Property_Time& p) + : name(p.name()) + { + char buf[128]; + ACE_UINT64 us = p.value(); +#ifdef ACE_LACKS_LONGLONG_T + us.as_string(buf); +#else + ACE_OS::sprintf(buf, ACE_UINT64_FORMAT_SPECIFIER, us); +#endif /* ACE_LACKS_LONGLONG_T */ + value = buf; + } + + NVP::NVP(const TAO_Notify_Property_Boolean& p) + : name(p.name()) + { + value = p.value() ? "true" : "false"; + } + + NVP::NVP(const char * n, CORBA::Long v) + : name(n) + { + char buf[64]; + long temp = v; + ACE_OS::sprintf (buf, "%ld", temp); + value = buf; + } + + NVP::NVP(const char * n, const char * v) + : name(n), value(v) + { + } + + NVP::NVP(const char * n, const ACE_CString & v) + : name(n), value(v) + { + } + + bool NVP::operator==(const NVP& rhs) const + { + return (this->name == rhs.name) != 0; + } + + bool NVP::operator!=(const NVP& rhs) const + { + return ! (rhs == *this); + } + + bool NVPList::find (const char * name, ACE_CString& val) const + { + for (size_t i = 0; i < list_.size(); ++i) + { + if (list_[i].name == name) + { + val = list_[i].value; + return true; + } + } + return false; + } + + bool NVPList::find (const char * name, const char *& val) const + { + for (size_t i = 0; i < list_.size(); ++i) + { + if (list_[i].name == name) + { + val = list_[i].value.c_str (); + return true; + } + } + return false; + } + + void NVPList::load(TAO_Notify_Property_Short& p) const + { + const char * v; + if (find(p.name(), v)) + { + p.assign (static_cast<CORBA::Short> (ACE_OS::atoi(v))); + } + } + + void NVPList::load(TAO_Notify_Property_Long& p) const + { + const char * v; + if (find(p.name(), v)) + { + p.assign (static_cast<CORBA::Long> (ACE_OS::atoi(v))); + } + } + + void NVPList::load(TAO_Notify_Property_Time& p) const + { + const char * v; + if (find(p.name (), v)) + { + p.assign (ACE_static_cast(TimeBase::TimeT, string_to_uint64(v))); + } + } + + void NVPList::load(TAO_Notify_Property_Boolean& p) const + { + ACE_CString v; + if (find(p.name (), v)) + { + if (v == "true") + { + p = 1; + } + else + { + p = 0; + } + } + } + + bool NVPList::load(const char * n, CORBA::Long& v) const + { + const char * val; + if (find(n, val)) + { + v = ACE_static_cast(CORBA::Long, ACE_OS::atoi(val)); + return true; + } + return false; + } + + bool NVPList::load(const char * n, ACE_CString& v) const + { + return find(n, v); + } + + void NVPList::push_back(const NVP& v) + { + for (size_t i = 0; i < list_.size(); ++i) + { + if (list_[i].name == v.name) + { + list_[i].value = v.value; + return; + } + } + list_.push_back(v); + } + + size_t NVPList::size() const + { + return list_.size(); + } + + const NVP& NVPList::operator[](size_t ndx) const + { + ACE_ASSERT(ndx < list_.size()); + return list_[ndx]; + } + +} // namespace TAO_Notify + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Array_Base<TAO_Notify::NVP>; +template class ACE_Array<TAO_Notify::NVP>; +template class ACE_Vector<TAO_Notify::NVP>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Array_Base<TAO_Notify::NVP> +#pragma instantiate ACE_Array<TAO_Notify::NVP> +#pragma instantiate ACE_Vector<TAO_Notify::NVP> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Name_Value_Pair.h b/TAO/orbsvcs/orbsvcs/Notify/Name_Value_Pair.h new file mode 100644 index 00000000000..0b569a7e77c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Name_Value_Pair.h @@ -0,0 +1,102 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** +* @file Name_Value_Pair.h +* +* $Id$ +* +* @author Jonathan Pollack <pollack_j@ociweb.com> +*/ +//============================================================================= + +#ifndef NAME_VALUE_PAIR_H +#define NAME_VALUE_PAIR_H +#include /**/ "ace/pre.h" + +#include "Property.h" +#include "Property_Boolean.h" +#include "notify_serv_export.h" + +#include "ace/SString.h" +#include "ace/Vector_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + /** + * \brief Name/Value Pair + * + * Associates a name (character string) with a value (encoded into a character string) + * For use in managing properties. + */ + class TAO_Notify_Serv_Export NVP { + public: + /// Construct an undefined name/value (to allow use in collections) + NVP(); + /// Construct from a property containing a short value. + explicit NVP(const TAO_Notify_Property_Short& p); + /// Construct from a property containing a long value. + explicit NVP(const TAO_Notify_Property_Long& p); + /// Construct from a property containing a time value + explicit NVP(const TAO_Notify_Property_Time& p); + /// Construct from a property containing a boolean value + explicit NVP(const TAO_Notify_Property_Boolean& p); + + /// Construct from name and long value. + NVP(const char * n, CORBA::Long v); + /// Construct from name and string value. + NVP(const char * n, const char * v); + /// Construct from name and string value. + NVP(const char * n, const ACE_CString & v); + + /// Assignment operator + bool operator==(const NVP& rhs) const; + /// Comparison operator compares only name (not value) + bool operator!=(const NVP& rhs) const; + ACE_CString name; + ACE_CString value; + }; + + /** + * \brief Collection of Name/Value Pairs + */ + class TAO_Notify_Serv_Export NVPList { + public: + /// Find the NVP with the same name as the property, copy the value. + void load(TAO_Notify_Property_Short& p) const; + /// Find the NVP with the same name as the property, copy the value. + void load(TAO_Notify_Property_Long& p) const; + /// Find the NVP with the same name as the property, copy the value. + void load(TAO_Notify_Property_Time& p) const; + /// Find the NVP with the same name as the property, copy the value. + void load(TAO_Notify_Property_Boolean& p) const; + /// Find the NVP with specified name, copy the value to a string. + bool load(const char * n, CORBA::Long& v) const; + /// Find the NVP with specified name, copy the value to a long. + bool load(const char * n, ACE_CString& v) const; + /// add a new name/value pair. + void push_back(const NVP& v); + /// size of the collection. + size_t size() const; + /// access NVP via numeric index. + const NVP& operator[](size_t ndx) const; + /// low level access: find + bool find (const char * name, ACE_CString& val) const; + /// low level access: use this when you don't need a CString + bool find (const char * name, const char *& val) const; + + private: + ACE_Vector<NVP> list_; + }; +} // namespace TAO_Notify + +#if defined (__ACE_INLINE__) +#include "Name_Value_Pair.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* NAME_VALUE_PAIR_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Name_Value_Pair.inl b/TAO/orbsvcs/orbsvcs/Notify/Name_Value_Pair.inl new file mode 100644 index 00000000000..cfa1da318d3 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Name_Value_Pair.inl @@ -0,0 +1 @@ +// $Id$ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Object.cpp b/TAO/orbsvcs/orbsvcs/Notify/Object.cpp index 49c9b9b07a1..61c305edb6d 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Object.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Object.cpp @@ -15,6 +15,8 @@ ACE_RCSID(Notify, TAO_Notify_Object, "$Id$") + + TAO_Notify_Object::TAO_Notify_Object (void) : event_manager_ (0) , admin_properties_ (0) @@ -66,6 +68,18 @@ TAO_Notify_Object::activate (PortableServer::Servant servant ACE_ENV_ARG_DECL) return this->poa_->activate (servant, this->id_ ACE_ENV_ARG_PARAMETER); } +/// Activate with existing id +CORBA::Object_ptr +TAO_Notify_Object::activate ( + PortableServer::Servant servant, + CORBA::Long id + ACE_ENV_ARG_DECL) +{ + this->id_ = id; + return this->poa_->activate_with_id (servant, this->id_ ACE_ENV_ARG_PARAMETER); +} + + void TAO_Notify_Object::deactivate (ACE_ENV_SINGLE_ARG_DECL) { @@ -77,10 +91,10 @@ TAO_Notify_Object::deactivate (ACE_ENV_SINGLE_ARG_DECL) ACE_CATCHANY { if (TAO_debug_level > 2) - { - ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "(%P|%t)\n"); - ACE_DEBUG ((LM_DEBUG, "Could not deactivate object %d\n", this->id_)); - } + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "(%P|%t)\n"); + ACE_DEBUG ((LM_DEBUG, "Could not deactivate object %d\n", this->id_)); + } // Do not propagate any exceptions } ACE_ENDTRY; @@ -133,7 +147,7 @@ TAO_Notify_Object::shutdown_proxy_poa (void) { this->proxy_poa_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + delete this->proxy_poa_; } ACE_CATCHANY @@ -268,6 +282,15 @@ TAO_Notify_Object::get_qos (ACE_ENV_SINGLE_ARG_DECL) return properties._retn (); } +bool +TAO_Notify_Object::find_qos_property_value ( + const char * name, + CosNotification::PropertyValue & value) const +{ + return this->qos_properties_.find (name, value); +} + + void TAO_Notify_Object::qos_changed (const TAO_Notify_QoSProperties& /*qos_properties*/) { @@ -279,3 +302,60 @@ TAO_Notify_Object::timer (void) { return this->worker_task_->timer (); } + +namespace { + template<class T> + void add_qos_attr(TAO_Notify::NVPList& attrs, const T& prop) { + if (prop.is_valid()) + { + attrs.push_back(TAO_Notify::NVP (prop)); + } + } +// Note : These instantiations have to be here because each namespace {} +// is unique. +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template void add_qos_attr<TAO_Notify_Property_Boolean>( + TAO_Notify::NVPList&, const TAO_Notify_Property_Boolean&); +template void add_qos_attr<TAO_Notify_Property_T<int> >( + TAO_Notify::NVPList&, const TAO_Notify_Property_T<int>&); +template void add_qos_attr<TAO_Notify_Property_T<unsigned long long> >( + TAO_Notify::NVPList&, const TAO_Notify_Property_T<unsigned long long>&); +template void add_qos_attr<TAO_Notify_Property_T<short> >( + TAO_Notify::NVPList&, const TAO_Notify_Property_T<short>&); +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate void add_qos_attr<TAO_Notify_Property_Boolean>(\ + TAO_Notify::NVPList&, const TAO_Notify_Property_Boolean&) +#pragma instantiate void add_qos_attr<TAO_Notify_Property_T<int> >(\ + TAO_Notify::NVPList&, const TAO_Notify_Property_T<int>&) +#pragma instantiate void add_qos_attr<TAO_Notify_Property_T<unsigned long long> >(\ + TAO_Notify::NVPList&, const TAO_Notify_Property_T<unsigned long long>&) +#pragma instantiate void add_qos_attr<TAO_Notify_Property_T<short> >(\ + TAO_Notify::NVPList&, const TAO_Notify_Property_T<short>&) +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ +} // namespace + +void +TAO_Notify_Object::save_attrs (TAO_Notify::NVPList& attrs) +{ + add_qos_attr(attrs, this->qos_properties_.event_reliability ()); + add_qos_attr(attrs, this->qos_properties_.connection_reliability ()); + add_qos_attr(attrs, this->qos_properties_.priority ()); + add_qos_attr(attrs, this->qos_properties_.timeout ()); + add_qos_attr(attrs, this->qos_properties_.stop_time_supported ()); + add_qos_attr(attrs, this->qos_properties_.maximum_batch_size ()); + add_qos_attr(attrs, this->qos_properties_.pacing_interval ()); +} + +void +TAO_Notify_Object::load_attrs(const TAO_Notify::NVPList& attrs) +{ + attrs.load (this->qos_properties_.event_reliability ()); + attrs.load (this->qos_properties_.connection_reliability ()); + attrs.load (this->qos_properties_.priority ()); + attrs.load (this->qos_properties_.timeout ()); + attrs.load (this->qos_properties_.stop_time_supported ()); + attrs.load (this->qos_properties_.maximum_batch_size ()); + attrs.load (this->qos_properties_.pacing_interval ()); + this->qos_properties_.init (); +} + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Object.h b/TAO/orbsvcs/orbsvcs/Notify/Object.h index cf1f1044fac..2ff8aa537eb 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Object.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Object.h @@ -27,6 +27,7 @@ #include "QoSProperties.h" #include "AdminProperties.h" #include "Refcountable.h" +#include "Name_Value_Pair.h" class TAO_Notify_POA_Helper; class TAO_Notify_Worker_Task; @@ -54,11 +55,17 @@ public: virtual ~TAO_Notify_Object (void); /// This Object's ID - ID id (void); + ID id (void) const; /// Activate virtual CORBA::Object_ptr activate (PortableServer::Servant servant ACE_ENV_ARG_DECL); + /// Activate with existing id + virtual CORBA::Object_ptr activate ( + PortableServer::Servant servant, + CORBA::Long id + ACE_ENV_ARG_DECL); + /// Deactivate void deactivate (ACE_ENV_SINGLE_ARG_DECL); @@ -98,6 +105,10 @@ public: /// Get the QoS Properties. CosNotification::QoSProperties* get_qos (ACE_ENV_SINGLE_ARG_DECL); + bool find_qos_property_value ( + const char * name, + CosNotification::PropertyValue & value)const; + /// Obtain the Timer manager associated with this object. virtual TAO_Notify_Timer* timer (void); @@ -107,6 +118,10 @@ public: /// Accessor for the Event Manager TAO_Notify_Event_Manager* event_manager (void); + /// Load our attributes. Each derived type should call the superclass + /// load first before loading its own attributes. + virtual void load_attrs(const TAO_Notify::NVPList& attrs); + protected: /// Init this object with data from <rhs>. void init (TAO_Notify_Object* parent); @@ -123,6 +138,11 @@ protected: /// Notification that can be overridden by subclasses to be informed that <qos_properties_> have been modified. virtual void qos_changed (const TAO_Notify_QoSProperties& qos_properties); + /// Called by derived types to save their attributes. Each + /// derived type should call its superclass version before + /// saving its own attrs. + virtual void save_attrs(TAO_Notify::NVPList& attrs); + ///= Protected data members. /// The event manager. diff --git a/TAO/orbsvcs/orbsvcs/Notify/Object.inl b/TAO/orbsvcs/orbsvcs/Notify/Object.inl index 9ba8797906a..3a20131bbec 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Object.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Object.inl @@ -1,7 +1,7 @@ // $Id$ ACE_INLINE CORBA::Long -TAO_Notify_Object::id (void) +TAO_Notify_Object::id (void) const { return id_; } diff --git a/TAO/orbsvcs/orbsvcs/Notify/POA_Helper.cpp b/TAO/orbsvcs/orbsvcs/Notify/POA_Helper.cpp index fd0182a8dfc..6315d38f3e9 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/POA_Helper.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/POA_Helper.cpp @@ -9,7 +9,10 @@ ACE_RCSID(RT_Notify, TAO_Notify_POA_Helper, "$Id$") #include "tao/debug.h" -#include "ID_Factory.h" +//#define DEBUG_LEVEL 10 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif // DEBUG_LEVEL TAO_Notify_POA_Helper::TAO_Notify_POA_Helper (void) { @@ -81,7 +84,7 @@ TAO_Notify_POA_Helper::create_i (PortableServer::POA_ptr parent_poa, const char* ACE_ENV_ARG_PARAMETER); ACE_CHECK; - if (TAO_debug_level > 0) + if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, "Created POA : %s\n", this->poa_->the_name ())); /* // Destroy the policies @@ -125,13 +128,10 @@ TAO_Notify_POA_Helper::long_to_ObjectId (CORBA::Long id ACE_ENV_ARG_DECL) const CORBA::Object_ptr TAO_Notify_POA_Helper::activate (PortableServer::Servant servant, CORBA::Long& id ACE_ENV_ARG_DECL) { - /// ID Factory for objects. - static TAO_Notify_ID_Factory id_factory; - // Generate a new ID. - id = id_factory.id (); + id = this->id_factory_.id (); - if (TAO_debug_level > 0) + if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, "Activating object with id = %d in POA : %s\n", id, this->poa_->the_name ())); // Convert CORBA::Long to ObjectId @@ -148,6 +148,27 @@ TAO_Notify_POA_Helper::activate (PortableServer::Servant servant, CORBA::Long& i ACE_ENV_ARG_PARAMETER); } +CORBA::Object_ptr +TAO_Notify_POA_Helper::activate_with_id (PortableServer::Servant servant, CORBA::Long id ACE_ENV_ARG_DECL) +{ + if (DEBUG_LEVEL > 0) + ACE_DEBUG ((LM_DEBUG, "Activating object with existing id = %d in POA : %s\n", id, this->poa_->the_name ())); + this->id_factory_.set_last_used (id); + + // Convert CORBA::Long to ObjectId + PortableServer::ObjectId_var oid = + this->long_to_ObjectId (id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + poa_->activate_object_with_id (oid.in (), + servant + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + return poa_->id_to_reference (oid.in () + ACE_ENV_ARG_PARAMETER); +} + void TAO_Notify_POA_Helper::deactivate (CORBA::Long id ACE_ENV_ARG_DECL) const { @@ -171,6 +192,20 @@ TAO_Notify_POA_Helper::id_to_reference (CORBA::Long id ACE_ENV_ARG_DECL) const ACE_ENV_ARG_PARAMETER); } +PortableServer::ServantBase * +TAO_Notify_POA_Helper::reference_to_servant (CORBA::Object_ptr ptr ACE_ENV_ARG_DECL) const +{ + return poa_->reference_to_servant (ptr ACE_ENV_ARG_PARAMETER); +} + +CORBA::Object_ptr +TAO_Notify_POA_Helper::servant_to_reference ( + PortableServer::ServantBase * servant ACE_ENV_ARG_DECL) const +{ + return poa_->servant_to_reference (servant ACE_ENV_ARG_PARAMETER); +} + + void TAO_Notify_POA_Helper::destroy (ACE_ENV_SINGLE_ARG_DECL) { diff --git a/TAO/orbsvcs/orbsvcs/Notify/POA_Helper.h b/TAO/orbsvcs/orbsvcs/Notify/POA_Helper.h index 831b0dc163d..01c79ed3665 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/POA_Helper.h +++ b/TAO/orbsvcs/orbsvcs/Notify/POA_Helper.h @@ -23,6 +23,7 @@ #include "ace/Copy_Disabled.h" #include "tao/PortableServer/PortableServer.h" +#include "ID_Factory.h" /** * @class TAO_Notify_POA_Helper @@ -54,12 +55,20 @@ public: /// Activate Object, the POA will assign an ID and return its value. CORBA::Object_ptr activate (PortableServer::Servant servant, CORBA::Long& id ACE_ENV_ARG_DECL); + /// Activate Object, using existing ID + CORBA::Object_ptr activate_with_id (PortableServer::Servant servant, CORBA::Long id ACE_ENV_ARG_DECL); + /// Deactivate Object with ID void deactivate (CORBA::Long id ACE_ENV_ARG_DECL) const; /// Convert ID to reference. CORBA::Object_ptr id_to_reference (CORBA::Long id ACE_ENV_ARG_DECL) const; + /// Convert reference to pointer to servant + PortableServer::ServantBase * reference_to_servant (CORBA::Object_ptr ptr ACE_ENV_ARG_DECL) const; + + CORBA::Object_ptr servant_to_reference (PortableServer::ServantBase * servant ACE_ENV_ARG_DECL) const; + protected: /// Set default POA policies. virtual void set_policy (PortableServer::POA_ptr parent_poa, CORBA::PolicyList &policy_list ACE_ENV_ARG_DECL); @@ -70,11 +79,15 @@ protected: /// Generate a unique id for each POA created. ACE_CString get_unique_id (void); + /// Convert id to ObjectID + PortableServer::ObjectId* long_to_ObjectId (CORBA::Long id ACE_ENV_ARG_DECL) const; + +protected: /// POA PortableServer::POA_var poa_; - /// Convert id to ObjectID - PortableServer::ObjectId* long_to_ObjectId (CORBA::Long id ACE_ENV_ARG_DECL) const; + /// ID Factory for objects. + TAO_Notify_ID_Factory id_factory_; }; #if defined (__ACE_INLINE__) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Peer.h b/TAO/orbsvcs/orbsvcs/Notify/Peer.h index deaf6fc66ea..5778281bc71 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Peer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Peer.h @@ -66,6 +66,9 @@ public: /// Handle dispatch exceptions. void handle_dispatch_exception (ACE_ENV_SINGLE_ARG_DECL); + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const = 0; + protected: /// Implementation of Peer specific dispatch_updates virtual void dispatch_updates_i (const CosNotification::EventTypeSeq& added, diff --git a/TAO/orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.cpp b/TAO/orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.cpp new file mode 100644 index 00000000000..c8e21dac7d9 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.cpp @@ -0,0 +1,403 @@ +// $Id$ + +#include "Persistent_File_Allocator.h" + +#include <tao/debug.h> +#include "ace/OS_NS_string.h" + +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + +namespace TAO_Notify +{ + +Persistent_Storage_Block::Persistent_Storage_Block(const size_t block_number, + const size_t block_size) + : block_number_(block_number) + , no_write_(false) + , sync_(false) + , block_size_(block_size) + , callback_(0) + , allocator_owns_(true) +{ + ACE_NEW(this->data_, unsigned char[this->block_size_]); + ACE_OS::memset(this->data_, 0, this->block_size_); + +} + +Persistent_Storage_Block::Persistent_Storage_Block( + const Persistent_Storage_Block& psb) + : block_number_(psb.block_number_) + , no_write_(psb.no_write_) + , sync_(psb.sync_) + , block_size_(psb.block_size_) + , callback_(psb.callback_) + , allocator_owns_(psb.allocator_owns_) +{ + ACE_NEW(this->data_, unsigned char[this->block_size_]); + ACE_OS::memcpy(this->data_, psb.data(), this->block_size_); +} + +Persistent_Storage_Block::~Persistent_Storage_Block() +{ + delete [] this->data_; + this->data_ = 0; +} + +void +Persistent_Storage_Block::set_no_write() +{ + this->no_write_ = true; + this->reassign_data(0, true); +} + +bool +Persistent_Storage_Block::get_no_write() +{ + return this->no_write_; +} + +void +Persistent_Storage_Block::set_sync() +{ + this->sync_ = true; +} + +bool +Persistent_Storage_Block::get_sync() const +{ + return this->sync_; +} + +size_t +Persistent_Storage_Block::block_number() const +{ + return this->block_number_; +} + +unsigned char* +Persistent_Storage_Block::data() const +{ + return this->data_; +} + +void +Persistent_Storage_Block::reassign_data(unsigned char* newptr, + bool delete_old) +{ + if (delete_old) + { + delete [] this->data_; + } + this->data_ = newptr; +} + +void +Persistent_Storage_Block::set_callback(Persistent_Callback* callback) +{ + this->callback_ = callback; +} + +Persistent_Callback* +Persistent_Storage_Block::get_callback() const +{ + return this->callback_; +} + +void +Persistent_Storage_Block::set_allocator_owns(bool allocator_owns) +{ + this->allocator_owns_ = allocator_owns; +} + +bool +Persistent_Storage_Block::get_allocator_owns() const +{ + return this->allocator_owns_; +} + +Persistent_File_Allocator::Persistent_File_Allocator() + : pstore_() + , terminate_thread_(false) + , thread_active_(false) + , wake_up_thread_(queue_lock_) +{ +} + +Persistent_File_Allocator::~Persistent_File_Allocator() +{ + this->shutdown_thread(); +} + +bool +Persistent_File_Allocator::open (const char* filename, + const size_t block_size) +{ + bool file_opened = this->pstore_.open(filename, block_size); + if (file_opened) + { + this->thread_active_ = true; + this->thread_manager_.spawn(this->thr_func, this); + } + return file_opened; +} + +void +Persistent_File_Allocator::shutdown() +{ + this->shutdown_thread(); +} + +Persistent_Storage_Block* +Persistent_File_Allocator::allocate() +{ + Persistent_Storage_Block* result = 0; + size_t block_number = 0; + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0); + if (!this->allocate_block(block_number)) + { + //@@todo: this should never happen + // why not. What if the disk is full? Oh, I see we + // allocate non-existent blocks. FIX this + } + if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Persistent_File_Allocator::allocate: %d\n"), + ACE_static_cast (int, block_number) + )); + result = this->allocate_at(block_number); + return result; +} + +Persistent_Storage_Block* +Persistent_File_Allocator::allocate_at(size_t block_number) +{ + Persistent_Storage_Block* result = 0; + this->used(block_number); + if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Persistent_File_Allocator::allocate at : %d\n"), + ACE_static_cast (int, block_number) + )); + ACE_NEW_RETURN(result, Persistent_Storage_Block( + block_number, + this->block_size()), + 0); + return result; +} + +Persistent_Storage_Block* +Persistent_File_Allocator::allocate_nowrite() +{ + Persistent_Storage_Block* result = 0; + ACE_NEW_RETURN(result, Persistent_Storage_Block(~0, 0), 0); + result->set_no_write(); + return result; +} + +void +Persistent_File_Allocator::used(size_t block_number) +{ + ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->free_blocks_lock_); + if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Persistent_File_Allocator::used: %d\n"), + ACE_static_cast (int, block_number) + )); + ACE_ASSERT (!this->free_blocks_.is_set (block_number)); + this->free_blocks_.set_bit(block_number, true); +} + +void +Persistent_File_Allocator::free(size_t block_number) +{ + if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Persistent_File_Allocator::free: %d\n"), + ACE_static_cast (int, block_number) + )); + ACE_ASSERT (this->free_blocks_.is_set (block_number)); + this->free_block(block_number); +} + +size_t +Persistent_File_Allocator::block_size() const +{ + return pstore_.block_size(); +} + +bool +Persistent_File_Allocator::read(Persistent_Storage_Block* psb) +{ + bool result = this->thread_active_; + bool cached = false; + if (result) + { + Persistent_Storage_Block** psbtemp = 0; + { + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_, false); + size_t queue_size = this->block_queue_.size(); + for (size_t idx = 0; !cached && (idx < queue_size); ++idx) + { + // We want to start at the end of the queue and work backwards... + size_t actual_block = (queue_size - idx) - 1; + if (0 == this->block_queue_.get(psbtemp, actual_block)) + { + cached = ((*psbtemp)->block_number() == psb->block_number()); + } + } + // this needs to be done in the guarded section + if (cached && (0 != psbtemp)) + { + ACE_OS::memcpy(psb->data(), (*psbtemp)->data(), this->block_size()); + } + } + if (!cached) + { + result = pstore_.read(psb->block_number(), psb->data()); + } + } + return result; +} + +bool +Persistent_File_Allocator::write(Persistent_Storage_Block* psb) +{ + bool result = this->thread_active_; + if (result) + { + Persistent_Storage_Block* ourpsb = psb; + if (!psb->get_allocator_owns()) + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Copy PSB %d\n") + , ACE_static_cast (int, psb->block_number ()) + )); + ACE_NEW_RETURN(ourpsb, Persistent_Storage_Block(*psb), false); + ourpsb->set_allocator_owns(true); + } + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_, false); + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Queueing PSB to write block %d\n") + , ACE_static_cast (int, psb->block_number ()) + )); + result = (0 == this->block_queue_.enqueue_tail(ourpsb)); + this->wake_up_thread_.signal(); + } + return result; +} + +void +Persistent_File_Allocator::free_block(const size_t block_number) +{ + ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->free_blocks_lock_); + ACE_ASSERT (this->free_blocks_.is_set (block_number)); + this->free_blocks_.set_bit(block_number, false); +} + +bool +Persistent_File_Allocator::allocate_block(size_t& block_number) +{ + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->free_blocks_lock_, 0); + block_number = this->free_blocks_.find_first_bit(false); + return true; +} + +ACE_THR_FUNC_RETURN +Persistent_File_Allocator::thr_func(void * arg) +{ + Persistent_File_Allocator* pfa = ACE_static_cast (Persistent_File_Allocator*, + arg); + pfa->run(); + return 0; +} + +size_t +Persistent_File_Allocator::file_size () const +{ + return this->pstore_.size (); +} + +void +Persistent_File_Allocator::shutdown_thread() +{ + if (this->thread_active_) + { + ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_); + this->terminate_thread_ = true; + this->wake_up_thread_.signal(); + ace_mon.release(); + this->thread_manager_.close(); + ACE_ASSERT (!this->terminate_thread_); + ACE_ASSERT (!this->thread_active_); + } +} + +void +Persistent_File_Allocator::run() +{ + // We need this because we could be working on writing data + // when a call to terminate comes in! + bool do_more_work = true; + while (do_more_work) + { + do_more_work = false; + Persistent_Storage_Block * blk = 0; + { + ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_); + while (this->block_queue_.is_empty() && !terminate_thread_) + { + this->wake_up_thread_.wait(); + } + // Awkward interface to peek at head of unbounded queue + Persistent_Storage_Block ** pblk = 0; + if (0 == this->block_queue_.get(pblk)) + { + do_more_work = true; + blk = *pblk; + } + } + if (0 != blk) + { + Persistent_Callback *callback = blk->get_callback(); + if (!blk->get_no_write()) + { + pstore_.write(blk->block_number(), blk->data(), blk->get_sync()); + } + { + Persistent_Storage_Block * blk2 = 0; + ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_); + this->block_queue_.dequeue_head (blk2); + // if this triggers, someone pushed onto the head of the queue + // or removed the head from the queue without telling ME. + ACE_ASSERT (blk2 == blk); + } + // If we own the block, then delete it. + if (blk->get_allocator_owns()) + { + delete blk; + blk = 0; + } + if (0 != callback) + { + callback->persist_complete(); + } + } + } + this->terminate_thread_ = false; + this->thread_active_ = false; +} + +} /* namespace TAO_Notify */ + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Node<size_t>; +template class ACE_Unbounded_Stack<size_t>; +template class ACE_Node<TAO_Notify::Persistent_Storage_Block*>; +template class ACE_Unbounded_Queue<TAO_Notify::Persistent_Storage_Block*>; +template class ACE_Unbounded_Queue_Iterator<TAO_Notify::Persistent_Storage_Block*>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Node<size_t> +#pragma instantiate ACE_Unbounded_Stack<size_t> +#pragma instantiate ACE_Node<TAO_Notify::Persistent_Storage_Block*> +#pragma instantiate ACE_Unbounded_Queue<TAO_Notify::Persistent_Storage_Block*> +#pragma instantiate ACE_Unbounded_Queue_Iterator<TAO_Notify::Persistent_Storage_Block*> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.h b/TAO/orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.h new file mode 100644 index 00000000000..97ea0556f36 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Persistent_File_Allocator.h @@ -0,0 +1,204 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Persistent_File_Allocator.h + * + * $Id$ + * + * A Persistent_File_Allocator manages a free list and allocates and + * deallocates blocks from a Random_File. There should be only one + * Persistent_File_Allocator for each Random_File. + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef PERSISTENT_FILE_ALLOCATOR_H +#define PERSISTENT_FILE_ALLOCATOR_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "notify_serv_export.h" +#include "Random_File.h" +#include "Bit_Vector.h" +#include "ace/Containers_T.h" +#include "ace/Unbounded_Queue.h" +#include "ace/Thread_Manager.h" + +namespace TAO_Notify +{ + + +/// \brief An interface to allow callbacks on completion of persistent storage +/// requests. +class TAO_Notify_Serv_Export Persistent_Callback +{ +public: + /// \brief Called by a Persistent_File_Allocator when a write request has + /// completed. + virtual void persist_complete() = 0; +}; + +/** + * \brief A class to represent a block on disk. + * + * Contains the raw data to be written on disk as well as + * positioning information, synchronization information, and a pointer + * to a callback. + */ +class TAO_Notify_Serv_Export Persistent_Storage_Block +{ +public: + /// The constructor. Initializes the callback to NULL. + Persistent_Storage_Block( + const size_t block_number, + const size_t block_size); + /// The copy constructor. Makes a deep copy of the passed in PSB. + Persistent_Storage_Block(const Persistent_Storage_Block& psb); + /// The destructor. + ~Persistent_Storage_Block(); + + /// Set our block to not have any data at all - a no-op. This can be + /// used to implement a checkpoint in the write stream. + void set_no_write(); + /// Find out whether we have data to be written. + bool get_no_write(); + + /// Set our block to be written as a near-atomic operation. + void set_sync(); + /// Find out whether this block should be written near-atomically. + bool get_sync() const; + + /// Find out our physical block number. + size_t block_number() const; + + /// Return our data to the user. + unsigned char* data() const; + /// Set our data pointer, and optionally delete it. + void reassign_data(unsigned char* newptr, bool delete_old = false); + + /// Return block number and relinquish ownership. + size_t detach (); + + /// Set our callback. + void set_callback(Persistent_Callback* callback); + /// Get our callback. + Persistent_Callback* get_callback() const; + + /// Set ownership of this PSB. + void set_allocator_owns(bool allocator_owns = true); + /// Get ownership status of this PSB. + bool get_allocator_owns() const; + +private: + /// Our raw data. + unsigned char* data_; + /// The block number corresponding to our data. + size_t block_number_; + /// Are we a no-op with just a callback? + bool no_write_; + /// Write in near-atomic fashion. + bool sync_; + /// The size of our block. + size_t block_size_; + /// Our optional callback function, to be used in such things as state + /// transitions. + Persistent_Callback* callback_; + /// Does the allocator obtain ownership of our block? + bool allocator_owns_; +}; + +/** + * \brief A class that manages the details of persistent storage. + * + * Maintains a free list, write queue, allocations of new + * blocks, reads, and writes. This class also manages a thread that performs + * background updating of a Random_File. + * @@todo this is too much for one class to do. It should be refactored. + * @@todo: we shouldn't arbitrarily use a thread. + */ +class TAO_Notify_Serv_Export Persistent_File_Allocator +{ +public: + /// The constructor. + Persistent_File_Allocator(); + /// The destructor. + ~Persistent_File_Allocator(); + + bool open (const char* filename, + const size_t block_size = 512); + + /// \brief Wait for pending I/O and terminate our work thread. + void shutdown(); + + /// Allocate a new Persistent_Storage_Block and initialize it to an unused + /// block of storage. + Persistent_Storage_Block* allocate(); + + /// \brief Allocate a new Persistent_Storage_Block at a given address + Persistent_Storage_Block* allocate_at(size_t block_number); + + /// \brief Allocate a PSB that is marked to not persist + Persistent_Storage_Block* allocate_nowrite(); + + /// \brief Mark a block as used, removing it from the free list. + void used(size_t block_number); + + /// \brief Mark a block number as able to be used again. + void free(size_t block_number); + + /// \brief Access block size. + size_t block_size() const; + + /// \brief Read data into a PSB. + /// + /// Data will come either from the queue of blocks to be written, or + /// it will be read from the file if there are no queued write requests for + /// this block. + bool read(Persistent_Storage_Block* psb); + + /// \brief Write this block to the file, + /// + /// Add the Persistent_Storage_Block to our write queue and let the + /// worker thread handle writing this to the Random_File. + bool write(Persistent_Storage_Block* psb); + + /// for information (unit test) only. + size_t file_size () const; + +private: + /// Free a previously assigned block. + void free_block(const size_t block_number); + /// Find and allocate a free block. + bool allocate_block(size_t& block_number); + + /// Used during thread startup to cast us back to ourselves and call the + /// run() method. + static ACE_THR_FUNC_RETURN thr_func(void * arg); + /// Wait for pending I/O to complete and shut our worker thread down safely. + void shutdown_thread(); + /// The worker's execution thread. + void run(); + +private: + ACE_Thread_Manager thread_manager_; + Random_File pstore_; + Bit_Vector free_blocks_; + ACE_Unbounded_Queue<Persistent_Storage_Block*> block_queue_; + ACE_SYNCH_MUTEX lock_; + ACE_SYNCH_MUTEX free_blocks_lock_; + ACE_SYNCH_MUTEX queue_lock_; + bool terminate_thread_; + bool thread_active_; + ACE_SYNCH_CONDITION wake_up_thread_; +}; + +} /* namespace TAO_Notify */ + +#include /**/ "ace/post.h" +#endif /* PERSISTENT_FILE_ALLOCATOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Properties.h b/TAO/orbsvcs/orbsvcs/Notify/Properties.h index 4542a14bff6..7801ed6dc99 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Properties.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Properties.h @@ -62,6 +62,9 @@ public: CORBA::Boolean asynch_updates (void); void asynch_updates (CORBA::Boolean asynch_updates); + bool allow_reconnect (void); + void allow_reconnect (bool b); + // Turn on/off update messages. CORBA::Boolean updates (void); void updates (CORBA::Boolean updates); @@ -112,6 +115,9 @@ protected: /// True if send asynch updates. CORBA::Boolean asynch_updates_; + /// True if clients can reconnect to proxies. + bool allow_reconnect_; + /// True if updates are enabled (default). CORBA::Boolean updates_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Properties.inl b/TAO/orbsvcs/orbsvcs/Notify/Properties.inl index 2b83846458c..c8a7893f4d7 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Properties.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Properties.inl @@ -60,6 +60,18 @@ TAO_Notify_Properties::asynch_updates (CORBA::Boolean asynch_updates) this->asynch_updates_ = asynch_updates; } +ACE_INLINE bool +TAO_Notify_Properties::allow_reconnect (void) +{ + return this->allow_reconnect_; +} + +ACE_INLINE void +TAO_Notify_Properties::allow_reconnect (bool b) +{ + this->allow_reconnect_ = b; +} + ACE_INLINE CORBA::Boolean TAO_Notify_Properties::updates (void) { diff --git a/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.cpp b/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.cpp index 77a4fbc7364..bb5a906dc07 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.cpp @@ -34,9 +34,9 @@ TAO_Notify_PropertySeq::init (const CosNotification::PropertySeq& prop_seq) } int -TAO_Notify_PropertySeq::populate (CosNotification::PropertySeq_var& prop_seq) +TAO_Notify_PropertySeq::populate (CosNotification::PropertySeq_var& prop_seq) const { - PROPERTY_MAP::ITERATOR iterator (this->property_map_); + PROPERTY_MAP::CONST_ITERATOR iterator (this->property_map_); int index = prop_seq->length (); prop_seq->length (ACE_static_cast (CORBA::ULong, @@ -52,3 +52,11 @@ TAO_Notify_PropertySeq::populate (CosNotification::PropertySeq_var& prop_seq) return 0; } + +void +TAO_Notify_PropertySeq::add(const ACE_CString& name, const CORBA::Any& val) +{ + int ret = this->property_map_.rebind (name, val); + ACE_ASSERT(ret >= 0); + ACE_UNUSED_ARG (ret); // because the assert disappears in release builds +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.h b/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.h index ca241e7bbee..1325b724e81 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.h +++ b/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.h @@ -48,7 +48,15 @@ public: int find (const char* name, CosNotification::PropertyValue& value) const; /// Return -1 on error. - int populate (CosNotification::PropertySeq_var& prop_seq); + int populate (CosNotification::PropertySeq_var& prop_seq) const; + + /// return the number of properties available as a sequence + size_t size() const; + +protected: + /// Add the value. Used by subclasses to initialize the property map from their + /// member variables. + void add(const ACE_CString& name, const CORBA::Any& val); protected: /// Property Map. diff --git a/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.inl b/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.inl index 0998ec76b1b..b96345cb11a 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/PropertySeq.inl @@ -6,3 +6,11 @@ TAO_Notify_PropertySeq::find (const char* name, CosNotification::PropertyValue& ACE_CString str_name (name); return this->property_map_.find (str_name, value); } + +ACE_INLINE +size_t +TAO_Notify_PropertySeq::size() const +{ + return this->property_map_.current_size(); +} + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Property_Boolean.h b/TAO/orbsvcs/orbsvcs/Notify/Property_Boolean.h index a0eeef05462..e2d8487d0d8 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Property_Boolean.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Property_Boolean.h @@ -57,6 +57,9 @@ public: void get (CosNotification::PropertySeq& prop_seq); + /// Return the name + const char * name (void) const; + /// Return the value. CORBA::Boolean value (void) const; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Property_Boolean.inl b/TAO/orbsvcs/orbsvcs/Notify/Property_Boolean.inl index f5522993d11..b1a469809bb 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Property_Boolean.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Property_Boolean.inl @@ -37,6 +37,13 @@ TAO_Notify_Property_Boolean::operator!= (const CORBA::Boolean &rhs) const return (this->value_ != rhs); } +ACE_INLINE +const char * +TAO_Notify_Property_Boolean::name (void) const +{ + return this->name_; +} + ACE_INLINE CORBA::Boolean TAO_Notify_Property_Boolean::value (void) const { diff --git a/TAO/orbsvcs/orbsvcs/Notify/Property_T.h b/TAO/orbsvcs/orbsvcs/Notify/Property_T.h index ff39b43a068..b1b6b7c39f0 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Property_T.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Property_T.h @@ -57,9 +57,15 @@ public: /// Populate the Property Sequence with this valid value. void get (CosNotification::PropertySeq& prop_seq); + // assign a new value + void assign (const TYPE& value); + /// Return the value. const TYPE& value (void) const; + /// Return the name + const char * name (void) const; + /// Is the current value valid CORBA::Boolean is_valid (void) const; @@ -125,6 +131,9 @@ public: /// Returns 0 on success, -1 on error int set (const TAO_Notify_PropertySeq& property_seq); + /// Return the name + const char * name (void) const; + /// Return the value. const TYPE& value (void) const; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Property_T.inl b/TAO/orbsvcs/orbsvcs/Notify/Property_T.inl index f014ab89b29..31d5290c72d 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Property_T.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Property_T.inl @@ -8,6 +8,13 @@ TAO_Notify_PropertyBase_T<TYPE>::value (void) const return this->value_; } +template <class TYPE> ACE_INLINE +const char * +TAO_Notify_PropertyBase_T<TYPE>::name (void) const +{ + return this->name_; +} + template <class TYPE> ACE_INLINE CORBA::Boolean TAO_Notify_PropertyBase_T<TYPE>::is_valid (void) const { @@ -32,14 +39,33 @@ TAO_Notify_PropertyBase_T<TYPE>:: invalidate (void) this->valid_ = 0; } +template <class TYPE> ACE_INLINE +void +TAO_Notify_PropertyBase_T<TYPE>:: assign (const TYPE& value) +{ + this->value_ = value; + this->valid_ = 1; +} + + + /******************************************************************************/ +template <class TYPE> ACE_INLINE +const char * +TAO_Notify_StructProperty_T<TYPE>::name (void) const +{ + return this->name_; +} + template <class TYPE> ACE_INLINE const TYPE& TAO_Notify_StructProperty_T<TYPE>::value (void) const { return this->value_; } + + template <class TYPE> ACE_INLINE CORBA::Boolean TAO_Notify_StructProperty_T<TYPE>::is_valid (void) const { diff --git a/TAO/orbsvcs/orbsvcs/Notify/Proxy.cpp b/TAO/orbsvcs/orbsvcs/Notify/Proxy.cpp index 34e95f70911..14a5b837054 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Proxy.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Proxy.cpp @@ -14,6 +14,7 @@ ACE_RCSID(RT_Notify, TAO_Notify_Proxy, "$Id$") #include "Worker_Task.h" #include "Properties.h" #include "POA_Helper.h" +#include "Topology_Saver.h" TAO_Notify_Proxy::TAO_Notify_Proxy (void) :updates_off_ (0) @@ -29,8 +30,17 @@ TAO_Notify_Proxy::activate (PortableServer::Servant servant ACE_ENV_ARG_DECL) { // Set the POA that we use to return our <ref> this->poa_ = this->proxy_poa_; + return TAO_Notify_Object::activate (servant ACE_ENV_ARG_PARAMETER); +} - return this->proxy_poa_->activate (servant, this->id_ ACE_ENV_ARG_PARAMETER); +CORBA::Object_ptr +TAO_Notify_Proxy::activate (PortableServer::Servant servant, + const CosNotifyChannelAdmin::ProxyID proxy_id + ACE_ENV_ARG_DECL) +{ + // Set the POA that we use to return our <ref> + this->poa_ = this->proxy_poa_; + return TAO_Notify_Object::activate (servant, proxy_id ACE_ENV_ARG_PARAMETER); } void @@ -113,3 +123,74 @@ TAO_Notify_Proxy::qos_changed (const TAO_Notify_QoSProperties& qos_properties) if (peer != 0) peer->qos_changed (qos_properties); } + +void +TAO_Notify_Proxy::save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL) +{ + bool changed = this->children_changed_; + this->children_changed_ = false; + this->self_changed_ = false; + + if (is_persistent ()) + { + TAO_Notify::NVPList attrs; + this->save_attrs(attrs); + + const char * type_name = this->get_proxy_type_name (); + bool want_all_children = saver.begin_object(this->id(), type_name, attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (want_all_children || this->filter_admin_.is_changed ()) + { + this->filter_admin_.save_persistent(saver ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + if (want_all_children || this->subscribed_types_.is_changed ()) + { + this->subscribed_types_.save_persistent(saver ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + // todo: handle removed children + + saver.end_object(this->id(), type_name ACE_ENV_ARG_PARAMETER); + } +} + +void +TAO_Notify_Proxy::save_attrs (TAO_Notify::NVPList& attrs) +{ + TAO_Notify_Object::save_attrs(attrs); + TAO_Notify_Peer * peer = this->peer(); + if (peer != 0) + { + ACE_CString ior; + if (peer->get_ior(ior)) + { + attrs.push_back (TAO_Notify::NVP("PeerIOR", ior)); + } + } +} + +TAO_Notify::Topology_Object* +TAO_Notify_Proxy::load_child (const ACE_CString &type, CORBA::Long id, + const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL) +{ + ACE_UNUSED_ARG (id); + ACE_UNUSED_ARG (attrs); + TAO_Notify::Topology_Object* result = this; + if (type == "subscriptions") + { + // since we initialized our subscribed types to everything + // in the constructor. we have to clear it out first. + this->subscribed_types_.reset(); + result = &this->subscribed_types_; + ACE_CHECK_RETURN(0); + } + else if (type == "filter_admin") + { + result = & this->filter_admin_; + } + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Proxy.h b/TAO/orbsvcs/orbsvcs/Notify/Proxy.h index 59a4c347909..f98a571a2e0 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Proxy.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Proxy.h @@ -20,7 +20,7 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "Object.h" +#include "Topology_Object.h" #include "EventTypeSeq.h" #include "FilterAdmin.h" #include "Admin.h" @@ -35,7 +35,8 @@ class TAO_Notify_Peer; * @brief Base class proxy for all proxys in NS. * */ -class TAO_Notify_Serv_Export TAO_Notify_Proxy : public virtual TAO_Notify_Object +class TAO_Notify_Serv_Export TAO_Notify_Proxy + : public TAO_Notify::Topology_Parent { friend class TAO_Notify_Peer; @@ -50,35 +51,33 @@ public: ~TAO_Notify_Proxy (); /// Activate - virtual CORBA::Object_ptr activate (PortableServer::Servant servant + virtual CORBA::Object_ptr activate (PortableServer::Servant servant ACE_ENV_ARG_DECL); + /// Activate with a given ID + virtual CORBA::Object_ptr activate ( + PortableServer::Servant servant, + CORBA::Long id + ACE_ENV_ARG_DECL); + /// Deactivate void deactivate (ACE_ENV_SINGLE_ARG_DECL); /// Obtain the Proxy's subscribed types. - void subscribed_types (TAO_Notify_EventTypeSeq& subscribed_types + void subscribed_types (TAO_Notify_EventTypeSeq& subscribed_types ACE_ENV_ARG_DECL); /// Check if this event passes the admin and proxy filters. CORBA::Boolean check_filters ( - const TAO_Notify_Event* event, - TAO_Notify_FilterAdmin& parent_filter_admin, - CosNotifyChannelAdmin::InterFilterGroupOperator filter_operator - ACE_ENV_ARG_DECL - ); - - /// Check if this event passes the admin and proxy filters. - CORBA::Boolean check_filters ( - const TAO_Notify_Event_var &event, - TAO_Notify_FilterAdmin& parent_filter_admin, + const TAO_Notify_Event* event, + TAO_Notify_FilterAdmin& parent_filter_admin, CosNotifyChannelAdmin::InterFilterGroupOperator filter_operator ACE_ENV_ARG_DECL ); /// Inform this proxy that the following types are being advertised. - void types_changed (const TAO_Notify_EventTypeSeq& added, - const TAO_Notify_EventTypeSeq& removed + void types_changed (const TAO_Notify_EventTypeSeq& added, + const TAO_Notify_EventTypeSeq& removed ACE_ENV_ARG_DECL); /// Have updates been turned off. @@ -92,8 +91,8 @@ public: /// Implement the Obtain Types. virtual CosNotification::EventTypeSeq* obtain_types ( - CosNotifyChannelAdmin::ObtainInfoMode mode, - const TAO_Notify_EventTypeSeq& types + CosNotifyChannelAdmin::ObtainInfoMode mode, + const TAO_Notify_EventTypeSeq& types ACE_ENV_ARG_DECL ) ACE_THROW_SPEC ((CORBA::SystemException)); @@ -107,6 +106,15 @@ public: /// Override, TAO_Notify_Object::qos_changed virtual void qos_changed (const TAO_Notify_QoSProperties& qos_properties); + // TAO_Notify::Topology_Object + + virtual void save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL); + virtual void save_attrs(TAO_Notify::NVPList& attrs); + virtual const char * get_proxy_type_name (void) const = 0; + + virtual TAO_Notify::Topology_Object* load_child (const ACE_CString &type, CORBA::Long id, + const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL); + protected: /// Filter Administration diff --git a/TAO/orbsvcs/orbsvcs/Notify/Proxy.inl b/TAO/orbsvcs/orbsvcs/Notify/Proxy.inl index e7bcc8907f5..ef84390455c 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Proxy.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Proxy.inl @@ -7,15 +7,6 @@ TAO_Notify_Proxy::updates_off (void) } ACE_INLINE CORBA::Boolean -TAO_Notify_Proxy::check_filters (const TAO_Notify_Event_var &event - , TAO_Notify_FilterAdmin& parent_filter_admin - , CosNotifyChannelAdmin::InterFilterGroupOperator filter_operator - ACE_ENV_ARG_DECL) -{ - return this->check_filters (event.get (), parent_filter_admin, filter_operator ACE_ENV_ARG_PARAMETER); -} - -ACE_INLINE CORBA::Boolean TAO_Notify_Proxy::check_filters (const TAO_Notify_Event* event , TAO_Notify_FilterAdmin& parent_filter_admin , CosNotifyChannelAdmin::InterFilterGroupOperator filter_operator diff --git a/TAO/orbsvcs/orbsvcs/Notify/ProxyConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/ProxyConsumer.cpp index 1675a777de5..1d95752eea9 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ProxyConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/ProxyConsumer.cpp @@ -19,6 +19,12 @@ ACE_RCSID(RT_Notify, TAO_Notify_ProxyConsumer, "$Id$") #include "Worker_Task.h" #include "Properties.h" #include "SupplierAdmin.h" +#include "EventChannel.h" +#include "Routing_Slip.h" +//#define DEBUG_LEVEL 10 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL TAO_Notify_ProxyConsumer::TAO_Notify_ProxyConsumer (void) : supplier_admin_ (0) @@ -40,7 +46,7 @@ TAO_Notify_ProxyConsumer::peer (void) void TAO_Notify_ProxyConsumer::init (TAO_Notify_SupplierAdmin* supplier_admin ACE_ENV_ARG_DECL) { - TAO_Notify_Object::init (supplier_admin); + TAO_Notify::Topology_Object::init (supplier_admin); this->supplier_admin_ = supplier_admin; @@ -70,17 +76,30 @@ TAO_Notify_ProxyConsumer::connect (TAO_Notify_Supplier *supplier ACE_ENV_ARG_DEC ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, ace_mon, this->lock_, CORBA::INTERNAL ()); ACE_CHECK; + TAO_Notify_Supplier* deleted_supplier = 0; if (this->is_connected ()) { - supplier->release (); - ACE_THROW (CosEventChannelAdmin::AlreadyConnected ()); + if (TAO_Notify_PROPERTIES::instance()->allow_reconnect()) + { + deleted_supplier = this->supplier_; + } + else + { + supplier->release (); + ACE_THROW (CosEventChannelAdmin::AlreadyConnected ()); + } } - supplier_ = supplier; + this->supplier_ = supplier; this->supplier_admin_->subscribed_types (this->subscribed_types_ ACE_ENV_ARG_PARAMETER); // get the parents subscribed types. ACE_CHECK; + + if (deleted_supplier != 0) + { + deleted_supplier->_decr_refcnt(); + } } // Inform QoS values. @@ -97,6 +116,46 @@ TAO_Notify_ProxyConsumer::connect (TAO_Notify_Supplier *supplier ACE_ENV_ARG_DEC // Increment the global supplier count ++supplier_count; } +void +TAO_Notify_ProxyConsumer::push_i (TAO_Notify_Event * event ACE_ENV_ARG_DECL) +{ + if (this->supports_reliable_events ()) + { + TAO_Notify_Event_var pevent; + event->queueable_copy (pevent ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + TAO_Notify::Routing_Slip_Ptr routing_slip = + TAO_Notify::Routing_Slip::create (pevent ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + if (DEBUG_LEVEL > 0) + ACE_DEBUG((LM_DEBUG, ACE_TEXT ("ProxyConsumer routing event.\n"))); + routing_slip->route (this, true ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + routing_slip->wait_persist (); + } + else + { + TAO_Notify_Method_Request_Lookup_No_Copy request (event, this); + this->worker_task ()->execute (request ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +} + +bool +TAO_Notify_ProxyConsumer::supports_reliable_events () const +{ + bool reliable = false; + CosNotification::PropertyValue value; + if (this->find_qos_property_value (CosNotification::EventReliability, value)) + { + CORBA::Long setting; + if (value >>= setting) + { + reliable = (setting == CosNotification::Persistent); + } + } + return reliable; +} void TAO_Notify_ProxyConsumer::disconnect (ACE_ENV_SINGLE_ARG_DECL) diff --git a/TAO/orbsvcs/orbsvcs/Notify/ProxyConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/ProxyConsumer.h index 349c9c7b150..797fc246e44 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ProxyConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/ProxyConsumer.h @@ -79,6 +79,13 @@ public: TAO_Notify_SupplierAdmin* supplier_admin (void); protected: + /// Accept an event from the Supplier + void push_i (TAO_Notify_Event * event ACE_ENV_ARG_DECL); + + /// Is this part of a reliable channel + bool supports_reliable_events () const; + +protected: ///= Data Members. /// The SA parent. TAO_Notify_SupplierAdmin* supplier_admin_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier.cpp index 3034ae07829..90b25182bad 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier.cpp @@ -31,7 +31,7 @@ TAO_Notify_ProxySupplier::~TAO_Notify_ProxySupplier () void TAO_Notify_ProxySupplier::init (TAO_Notify_ConsumerAdmin* consumer_admin ACE_ENV_ARG_DECL) { - TAO_Notify_Object::init (consumer_admin); + TAO_Notify::Topology_Object::init (consumer_admin); this->consumer_admin_ = consumer_admin; @@ -68,16 +68,28 @@ TAO_Notify_ProxySupplier::connect (TAO_Notify_Consumer *consumer ACE_ENV_ARG_DEC CORBA::INTERNAL ()); ACE_CHECK; + TAO_Notify_Consumer * deleted_consumer = 0; if (this->is_connected ()) { - consumer->release (); - ACE_THROW (CosEventChannelAdmin::AlreadyConnected ()); + if (TAO_Notify_PROPERTIES::instance()->allow_reconnect()) + { + deleted_consumer = this->consumer_; + } + else + { + consumer->release (); + ACE_THROW (CosEventChannelAdmin::AlreadyConnected ()); + } } consumer_ = consumer; this->consumer_admin_->subscribed_types (this->subscribed_types_ ACE_ENV_ARG_PARAMETER); // get the parents subscribed types. ACE_CHECK; + if (deleted_consumer != 0) + { + deleted_consumer->_decr_refcnt(); + } } // Inform QoS values. @@ -139,34 +151,8 @@ TAO_Notify_ProxySupplier::destroy (ACE_ENV_SINGLE_ARG_DECL) } void -TAO_Notify_ProxySupplier::push (const TAO_Notify_Event* event ACE_ENV_ARG_DECL) +TAO_Notify_ProxySupplier::deliver (TAO_Notify_Method_Request & request ACE_ENV_ARG_DECL) { - TAO_Notify_Method_Request_Dispatch_No_Copy request (event, this, 1); - - this->worker_task ()->execute (request ACE_ENV_ARG_PARAMETER); -} - -void -TAO_Notify_ProxySupplier::push (const TAO_Notify_Event_var &event ACE_ENV_ARG_DECL) -{ - TAO_Notify_Method_Request_Dispatch_No_Copy_Ex request (event, this, 1); - - this->worker_task ()->execute (request ACE_ENV_ARG_PARAMETER); -} - -void -TAO_Notify_ProxySupplier::push_no_filtering (const TAO_Notify_Event* event ACE_ENV_ARG_DECL) -{ - TAO_Notify_Method_Request_Dispatch_No_Copy request (event, this, 0); // No filtering. - - this->worker_task ()->execute (request ACE_ENV_ARG_PARAMETER); -} - -void -TAO_Notify_ProxySupplier::push_no_filtering (const TAO_Notify_Event_var &event ACE_ENV_ARG_DECL) -{ - TAO_Notify_Method_Request_Dispatch_No_Copy_Ex request (event, this, 0); // No filtering. - this->worker_task ()->execute (request ACE_ENV_ARG_PARAMETER); } diff --git a/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier.h b/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier.h index 272c9c3f1ea..a099204f539 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier.h @@ -26,7 +26,7 @@ class TAO_Notify_Consumer; class TAO_Notify_ConsumerAdmin; - +class TAO_Notify_Method_Request; /** * @class TAO_Notify_ProxySupplier * @@ -57,16 +57,7 @@ public: void disconnect (ACE_ENV_SINGLE_ARG_DECL); /// Dispatch Event to consumer - virtual void push (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); - - /// Dispatch Event to consumer - virtual void push (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL); - - /// Dispatch Event to consumer, no filtering - virtual void push_no_filtering (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); - - /// Dispatch Event to consumer, no filtering - virtual void push_no_filtering (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL); + virtual void deliver (TAO_Notify_Method_Request & request ACE_ENV_ARG_DECL); /// Override TAO_Notify_Container_T::shutdown method virtual int shutdown (ACE_ENV_SINGLE_ARG_DECL); @@ -89,6 +80,7 @@ public: /// The CA parent. TAO_Notify_ConsumerAdmin* consumer_admin (void); +// const char * get_proxy_type_name (void) const; protected: ///= Data Members. diff --git a/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier_T.cpp b/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier_T.cpp index 86f2c82569b..33c3ed70b8c 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier_T.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/ProxySupplier_T.cpp @@ -140,6 +140,9 @@ TAO_Notify_ProxySupplier_T<SERVANT_TYPE>::suspend_connection (ACE_ENV_SINGLE_ARG } this->consumer_->suspend (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; } template <class SERVANT_TYPE> void diff --git a/TAO/orbsvcs/orbsvcs/Notify/Proxy_T.cpp b/TAO/orbsvcs/orbsvcs/Notify/Proxy_T.cpp index d767751adc3..79856ed053b 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Proxy_T.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Proxy_T.cpp @@ -99,7 +99,12 @@ TAO_Notify_Proxy_T<SERVANT_TYPE>::add_filter (CosNotifyFilter::Filter_ptr new_fi CORBA::INTERNAL ()); ACE_CHECK_RETURN (0); - return this->filter_admin_.add_filter (new_filter ACE_ENV_ARG_PARAMETER); + CosNotifyFilter::FilterID fid = + this->filter_admin_.add_filter (new_filter ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN(fid); + return fid; } template <class SERVANT_TYPE> void diff --git a/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.cpp b/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.cpp index 805ae87ff67..7af2da443ab 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.cpp @@ -10,18 +10,21 @@ ACE_RCSID(Notify, TAO_Notify_QoSProperties, "$Id$") #include "Property.h" + + TAO_Notify_QoSProperties::TAO_Notify_QoSProperties (void) - : priority_ (CosNotification::Priority) + : event_reliability_(CosNotification::EventReliability) + , connection_reliability_(CosNotification::ConnectionReliability) + , priority_ (CosNotification::Priority) , timeout_ (CosNotification::Timeout) , stop_time_supported_ (CosNotification::StopTimeSupported) , maximum_batch_size_ (CosNotification::MaximumBatchSize) + , max_events_per_consumer_ (CosNotification::MaxEventsPerConsumer) , pacing_interval_ (CosNotification::PacingInterval) , thread_pool_ (NotifyExt::ThreadPool) , thread_pool_lane_ (NotifyExt::ThreadPoolLanes) { - unsupported_[0] = CosNotification::EventReliability; - unsupported_[1] = CosNotification::ConnectionReliability; - unsupported_[2] = CosNotification::StartTimeSupported; + unsupported_[0] = CosNotification::StartTimeSupported; } TAO_Notify_QoSProperties::~TAO_Notify_QoSProperties () @@ -39,6 +42,70 @@ TAO_Notify_QoSProperties::unsupported (ACE_CString& name) return 0; } +void +TAO_Notify_QoSProperties::init () +{ + if (this->event_reliability_.is_valid()) + { + CORBA::Any a; + a <<= this->event_reliability_.value(); + this->add(this->event_reliability_.name(), a); + } + if (this->connection_reliability_.is_valid()) + { + CORBA::Any a; + a <<= this->connection_reliability_.value(); + this->add(this->connection_reliability_.name(), a); + } + if (this->priority_.is_valid()) + { + CORBA::Any a; + a <<= this->priority_.value(); + this->add(this->priority_.name(), a); + } + if (this->timeout_.is_valid()) + { + CORBA::Any a; + a <<= this->timeout_.value(); + this->add(this->timeout_.name(), a); + } + if (this->stop_time_supported_.is_valid()) + { + CORBA::Any a; + a <<= CORBA::Any::from_boolean (this->stop_time_supported_.value()); + this->add(this->stop_time_supported_.name(), a); + } + if (this->maximum_batch_size_.is_valid()) + { + CORBA::Any a; + a <<= this->maximum_batch_size_.value(); + this->add(this->maximum_batch_size_.name(), a); + } + if (this->pacing_interval_.is_valid()) + { + CORBA::Any a; + a <<= this->pacing_interval_.value(); + this->add(this->pacing_interval_.name(), a); + } + if (this->max_events_per_consumer_.is_valid()) + { + CORBA::Any a; + a <<= this->max_events_per_consumer_.value(); + this->add(this->max_events_per_consumer_.name(), a); + } + if (this->thread_pool_.is_valid()) + { + CORBA::Any a; + a <<= this->thread_pool_.value(); + this->add(this->thread_pool_.name(), a); + } + if (this->thread_pool_lane_.is_valid()) + { + CORBA::Any a; + a <<= this->thread_pool_lane_.value(); + this->add(this->thread_pool_lane_.name(), a); + } +} int TAO_Notify_QoSProperties::init (const CosNotification::PropertySeq& prop_seq, CosNotification::PropertyErrorSeq& err_seq) @@ -64,8 +131,10 @@ TAO_Notify_QoSProperties::init (const CosNotification::PropertySeq& prop_seq, Co } if (prop_seq.length () > 0) - { + { // Now, init the supported properties + this->event_reliability_.set (*this); + this->connection_reliability_.set (*this); this->priority_.set (*this); this->timeout_.set (*this); this->stop_time_supported_.set (*this); @@ -81,6 +150,8 @@ TAO_Notify_QoSProperties::init (const CosNotification::PropertySeq& prop_seq, Co int TAO_Notify_QoSProperties::copy (TAO_Notify_QoSProperties& qos_properties) { + qos_properties.event_reliability_ = this->event_reliability_; + qos_properties.connection_reliability_ = this->connection_reliability_; qos_properties.priority_ = this->priority_; qos_properties.timeout_ = this->timeout_; qos_properties.stop_time_supported_ = this->stop_time_supported_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.h b/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.h index ba418a24cca..91572274252 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.h +++ b/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.h @@ -43,6 +43,9 @@ public: /// Return 0 on success, 1 if unsupported properties were detected and -1 on error. int init (const CosNotification::PropertySeq& prop_seq, CosNotification::PropertyErrorSeq& err_seq); + /// This version initializes the base from our members + void init (); + /// Populate <qos_properties> with all properties from this object. Returns -1 on error. int copy (TAO_Notify_QoSProperties& qos_properties); @@ -61,18 +64,42 @@ public: /// Pacing Interval const TAO_Notify_Property_Time& pacing_interval (void) const; + ///= Accessors + + const TAO_Notify_Property_Short& event_reliability (void) const; + const TAO_Notify_Property_Short& connection_reliability (void) const; + const TAO_Notify_Property_Short& priority (void) const; + const TAO_Notify_Property_Time& timeout (void) const; + const TAO_Notify_Property_Boolean& stop_time_supported (void) const; + const TAO_Notify_Property_Long& max_events_per_consumer (void) const; + + // The non-const accessors are used during topology load + TAO_Notify_Property_Short& event_reliability (void); + TAO_Notify_Property_Short& connection_reliability (void); + TAO_Notify_Property_Short& priority (void); + TAO_Notify_Property_Time& timeout (void); + TAO_Notify_Property_Boolean& stop_time_supported (void); + TAO_Notify_Property_Long& maximum_batch_size (void); + TAO_Notify_Property_Time& pacing_interval (void); + TAO_Notify_Property_Long& max_events_per_consumer (void); protected: /// Return 1 if <value> is unsupported. int unsupported (ACE_CString& name); - enum {UNSUPPORTED_PROPERTY_COUNT = 3}; + enum {UNSUPPORTED_PROPERTY_COUNT = 1}; ///= Unsupported Properties. ACE_CString unsupported_[UNSUPPORTED_PROPERTY_COUNT]; ///= Supported properties + /// Event Reliability + TAO_Notify_Property_Short event_reliability_; + + /// Connection Reliability + TAO_Notify_Property_Short connection_reliability_; + /// Priority TAO_Notify_Property_Short priority_; @@ -85,6 +112,9 @@ protected: /// Maximum Batch Size TAO_Notify_Property_Long maximum_batch_size_; + /// Maximum Events (queue length) Per Consumer + TAO_Notify_Property_Long max_events_per_consumer_; + /// Pacing Interval TAO_Notify_Property_Time pacing_interval_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.inl b/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.inl index 087ab21febe..14aab6a7866 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/QoSProperties.inl @@ -1,5 +1,47 @@ // $Id$ +ACE_INLINE +const TAO_Notify_Property_Short& +TAO_Notify_QoSProperties::event_reliability(void) const +{ + return this->event_reliability_; +} + +ACE_INLINE +const TAO_Notify_Property_Short& +TAO_Notify_QoSProperties::connection_reliability(void) const +{ + return this->connection_reliability_; +} + +ACE_INLINE +const TAO_Notify_Property_Short& +TAO_Notify_QoSProperties::priority(void) const +{ + return this->priority_; +} + +ACE_INLINE +const TAO_Notify_Property_Time& +TAO_Notify_QoSProperties::timeout(void) const +{ + return this->timeout_; +} + +ACE_INLINE +const TAO_Notify_Property_Boolean& +TAO_Notify_QoSProperties::stop_time_supported(void) const +{ + return this->stop_time_supported_; +} + +ACE_INLINE +const TAO_Notify_Property_Long& +TAO_Notify_QoSProperties::max_events_per_consumer (void) const +{ + return this->max_events_per_consumer_; +} + ACE_INLINE const TAO_Notify_Property_ThreadPool& TAO_Notify_QoSProperties::thread_pool (void) const { @@ -23,3 +65,58 @@ TAO_Notify_QoSProperties::pacing_interval (void) const { return this->pacing_interval_; } + +ACE_INLINE +TAO_Notify_Property_Short& +TAO_Notify_QoSProperties::event_reliability(void) +{ + return this->event_reliability_; +} + +ACE_INLINE +TAO_Notify_Property_Short& +TAO_Notify_QoSProperties::connection_reliability(void) +{ + return this->connection_reliability_; +} + +ACE_INLINE +TAO_Notify_Property_Short& +TAO_Notify_QoSProperties::priority(void) +{ + return this->priority_; +} + +ACE_INLINE +TAO_Notify_Property_Time& +TAO_Notify_QoSProperties::timeout(void) +{ + return this->timeout_; +} + +ACE_INLINE +TAO_Notify_Property_Boolean& +TAO_Notify_QoSProperties::stop_time_supported(void) +{ + return this->stop_time_supported_; +} + +ACE_INLINE +TAO_Notify_Property_Long& +TAO_Notify_QoSProperties::max_events_per_consumer (void) +{ + return this->max_events_per_consumer_; +} + + +ACE_INLINE TAO_Notify_Property_Long& +TAO_Notify_QoSProperties::maximum_batch_size (void) +{ + return this->maximum_batch_size_; +} + +ACE_INLINE TAO_Notify_Property_Time& +TAO_Notify_QoSProperties::pacing_interval (void) +{ + return this->pacing_interval_; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/RT_Builder.inl b/TAO/orbsvcs/orbsvcs/Notify/RT_Builder.inl index 1ce3c730804..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/RT_Builder.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/RT_Builder.inl @@ -1,3 +1,2 @@ // $Id$ -#include "RT_Builder.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/RT_Factory.inl b/TAO/orbsvcs/orbsvcs/Notify/RT_Factory.inl index adb4497a7fa..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/RT_Factory.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/RT_Factory.inl @@ -1,3 +1,2 @@ // $Id$ -#include "RT_Factory.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/RT_Notify_Service.inl b/TAO/orbsvcs/orbsvcs/Notify/RT_Notify_Service.inl index 2274b4dbd69..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/RT_Notify_Service.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/RT_Notify_Service.inl @@ -1,3 +1,2 @@ // $Id$ -#include "RT_Notify_Service.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/RT_POA_Helper.inl b/TAO/orbsvcs/orbsvcs/Notify/RT_POA_Helper.inl index a06831e3235..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/RT_POA_Helper.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/RT_POA_Helper.inl @@ -1,3 +1,2 @@ // $Id$ -#include "RT_POA_Helper.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/RT_Properties.inl b/TAO/orbsvcs/orbsvcs/Notify/RT_Properties.inl index 9eafa07973a..8451193ea97 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/RT_Properties.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/RT_Properties.inl @@ -1,6 +1,5 @@ // $Id$ -#include "RT_Properties.h" ACE_INLINE RTCORBA::RTORB_ptr TAO_Notify_RT_Properties::rt_orb (void) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Random_File.cpp b/TAO/orbsvcs/orbsvcs/Notify/Random_File.cpp new file mode 100644 index 00000000000..9fbb6e11c20 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Random_File.cpp @@ -0,0 +1,160 @@ +// $Id$ + +#include "Random_File.h" + +#include "ace/OS.h" +#include <tao/debug.h> +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + +namespace TAO_Notify +{ + +Random_File::Random_File() + : block_size_(512) +{ +} + +Random_File::~Random_File() +{ + this->close(); +} + +size_t +Random_File::block_size() const +{ + return this->block_size_; +} + +size_t +Random_File::size() const +{ + Random_File * mutable_this = ACE_const_cast (Random_File *, this); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, mutable_this->lock_, 0); + size_t original_pos = mutable_this->tell (); + mutable_this->ACE_FILE::seek(0, SEEK_END); + size_t cursize = mutable_this->tell(); + mutable_this->ACE_FILE::seek (original_pos, SEEK_SET); + if ((cursize % this->block_size_) != 0) + { + cursize += this->block_size_; + } + return cursize / this->block_size_; +} + +bool +Random_File::open(const char* filename, size_t block_size) +{ + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, false); + this->block_size_ = block_size; + bool result = (this->close() == 0); + + if (result) + { + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Opening file %s\n") + , filename + )); + ACE_HANDLE handle = ACE_OS::open(filename, + O_CREAT | O_RDWR | O_BINARY, + ACE_DEFAULT_FILE_PERMS); + + if (handle == ACE_INVALID_HANDLE) + { + result = false; + } + else + { + this->set_handle(handle); + if (this->get_handle() == 0) + { + result = false; + } + else + { + result = (this->addr_.set(filename) == 0); + } + } + } + return result; +} + +bool +Random_File::write(const size_t block_number, void* buf, bool atomic) +{ + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, false); + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Write block %d %c\n"), + ACE_static_cast (int, block_number), + (atomic ? '*' : ' ') + )); + bool result = this->seek(block_number); + if (result) + { + if (atomic) + { + // sync before so that any block pointed to from this block + // will be there when this block is written. + result = sync(); + } + // ACE uses an ssize_t for buffer size, so we do this to make it happy. + ssize_t block_size = this->block_size_; + if (result && (block_size != + ACE_OS::write(this->get_handle(), buf, block_size))) + { + result = false; + } + if (result && atomic) + { + // sync after to provide the caller with a guarantee that + // this block is physically written to the storage device. + result = sync(); + } + } + return result; +} + +bool +Random_File::read(const size_t block_number, void* buf) +{ + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, false); + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Read block %d\n"), + ACE_static_cast (int, block_number) + )); + bool result = this->seek(block_number); + if (result) + { + ssize_t block_size = this->block_size_; + if (block_size != + ACE_OS::read(this->get_handle(), buf, block_size)) + { + result = false; + } + } + return result; +} + +bool +Random_File::seek(const size_t block_number) +{ + ssize_t destloc = block_number * this->block_size_; + bool result = (destloc == this->ACE_FILE::seek(destloc, SEEK_SET)); + return result; +} + +bool +Random_File::sync() +{ + bool result = false; + result = (0 == ACE_OS::fsync(this->get_handle())); + return result; +} + +} /* namespace TAO_Notify */ + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Random_File.h b/TAO/orbsvcs/orbsvcs/Notify/Random_File.h new file mode 100644 index 00000000000..833d5274114 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Random_File.h @@ -0,0 +1,89 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Random_File.h + * + * $Id$ + * + * This class implements a a random-access file containing + * fixed-size blocks. + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef RANDOM_FILE_H +#define RANDOM_FILE_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "notify_serv_export.h" +#include "ace/FILE.h" +#include "ace/streams.h" +#include "ace/Synch_T.h" + +namespace TAO_Notify +{ + +/** + * \brief A random file class. + * + * Derived from ACE_FILE, this class provides access to a + * file of fixed-size blocks. + * + */ +class TAO_Notify_Serv_Export Random_File : public ACE_FILE +{ +public: + /// The constructor. + Random_File(); + + /// The destructor, which closes the open file. + ~Random_File(); + + /// Open a file with default permissions. + bool open(const char* filename, size_t block_size = 512); + + /// Accessor for the block size. + /// Note signed size_t is used to be compatible with + /// ACE_FILE. + size_t block_size() const; + + /// Return the current file size, in number of blocks. + size_t size() const; + + /// Write a block to our file, potentially as an "atomic" write. + /// If the atomic argument is true, then the operating system's + /// write-through cache for this file is flushed both before and + /// after the write. + /// The flush before ensures that any record pointers in this block + /// will point to records that actually appear in the file. + /// The flush after provides the caller with a guarantee that + /// the data will appear in the file even if the system fails + /// immediately after this method returns. + bool write(const size_t block_number, void* buffer, bool atomic = false); + + /// Read a block from our file. + bool read(const size_t block_number, void* buffer); + +private: + /// Seek to a given block number, used by reads and writes. + bool seek(const size_t block_number); + + /// Synchronize the file to disk, used to implement atomic. + bool sync(); + +private: + size_t block_size_; + ACE_SYNCH_MUTEX lock_; +}; + +} /* namespace TAO_Notify */ + +#include /**/ "ace/post.h" +#endif /* RANDOM_FILE_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Reactive_Task.cpp b/TAO/orbsvcs/orbsvcs/Notify/Reactive_Task.cpp index 6f51070662e..5485f75fd79 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Reactive_Task.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Reactive_Task.cpp @@ -40,7 +40,7 @@ TAO_Notify_Reactive_Task::shutdown (void) } void -TAO_Notify_Reactive_Task::execute (TAO_Notify_Method_Request_No_Copy& method_request ACE_ENV_ARG_DECL) +TAO_Notify_Reactive_Task::execute (TAO_Notify_Method_Request& method_request ACE_ENV_ARG_DECL) { method_request.execute (ACE_ENV_SINGLE_ARG_PARAMETER); } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Reactive_Task.h b/TAO/orbsvcs/orbsvcs/Notify/Reactive_Task.h index f0b9451f074..4ef50649649 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Reactive_Task.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Reactive_Task.h @@ -50,7 +50,7 @@ public: virtual void shutdown (void); /// Exec the request. - virtual void execute (TAO_Notify_Method_Request_No_Copy& method_request ACE_ENV_ARG_DECL); + virtual void execute (TAO_Notify_Method_Request& method_request ACE_ENV_ARG_DECL); /// The object used by clients to register timers. This method returns a Reactor based Timer. virtual TAO_Notify_Timer* timer (void); diff --git a/TAO/orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.cpp b/TAO/orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.cpp new file mode 100644 index 00000000000..6557823e111 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.cpp @@ -0,0 +1,39 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** +* @file Reconnect_Worker_T.cpp +* +* $Id$ +* +* @author Jonathan Pollack <pollack_j@ociweb.com> +*/ +//============================================================================= + +#ifndef RECONNECT_WORKER_CPP +#define RECONNECT_WORKER_CPP + +#include "Reconnect_Worker_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + template<class TOPOOBJ> + Reconnect_Worker<TOPOOBJ>::Reconnect_Worker() + { + } + + template<class TOPOOBJ> + void + Reconnect_Worker<TOPOOBJ>::work (TOPOOBJ* o ACE_ENV_ARG_DECL) + { + ACE_ASSERT(o != 0); + o->reconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } +} // namespace TAO_Notify + +#endif /* RECONNECT_WORKER_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.h b/TAO/orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.h new file mode 100644 index 00000000000..8190037e3bd --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Reconnect_Worker_T.h @@ -0,0 +1,50 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** +* @file Reconnect_Worker_T.h +* +* $Id$ +* +* @author Jonathan Pollack <pollack_j@ociweb.com> +*/ +//============================================================================= + +#ifndef RECONNECT_WORKER_H +#define RECONNECT_WORKER_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/ESF/ESF_Worker.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + /** + * \brief Iterate through children reconnecting after reloading persistent information. + */ + template<class TOPOOBJ> + class Reconnect_Worker : public TAO_ESF_Worker<TOPOOBJ> + { + public: + /// Constructor + Reconnect_Worker(); + + // override virtual ESF_Worker method + virtual void work (TOPOOBJ* o ACE_ENV_ARG_DECL); + }; +} // namespace TAO_Notify + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "Reconnect_Worker_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Reconnect_Worker_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* RECONECT_WORKER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Reconnection_Registry.cpp b/TAO/orbsvcs/orbsvcs/Notify/Reconnection_Registry.cpp new file mode 100644 index 00000000000..322cc463d45 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Reconnection_Registry.cpp @@ -0,0 +1,267 @@ +/* -*- C++ -*- */ +/** + * @file Reconnection_Registry.cpp + * + * $Id$ + * + * @author Dale Wilson <wilson_d@ociweb.com> + * + */ +#include "Reconnection_Registry.h" + +#if ! defined (__ACE_INLINE__) +#include "Reconnection_Registry.inl" +#endif /* __ACE_INLINE__ */ + +#include <tao/debug.h> +#include "Properties.h" +#include "Topology_Saver.h" +#include <ace/Vector_T.h> +//#define DEBUG_LEVEL 10 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif + +namespace TAO_Notify +{ + Reconnection_Registry::Reconnection_Registry (Topology_Parent & parent) + : highest_id_(0) + { + // not the best technique, here. Take advantage of "protected" + Topology_Object::topology_parent_ = &parent; + } + + Reconnection_Registry::~Reconnection_Registry () + { + } + + ////////////////////////// + // During normal operation + + NotifyExt::ReconnectionRegistry::ReconnectionID + Reconnection_Registry::register_callback ( + NotifyExt::ReconnectionCallback_ptr callback + ACE_ENV_ARG_DECL) + { + //@@todo DO WE NEED THREAD SAFENESS? + NotifyExt::ReconnectionRegistry::ReconnectionID next_id = ++highest_id_; + + if (DEBUG_LEVEL > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Reconnect registry: registering %d\n"), + ACE_static_cast (int, next_id) + )); + } + TAO_Notify_Properties* properties = TAO_Notify_PROPERTIES::instance(); + CORBA::ORB_var orb = properties->orb (); + + CORBA::String_var cior = orb->object_to_string (callback ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + ACE_CString ior(cior.in ()); + if ( 0 != reconnection_registry_.bind (next_id, ior)) + { + //todo throw something; + } + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return next_id; + } + + void + Reconnection_Registry::unregister_callback (NotifyExt::ReconnectionRegistry::ReconnectionID id + ACE_ENV_ARG_DECL) + { + if (DEBUG_LEVEL > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Reconnect registry: unregistering %d\n"), + ACE_static_cast (int, id) + )); + } + if ( 0 != reconnection_registry_.unbind (id)) + { + //@@todo throw something + } + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + } + + CORBA::Boolean + Reconnection_Registry::is_alive (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + { + return CORBA::Boolean(1); + } + + ////////////////////// + // During topology save + + void + Reconnection_Registry::save_persistent (Topology_Saver& saver ACE_ENV_ARG_DECL) + { + bool change = this->self_changed_; + this->self_changed_ = false; + this->children_changed_ = false; + + NVPList attrs; + //@@todo: bool want_all_children = + saver.begin_object (0, REGISTRY_TYPE, attrs, change ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + Reconnection_Registry_Type::ENTRY *entry; + for (Reconnection_Registry_Type::ITERATOR iter (this->reconnection_registry_); + iter.next (entry); + iter.advance ()) + { + NVPList cattrs; + if (DEBUG_LEVEL > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Reconnect registry: saving %d\n"), + ACE_static_cast (int, entry->ext_id_) + )); + } + cattrs.push_back(NVP(RECONNECT_ID, entry->ext_id_)); + cattrs.push_back(NVP(RECONNECT_IOR, entry->int_id_)); + saver.begin_object (entry->ext_id_, REGISTRY_CALLBACK_TYPE, cattrs, true ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + saver.end_object (entry->ext_id_, REGISTRY_CALLBACK_TYPE ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +// todo: +// for all deleted children +// { +// saver.delete_child(child_type, child_id); +// } + saver.end_object (0, REGISTRY_TYPE ACE_ENV_ARG_PARAMETER); + } + + /////////////////////////////////////// + // During reload of persistent topology + + Topology_Object* + Reconnection_Registry::load_child (const ACE_CString & type, + CORBA::Long, + const NVPList& attrs + ACE_ENV_ARG_DECL_NOT_USED) + { + if (type == REGISTRY_CALLBACK_TYPE) + { + NotifyExt::ReconnectionRegistry::ReconnectionID id; + ACE_CString ior; + if (attrs.load (RECONNECT_ID, id) && attrs.load (RECONNECT_IOR, ior)) + { + if (id > highest_id_) + { + highest_id_ = id; + + if (DEBUG_LEVEL > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Reconnect registry: reloading %d\n"), + ACE_static_cast (int, id) + )); + } + } + if ( 0 != reconnection_registry_.bind (id, ior)) + { + //@@todo - throw something; + } + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Reconnect registry: missing attribute\n") + )); + } + } + return this; + } + + void + Reconnection_Registry::send_reconnect (CosNotifyChannelAdmin::EventChannelFactory_ptr dest_factory + ACE_ENV_ARG_DECL_NOT_USED) + { + TAO_Notify_Properties* properties = TAO_Notify_PROPERTIES::instance(); + CORBA::ORB_var orb = properties->orb (); + ACE_Vector <NotifyExt::ReconnectionRegistry::ReconnectionID> bad_ids; + + Reconnection_Registry_Type::ENTRY *entry; + for (Reconnection_Registry_Type::ITERATOR iter (this->reconnection_registry_); + iter.next (entry); + iter.advance ()) + { + ACE_TRY_NEW_ENV + { + if (DEBUG_LEVEL > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Reconnection Registry: Sending reconnection to client %d\n"), + ACE_static_cast (int, entry->ext_id_) + )); + } + ACE_CString & ior = entry->int_id_; + CORBA::Object_var obj = orb->string_to_object (ior.c_str () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + NotifyExt::ReconnectionCallback_var callback = + NotifyExt::ReconnectionCallback::_narrow (obj.in ()); + if (!CORBA::is_nil (callback.in ())) + { + callback->reconnect (dest_factory ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Reconnection Registry: Can't resolve reconnection client's IOR %d\n"), + ACE_static_cast (int, entry->ext_id_) + )); + + //throw this entry away but you've got an iterator so be careful + bad_ids.push_back (entry->ext_id_); + } + } + ACE_CATCHANY + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Reconnection Registry: Exception sending reconnection to client -- discarding registry entry\n") + )); + //throw this entry away but you've got an iterator so be careful + bad_ids.push_back (entry->ext_id_); + //@@todo : we might want to check for retryable exceptions, but for now... + } + ACE_ENDTRY; + } + size_t bad_count = bad_ids.size (); + for (size_t nbad = 0; nbad < bad_count; ++nbad) + { + this->reconnection_registry_.unbind (bad_ids[nbad]); + } + } + + void + Reconnection_Registry::release (void) + { + delete this; + //@@ inform factory + } + + +} // namespace TAO_Notify + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Hash_Map_Entry<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString>; +template class ACE_Hash_Map_Manager_Ex<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString, ACE_Hash<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Equal_To<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Base_Ex<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString,ACE_Hash<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Equal_To<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Ex<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString,ACE_Hash<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Equal_To<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator_Ex<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString,ACE_Hash<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Equal_To<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Null_Mutex>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Hash_Map_Entry<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString > +#pragma instantiate ACE_Hash_Map_Manager_Ex<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString ,ACE_Hash<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Equal_To<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString ,ACE_Hash<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Equal_To<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Ex<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString ,ACE_Hash<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Equal_To<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<NotifyExt::ReconnectionRegistry::ReconnectionID, ACE_CString ,ACE_Hash<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Equal_To<NotifyExt::ReconnectionRegistry::ReconnectionID>, ACE_Null_Mutex> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Reconnection_Registry.h b/TAO/orbsvcs/orbsvcs/Notify/Reconnection_Registry.h new file mode 100644 index 00000000000..8571acc47db --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Reconnection_Registry.h @@ -0,0 +1,100 @@ +/* -*- C++ -*- */ +/** + * @file Reconnection_Registry.h + * + * $Id$ + * + * @author Dale Wilson <wilson_d@ociweb.com> + * + */ + +#ifndef TAO_NOTIFY_RECONNECTION_REGISTRY_H +#define TAO_NOTIFY_RECONNECTION_REGISTRY_H +#include /**/ <ace/pre.h> +#include /**/ <ace/config-all.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "Topology_Object.h" + +#include "orbsvcs/NotifyExtS.h" + +#include "ace/Hash_Map_Manager_T.h" +#include "ace/Null_Mutex.h" + +namespace TAO_Notify +{ + static const char REGISTRY_TYPE[] = "reconnect_registry"; + static const char RECONNECT_ID[] = "ReconnectId"; + static const char RECONNECT_IOR[] = "IOR"; + static const char REGISTRY_CALLBACK_TYPE[] = "reconnect_callback"; + + /** + * @class Reconnection_Registry + * + * @brief Implementation of ReconnectionRegistry + * + */ + class TAO_Notify_Serv_Export Reconnection_Registry + : public Topology_Object + { + /// The registry consists of a map from ReconnectionID to stringified IOR + typedef ACE_Hash_Map_Manager_Ex<NotifyExt::ReconnectionRegistry::ReconnectionID, + ACE_CString, + ACE_Hash<NotifyExt::ReconnectionRegistry::ReconnectionID>, + ACE_Equal_To<NotifyExt::ReconnectionRegistry::ReconnectionID>, + ACE_SYNCH_NULL_MUTEX> Reconnection_Registry_Type; + + public: + + /// Constructor + Reconnection_Registry (Topology_Parent & parent); + + /// Destructor + ~Reconnection_Registry (); + + ////////////////////////// + // During normal operation + + /// add a new callback to the registry + ::NotifyExt::ReconnectionRegistry::ReconnectionID register_callback ( + ::NotifyExt::ReconnectionCallback_ptr callback + ACE_ENV_ARG_DECL); + + /// + void unregister_callback (::NotifyExt::ReconnectionRegistry::ReconnectionID id + ACE_ENV_ARG_DECL); + + CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL); + + ////////////////////// + // During topology save + virtual void save_persistent (Topology_Saver& saver ACE_ENV_ARG_DECL); + + /////////////////////////////////////// + // During reload of persistent topology + + virtual Topology_Object* load_child (const ACE_CString & type, + CORBA::Long id, + const NVPList& attrs + ACE_ENV_ARG_DECL); + + void send_reconnect (CosNotifyChannelAdmin::EventChannelFactory_ptr dest_factory + ACE_ENV_ARG_DECL); + + void release (void); + + private: + Reconnection_Registry_Type reconnection_registry_; + ::NotifyExt::ReconnectionRegistry::ReconnectionID highest_id_; + }; +} // namespace TAO_Notify + +#if defined (__ACE_INLINE__) +#include "Reconnection_Registry.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ <ace/post.h> +#endif /* TAO_NOTIFY_RECONNECTION_REGISTRY_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Reconnection_Registry.inl b/TAO/orbsvcs/orbsvcs/Notify/Reconnection_Registry.inl new file mode 100644 index 00000000000..19ec798e989 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Reconnection_Registry.inl @@ -0,0 +1,2 @@ +// $Id$ + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.h b/TAO/orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.h index ac1af0f4323..77d1e2a5db1 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.h @@ -31,16 +31,29 @@ class TAO_Notify_Refcountable_Guard_T { public: /// Constuctor - TAO_Notify_Refcountable_Guard_T (T* t); + TAO_Notify_Refcountable_Guard_T (T* t = 0); + + /// Copy constructor + TAO_Notify_Refcountable_Guard_T (const TAO_Notify_Refcountable_Guard_T<T> & rhs); /// Destructor ~TAO_Notify_Refcountable_Guard_T (); /// Redirection operator + T * get (void) const; + + /// Redirection operator T *operator-> (void) const; T &operator *() const; + TAO_Notify_Refcountable_Guard_T<T> & operator = ( + const TAO_Notify_Refcountable_Guard_T<T> & rhs); + +private: + /// helper for exception safeness + /// @throws nothing + void swap (TAO_Notify_Refcountable_Guard_T & rhs); private: T* t_; }; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.inl b/TAO/orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.inl index 5e16e7d04f1..ad651ceb555 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Refcountable_Guard_T.inl @@ -1,26 +1,77 @@ // $Id$ +#include "ace/Log_Msg.h" + template <class T> ACE_INLINE TAO_Notify_Refcountable_Guard_T<T>::TAO_Notify_Refcountable_Guard_T (T *t) : t_ (t) { - this->t_->_incr_refcnt (); + if (this->t_ != 0) + { + this->t_->_incr_refcnt (); + } +} + +template <class T> ACE_INLINE +TAO_Notify_Refcountable_Guard_T<T>::TAO_Notify_Refcountable_Guard_T (const TAO_Notify_Refcountable_Guard_T<T> &rhs) + : t_ (rhs.t_) +{ + if (this->t_ != 0) + { + this->t_->_incr_refcnt (); + } } template <class T> ACE_INLINE TAO_Notify_Refcountable_Guard_T<T>::~TAO_Notify_Refcountable_Guard_T () { - this->t_->_decr_refcnt (); + if (this->t_ != 0) + { + this->t_->_decr_refcnt (); + } +} + +template <class T> ACE_INLINE T* +TAO_Notify_Refcountable_Guard_T<T>::get (void) const +{ + return this->t_; } template <class T> ACE_INLINE T* TAO_Notify_Refcountable_Guard_T<T>::operator-> (void) const { + ACE_ASSERT (this->t_ != 0); return this->t_; } -template <class T> ACE_INLINE T& +template <class T> ACE_INLINE +T& TAO_Notify_Refcountable_Guard_T<T>::operator *(void) const { + ACE_ASSERT (this->t_ != 0); return *this->t_; } + +template <class T> ACE_INLINE +TAO_Notify_Refcountable_Guard_T<T> & +TAO_Notify_Refcountable_Guard_T<T>::operator = ( + const TAO_Notify_Refcountable_Guard_T<T> & rhs) +{ + // note exception safe assignment. see Sutter's "Exceptional C++" + // note it's worth the following optimization to avoid threadsafe increment/decrement refcounters + if (this->t_ != rhs.t_) { + TAO_Notify_Refcountable_Guard_T<T> temp(rhs.t_); + swap (temp); +} + return *this; +} + + +template <class T> ACE_INLINE +void +TAO_Notify_Refcountable_Guard_T<T>::swap (TAO_Notify_Refcountable_Guard_T & rhs) +{ + T* pt = rhs.t_; + rhs.t_ = this->t_; + this->t_ = pt; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip.cpp b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip.cpp new file mode 100644 index 00000000000..1f86e0699d9 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip.cpp @@ -0,0 +1,955 @@ +// $Id$ + +#include "Routing_Slip.h" + +#if ! defined (__ACE_INLINE__) +#include "Routing_Slip.inl" +#endif /* __ACE_INLINE__ */ + +#include "Delivery_Request.h" +#include "Worker_Task.h" +#include "ProxyConsumer.h" +#include "ProxySupplier.h" +#include "Event_Persistence_Strategy.h" +#include "Routing_Slip_Persistence_Manager.h" +#include "Routing_Slip_Queue.h" +#include "tao/debug.h" +#include "ace/Dynamic_Service.h" +#include "Method_Request_Lookup.h" +#include "Method_Request_Dispatch.h" + +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + +#define QUEUE_ALLOWED 1 + +namespace TAO_Notify +{ +/////////////////////// +// Routing_Slip Statics + +Routing_Slip_Queue Routing_Slip::persistent_queue_(QUEUE_ALLOWED); + +TAO_SYNCH_MUTEX Routing_Slip::sequence_lock_; +int Routing_Slip::routing_slip_sequence_= 0; +size_t Routing_Slip::count_enter_transient_ = 0; +size_t Routing_Slip::count_continue_transient_ = 0; +size_t Routing_Slip::count_enter_reloaded_ = 0; +size_t Routing_Slip::count_enter_new_ = 0; +size_t Routing_Slip::count_continue_new_ = 0; +size_t Routing_Slip::count_enter_complete_while_new_ = 0; +size_t Routing_Slip::count_enter_saving_ = 0; +size_t Routing_Slip::count_enter_saved_ = 0; +size_t Routing_Slip::count_enter_updating_ = 0; +size_t Routing_Slip::count_enter_changed_while_saving_ = 0; +size_t Routing_Slip::count_continue_changed_while_saving_ = 0; +size_t Routing_Slip::count_enter_changed_ = 0; +size_t Routing_Slip::count_continue_changed_ = 0; +size_t Routing_Slip::count_enter_complete_ = 0; +size_t Routing_Slip::count_enter_deleting_ = 0; +size_t Routing_Slip::count_enter_terminal_ = 0; + +Routing_Slip_Ptr +Routing_Slip::create (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL) +{ + Routing_Slip * prs; + ACE_NEW_THROW_EX (prs, Routing_Slip (event), CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (Routing_Slip_Ptr()); + Routing_Slip_Ptr result(prs); + result->this_ptr_ = result; // let the pointers touch so they use the same ref count + + // note we don't care about ultra-precise stats, so no guard for these + if (DEBUG_LEVEL > 8 && ((result->sequence_ % 100) == 0)) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Routing_Slip_Statistics\n") + ACE_TEXT (" enter_transient \t%d\n") + ACE_TEXT (" continue_transient \t%d\n") + ACE_TEXT (" enter_reloaded \t%d\n") + ACE_TEXT (" enter_new \t%d\n") + ACE_TEXT (" continue_new \t%d\n") + ACE_TEXT (" enter_complete_while_new \t%d\n") + ACE_TEXT (" enter_saving \t%d\n") + ACE_TEXT (" enter_saved \t%d\n") + ACE_TEXT (" enter_updating \t%d\n") + ACE_TEXT (" enter_changed_while_saving \t%d\n") + ACE_TEXT (" continue_changed_while_saving\t%d\n") + ACE_TEXT (" enter_changed \t%d\n") + ACE_TEXT (" continue_changed \t%d\n") + ACE_TEXT (" enter_complete \t%d\n") + ACE_TEXT (" enter_deleting \t%d\n") + ACE_TEXT (" enter_terminal \t%d\n") + , ACE_static_cast (int, count_enter_transient_) + , ACE_static_cast (int, count_continue_transient_) + , ACE_static_cast (int, count_enter_reloaded_) + , ACE_static_cast (int, count_enter_new_) + , ACE_static_cast (int, count_continue_new_) + , ACE_static_cast (int, count_enter_complete_while_new_) + , ACE_static_cast (int, count_enter_saving_) + , ACE_static_cast (int, count_enter_saved_) + , ACE_static_cast (int, count_enter_updating_) + , ACE_static_cast (int, count_enter_changed_while_saving_) + , ACE_static_cast (int, count_continue_changed_while_saving_) + , ACE_static_cast (int, count_enter_changed_) + , ACE_static_cast (int, count_continue_changed_) + , ACE_static_cast (int, count_enter_complete_) + , ACE_static_cast (int, count_enter_deleting_) + , ACE_static_cast (int, count_enter_terminal_) + )); + } + return result; +} + +// static +Routing_Slip_Ptr +Routing_Slip::create ( + TAO_Notify_EventChannelFactory & ecf, + Routing_Slip_Persistence_Manager * rspm) +{ + Routing_Slip_Ptr result; + ACE_Message_Block * event_mb = 0; + ACE_Message_Block * rs_mb = 0; + ACE_TRY_NEW_ENV + { + if (rspm->reload (event_mb, rs_mb)) + { + TAO_InputCDR cdr_event (event_mb); + TAO_Notify_Event_Copy_var event (TAO_Notify_Event::unmarshal (cdr_event)); + if (event.get () != 0) + { + result = create (event ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + TAO_InputCDR cdr_rs (rs_mb); + if ( result->unmarshal (ecf, cdr_rs)) + { + result->set_rspm (rspm); + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Routing_Slip::create: Unmarshalling failed for routing slip.\n") + )); + result.reset (); + } + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Routing_Slip::create: Unmarshalling failed for event.\n") + )); + } + } + } + ACE_CATCHANY + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Routing_Slip::create: Exception reloading event.\n") + )); + } + ACE_ENDTRY; + delete event_mb; + delete rs_mb; + + return result; +} + +void +Routing_Slip::set_rspm (Routing_Slip_Persistence_Manager * rspm) +{ + this->rspm_ = rspm; + if (rspm_ != 0) + { + rspm->set_callback (this); + } +} + +Routing_Slip::Routing_Slip( + const TAO_Notify_Event_var& event) + : is_safe_ (false) + , until_safe_ (internals_) + , this_ptr_ (0) + , event_(event) + , state_ (rssCREATING) + , complete_requests_ (0) + , rspm_ (0) +{ + Routing_Slip_Guard guard (sequence_lock_); + this->sequence_ = ++routing_slip_sequence_; + if (DEBUG_LEVEL > 1) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: constructor\n"), + this->sequence_ + )); +} + +Routing_Slip::~Routing_Slip () +{ + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: destructor\n"), + this->sequence_ + )); +} + +bool +Routing_Slip::create_persistence_manager() +{ + if (this->rspm_ == 0) + { + Event_Persistence_Strategy * strategy = + ACE_Dynamic_Service <TAO_Notify::Event_Persistence_Strategy>::instance ("Event_Persistence"); + if (strategy != 0) + { + Event_Persistence_Factory * factory = strategy->get_factory (); + if (factory != 0) + { + set_rspm (factory->create_routing_slip_persistence_manager(this)); + } + } + } + return this->rspm_ != 0; +} + +const TAO_Notify_Event_var & +Routing_Slip::event () const +{ + return this->event_; +} + +void +Routing_Slip::wait_persist () +{ + Routing_Slip_Guard guard (this->internals_); + while (!this->is_safe_) + { + this->until_safe_.wait (); + } +} + +void +Routing_Slip::route (TAO_Notify_ProxyConsumer* pc, bool reliable_channel ACE_ENV_ARG_DECL) +{ + ACE_ASSERT(pc != 0); + + TAO_Notify_Refcountable_Guard_T<TAO_Notify_ProxyConsumer> pcgrd(pc); + + Routing_Slip_Guard guard (this->internals_); + + size_t request_id = delivery_requests_.size (); + + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: add Delivery_Request #%d: lookup, completed %d of %d\n"), + this->sequence_, + ACE_static_cast (int, request_id), + ACE_static_cast (int, this->complete_requests_), + ACE_static_cast (int, this->delivery_requests_.size ()) + )); + + Delivery_Request_Ptr request (new Delivery_Request (this->this_ptr_, request_id)); + this->delivery_requests_.push_back (request); + TAO_Notify_Method_Request_Lookup_Queueable method (request, pc); + + if (this->state_ == rssCREATING) + { + if (! reliable_channel) + { + enter_state_transient (guard); + } + else if (ACE_Dynamic_Service <TAO_Notify::Event_Persistence_Strategy>::instance ("Event_Persistence") == 0) + { + enter_state_transient (guard); + } + else if (! this->event_->reliable().is_valid()) + { + enter_state_new (guard); + } + else if (this->event_->reliable().value() == CosNotification::Persistent) + { + enter_state_new (guard); + } + else + { + enter_state_transient (guard); + } + } + guard.release (); + pc->worker_task()->execute (method ACE_ENV_ARG_PARAMETER); +} +#if 0 // forward +void +Routing_Slip::forward (TAO_Notify_ProxySupplier* ps, bool filter) +{ + // must be the first action + ACE_ASSERT (this->state_ == rssCREATING); + + TAO_Notify_Refcountable_Guard_T<TAO_Notify_ProxySupplier> psgrd(ps); + Routing_Slip_Guard guard (this->internals_); + + enter_state_transient (guard); + size_t request_id = delivery_requests_.size (); + + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: add Delivery_Request #%d: Forward %s; completed %d of %d\n"), + this->sequence_, + ACE_static_cast (int, request_id), + filter ? ACE_TEXT ("Filter") : ACE_TEXT ("No Filter"), + ACE_static_cast (int, this->complete_requests_), + ACE_static_cast (int, this->delivery_requests_.size ()) + )); + + Delivery_Request_Ptr request (new Delivery_Request (this->this_ptr_, request_id)); + if (! ps->has_shutdown() ) + { + this->delivery_requests_.push_back (request); +// Delivery_Method_Dispatch method (request, ps, filter); + TAO_Notify_Method_Request_Dispatch_No_Copy method (request, ps, filter); + guard.release (); + if (DEBUG_LEVEL > 8) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Routing Slip #%d: dispatching Delivery_Request %d to " + "proxy supplier %d\n", + this->sequence_, + ACE_static_cast (int, request_id), + ps->id())); + ps->worker_task()->execute (method); + } + else + { + if (DEBUG_LEVEL > 5) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Routing Slip #%d: not dispatching Delivery_Request %d to " + "proxy supplier %d; already shut down\n", + this->sequence_, + ACE_static_cast (int, request_id), + ps->id())); + } +} +#endif // forward + +void +Routing_Slip::dispatch ( + TAO_Notify_ProxySupplier* ps, + bool filter + ACE_ENV_ARG_DECL) +{ + // cannot be the first action + ACE_ASSERT (this->state_ != rssCREATING); + + TAO_Notify_Refcountable_Guard_T<TAO_Notify_ProxySupplier> psgrd(ps); + Routing_Slip_Guard guard (this->internals_); + + size_t request_id = delivery_requests_.size (); + + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: add Delivery_Request #%d: Dispatch %s; completed %d of %d\n"), + this->sequence_, + ACE_static_cast (int, request_id), + filter ? ACE_TEXT ("Filter") : ACE_TEXT ("No Filter"), + ACE_static_cast (int, this->complete_requests_), + ACE_static_cast (int, this->delivery_requests_.size ()) + )); + + Delivery_Request_Ptr request (new Delivery_Request (this->this_ptr_, request_id)); + if (! ps->has_shutdown() ) + { + this->delivery_requests_.push_back (request); + TAO_Notify_Method_Request_Dispatch_No_Copy method (request, ps, filter); + guard.release (); + if (DEBUG_LEVEL > 8) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Routing Slip #%d: dispatching Delivery_Request %d to " + "proxy supplier %d\n", + this->sequence_, + ACE_static_cast (int, request_id), + ps->id())); + ps->worker_task()->execute (method ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + if (DEBUG_LEVEL > 5) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Routing Slip #%d: not dispatching Delivery_Request %d to " + "proxy supplier %d; already shut down\n", + this->sequence_, + ACE_static_cast (int, request_id), + ps->id())); + } +} + +////////// +// signals + +void +Routing_Slip::delivery_request_complete (size_t request_id) +{ + Routing_Slip_Guard guard (this->internals_); + ACE_ASSERT (request_id < this->delivery_requests_.size ()); + // reset the pointer to allow the delivery_request to be deleted. + this->delivery_requests_[request_id].reset (); + this->complete_requests_ += 1; + + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: delivery_request_complete #%d: completed %d of %d\n"), + this->sequence_, + ACE_static_cast (int, request_id), + ACE_static_cast (int, this->complete_requests_), + ACE_static_cast (int, this->delivery_requests_.size ()) + )); + State state = this->state_; + switch (state) + { + case rssTRANSIENT: + { + continue_state_transient (guard); + break; + } + case rssNEW: + { + continue_state_new (guard); + break; + } + case rssSAVING: + { + enter_state_changed_while_saving (guard); + break; + } + case rssUPDATING: + { + enter_state_changed_while_saving (guard); + break; + } + case rssSAVED: + { + enter_state_changed (guard); + break; + } + case rssCHANGED_WHILE_SAVING: + { + continue_state_changed_while_saving (guard); + break; + } + case rssCHANGED: + { + continue_state_changed (guard); + break; + } + default: + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Notification Service Routing Slip: Unexpected delivery_request_complete in state %d\n"), + ACE_static_cast (int, this->state_) + )); + break; + } + } +} + +void +Routing_Slip::at_front_of_persist_queue () +{ + Routing_Slip_Guard guard (this->internals_); + State state = this->state_; + switch (state) + { + case rssNEW: + { + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: NEW Reached front of queue\n"), + this->sequence_ + )); + enter_state_saving (guard); + break; + } + case rssCOMPLETE_WHILE_NEW: + { + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: COMPLETE_WHILE_NEW Reached front of queue\n"), + this->sequence_ + )); + this->persistent_queue_.complete (); + enter_state_terminal (guard); + break; + } + case rssCHANGED: + { + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: CHANGED Reached front of queue\n"), + this->sequence_ + )); + enter_state_updating (guard); + break; + } + case rssCOMPLETE: + { + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: COMPLETE Reached front of queue\n"), + this->sequence_ + )); + enter_state_deleting (guard); + break; + } + default: + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Routing Slip %d: Unexpected at_front_of_persist_queue in state %d\n"), + this->sequence_, + ACE_static_cast (int, this->state_) + )); + break; + } + } +} + +void +Routing_Slip::persist_complete () +{ + // keep this object around til this method returns. + Routing_Slip_Ptr me(this->this_ptr_); + Routing_Slip_Guard guard (this->internals_); + ACE_ASSERT (guard.locked ()); + + // allow the ConsumerProxy to return from the CORBA push call. + if (! is_safe_) + { + is_safe_ = true; + this->until_safe_.signal (); + } + + State state = this->state_; + switch (state) + { + case rssSAVING: + { + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: SAVING persist complete\n"), + this->sequence_ + )); + enter_state_saved(guard); + break; + } + case rssCHANGED_WHILE_SAVING: + { + enter_state_changed (guard); + break; + } + case rssUPDATING: + { + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: UPDATING persist complete\n"), + this->sequence_ + )); + enter_state_saved (guard); + break; + } + case rssDELETING: + { + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: DELETING persist complete\n"), + this->sequence_ + )); + enter_state_terminal (guard); + break; + } + default: + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Notification Service Routing Slip: Unexpected transition in state %d\n"), + ACE_static_cast (int, this->state_) + )); + break; + } + } + this->persistent_queue_.complete (); +} + +////////////////// +// support methods + +bool +Routing_Slip::all_deliveries_complete () const +{ + return this->complete_requests_ == this->delivery_requests_.size (); +} + +void +Routing_Slip::add_to_persist_queue(Routing_Slip_Guard & guard) +{ + guard.release (); + this->persistent_queue_.add (this->this_ptr_); + guard.acquire (); // necessary? +} + +//////////////////// +// State transitions + +void +Routing_Slip::enter_state_new (Routing_Slip_Guard & guard) +{ + ++count_enter_new_; + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state NEW\n"), + this->sequence_ + )); + this->state_ = rssNEW; + add_to_persist_queue(guard); +} + +void +Routing_Slip::continue_state_new (Routing_Slip_Guard & guard) +{ + ++count_continue_new_; + if (all_deliveries_complete ()) + { + this->enter_state_complete_while_new (guard); + } +} +void +Routing_Slip::enter_state_complete_while_new (Routing_Slip_Guard & guard) +{ + ++count_enter_complete_while_new_; + ACE_UNUSED_ARG (guard); + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state COMPLETE_WHILE_NEW\n"), + this->sequence_ + )); + // allow the ConsumerProxy to return from the CORBA push call. + if (! is_safe_) + { + is_safe_ = true; + this->until_safe_.signal (); + } + this->state_ = rssCOMPLETE_WHILE_NEW; +} + +void +Routing_Slip::enter_state_reloaded (Routing_Slip_Guard & guard) +{ + ++count_enter_reloaded_; + ACE_UNUSED_ARG (guard); + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #&d: enter state RELOADED\n"), + this->sequence_ + )); + this->state_ = rssRELOADED; +} + +void +Routing_Slip::enter_state_transient (Routing_Slip_Guard & guard) +{ + ++count_enter_transient_; + ACE_UNUSED_ARG (guard); + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state TRANSIENT\n"), + this->sequence_ + )); + this->state_ = rssTRANSIENT; + if (! is_safe_) + { + is_safe_ = true; + this->until_safe_.signal (); + } + if (all_deliveries_complete ()) + { + enter_state_terminal (guard); + } +} + +void +Routing_Slip::continue_state_transient (Routing_Slip_Guard & guard) +{ + ++count_continue_transient_; + if (all_deliveries_complete ()) + { + enter_state_terminal (guard); + } +} +void +Routing_Slip::enter_state_saving (Routing_Slip_Guard & guard) +{ + ++count_enter_saving_; + if (!create_persistence_manager ()) + { + // Note This should actually be a throw (out of memory) + // but we cheat and make this a transient event. + this->persistent_queue_.complete (); + enter_state_transient (guard); + } + else + { + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state SAVING\n"), + this->sequence_ + )); + this->state_ = rssSAVING; + + TAO_OutputCDR event_cdr; + this->event_->marshal (event_cdr); + + const ACE_Message_Block *event_mb = event_cdr.begin (); + TAO_OutputCDR rs_cdr; + marshal (rs_cdr); + const ACE_Message_Block *rs_mb = rs_cdr.begin (); + + guard.release (); + this->rspm_->store (*event_mb, *rs_mb); + + guard.acquire (); // necessary? + } +} + +void +Routing_Slip::enter_state_saved (Routing_Slip_Guard & guard) +{ + ++count_enter_saved_; + ACE_UNUSED_ARG (guard); + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state SAVED\n"), + this->sequence_ + )); + this->state_ = rssSAVED; +} + +void +Routing_Slip::enter_state_updating (Routing_Slip_Guard & guard) +{ + ++count_enter_updating_; + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state UPDATING\n"), + this->sequence_ + )); + this->state_ = rssUPDATING; + + TAO_OutputCDR rs_cdr; + marshal (rs_cdr); + const ACE_Message_Block *rs_mb = rs_cdr.begin (); + guard.release (); + + ACE_ASSERT (this->rspm_ != 0); + this->rspm_->update (*rs_mb); + guard.acquire (); // necessary? +} + + +void +Routing_Slip::enter_state_changed_while_saving (Routing_Slip_Guard & guard) +{ + ++count_enter_changed_while_saving_; + ACE_UNUSED_ARG (guard); + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state CHANGED_WHILE_SAVING\n"), + this->sequence_ + )); + this->state_ = rssCHANGED_WHILE_SAVING; +} + +void +Routing_Slip::continue_state_changed_while_saving (Routing_Slip_Guard & guard) +{ + ACE_UNUSED_ARG (guard); + // no action necessary +} + +void +Routing_Slip::enter_state_changed (Routing_Slip_Guard & guard) +{ + ++count_enter_changed_; + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state CHANGED\n"), + this->sequence_ + )); + // complete state change BEFORE initiating request to avoid + // race condition if request finishes before state is stable. + this->state_ = rssCHANGED; + if (all_deliveries_complete ()) + { + enter_state_complete (guard); + } + add_to_persist_queue (guard); +} + +void +Routing_Slip::continue_state_changed (Routing_Slip_Guard & guard) +{ + ++count_continue_changed_; + if (all_deliveries_complete ()) + { + enter_state_complete (guard); + } +} + +void +Routing_Slip::enter_state_complete (Routing_Slip_Guard & guard) +{ + ++count_enter_complete_; + ACE_UNUSED_ARG (guard); + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state COMPLETE\n"), + this->sequence_ + )); + this->state_ = rssCOMPLETE; +} + +void +Routing_Slip::enter_state_deleting (Routing_Slip_Guard & guard) +{ + ++count_enter_deleting_; + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state DELETING\n"), + this->sequence_ + )); + this->state_ = rssDELETING; + guard.release (); + this->rspm_->remove (); + guard.acquire (); // necessary? +} + +void +Routing_Slip::enter_state_terminal (Routing_Slip_Guard & guard) +{ + ++count_enter_terminal_; + ACE_UNUSED_ARG (guard); + ACE_ASSERT( this->is_safe_); + if (DEBUG_LEVEL > 8) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Routing Slip #%d: enter state TERMINAL\n"), + this->sequence_ + )); + this->state_ = rssTERMINAL; + this->this_ptr_.reset (); +} + +void +Routing_Slip::marshal (TAO_OutputCDR & cdr) +{ + size_t request_count = this->delivery_requests_.size(); + cdr.write_ulong (request_count - this->complete_requests_); + for (size_t nreq = 0; nreq < request_count; ++nreq) + { + Delivery_Request * request = this->delivery_requests_[nreq].get (); + if (request != 0) + { + request->marshal (cdr); + } + } +} + +bool +Routing_Slip::unmarshal (TAO_Notify_EventChannelFactory &ecf, TAO_InputCDR & cdr) +{ + CORBA::ULong count = 0; + cdr.read_ulong (count); + for (size_t nreq = 0; nreq < count; ++nreq) + { + ACE_CDR::Octet code = 0; + while (cdr.read_octet(code)) + { + ACE_TRY_NEW_ENV + { + if (code == TAO_Notify_Method_Request_Dispatch::persistence_code) + { + Delivery_Request * prequest; + ACE_NEW_THROW_EX ( + prequest, + Delivery_Request(this_ptr_, this->delivery_requests_.size ()), + CORBA::NO_MEMORY ()); + ACE_TRY_CHECK; + Delivery_Request_Ptr request(prequest); + TAO_Notify_Method_Request_Dispatch_Queueable * method = + TAO_Notify_Method_Request_Dispatch::unmarshal ( + request, + ecf, + cdr + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (method != 0) + { + this->delivery_requests_.push_back (request); + this->delivery_methods_.push_back (method); + } + } + else if (code == TAO_Notify_Method_Request_Lookup::persistence_code) + { + Delivery_Request_Ptr request(new Delivery_Request(this_ptr_, this->delivery_requests_.size ())); + TAO_Notify_Method_Request_Lookup_Queueable * method = + TAO_Notify_Method_Request_Lookup::unmarshal ( + request, + ecf, + cdr + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK + if (method != 0) + { + this->delivery_requests_.push_back (request); + this->delivery_methods_.push_back (method); + } + } + } + ACE_CATCHANY; + { + // @@todo should we log this? + // just ignore failures + } + ACE_ENDTRY; + } + } + return this->delivery_requests_.size () > 0; +} + +void +Routing_Slip::reconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + Routing_Slip_Guard guard (this->internals_); + enter_state_saved (guard); + guard.release (); + //@@todo is there a worker_task available to do this? + size_t count = this->delivery_methods_.size (); + for (size_t nmethod = 0; nmethod < count; ++nmethod) + { + this->delivery_methods_[nmethod]->execute (ACE_ENV_SINGLE_ARG_PARAMETER); + } + this->delivery_methods_.clear (); +} + +int +Routing_Slip::sequence() const +{ + return this->sequence_; +} + +bool +Routing_Slip::should_retry () const +{ + // simple minded test: if it's transient, don't retry it + // @@todo Eventually this should check timeout, discard policy, etc. + return this->state_ != rssTRANSIENT; +} + + + +} // namespace + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Auto_Basic_Ptr<TAO_Notify::Routing_Slip>; +template class ACE_Strong_Bound_Ptr<TAO_Notify::Routing_Slip, TAO_SYNCH_MUTEX>; +template class ACE_Auto_Basic_Ptr<TAO_Notify::Delivery_Request>; +template class ACE_Strong_Bound_Ptr<TAO_Notify::Delivery_Request,TAO_SYNCH_MUTEX>; +template class ACE_Vector <TAO_Notify::Delivery_Request_Ptr>; +template class ACE_Array_Base<ACE_Strong_Bound_Ptr<TAO_Notify::Delivery_Request,TAO_SYNCH_MUTEX> >; +template class ACE_Vector <TAO_Notify::Delivery_Request *>; +template class ACE_Array_Base<TAO_Notify::Delivery_Request *>; +template class ACE_Dynamic_Service <TAO_Notify::Event_Persistence_Strategy>; +template class ACE_Array_Base<TAO_Notify_Method_Request_Dispatch_No_Copy*>; +template class ACE_Vector<TAO_Notify_Method_Request_Dispatch_No_Copy*>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Notify::Routing_Slip> +#pragma instantiate ACE_Strong_Bound_Ptr<TAO_Notify::Routing_Slip,TAO_SYNCH_MUTEX> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Notify::Delivery_Request> +#pragma instantiate ACE_Strong_Bound_Ptr<TAO_Notify::Delivery_Request,TAO_SYNCH_MUTEX> +#pragma instantiate ACE_Vector <TAO_Notify::Delivery_Request_Ptr> +#pragma instantiate ACE_Array_Base<ACE_Strong_Bound_Ptr<TAO_Notify::Delivery_Request,TAO_SYNCH_MUTEX> > +#pragma instantiate ACE_Vector <TAO_Notify::Delivery_Request *> +#pragma instantiate ACE_Array_Base<TAO_Notify::Delivery_Request *> +#pragma instantiate ACE_Dynamic_Service <TAO_Notify::Event_Persistence_Strategy> +#pragma instantiate ACE_Array_Base<TAO_Notify_Method_Request_Dispatch_No_Copy*> +#pragma instantiate ACE_Vector<TAO_Notify_Method_Request_Dispatch_No_Copy*> +#endif /*ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip.h b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip.h new file mode 100644 index 00000000000..92f21cb075a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip.h @@ -0,0 +1,243 @@ +/* -*- C++ -*- */ +/** + * @file Routing_Slip.h + * + * $Id$ + * + * @author Dale Wilson <wilson_d@ociweb.com> + * + * + */ + +#ifndef TAO_NOTIFY_ROUTING_SLIP_H +#define TAO_NOTIFY_ROUTING_SLIP_H +#include "ace/pre.h" + +#include "notify_serv_export.h" +#include "Event.h" +#include "Delivery_Request.h" +#include "Event_Persistence_Factory.h" + +#include "Persistent_File_Allocator.h" // for Persistent_Callback + +#include <ace/Vector_T.h> +#include <ace/Malloc_Base.h> // necessary? + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// Forward declarations of classes/pointers/collections +// referenced from this header +class TAO_Notify_EventChannelFactory; +class TAO_Notify_Method_Request; +class TAO_Notify_ProxyConsumer; +class TAO_Notify_ProxySupplier; +class TAO_Notify_Method_Request_Queueable; + +namespace TAO_Notify +{ + +class TAO_Notify_Serv_Export Routing_Slip_Persistence_Manager; + +// Forward declarations of TAO_Notify classes/pointers/collections +// referenced from this header + +/// A vector of Delivery Requests. The body of a Routing_Slip. +typedef ACE_Vector <Delivery_Request_Ptr> Delivery_Request_Vec; + +/// A vector of Methods_. Used during recovery. +typedef ACE_Vector <TAO_Notify_Method_Request_Queueable *> Delivery_Method_Vec; + +class Routing_Slip; +/// A reference-counted smart pointer to a Routing_Slip +typedef ACE_Strong_Bound_Ptr<Routing_Slip, TAO_SYNCH_MUTEX> Routing_Slip_Ptr; + +class Routing_Slip_Persistence_Manager; + +class Routing_Slip_Queue; + +/** + * \brief Class which manages the delivery of events to destination. + * + * Interacts with persistent storage to provide reliable delivery. + */ +class TAO_Notify_Serv_Export Routing_Slip : public Persistent_Callback +{ + typedef ACE_Guard< TAO_SYNCH_MUTEX > Routing_Slip_Guard; +public: + /// "Factory" method for normal use. + static Routing_Slip_Ptr create (const TAO_Notify_Event_var& event + ACE_ENV_ARG_DECL); + + /// "Factory" method for use during reload from persistent storage. + static Routing_Slip_Ptr create ( + TAO_Notify_EventChannelFactory & ecf, + Routing_Slip_Persistence_Manager * rspm); + + void set_rspm (Routing_Slip_Persistence_Manager * rspm); + + void reconnect (ACE_ENV_SINGLE_ARG_DECL); + + /// destructor (should be private but that inspires compiler wars) + virtual ~Routing_Slip (); + + ////////////////// + // Action requests + + /// Route this event to destinations + /// must be the Action request after + /// the routing slip is created. + void route (TAO_Notify_ProxyConsumer* pc, bool reliable_channel ACE_ENV_ARG_DECL); + + /// \brief Schedule delivery to a consumer via a proxy supplier + /// \param proxy_supplier the proxy supplier that will deliver the event + /// \param filter should consumer-based filtering be applied? + void dispatch (TAO_Notify_ProxySupplier * proxy_supplier, bool filter ACE_ENV_ARG_DECL); + + + ///////////////////////////////////////// + /// \brief Wait until the event/routing_slip has + /// been saved at least once. + void wait_persist (); + + ///////////////////////////////////// + // signals from the rest of the world + + /// \brief A delivery request has been satisfied. + void delivery_request_complete (size_t request_id); + + /// \brief This Routing_Slip reached the front of the persistence queue + void at_front_of_persist_queue (); + + /// \brief The persistent storage has completed the last request. + virtual void persist_complete (); + + ///////////////////////////////////////////////////// + // \brief Access the event associated with this routing slip + const TAO_Notify_Event_var & event () const; + + /// \brief Provide an identifying number for this Routing Slip + /// to use in debug messages. + int sequence() const; + + /// \brief Should delivery of this event be retried if it fails? + bool should_retry () const; + +private: + //////////////////// + // state transitions + void enter_state_transient (Routing_Slip_Guard & guard); + void continue_state_transient (Routing_Slip_Guard & guard); + void enter_state_reloaded (Routing_Slip_Guard & guard); + void enter_state_new (Routing_Slip_Guard & guard); + void continue_state_new (Routing_Slip_Guard & guard); + void enter_state_complete_while_new (Routing_Slip_Guard & guard); + void enter_state_saving (Routing_Slip_Guard & guard); + void enter_state_saved (Routing_Slip_Guard & guard); + void enter_state_updating (Routing_Slip_Guard & guard); + void enter_state_changed_while_saving (Routing_Slip_Guard & guard); + void continue_state_changed_while_saving (Routing_Slip_Guard & guard); + void enter_state_changed (Routing_Slip_Guard & guard); + void continue_state_changed (Routing_Slip_Guard & guard); + void enter_state_complete (Routing_Slip_Guard & guard); + void enter_state_deleting (Routing_Slip_Guard & guard); + void enter_state_terminal (Routing_Slip_Guard & guard); + +private: + bool create_persistence_manager(); + + /// Private constructor for use by create method + Routing_Slip(const TAO_Notify_Event_var& event); + + /// Test to see if all deliveries are complete. + bool all_deliveries_complete () const; + + /// This routing_slip needs to be saved. + void add_to_persist_queue(Routing_Slip_Guard & guard); + + /// Marshal into a CDR + void marshal (TAO_OutputCDR & cdr); + + /// Marshal from CDR + bool unmarshal (TAO_Notify_EventChannelFactory &ecf, TAO_InputCDR & rscdr); + +private: + /// Protection for internal information + TAO_SYNCH_MUTEX internals_; + /// true when event persistence qos is guaranteed + bool is_safe_; + /// signalled when is_safe_ goes true + ACE_SYNCH_CONDITION until_safe_; + + /// Smart pointer to this object + /// Provides continuity between smart pointers and "Routing_Slip::this" + /// Also lets the Routing_Slip manage its own minimum lifetime. + Routing_Slip_Ptr this_ptr_; + + // The event being delivered. + TAO_Notify_Event_var event_; + + /// A mini-state machine to control persistence + /// See external doc for circles and arrows. + enum State + { + rssCREATING, + rssTRANSIENT, + rssRELOADED, + rssNEW, + rssCOMPLETE_WHILE_NEW, + rssSAVING, + rssSAVED, + rssUPDATING, + rssCHANGED_WHILE_SAVING, + rssCHANGED, + rssCOMPLETE, + rssDELETING, + rssTERMINAL + } state_; + + /// A collection of delivery requests + Delivery_Request_Vec delivery_requests_; + + /// Methods that should be restarted during event recovery + Delivery_Method_Vec delivery_methods_; + + /// How many delivery requests are complete + size_t complete_requests_; + + /// Pointer to a Routing_Slip_Persistence_Manager + Routing_Slip_Persistence_Manager * rspm_; + + int sequence_; + + static TAO_SYNCH_MUTEX sequence_lock_; + static int routing_slip_sequence_; + static size_t count_enter_transient_; + static size_t count_continue_transient_; + static size_t count_enter_reloaded_; + static size_t count_enter_new_; + static size_t count_continue_new_; + static size_t count_enter_complete_while_new_; + static size_t count_enter_saving_; + static size_t count_enter_saved_; + static size_t count_enter_updating_; + static size_t count_enter_changed_while_saving_; + static size_t count_continue_changed_while_saving_; + static size_t count_enter_changed_; + static size_t count_continue_changed_; + static size_t count_enter_complete_; + static size_t count_enter_deleting_; + static size_t count_enter_terminal_; + + static Routing_Slip_Queue persistent_queue_; +}; + +} // namespace + +#if defined (__ACE_INLINE__) +#include "Routing_Slip.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" +#endif /* TAO_NOTIFY_ROUTING_SLIP_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip.inl b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip.inl new file mode 100644 index 00000000000..191a12b479b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip.inl @@ -0,0 +1,9 @@ +/* -*- C++ -*- */ +// $Id$ + +namespace TAO_Notify +{ + // this is a placeholder for code that will be moved here RSN. + +} // namespace TAO_Notify + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.cpp b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.cpp new file mode 100644 index 00000000000..b7240fd5d2f --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.cpp @@ -0,0 +1,803 @@ +// $Id$ + +#include "Routing_Slip_Persistence_Manager.h" +#include "Standard_Event_Persistence.h" +#include "Persistent_File_Allocator.h" + +namespace TAO_Notify +{ + +Routing_Slip_Persistence_Manager::Routing_Slip_Persistence_Manager( + Standard_Event_Persistence_Factory* factory) + : removed_(false) + , serial_number_(0) + , allocator_(factory->allocator()) + , factory_(factory) + , first_event_block_(0) + , first_routing_slip_block_(0) + , callback_(0) + , event_mb_ (0) + , routing_slip_mb_(0) +{ + this->prev_manager_ = this; + this->next_manager_ = this; +} + +Routing_Slip_Persistence_Manager::~Routing_Slip_Persistence_Manager() +{ + ACE_ASSERT(this->prev_manager_ == this); + ACE_ASSERT(this->next_manager_ == this); + delete this->first_event_block_; + this->first_event_block_ = 0; + delete this->first_routing_slip_block_; + this->first_routing_slip_block_ = 0; + delete this->event_mb_; + this->event_mb_ = 0; + delete this->routing_slip_mb_; + this->routing_slip_mb_ = 0; +} + +void +Routing_Slip_Persistence_Manager::set_callback(Persistent_Callback* callback) +{ + ACE_GUARD(ACE_SYNCH_MUTEX, ace_mon, this->lock_); + this->callback_ = callback; +} + +bool +Routing_Slip_Persistence_Manager::store_root() +{ + bool result = false; + + this->factory_->get_preallocated_pointer ( + this->routing_slip_header_.next_serial_number, + this->routing_slip_header_.next_routing_slip_block); + + // we should already have a psb, but JIC + ACE_ASSERT(this->first_routing_slip_block_ != 0); + ACE_ASSERT(this->first_routing_slip_block_->block_number() == + ROUTING_SLIP_ROOT_BLOCK_NUMBER); + + // Don't take any chances. Use hard-wired root serial number. + this->routing_slip_header_.serial_number = ROUTING_SLIP_ROOT_SERIAL_NUMBER; + + // This will eventually break after something like 58000 years. + // At such time we should change this to !=. + ACE_ASSERT(this->routing_slip_header_.next_serial_number > + ROUTING_SLIP_ROOT_SERIAL_NUMBER); + + ACE_Message_Block versioninfo(2); + versioninfo.wr_ptr()[0] = 1; // Major version number + versioninfo.wr_ptr()[1] = 0; // Minor version number + versioninfo.wr_ptr(2); + ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result); + result = this->build_chain(this->first_routing_slip_block_, + this->routing_slip_header_, this->allocated_routing_slip_blocks_, + versioninfo); + if (result) + { + this->routing_slip_header_.put_header(*this->first_routing_slip_block_); + this->allocator_->write(this->first_routing_slip_block_); + } + return result; +} + +bool +Routing_Slip_Persistence_Manager::reload( + ACE_Message_Block*& event, + ACE_Message_Block*& routing_slip) +{ + bool result = false; + if (this->event_mb_ != 0 && this->routing_slip_mb_ != 0) + { + event = this->event_mb_; + this->event_mb_ = 0; + routing_slip = this->routing_slip_mb_; + this->routing_slip_mb_ = 0; + result = true; + } + else + { + event = 0; + routing_slip = 0; + } + return result; +} + +bool +Routing_Slip_Persistence_Manager::load( + Block_Number block_number, + Block_Serial_Number expected_serial_number) +{ + /** + * NOTE: There is no need to worry about guarding anything. We assume + * that there will be one and only one thread doing the entire + * reload process. + */ + bool result = false; + size_t block_size = this->allocator_->block_size(); + this->first_routing_slip_block_ = + this->allocator_->allocate_at(block_number); + this->first_routing_slip_block_->set_allocator_owns(false); + this->first_routing_slip_block_->set_sync(); + + this->serial_number_ = expected_serial_number; + + ACE_NEW_NORETURN(this->routing_slip_mb_, ACE_Message_Block(block_size)); + ACE_NEW_NORETURN(this->event_mb_, ACE_Message_Block(block_size)); + if (this->event_mb_ != 0 && this->routing_slip_mb_ != 0) + { + if (this->reload_chain( + this->first_routing_slip_block_, + this->routing_slip_header_, + this->allocated_routing_slip_blocks_, + this->routing_slip_mb_, + expected_serial_number)) + { + if (this->routing_slip_header_.event_block != 0) + { + this->first_event_block_ = this->allocator_->allocate_at( + this->routing_slip_header_.event_block); + result = this->reload_chain( + this->first_event_block_, + this->event_header_, + this->allocated_event_blocks_, + this->event_mb_, + 0); + } + else if (block_number == ROUTING_SLIP_ROOT_BLOCK_NUMBER) + { + // only the root can lack event + result = true; + } + else + { + ACE_ERROR((LM_ERROR, + ACE_TEXT( + "(%P|%t) Reloaded Persistent Event is missing event.\n") + )); + } + } + } + if (! result) + { + delete this->routing_slip_mb_; + this->routing_slip_mb_ = 0; + delete this->event_mb_; + this->event_mb_ = 0; + } + return result; +} + +Routing_Slip_Persistence_Manager * +Routing_Slip_Persistence_Manager::load_next () +{ + Routing_Slip_Persistence_Manager * result; + ACE_NEW_RETURN(result, Routing_Slip_Persistence_Manager (this->factory_), 0); + + if (result->load(this->routing_slip_header_.next_routing_slip_block, + this->routing_slip_header_.next_serial_number)) + { + result->dllist_push_back(); + } + else + { + // steal the psb for use as the next psb. + // delete the rspm. We'll create another one later. + Persistent_Storage_Block * next_psb = result->first_routing_slip_block_; + result->first_routing_slip_block_ = 0; +// next_psb->set_allocator_owns(true); + this->factory_->done_reloading ( + next_psb, + result->serial_number_); + delete result; + result = 0; + } + return result; +} + +bool +Routing_Slip_Persistence_Manager::store(const ACE_Message_Block& event, + const ACE_Message_Block& routing_slip) +{ + bool result = false; + ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result); + if (!this->removed_) + { + result = store_i(event, routing_slip); + } + return result; +} + +bool +Routing_Slip_Persistence_Manager::update(const ACE_Message_Block& routing_slip) +{ + bool result = false; + ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result); + // If we have not gotten the event yet or we have no allocator, fail + if (!this->removed_) + { + if (this->persisted()) + { + result = update_i(routing_slip); + } + } + return result; +} + +bool +Routing_Slip_Persistence_Manager::remove() +{ + bool result = false; + ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result); + // Assert that this is in the dllist + ACE_ASSERT(this->prev_manager_ != this); + ACE_ASSERT(this->persisted()); + Routing_Slip_Persistence_Manager* prev = this->prev_manager_; + // Once our previous manager removes us, we can deallocate in any order + this->factory_->lock.acquire(); + this->remove_from_dllist(); + result = prev->update_next_manager(this); + this->factory_->lock.release(); + size_t block_number = 0; + if (this->first_routing_slip_block_ != 0) + { + this->allocator_->free(this->first_routing_slip_block_->block_number()); + delete this->first_routing_slip_block_; + this->first_routing_slip_block_ = 0; + } + if (this->first_event_block_ != 0) + { + this->allocator_->free(this->first_event_block_->block_number()); + delete this->first_event_block_; + this->first_event_block_ = 0; + } + while (this->allocated_routing_slip_blocks_.pop(block_number) == 0) + { + this->allocator_->free(block_number); + } + while (this->allocated_event_blocks_.pop(block_number) == 0) + { + this->allocator_->free(block_number); + } + this->removed_ = true; + Persistent_Storage_Block* callbackblock = + this->allocator_->allocate_nowrite(); + callbackblock->set_callback(this->callback_); + result &= this->allocator_->write(callbackblock); + return result; +} + +Routing_Slip_Persistence_Manager::Block_Header::Block_Header(Header_Type type) + : serial_number (0) + , next_overflow(0) + , header_type (ACE_static_cast (Block_Type, type)) + , data_size(0) +{ +} + +size_t +Routing_Slip_Persistence_Manager::Block_Header::extract_header( + Persistent_Storage_Block& psb, const size_t offset) +{ + size_t pos = offset; + unsigned char* data = psb.data(); + + serial_number = data[pos++]; + serial_number = (serial_number << 8) + data[pos++]; + serial_number = (serial_number << 8) + data[pos++]; + serial_number = (serial_number << 8) + data[pos++]; + serial_number = (serial_number << 8) + data[pos++]; + serial_number = (serial_number << 8) + data[pos++]; + serial_number = (serial_number << 8) + data[pos++]; + serial_number = (serial_number << 8) + data[pos++]; + + next_overflow = data[pos++]; + next_overflow = (next_overflow << 8) + data[pos++]; + next_overflow = (next_overflow << 8) + data[pos++]; + next_overflow = (next_overflow << 8) + data[pos++]; + + header_type = data[pos++]; + header_type = (data_size << 8) + data[pos++]; + + data_size = data[pos++]; + data_size = (data_size << 8) + data[pos++]; + return pos; +} + +size_t +Routing_Slip_Persistence_Manager::Block_Header::put_header( + Persistent_Storage_Block& psb, size_t offset) +{ + // Assume that our psb can hold our small amount of data... + size_t pos = offset; + unsigned char* data = psb.data(); + // Store serial_number + data[pos++] = ACE_static_cast (unsigned char, (serial_number >> 56) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (serial_number >> 48) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (serial_number >> 40) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (serial_number >> 32) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (serial_number >> 24) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (serial_number >> 16) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (serial_number >> 8) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (serial_number >> 0) & 0xff); + // Store next_overflow + data[pos++] = next_overflow >> 24; + data[pos++] = (next_overflow >> 16) & 0xff; + data[pos++] = (next_overflow >> 8) & 0xff; + data[pos++] = next_overflow & 0xff; + // Store header_type + data[pos++] = (header_type >> 8) & 0xff; + data[pos++] = header_type & 0xff; + // Store data_size + data[pos++] = (data_size >> 8) & 0xff; + data[pos++] = data_size & 0xff; + + return pos; +} + +Routing_Slip_Persistence_Manager::Routing_Slip_Header::Routing_Slip_Header() + : Block_Header (BT_Event) + , next_routing_slip_block(0) + , next_serial_number(0) + , event_block(0) +{ +} + +size_t +Routing_Slip_Persistence_Manager::Routing_Slip_Header::extract_header( + Persistent_Storage_Block& psb, const size_t offset) +{ + size_t pos = offset; + pos = this->Block_Header::extract_header(psb, pos); + unsigned char* data = psb.data(); + next_routing_slip_block = data[pos++]; + next_routing_slip_block = (next_routing_slip_block << 8) + data[pos++]; + next_routing_slip_block = (next_routing_slip_block << 8) + data[pos++]; + next_routing_slip_block = (next_routing_slip_block << 8) + data[pos++]; + next_serial_number = data[pos++]; + next_serial_number = (next_serial_number << 8) + data[pos++]; + next_serial_number = (next_serial_number << 8) + data[pos++]; + next_serial_number = (next_serial_number << 8) + data[pos++]; + next_serial_number = (next_serial_number << 8) + data[pos++]; + next_serial_number = (next_serial_number << 8) + data[pos++]; + next_serial_number = (next_serial_number << 8) + data[pos++]; + next_serial_number = (next_serial_number << 8) + data[pos++]; + event_block = data[pos++]; + event_block = (event_block << 8) + data[pos++]; + event_block = (event_block << 8) + data[pos++]; + event_block = (event_block << 8) + data[pos++]; + return pos; +} + +size_t +Routing_Slip_Persistence_Manager::Routing_Slip_Header::put_header( + Persistent_Storage_Block& psb, const size_t offset) +{ + // Assume that our psb can hold our small amount of data... + size_t pos = offset; + // Store serial number, next_overflow and data_size + pos = this->Block_Header::put_header(psb, pos); + + unsigned char* data = psb.data(); + // Store next_routing_slip_block + data[pos++] = next_routing_slip_block >> 24; + data[pos++] = (next_routing_slip_block >> 16) & 0xff; + data[pos++] = (next_routing_slip_block >> 8) & 0xff; + data[pos++] = next_routing_slip_block & 0xff; + // Store serial_number + data[pos++] = ACE_static_cast (unsigned char, (next_serial_number >> 56) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (next_serial_number >> 48) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (next_serial_number >> 40) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (next_serial_number >> 32) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (next_serial_number >> 24) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (next_serial_number >> 16) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (next_serial_number >> 8) & 0xff); + data[pos++] = ACE_static_cast (unsigned char, (next_serial_number >> 0) & 0xff); + // Store event_block + data[pos++] = event_block >> 24; + data[pos++] = (event_block >> 16) & 0xff; + data[pos++] = (event_block >> 8) & 0xff; + data[pos++] = event_block & 0xff; + return pos; +} + +Routing_Slip_Persistence_Manager::Overflow_Header::Overflow_Header () + : Block_Header (BT_Overflow) +{ +} + +Routing_Slip_Persistence_Manager::Event_Header::Event_Header () + : Block_Header (BT_Routing_Slip) +{ +} + +bool +Routing_Slip_Persistence_Manager::store_i(const ACE_Message_Block& event, + const ACE_Message_Block& routing_slip) +{ + bool result = false; + + bool initially_persisted = this->persisted(); + if (!initially_persisted) + { + this->factory_->lock.acquire(); + this->factory_->preallocate_next_record(this->serial_number_, + this->first_routing_slip_block_, + this->routing_slip_header_.next_serial_number, + this->routing_slip_header_.next_routing_slip_block); + this->routing_slip_header_.serial_number = this->serial_number_; + } + + result = this->build_chain(this->first_routing_slip_block_, + this->routing_slip_header_, this->allocated_routing_slip_blocks_, + routing_slip); + + if (result) + { + // No need for a callback here since we do our own below + result &= this->store_event(event); + // If we have an event block allocated, update our header + if (this->first_event_block_ != 0) + { + this->routing_slip_header_.event_block = + this->first_event_block_->block_number(); + } + else + { + ACE_ERROR((LM_ERROR, + ACE_TEXT( + "(%P|%t) No Event is being stored with this routing slip.\n") + )); + } + // Always write our first block out. + this->dllist_push_back(); + result &= (this->write_first_routing_slip_block() != 0); + // because the first rs blocks everywhere have been given sync, we are + // guaranteed that they will be totally written by the time we get to this + // empty callback-only block. + Persistent_Storage_Block* callbackblock = + this->allocator_->allocate_nowrite(); + callbackblock->set_callback(this->callback_); + result &= this->allocator_->write(callbackblock); + } + if (!initially_persisted) + { + this->factory_->lock.release(); + } + return result; +} + +bool +Routing_Slip_Persistence_Manager::update_i( + const ACE_Message_Block& routing_slip) +{ + bool result = true; + size_t routing_slip_size = routing_slip.total_length(); + if (routing_slip_size != 0) + { + result = this->build_chain(this->first_routing_slip_block_, + this->routing_slip_header_, this->allocated_routing_slip_blocks_, + routing_slip); + + result &= this->allocator_->write(this->first_routing_slip_block_); + } + Persistent_Storage_Block* callbackblock = + this->allocator_->allocate_nowrite(); + callbackblock->set_callback(this->callback_); + result &= this->allocator_->write(callbackblock); + return result; +} + +bool +Routing_Slip_Persistence_Manager::store_event( + const ACE_Message_Block& event) +{ + bool result = true; + size_t event_size = event.total_length(); + if (event_size != 0) + { + if (this->first_event_block_ == 0) + { + this->first_event_block_ = this->allocator_->allocate(); + this->first_event_block_->set_allocator_owns(false); + } + + result = this->build_chain(this->first_event_block_, + this->event_header_, this->allocated_event_blocks_, + event); + + result &= this->allocator_->write(this->first_event_block_); + } + return result; +} + +size_t +Routing_Slip_Persistence_Manager::fill_block(Persistent_Storage_Block& psb, + const size_t offset_into_block, const ACE_Message_Block* data, + const size_t offset_into_msg) +{ + unsigned char* ptr = (unsigned char*)data->rd_ptr(); + return this->fill_block(psb, offset_into_block, ptr + offset_into_msg, + data->length() - offset_into_msg); +} + +size_t +Routing_Slip_Persistence_Manager::fill_block(Persistent_Storage_Block& psb, + const size_t offset_into_block, unsigned char* data, const size_t data_size) +{ + size_t result = 0; + if (data_size > 0) + { + const size_t max_size = this->allocator_->block_size() - offset_into_block; + size_t size_to_copy = data_size; + if (size_to_copy > max_size) + { + size_to_copy = max_size; + result = data_size - size_to_copy; + } + else + { + result = 0; + } + ACE_OS::memcpy(psb.data() + offset_into_block, data, size_to_copy); + } + return result; +} + +bool +Routing_Slip_Persistence_Manager::build_chain( + Persistent_Storage_Block* first_block, Block_Header& first_header, + ACE_Unbounded_Stack<size_t>& allocated_blocks, + const ACE_Message_Block& data) +{ + size_t data_size = data.total_length(); + size_t remainder = data_size; + bool result = true; + // Save the number of items currently on the allocation list for + ACE_Unbounded_Stack<size_t> blocks_to_free; + size_t block_number = 0; + + // reverse the order so when we pop, we free up things closer to block 0 + // first + while (allocated_blocks.pop(block_number) == 0) + { + blocks_to_free.push(block_number); + } + size_t pos = first_header.put_header( + *first_block); + const ACE_Message_Block* mblk = &data; + remainder = this->fill_block(*first_block, pos, mblk, 0); + while ((remainder == 0) && (mblk->cont() != 0)) + { + pos += mblk->length(); + mblk = mblk->cont(); + remainder = this->fill_block(*first_block, pos, mblk, 0); + } + first_header.data_size = data_size - remainder; + first_header.next_overflow = 0; + + Block_Header* prevhdr = &first_header; + Persistent_Storage_Block* prevblk = first_block; + + while (remainder > 0) + { + Overflow_Header* hdr = 0; + ACE_NEW_RETURN(hdr, Overflow_Header, result); + + Persistent_Storage_Block* curblk = this->allocator_->allocate(); + allocated_blocks.push(curblk->block_number()); + // Set the previous block's overflow "pointer" to us. + prevhdr->next_overflow = curblk->block_number(); + prevhdr->put_header(*prevblk); + pos = hdr->put_header(*curblk); + hdr->data_size = remainder; + + size_t offset_into_msg = mblk->length() - remainder; + remainder = this->fill_block(*curblk, pos, mblk, offset_into_msg); + while ((remainder == 0) && (mblk->cont() != 0)) + { + pos += mblk->length(); + mblk = mblk->cont(); + remainder = this->fill_block(*curblk, pos, mblk, 0); + } + + hdr->data_size -= remainder; + if (prevblk != first_block) + { + // allocator obtains ownership, so write out and delete the header + // only. + result &= this->allocator_->write(prevblk); + delete prevhdr; + } + prevblk = curblk; + prevhdr = hdr; + } + if (prevblk != first_block) + { + prevhdr->put_header(*prevblk); + result &= this->allocator_->write(prevblk); + delete prevhdr; + } + pos = first_header.put_header( + *first_block); + // Free all but the first routing_slip_block + while (blocks_to_free.pop(block_number) == 0) + { + this->allocator_->free(block_number); + } + + return result; +} + +bool +Routing_Slip_Persistence_Manager::reload_chain( + Persistent_Storage_Block* first_block, Block_Header& first_header, + ACE_Unbounded_Stack<size_t>& allocated_blocks, + ACE_Message_Block* amb, + ACE_UINT64 expected_serial_number + ) +{ + bool result = false; + size_t block_size = this->allocator_->block_size(); + if (this->allocator_->read(first_block)) + { + size_t pos = 0; + size_t nextptr = 0; + ACE_Message_Block* mbptr = amb; + ACE_Message_Block* mbnew = 0; + + pos = first_header.extract_header(*first_block); + if (first_header.serial_number == expected_serial_number) + { + // We have to copy the first block because we cache it. + ACE_OS::memcpy(mbptr->wr_ptr(), first_block->data(), + block_size); + mbptr->rd_ptr(pos); + mbptr->wr_ptr(pos + first_header.data_size); + nextptr = first_header.next_overflow; + while (nextptr != 0) + { + Overflow_Header overflow_header; + ACE_NEW_RETURN(mbnew, ACE_Message_Block(block_size), result); + mbptr->cont(mbnew); + Persistent_Storage_Block* psb = this->allocator_->allocate_at(nextptr); + mbptr = mbnew; + // Deallocate the PSB's data and reallocate it to our wr_ptr()... + psb->reassign_data(ACE_static_cast(unsigned char*, + ACE_static_cast(void*, mbptr->wr_ptr())), true); + // ...read into the PSB (whose data is inside of the AMB)... + this->allocator_->read(psb); + allocated_blocks.push(psb->block_number()); + // ...extract all headers so we know the data's size... + pos = overflow_header.extract_header(*psb); + // ...set up the region that somebody else can look at... + mbptr->rd_ptr(pos); + mbptr->wr_ptr(pos + overflow_header.data_size); + // ...then make sure we don't delete data since we don't own it. + psb->reassign_data(0); + delete psb; + nextptr = overflow_header.next_overflow; + } + result = true; + } + } + return result; +} + +bool +Routing_Slip_Persistence_Manager::update_next_manager( + Routing_Slip_Persistence_Manager* next) +{ + bool result = false; + ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result); + ACE_ASSERT(this->persisted()); + if (!this->removed_) + { + bool updated = false; + if (this->next_manager_ != 0) + { + if (this->routing_slip_header_.next_serial_number != + next->routing_slip_header_.next_serial_number) + { + this->routing_slip_header_.next_serial_number = + next->routing_slip_header_.next_serial_number; + updated = true; + } + if (this->routing_slip_header_.next_routing_slip_block != + next->routing_slip_header_.next_routing_slip_block) + { + this->routing_slip_header_.next_routing_slip_block = + next->routing_slip_header_.next_routing_slip_block; + updated = true; + } + } + if (updated) + { + this->write_first_routing_slip_block(); + } + } + return result; +} + +bool +Routing_Slip_Persistence_Manager::persisted() +{ + return (0 != this->first_routing_slip_block_); +} + +bool +Routing_Slip_Persistence_Manager::is_root () const +{ + return this->serial_number_ == ROUTING_SLIP_ROOT_SERIAL_NUMBER; +} + +void +Routing_Slip_Persistence_Manager::release_all () +{ + ACE_ASSERT(is_root()); + while (this->next_manager_ != this) + { + Routing_Slip_Persistence_Manager * next = this->next_manager_; + next->remove_from_dllist(); + ACE_ASSERT(next != this->next_manager_); + delete next; + } +} + +size_t +Routing_Slip_Persistence_Manager::write_first_routing_slip_block( + bool prepare_only) +{ + size_t pos = this->routing_slip_header_.put_header( + *this->first_routing_slip_block_); + if (!prepare_only) + { + this->allocator_->write(this->first_routing_slip_block_); + } + return pos; +} + +void +Routing_Slip_Persistence_Manager::dllist_push_back() +{ + insert_before (&this->factory_->root()); +} + +void +Routing_Slip_Persistence_Manager::insert_before (Routing_Slip_Persistence_Manager * node) +{ + // Since this is a private function, the caller should have done locking + // on the factory before calling here. The same is true for removals. + ACE_ASSERT(this->prev_manager_ == this); + ACE_ASSERT(this->next_manager_ == this); + ACE_ASSERT(node != this); + this->prev_manager_ = node->prev_manager_; + node->prev_manager_ = this; + this->next_manager_ = node; + this->prev_manager_->next_manager_ = this; +} + +void +Routing_Slip_Persistence_Manager::remove_from_dllist() +{ + // Since this is a private function, the caller should have done locking + // on the factory before calling here. The same is true for insertions. + ACE_ASSERT(this->persisted()); + ACE_ASSERT(this->prev_manager_ != this); + ACE_ASSERT(this->next_manager_ != this); + this->prev_manager_->next_manager_ = this->next_manager_; + this->next_manager_->prev_manager_ = this->prev_manager_; + this->prev_manager_ = this; + this->next_manager_ = this; +} + +} /* namespace TAO_Notify */ + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +//template class ACE_Node<size_t>; +//template class ACE_Unbounded_Stack<size_t>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +//#pragma instantiate ACE_Node<size_t> +//#pragma instantiate ACE_Unbounded_Stack<size_t> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.h b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.h new file mode 100644 index 00000000000..09d84d03f15 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Persistence_Manager.h @@ -0,0 +1,261 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Routing_Slip_Persistence_Manager.h + * + * $Id$ + * + * A Routing_Slip_Persistence manager controls the actual allocation of + * blocks through a Persistent_Storage_Allocator and can persist an + * event and its routing slip. + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef ROUTING_SLIP_PERSISTENCE_MANAGER_H +#define ROUTING_SLIP_PERSISTENCE_MANAGER_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "notify_serv_export.h" +#include "ace/Message_Block.h" +#include "ace/Synch_T.h" +#include "ace/Containers_T.h" + +namespace TAO_Notify +{ +// Some forward declarations. +class Standard_Event_Persistence_Factory; +class Persistent_File_Allocator; +class Persistent_Storage_Block; +class Persistent_Callback; + +/** + * \brief Manage interaction between Routing_Slip and persistent storage. + * + * todo: to complete the strategization of event persistent storage this + * should become an interface that is implemented differently by different + * strategies. For now it interacts with Standard_Event_Persistence. + */ +class TAO_Notify_Serv_Export Routing_Slip_Persistence_Manager +{ +public: + /// A unique identifier for logical blocks in persistent storage. + typedef ACE_UINT64 Block_Serial_Number; + /// The physical address of a block in persistent storage. + typedef ACE_UINT32 Block_Number; + /// The size of a block in persistent storage. + typedef ACE_UINT16 Block_Size; + /// A code to indicate the type of block in persistent storage. + typedef ACE_UINT16 Block_Type; + + /// The constructor. + Routing_Slip_Persistence_Manager(Standard_Event_Persistence_Factory* factory); + + /// The destructor. + ~Routing_Slip_Persistence_Manager(); + + /// Set up callbacks + void set_callback(Persistent_Callback* callback); + + + /// Store an event + routing slip. + bool store(const ACE_Message_Block& event, + const ACE_Message_Block& routing_slip); + + /// \brief Update the routing slip. + /// + /// We must always overwrite the first block + /// last, and it may not chance. Other blocks should be freed and + /// reallocated. + bool update(const ACE_Message_Block& routing_slip); + + /// \brief Remove our associated event and routing slip from the + /// Persistent_File_Allocator. + bool remove(); + + ///////////////////////////////////////// + // Methods to be used during reload only. + + /// \brief Call this method to recover data during event reload. + /// + /// It should not fail under normal circumstances. + /// Caller owns the resulting message blocks and is responsible + /// for deleting them. + /// Reload the event and routing_slip from the Persistent_File_Allocator. + bool reload(ACE_Message_Block*& event, ACE_Message_Block*&routing_slip); + + /// \brief Get next RSPM during reload. + /// + /// After using the data from the reload method, call this + /// method to get the next RSPM. It returns a null pointer + /// when all persistent events have been reloaded. + Routing_Slip_Persistence_Manager * load_next (); + + ///////////////////////// + // Implementation methods. + // Should not be called by Routing_Slip + + /// \brief Commit root data to disk, which should only be done for a root node. + bool store_root(); + + /// \brief Reload data into this RSPM from the given block/serial# + /// + /// \return false if the reload is not successful. + bool load(Block_Number block_number, Block_Serial_Number expected_serial_number); + + /// \brief Is this RSPM attached to the root block? + bool is_root () const; + + /// \brief During cleanup for shut down, release all chained RSPMs. + void release_all (); + +private: + /** + * \brief private: Storage for header information of all persistent block. + */ + class Block_Header + { + public: + enum Header_Type { + BT_Routing_Slip, + BT_Event, + BT_Overflow + }; + + Block_Header(Header_Type type); + virtual size_t extract_header(Persistent_Storage_Block& psb, + const size_t offset = 0); + virtual size_t put_header(Persistent_Storage_Block& psb, + const size_t offset = 0); + + public: + /// Our serial number + Block_Serial_Number serial_number; + /// Address of the overflow record (if any) + Block_Number next_overflow; + /// How much extra header data is in this block (not including this header) + Block_Type header_type; + /// How much actual data is in this block? (not including headers) + Block_Size data_size; + }; + + /** + * \brief private: Storage for header information for Routing_Slip blocks. + */ + class Routing_Slip_Header : public Block_Header + { + public: + Routing_Slip_Header(); + virtual size_t extract_header(Persistent_Storage_Block& psb, + const size_t offset = 0); + virtual size_t put_header(Persistent_Storage_Block& psb, + const size_t offset = 0); + + public: + /// The next event in the system + Block_Number next_routing_slip_block; + /// The next expected serial number + Block_Serial_Number next_serial_number; + Block_Number event_block; + }; + + /// \brief An Event block header. + /// + /// is just a Block_Header with no extra data + class Event_Header : public Block_Header + { + public: + Event_Header (); + }; + + /// \brief An overflow block header. + /// + /// is just a Block_Header with no extra data + /// The same record type is used for both Routing_Slip + /// and Event overflows. + class Overflow_Header : public Block_Header + { + public: + Overflow_Header (); + }; + + bool store_i(const ACE_Message_Block& event, + const ACE_Message_Block& routing_slip); + + bool update_i(const ACE_Message_Block& routing_slip); + + bool store_event(const ACE_Message_Block& event); + + /// Fill in a block with data, and return the number of bytes + /// of data remaining to be written. + size_t fill_block(Persistent_Storage_Block& psb, + const size_t offset_into_block, const ACE_Message_Block* data, + const size_t offset_into_msg); + size_t fill_block(Persistent_Storage_Block& psb, + const size_t offset_into_block, unsigned char* data, + const size_t data_size); + + /// Build a chain of Persistent_Storage_Blocks + bool build_chain( + Persistent_Storage_Block* first_block, + Block_Header& first_header, + ACE_Unbounded_Stack<size_t>& allocated_blocks, + const ACE_Message_Block& data); + + /// Reload a chain from persistent store. + bool reload_chain(Persistent_Storage_Block* first_block, + Block_Header& first_header, + ACE_Unbounded_Stack<size_t>& allocated_blocks, + ACE_Message_Block* amb, + ACE_UINT64 expected_serial_number); + + /// Locked method to do the work of setting the next_manager_. + bool update_next_manager(Routing_Slip_Persistence_Manager* next); + + /// Have we been persisted yet? + bool persisted(); + + /// Write out our first event block. + size_t write_first_routing_slip_block(bool prepare_only = false); + + /// Insert ourselves into a linked list of Routing_Slip_Persistnce_Managers + void dllist_push_back(); + + void insert_before (Routing_Slip_Persistence_Manager * node); + + /// Remove ourselves from a linked list of Routing_Slip_Persistence_Managers + void remove_from_dllist(); + +private: + ACE_SYNCH_MUTEX lock_; + bool removed_; + ACE_UINT64 serial_number_; + Persistent_File_Allocator* allocator_; + Standard_Event_Persistence_Factory* factory_; + Event_Header event_header_; + Routing_Slip_Header routing_slip_header_; + Persistent_Storage_Block* first_event_block_; + Persistent_Storage_Block* first_routing_slip_block_; + /// We are part of a doubly-linked list + Routing_Slip_Persistence_Manager* prev_manager_; + Routing_Slip_Persistence_Manager* next_manager_; + ACE_Unbounded_Stack<size_t> allocated_event_blocks_; + ACE_Unbounded_Stack<size_t> allocated_routing_slip_blocks_; + Persistent_Callback* callback_; + + /// if these are non-zero we own 'em + ACE_Message_Block * event_mb_; + ACE_Message_Block * routing_slip_mb_; +}; + +} /* namespace TAO_Notify */ + +#include /**/ "ace/post.h" +#endif /* ROUTING_SLIP_PERSISTENCE_MANAGER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.cpp b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.cpp new file mode 100644 index 00000000000..10f316f4e7c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.cpp @@ -0,0 +1,122 @@ +// $Id$ + +#include "Routing_Slip_Queue.h" + +#if ! defined (__ACE_INLINE__) +#include "Routing_Slip_Queue.inl" +#endif /* __ACE_INLINE__ */ + +#include "tao/debug.h" +#include "ace/Dynamic_Service.h" + +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + +namespace TAO_Notify +{ + Routing_Slip_Queue::Routing_Slip_Queue (size_t allowed) + : allowed_ (allowed) + , active_ (0) + { + } + + Routing_Slip_Queue::~Routing_Slip_Queue () + { + } + + void + Routing_Slip_Queue::add (const Routing_Slip_Ptr & routing_slip) + { + Guard guard (internals_); + ACE_ASSERT (guard.locked()); // check recursion + if (this->allowed_ == 0) + { + ++this->active_; + guard.release (); + routing_slip->at_front_of_persist_queue (); +// guard.acquire (); + } + else + { + this->queue_.enqueue_tail (routing_slip); + dispatch (guard); + } + } + + void Routing_Slip_Queue::complete () + { + Guard guard (internals_); + ACE_ASSERT (guard.locked()); // check recursion + ACE_ASSERT (this->active_ > 0); + --this->active_; + dispatch (guard); + } + + void + Routing_Slip_Queue::dispatch (Guard & guard) + { + // we start out pretty nice, + // but the more work we do for other people + // the less nice we get. + size_t nice = this->allowed_ + 1; + while (nice > 0 && (this->active_ < this->allowed_)) + { + if (dispatch_one (guard)) + { + --nice; + } + else + { + // that's about as nice as I get. + nice = 0; + } + } + } + + bool + Routing_Slip_Queue::dispatch_one (Guard & guard) + { + bool ok = false; + Routing_Slip_Ptr routing_slip; + if (this->queue_.dequeue_head (routing_slip) == 0) + { + ++this->active_; + guard.release (); + routing_slip->at_front_of_persist_queue (); + guard.acquire (); + } + return ok; + } + + void + Routing_Slip_Queue::set_allowed (size_t allowed) + { + Guard guard (internals_); + size_t allowed_was = this->allowed_; + this->allowed_ = allowed; + if (allowed == 0 && allowed_was != 0) + { + while (dispatch_one (guard)) + { + ; // work happens in dispatc_one + } + } + else + { + dispatch (guard); + } + } +} // namespace + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Node<TAO_Notify::Routing_Slip_Ptr>; +template class ACE_Unbounded_Queue<TAO_Notify::Routing_Slip_Ptr>; +template class ACE_Unbounded_Queue_Iterator<TAO_Notify::Routing_Slip_Ptr>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Node<TAO_Notify::Routing_Slip_Ptr> +#pragma instantiate ACE_Unbounded_Queue<TAO_Notify::Routing_Slip_Ptr> +#pragma instantiate ACE_Unbounded_Queue_Iterator<TAO_Notify::Routing_Slip_Ptr> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.h b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.h new file mode 100644 index 00000000000..553116c5805 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.h @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// $Id$ + +#ifndef TAO_NOTIFY_ROUTING_SLIP_QUEUE_H +#define TAO_NOTIFY_ROUTING_SLIP_QUEUE_H +#include "ace/pre.h" + +#include "Routing_Slip.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + /** + * \brief A queue of Routing_Slips waiting to be persisted. + * + * The Routing_Slip_Queue keeps a queue of Routing_Slips waiting + * to be written to persistent storage. The "allowed" parameter + * determines how many Routing_Slips can be handled simultaneously + * by the persistent storage. Until this threshold is reached, + * Routing_Slips are not held in the queue, but pass straight through. + * + * Once the allowe number of Routing_Slips are being handled, any + * additional requests are held in the queue until persistence is + * complete for another Routing_Slips. + * + * Having Routing_Slips waiting in the queue is "a good thing" [TM] + * because it allows delivery completions to be applied to the + * routing slip before it is written -- thereby reducing or completely + * eliminating the number of actual writes to persistent storage. + * + * Experimentation indicates that a good value for "allowed" is 1. + * + * Allowed == 0 is treated as a special case meaning pass all Routing_Slips + * through the queue immediately. Setting it a good way to test how well + * your storage device withstands continuous beating. + */ + class TAO_Notify_Serv_Export Routing_Slip_Queue + { + typedef ACE_Unbounded_Queue <Routing_Slip_Ptr> Queue; + typedef ACE_Guard< TAO_SYNCH_MUTEX > Guard; + public: + /** + * \brief Construct setting "allowed". + * \param allowed the number of Routing_Slips that can be handled + * simultaneously by the persistent store. + */ + Routing_Slip_Queue (size_t allowed = 1); + /// Destructor. + ~Routing_Slip_Queue (); + + /** + * \brief Add a routing slip to the tail of the queue and dispatch if necessary. + */ + void add (const Routing_Slip_Ptr & routing_slip); + /** + * \brief A call back to indicate that processing is complete for a previously-queued + * Routing_Slip. + */ + void complete (); + + /** + * /brief Adjust the "allowed" value on-the-fly (not recommended, but it works.) + */ + void set_allowed (size_t allowed); + + private: + void dispatch (Guard & guard); + bool dispatch_one (Guard & guard); + + private: + Routing_Slip_Queue (const Routing_Slip_Queue & rhs); + Routing_Slip_Queue & operator = (const Routing_Slip_Queue & rhs); + private: + // configuration setting + size_t allowed_; + /// Protection for internal information + TAO_SYNCH_MUTEX internals_; + size_t active_; + Queue queue_; + + }; +} // namespace + +#if defined (__ACE_INLINE__) +#include "Routing_Slip_Queue.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" +#endif /* TAO_NOTIFY_ROUTING_SLIP_QUEUE_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.inl b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.inl new file mode 100644 index 00000000000..f500b5e35e4 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Routing_Slip_Queue.inl @@ -0,0 +1,7 @@ +// $Id$ +namespace TAO_Notify +{ + // code will go here soon + +} // namespace TAO_Notify + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.cpp b/TAO/orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.cpp new file mode 100644 index 00000000000..a18faf6abe7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.cpp @@ -0,0 +1,46 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** +* @file Save_Persist_Worker_T.h +* +* $Id$ +* +* @author Jonathan Pollack <pollack_j@ociweb.com> +*/ +//============================================================================= + +#ifndef SAVE_PERSIST_WORKER_CPP +#define SAVE_PERSIST_WORKER_CPP + +#include "orbsvcs/ESF/ESF_Worker.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + template<class TOPOOBJ> + Save_Persist_Worker<TOPOOBJ>::Save_Persist_Worker( + Topology_Saver& saver, + bool want_all_children) + : saver_(saver) + , want_all_children_ (want_all_children) + { + } + + template<class TOPOOBJ> + void + Save_Persist_Worker<TOPOOBJ>::work (TOPOOBJ* o ACE_ENV_ARG_DECL) + { + ACE_ASSERT(o != 0); + if (this->want_all_children_ || o->is_changed ()) + { + o->save_persistent (saver_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + } +} // namespace TAO_Notify + +#endif /* SAVE_PERSIST_WORKER_CPP */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.h b/TAO/orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.h new file mode 100644 index 00000000000..740b2128378 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Save_Persist_Worker_T.h @@ -0,0 +1,58 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** +* \file Save_Persist_Worker_T.h +* +* $Id$ +* +* \author Jonathan Pollack <pollack_j@ociweb.com> +*/ +//============================================================================= + +#ifndef SAVE_PERSIST_WORKER_H +#define SAVE_PERSIST_WORKER_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/ESF/ESF_Worker.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + /** + * \brief Iterate through children saving persistent topology information. + */ + template<class TOPOOBJ> + class Save_Persist_Worker : public TAO_ESF_Worker<TOPOOBJ> + { + public: + /** + * /brief Constructor + * /param saver the object that will save persistent information. + * /param want_all_children if true, unmodified children should be saved, too. + */ + Save_Persist_Worker(Topology_Saver& saver, bool want_all_children); + + // override virtual ESF_Worker method + virtual void work (TOPOOBJ* o ACE_ENV_ARG_DECL); + + private: + Topology_Saver& saver_; + bool want_all_children_; + }; +} // namespace TAO_Notify + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "Save_Persist_Worker_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Save_Persist_Worker_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* SAVE_PERSIST_WORKER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.cpp b/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.cpp index 73bd444b95d..28fe6cd3364 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.cpp @@ -78,7 +78,7 @@ TAO_Notify_Batch_Buffering_Strategy::dequeue_i (int max_deq_count, CosNotificati --this->global_queue_length_; - TAO_Notify_Method_Request_Event* mre = ACE_dynamic_cast (TAO_Notify_Method_Request_Event*, mb); + TAO_Notify_Method_Request_Event_Queueable* mre = ACE_dynamic_cast (TAO_Notify_Method_Request_Event_Queueable*, mb); mre->event ()->convert (event_batch[deq_count]); diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.h b/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.h index b49b367c654..bb682495e85 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.h @@ -13,7 +13,7 @@ #define TAO_Notify_BATCH_BUFFERING_STRATEGY_H #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.inl b/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.inl index 72a7bb34341..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/Batch_Buffering_Strategy.inl @@ -1,3 +1,2 @@ // $Id$ -#include "Batch_Buffering_Strategy.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp index af1faff9d17..253330c5af1 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp @@ -11,9 +11,8 @@ ACE_RCSID (Notify, TAO_Notify_SequenceProxyPushConsumer, "$Id$") #include "tao/debug.h" #include "SequencePushSupplier.h" #include "../AdminProperties.h" -#include "../Method_Request_Lookup.h" -#include "../Worker_Task.h" #include "../Structured/StructuredEvent.h" +#include "../Properties.h" TAO_Notify_SequenceProxyPushConsumer::TAO_Notify_SequenceProxyPushConsumer (void) :pacing_interval_ (CosNotification::PacingInterval) @@ -60,6 +59,8 @@ TAO_Notify_SequenceProxyPushConsumer::connect_sequence_push_supplier (CosNotifyC ACE_CHECK; this->connect (supplier ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -83,10 +84,8 @@ TAO_Notify_SequenceProxyPushConsumer::push_structured_events (const CosNotificat const CosNotification::StructuredEvent& notification = event_batch[i]; TAO_Notify_StructuredEvent_No_Copy event (notification); - - TAO_Notify_Method_Request_Lookup_No_Copy request (&event, this); - - this->worker_task ()->execute (request ACE_ENV_ARG_PARAMETER); + this->push_i (&event ACE_ENV_ARG_PARAMETER); + ACE_CHECK; } } @@ -97,4 +96,43 @@ TAO_Notify_SequenceProxyPushConsumer::disconnect_sequence_push_consumer (ACE_ENV )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +const char * +TAO_Notify_SequenceProxyPushConsumer::get_proxy_type_name (void) const +{ + return "sequence_proxy_push_consumer"; +} + +void +TAO_Notify_SequenceProxyPushConsumer::load_attrs (const TAO_Notify::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::SequencePushSupplier_var ps = + CosNotifyComm::SequencePushSupplier::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + // minor hack: suppress generating subscription updates during reload. + bool save_updates = this->updates_off_; + this->updates_off_ = true; + this->connect_sequence_push_supplier(ps.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->updates_off_ = save_updates; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + } } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h index b6d77b5d187..a47e2510576 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h @@ -14,7 +14,7 @@ #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -40,6 +40,7 @@ class TAO_Notify_Serv_Export TAO_Notify_SequenceProxyPushConsumer : public virtual TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::SequenceProxyPushConsumer> { + typedef TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::SequenceProxyPushConsumer> SuperClass; friend class TAO_Notify_Builder; public: /// Constuctor @@ -51,6 +52,10 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + + virtual void load_attrs (const TAO_Notify::NVPList& attrs); + protected: ///= Data Members TAO_Notify_Property_Time pacing_interval_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.inl b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.inl index 5470ff89e39..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.inl @@ -1,3 +1,2 @@ // $Id$ -#include "SequenceProxyPushConsumer.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp index ea5501c6872..1bf551586dc 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp @@ -10,6 +10,7 @@ ACE_RCSID (Notify, TAO_Notify_SequenceProxyPushSupplier, "$Id$") #include "tao/debug.h" #include "SequencePushConsumer.h" +#include "../Properties.h" TAO_Notify_SequenceProxyPushSupplier::TAO_Notify_SequenceProxyPushSupplier (void) { @@ -47,6 +48,8 @@ TAO_Notify_SequenceProxyPushSupplier::connect_sequence_push_consumer (CosNotifyC ACE_CHECK; this->connect (consumer ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -57,6 +60,8 @@ TAO_Notify_SequenceProxyPushSupplier::disconnect_sequence_push_supplier (ACE_ENV { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } CosNotifyChannelAdmin::ProxyType @@ -67,3 +72,36 @@ TAO_Notify_SequenceProxyPushSupplier::MyType (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) { return CosNotifyChannelAdmin::PUSH_SEQUENCE; } + +const char * +TAO_Notify_SequenceProxyPushSupplier::get_proxy_type_name (void) const +{ + return "sequence_proxy_push_supplier"; +} + +void +TAO_Notify_SequenceProxyPushSupplier::load_attrs (const TAO_Notify::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::SequencePushConsumer_var pc = + CosNotifyComm::SequencePushConsumer::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->connect_sequence_push_consumer(pc.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // if we can't reconnect, tough + } + ACE_ENDTRY; + } +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h index 0e34de6a20b..950ee882aa4 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h @@ -14,7 +14,7 @@ #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -46,6 +46,7 @@ TAO_Notify_ProxySupplier_T<POA_CosNotifyChannelAdmin::SequenceProxyPushSupplier> class TAO_Notify_Serv_Export TAO_Notify_SequenceProxyPushSupplier : public virtual TAO_Notify_ProxySupplier_T <POA_CosNotifyChannelAdmin::SequenceProxyPushSupplier> { + typedef TAO_Notify_ProxySupplier_T <POA_CosNotifyChannelAdmin::SequenceProxyPushSupplier> SuperClass; friend class TAO_Notify_Builder; public: @@ -58,6 +59,10 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + + virtual void load_attrs (const TAO_Notify::NVPList& attrs); + /// = Servant methods virtual CosNotifyChannelAdmin::ProxyType MyType (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.inl b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.inl index 5f4ceeb6181..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.inl @@ -1,3 +1,2 @@ // $Id$ -#include "SequenceProxyPushSupplier.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp index 56d7a13538d..e21a8dae22a 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp @@ -14,43 +14,57 @@ ACE_RCSID (Notify, TAO_Notify_SequencePushConsumer, "$Id$") #include "../ProxySupplier.h" #include "../Worker_Task.h" #include "../Consumer.h" +#include "../Method_Request_Dispatch.h" #include "../Method_Request_Event.h" #include "../Timer.h" #include "../Proxy.h" +#include "../Properties.h" +//#define DEBUG_LEVEL 10 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL TAO_Notify_SequencePushConsumer::TAO_Notify_SequencePushConsumer (TAO_Notify_ProxySupplier* proxy) - : TAO_Notify_Consumer (proxy), pacing_interval_ (ACE_Time_Value::zero), timer_id_ (-1), buffering_strategy_ (0), - max_batch_size_ (CosNotification::MaximumBatchSize, 0), timer_ (0) + : TAO_Notify_Consumer (proxy) { } TAO_Notify_SequencePushConsumer::~TAO_Notify_SequencePushConsumer () { - delete this->buffering_strategy_; } void -TAO_Notify_SequencePushConsumer::init (CosNotifyComm::SequencePushConsumer_ptr push_consumer, TAO_Notify_AdminProperties_var& admin_properties ACE_ENV_ARG_DECL) +TAO_Notify_SequencePushConsumer::init ( + CosNotifyComm::SequencePushConsumer_ptr push_consumer, TAO_Notify_AdminProperties_var& admin_properties +#if 1 + ACE_ENV_ARG_DECL_NOT_USED) +#else //1 + ACE_ENV_ARG_DECL) +#endif { - this->push_consumer_ = CosNotifyComm::SequencePushConsumer::_duplicate (push_consumer); + set_consumer (push_consumer); - this->publish_ = CosNotifyComm::NotifyPublish::_duplicate (push_consumer); +#if 1 //// @@ TODO: use buffering strategy in TAO_Notify_Consumer??? + ACE_UNUSED_ARG ( admin_properties); +#else //1 ACE_NEW_THROW_EX (this->buffering_strategy_, TAO_Notify_Batch_Buffering_Strategy (this->msg_queue_, admin_properties, this->max_batch_size_.value ()), CORBA::NO_MEMORY ()); - - this->timer_ = this->proxy ()->timer (); +#endif // 1 } void -TAO_Notify_SequencePushConsumer::shutdown (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +TAO_Notify_SequencePushConsumer::set_consumer ( + CosNotifyComm::SequencePushConsumer_ptr push_consumer) { - this->cancel_timer (); - this->timer_->_decr_refcnt (); + this->push_consumer_ = CosNotifyComm::SequencePushConsumer::_duplicate (push_consumer); + this->publish_ = CosNotifyComm::NotifyPublish::_duplicate (push_consumer); + } + void TAO_Notify_SequencePushConsumer::release (void) { @@ -58,89 +72,132 @@ TAO_Notify_SequencePushConsumer::release (void) //@@ inform factory } -void -TAO_Notify_SequencePushConsumer::qos_changed (const TAO_Notify_QoSProperties& qos_properties) +bool +TAO_Notify_SequencePushConsumer::dispatch_from_queue (Request_Queue& requests, ACE_Guard <TAO_SYNCH_MUTEX> & ace_mon) { - this->max_batch_size_ = qos_properties.maximum_batch_size (); - - if (this->max_batch_size_.is_valid ()) - {// set the max batch size. - this->buffering_strategy_->batch_size (this->max_batch_size_.value ()); - } - - const TAO_Notify_Property_Time &pacing_interval = qos_properties.pacing_interval (); - - if (pacing_interval.is_valid ()) + bool result = true; + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) SequencePushConsumer dispatch queued requests. queue size:%u\n"), + requests.size ())); + + long queue_size = requests.size (); + CORBA::Long max_batch_size = queue_size; + if (this->max_batch_size_.is_valid () ) { - this->pacing_interval_ = -# if defined (ACE_CONFIG_WIN32_H) - ACE_Time_Value (ACE_static_cast (long, pacing_interval.value ())); -# else - ACE_Time_Value (pacing_interval.value () / 1); -# endif /* ACE_CONFIG_WIN32_H */ + max_batch_size = this->max_batch_size_.value (); } + CORBA::Long batch_size = queue_size; + if (batch_size > max_batch_size) + { + batch_size = max_batch_size; + } + if (batch_size > 0) + { + CosNotification::EventBatch batch (batch_size); + batch.length (batch_size); + + Request_Queue completed; + + CORBA::Long pos = 0; + TAO_Notify_Method_Request_Event_Queueable * request; + while (pos < batch_size && requests.dequeue_head (request) == 0) + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) Sequence Dispatch Method_Request_Dispatch @%@\n"), + request)); - // Inform the buffering strategy of qos change. - this->buffering_strategy_->update_qos_properties (qos_properties); -} + const TAO_Notify_Event * ev = request->event (); + ev->convert (batch [pos]); + ++pos; -void -TAO_Notify_SequencePushConsumer::schedule_timer (void) -{ - // Schedule the timer. - if (this->pacing_interval_ != ACE_Time_Value::zero) + // note enqueue at head, use queue as stack. + completed.enqueue_head (request); + } + batch.length (pos); + ACE_ASSERT (pos > 0); + + ace_mon.release (); + TAO_Notify_Consumer::DispatchStatus status = + this->dispatch_batch (batch); + ace_mon.acquire (); + switch (status) { - this->timer_id_ = this->timer_->schedule_timer (this, this->pacing_interval_, 0); - - if (this->timer_id_ == -1) - this->pacing_interval_ = ACE_Time_Value::zero; // some error, revert to no pacing. + case DISPATCH_SUCCESS: + { + TAO_Notify_Method_Request_Event_Queueable * request; + while (completed.dequeue_head (request) == 0) + { + request->complete (); + request->release (); + } + result = true; + break; + } + // TODO: we should distinguish between these (someday) + case DISPATCH_FAIL: + case DISPATCH_DISCARD: + case DISPATCH_RETRY: + { + TAO_Notify_Method_Request_Event_Queueable * request; + while (completed.dequeue_head (request) == 0) + { + if (request->should_retry ()) + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) SequencePushConsumer: Failed to dispatch :%d. Will retry\n"), + request->sequence () + )); + requests.enqueue_head (request); + result = false; + } + else + { + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) SequencePushConsumer: Failed to dispatch :%d. Discarding event.\n"), + request->sequence () + )); + request->complete (); + request->release (); + } + } + break; + + if (DEBUG_LEVEL > 0) ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer %d: Will retry %d\n"), + ACE_static_cast (int, this->proxy ()->id ()), + request->sequence () + )); + ace_mon.acquire (); + requests.enqueue_head (request); // put the failed event back where it was + result = false; + break; + } } + } + return result; } -void -TAO_Notify_SequencePushConsumer::cancel_timer (void) +bool +TAO_Notify_SequencePushConsumer::enqueue_if_necessary ( + TAO_Notify_Method_Request_Event * request + ACE_ENV_ARG_DECL) { - timer_->cancel_timer (this->timer_id_); + if (DEBUG_LEVEL > 0) + ACE_DEBUG ( (LM_DEBUG, "SequencePushConsumer enqueing event.\n")); + this->enqueue_request (request ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (false); + + if (this->pacing_.is_valid ()) + { + schedule_timer (false); + } + else + { + this->dispatch_pending (ACE_ENV_SINGLE_ARG_PARAMETER); + } + return true; } -void -TAO_Notify_SequencePushConsumer::push_i (const TAO_Notify_Event* event ACE_ENV_ARG_DECL) -{ - TAO_Notify_Event* copy = event->copy (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_CHECK; - - TAO_Notify_Event_Copy_var copy_var (copy); - - this->push_i (copy_var ACE_ENV_ARG_PARAMETER); -} - -void -TAO_Notify_SequencePushConsumer::push_i (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL) -{ - TAO_Notify_Method_Request_Event* method_request; - - ACE_NEW_THROW_EX (method_request, - TAO_Notify_Method_Request_Event (event), - CORBA::NO_MEMORY ()); - - int msg_count = this->buffering_strategy_->enqueue (*method_request); - - if (msg_count == -1) - { - if (TAO_debug_level > 0) - ACE_DEBUG ((LM_DEBUG, "NS_Seq_Reactive_Task (%P|%t) - " - "failed to enqueue\n")); - return; - } - - if (this->pacing_interval_ == ACE_Time_Value::zero) - { - // If pacing is zero, there is no timer, hence dispatch immediately - this->handle_timeout (ACE_Time_Value::zero, 0); - } - else if (msg_count == 1) - this->schedule_timer (); -} void TAO_Notify_SequencePushConsumer::push (const CORBA::Any& /*event*/ ACE_ENV_ARG_DECL_NOT_USED) @@ -154,44 +211,41 @@ TAO_Notify_SequencePushConsumer::push (const CosNotification::StructuredEvent& / //NOP } -int -TAO_Notify_SequencePushConsumer::handle_timeout (const ACE_Time_Value& /*current_time*/, - const void* /*act*/) -{ - CosNotification::EventBatch event_batch; - - int pending = 0; - int deq_count = this->buffering_strategy_->dequeue_available (event_batch, pending); - - if (deq_count > 0) - { - TAO_Notify_Proxy_Guard ref_guard(this->proxy ()); // Protect this object from being destroyed in this scope. - - this->push (event_batch); - - if (pending) - this->schedule_timer (); - } - - return 0; +void +TAO_Notify_SequencePushConsumer::push (const CosNotification::EventBatch& event_batch ACE_ENV_ARG_DECL) +{ + this->push_consumer_->push_structured_events (event_batch ACE_ENV_ARG_PARAMETER); + ACE_CHECK; } -void -TAO_Notify_SequencePushConsumer::push (const CosNotification::EventBatch& event_batch) +bool +TAO_Notify_SequencePushConsumer::get_ior (ACE_CString & iorstr) const { - ACE_TRY_NEW_ENV - { - this->push_consumer_->push_structured_events (event_batch ACE_ENV_ARG_PARAMETER); - ACE_TRY_CHECK; - } + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance ()->orb (); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string (this->push_consumer_.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } ACE_CATCHANY - { - this->handle_dispatch_exception (ACE_ENV_SINGLE_ARG_PARAMETER); - ACE_TRY_CHECK; - - // we're scheduled to be destroyed. don't set the timer. - this->pacing_interval_ = ACE_Time_Value::zero; - } + { + ACE_ASSERT (0); + } ACE_ENDTRY; + return result; +} + +void +TAO_Notify_SequencePushConsumer::reconnect_from_consumer (TAO_Notify_Consumer* old_consumer + ACE_ENV_ARG_DECL_NOT_USED) +{ + TAO_Notify_SequencePushConsumer* tmp = dynamic_cast<TAO_Notify_SequencePushConsumer *> (old_consumer); + ACE_ASSERT(tmp != 0); + this->set_consumer(tmp->push_consumer_.in()); + this->schedule_timer(false); } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h index 6cbe894caa3..e2c39d71b43 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h @@ -13,7 +13,7 @@ #define TAO_Notify_SEQUENCEPUSHCONSUMER_H #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -38,7 +38,8 @@ class TAO_Notify_Timer; * @brief * */ -class TAO_Notify_Serv_Export TAO_Notify_SequencePushConsumer : public ACE_Event_Handler, public TAO_Notify_Consumer +class TAO_Notify_Serv_Export TAO_Notify_SequencePushConsumer + : public TAO_Notify_Consumer { public: /// Constuctor @@ -50,16 +51,21 @@ public: /// Init the Consumer void init (CosNotifyComm::SequencePushConsumer_ptr push_consumer, TAO_Notify_AdminProperties_var& admin_properties ACE_ENV_ARG_DECL); - /// Shutdown the consumer - virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL); + void set_consumer (CosNotifyComm::SequencePushConsumer_ptr push_consumer); /// TAO_Notify_Destroy_Callback methods. virtual void release (void); - /// Push <event> to this consumer. - virtual void push_i (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); + /// Add request to a queue if necessary. + /// for Sequence it's always necessary. + virtual bool enqueue_if_necessary( + TAO_Notify_Method_Request_Event * request + ACE_ENV_ARG_DECL); + + virtual bool dispatch_from_queue ( + Request_Queue & requests, + ACE_Guard <TAO_SYNCH_MUTEX> & ace_mon); - virtual void push_i (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL); /// Push <event> to this consumer. virtual void push (const CORBA::Any& event ACE_ENV_ARG_DECL); @@ -67,46 +73,22 @@ public: // Push event. virtual void push (const CosNotification::StructuredEvent & event ACE_ENV_ARG_DECL); - /// Push <event> to this consumer. - virtual void push (const CosNotification::EventBatch& event); - - /// Override, Peer::qos_changed - virtual void qos_changed (const TAO_Notify_QoSProperties& qos_properties); - -protected: - /// When the pacing interval is used, handle_timeout () is called by - /// the reactor. - virtual int handle_timeout (const ACE_Time_Value& current_time, - const void* act = 0); - - /// Schedule timer - void schedule_timer (void); - - /// Cancel timer - void cancel_timer (void); + /// Push a batch of events to this consumer. + virtual void push (const CosNotification::EventBatch& event ACE_ENV_ARG_DECL); - ///= Protected Data Members + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; - /// The Pacing Interval - ACE_Time_Value pacing_interval_; + /// on reconnect we need to move events from the old consumer + /// to the new one + virtual void reconnect_from_consumer (TAO_Notify_Consumer* old_consumer + ACE_ENV_ARG_DECL); - /// Timer Id. - long timer_id_; +protected: /// The Consumer CosNotifyComm::SequencePushConsumer_var push_consumer_; - /// The Message queue. - TAO_Notify_Message_Queue msg_queue_; - - /// The Buffering Strategy - TAO_Notify_Batch_Buffering_Strategy* buffering_strategy_; - - /// Max. batch size. - TAO_Notify_Property_Long max_batch_size_; - - /// The Timer Manager that we use. - TAO_Notify_Timer* timer_; }; #if defined (__ACE_INLINE__) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.inl b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.inl index d050292323e..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.inl @@ -1,3 +1,2 @@ // $Id$ -#include "SequencePushConsumer.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.cpp index d7fe6a1d682..e5699464314 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.cpp @@ -8,6 +8,8 @@ ACE_RCSID (Notify, TAO_Notify_SequencePushSupplier, "$Id$") +#include "../Properties.h" + TAO_Notify_SequencePushSupplier::TAO_Notify_SequencePushSupplier (TAO_Notify_ProxyConsumer* proxy) :TAO_Notify_Supplier (proxy) { @@ -31,3 +33,23 @@ TAO_Notify_SequencePushSupplier::release (void) delete this; //@@ inform factory } +bool +TAO_Notify_SequencePushSupplier::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_supplier_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h index a74f32fe500..c6713a2bc64 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h @@ -13,7 +13,7 @@ #define TAO_Notify_SEQUENCEPUSHSUPPLIER_H #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -45,6 +45,9 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + protected: /// The Supplier CosNotifyComm::SequencePushSupplier_var push_supplier_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.inl b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.inl index 507cd0b85c6..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.inl @@ -1,3 +1,2 @@ // $Id$ -#include "SequencePushSupplier.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.cpp b/TAO/orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.cpp new file mode 100644 index 00000000000..0494a409311 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.cpp @@ -0,0 +1,233 @@ +// $Id$ + +#include "Standard_Event_Persistence.h" +#include "Persistent_File_Allocator.h" +#include "tao/debug.h" +#include "ace/Dynamic_Service.h" +#include "ace/OS_NS_strings.h" + +namespace TAO_Notify +{ + +Standard_Event_Persistence::Standard_Event_Persistence () + : filename_ ("__PERSISTENT_EVENT__.DB") + , block_size_ (512) + , factory_ (0) +{ +} + +Standard_Event_Persistence::~Standard_Event_Persistence () +{ +} + +// get the current factory, creating it if necessary +Event_Persistence_Factory * +Standard_Event_Persistence::get_factory () +{ + //@@todo guard? ; doublecheck? + if (this->factory_ == 0) + { + ACE_NEW_NORETURN ( + this->factory_, + Standard_Event_Persistence_Factory () + ); + if (this->factory_ != 0) + { + if (!this->factory_->open (this->filename_.c_str ())) + { + this->factory_ = 0; + } + } + } + return this->factory_; +} + +// release the current factory so a new one can be created +void +Standard_Event_Persistence::reset () +{ + delete this->factory_; + this->factory_ = 0; +} + +int +Standard_Event_Persistence::init (int argc, ACE_TCHAR *argv[]) +{ + int result = 0; + bool verbose = false; + for (int narg = 0; narg < argc; ++narg) + { + ACE_TCHAR * av = argv[narg]; + if (ACE_OS::strcasecmp (av, "-v") == 0) + { + verbose = true; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Standard_Event_Persistence: -verbose\n") + )); + } + else if (ACE_OS::strcasecmp (av, "-file_path") == 0 && narg + 1 < argc) + { + this->filename_ = argv[narg + 1]; + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Standard_Event_Persistence: Setting -file_path: %s\n"), + this->filename_.c_str () + )); + } + narg += 1; + } + else if (ACE_OS::strcasecmp (av, "-block_size") == 0 && narg + 1 < argc) + { + this->block_size_ = ACE_OS::atoi(argv[narg + 1]); + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Standard_Event_Persistence: Setting -block_size: %d\n"), + this->block_size_ + )); + } + narg += 1; + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Unknown parameter to Standard Event Persistence: %s\n"), + argv[narg] + )); + result = -1; + } + } + return result; +} + +int +Standard_Event_Persistence::fini () +{ + delete this->factory_; + this->factory_ = 0; + return 0; +} + +Standard_Event_Persistence_Factory::Standard_Event_Persistence_Factory () + : allocator_() + , root_(this) + , psb_(0) + , serial_number_(ROUTING_SLIP_ROOT_SERIAL_NUMBER + 1) + , is_reloading_ (false) +{ +} + +bool +Standard_Event_Persistence_Factory::open (const char * filename, + ACE_UINT32 block_size) +{ + bool result = false; + if (allocator_.open (filename, block_size)) + { + this->is_reloading_ = this->root_.load(ROUTING_SLIP_ROOT_BLOCK_NUMBER, ROUTING_SLIP_ROOT_SERIAL_NUMBER); + if (! this->is_reloading_) + { + ACE_ASSERT (this->psb_ == 0); +// this->psb_ = this->allocator_.allocate(); + this->root_.store_root(); + } + result = true; + } + return result; +} + +Standard_Event_Persistence_Factory::~Standard_Event_Persistence_Factory() +{ + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Standard_Event_Persistence_Factory::~Standard_Event_Persistence_Factory\n") + )); + } + this->root_.release_all (); + delete this->psb_; + this->psb_ = 0; + this->allocator_.shutdown(); +} + +Routing_Slip_Persistence_Manager* +Standard_Event_Persistence_Factory::create_routing_slip_persistence_manager( + Persistent_Callback* callback) +{ + Routing_Slip_Persistence_Manager* rspm = 0; + ACE_NEW_RETURN(rspm, Routing_Slip_Persistence_Manager(this), rspm); + rspm->set_callback(callback); + return rspm; +} + +Routing_Slip_Persistence_Manager * +Standard_Event_Persistence_Factory::first_reload_manager() +{ + Routing_Slip_Persistence_Manager * result = 0; + if (this->is_reloading_) + { + result = this->root_.load_next(); + } + return result; +} + +void +Standard_Event_Persistence_Factory::done_reloading( + Persistent_Storage_Block * next_psb, + ACE_UINT64 current_serial_number) +{ + ACE_ASSERT (this->psb_ == 0); + this->psb_ = next_psb; + this->serial_number_ = current_serial_number; + this->is_reloading_ = false; +} + +void +Standard_Event_Persistence_Factory::preallocate_next_record( + ACE_UINT64& current_serial_number, + Persistent_Storage_Block*& current_psb, + ACE_UINT64& next_serial_number, + ACE_UINT32& next_block_number) +{ + // return current serial number and + // a psb containing current record number + current_serial_number = this->serial_number_; + this->psb_->set_allocator_owns(false); // give up ownership + this->psb_->set_sync(); + current_psb = this->psb_; + this->get_preallocated_pointer (next_serial_number, next_block_number); +} + +void +Standard_Event_Persistence_Factory::get_preallocated_pointer( + ACE_UINT64& next_serial_number, + ACE_UINT32& next_block_number) +{ + ++this->serial_number_; + this->psb_ = this->allocator_.allocate(); + + next_serial_number = this->serial_number_; + next_block_number = this->psb_->block_number(); +} + +Persistent_File_Allocator* +Standard_Event_Persistence_Factory::allocator() +{ + return &this->allocator_; +} + +Routing_Slip_Persistence_Manager & +Standard_Event_Persistence_Factory::root() +{ + return this->root_; +} + +ACE_FACTORY_DECLARE (TAO_Notify_Serv, Standard_Event_Persistence) +ACE_FACTORY_DEFINE (TAO_Notify_Serv, Standard_Event_Persistence) + +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.h b/TAO/orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.h new file mode 100644 index 00000000000..ae450d415da --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Standard_Event_Persistence.h @@ -0,0 +1,128 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * \file Event_Persistence_Factory.h + * + * $Id$ + * + * The standard implementation of Event_Persistence_Factory. + * + * \author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef STANDARD_EVENT_PERSISTENCE_H +#define STANDARD_EVENT_PERSISTENCE_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "Event_Persistence_Strategy.h" +#include "Event_Persistence_Factory.h" +#include "Persistent_File_Allocator.h" +#include "Routing_Slip_Persistence_Manager.h" +#include <ace/SString.h> + +namespace TAO_Notify +{ + static const ACE_UINT32 ROUTING_SLIP_ROOT_BLOCK_NUMBER = 0; + static const ACE_UINT64 ROUTING_SLIP_ROOT_SERIAL_NUMBER = 1; + + /// \brief Standard (i.e. default) implementation of Event_Persistence_Factory interface + class TAO_Notify_Serv_Export Standard_Event_Persistence_Factory : + public Event_Persistence_Factory + { + public: + /// Constructor + Standard_Event_Persistence_Factory (); + /// Destructor + virtual ~Standard_Event_Persistence_Factory(); + + /// Open persistence file and initialize. + /// /param filename the fully qualified path/name of the file to contain + /// persistent information. + /// /param block_size the size of a physical block on the device containing + /// the file. + bool open (const char * filename, ACE_UINT32 block_size = 512); + + ////////////////////////////////////////////////////// + // Implement Event_Persistence_Factory virtual methods. + virtual Routing_Slip_Persistence_Manager* + create_routing_slip_persistence_manager(Persistent_Callback* callback); + + virtual Routing_Slip_Persistence_Manager * first_reload_manager(); + + /// reloading process complete. Where should the chain continue? + void done_reloading( + Persistent_Storage_Block * next_psb, + ACE_UINT64 current_serial_number); + + /// return current serial # and a psb containing current record# + /// allocate new serial # and record number, and return those, too. + void preallocate_next_record( + ACE_UINT64& current_serial_number, + Persistent_Storage_Block*& current_psb, + ACE_UINT64& next_serial_number, + ACE_UINT32& next_block_number); + + // return block pointer info for the + void get_preallocated_pointer( + ACE_UINT64& next_serial_number, + ACE_UINT32& next_block_number); + + /// Accessor for file allocator. + /// Intended for use only by the Routing Slip Persistence Manager + Persistent_File_Allocator* allocator(); + + /// Access root record. + /// Intended for use only by the Routing Slip Persistence Manager + Routing_Slip_Persistence_Manager & root(); + + public: + ACE_SYNCH_MUTEX lock; + + private: + Persistent_File_Allocator allocator_; + Routing_Slip_Persistence_Manager root_; + Persistent_Storage_Block* psb_; + ACE_UINT64 serial_number_; + bool is_reloading_; + }; + + /// \brief The standard implementation of the + /// Event_Persistence_Strategy interface. + class TAO_Notify_Serv_Export Standard_Event_Persistence : + public Event_Persistence_Strategy + { + public : + /// Constructor. + Standard_Event_Persistence (); + /// Destructor. + virtual ~Standard_Event_Persistence (); + ///////////////////////////////////////////// + // Override Event_Persistent_Strategy methods + // Parse arguments and initialize. + virtual int init(int argc, ACE_TCHAR *argv[]); + // Prepare for shutdown + virtual int fini (); + + // get the current factory, creating it if necessary + virtual Event_Persistence_Factory * get_factory (); + + // release the current factory so a new one can be created + virtual void reset (); + + private: + ACE_CString filename_; // set via -file_path + ACE_UINT32 block_size_; // set via -block_size + Standard_Event_Persistence_Factory * factory_; + }; + +} + +#include /**/ "ace/post.h" +#endif /* STANDARD_EVENT_PERSISTENCE_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.cpp index 1dbaafc894d..74c9b2c1414 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.cpp @@ -4,6 +4,7 @@ #include "tao/debug.h" #include "tao/debug.h" +#include "../Method_Request_Dispatch.h" #if ! defined (__ACE_INLINE__) #include "RT_StructuredProxyPushSupplier.inl" @@ -35,11 +36,11 @@ TAO_Notify_RT_StructuredProxyPushSupplier::activate (PortableServer::Servant ser } void -TAO_Notify_RT_StructuredProxyPushSupplier::push (const TAO_Notify_Event* event ACE_ENV_ARG_DECL) +TAO_Notify_RT_StructuredProxyPushSupplier::deliver (TAO_Notify_Method_Request_Dispatch & request ACE_ENV_ARG_DECL) { ACE_TRY { - event->push (this->event_forwarder_.in () ACE_ENV_ARG_PARAMETER); + request.event()->push (this->event_forwarder_.in () ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } ACE_CATCHANY @@ -72,14 +73,3 @@ TAO_Notify_RT_StructuredProxyPushSupplier::push_no_filtering (const TAO_Notify_E ACE_ENDTRY; } -void -TAO_Notify_RT_StructuredProxyPushSupplier::push (const TAO_Notify_Event_var &event ACE_ENV_ARG_DECL) -{ - this->push (event.get () ACE_ENV_ARG_PARAMETER); -} - -void -TAO_Notify_RT_StructuredProxyPushSupplier::push_no_filtering (const TAO_Notify_Event_var &event ACE_ENV_ARG_DECL) -{ - this->push_no_filtering (event.get () ACE_ENV_ARG_PARAMETER); -} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.h index 9ba900c87a1..e38f255497b 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.h @@ -20,6 +20,7 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "StructuredProxyPushSupplier.h" +class TAO_Notify_Method_Request; /** * @class TAO_Notify_RT_StructuredProxyPushSupplier @@ -40,17 +41,11 @@ public: virtual CORBA::Object_ptr activate (PortableServer::Servant servant ACE_ENV_ARG_DECL); /// Dispatch Event to consumer - virtual void push (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); - - /// Dispatch Event to consumer - virtual void push (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL); + void deliver (TAO_Notify_Method_Request_Dispatch & request ACE_ENV_ARG_DECL); /// Dispatch Event to consumer, no filtering virtual void push_no_filtering (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); - /// Dispatch Event to consumer, no filtering - virtual void push_no_filtering (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL); - private: /// Our ref. Event_Forwarder::StructuredProxyPushSupplier_var event_forwarder_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.inl b/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.inl index 2387811a56a..cfa1da318d3 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/RT_StructuredProxyPushSupplier.inl @@ -1,3 +1 @@ // $Id$ - -#include "RT_StructuredProxyPushSupplier.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.cpp b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.cpp index 1ce4ede4465..7bd714ac793 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.cpp @@ -36,16 +36,36 @@ TAO_Notify_StructuredEvent_No_Copy::~TAO_Notify_StructuredEvent_No_Copy () { } -TAO_Notify_Event* -TAO_Notify_StructuredEvent_No_Copy::copy (ACE_ENV_SINGLE_ARG_DECL) const +void +TAO_Notify_StructuredEvent_No_Copy::marshal (TAO_OutputCDR & cdr) const { - TAO_Notify_Event* copy; + static const ACE_CDR::Octet STRUCTURED_CODE = MARSHAL_STRUCTURED; + cdr.write_octet (STRUCTURED_CODE); + cdr << (*this->notification_); +} - ACE_NEW_THROW_EX (copy, +//static +TAO_Notify_StructuredEvent * +TAO_Notify_StructuredEvent_No_Copy::unmarshal (TAO_InputCDR & cdr) +{ + TAO_Notify_StructuredEvent * event = 0; + CosNotification::StructuredEvent body; + if (cdr >> body) + { + event = new TAO_Notify_StructuredEvent (body); + } + return event; +} + +TAO_Notify_Event * +TAO_Notify_StructuredEvent_No_Copy::copy (ACE_ENV_SINGLE_ARG_DECL) const +{ + TAO_Notify_Event * new_event; + ACE_NEW_THROW_EX (new_event, TAO_Notify_StructuredEvent (*this->notification_), CORBA::NO_MEMORY ()); - - return copy; + ACE_CHECK_RETURN (0); + return new_event; } CORBA::Boolean @@ -119,3 +139,10 @@ TAO_Notify_StructuredEvent::TAO_Notify_StructuredEvent (const CosNotification::S TAO_Notify_StructuredEvent::~TAO_Notify_StructuredEvent () { } + +const TAO_Notify_Event * +TAO_Notify_StructuredEvent::queueable_copy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)const +{ + return this; +} + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.h b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.h index d6edc36aa28..4457f1c4298 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.h @@ -12,7 +12,7 @@ #define TAO_Notify_STRUCTUREDEVENT_H #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -22,6 +22,8 @@ #include "../EventType.h" #include "orbsvcs/CosNotificationC.h" +class TAO_Notify_StructuredEvent; + /** * @class TAO_Notify_StructuredEvent_No_Copy * @@ -38,8 +40,8 @@ public: /// Destructor ~TAO_Notify_StructuredEvent_No_Copy (); - /// Copy the event. - virtual TAO_Notify_Event* copy (ACE_ENV_SINGLE_ARG_DECL) const; + /// marshal this event into a CDR buffer (for persistence) + virtual void marshal (TAO_OutputCDR & cdr) const; CORBA::Boolean do_match (CosNotifyFilter::Filter_ptr filter ACE_ENV_ARG_DECL) const; @@ -64,7 +66,14 @@ public: /// Push event to the Event_Forwarder interface virtual void push_no_filtering (Event_Forwarder::ProxyPushSupplier_ptr forwarder ACE_ENV_ARG_DECL) const; + /// unmarshal this event from a CDR buffer (for persistence) + /// \return the new event, or NULL if this is the wrong type of event. + static TAO_Notify_StructuredEvent * unmarshal (TAO_InputCDR & cdr); + protected: + /// returns a copy of this event allocated on the heap + virtual TAO_Notify_Event * copy (ACE_ENV_SINGLE_ARG_DECL) const; + /// Structured Event const CosNotification::StructuredEvent* notification_; @@ -89,6 +98,9 @@ public: /// Destructor ~TAO_Notify_StructuredEvent (); + /// returns this + virtual const TAO_Notify_Event * queueable_copy (ACE_ENV_SINGLE_ARG_DECL)const; + protected: /// Copy of the Event. CosNotification::StructuredEvent notification_copy; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.inl b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.inl index f92715e126c..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredEvent.inl @@ -1,4 +1,2 @@ // $Id$ -#include "StructuredEvent.h" - diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp index b29fb8f0e6b..7966c3c2e3f 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp @@ -14,8 +14,7 @@ ACE_RCSID(RT_Notify, TAO_Notify_StructuredProxyPushConsumer, "$Id$") #include "StructuredPushSupplier.h" #include "StructuredEvent.h" #include "../AdminProperties.h" -#include "../Method_Request_Lookup.h" -#include "../Worker_Task.h" +#include "../Properties.h" TAO_Notify_StructuredProxyPushConsumer::TAO_Notify_StructuredProxyPushConsumer (void) { @@ -59,8 +58,9 @@ TAO_Notify_StructuredProxyPushConsumer::connect_structured_push_supplier (CosNot supplier->init (push_supplier ACE_ENV_ARG_PARAMETER); ACE_CHECK; - this->connect (supplier ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -81,10 +81,7 @@ TAO_Notify_StructuredProxyPushConsumer::push_structured_event (const CosNotifica } TAO_Notify_StructuredEvent_No_Copy event (notification); - - TAO_Notify_Method_Request_Lookup_No_Copy request (&event, this); - - this->worker_task ()->execute (request ACE_ENV_ARG_PARAMETER); + this->push_i (&event ACE_ENV_ARG_PARAMETER); } void @@ -94,4 +91,43 @@ TAO_Notify_StructuredProxyPushConsumer::disconnect_structured_push_consumer (ACE )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + +} +const char * +TAO_Notify_StructuredProxyPushConsumer::get_proxy_type_name (void) const +{ + return "structured_proxy_push_consumer"; +} + +void +TAO_Notify_StructuredProxyPushConsumer::load_attrs (const TAO_Notify::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::StructuredPushSupplier_var ps = + CosNotifyComm::StructuredPushSupplier::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + // minor hack: suppress generating subscription updates during reload. + bool save_updates = this->updates_off_; + this->updates_off_ = true; + this->connect_structured_push_supplier(ps.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->updates_off_ = save_updates; + } + ACE_CATCHANY + { + // if we can't reconnect to peer, tough... + } + ACE_ENDTRY; + } } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h index 4d12ce3a297..35fc44fe559 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h @@ -14,7 +14,7 @@ #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -40,6 +40,7 @@ class TAO_Notify_Serv_Export TAO_Notify_StructuredProxyPushConsumer : public virtual TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::StructuredProxyPushConsumer> { + typedef TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::StructuredProxyPushConsumer> SuperClass; friend class TAO_Notify_Builder; public: @@ -52,6 +53,8 @@ public: /// Release virtual void release (void); + virtual void load_attrs (const TAO_Notify::NVPList& attrs); + protected: // = interface methods @@ -69,14 +72,14 @@ protected: CosEventChannelAdmin::AlreadyConnected )); -virtual void push_structured_event ( - const CosNotification::StructuredEvent & notification - ACE_ENV_ARG_DECL - ) - ACE_THROW_SPEC (( - CORBA::SystemException, - CosEventComm::Disconnected - )); + virtual void push_structured_event ( + const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )); virtual void disconnect_structured_push_consumer ( ACE_ENV_SINGLE_ARG_DECL @@ -84,6 +87,8 @@ virtual void push_structured_event ( ACE_THROW_SPEC (( CORBA::SystemException )); + + virtual const char * get_proxy_type_name (void) const; }; #if defined(_MSC_VER) && (_MSC_VER >= 1200) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.inl b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.inl index 0ae697976e7..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.inl @@ -1,3 +1,2 @@ // $Id$ -#include "StructuredProxyPushConsumer.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp index 4417d59682a..fac13c9cdf1 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp @@ -1,14 +1,17 @@ // $Id$ #include "StructuredProxyPushSupplier.h" + +#if ! defined (__ACE_INLINE__) +#include "StructuredProxyPushSupplier.inl" +#endif /* __ACE_INLINE__ */ + #include "tao/PortableServer/Servant_Base.h" #include "tao/debug.h" #include "StructuredPushConsumer.h" +#include "../Properties.h" -#if ! defined (__ACE_INLINE__) -#include "StructuredProxyPushSupplier.inl" -#endif /* __ACE_INLINE__ */ ACE_RCSID(RT_Notify, TAO_Notify_StructuredProxyPushSupplier, "$Id$") @@ -57,6 +60,8 @@ TAO_Notify_StructuredProxyPushSupplier::connect_structured_push_consumer (CosNot ACE_CHECK; this->connect (consumer ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -67,4 +72,39 @@ TAO_Notify_StructuredProxyPushSupplier::disconnect_structured_push_supplier (ACE { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +const char * +TAO_Notify_StructuredProxyPushSupplier::get_proxy_type_name (void) const +{ + return "structured_proxy_push_supplier"; +} + +void +TAO_Notify_StructuredProxyPushSupplier::load_attrs (const TAO_Notify::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::StructuredPushConsumer_var pc = + CosNotifyComm::StructuredPushConsumer::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->connect_structured_push_consumer(pc.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // if we can't connect... tough + } + ACE_ENDTRY; + } } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h index b308766a4ce..5990e0ebd12 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h @@ -14,7 +14,7 @@ #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -47,6 +47,7 @@ TAO_Notify_ProxySupplier_T<POA_Event_Forwarder::StructuredProxyPushSupplier>; class TAO_Notify_Serv_Export TAO_Notify_StructuredProxyPushSupplier : public virtual TAO_Notify_ProxySupplier_T <POA_Event_Forwarder::StructuredProxyPushSupplier> { + typedef TAO_Notify_ProxySupplier_T <POA_Event_Forwarder::StructuredProxyPushSupplier> SuperClass; friend class TAO_Notify_Builder; public: @@ -59,6 +60,8 @@ public: /// Release virtual void release (void); + virtual void load_attrs (const TAO_Notify::NVPList& attrs); + /// = Servant methods // = interface methods virtual CosNotifyChannelAdmin::ProxyType MyType (ACE_ENV_SINGLE_ARG_DECL) @@ -83,6 +86,7 @@ public: CORBA::SystemException )); + virtual const char * get_proxy_type_name (void) const; }; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.inl b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.inl index 1e0efbafba2..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.inl @@ -1,3 +1,2 @@ // $Id$ -#include "StructuredProxyPushSupplier.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp index 185ffe305a1..01bb530cf57 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp @@ -1,7 +1,5 @@ // $Id$ #include "StructuredPushConsumer.h" -#include "ace/Refcounted_Auto_Ptr.h" -#include "../Event.h" #if ! defined (__ACE_INLINE__) #include "StructuredPushConsumer.inl" @@ -9,6 +7,10 @@ ACE_RCSID(RT_Notify, TAO_Notify_StructuredPushConsumer, "$Id$") +#include "../Properties.h" +#include "../Event.h" +#include "ace/Refcounted_Auto_Ptr.h" + TAO_Notify_StructuredPushConsumer::TAO_Notify_StructuredPushConsumer (TAO_Notify_ProxySupplier* proxy) :TAO_Notify_Consumer (proxy) { @@ -35,18 +37,6 @@ TAO_Notify_StructuredPushConsumer::release (void) } void -TAO_Notify_StructuredPushConsumer::push_i (const TAO_Notify_Event* event ACE_ENV_ARG_DECL) -{ - event->push (this ACE_ENV_ARG_PARAMETER); -} - -void -TAO_Notify_StructuredPushConsumer::push_i (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL) -{ - event->push (this ACE_ENV_ARG_PARAMETER); -} - -void TAO_Notify_StructuredPushConsumer::push (const CORBA::Any& event ACE_ENV_ARG_DECL) { CosNotification::StructuredEvent notification; @@ -61,3 +51,44 @@ TAO_Notify_StructuredPushConsumer::push (const CosNotification::StructuredEvent& { this->push_consumer_->push_structured_event (event ACE_ENV_ARG_PARAMETER); } + +/// Push a batch of events to this consumer. +void +TAO_Notify_StructuredPushConsumer::push (const CosNotification::EventBatch& event ACE_ENV_ARG_DECL_NOT_USED) +{ + ACE_ASSERT(false); + ACE_UNUSED_ARG (event); + // TODO exception? +} + +void +TAO_Notify_StructuredPushConsumer::reconnect_from_consumer (TAO_Notify_Consumer* old_consumer + ACE_ENV_ARG_DECL) +{ + TAO_Notify_StructuredPushConsumer* tmp = dynamic_cast<TAO_Notify_StructuredPushConsumer *> (old_consumer); + ACE_ASSERT(tmp != 0); + this->init(tmp->push_consumer_.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->schedule_timer(false); +} + +bool +TAO_Notify_StructuredPushConsumer::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_consumer_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h index 1dca5c25440..9e66107f208 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h @@ -13,7 +13,7 @@ #define TAO_Notify_STRUCTUREDPUSHCONSUMER_H #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -46,10 +46,7 @@ public: virtual void release (void); /// Push <event> to this consumer. - virtual void push_i (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); - - /// Push <event> to this consumer. - virtual void push_i (const TAO_Notify_Event_var& event ACE_ENV_ARG_DECL); +// virtual void push_i (const TAO_Notify_Event* event ACE_ENV_ARG_DECL); /// Push <event> to this consumer. virtual void push (const CORBA::Any& event ACE_ENV_ARG_DECL); @@ -57,6 +54,19 @@ public: /// Push <event> to this consumer. virtual void push (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL); + /// Push a batch of events to this consumer. + virtual void push (const CosNotification::EventBatch& event ACE_ENV_ARG_DECL); + + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + + /// on reconnect we need to move events from the old consumer + /// to the new one + virtual void reconnect_from_consumer ( + TAO_Notify_Consumer* old_consumer + ACE_ENV_ARG_DECL); + + protected: /// The Consumer CosNotifyComm::StructuredPushConsumer_var push_consumer_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.inl b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.inl index 24e952b7ae8..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.inl @@ -1,3 +1,2 @@ // $Id$ -#include "StructuredPushConsumer.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.cpp index 12e343f11b7..8c06d5864ee 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.cpp @@ -7,6 +7,7 @@ #endif /* __ACE_INLINE__ */ ACE_RCSID(RT_Notify, TAO_Notify_StructuredPushSupplier, "$Id$") +#include "../Properties.h" TAO_Notify_StructuredPushSupplier::TAO_Notify_StructuredPushSupplier (TAO_Notify_ProxyConsumer* proxy) :TAO_Notify_Supplier (proxy) @@ -31,3 +32,24 @@ TAO_Notify_StructuredPushSupplier::release (void) delete this; //@@ inform factory } + +bool +TAO_Notify_StructuredPushSupplier::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_supplier_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.h index f2329db3542..f0beb284f54 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.h @@ -13,7 +13,7 @@ #define TAO_Notify_STRUCTUREDPUSHSUPPLIER_H #include /**/ "ace/pre.h" -#include "../notify_export.h" +#include "../notify_serv_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -45,6 +45,9 @@ public: /// Release virtual void release (void); + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + protected: /// The Supplier CosNotifyComm::StructuredPushSupplier_var push_supplier_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.inl b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.inl index 12cb29daaef..74e88caa0c5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.inl +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushSupplier.inl @@ -1,3 +1,2 @@ // $Id$ -#include "StructuredPushSupplier.h" diff --git a/TAO/orbsvcs/orbsvcs/Notify/SupplierAdmin.cpp b/TAO/orbsvcs/orbsvcs/Notify/SupplierAdmin.cpp index 37823207801..c5923eda2d4 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/SupplierAdmin.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/SupplierAdmin.cpp @@ -6,19 +6,25 @@ #include "SupplierAdmin.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID (RT_Notify, - TAO_Notify_SupplierAdmin, +ACE_RCSID (RT_Notify, + TAO_Notify_SupplierAdmin, "$Id$") #include "orbsvcs/ESF/ESF_Proxy_Collection.h" #include "Builder.h" -#include "Proxy.h" +#include "ProxyConsumer.h" #include "EventChannel.h" #include "Subscription_Change_Worker.h" #include "Find_Worker_T.h" #include "Seq_Worker_T.h" #include "Properties.h" +#include "tao/debug.h" +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + typedef TAO_Notify_Find_Worker_T<TAO_Notify_Proxy , CosNotifyChannelAdmin::ProxyConsumer , CosNotifyChannelAdmin::ProxyConsumer_ptr @@ -28,7 +34,14 @@ TAO_Notify_ProxyConsumer_Find_Worker; typedef TAO_Notify_Seq_Worker_T<TAO_Notify_Proxy> TAO_Notify_Proxy_Seq_Worker; TAO_Notify_SupplierAdmin::TAO_Notify_SupplierAdmin (void) + : TAO_Notify_Admin () +{ +} + +const char * +TAO_Notify_SupplierAdmin::get_admin_type_name () const { + return "supplier_admin"; } TAO_Notify_SupplierAdmin::~TAO_Notify_SupplierAdmin () @@ -81,6 +94,65 @@ TAO_Notify_SupplierAdmin::destroy (ACE_ENV_SINGLE_ARG_DECL) ACE_CHECK; } +TAO_Notify::Topology_Object* +TAO_Notify_SupplierAdmin::load_child (const ACE_CString &type, + CORBA::Long id, const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL) +{ + TAO_Notify::Topology_Object* result = this; + if (type == "proxy_push_consumer") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Admin reload proxy %d\n") + , ACE_static_cast (int, id) + )); + result = this->load_proxy(id, CosNotifyChannelAdmin::ANY_EVENT, attrs ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + else if (type == "structured_proxy_push_consumer") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Admin reload proxy %d\n") + , ACE_static_cast (int, id) + )); + result = this->load_proxy(id, CosNotifyChannelAdmin::STRUCTURED_EVENT, attrs ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + else if (type == "sequence_proxy_push_consumer") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Admin reload proxy %d\n") + , ACE_static_cast (int, id) + )); + result = this->load_proxy(id, CosNotifyChannelAdmin::SEQUENCE_EVENT, attrs ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + else + { + result = TAO_Notify_Admin::load_child (type, id, attrs ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + return result; +} + +TAO_Notify::Topology_Object* +TAO_Notify_SupplierAdmin::load_proxy ( + CORBA::Long id, + CosNotifyChannelAdmin::ClientType ctype, + const TAO_Notify::NVPList& attrs ACE_ENV_ARG_DECL) +{ + TAO_Notify_Builder* bld = TAO_Notify_PROPERTIES::instance()->builder(); + TAO_Notify_ProxyConsumer * proxy = + bld->build_proxy (this + , ctype + , id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + ACE_ASSERT(proxy != 0); + proxy->load_attrs (attrs); + return proxy; +} + + void TAO_Notify_SupplierAdmin::set_qos (const CosNotification::QoSProperties & qos ACE_ENV_ARG_DECL) ACE_THROW_SPEC (( @@ -112,11 +184,16 @@ TAO_Notify_SupplierAdmin::obtain_notification_push_consumer (CosNotifyChannelAdm { CosNotification::QoSProperties initial_qos; - return TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this + CosNotifyChannelAdmin::ProxyConsumer_var proxy = + TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this , ctype , proxy_id , initial_qos ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + return proxy._retn (); } CosNotifyChannelAdmin::ProxyConsumer_ptr @@ -131,11 +208,16 @@ TAO_Notify_SupplierAdmin::obtain_notification_push_consumer_with_qos (CosNotifyC , CosNotification::UnsupportedQoS )) { - return TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this + CosNotifyChannelAdmin::ProxyConsumer_var proxy = + TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this , ctype , proxy_id, initial_qos ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + return proxy._retn (); } @@ -145,7 +227,12 @@ TAO_Notify_SupplierAdmin::obtain_push_consumer (ACE_ENV_SINGLE_ARG_DECL) CORBA::SystemException )) { - return TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this ACE_ENV_ARG_PARAMETER); + CosEventChannelAdmin::ProxyPushConsumer_var proxy = + TAO_Notify_PROPERTIES::instance()->builder()->build_proxy (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxy._retn ()); + return proxy._retn (); } CosNotifyChannelAdmin::AdminID @@ -231,7 +318,12 @@ TAO_Notify_SupplierAdmin::add_filter (CosNotifyFilter::Filter_ptr new_filter ACE CORBA::SystemException )) { - return this->filter_admin_.add_filter (new_filter ACE_ENV_ARG_PARAMETER); + CosNotifyFilter::FilterID fid = + this->filter_admin_.add_filter (new_filter ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (fid); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (fid); + return fid; } void @@ -317,6 +409,23 @@ TAO_Notify_SupplierAdmin::obtain_notification_pull_consumer (CosNotifyChannelAdm ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), CosNotifyChannelAdmin::ProxyConsumer::_nil ()); } +TAO_Notify_ProxyConsumer * +TAO_Notify_SupplierAdmin::find_proxy_consumer ( + TAO_Notify::IdVec & id_path, + size_t position + ACE_ENV_ARG_DECL) +{ + TAO_Notify_ProxyConsumer * result = 0; + size_t path_size = id_path.size (); + if (position < path_size) + { + TAO_Notify_ProxyConsumer_Find_Worker find_worker; + TAO_Notify_Proxy * proxy = find_worker.find (id_path[position], *this->proxy_container_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + result = dynamic_cast <TAO_Notify_ProxyConsumer *> (proxy); + } + return result; +} #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) diff --git a/TAO/orbsvcs/orbsvcs/Notify/SupplierAdmin.h b/TAO/orbsvcs/orbsvcs/Notify/SupplierAdmin.h index bb1233eeae0..2a3f168f7ef 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/SupplierAdmin.h +++ b/TAO/orbsvcs/orbsvcs/Notify/SupplierAdmin.h @@ -24,6 +24,8 @@ #include "Admin.h" +class TAO_Notify_ProxyConsumer; + #if defined(_MSC_VER) #if (_MSC_VER >= 1200) #pragma warning(push) @@ -37,8 +39,8 @@ * @brief Implementation of CosNotifyChannelAdmin::SupplierAdmin * */ -class TAO_Notify_Serv_Export TAO_Notify_SupplierAdmin - : public virtual POA_NotifyExt::SupplierAdmin, +class TAO_Notify_Serv_Export TAO_Notify_SupplierAdmin + : public virtual POA_NotifyExt::SupplierAdmin, public virtual TAO_Notify_Admin { public: @@ -58,8 +60,27 @@ public: /// Release virtual void release (void); + virtual const char * get_admin_type_name () const; + + virtual TAO_Notify::Topology_Object* load_child ( + const ACE_CString &type, + CORBA::Long id, + const TAO_Notify::NVPList& attrs + ACE_ENV_ARG_DECL); + + TAO_Notify_ProxyConsumer * find_proxy_consumer ( + TAO_Notify::IdVec & id_path, + size_t position + ACE_ENV_ARG_DECL); + protected: + TAO_Notify::Topology_Object *load_proxy ( + CORBA::Long id, + CosNotifyChannelAdmin::ClientType ctype, + const TAO_Notify::NVPList& attrs + ACE_ENV_ARG_DECL); + /// = NotifyExt::SupplierAdmin methods CosNotifyChannelAdmin::ProxyConsumer_ptr obtain_notification_push_consumer_with_qos ( @@ -103,7 +124,7 @@ protected: ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyChannelAdmin::ProxyNotFound)); - virtual ::CosNotifyChannelAdmin::ProxyConsumer_ptr + virtual ::CosNotifyChannelAdmin::ProxyConsumer_ptr obtain_notification_pull_consumer ( CosNotifyChannelAdmin::ClientType ctype, CosNotifyChannelAdmin::ProxyID_out proxy_id @@ -112,7 +133,7 @@ protected: ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyChannelAdmin::AdminLimitExceeded)); - virtual ::CosNotifyChannelAdmin::ProxyConsumer_ptr + virtual ::CosNotifyChannelAdmin::ProxyConsumer_ptr obtain_notification_push_consumer ( CosNotifyChannelAdmin::ClientType ctype, CosNotifyChannelAdmin::ProxyID_out proxy_id @@ -127,7 +148,7 @@ protected: virtual ::CosNotification::QoSProperties* get_qos (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException)); - virtual void set_qos (const CosNotification::QoSProperties& qos + virtual void set_qos (const CosNotification::QoSProperties& qos ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, CosNotification::UnsupportedQoS)); @@ -160,7 +181,7 @@ protected: CosNotifyFilter::FilterNotFound)); virtual ::CosNotifyFilter::Filter_ptr get_filter ( - CosNotifyFilter::FilterID filter + CosNotifyFilter::FilterID filter ACE_ENV_ARG_DECL ) ACE_THROW_SPEC ((CORBA::SystemException, diff --git a/TAO/orbsvcs/orbsvcs/Notify/ThreadPool_Task.cpp b/TAO/orbsvcs/orbsvcs/Notify/ThreadPool_Task.cpp index a234e7882d6..1bbd9c1f7cf 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ThreadPool_Task.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/ThreadPool_Task.cpp @@ -96,9 +96,9 @@ TAO_Notify_ThreadPool_Task::init (const NotifyExt::ThreadPoolParams& tp_params, } void -TAO_Notify_ThreadPool_Task::execute (TAO_Notify_Method_Request_No_Copy& method_request ACE_ENV_ARG_DECL) +TAO_Notify_ThreadPool_Task::execute (TAO_Notify_Method_Request& method_request ACE_ENV_ARG_DECL) { - TAO_Notify_Method_Request& request_copy = *method_request.copy (ACE_ENV_SINGLE_ARG_PARAMETER); + TAO_Notify_Method_Request_Queueable& request_copy = *method_request.copy (ACE_ENV_SINGLE_ARG_PARAMETER); if (this->buffering_strategy_->enqueue (request_copy) == -1) { @@ -111,7 +111,7 @@ TAO_Notify_ThreadPool_Task::execute (TAO_Notify_Method_Request_No_Copy& method_r int TAO_Notify_ThreadPool_Task::svc (void) { - TAO_Notify_Method_Request* method_request; + TAO_Notify_Method_Request_Queueable* method_request; while (!shutdown_) { diff --git a/TAO/orbsvcs/orbsvcs/Notify/ThreadPool_Task.h b/TAO/orbsvcs/orbsvcs/Notify/ThreadPool_Task.h index c2f41442f98..83ef404dcaa 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/ThreadPool_Task.h +++ b/TAO/orbsvcs/orbsvcs/Notify/ThreadPool_Task.h @@ -59,7 +59,7 @@ public: void init (const NotifyExt::ThreadPoolParams& tp_params, TAO_Notify_AdminProperties_var& admin_properties ACE_ENV_ARG_DECL); /// Queue the request - virtual void execute (TAO_Notify_Method_Request_No_Copy& method_request ACE_ENV_ARG_DECL); + virtual void execute (TAO_Notify_Method_Request& method_request ACE_ENV_ARG_DECL); /// Shutdown task virtual void shutdown (void); diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Factory.h b/TAO/orbsvcs/orbsvcs/Notify/Topology_Factory.h new file mode 100644 index 00000000000..30ffaadba58 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Factory.h @@ -0,0 +1,46 @@ +/** + * @file Topology_Factory.h + * + * $Id$ + * + * @author Dale Wilson <wilson_d@ociweb.com> + * + * + */ +#ifndef TAO_NOTIFY_TOPOLOGY_FACTORY_H +#define TAO_NOTIFY_TOPOLOGY_FACTORY_H +#include /**/ "ace/pre.h" + +#include "notify_serv_export.h" + +#include "ace/Service_Object.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + class Topology_Saver; + class Topology_Loader; + + /** + * @brief Service Object to allow dynamic control of the loaded saver factory. + * + */ + class TAO_Notify_Serv_Export Topology_Factory : public ACE_Service_Object + { + public: + /// Create a Saver. + /// \return a pointer to a Topology_Saver which must be deleted + /// by the caller. + virtual Topology_Saver* create_saver () = 0; + /// Create a Loader + /// \return a pointer to a Topology_Loader which must be deleted + /// by the caller. + virtual Topology_Loader* create_loader () = 0; + }; +} + +#include /**/ "ace/post.h" +#endif diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Loader.cpp b/TAO/orbsvcs/orbsvcs/Notify/Topology_Loader.cpp new file mode 100644 index 00000000000..253f988ff37 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Loader.cpp @@ -0,0 +1,16 @@ +// $Id$ + +#include "Topology_Loader.h" + +TAO_Notify::Topology_Loader::Topology_Loader () +{ +} + +TAO_Notify::Topology_Loader::~Topology_Loader () +{ +} + +void +TAO_Notify::Topology_Loader::close (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Loader.h b/TAO/orbsvcs/orbsvcs/Notify/Topology_Loader.h new file mode 100644 index 00000000000..5557b23246c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Loader.h @@ -0,0 +1,73 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Topology_Loader.h + * + * $Id$ + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef TOPOLOGY_LOADER_H +#define TOPOLOGY_LOADER_H +#include "ace/pre.h" + +#include "ace/config-all.h" + +#include "tao/corba.h" +#include "notify_serv_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + +/// A forward declaration. +class Topology_Object; + +/** + * \brief An interface for an object that loads Persistent Topology Information. + * + * A persistent store must provide an implemention this interface. + * + */ +class TAO_Notify_Serv_Export Topology_Loader +{ +public: + /// The constructor. + Topology_Loader (); + + /// The destructor. + virtual ~Topology_Loader (); + + /** \brief Begin the restore process. + * + * Call this function to start the reload of data from a persistent store. + * When the Topology_Loader detects a child object, it should + * call the load_child method of the object passed in, then do the same + * loading process on the returned object. + */ + virtual void load (Topology_Object *root ACE_ENV_ARG_DECL) = 0; + + /** + * \brief Close the loader after loading is complete. + * + * This is not pure virtual because some loaders may not need to be closed. + * The default implementation does nothing. + * + * There should be a corresponding open, but the signature may + * vary based on the type of loader, so we can't include it in the + * interface. + */ + virtual void close (ACE_ENV_SINGLE_ARG_DECL); +}; + +} // namespace TAO_Notify + +#include /**/ "ace/post.h" + +#endif /* TOPOLOGY_LOADER */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.cpp b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.cpp new file mode 100644 index 00000000000..15832ead771 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.cpp @@ -0,0 +1,148 @@ +// $Id$ + +#include "Topology_Object.h" + +#if ! defined (__ACE_INLINE__) +#include "Topology_Object.inl" +#endif /* __ACE_INLINE__ */ + +// question: is there a race_conditon with self_changed and children_changed? +// answer: toplogy_changed and/or children_changed must be set after the change is +// made, and before the call to child_change. +// self_changed and children_changed must be cleared before this object and its +// children have been saved in Topology_Object::save_persistent (). +// If these rules are followed, the only risk is a (harmless) extra save. + +namespace TAO_Notify +{ + void + Topology_Savable::reconnect (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + { + } + + Topology_Object::Topology_Object () + : self_changed_ (false) + , children_changed_ (false) + , topology_parent_ (0) + { + } + + Topology_Object::~Topology_Object () + { + } + + void + Topology_Object::init (Topology_Parent * parent) + { + this->topology_parent_ = parent; + TAO_Notify_Object::init (parent); + } + + Topology_Parent * + Topology_Object::topology_parent () const + { + return this->topology_parent_; + } + + + Topology_Object * + Topology_Object::load_child (const ACE_CString & /*type*/, + CORBA::Long /* id */, + const NVPList& /* attrs */ + ACE_ENV_ARG_DECL_NOT_USED) + { + return 0; + } + + bool + Topology_Object::is_persistent () const + { + bool result = false; + if (this->qos_properties_.event_reliability().is_valid ()) + { + result = CosNotification::Persistent == this->qos_properties_.event_reliability().value (); + } + else if (this->topology_parent () != 0) + { + result = this->topology_parent ()->is_persistent (); + } + return result; + } + + bool + Topology_Object::self_change (ACE_ENV_SINGLE_ARG_DECL) + { + this->self_changed_ = true; + return send_change (ACE_ENV_SINGLE_ARG_PARAMETER); + } + + bool + Topology_Object::send_change (ACE_ENV_SINGLE_ARG_DECL) + { + bool saving = false; + if (is_persistent ()) + { + while (this->self_changed_ || this->children_changed_) + { + saving = this->change_to_parent (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (false); + if (!saving) + { + this->self_changed_ = false; + this->children_changed_ = false; + } + } + } + else + { + this->self_changed_ = false; + this->children_changed_ = false; + } + return saving; + } + + bool + Topology_Object::change_to_parent (ACE_ENV_SINGLE_ARG_DECL) + { + bool result = false; + Topology_Parent * parent = this->topology_parent(); + if (parent != 0) + { + result = parent->child_change(ACE_ENV_SINGLE_ARG_PARAMETER); + } + return result; + } + + void + Topology_Object::get_id_path (TAO_Notify::IdVec & id_path) const + { + if (this->topology_parent() != 0) + { + this->topology_parent()->get_id_path (id_path); + } + id_path.push_back (this->get_id ()); + } + + TAO_Notify_Object::ID + Topology_Object::get_id () const + { + // If this assert triggers then implement the + // get_id method in the actual class + // derived from Topology_Object + // or else figure out why this method was called + // on an object that doesn't have an id. + ACE_ASSERT (false); + // if it is called in a release build, provide 'em a value + return -1; + } + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Vector <TAO_Notify_Object::ID>; +template class ACE_Array_Base <TAO_Notify_Object::ID>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Vector <TAO_Notify_Object::ID> +#pragma instantiate ACE_Array_Base <TAO_Notify_Object::ID> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + +} // namespace TAO_Notify diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.h b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.h new file mode 100644 index 00000000000..ee3af40ecbd --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.h @@ -0,0 +1,197 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** +* @file Topology_Object.h +* +* $Id$ +* +* @author Jonathan Pollack <pollack_j@ociweb.com> +*/ +//============================================================================= + +#ifndef TOPOLOGY_OBJECT_H +#define TOPOLOGY_OBJECT_H +#include /**/ "ace/pre.h" + +#include "Object.h" +#include "Name_Value_Pair.h" + +#include <tao/corba.h> + +#include <ace/SString.h> +#include <ace/Vector_T.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +/// \namespace TAO_Notify +/// \brief A namespace to be used by all of TAO's Notification Service implementation. +/// +/// The initial implementation used the TAO_Notify_ prefix rather than a namespace. As part +/// of the reliable Notification Service project we started using this TAO_Notify namespace, +/// but there are still many parts of the Notification Service that are in the global namespace +/// with a TAO_NS prefix. +namespace TAO_Notify +{ + static const char TOPOLOGY_ID_NAME[] = "TopologyID"; + + class Topology_Saver; + class Topology_Parent; + + /// A vector of IDS. Used as a path from the EventChannelFactory to a proxy. + typedef ACE_Vector <TAO_Notify_Object::ID> IdVec; + + /// \brief Interface to be implemented by savable topology objects. + class TAO_Notify_Serv_Export Topology_Savable + { + public: + /// Save our state to a Topology_Saver. + /// + /// Use the methods of a Topology_Saver to store all information we want + /// persisted. This function is called by our parent, which gives us a + /// saver to use. In turn, we must call this function on all of our + /// children. + /// The implementation should look like: + /// bool change = this->self_changed_; + /// this->self_changed_ = false; + /// this->children_changed_ = false; + /// if (is_persistent ()) + /// { + /// bool want_all_children = saver.begin_object( + /// this->id(), type, attrs, change ACE_ENV_ARG_PARAMETER); + /// ACE_CHECK; + /// for all children + /// { + /// if (want_all_children || child.is_changed()) + /// { + /// child.save_persistent(saver ACE_ENV_ARG_PARAMETER); + /// ACE_CHECK; + /// } + /// } + /// for all deleted children + /// { + /// saver.delete_child(child_type, child_id); + /// } + /// saver.end_object(this->id(), type ACE_ENV_ARG_PARAMETER); + /// ) + virtual void save_persistent (Topology_Saver& saver ACE_ENV_ARG_DECL) = 0; + + /// Re-establish connections that we had before a shutdown. + /// + /// After a topology restore, this method is called so we can reconnect + /// to any external objects with whom we were interacting. We should + /// call the reconnect() method on all of our children to give them + /// the chance to do the same. + virtual void reconnect (ACE_ENV_SINGLE_ARG_DECL_NOT_USED); + + }; + + /// \brief Base class for Persistent Topology Objects. + /// + /// Topology objects must be derived from this class to allow themselves + /// to be persisted. + class TAO_Notify_Serv_Export Topology_Object : public virtual TAO_Notify_Object, public Topology_Savable + { + public: + /// The constructor. + Topology_Object (); + + /// The destructor. + virtual ~Topology_Object (); + + /// Init this object with data from <rhs>. + /// Intentionally hides TAO_NotifyObject::init + void init (Topology_Parent * topology_parent); + + /// \brief Create a child of the appropriate type and return it. + /// + /// Use "type" as passed in to determine what kind of child (supporting + /// the Topology_Object interface) to create and return. Inform it of + /// its new ID. + virtual Topology_Object* load_child (const ACE_CString & /*type*/, + CORBA::Long /* id */, + const NVPList& /* attrs */ + ACE_ENV_ARG_DECL_NOT_USED); + + /// \brief Find the id associated with topology object. + /// + /// A bit of a hack because id is unknown to Topology_Object + /// the get_id returns the same thing as id -- we just need someone + /// to find it for us. + virtual TAO_Notify_Object::ID get_id () const; + + /// \brief Get the path of id's from the root to this object. + void get_id_path (IdVec & id_path) const; + + /// \brief Is there an unsaved change for this object or its children? + bool is_changed () const; + + protected: + /// \brief Should this object be saved? + /// + /// This is a way for send_change() and save_persistent() to find out + /// if this object has a persistent QoS connection property. + /// \return true (default) if object should be saved. + virtual bool is_persistent () const; + + /// \brief Method to report change in this object + /// + /// see also Topology_Parent::child_change () + /// \return false if save will never happen + bool self_change (ACE_ENV_SINGLE_ARG_DECL); + + /// \brief pointer to our topological parent + /// + /// \return 0 if none + Topology_Parent * topology_parent () const; + + /// \brief Handle details of propagating change + /// + /// \return false if save will never happen + bool send_change (ACE_ENV_SINGLE_ARG_DECL); + + private: + /// \brief Send change to parent. + /// + /// Override this if you don't expect to have a parent + /// (top level of tree) + /// private virtual because this should only be called from send_change() + /// \return false if save will never happen + virtual bool change_to_parent (ACE_ENV_SINGLE_ARG_DECL); + + protected: + /// true if this object changed since last save_persistent + bool self_changed_; + /// true of any of this object's children changed since last save_persistent + bool children_changed_; + + /// A safely-typed copy of parent_; + Topology_Parent * topology_parent_; + }; + + /// \brief Interface for topology objects that act as parents. + /// + /// Any topology object which contains other topology objects + /// must implement this interface so that it's children can signal + /// that they have changed. + class TAO_Notify_Serv_Export Topology_Parent : public Topology_Object + { + public: + /// Called by a child that has changed. + /// A child calls this method to report that it has changed. + /// \return false if save will never happen + bool child_change (ACE_ENV_SINGLE_ARG_DECL); + }; + +} // namespace TAO_Notify + +#if defined (__ACE_INLINE__) +#include "Topology_Object.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TOPOLOGY_OBJECT */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.inl b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.inl new file mode 100644 index 00000000000..efb34f9315f --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.inl @@ -0,0 +1,20 @@ +// $Id$ +namespace TAO_Notify +{ + ACE_INLINE + bool + Topology_Object::is_changed () const + { + return this->self_changed_ | this->children_changed_; + } + + ACE_INLINE + bool + Topology_Parent::child_change (ACE_ENV_SINGLE_ARG_DECL) + { + this->children_changed_ = true; + return send_change (ACE_ENV_SINGLE_ARG_PARAMETER); + } + +} // namespace TAO_Notify + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.cpp b/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.cpp new file mode 100644 index 00000000000..91873af0136 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.cpp @@ -0,0 +1,13 @@ +// $Id$ + +#include "Topology_Saver.h" + +TAO_Notify::Topology_Saver::~Topology_Saver () +{ +} + +void +TAO_Notify::Topology_Saver::close (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.h b/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.h new file mode 100644 index 00000000000..781da2721b7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.h @@ -0,0 +1,111 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** +* @file Topology_Saver.h +* +* $Id$ +* +* @author Jonathan Pollack <pollack_j@ociweb.com> +*/ +//============================================================================= + +#ifndef TOPOLOGY_SAVER_H +#define TOPOLOGY_SAVER_H +#include /**/ "ace/pre.h" + +#include "Topology_Object.h" +#include "notify_serv_export.h" + +#include "tao/corba.h" +#include "ace/SString.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + /** + * \brief An interface to be implemented by objects that save Topology. + * + * A persistent topology store must provide an implemention this interface. + * + */ + class TAO_Notify_Serv_Export Topology_Saver + { + public: + + /// The destructor. + virtual ~Topology_Saver (); + + /** \brief Begin the storage of an object. + * + * Call this function with the type and ID of an object to be stored. + * This object may have children, and this will necessitate nested calls + * to begin_object. + * Design principle: + * Names should be descriptive enough to allow the objects' parent to create + * an instance of the desired class. This instance will be registered + * with the poa using the id. + * The instance itself should will load its own attributes. + * Example <proxy type="push_supplier" events="any" id="20"...> is not a + * good design because the name "proxy" is not descriptive enough. + * "<structured_proxy_push_supplier id="20"...> is better because this + * allows the parent to create the correct type of object without decoding + * attributes. + * \param id numeric id for this object + * \param type string containing the unique type name for this class of objects + * \param attrs a collection of name/value attributes + * \param change true if this object's attributes have changed. + * \return bool want_all_children. If true even changed children should be saved. + */ + virtual bool begin_object (CORBA::Long id, + const ACE_CString &type, + const NVPList& attrs, + bool changed + ACE_ENV_ARG_DECL) = 0; + + /** \brief Report deleted children to the saver. + * + * Use the ID and "type" as passed in to determine which child we should + * delete. A parent should call this function when one of its children + * is deleted. + * \param id numeric id for the deleted child + * \param type the type name for the class of the deleted child. + * + */ + virtual void delete_child ( + CORBA::Long id, + const ACE_CString & type + ACE_ENV_ARG_DECL_NOT_USED) + { + ACE_UNUSED_ARG (id); + ACE_UNUSED_ARG (type); + } + + /** \brief End the storage of an object. + * + * This function should be called to end the scope of the current object + * and commit it to the persistent store. + */ + virtual void end_object (CORBA::Long id, + const ACE_CString &type + ACE_ENV_ARG_DECL) = 0; + + /** + * \brief Close the saver. + * + * This is not pure virtual. The default implementation does nothing. + * + * There should be a corresponding open, but the signature may + * vary based on the type of saver, so we can't include it in the + * interface. + */ + virtual void close (ACE_ENV_SINGLE_ARG_DECL); + }; +} // namespace TAO_Notify + +#include /**/ "ace/post.h" + +#endif /* TOPOLOGY_SAVER */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Worker_Task.h b/TAO/orbsvcs/orbsvcs/Notify/Worker_Task.h index 394e3651059..4bb5542b275 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Worker_Task.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Worker_Task.h @@ -48,7 +48,7 @@ public: ///= Public method to be implemented by subclasses. /// Exec the request. - virtual void execute (TAO_Notify_Method_Request_No_Copy& method_request ACE_ENV_ARG_DECL) = 0; + virtual void execute (TAO_Notify_Method_Request& method_request ACE_ENV_ARG_DECL) = 0; /// Shutdown task virtual void shutdown (void) = 0; diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.cpp b/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.cpp new file mode 100644 index 00000000000..3e32458b1e3 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.cpp @@ -0,0 +1,228 @@ +// $Id$ + +#include "XML_Loader.h" +#include "Topology_Object.h" + +#include "ACEXML/common/DefaultHandler.h" +#include "ACEXML/parser/parser/Parser.h" +#include "ACEXML/common/FileCharStream.h" + +#include "ace/Containers_T.h" +#include <tao/debug.h> +#include "ace/OS_NS_unistd.h" + +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL + +using namespace TAO_Notify; + +namespace { + CORBA::Long makeNVPList (NVPList& nvp, ACEXML_Attributes* attrs) + { + CORBA::Long id = 0; + for (size_t i = 0; i < attrs->getLength (); ++i) + { + const char * name = attrs->getQName (i); + const char * value = attrs->getValue (i); + if (ACE_OS::strcmp (name, TOPOLOGY_ID_NAME) == 0) + { + id = ACE_OS::atoi (value); + } + nvp.push_back (NVP (name, value)); + } + return id; + } +} + +namespace TAO_Notify +{ + XML_Loader::XML_Loader () + : input_ (0) + , live_ (false) + { + } + + XML_Loader::~XML_Loader () + { + } + + bool + XML_Loader::open (const ACE_CString & base_name) + { + bool result = false; + + // if *.xml exists, use it + // if it does not exist then + // use the previous one was renamed to *.000 + // If neither *.xml nor *.000 exist then something + // "impossible" happened (or its a new system with no saved state). + + this->file_name_ = base_name; + this->file_name_ += ".xml"; + + // 4 is "read permission" + result = (0 == ACE_OS::access (this->file_name_.c_str (), 4)); + if (result) + { + this->live_ = false; + ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream; + // xml input source will take ownership + + if (fstm->open (this->file_name_.c_str ()) == 0) + { + // InputSource takes ownership + ACEXML_InputSource input (fstm); + + ACEXML_Parser parser; + parser.setContentHandler (this); + parser.setDTDHandler (this); + parser.setErrorHandler (this); + parser.setEntityResolver (this); + + ACEXML_TRY_NEW_ENV + { + parser.parse (&input ACEXML_ENV_ARG_PARAMETER); + ACEXML_TRY_CHECK; + } + ACEXML_CATCH (ACEXML_Exception, ex) + { + // The only way to find out what it is, it to let it print itself, so... + ACE_ERROR ((LM_ERROR, "Error during load of \"%s\".\n Will try backup file.\n", this->file_name_.c_str ())); + ex.print (); + result = false; + } + ACEXML_ENDTRY; + } + else + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("Unable to open the XML input file: %s.\n Will try backup file.\n"), file_name_.c_str())); + result = false; + } + } + + if (! result) + { + this->file_name_ = base_name; + this->file_name_ += ".000"; + result = (0 == ACE_OS::access (this->file_name_.c_str (), 4)); + } + return result; + } + + //virtual + void + XML_Loader::load (Topology_Object *root ACE_ENV_ARG_DECL) + { + ACE_ASSERT (root != 0); + this->live_ = true; + + ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream; + // xml input source will take ownership + + if (fstm->open (this->file_name_.c_str ()) == 0) + { + // InputSource takes ownership + ACEXML_InputSource input (fstm); + + ACEXML_Parser parser; + parser.setContentHandler (this); + parser.setDTDHandler (this); + parser.setErrorHandler (this); + parser.setEntityResolver (this); + + ACEXML_TRY_NEW_ENV + { + object_stack_.push (root); + parser.parse (&input ACEXML_ENV_ARG_PARAMETER); + ACEXML_TRY_CHECK; + ACE_ASSERT (object_stack_.size () == 1); + Topology_Object* cur; + object_stack_.pop (cur); + } + ACEXML_CATCH (ACEXML_Exception, ex) + { + // The only way to find out what it is, it to let it print itself, so... + ACE_ERROR ((LM_ERROR, "Error during load of \"%s\".\n", this->file_name_.c_str ())); + ex.print (); + ACE_THROW(CORBA::INTERNAL()); + } + ACEXML_ENDTRY; + } + else + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("Unable to open the XML input file: %s.\n"), file_name_.c_str())); + ACE_THROW(CORBA::INTERNAL()); + } + } + + void + XML_Loader::startElement (const ACEXML_Char*, + const ACEXML_Char*, + const ACEXML_Char* name, + ACEXML_Attributes* xml_attrs ACEXML_ENV_ARG_DECL) + ACE_THROW_SPEC ( (ACEXML_SAXException)) + { + ACE_ASSERT (name != 0); + ACE_ASSERT (xml_attrs != 0); + if (this->live_) + { + ACE_ASSERT (object_stack_.size () > 0); + Topology_Object* cur; + if (object_stack_.top (cur) == 0) + { + ACE_TRY_NEW_ENV + { + NVPList attrs; + CORBA::Long id = makeNVPList (attrs, xml_attrs); + + if (DEBUG_LEVEL > 5) ACE_DEBUG ((LM_INFO, + ACE_TEXT("(%P|%t) XML_Loader: Element %s\n"), + name + )); + + ACE_CString cname (name); + Topology_Object* next = cur->load_child ( + cname, id, attrs ACE_ENV_ARG_PARAMETER); + ACE_ASSERT(next != 0); + ACE_TRY_CHECK; + object_stack_.push (next); + } + ACE_CATCHANY + { + ACEXML_THROW (ACEXML_SAXException (ACE_ANY_EXCEPTION._info ().c_str ())); + } + ACE_ENDTRY; + } + } + } + + void + XML_Loader::endElement (const ACEXML_Char*, + const ACEXML_Char*, + const ACEXML_Char* name ACEXML_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ( (ACEXML_SAXException)) + { + ACE_UNUSED_ARG (name); + if (this->live_) + { + ACE_ASSERT (object_stack_.size () > 0); + if (DEBUG_LEVEL > 5) ACE_DEBUG ((LM_INFO, + ACE_TEXT("(%P|%t) XML_Loader: End Element %s\n"), + name + )); + Topology_Object* cur; + object_stack_.pop (cur); + } + } + +} /* namespace TAO_Notify */ + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Unbounded_Stack<TAO_Notify::Topology_Object*>; +template class ACE_Node<TAO_Notify::Topology_Object*>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Unbounded_Stack<TAO_Notify::Topology_Object*> +#pragma instantiate ACE_Node<TAO_Notify::Topology_Object*> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.h b/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.h new file mode 100644 index 00000000000..a56dd98809a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.h @@ -0,0 +1,86 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file XML_Loader.h + * + * $Id$ + * + * A topology saver class that outputs XML. + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef XML_LOADER_H +#define XML_LOADER_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "Topology_Loader.h" + +#include "ACEXML/common/DefaultHandler.h" +#include "ACEXML/parser/parser/Parser.h" +#include "ACEXML/common/FileCharStream.h" + +#include "tao/corba.h" + +#include "ace/streams.h" + +namespace TAO_Notify +{ + + /// \brief Load Notification Service Topology from an XML file. +class XML_Loader : public ACEXML_DefaultHandler , public Topology_Loader +{ +public: + /// The constructor. + XML_Loader (); + + virtual ~XML_Loader (); + + /// Open a file and perform preliminary validation to determine whether + /// the file is complete and valid. + bool open (const ACE_CString & file_name); + + /////////////////////////////////// + // Override Topology_Loader methods + // see Topology_Loader.h for documentation + virtual void load (Topology_Object *root ACE_ENV_ARG_DECL); + + + ///////////////////////////////////////// + // Override ACEXML_DefaultHandler methods + + virtual void startElement (const ACEXML_Char* namespaceURI, + const ACEXML_Char* localName, + const ACEXML_Char* qName, + ACEXML_Attributes* atts ACEXML_ENV_ARG_DECL) + ACE_THROW_SPEC ((ACEXML_SAXException)); + + virtual void endElement (const ACEXML_Char*, + const ACEXML_Char*, + const ACEXML_Char* name ACEXML_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((ACEXML_SAXException)); + + +private: + /// The name of the file from which data is read. + ACE_CString file_name_; + /// A stream representing our current output. + istream * input_; + + typedef ACE_Unbounded_Stack<Topology_Object*> TopoStack; + TopoStack object_stack_; + // if false, then we're just checking syntax of topology file. + bool live_; +}; + +} // namespace TAO_Notify + +#include /**/ "ace/post.h" +#endif /* XML_LOADER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.cpp b/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.cpp new file mode 100644 index 00000000000..7d968ee0290 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.cpp @@ -0,0 +1,260 @@ +// $Id$ + +#include "XML_Saver.h" + +#include "ace/High_Res_Timer.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" + +namespace TAO_Notify +{ + XML_Saver::XML_Saver(bool timestamp) + : output_ (0) + , close_out_ (false) + , backup_count_ (1) + , timestamp_ (timestamp) + { + } + + XML_Saver::~XML_Saver() + { + if (this->output_ != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) XML_Saver warning close not called or failed\n") + )); + } + } + + void + XML_Saver::backup_file_name (char * file_path, int nfile) + { + ACE_OS::snprintf(file_path, MAXPATHLEN, "%s.%3.3d", + this->base_name_.c_str (), + nfile); + } + + void + XML_Saver::close (ACE_ENV_SINGLE_ARG_DECL) + { + if (this->close_out_ && this->output_ != 0) + { + this->end_object(0, "notification_service" ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + delete this->output_; + this->output_ = 0; + + // delete the oldest backup file (if it exists) + size_t nfile = this->backup_count_ - 1; + char old_path [MAXPATHLEN + 1]; + backup_file_name (old_path, nfile); + ACE_OS::unlink (old_path); + + while (nfile != 0) + { + char new_path [MAXPATHLEN + 1]; + nfile -= 1; + backup_file_name (new_path, nfile); + // this may fail, we don't care + ACE_OS::rename (new_path, old_path); + ACE_OS::strcpy (old_path, new_path); + } + // old_path now contains the name of the backup file + ACE_CString xml_name = this->base_name_; + xml_name += ".xml"; + + ACE_OS::rename (xml_name.c_str (), old_path); + + ACE_CString new_name = this->base_name_; + new_name += ".new"; + ACE_OS::rename (new_name.c_str (), xml_name.c_str ()); + } + this->output_ = 0; + } + + bool + XML_Saver::open(const ACE_CString & base_name, size_t backup_count) + { + this->base_name_ = base_name; + this->backup_count_ = backup_count; + if (base_name == "cout") + { + this->output_ = & cout; + this->close_out_ = false; + } + else if (base_name == "cerr") + { + this->output_ = & cerr; + this->close_out_ = false; + } + else + { + ACE_CString file_name = base_name; + file_name += ".new"; + + ofstream * fs = 0; + ACE_NEW_RETURN (fs, ofstream , false); + fs-> open (file_name.c_str()); + if (fs->is_open ()) + { + this->output_ = fs; + this->close_out_ = true; + } + else + { + delete fs; + ACE_ASSERT(this->output_ == 0); + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) XML_Saver unable to open %s\n"), + base_name.c_str())); + } + } + if (this->output_ != 0) + { + ostream& out = * this->output_; + + out << "<?xml version=\"1.0\"?>\n"; + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + bool changed = true; + NVPList attrs; + + ACE_Time_Value now = ACE_High_Res_Timer::gettimeofday(); + + ACE_UINT64 nowus = now.usec(); + static const ACE_UINT64 USECSPERSEC = 1000 * 1000; + ACE_UINT64 tmpus = now.sec(); + nowus += tmpus * USECSPERSEC; + + char nowusstr[128]; +#ifdef ACE_LACKS_LONGLONG_T + nowus.as_string(nowusstr); +#else + ACE_OS::sprintf(nowusstr, ACE_UINT64_FORMAT_SPECIFIER, nowus); +#endif /* ACE_LACKS_LONGLONG_T */ + + attrs.push_back(NVP("version", "1.0")); + if (this->timestamp_) + { + attrs.push_back(NVP("timestamp", nowusstr)); + } + this->begin_object(0, "notification_service", attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("(%P|%t) XML_Saver Unknown exception\n")); + delete this->output_; + this->output_ = 0; + } + ACE_ENDTRY; + } + return this->output_ != 0; + } + + bool XML_Saver::begin_object(CORBA::Long id, + const ACE_CString& type, + const NVPList& attrs, + bool /* changed */ + ACE_ENV_ARG_DECL_NOT_USED) + { + ACE_ASSERT(this->output_ != 0); + ostream& out = * this->output_; + + out << indent_ << "<" << type; + if (id != 0) + { + // not all ostreams know what to do with a CORBA::Long + long lid = id; + out << " " << TOPOLOGY_ID_NAME << "=\"" << lid << "\""; + } + + char * buffer = 0; + size_t buffer_size = 0; + for (size_t idx = 0; idx < attrs.size(); idx++) + { + out << " " + << attrs[idx].name.c_str () + << "=\"" + << escape_string(buffer, buffer_size, attrs[idx].value.c_str ()) + << "\""; + } + delete [] buffer; + out << ">\n"; + this->indent_ += " "; + return true; + } + + void XML_Saver::end_object (CORBA::Long id, + const ACE_CString& type ACE_ENV_ARG_DECL_NOT_USED) + { + ACE_ASSERT(this->output_ != 0); + ACE_UNUSED_ARG (id); + ostream& out = * this->output_; + if (this->indent_.length() >= 2) + { + this->indent_ = this->indent_.substr(2); + } + // Note : We avoid flushing after every object by using \n instead of << endl; + out << indent_ << "</" << type << ">\n"; + } + + static const char escaped_amp[] = "&"; + static const char escaped_less[] = "<"; + static const char escaped_greater[] = ">"; + static const char escaped_apos[] = "'"; + static const char escaped_quote[] = """; + + char * + XML_Saver::escape_string(char *& buffer, size_t & size, const ACE_CString & str) + { + size_t len = str.length (); + size_t needed = len * (sizeof(escaped_quote)-1) + 1; + if (needed > size) + { + delete [] buffer; + buffer = new char [needed]; + size = needed; + } + size_t pos = 0; // position in output buffer + for (size_t stridx = 0; stridx < len; stridx++) + { + char curchar = str[stridx]; + if (curchar == '&') + { + strcpy (&buffer[pos], escaped_amp); + pos += sizeof (escaped_amp) -1; + } + else if (curchar == '<') + { + strcpy (&buffer[pos], escaped_less); + pos += sizeof (escaped_less) -1; + } + else if (curchar == '>') + { + strcpy (&buffer[pos], escaped_greater); + pos += sizeof (escaped_greater) -1; + } + else if (curchar == '\'') + { + strcpy (&buffer[pos], escaped_apos); + pos += sizeof (escaped_apos) -1; + } + else if (curchar == '\"') + { + strcpy (&buffer[pos], escaped_quote); + pos += sizeof (escaped_quote) -1; + } + else + { + buffer[pos++] = curchar; + } + } + buffer[pos++] = '\0'; + return buffer; + } + +} /* namespace TAO_Notify */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.h b/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.h new file mode 100644 index 00000000000..e0ff886ebd7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file XML_Saver.h + * + * $Id$ + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef XML_SAVER_H +#define XML_SAVER_H +#include /**/ "ace/pre.h" + +#include "Topology_Saver.h" + +#include "tao/corba.h" +#include "ace/streams.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + +/** + * \brief Save Notification Service Topology to an XML file. + */ +class XML_Saver : public Topology_Saver +{ +public: + /// Construct an XML_Saver. + /// Initialization is deferred to "open()" + XML_Saver (bool timestamp = true); + + virtual ~XML_Saver (); + + /// Open the output file. + /// \param file_name the fully qualified file name + /// \return true if successful + bool open (const ACE_CString & file_name, size_t backup_count); + + ////////////////////////////////// + // Override Topology_Saver methods + // see Topology_Saver.h for doc + virtual bool begin_object (CORBA::Long id, + const ACE_CString& type, + const NVPList& attrs, + bool changed + ACE_ENV_ARG_DECL); + + virtual void end_object (CORBA::Long id, + const ACE_CString& type + ACE_ENV_ARG_DECL); + + virtual void close (ACE_ENV_SINGLE_ARG_DECL); + +private: + void backup_file_name (char * file_path, int nfile); + + /// \return newstr to allow in-line use + char* escape_string(char *& newstr, size_t & size, const ACE_CString & str); + +private: + /// A stream representing our current output. + ostream * output_; + bool close_out_; + + /// the name of the output file + ACE_CString base_name_; + size_t backup_count_; + + /// true to enable timestamping + bool timestamp_; + + /// A string consisting of spaces that is our current indentation level. + ACE_CString indent_; + +}; + +} // namespace TAO_Notify + +#include /**/ "ace/post.h" +#endif /* XML_SAVER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.cpp b/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.cpp new file mode 100644 index 00000000000..e654afc71f3 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.cpp @@ -0,0 +1,154 @@ +// $Id$ + +#include "XML_Topology_Factory.h" +#include "XML_Saver.h" +#include "XML_Loader.h" + +#include "tao/debug.h" +#include "ace/OS_NS_strings.h" +//#include "ace/Service_Object.h" + +namespace TAO_Notify +{ + + XML_Topology_Factory::XML_Topology_Factory() + : save_base_path_ ("./Notification_Service_Topology") + , load_base_path_ ("./Notification_Service_Topology") + , backup_count_ (2) + , timestamp_ (true) + { + } + + // virtual + Topology_Saver* + XML_Topology_Factory::create_saver () + { + XML_Saver *saver = 0; + + ACE_NEW_RETURN (saver, XML_Saver (this->timestamp_), 0); + + if (! saver->open ( this->save_base_path_.c_str (), this->backup_count_)) + { + delete saver; + saver = 0; + } + return ACE_static_cast (Topology_Saver *, saver); + } + + // virtual + Topology_Loader* + XML_Topology_Factory::create_loader() + { + XML_Loader *loader = 0; + ACE_NEW_NORETURN(loader, XML_Loader); + + if (! loader->open(this->load_base_path_)) + { + delete loader; + loader = 0; + } + return ACE_static_cast (Topology_Loader *, loader); + } + + // virtual + int + XML_Topology_Factory::init (int argc, ACE_TCHAR *argv[]) + { + int result = 0; + bool verbose = false; + for (int narg = 0; narg < argc; ++narg) + { + ACE_TCHAR * av = argv[narg]; + if (ACE_OS::strcasecmp (av, "-v") == 0) + { + verbose = true; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Standard_Event_Persistence: -verbose\n") + )); + } + else if (ACE_OS::strcasecmp (av, "-base_path") == 0 && narg + 1 < argc) + { + this->save_base_path_ = argv[narg + 1]; + this->load_base_path_ = argv[narg + 1]; + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -base_path: %s\n"), + this->save_base_path_.c_str () + )); + } + narg += 1; + } + else if (ACE_OS::strcasecmp (av, "-save_base_path") == 0 && narg + 1 < argc) + { + this->save_base_path_ = argv[narg + 1]; + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -save_base_path: %s\n"), + this->save_base_path_.c_str () + )); + } + narg += 1; + } + else if (ACE_OS::strcasecmp (av, "-load_base_path") == 0 && narg + 1 < argc) + { + this->load_base_path_ = argv[narg + 1]; + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -load_base_path: %s\n"), + this->load_base_path_.c_str () + )); + } + narg += 1; + } + else if (ACE_OS::strcasecmp (av, "-backup_count") == 0 && narg + 1 < argc) + { + this->backup_count_ = ACE_OS::atoi(argv[narg + 1]); + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -file_count: %d\n"), + this->backup_count_ + )); + } + narg += 1; + } + else if (ACE_OS::strcasecmp (av, "-no_timestamp") == 0) + { + this->timestamp_ = false; + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -no_timestamp\n") + )); + } + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Unknown parameter to XML Topology Factory: %s\n"), + argv[narg] + )); + result = -1; + } + } + return result; + } + + // virtual + int + XML_Topology_Factory::fini () + { + // nothing to do yet + return 0; + } + +ACE_FACTORY_DECLARE (TAO_Notify_Persist, XML_Topology_Factory) +ACE_FACTORY_DEFINE (TAO_Notify_Persist, XML_Topology_Factory) + + +} /* namespace TAO_Notify */ + + diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.h b/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.h new file mode 100644 index 00000000000..8623ca53a9c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.h @@ -0,0 +1,77 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file XML_Topology_Factory.h + * + * $Id$ + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef XML_TOPOLOGY_FACTORY_H +#define XML_TOPOLOGY_FACTORY_H +#include /**/ "ace/pre.h" + +#include "Topology_Factory.h" +#include "notify_persist_export.h" + +#include "tao/corba.h" +#include "ace/SString.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_Notify +{ + + /** + * \brief Create XML topology savers and loaders + * + * Loaded by a svc.conf line like: + * dynamic Topology_Factory Service_Object* TAO_CosNotificationd:_make_XML_Topology_Factory() "[arguments]" + * where arguments are: + * -base_path Base path (directory and filename) for both saving and loading. + * .xml will be appended to the base path + * Default is ./Notification_Service_Topology + * -save_base_path Base path for saving. + * -load_base_path Base path for loading. + * -file_count How many backup copies to keep. Default is 1 + * -no_timestamp Disable timestamping (makes files diffable) + * Note: you can set both saving and storing to the same file using -base_path + * Or you can set them independently using -save_base_path + * and -load_base_path + * + */ + class TAO_Notify_Persist_Export XML_Topology_Factory : public Topology_Factory + { + public: + /// The constructor. + XML_Topology_Factory (); + + //////////////////////////////////// + // Override Topology_Factory methods + // documented in Topology_Factory.h + virtual Topology_Saver* create_saver (); + virtual Topology_Loader* create_loader(); + + //////////////////////////////// + // Override Share_Object methods + // documented in ace/Shared_Object.h + virtual int init (int argc, ACE_TCHAR *argv[]); + virtual int fini (); + + private: + ACE_CString save_base_path_; + ACE_CString load_base_path_; + size_t backup_count_; + bool timestamp_; + }; + +} // namespace TAO_Notify + +#include /**/ "ace/post.h" +#endif /* XML_TOPOLOGY_FACTORY_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/notify_persist_export.h b/TAO/orbsvcs/orbsvcs/Notify/notify_persist_export.h new file mode 100644 index 00000000000..a1672e8c3ca --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/notify_persist_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl TAO_Notify_Persist +// ------------------------------ +#ifndef TAO_NOTIFY_PERSIST_EXPORT_H +#define TAO_NOTIFY_PERSIST_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (TAO_NOTIFY_PERSIST_HAS_DLL) +# define TAO_NOTIFY_PERSIST_HAS_DLL 1 +#endif /* ! TAO_NOTIFY_PERSIST_HAS_DLL */ + +#if defined (TAO_NOTIFY_PERSIST_HAS_DLL) && (TAO_NOTIFY_PERSIST_HAS_DLL == 1) +# if defined (TAO_NOTIFY_PERSIST_BUILD_DLL) +# define TAO_Notify_Persist_Export ACE_Proper_Export_Flag +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TAO_NOTIFY_PERSIST_BUILD_DLL */ +# define TAO_Notify_Persist_Export ACE_Proper_Import_Flag +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TAO_NOTIFY_PERSIST_BUILD_DLL */ +#else /* TAO_NOTIFY_PERSIST_HAS_DLL == 1 */ +# define TAO_Notify_Persist_Export +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARATION(T) +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TAO_NOTIFY_PERSIST_HAS_DLL == 1 */ + +// Set TAO_NOTIFY_PERSIST_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (TAO_NOTIFY_PERSIST_NTRACE) +# if (ACE_NTRACE == 1) +# define TAO_NOTIFY_PERSIST_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define TAO_NOTIFY_PERSIST_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !TAO_NOTIFY_PERSIST_NTRACE */ + +#if (TAO_NOTIFY_PERSIST_NTRACE == 1) +# define TAO_NOTIFY_PERSIST_TRACE(X) +#else /* (TAO_NOTIFY_PERSIST_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define TAO_NOTIFY_PERSIST_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (TAO_NOTIFY_PERSIST_NTRACE == 1) */ + +#endif /* TAO_NOTIFY_PERSIST_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/orbsvcs/orbsvcs/NotifyExt.idl b/TAO/orbsvcs/orbsvcs/NotifyExt.idl index 7c94e9bcb26..5e0d9ca9b69 100644 --- a/TAO/orbsvcs/orbsvcs/NotifyExt.idl +++ b/TAO/orbsvcs/orbsvcs/NotifyExt.idl @@ -83,12 +83,55 @@ module NotifyExt unsigned long max_request_buffer_size; }; - /* - * Extend the EventChannelFactory to have a shutdown method. + /** + * \brief An interface which gets registered with a ReconnectionRegistry. + * + * A supplier or consumer must implement this interface in order to + * allow the Notification Service to attempt to reconnect to it after + * a failure. The supplier or consumer must register its instance of + * this interface with the ReconnectionRegistry. + */ + interface ReconnectionCallback + { + /// Perform operations to reconnect to the Notification Service + /// after a failure. + void reconnect (in Object new_connection); + + /// Check to see if the ReconnectionCallba ck is alive + boolean is_alive (); + }; + + /** + * \brief An interface that handles registration of suppliers and consumers. + * + * This registry should be implemented by an EventChannelFactory and + * will call the appropriate reconnect methods for all ReconnectionCallback + * objects registered with it. + */ + interface ReconnectionRegistry + { + typedef long ReconnectionID; + ReconnectionID register_callback(in ReconnectionCallback reconection); + + void unregister_callback (in ReconnectionID id); + + /// Check to see if the ReconnectionRegistry is alive + boolean is_alive (); + }; + + /** + * Extend the EventChannelFactory to have a shutdown method + * and a Reconnection Registry */ - interface EventChannelFactory : CosNotifyChannelAdmin::EventChannelFactory + interface EventChannelFactory + : CosNotifyChannelAdmin::EventChannelFactory + , ReconnectionRegistry { void destroy (); + /// save topology: for diagnostic and testing purposes + /// Normal topology save is automatic when connectivity persistence + /// is configured. + void save_topology(); }; interface ConsumerAdmin : CosNotifyChannelAdmin::ConsumerAdmin diff --git a/TAO/orbsvcs/tests/Notify/Basic/MultiTypes.cpp b/TAO/orbsvcs/tests/Notify/Basic/MultiTypes.cpp index ec0758fbe6a..275567eab72 100644 --- a/TAO/orbsvcs/tests/Notify/Basic/MultiTypes.cpp +++ b/TAO/orbsvcs/tests/Notify/Basic/MultiTypes.cpp @@ -52,6 +52,8 @@ MultiTypes_SequencePushConsumer::MultiTypes_SequencePushConsumer (MultiTypes* cl { } +// TODO: if the batch contains more than one event this counts only one received event +// Since this should *never* happen, I'm not fixing it now. void MultiTypes_SequencePushConsumer::push_structured_events (const CosNotification::EventBatch & /*notifications*/ ACE_ENV_ARG_DECL_NOT_USED @@ -359,7 +361,8 @@ MultiTypes::wait_for_all_consumers (int expected_count_per_consumer) break; { - if (this->orb_->work_pending ()) + ACE_Time_Value tv (0,1000); + if (this->orb_->work_pending (tv)) this->orb_->perform_work (); } } diff --git a/TAO/orbsvcs/tests/Notify/PluggableTopology/PlugTop.mpc b/TAO/orbsvcs/tests/Notify/PluggableTopology/PlugTop.mpc new file mode 100644 index 00000000000..2b0f1467d3f --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/PluggableTopology/PlugTop.mpc @@ -0,0 +1,19 @@ +project(*lib): orbsvcslib, notify_serv { + requires += exceptions + sharedname = NotifyPlugTop + dynamicflags = PLUGTOP_BUILD_DLL + source_files { + Test_Saver.cpp + Test_Topology_Factory.cpp + } +} + +project : orbsvcsexe, notify_serv { + requires += exceptions + after += *lib + source_files { + main.cpp + } + header_files { + } +} diff --git a/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Saver.cpp b/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Saver.cpp new file mode 100644 index 00000000000..9ecf357818f --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Saver.cpp @@ -0,0 +1,37 @@ +// $Id$ + +#include "Test_Saver.h" + +#include <ace/streams.h> + +Test_Saver::Test_Saver() +{ +} + +bool +Test_Saver::begin_object(CORBA::Long id, + const ACE_CString &type, + const TAO_Notify::NVPList& attrs, + bool changed + ACE_ENV_ARG_DECL_NOT_USED) +{ + cout << "Test_Saver::begin_object type=\"" << type << "\" " + << " id=" << id + << " changed=\"" << changed << "\""; + for (size_t idx = 0; idx < attrs.size(); idx++) + { + cout << " " << attrs[idx].name << "=\"" << attrs[idx].value << "\""; + } + cout << endl; + return true; +} + +void +Test_Saver::end_object (CORBA::Long id, + const ACE_CString &type ACE_ENV_ARG_DECL_NOT_USED) +{ + cout << "Test_Saver::end_object type=\"" << type << "\"" + << " id=" << id + << endl; +} + diff --git a/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Saver.h b/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Saver.h new file mode 100644 index 00000000000..287832cf336 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Saver.h @@ -0,0 +1,39 @@ +/* -*- C++ -*- */ +/** + * $Id$ + */ + +#ifndef TEST_SAVER_H +#define TEST_SAVER_H +#include /**/ "ace/pre.h" + +#include "plugtop_export.h" + +#include "orbsvcs/Notify/Topology_Saver.h" + +#include "tao/corba.h" +#include "ace/streams.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class PLUGTOP_Export Test_Saver : public TAO_Notify::Topology_Saver +{ +public: + Test_Saver(); + + virtual bool begin_object (CORBA::Long id, + const ACE_CString &type, + const TAO_Notify::NVPList& attrs, + bool changed + ACE_ENV_ARG_DECL); + + virtual void end_object (CORBA::Long id, + const ACE_CString &type + ACE_ENV_ARG_DECL); +}; + + +#include /**/ "ace/post.h" +#endif /* TEST_SAVER_H */ diff --git a/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.cpp b/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.cpp new file mode 100644 index 00000000000..4363e41b899 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.cpp @@ -0,0 +1,26 @@ +// $Id$ + +#include "Test_Topology_Factory.h" +#include "Test_Saver.h" + +Test_Topology_Factory::Test_Topology_Factory() +{ +} + +TAO_Notify::Topology_Saver* +Test_Topology_Factory::create_saver () +{ + TAO_Notify::Topology_Saver *saver = 0; + ACE_NEW_RETURN (saver, Test_Saver, 0); + return saver; +} + +//virtual +TAO_Notify::Topology_Loader* +Test_Topology_Factory::create_loader () +{ + return 0; +} + + +ACE_FACTORY_DEFINE (PLUGTOP, Test_Topology_Factory) diff --git a/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.h b/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.h new file mode 100644 index 00000000000..e8ac5a5b9dc --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/PluggableTopology/Test_Topology_Factory.h @@ -0,0 +1,31 @@ +/* -*- C++ -*- */ +//$Id$ + +#ifndef TEST_TOPOLOGY_FACTORY_H +#define TEST_TOPOLOGY_FACTORY_H +#include /**/ "ace/pre.h" + +#include "plugtop_export.h" + +#include "orbsvcs/Notify/Topology_Factory.h" + +#include "tao/corba.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class PLUGTOP_Export Test_Topology_Factory : public TAO_Notify::Topology_Factory +{ +public: + Test_Topology_Factory (); + ///////////////////////////////////////////////// + // override virtual methods from Topology_Factory + virtual TAO_Notify::Topology_Saver* create_saver (); + virtual TAO_Notify::Topology_Loader* create_loader (); +}; + +ACE_FACTORY_DECLARE (PLUGTOP, Test_Topology_Factory) + +#include /**/ "ace/post.h" +#endif /* TEST_TOPOLOGY_FACTORY_H */ diff --git a/TAO/orbsvcs/tests/Notify/PluggableTopology/main.cpp b/TAO/orbsvcs/tests/Notify/PluggableTopology/main.cpp new file mode 100644 index 00000000000..786728187fa --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/PluggableTopology/main.cpp @@ -0,0 +1,109 @@ +/** + * $Id$ + */ + +#include <orbsvcs/CosNotifyChannelAdminC.h> +//#include <orbsvcs/CosNotifyCommS.h> +//#include <orbsvcs/CosNotificationS.h> +#include <tao/TimeBaseC.h> + +#include <ace/ARGV.h> +#include <ace/OS_NS_stdio.h> + +using namespace CORBA; +namespace CNCA = CosNotifyChannelAdmin; +namespace CN = CosNotification; +namespace CNC = CosNotifyComm; + +const char* NOTIFY_IOR = "corbaloc::localhost:9050/NotifyEventChannelFactory"; + +ORB_var orb; +CNCA::EventChannelFactory_var ecf; + +namespace { + void init_qos_props(CN::QoSProperties& qos, bool topology_persist) { + qos.length(13); + ULong i = 0; + qos[i].name = "EventReliability"; + qos[i++].value <<= CN::BestEffort; + if (topology_persist) { + qos[i].name = "ConnectionReliability"; + qos[i++].value <<= CN::Persistent; + } + else + { + qos[i].name = "ConnectionReliability"; + qos[i++].value <<= CN::BestEffort; + } + qos[i].name = "Priority"; + qos[i++].value <<= (Short) 1234; + qos[i].name = "Timeout"; + qos[i++].value <<= (TimeBase::TimeT) 55555; + qos[i].name = "MaximumBatchSize"; + qos[i++].value <<= (Long) 200; + qos[i].name = "PacingInterval"; + qos[i++].value <<= (TimeBase::TimeT) 42000; + qos[i].name = "StopTimeSupported"; + qos[i++].value <<= Any::from_boolean(0); + qos.length(i); + } + void init_admin_props(CN::AdminProperties& admin) { + admin.length(13); + ULong i = 0; + admin[i].name = "MaxQueueLength"; + admin[i++].value <<= (Long) 200; + admin[i].name = "MaxConsumers"; + admin[i++].value <<= (Long) 2; + admin[i].name = "MaxSuppliers"; + admin[i++].value <<= (Long) 1; + admin[i].name = "RejectNewEvents"; + admin[i++].value <<= Any::from_boolean(1); + } + void setUp() + { + ACE_ARGV av; + int ac = 0; + orb = ORB_init(ac, av.argv()); + ACE_ASSERT(! is_nil(orb.in())); + Object_var obj = orb->string_to_object(NOTIFY_IOR); + ACE_ASSERT(! is_nil(obj.in())); + ecf = CNCA::EventChannelFactory::_narrow(obj.in()); + ACE_ASSERT(! is_nil(ecf.in())); + } + + void tearDown() + { + ecf = CNCA::EventChannelFactory::_nil(); + orb->destroy(); + orb = ORB::_nil(); + } +} + + +int main(int, char**) +{ + try + { + setUp(); + + CN::QoSProperties qos; + CN::AdminProperties admin; + init_qos_props(qos, true); + init_admin_props(admin); + + CNCA::ChannelID ecid; + CNCA::EventChannel_var ec = ecf->create_channel(qos, admin, ecid); + + printf("Created channel id=\"%ld\"\n", static_cast<long>(ecid)); + + tearDown(); + + return 0; + } + catch (Exception& e) + { + ACE_OS::fputs(e._name (), stderr); + ACE_OS::fputs("\n", stderr); + } + return 1; +} diff --git a/TAO/orbsvcs/tests/Notify/PluggableTopology/plugtop_export.h b/TAO/orbsvcs/tests/Notify/PluggableTopology/plugtop_export.h new file mode 100644 index 00000000000..fe7fbfbee28 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/PluggableTopology/plugtop_export.h @@ -0,0 +1,40 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl +// ------------------------------ +#ifndef PLUGTOP_EXPORT_H +#define PLUGTOP_EXPORT_H + +#include "ace/config-all.h" + +#if defined (TAO_AS_STATIC_LIBS) +# if !defined (PLUGTOP_HAS_DLL) +# define PLUGTOP_HAS_DLL 0 +# endif /* ! PLUGTOP_HAS_DLL */ +#else +# if !defined (PLUGTOP_HAS_DLL) +# define PLUGTOP_HAS_DLL 1 +# endif /* ! PLUGTOP_HAS_DLL */ +#endif + +#if defined (PLUGTOP_HAS_DLL) && (PLUGTOP_HAS_DLL == 1) +# if defined (PLUGTOP_BUILD_DLL) +# define PLUGTOP_Export ACE_Proper_Export_Flag +# define PLUGTOP_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define PLUGTOP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* PLUGTOP_BUILD_DLL */ +# define PLUGTOP_Export ACE_Proper_Import_Flag +# define PLUGTOP_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define PLUGTOP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* PLUGTOP_BUILD_DLL */ +#else /* PLUGTOP_HAS_DLL == 1 */ +# define PLUGTOP_Export +# define PLUGTOP_SINGLETON_DECLARATION(T) +# define PLUGTOP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* PLUGTOP_HAS_DLL == 1 */ + +#endif /* PLUGTOP_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/orbsvcs/tests/Notify/PluggableTopology/plugtop_ns.conf b/TAO/orbsvcs/tests/Notify/PluggableTopology/plugtop_ns.conf new file mode 100644 index 00000000000..63b5faf531b --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/PluggableTopology/plugtop_ns.conf @@ -0,0 +1,3 @@ + +dynamic TopologyFactory Service_Object * NotifyPlugTop:_make_Test_Topology_Factory() "" +#dynamic TopologyFactory Service_Object * TAO_CosNotification:_make_XML_Topology_Factory() ""
\ No newline at end of file diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/Consumer.cpp b/TAO/orbsvcs/tests/Notify/Reconnecting/Consumer.cpp new file mode 100644 index 00000000000..3ac4643c225 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/Consumer.cpp @@ -0,0 +1,1919 @@ +//$Id$ + +#include "Consumer.h" +#include "tao/debug.h" +#include "tao/PortableServer/PortableServerC.h" +#include <tao/TimeBaseC.h> +#include <ace/OS_NS_strings.h> +#include <ace/OS_NS_stdio.h> +#include <tao/Any.h> + +ACE_RCSID (Notify_Tests, Consumer_Main, "$Id$") + +static const char NOTIFY_FACTORY_NAME[] = "NotifyEventChannelFactory"; +static const char NAMING_SERVICE_NAME[] = "NameService"; + +static const size_t minus_one = ACE_static_cast (size_t, -1); + +/////////////////////////// +// StructuredPushConsumer_i + +StructuredPushConsumer_i::StructuredPushConsumer_i () + : verbose_ (false) + , received_ (0) + , expect_ (10) + , fail_ (0) + , may_discard_ (0) + , serial_number_ (0) + , exceptions_thrown_ (0) + , problem_ (false) + , connected_ (false) +{ +} + +size_t +StructuredPushConsumer_i::received () const +{ + return this->received_; +} + +bool +StructuredPushConsumer_i::has_problem () const +{ + return this->problem_; +} + +void +StructuredPushConsumer_i::set_connected (bool flag) +{ + this->connected_ = flag; +} + +bool +StructuredPushConsumer_i::is_connected () const +{ + return this->connected_; +} + +void +StructuredPushConsumer_i::set_expectations (size_t expected, size_t fail, size_t serial_number, bool verbose) +{ + this->expect_ = expected; + this->fail_ = fail; + this->serial_number_ = serial_number; + this->verbose_ = verbose; +} + +void +StructuredPushConsumer_i::offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) StructuredPushConsumer offered change \n") + )); +} + +void +StructuredPushConsumer_i::check_serial_number (CORBA::ULong seq) +{ + if (this->serial_number_ == minus_one) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Structured Consumer received event %d.\n"), + ACE_static_cast (int, seq) + )); + } + } + else + { + if (seq == this->serial_number_) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Structured Consumer received correct event %d.\n"), + ACE_static_cast (int, seq) + )); + } + } + else if ((seq - this->serial_number_) <= this->may_discard_) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Structured Consumer: service received event %d; Notify discarded %d*.\n"), + ACE_static_cast (int, seq), + ACE_static_cast (int, this->serial_number_) + )); + } + this->received_ += seq - this->serial_number_; + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Structured Consumer received notifications out of sequence. Expecting %d received %d.\n"), + ACE_static_cast (int, this->serial_number_), + ACE_static_cast (int, seq) + )); + } + this->serial_number_ = seq + 1; + } + may_discard_ = 0; +} + + +void +StructuredPushConsumer_i::push_structured_event ( + const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)) +{ + this->received_ += 1; + if (this->received_ == this->expect_ + 1) + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Structured Consumer received more than the %d events that were expected.\n"), + this->expect_ + )); + } + if (this->fail_ != 0 && ((this->received_ + this->exceptions_thrown_) % this->fail_) == 0) + { + this->received_ -= 1; + this->exceptions_thrown_ += 1; + this->may_discard_ = 1; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Structured Consumer failing at event # %d.\n"), + ACE_static_cast (int, this->received_) + )); + ACE_THROW (CORBA::UNKNOWN()); + ACE_CHECK; + } + if (notification.filterable_data.length () > 0) + { + if (0 == ACE_OS::strcmp (notification.filterable_data[0].name, "serial_number")) + { + const CORBA::Any & data = notification.filterable_data[0].value; + + CORBA::ULong seq = 0; + if (data >>= seq) + { + check_serial_number (seq); + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Structured Consumer received unexpected data type for serial_number.\n") + )); + } + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Structured Consumer received wrong filterable data name.%s. Expecting serial_number\n"), + ACE_static_cast (const char *, notification.filterable_data[0].name) + )); + } + } + else if (0 == ACE_OS::strcmp (notification.header.fixed_header.event_type.type_name, "%ANY") + && 0 == strcmp (notification.header.fixed_header.event_type.domain_name, "")) + { + const CORBA::Any * any; + if (notification.remainder_of_body >>= any) + { + // this is a wrapped "Any" + CORBA::ULong seq = 0; + if ((*any) >>= seq) + { + check_serial_number (seq); + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Structured Consumer received Any with unknown data type\n") + )); + } + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Structured Consumer received remainder_of_body with unknown data type\n") + )); + } + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Structured Consumer: no filterable data. \n") + )); + } + this->may_discard_ = 0; +} + +void +StructuredPushConsumer_i::disconnect_structured_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) StructuredPushConsumer received disconnect\n") + )); +} + +/////////////////////////// +// SequencePushConsumer_i + +SequencePushConsumer_i::SequencePushConsumer_i () + : verbose_ (false) + , received_ (0) + , expect_ (10) + , fail_ (0) + , may_discard_ (0) + , serial_number_ (0) + , exceptions_thrown_ (0) + , problem_ (false) + , connected_ (false) +{ +} + +size_t +SequencePushConsumer_i::received () const +{ + return this->received_; +} + +bool +SequencePushConsumer_i::has_problem () const +{ + return this->problem_; +} + +void +SequencePushConsumer_i::set_connected (bool flag) +{ + this->connected_ = flag; +} + +bool +SequencePushConsumer_i::is_connected () const +{ + return this->connected_; +} + +void +SequencePushConsumer_i::set_expectations (size_t expected, size_t fail,size_t serial_number, bool verbose) +{ + this->expect_ = expected; + this->fail_ = fail; + this->serial_number_ = serial_number; + this->verbose_ = verbose; +} + +void +SequencePushConsumer_i::offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) SequencePushConsumer offered subscription change\n") + )); +} + +void +SequencePushConsumer_i::check_serial_number (CORBA::ULong seq) +{ + if (this->serial_number_ == minus_one) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Sequence Consumer received event %d.\n"), + ACE_static_cast (int, seq) + )); + } + } + else + { + if (seq == this->serial_number_) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Sequence Consumer received correct event %d.\n"), + ACE_static_cast (int, seq) + )); + } + } + else if ((seq - this->serial_number_) <= this->may_discard_) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Sequence Consumer: service received event %d; Notify discarded %d*.\n"), + ACE_static_cast (int, seq), + ACE_static_cast (int, this->serial_number_) + )); + } + this->received_ += seq - this->serial_number_; + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Sequence Consumer received notifications out of sequence. Expecting %d received %d.\n"), + ACE_static_cast (int, this->serial_number_), + ACE_static_cast (int, seq) + )); + } + this->serial_number_ = seq + 1; + } + may_discard_ = 0; +} + +void +SequencePushConsumer_i::push_structured_events ( + const CosNotification::EventBatch & notifications + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)) +{ + size_t batch_size = notifications.length(); + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Sequence Consumer received batch of %d events.\n"), + ACE_static_cast (int, batch_size) + )); + } + for (size_t nevent = 0; nevent < batch_size; ++nevent) + { + this->received_ += 1; + if (this->received_ == this->expect_ + 1) + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Sequence Consumer received more than the %d events that were expected.\n"), + this->expect_ + )); + } + if (this->fail_ != 0 && ((this->received_ + this->exceptions_thrown_) % this->fail_) == 0) + { + this->received_ -= 1; + this->exceptions_thrown_ += 1; + this->may_discard_ = batch_size; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Sequence Consumer failing at event # %d. Expecting %d duplicates.\n"), + ACE_static_cast (int, this->received_), + ACE_static_cast (int, nevent + 1) + )); + ACE_THROW (CORBA::UNKNOWN()); + ACE_CHECK; + } + const CosNotification::StructuredEvent & notification = notifications[nevent]; + if (notification.filterable_data.length () > 0) + { + if (0 == ACE_OS::strcmp (notification.filterable_data[0].name, "serial_number")) + { + const CORBA::Any & data = notification.filterable_data[0].value; + + CORBA::ULong seq = 0; + if (data >>= seq) + { + check_serial_number (seq); + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Sequence Consumer received unexpected data type for serial_number.\n") + )); + } + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Sequence Consumer received wrong filterable data name.%s. Expecting serial_number\n"), + ACE_static_cast (const char *, notification.filterable_data[0].name) + )); + } + } + else if (0 == ACE_OS::strcmp (notification.header.fixed_header.event_type.type_name, "%ANY") + && 0 == strcmp (notification.header.fixed_header.event_type.domain_name, "")) + { + CORBA::ULong seq = 0; + if (notification.remainder_of_body >>= seq) + { + check_serial_number (seq); + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Sequence Consumer received Any with unknown data type\n") + )); + } + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Sequence Consumer received no filterable data\n") + )); + } + } +} + +void +SequencePushConsumer_i::disconnect_sequence_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) SequencePushConsumer received disconnect\n") + )); +} + +/////////////////////////// +// AnyPushConsumer_i + +AnyPushConsumer_i::AnyPushConsumer_i () + : verbose_ (false) + , received_ (0) + , expect_ (10) + , fail_ (0) + , may_discard_ (0) + , serial_number_ (0) + , exceptions_thrown_ (0) + , problem_ (false) + , connected_ (false) +{ +} + +size_t +AnyPushConsumer_i::received () const +{ + return this->received_; +} + +bool +AnyPushConsumer_i::has_problem () const +{ + return this->problem_; +} + +void +AnyPushConsumer_i::set_connected (bool flag) +{ + this->connected_ = flag; +} + +bool +AnyPushConsumer_i::is_connected () const +{ + return this->connected_; +} + +void +AnyPushConsumer_i::set_expectations (size_t expected, size_t fail, size_t serial_number, bool verbose) +{ + this->expect_ = expected; + this->fail_ = fail; + this->serial_number_ = serial_number; + this->verbose_ = verbose; +} + +void +AnyPushConsumer_i::offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) SequencePushConsumer offered subscription change\n") + )); +} + +void +AnyPushConsumer_i::check_serial_number (CORBA::ULong seq) +{ + if (this->serial_number_ == minus_one) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Any Consumer received event %d.\n"), + ACE_static_cast (int, seq) + )); + } + } + else + { + if (seq == this->serial_number_) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Any Consumer received correct event %d.\n"), + ACE_static_cast (int, seq) + )); + } + } + else if ((seq - this->serial_number_) <= this->may_discard_) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Any Consumer: service received event %d; Notify discarded %d*.\n"), + ACE_static_cast (int, seq), + ACE_static_cast (int, this->serial_number_) + )); + } + this->received_ += seq - this->serial_number_; + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Any Consumer received notifications out of sequence. Expecting %d received %d.\n"), + ACE_static_cast (int, this->serial_number_), + ACE_static_cast (int, seq) + )); + } + this->serial_number_ = seq + 1; + } + may_discard_ = 0; +} + +void +AnyPushConsumer_i::push ( + const CORBA::Any & data + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)) +{ + this->received_ += 1; + if (this->received_ == this->expect_ + 1) + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Any Consumer received more than the %d events that were expected.\n"), + this->expect_ + )); + } + if (this->fail_ != 0 && ((this->received_ + this->exceptions_thrown_) % this->fail_) == 0) + { + this->received_ -= 1; + this->exceptions_thrown_ += 1; + this->may_discard_ = 1; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Any Consumer failing at event # %d.\n"), + ACE_static_cast (int, this->received_) + )); + ACE_THROW (CORBA::UNKNOWN()); + ACE_CHECK; + } + CORBA::ULong seq = 0; + if (data >>= seq) + { + check_serial_number (seq); + } + else + { + const CosNotification::StructuredEvent * notification; + if (data >>= notification) + { + if (notification->filterable_data.length () > 0) + { + if (0 == ACE_OS::strcmp (notification->filterable_data[0].name, "serial_number")) + { + const CORBA::Any & data = notification->filterable_data[0].value; + + CORBA::ULong seq = 0; + if (data >>= seq) + { + check_serial_number (seq); + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Any Consumer received structured notification with unexpected data type for serial_number in structured event.\n") + )); + } + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Any Consumer received wrong filterable data name in structured event: %s. Expecting serial_number\n"), + ACE_static_cast (const char *, notification->filterable_data[0].name) + )); + } + } + else + { + this->problem_ = true; + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Any Consumer: no filterable data in structured event. \n") + )); + } + } + else + { + this->problem_ = true; + + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Any Consumer received unexpected data type.\n") + )); + } + } +} + +void +AnyPushConsumer_i::disconnect_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) AnyPushConsumer received disconnect\n") + )); +} + +///////////////////////// +// ReconnectionCallback_i + +ReconnectionCallback_i::ReconnectionCallback_i (Consumer_Main & consumer_main) + : consumer_main_ (consumer_main) + , id_is_valid_ (false) + , reconnect_count_ (0) +{ +} + +size_t +ReconnectionCallback_i::reconnect_count () const +{ + return this->reconnect_count_; +} + +void +ReconnectionCallback_i::reconnect ( + CORBA::Object_ptr reconnection + ACE_ENV_ARG_DECL + ) ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer received reconnection request\n") + )); + this->ecf_ = CosNotifyChannelAdmin::EventChannelFactory::_narrow (reconnection ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + if (!CORBA::is_nil (this->ecf_.in ())) + { + this->consumer_main_.reconnect (this->ecf_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->reconnect_count_ += 1; + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer reconnection request failed: wrong object type\n") + )); + } +} + +CORBA::Boolean +ReconnectionCallback_i::is_alive (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::Boolean (1); +} + + +ReconnectionCallback_i::~ReconnectionCallback_i () +{ + // normally you would disconnect from registry here, but + // to simulate a failure, we exit without cleaning up + // if the fini method is not called. +} + + +void +ReconnectionCallback_i::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->id_is_valid_) + { + NotifyExt::ReconnectionRegistry_var registry = + NotifyExt::ReconnectionRegistry::_narrow (this->ecf_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + registry->unregister_callback (this->callback_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->id_is_valid_ = false; + } +} + +void +ReconnectionCallback_i::init ( + PortableServer::POA_ptr poa, + CosNotifyChannelAdmin::EventChannelFactory_ptr ecf + ACE_ENV_ARG_DECL) +{ + this->ecf_ = CosNotifyChannelAdmin::EventChannelFactory::_duplicate (ecf); + PortableServer::ObjectId_var reconnection_callback_id = + poa->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var obj = + poa->id_to_reference (reconnection_callback_id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + NotifyExt::ReconnectionCallback_var callback = + NotifyExt::ReconnectionCallback::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + NotifyExt::ReconnectionRegistry_var registry = + NotifyExt::ReconnectionRegistry::_narrow (ecf ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->callback_id_ = registry->register_callback (callback.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->id_is_valid_ = true; +} + +///////////////// +// Consumer_Main + +Consumer_Main::Consumer_Main () + : verbose_ (false) + , mode_ (MODE_ANY) + , expect_ (10) + , fail_ (0) + , use_naming_service_ (true) + , serial_number_ (0) + , disconnect_on_exit_ (false) + , structured_count_(0) + , sequence_count_(0) + , any_count_(0) + , id_file_ ("consumer.ids") + , ec_id_ (0) + , sa_id_ (0) + , structured_proxy_id_ (0) + , sequence_proxy_id_ (0) + , any_proxy_id_ (0) + , reconnection_callback_ (*this) + , reconnecting_ (false) +{ +} + +Consumer_Main::~Consumer_Main () +{ +} + +int +Consumer_Main::parse_args (int argc, char *argv[]) +{ + int result = 0; + int narg = 1; + bool corba_arg = false; + while (narg < argc && result == 0) + { + int consumed = parse_single_arg (argc - narg, &argv[narg]); + if ( consumed > 0) + { + narg += consumed; + corba_arg = false; + } + else if (ACE_OS::strncmp (argv[narg], "-ORB", 4) == 0) + { + corba_arg = true; + } + else if (corba_arg) + { + // previous argument was a ORB arg. + // current argument is unrecognized + // assume the ORB eats this arg + narg += 1; + corba_arg = false; + } + else + { + ACE_OS::fprintf (stderr, ACE_TEXT ("Unrecognized argument: %s\n"), + argv[narg]); + usage (stderr); + result = -1; + } + } + return result; +} + +int +Consumer_Main::parse_single_arg (int argc, char *argv[]) +{ + int consumed = 0; + if (ACE_OS::strcasecmp (argv[0], "-any") == 0) + { + this->mode_ = MODE_ANY; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], "-structured") == 0) + { + this->mode_ = MODE_STRUCTURED; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], "-sequence") == 0) + { + this->mode_ = MODE_SEQUENCE; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], "-v") == 0) + { + this->verbose_ = true; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], "-channel") == 0) + { + this->channel_file_= argv[1]; + consumed = 2; + } + else if (ACE_OS::strcasecmp (argv[0], "-expect") == 0 && argc > 1) + { + this->expect_ = ACE_OS::atoi (argv[1]); + consumed = 2; + } + else if (ACE_OS::strcasecmp (argv[0], "-fail") == 0 && argc > 1) + { + this->fail_ = ACE_OS::atoi (argv[1]); + consumed = 2; + } + else if (ACE_OS::strcasecmp (argv[0], "-serial_number") == 0) + { + this->serial_number_= ACE_OS::atoi (argv[1]); + consumed = 2; + } + else if (ACE_OS::strcasecmp (argv[0], "-nonamesvc") == 0) + { + this->use_naming_service_ = false; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], "-disconnect") == 0) + { + this->disconnect_on_exit_ = true; + consumed = 1; + } + return consumed; +} + +void Consumer_Main::usage(FILE * out)const +{ + ACE_OS::fputs ( + ACE_TEXT ("usage\n") + ACE_TEXT (" -channel filename Where to find a channel number.\n") + ACE_TEXT (" -any or -structured or -sequence\n") + ACE_TEXT (" What type of event to send (pick one, default is -any)\n") + ACE_TEXT (" -expect n How many events of each type are expected.\n") + ACE_TEXT (" -fail n Throw an exception every n events.\n") + ACE_TEXT (" -serial_number n What serial number to start with \n") + ACE_TEXT (" or -1 to disable serial number checking.\n") + ACE_TEXT (" -v Verbose output.\n") + ACE_TEXT (" -disconnect Disconnect from channel on exit (prevents reconnect.) \n") + ACE_TEXT (" -nonamesvc Don't use the name service to find EventChannelFactory\n") + , out); +} + +int Consumer_Main::init (int argc, char *argv[] ACE_ENV_ARG_DECL) +{ + this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (0 != this->parse_args(argc, argv)) + { + return -1; + } + + CORBA::Object_ptr poa_object = + this->orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object)) + { + ACE_ERROR ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n")); + return -1; + } + + this->root_poa_ = + PortableServer::POA::_narrow (poa_object ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + PortableServer::POAManager_var poa_manager = + root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (this->use_naming_service_ ) + { + this->find_notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + else + { + int ok = resolve_notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (!ok) + { + return -1; + } + } + + this->reconnecting_ = load_ids (); + + init_event_channel (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + init_consumer_admin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + switch (this->mode_) + { + case MODE_STRUCTURED: + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Consumer: Listening for %d structured events. Failing every %d events.\n"), + ACE_static_cast (int, this->expect_), + ACE_static_cast (int, this->fail_) + )); + } + this->structured_push_consumer_.set_expectations (this->expect_, this->fail_, this->serial_number_, this->verbose_); + init_structured_proxy_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + break; + } + case MODE_SEQUENCE: + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Consumer: Listening for %d sequence events. Failing every %d events.\n"), + ACE_static_cast (int, this->expect_), + ACE_static_cast (int, this->fail_) + )); + } + this->sequence_push_consumer_.set_expectations (this->expect_, this->fail_, this->serial_number_, this->verbose_); + init_sequence_proxy_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + break; + } + case MODE_ANY: + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Consumer: Listening for %d CORBA::Any events. Failing every %d events.\n"), + ACE_static_cast (int, this->expect_), + ACE_static_cast (int, this->fail_) + )); + } + this->any_push_consumer_.set_expectations (this->expect_, this->fail_, this->serial_number_, this->verbose_); + init_any_proxy_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + break; + } + default: + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Consumer: Unknown listening mode.\n") + )); + break; + } + } + + this->reconnection_callback_.init ( + this->root_poa_.in (), + this->ecf_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + save_ids (); + return 0; +} +void +Consumer_Main::save_ids() +{ + FILE *idf = + ACE_OS::fopen (this->id_file_.c_str (), "w"); + + if (idf != 0) + { + int endflag = 12345; + int imode = ACE_static_cast (int, this->mode_); + ACE_OS::fprintf (idf, + "%d,%d,%d,%d,%d,%d,%d,\n", + static_cast<int> (imode), + static_cast<int> (ec_id_), + static_cast<int> (sa_id_), + static_cast<int> (structured_proxy_id_), + static_cast<int> (sequence_proxy_id_), + static_cast<int> (any_proxy_id_), + static_cast<int> (endflag) ); + ACE_OS::fclose (idf); + } +} + +bool +Consumer_Main::load_ids() +{ + bool ok = false; + FILE *idf = + ACE_OS::fopen (this->id_file_.c_str (), "r"); + + if (idf != 0) + { + int field = 0; + + char buffer[100] = ""; // because ACE fgets doesn't put a null if the file is empty + ACE_OS::fgets (buffer, sizeof(buffer), idf); + ACE_OS::fclose (idf); + char * pb = buffer; + while (!ok && *pb != 0) + { + char * eb = ACE_OS::strchr (pb, ','); + char * nb = eb + 1; + if (eb == 0) + { + eb = pb + ACE_OS::strlen (pb); + nb = eb; + } + *eb = 0; + if (pb < eb) + { + int value = ACE_OS::atoi(pb); + switch (++field) + { + case 1: + this->mode_ = static_cast<Mode_T> (value); + break; + case 2: + this->ec_id_ = value; + break; + case 3: + this->sa_id_ = value; + break; + case 4: + this->structured_proxy_id_ = value; + break; + case 5: + this->sequence_proxy_id_ = value; + break; + case 6: + this->any_proxy_id_ = value; + break; + case 7: + ok = value == 12345; + break; + default: + ACE_OS::fprintf (stderr, ACE_TEXT ("Consumer: Warning: too many fields in saved id file.\n")); + ok = false; + break; + } + } + pb = nb; + } + } + return ok; +} + +void +Consumer_Main::reconnect ( + CosNotifyChannelAdmin::EventChannelFactory_ptr dest_factory + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer begin ReconnectRegistry based reconnection\n") + )); + } + this->ecf_ = CosNotifyChannelAdmin::EventChannelFactory::_duplicate (dest_factory); + this->reconnecting_ = true; + init_event_channel (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + init_consumer_admin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + switch (this->mode_) + { + case MODE_STRUCTURED: + { + init_structured_proxy_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + break; + } + + case MODE_SEQUENCE: + { + init_sequence_proxy_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + break; + } + + case MODE_ANY : + { + init_any_proxy_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + break; + } + } + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer ReconnectRegistry based reconnection complete\n") + )); + } +} + + +int +Consumer_Main::resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL) +{ + // ignore redundant calls + if (CORBA::is_nil (this->naming_context_.in ())) + { + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + + return !CORBA::is_nil (this->naming_context_.in ()); +} + +int +Consumer_Main::find_notify_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + int status = this->resolve_naming_service (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + if (status) + { + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (NOTIFY_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + + this->ecf_ = + CosNotifyChannelAdmin::EventChannelFactory::_narrow ( + obj.in () + ACE_ENV_ARG_PARAMETER + ); + ACE_CHECK_RETURN(0); + } + return ! CORBA::is_nil (this->ecf_.in ()); +} + +int +Consumer_Main::resolve_notify_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + CORBA::Object_var factory_obj = + this->orb_->resolve_initial_references (NOTIFY_FACTORY_NAME + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + + this->ecf_ = + CosNotifyChannelAdmin::EventChannelFactory::_narrow ( + factory_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + return ! CORBA::is_nil (this->ecf_.in ()); +} + +void +Consumer_Main::init_event_channel (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + if (this->reconnecting_) + { + ACE_TRY_NEW_ENV + { + this->ec_ = this->ecf_->get_event_channel ( + this->ec_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ok = ! CORBA::is_nil (this->ec_.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Reconnect to event channel %d\n"), + ACE_static_cast (int, this->ec_id_) + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + + // if we don't have a channel yet, and a channel id file was specified + // try to read from it + if (!ok && this->channel_file_.length () > 0) + { + FILE * chf = ACE_OS::fopen (this->channel_file_.c_str (), "r"); + if (chf != 0) + { + char buffer[100]; + ACE_OS::fgets (buffer, sizeof(buffer), chf); + ACE_OS::fclose (chf); + this->ec_id_ = ACE_OS::atoi (buffer); + + ACE_DECLARE_NEW_ENV; + ACE_TRY_EX (unique_label_1) + { + this->ec_ = this->ecf_->get_event_channel ( + this->ec_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK_EX (unique_label_1) + ok = ! CORBA::is_nil (this->ec_.in ()); + if (ok) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Connect to Existing event channel %d\n"), + ACE_static_cast (int, this->ec_id_) + )); + } + // kill the channel filename so we don't overwrite the file + this->channel_file_ = ""; + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + } + + if (!ok) + { + CosNotification::QoSProperties qosprops (7); + qosprops.length (7); + CORBA::ULong i = 0; +#ifdef DISABLE_PROPERTIES_TODO + qosprops[i].name = CORBA::string_dup(CosNotification::EventReliability); + qosprops[i++].value <<= CosNotification::Persistent; + qosprops[i].name = CORBA::string_dup(CosNotification::ConnectionReliability); + qosprops[i++].value <<= CosNotification::Persistent; // Required, or we won't persist much + qosprops[i].name = CORBA::string_dup(CosNotification::Priority); + qosprops[i++].value <<= CosNotification::HighestPriority; + qosprops[i].name = CORBA::string_dup(CosNotification::Timeout); + qosprops[i++].value <<= (TimeBase::TimeT) 42 * 10000; // 42ms + qosprops[i].name = CORBA::string_dup(CosNotification::StopTimeSupported); + qosprops[i++].value <<= CORBA::Any::from_boolean(1); + qosprops[i].name = CORBA::string_dup(CosNotification::MaximumBatchSize); + qosprops[i++].value <<= (CORBA::Long)2; + qosprops[i].name = CORBA::string_dup(CosNotification::PacingInterval); + qosprops[i++].value <<= (TimeBase::TimeT) 50 * 10000; // 50ms +#endif + qosprops.length (i); + CosNotification::AdminProperties adminprops(4); + adminprops.length (4); + i = 0; +#ifdef DISABLE_PROPERTIES_TODO + adminprops[i].name = CORBA::string_dup(CosNotification::MaxQueueLength); + adminprops[i++].value <<= (CORBA::Long) 1234; + adminprops[i].name = CORBA::string_dup(CosNotification::MaxSuppliers); + adminprops[i++].value <<= (CORBA::Long) 1000; + adminprops[i].name = CORBA::string_dup(CosNotification::MaxConsumers); + adminprops[i++].value <<= (CORBA::Long) 1000; + adminprops[i].name = CORBA::string_dup(CosNotification::RejectNewEvents); + adminprops[i++].value <<= CORBA::Any::from_boolean(1); +#endif + adminprops.length(i); + + ec_ = this->ecf_->create_channel ( + qosprops, + adminprops, + this->ec_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (ec_.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Create event channel %d\n"), + static_cast<int> (this->ec_id_) + )); + } + } + + // save channel id + if (ok && this->channel_file_.length() > 0) + { + FILE * chf = ACE_OS::fopen (this->channel_file_.c_str (), "w"); + if (chf != 0) + { + fprintf (chf, "%d\n", static_cast<int> (this->ec_id_)); + fclose (chf); + } + } +} + +CosNotifyChannelAdmin::AdminID default_admin_id = ACE_static_cast (CosNotifyChannelAdmin::AdminID, -1); + +void +Consumer_Main::init_consumer_admin (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + if (this->reconnecting_) + { + if (this->sa_id_ == default_admin_id) + { + ACE_TRY_EX(TWO) + { + this->sa_ = this->ec_->default_consumer_admin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK_EX(TWO); + ok = ! CORBA::is_nil (this->sa_.in ()); + this->sa_id_ = default_admin_id; + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Using default consumer admin\n") + )); + } + else if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: No default consumer admin\n") + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + else // not default admin + { + ACE_TRY_EX(ONE) + { + this->sa_ = this->ec_->get_consumeradmin( + this->sa_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK_EX(ONE); + ok = ! CORBA::is_nil (this->sa_.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Reconnect to consumer admin %d\n"), + ACE_static_cast (int, this->sa_id_) + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + } + else // !reconnecting + { + ACE_TRY_EX(THREE) + { + this->sa_ = this->ec_->default_consumer_admin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK_EX(THREE); + ok = ! CORBA::is_nil (this->sa_.in ()); + this->sa_id_ = default_admin_id; + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Using default consumer admin\n") + )); + } + else if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: No default consumer admin\n") + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + + if (!ok) + { + this->sa_ = this->ec_->new_for_consumers( + CosNotifyChannelAdmin::OR_OP, + this->sa_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (this->sa_.in ()); + +#ifdef TEST_SET_QOS + // temporary: be sure we can set qos properties here + if (ok) + { + CosNotification::QoSProperties qosprops(2); + CORBA::ULong i = 0; + qosprops.length(2); + + qosprops[i].name = CORBA::string_dup(CosNotification::EventReliability); + qosprops[i++].value <<= CosNotification::Persistent; + qosprops[i].name = CORBA::string_dup(CosNotification::ConnectionReliability); + qosprops[i++].value <<= CosNotification::Persistent; // Required, or we won't persist much + qosprops.length(i); + this->sa_->set_qos (qosprops ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +#endif + + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Create new consumer admin %d\n"), + ACE_static_cast (int, this->sa_id_) + )); + } + } + } + if (!ok) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: connect to consumer admin failed %d\n"), + ACE_static_cast (int, this->sa_id_) + )); + } +} +void +Consumer_Main::init_structured_proxy_supplier (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + CosNotifyChannelAdmin::ProxySupplier_var proxy; + if (this->reconnecting_) + { + ACE_TRY_NEW_ENV + { + proxy = this->sa_->get_proxy_supplier ( + this->structured_proxy_id_ + ACE_ENV_ARG_PARAMETER + ); + ACE_TRY_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Reconnect to proxy supplier %d\n"), + ACE_static_cast (int, this->structured_proxy_id_) + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + + if (!ok) + { + proxy = this->sa_->obtain_notification_push_supplier( + CosNotifyChannelAdmin::STRUCTURED_EVENT, + this->structured_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Create new structured proxy %d\n"), + ACE_static_cast (int, this->structured_proxy_id_) + )); + } + } + this->structured_proxy_push_supplier_ = + CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow(proxy.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (this->structured_proxy_push_supplier_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) init_structured_proxy_supplier received nil ProxySupplier\n") + )); + ACE_THROW (CORBA::OBJECT_NOT_EXIST ()); + } + + if (CORBA::is_nil (this->structured_push_consumer_ref_.in ())) + { + PortableServer::ObjectId_var push_consumer_id = + this->root_poa_->activate_object ( + &(this->structured_push_consumer_) ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var obj = + this->root_poa_->id_to_reference (push_consumer_id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->structured_push_consumer_ref_ = + CosNotifyComm::StructuredPushConsumer::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + if (CORBA::is_nil (this->structured_push_consumer_ref_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Consumer: Error activating structured push consumer\n") + )); + + ACE_THROW (CORBA::BAD_PARAM()); + } + + this->structured_proxy_push_supplier_->connect_structured_push_consumer ( + this->structured_push_consumer_ref_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->structured_push_consumer_.set_connected(true); +} + +void +Consumer_Main::init_sequence_proxy_supplier (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + CosNotifyChannelAdmin::ProxySupplier_var proxy; + if (this->reconnecting_) + { + ACE_TRY_NEW_ENV + { + proxy = this->sa_->get_proxy_supplier( + this->sequence_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Reconnect to proxy %d\n"), + ACE_static_cast (int, this->sequence_proxy_id_) + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + + if (!ok) + { + proxy = this->sa_->obtain_notification_push_supplier( + CosNotifyChannelAdmin::SEQUENCE_EVENT, + this->sequence_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); +#ifdef TEST_SET_QOS + // temporary + if (ok) + { + set_proxy_qos (proxy.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +#endif // TEST_SET_QOS + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Create new sequence proxy %d\n"), + ACE_static_cast (int, this->sequence_proxy_id_) + )); + } + } + this->sequence_proxy_push_supplier_ = + CosNotifyChannelAdmin::SequenceProxyPushSupplier::_narrow(proxy.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (this->sequence_proxy_push_supplier_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Consumer: Received wrong type of push supplier proxy %d\n"), + ACE_static_cast (int, this->sequence_proxy_id_) + )); + + ACE_THROW (CORBA::BAD_PARAM()); + } + + if (CORBA::is_nil (this->sequence_push_consumer_ref_.in ())) + { + PortableServer::ObjectId_var push_consumer_id = + this->root_poa_->activate_object ( + &(this->sequence_push_consumer_) ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var obj = + this->root_poa_->id_to_reference (push_consumer_id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->sequence_push_consumer_ref_ = + CosNotifyComm::SequencePushConsumer::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + if (CORBA::is_nil (this->sequence_push_consumer_ref_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Consumer: Error activating sequence push consumer\n") + )); + + ACE_THROW (CORBA::BAD_PARAM()); + } + + this->sequence_proxy_push_supplier_->connect_sequence_push_consumer ( + this->sequence_push_consumer_ref_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->sequence_push_consumer_.set_connected(true); + +} + + +void +Consumer_Main::set_proxy_qos (CosNotifyChannelAdmin::ProxySupplier_ptr proxy + ACE_ENV_ARG_DECL) +{ + // temporary: be sure we can set qos properties for proxyw + CosNotification::QoSProperties qosprops(2); + CORBA::ULong i = 0; + qosprops.length(2); + + qosprops[i].name = CORBA::string_dup(CosNotification::EventReliability); + qosprops[i++].value <<= CosNotification::Persistent; + qosprops[i].name = CORBA::string_dup(CosNotification::ConnectionReliability); + qosprops[i++].value <<= CosNotification::Persistent; // Required, or we won't persist much + qosprops.length(i); + proxy->set_qos (qosprops ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer_Main::init_any_proxy_supplier (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + CosNotifyChannelAdmin::ProxySupplier_var proxy; + if (this->reconnecting_) + { + ACE_TRY_NEW_ENV + { + proxy = this->sa_->get_proxy_supplier( + this->any_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Reconnect to proxy %d\n"), + ACE_static_cast (int, this->any_proxy_id_) + )); + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Get proxy supplier %d returned nil\n"), + ACE_static_cast (int, this->any_proxy_id_) + )); + } + } + ACE_CATCHANY + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Get proxy supplier %d threw exception\n"), + ACE_static_cast (int, this->any_proxy_id_) + )); + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, ACE_TEXT ("To wit:")); + } + ACE_CATCHALL + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Get proxy supplier %d threw exception\n"), + ACE_static_cast (int, this->any_proxy_id_) + )); + } + ACE_ENDTRY; + } + + if (!ok) + { + proxy = this->sa_->obtain_notification_push_supplier( + CosNotifyChannelAdmin::ANY_EVENT, + this->any_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Consumer: Create new Any proxy %d\n"), + ACE_static_cast (int, this->any_proxy_id_) + )); + } + } + this->any_proxy_push_supplier_ = + CosNotifyChannelAdmin::ProxyPushSupplier::_narrow(proxy.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (this->any_proxy_push_supplier_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Consumer: Received wrong type of push supplier proxy %d\n"), + ACE_static_cast (int, this->any_proxy_id_) + )); + ACE_THROW (CORBA::BAD_PARAM()); + } + if (CORBA::is_nil (this->any_push_consumer_ref_.in ())) + { + PortableServer::ObjectId_var push_consumer_id = + this->root_poa_->activate_object ( + &(this->any_push_consumer_) ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var obj = + this->root_poa_->id_to_reference (push_consumer_id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->any_push_consumer_ref_ = + CosNotifyComm::PushConsumer::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + if (CORBA::is_nil (this->any_push_consumer_ref_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Consumer:Error activating push consumer\n") + )); + + ACE_THROW (CORBA::BAD_PARAM()); + } + this->any_proxy_push_supplier_->connect_any_push_consumer ( + this->any_push_consumer_ref_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->any_push_consumer_.set_connected(true); +} + +int Consumer_Main::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + + this->reconnection_callback_.fini (ACE_ENV_SINGLE_ARG_PARAMETER); + if (this->disconnect_on_exit_) + { + if (!CORBA::is_nil (this->structured_proxy_push_supplier_.in ())) + { + this->structured_proxy_push_supplier_->disconnect_structured_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-4); + } + if (!CORBA::is_nil (this->sequence_proxy_push_supplier_.in ())) + { + this->sequence_proxy_push_supplier_->disconnect_sequence_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-4); + } + if (!CORBA::is_nil (this->any_proxy_push_supplier_.in ())) + { + this->any_proxy_push_supplier_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-4); + } + if (!CORBA::is_nil (this->sa_.in ()) && this->sa_id_ != default_admin_id) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) destroy admin %d\n"), + ACE_static_cast(int, this->sa_id_) + )); + } + this->sa_->destroy(); + } + } + this->orb_->shutdown (); + return 0; +} + + +int Consumer_Main::run (ACE_ENV_SINGLE_ARG_DECL) +{ + int result = 0; + + ////////////////////////////////// + // Run the event loop for the ORB. + // Initial run to initialize the orb + ACE_Time_Value tv(1,0); + this->orb_->run (tv ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + while (this->structured_push_consumer_.received () < this->expect_ + && this->sequence_push_consumer_.received () < this->expect_ + && this->any_push_consumer_.received () < this->expect_ + ) + { + ACE_Time_Value work_tv(1,0); + // keep the orb alive -- listenting for reconnect + this->orb_->perform_work (work_tv ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + } + + // see if consumers detected errors + if (this->structured_push_consumer_.has_problem () + || this->sequence_push_consumer_.has_problem () + || this->any_push_consumer_.has_problem ()) + { + result = -3; + } + return result; +} + +int +main (int argc, char *argv[]) +{ + int result = -1; + Consumer_Main app; + ACE_TRY_NEW_ENV + { + result = app.init(argc, argv ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK + + if (result == 0) + { + result = app.run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + if (result == 0) + { + app.fini (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Consumer::main\t\n"); + result = -1; + } + ACE_ENDTRY; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Consumer exits: code %d\n"), + result + )); + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/Consumer.h b/TAO/orbsvcs/tests/Notify/Reconnecting/Consumer.h new file mode 100644 index 00000000000..0f21447744e --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/Consumer.h @@ -0,0 +1,300 @@ +/* -*- C++ -*- */ +// $Id$ +// ========================================================================== +// +// = FILENAME +// Consumer.h +// +// = DESCRIPTION +// Test Consumer reconnect to existing channel/admin/proxy Notification Service +// +// = AUTHOR +// Dale Wilson <wilson_d@ociweb.com> +// +// ========================================================================== + +#ifndef RECONNECTNG_CONSUMER_H +#define RECONNECTNG_CONSUMER_H + +//#if defined(_MSC_VER) && (_MSC_VER >= 1200) +//#pragma warning(pop) +//#endif /* _MSC_VER */ + + +#include "orbsvcs/CosNotifyChannelAdminC.h" +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/NotifyExtS.h" +#include "ace/SString.h" + +class Consumer_Main; + +class StructuredPushConsumer_i : public virtual POA_CosNotifyComm::StructuredPushConsumer +{ +public: + StructuredPushConsumer_i (); + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)); + + virtual void push_structured_event ( + const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)); + + virtual void disconnect_structured_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + size_t received () const; + void set_expectations (size_t expecte, size_t fail, size_t serial_number, bool verbose); + bool has_problem () const; + void set_connected (bool flag); + bool is_connected () const; + +private: + void check_serial_number (CORBA::ULong seq); + +private: + bool verbose_; + size_t received_; + size_t expect_; + size_t fail_; + size_t may_discard_; + size_t serial_number_; + size_t exceptions_thrown_; + bool problem_; + bool connected_; +}; + +class SequencePushConsumer_i : public virtual POA_CosNotifyComm::SequencePushConsumer +{ +public: + SequencePushConsumer_i (); + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)); + + virtual void push_structured_events ( + const CosNotification::EventBatch & notifications + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)); + + virtual void disconnect_sequence_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + size_t received () const; + void set_expectations (size_t expecte, size_t fail, size_t serial_number, bool verbose); + bool has_problem () const; + void set_connected (bool flag); + bool is_connected () const; + +private: + void check_serial_number (CORBA::ULong seq); + +private: + bool verbose_; + size_t received_; + size_t expect_; + size_t fail_; + size_t may_discard_; + size_t serial_number_; + size_t exceptions_thrown_; + bool problem_; + bool connected_; +}; + +class AnyPushConsumer_i : public virtual POA_CosNotifyComm::PushConsumer +{ +public: + AnyPushConsumer_i (); + + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)); + + virtual void push ( + const CORBA::Any & data + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)); + + virtual void disconnect_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + size_t received () const; + void set_expectations (size_t expecte, size_t fail, size_t serial_number, bool verbose); + bool has_problem () const; + void set_connected (bool flag); + bool is_connected () const; + +private: + void check_serial_number (CORBA::ULong seq); + +private: + bool verbose_; + size_t received_; + size_t expect_; + size_t fail_; + size_t may_discard_; + size_t serial_number_; + size_t exceptions_thrown_; + bool problem_; + bool connected_; +}; + +class ReconnectionCallback_i : public virtual POA_NotifyExt::ReconnectionCallback +{ +public: + ReconnectionCallback_i (Consumer_Main & consumer_main); + + virtual ~ReconnectionCallback_i (); + + void init ( + PortableServer::POA_ptr poa, + CosNotifyChannelAdmin::EventChannelFactory_ptr ecf_ + ACE_ENV_ARG_DECL); + + void fini (ACE_ENV_SINGLE_ARG_DECL); + + size_t reconnect_count () const; + + virtual void reconnect ( + CORBA::Object_ptr reconnection + ACE_ENV_ARG_DECL + ) ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + Consumer_Main & consumer_main_; + bool id_is_valid_; + NotifyExt::ReconnectionRegistry::ReconnectionID callback_id_; + CosNotifyChannelAdmin::EventChannelFactory_var ecf_; + size_t reconnect_count_; +}; + +class Consumer_Main +{ + public: + Consumer_Main (); + ~Consumer_Main (); + + int parse_args (int argc, char *argv[]); + int parse_single_arg (int argc, char *argv[]); + + int init (int argc, char *argv[] ACE_ENV_ARG_DECL); + int run (ACE_ENV_SINGLE_ARG_DECL); + int fini (ACE_ENV_SINGLE_ARG_DECL); + void usage (FILE * log) const; + + void reconnect ( + CosNotifyChannelAdmin::EventChannelFactory_ptr dest_factory + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + private: + /// Find naming service. + int resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL); + + /// Resolve the Notify factory from the Naming service. + int find_notify_factory (ACE_ENV_SINGLE_ARG_DECL); + + /// Resolve the Notify factory using resolve_initial_reference ("NotifyEventChannelFactory") + int resolve_notify_factory (ACE_ENV_SINGLE_ARG_DECL); + + void init_event_channel (ACE_ENV_SINGLE_ARG_DECL); + void init_consumer_admin (ACE_ENV_SINGLE_ARG_DECL); + void init_structured_proxy_supplier (ACE_ENV_SINGLE_ARG_DECL); + void init_sequence_proxy_supplier (ACE_ENV_SINGLE_ARG_DECL); + void init_any_proxy_supplier (ACE_ENV_SINGLE_ARG_DECL); + + void set_proxy_qos (CosNotifyChannelAdmin::ProxySupplier_ptr proxy ACE_ENV_ARG_DECL); + + void save_ids(); + bool load_ids(); + + //////////////////// + // forbidden methods + private: + Consumer_Main (const Consumer_Main & rhs); + Consumer_Main & operator = (const Consumer_Main & rhs); + + //////////////// + // Data members + private: + + // set by command line parameters + bool verbose_; // -v make a glorious noise + enum Mode_T{ + MODE_ANY, + MODE_STRUCTURED, + MODE_SEQUENCE} mode_; // -any, -structured, or -sequence + ACE_CString channel_file_; // -channel fileneame + size_t expect_; // -expect n + size_t fail_; // -fail n + bool use_naming_service_; // -nonamesvc + size_t serial_number_; // -serial_number + bool disconnect_on_exit_; // -disconnect + size_t structured_count_; + size_t sequence_count_; + size_t any_count_; + + ACE_CString id_file_; // -ids + CORBA::ORB_var orb_; + PortableServer::POA_var root_poa_; + CosNaming::NamingContext_var naming_context_; + CosNotifyChannelAdmin::EventChannelFactory_var ecf_; + + CosNotifyChannelAdmin::EventChannel_var ec_; + CosNotifyChannelAdmin::ChannelID ec_id_; + + CosNotifyChannelAdmin::ConsumerAdmin_var sa_; + CosNotifyChannelAdmin::AdminID sa_id_; + + CosNotifyChannelAdmin::StructuredProxyPushSupplier_var structured_proxy_push_supplier_; + CosNotifyChannelAdmin::ProxyID structured_proxy_id_; + StructuredPushConsumer_i structured_push_consumer_; + CosNotifyComm::StructuredPushConsumer_var structured_push_consumer_ref_; + + CosNotifyChannelAdmin::SequenceProxyPushSupplier_var sequence_proxy_push_supplier_; + CosNotifyChannelAdmin::ProxyID sequence_proxy_id_; + SequencePushConsumer_i sequence_push_consumer_; + CosNotifyComm::SequencePushConsumer_var sequence_push_consumer_ref_; + + CosNotifyChannelAdmin::ProxyPushSupplier_var any_proxy_push_supplier_; + CosNotifyChannelAdmin::ProxyID any_proxy_id_; + AnyPushConsumer_i any_push_consumer_; + CosNotifyComm::PushConsumer_var any_push_consumer_ref_; + + ReconnectionCallback_i reconnection_callback_; + + bool reconnecting_; +}; + +#endif /* RECONNECTNG_CONSUMER_H */ diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/README b/TAO/orbsvcs/tests/Notify/Reconnecting/README new file mode 100644 index 00000000000..723c0a4f730 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/README @@ -0,0 +1,351 @@ +$Id$ + +README for the Notification Service Reconnection Test +----------------------------------------------------- + +Implementation notes +-------------------- + +Notification Service Supplier/Consumer reconnection test. + +This directory contains: + + Supplier.cpp -- source for a configurable event supplier + Supplier.h + Consumer.cpp -- source for a configurable consumer for events produced + Consumer.h by a Supplier + run_ns.pl -- a script to start the Notification Service manually + run_supplier.pl -- a script to start Supplier manually + run_consumer.pl -- a script to start Consumer manually + run_test.pl -- a script to run several tests of the Reliable + Notification Service + ns_st.conf -- configures the Notification Service for single + thread operation with no persistence support. + ns_mt.conf -- configures the Notification Service for multi- + threaded operation with no persistence support. + ns_st_topo.conf -- configures the Notification Service for single + thread operation with support for topological, + but not event persistence. + ns_mt_topo.conf -- configures the Notification Service for multi- + threaded operation with support for topological, + but not event persistence. + ns_st_both.conf -- configures the Notification Service for single + thread operation with support for both topological, + and event persistence. + ns_mt_both.conf -- configures the Notification Service for multi- + threaded operation with support for both topological, + and event persistence. + event.conf -- configures the Notification Service for event + persistence without topology persistence. This is + an invalid configuration and should cause the + Notification Service to refuse to start. + Reconnecting.mpc -- a configuration/build file for MPC + README -- this file + +Supplier +-------- +This program connects to the Notification Service and generates events based +on command line parameters. + + -nonamesvc Don't use the Naming Service to find + EventChannelFactory + -channel filename Where to find a channel number + -any or -str or -seq What type of event to send (pick one, default is -any) + -send n How many events to send + -pause n Pause after sending n events + Signal the pause by writing to file "Supplier.paused" + -serial_number n What serial number to start with + -v Verbose output + +Because the Supplier and Consumer share many command line options, the +descriptions of these options will be combined below. + +Consumer +-------- +This program connects to the Notification Service and consumes events from +the Supplier. + + -nonamesvc Don't use the Naming Service to find + EventChannelFactory + -channel filename Where to store a channel number so the Supplier can + find it + -any or -str or -seq What type of event supplier will send (pick one, + default: -any) + -expect n How many events are expected. + -fail n Simulate a recoverable failure every n events. + -serial_number n What serial number to expect first. If -1 is + used, then serial number checking is disabled. + This allows testing the consumer with multiple + Suppliers. + -disconnect Disconnect from notfication service cleanly + (no reconnect will be possible) + -v Verbose output. + +Command line option: -nonamesvc +------------------------------- +There are several techniques that Notification Service clients (Suppliers +and Consumers) may use to find and connect to the Notification Service. +One common technique is for the Notification Service to register an Event +Channel Factory with the Naming Service using a well-known name (specified in +the CORBA standard.) + +Although this technique is a good one for use in a system that already depends +on the Naming Service, the test scripts in this directory do not depend on the +Naming Service. When this option is specified, the Supplier and Consumer use +"resolve_initial_references ()" to find the Notification Service. + +When this option is used, the ORB option -ORBInitRef must also be used to +define an initial reference to the Notification Service. + +Command line option: -channel filename +-------------------------------------- +The Notification Service has the ability to support several channels +simultaneously. For these tests to work, the Supplier and Consumer must +use the same channel. There are several techniques the Consumer(s) and +Supplier(s) can use to select which channel to use. These programs use a +shared file to communicate the channel number from the Consumer that creates +the channel to the Supplier that uses it. + +When the Consumer starts up but is not reconnecting to an existing service, +it creates a new channel and writes the channel ID to the file specified by +this command (if no -channel option is given, the channel ID is not written.) + +When the Supplier starts up, but is not reconnecting to an existing service, +it attempts to read the channel ID from the file specified by this option. +If it is successful it uses that channel ID to send events. + +Command line options: -any or -str or -seq +------------------------------------------ +The Notification Service supports three types of Events. Any events are +like those used by the Event Service (an ancestor to the Notification +Service). Structured events and Sequence events are events supported only +by the Notification Service. See the TAO Developer's Guide or the CORBA +specification for more details. + +Only one of these three options should be specified. If none of these +is specified, the default is "-any". + +Command line option: -send n +---------------------------- +This Supplier-only option tells the Supplier how many events to send. +After it has sent that many events, the Supplier will shut down. + +Command line option: -expect n +------------------------------ +This Consumer-only option tells the Consumer how many events to expect. +After it has received that many events, the Consumer will shut down. + +Command line option: -fail n +------------------------------ +This Consumer-only option tells the Consumer to throw an exception +(CORBA::UNKNOWN) every n events. This simulates a recoverable error in +the consumer. After throwing the exception, the consumer continues +to listen for incoming events. It expects the event it was processing +to be retransmitted. + +Because of the retransmission, the use of the -fail option may be +counterintuitive. If the consumer options are "-expect 10 -fail 4" then +it will receive events 0, 1, 2, and fail on event 3. It will then +receive 3, 4, 5, and fail on event 6. Then it will receive 6, 7, 8, +and fail on event 9. Finally it will receive the retransmission of event +9 and exit. + +Command line option: -pause n +----------------------------- +This Supplier-only option is used during testing. The Supplier will send +the specified number of events then wait for the Notification Service to +stop and restart before sending the remaining events. + +To signal test scripts that a pause has happened, the Supplier will create +a file named "Supplier.pause" This file can be used to synchronize a +script with a running Supplier. It has no other purpose. + +Obviously the -pause option should specify a smaller number than the -send +option. If this option is not used, no pause will occur. + +Command line option: -serial_number n +------------------------------------- +Each event sent by the the Supplier has a sequential serial number. As the +Consumer receives events, it checks to see that the events arrived in serial +number order. Missing or duplicated events will be detected by the Consumer. + +This option tells the Supplier what serial number to use for the first event +it sends, and the Consumer what serial number to expect in the first event +it receives. + +For the Consumer only, a value of -1 disables checking of incoming serial +numbers. This should be used when the Consumer is receiving events from +multiple suppliers. + +Command line option: -v +----------------------- +This option enables verbose messages. The Supplier and Consumer are +relatively silent during normal operation -- displaying messages only when +something goes wrong. If this verbose option is specified, more detailed +progress messages will be displayed. + +Reconnection +------------ +Reconnection to the Notification Service is based on ID numbers assigned to +the objects within the Notification Service (objects like Channels, Admins, +and Proxies). After initially starting up, the supplier writes the IDs it +needs to preserve to a file named Supplier.ids. The Consumer writes its +IDs to Consumer.ids. + +When a client (Supplier or Consumer) starts up, it looks for its corresponding +".ids" file. If the file is found, the client attempts to reconnect to an +existing Notification Service using these IDs. If the file is not found, or +the reconnection fails, the client falls back on its normal startup procedure. + +In addition, a running client can receive a request for reconnection from +the Notification Service. When it does so, it uses the saved ID numbers to +complete the reconnection process. + +Programming Style +----------------- +The Supplier and Consumer source files were designed to be complete, +stand-alone applications. Other than their basic dependency on ACE, TAO, +and CORBA, they avoid using outside facilities. For example, there is a +Notification Tests library used by many Notification Service tests that +encapsulates connections to the Notification Service and typical CORBA +application issues. Because these programs were intended to illustrate +everything necessary for a client application to work with a reliable +Notification Service, this library is not used. + +Obviously a real-world application should take advantage of such helper +classes to allow the developer to concentrate on the domain problem for +which the application is written. + +Also these programs use ACE-style platform independence techniques. +Applications that do not need to support the wide variety of platforms +supported by ACE and TAO can relax some of these coding techniques. + +run_test.pl +----------- +The run_test.pl script runs tests of different cases in which +reliable topology is needed. The following command line options can +be given to the test script: + +run_test.pl: command line options -any, -str, or -seq +----------------------------------------------------- +Specify one of these options to determine what type of event will be used +during the test. The default if none of these options is present is "-any". + +run_test.pl: command line option -v +-------------------------------------------- +This option controls the verbosity of the test script and the Supplier and +Consumer applications. When it is present, a detailed step-by-step +report is produced by the test. + +run_test.pl: Test #1: Supplier reconnection. +-------------------------------------------- +All persistent information is discarded before the test starts. The test +script starts the Notification Service, a Consumer and a Supplier. + +The Consumer is configured to receive 20 events. The Supplier is configured +to send ten events. + +After sending ten events, the Supplier exits -- simulating a Supplier failure. +The test script starts a new copy of the Supplier. The new Supplier is +configured to send ten events starting with event number 10. +It uses information saved by the previous supplier to reconnect to the same +channel, admin, and proxy in the Notification Services. +The Suppler sends the remaining ten events then exists. The Consumer having +received the 20 events it expects, exits as well and the test is complete. + +This demonstrates that a Supplier can stop then restart and its events will e +delivered to the correct Consumer. + +run_test.pl: Test #2: Consumer reconnection. +-------------------------------------------- +The Notification Service from the previous test is still running and the +saved reconnection information for both the Supplier and Consumer is still +available. + +The test script starts a Consumer configured to receive 20 events and a +Supplier configured to send twenty events. Both clients use the reconnection +information from the previous test to reconnect to the Notification Service. + +Twenty events are sent successfully, then both clients exit and the test +is complete. + +This demonstrates that a Consumer can stop then restart and reconnect. It +will continue to receive the events on the channel to which it was originally +connected. + +run_test.pl: Test #3: Saving and Restoring Topology +--------------------------------------------------- +The test script stops the Notification Server from the previous two tests and +starts a new Notification Server. It reloads the topology from the XML topology +persistence files saved during the first two tests. + +The test script starts a Consumer and a Supplier. They are configured to +receive and send respectively twenty events. The clients use the reconnection +information from the previous tests to connect to the event channel, admins, +and proxies that were reloaded from persistent topology information. +The Supplier sends and the Consumer receives 20 events. Both clients exit. + +This demonstrates that the Notification Server can save its topology, then +reload it, and the resulting topology behaves correctly when clients reconnect. + +run_test.pl: Test #4: The Reconnection Registry +----------------------------------------------- +This test starts with the Notification Service from the previous test. + +The script starts a new Consumer that expects to receive 20 events. The +Consumer reconnects to the Notification Server. +The script starts a Supplier. It is configured to send 10 events then +pause waiting for a Notification Service initiated reconnection before +sending the remaining 10 events. + +Both clients register with the Reconnection Registry to receive reconnection +callbacks. + +The test script waits for the Supplier to pause. It then kills the +Notification Service and starts a new copy. The new Notification Service +is not configured to listen at the same endpoint as the previous one did, +so the clients have no way to find the new copy directly. They must rely +on the callback received from the Reconnection Registry. + +The new Notification Service reloads its topology, including the Reconnection +Registry entries from the XML file. It sends reconnection callbacks to the +registered clients. + +Using their saved reconnection information, the clients complete the +reconnection to the new Notification Service. + +The Supplier sends the remaining 10 events then terminates. The Consumer, +having received its expected 10 events also terminates. + +This demonstrates the reconnection registry and reconnection to live clients. + +run_test.pl: Test #5: Consumer Recoverable Exception +---------------------------------------------------- +Using the Notification Service still running from the previous test, +but discarding reconnection information, a new Consumer is started. +It is configured to expect 10 events, but to throw an exception after +receiving the sixth event. After throwing the exception it expects to see +the sixth event retransmitted, then to receive the remaining four events. +A Supplier is started that sends 10 events, and then exits. +When the Consumer has received the events it expects, including the +retransmission of the sixth event, it shuts down. + +This demonstrates the Notification Service can recover from transient +communication or Consumer failures. + +Known Problems as of Feb 2004. +------------------------------ +Sequence events are not working. It is unclear whether this is a problem in +the test or in the Notification Service itself. + +Known Problems as of Mar 2004. +------------------------------ +The problem with sequence events reported previously turned out to be problems +in both the test and in the Notification Service itself. These problems +have been resolved. It is now possible to mix and match consumers and +suppliers. + +There are no new known problems. + +[----------------------------------------------------------------------------] + diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/Reconnecting.mpc b/TAO/orbsvcs/tests/Notify/Reconnecting/Reconnecting.mpc new file mode 100644 index 00000000000..75de6986a9b --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/Reconnecting.mpc @@ -0,0 +1,12 @@ +project(*Supplier): notifytest { + Source_Files { + Supplier.cpp + } +} + +project(*Consumer): notifytest { + Source_Files { + Consumer.cpp + } +} + diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/Supplier.cpp b/TAO/orbsvcs/tests/Notify/Reconnecting/Supplier.cpp new file mode 100644 index 00000000000..88bfd7cdb3a --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/Supplier.cpp @@ -0,0 +1,1383 @@ +//$Id$ + +#include "Supplier.h" +#include "orbsvcs/CosNotifyChannelAdminC.h" +#include "tao/debug.h" +#include "tao/PortableServer/PortableServerC.h" +#include <tao/TimeBaseC.h> +#include <ace/OS_NS_stdio.h> +#include <ace/OS_NS_strings.h> + +ACE_RCSID (Notify_Tests, Supplier_Main, "$Id$") + +static const char NOTIFY_FACTORY_NAME[] = "NotifyEventChannelFactory"; +static const char NAMING_SERVICE_NAME[] = "NameService"; + +/////////////////////////// +// StructuredPushSupplier_i + +void +StructuredPushSupplier_i::subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Supplier StructuredPushSupplier received subscription change\n") + )); +} + + +void +StructuredPushSupplier_i::disconnect_structured_push_supplier ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Supplier StructuredPushSupplier received disconnect\n") + )); +} + +/////////////////////////// +// SequencePushSupplier_i + +void +SequencePushSupplier_i::subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Supplier SequencePushSupplier received subscription change\n") + )); +} + + +void +SequencePushSupplier_i::disconnect_sequence_push_supplier ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Supplier SequencePushSupplier received disconnect\n") + )); +} + +/////////////////////////// +// AnyPushSupplier_i + +void +AnyPushSupplier_i::subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Supplier AnyPushSupplier received subscription change\n") + )); +} + + +void +AnyPushSupplier_i::disconnect_push_supplier ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Suppleir AnyPushSupplier received disconnect\n") + )); +} + +///////////////////////// +// ReconnectionCallback_i + +ReconnectionCallback_i::ReconnectionCallback_i (Supplier_Main & supplier_main) + : supplier_main_ (supplier_main) + , id_is_valid_ (false) + , reconnect_count_ (0) +{ +} + +size_t +ReconnectionCallback_i::reconnect_count () const +{ + return this->reconnect_count_; +} + +void +ReconnectionCallback_i::reconnect ( + CORBA::Object_ptr reconnection + ACE_ENV_ARG_DECL + ) ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier received reconnection request\n") + )); + this->ecf_ = CosNotifyChannelAdmin::EventChannelFactory::_narrow (reconnection ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + if (!CORBA::is_nil (this->ecf_.in ())) + { + this->supplier_main_.reconnect (this->ecf_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->reconnect_count_ += 1; + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier reconnection request failed: wrong object type\n") + )); + } +} + +CORBA::Boolean +ReconnectionCallback_i::is_alive (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::Boolean (1); +} + +ReconnectionCallback_i::~ReconnectionCallback_i () +{ + // normally you would disconnect from registry here, but + // to simulate a failure, we exit without cleaning up + // if the fini method is not called. +} + + +void +ReconnectionCallback_i::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->id_is_valid_) + { + NotifyExt::ReconnectionRegistry_var registry = + NotifyExt::ReconnectionRegistry::_narrow (this->ecf_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + registry->unregister_callback (this->callback_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->id_is_valid_ = false; + } +} + +void +ReconnectionCallback_i::init ( + PortableServer::POA_ptr poa, + CosNotifyChannelAdmin::EventChannelFactory_ptr ecf + ACE_ENV_ARG_DECL) +{ + this->ecf_ = CosNotifyChannelAdmin::EventChannelFactory::_duplicate (ecf); + PortableServer::ObjectId_var reconnection_callback_id = + poa->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var obj = + poa->id_to_reference (reconnection_callback_id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + NotifyExt::ReconnectionCallback_var callback = + NotifyExt::ReconnectionCallback::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + NotifyExt::ReconnectionRegistry_var registry = + NotifyExt::ReconnectionRegistry::_narrow (ecf ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->callback_id_ = registry->register_callback (callback.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->id_is_valid_ = true; +} + + + +///////////////// +// Supplier_Main + +Supplier_Main::Supplier_Main () + : verbose_ (false) + , mode_ (MODE_ANY) + , send_ (10) + , use_naming_service_ (true) + , serial_number_ (0) + , disconnect_on_exit_ (false) + , id_file_ (ACE_TEXT ("supplier.ids")) + , pause_ (0) + , ec_id_ (0) + , sa_id_(0) + , structured_proxy_id_(0) + , sequence_proxy_id_(0) + , any_proxy_id_(0) + , reconnection_callback_ (*this) + , reconnecting_ (false) +{ +} + +Supplier_Main::~Supplier_Main () +{ +} + +int +Supplier_Main::parse_args (int argc, char *argv[]) +{ + int result = 0; + int narg = 1; + bool corba_arg = false; + while (narg < argc && result == 0) + { + int consumed = parse_single_arg (argc - narg, &argv[narg]); + if ( consumed > 0) + { + narg += consumed; + corba_arg = false; + } + else if (ACE_OS::strncmp (argv[narg], "-ORB", 4) == 0) + { + corba_arg = true; + } + else if (corba_arg) + { + // previous argument was a ORB arg. + // current argument is unrecognized + // assume the ORB eats this arg + narg += 1; + corba_arg = false; + } + else + { + ACE_OS::fprintf(stderr, "Unrecognized argument: %s\n", argv[narg]); + usage (stderr); + result = -1; + } + } + return result; +} + +int +Supplier_Main::parse_single_arg (int argc, char *argv[]) +{ + int consumed = 0; + if (ACE_OS::strcasecmp (argv[0], ACE_TEXT ("-v")) == 0) + { + this->verbose_ = true; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], ACE_TEXT ("-any")) == 0) + { + this->mode_ = MODE_ANY; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], ACE_TEXT ("-structured")) == 0) + { + this->mode_ = MODE_STRUCTURED; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], ACE_TEXT ("-sequence")) == 0) + { + this->mode_ = MODE_SEQUENCE; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], ACE_TEXT ("-channel")) == 0) + { + this->channel_file_= argv[1]; + consumed = 2; + } + else if (ACE_OS::strcasecmp (argv[0], ACE_TEXT ("-send")) == 0 && argc > 1) + { + this->send_ = ACE_OS::atoi (argv[1]); + consumed = 2; + } + else if (ACE_OS::strcasecmp (argv[0], ACE_TEXT ("-pause")) == 0 && argc > 1) + { + this->pause_ = ACE_OS::atoi (argv[1]); + consumed = 2; + } + else if (ACE_OS::strcasecmp (argv[0], ACE_TEXT ("-serial_number")) == 0) + { + this->serial_number_= ACE_OS::atoi (argv[1]); + consumed = 2; + } + else if (ACE_OS::strcasecmp (argv[0], ACE_TEXT ("-nonamesvc")) == 0) + { + this->use_naming_service_ = false; + consumed = 1; + } + else if (ACE_OS::strcasecmp (argv[0], "-disconnect") == 0) + { + this->disconnect_on_exit_ = true; + consumed = 1; + } + + return consumed; +} + +void Supplier_Main::usage(FILE * log)const +{ + ACE_OS::fputs ( + ACE_TEXT ("usage\n") + ACE_TEXT (" -channel filename Where to find a channel number.\n") + ACE_TEXT (" -any or -structured or -sequence\n") + ACE_TEXT (" What type of event to send (pick one, default is -any)\n") + ACE_TEXT (" -send n How many events of each type to send.\n") + ACE_TEXT (" -pause n Pause after sending n events. Write to file \"Supplier.paused\"\n") + ACE_TEXT (" -serial_number n What serial number to start with.\n") + ACE_TEXT (" -v Verbose output.\n") + ACE_TEXT (" -disconnect Disconnect from channel on exit (prevents reconnect.) \n") + ACE_TEXT (" -nonamesvc Don't use the name service to find EventChannelFactory\n") + , log); +} + +int Supplier_Main::init (int argc, char *argv[] ACE_ENV_ARG_DECL) +{ + this->orb_ = CORBA::ORB_init(argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (0 != this->parse_args(argc, argv)) + { + return -1; + } + + CORBA::Object_ptr poa_object = + this->orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object)) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n"))); + return -1; + } + + this->root_poa_ = + PortableServer::POA::_narrow (poa_object ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + PortableServer::POAManager_var poa_manager = + root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (this->use_naming_service_ ) + { + this->find_notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + else + { + int ok = resolve_notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (!ok) + { + return -1; + } + } + + this->reconnecting_ = load_ids (); + + init_event_channel (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + init_supplier_admin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + switch (this->mode_) + { + case MODE_STRUCTURED: + { + init_structured_proxy_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + break; + } + case MODE_SEQUENCE: + { + init_sequence_proxy_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + break; + } + case MODE_ANY: + { + + init_any_proxy_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + break; + } + default: + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Supplier: Unknown event push mode.\n") + )); + break; + } + } + this->reconnection_callback_.init ( + this->root_poa_.in (), + this->ecf_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + save_ids (); + return 0; +} +void +Supplier_Main::save_ids() +{ + FILE *idf = + ACE_OS::fopen (this->id_file_.c_str (), "w"); + + if (idf != 0) + { + int endflag = 12345; + int imode = ACE_static_cast (int, this->mode_); + ACE_OS::fprintf (idf, + "%d,%d,%d,%d,%d,%d,%d,\n", + static_cast<int> (imode), + static_cast<int> (ec_id_), + static_cast<int> (sa_id_), + static_cast<int> (structured_proxy_id_), + static_cast<int> (sequence_proxy_id_), + static_cast<int> (any_proxy_id_), + static_cast<int> (endflag) ); + ACE_OS::fclose (idf); + } +} + +bool +Supplier_Main::load_ids() +{ + bool ok = false; + FILE *idf = + ACE_OS::fopen (this->id_file_.c_str (), "r"); + + if (idf != 0) + { + int field = 0; + + char buffer[100] = ""; // because ACE fgets doesn't put a null if the file is empty + ACE_OS::fgets (buffer, sizeof(buffer), idf); + ACE_OS::fclose (idf); + char * pb = buffer; + while (!ok && *pb != 0) + { + char * eb = ACE_OS::strchr (pb, ','); + char * nb = eb + 1; + if (eb == 0) + { + eb = pb + ACE_OS::strlen (pb); + nb = eb; + } + *eb = 0; + if (pb < eb) + { + int value = ACE_OS::atoi(pb); + switch (++field) + { + case 1: + this->mode_ = static_cast<Mode_T> (value); + break; + case 2: + this->ec_id_ = value; + break; + case 3: + this->sa_id_ = value; + break; + case 4: + this->structured_proxy_id_ = value; + break; + case 5: + this->sequence_proxy_id_ = value; + break; + case 6: + this->any_proxy_id_ = value; + break; + case 7: + ok = value == 12345; + break; + default: + ACE_OS::fprintf (stderr, ACE_TEXT ("Supplier: Warning: too many fields in saved id file.\n")); + ok = false; + break; + } + } + pb = nb; + } + } + return ok; +} + +void +Supplier_Main::reconnect ( + CosNotifyChannelAdmin::EventChannelFactory_ptr dest_factory + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->ecf_ = CosNotifyChannelAdmin::EventChannelFactory::_duplicate (dest_factory); + this->reconnecting_ = true; + init_event_channel (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + init_supplier_admin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + switch (this->mode_) + { + case MODE_STRUCTURED: + { + init_structured_proxy_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + break; + } + case MODE_SEQUENCE: + { + init_sequence_proxy_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + break; + } + case MODE_ANY: + { + init_any_proxy_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + break; + } + } +} + + +int +Supplier_Main::resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL) +{ + // ignore redundant calls + if (CORBA::is_nil (this->naming_context_.in ())) + { + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + + return !CORBA::is_nil (this->naming_context_.in ()); +} + +int +Supplier_Main::find_notify_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + int status = this->resolve_naming_service (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + if (status) + { + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (NOTIFY_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + + this->ecf_ = + CosNotifyChannelAdmin::EventChannelFactory::_narrow ( + obj.in () + ACE_ENV_ARG_PARAMETER + ); + ACE_CHECK_RETURN(0); + } + return ! CORBA::is_nil (this->ecf_.in ()); +} + +int +Supplier_Main::resolve_notify_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + CORBA::Object_var factory_obj = + this->orb_->resolve_initial_references (NOTIFY_FACTORY_NAME + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + + this->ecf_ = + CosNotifyChannelAdmin::EventChannelFactory::_narrow ( + factory_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + return ! CORBA::is_nil (this->ecf_.in ()); +} + +void +Supplier_Main::init_event_channel (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + if (this->reconnecting_) + { + ACE_TRY_NEW_ENV + { + this->ec_ = this->ecf_->get_event_channel ( + this->ec_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ok = ! CORBA::is_nil (this->ec_.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Reconnect to event channel %d\n"), + ACE_static_cast (int, this->ec_id_) + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + + // if we don't have a channel yet, and a channel id file was specified + // try to read from it + if (!ok && this->channel_file_.length () > 0) + { + FILE * chf = ACE_OS::fopen (this->channel_file_.c_str (), "r"); + if (chf != 0) + { + char buffer[100]; + ACE_OS::fgets (buffer, sizeof(buffer), chf); + ACE_OS::fclose (chf); + this->ec_id_ = ACE_OS::atoi (buffer); + + ACE_DECLARE_NEW_ENV; + ACE_TRY_EX (unique_label_1) + { + this->ec_ = this->ecf_->get_event_channel ( + this->ec_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK_EX (unique_label_1) + ok = ! CORBA::is_nil (this->ec_.in ()); + if (ok) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Connect to Existing event channel %d\n"), + ACE_static_cast (int, this->ec_id_) + )); + } + // kill the channel filename so we don't overwrite the file + this->channel_file_ = ""; + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + } + + if (!ok) + { + CosNotification::QoSProperties qosprops (7); + qosprops.length (7); + CORBA::ULong i = 0; +#ifdef DISABLE_PROPERTIES_TODO + qosprops[i].name = CORBA::string_dup(CosNotification::EventReliability); + qosprops[i++].value <<= CosNotification::Persistent; + qosprops[i].name = CORBA::string_dup(CosNotification::ConnectionReliability); + qosprops[i++].value <<= CosNotification::Persistent; // Required, or we won't persist much + qosprops[i].name = CORBA::string_dup(CosNotification::Priority); + qosprops[i++].value <<= CosNotification::HighestPriority; + qosprops[i].name = CORBA::string_dup(CosNotification::Timeout); + qosprops[i++].value <<= (TimeBase::TimeT) 42 * 1000000; // 4.2s + qosprops[i].name = CORBA::string_dup(CosNotification::StopTimeSupported); + qosprops[i++].value <<= CORBA::Any::from_boolean(1); + qosprops[i].name = CORBA::string_dup(CosNotification::MaximumBatchSize); + qosprops[i++].value <<= (CORBA::Long) 2; + qosprops[i].name = CORBA::string_dup(CosNotification::PacingInterval); + qosprops[i++].value <<= (TimeBase::TimeT) 50 * 10000; // 50ms +#endif + qosprops.length (i); + CosNotification::AdminProperties adminprops(4); + adminprops.length (4); + i = 0; +#ifdef DISABLE_PROPERTIES_TODO + adminprops[i].name = CORBA::string_dup(CosNotification::MaxQueueLength); + adminprops[i++].value <<= (CORBA::Long) 1234; + adminprops[i].name = CORBA::string_dup(CosNotification::MaxConsumers); + adminprops[i++].value <<= (CORBA::Long) 1000; + adminprops[i].name = CORBA::string_dup(CosNotification::MaxSuppliers); + adminprops[i++].value <<= (CORBA::Long) 1000; + adminprops[i].name = CORBA::string_dup(CosNotification::RejectNewEvents); + adminprops[i++].value <<= CORBA::Any::from_boolean(1); +#endif + adminprops.length(i); + + ec_ = this->ecf_->create_channel ( + qosprops, + adminprops, + this->ec_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (ec_.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Create event channel %d\n"), + static_cast<int> (this->ec_id_) + )); + } + } + + // save channel id + if (ok && this->channel_file_.length() > 0) + { + FILE * chf = ACE_OS::fopen (this->channel_file_.c_str (), "w"); + if (chf != 0) + { + fprintf (chf, "%d\n", static_cast<int> (this->ec_id_)); + fclose (chf); + } + } +} + +CosNotifyChannelAdmin::AdminID default_admin_id = ACE_static_cast (CosNotifyChannelAdmin::AdminID, -1); + +void +Supplier_Main::init_supplier_admin (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + if (this->reconnecting_ && this->sa_id_ != default_admin_id) + { + ACE_TRY_EX(ONE) + { + this->sa_ = this->ec_->get_supplieradmin( + this->sa_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK_EX(ONE); + ok = ! CORBA::is_nil (this->sa_.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Reconnect to supplier admin %d\n"), + ACE_static_cast (int, this->sa_id_) + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + + if (!ok) + { + ACE_TRY_EX(TWO) + { + this->sa_ = this->ec_->default_supplier_admin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK_EX(TWO); + ok = ! CORBA::is_nil (this->sa_.in ()); + this->sa_id_ = default_admin_id; + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Using default supplier admin\n") + )); + } + else if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: No default supplier admin\n") + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + + if (!ok) + { + this->sa_ = this->ec_->new_for_suppliers( + CosNotifyChannelAdmin::OR_OP, + this->sa_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (this->sa_.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Create new supplier admin %d\n"), + ACE_static_cast (int, this->sa_id_) + )); + } + } +} + +void +Supplier_Main::init_structured_proxy_consumer (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + CosNotifyChannelAdmin::ProxyConsumer_var proxy; + if (this->reconnecting_) + { + ACE_TRY_NEW_ENV + { + proxy = this->sa_->get_proxy_consumer ( + this->structured_proxy_id_ + ACE_ENV_ARG_PARAMETER + ); + ACE_TRY_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Reconnect to proxy supplier %d\n"), + ACE_static_cast (int, this->structured_proxy_id_) + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + + if (!ok) + { + proxy = this->sa_->obtain_notification_push_consumer( + CosNotifyChannelAdmin::STRUCTURED_EVENT, + this->structured_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Create new proxy %d\n"), + ACE_static_cast (int, this->structured_proxy_id_) + )); + } + } + this->structured_proxy_push_consumer_ = + CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow(proxy.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (this->structured_proxy_push_consumer_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) init_structured_proxy_consumer received nil ProxyConsumer\n") + )); + ACE_THROW (CORBA::OBJECT_NOT_EXIST ()); + } + if (CORBA::is_nil (this->structured_push_supplier_ref_.in ())) + { + PortableServer::ObjectId_var push_supplier_id = + this->root_poa_->activate_object ( + &(this->structured_push_supplier_) ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var obj = + this->root_poa_->id_to_reference (push_supplier_id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->structured_push_supplier_ref_ = + CosNotifyComm::StructuredPushSupplier::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + if (CORBA::is_nil (structured_push_supplier_ref_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Supplier: Received wrong type of push consumer proxy %d\n"), + ACE_static_cast (int, this->structured_proxy_id_) + )); + + ACE_THROW (CORBA::UNKNOWN()); + } + + this->structured_proxy_push_consumer_->connect_structured_push_supplier ( + structured_push_supplier_ref_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier_Main::init_sequence_proxy_consumer (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + CosNotifyChannelAdmin::ProxyConsumer_var proxy; + if (this->reconnecting_) + { + ACE_TRY_NEW_ENV + { + proxy = this->sa_->get_proxy_consumer( + this->sequence_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Reconnect to proxy %d\n"), + ACE_static_cast (int, this->sequence_proxy_id_) + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + + if (!ok) + { + proxy = this->sa_->obtain_notification_push_consumer( + CosNotifyChannelAdmin::SEQUENCE_EVENT, + this->sequence_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Create new proxy %d\n"), + ACE_static_cast (int, this->sequence_proxy_id_) + )); + } + } + this->sequence_proxy_push_consumer_ = + CosNotifyChannelAdmin::SequenceProxyPushConsumer::_narrow(proxy.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (this->sequence_proxy_push_consumer_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Supplier: Received wrong type of push consumer proxy %d\n"), + ACE_static_cast (int, this->sequence_proxy_id_) + )); + ACE_THROW (CORBA::UNKNOWN()); + } + + if (CORBA::is_nil (this->sequence_push_supplier_ref_.in ())) + { + PortableServer::ObjectId_var push_supplier_id = + this->root_poa_->activate_object ( + &(this->sequence_push_supplier_) ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var obj = + this->root_poa_->id_to_reference (push_supplier_id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->sequence_push_supplier_ref_ = + CosNotifyComm::SequencePushSupplier::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + if (CORBA::is_nil (sequence_push_supplier_ref_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Supplier: Received wrong type of push consumer proxy %d\n"), + ACE_static_cast (int, this->sequence_proxy_id_) + )); + ACE_THROW (CORBA::UNKNOWN()); + } + + this->sequence_proxy_push_consumer_->connect_sequence_push_supplier ( + sequence_push_supplier_ref_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier_Main::init_any_proxy_consumer (ACE_ENV_SINGLE_ARG_DECL) +{ + bool ok = false; + CosNotifyChannelAdmin::ProxyConsumer_var proxy; + if (this->reconnecting_) + { + ACE_TRY_NEW_ENV + { + proxy = this->sa_->get_proxy_consumer( + this->any_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Reconnect to proxy %d\n"), + ACE_static_cast (int, this->any_proxy_id_) + )); + } + } + ACE_CATCHALL + { + } + ACE_ENDTRY; + } + + if (!ok) + { + proxy = this->sa_->obtain_notification_push_consumer( + CosNotifyChannelAdmin::ANY_EVENT, + this->any_proxy_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + ok = ! CORBA::is_nil (proxy.in ()); + if (ok && this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier: Create new proxy %d\n"), + ACE_static_cast (int, this->any_proxy_id_) + )); + } + } + this->any_proxy_push_consumer_ = + CosNotifyChannelAdmin::ProxyPushConsumer::_narrow(proxy.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (this->any_proxy_push_consumer_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Supplier: Received wrong type of push consumer proxy %d\n"), + ACE_static_cast (int, this->any_proxy_id_) + )); + ACE_THROW (CORBA::UNKNOWN()); + } + + if (CORBA::is_nil (this->any_push_supplier_ref_.in ())) + { + PortableServer::ObjectId_var push_supplier_id = + this->root_poa_->activate_object ( + &(this->any_push_supplier_) ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var obj = + this->root_poa_->id_to_reference (push_supplier_id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->any_push_supplier_ref_ = + CosNotifyComm::PushSupplier::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + if (CORBA::is_nil (any_push_supplier_ref_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Supplier: Received wrong type of push consumer proxy %d\n"), + ACE_static_cast (int, this->sequence_proxy_id_) + )); + ACE_THROW (CORBA::UNKNOWN()); + } + + this->any_proxy_push_consumer_->connect_any_push_supplier ( + any_push_supplier_ref_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +int Supplier_Main::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->disconnect_on_exit_) + { + this->reconnection_callback_.fini (ACE_ENV_SINGLE_ARG_PARAMETER); + if (!CORBA::is_nil (this->structured_proxy_push_consumer_.in ())) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Disconnecting structured\n") + )); + } + this->structured_proxy_push_consumer_->disconnect_structured_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-4); + } + if (!CORBA::is_nil (this->sequence_proxy_push_consumer_.in ())) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Disconnecting sequence\n") + )); + } + this->sequence_proxy_push_consumer_->disconnect_sequence_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-4); + } + if (!CORBA::is_nil (this->any_proxy_push_consumer_.in ())) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Disconnecting any\n") + )); + } + this->any_proxy_push_consumer_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-4); + } + if (!CORBA::is_nil (this->sa_.in ()) && this->sa_id_ != default_admin_id) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) destroy admin %d\n"), + ACE_static_cast(int, this->sa_id_) + )); + } + this->sa_->destroy(); + } + } + this->orb_->shutdown (); + return 0; +} + +void Supplier_Main::send_structured_event (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotification::StructuredEvent event; + + // EventHeader. + + // FixedEventHeader. + // EventType. + // string. + event.header.fixed_header.event_type.domain_name = CORBA::string_dup("*"); + // string + event.header.fixed_header.event_type.type_name = CORBA::string_dup("*"); + // string + event.header.fixed_header.event_name = CORBA::string_dup("reconnect_test"); + + // OptionalHeaderFields. + // PropertySeq. + // sequence<Property>: string name, any value + CosNotification::PropertySeq& qos = event.header.variable_header; + qos.length (2); + qos[0].name = CORBA::string_dup (CosNotification::Priority); + qos[0].value <<= CosNotification::LowestPriority; + qos[1].name = CORBA::string_dup (CosNotification::EventReliability); + qos[1].value <<= CosNotification::Persistent; + + // FilterableEventBody + // PropertySeq + // sequence<Property>: string name, any value + event.filterable_data.length (1); + event.filterable_data[0].name = CORBA::string_dup("serial_number"); + event.filterable_data[0].value <<= CORBA::ULong ( this->serial_number_); + + // any + event.remainder_of_body <<= CORBA::ULong ( this->serial_number_); + + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Supplier push structured event %d\n"), + ACE_static_cast (int, serial_number_) + )); + } + + this->structured_proxy_push_consumer_->push_structured_event (event + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void Supplier_Main::send_sequence_event (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotification::EventBatch event_batch(1); + event_batch.length (1); + CosNotification::StructuredEvent & event = event_batch[0]; + + // EventHeader. + + // FixedEventHeader. + // EventType. + // string. + event.header.fixed_header.event_type.domain_name = CORBA::string_dup("*"); + // string + event.header.fixed_header.event_type.type_name = CORBA::string_dup("*"); + // string + event.header.fixed_header.event_name = CORBA::string_dup("reconnect_test"); + + // OptionalHeaderFields. + // PropertySeq. + // sequence<Property>: string name, any value + CosNotification::PropertySeq& qos = event.header.variable_header; + qos.length (2); + qos[0].name = CORBA::string_dup (CosNotification::Priority); + qos[0].value <<= CosNotification::LowestPriority; + qos[1].name = CORBA::string_dup (CosNotification::EventReliability); + qos[1].value <<= CosNotification::Persistent; + + // FilterableEventBody + // PropertySeq + // sequence<Property>: string name, any value + event.filterable_data.length (1); + event.filterable_data[0].name = CORBA::string_dup("serial_number"); + event.filterable_data[0].value <<= CORBA::ULong ( this->serial_number_); + + // any + event.remainder_of_body <<= CORBA::ULong ( this->serial_number_); + + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Supplier push sequence events %d\n"), + ACE_static_cast (int, this->serial_number_) + )); + } + + this->sequence_proxy_push_consumer_->push_structured_events (event_batch + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void Supplier_Main::send_any_event (ACE_ENV_SINGLE_ARG_DECL) +{ + CORBA::Any event; + event <<= CORBA::ULong (this->serial_number_); + + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Supplier push any event %d\n"), + ACE_static_cast (int, this->serial_number_) + )); + } + + this->any_proxy_push_consumer_->push (event + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +int Supplier_Main::run (ACE_ENV_SINGLE_ARG_DECL) +{ + int result = 0; + bool paused = false; + size_t reconnections = 0; + + size_t send = 0; + while ( send < this->send_) + { + // keep the orb alive -- listenting for reconnect + if (this->orb_->work_pending ()) + { + this->orb_->perform_work (); + } + + if (this->pause_ != 0 && send == this->pause_) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier paused after %d events\n"), + ACE_static_cast (int, this->pause_) + )); + } + reconnections = this->reconnection_callback_.reconnect_count (); + FILE * pause_file = ACE_OS::fopen ("Supplier.paused", "w"); + if (pause_file != 0) + { + ACE_OS::fputs (ACE_TEXT ("paused\n"), pause_file); + ACE_OS::fclose (pause_file); + } + paused = true; + this->pause_ = 0; + } + if (paused) + { + if (this->reconnection_callback_.reconnect_count () != reconnections) + { + if (this->verbose_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Supplier no longer paused. Next s# %d\n"), + ACE_static_cast (int, this->serial_number_) + )); + } + paused = false; + } + } + + if (!paused) + { + switch (this->mode_) + { + case MODE_STRUCTURED: + { + send_structured_event (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + break; + } + case MODE_SEQUENCE: + { + send_sequence_event (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + break; + } + case MODE_ANY: + { + send_any_event (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + break; + } + } + this->serial_number_ += 1; + send += 1; + } + } + return result; +} + + +int +main (int argc, char *argv[]) +{ + int result = -1; + Supplier_Main app; + ACE_TRY_NEW_ENV + { + result = app.init(argc, argv ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK + + if (result == 0) + { + result = app.run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + if (result == 0) + { + app.fini (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Supplier::main\t\n"); + result = -1; + } + ACE_ENDTRY; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P,%t) Supplier exits: code %d\n"), + result + )); + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/Supplier.h b/TAO/orbsvcs/tests/Notify/Reconnecting/Supplier.h new file mode 100644 index 00000000000..f429cf7892c --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/Supplier.h @@ -0,0 +1,209 @@ +/* -*- C++ -*- */ +// $Id$ +// ========================================================================== +// +// = FILENAME +// Supplier.h +// +// = DESCRIPTION +// Test Supplier reconnect to existing channel/admin/proxy Notification Service +// +// = AUTHOR +// Dale Wilson <wilson_d@ociweb.com> +// +// ========================================================================== + +#ifndef RECONNECTNG_SUPPLIER_H +#define RECONNECTNG_SUPPLIER_H + +#include "orbsvcs/CosNotifyChannelAdminC.h" +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/NotifyExtS.h" +#include <ace/SString.h> + +class Supplier_Main; + +class StructuredPushSupplier_i : public virtual POA_CosNotifyComm::StructuredPushSupplier +{ + virtual void subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)); + + virtual void disconnect_structured_push_supplier ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); +}; + +class SequencePushSupplier_i : public virtual POA_CosNotifyComm::SequencePushSupplier +{ + virtual void subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)); + + virtual void disconnect_sequence_push_supplier ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); +}; + +class AnyPushSupplier_i : public virtual POA_CosNotifyComm::PushSupplier +{ + virtual void subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType)); + + virtual void disconnect_push_supplier ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); +}; + +class ReconnectionCallback_i : public virtual POA_NotifyExt::ReconnectionCallback +{ +public: + ReconnectionCallback_i (Supplier_Main & supplier_main); + + virtual ~ReconnectionCallback_i (); + + void init ( + PortableServer::POA_ptr poa, + CosNotifyChannelAdmin::EventChannelFactory_ptr ecf_ + ACE_ENV_ARG_DECL); + + void fini (ACE_ENV_SINGLE_ARG_DECL); + + size_t reconnect_count () const; + + virtual void reconnect ( + CORBA::Object_ptr reconnection + ACE_ENV_ARG_DECL + ) ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + Supplier_Main & supplier_main_; + bool id_is_valid_; + NotifyExt::ReconnectionRegistry::ReconnectionID callback_id_; + CosNotifyChannelAdmin::EventChannelFactory_var ecf_; + size_t reconnect_count_; +}; + +class Supplier_Main +{ + public: + Supplier_Main (); + ~Supplier_Main (); + + int parse_args (int argc, char *argv[]); + int parse_single_arg (int argc, char *argv[]); + + int init (int argc, char *argv[] ACE_ENV_ARG_DECL); + int run (ACE_ENV_SINGLE_ARG_DECL); + int fini (ACE_ENV_SINGLE_ARG_DECL); + void usage (FILE * log) const; + + void reconnect ( + CosNotifyChannelAdmin::EventChannelFactory_ptr dest_factory + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + private: + /// Find naming service. + int resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL); + + /// Resolve the Notify factory from the Naming service. + int find_notify_factory (ACE_ENV_SINGLE_ARG_DECL); + + /// Resolve the Notify factory using resolve_initial_reference ("NotifyEventChannelFactory") + int resolve_notify_factory (ACE_ENV_SINGLE_ARG_DECL); + + void init_event_channel (ACE_ENV_SINGLE_ARG_DECL); + void init_supplier_admin (ACE_ENV_SINGLE_ARG_DECL); + void init_structured_proxy_consumer (ACE_ENV_SINGLE_ARG_DECL); + void init_sequence_proxy_consumer (ACE_ENV_SINGLE_ARG_DECL); + void init_any_proxy_consumer (ACE_ENV_SINGLE_ARG_DECL); + + /// send events. + void send_structured_event (ACE_ENV_SINGLE_ARG_DECL); + void send_sequence_event (ACE_ENV_SINGLE_ARG_DECL); + void send_any_event (ACE_ENV_SINGLE_ARG_DECL); + + void save_ids(); + bool load_ids(); + + //////////////////// + // forbidden methods + private: + Supplier_Main (const Supplier_Main & rhs); + Supplier_Main & operator = (const Supplier_Main & rhs); + + //////////////// + // Data members + private: + + // set by command line parameters + bool verbose_; // -v make a glorious noise + enum Mode_T { + MODE_ANY, + MODE_STRUCTURED, + MODE_SEQUENCE} mode_; // -any, -structured, or -sequence + ACE_CString channel_file_; // -channel filename + size_t send_; // -send n + bool use_naming_service_; // -nonamesvc + size_t serial_number_; // -serial_number + bool disconnect_on_exit_; // -disconnect + ACE_CString id_file_; // -ids + size_t pause_; // -pause n (pause after sending n messages) + CORBA::ORB_var orb_; + PortableServer::POA_var root_poa_; + CosNaming::NamingContext_var naming_context_; + CosNotifyChannelAdmin::EventChannelFactory_var ecf_; + + CosNotifyChannelAdmin::EventChannel_var ec_; + CosNotifyChannelAdmin::ChannelID ec_id_; + + CosNotifyChannelAdmin::SupplierAdmin_var sa_; + CosNotifyChannelAdmin::AdminID sa_id_; + + CosNotifyChannelAdmin::StructuredProxyPushConsumer_var structured_proxy_push_consumer_; + CosNotifyChannelAdmin::ProxyID structured_proxy_id_; + StructuredPushSupplier_i structured_push_supplier_; + CosNotifyComm::StructuredPushSupplier_var structured_push_supplier_ref_; + + + CosNotifyChannelAdmin::SequenceProxyPushConsumer_var sequence_proxy_push_consumer_; + CosNotifyChannelAdmin::ProxyID sequence_proxy_id_; + SequencePushSupplier_i sequence_push_supplier_; + CosNotifyComm::SequencePushSupplier_var sequence_push_supplier_ref_; + + CosNotifyChannelAdmin::ProxyPushConsumer_var any_proxy_push_consumer_; + CosNotifyChannelAdmin::ProxyID any_proxy_id_; + AnyPushSupplier_i any_push_supplier_; + CosNotifyComm::PushSupplier_var any_push_supplier_ref_; + + ReconnectionCallback_i reconnection_callback_; + + bool reconnecting_; +}; + + + +#endif /* RECONNECTNG_SUPPLIER_H */ diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/event.conf b/TAO/orbsvcs/tests/Notify/Reconnecting/event.conf new file mode 100644 index 00000000000..e9cc17ec979 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/event.conf @@ -0,0 +1,6 @@ + +static TAO_CosNotify_Service "-AllowReconnect" + +# This should fail because event perstence requires topology persistence + +dynamic Event_Persistence Service_Object* TAO_CosNotification:_make_Standard_Event_Persistence() "-v -file_path ./event_persist.db"
\ No newline at end of file diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/ns_mt.conf b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_mt.conf new file mode 100644 index 00000000000..be282852191 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_mt.conf @@ -0,0 +1,10 @@ + +## -DispatchingThreads N - creates a thread pool for dispatching and consumer side filter eval +## -SourceThreads M - creates a thread pool for lookup and supplier side filter eval + +## This prevents worker threads from joining the tp reactor +##static Client_Strategy_Factory "-ORBClientConnectionHandler rw" + +static TAO_CosNotify_Service "-DispatchingThreads 2 -SourceThreads 2 -AllowReconnect" + + diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/ns_mt_both.conf b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_mt_both.conf new file mode 100644 index 00000000000..827376b2a71 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_mt_both.conf @@ -0,0 +1,5 @@ +static TAO_CosNotify_Service "-DispatchingThreads 2 -SourceThreads 2 -AllowReconnect" + +dynamic Topology_Factory Service_Object* TAO_CosNotification_Persist:_make_XML_Topology_Factory() "-base_path ./reconnect_test" +dynamic Event_Persistence Service_Object* TAO_CosNotification_Persist:_make_Standard_Event_Persistence() "-file_path ./event_persist.db" + diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/ns_mt_topo.conf b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_mt_topo.conf new file mode 100644 index 00000000000..06147c0fe8a --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_mt_topo.conf @@ -0,0 +1,3 @@ +static TAO_CosNotify_Service "-DispatchingThreads 2 -SourceThreads 2 -AllowReconnect" +dynamic Topology_Factory Service_Object* TAO_CosNotification_Persist:_make_XML_Topology_Factory() "-base_path ./reconnect_test" + diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/ns_st.conf b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_st.conf new file mode 100644 index 00000000000..fc890d01fc2 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_st.conf @@ -0,0 +1,4 @@ + +static TAO_CosNotify_Service "-AllowReconnect" + + diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/ns_st_both.conf b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_st_both.conf new file mode 100644 index 00000000000..6c07255dcb2 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_st_both.conf @@ -0,0 +1,4 @@ +static TAO_CosNotify_Service "-AllowReconnect" + +dynamic Topology_Factory Service_Object* TAO_CosNotification_Persist:_make_XML_Topology_Factory() "-v -base_path ./reconnect_test" +dynamic Event_Persistence Service_Object* TAO_CosNotification_Persist:_make_Standard_Event_Persistence() "-v -file_path ./event_persist.db" diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/ns_st_topo.conf b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_st_topo.conf new file mode 100644 index 00000000000..e84d2c18713 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/ns_st_topo.conf @@ -0,0 +1,2 @@ +static TAO_CosNotify_Service "-AllowReconnect" +dynamic Topology_Factory Service_Object* TAO_CosNotification_Persist:_make_XML_Topology_Factory() "-v -base_path ./reconnect_test" diff --git a/TAO/orbsvcs/tests/Notify/Reconnecting/run_test.pl b/TAO/orbsvcs/tests/Notify/Reconnecting/run_test.pl new file mode 100755 index 00000000000..8d964e69644 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Reconnecting/run_test.pl @@ -0,0 +1,390 @@ +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($eventType) = "-any"; # your choice of -any -structured or -sequence + +my($ACE_ROOT) = $ENV{ACE_ROOT}; +my($TAO_ROOT) = "$ACE_ROOT/TAO"; + +my($notify_port) = "9889"; + +#file used to detect notification service startup +my($notify_ior) = PerlACE::LocalFile("notify.ior"); +#hard coded file name in Consumer.cpp (for now) +my($consumer_ids) = PerlACE::LocalFile("consumer.ids"); +#hard coded file name in Supplier.cpp (for now) +my($supplier_ids) = PerlACE::LocalFile("supplier.ids"); +#file used to communicate channel # from consumer to supplier +my($channel_id) = PerlACE::LocalFile("channel_id"); +#file names comes from svc.conf (+.xml & .000) +my($save_xml) = PerlACE::LocalFile("./reconnect_test.xml"); +my($save_000) = PerlACE::LocalFile("./reconnect_test.000"); +my($eventpersist) = PerlACE::LocalFile("./event_persist.db"); +# hardcode filename written by the Supplier when it pauses. +my($supplier_pause) = PerlACE::LocalFile("Supplier.paused"); + +my($verbose) = ""; + +my $svcconf = "ns_st_topo.conf"; + +# Process command line arguments +foreach $i (@ARGV) { + if ($i eq "-any") { + $eventType = "-any"; + } + elsif ($i eq "-str" or $i eq "-structured") { + $eventType = "-structured"; + } + elsif ($i eq "-seq" or $i eq "-sequence") { + $eventType = "-sequence"; + } + elsif ($i eq "-mt") { + $svcconf = "ns_mt_topo.conf"; + } + elsif ($i eq "-v" or $i eq "-verbose") { + $verbose = "-v"; + } + else { + print "TEST SCRIPT: unknown: $i\n"; + print "TEST SCRIPT: usage: [-any|-str|-seq] -mt -v\n"; + exit -4; + } +} + +my($client_args) = " $eventType $verbose -NoNameSvc -ORBInitRef NotifyEventChannelFactory=corbaloc::localhost:$notify_port/NotifyEventChannelFactory "; +my($ns_args) = " -NoNameSvc -Boot -ORBSvcConf $svcconf -IORoutput $notify_ior -ORBEndpoint iiop://:$notify_port "; +#my($ns_args_hidden) = " -NoNameSvc -Boot -ORBSvcConf $svcconf -IORoutput $notify_ior"; +# nuke the topology save files so we start clean +unlink $save_xml; +unlink $save_000; +unlink $eventpersist; +unlink $notify_ior; + + +##define the processes first +my($NS) = new PerlACE::Process("$TAO_ROOT/orbsvcs/Notify_Service/Notify_Service"); +my($CON) = new PerlACE::Process("./Consumer"); +my($SUP) = new PerlACE::Process("./Supplier"); + +if ($verbose eq "-v") {print "TEST SCRIPT: Starting Notify Service on port $notify_port\n";} +$NS->Arguments($ns_args); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $NS->CommandLine . "\n";} +print $NS->CommandLine (); +$NS->Spawn(); + +# the ior file is only used to wait for the service to start +if (PerlACE::waitforfile_timed ($notify_ior, 10) == -1) { + print STDERR "ERROR: Timed out waiting for $notify_ior\n"; + $NS->Kill (); + exit 1; +} +# be sure consumer doesn't try to reconnect the first time +unlink $consumer_ids; +# don't use previous channel id +unlink $channel_id; + +# start the consumer, +# write the channel number to channel.id for use by Supplier +# expect to receive 20 events of type any +# +$CON->Arguments("-channel $channel_id -expect 20 $client_args"); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $CON->CommandLine . "\n";} +print $CON->CommandLine (); +$CON->Spawn(); + +# wait for the channel number file +if (PerlACE::waitforfile_timed ($channel_id, 10) == -1) { + print STDERR "ERROR: Timed out waiting for Consumer to write $channel_id\n"; + $NS->Kill (); + $CON->Kill (); + exit 1; +} + +# discard old reconnect information +unlink $supplier_ids; + +# send 10 Any's, picking up the channel# from channel.id +$SUP->Arguments("-channel $channel_id -send 10 $client_args"); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $SUP->CommandLine . "\n";} +print $SUP->CommandLine (); +$SUP->SpawnWaitKill(60); + +# forget the channel id, depend on the reconnect information +unlink $channel_id; + +$SUP->Arguments("-send 10 -serial_number 10 $client_args"); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $SUP->CommandLine . "\n";} +print $SUP->CommandLine (); +$SUP->SpawnWaitKill(60); + +$status = $CON->WaitKill (60); + +if ($status) { + print STDERR "ERROR: Consumer reported error\n"; + $NS->Kill(); + exit $status; + } + +print "TEST SCRIPT: ****Passed: Supplier reconnect test.\n"; + +################ +#end of test 1 +################ + +# Now start the consumer again. Depending on reconnect this time +# Let it write the channel.id file so we know when it's up. + +if ($verbose eq "-v") {print "TEST SCRIPT: " . $CON->CommandLine . "\n";} +$CON->Spawn(); +# wait for the channel number file +if (PerlACE::waitforfile_timed ($channel_id, 10) == -1) { + print STDERR "ERROR: Timed out waiting for Consumer to write $channel_id\n"; + $NS->Kill (); + $CON->Kill (); + exit 1; +} + +# forget the channel id, depend on the supplier reconnect information +unlink $channel_id; + +$SUP->Arguments("-send 20 -serial_number 0 $client_args"); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $SUP->CommandLine . "\n";} +$status= $SUP->SpawnWaitKill(60); +if ($status) { + print STDERR "ERROR: Supplier reported error\n"; + $CON->Kill(); + $NS->Kill(); + exit $status; + } + +$status = $CON->WaitKill (60); +if ($status) { + print STDERR "ERROR: Consumer reported error\n"; + $NS->Kill(); + exit $status; + } + +print "TEST SCRIPT: ****Passed: Consumer reconnect test.\n"; + +################ +#end of test 2 +################ + +if ($verbose eq "-v") {print "TEST SCRIPT: Stop the Notification Service\n";} +$NS->Kill(); +unlink $notify_ior; + +if ($verbose eq "-v") {print "TEST SCRIPT: Restarting Notify Service on port $notify_port\n";} +if ($verbose eq "-v") {print "TEST SCRIPT: It should load topology from $save_xml\n";} + +# sleep to avoid socket-related problems +sleep (10 * $PerlACE::Process::WAIT_DELAY_FACTOR); +$NS->Arguments($ns_args); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $NS->CommandLine . "\n";} +$NS->Spawn(); + +# the ior file is only used to wait for the service to start +if (PerlACE::waitforfile_timed ($notify_ior, 10) == -1) { + print STDERR "ERROR: Timed out waiting for $notify_ior\n"; + $NS->Kill (); + exit 1; +} + +# Now start the consumer again. It will use the reconnect info. +# Let it write the channel.id file so we know when it's up. +unlink $channel_id; + +if ($verbose eq "-v") {print "TEST SCRIPT: " . $CON->CommandLine . "\n";} +$CON->Spawn(); +# wait for the channel number file +if (PerlACE::waitforfile_timed ($channel_id, 10) == -1) { + print STDERR "ERROR: Timed out waiting for Consumer to write $channel_id\n"; + $NS->Kill (); + $CON->Kill (); + exit 1; +} + +# forget the channel id, depend on the supplier reconnect information +unlink $channel_id; + +$SUP->Arguments("-send 20 -serial_number 0 $client_args"); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $SUP->CommandLine . "\n";} +$status = $SUP->SpawnWaitKill(60); +if ($status) { + print STDERR "ERROR: Supplier reported error\n"; + $NS->Kill(); + $CON->Kill(); + exit $status; + } + +$status = $CON->WaitKill (60); +if ($status) { + print STDERR "ERROR: Consumer reported error\n"; + $NS->Kill(); + exit $status; + } + +print "TEST SCRIPT: ****Passed: Topology Persistence Test.\n"; + +################ +#end of test 3 +################ + +# Now start the consumer one more time +# Let it write the channel.id file so we know when it's up. +unlink $channel_id; + +if ($verbose eq "-v") {print "TEST SCRIPT: " . $CON->CommandLine . "\n";} +$CON->Spawn(); +# wait for the channel number file +if (PerlACE::waitforfile_timed ($channel_id, 10) == -1) { + print STDERR "ERROR: Timed out waiting for Consumer to write $channel_id\n"; + $NS->Kill (); + $CON->Kill (); + exit 1; +} + +# forget the channel id, depend on the supplier reconnect information +unlink $channel_id; + +# Start the Supplier, tell it to send 10 messages, pause until it is reconnected +# then send another 10. + +unlink ($supplier_pause); + +$SUP->Arguments("-send 20 -pause 10 -serial_number 0 $client_args"); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $SUP->CommandLine . "\n";} +$SUP->Spawn(); + +# wait for the supplier's "paused" file +if (PerlACE::waitforfile_timed ($supplier_pause, 30) == -1) { + print STDERR "ERROR: Timed out waiting for Supplier to write $supplier_pause\n"; + $NS->Kill (); + $SUP->Kill (); + $CON->Kill (); + exit 1; +} +unlink ($supplier_pause); + +if ($verbose eq "-v") {print "TEST SCRIPT: Stop the Notification Service\n";} +$NS->Kill(); +unlink $notify_ior; + +if ($verbose eq "-v") {print "TEST SCRIPT: Restarting Notify Service\n";} +if ($verbose eq "-v") {print "TEST SCRIPT: Use unspecified port to make it \"invisible\" to clients\n";} +if ($verbose eq "-v") {print "TEST SCRIPT: It should load topology from $save_xml\n";} +if ($verbose eq "-v") {print "TEST SCRIPT: and reconnect to registered clients.\n";} + +#$NS->Arguments($ns_args_hidden); +# sleep to avoid socket-related problems +sleep (10 * $PerlACE::Process::WAIT_DELAY_FACTOR); + +if ($verbose eq "-v") {print "TEST SCRIPT: " . $NS->CommandLine . "\n";} +$NS->Spawn(); + +# at this point, both the consumer and the supplier should reconnect +# and the remaining events should be delivered +# eventually the consumer will finish + +$status = $CON->WaitKill (20); +if ($status) { + print STDERR "ERROR: Consumer reported error\n"; + $SUP->Kill(); + $NS->Kill(); + exit $status; + } + +$status = $SUP->Kill (); +if ($status) { + print STDERR "ERROR: Supplier reported error\n"; + $NS->Kill(); + exit $status; + } + +print "TEST SCRIPT: ****Passed: Reconnection Factory test.\n"; + +################ +#end of test 4 +################ + +if ($verbose eq "-v") {print "TEST SCRIPT: Stop the Notification Service\n";} +$NS->Kill(); + +unlink $notify_ior; +unlink $save_xml; +unlink $save_000; +unlink $eventpersist; +unlink $consumer_ids; +unlink $channel_id; +unlink $supplier_ids; + +sleep (10 * $PerlACE::Process::WAIT_DELAY_FACTOR); ## avoid lingering sockets +# go back to normal ns args +$NS->Arguments($ns_args); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $NS->CommandLine . "\n";} +$NS->Spawn(); + +# the ior file is only used to wait for the service to start +if (PerlACE::waitforfile_timed ($notify_ior, 20) == -1) { + print STDERR "ERROR: Timed out waiting for $notify_ior\n"; + $NS->Kill (); + exit 1; +} + +#configure the consumer to expect 20 events, fail (throw an exception +# after 8 events) then continue to listen for remaining events. +#The Notification service should automatically retry (but may discard) +# the failed events. +$CON->Arguments("-channel $channel_id -expect 20 -fail 8 $client_args"); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $CON->CommandLine . "\n";} +$CON->Spawn(); + +# wait for the channel number file +if (PerlACE::waitforfile_timed ($channel_id, 10) == -1) { + print STDERR "ERROR: Timed out waiting for Consumer to write $channel_id\n"; + $NS->Kill (); + $CON->Kill (); + exit 1; +} + +$SUP->Arguments("-channel $channel_id -send 20 $client_args"); +if ($verbose eq "-v") {print "TEST SCRIPT: " . $SUP->CommandLine . "\n";} +$status = $SUP->SpawnWaitKill(20); +if ($status) { + print STDERR "ERROR: Supplier reported error\n"; + $NS->Kill(); + $CON->Kill (); + exit $status; + } + +## this is a slow test due to the reconnection +## time, so give it enough time... +$status = $CON->WaitKill (240); + +if ($status) { + print STDERR "ERROR: Consumer reported error\n"; + $NS->Kill(); + exit $status; + } + +print "TEST SCRIPT: ****Passed: Consumer recoverable exception test.\n"; + +################ +#end of test 5 +################ + +if ($verbose eq "-v") {print "TEST SCRIPT: Stop the Notification Service\n";} +$NS->Kill(); +unlink $notify_ior; +unlink $save_xml; +unlink $save_000; +unlink $eventpersist; + +exit $status; diff --git a/TAO/orbsvcs/tests/Notify/XML_Persistence/XML_Persistence.mpc b/TAO/orbsvcs/tests/Notify/XML_Persistence/XML_Persistence.mpc new file mode 100644 index 00000000000..040b6dab9f0 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/XML_Persistence/XML_Persistence.mpc @@ -0,0 +1,2 @@ +project : orbsvcsexe, portableserver, notify_serv { +} diff --git a/TAO/orbsvcs/tests/Notify/XML_Persistence/main.cpp b/TAO/orbsvcs/tests/Notify/XML_Persistence/main.cpp new file mode 100644 index 00000000000..d5fc70bfc38 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/XML_Persistence/main.cpp @@ -0,0 +1,360 @@ +/** + * $Id$ + */ + +#include <orbsvcs/orbsvcs/CosNotificationC.h> +#include <orbsvcs/orbsvcs/NotifyExtC.h> +#include <orbsvcs/orbsvcs/Notify/Notify_EventChannelFactory_i.h> + +#include <tao/TimeBaseC.h> +#include <tao/corba.h> +#include <tao/PortableServer/PortableServer.h> + +#include "ace/OS_NS_string.h" +#include <ace/OS_NS_stdio.h> +#include <ace/Dynamic_Service.h> +#include <ace/ARGV.h> + +class TestSupplier +: public POA_CosNotifyComm::StructuredPushSupplier +{ + virtual void disconnect_structured_push_supplier(ACE_ENV_SINGLE_ARG_DECL_NOT_USED) throw (CORBA::SystemException) { + } + + virtual void subscription_change( const CosNotification::EventTypeSeq&, + const CosNotification::EventTypeSeq& ACE_ENV_ARG_DECL_NOT_USED) + throw (CORBA::SystemException, CosNotifyComm::InvalidEventType) + { + } +}; + +class TestConsumer +: public POA_CosNotifyComm::StructuredPushConsumer +{ + virtual void disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_DECL_NOT_USED) throw (CORBA::SystemException) { + } + + virtual void offer_change( const CosNotification::EventTypeSeq&, const CosNotification::EventTypeSeq& ACE_ENV_ARG_DECL_NOT_USED) + throw (CORBA::SystemException, CosNotifyComm::InvalidEventType) + { + } + + virtual void push_structured_event(const CosNotification::StructuredEvent& ACE_ENV_ARG_DECL_NOT_USED) + throw (CORBA::SystemException, CosEventComm::Disconnected) + { + } +}; + +int main(int ac, char **av) +{ + int retval = 1; + + bool pass1 = false; + bool pass2 = false; + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::ORB_var orb; + PortableServer::POA_var poa; + + orb = CORBA::ORB_init(ac, av, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_ASSERT(! CORBA::is_nil (orb.in ())); + + if (ac > 2 + && ACE_OS::strcmp (av[1], "-pass")) + { + int pn = av[2][0] - '0'; + switch (pn) + { + case 1: + pass1 = true; + pass2 = false; + break; + case 2: + pass1 = false; + pass2 = true; + break; + case 3: + pass1 = true; + pass2 = true; + break; + default: + fprintf (stderr, "Illegal -pass command line option. Expecting 1, 2, or 3\n"); + return -1; + } + } + if (! pass1 && !pass2) + { + FILE *f; + f = fopen ("loadtest.xml", "r"); + if (f != 0) + { + fclose (f); + pass1 = false; + pass2 = true; + } + else + { + pass1 = true; + pass2 = false; + } + } + CORBA::Object_var obj = + orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_ASSERT(! CORBA::is_nil (obj.in ())); + poa = PortableServer::POA::_narrow(obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_ASSERT(! CORBA::is_nil (poa.in ())); + PortableServer::POAManager_var mgr = poa->the_POAManager(); + mgr->activate(); + + if (pass1) + { + CosNotifyChannelAdmin::EventChannelFactory_var cosecf = + TAO_Notify_EventChannelFactory_i::create(poa.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + NotifyExt::EventChannelFactory_var ecf = + NotifyExt::EventChannelFactory::_narrow (cosecf.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (ecf.in ())) + { + return -1; + } + + CosNotification::QoSProperties qosprops(7); + CORBA::ULong i = 0; + + qosprops.length(7); + qosprops[i].name = CORBA::string_dup(CosNotification::EventReliability); + qosprops[i++].value <<= CosNotification::Persistent; + qosprops[i].name = CORBA::string_dup(CosNotification::ConnectionReliability); + qosprops[i++].value <<= CosNotification::Persistent; // Required, or we won't persist much + qosprops[i].name = CORBA::string_dup(CosNotification::Priority); + qosprops[i++].value <<= CosNotification::HighestPriority; + qosprops[i].name = CORBA::string_dup(CosNotification::Timeout); + qosprops[i++].value <<= (TimeBase::TimeT) 42000; + qosprops[i].name = CORBA::string_dup(CosNotification::StopTimeSupported); + qosprops[i++].value <<= CORBA::Any::from_boolean(1); + qosprops[i].name = CORBA::string_dup(CosNotification::MaximumBatchSize); + qosprops[i++].value <<= (CORBA::Long) 555; + qosprops[i].name = CORBA::string_dup(CosNotification::PacingInterval); + qosprops[i++].value <<= (TimeBase::TimeT) 34300; + qosprops.length(i); + + CosNotification::AdminProperties adminprops(4); + adminprops.length(4); + i = 0; + adminprops[i].name = CORBA::string_dup(CosNotification::MaxQueueLength); + adminprops[i++].value <<= (CORBA::Long) 1234; + adminprops[i].name = CORBA::string_dup(CosNotification::MaxConsumers); + adminprops[i++].value <<= (CORBA::Long) 3; + adminprops[i].name = CORBA::string_dup(CosNotification::MaxSuppliers); + adminprops[i++].value <<= (CORBA::Long) 3; + adminprops[i].name = CORBA::string_dup(CosNotification::RejectNewEvents); + adminprops[i++].value <<= CORBA::Any::from_boolean(1); + adminprops.length (i); + + CosNotifyChannelAdmin::ChannelID ecid; + ::CosNotifyChannelAdmin::EventChannel_var ec = + ecf->create_channel(qosprops, adminprops, ecid ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyChannelAdmin::AdminID consumer_admin_id; + CosNotifyChannelAdmin::ConsumerAdmin_var ca = + ec->new_for_consumers(CosNotifyChannelAdmin::OR_OP, + consumer_admin_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyChannelAdmin::AdminID supplier_admin_id; + CosNotifyChannelAdmin::SupplierAdmin_var sa = + ec->new_for_suppliers(CosNotifyChannelAdmin::OR_OP, + supplier_admin_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyChannelAdmin::ProxyID proxy_id; + CosNotifyChannelAdmin::ProxySupplier_var ps = + ca->obtain_notification_push_supplier( + CosNotifyChannelAdmin::STRUCTURED_EVENT, + proxy_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyChannelAdmin::StructuredProxyPushSupplier_var strps = + CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow(ps.in()); + + ps = ca->obtain_notification_push_supplier( + CosNotifyChannelAdmin::SEQUENCE_EVENT, + proxy_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyChannelAdmin::SequenceProxyPushSupplier_var seqps = + CosNotifyChannelAdmin::SequenceProxyPushSupplier::_narrow(ps.in()); + + ps = ca->obtain_notification_push_supplier( + CosNotifyChannelAdmin::ANY_EVENT, + proxy_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyChannelAdmin::ProxyPushSupplier_var anyps = + CosNotifyChannelAdmin::ProxyPushSupplier::_narrow(ps.in()); + + CosNotifyChannelAdmin::ProxyConsumer_var pc = + sa->obtain_notification_push_consumer( + CosNotifyChannelAdmin::STRUCTURED_EVENT, + proxy_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyChannelAdmin::StructuredProxyPushConsumer_var strpc = CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow(pc.in()); + + pc = sa->obtain_notification_push_consumer( + CosNotifyChannelAdmin::SEQUENCE_EVENT, + proxy_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyChannelAdmin::SequenceProxyPushConsumer_var seqpc = CosNotifyChannelAdmin::SequenceProxyPushConsumer::_narrow(pc.in()); + + pc = + sa->obtain_notification_push_consumer( + CosNotifyChannelAdmin::ANY_EVENT, + proxy_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyChannelAdmin::ProxyPushConsumer_var anypc = CosNotifyChannelAdmin::ProxyPushConsumer::_narrow(pc.in()); + + CosNotifyFilter::FilterFactory_var ff = + ec->default_filter_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyFilter::Filter_var filter1 = + ff->create_filter("EXTENDED_TCL" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT(! CORBA::is_nil (filter1.in ())); + + CosNotifyFilter::Filter_var filter2 = + ff->create_filter("EXTENDED_TCL" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT(! CORBA::is_nil (filter2.in ())); + + CosNotifyFilter::ConstraintExpSeq constraint_list(1); + constraint_list.length(1); + constraint_list[0].event_types.length(0); + constraint_list[0].constraint_expr = CORBA::string_dup("Number == 100"); + + filter1->add_constraints(constraint_list ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + filter2->add_constraints(constraint_list ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ca->add_filter (filter1.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + sa->add_filter (filter2.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + strps->add_filter (filter1.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + seqps->add_filter (filter2.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + anyps->add_filter (filter1.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + strpc->add_filter (filter2.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + seqpc->add_filter (filter1.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + anypc->add_filter (filter1.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + anypc->add_filter (filter2.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotification::EventTypeSeq added1(1), removed1(0); + added1.length(1); + added1[0].domain_name = CORBA::string_dup("nightly_builds"); + added1[0].type_name = CORBA::string_dup("*"); + ca->subscription_change(added1, removed1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Connect a PushConsumer and PushSupplier + TestSupplier test_supplier_svt; + CosNotifyComm::StructuredPushSupplier_var push_sup = test_supplier_svt._this(); + TestConsumer test_consumer_svt; + CosNotifyComm::StructuredPushConsumer_var push_cons = test_consumer_svt._this(); + strpc->connect_structured_push_supplier(push_sup.in()); + strps->connect_structured_push_consumer(push_cons.in()); + + strps->suspend_connection(); + + ecf->destroy(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + //////////////////////////////// + // TODO make this not hardcoded + ACE_OS::rename ("abc.xml", "loadtest.xml"); + + } // end of pass 1 + + if (pass2) + { + + // Create a new ecf, which should load itself from loadtest.xml + CosNotifyChannelAdmin::EventChannelFactory_var + cosecf = TAO_Notify_EventChannelFactory_i::create(poa.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_TRY_CHECK; + NotifyExt::EventChannelFactory_var + ecf = NotifyExt::EventChannelFactory::_narrow (cosecf.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (ecf.in ())) + { + return -1; + } + + // Force a change, which should write out a new abc.xml. + ecf->save_topology (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ecf->destroy(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (1); + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (1); + poa = PortableServer::POA::_nil (); + orb = CORBA::ORB::_nil (); + retval = 0; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ex, "Unexpected exception caught in main. "); + retval = -1; + } + ACE_CATCHALL + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Error : Unknown exception caught in main.") )); + retval = -2; + } + ACE_ENDTRY; + return retval; +} diff --git a/TAO/orbsvcs/tests/Notify/XML_Persistence/run_test.pl b/TAO/orbsvcs/tests/Notify/XML_Persistence/run_test.pl new file mode 100755 index 00000000000..6b73d986e0f --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/XML_Persistence/run_test.pl @@ -0,0 +1,62 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# ex + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; +use File::Compare; + +$ACE_ROOT = $ENV{ACE_ROOT}; +$TAO_ROOT = "$ACE_ROOT/TAO"; + +sub cleanup() { + unlink "loadtest.xml"; + unlink "abc.xml"; + for ($i = 0; $i < 10; ++$i) { + unlink "abc.00" . $i; + } + for ($i = 10; $i < 20; ++$i) { + unlink "abc.0" . $i; + } +} + +cleanup(); + +$ret = 0; + +$UTEST = new PerlACE::Process("main"); +$ret = $UTEST->SpawnWaitKill(10); +if ($ret != 0) { + print "ERROR : main returned $ret\n"; + exit $ret; +} + +# NOTE: In TAO 1.3a main ran the notification service twice +# producing both abc.xml and loadtest.xml. Unfortunately +# in TAO 1.4 the notification service will does not run +# successfully the second time in the same EXE. +# -- todo figure out why and fix it. +# Thus main was modified to run in two passes. If loadtest.xml +# exists, it runs pass 2. +$ret = $UTEST->SpawnWaitKill(10); +if ($ret != 0) { + print "ERROR : main returned $ret\n"; + exit $ret; +} + +$different = compare("loadtest.xml", "abc.xml"); +if ($different) { + print "ERROR : loadtest.xml != abc.xml\n"; + exit 1; +} else { + print "Success : loadtest.xml == abc.xml\n"; + cleanup(); +} + + +exit $ret; diff --git a/TAO/orbsvcs/tests/Notify/XML_Persistence/svc.conf b/TAO/orbsvcs/tests/Notify/XML_Persistence/svc.conf new file mode 100644 index 00000000000..10b21998a5b --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/XML_Persistence/svc.conf @@ -0,0 +1,2 @@ +static Notify_Default_Event_Manager_Objects_Factory "-MTDispatching -DispatchingThreads 1" +dynamic Topology_Factory Service_Object* TAO_CosNotification_persist:_make_XML_Topology_Factory() "-save_base_path ./abc -load_base_path ./loadtest -backup_count 2 -no_timestamp" diff --git a/TAO/orbsvcs/tests/Notify/lib/Periodic_Consumer.cpp b/TAO/orbsvcs/tests/Notify/lib/Periodic_Consumer.cpp index 66d655dd9b6..efa4eb67f71 100644 --- a/TAO/orbsvcs/tests/Notify/lib/Periodic_Consumer.cpp +++ b/TAO/orbsvcs/tests/Notify/lib/Periodic_Consumer.cpp @@ -12,8 +12,8 @@ #include "LookupManager.h" #include "Priority_Mapping.h" -ACE_RCSID (RT_Notify, - TAO_Notify_Tests_Periodic_Consumer, +ACE_RCSID (RT_Notify, + TAO_Notify_Tests_Periodic_Consumer, "$Id$") int WARMUP_COUNT = 10; @@ -234,6 +234,8 @@ TAO_Notify_Tests_Periodic_Consumer::push_structured_event (const CosNotification // Eat CPU static CORBA::ULong prime_number = 9619; + (void)ACE::gcd (prime_number, prime_number/2 -1); + for (CORBA::ULong load = this->load_; load != 0; --load) ACE::is_prime (prime_number, 2, diff --git a/TAO/orbsvcs/tests/Notify/performance-tests/Filter/run_test.pl b/TAO/orbsvcs/tests/Notify/performance-tests/Filter/run_test.pl index 7dbaa140fca..2f1afb472bf 100755 --- a/TAO/orbsvcs/tests/Notify/performance-tests/Filter/run_test.pl +++ b/TAO/orbsvcs/tests/Notify/performance-tests/Filter/run_test.pl @@ -36,7 +36,9 @@ $SEC = new PerlACE::Process ("Sequence_Consumer"); $client_args = "-ORBInitRef NameService=iioploc://localhost:" . "$port/NameService"; $NS->Spawn (); +print $NS->CommandLine ()."\n"; $TS->Spawn (); +print $TS->CommandLine ()."\n"; if (PerlACE::waitforfile_timed ($notifyior, 20) == -1) { print STDERR "ERROR: waiting for the notify service to start\n"; @@ -49,6 +51,7 @@ print "********* Running Structured Consumer with two " . "consumers and no filter *******\n"; unlink $ior; +print $STS->CommandLine ()."\n"; $STS->Spawn (); if (PerlACE::waitforfile_timed ($ior, 20) == -1) { @@ -61,7 +64,8 @@ if (PerlACE::waitforfile_timed ($ior, 20) == -1) { if ($status == 0) { $STC->Arguments($client_args); - $client = $STC->SpawnWaitKill (60); + print $STC->CommandLine ()."\n"; + $client = $STC->SpawnWaitKill (300); print "\n"; $STS->Kill (); diff --git a/TAO/tao/PortableServer/ImplRepoS.cpp b/TAO/tao/PortableServer/ImplRepoS.cpp index 67e8185c5cc..2b072a9b603 100644 --- a/TAO/tao/PortableServer/ImplRepoS.cpp +++ b/TAO/tao/PortableServer/ImplRepoS.cpp @@ -26,13 +26,15 @@ // http://www.cs.wustl.edu/~schmidt/TAO.html -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_codegen.cpp:605 #ifndef _TAO_IDL_IMPLREPOS_CPP_ #define _TAO_IDL_IMPLREPOS_CPP_ +#include "tao/Var_Size_SArgument_T.h" +#include "tao/Object_SArgument_T.h" #include "ImplRepoS.h" #include "tao/PortableServer/Object_Adapter.h" #include "tao/PortableServer/Operation_Table.h" @@ -79,7 +81,7 @@ namespace TAO #if !defined (_IMPLEMENTATIONREPOSITORY_SERVEROBJECT__ARG_TRAITS_SS_) #define _IMPLEMENTATIONREPOSITORY_SERVEROBJECT__ARG_TRAITS_SS_ - + ACE_TEMPLATE_SPECIALIZATION class TAO_PortableServer_Export Arg_Traits<ImplementationRepository::ServerObject> : public @@ -93,13 +95,13 @@ namespace TAO }; #endif /* end #if !defined */ - + // TAO_IDL - Generated from // be/be_visitor_arg_traits.cpp:654 #if !defined (_IMPLEMENTATIONREPOSITORY_STARTUPOPTIONS__ARG_TRAITS_SS_) #define _IMPLEMENTATIONREPOSITORY_STARTUPOPTIONS__ARG_TRAITS_SS_ - + ACE_TEMPLATE_SPECIALIZATION class TAO_PortableServer_Export Arg_Traits<ImplementationRepository::StartupOptions> : public @@ -112,13 +114,13 @@ namespace TAO }; #endif /* end #if !defined */ - + // TAO_IDL - Generated from // be/be_visitor_arg_traits.cpp:654 #if !defined (_IMPLEMENTATIONREPOSITORY_SERVERINFORMATION__ARG_TRAITS_SS_) #define _IMPLEMENTATIONREPOSITORY_SERVERINFORMATION__ARG_TRAITS_SS_ - + ACE_TEMPLATE_SPECIALIZATION class TAO_PortableServer_Export Arg_Traits<ImplementationRepository::ServerInformation> : public @@ -131,13 +133,13 @@ namespace TAO }; #endif /* end #if !defined */ - + // TAO_IDL - Generated from // be/be_visitor_arg_traits.cpp:382 #if !defined (_IMPLEMENTATIONREPOSITORY_SERVERINFORMATIONLIST__ARG_TRAITS_SS_) #define _IMPLEMENTATIONREPOSITORY_SERVERINFORMATIONLIST__ARG_TRAITS_SS_ - + ACE_TEMPLATE_SPECIALIZATION class TAO_PortableServer_Export Arg_Traits<ImplementationRepository::ServerInformationList> : public @@ -153,7 +155,7 @@ namespace TAO #if !defined (_IMPLEMENTATIONREPOSITORY_SERVERINFORMATIONITERATOR__ARG_TRAITS_SS_) #define _IMPLEMENTATIONREPOSITORY_SERVERINFORMATIONITERATOR__ARG_TRAITS_SS_ - + ACE_TEMPLATE_SPECIALIZATION class TAO_PortableServer_Export Arg_Traits<ImplementationRepository::ServerInformationIterator> : public @@ -300,45 +302,45 @@ public: POA_ImplementationRepository::ServerObject *tao_impl ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_ServerObject_ping ( const TAO_ServerRequestInfo_ImplementationRepository_ServerObject_ping & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_ServerObject_ping & ); - + private: POA_ImplementationRepository::ServerObject *_tao_impl; - + }; // TAO_IDL - Generated from @@ -364,7 +366,7 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerObject_ping::arguments ( Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return parameter_list; } @@ -378,11 +380,11 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerObject_ping::exceptions ( Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return exception_list; } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_ServerObject_ping::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -393,7 +395,7 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerObject_ping::result ( CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -429,45 +431,45 @@ public: POA_ImplementationRepository::ServerObject *tao_impl ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_ServerObject_shutdown ( const TAO_ServerRequestInfo_ImplementationRepository_ServerObject_shutdown & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_ServerObject_shutdown & ); - + private: POA_ImplementationRepository::ServerObject *_tao_impl; - + }; // TAO_IDL - Generated from @@ -493,7 +495,7 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerObject_shutdown::arguments Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return parameter_list; } @@ -507,11 +509,11 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerObject_shutdown::exceptions Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return exception_list; } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_ServerObject_shutdown::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -522,7 +524,7 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerObject_shutdown::result ( CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -561,7 +563,7 @@ POA_ImplementationRepository::_TAO_ServerObject_Strategized_Proxy_Broker::the_TA { static POA_ImplementationRepository::_TAO_ServerObject_Strategized_Proxy_Broker strategized_proxy_broker; - + return &strategized_proxy_broker; } @@ -583,7 +585,7 @@ POA_ImplementationRepository::_TAO_ServerObject_Strategized_Proxy_Broker::get_st TAO::Collocation_Strategy strategy = TAO_ORB_Core::collocation_strategy (obj ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (TAO::TAO_CS_REMOTE_STRATEGY); - + return strategy; } @@ -603,10 +605,10 @@ POA_ImplementationRepository::_TAO_ServerObject_Strategized_Proxy_Broker::dispat TAO_Object_Adapter::Servant_Upcall servant_upcall ( obj->_stubobj ()->servant_orb_var ()->orb_core () ); - + TAO_Collocated_Skeleton collocated_skel; TAO_Abstract_ServantBase *servant = 0; - + if (strategy == TAO::TAO_CS_THRU_POA_STRATEGY) { servant_upcall.prepare_for_upcall ( @@ -616,29 +618,29 @@ POA_ImplementationRepository::_TAO_ServerObject_Strategized_Proxy_Broker::dispat ACE_ENV_ARG_PARAMETER ); ACE_CHECK; - + servant_upcall.pre_invoke_collocated_request ( ACE_ENV_SINGLE_ARG_PARAMETER ); ACE_CHECK; - + servant = servant_upcall.servant (); } else { servant = obj->_servant (); } - + int status = servant->_find (op, collocated_skel, strategy, op_len); - + if (status == -1) { ACE_THROW (CORBA::BAD_OPERATION ()); } - + ACE_TRY { collocated_skel (servant, @@ -682,9 +684,9 @@ ImplementationRepository__TAO_ServerObject_Proxy_Broker_Factory_function (CORBA: int ImplementationRepository__TAO_ServerObject_Proxy_Broker_Factory_Initializer (size_t) { - ImplementationRepository__TAO_ServerObject_Proxy_Broker_Factory_function_pointer = + ImplementationRepository__TAO_ServerObject_Proxy_Broker_Factory_function_pointer = ImplementationRepository__TAO_ServerObject_Proxy_Broker_Factory_function; - + return 0; } @@ -710,14 +712,14 @@ POA_ImplementationRepository::_TAO_ServerObject_ThruPOA_Proxy_Impl::_TAO_ServerO // ThruPOA Implementation of the IDL interface methods -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_ServerObject_ThruPOA_Proxy_Impl::ping ( TAO_Abstract_ServantBase *servant, TAO::Argument **, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -735,14 +737,14 @@ POA_ImplementationRepository::_TAO_ServerObject_ThruPOA_Proxy_Impl::ping ( ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_ServerObject_ThruPOA_Proxy_Impl::shutdown ( TAO_Abstract_ServantBase *servant, TAO::Argument **, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -771,14 +773,14 @@ POA_ImplementationRepository::_TAO_ServerObject_ThruPOA_Proxy_Impl::shutdown ( POA_ImplementationRepository::_TAO_ServerObject_Direct_Proxy_Impl::_TAO_ServerObject_Direct_Proxy_Impl (void) {} -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_ServerObject_Direct_Proxy_Impl::ping ( TAO_Abstract_ServantBase *servant, TAO::Argument **, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -794,14 +796,14 @@ POA_ImplementationRepository::_TAO_ServerObject_Direct_Proxy_Impl::ping ( ACE_ENV_SINGLE_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_ServerObject_Direct_Proxy_Impl::shutdown ( TAO_Abstract_ServantBase *servant, TAO::Argument **, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -823,7 +825,7 @@ POA_ImplementationRepository::_TAO_ServerObject_Direct_Proxy_Impl::shutdown ( // End Direct Proxy Implementation /////////////////////////////////////////////////////////////////////// -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_interface/interface_ss.cpp:97 POA_ImplementationRepository::ServerObject::ServerObject (void) @@ -841,7 +843,7 @@ POA_ImplementationRepository::ServerObject::~ServerObject (void) { } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::ServerObject::ping_skel ( @@ -857,40 +859,40 @@ void POA_ImplementationRepository::ServerObject::ping_skel ( _tao_servant ); _tao_server_request.argument_flag (0); - - + + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_ServerObject_ping _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->ping ( ACE_ENV_SINGLE_ARG_PARAMETER ); @@ -898,7 +900,7 @@ void POA_ImplementationRepository::ServerObject::ping_skel ( #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -914,35 +916,35 @@ void POA_ImplementationRepository::ServerObject::ping_skel ( ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -950,14 +952,14 @@ void POA_ImplementationRepository::ServerObject::ping_skel ( ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::ServerObject::shutdown_skel ( @@ -973,40 +975,40 @@ void POA_ImplementationRepository::ServerObject::shutdown_skel ( _tao_servant ); _tao_server_request.argument_flag (0); - - + + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_ServerObject_shutdown _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->shutdown ( ACE_ENV_SINGLE_ARG_PARAMETER ); @@ -1014,7 +1016,7 @@ void POA_ImplementationRepository::ServerObject::shutdown_skel ( #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -1030,35 +1032,35 @@ void POA_ImplementationRepository::ServerObject::shutdown_skel ( ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -1066,42 +1068,42 @@ void POA_ImplementationRepository::ServerObject::shutdown_skel ( ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_interface/interface_ss.cpp:162 void POA_ImplementationRepository::ServerObject::_is_a_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_servant, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL ) { TAO_InputCDR &_tao_in = _tao_server_request.incoming (); - + POA_ImplementationRepository::ServerObject *_tao_impl = (POA_ImplementationRepository::ServerObject *) _tao_servant; - + CORBA::Boolean _tao_retval = 0; CORBA::String_var value; - + if (!(_tao_in >> value.out ())) { ACE_THROW (CORBA::MARSHAL ()); } - + _tao_retval = _tao_impl->_is_a (value.in () ACE_ENV_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!(_tao_out << CORBA::Any::from_boolean (_tao_retval))) { ACE_THROW (CORBA::MARSHAL ()); @@ -1109,7 +1111,7 @@ void POA_ImplementationRepository::ServerObject::_is_a_skel ( } void POA_ImplementationRepository::ServerObject::_non_existent_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_servant, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL @@ -1117,14 +1119,14 @@ void POA_ImplementationRepository::ServerObject::_non_existent_skel ( { POA_ImplementationRepository::ServerObject *_tao_impl = (POA_ImplementationRepository::ServerObject *) _tao_servant; - + CORBA::Boolean _tao_retval = _tao_impl->_non_existent (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!(_tao_out << CORBA::Any::from_boolean (_tao_retval))) { ACE_THROW (CORBA::MARSHAL ()); @@ -1132,7 +1134,7 @@ void POA_ImplementationRepository::ServerObject::_non_existent_skel ( } void POA_ImplementationRepository::ServerObject::_interface_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_servant, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL @@ -1142,30 +1144,30 @@ void POA_ImplementationRepository::ServerObject::_interface_skel ( ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance ( TAO_ORB_Core::ifr_client_adapter_name () ); - + if (_tao_adapter == 0) { ACE_THROW (CORBA::INTF_REPOS ()); } - + POA_ImplementationRepository::ServerObject *_tao_impl = (POA_ImplementationRepository::ServerObject *) _tao_servant; - - CORBA::InterfaceDef_ptr _tao_retval = + + CORBA::InterfaceDef_ptr _tao_retval = _tao_impl->_get_interface (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + CORBA::Boolean _tao_result = _tao_adapter->interfacedef_cdr_insert ( _tao_out, _tao_retval ); - + _tao_adapter->dispose (_tao_retval); - + if (_tao_result == 0) { ACE_THROW (CORBA::MARSHAL ()); @@ -1173,7 +1175,7 @@ void POA_ImplementationRepository::ServerObject::_interface_skel ( } void POA_ImplementationRepository::ServerObject::_component_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_object_reference, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL @@ -1181,14 +1183,14 @@ void POA_ImplementationRepository::ServerObject::_component_skel ( { POA_ImplementationRepository::ServerObject *_tao_impl = (POA_ImplementationRepository::ServerObject *) _tao_object_reference; - + CORBA::Object_var _tao_retval = _tao_impl->_get_component (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!(_tao_out << _tao_retval.in ())) { ACE_THROW (CORBA::MARSHAL ()); @@ -1228,13 +1230,13 @@ void* POA_ImplementationRepository::ServerObject::_downcast ( { return static_cast<POA_ImplementationRepository::ServerObject_ptr> (this); } - + if (ACE_OS::strcmp (logical_type_id, "IDL:omg.org/CORBA/Object:1.0") == 0) { return static_cast<PortableServer::Servant> (this); } - + return 0; } @@ -1266,10 +1268,10 @@ POA_ImplementationRepository::ServerObject::_this (ACE_ENV_SINGLE_ARG_DECL) { TAO_Stub *stub = this->_create_stub (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + TAO_Stub_Auto_Ptr safe_stub (stub); CORBA::Object_ptr tmp = CORBA::Object::_nil (); - + if (stub->servant_orb_var ()->orb_core ()->optimize_collocation_objects ()) { ACE_NEW_RETURN ( @@ -1286,10 +1288,10 @@ POA_ImplementationRepository::ServerObject::_this (ACE_ENV_SINGLE_ARG_DECL) 0 ); } - + CORBA::Object_var obj = tmp; (void) safe_stub.release (); - + typedef ::ImplementationRepository::ServerObject STUB_SCOPED_NAME; return TAO::Narrow_Utils<STUB_SCOPED_NAME>::unchecked_narrow ( @@ -1428,47 +1430,47 @@ public: const ::CORBA::ULong & how_many ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + void result (CORBA::Boolean result); private: TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n ( const TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n & ); - + private: POA_ImplementationRepository::ServerInformationIterator *_tao_impl; - + const ::CORBA::ULong & how_many_; CORBA::Boolean _result; }; @@ -1498,15 +1500,15 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n: Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (1); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= how_many_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -1520,11 +1522,11 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n: Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return exception_list; } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -1535,11 +1537,11 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n: CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + CORBA::Any_var safe_result_any = result_any; - + (*result_any) <<= CORBA::Any::from_boolean (this->_result); - + return safe_result_any._retn (); } @@ -1563,7 +1565,7 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n: return this->_tao_impl->_is_a (id ACE_ENV_ARG_PARAMETER); } -void +void TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n::result (CORBA::Boolean result) { // Update the result. @@ -1582,45 +1584,45 @@ public: POA_ImplementationRepository::ServerInformationIterator *tao_impl ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_destroy ( const TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_destroy & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_destroy & ); - + private: POA_ImplementationRepository::ServerInformationIterator *_tao_impl; - + }; // TAO_IDL - Generated from @@ -1646,7 +1648,7 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_destroy Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return parameter_list; } @@ -1660,11 +1662,11 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_destroy Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return exception_list; } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_destroy::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -1675,7 +1677,7 @@ TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_destroy CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -1714,7 +1716,7 @@ POA_ImplementationRepository::_TAO_ServerInformationIterator_Strategized_Proxy_B { static POA_ImplementationRepository::_TAO_ServerInformationIterator_Strategized_Proxy_Broker strategized_proxy_broker; - + return &strategized_proxy_broker; } @@ -1736,7 +1738,7 @@ POA_ImplementationRepository::_TAO_ServerInformationIterator_Strategized_Proxy_B TAO::Collocation_Strategy strategy = TAO_ORB_Core::collocation_strategy (obj ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (TAO::TAO_CS_REMOTE_STRATEGY); - + return strategy; } @@ -1756,10 +1758,10 @@ POA_ImplementationRepository::_TAO_ServerInformationIterator_Strategized_Proxy_B TAO_Object_Adapter::Servant_Upcall servant_upcall ( obj->_stubobj ()->servant_orb_var ()->orb_core () ); - + TAO_Collocated_Skeleton collocated_skel; TAO_Abstract_ServantBase *servant = 0; - + if (strategy == TAO::TAO_CS_THRU_POA_STRATEGY) { servant_upcall.prepare_for_upcall ( @@ -1769,29 +1771,29 @@ POA_ImplementationRepository::_TAO_ServerInformationIterator_Strategized_Proxy_B ACE_ENV_ARG_PARAMETER ); ACE_CHECK; - + servant_upcall.pre_invoke_collocated_request ( ACE_ENV_SINGLE_ARG_PARAMETER ); ACE_CHECK; - + servant = servant_upcall.servant (); } else { servant = obj->_servant (); } - + int status = servant->_find (op, collocated_skel, strategy, op_len); - + if (status == -1) { ACE_THROW (CORBA::BAD_OPERATION ()); } - + ACE_TRY { collocated_skel (servant, @@ -1835,9 +1837,9 @@ ImplementationRepository__TAO_ServerInformationIterator_Proxy_Broker_Factory_fun int ImplementationRepository__TAO_ServerInformationIterator_Proxy_Broker_Factory_Initializer (size_t) { - ImplementationRepository__TAO_ServerInformationIterator_Proxy_Broker_Factory_function_pointer = + ImplementationRepository__TAO_ServerInformationIterator_Proxy_Broker_Factory_function_pointer = ImplementationRepository__TAO_ServerInformationIterator_Proxy_Broker_Factory_function; - + return 0; } @@ -1863,7 +1865,7 @@ POA_ImplementationRepository::_TAO_ServerInformationIterator_ThruPOA_Proxy_Impl: // ThruPOA Implementation of the IDL interface methods -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void @@ -1891,14 +1893,14 @@ POA_ImplementationRepository::_TAO_ServerInformationIterator_ThruPOA_Proxy_Impl: ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_ServerInformationIterator_ThruPOA_Proxy_Impl::destroy ( TAO_Abstract_ServantBase *servant, TAO::Argument **, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -1927,7 +1929,7 @@ POA_ImplementationRepository::_TAO_ServerInformationIterator_ThruPOA_Proxy_Impl: POA_ImplementationRepository::_TAO_ServerInformationIterator_Direct_Proxy_Impl::_TAO_ServerInformationIterator_Direct_Proxy_Impl (void) {} -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void @@ -1953,14 +1955,14 @@ POA_ImplementationRepository::_TAO_ServerInformationIterator_Direct_Proxy_Impl:: ACE_ENV_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_ServerInformationIterator_Direct_Proxy_Impl::destroy ( TAO_Abstract_ServantBase *servant, TAO::Argument **, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -1982,7 +1984,7 @@ POA_ImplementationRepository::_TAO_ServerInformationIterator_Direct_Proxy_Impl:: // End Direct Proxy Implementation /////////////////////////////////////////////////////////////////////// -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_interface/interface_ss.cpp:97 POA_ImplementationRepository::ServerInformationIterator::ServerInformationIterator (void) @@ -2000,7 +2002,7 @@ POA_ImplementationRepository::ServerInformationIterator::~ServerInformationItera { } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::ServerInformationIterator::next_n_skel ( @@ -2019,8 +2021,8 @@ POA_ImplementationRepository::ServerInformationIterator *_tao_impl = CORBA::Boolean _tao_retval = 0; ::CORBA::ULong how_many; ::ImplementationRepository::ServerInformationList_var servers; - - + + if (!( (_tao_in >> how_many) )) @@ -2028,44 +2030,44 @@ POA_ImplementationRepository::ServerInformationIterator *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_next_n _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - + how_many ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - _tao_retval = + _tao_retval = _tao_impl->next_n ( how_many, - + servers.out () ACE_ENV_ARG_PARAMETER ); @@ -2073,7 +2075,7 @@ POA_ImplementationRepository::ServerInformationIterator *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { CORBA::Boolean _tao_retval_info = _tao_retval; @@ -2091,35 +2093,35 @@ POA_ImplementationRepository::ServerInformationIterator *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -2127,14 +2129,14 @@ POA_ImplementationRepository::ServerInformationIterator *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); #if (TAO_HAS_INTERCEPTORS == 1) if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!( (_tao_out << CORBA::Any::from_boolean (_tao_retval)) && (_tao_out << servers.in ()) @@ -2146,13 +2148,13 @@ POA_ImplementationRepository::ServerInformationIterator *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } #endif /* TAO_HAS_INTERCEPTORS */ - - + + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::ServerInformationIterator::destroy_skel ( @@ -2168,40 +2170,40 @@ void POA_ImplementationRepository::ServerInformationIterator::destroy_skel ( _tao_servant ); _tao_server_request.argument_flag (0); - - + + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_ServerInformationIterator_destroy _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->destroy ( ACE_ENV_SINGLE_ARG_PARAMETER ); @@ -2209,7 +2211,7 @@ void POA_ImplementationRepository::ServerInformationIterator::destroy_skel ( #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -2225,35 +2227,35 @@ void POA_ImplementationRepository::ServerInformationIterator::destroy_skel ( ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -2261,42 +2263,42 @@ void POA_ImplementationRepository::ServerInformationIterator::destroy_skel ( ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_interface/interface_ss.cpp:162 void POA_ImplementationRepository::ServerInformationIterator::_is_a_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_servant, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL ) { TAO_InputCDR &_tao_in = _tao_server_request.incoming (); - + POA_ImplementationRepository::ServerInformationIterator *_tao_impl = (POA_ImplementationRepository::ServerInformationIterator *) _tao_servant; - + CORBA::Boolean _tao_retval = 0; CORBA::String_var value; - + if (!(_tao_in >> value.out ())) { ACE_THROW (CORBA::MARSHAL ()); } - + _tao_retval = _tao_impl->_is_a (value.in () ACE_ENV_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!(_tao_out << CORBA::Any::from_boolean (_tao_retval))) { ACE_THROW (CORBA::MARSHAL ()); @@ -2304,7 +2306,7 @@ void POA_ImplementationRepository::ServerInformationIterator::_is_a_skel ( } void POA_ImplementationRepository::ServerInformationIterator::_non_existent_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_servant, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL @@ -2312,14 +2314,14 @@ void POA_ImplementationRepository::ServerInformationIterator::_non_existent_skel { POA_ImplementationRepository::ServerInformationIterator *_tao_impl = (POA_ImplementationRepository::ServerInformationIterator *) _tao_servant; - + CORBA::Boolean _tao_retval = _tao_impl->_non_existent (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!(_tao_out << CORBA::Any::from_boolean (_tao_retval))) { ACE_THROW (CORBA::MARSHAL ()); @@ -2327,7 +2329,7 @@ void POA_ImplementationRepository::ServerInformationIterator::_non_existent_skel } void POA_ImplementationRepository::ServerInformationIterator::_interface_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_servant, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL @@ -2337,30 +2339,30 @@ void POA_ImplementationRepository::ServerInformationIterator::_interface_skel ( ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance ( TAO_ORB_Core::ifr_client_adapter_name () ); - + if (_tao_adapter == 0) { ACE_THROW (CORBA::INTF_REPOS ()); } - + POA_ImplementationRepository::ServerInformationIterator *_tao_impl = (POA_ImplementationRepository::ServerInformationIterator *) _tao_servant; - - CORBA::InterfaceDef_ptr _tao_retval = + + CORBA::InterfaceDef_ptr _tao_retval = _tao_impl->_get_interface (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + CORBA::Boolean _tao_result = _tao_adapter->interfacedef_cdr_insert ( _tao_out, _tao_retval ); - + _tao_adapter->dispose (_tao_retval); - + if (_tao_result == 0) { ACE_THROW (CORBA::MARSHAL ()); @@ -2368,7 +2370,7 @@ void POA_ImplementationRepository::ServerInformationIterator::_interface_skel ( } void POA_ImplementationRepository::ServerInformationIterator::_component_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_object_reference, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL @@ -2376,14 +2378,14 @@ void POA_ImplementationRepository::ServerInformationIterator::_component_skel ( { POA_ImplementationRepository::ServerInformationIterator *_tao_impl = (POA_ImplementationRepository::ServerInformationIterator *) _tao_object_reference; - + CORBA::Object_var _tao_retval = _tao_impl->_get_component (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!(_tao_out << _tao_retval.in ())) { ACE_THROW (CORBA::MARSHAL ()); @@ -2423,13 +2425,13 @@ void* POA_ImplementationRepository::ServerInformationIterator::_downcast ( { return static_cast<POA_ImplementationRepository::ServerInformationIterator_ptr> (this); } - + if (ACE_OS::strcmp (logical_type_id, "IDL:omg.org/CORBA/Object:1.0") == 0) { return static_cast<PortableServer::Servant> (this); } - + return 0; } @@ -2461,10 +2463,10 @@ POA_ImplementationRepository::ServerInformationIterator::_this (ACE_ENV_SINGLE_A { TAO_Stub *stub = this->_create_stub (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + TAO_Stub_Auto_Ptr safe_stub (stub); CORBA::Object_ptr tmp = CORBA::Object::_nil (); - + if (stub->servant_orb_var ()->orb_core ()->optimize_collocation_objects ()) { ACE_NEW_RETURN ( @@ -2481,10 +2483,10 @@ POA_ImplementationRepository::ServerInformationIterator::_this (ACE_ENV_SINGLE_A 0 ); } - + CORBA::Object_var obj = tmp; (void) safe_stub.release (); - + typedef ::ImplementationRepository::ServerInformationIterator STUB_SCOPED_NAME; return TAO::Narrow_Utils<STUB_SCOPED_NAME>::unchecked_narrow ( @@ -2633,45 +2635,45 @@ public: const char * server ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_Administration_activate_server ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_activate_server & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_activate_server & ); - + private: POA_ImplementationRepository::Administration *_tao_impl; - + const char * server_; }; @@ -2700,15 +2702,15 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_activate_server::a Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (1); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= server_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -2722,15 +2724,15 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_activate_server::e Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ExceptionList_var safe_exception_list = exception_list; - - static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_activate_server_exceptiondata[] = + + static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_activate_server_exceptiondata[] = { ImplementationRepository::_tc_NotFound, ImplementationRepository::_tc_CannotActivate }; - + exception_list->length (2); for (CORBA::ULong i = 0; i < 2; ++i) { @@ -2742,7 +2744,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_activate_server::e return safe_exception_list._retn (); } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_Administration_activate_server::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -2753,7 +2755,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_activate_server::r CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -2791,45 +2793,45 @@ public: const ::ImplementationRepository::StartupOptions & options ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_Administration_register_server ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_register_server & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_register_server & ); - + private: POA_ImplementationRepository::Administration *_tao_impl; - + const char * server_; const ::ImplementationRepository::StartupOptions & options_; }; @@ -2861,19 +2863,19 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_register_server::a Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (2); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= server_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + (*parameter_list)[len].argument <<= this->options_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -2887,15 +2889,15 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_register_server::e Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ExceptionList_var safe_exception_list = exception_list; - - static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_register_server_exceptiondata[] = + + static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_register_server_exceptiondata[] = { ImplementationRepository::_tc_AlreadyRegistered, ImplementationRepository::_tc_NotFound }; - + exception_list->length (2); for (CORBA::ULong i = 0; i < 2; ++i) { @@ -2907,7 +2909,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_register_server::e return safe_exception_list._retn (); } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_Administration_register_server::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -2918,7 +2920,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_register_server::r CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -2956,45 +2958,44 @@ public: const ::ImplementationRepository::StartupOptions & options ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_Administration_reregister_server ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_reregister_server & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_reregister_server & ); - + private: POA_ImplementationRepository::Administration *_tao_impl; - + const char * server_; const ::ImplementationRepository::StartupOptions & options_; }; @@ -3026,19 +3027,19 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_reregister_server: Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (2); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= server_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + (*parameter_list)[len].argument <<= this->options_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -3052,15 +3053,15 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_reregister_server: Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ExceptionList_var safe_exception_list = exception_list; - - static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_reregister_server_exceptiondata[] = + + static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_reregister_server_exceptiondata[] = { ImplementationRepository::_tc_AlreadyRegistered, ImplementationRepository::_tc_NotFound }; - + exception_list->length (2); for (CORBA::ULong i = 0; i < 2; ++i) { @@ -3072,7 +3073,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_reregister_server: return safe_exception_list._retn (); } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_Administration_reregister_server::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -3083,7 +3084,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_reregister_server: CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -3120,45 +3121,45 @@ public: const char * server ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_Administration_remove_server ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_remove_server & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_remove_server & ); - + private: POA_ImplementationRepository::Administration *_tao_impl; - + const char * server_; }; @@ -3187,15 +3188,15 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_remove_server::arg Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (1); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= server_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -3209,14 +3210,14 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_remove_server::exc Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ExceptionList_var safe_exception_list = exception_list; - - static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_remove_server_exceptiondata[] = + + static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_remove_server_exceptiondata[] = { ImplementationRepository::_tc_NotFound }; - + exception_list->length (1); for (CORBA::ULong i = 0; i < 1; ++i) { @@ -3228,7 +3229,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_remove_server::exc return safe_exception_list._retn (); } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_Administration_remove_server::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -3239,7 +3240,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_remove_server::res CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -3276,45 +3277,45 @@ public: const char * server ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_Administration_shutdown_server ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_shutdown_server & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_shutdown_server & ); - + private: POA_ImplementationRepository::Administration *_tao_impl; - + const char * server_; }; @@ -3343,15 +3344,15 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_shutdown_server::a Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (1); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= server_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -3365,14 +3366,14 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_shutdown_server::e Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ExceptionList_var safe_exception_list = exception_list; - - static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_shutdown_server_exceptiondata[] = + + static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_shutdown_server_exceptiondata[] = { ImplementationRepository::_tc_NotFound }; - + exception_list->length (1); for (CORBA::ULong i = 0; i < 1; ++i) { @@ -3384,7 +3385,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_shutdown_server::e return safe_exception_list._retn (); } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_Administration_shutdown_server::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -3395,7 +3396,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_shutdown_server::r CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -3434,45 +3435,45 @@ public: ::ImplementationRepository::ServerObject_ptr server_object ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_running ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_running & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_running & ); - + private: POA_ImplementationRepository::Administration *_tao_impl; - + const char * server_; const char * partial_ior_; ::ImplementationRepository::ServerObject_ptr server_object_; @@ -3507,23 +3508,23 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_running: Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (3); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= server_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + (*parameter_list)[len].argument <<= partial_ior_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + (*parameter_list)[len].argument <<= this->server_object_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -3537,14 +3538,14 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_running: Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ExceptionList_var safe_exception_list = exception_list; - - static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_server_is_running_exceptiondata[] = + + static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_server_is_running_exceptiondata[] = { ImplementationRepository::_tc_NotFound }; - + exception_list->length (1); for (CORBA::ULong i = 0; i < 1; ++i) { @@ -3556,7 +3557,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_running: return safe_exception_list._retn (); } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_running::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -3567,7 +3568,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_running: CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -3604,45 +3605,45 @@ public: const char * server ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_shutting_down ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_shutting_down & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_shutting_down & ); - + private: POA_ImplementationRepository::Administration *_tao_impl; - + const char * server_; }; @@ -3671,15 +3672,15 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_shutting Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (1); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= server_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -3693,14 +3694,14 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_shutting Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ExceptionList_var safe_exception_list = exception_list; - - static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_server_is_shutting_down_exceptiondata[] = + + static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_server_is_shutting_down_exceptiondata[] = { ImplementationRepository::_tc_NotFound }; - + exception_list->length (1); for (CORBA::ULong i = 0; i < 1; ++i) { @@ -3712,7 +3713,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_shutting return safe_exception_list._retn (); } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_shutting_down::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -3723,7 +3724,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_shutting CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -3760,45 +3761,45 @@ public: const char * server ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_Administration_find ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_find & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_find & ); - + private: POA_ImplementationRepository::Administration *_tao_impl; - + const char * server_; }; @@ -3827,15 +3828,15 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_find::arguments ( Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (1); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= server_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -3849,14 +3850,14 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_find::exceptions ( Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ExceptionList_var safe_exception_list = exception_list; - - static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_find_exceptiondata[] = + + static CORBA::TypeCode_ptr _tao_ImplementationRepository_Administration_find_exceptiondata[] = { ImplementationRepository::_tc_NotFound }; - + exception_list->length (1); for (CORBA::ULong i = 0; i < 1; ++i) { @@ -3868,7 +3869,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_find::exceptions ( return safe_exception_list._retn (); } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_Administration_find::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -3879,7 +3880,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_find::result ( CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -3913,50 +3914,50 @@ public: TAO_ServerRequest &_tao_server_request, TAO_Object_Adapter::Servant_Upcall *tao_servant_upcall, POA_ImplementationRepository::Administration *tao_impl, - const ::CORBA::ULong & how_many + const ::CORBA::ULong & how_many ACE_ENV_ARG_DECL_WITH_DEFAULTS ); - + virtual Dynamic::ParameterList * arguments ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual Dynamic::ExceptionList * exceptions ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Any * result ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual char * target_most_derived_interface ( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + virtual CORBA::Boolean target_is_a ( const char * id ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)); - + private: TAO_ServerRequestInfo_ImplementationRepository_Administration_list ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_list & ); - + void operator= ( const TAO_ServerRequestInfo_ImplementationRepository_Administration_list & ); - + private: POA_ImplementationRepository::Administration *_tao_impl; - - const ::CORBA::ULong & how_many_; + + const ::CORBA::ULong & how_many_; }; @@ -3967,13 +3968,13 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_list::TAO_ServerRe TAO_ServerRequest &_tao_server_request, TAO_Object_Adapter::Servant_Upcall *_tao_servant_upcall, POA_ImplementationRepository::Administration *tao_impl, - const ::CORBA::ULong & how_many + const ::CORBA::ULong & how_many ACE_ENV_ARG_DECL_NOT_USED ) : TAO_ServerRequestInfo (_tao_server_request, _tao_servant_upcall), _tao_impl (tao_impl), - how_many_ (how_many) + how_many_ (how_many) {} @@ -3987,15 +3988,15 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_list::arguments ( Dynamic::ParameterList *parameter_list = TAO_RequestInfo_Util::make_parameter_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + Dynamic::ParameterList_var safe_parameter_list = parameter_list; parameter_list->length (1); CORBA::ULong len = 0; - + (*parameter_list)[len].argument <<= how_many_; (*parameter_list)[len].mode = CORBA::PARAM_IN; len++; - + return safe_parameter_list._retn (); } @@ -4010,11 +4011,11 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_list::exceptions ( Dynamic::ExceptionList *exception_list = TAO_RequestInfo_Util::make_exception_list (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return exception_list; } -CORBA::Any * +CORBA::Any * TAO_ServerRequestInfo_ImplementationRepository_Administration_list::result ( ACE_ENV_SINGLE_ARG_DECL ) @@ -4025,7 +4026,7 @@ TAO_ServerRequestInfo_ImplementationRepository_Administration_list::result ( CORBA::Any *result_any = TAO_RequestInfo_Util::make_any (tk_void_any ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + return result_any; } @@ -4064,7 +4065,7 @@ POA_ImplementationRepository::_TAO_Administration_Strategized_Proxy_Broker::the_ { static POA_ImplementationRepository::_TAO_Administration_Strategized_Proxy_Broker strategized_proxy_broker; - + return &strategized_proxy_broker; } @@ -4086,7 +4087,7 @@ POA_ImplementationRepository::_TAO_Administration_Strategized_Proxy_Broker::get_ TAO::Collocation_Strategy strategy = TAO_ORB_Core::collocation_strategy (obj ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (TAO::TAO_CS_REMOTE_STRATEGY); - + return strategy; } @@ -4106,10 +4107,10 @@ POA_ImplementationRepository::_TAO_Administration_Strategized_Proxy_Broker::disp TAO_Object_Adapter::Servant_Upcall servant_upcall ( obj->_stubobj ()->servant_orb_var ()->orb_core () ); - + TAO_Collocated_Skeleton collocated_skel; TAO_Abstract_ServantBase *servant = 0; - + if (strategy == TAO::TAO_CS_THRU_POA_STRATEGY) { servant_upcall.prepare_for_upcall ( @@ -4119,29 +4120,29 @@ POA_ImplementationRepository::_TAO_Administration_Strategized_Proxy_Broker::disp ACE_ENV_ARG_PARAMETER ); ACE_CHECK; - + servant_upcall.pre_invoke_collocated_request ( ACE_ENV_SINGLE_ARG_PARAMETER ); ACE_CHECK; - + servant = servant_upcall.servant (); } else { servant = obj->_servant (); } - + int status = servant->_find (op, collocated_skel, strategy, op_len); - + if (status == -1) { ACE_THROW (CORBA::BAD_OPERATION ()); } - + ACE_TRY { collocated_skel (servant, @@ -4185,9 +4186,9 @@ ImplementationRepository__TAO_Administration_Proxy_Broker_Factory_function (CORB int ImplementationRepository__TAO_Administration_Proxy_Broker_Factory_Initializer (size_t) { - ImplementationRepository__TAO_Administration_Proxy_Broker_Factory_function_pointer = + ImplementationRepository__TAO_Administration_Proxy_Broker_Factory_function_pointer = ImplementationRepository__TAO_Administration_Proxy_Broker_Factory_function; - + return 0; } @@ -4213,7 +4214,7 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::_TAO_Admin // ThruPOA Implementation of the IDL interface methods -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void @@ -4241,14 +4242,14 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::activate_s ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::register_server ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4270,14 +4271,14 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::register_s ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::reregister_server ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4299,14 +4300,14 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::reregister ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::remove_server ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4326,14 +4327,14 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::remove_ser ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::shutdown_server ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4353,14 +4354,14 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::shutdown_s ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::server_is_running ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4382,14 +4383,14 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::server_is_ ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::server_is_shutting_down ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4409,14 +4410,14 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::server_is_ ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::find ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4437,14 +4438,14 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::find ( ACE_CHECK; } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/thru_poa_proxy_impl_ss.cpp:52 void POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::list ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4476,7 +4477,7 @@ POA_ImplementationRepository::_TAO_Administration_ThruPOA_Proxy_Impl::list ( POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::_TAO_Administration_Direct_Proxy_Impl (void) {} -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void @@ -4502,14 +4503,14 @@ POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::activate_se ACE_ENV_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::register_server ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4529,14 +4530,14 @@ POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::register_se ACE_ENV_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::reregister_server ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4556,14 +4557,14 @@ POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::reregister_ ACE_ENV_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::remove_server ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4581,14 +4582,14 @@ POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::remove_serv ACE_ENV_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::shutdown_server ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4606,14 +4607,14 @@ POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::shutdown_se ACE_ENV_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::server_is_running ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4633,14 +4634,14 @@ POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::server_is_r ACE_ENV_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::server_is_shutting_down ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4658,14 +4659,14 @@ POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::server_is_s ACE_ENV_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::find ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4684,14 +4685,14 @@ POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::find ( ACE_ENV_ARG_PARAMETER ); ACE_CHECK; -}// TAO_IDL - Generated from +}// TAO_IDL - Generated from // be/be_visitor_operation/direct_proxy_impl_ss.cpp:42 void POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::list ( TAO_Abstract_ServantBase *servant, TAO::Argument ** args, - int + int ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( @@ -4716,7 +4717,7 @@ POA_ImplementationRepository::_TAO_Administration_Direct_Proxy_Impl::list ( // End Direct Proxy Implementation /////////////////////////////////////////////////////////////////////// -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_interface/interface_ss.cpp:97 POA_ImplementationRepository::Administration::Administration (void) @@ -4734,7 +4735,7 @@ POA_ImplementationRepository::Administration::~Administration (void) { } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::Administration::activate_server_skel ( @@ -4751,9 +4752,9 @@ POA_ImplementationRepository::Administration *_tao_impl = _tao_servant ); _tao_server_request.argument_flag (0); - + ::CORBA::String_var server; - + if (!( (_tao_in >> server.out ()) )) @@ -4761,41 +4762,41 @@ POA_ImplementationRepository::Administration *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_Administration_activate_server _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - + server.in () ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->activate_server ( server.in () ACE_ENV_ARG_PARAMETER @@ -4804,7 +4805,7 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -4820,35 +4821,35 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -4856,14 +4857,14 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::Administration::register_server_skel ( @@ -4880,10 +4881,10 @@ POA_ImplementationRepository::Administration *_tao_impl = _tao_servant ); _tao_server_request.argument_flag (0); - + ::CORBA::String_var server; ::ImplementationRepository::StartupOptions options; - + if (!( (_tao_in >> server.out ()) && (_tao_in >> options) @@ -4892,46 +4893,46 @@ POA_ImplementationRepository::Administration *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_Administration_register_server _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - + server.in (), - + options ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->register_server ( server.in (), - + options ACE_ENV_ARG_PARAMETER ); @@ -4939,7 +4940,7 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -4955,35 +4956,35 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -4991,14 +4992,14 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::Administration::reregister_server_skel ( @@ -5015,10 +5016,10 @@ POA_ImplementationRepository::Administration *_tao_impl = _tao_servant ); _tao_server_request.argument_flag (0); - + ::CORBA::String_var server; ::ImplementationRepository::StartupOptions options; - + if (!( (_tao_in >> server.out ()) && (_tao_in >> options) @@ -5027,46 +5028,46 @@ POA_ImplementationRepository::Administration *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_Administration_reregister_server _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - + server.in (), - + options ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->reregister_server ( server.in (), - + options ACE_ENV_ARG_PARAMETER ); @@ -5074,7 +5075,7 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -5090,35 +5091,35 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -5126,14 +5127,14 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::Administration::remove_server_skel ( @@ -5150,9 +5151,9 @@ POA_ImplementationRepository::Administration *_tao_impl = _tao_servant ); _tao_server_request.argument_flag (0); - + ::CORBA::String_var server; - + if (!( (_tao_in >> server.out ()) )) @@ -5160,41 +5161,41 @@ POA_ImplementationRepository::Administration *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_Administration_remove_server _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - + server.in () ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->remove_server ( server.in () ACE_ENV_ARG_PARAMETER @@ -5203,7 +5204,7 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -5219,35 +5220,35 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -5255,14 +5256,14 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::Administration::shutdown_server_skel ( @@ -5279,9 +5280,9 @@ POA_ImplementationRepository::Administration *_tao_impl = _tao_servant ); _tao_server_request.argument_flag (0); - + ::CORBA::String_var server; - + if (!( (_tao_in >> server.out ()) )) @@ -5289,41 +5290,41 @@ POA_ImplementationRepository::Administration *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_Administration_shutdown_server _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - + server.in () ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->shutdown_server ( server.in () ACE_ENV_ARG_PARAMETER @@ -5332,7 +5333,7 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -5348,35 +5349,35 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -5384,14 +5385,14 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::Administration::server_is_running_skel ( @@ -5408,11 +5409,11 @@ POA_ImplementationRepository::Administration *_tao_impl = _tao_servant ); _tao_server_request.argument_flag (0); - + ::CORBA::String_var server; ::CORBA::String_var partial_ior; ::ImplementationRepository::ServerObject_var server_object; - + if (!( (_tao_in >> server.out ()) && (_tao_in >> partial_ior.out ()) && @@ -5422,50 +5423,50 @@ POA_ImplementationRepository::Administration *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_running _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - + server.in (), - + partial_ior.in (), - + server_object.in () ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->server_is_running ( server.in (), - + partial_ior.in (), - + server_object.in () ACE_ENV_ARG_PARAMETER ); @@ -5473,7 +5474,7 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -5489,35 +5490,35 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -5525,14 +5526,14 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::Administration::server_is_shutting_down_skel ( @@ -5549,9 +5550,9 @@ POA_ImplementationRepository::Administration *_tao_impl = _tao_servant ); _tao_server_request.argument_flag (0); - + ::CORBA::String_var server; - + if (!( (_tao_in >> server.out ()) )) @@ -5559,41 +5560,41 @@ POA_ImplementationRepository::Administration *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_Administration_server_is_shutting_down _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - + server.in () ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->server_is_shutting_down ( server.in () ACE_ENV_ARG_PARAMETER @@ -5602,7 +5603,7 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -5618,35 +5619,35 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -5654,14 +5655,14 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); - + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::Administration::find_skel ( @@ -5677,10 +5678,10 @@ POA_ImplementationRepository::Administration *_tao_impl = POA_ImplementationRepository::Administration *> ( _tao_servant ); - + ::CORBA::String_var server; ::ImplementationRepository::ServerInformation_var info; - + if (!( (_tao_in >> server.out ()) )) @@ -5688,44 +5689,44 @@ POA_ImplementationRepository::Administration *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_Administration_find _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - + server.in () ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->find ( server.in (), - + info.out () ACE_ENV_ARG_PARAMETER ); @@ -5733,7 +5734,7 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -5749,35 +5750,35 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -5785,14 +5786,14 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); #if (TAO_HAS_INTERCEPTORS == 1) if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!( (_tao_out << info.in ()) )) @@ -5803,13 +5804,13 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } #endif /* TAO_HAS_INTERCEPTORS */ - - + + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_operation/operation_ss.cpp:98 void POA_ImplementationRepository::Administration::list_skel ( @@ -5825,12 +5826,12 @@ POA_ImplementationRepository::Administration *_tao_impl = POA_ImplementationRepository::Administration *> ( _tao_servant ); - + ::CORBA::ULong how_many; ::ImplementationRepository::ServerInformationList_var server_list; - + ::ImplementationRepository::ServerInformationIterator_var server_iterator; - + if (!( (_tao_in >> how_many) )) @@ -5838,47 +5839,47 @@ POA_ImplementationRepository::Administration *_tao_impl = TAO_InputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER); ACE_CHECK; } - + #if (TAO_HAS_INTERCEPTORS == 1) TAO_Object_Adapter::Servant_Upcall *_tao_upcall = static_cast< TAO_Object_Adapter::Servant_Upcall *> ( _tao_servant_upcall ); - + TAO_ServerRequestInterceptor_Adapter _tao_vfr ( _tao_server_request.orb_core ()->server_request_interceptors (), _tao_server_request.interceptor_count () ); - + TAO_ServerRequestInfo_ImplementationRepository_Administration_list _tao_ri ( _tao_server_request, _tao_upcall, _tao_impl, - - how_many + + how_many ACE_ENV_ARG_PARAMETER ); - + ACE_TRY { { TAO::PICurrent_Guard _tao_pi_guard (_tao_ri.server_request (), true /* Copy TSC to RSC */); - + _tao_vfr.receive_request (&_tao_ri ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - + if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_impl->list ( how_many, - + server_list.out (), - + server_iterator.out () ACE_ENV_ARG_PARAMETER ); @@ -5886,7 +5887,7 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } } - + if (!_tao_vfr.location_forwarded ()) { _tao_ri.reply_status (PortableInterceptor::SUCCESSFUL); @@ -5902,35 +5903,35 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION || _tao_status == PortableInterceptor::USER_EXCEPTION) { ACE_RE_THROW; } } - + # if defined (ACE_HAS_EXCEPTIONS) \ && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) ACE_CATCHALL { CORBA::UNKNOWN ex; - + _tao_ri.exception (&ex); _tao_vfr.send_exception ( &_tao_ri ACE_ENV_ARG_PARAMETER ); ACE_TRY_CHECK; - + PortableInterceptor::ReplyStatus _tao_status = _tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - + if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION) ACE_TRY_THROW (ex); } @@ -5938,14 +5939,14 @@ POA_ImplementationRepository::Administration *_tao_impl = ACE_ENDTRY; ACE_CHECK; #endif /* TAO_HAS_INTERCEPTORS */ - + _tao_server_request.init_reply (); #if (TAO_HAS_INTERCEPTORS == 1) if (!_tao_vfr.location_forwarded ()) { #endif /* TAO_HAS_INTERCEPTORS */ TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!( (_tao_out << server_list.in ()) && (_tao_out << server_iterator.in ()) @@ -5957,41 +5958,41 @@ POA_ImplementationRepository::Administration *_tao_impl = #if (TAO_HAS_INTERCEPTORS == 1) } #endif /* TAO_HAS_INTERCEPTORS */ - - + + // In case _tao_servant_upcall is not used in this function ACE_UNUSED_ARG (_tao_servant_upcall); } -// TAO_IDL - Generated from +// TAO_IDL - Generated from // be/be_visitor_interface/interface_ss.cpp:162 void POA_ImplementationRepository::Administration::_is_a_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_servant, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL ) { TAO_InputCDR &_tao_in = _tao_server_request.incoming (); - + POA_ImplementationRepository::Administration *_tao_impl = (POA_ImplementationRepository::Administration *) _tao_servant; - + CORBA::Boolean _tao_retval = 0; CORBA::String_var value; - + if (!(_tao_in >> value.out ())) { ACE_THROW (CORBA::MARSHAL ()); } - + _tao_retval = _tao_impl->_is_a (value.in () ACE_ENV_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!(_tao_out << CORBA::Any::from_boolean (_tao_retval))) { ACE_THROW (CORBA::MARSHAL ()); @@ -5999,7 +6000,7 @@ void POA_ImplementationRepository::Administration::_is_a_skel ( } void POA_ImplementationRepository::Administration::_non_existent_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_servant, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL @@ -6007,14 +6008,14 @@ void POA_ImplementationRepository::Administration::_non_existent_skel ( { POA_ImplementationRepository::Administration *_tao_impl = (POA_ImplementationRepository::Administration *) _tao_servant; - + CORBA::Boolean _tao_retval = _tao_impl->_non_existent (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!(_tao_out << CORBA::Any::from_boolean (_tao_retval))) { ACE_THROW (CORBA::MARSHAL ()); @@ -6022,7 +6023,7 @@ void POA_ImplementationRepository::Administration::_non_existent_skel ( } void POA_ImplementationRepository::Administration::_interface_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_servant, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL @@ -6032,30 +6033,30 @@ void POA_ImplementationRepository::Administration::_interface_skel ( ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance ( TAO_ORB_Core::ifr_client_adapter_name () ); - + if (_tao_adapter == 0) { ACE_THROW (CORBA::INTF_REPOS ()); } - + POA_ImplementationRepository::Administration *_tao_impl = (POA_ImplementationRepository::Administration *) _tao_servant; - - CORBA::InterfaceDef_ptr _tao_retval = + + CORBA::InterfaceDef_ptr _tao_retval = _tao_impl->_get_interface (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + CORBA::Boolean _tao_result = _tao_adapter->interfacedef_cdr_insert ( _tao_out, _tao_retval ); - + _tao_adapter->dispose (_tao_retval); - + if (_tao_result == 0) { ACE_THROW (CORBA::MARSHAL ()); @@ -6063,7 +6064,7 @@ void POA_ImplementationRepository::Administration::_interface_skel ( } void POA_ImplementationRepository::Administration::_component_skel ( - TAO_ServerRequest &_tao_server_request, + TAO_ServerRequest &_tao_server_request, void * _tao_object_reference, void * /* Servant_Upcall */ ACE_ENV_ARG_DECL @@ -6071,14 +6072,14 @@ void POA_ImplementationRepository::Administration::_component_skel ( { POA_ImplementationRepository::Administration *_tao_impl = (POA_ImplementationRepository::Administration *) _tao_object_reference; - + CORBA::Object_var _tao_retval = _tao_impl->_get_component (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; - + _tao_server_request.init_reply (); TAO_OutputCDR &_tao_out = _tao_server_request.outgoing (); - + if (!(_tao_out << _tao_retval.in ())) { ACE_THROW (CORBA::MARSHAL ()); @@ -6118,13 +6119,13 @@ void* POA_ImplementationRepository::Administration::_downcast ( { return static_cast<POA_ImplementationRepository::Administration_ptr> (this); } - + if (ACE_OS::strcmp (logical_type_id, "IDL:omg.org/CORBA/Object:1.0") == 0) { return static_cast<PortableServer::Servant> (this); } - + return 0; } @@ -6156,10 +6157,10 @@ POA_ImplementationRepository::Administration::_this (ACE_ENV_SINGLE_ARG_DECL) { TAO_Stub *stub = this->_create_stub (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); - + TAO_Stub_Auto_Ptr safe_stub (stub); CORBA::Object_ptr tmp = CORBA::Object::_nil (); - + if (stub->servant_orb_var ()->orb_core ()->optimize_collocation_objects ()) { ACE_NEW_RETURN ( @@ -6176,10 +6177,10 @@ POA_ImplementationRepository::Administration::_this (ACE_ENV_SINGLE_ARG_DECL) 0 ); } - + CORBA::Object_var obj = tmp; (void) safe_stub.release (); - + typedef ::ImplementationRepository::Administration STUB_SCOPED_NAME; return TAO::Narrow_Utils<STUB_SCOPED_NAME>::unchecked_narrow ( @@ -6202,7 +6203,7 @@ POA_ImplementationRepository::Administration::_this (ACE_ENV_SINGLE_ARG_DECL) TAO::Object_SArg_Traits_T< ImplementationRepository::ServerObject_ptr, ImplementationRepository::ServerObject_var, - ImplementationRepository::ServerObject_out, + ImplementationRepository::ServerObject_out >; #endif /* end #if !defined */ @@ -6258,7 +6259,7 @@ POA_ImplementationRepository::Administration::_this (ACE_ENV_SINGLE_ARG_DECL) TAO::Object_SArg_Traits_T< ImplementationRepository::ServerInformationIterator_ptr, ImplementationRepository::ServerInformationIterator_var, - ImplementationRepository::ServerInformationIterator_out, + ImplementationRepository::ServerInformationIterator_out >; #endif /* end #if !defined */ @@ -6266,7 +6267,7 @@ POA_ImplementationRepository::Administration::_this (ACE_ENV_SINGLE_ARG_DECL) template class TAO::Out_Var_Size_SArgument_T< ImplementationRepository::ServerInformationList, - ImplementationRepository::ServerInformationList_out + ImplementationRepository::ServerInformationList_var >; template class @@ -6275,19 +6276,21 @@ POA_ImplementationRepository::Administration::_this (ACE_ENV_SINGLE_ARG_DECL) >; template class - TAO::In_Object_SArgument_T< - ImplementationRepository::ServerObject_ptr - >; + TAO::In_Object_SArgument_T< + ImplementationRepository::ServerObject_ptr, + ImplementationRepository::ServerObject_var + >; template class TAO::Out_Var_Size_SArgument_T< ImplementationRepository::ServerInformation, - ImplementationRepository::ServerInformation_out + ImplementationRepository::ServerInformation_var >; template class TAO::Out_Object_SArgument_T< ImplementationRepository::ServerInformationIterator_ptr, + ImplementationRepository::ServerInformationIterator_var, ImplementationRepository::ServerInformationIterator_out >; @@ -6366,7 +6369,7 @@ POA_ImplementationRepository::Administration::_this (ACE_ENV_SINGLE_ARG_DECL) # pragma instantiate \ TAO::Out_Var_Size_SArgument_T< \ ImplementationRepository::ServerInformationList, \ - ImplementationRepository::ServerInformationList_out \ + ImplementationRepository::ServerInformationList_var \ > # pragma instantiate \ @@ -6382,7 +6385,7 @@ POA_ImplementationRepository::Administration::_this (ACE_ENV_SINGLE_ARG_DECL) # pragma instantiate \ TAO::Out_Var_Size_SArgument_T< \ ImplementationRepository::ServerInformation, \ - ImplementationRepository::ServerInformation_out \ + ImplementationRepository::ServerInformation_var \ > # pragma instantiate \ @@ -6391,7 +6394,7 @@ POA_ImplementationRepository::Administration::_this (ACE_ENV_SINGLE_ARG_DECL) ImplementationRepository::ServerInformationIterator_out \ > -#endif /* !ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ +#endif /* !ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ #endif /* ifndef */ diff --git a/TAO/tao/UTF16_BOM_Factory.cpp b/TAO/tao/UTF16_BOM_Factory.cpp index 98f6ed56d7c..34268eea685 100644 --- a/TAO/tao/UTF16_BOM_Factory.cpp +++ b/TAO/tao/UTF16_BOM_Factory.cpp @@ -19,6 +19,7 @@ #include "UTF16_BOM_Factory.h" #include "ace/OS_NS_strings.h" +#include "ace/Dynamic_Service.h" #include "ace/Log_Msg.h" // Instantiate templates that allow discovery of this factory |