diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Event')
48 files changed, 0 insertions, 13315 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Event/BCU.cpp b/TAO/orbsvcs/orbsvcs/Event/BCU.cpp deleted file mode 100644 index 45d121f8b60..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/BCU.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// $Id$ - -#include "ace/ACE.h" -#include "BCU.h" - -ACE_RCSID(Event, BCU, "$Id$") - -u_long -ACE_BCU (u_long n) -{ - const u_long ACE_BCU_PRIME_NUMBER = 9619; - - u_long retval = 0; - - while (n-- > 0) - retval = ACE::is_prime (ACE_BCU_PRIME_NUMBER, 2, ACE_BCU_PRIME_NUMBER / 2); - - return retval; -} - - -u_long -ACE_BCU (u_long number, - u_long n) -{ - u_long retval = 0; - - while (n-- > 0) - retval = ACE::is_prime (number, 2, number); - - return retval; -} diff --git a/TAO/orbsvcs/orbsvcs/Event/BCU.h b/TAO/orbsvcs/orbsvcs/Event/BCU.h deleted file mode 100644 index 6e81c989e15..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/BCU.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ace ORB -// -// = FILENAME -// Benchmark Computation Units -// -// = AUTHOR -// David Levine and Tim Harrison (harrison@cs.wustl.edu) -// -// = DESCRIPTION -// -// Times how long it takes to generate each of the first N prime -// numbers. -// ============================================================================ - -#ifndef ACE_BCU_H -#define ACE_BCU_H - -#include "ace/OS.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "orbsvcs/orbsvcs_export.h" - - -TAO_ORBSVCS_Export u_long ACE_BCU (u_long n); -// Check if a specific, hardcoded number is prime (via ACE::is_prime) <n> -// times. - - -TAO_ORBSVCS_Export u_long ACE_BCU (u_long number, u_long n); -// Check if <number> is prime (via ACE::is_prime ()) <n> times. - -#endif /* ACE_BCU_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Channel_Clients.i b/TAO/orbsvcs/orbsvcs/Event/Channel_Clients.i deleted file mode 100644 index 6318deb79a0..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Channel_Clients.i +++ /dev/null @@ -1,2 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ diff --git a/TAO/orbsvcs/orbsvcs/Event/Channel_Clients_T.i b/TAO/orbsvcs/orbsvcs/Event/Channel_Clients_T.i deleted file mode 100644 index f7c0760fd86..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Channel_Clients_T.i +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -template <class TARGET> ACE_INLINE -ACE_PushConsumer_Adapter<TARGET>::ACE_PushConsumer_Adapter (TARGET *target) - : target_ (target) -{ -} - -template <class TARGET> ACE_INLINE void -ACE_PushConsumer_Adapter<TARGET>::push (const RtecEventComm::EventSet& events, - CORBA::Environment &_env) -{ - target_->_push (events, _env); -} - -template <class TARGET> ACE_INLINE void -ACE_PushConsumer_Adapter<TARGET>::disconnect_push_consumer (CORBA::Environment &_env) -{ - target_->_disconnect_push_consumer (_env); -} - -// ************************************************************ - -template <class TARGET> ACE_INLINE -ACE_PushSupplier_Adapter<TARGET>::ACE_PushSupplier_Adapter (TARGET *target) - : target_ (target) -{ -} - -template <class TARGET> ACE_INLINE void -ACE_PushSupplier_Adapter<TARGET>::disconnect_push_supplier (CORBA::Environment &_env) -{ - target_->_disconnect_push_supplier (_env); -} diff --git a/TAO/orbsvcs/orbsvcs/Event/Debug_Macros.h b/TAO/orbsvcs/orbsvcs/Event/Debug_Macros.h deleted file mode 100644 index ca7122d7c69..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Debug_Macros.h +++ /dev/null @@ -1,13 +0,0 @@ -// $Id$ - - -#if defined (ACE_ES_NOLOGGING) -#define ACE_ES_DEBUG(X) -#define ACE_ES_DEBUG_ST(X) -#else -#define ACE_ES_DEBUG(X) \ - do { \ - ACE_Log_Msg::instance ()->log X; \ - } while (0) -#define ACE_ES_DEBUG_ST(X) X -#endif /* ACE_ES_NOLOGGING */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.cpp b/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.cpp deleted file mode 100644 index 55c57829908..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.cpp +++ /dev/null @@ -1,744 +0,0 @@ -// $Id$ - -#include "ace/Sched_Params.h" -#include "orbsvcs/Scheduler_Factory.h" -#include "orbsvcs/Time_Utilities.h" -#include "Memory_Pools.h" - -#include "Dispatching_Modules.h" - -#if !defined (__ACE_INLINE__) -#include "Dispatching_Modules.i" -#endif /* __ACE_INLINE__ */ - -#include "tao/Timeprobe.h" - -ACE_RCSID(Event, Dispatching_Modules, "$Id$") - -#if defined (ACE_ENABLE_TIMEPROBES) - -static const char *TAO_Dispatching_Modules_Timeprobe_Description[] = -{ - "dispatch (dequeue) the event", - "push_source_type: Correlation Module", - "Priority_Dispatching::push - priority requested", - "Priority_Dispatching::push - priority obtained" -}; - -enum -{ - // Timeprobe description table start key - TAO_DISPATCHING_MODULES_DISPATCH_THE_EVENT = 5000, - TAO_DISPATCHING_MODULES_PUSH_SOURCE_TYPE_CORRELATION_MODULE, - TAO_DISPATCHING_MODULES_PRIORITY_DISPATCHING_PUSH_PRIORITY_REQUESTED, - TAO_DISPATCHING_MODULES_PRIORITY_DISPATCHING_PUSH_PRIORITY_OBTAINED -}; - -// Setup Timeprobes -ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Dispatching_Modules_Timeprobe_Description, - TAO_DISPATCHING_MODULES_DISPATCH_THE_EVENT); - -#endif /* ACE_ENABLE_TIMEPROBES */ - -// ************************************************************ - -ACE_ES_Dispatch_Request:: -ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, - const TAO_EC_Event &event, - RtecScheduler::handle_t rt_info) - : priority_ (0), - rt_info_ (rt_info), - dispatching_module_ (0), - use_single_event_ (0), - consumer_ (consumer), - event_set_ (1) -{ - this->event_set_.set (event, 0); -} - -void -ACE_ES_Dispatch_Request::make_copy (RtecEventComm::EventSet &dest) const -{ - if (use_single_event_) - { - // The RtecEventComm::EventSet will hold a pointer to the - // buffer, without owning it, thus it is not removed! - // @@ TODO Check what happens in the collocated case. - dest.replace (1, 1, - ACE_const_cast(RtecEventComm::Event*, - &this->single_event_.event ()), - 0); - } - else if (this->event_set_.size () == 1) - { - dest.replace (1, 1, - ACE_const_cast(RtecEventComm::Event*, - &this->event_set_[0].event ()), - 0); - } - else - { - dest.length (this->event_set_.size ()); - - int c = 0; - for (CORBA::ULong i = 0; i < this->event_set_.size (); ++i) - { - if (this->event_set_[i].empty ()) - continue; - dest[c] = this->event_set_[i].event (); - c++; - } - dest.length (c); - } -} - -void -ACE_ES_Dispatch_Request::append_event (const TAO_EC_Event& event) -{ - size_t size = this->event_set_.size (); - if (this->event_set_.size (size + 1) == 0) - this->event_set_.set (event, size); -} - -int -ACE_ES_Dispatch_Request::execute (u_long &command_action) -{ - ACE_TIMEPROBE (TAO_DISPATCHING_MODULES_DISPATCH_THE_EVENT); - - return dispatching_module_->dispatch_event (this, command_action); -} - -#if 0 -// @@ Memory pools -void * -ACE_ES_Dispatch_Request::operator new (size_t nbytes) -{ - if (nbytes > sizeof (ACE_ES_Dispatch_Request)) - { - ACE_ERROR ((LM_ERROR, "nbytes = %d, sizeof (ACE_ES_Dispatch_Request_Chunk) = %d.\n", - sizeof (ACE_ES_Dispatch_Request))); - ACE_ASSERT (nbytes <= sizeof (ACE_ES_Dispatch_Request)); - } - - return ACE_ES_Memory_Pools::new_Dispatch_Request (); -} - -void -ACE_ES_Dispatch_Request::operator delete (void *mem) -{ - ACE_ES_Memory_Pools::delete_Dispatch_Request (mem); -} -#endif /* 0 */ - -// ************************************************************ - -void -ACE_ES_Dispatching_Base::activate (int) -{ -} - -void -ACE_ES_Dispatching_Base::shutdown (void) -{ - ACE_DEBUG ((LM_DEBUG, - "EC (%t) ACE_ES_Dispatching_Base module shutting down.\n")); -} - -// Just forward the request. This is basically a hook for the RTU -// stuff. -int -ACE_ES_Dispatching_Base::dispatch_event (ACE_ES_Dispatch_Request *request, - u_long &command_action) -{ - TAO_TRY - { - // Forward the request. - up_->push (request, TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - // No exceptions should be raised (push is a oneway) but we try - // to print something useful anyway. - TAO_TRY_ENV.print_exception ("ACE_ES_Dispatching_Base::dispatch_event"); - } - TAO_ENDTRY; - - // Tell our caller to release the request. - command_action = ACE_RT_Task_Command::RELEASE; - - // Return zero so our calling thread does not exit. - return 0; -} - -// ************************************************************ - -ACE_ES_Priority_Dispatching::ACE_ES_Priority_Dispatching (ACE_EventChannel *channel) - : ACE_ES_Dispatching_Base (channel), - notification_strategy_ (this, channel->timer_module ()), - highest_priority_ (0), - shutdown_ (0), - threads_per_queue_ (0) -{ - // If we're single threaded, then we need to use the notification strategy. - if ((threads_per_queue_ == 0) && - (notification_strategy_.open () == -1)) - ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Priority_Dispatching")); - - // Initialize the queues. - for (int x = 0; x < ACE_Scheduler_MAX_PRIORITIES; x++) - { - this->queues_[x] = 0; - } -} - -ACE_ES_Priority_Dispatching::~ACE_ES_Priority_Dispatching (void) -{ -} - - -void -ACE_ES_Priority_Dispatching::initialize_queues (void) -{ - for (int x = 0; x < ACE_Scheduler_MAX_PRIORITIES; x++) - { - if (this->queues_[x] != 0) - continue; - - // Convert ACE_Scheduler_Rate (it's really a period, not a rate!) - // to a form we can easily work with. - ACE_Time_Value period_tv; - ORBSVCS_Time::TimeT_to_Time_Value (period_tv, ACE_Scheduler_Rates[x]); - - RtecScheduler::Period_t period = period_tv.sec () * 10000000 + - period_tv.usec () * 10; - - ACE_NEW (this->queues_[x], - ACE_ES_Dispatch_Queue (this, ¬ification_strategy_)); - this->queues_[x]->thr_mgr (&this->thr_mgr_); - - if ( this->queues_[x]->open_queue (period, - threads_per_queue_) == -1) - { - ACE_ERROR ((LM_ERROR, "%p.\n", - "ACE_ES_Priority_Dispatching::initialize_queues")); - return; - } - - this->queue_count_[x] = 1; - } - highest_priority_ = ACE_Scheduler_MAX_PRIORITIES - 1; -} - -void -ACE_ES_Priority_Dispatching::connected (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &TAO_IN_ENV) -{ - down_->connected (consumer, TAO_IN_ENV); - - // This code does dynamic allocation of channel dispatch threads. - // It requires that consumer's priorities are known at connection - // time and that threads can request priorities from the scheduler - // at run-time. These are both antithetical to static scheduling. - // The constructor now allocates a thread per rate group. -#if 0 - // We have to tell the lower portions of the channel about the - // consumer first. This is so that any changes to the consumer's - // qos will take effect when we get the dispatch priority. - down_->connected (consumer, TAO_IN_ENV); - - RtecScheduler::OS_Priority priority = - ACE_Scheduler::instance ().preemption_priority (consumer->qos ().rt_info_); - - { - ACE_ES_GUARD ace_mon (lock_); - - // If a queue has not been created for the consumer's priority, - // create one. - if (queues_[priority] == 0) - { - // Allocate a new dispatch queue. - queues_[priority] = new ACE_ES_Dispatch_Queue (this, ¬ification_strategy_); - if (queues_[priority] == 0) - TAO_THROW (CORBA::NO_MEMORY (0, CORBA::COMPLETED_NO, - "ACE_ES_Priority_Dispatching::connected")); - - // Initialize the dispatch queue corresponding to the - // consumer's priority. With a full implementation of the - // run-time scheduler, the dispatch queue can find it's - // scheduling qos online. However, we pass the rate in case - // one is not found. The rate can be used to obtain the - // proper priority. If threads_per_queue_ == 0, then these - // queues will be passive. Otherwise, they will be active. - // This switches us between MT_ORB and ST_ORB. If we're - // single-threaded, this registers us with the ReactorEx using - // our notification_strategy_. If we're multi-threaded, this - // spawns the threads. - if (queues_[priority]->open_queue (priority, - threads_per_queue_) == -1) - TAO_THROW (DISPATCH_ERROR (0, CORBA::COMPLETED_NO, - "ACE_ES_Priority_Dispatching::connected:" - "queue open failed.\n")); - - // When this goes down to 0, we will shutdown the queue. - queue_count_[priority] = 1; - - // Keep track of this to optimize handle_signal. - if (priority > highest_priority_) - highest_priority_ = priority; - - ACE_DEBUG ((LM_DEBUG, - "EC (%t) Created queue priority = %d.\n", priority)); - } - else - queue_count_[priority]++; - } -#endif -} - -void -ACE_ES_Priority_Dispatching::disconnected (ACE_Push_Consumer_Proxy *consumer) -{ - // We'll not dynamically close down queues. - ACE_UNUSED_ARG (consumer); - -#if 0 - RtecScheduler::OS_Priority priority = - ACE_Scheduler::instance ().preemption_priority (consumer->qos ().rt_info_); - - { - ACE_ES_GUARD ace_mon (lock_); - - // If there are no more users of this queue, then we *could* shut - // it down. However, we will not. - if (--queue_count_[priority] <= 0) - { - ACE_DEBUG ((LM_DEBUG, "EC (%t) unused dispatch queue priority = %d, " - "is_empty = %d.\n", - priority, queues_[priority]->msg_queue ()->is_empty ())); - - queues_[priority]->shutdown_task (); - } - } -#endif -} - -// @@ This method could have a bypass optimization. -// <request> has been dynamically allocated by the filtering module. -void -ACE_ES_Priority_Dispatching::push (ACE_ES_Dispatch_Request *request, - CORBA::Environment &TAO_IN_ENV) -{ - ACE_TIMEPROBE (TAO_DISPATCHING_MODULES_PUSH_SOURCE_TYPE_CORRELATION_MODULE); - - RtecScheduler::OS_Priority thread_priority; - RtecScheduler::Preemption_Subpriority_t subpriority; - RtecScheduler::Preemption_Priority_t preemption_priority; - - if (request->rt_info () != 0) - { - // @@ TODO use TAO_TRY&friends - ACE_TIMEPROBE (TAO_DISPATCHING_MODULES_PRIORITY_DISPATCHING_PUSH_PRIORITY_REQUESTED); - ACE_Scheduler_Factory::server ()->priority - (request->rt_info (), - thread_priority, - subpriority, - preemption_priority, - TAO_IN_ENV); - ACE_TIMEPROBE (TAO_DISPATCHING_MODULES_PRIORITY_DISPATCHING_PUSH_PRIORITY_OBTAINED); - if (TAO_IN_ENV.exception ()) - { - return; - } - } - else - { - thread_priority = - ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, - ACE_SCOPE_PROCESS); - subpriority = ACE_Scheduler_MIN_SUB_PRIORITY; - preemption_priority = ACE_Scheduler_MIN_PREEMPTION_PRIORITY; - } - - // If it's a request to forward an event, it needs a reference to us - // to call dispatch_event. - request->set (this, preemption_priority, subpriority); - - // Make sure that a queue exists for this priority. - if (queues_[preemption_priority] == 0) - { - ACE_ERROR ((LM_ERROR, "EC (%t): Push to closed queue %d," - " dropping event.\n", preemption_priority)); - return; -#if 0 - TAO_THROW (SYNC_ERROR (0, CORBA::COMPLETED_NO, "ACE_ES_Priority_Dispatching::push")); -#endif /* 0 */ - } - - // Enqueue the request. If we're multi-threaded, this request is a - // command object that will be called by the threads in the queue, - // or will be dequeued by this->handle_signal if we're - // single-threaded. - if (queues_[preemption_priority]->try_put (request) == -1) - { - if (ACE_ES_Dispatch_Request::release (request) != 0) - ACE_ERROR ((LM_ERROR, "ACE_ES_Priority_Dispatching::push" - " release failed.\n")); - if (errno != EPIPE) - { - TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); - // @@ Orbix parameters - // 0, CORBA::COMPLETED_NO, - // "ACE_ES_Priority_Dispatching::push enqueue failed")); - } - else - { - ACE_DEBUG ((LM_DEBUG, - "EC (%t) Request rejected from closed queue %d.\n", - preemption_priority)); - } - } -} - -// Start at highest priority queue checking for queued events -// continuing to lowest priority queue. If an event is ever found, -// dispatch it and then start back at the highest priority queue -// again. -int -ACE_ES_Priority_Dispatching::handle_signal (int, siginfo_t *, ucontext_t *) -{ - int done; - - do - { - done = 1; - for (int x = 0; x <= highest_priority_; x++) - { - // If the queue is not empty, dispatch the request and then - // start the for loop from the beginning. - if ((queues_[x] != 0) && (!queues_[x]->msg_queue ()->is_empty ())) - { - // Dequeue and service the request. - queues_[x]->svc_one (); - - // Exit the for loop and start over. - done = 0; - break; - } - - // If we get through the whole for loop without dispatching - // anything, then we're done. - } - } - while (!done); - - - return 0; -} - -// This is only for the non-win32 single-threaded implementation. -int -ACE_ES_Priority_Dispatching::handle_input (ACE_HANDLE) -{ - return this->handle_signal (0, 0, 0); -} - -void -ACE_ES_Priority_Dispatching::activate (int threads_per_queue) -{ - this->threads_per_queue_ = threads_per_queue; - this->initialize_queues (); -} - -// Shutdown each queue. When each queue exits, they will call back -// this->dispatch_queue_closed which allows us to free up resources. -// When the last queue has closed, we'll delete ourselves. -void -ACE_ES_Priority_Dispatching::shutdown (void) -{ - if (shutdown_) - return; - - ACE_DEBUG ((LM_DEBUG, "EC (%t) ACE_ES_Priority_Dispatching " - "module shutting down.\n")); - - shutdown_ = 1; - - // If we're single threaded, then we need to shut down the - // notification strategy so it can remove itself from the reactor. - if (threads_per_queue_ == 0) - notification_strategy_.shutdown (); - - // Whether these are active or not, they must be shut down. - for (int x = 0; x <= highest_priority_; x++) - if (queues_[x] != 0) - { - ACE_DEBUG ((LM_DEBUG, - "EC (%t) shutting down dispatch queue %d.\n", x)); - queues_[x]->shutdown_task (); - } - - if (this->thr_mgr_.wait () == -1) - ACE_ERROR ((LM_ERROR, "%p\n", - "Priority_Dispatching::shutdown - waiting")); - - for (int i = 0; i <= this->highest_priority_; ++i) - { - if (this->queues_[i] != 0) - { - delete this->queues_[i]; - this->queues_[i] = 0; - } - } -} - -// This gets called every time a Dispatch Queue closes down. We -// search for <queue> and delete it. If we have been told to delete -// ourself, after the last queue has been deleted, we delete -// ourselves. -void -ACE_ES_Priority_Dispatching::dispatch_queue_closed (ACE_ES_Dispatch_Queue *queue) -{ -} - -/* -ACE_HANDLE -ACE_ES_Priority_Dispatching::get_handle (void) const -{ - ACE_ES_Priority_Dispatching *fake_this = (ACE_ES_Priority_Dispatching *) this; - return fake_this->notification_strategy_.get_handle (); -} -*/ - -// ************************************************************ - -ACE_ES_Dispatch_Queue::ACE_ES_Dispatch_Queue (ACE_ES_Dispatching_Base *dispatching_module, - ACE_ES_Notification_Strategy *notification_strategy) - : dispatching_module_ (dispatching_module), - notification_strategy_ (notification_strategy) -{ -} - -int -ACE_ES_Dispatch_Queue::open_queue (RtecScheduler::Period_t &period, - int threads) -{ - // First set up the correct message queue according to whether the - // dispatch queue will be active or not. - - // If there are no threads specified, we'll register with the - // reactor to be called back when someone queues a message. - if (threads == 0) - { - // Allocate a message queue that notifies a reactor when events - // arrive via the msg_queue call. If that succeeds, set the - // notification strategy in our message queue via the open call. - if (this->msg_queue () == 0 || - this->msg_queue ()->open (ACE_ES_QUEUE::DEFAULT_HWM, - ACE_ES_QUEUE::DEFAULT_LWM, - notification_strategy_) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p msg_queue.open failed.\n", - "ACE_ES_Dispatch_Queue::open_queue"), -1); - } - else - { - // quick hack to test dynamic queue performance (to be replaced soon) - ACE_ES_QUEUE *mq = 0; - #if defined (TAO_USES_STRATEGY_SCHEDULER) - #if defined (TAO_USES_EDF_SCHEDULING) - - ACE_Deadline_Message_Strategy *adms = new ACE_Deadline_Message_Strategy; - - if (adms) - { - mq = new ACE_Dynamic_Message_Queue<ACE_SYNCH> (*adms); - } - - #elif defined (TAO_USES_MLF_SCHEDULING) || defined (TAO_USES_MUF_SCHEDULING) - - ACE_Laxity_Message_Strategy *alms = new ACE_Laxity_Message_Strategy; - - if (alms) - { - mq = new ACE_Dynamic_Message_Queue<ACE_SYNCH> (*alms); - } - - #else - mq = new ACE_ES_QUEUE; - #endif - #else - // Allocate a message queue that does not notify. - mq = new ACE_ES_MQ; - #endif - - if (mq == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Dispatch_Queue::open_queue"), -1); - else - { - // This deletes previous message queue. - this->msg_queue (mq); - // Set this so that the destructor of ACE_Task deletes our - // message queue. Note, this must be after the call to - // msg_queue. - delete_msg_queue_ = 1; - } - } - - // Create a name for ourselves using the period. The period is - // in 100 ns units; first convert to usec by dividing by 10. - char temp[64]; - ACE_OS::sprintf (temp, "ACE_ES_Dispatch_Queue-%u.us", period / 10); - - // Open the task. This will query the scheduler for our qos - // structure. It will also synch_threads if it succeeds. - int result = this->open_task (temp); - - switch (result) - { - case -1: - // Error. - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Dispatch_Queue::open_queue"), -1); - case 0: - { - TAO_TRY - {// @@ TODO: Handle exceptions... - ACE_Scheduler_Factory::server()->set (rt_info_, - RtecScheduler::VERY_HIGH_CRITICALITY, - ORBSVCS_Time::zero, - ORBSVCS_Time::zero, - ORBSVCS_Time::zero, - period, - RtecScheduler::VERY_LOW_IMPORTANCE, - ORBSVCS_Time::zero, - 1, - RtecScheduler::OPERATION, - TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - ACE_ERROR_RETURN ((LM_ERROR, - "ACE_ES_Dispatch_Queue::exception"), -1); - } - TAO_ENDTRY; - } - // FALLTHROUGH - case 1: - // Found. - break; - } - - // Spawn threads. - return this->synch_threads (threads); -} - -// This is called back by ACE_RT_Task when all the threads have -// exited. We're going to forward this event to the dispatching -// module so it can clean up any resources. -void -ACE_ES_Dispatch_Queue::threads_closed (void) -{ - dispatching_module_->dispatch_queue_closed (this); -} - -// ************************************************************ - -ACE_ES_EFD_Dispatching::ACE_ES_EFD_Dispatching (ACE_EventChannel *channel) - : ACE_ES_Dispatching_Base (channel) -{ -} - -void -ACE_ES_EFD_Dispatching::push (ACE_ES_Dispatch_Request *request, - CORBA::Environment &) -{ - // If it's a request to forward an event, it needs a reference to us - // to call dispatch_event. - request->set (this, 0, ACE_Scheduler_MIN_SUB_PRIORITY); - - u_long command_action = ACE_RT_Task_Command::RELEASE; - - // This may be a request to delete a push consumer proxy, so we - // should execute it instead of just forwarding it. - request->execute (command_action); - - switch (command_action) - { - case ACE_RT_Task_Command::RELEASE: - // Free the request. - if (ACE_ES_Dispatch_Request::release (request) != 0) - ACE_ERROR ((LM_ERROR, "ACE_ES_EFD_Dispatching::push" - " release failed.\n")); - break; - - default: - ACE_ERROR ((LM_ERROR, "ACE_ES_EFD_Dispatching::push: unknown command action.\n")); - } -} - -// ************************************************************ - -ACE_ES_RTU_Dispatching::ACE_ES_RTU_Dispatching (ACE_EventChannel *channel) - : ACE_ES_Priority_Dispatching (channel) -{ -} - -// We're called from a dispatch queue, so we can not release the request. -int -ACE_ES_RTU_Dispatching::dispatch_event (ACE_ES_Dispatch_Request *request, - u_long &command_action) -{ - // Store the priority of the task currently running. - channel_->rtu_manager ()->priority (request->priority ()); - - TAO_TRY - { - // Forward the request. - up_->push (request, TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - // No exceptions should be raised (push is a oneway) but we try - // to print something useful anyway. - TAO_TRY_ENV.print_exception ("ACE_ES_Dispatching_Base::dispatch_event"); - } - TAO_ENDTRY; - - // Reset the priority. - channel_->rtu_manager ()->priority (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, ACE_SCOPE_PROCESS)); - - // If the task was preempted, enqueue the request on the head of the - // dispatch queue. - if (channel_->rtu_manager ()->not_done ()) - command_action = ACE_RT_Task_Command::UNGETQ; - else - // We're done with it. - command_action = ACE_RT_Task_Command::RELEASE; - - return 0; -} - -void -ACE_ES_RTU_Dispatching::push (ACE_ES_Dispatch_Request *request, - CORBA::Environment &TAO_IN_ENV) -{ - // First enqueue the message in the proper queue. - ACE_ES_Priority_Dispatching::push (request, TAO_IN_ENV); - - // If the current event is higher priority (lower value) than the - // current running task, then tell the task to preempt itself. - int request_priority = request->priority (); - int running_priority = channel_->rtu_manager ()->priority (); - if (request_priority < running_priority) - channel_->rtu_manager ()->should_preempt (1); - return; -} - -#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/Event/Dispatching_Modules.h b/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.h deleted file mode 100644 index 17fbf06b9b9..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.h +++ /dev/null @@ -1,503 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// orbsvcs -// -// = FILENAME -// Dispatching_Module -// -// = AUTHOR -// Tim Harrison (harrison@cs.wustl.edu) -// -// = DESCRIPTION -// This file holds the different Event Service dispatching -// mechanisms. These include null-dispatching (EFD), -// single-threaded with (RTU) and without preemption (LAME), and a -// multithreaded implementation. -// -// ============================================================================ - -#ifndef ACE_DISPATCHING_MODULES_H -#define ACE_DISPATCHING_MODULES_H - -#include "tao/Timeprobe.h" -#include "orbsvcs/Event/ReactorTask.h" -#include "orbsvcs/Event/Event_Manip.h" -#include "orbsvcs/Event/Event_Channel.h" - -// ************************************************************ - -// Forward declarations. -class ACE_ES_Dispatch_Queue; -class ACE_ES_Dispatch_Request; - -// ************************************************************ - -// Forward declarations. -class ACE_ES_Consumer_Module; - -class TAO_ORBSVCS_Export ACE_ES_Dispatching_Base : public ACE_Event_Handler -// = TITLE -// Event Service Dispatch Module base class -// -// = DESCRIPTION -// We inherit from ACE_Event_Handler so that we can be called back -// by the ReactorEx when requests are queued. The virtual -// dispatch_event method allows ACE_ES_Dispatch_Requests to call -// back the dispatching module when acting as command objects. When -// this implementation is used by the Event Channel it forwards all -// dispatch calls without any queuing. Therefore, it can be -// used to build an EFD. It is also inherited by the Priority -// Dispatching module. -{ -public: - ACE_ES_Dispatching_Base (ACE_EventChannel *channel); - // Default construction. - - virtual void open (ACE_ES_Consumer_Module *up, - ACE_ES_Correlation_Module *down); - // Link to adjacent modules. - - virtual void connected (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &); - // Forward down_. - - virtual void disconnecting (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &); - // Forward down_. - - virtual void disconnected (ACE_Push_Consumer_Proxy *consumer); - // Release any unneeded dispatching resources. - - // = Not needed. - // void connected (ACE_Push_Supplier_Proxy *supplier); - // void disconnecting (ACE_Push_Supplier_Proxy *supplier); - - virtual void push (ACE_ES_Dispatch_Request *request, - CORBA::Environment &) = 0; - // Forward up_. - - virtual int dispatch_event (ACE_ES_Dispatch_Request *request, - u_long &command_action); - // Called by ACE_ES_Dispatch_Requests when dequeued by RT_Tasks. - - virtual void dispatch_queue_closed (ACE_ES_Dispatch_Queue *q); - // Called when all the threads of a <q> have exited. - - virtual void activate (int threads_per_queue); - // This is called by the Event Channel. It will create all the - // threads and only return once they are all up and running. - - virtual void shutdown (void); - // This is called by the Event Channel. This will attempt to shut - // down all of its threads gracefully. Wish it luck. - -protected: - ACE_EventChannel *channel_; - // Dat der channel. - - ACE_ES_MUTEX lock_; - // To synchronize thr_count_. - - int thr_count_; - // The total number of threads in the Dispatching Module. This will - // be the sum of all the Dispatch Queue threads. - - ACE_ES_Consumer_Module *up_; - // Next module up. - - ACE_ES_Correlation_Module *down_; - // Next module down. -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_Dispatch_Request : public ACE_RT_Task_Command -// = TITLE -// ACE Event Service Dispatch Request -// -// = DESCRIPTION -// Encapsulates a consumer and the events that will be sent to the -// consumer. Right now, this class keeps a single_event_ that can -// be used when only one event is sent to the consumer. Since this -// is frequently the case (except for correlations), this -// optimization reduces the amount of dynamic memory allocation is -// necessary. This class is also a GOF Command object since it can -// be dequeued by an RT_Task to call back the dispatching module -// for request dispatching. -{ -public: - ACE_ES_Dispatch_Request (void); - // Default construction. - - virtual ~ACE_ES_Dispatch_Request (void); - // Default destruction. - - ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, - RtecScheduler::handle_t rt_info); - // All the events must be added after construction to the - // event_set. - - ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, - const TAO_EC_Event_Array &event_set, - RtecScheduler::handle_t rt_info); - // Set consumer_ to <consumer> and copy <event_set> to event_set_. - // <rt_info> describes the method receiving this dispatch. - - ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, - const RtecEventComm::Time &time, - RtecScheduler::handle_t rt_info); - // Set consumer_ to <consumer> and sets - // single_event_.header.creation_time to <time>. Sets - // use_single_event_ to 1. <rt_info> describes the method - // receiving this dispatch. - - ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, - const TAO_EC_Event &event, - RtecScheduler::handle_t rt_info); - // Sets consumer_ and the first slot of event_set_. We use the - // event_set_ instead of the single_event_ so that we can just carry - // around the pointer to <event>. <rt_info> describes the method - // receiving this dispatch. - - RtecScheduler::handle_t rt_info (void); - // Description of the method receiving this request. - - void set (ACE_ES_Dispatching_Base *dispatching_module, - RtecScheduler::OS_Priority priority, - RtecScheduler::Preemption_Subpriority_t sub_priority); - // For multi-threaded implementations, <dispatching_module> is - // called back when a request is dequeued. <priority> is the - // dispatch priority of the event. <sub_priority> is the enqueue - // priority of the event and will be forwarded to - // ACE_Message_Block. - - ACE_Push_Consumer_Proxy *consumer (void) const; - // Consumer accessor. - - const TAO_EC_Event_Array &event_set (void) const; - // If accessed, make_copy will use event_set_. - - TAO_EC_Event_Array &event_set (void); - // If accessed, make_copy will use event_set_. - - void append_event (const TAO_EC_Event& event); - // Append an event to the list of events in the Request. - - CORBA::ULong number_of_events (void) const; - // Returns 1 if we're using single_event, or event_set_.size (). - - void make_copy (RtecEventComm::EventSet &dest) const; - // Copy single_event or event_set into <dest>. - // @@ Change the name to something more meaningful... - - virtual int execute (u_long &command_action); - // Calls dispatching_module_->dispatch_event. - - RtecScheduler::OS_Priority priority (void); - // Priority accessor. - -#if 0 - // @@ Memory pools - // @@ This cannot be done: the object would be allocated using this - // class operator new, but it will be removed using the - // ACE_Message_Block operator delete! - void *operator new (size_t nbytes); - // Allocates memory from a thread-specific memory pool. - - void operator delete (void *); - // Returns memory to a thread-specific memory pool. -#endif - -protected: - RtecScheduler::OS_Priority priority_; - - RtecScheduler::handle_t rt_info_; - // Describes the method receiving this dispatch. - - ACE_ES_Dispatching_Base *dispatching_module_; - // The dispatching module called back when we're dequeued by a - // thread. - - int use_single_event_; - // Is true if we're using a single event. Is 0 is we're using - // event_set_. - - ACE_Push_Consumer_Proxy *consumer_; - // The final destination for single_event_ or event_set_. - - TAO_EC_Event single_event_; - // This is used for single event dispatches. - - TAO_EC_Event_Array event_set_; - // This is used for event sets that need to be dispatched. -}; - -// ************************************************************ - -#if defined (ACE_WIN32) -class TAO_ORBSVCS_Export ACE_ES_ReactorEx_NS : public ACE_Notification_Strategy -// = TITLE -// Event Service ReactorEx Notification Strategy -// -// = DESCRIPTION -// Integrates the ACE_Message_Queue notification to signal a -// handle that will wake up the ACE_ES_Priority_Dispatching -// module. This is used in place of the -// ACE_ReactorEx_Notification_Strategy to avoid any queueing by -// the ReactorEx::notify mechanism. -{ -public: - ACE_ES_ReactorEx_NS (ACE_Event_Handler *eh, - TAO_EC_Timer_Module *tm); - // Stores away <eh> for when this->open is called. - - int open (void); - // Registers eh_ with the ReactorEx to be notified when this->notify - // is called. - - void shutdown (void); - // Removes self from the reactor. - - // = These result in eh_->handle_signal getting called. eh_ should - // point to a dispatching module. - virtual int notify (void); - virtual int notify (ACE_Event_Handler *, - ACE_Reactor_Mask mask); - - // ACE_HANDLE get_handle (void); - // Returns event_.handle (). - -private: - ACE_Auto_Event event_; - // Registered with the ReactorEx. - - TAO_EC_Timer_Module *timer_module_; - // To schedule timers. -}; - -typedef ACE_ES_ReactorEx_NS ACE_ES_Notification_Strategy; - -#else // ******************************************************* - -class TAO_ORBSVCS_Export ACE_ES_Reactor_NS : public ACE_Reactor_Notification_Strategy -// = TITLE -// Event Service Reactor Notification Strategy -// -// = DESCRIPTION -// Maps to the ACE_Reactor_Notification_Strategy interface. This -// version is for non WIN32 platforms. -{ -public: - ACE_ES_Reactor_NS (ACE_Event_Handler *eh, - TAO_EC_Timer_Module *tm); - // Calls ACE_Reactor_Notification_Strategy with the ORB's reactor - // and signal mask. - - int open (void); - // Does nothing. - - void shutdown (void); - // Does nothing. -}; - -typedef ACE_ES_Reactor_NS ACE_ES_Notification_Strategy; - -#endif /* ACE_WIN32 */ - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_MQ : public ACE_ES_QUEUE -// = TITLE -// Event Service Message Queue -{ - virtual int notify (void) { return 0;} - // Does nothing. -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_Dispatch_Queue : public ACE_RT_Task -// = TITLE -// Event Service Dispatch Queue -// -// = DESCRIPTION -// An encapsulation of a dispatch queue. By inheriting from -// ACE_RT_Task, we can make this zero-threaded or multi-threaded. -{ -public: - ACE_ES_Dispatch_Queue (ACE_ES_Dispatching_Base *dispatching_module, - ACE_ES_Notification_Strategy *notification_strategy); - // Stores <dispatching_module> for this->threads_closed. Stores - // away <notification_strategy> for this->synch_threads. - - int open_queue (RtecScheduler::Period_t &period, - int threads); - // This is a hack to get the channel to work with the new - // scheduler. - -#if 0 - int open_queue (RtecScheduler::OS_Priority priority, - int threads); - // Creates a name from the <priority> and tries to find a scheduling - // qos structure. If one is not found, but created, qos_ is set - // with default values. Either way, if qos_->thread_ > 0, it calls - // this->synch_threads. Otherwise, our message queue will use - // notification_strategy_. This will cause the ReactorEx to call - // back the dispatching_module_ when requests are queued on our - // message queue. Returns 0 on success, -1 on failure. -#endif - - virtual void threads_closed (void); - // Called when every thread has exited. This will call - // dispatching_module_->dispatch_queue_closed. - -private: - ACE_ES_Dispatching_Base *dispatching_module_; - // Used in threads_closed. - - ACE_ES_Notification_Strategy *notification_strategy_; - // Notifies the Dispatching Module when a request has been queued on - // our message queue. -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_Priority_Dispatching : public ACE_ES_Dispatching_Base -// = TITLE -// Event Service Priority Dispatching Module -// -// = DESCRIPTION -// Inherits from ACE_Event_Handler to utilitize the -// ACE_Message_Queue notification strategy. This implementation -// does priority dispatching without preemption. -{ -public: - ACE_ES_Priority_Dispatching (ACE_EventChannel *channel); - // Store <channel>. - - ~ACE_ES_Priority_Dispatching (void); - // Delete queues. - - void connected (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &); - // Allocate any needed dispatching resources for this consumers - // priority. - - void disconnected (ACE_Push_Consumer_Proxy *consumer); - // Release unneeded dispatch queues. - - // = Not needed. - // void connected (ACE_Push_Supplier_Proxy *supplier); - // void disconnecting (ACE_Push_Supplier_Proxy *supplier); - - virtual void push (ACE_ES_Dispatch_Request *request, - CORBA::Environment &); - // Enqueues the request on the appropriate Dispatch Queue. - - virtual void activate (int threads_per_queue); - // Open all queues. - // Spawns <threads_per_queue> thread for each dispatch queue. - // If != 0, then the channel is an MT_CHANNEL. - // If == 0, then the channel is an ST_CHANNEL. - - virtual void shutdown (void); - // Closes all queues "asynchronously." When all queues are closed, - // deletes them all and then deletes itself. - - virtual void dispatch_queue_closed (ACE_ES_Dispatch_Queue *q); - // Called when all the threads of a <q> have exited. Deletes <q>. - - // virtual ACE_HANDLE get_handle (void) const; - // Get the I/O handle. - -protected: - virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); - // Called when input has arrived on a message queue. This is used - // for single-threaded implementations. - - virtual int handle_input (ACE_HANDLE); - // For single-threaded implementations on non-win32 platforms that - // use the ACE_Reactor_Notification_Strategy. This just forwards - // all calls to this->handle_signal (). - - ACE_ES_Notification_Strategy notification_strategy_; - // Shared between all dispatch queues. - - void initialize_queues (void); - // This is a hack to create a queue for each of the 4 rate groups. - - ACE_ES_Dispatch_Queue *queues_[ACE_Scheduler_MAX_PRIORITIES]; - // Pointers to dispatch queues. - - int queue_count_[ACE_Scheduler_MAX_PRIORITIES]; - // The number of consumers using each queue. - - int highest_priority_; - // The highest priority queue in queues_. This allows us to - // optimize the handle_signal method. - - int shutdown_; - // Make sure to only shutdown the dispatching module once. - - int threads_per_queue_; - // The number of threads to spawn for each dispatch queue. - - ACE_RT_Thread_Manager thr_mgr_; - // The thread manager for the threads of this object. -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_EFD_Dispatching : public ACE_ES_Dispatching_Base -// = TITLE -// Event Service EFD Dispatching Module -// -// = DESCRIPTION -// Implements a zero-threaded dispatcher with no preemption. -{ -public: - ACE_ES_EFD_Dispatching (ACE_EventChannel *channel); - // Acquires the proper qos structure and passes <channel> onto to - // the dispatching base constructor. - - virtual void push (ACE_ES_Dispatch_Request *request, - CORBA::Environment &); - // Forward up_. -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_RTU_Dispatching : public ACE_ES_Priority_Dispatching -// = TITLE -// Event Service RTU Dispatching Module -// -// = DESCRIPTION -// Implements a single-threaded dispatcher with delayed preemption. -{ -public: - ACE_ES_RTU_Dispatching (ACE_EventChannel *channel); - // Store <channel>. - - virtual int dispatch_event (ACE_ES_Dispatch_Request *request, - u_long &command_action); - // Called by ACE_Dispatch_Queues and handle_signal when an event - // needs to be dequeued. Implements an RTU-like delayed preemption - // policy. - - virtual void push (ACE_ES_Dispatch_Request *request, - CORBA::Environment &); - // Calls ACE_ES_Priority_Dispatching::push and then checks if - // preemption is necessary. -}; - -#if defined (__ACE_INLINE__) -#include "Dispatching_Modules.i" -#endif /* __ACE_INLINE__ */ - -#endif /* ACE_DISPATCHING_MODULES_H */ - - diff --git a/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.i b/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.i deleted file mode 100644 index fd86083a7f0..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Dispatching_Modules.i +++ /dev/null @@ -1,248 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -ACE_INLINE -ACE_ES_Dispatch_Request::ACE_ES_Dispatch_Request (void) - : priority_ (0), - rt_info_ (0), - dispatching_module_ (0), - use_single_event_ (0), - consumer_ (0), - event_set_ (1) -{ -} - -ACE_INLINE -ACE_ES_Dispatch_Request::~ACE_ES_Dispatch_Request (void) -{ -} - -ACE_INLINE -ACE_ES_Dispatch_Request:: -ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, - RtecScheduler::handle_t rt_info) - : priority_ (0), - rt_info_ (rt_info), - dispatching_module_ (0), - use_single_event_ (0), - consumer_ (consumer), - event_set_ (1) -{ -} - -ACE_INLINE -ACE_ES_Dispatch_Request:: -ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, - const TAO_EC_Event_Array &event_set, - RtecScheduler::handle_t rt_info) - : priority_ (0), - rt_info_ (rt_info), - dispatching_module_ (0), - use_single_event_ (0), - consumer_ (consumer), - single_event_ (), - event_set_ (event_set) -{ -} - -#if 0 -ACE_INLINE -ACE_ES_Dispatch_Request::ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, - ACE_ES_Event_Container *event, - RtecScheduler::handle_t rt_info) : - priority_ (0), - rt_info_ (rt_info), - dispatching_module_ (0), - use_single_event_ (0), - consumer_ (consumer), - single_event_ (), - event_set_ () -{ - event_set_ += event; -} -#endif - -ACE_INLINE -ACE_ES_Dispatch_Request:: -ACE_ES_Dispatch_Request (ACE_Push_Consumer_Proxy *consumer, - const RtecEventComm::Time &time, - RtecScheduler::handle_t rt_info) - : priority_ (0), - rt_info_ (rt_info), - dispatching_module_ (0), - use_single_event_ (1), - consumer_ (consumer), - event_set_ (1) -{ - // @@ TODO this could be more efficient - RtecEventComm::Event tmp; - tmp.header.creation_time = time; - tmp.header.type = ACE_ES_EVENT_TIMEOUT; - TAO_EC_Event_Set* set = - TAO_EC_Event_Set::_create (tmp); - this->single_event_ = TAO_EC_Event (set, set->length ()); - - TAO_EC_Event_Set::_release (set); -} - -ACE_INLINE void -ACE_ES_Dispatch_Request::set (ACE_ES_Dispatching_Base *dispatching_module, - RtecScheduler::OS_Priority preemption_priority, - RtecScheduler::Preemption_Subpriority_t sub_priority) -{ - dispatching_module_ = dispatching_module; - priority_ = preemption_priority; - ACE_Message_Block::msg_priority (sub_priority); -} - -ACE_INLINE ACE_Push_Consumer_Proxy * -ACE_ES_Dispatch_Request::consumer (void) const -{ - return consumer_; -} - -ACE_INLINE const TAO_EC_Event_Array& -ACE_ES_Dispatch_Request::event_set (void) const -{ - return event_set_; -} - -ACE_INLINE TAO_EC_Event_Array& -ACE_ES_Dispatch_Request::event_set (void) -{ - return event_set_; -} - -ACE_INLINE CORBA::ULong -ACE_ES_Dispatch_Request::number_of_events (void) const -{ - if (this->use_single_event_) - return 1; - else - return this->event_set_.size (); -} - -ACE_INLINE RtecScheduler::OS_Priority -ACE_ES_Dispatch_Request::priority (void) -{ - return priority_; -} - -ACE_INLINE RtecScheduler::handle_t -ACE_ES_Dispatch_Request::rt_info (void) -{ - return rt_info_; -} - -// ************************************************************ - -ACE_INLINE -ACE_ES_Dispatching_Base::ACE_ES_Dispatching_Base (ACE_EventChannel *channel) - : channel_ (channel), - thr_count_ (0), - up_ (0), - down_ (0) -{ -} - -ACE_INLINE void -ACE_ES_Dispatching_Base::open (ACE_ES_Consumer_Module *up, - ACE_ES_Correlation_Module *down) -{ - up_ = up; - down_ = down; - // 1 == 2. -} - -ACE_INLINE void -ACE_ES_Dispatching_Base::connected (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &_env) -{ - down_->connected (consumer, _env); -} - -ACE_INLINE void -ACE_ES_Dispatching_Base::disconnected (ACE_Push_Consumer_Proxy *consumer) -{ - // Do nothing. - ACE_UNUSED_ARG (consumer); -} - -ACE_INLINE void -ACE_ES_Dispatching_Base::disconnecting (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &_env) -{ - down_->disconnecting (consumer, _env); -} - -ACE_INLINE void -ACE_ES_Dispatching_Base::dispatch_queue_closed (ACE_ES_Dispatch_Queue *q) -{ - ACE_UNUSED_ARG (q); -} - -// ************************************************************ - -#if defined (ACE_WIN32) -ACE_INLINE -ACE_ES_ReactorEx_NS::ACE_ES_ReactorEx_NS (ACE_Event_Handler *eh, - TAO_EC_Timer_Module* tm) - : ACE_Notification_Strategy (eh, ACE_Event_Handler::NULL_MASK), - timer_module_ (tm) -{ -} - -ACE_INLINE int -ACE_ES_ReactorEx_NS::open (void) -{ - return this->timer_module_->register_handler (0, - eh_, - event_.handle ()); -} - -ACE_INLINE void -ACE_ES_ReactorEx_NS::shutdown (void) -{ -// @@ TODO: Fix this. -// this->timer_module_->remove_handler (0, -// eh_, -// ACE_Event_Handler::DONT_CALL); -} - -ACE_INLINE int -ACE_ES_ReactorEx_NS::notify (void) -{ - return this->event_.signal (); -} - -ACE_INLINE int -ACE_ES_ReactorEx_NS::notify (ACE_Event_Handler *, - ACE_Reactor_Mask) -{ - return this->event_.signal (); -} - -#else /* !defined (ACE_WIN32) */ -// This class is only necessary on non-win32 platforms. -ACE_INLINE -ACE_ES_Reactor_NS::ACE_ES_Reactor_NS (ACE_Event_Handler *eh, - TAO_EC_Timer_Module *tm) - : ACE_Reactor_Notification_Strategy (tm->reactor (0), - eh, ACE_Event_Handler::READ_MASK) -{ -} - -ACE_INLINE int -ACE_ES_Reactor_NS::open (void) -{ - return 0; -} - -ACE_INLINE void -ACE_ES_Reactor_NS::shutdown (void) -{ -} - -#endif /* ACE_WIN32 */ - -// ************************************************************ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_ConsumerAdmin.h b/TAO/orbsvcs/orbsvcs/Event/EC_ConsumerAdmin.h deleted file mode 100644 index 7df39d3058c..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_ConsumerAdmin.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ORBSVCS Real-time Event Channel -// -// = FILENAME -// EC_ConsumerAdmin -// -// = AUTHOR -// Carlos O'Ryan (coryan@cs.wustl.edu) -// -// = DESCRIPTION -// Implement the RtecEventChannelAdmin::ConsumerAdmin interface. -// This class is an Abstract Factory for the -// TAO_EC_ProxyPushSupplier. -// -// = CREDITS -// Based on previous work by Tim Harrison (harrison@cs.wustl.edu) -// and other members of the DOC group. -// More details can be found in: -// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz -// http://www.cs.wustl.edu/~schmidt/JSAC-98.ps.gz -// -// -// ============================================================================ - -#ifndef TAO_EC_PROXYSUPPLIER_H -#define TAO_EC_PROXYSUPPLIER_H - -#include "orbsvcs/Event/EC_Filter.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class TAO_EC_Dispatching; -class TAO_EC_Filter_Builder; - -class TAO_EC_ConsumerAdmin : public POA_RtecEventChannelAdmin::ConsumerAdmin -{ - // = TITLE - // ProxyPushSupplier - // - // = DESCRIPTION - // Implements the ConsumerAdmin interface, i.e. the factory for - // ProxyPushSupplier objects. - // - // = MEMORY MANAGMENT - // It does not assume ownership of the TAO_EC_Dispatching object - // or the EC_Filter_Builder object. - // - // = LOCKING - // No provisions for locking, access must be serialized - // externally. - // - // = TODO - // We don't need to provide a trivial filter, the object itself - // could short-circuit the filter() ---> push() cycle when the EC - // is properly configured, we need to explore this... - // -public: - TAO_EC_ConsumerAdmin (TAO_EC_Event_Channel* dispatching); - // constructor... - - virtual ~TAO_EC_ConsumerAdmin (void); - // destructor... - - virtual void activate (TAO_EC_ProxyPushSupplier* proxy, - RtecEventChannelAdmin::ProxyPushSupplier_out objref, - CORBA::Environment& env) = 0; - virtual void deactivate (TAO_EC_ProxyPushSupplier* proxy, - RtecEventChannelAdmin::ProxyPushSupplier_ptr objref, - CORBA::Environment& env) = 0; - - // = The RtecEventChannelAdmin::ConsumerAdmin methods... - virtual RtecEventChannelAdmin::ProxyPushSupplier_ptr - obtain_push_supplier (CORBA::Environment &); - -private: - TAO_EC_ConsumerAdmin* consumer_admin_; - // The consumer admin, used for activation and memory managment. - - TAO_EC_Dispatching *dispatching_; - // We delegate on this object to handle - - RtecEventComm::PushConsumer_var consumer_; - // The consumer.... - - CORBA::Boolean suspended_; - // Is this consumer suspended? - - RtecEventChannelAdmin::ConsumerQOS qos_; - // The subscription and QoS information... -}; - -#if defined (__ACE_INLINE__) -#include "EC_ProxySupplier.i" -#endif /* __ACE_INLINE__ */ - -#endif /* TAO_EC_PROXYSUPPLIER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_Dispatching.h b/TAO/orbsvcs/orbsvcs/Event/EC_Dispatching.h deleted file mode 100644 index 0fecaa31896..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_Dispatching.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ORBSVCS Real-time Event Channel -// -// = FILENAME -// EC_Dispatching -// -// = AUTHOR -// Carlos O'Ryan (coryan@cs.wustl.edu) -// -// = DESCRIPTION -// The dispatching strategies. -// The EC may be configured with different dispatching strategies, -// for instance, it can use a pool of threads to dispatch the -// events, or a set of queues with threads at different priorities -// for each queue or can simply push the event to the consumer in -// FIFO order. -// -// = CREDITS -// Based on previous work by Tim Harrison (harrison@cs.wustl.edu) -// and other members of the DOC group. -// More details can be found in: -// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz -// http://www.cs.wustl.edu/~schmidt/JSAC-98.ps.gz -// -// -// ============================================================================ - -#ifndef TAO_EC_FILTER_H -#define TAO_EC_FILTER_H - -#include "orbsvcs/RtecEventComm.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class TAO_EC_Dispatching -{ - // = TITLE - // Abstract base class for the dispatching strategies. - // - // = DESCRIPTION - // Defines the dispatching strategy interface. - // -public: - virtual ~TAO_EC_Dispatching (void); - // destructor... - - virtual void activate (void) = 0; - // Initialize all the data structures, activate any internal threads, - // etc. - - virtual void shutdown (void) = 0; - // Deactivate any internal threads and cleanup internal data - // structures, it should only return once the threads have finished - // their jobs. - - virtual void push (TAO_EC_ProxyPushSupplier* proxy, - const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env) = 0; - // The consumer represented by <proxy> should receive <event>. - // It can use the information in <qos_info> to determine the event - // priority (among other things). -}; - -// **************************************************************** - -class TAO_EC_Reactive_Dispatching -{ - // = TITLE - // Dispatch using the caller thread. - // - // = DESCRIPTION - // The events are dispatched in FIFO ordering, using the invoking - // thread to push the event to the consumer. - // -public: - TAO_EC_Priority_Dispatching (RtecScheduler::Scheduler_ptr - scheduler); - // The scheduler is used to find the range of priorities and similar - // info. - - // = The EC_Dispatching methods. - virtual void activate (void); - virtual void shutdown (void); - virtual void push (TAO_EC_ProxyPushSupplier* proxy, - const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - // @@ proxy->consumer ()->push (event, env); - -}; - -// **************************************************************** - -#if 0 -#include "orbsvcs/RtecSchedulerC.h" -// @@ Move to a separate file, otherwise we have to include the file -// above everywhere -class TAO_EC_Priority_Dispatching -{ - // = TITLE - // Priority based dispatching. - // - // = DESCRIPTION - // The events are processed using a different queue for each - // priority; a thread process each queue, each thread runs at a - // different OS priority. - // -public: - TAO_EC_Priority_Dispatching (RtecScheduler::Scheduler_ptr - scheduler); - // The scheduler is used to find the range of priorities and similar - // info. - - // = The EC_Dispatching methods. - virtual void activate (void); - virtual void shutdown (void); - virtual void push (TAO_EC_ProxyPushSupplier* proxy, - const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - -private: - ACE_Thread_Manager thread_manager_; - // Use our own thread manager. -}; -#endif /* 0 */ - -// @@ TODO -// We could implement other dispatching strategies, such as: -// - A single queue with a thread pool to process each event (how does -// it compare to a thread pool in the ORB?): it should improve -// throughput when multiple CPUs are present. -// - Enqueuing, but ordering the queue by priority. - -#if defined (__ACE_INLINE__) -#include "EC_Dispatching.i" -#endif /* __ACE_INLINE__ */ - -#endif /* TAO_EC_DISPATCHING_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_Event_Channel.h b/TAO/orbsvcs/orbsvcs/Event/EC_Event_Channel.h deleted file mode 100644 index f8c99265931..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_Event_Channel.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ORBSVCS Real-time Event Channel -// -// = FILENAME -// EC_Event_Channel -// -// = AUTHOR -// Carlos O'Ryan (coryan@cs.wustl.edu) -// -// = DESCRIPTION -// A new implementation of the Real Time Event Services. -// Based on previous work by Tim Harrison (harrison@cs.wustl.edu) -// and other members of the DOC group. -// More details can be found in: -// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz -// http://www.cs.wustl.edu/~schmidt/JSAC-98.ps.gz -// -// -// ============================================================================ - -#ifndef TAO_EC_EVENT_CHANNEL_H -#define TAO_EC_EVENT_CHANNEL_H - -#include "ace/OS.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class TAO_EC_Event_Channel : public POA_RtecEventChannelAdmin::EventChannel -{ -public: - TAO_EC_Event_Channel (TAO_EC_Factory* factory); - // constructor - - virtual ~TAO_EC_Event_Channel (void); - // destructor - - virtual void activate (CORBA::Environment& env); - // Create all the objects, connect them, start the internal threads - // (if any), etc. - // After this call the EC can be used. - - virtual void shutdown (CORBA::Environment &env); - // Shutdown any internal threads, cleanup all the internal - // structures, flush all the messages, etc. - - TAO_EC_Dispatching* dispatching (void) const; - // Access the dispatching module.... - - TAO_EC_Filter_Builder* filter_builder (void) const; - // Access the filter builder.... - - TAO_EC_ConsumerAdmin* consumer_admin (void) const; - // Access the consumer admin implementation, useful for controlling - // the activation... - - TAO_EC_SupplierAdmin* supplier_admin (void) const; - // Access the supplier admin implementation, useful for controlling - // the activation... - - TAO_EC_Timer_Module* timer_module (void) const; - // Access the timer module... - - // = The RtecEventChannelAdmin::EventChannel methods... - virtual RtecEventChannelAdmin::ConsumerAdmin_ptr - for_consumers (CORBA::Environment& env); - // The default implementation is: - // this->consumer_admin ()->_this (env); - - virtual RtecEventChannelAdmin::SupplierAdmin_ptr - for_suppliers (CORBA::Environment& env); - // The default implementation is: - // this->supplier_admin ()->_this (env); - - virtual void destroy (CORBA::Environment &env); - RtecEventChannelAdmin::Observer_Handle - append_observer (RtecEventChannelAdmin::Observer_ptr, - CORBA::Environment &env); - void remove_objserver (RtecEventChannelAdmin::Observer_Handle, - CORBA::Environment &env); - // @@ Do we need to strategize this also????? How??? - -private: - TAO_EC_Factory *factory_; - // This is the abstract factory that creates all the objects that - // compose an event channel, the event channel simply acts as a - // Mediator among them. - - TAO_EC_Dispatching *dispatching_; - // The dispatching "module"... - - TAO_EC_ConsumerAdmin *consumer_admin_; - // The ConsumerAdmin implementation.... - - TAO_EC_SupplierAdmin *supplier_admin_; - // The SupplierAdmin implementation.... - - TAO_EC_TimerModule *timer_module_; - // The TimerModule... -}; - -#if defined (__ACE_INLINE__) -#include "EC_Event_Channel.i" -#endif /* __ACE_INLINE__ */ - -#endif /* TAO_EC_EVENT_CHANNEL_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_Filter.h b/TAO/orbsvcs/orbsvcs/Event/EC_Filter.h deleted file mode 100644 index 213ca1f8600..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_Filter.h +++ /dev/null @@ -1,222 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ORBSVCS Real-time Event Channel -// -// = FILENAME -// EC_Filter -// -// = AUTHOR -// Carlos O'Ryan (coryan@cs.wustl.edu) -// -// = DESCRIPTION -// The per-consumer filtering mechanisms. -// The EC needs to filter data passed to the consumers, so it can -// correctly satisfy its subscription requirements. -// This filtering can include correlations, sequences, timeouts, -// etc. each consumer can request different filtering criteria. -// -// Different filtering objects are associated with each consumer, -// the filters are organized in a hierarchical structure, -// corresponding to the subscription "expression" that the events -// must satisfy. -// The hierarchy is constructed using the "Builder" pattern. -// -// = CREDITS -// Based on previous work by Tim Harrison (harrison@cs.wustl.edu) -// and other members of the DOC group. -// More details can be found in: -// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz -// http://www.cs.wustl.edu/~schmidt/JSAC-98.ps.gz -// -// -// ============================================================================ - -#ifndef TAO_EC_FILTER_H -#define TAO_EC_FILTER_H - -#include "orbsvcs/RtecEventComm.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class TAO_EC_QOS_Info; - -class TAO_EC_Filter -{ - // = TITLE - // Abstract base class for the filter hierarchy. - // - // = DESCRIPTION - // Defines the filter interface. - // - // = MEMORY MANAGMENT - // It does *not* assume ownership of its parent. - // -public: - TAO_EC_Filter (void); - // constructor... - - virtual ~TAO_EC_Filter (void); - // destructor... - - TAO_EC_Filter* parent (void) const; - // Obtain the parent of this filter. - - void adopt_child (TAO_EC_Filter* child); - // Become the parent of <child> - - static int matches (const RtecEventComm::EventHeader& rhs, - const RtecEventComm::EventHeader& lhs); - // matches two event headers. - // @@ TODO: stragize this... - - virtual int filter (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env) = 0; - // Filter this event, returns 1 if the event is accepted, 0 - // otherwise. - - virtual void push (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env) = 0; - // This is called by the children when they accept an event and - // which to pass it up. - - virtual void clear (void) = 0; - // Clear any saved state, must reset and assume no events have been - // received. - - virtual CORBA::ULong max_event_size (void) const = 0; - // Returns the maximum size of the events pushed by this filter. - - virtual void event_ids (RtecEventComm::EventHeaderSet& headerset) = 0; - // Compute the disjunction of all the event types that could be of - // interest for this filter (and its children). - -private: - TAO_EC_Filter* parent_; - // The parent... -}; - -// **************************************************************** - -class TAO_EC_Trivial_Filter : public TAO_EC_Filter -{ - // = TITLE - // - // = DESCRIPTION - // - // = MEMORY MANAGMENT - // -public: - TAO_EC_Trivial_Filter (void); - // constructor. - - // = The TAO_EC_Filter methods, please check the documentation in - // TAO_EC_Filter. - virtual int filter (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void push (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void clear (void); - virtual CORBA::ULong max_event_size (void) const; - virtual void event_ids (RtecEventComm::EventHeaderSet& headerset); -}; - -// **************************************************************** - -class TAO_EC_Disjunction_Filter : public TAO_EC_Filter -{ - // = TITLE - // - // = DESCRIPTION - // - // = MEMORY MANAGMENT - // -public: - - // = The TAO_EC_Filter methods, please check the documentation in - // TAO_EC_Filter. - virtual int filter (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void push (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void clear (void); - virtual CORBA::ULong max_event_size (void) const; - virtual void event_ids (RtecEventComm::EventHeaderSet& headerset); -}; - -// **************************************************************** - -class TAO_EC_Conjunction_Filter : public TAO_EC_Filter -{ - // = TITLE - // - // = DESCRIPTION - // - // = MEMORY MANAGMENT - // -public: - - // = The TAO_EC_Filter methods, please check the documentation in - // TAO_EC_Filter. - virtual int filter (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void push (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void clear (void); - virtual CORBA::ULong max_event_size (void) const; - virtual void event_ids (RtecEventComm::EventHeaderSet& headerset); -}; - -// **************************************************************** - -class TAO_EC_Type_Filter : public TAO_EC_Filter -{ - // = TITLE - // - // = DESCRIPTION - // - // = MEMORY MANAGMENT - // -public: - - // = The TAO_EC_Filter methods, please check the documentation in - // TAO_EC_Filter. - virtual int filter (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void push (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void clear (void); - virtual CORBA::ULong max_event_size (void) const; - virtual void event_ids (RtecEventComm::EventHeaderSet& headerset); -}; - -// **************************************************************** - -// Add more types of filters like: -// - Events in a sequence. -// - Events in a sequence with timeouts. -// - Conjunction with timeout -// - etc. - -// **************************************************************** - -#if defined (__ACE_INLINE__) -#include "EC_Filter.i" -#endif /* __ACE_INLINE__ */ - -#endif /* TAO_EC_FILTER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_Filter_Builder.h b/TAO/orbsvcs/orbsvcs/Event/EC_Filter_Builder.h deleted file mode 100644 index d208e59db41..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_Filter_Builder.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ORBSVCS Real-time Event Channel -// -// = FILENAME -// EC_Filter_Builder -// -// = AUTHOR -// Carlos O'Ryan (coryan@cs.wustl.edu) -// -// = DESCRIPTION -// The creation of a builder hierarchy is controlled by a -// Filter_Builder. The relationship between TAO_EC_Filter and -// TAO_EC_Filter_Builder follows the "Builder Pattern" (Gamma et -// al.) -// -// = CREDITS -// Based on previous work by Tim Harrison (harrison@cs.wustl.edu) -// and other members of the DOC group. -// More details can be found in: -// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz -// http://www.cs.wustl.edu/~schmidt/JSAC-98.ps.gz -// -// -// ============================================================================ - -#ifndef TAO_EC_FILTER_BUILDER_H -#define TAO_EC_FILTER_BUILDER_H - -#include "orbsvcs/RtecEventChannelAdmin.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class TAO_EC_Filter_Builder -{ - // = TITLE - // Abstract base class for the filter builders. - // - // = DESCRIPTION - // Defines the filter builder interface. - // -public: - virtual ~TAO_EC_Filter_Builder (void); - // destructor... - - TAO_EC_Filter* build (RtecEventChannelAdmin::ConsumerQOS& qos) const - = 0; - // Create the filter, the caller must assume ownership of the filter - // returned. - -}; - -// **************************************************************** - -class TAO_EC_Default_Filter_Builder -{ - // = TITLE - // A simple implementation of the filter builder. - // - // = DESCRIPTION - // Defines the default filter builder. - // -public: - TAO_EC_Default_Filter_Builder (void); - // constructor. - - virtual ~TAO_EC_Default_Filter_Builder (void); - // destructor... - - // = The TAO_EC_Filter_Builder methods... - TAO_EC_Filter* build (RtecEventChannelAdmin::ConsumerQOS& qos) const; -}; - -// **************************************************************** - -#if defined (__ACE_INLINE__) -#include "EC_Filter_Builder.i" -#endif /* __ACE_INLINE__ */ - -#endif /* TAO_EC_FILTER_BUILDER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway.cpp b/TAO/orbsvcs/orbsvcs/Event/EC_Gateway.cpp deleted file mode 100644 index 1b847895381..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway.cpp +++ /dev/null @@ -1,369 +0,0 @@ -// $Id$ - -#include "orbsvcs/Event/EC_Gateway.h" -#include "orbsvcs/Event_Utilities.h" -#include "orbsvcs/Time_Utilities.h" - -ACE_RCSID(Event, EC_Gateway, "$Id$") - -TAO_EC_Gateway::TAO_EC_Gateway (void) - : handle_ (0) -{ -} - -TAO_EC_Gateway::~TAO_EC_Gateway (void) -{ -} - -void -TAO_EC_Gateway::observer_handle (RtecEventChannelAdmin::Observer_Handle h) -{ - this->handle_ = h; -} - -RtecEventChannelAdmin::Observer_Handle -TAO_EC_Gateway::observer_handle (void) const -{ - return this->handle_; -} - -// **************************************************************** - -TAO_EC_Gateway_IIOP::TAO_EC_Gateway_IIOP (void) - : consumer_ (this), - supplier_ (this) -{ -} - -TAO_EC_Gateway_IIOP::~TAO_EC_Gateway_IIOP (void) -{ -} - -void -TAO_EC_Gateway_IIOP::init (RtecEventChannelAdmin::EventChannel_ptr rmt_ec, - RtecEventChannelAdmin::EventChannel_ptr lcl_ec, - RtecScheduler::Scheduler_ptr rmt_sched, - RtecScheduler::Scheduler_ptr lcl_sched, - const char* lcl_name, - const char* rmt_name, - CORBA::Environment &TAO_IN_ENV) -{ - this->rmt_ec_ = - RtecEventChannelAdmin::EventChannel::_duplicate (rmt_ec); - this->lcl_ec_ = - RtecEventChannelAdmin::EventChannel::_duplicate (lcl_ec); - - this->rmt_info_ = - rmt_sched->create (rmt_name, TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - // @@ TODO Many things are hard-coded in the RT_Info here. - - // The worst case execution time is far less than 500 usecs, but - // that is a safe estimate.... - ACE_Time_Value tv (0, 500); - TimeBase::TimeT time; - ORBSVCS_Time::Time_Value_to_TimeT (time, tv); - rmt_sched->set (this->rmt_info_, - RtecScheduler::VERY_HIGH_CRITICALITY, - time, time, time, - 25000 * 10, - RtecScheduler::VERY_LOW_IMPORTANCE, - time, - 0, - RtecScheduler::OPERATION, - TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - this->lcl_info_ = - lcl_sched->create (lcl_name, TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - lcl_sched->set (this->lcl_info_, - RtecScheduler::VERY_HIGH_CRITICALITY, - time, time, time, - 25000 * 10, - RtecScheduler::VERY_LOW_IMPORTANCE, - time, - 1, - RtecScheduler::REMOTE_DEPENDANT, - TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - -} - -void -TAO_EC_Gateway_IIOP::close (CORBA::Environment &env) -{ - // ACE_DEBUG ((LM_DEBUG, "ECG (%t) Closing gateway\n")); - if (CORBA::is_nil (this->supplier_proxy_.in ())) - return; - - if (this->consumer_proxy_map_.current_size () > 0) - { - for (Consumer_Map_Iterator j = this->consumer_proxy_map_.begin (); - j != this->consumer_proxy_map_.end (); - ++j) - { - (*j).int_id_->disconnect_push_consumer (env); - CORBA::release ((*j).int_id_); - TAO_CHECK_ENV_RETURN_VOID (env); - } - this->consumer_proxy_map_.close (); - } - - this->default_consumer_proxy_->disconnect_push_consumer (env); - TAO_CHECK_ENV_RETURN_VOID (env); - this->default_consumer_proxy_ = - RtecEventChannelAdmin::ProxyPushConsumer::_nil (); - - this->supplier_proxy_->disconnect_push_supplier (env); - TAO_CHECK_ENV_RETURN_VOID (env); - this->supplier_proxy_ = - RtecEventChannelAdmin::ProxyPushSupplier::_nil (); -} - -void -TAO_EC_Gateway_IIOP::update_consumer (const RtecEventChannelAdmin::ConsumerQOS& c_qos, - CORBA::Environment& env) -{ - this->close (env); - TAO_CHECK_ENV_RETURN_VOID (env); - - if (c_qos.dependencies.length () <= 1) - return; - - // ACE_DEBUG ((LM_DEBUG, "ECG (%t) Open gateway\n")); - if (CORBA::is_nil (this->lcl_ec_.in ()) - || CORBA::is_nil (this->rmt_ec_.in ())) - return; - - // = Connect as a supplier to the local EC - RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = - this->lcl_ec_->for_suppliers (env); - TAO_CHECK_ENV_RETURN_VOID (env); - - this->default_consumer_proxy_ = - supplier_admin->obtain_push_consumer (env); - TAO_CHECK_ENV_RETURN_VOID (env); - - // Change the RT_Info in the consumer QoS. - // On the same loop we discover the subscriptions by event source, - // and fill the consumer proxy map. - RtecEventChannelAdmin::ConsumerQOS sub = c_qos; - for (CORBA::ULong i = 0; i < sub.dependencies.length (); ++i) - { - sub.dependencies[i].rt_info = this->rmt_info_; - - RtecEventChannelAdmin::ProxyPushConsumer_ptr proxy = 0; - RtecEventComm::EventSourceID sid = - sub.dependencies[i].event.header.source; - if (sid != 0 - && this->consumer_proxy_map_.find (sid, proxy) == -1) - { - proxy = supplier_admin->obtain_push_consumer (env); - TAO_CHECK_ENV_RETURN_VOID (env); - this->consumer_proxy_map_.bind (sid, proxy); - } - } - - // Obtain a reference to our supplier personality... - RtecEventComm::PushSupplier_var supplier_ref = - this->supplier_._this (env); - TAO_CHECK_ENV_RETURN_VOID (env); - - if (this->consumer_proxy_map_.current_size () > 0) - { - // For each subscription by source build the set of publications - // (they may several, by type, for instance) and connect to the - // consumer proxy. - for (Consumer_Map_Iterator j = this->consumer_proxy_map_.begin (); - j != this->consumer_proxy_map_.end (); - ++j) - { - RtecEventChannelAdmin::SupplierQOS pub; - pub.publications.length (sub.dependencies.length () - 1); - pub.is_gateway = 1; - int c = 0; - - RtecEventComm::EventSourceID sid = (*j).ext_id_; - for (CORBA::ULong k = 0; k < sub.dependencies.length (); ++k) - { - const RtecEventComm::EventHeader& h = - sub.dependencies[k].event.header; - if (h.source != sid - || (1 <= h.type - && h.type < ACE_ES_EVENT_UNDEFINED)) - continue; - pub.publications[c].event.header = h; - pub.publications[c].dependency_info.dependency_type = - RtecScheduler::TWO_WAY_CALL; - pub.publications[c].dependency_info.number_of_calls = 1; - pub.publications[c].dependency_info.rt_info = this->lcl_info_; - c++; - } - if (c == 0) - continue; - - pub.publications.length (c); - (*j).int_id_->connect_push_supplier (supplier_ref.in (), - pub, - env); - TAO_CHECK_ENV_RETURN_VOID (env); - } - } - - // Also build the subscriptions that are *not* by source and connect - // to the default consumer proxy. - RtecEventChannelAdmin::SupplierQOS pub; - pub.publications.length (sub.dependencies.length () - 1); - pub.is_gateway = 1; - int c = 0; - for (CORBA::ULong k = 0; k < sub.dependencies.length (); ++k) - { - const RtecEventComm::EventHeader& h = - sub.dependencies[k].event.header; - RtecEventComm::EventSourceID sid = h.source; - if (sid != 0 - || (0 <= h.type - && h.type < ACE_ES_EVENT_UNDEFINED)) - continue; - pub.publications[c].event.header = h; - pub.publications[c].event.header.creation_time = ORBSVCS_Time::zero; - pub.publications[c].dependency_info.dependency_type = - RtecScheduler::TWO_WAY_CALL; - pub.publications[c].dependency_info.number_of_calls = 1; - pub.publications[c].dependency_info.rt_info = this->lcl_info_; - c++; - } - if (c > 0) - { - pub.publications.length (c); - this->default_consumer_proxy_->connect_push_supplier (supplier_ref.in (), - pub, - env); - TAO_CHECK_ENV_RETURN_VOID (env); - } - - - //ACE_DEBUG ((LM_DEBUG, "ECG (%t) Gateway/Supplier ")); - //ACE_SupplierQOS_Factory::debug (pub); - - RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = - this->rmt_ec_->for_consumers (env); - TAO_CHECK_ENV_RETURN_VOID (env); - - this->supplier_proxy_ = - consumer_admin->obtain_push_supplier (env); - TAO_CHECK_ENV_RETURN_VOID (env); - - RtecEventComm::PushConsumer_var consumer_ref = - this->consumer_._this (env); - TAO_CHECK_ENV_RETURN_VOID (env); - - //ACE_DEBUG ((LM_DEBUG, "ECG (%t) Gateway/Consumer ")); - //ACE_ConsumerQOS_Factory::debug (sub); - - this->supplier_proxy_->connect_push_consumer (consumer_ref.in (), - sub, - env); - TAO_CHECK_ENV_RETURN_VOID (env); - -} - -void -TAO_EC_Gateway_IIOP::update_supplier (const RtecEventChannelAdmin::SupplierQOS&, - CORBA::Environment&) -{ - // Do nothing... -} - -void -TAO_EC_Gateway_IIOP::disconnect_push_consumer (CORBA::Environment &) -{ - ACE_DEBUG ((LM_DEBUG, - "ECG (%t): Supplier-consumer received " - "disconnect from channel.\n")); -} - -void -TAO_EC_Gateway_IIOP::disconnect_push_supplier (CORBA::Environment &) -{ - ACE_DEBUG ((LM_DEBUG, - "ECG (%t): Supplier received " - "disconnect from channel.\n")); -} - -void -TAO_EC_Gateway_IIOP::push (const RtecEventComm::EventSet &events, - CORBA::Environment & env) -{ - //ACE_DEBUG ((LM_DEBUG, "TAO_EC_Gateway_IIOP::push - ")); - - if (events.length () == 0) - { - // ACE_DEBUG ((LM_DEBUG, "no events\n")); - return; - } - - //ACE_DEBUG ((LM_DEBUG, "ECP: %d event(s) - ", events.length ())); - - // @@ TODO, there is an extra data copy here, we should do the event - // modification without it and only compact the necessary events. - RtecEventComm::EventSet out (1); - out.length (1); - for (CORBA::ULong i = 0; i < events.length (); ++i) - { - if (events[i].header.ttl == 0) - continue; - - RtecEventChannelAdmin::ProxyPushConsumer_ptr proxy = 0; - RtecEventComm::EventSourceID sid = events[i].header.source; - if (sid == 0 - || this->consumer_proxy_map_.find (sid, proxy) == -1) - { - // If the source is not in our map we have to use the - // default consumer proxy. - proxy = this->default_consumer_proxy_.in (); - } - out[0] = events[i]; - out[0].header.ttl--; - proxy->push (out, env); - TAO_CHECK_ENV_RETURN_VOID (env); - } -} - -int -TAO_EC_Gateway_IIOP::shutdown (CORBA::Environment& TAO_IN_ENV) -{ - this->close (TAO_IN_ENV); - if (TAO_IN_ENV.exception () == 0) return -1; - - this->lcl_ec_ = 0; - this->rmt_ec_ = 0; - - return 0; -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -template class ACE_PushConsumer_Adapter<TAO_EC_Gateway_IIOP>; -template class ACE_PushSupplier_Adapter<TAO_EC_Gateway_IIOP>; -template class ACE_Map_Entry<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr>; -template class ACE_Map_Manager<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex>; -template class ACE_Map_Iterator_Base<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex>; -template class ACE_Map_Iterator<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex>; -template class ACE_Map_Reverse_Iterator<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex>; - -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) - -#pragma instantiate ACE_PushConsumer_Adapter<TAO_EC_Gateway_IIOP> -#pragma instantiate ACE_PushSupplier_Adapter<TAO_EC_Gateway_IIOP> - -#pragma instantiate ACE_Map_Entry<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr> -#pragma instantiate ACE_Map_Manager<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex> -#pragma instantiate ACE_Map_Iterator_Base<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex> -#pragma instantiate ACE_Map_Iterator<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex> -#pragma instantiate ACE_Map_Reverse_Iterator<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex> - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway.h b/TAO/orbsvcs/orbsvcs/Event/EC_Gateway.h deleted file mode 100644 index e5ba8e67229..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway.h +++ /dev/null @@ -1,175 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// TAO services -// -// = FILENAME -// EC_Gateway -// -// = AUTHOR -// Carlos O'Ryan -// -// = DESCRIPTION -// This class can be used to connect two event channels; the class -// connects to a "remote" EC as a consumer, it also connects to the -// <local> EC as a supplier of events, this later EC is usually -// collocated. -// The QoS parameters for both connections must be provided by the -// user. -// To avoid infinite loops of events the Gateway descreases the TTL -// field of the events and will not deliver any events with TTL less -// than or equal to 0. -// -// = TODO -// The class makes an extra copy of the events, we need to -// investigate if closer collaboration with its collocated EC could -// be used to remove that copy. -// -// ============================================================================ - -#ifndef TAO_EC_GATEWAY_H -#define TAO_EC_GATEWAY_H - -#include "orbsvcs/RtecEventChannelAdminS.h" -#include "orbsvcs/RtecEventCommS.h" -#include "orbsvcs/Channel_Clients_T.h" -#include "orbsvcs/orbsvcs_export.h" - -class TAO_ORBSVCS_Export TAO_EC_Gateway : public POA_RtecEventChannelAdmin::Observer -{ - // = TITLE - // Event Channel Gateway - // - // = DESCRIPTION - // There are several ways to connect several EC together, for - // instance: - // + A single class can use normal IIOP and connect to one EC as - // a supplier and to another EC as a consumer. - // + A class connects as a consumer and transmit the events using - // multicast, another class receives the multicast messages and - // transform them back into a push() call. - // - // This is an abstract class to represent all the different - // strategies for EC distribution. - // -public: - TAO_EC_Gateway (void); - // Default constructor. - - virtual ~TAO_EC_Gateway (void); - // Destructor - - virtual void close (CORBA::Environment& env) = 0; - // The gateway must disconnect from all the relevant event channels, - // or any other communication media (such as multicast groups). - -private: - friend class ACE_EventChannel; - void observer_handle (RtecEventChannelAdmin::Observer_Handle h); - RtecEventChannelAdmin::Observer_Handle observer_handle (void) const; - // Obtain and modify the observer handle. - -private: - RtecEventChannelAdmin::Observer_Handle handle_; -}; - -// **************************************************************** -class TAO_ORBSVCS_Export TAO_EC_Gateway_IIOP : public TAO_EC_Gateway -// -// = TITLE -// Event Channel Gateway using IIOP. -// -// = DESCRIPTION -// This class mediates among two event channels, it connects as a -// consumer of events with a remote event channel, and as a supplier -// of events with the local EC. -// As a consumer it gives a QoS designed to only accept the events -// in which *local* consumers are interested. -// Eventually the local EC should create this object and compute its -// QoS in an automated manner; but this requires some way to filter -// out the peers registered as consumers, otherwise we will get -// loops in the QoS graph. -// It uses exactly the same set of events in the publications list -// when connected as a supplier. -// -// = NOTES -// An alternative implementation would be to register with the -// remote EC as a supplier, and then filter on the remote EC, but -// one of the objectives is to minimize network traffic. -// On the other hand the events will be pushed to remote consumers, -// event though they will be dropped upon receipt (due to the TTL -// field); IMHO this is another suggestion that the EC needs to know -// (somehow) which consumers are truly its peers in disguise. -// -// -{ -public: - TAO_EC_Gateway_IIOP (void); - ~TAO_EC_Gateway_IIOP (void); - - void init (RtecEventChannelAdmin::EventChannel_ptr rmt_ec, - RtecEventChannelAdmin::EventChannel_ptr lcl_ec, - RtecScheduler::Scheduler_ptr rmt_sched, - RtecScheduler::Scheduler_ptr lcl_sched, - const char* lcl_name, - const char* rmt_name, - CORBA::Environment &_env); - // To do its job this class requires to know the local and remote - // ECs it will connect to; furthermore it also requires to build - // RT_Infos for the local and remote schedulers. - // @@ TODO part of the RT_Info is hardcoded, we need to make it - // parametric. - - void disconnect_push_supplier (CORBA::Environment &); - // The channel is disconnecting. - - void disconnect_push_consumer (CORBA::Environment &); - // The channel is disconnecting. - - void push (const RtecEventComm::EventSet &events, - CORBA::Environment &); - // This is the Consumer side behavior, it pushes the events to the - // local event channel. - - int shutdown (CORBA::Environment&); - // Disconnect and shutdown the gateway - - // The following methods are documented in the base class. - virtual void close (CORBA::Environment& _env); - virtual void update_consumer (const RtecEventChannelAdmin::ConsumerQOS& sub, - CORBA::Environment& env); - virtual void update_supplier (const RtecEventChannelAdmin::SupplierQOS& pub, - CORBA::Environment& env); - -private: - RtecEventChannelAdmin::EventChannel_var rmt_ec_; - RtecEventChannelAdmin::EventChannel_var lcl_ec_; - // The remote and the local EC, so we can reconnect when the list changes. - - RtecScheduler::handle_t rmt_info_; - RtecScheduler::handle_t lcl_info_; - // Our local and remote RT_Infos. - - ACE_PushConsumer_Adapter<TAO_EC_Gateway_IIOP> consumer_; - // Our consumer personality.... - - ACE_PushSupplier_Adapter<TAO_EC_Gateway_IIOP> supplier_; - // Our supplier personality.... - - // We use a different Consumer_Proxy - typedef ACE_Map_Manager<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex> Consumer_Map; - typedef ACE_Map_Iterator<RtecEventComm::EventSourceID,RtecEventChannelAdmin::ProxyPushConsumer_ptr,ACE_Null_Mutex> Consumer_Map_Iterator; - - Consumer_Map consumer_proxy_map_; - RtecEventChannelAdmin::ProxyPushConsumer_var default_consumer_proxy_; - // We talk to the EC (as a supplier) using either an per-supplier - // proxy or a generic proxy for the type only subscriptions. - - RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_; - // We talk to the EC (as a consumer) using this proxy. -}; - -#endif /* ACE_EC_GATEWAY_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway_UDP.cpp b/TAO/orbsvcs/orbsvcs/Event/EC_Gateway_UDP.cpp deleted file mode 100644 index 9e8b2a1d0de..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway_UDP.cpp +++ /dev/null @@ -1,1241 +0,0 @@ -// $Id$ - -#include "orbsvcs/Event/EC_Gateway_UDP.h" -#include "orbsvcs/Event_Utilities.h" -#include "orbsvcs/Time_Utilities.h" - -#if !defined(__ACE_INLINE__) -#include "EC_Gateway_UDP.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(Event, EC_Gateway_UDP, "$Id$") - -// **************************************************************** - -TAO_ECG_UDP_Sender::TAO_ECG_UDP_Sender (void) - : mtu_ (TAO_ECG_UDP_Sender::ECG_DEFAULT_MTU) -{ -} - -int -TAO_ECG_UDP_Sender::get_local_addr (ACE_INET_Addr& addr) -{ - if (this->endpoint_ == 0) - return -1; - return this->dgram ().get_local_addr (addr); -} - -void -TAO_ECG_UDP_Sender::init (RtecEventChannelAdmin::EventChannel_ptr lcl_ec, - RtecScheduler::Scheduler_ptr lcl_sched, - const char* lcl_name, - RtecUDPAdmin::AddrServer_ptr addr_server, - TAO_ECG_UDP_Out_Endpoint* endpoint, - CORBA::Environment &TAO_IN_ENV) -{ - this->lcl_ec_ = - RtecEventChannelAdmin::EventChannel::_duplicate (lcl_ec); - - this->addr_server_ = - RtecUDPAdmin::AddrServer::_duplicate (addr_server); - - this->endpoint_ = endpoint; - - this->lcl_info_ = lcl_sched->lookup (lcl_name, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - if (this->lcl_info_ == -1) - { - this->lcl_info_ = - lcl_sched->create (lcl_name, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - - ACE_Time_Value tv (0, 500); - TimeBase::TimeT time; - ORBSVCS_Time::Time_Value_to_TimeT (time, tv); - lcl_sched->set (this->lcl_info_, - RtecScheduler::VERY_HIGH_CRITICALITY, - time, time, time, - 25000 * 10, - RtecScheduler::VERY_LOW_IMPORTANCE, - time, - 0, - RtecScheduler::OPERATION, - TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - } -} - -int -TAO_ECG_UDP_Sender::mtu (CORBA::ULong new_mtu) -{ - if (new_mtu < TAO_ECG_UDP_Sender::ECG_MIN_MTU - || new_mtu >= TAO_ECG_UDP_Sender::ECG_MAX_MTU) - return -1; - this->mtu_ = new_mtu; - return 0; -} - -void -TAO_ECG_UDP_Sender::shutdown (CORBA::Environment& TAO_IN_ENV) -{ - this->close (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - this->lcl_ec_ = RtecEventChannelAdmin::EventChannel::_nil (); -} - -void -TAO_ECG_UDP_Sender::open (RtecEventChannelAdmin::ConsumerQOS& sub, - CORBA::Environment &TAO_IN_ENV) -{ - // ACE_DEBUG ((LM_DEBUG, "ECG (%t) Open gateway\n")); - if (CORBA::is_nil (this->lcl_ec_.in ())) - return; - - if (!CORBA::is_nil (this->supplier_proxy_.in ())) - this->close (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - if (sub.dependencies.length () == 0) - return; - for (CORBA::ULong j = 0; j < sub.dependencies.length (); ++j) - { - sub.dependencies[j].rt_info = this->lcl_info_; - } - - //ACE_DEBUG ((LM_DEBUG, "ECG (%t) Gateway/Supplier ")); - //ACE_SupplierQOS_Factory::debug (pub); - - RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = - this->lcl_ec_->for_consumers (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - this->supplier_proxy_ = - consumer_admin->obtain_push_supplier (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - RtecEventComm::PushConsumer_var consumer_ref = - this->_this (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - //ACE_DEBUG ((LM_DEBUG, "ECG (%t) Gateway/Consumer ")); - //ACE_ConsumerQOS_Factory::debug (sub); - - this->supplier_proxy_->connect_push_consumer (consumer_ref.in (), - sub, - TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; -} - -void -TAO_ECG_UDP_Sender::close (CORBA::Environment &env) -{ - // ACE_DEBUG ((LM_DEBUG, "ECG (%t) Closing gateway\n")); - if (CORBA::is_nil (this->supplier_proxy_.in ())) - return; - - this->supplier_proxy_->disconnect_push_supplier (env); - if (env.exception () != 0) return; - this->supplier_proxy_ = - RtecEventChannelAdmin::ProxyPushSupplier::_nil (); -} - -void -TAO_ECG_UDP_Sender::disconnect_push_consumer (CORBA::Environment &) -{ - ACE_DEBUG ((LM_DEBUG, - "ECG (%t): Supplier-consumer received " - "disconnect from channel.\n")); -} - -void -TAO_ECG_UDP_Sender::push (const RtecEventComm::EventSet &events, - CORBA::Environment & TAO_IN_ENV) -{ - // ACE_DEBUG ((LM_DEBUG, "ECG_UDP_Sender::push - \n")); - - if (events.length () == 0) - { - // ACE_DEBUG ((LM_DEBUG, "no events\n")); - return; - } - - // @@ TODO precompute this when the MTU changes... - CORBA::ULong max_fragment_payload = this->mtu () - - TAO_ECG_UDP_Sender::ECG_HEADER_SIZE; - // ACE_ASSERT (max_fragment_payload != 0); - - // ACE_DEBUG ((LM_DEBUG, "%d event(s) - ", events.length ())); - - // Send each event in a separate message. - // @@ TODO It is interesting to group events destined to the - // same mcast group in a single message. - for (u_int i = 0; i < events.length (); ++i) - { - // To avoid loops we keep a TTL field on the events and skip the - // events with TTL <= 0 - if (events[i].header.ttl <= 0) - continue; - - const RtecEventComm::Event& e = events[i]; - - // We need to modify the TTL field, but copying the entire event - // would be wasteful; instead we create a new header and only - // modify the header portion. - RtecEventComm::EventHeader header = e.header; - header.ttl--; - - // Grab the right mcast group for this event... - RtecUDPAdmin::UDP_Addr udp_addr; - this->addr_server_->get_addr (header, udp_addr, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID(TAO_IN_ENV); - - // Start building the message - TAO_OutputCDR cdr; - - // Marshal as if it was a sequence of one element, notice how we - // marshal a modified version of the header, but the payload is - // marshal without any extra copies. - cdr.write_ulong (1); - cdr.encode (RtecEventComm::_tc_EventHeader, &header, 0, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID(TAO_IN_ENV); - - cdr.encode (RtecEventComm::_tc_EventData, &e.data, 0, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID(TAO_IN_ENV); - - const int TAO_WRITEV_MAX = IOV_MAX; - iovec iov[TAO_WRITEV_MAX]; - - CORBA::ULong total_length; - CORBA::ULong fragment_count = - this->compute_fragment_count (cdr.begin (), - cdr.end (), - TAO_WRITEV_MAX, - max_fragment_payload, - total_length); - - CORBA::ULong request_id = this->endpoint_->next_request_id (); - - // Reserve the first iovec for the header... - int iovcnt = 1; - CORBA::ULong fragment_id = 0; - CORBA::ULong fragment_offset = 0; - CORBA::ULong fragment_size = 0; - for (const ACE_Message_Block* b = cdr.begin (); - b != cdr.end (); - b = b->cont ()) - { - CORBA::ULong l = b->length (); - - iov[iovcnt].iov_base = b->rd_ptr (); - iov[iovcnt].iov_len = l; - fragment_size += l; - iovcnt++; - while (fragment_size > max_fragment_payload) - { - // This fragment is full, we have to send it... - - // First adjust the last iov entry: - CORBA::ULong last_mb_length = - max_fragment_payload - (fragment_size - l); - iov[iovcnt - 1].iov_len = last_mb_length; - - this->send_fragment (udp_addr, - request_id, - total_length, - max_fragment_payload, - fragment_offset, - fragment_id, - fragment_count, - iov, - iovcnt, - TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID(TAO_IN_ENV); - fragment_id++; - fragment_offset += max_fragment_payload; - - // Reset, but don't forget that the last Message_Block - // may need to be sent in multiple fragments.. - l -= last_mb_length; - iov[1].iov_base = b->rd_ptr () + last_mb_length; - iov[1].iov_len = l; - fragment_size = l; - iovcnt = 2; - } - if (fragment_size == max_fragment_payload) - { - // We filled a fragment, but this time it was filled - // exactly, the treatment is a little different from the - // loop above... - this->send_fragment (udp_addr, - request_id, - total_length, - max_fragment_payload, - fragment_offset, - fragment_id, - fragment_count, - iov, - iovcnt, - TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID(TAO_IN_ENV); - fragment_id++; - fragment_offset += max_fragment_payload; - - iovcnt = 1; - fragment_size = 0; - } - if (iovcnt == TAO_WRITEV_MAX) - { - // Now we ran out of space in the iovec, we must send a - // fragment to work around that.... - this->send_fragment (udp_addr, - request_id, - total_length, - fragment_size, - fragment_offset, - fragment_id, - fragment_count, - iov, - iovcnt, - TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID(TAO_IN_ENV); - fragment_id++; - fragment_offset += fragment_size; - - iovcnt = 1; - fragment_size = 0; - } - } - // There is something left in the iovvec that we must send - // also... - if (iovcnt != 1) - { - // Now we ran out of space in the iovec, we must send a - // fragment to work around that.... - this->send_fragment (udp_addr, - request_id, - total_length, - fragment_size, - fragment_offset, - fragment_id, - fragment_count, - iov, - iovcnt, - TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID(TAO_IN_ENV); - fragment_id++; - fragment_offset += fragment_size; - - // reset, not needed here... - // iovcnt = 1; - // fragment_size = 0; - } - // ACE_ASSERT (total_length == fragment_offset); - // ACE_ASSERT (fragment_id == fragment_count); - - } -} - -void -TAO_ECG_UDP_Sender::send_fragment (const RtecUDPAdmin::UDP_Addr& udp_addr, - CORBA::ULong request_id, - CORBA::ULong request_size, - CORBA::ULong fragment_size, - CORBA::ULong fragment_offset, - CORBA::ULong fragment_id, - CORBA::ULong fragment_count, - iovec iov[], - int iovcnt, - CORBA::Environment& TAO_IN_ENV) -{ - CORBA::ULong header[TAO_ECG_UDP_Sender::ECG_HEADER_SIZE - / sizeof(CORBA::ULong) - + CDR::MAX_ALIGNMENT]; - char* buf = ACE_reinterpret_cast(char*,header); - TAO_OutputCDR cdr (buf, sizeof(header)); - cdr.write_boolean (TAO_ENCAP_BYTE_ORDER); - cdr.write_ulong (request_id); - cdr.write_ulong (request_size); - cdr.write_ulong (fragment_size); - cdr.write_ulong (fragment_offset); - cdr.write_ulong (fragment_id); - cdr.write_ulong (fragment_count); - CORBA::Octet padding[4]; - cdr.write_octet_array (padding, 4); - - iov[0].iov_base = cdr.begin ()->rd_ptr (); - iov[0].iov_len = cdr.begin ()->length (); - - ACE_INET_Addr inet_addr (udp_addr.port, - udp_addr.ipaddr); - - // ACE_DEBUG ((LM_DEBUG, - // "ECG_UDP_Sender (%P|%t): msg = %d, fragment %d/%d, " - // "dest = (%u:%d)\n", - // request_id, - // fragment_id, fragment_count, - // udp_addr.ipaddr, udp_addr.port)); - - ssize_t n = this->dgram ().send (iov, - iovcnt, - inet_addr); - if (n == -1) - { - // @@ TODO Use a Event Channel specific exception - ACE_DEBUG ((LM_DEBUG, - "ECG_UDP (%t) send failed %p\n", "")); - TAO_THROW(CORBA::COMM_FAILURE (CORBA::COMPLETED_NO)); - } - else if (n == 0) - { - // @@ TODO Use a Event Channel specific exception - ACE_DEBUG ((LM_DEBUG, - "ECG_UDP (%t) EOF on send \n")); - TAO_THROW(CORBA::COMM_FAILURE (CORBA::COMPLETED_NO)); - } -} - - -CORBA::ULong -TAO_ECG_UDP_Sender::compute_fragment_count (const ACE_Message_Block* begin, - const ACE_Message_Block* end, - int iov_size, - CORBA::ULong max_fragment_payload, - CORBA::ULong& total_length) -{ - CORBA::ULong fragment_count = 0; - total_length = 0; - - CORBA::ULong fragment_size = 0; - // Reserve the first iovec for the header... - int iovcnt = 1; - for (const ACE_Message_Block* b = begin; - b != end; - b = b->cont ()) - { - CORBA::ULong l = b->length (); - total_length += l; - fragment_size += l; - iovcnt++; - while (fragment_size > max_fragment_payload) - { - // Ran out of space, must create a fragment... - fragment_count++; - - // The next iovector will contain what remains of this - // buffer, but also consider - iovcnt = 2; - l -= max_fragment_payload - (fragment_size - l); - fragment_size = l; - } - if (fragment_size == max_fragment_payload) - { - fragment_count++; - iovcnt = 1; - fragment_size = 0; - } - if (iovcnt >= iov_size) - { - // Ran out of space in the iovector.... - fragment_count++; - iovcnt = 1; - fragment_size = 0; - } - } - if (iovcnt != 1) - { - // Send the remaining data in another fragment - fragment_count++; - } - return fragment_count; -} - -// **************************************************************** - -TAO_ECG_UDP_Out_Endpoint::~TAO_ECG_UDP_Out_Endpoint (void) -{ - delete[] this->ifs_; - this->ifs_ = 0; -} - -CORBA::Boolean -TAO_ECG_UDP_Out_Endpoint::is_loopback (const ACE_INET_Addr& from) -{ - if (this->port_number_ == 0) - { - // Cache the port number... - ACE_INET_Addr local_addr; - if (this->dgram ().get_local_addr (local_addr) == -1) - return 0; - this->port_number_ = local_addr.get_port_number (); - } - - // Most of the time the port number is enough to determine if the - // message is remote, only when the local port number and the remote - // port number match we have to look at the local ip addresses. - if (from.get_port_number () != this->port_number_) - return 0; - - if (this->ifs_ == 0) - { - ACE::get_ip_interfaces (this->if_count_, this->ifs_); - } - - for (ACE_INET_Addr* i = this->ifs_; - i != this->ifs_ + this->if_count_; - ++i) - { - if ((*i).get_ip_address () == from.get_ip_address ()) - return 1; - } - return 0; -} - - -// **************************************************************** - -#if 0 -TAO_ECG_UDP_Request_Entry::TAO_ECG_UDP_Request_Entry (void) - : request_size_ (0), - fragment_count_ (0), - timeout_counter_ (0), - payload_ (0), - received_fragments_ (default_received_fragments_), - own_received_fragments_ (0) -{ -} - -TAO_ECG_UDP_Request_Entry:: -TAO_ECG_UDP_Request_Entry (const TAO_ECG_UDP_Request_Entry& rhs) - : byte_order_ (rhs.byte_order_), - request_id_ (rhs.request_id_), - request_size_ (rhs.request_size_), - fragment_count_ (rhs.fragment_count_), - timeout_counter_ (rhs.timeout_counter_), - payload_ (ACE_Message_Block::duplicate (rhs.payload_)), - received_fragments_ (default_received_fragments_), - own_received_fragments_ (0) -{ -} -#endif - -TAO_ECG_UDP_Request_Entry::~TAO_ECG_UDP_Request_Entry (void) -{ - if (this->own_received_fragments_) - { - this->own_received_fragments_ = 0; - delete[] this->received_fragments_; - } -} - -TAO_ECG_UDP_Request_Entry:: -TAO_ECG_UDP_Request_Entry (CORBA::Boolean byte_order, - CORBA::ULong request_id, - CORBA::ULong request_size, - CORBA::ULong fragment_count) - : byte_order_ (byte_order), - request_id_ (request_id), - request_size_ (request_size), - fragment_count_ (fragment_count) -{ - CDR::grow (&this->payload_, this->request_size_); - this->payload_.wr_ptr (request_size_); - - this->received_fragments_ = this->default_received_fragments_; - this->own_received_fragments_ = 0; - const int bits_per_ulong = sizeof(CORBA::ULong) * CHAR_BIT; - this->received_fragments_size_ = - this->fragment_count_ / bits_per_ulong + 1; - if (this->received_fragments_size_ > ECG_DEFAULT_FRAGMENT_BUFSIZ) - { - ACE_NEW (this->received_fragments_, - CORBA::ULong[this->received_fragments_size_]); - this->own_received_fragments_ = 1; - } - - for (CORBA::ULong i = 0; i < this->received_fragments_size_; ++i) - this->received_fragments_[i] = 0; - CORBA::ULong idx = this->fragment_count_ / bits_per_ulong; - CORBA::ULong bit = this->fragment_count_ % bits_per_ulong; - this->received_fragments_[idx] = (0xFFFFFFFF << bit); -} - -int -TAO_ECG_UDP_Request_Entry::validate_fragment (CORBA::Boolean byte_order, - CORBA::ULong request_size, - CORBA::ULong fragment_size, - CORBA::ULong fragment_offset, - CORBA::ULong /* fragment_id */, - CORBA::ULong fragment_count) const -{ - if (byte_order != this->byte_order_ - || request_size != this->request_size_ - || fragment_count != this->fragment_count_) - return 0; - - if (fragment_offset >= request_size - || fragment_offset + fragment_size > request_size) - return 0; - - return 1; -} - -int -TAO_ECG_UDP_Request_Entry::test_received (CORBA::ULong fragment_id) const -{ - // Assume out-of-range fragments as received, so they are dropped... - if (fragment_id > this->fragment_count_) - return 1; - - const int bits_per_ulong = sizeof(CORBA::ULong) * CHAR_BIT; - CORBA::ULong idx = fragment_id / bits_per_ulong; - CORBA::ULong bit = fragment_id % bits_per_ulong; - return ACE_BIT_ENABLED (this->received_fragments_[idx], 1<<bit); -} - -void -TAO_ECG_UDP_Request_Entry::mark_received (CORBA::ULong fragment_id) -{ - // Assume out-of-range fragments as received, so they are dropped... - if (fragment_id > this->fragment_count_) - return; - - const int bits_per_ulong = sizeof(CORBA::ULong) * CHAR_BIT; - CORBA::ULong idx = fragment_id / bits_per_ulong; - CORBA::ULong bit = fragment_id % bits_per_ulong; - ACE_SET_BITS (this->received_fragments_[idx], 1<<bit); -} - -int -TAO_ECG_UDP_Request_Entry::complete (void) const -{ - for (CORBA::ULong i = 0; - i < this->received_fragments_size_; - ++i) - { - if (this->received_fragments_[i] != 0xFFFFFFFF) - return 0; - } - return 1; -} - -char* -TAO_ECG_UDP_Request_Entry::fragment_buffer (CORBA::ULong fragment_offset) -{ - return this->payload_.rd_ptr () + fragment_offset; -} - -void -TAO_ECG_UDP_Request_Entry::decode (RtecEventComm::EventSet& event, - CORBA::Environment& TAO_IN_ENV) -{ - TAO_InputCDR cdr (&this->payload_, - ACE_static_cast(int,this->byte_order_)); - cdr.decode (RtecEventComm::_tc_EventSet, &event, 0, TAO_IN_ENV); -} - -// **************************************************************** - -TAO_ECG_UDP_TH::TAO_ECG_UDP_TH (TAO_ECG_UDP_Receiver* r) - : receiver_ (r) -{ -} - -int -TAO_ECG_UDP_TH::handle_timeout (const ACE_Time_Value& tv, - const void* act) -{ - return this->receiver_->handle_timeout (tv, act); -} - -// **************************************************************** - -TAO_ECG_UDP_Receiver::TAO_ECG_UDP_Receiver (void) - : timeout_handler_ (this), - reactor_ (0) -{ -} - -void -TAO_ECG_UDP_Receiver::init (RtecEventChannelAdmin::EventChannel_ptr lcl_ec, - RtecScheduler::Scheduler_ptr lcl_sched, - const char* lcl_name, - TAO_ECG_UDP_Out_Endpoint* ignore_from, - RtecUDPAdmin::AddrServer_ptr addr_server, - ACE_Reactor *reactor, - const ACE_Time_Value &expire_interval, - int max_timeout, - CORBA::Environment &TAO_IN_ENV) -{ - this->ignore_from_ = ignore_from; - - this->lcl_ec_ = - RtecEventChannelAdmin::EventChannel::_duplicate (lcl_ec); - - this->addr_server_ = - RtecUDPAdmin::AddrServer::_duplicate (addr_server); - - this->lcl_info_ = lcl_sched->lookup (lcl_name, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - if (this->lcl_info_ == -1) - { - this->lcl_info_ = - lcl_sched->create (lcl_name, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - - ACE_Time_Value tv (0, 500); - TimeBase::TimeT time; - ORBSVCS_Time::Time_Value_to_TimeT (time, tv); - lcl_sched->set (this->lcl_info_, - RtecScheduler::VERY_HIGH_CRITICALITY, - time, time, time, - 25000 * 10, - RtecScheduler::VERY_LOW_IMPORTANCE, - time, - 1, - RtecScheduler::REMOTE_DEPENDANT, - TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - } - - this->reactor_ = reactor; - this->max_timeout_ = max_timeout; - // @@ TODO throw an exception.... - if (this->reactor_ == 0 - || this->reactor_->schedule_timer (&this->timeout_handler_, 0, - expire_interval, - expire_interval) == -1) - ACE_ERROR ((LM_ERROR, - "TAO_ECG_UDP_Receiver::init - " - "cannot schedule timer\n")); -} - -void -TAO_ECG_UDP_Receiver::open (RtecEventChannelAdmin::SupplierQOS& pub, - CORBA::Environment &TAO_IN_ENV) -{ - if (CORBA::is_nil (this->lcl_ec_.in ())) - return; - - if (!CORBA::is_nil (this->consumer_proxy_.in ())) - this->close (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - if (pub.publications.length () == 0) - return; - - for (CORBA::ULong i = 0; i < pub.publications.length (); ++i) - { - pub.publications[i].dependency_info.rt_info = this->lcl_info_; - } - - // = Connect as a supplier to the local EC - RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = - this->lcl_ec_->for_suppliers (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - this->consumer_proxy_ = - supplier_admin->obtain_push_consumer (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - RtecEventComm::PushSupplier_var supplier_ref = - this->_this (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - // ACE_DEBUG ((LM_DEBUG, "ECG_UDP_Receiver (%t) Gateway/Supplier ")); - // ACE_SupplierQOS_Factory::debug (pub); - - this->consumer_proxy_->connect_push_supplier (supplier_ref.in (), - pub, - TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; -} - -void -TAO_ECG_UDP_Receiver::close (CORBA::Environment &env) -{ - // ACE_DEBUG ((LM_DEBUG, "ECG (%t) Closing gateway\n")); - if (CORBA::is_nil (this->consumer_proxy_.in ())) - return; - - this->consumer_proxy_->disconnect_push_consumer (env); - if (env.exception () != 0) return; - this->consumer_proxy_ = - RtecEventChannelAdmin::ProxyPushConsumer::_nil (); - -} - -void -TAO_ECG_UDP_Receiver::disconnect_push_supplier (CORBA::Environment &) -{ - ACE_DEBUG ((LM_DEBUG, - "ECG (%t): Supplier received " - "disconnect from channel.\n")); -} - -void -TAO_ECG_UDP_Receiver::shutdown (CORBA::Environment& TAO_IN_ENV) -{ - this->close (TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - - this->lcl_ec_ = RtecEventChannelAdmin::EventChannel::_nil (); - - this->reactor_->cancel_timer (&this->timeout_handler_); -} - -int -TAO_ECG_UDP_Receiver::handle_input (ACE_SOCK_Dgram& dgram) -{ - // Use ULong so the alignment is right. - CORBA::ULong header[TAO_ECG_UDP_Sender::ECG_HEADER_SIZE - / sizeof(CORBA::ULong) - + CDR::MAX_ALIGNMENT]; - ACE_INET_Addr from; - ssize_t n = dgram.recv (header, sizeof(header), from, MSG_PEEK); - if (n == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "ECG_UDP_Receive_EH::handle_input - peek\n"), -1); - else if (n == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "ECG_UDP_Receive_EH::handle_input - peek 0\n"), - 0); - - // This is to avoid receiving the events we send; notice that we - // must read the message to drop it... - if (this->ignore_from_ != 0 - && this->ignore_from_->is_loopback (from)) - { - n = dgram.recv (header, sizeof(header), from); - // ACE_DEBUG ((LM_DEBUG, - // "ECG_UDP_Receiver (%P|%t): cycle dropped\n")); - return 0; - } - - char* buf = ACE_reinterpret_cast(char*,header); - int byte_order = buf[0]; - TAO_InputCDR header_cdr (buf, sizeof(header), byte_order); - CORBA::Boolean unused; - CORBA::ULong request_id; - CORBA::ULong request_size; - CORBA::ULong fragment_size; - CORBA::ULong fragment_offset; - CORBA::ULong fragment_id; - CORBA::ULong fragment_count; - header_cdr.read_boolean (unused); - header_cdr.read_ulong (request_id); - header_cdr.read_ulong (request_size); - header_cdr.read_ulong (fragment_size); - header_cdr.read_ulong (fragment_offset); - header_cdr.read_ulong (fragment_id); - header_cdr.read_ulong (fragment_count); - - if (request_size < fragment_size - || fragment_offset >= request_size - || fragment_id >= fragment_count) - { - // Drop the packet... - n = dgram.recv (header, sizeof(header), from); - return 0; - // ACE_DEBUG ((LM_DEBUG, - // "ECG_UDP_Receiver (%P|%t): invalid fragment dropped" - // ", from = (%u:%d)\n", - // from.get_ip_address (), from.get_port_number ())); - } - - // ACE_DEBUG ((LM_DEBUG, - // "ECG_UDP_Receiver (%P|%t): msg = %d, from = (%u:%d) " - // "fragment = %d/%d\n", - // request_id, - // from.get_ip_address (), from.get_port_number (), - // fragment_id, fragment_count)); - - TAO_ECG_UDP_Request_Index index (from, request_id); - Request_Map_Entry* entry; - - if (this->request_map_.find (index, entry) == -1) - { - // ACE_DEBUG ((LM_DEBUG, - // "ECG_UDP_Receiver (%P|%t): new entry\n" - // " byte_order = %d\n" - // " request_id = %d\n" - // " request_size = %d\n" - // " fragment_size = %d\n" - // " fragment_offset = %d\n" - // " fragment_id = %d\n" - // " fragment_count = %d\n", - // byte_order, - // request_id, - // request_size, - // fragment_size, - // fragment_offset, - // fragment_id, - // fragment_count)); - - // Create an entry and insert it.... - TAO_ECG_UDP_Request_Entry* request_entry = - new TAO_ECG_UDP_Request_Entry(byte_order, - request_id, - request_size, - fragment_count); - if (request_entry == 0 - || this->request_map_.bind (index, - request_entry, - entry) == -1) - { - // Drop the packet... - n = dgram.recv (header, sizeof(header), from); - return 0; - } - } - - // Validate the message... - if (entry->int_id_->validate_fragment (byte_order, - request_size, - fragment_size, - fragment_offset, - fragment_id, - fragment_count) == 0) - { - // ACE_DEBUG ((LM_DEBUG, - // "ECG_UDP_Receiver (%P|%t): fragment rejected:" - // " byte_order = %d\n" - // " request_id = %d\n" - // " request_size = %d\n" - // " fragment_size = %d\n" - // " fragment_offset = %d\n" - // " fragment_id = %d\n" - // " fragment_count = %d\n", - // byte_order, - // request_id, - // request_size, - // fragment_size, - // fragment_offset, - // fragment_id, - // fragment_count)); - - // Drop the fragment if it is invalid... - n = dgram.recv (header, sizeof(header), from); - return 0; - } - - // Was this fragment received already? - if (entry->int_id_->test_received (fragment_id) == 1) - { - // ACE_DEBUG ((LM_DEBUG, - // "ECG_UDP_Receiver (%P|%t): fragment duplicate\n")); - - // Drop the fragment... - n = dgram.recv (header, sizeof(header), from); - return 0; - } - - // Now we should read the fragment, use an iovec to drop the header - // into the bit bucket and the payload into the entry's buffer: - const int iovcnt = 2; - iovec iov[iovcnt]; - char drop_header[TAO_ECG_UDP_Sender::ECG_HEADER_SIZE]; - iov[0].iov_base = drop_header; - iov[0].iov_len = sizeof(drop_header); - iov[1].iov_base = entry->int_id_->fragment_buffer (fragment_offset); - iov[1].iov_len = fragment_size; - - n = dgram.recv (iov, iovcnt, from); - - if (n == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "ECG_UDP_Receive_EH::handle_input - read\n"), -1); - else if (n == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "ECG_UDP_Receive_EH::handle_input - read 0\n"), - 0); - - entry->int_id_->mark_received (fragment_id); - // If the message is not complete we must return... - if (!entry->int_id_->complete ()) - { - // ACE_DEBUG ((LM_DEBUG, - // "ECG_UDP_Receiver (%P|%t): incomplete message\n")); - - return 0; - } - - TAO_TRY - { - RtecEventComm::EventSet event; - entry->int_id_->decode (event, TAO_TRY_ENV); - TAO_CHECK_ENV; - - this->consumer_proxy_->push (event, TAO_TRY_ENV); - TAO_CHECK_ENV; - - // ACE_DEBUG ((LM_DEBUG, - // "TAO_ECG_UDP_Received (%P|%t): push %d " - // "from = (%u:%d)\n", - // request_id, - // from.get_ip_address (), from.get_port_number ())); - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception ("ECG_UDP_Receive_EH::handle_input"); - } - TAO_ENDTRY; - return 0; -} - -void -TAO_ECG_UDP_Receiver::get_addr (const RtecEventComm::EventHeader& header, - RtecUDPAdmin::UDP_Addr_out addr, - CORBA::Environment& env) -{ - this->addr_server_->get_addr (header, addr, env); -} - -int -TAO_ECG_UDP_Receiver::handle_timeout (const ACE_Time_Value& /* tv */, - const void* /* act */) -{ - Request_Map::iterator begin = this->request_map_.begin (); - Request_Map::iterator end = this->request_map_.end (); - { - for (Request_Map::iterator i = begin; - i != end; - ++i) - { - (*i).int_id_->inc_timeout (); - } - } - for (Request_Map::iterator j = begin; - j != end; - ) - { - if ((*j).int_id_->get_timeout () > this->max_timeout_) - { - Request_Map_Entry& entry = *j; - ++j; - { - // ACE_DEBUG ((LM_DEBUG, - // "TAO_ECG_UDP_Receiver::handle_timeout (%P|%t) " - // "msg = %d\n", - // entry.ext_id_.request_id)); - delete entry.int_id_; - this->request_map_.unbind (&entry); - } - } - else - { - ++j; - } - } - return 0; -} - -// **************************************************************** - -TAO_ECG_UDP_EH::TAO_ECG_UDP_EH (TAO_ECG_UDP_Receiver *recv) - : receiver_ (recv) -{ -} - -int -TAO_ECG_UDP_EH::open (const ACE_INET_Addr& ipaddr) -{ - if (this->dgram_.open (ipaddr) == -1) - return -1; - return this->reactor ()->register_handler (this, - ACE_Event_Handler::READ_MASK); -} - -int -TAO_ECG_UDP_EH::close (void) -{ - if (this->reactor ()->remove_handler (this, - ACE_Event_Handler::READ_MASK) == -1) - return -1; - - return this->dgram_.close (); -} - -int -TAO_ECG_UDP_EH::handle_input (ACE_HANDLE) -{ - return this->receiver_->handle_input (this->dgram_); -} - -ACE_HANDLE -TAO_ECG_UDP_EH::get_handle (void) const -{ - return this->dgram_.get_handle (); -} - - -// **************************************************************** - -TAO_ECG_Mcast_EH::TAO_ECG_Mcast_EH (TAO_ECG_UDP_Receiver *recv) - : receiver_ (recv), - observer_ (this) -{ -} - -int -TAO_ECG_Mcast_EH::open (RtecEventChannelAdmin::EventChannel_ptr ec, - CORBA::Environment& TAO_IN_ENV) -{ - this->ec_ = RtecEventChannelAdmin::EventChannel::_duplicate (ec); - RtecEventChannelAdmin::Observer_var obs = - this->observer_._this (TAO_IN_ENV); - TAO_CHECK_ENV_RETURN (TAO_IN_ENV, -1); - - this->handle_ = this->ec_->append_observer (obs.in (), TAO_IN_ENV); - TAO_CHECK_ENV_RETURN (TAO_IN_ENV, -1); - - return 0; -} - -int -TAO_ECG_Mcast_EH::close (CORBA::Environment& TAO_IN_ENV) -{ - if (this->reactor ()->remove_handler (this, - ACE_Event_Handler::READ_MASK) == -1) - return -1; - - if (this->dgram_.unsubscribe () == -1) - return -1; - - this->ec_->remove_observer (this->handle_, TAO_IN_ENV); - this->handle_ = 0; - TAO_CHECK_ENV_RETURN (TAO_IN_ENV, -1); - - return 0; -} - -int -TAO_ECG_Mcast_EH::handle_input (ACE_HANDLE) -{ - return this->receiver_->handle_input (this->dgram_); -} - -ACE_HANDLE -TAO_ECG_Mcast_EH::get_handle (void) const -{ - return this->dgram_.get_handle (); -} - -int -TAO_ECG_Mcast_EH::subscribe (const ACE_INET_Addr &mcast_addr) -{ - return this->dgram_.subscribe (mcast_addr); -} - -int -TAO_ECG_Mcast_EH::unsubscribe (const ACE_INET_Addr &mcast_addr) -{ - return this->dgram_.unsubscribe (mcast_addr); -} - -void -TAO_ECG_Mcast_EH::update_consumer (const RtecEventChannelAdmin::ConsumerQOS& sub, - CORBA::Environment& TAO_IN_ENV) -{ - // ACE_DEBUG ((LM_DEBUG, - // "ECG_Mcast_EH (%t) updating consumer\n")); - - // @@ TODO: If we are more careful we may simply subscribe for the - // new event types and unsubscribe from the old ones... - this->reactor ()->remove_handler (this, - ACE_Event_Handler::READ_MASK); - this->dgram_.close (); - - int must_register = 0; - for (CORBA::ULong i = 0; i < sub.dependencies.length (); ++i) - { - const RtecEventComm::EventHeader& header = - sub.dependencies[i].event.header; - - if (0 <= header.type && header.type <= ACE_ES_EVENT_UNDEFINED) - { - // ACE_DEBUG ((LM_DEBUG, - // "ECG_Mcast_EH (%t) type = %d skipped\n", - // header.type)); - continue; - } - must_register = 1; - RtecUDPAdmin::UDP_Addr addr; - - this->receiver_->get_addr (header, addr, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - - ACE_INET_Addr inet_addr (addr.port, addr.ipaddr); - if (this->subscribe (inet_addr) == -1) - ACE_ERROR ((LM_DEBUG, - "cannot subscribe to %s:%d\n", - inet_addr.get_host_addr (), - inet_addr.get_port_number ())); - // ACE_DEBUG ((LM_DEBUG, - // "ECG_Mcast_EH (%t) subscribed to %s:%d\n", - // inet_addr.get_host_addr (), - // inet_addr.get_port_number ())); - } - - if (must_register) - this->reactor ()->register_handler (this, - ACE_Event_Handler::READ_MASK); -} - -void -TAO_ECG_Mcast_EH::update_supplier (const RtecEventChannelAdmin::SupplierQOS&, - CORBA::Environment&) -{ - // Do nothing -} - -// **************************************************************** - -TAO_ECG_Mcast_EH::Observer::Observer (TAO_ECG_Mcast_EH* eh) - : eh_ (eh) -{ -} - -void -TAO_ECG_Mcast_EH::Observer::update_consumer (const RtecEventChannelAdmin::ConsumerQOS& sub, - CORBA::Environment& TAO_IN_ENV) -{ - this->eh_->update_consumer (sub, TAO_IN_ENV); -} - -void -TAO_ECG_Mcast_EH::Observer::update_supplier (const - RtecEventChannelAdmin::SupplierQOS& pub, - CORBA::Environment& TAO_IN_ENV) -{ - this->eh_->update_supplier (pub, TAO_IN_ENV); -} - -// **************************************************************** - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -template class ACE_Hash_Map_Manager<TAO_ECG_UDP_Request_Index,TAO_ECG_UDP_Request_Entry*,ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Manager_Ex<TAO_ECG_UDP_Request_Index, TAO_ECG_UDP_Request_Entry*, ACE_Hash<TAO_ECG_UDP_Request_Index>, ACE_Equal_To<TAO_ECG_UDP_Request_Index>, ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Entry<TAO_ECG_UDP_Request_Index,TAO_ECG_UDP_Request_Entry*>; -template class ACE_Hash<TAO_ECG_UDP_Request_Index>; -template class ACE_Equal_To<TAO_ECG_UDP_Request_Index>; -template class ACE_Hash_Map_Iterator_Base_Ex<TAO_ECG_UDP_Request_Index, TAO_ECG_UDP_Request_Entry*, ACE_Hash<TAO_ECG_UDP_Request_Index>, ACE_Equal_To<TAO_ECG_UDP_Request_Index>, ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Iterator<TAO_ECG_UDP_Request_Index,TAO_ECG_UDP_Request_Entry*,ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Iterator_Ex<TAO_ECG_UDP_Request_Index, TAO_ECG_UDP_Request_Entry*, ACE_Hash<TAO_ECG_UDP_Request_Index>, ACE_Equal_To<TAO_ECG_UDP_Request_Index>, ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator<TAO_ECG_UDP_Request_Index,TAO_ECG_UDP_Request_Entry*,ACE_SYNCH_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_ECG_UDP_Request_Index, TAO_ECG_UDP_Request_Entry*, ACE_Hash<TAO_ECG_UDP_Request_Index>, ACE_Equal_To<TAO_ECG_UDP_Request_Index>, ACE_SYNCH_MUTEX>; - -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) - -#pragma instantiate ACE_Hash_Map_Manager<TAO_ECG_UDP_Request_Index,TAO_ECG_UDP_Request_Entry*,ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_ECG_UDP_Request_Index, TAO_ECG_UDP_Request_Entry*, ACE_Hash<TAO_ECG_UDP_Request_Index>, ACE_Equal_To<TAO_ECG_UDP_Request_Index>, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Entry<TAO_ECG_UDP_Request_Index,TAO_ECG_UDP_Request_Entry*> -#pragma instantiate ACE_Hash<TAO_ECG_UDP_Request_Index> -#pragma instantiate ACE_Equal_To<TAO_ECG_UDP_Request_Index> -#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_ECG_UDP_Request_Index, TAO_ECG_UDP_Request_Entry*, ACE_Hash<TAO_ECG_UDP_Request_Index>, ACE_Equal_To<TAO_ECG_UDP_Request_Index>, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator<TAO_ECG_UDP_Request_Index,TAO_ECG_UDP_Request_Entry*,ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_ECG_UDP_Request_Index, TAO_ECG_UDP_Request_Entry*, ACE_Hash<TAO_ECG_UDP_Request_Index>, ACE_Equal_To<TAO_ECG_UDP_Request_Index>, ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_ECG_UDP_Request_Index,TAO_ECG_UDP_Request_Entry*,ACE_SYNCH_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_ECG_UDP_Request_Index, TAO_ECG_UDP_Request_Entry*, ACE_Hash<TAO_ECG_UDP_Request_Index>, ACE_Equal_To<TAO_ECG_UDP_Request_Index>, ACE_SYNCH_MUTEX> - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway_UDP.h b/TAO/orbsvcs/orbsvcs/Event/EC_Gateway_UDP.h deleted file mode 100644 index 70c3df83ba7..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway_UDP.h +++ /dev/null @@ -1,638 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// TAO services -// -// = FILENAME -// EC_Gateway_UDP -// -// = AUTHOR -// Carlos O'Ryan -// -// = DESCRIPTION -// Define helper classes to propagate events between ECs using -// either UDP or multicast. -// The architecture is a bit complicated and deserves some -// explanation: sending the events over UDP (or mcast) is easy, a -// Consumer (TAO_ECG_UDP_Sender) subscribes for a certain set of -// events, its push() method marshalls the event set into a CDR -// stream that is sent using an ACE_SOCK_CODgram. The subscription -// set and IP address can be configured. -// Another helper class (TAO_ECG_UDP_Receiver) acts as a supplier of -// events; it receives a callback when an event is available on an -// ACE_SOCK_Dgram, it demarshalls the event and pushes it to the -// EC. Two ACE_Event_Handler classes are provided that can forward -// the events to this Supplier: TAO_ECG_Mcast_EH can receive events -// from a multicast group; TAO_ECG_UDP_EH can receive events from a -// regular UDP socket. -// -// Matching of the events types carried by a multicast group (or IP -// address) is up to the application. Gateway classes can be -// implemented to automate this: the EC informs its gateways about -// local changes in the subscriptions (for example), the Gateway -// could then consult an administrative server that will inform it -// which multicast groups carry those event types, it can then -// create the proper event handlers and TAO_ECG_Receivers. An -// analogous class can be implemented for the Supplier side. -// -// An alternative approach would be to look the current set of -// multicast groups and the events carried on each, using that -// information a suitable TAO_ECG_UDP_Receiver can be configured -// (and of course the Senders on the client side). -// -// = TODO -// The class makes an extra copy of the events, we need to -// investigate if closer collaboration with its collocated EC could -// be used to remove that copy. -// -// ============================================================================ - -#ifndef TAO_EC_GATEWAY_UDP_H -#define TAO_EC_GATEWAY_UDP_H - -#include "ace/SOCK_CODgram.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Dgram_Mcast.h" -#include "orbsvcs/RtecEventChannelAdminS.h" -#include "orbsvcs/RtecUDPAdminS.h" -#include "orbsvcs/orbsvcs_export.h" - -class TAO_ECG_UDP_Out_Endpoint; - -class TAO_ORBSVCS_Export TAO_ECG_UDP_Sender : public POA_RtecEventComm::PushConsumer -{ - // - // = TITLE - // Send events received from a "local" EC using UDP. - // - // = DESCRIPTION - // This class connect as a consumer to an EventChannel - // and it sends the events using UDP, the UDP address can be a - // normal IP address or it can be a multicast group. - // The UDP address is obtained from a RtecUDPAdmin::AddrServer - // class. - // It marshalls the events using TAO CDR classes. - // - // = MESSAGE FORMAT - // - // The messages header are encapsulated using CDR, with the - // following format: - // - // struct Header { - // octet byte_order_flags; - // // bit 0 represents the byte order as in GIOP 1.1 - // // bit 1 is set if this is the last fragment - // - // unsigned long request_id; - // // The request ID, senders must not send two requests with - // // the same ID, senders can be distinguished using recvfrom.. - // - // unsigned long request_size; - // // The size of this request, this can be used to pre-allocate - // // the request buffer. - // - // unsgined long fragment_size; - // // The size of this fragment, excluding the header... - // - // unsigned long fragment_offset; - // // Where does this fragment fit in the complete message... - // - // unsigned long fragment_id; - // // The ID of this fragment... - // - // unsigned long fragment_count; - // // The total number of fragments to expect in this request - // // @@ TODO This could be eliminated if efficient reassembly - // // could be implemented without it. - // - // octet padding[4]; - // // Ensures the header ends at an 8-byte boundary. - // }; // size (in CDR stream) = 32 - // - // -public: - TAO_ECG_UDP_Sender (void); - - enum { - ECG_HEADER_SIZE = 32, - ECG_MIN_MTU = 32 + 8, - ECG_MAX_MTU = 65536, // Really optimistic... - ECG_DEFAULT_MTU = 1024 - }; - - int get_local_addr (ACE_INET_Addr& addr); - // Get the local endpoint used to send the events. - - void init (RtecEventChannelAdmin::EventChannel_ptr lcl_ec, - RtecScheduler::Scheduler_ptr lcl_sched, - const char* lcl_name, - RtecUDPAdmin::AddrServer_ptr addr_server, - TAO_ECG_UDP_Out_Endpoint* endpoint, - CORBA::Environment &_env); - // To do its job this class requires to know the local EC it will - // connect to; it also requires to build an RT_Info for the local - // scheduler. - // It only keeps a copy of its SupplierProxy, used for later - // connection and disconnections. - // @@ TODO part of the RT_Info is hardcoded, we need to make it - // parametric. - - int mtu (CORBA::ULong mtu); - CORBA::ULong mtu (void) const; - // The sender may need to fragment the message, otherwise the - // network may drop the packets. - // Setting the MTU can fail if the value is too small (at least the - // header + 8 bytes must fit). - - void shutdown (CORBA::Environment&); - // Disconnect and shutdown the sender, no further connections will - // work unless init() is called again. - - void open (RtecEventChannelAdmin::ConsumerQOS& sub, - CORBA::Environment& env); - // Connect (or reconnect) to the EC with the given subscriptions. - - void close (CORBA::Environment& _env); - // Disconnect from the EC, but reconnection is still possible. - - virtual void disconnect_push_consumer (CORBA::Environment &); - virtual void push (const RtecEventComm::EventSet &events, - CORBA::Environment &); - // The PushConsumer methods. - -private: - ACE_SOCK_Dgram& dgram (void); - // Return the datagram... - - void send_fragment (const RtecUDPAdmin::UDP_Addr& udp_addr, - CORBA::ULong request_id, - CORBA::ULong request_size, - CORBA::ULong fragment_size, - CORBA::ULong fragment_offset, - CORBA::ULong fragment_id, - CORBA::ULong fragment_count, - iovec iov[], - int iovcnt, - CORBA::Environment& _env); - // Send one fragment, the first entry in the iovec is used to send - // the header, the rest of the iovec array should contain pointers - // to the actual data. - - CORBA::ULong compute_fragment_count (const ACE_Message_Block* begin, - const ACE_Message_Block* end, - int iov_size, - CORBA::ULong max_fragment_payload, - CORBA::ULong& total_length); - // Count the number of fragments that will be required to send the - // message blocks in the range [begin,end) - // The maximum fragment payload (i.e. the size without the header is - // also required); <total_length> returns the total message size. - -private: - RtecEventChannelAdmin::EventChannel_var lcl_ec_; - // The remote and the local EC, so we can reconnect when the - // subscription list changes. - - RtecScheduler::handle_t lcl_info_; - // Our local and remote RT_Infos. - - RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_; - // We talk to the EC (as a consumer) using this proxy. - - RtecUDPAdmin::AddrServer_var addr_server_; - // We query this object to determine where are the events sent. - - TAO_ECG_UDP_Out_Endpoint *endpoint_; - // The datagram used to sendto(), this object is *not* owned by the - // UDP_Sender. - - CORBA::ULong mtu_; - // The MTU for this sender... -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_ECG_UDP_Out_Endpoint -{ - // - // = TITLE - // Maintains information about an outgoing endpoint. - // - // = DESCRIPTION - // UDP senders can share a single endpoint to send UDP packets, - // but there is more state associated with this endpoint than its - // datagram SAP; for instance we need to keep track of the request - // id. -public: - TAO_ECG_UDP_Out_Endpoint (void); - // Constructor - - ~TAO_ECG_UDP_Out_Endpoint (void); - // Constructor - - ACE_SOCK_Dgram& dgram (void); - // Obtain the datagram associated with this endpoint. Clients of - // this class must open, and register (if necessary) this datagram. - - CORBA::ULong next_request_id (void); - // Obtain the next request id. - - CORBA::Boolean is_loopback (const ACE_INET_Addr& from); - // The endpoint can detect if a data-gram was sent by itself, this - // is useful to ignore or remove messages sent by the same process. - -private: - ACE_Atomic_Op<ACE_SYNCH_MUTEX,CORBA::ULong> request_id_generator_; - // The request id.... - - ACE_SOCK_Dgram dgram_; - // The datagram.... - - u_short port_number_; - // cache the port-number so we can quickly determine if an event is - // coming from another endpoint. - - size_t if_count_; - ACE_INET_Addr* ifs_; - // Keep the list of local interfaces, needed for the is_loopback - // method. -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_ECG_UDP_Request_Index -{ - // = TITLE - // Index to the request map. - // - // = DESCRIPTION - // This object is used to index the map of incomplete (due to - // fragmentation) requests. - // -public: - TAO_ECG_UDP_Request_Index (void); - TAO_ECG_UDP_Request_Index (const ACE_INET_Addr& from, - CORBA::ULong request_id); - // default copy ctor, dtor and operator= - - ACE_INLINE u_long hash (void) const; - // Return a hash value... - - ACE_INLINE int operator== (const TAO_ECG_UDP_Request_Index& rhs) const; - ACE_INLINE int operator!= (const TAO_ECG_UDP_Request_Index& rhs) const; - // Compare - - ACE_INET_Addr from; - CORBA::ULong request_id; -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_ECG_UDP_Request_Entry -{ - // = TITLE - // Keeps information about an incomplete request. - // - // = DESCRIPTION - // When a request arrives in fragments this object is used to - // keep track of the incoming data. - // -public: - enum { - ECG_DEFAULT_FRAGMENT_BUFSIZ = 8 - }; - - // TAO_ECG_UDP_Request_Entry (void); - // TAO_ECG_UDP_Request_Entry (const TAO_ECG_UDP_Request_Entry& rhs); - // TAO_ECG_UDP_Request_Entry& operator=(const TAO_ECG_UDP_Request_Entry& rhs); - ~TAO_ECG_UDP_Request_Entry (void); - - TAO_ECG_UDP_Request_Entry (CORBA::Boolean byte_order, - CORBA::ULong request_id, - CORBA::ULong request_size, - CORBA::ULong fragment_count); - // Initialize the fragment, allocating memory, etc. - - int validate_fragment (CORBA::Boolean byte_order, - CORBA::ULong request_size, - CORBA::ULong fragment_size, - CORBA::ULong fragment_offset, - CORBA::ULong fragment_id, - CORBA::ULong fragment_count) const; - // Validate a fragment, it should be rejected if it is invalid.. - - int test_received (CORBA::ULong fragment_id) const; - // Has <fragment_id> been received? - - void mark_received (CORBA::ULong fragment_id); - // Mark <fragment_id> as received, reset timeout counter... - - int complete (void) const; - // Is the message complete? - - char* fragment_buffer (CORBA::ULong fragment_offset); - // Return a buffer for the fragment at offset <fragment_offset> - - void decode (RtecEventComm::EventSet& event, - CORBA::Environment& _env); - // Decode the events, the message must be complete. - - void inc_timeout (void); - // Increment the timeout counter... - - int get_timeout (void) const; - // Get the timeout counter.... - -private: - CORBA::Boolean byte_order_; - CORBA::ULong request_id_; - CORBA::ULong request_size_; - CORBA::ULong fragment_count_; - // This attributes should remain constant in all the fragments, used - // for validation.... - - CORBA::ULong timeout_counter_; - ACE_Message_Block payload_; - - CORBA::ULong* received_fragments_; - int own_received_fragments_; - CORBA::ULong received_fragments_size_; - CORBA::ULong default_received_fragments_[ECG_DEFAULT_FRAGMENT_BUFSIZ]; - // This is a bit vector, used to keep track of the received buffers. -}; - -// **************************************************************** - -class TAO_ECG_UDP_Receiver; - -class TAO_ORBSVCS_Export TAO_ECG_UDP_TH : public ACE_Event_Handler -{ - // - // = TITLE - // Timer Handler for the UDP Receivers. - // - // = DESCRIPTION - // This object receives timer events from the reactor and forwards - // them to the UDP_Receiver; which uses those events to expire old - // messages that did not receive all their fragments. - // -public: - TAO_ECG_UDP_TH (TAO_ECG_UDP_Receiver *recv); - - // Reactor callbacks - virtual int handle_timeout (const ACE_Time_Value& tv, - const void* act); - -private: - TAO_ECG_UDP_Receiver* receiver_; - // We callback to this object when a message arrives. -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_ECG_UDP_Receiver : public POA_RtecEventComm::PushSupplier -{ - // - // = TITLE - // Decodes events from an ACE_SOCK_Dgram and pushes them to the - // Event_Channel. - // - // = DESCRIPTION - // This supplier receives events from an ACE_SOCK_Dgram, either - // from a UDP socket or a Mcast group, decodes them and push them - // to the EC. - // - // = REASSEMBLY - // - // Whenever an incomplete fragment is received (one with - // fragment_count > 1) we allocate an entry for the message in an - // map indexed by (host,port,request_id). The entry contains the - // buffer, a bit vector to keep track of the fragments received - // so far, and a timeout counter. This timeout counter is set to - // 0 on each (new) fragment arrival, and incremented on a regular - // basis. If the counter reaches a maximum value the message is - // dropped. - // Once all the fragments have been received the message is sent - // up, and the memory reclaimed. The entry is *not* removed until - // the timer expires (to handle re-transmitions). - // -public: - TAO_ECG_UDP_Receiver (void); - - void init (RtecEventChannelAdmin::EventChannel_ptr lcl_ec, - RtecScheduler::Scheduler_ptr lcl_sched, - const char* lcl_name, - TAO_ECG_UDP_Out_Endpoint* ignore_from, - RtecUDPAdmin::AddrServer_ptr addr_server, - ACE_Reactor *reactor, - const ACE_Time_Value &expire_interval, - int max_timeout, - CORBA::Environment &_env); - // To do its job this class requires to know the local EC it will - // connect to; it also requires to build an RT_Info for the local - // scheduler. - // The <reactor> is used to receive timeout events.. - // The <ignore_from> endpoint is used to remove events generated by - // the same process. - // @@ TODO part of the RT_Info is hardcoded, we need to make it - // parametric. - - void shutdown (CORBA::Environment&); - // Disconnect and shutdown the gateway, no further connectsions - - void open (RtecEventChannelAdmin::SupplierQOS& pub, - CORBA::Environment &env); - // Connect to the EC using the given publications lists. - - virtual void close (CORBA::Environment& env); - // Disconnect to the EC. - - int handle_input (ACE_SOCK_Dgram& dgram); - // The Event_Handlers call this method when data is available at the - // socket, the <dgram> must be ready for reading and contain a full - // event. - - int handle_timeout (const ACE_Time_Value& tv, - const void* act); - // The timer has expired, must update all the unreceived - // messages... - - // The PushSupplier method. - virtual void disconnect_push_supplier (CORBA::Environment &); - - - void get_addr (const RtecEventComm::EventHeader& header, - RtecUDPAdmin::UDP_Addr_out addr, - CORBA::Environment& env); - // Call the RtecUDPAdmin::AddrServer - -private: - RtecEventChannelAdmin::EventChannel_var lcl_ec_; - // The remote and the local EC, so we can reconnect when the list changes. - - RtecScheduler::handle_t lcl_info_; - // Our RT_Info. - - RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy_; - // We talk to the EC (as a consumer) using this proxy. - - TAO_ECG_UDP_Out_Endpoint* ignore_from_; - // Ignore any events coming from this IP addres. - - RtecUDPAdmin::AddrServer_var addr_server_; - // The server used to map event types into multicast groups. - - typedef ACE_Hash_Map_Manager<TAO_ECG_UDP_Request_Index, - TAO_ECG_UDP_Request_Entry*, - ACE_SYNCH_MUTEX> Request_Map; - typedef ACE_Hash_Map_Entry<TAO_ECG_UDP_Request_Index, - TAO_ECG_UDP_Request_Entry*> Request_Map_Entry; - - Request_Map request_map_; - // The map containing all the incoming requests which have been - // partially received. - - TAO_ECG_UDP_TH timeout_handler_; - // To receive the timeouts.. - - ACE_Reactor* reactor_; - // The reactor we are using for the timeout handler... - - int max_timeout_; - // How many timeouts before we expire a message... -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_ECG_UDP_EH : public ACE_Event_Handler -{ - // - // = TITLE - // Event Handler for UDP messages. - // - // = DESCRIPTION - // This object receives callbacks from the Reactor when data is - // available on a UDP socket, it forwards to the ECG_UDP_Receiver - // which reads the events and transform it into an event. - // -public: - TAO_ECG_UDP_EH (TAO_ECG_UDP_Receiver *recv); - - int open (const ACE_INET_Addr& ipaddr); - // Open the datagram and register with this->reactor() - - int close (void); - // Close the datagram and unregister with the reactor. - - // Reactor callbacks - virtual int handle_input (ACE_HANDLE fd); - virtual ACE_HANDLE get_handle (void) const; - -private: - ACE_SOCK_Dgram dgram_; - // The datagram used to receive the data. - - TAO_ECG_UDP_Receiver* receiver_; - // We callback to this object when a message arrives. -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_ECG_Mcast_EH : public ACE_Event_Handler -{ - // - // = TITLE - // Event Handler for UDP messages. - // - // = DESCRIPTION - // This object receives callbacks from the Reactor when data is - // available on the mcast socket, it forwards to the UDP_Receive - // gateway which reads the events and transform it into an event. - // -public: - TAO_ECG_Mcast_EH (TAO_ECG_UDP_Receiver *recv); - - int open (RtecEventChannelAdmin::EventChannel_ptr ec, - CORBA::Environment& _env); - // Register for changes in the EC subscription list. - // When the subscription list becomes non-empty we join the proper - // multicast groups (using the receiver to translate between event - // types and mcast groups) and the class registers itself with the - // reactor. - - int close (CORBA::Environment& _env); - // Remove ourselves from the event channel, unsubscribe from the - // multicast groups, close the sockets and unsubscribe from the - // reactor. - - virtual int handle_input (ACE_HANDLE fd); - virtual ACE_HANDLE get_handle (void) const; - // Reactor callbacks - - void update_consumer (const RtecEventChannelAdmin::ConsumerQOS& sub, - CORBA::Environment& _env); - void update_supplier (const RtecEventChannelAdmin::SupplierQOS& pub, - CORBA::Environment& _env); - // The Observer methods - - class Observer : public POA_RtecEventChannelAdmin::Observer - { - // = TITLE - // Observe changes in the EC subscriptions. - // - // = DESCRIPTION - // As the subscriptions on the EC change we also change the - // mcast groups that we join. - // We could use the TIE classes, but they don't work in all - // compilers. - public: - Observer (TAO_ECG_Mcast_EH* eh); - // We report changes in the EC subscriptions to the event - // handler. - - // The Observer methods - virtual void update_consumer (const RtecEventChannelAdmin::ConsumerQOS& sub, - CORBA::Environment& _env); - virtual void update_supplier (const RtecEventChannelAdmin::SupplierQOS& pub, - CORBA::Environment& _env); - - private: - TAO_ECG_Mcast_EH* eh_; - // Our callback object. - }; - -private: - int subscribe (const ACE_INET_Addr &mcast_addr); - int unsubscribe (const ACE_INET_Addr &mcast_addr); - // Control the multicast group subscriptions - -private: - ACE_SOCK_Dgram_Mcast dgram_; - // The datagram used to receive the data. - - TAO_ECG_UDP_Receiver* receiver_; - // We callback to this object when a message arrives. - - Observer observer_; - // This object will call us back when the subscription list - // changes. - - RtecEventChannelAdmin::Observer_Handle handle_; - // Keep the handle of the observer so we can unregister later. - - RtecEventChannelAdmin::EventChannel_var ec_; - // The Event Channel. -}; - -#if defined(__ACE_INLINE__) -#include "EC_Gateway_UDP.i" -#endif /* __ACE_INLINE__ */ - -#endif /* ACE_EVENT_CHANNEL_UDP_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway_UDP.i b/TAO/orbsvcs/orbsvcs/Event/EC_Gateway_UDP.i deleted file mode 100644 index 5d494997767..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_Gateway_UDP.i +++ /dev/null @@ -1,90 +0,0 @@ -// -// $Id$ -// - -ACE_INLINE -TAO_ECG_UDP_Out_Endpoint::TAO_ECG_UDP_Out_Endpoint (void) - : port_number_ (0), - if_count_ (0), - ifs_ (0) -{ -} - -ACE_INLINE ACE_SOCK_Dgram& -TAO_ECG_UDP_Out_Endpoint::dgram (void) -{ - return this->dgram_; -} - -ACE_INLINE CORBA::ULong -TAO_ECG_UDP_Out_Endpoint::next_request_id (void) -{ - return this->request_id_generator_++; -} - -// **************************************************************** - -ACE_INLINE ACE_SOCK_Dgram& -TAO_ECG_UDP_Sender::dgram (void) -{ - return this->endpoint_->dgram (); -} - -ACE_INLINE CORBA::ULong -TAO_ECG_UDP_Sender::mtu (void) const -{ - return this->mtu_; -} - -// **************************************************************** - -ACE_INLINE -TAO_ECG_UDP_Request_Index::TAO_ECG_UDP_Request_Index (void) - : request_id (0) -{ -} - -ACE_INLINE -TAO_ECG_UDP_Request_Index::TAO_ECG_UDP_Request_Index (const ACE_INET_Addr& from_, - CORBA::ULong request_id_) - : from (from_), - request_id (request_id_) -{ -} - -ACE_INLINE u_long -TAO_ECG_UDP_Request_Index::hash (void) const -{ - return ((from.get_ip_address() << 24) - | (from.get_port_number () << 8) - | (request_id & 0x000000ff)); -} - -ACE_INLINE int -TAO_ECG_UDP_Request_Index::operator== (const TAO_ECG_UDP_Request_Index& rhs) const -{ - return (this->from == rhs.from && - this->request_id == rhs.request_id); -} - -ACE_INLINE int -TAO_ECG_UDP_Request_Index::operator!= (const TAO_ECG_UDP_Request_Index& rhs) const -{ - return !(*this == rhs); -} - -// **************************************************************** - -void -TAO_ECG_UDP_Request_Entry::inc_timeout (void) -{ - this->timeout_counter_++; -} - -int -TAO_ECG_UDP_Request_Entry::get_timeout (void) const -{ - return this->timeout_counter_; -} - - diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.h b/TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.h deleted file mode 100644 index f8a6039d1dd..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ORBSVCS Real-time Event Channel -// -// = FILENAME -// EC_ProxyConsumer -// -// = AUTHOR -// Carlos O'Ryan (coryan@cs.wustl.edu) -// -// = DESCRIPTION -// Implement the RtecEventChannelAdmin::ProxyPushConsumer interface, -// remember that this class is used to communicate with a -// PushSupplier, so, in effect, this is the ambassador for a -// supplier inside the event channel. -// -// = CREDITS -// Based on previous work by Tim Harrison (harrison@cs.wustl.edu) -// and other members of the DOC group. -// More details can be found in: -// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz -// http://www.cs.wustl.edu/~schmidt/JSAC-98.ps.gz -// -// -// ============================================================================ - -#ifndef TAO_EC_PROXYCONSUMER_H -#define TAO_EC_PROXYCONSUMER_H - -#include "orbsvcs/Event/EC_Filter.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class TAO_EC_Dispatching; -class TAO_EC_Filter_Builder; - -class TAO_EC_ProxyPushConsumer : public TAO_EC_Filter -{ - // = TITLE - // ProxyPushConsumer - // - // = DESCRIPTION - // Implements the ProxyPushConsumer interface, i.e. the object - // used to communicate with a particular consumer. - // - // = MEMORY MANAGMENT - // It makes a copy of the SupplierQOS and the supplier object - // reference. - // The object commits suicide when disconnect_push_consumer() is - // called. - // - // = LOCKING - // No provisions for locking, access must be serialized - // externally. - // -public: - TAO_EC_ProxyPushConsumer (TAO_EC_SupplierAdmin* supplier_admin); - // constructor... - - virtual ~TAO_EC_ProxyPushConsumer (void); - // destructor... - - CORBA::Boolean is_connected (void) const; - // Return 0 if no supplier is connected... - - RtecEventComm::PushSupplier_ptr supplier (void) const; - // Return the consumer object reference. It returns nil() if it has - // not connected yet. - - const RtecEventChannelAdmin::SupplierQOS& publications (void) const; - // The QoS (subscription) used to connect to the EC. - - virtual void connected (TAO_EC_ProxyPushSupplier* supplier) = 0; - virtual void disconnected (TAO_EC_ProxyPushSupplier* supplier) = 0; - // Concrete implementations can use this methods to keep track of - // the consumers interested in this events. - - // = The RtecEventChannelAdmin::ProxyPushConsumer methods... - virtual void connect_push_supplier ( - RtecEventComm::PushConsumer_ptr push_consumer, - const RtecEventChannelAdmin::ConsumerQOS& qos, - CORBA::Environment &); - virtual void push (const RtecEventComm::EventSet& event, - CORBA::Environment &); - virtual void disconnect_push_consumer (CORBA::Environment &); - -private: - TAO_EC_SupplierAdmin* supplier_admin_; - // The supplier admin, used for activation and memory managment. - - RtecEventComm::PushSupplier_var supplier_; - // The supplier.... - - RtecEventChannelAdmin::SupplierQOS qos_; - // The publication and QoS information... -}; - -#if defined (__ACE_INLINE__) -#include "EC_ProxyConsumer.i" -#endif /* __ACE_INLINE__ */ - -#endif /* TAO_EC_PROXYCONSUMER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.h b/TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.h deleted file mode 100644 index 0517dd28344..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.h +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ORBSVCS Real-time Event Channel -// -// = FILENAME -// EC_ProxySupplier -// -// = AUTHOR -// Carlos O'Ryan (coryan@cs.wustl.edu) -// -// = DESCRIPTION -// Implement the RtecEventChannelAdmin::ProxyPushSupplier interface, -// remember that this class is used to communicate with a -// PushConsumer, so, in effect, this is the ambassador for a -// consumer inside the event channel. -// -// = CREDITS -// Based on previous work by Tim Harrison (harrison@cs.wustl.edu) -// and other members of the DOC group. -// More details can be found in: -// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz -// http://www.cs.wustl.edu/~schmidt/JSAC-98.ps.gz -// -// -// ============================================================================ - -#ifndef TAO_EC_PROXYSUPPLIER_H -#define TAO_EC_PROXYSUPPLIER_H - -#include "orbsvcs/Event/EC_Filter.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class TAO_EC_Dispatching; -class TAO_EC_Filter_Builder; - -class TAO_EC_ProxyPushSupplier : public TAO_EC_Filter -{ - // = TITLE - // ProxyPushSupplier - // - // = DESCRIPTION - // Implements the ProxyPushSupplier interface, i.e. the object - // used to communicate with a particular consumer. - // - // = MEMORY MANAGMENT - // This object is reference counted. - // It does not assume ownership of the TAO_EC_Dispatching object. - // It makes a copy of the ConsumerQOS and the consumer object - // reference. - // - // = LOCKING - // No provisions for locking, access must be serialized - // externally. - // - // = TODO - // We don't need to provide a trivial filter, the object itself - // could short-circuit the filter() ---> push() cycle when the EC - // is properly configured, we need to explore this... - // -public: - TAO_EC_ProxyPushSupplier (TAO_EC_ConsumerAdmin* consumer_admin, - TAO_EC_Dispatching* dispatching, - TAO_EC_Filter_Builder* builder); - // constructor... - - virtual ~TAO_EC_ProxyPushSupplier (void); - // destructor... - - CORBA::Boolean is_connected (void) const; - // Return 0 if no consumer is connected... - - CORBA::Boolean is_suspended (void) const; - // Return 1 if it is suspended. - - RtecEventComm::PushConsumer_ptr consumer (void) const; - // Return the consumer object reference. It returns nil() if it has - // not connected yet. - - const RtecEventChannelAdmin::ConsumerQOS& subscriptions (void) const; - // The QoS (subscription) used to connect to the EC. - - // = The RtecEventChannelAdmin::ProxyPushSupplier methods... - virtual void connect_push_consumer ( - RtecEventComm::PushConsumer_ptr push_consumer, - const RtecEventChannelAdmin::ConsumerQOS& qos, - CORBA::Environment &); - virtual void disconnect_push_supplier (CORBA::Environment &); - virtual void suspend_connection (CORBA::Environment &); - virtual void resume_connection (CORBA::Environment &); - - // = The TAO_EC_Filter methods, only push() is implemented... - virtual int filter (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void push (const RtecEventComm::EventSet& event, - const TAO_EC_QOS_Info& qos_info, - CORBA::Environment& env); - virtual void clear (void); - virtual CORBA::ULong max_event_size (void) const; - virtual void event_ids (RtecEventComm::EventHeaderSet& headerset); - -private: - TAO_EC_ConsumerAdmin* consumer_admin_; - // The consumer admin, used for activation and memory managment. - - TAO_EC_Dispatching *dispatching_; - // We delegate on this object to handle - - RtecEventComm::PushConsumer_var consumer_; - // The consumer.... - - CORBA::Boolean suspended_; - // Is this consumer suspended? - - RtecEventChannelAdmin::ConsumerQOS qos_; - // The subscription and QoS information... -}; - -#if defined (__ACE_INLINE__) -#include "EC_ProxySupplier.i" -#endif /* __ACE_INLINE__ */ - -#endif /* TAO_EC_PROXYSUPPLIER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_UDP_Admin.cpp b/TAO/orbsvcs/orbsvcs/Event/EC_UDP_Admin.cpp deleted file mode 100644 index d45ce1002ab..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_UDP_Admin.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// $Id$ - -#include "orbsvcs/Event/EC_UDP_Admin.h" - -ACE_RCSID(Event, EC_UDP_Admin, "$Id$") - -TAO_EC_Simple_AddrServer::TAO_EC_Simple_AddrServer (CORBA::UShort port) - : port_ (port) -{ -} - -TAO_EC_Simple_AddrServer::~TAO_EC_Simple_AddrServer (void) -{ -} - -void -TAO_EC_Simple_AddrServer::get_addr (const RtecEventComm::EventHeader& header, - RtecUDPAdmin::UDP_Addr_out addr, - CORBA::Environment&) -{ - addr.ipaddr = header.type; - addr.port = this->port_; -} diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_UDP_Admin.h b/TAO/orbsvcs/orbsvcs/Event/EC_UDP_Admin.h deleted file mode 100644 index 8d7c41842b0..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/EC_UDP_Admin.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// TAO services -// -// = FILENAME -// EC_UDP_Admin -// -// = AUTHOR -// Carlos O'Ryan -// -// = DESCRIPTION -// Simple implementations of the UDP Administration service. -// -// connects to a "remote" EC as a consumer, it also connects to the -// <local> EC as a supplier of events, this later EC is usually -// collocated. -// The QoS parameters for both connections must be provided by the -// user. -// To avoid infinite loops of events the Gateway descreases the TTL -// field of the events and will not deliver any events with TTL less -// than or equal to 0. -// -// = TODO -// The class makes an extra copy of the events, we need to -// investigate if closer collaboration with its collocated EC could -// be used to remove that copy. -// -// ============================================================================ - -#ifndef TAO_EC_UDP_ADMIN_H -#define TAO_EC_UDP_ADMIN_H - -#include "orbsvcs/RtecUDPAdminS.h" -#include "orbsvcs/orbsvcs_export.h" - -class TAO_ORBSVCS_Export TAO_EC_Simple_AddrServer : public POA_RtecUDPAdmin::AddrServer -{ - // = TITLE - // TAO Real-time Event Service; a simple UDP address server. - // - // = DESCRIPTION - // The EC is able to use multiple multicast groups to transmit its - // data, the is given control over the mapping between the Event - // (type,source) pair and the (ipaddr,port) pair using a - // AddrServer. - // This class implements a very simple server that simply maps the - // <type> component to the <ipaddr> and uses a fixed <port>, - // provided at initialization time. - // -public: - TAO_EC_Simple_AddrServer (CORBA::UShort port); - // Constructor - - virtual ~TAO_EC_Simple_AddrServer (void); - // Destructor - - // = The RtecUDPAdmin::AddrServer methods - virtual void get_addr (const RtecEventComm::EventHeader& header, - RtecUDPAdmin::UDP_Addr_out addr, - CORBA::Environment& env); - -private: - CORBA::UShort port_; -}; - -#endif /* TAO_EC_UDP_ADMIN_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Channel.cpp b/TAO/orbsvcs/orbsvcs/Event/Event_Channel.cpp deleted file mode 100644 index db04889aa21..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Event_Channel.cpp +++ /dev/null @@ -1,3343 +0,0 @@ -// $Id$ - -#include "ace/Service_Config.h" -#include "ace/Auto_Ptr.h" -#include "orbsvcs/Scheduler_Factory.h" -#include "orbsvcs/Event_Utilities.h" - -#include "orbsvcs/Event/Dispatching_Modules.h" -#include "orbsvcs/Event/Memory_Pools.h" -#include "orbsvcs/Event/EC_Gateway.h" -#include "orbsvcs/Event/Module_Factory.h" -#include "orbsvcs/Event/Event_Manip.h" -#include "orbsvcs/Event/Event_Channel.h" - -// These are to save space. -#define WRITE_GUARD ACE_ES_WRITE_GUARD -#define READ_GUARD ACE_ES_READ_GUARD - -#if !defined (__ACE_INLINE__) -#include "Event_Channel.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(Event, Event_Channel, "$Id$") - -#include "tao/Timeprobe.h" - -#if defined (ACE_ENABLE_TIMEPROBES) - -static const char *TAO_Event_Channel_Timeprobe_Description[] = -{ - "Preemption_Priority - priority requested", - "connected - priority obtained", - "enter Push_Supplier_Proxy::push", - "enter ES_Consumer_Module::push", - "leave ES_Consumer_Module::push", - "enter ACE_ES_Correlation_Module::push", - "pushed to Correlation_Module", - "push_source_type: Dispatch Module enqueuing", - "ACE_ES_Consumer_Correlation::push, enter", - "Consumer_Correlation::push, determine NO CORR.", - "Consumer_Correlation::push, NO_CORR: alloc", - "Consumer_Rep_Timeout::execute", - "deliver to Subscription Module", - "begin push_source_type", - "end push_source_type", - "deliver to Supplier Module (thru Supplier Proxy)", - "connected - priority requested", - "Consumer_Name - priority requested", - "Consumer_Name - priority obtained", - "deliver event to consumer proxy", - "enter ACE_ES_Subscription_Module::push", - "push_source_type" -}; - -enum -{ - // Timeprobe description table start key - TAO_EVENT_CHANNEL_PREEMPTION_PRIORITY_PRIORITY_REQUESTED = 5100, - TAO_EVENT_CHANNEL_CONNECTED_PRIORITY_OBTAINED, - TAO_EVENT_CHANNEL_ENTER_PUSH_SUPPLIER_PROXY_PUSH, - TAO_EVENT_CHANNEL_ENTER_ES_CONSUMER_MODULE_PUSH, - TAO_EVENT_CHANNEL_LEAVE_ES_CONSUMER_MODULE_PUSH, - TAO_EVENT_CHANNEL_ENTER_ACE_ES_CORRELATION_MODULE_PUSH, - TAO_EVENT_CHANNEL_PUSHED_TO_CORRELATION_MODULE, - TAO_EVENT_CHANNEL_PUSH_SOURCE_TYPE_DISPATCH_MODULE_ENQUEUING, - TAO_EVENT_CHANNEL_ACE_ES_CONSUMER_CORRELATION_PUSH_ENTER, - TAO_EVENT_CHANNEL_CONSUMER_CORRELATION_PUSH_DETERMINE_NO_CORR, - TAO_EVENT_CHANNEL_CONSUMER_CORRELATION_PUSH_NO_CORR_ALLOC, - TAO_EVENT_CHANNEL_CONSUMER_REP_TIMEOUT_EXECUTE, - TAO_EVENT_CHANNEL_DELIVER_TO_SUBSCRIPTION_MODULE, - TAO_EVENT_CHANNEL_BEGIN_PUSH_SOURCE_TYPE, - TAO_EVENT_CHANNEL_END_PUSH_SOURCE_TYPE, - TAO_EVENT_CHANNEL_DELIVER_TO_SUPPLIER_MODULE_THRU_SUPPLIER_PROXY, - TAO_EVENT_CHANNEL_CONNECTED_PRIORITY_REQUESTED, - TAO_EVENT_CHANNEL_CONSUMER_NAME_PRIORITY_REQUESTED, - TAO_EVENT_CHANNEL_CONSUMER_NAME_PRIORITY_OBTAINED, - TAO_EVENT_CHANNEL_DELIVER_EVENT_TO_CONSUMER_PROXY, - TAO_EVENT_CHANNEL_ENTER_ACE_ES_SUBSCRIPTION_MODULE_PUSH, - TAO_EVENT_CHANNEL_PUSH_SOURCE_TYPE -}; - -// Setup Timeprobes -ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Event_Channel_Timeprobe_Description, - TAO_EVENT_CHANNEL_PREEMPTION_PRIORITY_PRIORITY_REQUESTED); - -#endif /* ACE_ENABLE_TIMEPROBES */ - -// ************************************************************ - -static RtecScheduler::Preemption_Priority_t -Preemption_Priority (RtecScheduler::handle_t rtinfo, - CORBA::Environment &TAO_IN_ENV) -{ - RtecScheduler::OS_Priority thread_priority; - RtecScheduler::Preemption_Subpriority_t subpriority; - RtecScheduler::Preemption_Priority_t preemption_priority; - - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_PREEMPTION_PRIORITY_PRIORITY_REQUESTED); - ACE_Scheduler_Factory::server ()->priority - (rtinfo, - thread_priority, - subpriority, - preemption_priority, - TAO_IN_ENV); - TAO_CHECK_ENV_RETURN (TAO_IN_ENV, 0); - return preemption_priority; -} - -static RtecScheduler::OS_Priority -IntervalToPriority (RtecScheduler::Time interval) -{ - for (int x=0; x < ACE_Scheduler_MAX_PRIORITIES; x++) - if (interval <= ACE_Scheduler_Rates[x]) - return x; - - return ACE_Scheduler_MIN_PREEMPTION_PRIORITY; -} - -// ************************************************************ - -class TAO_ORBSVCS_Export Shutdown_Consumer : public ACE_ES_Dispatch_Request -// = TITLE -// Shutdown Consumer command -// -// = DESCRIPTION -// This command object is sent through the system when a consumer -// disconnects. When the Dispatching Module dequeues this request, -// it calls execute which execute calls back to the Consumer -// Module. At that point, the Consumer Module can tell the rest of -// the system that the consumer has disconnected and delete the -// consumer proxy. This allows all events queued for the consumer -// to be flushed to the consumer proxy (which will drop them). -// Events can be queued in the ReactorEx (in a dispatch set), or in -// the Dispatching Module. -{ -public: - // When executed, tells <consumer_module> that <consumer> has shut - // down. - Shutdown_Consumer (ACE_ES_Consumer_Module *consumer_module, - ACE_Push_Consumer_Proxy *consumer) - : consumer_module_ (consumer_module) - { - consumer_ = consumer; - - // Set rt_info_ to the lowest priority rt_info in consumer_. - // This is so the dispatching module can query us as a dispatch - // request to get the appropriate preemption priority. - ACE_ES_Dependency_Iterator iter (consumer->qos ().dependencies); - CORBA::Environment env; - RtecScheduler::Preemption_Priority_t p = - ACE_Scheduler_MIN_PREEMPTION_PRIORITY; - while (iter.advance_dependency () == 0) - { - RtecEventComm::EventType &type = (*iter).event.header.type; - - if (type != ACE_ES_GLOBAL_DESIGNATOR && - type != ACE_ES_CONJUNCTION_DESIGNATOR && - type != ACE_ES_DISJUNCTION_DESIGNATOR) - { - env.clear (); - RtecScheduler::Preemption_Priority_t q = - ::Preemption_Priority ((*iter).rt_info, env); - if (env.exception () != 0) - continue; - if (rt_info_ == 0 || q < p) - { - this->rt_info_ = ((*iter).rt_info); - p = q; - continue; - } - } - } - } - - // Report to the consumer module that consumer_ has shutdown. - virtual int execute (u_long &command_action) - { - consumer_module_->shutdown_request (this); - command_action = ACE_RT_Task_Command::RELEASE; - return 0; - } - -#if 0 - // @@ Memory allocators - void *operator new (size_t /* nbytes */) - { return ::new char[sizeof (Shutdown_Consumer)]; } - - void operator delete (void *buf) - { ::delete [] ACE_static_cast(char*,buf); } -#endif /* 0 */ - - // The module that we report to. - ACE_ES_Consumer_Module *consumer_module_; -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export Shutdown_Channel : public ACE_ES_Dispatch_Request -{ -public: - Shutdown_Channel (ACE_EventChannel *channel) : - channel_ (channel) {} - - // Report to the consumer module that consumer_ has shutdown. - virtual int execute (u_long &command_action) - { -#if 0 - channel_->destroy_i (); -#endif - command_action = ACE_RT_Task_Command::RELEASE; - return 0; - } - -#if 0 - // @@ Memory allocators - void *operator new (size_t /* nbytes */) - { return ::new char[sizeof (Shutdown_Channel)]; } - - void operator delete (void *buf) - { ::delete [] ACE_static_cast(char*,buf); } -#endif - - ACE_EventChannel *channel_; -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export Flush_Queue_ACT : public ACE_Command_Base -// = TITLE -// Flush Queue Asynchronous Completion Token -// -// = DESCRIPTION -// Carries a single dispatch request through the ReactorEx. -// Deletes itself when execute is called. -{ -public: - Flush_Queue_ACT (ACE_ES_Dispatch_Request *request, - ACE_ES_Dispatching_Module *dispatching_module) : - request_ (request), - dispatching_module_ (dispatching_module) { } - - virtual int execute (void* arg = 0) - { - TAO_TRY - { - ACE_ES_Dispatch_Request *request = request_; - dispatching_module_->push (request, TAO_TRY_ENV); - TAO_CHECK_ENV; - delete this; - } - TAO_CATCHANY - { - ACE_ERROR ((LM_ERROR, "(%t) Flush_Queue_ACT::execute: " - "Unknown exception..\n")); - } - TAO_ENDTRY; - return 0; - } - - ACE_ES_Dispatch_Request *request_; - ACE_ES_Dispatching_Module *dispatching_module_; -}; - -// ************************************************************ - -void -dump_event (const RtecEventComm::Event &event) -{ - ACE_DEBUG ((LM_DEBUG, "source_ = %d " - "type_ = %d " - "time_ = %u.\n", - (void*)event.header.source, - event.header.type, - // The divide-by-1 is for ACE_U_LongLong support. - ORBSVCS_Time::to_hrtime (event.header.creation_time) / 1)); -} - -// ************************************************************ - -ACE_Push_Supplier_Proxy::ACE_Push_Supplier_Proxy (ACE_ES_Supplier_Module *sm) - : supplier_module_ (sm), - push_supplier_ (0) -{ -} - -void -ACE_Push_Supplier_Proxy::connect_push_supplier (RtecEventComm::PushSupplier_ptr push_supplier, - const RtecEventChannelAdmin::SupplierQOS &qos, - CORBA::Environment &TAO_IN_ENV) -{ - if (this->connected ()) - TAO_THROW (RtecEventChannelAdmin::AlreadyConnected()); - - this->push_supplier_ = - RtecEventComm::PushSupplier::_duplicate(push_supplier); - - //ACE_DEBUG ((LM_DEBUG, "EC (%t) connect_push_supplier QOS is ")); - //ACE_SupplierQOS_Factory::debug (qos); - - // Copy by value. - this->qos_ = qos; - - // ACE_SupplierQOS_Factory::debug (qos_); - - // @@ TODO: The SupplierQOS should have a more reasonable interface to - // obtain the supplier_id(), BTW, a callback to push_supplier will - // not work: it usually results in some form of dead-lock. - this->source_id_ = qos_.publications[0].event.header.source; - - supplier_module_->connected (this, TAO_IN_ENV); -} - -void -ACE_Push_Supplier_Proxy::push (const RtecEventComm::EventSet &event, - CORBA::Environment &TAO_IN_ENV) -{ - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_ENTER_PUSH_SUPPLIER_PROXY_PUSH); - - // NOTE: Detecting that the supplier is collocated is a TAOism. - if (!this->push_supplier_->_is_collocated ()) - { - // NOTE: This is *extremely* non-portable, we know that the ORB - // core allocates this buffer from the global heap, hence it is - // safe to steal it (further the EC will release the buffer, but - // in another thread!). Other ORBs may do different things and - // this may not work! - RtecEventComm::EventSet& copy = - ACE_const_cast (RtecEventComm::EventSet&, event); - - this->time_stamp (copy); - this->supplier_module_->push (this, copy, TAO_IN_ENV); - } - else - { - RtecEventComm::EventSet copy = event; - this->time_stamp (copy); - this->supplier_module_->push (this, copy, TAO_IN_ENV); - } -} - -void -ACE_Push_Supplier_Proxy::time_stamp (RtecEventComm::EventSet& event) -{ - ACE_hrtime_t ec_recv = ACE_OS::gethrtime (); - for (CORBA::ULong i = 0; i < event.length (); ++i) - { - ORBSVCS_Time::hrtime_to_TimeT (event[i].header.ec_recv_time, - ec_recv); - } -} - -void -ACE_Push_Supplier_Proxy::disconnect_push_consumer (CORBA::Environment &TAO_IN_ENV) -{ - ACE_TIMEPROBE_PRINT; - if (this->connected ()) - { - supplier_module_->disconnecting (this, TAO_IN_ENV); - push_supplier_ = 0; - } -} - -void -ACE_Push_Supplier_Proxy::shutdown (void) -{ - TAO_TRY - { - push_supplier_->disconnect_push_supplier (TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - ACE_ERROR ((LM_ERROR, "ACE_Push_Supplier_Proxy::shutdown failed.\n")); - } - TAO_ENDTRY; -} - -// ************************************************************ - -ACE_Push_Consumer_Proxy::ACE_Push_Consumer_Proxy (ACE_ES_Consumer_Module *cm) - : push_consumer_ (0), - consumer_module_ (cm) -{ -} - -ACE_Push_Consumer_Proxy::~ACE_Push_Consumer_Proxy (void) -{ -} - -void -ACE_Push_Consumer_Proxy::push (const RtecEventComm::EventSet &events, - CORBA::Environment &TAO_IN_ENV) -{ - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_DELIVER_EVENT_TO_CONSUMER_PROXY); - - if (CORBA::is_nil (push_consumer_.in ())) - { - ACE_DEBUG ((LM_DEBUG, - "EC (%t) Push to disconnected consumer %s\n", - ::ACE_ES_Consumer_Name (this->qos (), - TAO_IN_ENV))); - // ACE_ES_DEBUG_ST (::dump_sequence (events)); - return; - } - - push_consumer_->push (events, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); -} - -void -ACE_Push_Consumer_Proxy::connect_push_consumer (RtecEventComm::PushConsumer_ptr push_consumer, - const RtecEventChannelAdmin::ConsumerQOS &qos, - CORBA::Environment &TAO_IN_ENV) -{ - if (this->connected ()) - TAO_THROW (RtecEventChannelAdmin::AlreadyConnected()); - - this->push_consumer_ = - RtecEventComm::PushConsumer::_duplicate(push_consumer); - // @@ TODO Find out why are two duplicates needed... - RtecEventComm::PushConsumer::_duplicate(push_consumer); - - //ACE_DEBUG ((LM_DEBUG, "EC (%t) connect_push_consumer QOS is ")); - //ACE_ConsumerQOS_Factory::debug (qos); - - // Copy by value. - this->qos_ = qos; - - // ACE_ConsumerQOS_Factory::debug (qos_); - - this->consumer_module_->connected (this, TAO_IN_ENV); -} - -void -ACE_Push_Consumer_Proxy::disconnect_push_supplier (CORBA::Environment &TAO_IN_ENV) -{ - ACE_TIMEPROBE_PRINT; - this->push_consumer_ = RtecEventComm::PushConsumer::_nil (); - this->consumer_module_->disconnecting (this, TAO_IN_ENV); -} - -void -ACE_Push_Consumer_Proxy::suspend_connection (CORBA::Environment &) -{ - correlation_.suspend (); -} - -void -ACE_Push_Consumer_Proxy::resume_connection (CORBA::Environment &) -{ - correlation_.resume (); -} - -void -ACE_Push_Consumer_Proxy::shutdown (void) -{ - TAO_TRY - { - this->push_consumer_->disconnect_push_consumer (TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - ACE_ERROR ((LM_ERROR, "ACE_Push_Consumer_Proxy::shutdown failed.\n")); - } - TAO_ENDTRY; -} - -// ************************************************************ - -ACE_EventChannel::ACE_EventChannel (CORBA::Boolean activate_threads, - u_long type, - TAO_Module_Factory* factory) - : rtu_manager_ (0), - type_ (type), - state_ (INITIAL_STATE), - destroyed_ (0), - handle_generator_ (0), - own_factory_ (0), - module_factory_ (factory) -{ - if (this->module_factory_ == 0) - { - this->own_factory_ = 1; - ACE_NEW (this->module_factory_, TAO_Default_Module_Factory); - } - - consumer_module_ = - this->module_factory_->create_consumer_module (this); - - this->timer_module_ = - this->module_factory_->create_timer_module (this); - - this->dispatching_module_ = - this->module_factory_->create_dispatching_module(this); - - this->correlation_module_ = - this->module_factory_->create_correlation_module (this); - this->subscription_module_ = - this->module_factory_->create_subscription_module (this); - this->supplier_module_ = - this->module_factory_->create_supplier_module (this); - - consumer_module_->open (dispatching_module_); - dispatching_module_->open (consumer_module_, correlation_module_); - correlation_module_->open (dispatching_module_, subscription_module_); - subscription_module_->open (correlation_module_, supplier_module_); - supplier_module_->open (subscription_module_); - - if (activate_threads) - this->activate (); -} - -ACE_EventChannel::~ACE_EventChannel (void) -{ - ACE_DEBUG ((LM_DEBUG, - "EC (%t) ACE_EventChannel deleting all modules.\n")); - - // @@ This should go away, it is too late to raise a CORBA - // exception, at this point we should only be cleaning up memory, - // not sending messages. - TAO_TRY - { - this->destroy (TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_EventChannel::~ACE_EventChannel")); - } - TAO_ENDTRY; - - this->cleanup_observers (); - - this->timer_module_->shutdown (); - this->dispatching_module_->shutdown (); - - this->module_factory_->destroy_timer_module (this->timer_module_); - this->module_factory_->destroy_supplier_module (this->supplier_module_); - this->module_factory_->destroy_subscription_module (this->subscription_module_); - this->module_factory_->destroy_correlation_module (this->correlation_module_); - this->module_factory_->destroy_dispatching_module(this->dispatching_module_); - this->module_factory_->destroy_consumer_module (this->consumer_module_); - - if (this->own_factory_) - delete this->module_factory_; -} - -void -ACE_EventChannel::destroy (CORBA::Environment &) -{ - TAO_ORB_Core_instance ()->orb ()->shutdown (); - - { - ACE_GUARD (ACE_ES_MUTEX, ace_mon, this->lock_); - - if (this->destroyed_ != 0) - return; - - this->destroyed_ = 1; - ACE_DEBUG ((LM_DEBUG, "EC (%t) Event Channel shutting down.\n")); - - } - this->cleanup_observers (); - - // Send a shutdown message through the modules. - this->supplier_module_->shutdown (); - -#if 0 - // Flush all messages in the channel. - Shutdown_Channel *sc = new Shutdown_Channel (this); - if (sc == 0) - TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); - - // Create a wrapper around the dispatch request. - Flush_Queue_ACT *act = new Flush_Queue_ACT (sc, dispatching_module_); - if (act == 0) - TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); - - // Set a 100ns timer. - if (this->timer_module ()->schedule_timer (0, // no rt-info - act, - ACE_Scheduler_MIN_PREEMPTION_PRIORITY, - 100, // 10 usec delta - 0) == -1) // no interval - { - ACE_ERROR ((LM_ERROR, "%p queue_request failed.\n", "ACE_ES_Consumer_Module")); - delete sc; - delete act; - } -#endif -} - -void -ACE_EventChannel::activate (void) -{ - this->dispatching_module_->activate (THREADS_PER_DISPATCH_QUEUE); - this->timer_module_->activate (); -} - -void -ACE_EventChannel::shutdown (void) -{ - this->cleanup_observers (); - - this->timer_module_->shutdown (); - this->dispatching_module_->shutdown (); -} - -void -ACE_EventChannel::report_connect (u_long event) -{ - ACE_ES_GUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - ACE_ERROR ((LM_ERROR, "ACE_EventChannel::report_connect")); - - this->report_connect_i (event); -} - -void -ACE_EventChannel::report_connect_i (u_long event) -{ - ACE_CLR_BITS (state_, event); -} - -void -ACE_EventChannel::report_disconnect (u_long event) -{ - // No need to gtrab the lock is already take by our callers. - ACE_ES_GUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - ACE_ERROR ((LM_ERROR, "ACE_EventChannel::report_disconnect")); - - this->report_disconnect (event); -} - -void -ACE_EventChannel::report_disconnect_i (u_long event) -{ - ACE_SET_BITS (state_, event); - if (state_ == SHUTDOWN) - ACE_DEBUG ((LM_DEBUG, - "EC (%t) Event Channel has no consumers or suppliers.\n")); -} - -void -ACE_EventChannel::add_gateway (TAO_EC_Gateway* gw, - CORBA::Environment& TAO_IN_ENV) -{ - RtecEventChannelAdmin::Observer_var observer = gw->_this (TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - - gw->observer_handle (this->append_observer (observer.in (), TAO_IN_ENV)); -} - -void -ACE_EventChannel::del_gateway (TAO_EC_Gateway* gw, - CORBA::Environment& TAO_IN_ENV) -{ - this->remove_observer (gw->observer_handle (), TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - - gw->observer_handle (0); -} - -void -ACE_EventChannel::update_consumer_gwys (CORBA::Environment& TAO_IN_ENV) -{ - Observer_Map observers; - { - TAO_GUARD_THROW (ACE_ES_MUTEX, ace_mon, this->lock_, TAO_IN_ENV, - RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - if (this->observers_.current_size () == 0 - || this->state_ == ACE_EventChannel::SHUTDOWN) - return; - - observers.open (this->observers_.current_size ()); - for (Observer_Map_Iterator i = this->observers_.begin (); - i != this->observers_.end (); - ++i) - { - observers.bind ((*i).ext_id_, (*i).int_id_); - } - } - - // ACE_DEBUG ((LM_DEBUG, - // "EC (%t) Event_Channel::update_consumer_gwys\n")); - - RtecEventChannelAdmin::ConsumerQOS c_qos; - this->consumer_module_->fill_qos (c_qos); - for (Observer_Map_Iterator i = observers.begin (); - i != observers.end (); - ++i) - { - (*i).int_id_.observer->update_consumer (c_qos, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - } -} - -void -ACE_EventChannel::update_supplier_gwys (CORBA::Environment& TAO_IN_ENV) -{ - Observer_Map observers; - { - TAO_GUARD_THROW (ACE_ES_MUTEX, ace_mon, this->lock_, TAO_IN_ENV, - RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - if (this->observers_.current_size () == 0 - || this->state_ == ACE_EventChannel::SHUTDOWN) - return; - - observers.open (this->observers_.current_size ()); - for (Observer_Map_Iterator i = this->observers_.begin (); - i != this->observers_.end (); - ++i) - { - observers.bind ((*i).ext_id_, (*i).int_id_); - } - } - - // ACE_DEBUG ((LM_DEBUG, - // "EC (%t) Event_Channel::update_supplier_gwys\n")); - - RtecEventChannelAdmin::SupplierQOS s_qos; - this->supplier_module_->fill_qos (s_qos); - for (Observer_Map_Iterator i = observers.begin (); - i != observers.end (); - ++i) - { - (*i).int_id_.observer->update_supplier (s_qos, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - } -} - -RtecEventChannelAdmin::Observer_Handle -ACE_EventChannel::append_observer (RtecEventChannelAdmin::Observer_ptr obs, - CORBA::Environment &TAO_IN_ENV) - TAO_THROW_SPEC ((CORBA::SystemException, - RtecEventChannel::EventChannel::SYNCHRONIZATION_ERROR)) -{ - TAO_GUARD_THROW_RETURN (ACE_ES_MUTEX, ace_mon, this->lock_, 0, TAO_IN_ENV, - RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - this->handle_generator_++; - Observer_Entry entry (this->handle_generator_, - RtecEventChannelAdmin::Observer::_duplicate (obs)); - - if (this->observers_.bind (entry.handle, entry) == -1) - TAO_THROW_ENV_RETURN (RtecEventChannelAdmin::EventChannel::CANT_APPEND_OBSERVER(), - TAO_IN_ENV, 0); - - RtecEventChannelAdmin::ConsumerQOS c_qos; - this->consumer_module_->fill_qos (c_qos); - obs->update_consumer (c_qos, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN (TAO_IN_ENV, 0); - - RtecEventChannelAdmin::SupplierQOS s_qos; - this->supplier_module_->fill_qos (s_qos); - obs->update_supplier (s_qos, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN (TAO_IN_ENV, 0); - - return entry.handle; -} - -void -ACE_EventChannel::remove_observer (RtecEventChannelAdmin::Observer_Handle h, - CORBA::Environment &TAO_IN_ENV) -{ - TAO_GUARD_THROW (ACE_ES_MUTEX, ace_mon, this->lock_, TAO_IN_ENV, - RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - if (this->observers_.unbind (h) == -1) - TAO_THROW_ENV - (RtecEventChannelAdmin::EventChannel::CANT_REMOVE_OBSERVER(), TAO_IN_ENV); -} - -void -ACE_EventChannel::cleanup_observers (void) -{ - ACE_GUARD (ACE_ES_MUTEX, ace_mon, this->lock_); - - // @@ TODO report back any errors here... - this->observers_.close (); -} - - -// **************************************************************** - -ACE_EventChannel::Observer_Entry::Observer_Entry (void) - : handle (0) -{ -} - -ACE_EventChannel::Observer_Entry::Observer_Entry (RtecEventChannelAdmin::Observer_Handle h, - RtecEventChannelAdmin::Observer_ptr o) - : handle (h), - observer (o) -{ -} - - -// **************************************************************** - -ACE_ES_Disjunction_Group::~ACE_ES_Disjunction_Group (void) -{ -} - -ACE_ES_Conjunction_Group::~ACE_ES_Conjunction_Group (void) -{ -} - -// ************************************************************ - -ACE_ES_Subscription_Info::~ACE_ES_Subscription_Info (void) -{ - Subscriber_Map_Iterator iter (type_subscribers_); - - // Delete all type collections. - for (Subscriber_Map_Entry *temp = 0; - iter.next (temp) != 0; - iter.advance ()) - { - delete temp->int_id_; - } -} - -/* -void -ACE_ES_Subscription_Info::Type_Subscribers::operator= -(const ACE_ES_Subscription_Info::Type_Subscribers &rhs) -{ - ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (rhs.subscribers_); - - for (ACE_ES_Consumer_Rep **consumer = 0; - iter.next (consumer) != 0; - iter.advance ()) - { - if (subscribers_.insert (consumer) != 0) - ACE_ERROR ((LM_ERROR, "%p insert failed.\n", - "ACE_ES_Subscription_Info::Type_Subscribers::operator=")); - } - - // Pointer copy. - dependency_info_ = rhs.dependency_info_; -} -*/ - -// Remove <consumer> from the consumer set in <type_map> set -// corresponding to <type>. -int -ACE_ES_Subscription_Info::remove (Subscriber_Map &type_map, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type) -{ - Type_Subscribers *subscribers; - - // Find the type set within the type collection. - if (type_map.find (type, subscribers) == -1) - { - ACE_DEBUG ((LM_DEBUG, - "EC (%t) Info::remove - not found %d\n", type)); - // type_map does not contain the type. - return -1; - } - - // Remove the consumer from the type set. - if (subscribers->consumers_.remove (consumer) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p remove failed.\n", - "ACE_ES_Subscriber_Info::remove"), -1); - // @@ Should probably remove the supplier from the consumers caller - // list. - - // @@ Should we release here? consumer->_release (); - -#if 0 - // If the set is empty, remove it from the type collection. - // NOT!!!! In some cases the map is initialized to the types that a - // certain supplier export; removing an entry from the map renders - // that supplier unable to send that event type. - // Before changing this ask me (coryan). - if (subscribers->consumers_.size () == 0) - { - Type_Subscribers *removed_subscribers; - if (type_map.unbind (type, removed_subscribers) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p unbind failed.\n", - "ACE_ES_Subscriber_Info::remove"), -1); - - // Sanity check. - if (removed_subscribers != subscribers) - ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Subscriber_Info::remove: " - "removed wrong set!\n"), -1); - - // Free up the set removed. - delete removed_subscribers; - } -#endif /* 0 */ - - return 0; -} - - -int -ACE_ES_Subscription_Info::remove (SourceID_Map &source_subscribers, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID sid) -{ - Subscriber_Set *subscribers; - - // Find the subscribers of <sid>. - if (source_subscribers.find (sid, subscribers) == -1) - // does not contain the <sid>. - return -1; - - // Remove the consumer from the subscriber set. - if (subscribers->remove (consumer) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p remove failed.\n", - "ACE_ES_Subscriber_Info::remove"), -1); - - // @@ Should we release here? consumer->_release (); - - // @@ Should probably remove the supplier from the consumers caller - // list. - -#if 0 - // If the set is empty, remove it from the type collection. - // NOT!!!! In some cases the map is initialized to the types that a - // certain supplier export; removing an entry from the map renders - // that supplier unable to send that event type. - // Before changing this ask me (coryan). - if (subscribers->size () == 0) - { - Subscriber_Set *removed_subscribers; - if (source_subscribers.unbind (sid, removed_subscribers) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p unbind failed.\n", - "ACE_ES_Subscriber_Info::remove"), -1); - - // Sanity check. - if (removed_subscribers != subscribers) - ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Subscriber_Info::remove: " - "removed wrong set!\n"), -1); - - // Free up the set removed. - delete removed_subscribers; - } -#endif /* 0 */ - - return 0; -} - - -void -ACE_ES_Subscription_Info::append_subscribers (Subscriber_Set &dest, - Subscriber_Set &src) -{ - Subscriber_Set_Iterator src_iter (src); - - // Iterate through the source set. Add each source proxy to the - // destination set. - for (ACE_ES_Consumer_Rep **proxy = 0; - src_iter.next (proxy) != 0; - src_iter.advance ()) - { - if (dest.insert (*proxy) == -1) - ACE_ERROR ((LM_ERROR, "%p: insert failed.\n", "append_subscribers")); - } -} - -int -ACE_ES_Subscription_Info::insert_or_allocate (SourceID_Map &sid_map, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID sid) -{ - Subscriber_Set *subscribers; - - if (sid_map.find (sid, subscribers) == -1) - { - // If the correct type set does not exist, make one with a null - // dependency info (since there is no supplier of this event). - subscribers = new Subscriber_Set; - - if (sid_map.bind (sid, subscribers) == -1) - { - ACE_ERROR ((LM_ERROR, "%p bind failed.\n", - "ACE_ES_Subscription_Info::insert_or_allocate")); - delete subscribers; - return -1; - } - } - - // 0 and 1 are success for insert. - if (subscribers->insert (consumer) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p insert failed.\n", - "ACE_ES_Subscription_Info::insert_or_allocate"), - -1); - - consumer->_duplicate (); - return 0; -} - -int -ACE_ES_Subscription_Info::insert_or_allocate (Subscriber_Map &type_map, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type) -{ - Type_Subscribers *subscribers; - - if (type_map.find (type, subscribers) == -1) - { - // If the correct type set does not exist, make one with a null - // dependency info (since there is no supplier of this event). - subscribers = new Type_Subscribers (0); - - if (type_map.bind (type, subscribers) == -1) - { - ACE_ERROR ((LM_ERROR, "%p bind failed.\n", - "ACE_ES_Subscription_Info::insert_or_allocate")); - delete subscribers; - return -1; - } - } - - if (subscribers->consumers_.insert (consumer) == -1) - { - ACE_ERROR ((LM_ERROR, "%p insert failed.\n", - "ACE_ES_Subscription_Info::insert_or_allocate")); - } - - consumer->_duplicate (); - return 0; -} - -int -ACE_ES_Subscription_Info::insert_or_fail (Subscriber_Map &type_map, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type, - RtecScheduler::Dependency_Info *&dependency) -{ - Type_Subscribers *subscribers; - - // Get the subscriber set for <type>. - if (type_map.find (type, subscribers) == -1) - return -1; - - // Pass back the description of the method generating <type>. - dependency = subscribers->dependency_info_; - - // Insert the new consumer into the subscriber set. - if (subscribers->consumers_.insert (consumer) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p insert failed.\n", - "ACE_ES_Subscription_Info::insert_or_fail"), - -1); - } - - consumer->_duplicate (); - return 0; -} - -// ************************************************************ - -ACE_ES_Consumer_Module::ACE_ES_Consumer_Module (ACE_EventChannel* channel) - : lock_ (), - all_consumers_ (), - channel_ (channel), - down_ (0) -{ -} - -void -ACE_ES_Consumer_Module::open (ACE_ES_Dispatching_Module *down) -{ - down_ = down; -} - -void -ACE_ES_Consumer_Module::connected (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &TAO_IN_ENV) -{ - // ACE_DEBUG ((LM_DEBUG, - // "EC (%t) Consumer_Module - connecting consumer %x\n", - // consumer)); - - this->channel_->report_connect (ACE_EventChannel::CONSUMER); - this->down_->connected (consumer, TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return; - if (!consumer->qos ().is_gateway) - this->channel_->update_consumer_gwys (TAO_IN_ENV); -} - -void -ACE_ES_Consumer_Module::shutdown_request (ACE_ES_Dispatch_Request *request) -{ - TAO_TRY - { - Shutdown_Consumer *sc = (Shutdown_Consumer *) request; - - // Tell everyone else that the consumer is disconnected. This means - // that *nothing* is left in the system for the consumer, so - // everyone can free up any resources. - this->down_->disconnected (sc->consumer ()); - - // ACE_DEBUG ((LM_DEBUG, - // "EC (%t) Consumer_Module - remove consumer %x\n", - // sc->consumer ())); - - CORBA::Boolean dont_update = sc->consumer ()->qos ().is_gateway; - - // Deactivate the consumer proxy - PortableServer::POA_var poa = - sc->consumer ()->_default_POA (TAO_TRY_ENV); - TAO_CHECK_ENV; - PortableServer::ObjectId_var id = - poa->servant_to_id (sc->consumer (), TAO_TRY_ENV); - TAO_CHECK_ENV; - poa->deactivate_object (id.in (), TAO_TRY_ENV); - TAO_CHECK_ENV; - - // Delete the consumer proxy. - delete sc->consumer (); - - if (!dont_update) - this->channel_->update_consumer_gwys (TAO_TRY_ENV); - TAO_CHECK_ENV; - - ACE_ES_GUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - return; - - // Tell the channel that we may need to shut down. - if (all_consumers_.size () <= 0) - { - // ACE_DEBUG ((LM_DEBUG, - // "EC (%t) No more consumers connected.\n")); - channel_->report_disconnect_i (ACE_EventChannel::CONSUMER); - } - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception ("Consumer_Module::shutdown_request"); - } - TAO_ENDTRY; -} - -void -ACE_ES_Consumer_Module::shutdown (void) -{ - Consumers copy; - - { - ACE_ES_GUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - goto DONE; - - if (all_consumers_.size () == 0) - goto DONE; - - // Make a copy so that the consumers can disconnect without the - // lock being held. - copy = all_consumers_; - } - - // This scope is just to thwart the compiler. It was complaining - // about the above goto's bypassing variable initializations. Yadda - // yadda. - { - Consumer_Iterator iter (copy); - - CORBA::Environment env; - - for (ACE_Push_Consumer_Proxy **proxy = 0; - iter.next (proxy) != 0; - iter.advance ()) - { - (*proxy)->shutdown (); - // @@ Cannnot use CORBA::release (*proxy), since it is a - // servant. - // Deactivate the proxy... - PortableServer::POA_var poa = - (*proxy)->_default_POA (env); - TAO_CHECK_ENV_RETURN_VOID (env); - PortableServer::ObjectId_var id = - poa->servant_to_id (*proxy, env); - TAO_CHECK_ENV_RETURN_VOID (env); - poa->deactivate_object (id.in (), env); - TAO_CHECK_ENV_RETURN_VOID (env); - - // Remove the consumer from our list. - { - ACE_ES_GUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - ACE_ERROR ((LM_ERROR, "%p Failed to acquire lock.\n", "ACE_ES_Consumer_Module::shutdown")); - - if (all_consumers_.remove (*proxy) == -1) - ACE_ERROR ((LM_ERROR, "%p Failed to remove consumer.\n", "ACE_ES_Consumer_Module::shutdown")); - } - - delete *proxy; - } - } - -DONE: - channel_->shutdown (); -} - -void -ACE_ES_Consumer_Module::disconnecting (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &TAO_IN_ENV) -{ - { - ACE_ES_GUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - TAO_THROW (RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - if (all_consumers_.remove (consumer) == -1) - TAO_THROW (RtecEventChannelAdmin::EventChannel::SUBSCRIPTION_ERROR()); - } - - // Tell everyone else that the consumer is disconnecting. This - // allows them to remove the consumer from any subscription lists - // etc. However, messages may still be queued in the ReactorEx or - // in the Dispatching Module for this consumer, so no queues or - // proxies can be deleted just yet. - down_->disconnecting (consumer, TAO_IN_ENV); - - // Send a shutdown message through the system. When this is - // dispatched, the consumer proxy will be deleted. <request> is - // queued in the Priority_Timer at <priority> level. It will be - // scheduled for dispatching in 1 nanosecond. This gives components - // a hook into the first queueing point in the channel. - - // Create a shutdown message. When this is dispatched, it will - // delete the proxy. - Shutdown_Consumer *sc = new Shutdown_Consumer (this, consumer); - if (sc == 0) - TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); - - // Create a wrapper around the dispatch request. - Flush_Queue_ACT *act = - new Flush_Queue_ACT (sc, channel_->dispatching_module_); - if (act == 0) - TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); - - // ACE_DEBUG ((LM_DEBUG, "EC (%t) initiating consumer disconnect.\n")); - - // Set a 100ns timer. - TimeBase::TimeT ns100; - ORBSVCS_Time::hrtime_to_TimeT (ns100, 100); - if (this->channel_->schedule_timer (0, // no rt_info - act, - ACE_Scheduler_MIN_PREEMPTION_PRIORITY, - ns100, - ORBSVCS_Time::zero) == -1) - { - ACE_ERROR ((LM_ERROR, "%p queue_request failed.\n", "ACE_ES_Consumer_Module")); - delete sc; - delete act; - } -} - -// This method executes in the same thread of control that will hand -// the event set to the consumer (or it's proxy). A network proxy may -// copy the event set to the network buffer. An active client may -// copy the event set to be queued. Or a same address-space consumer -// can read the set we allocated off the stack. -void -ACE_ES_Consumer_Module::push (const ACE_ES_Dispatch_Request *request, - CORBA::Environment &TAO_IN_ENV) -{ - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Consumer_Module::push\n")); - - ACE_FUNCTION_TIMEPROBE (TAO_EVENT_CHANNEL_ENTER_ES_CONSUMER_MODULE_PUSH); - // We'll create a temporary event set with the size of the incoming - // request. - RtecEventComm::EventSet event_set; - request->make_copy (event_set); - - // Forward the event set. - ACE_hrtime_t ec_send = ACE_OS::gethrtime (); - for (CORBA::ULong i = 0; i < event_set.length (); ++i) - { - RtecEventComm::Event& ev = event_set[i]; - ORBSVCS_Time::hrtime_to_TimeT (ev.header.ec_send_time, ec_send); - } - request->consumer ()->push (event_set, TAO_IN_ENV); -} - -RtecEventChannelAdmin::ProxyPushSupplier_ptr -ACE_ES_Consumer_Module::obtain_push_supplier (CORBA::Environment &TAO_IN_ENV) -{ - auto_ptr<ACE_Push_Consumer_Proxy> new_consumer (new ACE_Push_Consumer_Proxy (this)); - - // Get a new supplier proxy object. - if (new_consumer.get () == 0) - { - ACE_ERROR ((LM_ERROR, "ACE_EventChannel" - "::obtain_push_supplier failed.\n")); - TAO_THROW_RETURN (CORBA::NO_MEMORY (CORBA::COMPLETED_NO), 0); - } - - { - TAO_GUARD_THROW_RETURN (ACE_ES_MUTEX, ace_mon, this->lock_, 0, TAO_IN_ENV, - RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - if (all_consumers_.insert (new_consumer.get ()) == -1) - ACE_ERROR ((LM_ERROR, "ACE_ES_Consumer_Module insert failed.\n")); - } - - // Return the CORBA object reference to the new supplier proxy, - // there is no need to hold a pointer, it is now help in the map... - return new_consumer.release ()->get_ref (TAO_IN_ENV); -} - -void -ACE_ES_Consumer_Module::fill_qos (RtecEventChannelAdmin::ConsumerQOS& c_qos) -{ - ACE_GUARD (ACE_ES_MUTEX, ace_mon, this->lock_); - - c_qos.is_gateway = 1; - - int count = 0; - { - for (Consumer_Iterator i = this->all_consumers_.begin (); - i != this->all_consumers_.end (); - ++i) - { - ACE_Push_Consumer_Proxy *c = *i; - - if (c->qos ().is_gateway) - continue; - - count += c->qos ().dependencies.length (); - } - } - - RtecEventChannelAdmin::DependencySet& dep = c_qos.dependencies; - - dep.length (count + 1); - - CORBA::ULong cc = 0; - dep[cc].event.header.type = ACE_ES_DISJUNCTION_DESIGNATOR; - dep[cc].event.header.source = 0; - dep[cc].event.header.creation_time = ORBSVCS_Time::zero; - dep[cc].rt_info = 0; - cc++; - - for (Consumer_Iterator i = this->all_consumers_.begin (); - i != this->all_consumers_.end (); - ++i) - { - ACE_Push_Consumer_Proxy *c = *i; - - // ACE_DEBUG ((LM_DEBUG, "EC (%t) fill_qos ")); - // ACE_ConsumerQOS_Factory::debug (c->qos ()); - - if (c->qos ().is_gateway) - continue; - - CORBA::ULong count = c->qos ().dependencies.length (); - for (CORBA::ULong j = 0; j < count; ++j) - { - RtecEventComm::Event& event = - c->qos ().dependencies[j].event; - - RtecEventComm::EventType type = event.header.type; - - // Only type and source dependencies are relevant, notice - // that we turn conjunctions into disjunctions because - // correlations could be satisfied by events coming from - // several remote ECs. - // Notice that <0> is a *not* skipped, otherwise source only - // filtering does not work. - if (1 <= type && type <= ACE_ES_EVENT_UNDEFINED) - continue; - - // If the dependency is already there we don't add it. - CORBA::ULong k; - for (k = 0; k < cc; ++k) - { - if (dep[k].event.header.type == event.header.type - && dep[k].event.header.source == event.header.source) - break; - } - if (k == cc) - { - dep[cc].event.header.type = event.header.type; - dep[cc].event.header.source = event.header.source; - dep[cc].event.header.creation_time = ORBSVCS_Time::zero; - // The RT_Info is filled up later. - dep[cc].rt_info = 0; - cc++; - } - } - } - dep.length (cc); - - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Consumer::fill_qos - %d\n", cc)); -} - -// ************************************************************ - -ACE_ES_Correlation_Module::ACE_ES_Correlation_Module (ACE_EventChannel *channel) - : channel_ (channel), - up_ (0), - subscription_module_ (0) -{ -} - -void -ACE_ES_Correlation_Module::open (ACE_ES_Dispatching_Module *up, - ACE_ES_Subscription_Module *sm) -{ - up_ = up; - subscription_module_ = sm; -} - -void -ACE_ES_Correlation_Module::connected (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &TAO_IN_ENV) -{ - // Initialize the consumer correlation filter. - if (consumer->correlation ().connected (consumer, this) == -1) - TAO_THROW (RtecEventChannelAdmin::EventChannel::CORRELATION_ERROR()); -} - -void -ACE_ES_Correlation_Module::disconnecting (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &) -{ - if (consumer->correlation ().disconnecting () == -1) - ACE_ERROR ((LM_ERROR, - "ACE_ES_Correlation_Module::disconnecting failed.\n")); -} - -int -ACE_ES_Correlation_Module::subscribe (ACE_ES_Consumer_Rep *consumer) -{ - return subscription_module_->subscribe (consumer); -} - -int -ACE_ES_Correlation_Module::unsubscribe (ACE_ES_Consumer_Rep *cr) -{ - return subscription_module_->unsubscribe (cr); -} - -void -ACE_ES_Correlation_Module::push (ACE_ES_Consumer_Rep *consumer, - const TAO_EC_Event& event, - CORBA::Environment &TAO_IN_ENV) -{ - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Correlation_Module::push\n")); - - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_ENTER_ACE_ES_CORRELATION_MODULE_PUSH); - ACE_ES_Dispatch_Request *request = - consumer->correlation ()->push (consumer, event); - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_PUSHED_TO_CORRELATION_MODULE); - - // If request == 0, then the event was queued for later. Otherwise, - // we need to push the event now. - if (request != 0) - up_->push (request, TAO_IN_ENV); - - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_PUSH_SOURCE_TYPE_DISPATCH_MODULE_ENQUEUING); -} - -// Must check consumer->qos ().use_timeout () before calling this. -// This method is supposed properly schedule a timer with respect to -// the consumer's priority AND the correlation that should receive the -// timeout event. -int -ACE_ES_Correlation_Module::schedule_timeout (ACE_ES_Consumer_Rep_Timeout *consumer) -{ - RtecEventComm::Time &interval = - consumer->dependency ()->event.header.creation_time; - RtecEventComm::Time &delay = - consumer->dependency ()->event.header.creation_time; - - // Store the preemption priority so we can cancel the correct timer. - // The priority values may change during the process lifetime (e.g., - // after the scheduler has been run). - consumer->preemption_priority (::IntervalToPriority (interval)); - - // ACE_DEBUG ((LM_DEBUG, - // "EC (%t) Adding timer at preemption %d, rate = (%d,%d)\n", - // consumer->preemption_priority (), - // interval.low, interval.high)); - - // Register the timer. - int id = - this->channel_->schedule_timer (consumer->dependency ()->rt_info, - consumer, - consumer->preemption_priority (), - delay, interval); - - // Store the timer id for canceling. - consumer->timer_id (id); - - if (id == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p schedule timer failed.\n", - "ACE_ES_Correlation_Module::schedule_timeout"), -1); - - return 0; -} - -// Must check consumer->qos ().timeout_ before calling this. -int -ACE_ES_Correlation_Module::cancel_timeout (ACE_ES_Consumer_Rep_Timeout *consumer) -{ - // Cancel the timer from the Priority Timer. - ACE_Command_Base *act; - this->channel_->cancel_timer (consumer->preemption_priority (), - consumer->timer_id (), - act); - - ACE_ASSERT (consumer == act); - - // Free up the Timer ACT. - // delete act; - - return 0; -} - - -int -ACE_ES_Correlation_Module::reschedule_timeout (ACE_ES_Consumer_Rep_Timeout *consumer) -{ - if (this->cancel_timeout (consumer) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "ACE_ES_Disjunction_Group::reschedule_deadline"), -1); - else - { - RtecEventComm::Time &interval = - consumer->dependency ()->event.header.creation_time; - RtecEventComm::Time &delay = - consumer->dependency ()->event.header.creation_time; - - // Store the preemption priority so we can cancel the correct timer. - // The priority values may change during the process lifetime (e.g., - // after the scheduler has been run). - consumer->preemption_priority (::IntervalToPriority (interval)); - - // Register the timer. - int id = - this->channel_->schedule_timer (0, // Do not pass an RT_Info. - consumer, - consumer->preemption_priority (), - delay, interval); - - // Store the timer id for canceling. - consumer->timer_id (id); - - if (id == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p schedule timer failed.\n", - "ACE_ES_Correlation_Module::reschedule_timeout"), -1); - - return 0; - } -} - -void -ACE_ES_Correlation_Module::shutdown (void) -{ - // Perhaps this should call disconnecting on all the consumers? - // We'll opt to just forward this message for now. - up_->shutdown (); -} - -// ************************************************************ - -ACE_ES_Consumer_Correlation::ACE_ES_Consumer_Correlation (void) : - correlation_module_ (0), - type_id_index_ (0), - channel_ (0), - qos_ (), - pending_events_ (0), - lock_ (), - consumer_ (0), - pending_flags_ (0), - consumer_reps_ (0), - n_consumer_reps_ (0), - timer_reps_ (0), - n_timer_reps_ (0), - conjunction_groups_ (0), - n_conjunction_groups_ (0), - disjunction_groups_ (0), - n_disjunction_groups_ (0), - connected_ (0) -{ -} - -ACE_ES_Consumer_Correlation::~ACE_ES_Consumer_Correlation (void) -{ - delete [] timer_reps_; - for (int i = 0; i < this->n_consumer_reps_; ++i) - { - ACE_ES_Consumer_Rep *r = this->consumer_reps_[i]; - if (r != 0) - { - this->correlation_module_->unsubscribe (r); - r->_release (); - } - } - delete [] consumer_reps_; - delete [] conjunction_groups_; - delete [] disjunction_groups_; - delete [] pending_events_; -} - -void -ACE_ES_Consumer_Correlation::disconnect_push_supplier (CORBA::Environment &TAO_IN_ENV) -{ - connected_ = 0; -} - -int -ACE_ES_Consumer_Correlation::allocate_correlation_resources (ACE_ES_Dependency_Iterator &iter) -{ - n_conjunction_groups_ = iter.n_conjunctions (); - if (n_conjunction_groups_ > 0) - { - conjunction_groups_ = new ACE_ES_Conjunction_Group[n_conjunction_groups_]; - if (conjunction_groups_ == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Consumer_Correlation::" - "allocate_correlation_resources"), -1); - for (int n=0; n < n_conjunction_groups_; n++) - conjunction_groups_[n].set_correlation_module (correlation_module_); - } - - n_disjunction_groups_ = iter.n_disjunctions (); - if (n_disjunction_groups_ > 0) - { - disjunction_groups_ = new ACE_ES_Disjunction_Group[n_disjunction_groups_]; - if (disjunction_groups_ == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Consumer_Correlation::" - "allocate_correlation_resources"), -1); - for (int n=0; n < n_disjunction_groups_; n++) - disjunction_groups_[n].set_correlation_module (correlation_module_); - } - - n_consumer_reps_ = iter.n_events (); - if (n_consumer_reps_ > 0) - { - // This allocates more than is needed if there are repeats: - // (A+B)|(B+C). We allocate these individually so that they can - // be deleted individually. - - typedef ACE_ES_Consumer_Rep *reparray; - consumer_reps_ = new reparray[n_consumer_reps_]; - - for (int cr = 0; cr < n_consumer_reps_; cr++) - { - consumer_reps_[cr] = new ACE_ES_Consumer_Rep; - if (consumer_reps_[cr] == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Consumer_Correlation::" - "allocate_correlation_resources"), -1); - } - } - - n_timer_reps_ = iter.n_timeouts (); - if (n_timer_reps_ > 0) - { - timer_reps_ = new ACE_ES_Consumer_Rep_Timeout[n_timer_reps_]; - if (timer_reps_ == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Consumer_Correlation::" - "allocate_correlation_resources"), -1); - } - - // This allocates more than is needed. - // @@ throw an exception. - ACE_NEW_RETURN (this->pending_events_, - TAO_EC_Event_Array[n_consumer_reps_ + n_timer_reps_], - -1); - - return 0; -} - -// We don't need synchronization until after we've been connected and -// subscribed to events. -int -ACE_ES_Consumer_Correlation::connected (ACE_Push_Consumer_Proxy *consumer, - ACE_ES_Correlation_Module *correlation_module) -{ - correlation_module_ = correlation_module; - consumer_ = consumer; - - // for (CORBA_Types::ULong index=0; index < consumer->qos ().dependencies_.length (); index++) - // consumer->qos ().dependencies_[index].event.dump (); - - ACE_ES_Dependency_Iterator iter (consumer->qos ().dependencies); - iter.parse (); - if (this->allocate_correlation_resources (iter) == -1) - return -1; - - - int cgroup_index = -1; - int dgroup_index = -1; - int crep_index = 0; - int trep_index = 0; - RtecEventComm::EventType group_type = 0; - - while (iter.advance_dependency () == 0) - { - // Keep track of how many conjunction and disjunction groups are - // registered. Update the index pointers so that the helper - // functions can update the appropriate group objects. - switch ((*iter).event.header.type) - { - case ACE_ES_CONJUNCTION_DESIGNATOR: - cgroup_index++; - ACE_ASSERT (cgroup_index < n_conjunction_groups_); - group_type = ACE_ES_CONJUNCTION_DESIGNATOR; - continue; - - case ACE_ES_DISJUNCTION_DESIGNATOR: - dgroup_index++; - ACE_ASSERT (dgroup_index < n_disjunction_groups_); - group_type = ACE_ES_DISJUNCTION_DESIGNATOR; - continue; - - case ACE_ES_GLOBAL_DESIGNATOR: - group_type = ACE_ES_GLOBAL_DESIGNATOR; - continue; - - // These Delegate to the appropriate registration method. -#if 0 - // @@ TODO rt_info_ is a handle_t now, does checking against - // 0 still make sense? - // Check for a null rt_info. - if ((*iter).rt_info_ == 0) - { - ACE_ERROR ((LM_ERROR, "Found a ConsumerQOS::dependencies[].rt_info_ == 0.\n")); - continue; - } -#endif /* 0 */ - - case ACE_ES_EVENT_TIMEOUT: - // For backwards compatibility. - case ACE_ES_EVENT_DEADLINE_TIMEOUT: - if (this->register_deadline_timeout (*iter, - group_type, - cgroup_index, - dgroup_index, - trep_index) == -1) - return -1; - break; - - case ACE_ES_EVENT_INTERVAL_TIMEOUT: - if (this->register_interval_timeout (*iter, - group_type, - cgroup_index, - dgroup_index, - trep_index) == -1) - return -1; - break; - - case ACE_ES_EVENT_ACT: - // Store the ACT in the current conjunction or disjunction - // group. - switch (group_type) - { - case ACE_ES_CONJUNCTION_DESIGNATOR: - conjunction_groups_[cgroup_index].set_act ((*iter).event); - break; - case ACE_ES_DISJUNCTION_DESIGNATOR: - disjunction_groups_[cgroup_index].set_act ((*iter).event); - break; - case ACE_ES_GLOBAL_DESIGNATOR: - default: - ACE_ERROR ((LM_ERROR, "Warning: ACTs not implemented for Global.\n")); - } - break; - - default: - // Non-timer event subscription. - if (this->register_event (*iter, - group_type, - cgroup_index, - dgroup_index, - crep_index) == -1) - return -1; - break; - } - } - - // We may not use all of the consumer reps if there are repeats: - // (A+B)|(B+C). Must update n_consumer_reps_ so we don't try to - // unsubscribe a blank rep during disconnect. - if (crep_index < n_consumer_reps_) - n_consumer_reps_ = crep_index; - - return 0; -} - -int -ACE_ES_Consumer_Correlation::register_deadline_timeout (RtecEventChannelAdmin::Dependency &dependency, - RtecEventComm::EventType group_type, - int cgindex, - int dgindex, - int &trep_index) -{ - // new_timeout will be returned as an ACT. When executed, it will - // forward *iter.event_ to the consumer. - ACE_ES_Consumer_Rep_Timeout *new_timeout = &timer_reps_[trep_index++]; - new_timeout->init (this, dependency); - new_timeout->correlation_type (ACE_ES_Consumer_Rep::DEADLINE_TIMEOUT); - // Deadline timers do not need type ids. - - switch (group_type) - { - case ACE_ES_CONJUNCTION_DESIGNATOR: - // Reps keep pointers back to the groups that they're deadlines for. - new_timeout->add_disjunction_group (conjunction_groups_[cgindex]); - // Groups keep references to the deadline timers for rescheduling. - if (conjunction_groups_[cgindex].set_deadline_timeout (new_timeout) == -1) - return -1; - break; - - case ACE_ES_DISJUNCTION_DESIGNATOR: - new_timeout->add_disjunction_group (disjunction_groups_[dgindex]); - if (disjunction_groups_[dgindex].set_deadline_timeout (new_timeout) == -1) - return -1; - break; - - case ACE_ES_GLOBAL_DESIGNATOR: - ACE_ERROR_RETURN ((LM_ERROR, "No global deadline timeouts, yet!\n"), -1); - } - - return 0; -} - -int -ACE_ES_Consumer_Correlation::register_interval_timeout (RtecEventChannelAdmin::Dependency &dependency, - RtecEventComm::EventType group_type, - int cgindex, - int /* dgindex */, - int &trep_index) -{ - // new_timeout will be returned as an ACT. When executed, it will - // forward *iter.event_ to the consumer. - ACE_ES_Consumer_Rep_Timeout *new_timeout = &timer_reps_[trep_index++]; - new_timeout->init (this, dependency); - new_timeout->type_id (this->new_type_id ()); - - switch (group_type) - { - case ACE_ES_CONJUNCTION_DESIGNATOR: - // If it's a conjunction, then we need to perform correlations - // on the timeout. - new_timeout->correlation_type (ACE_ES_Consumer_Rep::CORRELATE); - conjunction_groups_[cgindex].add_type (new_timeout->type_id ()); - break; - - case ACE_ES_DISJUNCTION_DESIGNATOR: - case ACE_ES_GLOBAL_DESIGNATOR: - new_timeout->correlation_type (ACE_ES_Consumer_Rep::NO_CORRELATION); - break; - } - - // Schedule the timeout. - if (correlation_module_->schedule_timeout (new_timeout) == -1) - return -1; - else - return 0; -} - -// Search <creps> for a rep matching <dependency>. If one is not -// found, allocate one. All returned reps should have the appropriate -// type_id set. -ACE_ES_Consumer_Rep * -ACE_ES_Consumer_Correlation::get_consumer_rep (RtecEventChannelAdmin::Dependency &dependency, - int &crep_index) -{ - ACE_ES_Consumer_Rep *rep = 0; - - // Step through all existing consumer reps. - for (int x=0; x < crep_index; x++) - { - RtecEventComm::Event& e = consumer_reps_[x]->dependency ()->event; - // If <dependency> matches any previously subscribed consumer - // reps, we'll reuse it. - if (e.header.type == dependency.event.header.type - && e.header.source == dependency.event.header.source ) - { - rep = consumer_reps_[x]; - break; - } - } - - // Check if we didn't find it. - if (rep == 0) - { - if (crep_index >= n_consumer_reps_) - ACE_ERROR_RETURN ((LM_ERROR, "Too many event registrations.\n"), 0); - // Allocate a new rep and set its type id. - rep = consumer_reps_[crep_index]; - crep_index++; - rep->init (this, dependency); - rep->type_id (this->new_type_id ()); - } - - return rep; -} - -int -ACE_ES_Consumer_Correlation::new_type_id (void) -{ - int type_id = type_id_index_; - if (++type_id_index_ >= ACE_ES_MAX_SUBSCRIPTIONS) - ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_MAX_SUBSCRIPTIONS exceeded.\n"),0); - else - return type_id; -} - -int -ACE_ES_Consumer_Correlation::register_event (RtecEventChannelAdmin::Dependency &dependency, - RtecEventComm::EventType group_type, - int cgindex, - int dgindex, - int &crep_index) -{ - // These are stored in the subscription module data structures. - ACE_ES_Consumer_Rep *consumer_rep = this->get_consumer_rep (dependency, crep_index); - - if (consumer_rep == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Consumer_Correlation::register_event"), -1); - - switch (group_type) - { - case ACE_ES_CONJUNCTION_DESIGNATOR: - // If it's a conjunction, then we need to perform correlations - // on the object. Otherwise, NO_CORRELATION is set by default. - consumer_rep->correlation_type (ACE_ES_Consumer_Rep::CORRELATE); - conjunction_groups_[cgindex].add_type (consumer_rep->type_id ()); - break; - - case ACE_ES_DISJUNCTION_DESIGNATOR: - consumer_rep->add_disjunction_group (disjunction_groups_[dgindex]); - break; - - case ACE_ES_GLOBAL_DESIGNATOR: - ACE_ERROR ((LM_ERROR, "ACE_ES_Consumer_Correlation::register_event: " - "ACE_ES_GLOBAL_DESIGNATOR not implemented.\n")); - break; - } - - // Subscribe the consumer_rep to the suppliers. - if (correlation_module_->subscribe (consumer_rep) == -1) - return -1; - else - return 0; -} - -int -ACE_ES_Consumer_Correlation::disconnecting (void) -{ - // If we were forwarding events, disconnect as a supplier. - if (connected_) - { - CORBA::Environment env; - channel_->disconnect_push_consumer (env); - if (env.exception () != 0) - ACE_ERROR ((LM_ERROR, "ACE_ES_Consumer_Correlation::disconnecting failed.\n")); - } - - for (int j = 0; j < this->n_timer_reps_; ++j) - this->correlation_module_->cancel_timeout (&timer_reps_[j]); - - for (int i = 0; i < this->n_consumer_reps_; ++i) - { - ACE_ES_Consumer_Rep *r = this->consumer_reps_[i]; - if (r != 0) - { - r->disconnect (); - } - } - - return 0; -} - -ACE_ES_Dispatch_Request * -ACE_ES_Consumer_Correlation::push (ACE_ES_Consumer_Rep *cr, - const TAO_EC_Event& event) -{ - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Consumer_Correlation_Module::push\n")); - - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_ACE_ES_CONSUMER_CORRELATION_PUSH_ENTER); - - // Check if this event needs any correlating, or if it should just - // be forwarded real fast-like. - switch (cr->correlation_type ()) - { - case ACE_ES_Consumer_Rep::NO_CORRELATION: - { - // Calls reschedule on all disjunction groups it belongs to. - cr->reschedule_deadlines (); - - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_CONSUMER_CORRELATION_PUSH_DETERMINE_NO_CORR); - ACE_ES_Dispatch_Request *request = - new ACE_ES_Dispatch_Request (consumer_, event, - cr->dependency ()->rt_info); - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_CONSUMER_CORRELATION_PUSH_NO_CORR_ALLOC); - - if (request == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Consumer_Correlation::push"), 0); - - return request; - } - - case ACE_ES_Consumer_Rep::CORRELATE: - return this->correlate (cr, event); - - case ACE_ES_Consumer_Rep::DEADLINE_TIMEOUT: - { - ACE_ES_Dispatch_Request *request = - new ACE_ES_Dispatch_Request (consumer_, - cr->dependency ()->rt_info); - - if (request == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Consumer_Correlation::push"), 0); - - // Add the deadline timeout to the outbox. - request->append_event (event); - - // Add any pending events to the outbox. - cr->top_group ()->add_events (&(request->event_set ()), - pending_events_, pending_flags_); - - return request; - } - - default: - ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Consumer_Correlation::push:" - " unknown correlation type\n"), 0); - } -} - -// @@ If we're just event forwarding, then no pending_events_ need to -// be kept! I'll add this optimization later. -ACE_ES_Dispatch_Request * -ACE_ES_Consumer_Correlation::correlate (ACE_ES_Consumer_Rep *cr, - const TAO_EC_Event &event) -{ - // If the consumer has specified correlation criteria, then we must - // first acquire the mutex. - ACE_ES_GUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Consumer_Correlation::push"), 0); - - int bit = ACE_INT2BIT[cr->type_id ()]; - if (ACE_BIT_DISABLED (this->pending_flags_, bit)) - { - // Add the new event to the pending events. - pending_events_[cr->type_id ()] += event; - // Set the bit corresponding to the arrived event. - // This should be pending_flags_->event_arrived (index); - ACE_SET_BITS (pending_flags_, bit); - } - - ACE_ES_Dispatch_Request *request = 0; - TAO_EC_Event_Array *outbox = 0; - // Since add_events changes pending_flags_, we need to keep this - // for all iterations through the conjunction groups. - u_long freeze_pending_flags = pending_flags_; - - for (int x=0; x < n_conjunction_groups_; x++) - { - if (conjunction_groups_[x].should_forward (freeze_pending_flags)) - { - // If there is a deadline timer for this conjunction group, - // this will reschedule them. - conjunction_groups_[x].reschedule_deadline (); - - // First time in, allocate the new dispatch request. - if (request == 0) - { - request = - new ACE_ES_Dispatch_Request (consumer_, - cr->dependency ()->rt_info); - if (request == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Consumer_Correlation::correlate"), 0); - outbox = &(request->event_set ()); - } - - // Add each of the pending events for this correlation to - // the outgoing dispatch request. If outbox == 0, then - // this will just clear any pending events. - conjunction_groups_[x].add_events (outbox, - pending_events_, - pending_flags_); - } - } - - return request; -} - - -// ************************************************************ - -ACE_ES_Consumer_Rep::~ACE_ES_Consumer_Rep (void) -{ -} - -int -ACE_ES_Consumer_Rep::execute (void* arg) -{ - ACE_ERROR ((LM_ERROR, "Warning! ACE_ES_Consumer_Rep::execute called.\n")); - return -1; -} - -// ************************************************************ - -int -ACE_ES_Consumer_Rep_Timeout::execute (void* arg) -{ - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_CONSUMER_REP_TIMEOUT_EXECUTE); - if (this->receiving_events ()) - { - TAO_TRY - { - ACE_Time_Value tv = ACE_OS::gettimeofday (); - ORBSVCS_Time::Time_Value_to_TimeT (this->timeout_event_.header ().creation_time, tv); - correlation_->correlation_module_->push (this, - this->timeout_event_, - TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCH (CORBA::Exception, ex) - { - ACE_ERROR_RETURN ((LM_ERROR, - "ACE_ES_Consumer_Rep_Timeout::execute: " - "unexpected exception.\n"), -1); - } - TAO_ENDTRY; - } - return 0; -} - -// ************************************************************ - -ACE_ES_Subscription_Module::ACE_ES_Subscription_Module (ACE_EventChannel *channel) - : channel_ (channel), - up_ (0), - down_ (0) -{ -} - -void -ACE_ES_Subscription_Module::open (ACE_ES_Correlation_Module *up, - ACE_ES_Supplier_Module *down) -{ - // Brilliant. - up_ = up; - down_ = down; -} - -ACE_ES_Subscription_Module::~ACE_ES_Subscription_Module (void) -{ -} - -// When a supplier connects, we step through each of its -// publications. For each event type published, we allocate a set in -// the suppliers type collection. Then we build a subscribers list -// starting with any consumers having a type-based subscription in the -// global type collection. -void -ACE_ES_Subscription_Module::connected (ACE_Push_Supplier_Proxy *supplier, - CORBA::Environment &TAO_IN_ENV) -{ - RtecEventComm::EventSourceID sid = 0; - // We will record the source_id for later usage. - { - ACE_ES_WGUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - TAO_THROW (RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - if (all_suppliers_.insert (supplier) == -1) - ACE_ERROR ((LM_ERROR, "ACE_ES_Subscription_Module insert failed.\n")); - - // For every type that this supplier generates, bind a new - // Type_Subscribers to the type in the supplier proxy's type - // collection. - RtecEventChannelAdmin::PublicationSet &publications = - supplier->qos ().publications; - - sid = publications[0].event.header.source; - for (CORBA::ULong index=0; index < publications.length (); index++) - { - // Check to make sure an RT_Info was specified. -#if 0 - // @@ TODO: We should check if rt_info is a valid handle_t. - if (publications[index].dependency_info_.rt_info.value() == 0) - { - ACE_ERROR ((LM_ERROR, "Found a SupplierQOS::dependency_info_.rt_info_ == 0\n")); - continue; - } -#endif - - RtecEventComm::EventType event_type = - publications[index].event.header.type; - - // @@ TODO we should throw something Check to make sure a type - // was specified. - if (event_type == ACE_ES_EVENT_ANY) - { - ACE_ERROR ((LM_ERROR, "ACE_ES_Subscription_Module::connected: " - "source is publishing ACE_ES_EVENT_ANY.\n")); - continue; - } - - // Make a new set for the proxy. Include the dependency - // info describing the RT_Method that generates this event. - // This object will hold all the consumers that subscribe to - // this publication. - ACE_ES_Subscription_Info::Type_Subscribers *new_subscribers = - new ACE_ES_Subscription_Info::Type_Subscribers (&(publications[index].dependency_info)); - - if (new_subscribers == 0) - { - ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Subscription_Module::connected")); - return; - } - - // Check the global type collection for consumers that register - // before suppliers. - ACE_ES_Subscription_Info::Type_Subscribers *existing_subscribers; - if (type_subscribers_.find (event_type, existing_subscribers) != -1) - { - // Iterate through existing subscribers. - ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (existing_subscribers->consumers_); - - for (ACE_ES_Consumer_Rep **proxy = 0; - iter.next (proxy) != 0; - iter.advance ()) - { - // Each existing subscriber will get appended to the - // new subscribers list. Dependencies are updated. - - // @@ TODO: Handle exceptions. - ACE_Scheduler_Factory::server()->add_dependency - ((*proxy)->dependency()->rt_info, - new_subscribers->dependency_info_->rt_info, - new_subscribers->dependency_info_->number_of_calls, - RtecScheduler::ONE_WAY_CALL, - TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) - return; - // @@ TODO use the TAO_TRY macros. - - if (new_subscribers->consumers_.insert (*proxy) == -1) - { - ACE_ERROR ((LM_ERROR, - "%p: add_dependency/insert failed.\n", - "ACE_ES_Subscription_Module::connected")); - continue; - } - (*proxy)->_duplicate (); - } - } -#if 0 - else - { - //ACE_DEBUG ((LM_DEBUG, - // "EC (%t) No consumers for type %d\n", event_type)); - } -#endif - - // Put the new subscribers for this event type in the supplier - // proxy's type map. - if (supplier->subscription_info ().type_subscribers_. - bind (event_type, new_subscribers) != 0) - { - // This may occur with a double bind, I think. - ACE_ERROR ((LM_ERROR, "%p can't initialize type.\n", - "ACE_ES_Subscription_Module::connected")); - delete new_subscribers; - continue; - } - } - } // release lock - - // Reregister any consumers that tried to subscribe before this - // supplier connected. - // NOTE: We used to call back the supplier here (using - // supplier->source_id()), this is ineffective and leads to all kind - // of dead-locks (the supplier is blocked and waiting for us). - // We use the information on the publications to get the source_id. - this->reregister_consumers (sid); -} - -// Step through each of the source_subscribers looking for consumers -// that registered for <source> before <source> connected. -void -ACE_ES_Subscription_Module::reregister_consumers (RtecEventComm::EventSourceID source_id) -{ - ACE_ES_Subscription_Info::Subscriber_Set *subscribers = 0; - if (source_subscribers_.find (source_id, subscribers) == -1) - // Not found. - return; - - ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (*subscribers); - - // Try to reregister all consumers. - for (ACE_ES_Consumer_Rep **consumer = 0; - iter.next (consumer) != 0; - iter.advance ()) - if (this->subscribe (*consumer) == -1) - ACE_ERROR ((LM_ERROR, "%p.\n" "ACE_ES_Subscription_Module::reregister_consumers")); -} - - -void -ACE_ES_Subscription_Module::disconnecting (ACE_Push_Supplier_Proxy *supplier, - CORBA::Environment &TAO_IN_ENV) -{ - ACE_ES_WGUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - TAO_THROW (RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - if (all_suppliers_.remove (supplier) == -1) - TAO_THROW (RtecEventChannelAdmin::EventChannel::SUBSCRIPTION_ERROR()); - - // Remove all consumers from the supplier's source-based subscription lists. - ACE_ES_Subscription_Info::Subscriber_Set_Iterator source_iterator - (supplier->subscription_info ().source_subscribers_); - - for (ACE_ES_Consumer_Rep **consumer; - source_iterator.next (consumer) != 0; - source_iterator.advance ()) - { - (*consumer)->_release (); - } - - // Get the subscriber list for each type. - ACE_ES_Subscription_Info::Subscriber_Map_Iterator type_map_iterator - (supplier->subscription_info ().type_subscribers_); - - for (ACE_ES_Subscription_Info::Subscriber_Map_Entry *entry; - type_map_iterator.next (entry) != 0; - type_map_iterator.advance ()) - { - // Remove all consumers from the supplier's source-based - // subscription lists. - ACE_ES_Subscription_Info::Subscriber_Set_Iterator type_iterator - (entry->int_id_->consumers_); - - for (ACE_ES_Consumer_Rep **c; - type_iterator.next (c) != 0; - type_iterator.advance ()) - { - (*c)->_release (); - } - } -} - -int -ACE_ES_Subscription_Module::subscribe_all (ACE_ES_Consumer_Rep *) -{ - ACE_ERROR_RETURN ((LM_ERROR, "Consumer tried to register for all" - "events! This is not implemented.\n"), -1); -} - -// Forward <events> to all consumers subscribed to <source> only. -int -ACE_ES_Subscription_Module::push_source (ACE_Push_Supplier_Proxy *source, - const TAO_EC_Event &event, - CORBA::Environment &TAO_IN_ENV) -{ - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Subscription_Module::push_source\n")); - - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_ENTER_ACE_ES_SUBSCRIPTION_MODULE_PUSH); - // If there are now source-based subscribers for this supplier, - // return. - if (source->subscription_info ().source_subscribers_.size () == 0) - return 0; - - ACE_ES_Subscription_Info::Subscriber_Set &set = - source->subscription_info ().source_subscribers_; - - // List of consumers that need to be disconnected. - ACE_ES_Subscription_Info::Subscriber_Set disconnect_list; - - { - // Acquire a read lock. - ACE_ES_RGUARD ace_mon (source->subscription_info ().lock_); - if (ace_mon.locked () == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "ACE_ES_Subscription_Module::push_source.\n"), -1); - - ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (set); - - // Iterate through all subscribers. - for (ACE_ES_Consumer_Rep **consumer = 0; - iter.next (consumer) != 0; - iter.advance ()) - { - // Only push the event if the consumer is not suspended - // and not disconnected. - if ((*consumer)->receiving_events ()) - { - up_->push (*consumer, event, TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return -1; - } - // If the consumer has disconnected, schedule it for - // disconnection. We can not modify our list now. It - // would mess up the iterator. - if ((*consumer)->disconnected ()) - disconnect_list.insert (*consumer); - } - // Release the read lock. - } - - // If there are consumers scheduled for disconnect, acquire a write - // lock and disconnect them. - if (disconnect_list.size () != 0) - { - ACE_ES_WGUARD ace_mon (source->subscription_info ().lock_); - if (ace_mon.locked () == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "ACE_ES_Subscription_Module::push_source.\n"), -1); - - // Iterate through the disconnecting consumers. - for (ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter = - disconnect_list.begin (), - end = disconnect_list.end (); - iter != end; - iter++) - { - ACE_ES_Consumer_Rep *consumer = (*iter); - // Remove the consumer from subscriber list. - if (set.remove (consumer) == -1) - ACE_ERROR ((LM_ERROR, "%p remove failed.\n", - "ACE_ES_Subscription_Module::push_source.\n")); - else - // Decrement the consumer rep's reference count. - consumer->_release (); - } - } - - return 0; -} - -// 1. figure out why we're going through the subscription module, -// instead of just passing through. -// 2. where is lock_? Is there only one per module!? - -int -ACE_ES_Subscription_Module::push_source_type (ACE_Push_Supplier_Proxy *source, - const TAO_EC_Event &event, - CORBA::Environment& TAO_IN_ENV) -{ - // ACE_DEBUG ((LM_DEBUG, - // "EC (%t) Subscription_Module::push_source_type: \n")); - - // Step through each event in the set. For each event type, find - // the corresponding set in the type collection. Push the single - // event to each consumer in the set. - - ACE_ES_Subscription_Info::Subscriber_Map &supplier_map = - source->subscription_info ().type_subscribers_; - - ACE_ES_Subscription_Info::Subscriber_Set disconnect_list; - - ACE_ES_Subscription_Info::Subscriber_Set *set; - - { - ACE_ES_RGUARD ace_mon (source->subscription_info ().lock_); - if (ace_mon.locked () == 0) - { - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_PUSH_SOURCE_TYPE); - ACE_ERROR_RETURN ((LM_ERROR, - "ACE_ES_Subscription_Module::" - "push_source_type.\n"), -1); - } - - ACE_ES_Subscription_Info::Type_Subscribers *subscribers; - - if (supplier_map.current_size () == 0) - { - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_PUSH_SOURCE_TYPE); - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Subscription_Module::" - // "push_source_type - empty supplier map\n")); - return 0; - } - - if (supplier_map.find (event.header ().type, subscribers) == -1) - { - ACE_DEBUG ((LM_ERROR, - "EC (%t) ACE_ES_Subscription_Module::push_source_type" - " Warning: event type %d not registered.\n", - event.header ().type)); - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_PUSH_SOURCE_TYPE); - return 0; // continue anyway - } - - if (subscribers->consumers_.size () == 0) - { - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Subscription_Module::" - // "push_source_type - empty consumer set for %d\n", - // event->type_)); - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_PUSH_SOURCE_TYPE); - return 0; - } - - set = &subscribers->consumers_; - - // We've found the set of consumers subscribed to this type - // of event from this supplier. Forward the event to each. - ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter (*set); - - for (ACE_ES_Consumer_Rep **consumer = 0; - iter.next (consumer) != 0; - iter.advance ()) - { - if ((*consumer)->receiving_events ()) - { - up_->push (*consumer, event, TAO_IN_ENV); - if (TAO_IN_ENV.exception () != 0) return -1; - } - if ((*consumer)->disconnected ()) - { - disconnect_list.insert (*consumer); - } - } - } - - // Acquire a write lock and remove all disconnected consumers. - if (disconnect_list.size () != 0) - { - // ACE_DEBUG ((LM_DEBUG, - // "EC (%t) Subscription_Module::push_source_type" - // " - disconnecting consumers\n")); - ACE_ES_WGUARD ace_mon (source->subscription_info ().lock_); - if (ace_mon.locked () == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "ACE_ES_Subscription_Module::" - "push_source.\n"), -1); - - for (ACE_ES_Subscription_Info::Subscriber_Set_Iterator iter = - disconnect_list.begin (), - disconnect_list_end = disconnect_list.end (); - iter != disconnect_list_end; - iter++) - { - ACE_ES_Consumer_Rep *consumer = (*iter); - if (set->remove (consumer) == -1) - ACE_ERROR ((LM_ERROR, "%p remove failed.\n", - "ACE_ES_Subscription_Module::push_source.\n")); - else - consumer->_release (); - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Subscription_Module::" - // "push_source_type - consumer %x removed\n", - // *Consumer)); - } - } - - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_PUSH_SOURCE_TYPE); - return 0; -} - -int -ACE_ES_Subscription_Module::subscribe_source (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID source) -{ - // Step through all Supplier Proxies looking for a match to - // -supplier-. Add the -consumer- to the correct supplier proxy. - Supplier_Iterator iter (all_suppliers_); - - for (ACE_Push_Supplier_Proxy **proxy = 0; - iter.next (proxy) != 0; - iter.advance ()) - { - // Operator == checks if <proxy> is a proxy for <supplier>. - if (!((**proxy) == source)) - continue; - - ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); - - ACE_ES_Subscription_Info::Subscriber_Set &set = - (*proxy)->subscription_info ().source_subscribers_; - - // Insert the consumer to the supplier's subscription set for - // the type. - int insert_result = set.insert (consumer); - switch (insert_result) - { - case -1: - // Error. - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "Subscription Module::subscribe_source"), -1); - case 1: - // Already there. - break; - case 0: - default: - { - // Increment the consumer rep's reference count. - consumer->_duplicate (); - - // Add each of the supplier's dependency infos to the - // consumer's dependency list. - ACE_ES_Subscription_Info::Subscriber_Map_Iterator iter2 - ((*proxy)->subscription_info ().type_subscribers_); - - // Delete all type collections. - for (ACE_ES_Subscription_Info::Subscriber_Map_Entry *temp = 0; - iter2.next (temp) != 0; - iter2.advance ()) - { - TAO_TRY - { - ACE_Scheduler_Factory::server()->add_dependency - (consumer->dependency()->rt_info, - temp->int_id_->dependency_info_->rt_info, - temp->int_id_->dependency_info_->number_of_calls, - RtecScheduler::ONE_WAY_CALL, - TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception ("error adding dependency"); - return -1; - } - TAO_ENDTRY; - } - } - } - } - - return ACE_ES_Subscription_Info::insert_or_allocate (source_subscribers_, - consumer, - source); -} - -// Step through all Supplier Proxies. For each proxy, if it generates -// <type>, add <consumer> to its subscription info. -int -ACE_ES_Subscription_Module::subscribe_type (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type) -{ - // ACE_DEBUG ((LM_DEBUG, - // "EC (%t) Subscription_Module::subscribe_type - %d\n", type)); - - // First insert <consumer> into the global type collection set - // corresponding to <type>. The type collection will only be used - // when suppliers register late. - if (ACE_ES_Subscription_Info::insert_or_allocate (type_subscribers_, - consumer, type) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - "Subscription_Module - insert_or_allocate failed\n"), - -1); - } - - Supplier_Iterator iter (all_suppliers_); - - for (ACE_Push_Supplier_Proxy **proxy = 0; - iter.next (proxy) != 0; - iter.advance ()) - { - ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); - // Insert the consumer to the supplier's subscription set for - // the type. If the supplier does not publish this type, the - // operation will fail. If this succeeds, dependency_info will - // be added to the consumer. - RtecScheduler::Dependency_Info *dependency_info; - if (ACE_ES_Subscription_Info::insert_or_fail - ((*proxy)->subscription_info ().type_subscribers_, - consumer, type, dependency_info) == 0) - { - // Success. Add the supplier dependency info to the - // consumer's dependency list. - // @@ TODO handle exceptions. - TAO_TRY - { - ACE_Scheduler_Factory::server()->add_dependency - (consumer->dependency ()->rt_info, - dependency_info->rt_info, - dependency_info->number_of_calls, - RtecScheduler::ONE_WAY_CALL, - TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - ACE_ERROR ((LM_ERROR, "Subscription_Module::subscribe_type:" - " add_dependency failed.\n")); - return -1; - } - TAO_ENDTRY; - } - } - - return 0; -} - -int -ACE_ES_Subscription_Module::subscribe_source_type (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID source, - RtecEventComm::EventType type) -{ - // Step through all Supplier Proxies looking for a match to - // <supplier>. Once we find one, find the correct set for the - // specified type. Add the <consumer> to that set. - Supplier_Iterator iter (all_suppliers_); - - for (ACE_Push_Supplier_Proxy **proxy = 0; - iter.next (proxy) != 0; - iter.advance ()) - { - ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); - - if ((**proxy) == source) - { - // Insert the consumer to the supplier's subscription set for - // the type. - RtecScheduler::Dependency_Info *dependency_info; - int insert_result = ACE_ES_Subscription_Info::insert_or_fail - ((*proxy)->subscription_info().type_subscribers_, - consumer, type, dependency_info); - - switch (insert_result) - { - case -1: - // Error. - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "Subscription Module::subscribe_source_type"), -1); - case 0: - default: - { - // Success. - // Add the supplier to the consumer's dependency list. - // @@ TODO handle exceptions. - TAO_TRY - { - ACE_Scheduler_Factory::server()->add_dependency - (consumer->dependency ()->rt_info, - dependency_info->rt_info, - dependency_info->number_of_calls, - RtecScheduler::ONE_WAY_CALL, - TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - ACE_ERROR_RETURN ((LM_ERROR, "Subscription_Module::subscribe_source_type:" - " add_dependency failed.\n"), - -1); - } - TAO_ENDTRY; - } - /* FALLTHROUGH */ - case 1: - // Already there. - break; - } - - } - } - - return ACE_ES_Subscription_Info::insert_or_allocate (source_subscribers_, - consumer, - source); -} - -// <consumer> contains information for one type of subscription. -// Delegate to the appropriate method for subscription. -int -ACE_ES_Subscription_Module::subscribe (ACE_ES_Consumer_Rep *consumer) -{ - // We could have finer granularity by putting RGUARDs in some of the - // subscribe methods. - ACE_ES_WGUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Subscription_Module::subscribe"), -1); - - int result = 0; - RtecEventComm::Event &event = consumer->dependency ()->event; - - if (event.header.source == 0) - // Not source-based subscription. - { - if (event.header.type == ACE_ES_EVENT_ANY) - result = this->subscribe_all (consumer); - else - result = this->subscribe_type (consumer, event.header.type); - } - else - // Source-based subscription. - { - if (event.header.type == ACE_ES_EVENT_ANY) - result = this->subscribe_source (consumer, event.header.source); - else - result = this->subscribe_source_type (consumer, - event.header.source, - event.header.type); - } - - return result; -} - -int -ACE_ES_Subscription_Module::unsubscribe (ACE_ES_Consumer_Rep *consumer) -{ - // We could have finer granularity by putting RGUARDs in some of the - // unsubscribe methods. - ACE_ES_WGUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "ACE_ES_Subscription_Module::unsubscribe"), -1); - - RtecEventComm::Event &event = consumer->dependency ()->event; - - if (event.header.source == 0) - { - // Remove the consumer from the global type-based subscription list. - ACE_ES_Subscription_Info::remove (type_subscribers_, - consumer, - event.header.type); - } - else - // Remove the consumer from the global source-based subscription list. - ACE_ES_Subscription_Info::remove (source_subscribers_, - consumer, - event.header.source); - -#if 0 - // @@ TODO This code was removed and I'm (coryan) adding it again - // because it does seem necessary, the only explanation for its - // removal is this comment: - // - // /* - // - // This old code manually removed the consumer from the subscription - // lists. Now we do lazy removal. - // */ - // - // I quite not follow what was going on. - // - // [CORYAN]: The mistery seems resolved: the code was here to remove - // the consumer proxy from the supplier sets, but the "new" strategy - // was to remove them as the supplier tries to push events through - // them, unfortunately that code was broken and did not remove the - // objects at all, hence the apparent need to re-instate this code. - // Bottom line: it seems the code is not needed after all. - - int result = 0; - - if (event.header.source == 0) - { - if (event.header.type == ACE_ES_EVENT_ANY) - result = this->unsubscribe_all (consumer); - else - result = this->unsubscribe_type (consumer, event.header.type); - } - else - { - if (event.header.type == ACE_ES_EVENT_ANY) - result = this->unsubscribe_source (consumer, event.header.source); - else - result = this->unsubscribe_source_type (consumer, - event.header.source, - event.header.type); - } - return result; -#else - return 0; -#endif /* 0 */ -} - -int -ACE_ES_Subscription_Module::unsubscribe_all (ACE_ES_Consumer_Rep *) -{ - return 0; -} - -int -ACE_ES_Subscription_Module::unsubscribe_type (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type) -{ - // Step through all Supplier Proxies trying to remove the - // consumer-type pair. ACE_ES_Subscription_Info::remove will fail - // if the supplier does not generate <type>, but that's ok. - Supplier_Iterator iter (all_suppliers_); - - for (ACE_Push_Supplier_Proxy **proxy = 0; - iter.next (proxy) != 0; - iter.advance ()) - { - ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); - - // This remove will be harmless if the supplier does not - // generate <type>. - ACE_ES_Subscription_Info::remove ((*proxy)->subscription_info ().type_subscribers_, - consumer, type); - } - - return 0; -} - -int -ACE_ES_Subscription_Module::unsubscribe_source (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID source) -{ - Supplier_Iterator iter (all_suppliers_); - - for (ACE_Push_Supplier_Proxy **proxy = 0; - iter.next (proxy) != 0; - iter.advance ()) - { - ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); - - if ((**proxy) == source) - { - ACE_ES_Subscription_Info::Subscriber_Set &set = - (*proxy)->subscription_info ().source_subscribers_; - if (set.remove (consumer) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", - "Subscription Module::unsubscribe_source"), -1); - consumer->_release (); - } - } - - return 0; -} - -int -ACE_ES_Subscription_Module::unsubscribe_source_type (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID source, - RtecEventComm::EventType type) - -{ - Supplier_Iterator iter (all_suppliers_); - - // Step through all supplier proxies looking for a match to the - // consumer's event.header.source. This is the same as - // unsubscribe_type, only we can check the source first. - for (ACE_Push_Supplier_Proxy **proxy = 0; - iter.next (proxy) != 0; - iter.advance ()) - // If the proxy matches the source id we're looking for, try to - // remove <consumer> from the proxy's <event.header.type> set. - if ((**proxy) == source) - { - ACE_ES_WGUARD mon ((*proxy)->subscription_info ().lock_); - - // Continue in spite of errors. - ACE_ES_Subscription_Info::remove ((*proxy)->subscription_info ().type_subscribers_, - consumer, type); - } - - return 0; -} - -void -ACE_ES_Subscription_Module::push (ACE_Push_Supplier_Proxy *source, - const TAO_EC_Event &event, - CORBA::Environment &TAO_IN_ENV) -{ - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Subscription_Module::push\n")); - - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_DELIVER_TO_SUBSCRIPTION_MODULE); - // These are all inline function calls. - if (this->push_source (source, event, TAO_IN_ENV) == -1) - return; - - { - ACE_FUNCTION_TIMEPROBE (TAO_EVENT_CHANNEL_BEGIN_PUSH_SOURCE_TYPE); - - if (this->push_source_type (source, event, TAO_IN_ENV) == -1) - return; - } -} - -void -ACE_ES_Subscription_Module::shutdown (void) -{ - ACE_ES_WGUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - ACE_ERROR ((LM_ERROR, "%p.\n", - "ACE_ES_Subscription_Module::shutdown")); - - // Remove all type_subscribers_ and source_subscribers_. - - ACE_ES_Subscription_Info::Subscriber_Map_Iterator type_iter (type_subscribers_); - for (ACE_ES_Subscription_Info::Subscriber_Map_Entry *entry = 0; - type_iter.next (entry) != 0; - type_iter.advance ()) - { - ACE_ES_Subscription_Info::Subscriber_Set_Iterator ts_iter (entry->int_id_->consumers_); - - for (ACE_ES_Consumer_Rep **consumer = 0; - ts_iter.next (consumer) != 0; - ts_iter.advance ()) - (*consumer)->_release (); - - delete entry->int_id_; - } - - ACE_ES_Subscription_Info::SourceID_Map_Iterator source_iter (source_subscribers_); - - for (ACE_ES_Subscription_Info::SourceID_Map_Entry *entry2; - source_iter.next (entry2) != 0; - source_iter.advance ()) - { - ACE_ES_Subscription_Info::Subscriber_Set_Iterator ss_iter (*entry2->int_id_); - - for (ACE_ES_Consumer_Rep **consumer = 0; - ss_iter.next (consumer) != 0; - ss_iter.advance ()) - (*consumer)->_release (); - - delete entry2->int_id_; - } - - // We don't need to do anything to all_suppliers_ since the supplier - // module should have disconnected all suppliers. To be more - // independent from the supplier module, this method should iterate - // through all suppliers and call this->disconnecting. - up_->shutdown (); -} - -// ************************************************************ - -ACE_ES_Supplier_Module::ACE_ES_Supplier_Module (ACE_EventChannel *channel) : - all_suppliers_ (), - lock_ (), - up_ (0), - channel_ (channel) -{ -} - -void -ACE_ES_Supplier_Module::open (ACE_ES_Subscription_Module *up) -{ - // There is the theory of the Mobius, a twist, in the fabric of - // space, where time becomes a loop, where time becomes a loop. - up_ = up; -} - -void -ACE_ES_Supplier_Module::connected (ACE_Push_Supplier_Proxy *supplier, - CORBA::Environment &TAO_IN_ENV) -{ - channel_->report_connect (ACE_EventChannel::SUPPLIER); - up_->connected (supplier, TAO_IN_ENV); - if (!supplier->qos ().is_gateway) - this->channel_->update_supplier_gwys (TAO_IN_ENV); -} - -void -ACE_ES_Supplier_Module::disconnecting (ACE_Push_Supplier_Proxy *supplier, - CORBA::Environment &TAO_IN_ENV) -{ - CORBA::Boolean need_update = 0; - { - TAO_GUARD_THROW (ACE_SYNCH_MUTEX, ace_mon, this->lock_, TAO_IN_ENV, - RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - if (all_suppliers_.remove (supplier) == -1) - TAO_THROW (RtecEventChannelAdmin::EventChannel::SUBSCRIPTION_ERROR()); - - up_->disconnecting (supplier, TAO_IN_ENV); - - if (this->all_suppliers_.size () <= 0) - { - // ACE_DEBUG ((LM_DEBUG, "EC (%t) No more suppliers connected.\n")); - channel_->report_disconnect_i (ACE_EventChannel::SUPPLIER); - } - - need_update = (supplier->qos ().is_gateway == 0); - - // @@ TODO It would seem - // IMHO this release is broken: supplier is a parameter, we never - // actually increased its reference count, so we shouldn't decrease - // it. - // CORBA::release (supplier); - } - if (need_update) - this->channel_->update_supplier_gwys (TAO_IN_ENV); -} - -void -ACE_ES_Supplier_Module::shutdown (void) -{ - Suppliers copy; - - { - ACE_ES_GUARD ace_mon (lock_); - if (ace_mon.locked () == 0) - return; - - copy = all_suppliers_; - } - - if (copy.size () > 0) - { - Supplier_Iterator iter (copy); - - CORBA::Environment env; - - for (ACE_Push_Supplier_Proxy **proxy = 0; - iter.next (proxy) != 0; - iter.advance ()) - { - (*proxy)->shutdown (); - this->disconnecting (*proxy, env); - } - } - - up_->shutdown (); -} - -RtecEventChannelAdmin::ProxyPushConsumer_ptr -ACE_ES_Supplier_Module::obtain_push_consumer (CORBA::Environment &TAO_IN_ENV) -{ - auto_ptr<ACE_Push_Supplier_Proxy> new_supplier (new ACE_Push_Supplier_Proxy (this)); - - if (new_supplier.get () == 0) - TAO_THROW_RETURN (CORBA::NO_MEMORY (CORBA::COMPLETED_NO), 0); - - { - TAO_GUARD_THROW_RETURN (ACE_ES_MUTEX, ace_mon, this->lock_, 0, TAO_IN_ENV, - RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR()); - - if (all_suppliers_.insert (new_supplier.get ()) == -1) - ACE_ERROR ((LM_ERROR, "ACE_ES_Supplier_Module insert failed.\n")); - } - - return new_supplier.release ()->get_ref (TAO_IN_ENV); -} - -void -ACE_ES_Supplier_Module::push (ACE_Push_Supplier_Proxy *proxy, - RtecEventComm::EventSet &event_set, - CORBA::Environment &TAO_IN_ENV) -{ - // Steal the events from the EventSet and put them into a reference - // counted event set. - TAO_EC_Event_Set* event = - TAO_EC_Event_Set::_create (event_set); - - if (event == 0) - TAO_THROW (CORBA::NO_MEMORY (CORBA::COMPLETED_NO)); - - // ACE_DEBUG ((LM_DEBUG, "EC (%t) Supplier_Module::push\n")); - for (CORBA::ULong i = 0; i < event->length (); ++i) - { - // This will guarantee that release gets called when we exit - // the scope. - TAO_EC_Event event_copy (event, i); - ACE_TIMEPROBE (TAO_EVENT_CHANNEL_DELIVER_TO_SUPPLIER_MODULE_THRU_SUPPLIER_PROXY); - up_->push (proxy, event_copy, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN_VOID (TAO_IN_ENV); - } - TAO_EC_Event_Set::_release (event); -} - -void -ACE_ES_Supplier_Module::fill_qos (RtecEventChannelAdmin::SupplierQOS& s_qos) -{ - ACE_GUARD (ACE_ES_MUTEX, ace_mon, this->lock_); - - s_qos.is_gateway = 1; - - int count = 0; - { - for (Supplier_Iterator i = this->all_suppliers_.begin (); - i != this->all_suppliers_.end (); - ++i) - { - ACE_Push_Supplier_Proxy *s = *i; - - if (s->qos ().is_gateway) - continue; - - count += s->qos ().publications.length (); - } - } - - RtecEventChannelAdmin::PublicationSet& pub = s_qos.publications; - - pub.length (count); - - CORBA::ULong sc = 0; - - for (Supplier_Iterator i = this->all_suppliers_.begin (); - i != this->all_suppliers_.end (); - ++i) - { - ACE_Push_Supplier_Proxy *s = *i; - - if (s->qos ().is_gateway) - continue; - - CORBA::ULong count = s->qos ().publications.length (); - for (CORBA::ULong j = 0; j < count; ++j) - { - RtecEventComm::Event& event = - s->qos ().publications[j].event; - - RtecEventComm::EventType type = event.header.type; - - // Only type and source dependencies are relevant, notice - // that we turn conjunctions into disjunctions because - // correlations could be satisfied by events coming from - // several remote ECs. - if (0 <= type && type <= ACE_ES_EVENT_UNDEFINED) - continue; - - // If the dependency is already there we don't add it. - CORBA::ULong k; - for (k = 0; k < sc; ++k) - { - if (pub[k].event.header.type == event.header.type - && pub[k].event.header.source == event.header.source) - break; - } - if (k == sc) - { - pub[sc].event.header.type = event.header.type; - pub[sc].event.header.source = event.header.source; - pub[sc].event.header.creation_time = ORBSVCS_Time::zero; - pub[sc].dependency_info.dependency_type = - RtecScheduler::TWO_WAY_CALL; - pub[sc].dependency_info.number_of_calls = 1; - pub[sc].dependency_info.rt_info = 0; - sc++; - } - } - } - pub.length (sc); -} - -// ************************************************************ - -const char * -ACE_ES_Consumer_Name (const RtecEventChannelAdmin::ConsumerQOS &qos, - CORBA::Environment &TAO_IN_ENV) -{ - // The first dependency should designate a correlation group. - - ACE_FUNCTION_TIMEPROBE (TAO_EVENT_CHANNEL_CONSUMER_NAME_PRIORITY_REQUESTED); - if (qos.dependencies.length () <= 1) - return "no-name"; - - RtecScheduler::RT_Info* rt_info = ACE_Scheduler_Factory::server ()->get - (qos.dependencies[1].rt_info, TAO_IN_ENV); - TAO_CHECK_ENV_RETURN (TAO_IN_ENV, 0); - - if (rt_info == 0) - return "no-name"; - - return rt_info->entry_point; -} - -// ************************************************************ - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -template class ACE_Atomic_Op<ACE_ES_MUTEX, int>; -template class ACE_Map_Entry<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT>; -template class ACE_Map_Entry<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT>; -template class ACE_Map_Entry<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry>; -template class ACE_Map_Manager<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH>; -template class ACE_Map_Manager<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH>; -template class ACE_Map_Manager<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry, ACE_Null_Mutex>; -template class ACE_Map_Iterator_Base<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH>; -template class ACE_Map_Iterator_Base<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH>; -template class ACE_Map_Iterator_Base<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry, ACE_Null_Mutex>; -template class ACE_Map_Iterator<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH>; -template class ACE_Map_Iterator<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry, ACE_Null_Mutex>; -template class ACE_Map_Reverse_Iterator<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH>; -template class ACE_Map_Iterator<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH>; -template class ACE_Map_Reverse_Iterator<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH>; -template class ACE_Map_Reverse_Iterator<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry, ACE_Null_Mutex>; -template class ACE_Node<ACE_ES_Consumer_Rep *>; -template class ACE_Node<ACE_Push_Consumer_Proxy *>; -template class ACE_Node<ACE_Push_Supplier_Proxy *>; -template class ACE_Unbounded_Set<ACE_ES_Consumer_Rep *>; -template class ACE_Unbounded_Set<ACE_Push_Consumer_Proxy *>; -template class ACE_Unbounded_Set<ACE_Push_Supplier_Proxy *>; -template class ACE_Unbounded_Set_Iterator<ACE_ES_Consumer_Rep *>; -template class ACE_Unbounded_Set_Iterator<ACE_Push_Consumer_Proxy *>; -template class ACE_Unbounded_Set_Iterator<ACE_Push_Supplier_Proxy *>; - -template class ACE_Auto_Basic_Ptr<ACE_Push_Supplier_Proxy>; -template class ACE_Auto_Basic_Ptr<ACE_Push_Consumer_Proxy>; -template class auto_ptr<ACE_Push_Supplier_Proxy>; -template class auto_ptr<ACE_Push_Consumer_Proxy>; - -template class ACE_Array<TAO_EC_Event>; -template class ACE_Array_Base<TAO_EC_Event>; -template class ACE_Array_Iterator<TAO_EC_Event>; - -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) - -#pragma instantiate ACE_Atomic_Op<ACE_ES_MUTEX, int> -#pragma instantiate ACE_Map_Entry<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT> -#pragma instantiate ACE_Map_Entry<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT> -#pragma instantiate ACE_Map_Entry<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry> -#pragma instantiate ACE_Map_Manager<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH> -#pragma instantiate ACE_Map_Manager<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH> -#pragma instantiate ACE_Map_Manager<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry, ACE_Null_Mutex> -#pragma instantiate ACE_Map_Iterator_Base<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH> -#pragma instantiate ACE_Map_Iterator_Base<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH> -#pragma instantiate ACE_Map_Iterator_Base<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry, ACE_Null_Mutex> -#pragma instantiate ACE_Map_Iterator<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH> -#pragma instantiate ACE_Map_Iterator<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry, ACE_Null_Mutex> -#pragma instantiate ACE_Map_Reverse_Iterator<ACE_ES_Subscription_Info::EXT, ACE_ES_Subscription_Info::INT, ACE_ES_Subscription_Info::SYNCH> -#pragma instantiate ACE_Map_Iterator<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH> -#pragma instantiate ACE_Map_Reverse_Iterator<ACE_ES_Subscription_Info::sEXT, ACE_ES_Subscription_Info::sINT, ACE_ES_Subscription_Info::SYNCH> -#pragma instantiate ACE_Map_Reverse_Iterator<RtecEventChannelAdmin::Observer_Handle, ACE_EventChannel::Observer_Entry, ACE_Null_Mutex> -#pragma instantiate ACE_Node<ACE_ES_Consumer_Rep *> -#pragma instantiate ACE_Node<ACE_Push_Consumer_Proxy *> -#pragma instantiate ACE_Node<ACE_Push_Supplier_Proxy *> -#pragma instantiate ACE_Unbounded_Set<ACE_ES_Consumer_Rep *> -#pragma instantiate ACE_Unbounded_Set<ACE_Push_Consumer_Proxy *> -#pragma instantiate ACE_Unbounded_Set<ACE_Push_Supplier_Proxy *> -#pragma instantiate ACE_Unbounded_Set_Iterator<ACE_ES_Consumer_Rep *> -#pragma instantiate ACE_Unbounded_Set_Iterator<ACE_Push_Consumer_Proxy *> -#pragma instantiate ACE_Unbounded_Set_Iterator<ACE_Push_Supplier_Proxy *> - -#pragma instantiate ACE_Auto_Basic_Ptr<ACE_Push_Supplier_Proxy> -#pragma instantiate ACE_Auto_Basic_Ptr<ACE_Push_Consumer_Proxy> -#pragma instantiate auto_ptr<ACE_Push_Supplier_Proxy> -#pragma instantiate auto_ptr<ACE_Push_Consumer_Proxy> - -#pragma instantiate ACE_Array<TAO_EC_Event> -#pragma instantiate ACE_Array_Base<TAO_EC_Event> -#pragma instantiate ACE_Array_Iterator<TAO_EC_Event> - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Channel.h b/TAO/orbsvcs/orbsvcs/Event/Event_Channel.h deleted file mode 100644 index 4a1b1302219..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Event_Channel.h +++ /dev/null @@ -1,1388 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ace ORB -// -// = FILENAME -// Event_Channel -// -// = AUTHOR -// Tim Harrison (harrison@cs.wustl.edu) -// -// = DESCRIPTION -// TAO implementation of the Real Time Event Services. For more -// detailed information, see -// http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz -// -// = NAMING CONVENTIONS -// Some of the naming might be confusing. For instance -// ACE_Push_Consumer_Proxy "is-a" ProxyPushSupplier. To the -// channel, ACE_Push_Consumer_Proxy is a proxy to push consumers. -// To a push consumer, ACE_Push_Consumer_Proxy is a proxy to push -// suppliers. I chose to name classes relative to the Event -// Channel. -// -// ============================================================================ - -#ifndef ACE_EVENT_CHANNEL_H -#define ACE_EVENT_CHANNEL_H - -#include "ace/Containers.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/Map_Manager.h" -#include "ace/Functor.h" - -#include "tao/Timeprobe.h" -#include "orbsvcs/Scheduler_Factory.h" -#include "orbsvcs/Event/Local_ESTypes.h" -#include "orbsvcs/Event/Timer_Module.h" -#include "orbsvcs/Event/ReactorTask.h" -#include "orbsvcs/Event/Event_Manip.h" - -// ************************************************************ - -// = TITLE -// An array of Events. -// -// = DESCRIPTION -// The Event Channel keeps several collections of TAO_EC_Event -// objects, this is implemented using a simple Event Array. -typedef ACE_Array<TAO_EC_Event> TAO_EC_Event_Array; - -// ************************************************************ - -// = TITLE -// Append an event to an event Array. -// -// = DESCRIPTION -// Simplify a common idiom when manipulating arrays of events. -// -ACE_INLINE -void operator += (TAO_EC_Event_Array &dest, - const TAO_EC_Event &item); - -// ************************************************************ - -// = TITLE -// Compare two events -// -// = DESCRIPTION -// The Event Channel must compare events (actually event headers) -// for equality. -// -ACE_INLINE int operator == (const RtecEventComm::Event &event1, - const RtecEventComm::Event &event2); - -// ************************************************************ - -// = TITLE -// Compare two TAO_EC_Events. -// -// = DESCRIPTION -// This is only used in the instantiation of ACE_Array<TAO_EC_Event> -// -ACE_INLINE -int operator != (const TAO_EC_Event &rhs, const TAO_EC_Event &lhs); - -// ************************************************************ - -// = DESCRIPTION -// Utility for debugging events. -void TAO_ORBSVCS_Export dump_event (const RtecEventComm::Event &event); - -// ************************************************************ - - -// Helper function that returns the first RT_Info entry point name. -// Use for debugging purposes only. -const TAO_ORBSVCS_Export char * -ACE_ES_Consumer_Name (const RtecEventChannelAdmin::ConsumerQOS &qos, - CORBA::Environment &_env); - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_RTU_Manager -// = TITLE -// ACE RTU Manager -// -// = DESCRIPTION -{ -public: - ACE_RTU_Manager (int active); - // If <active> == 0, everything returns 0. If <active> != 0, RTUs - // galore. - - int should_preempt (void); - // Returns 1 if the current task should preempt itself. Otherwise, - // returns 0. Resets should_preempt to zero. - - void should_preempt (int s); - // Called by the dispatching module when the current task should - // preempt itself. - - void not_done (int nd); - // If <nd> != 0, the current running task will be enqueued at the - // head of its dispatch tail. - - int not_done (void); - // Returns 1 if the current task needs to be dispatched again. - // Resets not_done_ to 0; - - // = Get/set the priority of the current running task. - RtecScheduler::OS_Priority priority (void); - void priority (RtecScheduler::OS_Priority priority); - -private: - int active_; - int should_preempt_; - int not_done_; - RtecScheduler::OS_Priority priority_; -}; - -// ************************************************************ - -// Chesire cat. -class ACE_ES_Priority_Timer; -// Forward declarations. -class ACE_ES_Consumer_Module; -class ACE_ES_Correlation_Module; -class ACE_ES_Subscription_Module; -class ACE_ES_Supplier_Module; -// This forward decl and typedef allow us to remove inheritence later -// on without changing any code. -class ACE_ES_Dispatching_Base; -typedef ACE_ES_Dispatching_Base ACE_ES_Dispatching_Module; - -class TAO_EC_Gateway; -// Forward declare the class used to connect several EC together. - -class TAO_Module_Factory; -// Factory class for the modules in the EC. - -class TAO_ORBSVCS_Export ACE_EventChannel : public POA_RtecEventChannelAdmin::EventChannel -// -// = TITLE -// TAO's Real-time Event Channel. -// -// = DESCRIPTION -// This class implements the interface defined in -// RtecEventChannelAdmin.idl. For more details check: -// http://www.cs.wustl.edu/~coryan/EC/JSAC98.pdf -{ -public: - enum { INITIAL_STATE = 0, - CONSUMER = 1, SUPPLIER = 2, - SHUTDOWN = CONSUMER | SUPPLIER }; - - ACE_EventChannel (CORBA::Boolean activate_threads = 1, - u_long type = ACE_DEFAULT_EVENT_CHANNEL_TYPE, - TAO_Module_Factory* factory = 0); - // Construction of the given <type>. Check the **_CHANNEL - // enumerations defined below. - // By default we activate the threads on construction, but it is - // possible to create the EC first and activate the threads later. - - virtual ~ACE_EventChannel (void); - // Calls destroy. - - RtecEventChannelAdmin::EventChannel_ptr get_ref (CORBA::Environment &); - // Allow transformations to RtecEventChannelAdmin::EventChannel. - - ACE_RTU_Manager *rtu_manager (void); - // Returns a reference to the RTU manager. - - // = These should be private. - ACE_ES_Consumer_Module *consumer_module_; - ACE_ES_Dispatching_Module *dispatching_module_; - ACE_ES_Correlation_Module *correlation_module_; - ACE_ES_Subscription_Module *subscription_module_; - ACE_ES_Supplier_Module *supplier_module_; - - void report_connect (u_long); - // Consumer or supplier connected. - - void report_disconnect (u_long); - // Consumer or supplier disconnected. - - void activate (void); - // Activate the internal threads of the EC - - void shutdown (void); - // Do not call this. The last module has shut down. - - void report_connect_i (u_long); - // Consumer or supplier connected. - - void report_disconnect_i (u_long); - // Consumer or supplier disconnected. - - void add_gateway (TAO_EC_Gateway* gw, CORBA::Environment& _env); - void del_gateway (TAO_EC_Gateway* gw, CORBA::Environment& _env); - // Add and remove gateways from the EC. - - void update_consumer_gwys (CORBA::Environment& _env); - void update_supplier_gwys (CORBA::Environment& _env); - // The consumer (or supplier) list has changed, thus the EC has to - // inform any gateways it has. - - TAO_EC_Timer_Module* timer_module (void) const; - // The timer module controls the strategy to dispatch timers. - - // = The RtecEventChannelAdmin::EventChannel methods. - - virtual RtecEventChannelAdmin::ConsumerAdmin_ptr - for_consumers (CORBA::Environment &); - // In this implementation of the EC this returns the interface for - // the Consumer_Module. - - virtual RtecEventChannelAdmin::SupplierAdmin_ptr - for_suppliers (CORBA::Environment &); - // Return an interface to the Supplier_Module. - - virtual void destroy (CORBA::Environment &); - // Shutdown the EC, free all resources, stop all threads and then - // shutdown the server where the Servant is running. - - virtual RtecEventChannelAdmin::Observer_Handle - append_observer (RtecEventChannelAdmin::Observer_ptr observer, - CORBA::Environment &env); - virtual void remove_observer (RtecEventChannelAdmin::Observer_Handle, - CORBA::Environment &env); - // The observer manipulators - - // = Timer managment - int schedule_timer (RtecScheduler::handle_t rt_info, - const ACE_Command_Base *act, - RtecScheduler::OS_Priority preemption_priority, - const RtecScheduler::Time& delta, - const RtecScheduler::Time& interval = ORBSVCS_Time::zero); - // Schedule a timer at the appropriate priority for <preemption_priority>. - // Returns the preemption priority used on success, -1 on failure. - - int cancel_timer (RtecScheduler::OS_Priority preemption_priority, - int id, - ACE_Command_Base *&act); - // Cancel the timer associated with the priority of - // <preemption_priority> and <id>. <act> is filled in with the - // Timer_ACT used when scheduling the timer. Returns 0 on success, - // -1 on failure. - -private: - void cleanup_observers (void); - // Remove all the observers, this simplifies the shutdown process. - -private: - ACE_RTU_Manager *rtu_manager_; - // The RTU manager dude! - - u_long type_; - // Can be any **_CHANNEL. (well, except NO_CHANNEL). - - u_long state_; - // Can be INITIAL_STATE, NO_CONSUMERS, NO_SUPPLIERS, or SHUTDOWN. - - ACE_ES_MUTEX lock_; - // Used to lock shared state. - - int destroyed_; - // Ensures this->destory is executed only once. - - struct Observer_Entry - { - // = TITLE - // The data kept for each observer. - // - // = DESCRIPTION - // The observer and its handle are kept in a simple structure. - // In the future this structure could contain QoS information, - // such as: - // + how often do we update the observer? - // + When was the last update. - // + Does it want to receive all changes? - // - - Observer_Entry (void); - Observer_Entry (RtecEventChannelAdmin::Observer_Handle h, - RtecEventChannelAdmin::Observer_ptr o); - - RtecEventChannelAdmin::Observer_Handle handle; - // The handle - - RtecEventChannelAdmin::Observer_var observer; - // The observer - - }; - - typedef ACE_Map_Manager<RtecEventChannelAdmin::Observer_Handle,Observer_Entry,ACE_Null_Mutex> Observer_Map; - typedef ACE_Map_Iterator<RtecEventChannelAdmin::Observer_Handle,Observer_Entry,ACE_Null_Mutex> Observer_Map_Iterator; - - RtecEventChannelAdmin::Observer_Handle handle_generator_; - // The handles are generated in sequential order, but are opaque to - // the client. - - Observer_Map observers_; - // Keep the set of Gateways, i.e. connections to peer EC. - - TAO_EC_Timer_Module* timer_module_; - // The strategy to dispatch timers. - - int own_factory_; - // If 1 then we created the factory, thus we have to destroy it. - - TAO_Module_Factory* module_factory_; - // This is the factory we use to create and destroy the Event - // Channel modules. -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_Dependency_Iterator -// = TITLE -// ConsumerQOS Iterator -// -// = DESCRIPTION -// This is used by the Event Channel to parse ConsumerDependency objects. -{ -public: - ACE_ES_Dependency_Iterator (RtecEventChannelAdmin::DependencySet &rep); - // Construct and iterator for <rep>. - - int advance_dependency (void); - // Returns 0 if the advance succeeded. Returns -1 if there are no - // more dependencies in the group. - - int parse (void); - // Cache values for n_** methods. - - int n_conjunctions (void); - // Returns the number of conjunction groups in the dependency set. - - int n_disjunctions (void); - // Returns the number of disjunction groups in the dependency set. - - int n_timeouts (void); - // Returns the number of timeouts registered. - - int n_events (void); - // Returns the number of events registered. - - RtecEventChannelAdmin::Dependency &operator *(void); - // Accessor to the current ConsumerDependency pointed to by the - // iterator. - - RtecScheduler::handle_t first_rt_info (void); - // Returns the first RT_Info in the dependencies. - -protected: - RtecScheduler::handle_t rt_info_; - // The first rt_info in the dependencies. - - RtecEventChannelAdmin::DependencySet &rep_; - // Reference to the dependency array. - - int index_; - // Index into rep_. - - RtecEventComm::EventType group_type_; - // The type of the current correlation group. - - int n_conjunctions_; - // Number of conjunction groups. - - int n_disjunctions_; - // Number of disjunction groups. - - int n_timeouts_; - // Number of timeouts registered. - - int n_events_; - // Number of events registered. -}; - -// ************************************************************ -// Forward decl. -class ACE_ES_Consumer_Rep_Timeout; - -class TAO_ORBSVCS_Export ACE_ES_Disjunction_Group -// = TITLE -// Disjunction Group -// -// = DESCRIPTION -// Represents a disjunction group, such as (A|B|C). -{ -public: - ACE_ES_Disjunction_Group (void); - // Default construction. - - virtual ~ACE_ES_Disjunction_Group (void); - // Destructor. - - void set_correlation_module (ACE_ES_Correlation_Module *cm); - // <cm> is needed for rescheduling deadlines. - - void reschedule_deadline (void); - // If deadline_timer_rep_ is set, it is cancelled and rescheduled. - - int set_deadline_timeout (ACE_ES_Consumer_Rep_Timeout *cr); - // Set the group's reference to the deadline timer. Returns 0 on - // success, -1 on failure. - - virtual void add_events (TAO_EC_Event_Array *outbox, - TAO_EC_Event_Array *pending_events, - u_long &pending_flags); - // Does nothing. This is the only virtual method in this little - // heirarchy with the conjunction group. - - void set_act (RtecEventComm::Event &act); - // Set the ACT for this group. - -protected: - TAO_EC_Event act_; - // To be sent with this group. - -private: - ACE_ES_Consumer_Rep_Timeout *deadline_timer_rep_; - // The disjunction group keeps a reference to the deadline timer. - - ACE_ES_Correlation_Module *correlation_module_; - // Used for cancelling and scheduling deadline_timer_rep_. -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_Conjunction_Group : public ACE_ES_Disjunction_Group -// = TITLE -// Conjunction Group -// -// = DESCRIPTION -// Represents a conjunction group, such as (A+B+C). -{ -public: - ACE_ES_Conjunction_Group (void); - // Default construction. - - virtual ~ACE_ES_Conjunction_Group (void); - // Destructor. - - int add_type (int type_id); - // Set the <type_id>th bit in the forward_value_. - - int should_forward (u_long pending_flags); - // Returns 1 if this conjunction group's dependencies have been - // satisfied. Returns 0 otherwise. - - virtual void add_events (TAO_EC_Event_Array *outbox, - TAO_EC_Event_Array *pending_events, - u_long &pending_flags); - // For each bit set in forward_value_, the corresponding events in - // <pending_events> is added to <outbox>. Each bit set in - // <forward_value_> is cleared in <pending_flags>. If <oubox> == 0, - // then add_events just clears the pending events and flags. - -private: - u_long forward_value_; -}; - -// ************************************************************ - -// Forward decl. -class ACE_ES_Consumer_Correlation; - -class TAO_ORBSVCS_Export ACE_ES_Consumer_Rep : public ACE_Command_Base -// = TITLE -// Consumer Representation. -// -// = DESCRIPTION -// These are stored in the subscription module. They store -// information that allows optimized correlations. It represents -// the consumer that will handle *one* type of event. This -// probably shouldn't inherit from ACE_Command_Base since it's used -// only by ACE_ES_Consumer_Rep_Timeout. However, this allows me to -// minimize dynamic allocation. -{ -public: - ACE_ES_Consumer_Rep (void); - // Default construction. - - void init (ACE_ES_Consumer_Correlation *correlation, - RtecEventChannelAdmin::Dependency &dep); - // <dep> describes the event subscribed to and the method handling - // the event. <correlation> is the parent correlation object. - - virtual ~ACE_ES_Consumer_Rep (void); - // Virtual destruction. - - RtecEventChannelAdmin::Dependency *dependency (void); - // The event subscribed to and the method that will handle this - // event. - - int type_id (void); - // Get the correlation group index of this consumer rep's event - // type. - - void type_id (int); - // Set the correlation group index of this consumer rep's event - // type. - - enum Correlation_Type - { - NO_CORRELATION, - CORRELATE, - DEADLINE_TIMEOUT, - GLOBAL_DEADLINE - }; - - u_long correlation_type (void); - // If this returns 0, then the event associated with this consumer - // should be forwarded without running any correlations. - - void correlation_type (u_long ct); - // Set whether the event should be correlated. <ct> is a - // Correlation_Type. - - int add_disjunction_group (ACE_ES_Disjunction_Group &); - // Add a disjunction group. - - ACE_ES_Disjunction_Group *top_group (void); - // Returns the first disjunction group added via - // this->add_disjunction_group. - - void reschedule_deadlines (void); - // Calls reschedule_deadline on all disjunction groups added through - // this->add_disjunction_group. - - int receiving_events (void); - // Returns 1 if events should be sent to this consumer. Returns 0 - // if they should not (suspended or disconnected). - - void suspend (void); - // Stop forwarding events to the calling consumer. - - void resume (void); - // Resume forwarding events to the calling consumer. - - ACE_ES_Consumer_Correlation *correlation (void); - // Returns the Consumer_Correlation object for the target consumer. - - void disconnect (void); - // Schedules the consumer rep to be removed from all subscription - // lists. - - int disconnected (void); - // Returns 1 if the consumer rep should be removed from all - // subscription lists. - - void _duplicate (void); - // Increments ref_count_. - - void _release (void); - // Decrements ref_count_ and deletes this if 0. - -protected: - int disconnected_; - // Whether the rep should be removed from all subscription lists. - - virtual int execute (void* arg = 0); - // This is called when timeouts occur. This implementation prints - // out an error message (since it really shouldn't be implemented in - // this class). - - int suspended_; - // Whether events should be dropped or forwarded. - - u_long correlation_type_; - // Whether any correlating should be done for this event. - - RtecEventChannelAdmin::Dependency *dependency_; - // Event subscribed to. - - ACE_ES_Consumer_Correlation *correlation_; - // The target consumer of events. - - int type_id_; - // Correlation group index of event_->type_. - - ACE_ES_Disjunction_Group *disjunction_group_; - // This should be a set. We'll just have room for one now. - - ACE_Atomic_Op<ACE_ES_MUTEX, int> ref_count_; - // Lock for reference count. -}; - -class TAO_ORBSVCS_Export ACE_ES_Consumer_Rep_Timeout : public ACE_ES_Consumer_Rep -// = TITLE -// Consumer Representation. -// -// = DESCRIPTION -// These are stored in the subscription module. They store -// information that allows optimized correlations. It represents -// the consumer that will handle *one* type of event. -{ -public: - ACE_ES_Consumer_Rep_Timeout (void); - // Default construction. - - void init (ACE_ES_Consumer_Correlation *correlation, - RtecEventChannelAdmin::Dependency &dep); - // <dep> describes the event subscribed to and the method handling - // the event. <correlation> is the parent correlation object. - - // = Get/set timer returned from the reactor. - int timer_id (void); - void timer_id (int); - - // = Get/set preemption priority. - RtecScheduler::OS_Priority preemption_priority (void); - void preemption_priority (RtecScheduler::OS_Priority pp); - -protected: - virtual int execute (void* arg = 0); - // This is called when timeouts occur. Calls correlation_-> - - int timer_id_; - // For cancelling timers. - - RtecScheduler::OS_Priority preemption_priority_; - // Store the preemption priority so we can cancel the correct timer. - // The priority values may change during the life. - - TAO_EC_Event timeout_event_; -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_Subscription_Info -// = TITLE -// Event Service Subscription Info -// -// = DESCRIPTION -// Contains information on all consumers subscribed to a supplier. -// Each Push_Supplier_Proxy has an instance of this class. This -// should really be defined in Channel_Modules.h, but I want to -// have an instance of it in each ACE_Push_Supplier_Proxy. This -// allows us to reduce the amount of dynamic memory allocation. -{ -public: - ~ACE_ES_Subscription_Info (void); - // Free up dynamic resources. - - typedef ACE_Unbounded_Set_Iterator<ACE_ES_Consumer_Rep *> Subscriber_Set_Iterator; - typedef ACE_Unbounded_Set<ACE_ES_Consumer_Rep *> Subscriber_Set; - - class Type_Subscribers - // = DESCRIPTION - // There is one of these for each event type generated by the - // supplier. It contains the subscribers and the - // dependency_info_ describing the method that generates this - // event type. - { - public: - Type_Subscribers (RtecScheduler::Dependency_Info *d) - : dependency_info_ (d) {} - // Construction requires a dependency info describing the method - // that generates events for the consumers_. We use a pointer so - // that a null can be passed in this->insert_or_allocate. - - // void operator= (const Subscriber_Set &); - // Copy. - - Subscriber_Set consumers_; - // All the consumers that have registered for this event. - - RtecScheduler::Dependency_Info *dependency_info_; - // Description of the method that generates this event. - }; - - typedef RtecEventComm::EventType EXT; - typedef Type_Subscribers *INT; - typedef ACE_Null_Mutex SYNCH; - typedef ACE_Map_Manager<EXT, INT, SYNCH> Subscriber_Map; - typedef ACE_Map_Iterator<EXT, INT, SYNCH> Subscriber_Map_Iterator; - typedef ACE_Map_Entry<EXT, INT> Subscriber_Map_Entry; - - Subscriber_Set source_subscribers_; - // Source-based subscribers. - - Subscriber_Map type_subscribers_; - // Type-based subscribers. - - // = These are just typedefs for source-based subscriptions. - typedef RtecEventComm::EventSourceID sEXT; - typedef Subscriber_Set *sINT; - typedef ACE_Map_Manager<sEXT, sINT, SYNCH> SourceID_Map; - typedef ACE_Map_Iterator<sEXT, sINT, SYNCH> SourceID_Map_Iterator; - typedef ACE_Map_Entry<sEXT, sINT> SourceID_Map_Entry; - - ACE_ES_RW_LOCK lock_; - // Serializes writes to source_subscribers_ and type_subscribers_. - - static int insert_or_allocate (SourceID_Map &source_subscribers, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID sid); - // <source_subscribers> contains a mapping of source id to consumer - // list. Insert <consumer> into the list of consumers subscribed to - // <sid>. Allocate a list for <sid> if necessary. - - static int insert_or_allocate (Subscriber_Map &type_subscribers, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type); - // Add <consumer> to the set of consumers bound to <type> in - // <type_subscribers>. If there is consumer set for <type>, one is - // allocated. Returns -1 on failure, 0 otherwise. - - static int insert_or_fail (Subscriber_Map &type_subscribers, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type, - RtecScheduler::Dependency_Info *&dependency); - // Add <consumer> to the set of consumers bound to <type> in - // <type_subscribers>. If there is consumer set for <type>, the - // operation fails. Returns -1 on failure, 0 otherwise. - - static int remove (Subscriber_Map &type_map, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type); - // Remove <consumer> from the consumer set in <type_map> set - // corresponding to <type>. - - static int remove (SourceID_Map &source_subscribers, - ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID sid); - // Remove <consumer> from the consumer set in the - // <source_subscribers> set corresponding to <sid>. - - static void append_subscribers (Subscriber_Set &dest, - Subscriber_Set &src); - // Insert all elements of <src> into <dest>. -}; - -// ************************************************************ - -// Forward declarations. -class ACE_ES_Dispatch_Request; -class ACE_Push_Consumer_Proxy; - -class TAO_ORBSVCS_Export ACE_ES_Consumer_Correlation : public POA_RtecEventComm::PushSupplier -// = TITLE -// Event Service Consumer_Correlation -// -// = DESCRIPTION -// There is one Consumer Correlation object per call to -// connect_push_consumer. It handles all the consumer's -// correlation dependencies including timeouts. This is also a -// PushSupplier to support event forwarding. -{ -public: - ACE_ES_Consumer_Correlation (void); - // Default construction. - - virtual ~ACE_ES_Consumer_Correlation (void); - // Deletes lock_. - - int connected (ACE_Push_Consumer_Proxy *consumer, - ACE_ES_Correlation_Module *correlation_module); - // Initialization. <correlation_module> is stored for delegating - // channel operations. <consumer> is stored to access the consumers - // qos and filterin data. Returns 0 on success, -1 on failure. - - int disconnecting (void); - // Shutdown. - - ACE_ES_Dispatch_Request *push (ACE_ES_Consumer_Rep *consumer, - const TAO_EC_Event& event); - // Takes <event> and adds it to the correlation. Returns the - // dispatch request that should be forwarded. - - void suspend (void); - // Stop forwarding events to the calling consumer. - - void resume (void); - // Resume forwarding events to the calling consumer. - - ACE_ES_Correlation_Module *correlation_module_; - // Pointer back to the main correlation module. This is public so - // that ACE_ES_Consumer_Rep_Timeout::execute can access it. - -private: - virtual void disconnect_push_supplier (CORBA::Environment &); - // Called when the channel disconnects us. - - int allocate_correlation_resources (ACE_ES_Dependency_Iterator &iter); - // Dynamically allocates structures needed for correlations. 0 on - // success, -1 on failure. - - ACE_ES_Dispatch_Request * correlate (ACE_ES_Consumer_Rep *cr, - const TAO_EC_Event& event); - // Helper function for this->push. - - // = Registration helper functions. - int register_deadline_timeout (RtecEventChannelAdmin::Dependency &dependency, - RtecEventComm::EventType group_type, - int cgindex, - int dgindex, - int &trep_index); - int register_interval_timeout (RtecEventChannelAdmin::Dependency &dependency, - RtecEventComm::EventType group_type, - int cgindex, - int dgindex, - int &trep_index); - int register_event (RtecEventChannelAdmin::Dependency &dependency, - RtecEventComm::EventType group_type, - int cgindex, - int dgindex, - int &crep_index); - - ACE_ES_Consumer_Rep *get_consumer_rep (RtecEventChannelAdmin::Dependency &dependency, - int &crep_index); - int new_type_id (void); - - int type_id_index_; - - RtecEventChannelAdmin::ProxyPushConsumer_ptr channel_; - // For event forwarding. - - RtecEventChannelAdmin::SupplierQOS qos_; - // Supplier QOS specifications. - - // Events waiting to be forwarded. - TAO_EC_Event_Array *pending_events_; - - // Used to synchronize pending_events_ and by the correlation module. - ACE_ES_MUTEX lock_; - // Used to lock shared state. - - ACE_Push_Consumer_Proxy *consumer_; - - u_long pending_flags_; - // A bit is set for each dependency satisfied. - - ACE_ES_Consumer_Rep **consumer_reps_; - // Array of consumer rep pointers. - int n_consumer_reps_; - ACE_ES_Consumer_Rep_Timeout *timer_reps_; - int n_timer_reps_; - - ACE_ES_Conjunction_Group *conjunction_groups_; - int n_conjunction_groups_; - ACE_ES_Disjunction_Group *disjunction_groups_; - int n_disjunction_groups_; - - int connected_; - // True when we're connected to the channel for forwarding. -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_ACT -// = TITLE -// Event Service ACT -// -// = DESCRIPTION -// -{ -public: - ACE_ES_ACT (void); - int has_act_; - RtecEventComm::Event act_; -}; - -// ************************************************************ - -// Forward declarations. -class ACE_ES_Dispatch_Request; - -class TAO_ORBSVCS_Export ACE_ES_Consumer_Module : public POA_RtecEventChannelAdmin::ConsumerAdmin -// = TITLE -// Event Service Consumer Module -// -// = DESCRIPTION -// ProxyPushSupplier factory. -{ -public: - ACE_ES_Consumer_Module (ACE_EventChannel *channel); - // Default construction. - - void open (ACE_ES_Dispatching_Module *down); - // Link to the next module. - - virtual RtecEventChannelAdmin::ProxyPushSupplier_ptr obtain_push_supplier (CORBA::Environment &); - // Factory method for push consumer proxies. - - void connected (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &); - // Register the consumer with the Event Service. This handles all - // the details regarding Correlation_Module and Subscription_Module. - - void disconnecting (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &); - // Unregister the consumer from the Event Service. - - virtual void push (const ACE_ES_Dispatch_Request *request, - CORBA::Environment &); - - RtecEventChannelAdmin::ConsumerAdmin_ptr get_ref (CORBA::Environment &); - // Allow transformations to RtecEventChannelAdmin::ConsumerAdmin. - - void shutdown_request (ACE_ES_Dispatch_Request *request); - // This is called by Shutdown_Consumer command objects when a - // consumer proxy is ready to be deleted. - - void shutdown (void); - // Actively disconnect from all consumers. - - void fill_qos (RtecEventChannelAdmin::ConsumerQOS& c_qos); - // Fill the QoS with the disjuction off all the subscriptions in - // this EC. - // It leaves the gateways out of the list. - -private: - typedef ACE_Unbounded_Set_Iterator<ACE_Push_Consumer_Proxy *> Consumer_Iterator; - typedef ACE_Unbounded_Set<ACE_Push_Consumer_Proxy *> Consumers; - - ACE_ES_MUTEX lock_; - // Protects access to all_consumers_. - - Consumers all_consumers_; - - ACE_EventChannel *channel_; - // Used to test for shutdown. - - ACE_ES_Dispatching_Module *down_; - // Next module down. -}; - -// ************************************************************ - -// Forward declaration. -class ACE_ES_Subscription_Module; - -class TAO_ORBSVCS_Export ACE_ES_Correlation_Module -// = TITLE -// Event Service Correlation Module -// -// = DESCRIPTION -// -{ -public: - ACE_ES_Correlation_Module (ACE_EventChannel *channel); - // Default construction. - - void open (ACE_ES_Dispatching_Module *up, - ACE_ES_Subscription_Module *down); - // Link to adjacent modules. - - void connected (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &); - // Create the consumers filter object. - - void disconnecting (ACE_Push_Consumer_Proxy *consumer, - CORBA::Environment &); - // Release the consumers filter object. - - void push (ACE_ES_Consumer_Rep *consumer, - const TAO_EC_Event &event, - CORBA::Environment &); - // Take in an event and its subscriber. Apply consumer-specific - // filters to each event and forward any dispatch requests to the - // Dispatching Module. - - // = These are called by ACE_ES_Consumer_Reps. - - int subscribe (ACE_ES_Consumer_Rep *consumer); - // Forwards to the subscription module. - - int unsubscribe (ACE_ES_Consumer_Rep *consumer); - // Forwards to the subscription module. - - int schedule_timeout (ACE_ES_Consumer_Rep_Timeout *consumer); - // Schedule consumer timeout. Return 0 on success, -1 on failure. - - int cancel_timeout (ACE_ES_Consumer_Rep_Timeout *consumer); - // Cancel consumer timeout. Return 0 on success, -1 on failure. - - int reschedule_timeout (ACE_ES_Consumer_Rep_Timeout *consumer); - // Reschedule consumer timeout. Return 0 on success, -1 on failure. - - ACE_EventChannel *channel_; - // The master channel. This is public so that Consumer_Correlation - // objects can access it. - - void shutdown (void); - // Does nothing. - -private: - ACE_ES_Dispatching_Module *up_; - // Next module up. - - ACE_ES_Subscription_Module *subscription_module_; - // Next module down. -}; - -// ************************************************************ - -// Forward declaration. -class ACE_ES_Supplier_Module; -class ACE_Push_Supplier_Proxy; - -class TAO_ORBSVCS_Export ACE_ES_Subscription_Module -// = TITLE -// Event Service Subscription Module -// -// = DESCRIPTION -// -// = SYNCHRONIZATION -// This is currently implemented with very coarse-grain -// synchronization. Basically, there is a single readers/writer -// lock. All operations acquire the writer lock to change any -// subscription record. All operations acquire a reader lock to -// read any subscription record. This is fine for normal -// operations (which are *all* read operations). However, the -// initialization and shutdown periods might benefit from the -// potential increase in concurrency if we used finer grain locks -// (e.g., lock-per-source). -{ -public: - ACE_ES_Subscription_Module (ACE_EventChannel *channel); - // Default construction. - - void open (ACE_ES_Correlation_Module *up, - ACE_ES_Supplier_Module *down); - // Link to the adjacent modules. - - ~ACE_ES_Subscription_Module (void); - // Deletes the lock_. - - int subscribe (ACE_ES_Consumer_Rep *consumer); - // Register a new consumer. Calls into <consumer> to figure out the - // subscription options. Returns 0 on success, -1 on failure. - - int unsubscribe (ACE_ES_Consumer_Rep *consumer); - // Removes the -consumer- from any subscription lists. - - void connected (ACE_Push_Supplier_Proxy *supplier, - CORBA::Environment &); - void disconnecting (ACE_Push_Supplier_Proxy *supplier, - CORBA::Environment &); - - void push (ACE_Push_Supplier_Proxy *source, - const TAO_EC_Event &event, - CORBA::Environment &); - // Takes in an event and pushes subscriber sets to the - // Correlation Module. - - void shutdown (void); - // Unsubscribes all consumers from the suppliers. - -private: - void reregister_consumers (RtecEventComm::EventSourceID source_id); - // Reregister any consumers that registered for <source_id> before - // it actually connected to the channel. - - ACE_EventChannel *channel_; - // The channel of all channels. - - /* - typedef ACE_ES_Subscription_Info::Subscriber_Set INT; - typedef ACE_Null_Mutex SYNCH; - typedef ACE_Map_Manager<EXT, INT, SYNCH> Source_Collection; - typedef ACE_Map_Iterator<EXT, INT, SYNCH> Source_Collection_Iterator; - typedef ACE_Map_Entry<EXT, INT> Source_Collection_Entry; - Source_Collection source_subscription_info_; - // Source-only subscribers. - */ - - // = Subscribe helper methods. Returns 0 on success, -1 on failure. - - int subscribe_all (ACE_ES_Consumer_Rep *consumer); - - int subscribe_type (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type); - - int subscribe_source (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID source); - - int subscribe_source_type (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID source, - RtecEventComm::EventType type); - - int unsubscribe_all (ACE_ES_Consumer_Rep *consumer); - - int unsubscribe_type (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventType type); - - int unsubscribe_source (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID source); - - int unsubscribe_source_type (ACE_ES_Consumer_Rep *consumer, - RtecEventComm::EventSourceID source, - RtecEventComm::EventType type); - - // = Push helper methods. - - int push_source (ACE_Push_Supplier_Proxy *source, - const TAO_EC_Event &event, - CORBA::Environment &_env); - // Push <event> to all consumers subscribed to all events from - // <source>. Returns 0 on success, -1 on failure. - - int push_source_type (ACE_Push_Supplier_Proxy *source, - const TAO_EC_Event &event, - CORBA::Environment &_env); - // Push <event> to all consumers subscribed to <event>.type_ from - // <source>. Returns 0 on success, -1 on failure. - - void push_all (const TAO_EC_Event &event, - CORBA::Environment &); - // Push <event> to all_suppliers_. - - ACE_ES_Correlation_Module *up_; - // Next module up stream. - - ACE_ES_Supplier_Module *down_; - // Next module down stream. - - typedef ACE_Unbounded_Set_Iterator<ACE_Push_Supplier_Proxy *> Supplier_Iterator; - typedef ACE_Unbounded_Set<ACE_Push_Supplier_Proxy *> Suppliers; - - Suppliers all_suppliers_; - // All suppliers. - - ACE_ES_Subscription_Info::Subscriber_Map type_subscribers_; - // Type-based subscribers. - - ACE_ES_Subscription_Info::SourceID_Map source_subscribers_; - // Source-based subscribers. - - ACE_ES_RW_LOCK lock_; - // Protects access to all_suppliers_ and type_suppliers_; -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_ES_Supplier_Module : public POA_RtecEventChannelAdmin::SupplierAdmin -// = TITLE -// Event Service Supplier Proxy Module -// -// = DESCRIPTION -// ProxyPushConsumer factory. -{ -public: - ACE_ES_Supplier_Module (ACE_EventChannel *channel); - // Default construction. - - void open (ACE_ES_Subscription_Module *up); - // Associate the module to a channel. - - virtual RtecEventChannelAdmin::ProxyPushConsumer_ptr obtain_push_consumer (CORBA::Environment &); - // Factory method for push supplier proxies. - - virtual void push (ACE_Push_Supplier_Proxy *proxy, - RtecEventComm::EventSet &event, - CORBA::Environment &); - // The supplier module acts on behalf of the supplier proxy to - // forward events through the channel. - - void connected (ACE_Push_Supplier_Proxy *supplier, - CORBA::Environment &); - // Register the consumer with the Event Service. This handles all - // the details regarding Correlation_Module and Subscription_Module. - - void disconnecting (ACE_Push_Supplier_Proxy *supplier, - CORBA::Environment &); - // Unregister the consumer from the Event Service. - - RtecEventChannelAdmin::SupplierAdmin_ptr get_ref (CORBA::Environment &); - // Allow transformations to RtecEventComm::PushConsumer. - - void shutdown (void); - // Actively disconnect from all suppliers. - - void fill_qos (RtecEventChannelAdmin::SupplierQOS& s_qos); - // Fill the QoS with the disjuction off all the publications in - // this EC. - // It leaves the gateways out of the list. - -private: - typedef ACE_Unbounded_Set_Iterator<ACE_Push_Supplier_Proxy *> Supplier_Iterator; - typedef ACE_Unbounded_Set<ACE_Push_Supplier_Proxy *> Suppliers; - - Suppliers all_suppliers_; - // All suppliers. - - ACE_ES_MUTEX lock_; - // Protects access to all_suppliers_ and type_suppliers_; - - ACE_ES_Subscription_Module *up_; - - ACE_EventChannel *channel_; - // Used to test for shutdown. -}; - -// ************************************************************ - -// Forward declarations. -class ACE_EventChannel; - -// = Event Channel interfaces. - -class TAO_ORBSVCS_Export ACE_Push_Supplier_Proxy : public POA_RtecEventChannelAdmin::ProxyPushConsumer -// = TITLE -// Push Supplier Proxy. -// -// = DESCRIPTION -// To the channel, this is a proxy to suppliers. To suppliers, it -// exports a PushConsumer interface. It is a -// RtecEventChannelAdmin::ProxyPushConsumer. Suppliers use this -// interface to connect to the channel, push events to consumers, -// and to disconnect from the channel. -{ -public: - ACE_Push_Supplier_Proxy (ACE_ES_Supplier_Module *supplier_module); - // Must be created with an owning supplier admin. - - // = Operations public to suppliers. - - virtual void connect_push_supplier (RtecEventComm::PushSupplier_ptr push_supplier, - const RtecEventChannelAdmin::SupplierQOS& qos, - CORBA::Environment &); - // Suppliers connect via this interface. <push_supplier> is a - // reference to the supplier. <qos> represents the publish types of - // the supplier. - - virtual void push (const RtecEventComm::EventSet &event, - CORBA::Environment &); - // Data arriving from a PushSupplier that must be sent to - // consumers. This is the entry point of all events. - - virtual void disconnect_push_consumer (CORBA::Environment &); - // Disconnect the supplier from the channel. - - // = Operations for the Event Channel. - - RtecEventChannelAdmin::ProxyPushConsumer_ptr get_ref (CORBA::Environment &); - // Allow transformations to RtecEventChannelAdmin::ProxyPushConsumer. - - int connected (void); - // Returns 1 if the proxy has been connected to a "remote" client. - - void shutdown (void); - // Actively disconnect from the supplier. - - // This is a hook so that the Subscription Module can associate - // state with supplier proxies. - ACE_ES_Subscription_Info &subscription_info (void); - - RtecEventChannelAdmin::SupplierQOS &qos (void); - // Filtering criteria. - - int operator== (const RtecEventComm::EventSourceID rhs); - // Is this object a proxy for -rhs-. Simple pointer comparison for now. - - RtecEventComm::EventSourceID source_id (void); - // Returns underlying supplier object ref. - - const RtecEventChannelAdmin::SupplierQOS& qos (void) const; - // The QoS for this supplier - -private: - void time_stamp (RtecEventComm::EventSet &event); - -private: - RtecEventChannelAdmin::SupplierQOS qos_; - // Reference to the supplier's qos params. - - ACE_ES_Subscription_Info subscription_info_; - - ACE_ES_Supplier_Module *supplier_module_; - - RtecEventComm::EventSourceID source_id_; - // We keep a proxy of the Supplier source_id_; - - RtecEventComm::PushSupplier_ptr push_supplier_; - // CORBA reference to remote push supplier. -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_Push_Consumer_Proxy : public POA_RtecEventChannelAdmin::ProxyPushSupplier -// = TITLE -// Push Consumer Proxy. -// -// = DESCRIPTION -// This is the channels proxy to a push consumer. It implements -// the RtecEventChannelAdmin::ProxyPushSupplier IDL interface. -// Consumers use this interface to connect and disconnect from the -// channel. -{ -public: - ACE_Push_Consumer_Proxy (ACE_ES_Consumer_Module *cm); - // Must be created with an consumer admin. - - virtual ~ACE_Push_Consumer_Proxy (void); - // Default destruction - - // = Interfaces exported to consumers. - - virtual void connect_push_consumer (RtecEventComm::PushConsumer_ptr push_consumer, - const RtecEventChannelAdmin::ConsumerQOS& qos, - CORBA::Environment &); - // A push consumer is connecting. <push_consumer> is a reference to - // the consumer. <qos> is the subscription types for the consumer. - - virtual void disconnect_push_supplier (CORBA::Environment &); - // The consumer is disconnecting. - - virtual void suspend_connection (CORBA::Environment &); - // Stop forwarding events to the calling consumer. - - virtual void resume_connection (CORBA::Environment &); - // Resume forwarding events to the calling consumer. - - // = Event Channel operations. - - void push (const RtecEventComm::EventSet &events, - CORBA::Environment &); - // Push <events> to push_consumer_. - - int connected (void); - // Returns 1 if the proxy has been connected to a "remote" client. - - void shutdown (void); - // Actively disconnect from the consumer. - - RtecEventChannelAdmin::ProxyPushSupplier_ptr get_ref (CORBA::Environment &); - // Allow transformations to RtecEventChannelAdmin::ProxyPushSupplier. - - ACE_ES_Consumer_Correlation &correlation (void); - // Access the consumer-specific Consumer_Correlation. - - RtecEventChannelAdmin::ConsumerQOS &qos (void); - // Filtering criteria. - -private: - RtecEventChannelAdmin::ConsumerQOS qos_; - // A reference to the consumers Quality of Service parameters. - - ACE_ES_Consumer_Correlation correlation_; - // A hook so that the Correlation Module can associate correlation - // information with the consumer. - - RtecEventComm::PushConsumer_var push_consumer_; - // Reference to our push consumer. - - ACE_ES_Consumer_Module *consumer_module_; - // TODO: Maybe this should be a _var or _duplicate/_release should - // be used -}; - -#if defined (__ACE_INLINE__) -#include "Event_Channel.i" -#endif /* __ACE_INLINE__ */ - -#endif /* ACE_EVENT_CHANNEL_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Channel.i b/TAO/orbsvcs/orbsvcs/Event/Event_Channel.i deleted file mode 100644 index 710add82135..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Event_Channel.i +++ /dev/null @@ -1,740 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -const unsigned int ACE_INT2BIT[32] = -{ - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, - 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, - 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, - 268435456, 536870912, 1073741824, 2147483648u, -}; - -// ************************************************** - -ACE_INLINE RtecEventChannelAdmin::ProxyPushConsumer_ptr -ACE_Push_Supplier_Proxy::get_ref (CORBA::Environment &env) -{ - return this->_this (env); -} - -ACE_INLINE int -ACE_Push_Supplier_Proxy::connected (void) -{ - return !CORBA::is_nil((CORBA::Object*) push_supplier_); -} - -ACE_INLINE ACE_ES_Subscription_Info & -ACE_Push_Supplier_Proxy::subscription_info (void) -{ - return subscription_info_; -} - -ACE_INLINE RtecEventChannelAdmin::SupplierQOS & -ACE_Push_Supplier_Proxy::qos (void) -{ - return qos_; -} - -ACE_INLINE int -ACE_Push_Supplier_Proxy::operator== (const RtecEventComm::EventSourceID rhs) -{ - // Pointer comparison is fine for now. - return (source_id_ == rhs); -} - -ACE_INLINE RtecEventComm::EventSourceID -ACE_Push_Supplier_Proxy::source_id (void) -{ - return source_id_; -} - -ACE_INLINE const RtecEventChannelAdmin::SupplierQOS& -ACE_Push_Supplier_Proxy::qos (void) const -{ - return this->qos_; -} - -// ************************************************** - -ACE_INLINE RtecEventChannelAdmin::ProxyPushSupplier_ptr -ACE_Push_Consumer_Proxy::get_ref (CORBA::Environment &env) -{ - return this->_this (env); -} - -ACE_INLINE RtecEventChannelAdmin::ConsumerQOS & -ACE_Push_Consumer_Proxy::qos (void) -{ - return qos_; -} - -ACE_INLINE int -ACE_Push_Consumer_Proxy::connected (void) -{ - return !CORBA::is_nil(push_consumer_.in ()); -} - -ACE_INLINE ACE_ES_Consumer_Correlation & -ACE_Push_Consumer_Proxy::correlation (void) -{ - return correlation_; -} - -ACE_INLINE RtecEventChannelAdmin::ConsumerAdmin_ptr -ACE_ES_Consumer_Module::get_ref (CORBA::Environment &env) -{ - return this->_this (env); -} - -ACE_INLINE RtecEventChannelAdmin::SupplierAdmin_ptr -ACE_ES_Supplier_Module::get_ref (CORBA::Environment &env) -{ - return this->_this (env); -} - -// ************************************************** - -ACE_INLINE RtecEventChannelAdmin::EventChannel_ptr -ACE_EventChannel::get_ref (CORBA::Environment &env) -{ - return this->_this (env); -} - -ACE_INLINE RtecEventChannelAdmin::SupplierAdmin_ptr -ACE_EventChannel::for_suppliers (CORBA::Environment &env) -{ - return supplier_module_->get_ref (env); -} - -ACE_INLINE RtecEventChannelAdmin::ConsumerAdmin_ptr -ACE_EventChannel::for_consumers (CORBA::Environment &env) -{ - return consumer_module_->get_ref (env); -} - -ACE_INLINE TAO_EC_Timer_Module* -ACE_EventChannel::timer_module (void) const -{ - return this->timer_module_; -} - -// ************************************************************ - -// Makes a temporary Event_var and appends it to the <dest>. -ACE_INLINE void -operator += (TAO_EC_Event_Array &dest, - const TAO_EC_Event &item) -{ - int length = dest.size (); - dest.size (length + 1); - dest[length] = item; -} - -ACE_INLINE int -operator == (const RtecEventComm::Event &event1, - const RtecEventComm::Event &event2) -{ - // Check if the sources are equal. 0 is a wildcard. - if ((event1.header.source != 0) - && (event2.header.source != 0) - && (event1.header.source != event2.header.source)) - return 0; - - // Check if the types are equal. ACE_ES_EVENT_ANY is a wildcard. - if ((event1.header.type != ACE_ES_EVENT_ANY) && - (event2.header.type != ACE_ES_EVENT_ANY) && - (event1.header.type != event2.header.type)) - return 0; - - return 1; -} - -ACE_INLINE int -operator != (const TAO_EC_Event& rhs, const TAO_EC_Event& lhs) -{ - if (rhs.empty () && lhs.empty ()) - return 1; - if (rhs.empty () || lhs.empty ()) - return 0; - return ! (rhs.event () == lhs.event ()); -} - - - -// ************************************************************ - -ACE_INLINE -ACE_ES_ACT::ACE_ES_ACT (void) - : has_act_ (0) -{ -} - -// ************************************************************ - -ACE_INLINE -ACE_ES_Disjunction_Group::ACE_ES_Disjunction_Group (void) : - act_ (), - deadline_timer_rep_ (0), - correlation_module_ (0) -{ -} - -ACE_INLINE void -ACE_ES_Disjunction_Group::set_correlation_module (ACE_ES_Correlation_Module *cm) -{ - correlation_module_ = cm; -} - -ACE_INLINE void -ACE_ES_Disjunction_Group::reschedule_deadline (void) -{ - if (deadline_timer_rep_ != 0) - { - if (correlation_module_->reschedule_timeout (deadline_timer_rep_) == -1) - ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Disjunction_Group::reschedule_deadline")); - } -} - -ACE_INLINE int -ACE_ES_Disjunction_Group::set_deadline_timeout (ACE_ES_Consumer_Rep_Timeout *cr) -{ - deadline_timer_rep_ = cr; - // Schedule the timeout. - if (correlation_module_->schedule_timeout (deadline_timer_rep_) == -1) - return -1; - else - return 0; -} - -ACE_INLINE void -ACE_ES_Disjunction_Group::add_events (TAO_EC_Event_Array *outbox, - TAO_EC_Event_Array *, - u_long &) -{ - // Append the act. - if (!this->act_.empty ()) - *outbox += this->act_; -} - -ACE_INLINE void -ACE_ES_Disjunction_Group::set_act (RtecEventComm::Event &act) -{ - TAO_EC_Event_Set* set = TAO_EC_Event_Set::_create (act); - if (set == 0) - { - // @@ throw an exception... - ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Disjunction_Group::set_act")); - return; - } - - this->act_ = TAO_EC_Event (set, 0); - TAO_EC_Event_Set::_release (set); -} - -// ************************************************************ - -ACE_INLINE -ACE_ES_Consumer_Rep::ACE_ES_Consumer_Rep (void) : - disconnected_ (0), - suspended_ (0), - correlation_type_ (ACE_ES_Consumer_Rep::NO_CORRELATION), - dependency_ (0), - correlation_ (0), - type_id_ (0), - disjunction_group_ (0), - ref_count_ (1) -{ -} - -ACE_INLINE void -ACE_ES_Consumer_Rep::init (ACE_ES_Consumer_Correlation *correlation, - RtecEventChannelAdmin::Dependency& dependency) -{ - dependency_ = &dependency; - correlation_ = correlation; -} - -ACE_INLINE RtecEventChannelAdmin::Dependency* -ACE_ES_Consumer_Rep::dependency (void) -{ - return dependency_; -} - -ACE_INLINE int -ACE_ES_Consumer_Rep::type_id (void) -{ - return type_id_; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep::type_id (int id) -{ - type_id_ = id; -} - -ACE_INLINE ACE_ES_Consumer_Correlation * -ACE_ES_Consumer_Rep::correlation (void) -{ - return correlation_; -} - -ACE_INLINE u_long -ACE_ES_Consumer_Rep::correlation_type (void) -{ - return correlation_type_; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep::correlation_type (u_long ct) -{ - correlation_type_ = ct; -} - -ACE_INLINE int -ACE_ES_Consumer_Rep::add_disjunction_group (ACE_ES_Disjunction_Group &dg) -{ - if (disjunction_group_ != 0) - ACE_ERROR ((LM_ERROR, "ACE_ES_Consumer_Rep::add_disjunction_group: " - "disjunction_group already set!\n")); - disjunction_group_ = &dg; - return 0; -} - -ACE_INLINE ACE_ES_Disjunction_Group * -ACE_ES_Consumer_Rep::top_group (void) -{ - return disjunction_group_; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep::reschedule_deadlines (void) -{ - if (disjunction_group_ != 0) - disjunction_group_->reschedule_deadline (); -} - -ACE_INLINE int -ACE_ES_Consumer_Rep::receiving_events (void) -{ - return suspended_ == 0 && disconnected_ == 0; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep::suspend (void) -{ - suspended_ = 1; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep::resume (void) -{ - suspended_ = 0; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep::_duplicate (void) -{ - // This is atomic. - ref_count_++; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep::_release (void) -{ - // This is atomic. rc is because we want to avoid Atomic_Op's - // operator==. Don't change this code unless you think you're more - // studly than ACE_Atomic_Op. - int rc = --ref_count_; - - if (rc == 0) - delete this; -} - -ACE_INLINE int -ACE_ES_Consumer_Rep::disconnected (void) -{ - return disconnected_; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep::disconnect (void) -{ - disconnected_ = 1; -} - -// ************************************************************ - -ACE_INLINE ACE_RTU_Manager * -ACE_EventChannel::rtu_manager (void) -{ - return rtu_manager_; -} - -ACE_INLINE -ACE_RTU_Manager::ACE_RTU_Manager (int active) - : active_ (active), - should_preempt_ (0), - not_done_ (0), - priority_ (ACE_Scheduler_MIN_PREEMPTION_PRIORITY) -{ -} - -ACE_INLINE int -ACE_RTU_Manager::should_preempt (void) -{ - if (!active_) - return 0; - else - { - // This routine was dead-code, but I'll leave it here until I - // find out what it is supposed to do. - ACE_ERROR ((LM_WARNING, - "EC (%t) RTU_Manager::should_preempt - obsolete\n")); - - int should_preempt = should_preempt_; - should_preempt_ = 0; - return should_preempt; - } -} - -ACE_INLINE void -ACE_RTU_Manager::should_preempt (int s) -{ - should_preempt_ = s; -} - -ACE_INLINE int -ACE_RTU_Manager::not_done (void) -{ - int not_done = not_done_; - not_done_ = 0; - return not_done; -} - -ACE_INLINE void -ACE_RTU_Manager::not_done (int nd) -{ - not_done_ = nd; -} - -ACE_INLINE RtecScheduler::OS_Priority -ACE_RTU_Manager::priority (void) -{ - return priority_; -} - -ACE_INLINE void -ACE_RTU_Manager::priority (RtecScheduler::OS_Priority p) -{ - priority_ = p; -} - -// ************************************************************ - -ACE_INLINE -ACE_ES_Consumer_Rep_Timeout::ACE_ES_Consumer_Rep_Timeout (void) - : timer_id_ (0), - preemption_priority_ (ACE_Scheduler_MIN_PREEMPTION_PRIORITY), - timeout_event_ () -{ -} - -ACE_INLINE void -ACE_ES_Consumer_Rep_Timeout::init (ACE_ES_Consumer_Correlation *correlation, - RtecEventChannelAdmin::Dependency &dep) -{ - TAO_EC_Event_Set *temp = TAO_EC_Event_Set::_create (dep.event); - // @@ TODO throw an exception - if (temp == 0) - { - ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_ES_Consumer_Rep_Timeout::init")); - return; - } - - this->timeout_event_ = TAO_EC_Event (temp, 0); - TAO_EC_Event_Set::_release (temp); - - ACE_ES_Consumer_Rep::init (correlation, dep); -} - -ACE_INLINE int -ACE_ES_Consumer_Rep_Timeout::timer_id (void) -{ - return timer_id_; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep_Timeout::timer_id (int id) -{ - timer_id_ = id; -} - -ACE_INLINE RtecScheduler::OS_Priority -ACE_ES_Consumer_Rep_Timeout::preemption_priority (void) -{ - return preemption_priority_; -} - -ACE_INLINE void -ACE_ES_Consumer_Rep_Timeout::preemption_priority (RtecScheduler::OS_Priority p) -{ - preemption_priority_ = p; -} - -// ************************************************************ - -ACE_INLINE void -ACE_ES_Consumer_Correlation::suspend (void) -{ - for (int x=0; x < n_timer_reps_; x++) - timer_reps_[x].suspend (); - - for (int y=0; y < n_consumer_reps_; y++) - consumer_reps_[y]->suspend (); -} - -ACE_INLINE void -ACE_ES_Consumer_Correlation::resume (void) -{ - for (int x=0; x < n_timer_reps_; x++) - timer_reps_[x].resume (); - - for (int y=0; y < n_consumer_reps_; y++) - consumer_reps_[y]->resume (); -} - -// ************************************************************ - -ACE_INLINE -ACE_ES_Dependency_Iterator::ACE_ES_Dependency_Iterator (RtecEventChannelAdmin::DependencySet &rep) : - rt_info_ (0), - rep_ (rep), - index_ (-1), - n_conjunctions_ (0), - n_disjunctions_ (0), - n_timeouts_ (0), - n_events_ (0) -{ -} - -ACE_INLINE int -ACE_ES_Dependency_Iterator::advance_dependency (void) -{ - index_++; - if ((CORBA::ULong) index_ >= rep_.length ()) - return -1; - else - return 0; -} - -ACE_INLINE RtecEventChannelAdmin::Dependency & -ACE_ES_Dependency_Iterator::operator *(void) -{ - return rep_[index_]; -} - -ACE_INLINE int -ACE_ES_Dependency_Iterator::parse (void) -{ - for (CORBA::ULong x = 0; x < rep_.length (); x++) - { - if (rt_info_ == 0) - rt_info_ = rep_[x].rt_info; - - switch (rep_[x].event.header.type) - { - case ACE_ES_CONJUNCTION_DESIGNATOR: - n_conjunctions_++; - break; - - case ACE_ES_DISJUNCTION_DESIGNATOR: - n_disjunctions_++; - break; - - case ACE_ES_EVENT_TIMEOUT: - case ACE_ES_EVENT_INTERVAL_TIMEOUT: - case ACE_ES_EVENT_DEADLINE_TIMEOUT: - n_timeouts_++; - break; - - default: - n_events_++; - break; - } - } - - return 0; -} - -ACE_INLINE int -ACE_ES_Dependency_Iterator::n_conjunctions (void) -{ - return n_conjunctions_; -} - -ACE_INLINE int -ACE_ES_Dependency_Iterator::n_disjunctions (void) -{ - return n_disjunctions_; -} - -ACE_INLINE int -ACE_ES_Dependency_Iterator::n_timeouts (void) -{ - return n_timeouts_; -} - -ACE_INLINE int -ACE_ES_Dependency_Iterator::n_events (void) -{ - return n_events_; -} - -ACE_INLINE RtecScheduler::handle_t -ACE_ES_Dependency_Iterator::first_rt_info (void) -{ - return rt_info_; -} - -// ************************************************************ - -ACE_INLINE -ACE_ES_Conjunction_Group::ACE_ES_Conjunction_Group (void) : - forward_value_ (0) -{ -} - -ACE_INLINE int -ACE_ES_Conjunction_Group::add_type (int type_id) -{ - ACE_SET_BITS (forward_value_, ACE_INT2BIT[type_id]); - return 0; -} - -/* - // Set length bits. - for (int x=0; x < length; x++) - { - forward_value_ <<= 1; - forward_value_ |= 1; - } - */ - -ACE_INLINE int -ACE_ES_Conjunction_Group::should_forward (u_long pending_flags) -{ - if ((forward_value_ & pending_flags) == forward_value_) - return 1; - else - return 0; -} - -ACE_INLINE void -ACE_ES_Conjunction_Group::add_events (TAO_EC_Event_Array *outbox, - TAO_EC_Event_Array *pending_events, - u_long &pending_flags) -{ - // Append the act first. - if (!this->act_.empty ()) - *outbox += this->act_; - - u_long fv = forward_value_; - int x = 0; - while (fv > 0) - { - // If this type_id is part of the correlation, then append each - // event pending to the outbox. - if (ACE_BIT_ENABLED (forward_value_, ACE_INT2BIT[x])) - { - // Step through each of the pending events. - TAO_EC_Event_Array &pending = pending_events[x]; - - size_t outbox_end = 0; - if (outbox != 0) - { - outbox_end = outbox->size (); - outbox->size (outbox_end + pending.size ()); - } - for (CORBA::ULong i = 0; i < pending.size (); ++i) - { - if (pending[i].empty ()) - continue; - - // Add the pending event to the outbox. - if (outbox != 0) - outbox->set (pending[i], outbox_end++); - - // Remove the event from the pending events array. - pending[i].clear (); - } - - // Reset the array length. - pending.size (0); - // Since we just emptied the events for this type, clear the - // x^th bit in pending flags. - ACE_CLR_BITS (pending_flags, ACE_INT2BIT[x]); - // Clear the x^th bit in fv. - ACE_CLR_BITS (fv, ACE_INT2BIT[x]); - } - - x++; - } -} - -// ************************************************************ - -ACE_INLINE int -ACE_EventChannel::schedule_timer (RtecScheduler::handle_t rt_info, - const ACE_Command_Base *act, - RtecScheduler::Preemption_Priority_t preemption_priority, - const RtecScheduler::Time &delta, - const RtecScheduler::Time &interval) -{ - if (rt_info != 0) - { - // Add the timer to the task's dependency list. - RtecScheduler::handle_t timer_rtinfo = - this->timer_module ()->rt_info (preemption_priority); - - TAO_TRY - { - ACE_Scheduler_Factory::server()->add_dependency - (rt_info, - timer_rtinfo, - 1, - RtecScheduler::ONE_WAY_CALL, - TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - ACE_ERROR ((LM_ERROR, "add dependency failed")); - } - TAO_ENDTRY; - } - - // @@ We're losing resolution here. - ACE_Time_Value tv_delta; - ORBSVCS_Time::TimeT_to_Time_Value (tv_delta, delta); - - ACE_Time_Value tv_interval; - ORBSVCS_Time::TimeT_to_Time_Value (tv_interval, interval); - - return this->timer_module ()->schedule_timer (preemption_priority, - ACE_const_cast(ACE_Command_Base*,act), - tv_delta, - tv_interval); -} - -ACE_INLINE int -ACE_EventChannel::cancel_timer (RtecScheduler::OS_Priority preemption_priority, - int id, - ACE_Command_Base *&act) -{ - return this->timer_module ()->cancel_timer (preemption_priority, - id, - act); -} - -// ************************************************************ - diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Manip.cpp b/TAO/orbsvcs/orbsvcs/Event/Event_Manip.cpp deleted file mode 100644 index ae15bb3aa32..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Event_Manip.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// TAO Real-tiem Event Services -// -// ============================================================================ - -#include "orbsvcs/Event/Event_Manip.h" - -#if !defined (__ACE_INLINE__) -#include "Event_Manip.i" -#endif /* __ACE_INLINE__ */ - -TAO_EC_Event_Set::~TAO_EC_Event_Set (void) -{ - RtecEventComm::EventSet::freebuf (this->buffer_); - this->buffer_ = 0; - this->length_ = 0; -} - -TAO_EC_Event_Set* -TAO_EC_Event_Set::_create (const RtecEventComm::Event& event) -{ - RtecEventComm::Event* buffer = - RtecEventComm::EventSet::allocbuf (1); - buffer[0] = event; - return new TAO_EC_Event_Set (1, buffer); -} - -TAO_EC_Event_Set* -TAO_EC_Event_Set::_create (RtecEventComm::EventSet& event_set) -{ - // Orphan the buffer.... - CORBA::ULong length = event_set.length (); - return new TAO_EC_Event_Set (length, - event_set.get_buffer (1)); -} - -CORBA::ULong -TAO_EC_Event_Set::_incr_refcnt (void) -{ - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0); - return this->refcnt_++; -} - -CORBA::ULong -TAO_EC_Event_Set::_decr_refcnt (void) -{ - { - ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0); - this->refcnt_--; - if (this->refcnt_ != 0) - return this->refcnt_; - } - - delete this; - return 0; -} - -// **************************************************************** - -TAO_EC_Event::TAO_EC_Event (void) - : event_set_ (0), - index_ (0) -{ -} - -TAO_EC_Event::TAO_EC_Event (TAO_EC_Event_Set *event_set, - CORBA::ULong index) - : event_set_ (TAO_EC_Event_Set::_duplicate (event_set)), - index_ (index) -{ -} - -TAO_EC_Event::~TAO_EC_Event (void) -{ - TAO_EC_Event_Set::_release (this->event_set_); - this->event_set_ = 0; -} - -TAO_EC_Event::TAO_EC_Event (const TAO_EC_Event& rhs) - : event_set_ (TAO_EC_Event_Set::_duplicate (rhs.event_set_)), - index_ (rhs.index_) -{ -} - -TAO_EC_Event& -TAO_EC_Event::operator= (const TAO_EC_Event& rhs) -{ - if (this == &rhs) - return *this; - - // Be careful, increase the reference count and then release our - // event set, just in case they happen to be the same. - TAO_EC_Event_Set* tmp = - TAO_EC_Event_Set::_duplicate (rhs.event_set_); - - TAO_EC_Event_Set::_release (this->event_set_); - this->event_set_ = tmp; - this->index_ = rhs.index_; - - return *this; -} - - - - - diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Manip.h b/TAO/orbsvcs/orbsvcs/Event/Event_Manip.h deleted file mode 100644 index 66a281e7c22..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Event_Manip.h +++ /dev/null @@ -1,146 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// TAO Real-time Event Services -// -// = FILENAME -// Event_Manip -// -// = AUTHOR -// Carlos O'Ryan (coryan@cs.wust.edu) -// -// = DESCRIPTION -// The Event Channel uses some of this classes to simplify its event -// manipulation. -// For instance it keeps a reference counted RtecEventComm::EventSet -// and classes to automatically manage this reference count. -// -// ============================================================================ - -#ifndef TAO_EC_EVENT_MANIP_H -#define TAO_EC_EVENT_MANIP_H - -#include "orbsvcs/RtecEventCommC.h" - -class TAO_ORBSVCS_Export TAO_EC_Event_Set -{ - // = TITLE - // A reference counted RtecEventComm::EventSet - // - // = DESCRIPTION - // The Event_Channel receives an event set from its suppliers, but - // it has to pass it to (potentially) multiple consumers, running - // at different priorities. - // Thus is is difficult to know in advance the life time of this - // EventSet. - // -public: - TAO_EC_Event_Set (CORBA::ULong length, - RtecEventComm::Event* buffer); - // Constructor... - - ~TAO_EC_Event_Set (void); - // destructor - - CORBA::ULong length (void) const; - // The length. - - RtecEventComm::Event& operator[] (CORBA::ULong i) const; - // Access a particular element. - - static TAO_EC_Event_Set* _create (const RtecEventComm::Event&); - static TAO_EC_Event_Set* _create (RtecEventComm::EventSet&); - // Create from an event set. - - static TAO_EC_Event_Set* _duplicate (TAO_EC_Event_Set*); - static void _release (TAO_EC_Event_Set*); - // Reference counting. - -private: - CORBA::ULong _incr_refcnt (void); - CORBA::ULong _decr_refcnt (void); - // Manipulate the reference count. - -private: - ACE_UNIMPLEMENTED_FUNC (TAO_EC_Event_Set (const TAO_EC_Event_Set&)) - ACE_UNIMPLEMENTED_FUNC (TAO_EC_Event_Set& operator= (const TAO_EC_Event_Set&)) - -private: - CORBA::ULong length_; - // The length of the buffer. - - RtecEventComm::Event* buffer_; - // The buffer. - - ACE_SYNCH_MUTEX lock_; - // Synchronize access to the class internals. - - CORBA::ULong refcnt_; - // The reference count. -}; - -class TAO_ORBSVCS_Export TAO_EC_Event -{ - // = TITLE - // A smart event class. - // - // = DESCRIPTION - // Inside the Event Channl a set of events is broken into the - // events that compose it and processed independently. - // To minimize data copying and memory allocations the Event is - // represented as a smart reference to one element of the - // reference counted Event Set (see TAO_EC_Event_Set above). - // Events can be chained together using a cont() field, much like - // ACE_Message_Block. - // -public: - TAO_EC_Event (void); - // Default constructor. - - TAO_EC_Event (TAO_EC_Event_Set *event_set, - CORBA::ULong index); - // Constructor, we assume ownership (i.e. duplicate and release the - // set) - - ~TAO_EC_Event (void); - // Destructor - - TAO_EC_Event (const TAO_EC_Event& event); - TAO_EC_Event& operator= (const TAO_EC_Event& event); - // "Deep" copy, i.e. increases the reference count. - - int empty (void) const; - // Return true if there is no event inside this object. - - void clear (void); - // Release the event... - - RtecEventComm::Event& event (void); - const RtecEventComm::Event& event (void) const; - // The event.. - - // = Shortcuts - RtecEventComm::EventHeader& header (void); - RtecEventComm::EventData& data (void); - const RtecEventComm::EventHeader& header (void) const; - const RtecEventComm::EventData& data (void) const; - - RtecEventComm::EventSourceID source (void) const; - RtecEventComm::EventType type (void) const; - -private: - TAO_EC_Event_Set *event_set_; - // The event set. - - CORBA::ULong index_; - // The position of the event in the set -}; - -#if defined (__ACE_INLINE__) -#include "Event_Manip.i" -#endif /* __ACE_INLINE__ */ - -#endif /* TAO_EC_EVENT_MANIP_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Event_Manip.i b/TAO/orbsvcs/orbsvcs/Event/Event_Manip.i deleted file mode 100644 index 15d2bf13371..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Event_Manip.i +++ /dev/null @@ -1,104 +0,0 @@ -// $Id$ - -ACE_INLINE -TAO_EC_Event_Set::TAO_EC_Event_Set (CORBA::ULong length, - RtecEventComm::Event* buffer) - : length_ (length), - buffer_ (buffer), - refcnt_ (1) -{ -} - -ACE_INLINE CORBA::ULong -TAO_EC_Event_Set::length (void) const -{ - return this->length_; -} - -ACE_INLINE RtecEventComm::Event& -TAO_EC_Event_Set::operator[] (CORBA::ULong i) const -{ - return this->buffer_[i]; -} - -ACE_INLINE TAO_EC_Event_Set* -TAO_EC_Event_Set::_duplicate (TAO_EC_Event_Set* x) -{ - if (x == 0) - return 0; - x->_incr_refcnt (); - return x; -} - -ACE_INLINE void -TAO_EC_Event_Set::_release (TAO_EC_Event_Set* x) -{ - if (x == 0) - return; - x->_decr_refcnt (); -} - - -// **************************************************************** - -ACE_INLINE int -TAO_EC_Event::empty (void) const -{ - return this->event_set_ == 0; -} - -ACE_INLINE void -TAO_EC_Event::clear (void) -{ - TAO_EC_Event_Set::_release (this->event_set_); - this->event_set_ = 0; - this->index_ = 0; -} - -ACE_INLINE RtecEventComm::Event& -TAO_EC_Event::event (void) -{ - return (*this->event_set_)[this->index_]; -} - -ACE_INLINE const RtecEventComm::Event& -TAO_EC_Event::event (void) const -{ - return (*this->event_set_)[this->index_]; -} - -ACE_INLINE RtecEventComm::EventHeader& -TAO_EC_Event::header (void) -{ - return this->event ().header; -} - -ACE_INLINE const RtecEventComm::EventHeader& -TAO_EC_Event::header (void) const -{ - return this->event ().header; -} - -ACE_INLINE RtecEventComm::EventData& -TAO_EC_Event::data (void) -{ - return this->event ().data; -} - -ACE_INLINE const RtecEventComm::EventData& -TAO_EC_Event::data (void) const -{ - return this->event ().data; -} - -ACE_INLINE RtecEventComm::EventSourceID -TAO_EC_Event::source (void) const -{ - return this->event ().header.source; -} - -ACE_INLINE RtecEventComm::EventType -TAO_EC_Event::type (void) const -{ - return this->event ().header.type; -} diff --git a/TAO/orbsvcs/orbsvcs/Event/Fast_Reactor.h b/TAO/orbsvcs/orbsvcs/Event/Fast_Reactor.h deleted file mode 100644 index ced85087e93..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Fast_Reactor.h +++ /dev/null @@ -1,60 +0,0 @@ -// -// $Id$ -// -#ifndef FAST_REACTOR_H -#define FAST_REACTOR_H - -#if defined (ACE_OLD_STYLE_REACTOR) -# if defined (ACE_WIN32) -# include "ace/ReactorEx.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -# define ACE_ES_FAST_REACTOR_BASE ACE_ReactorEx -# else -# include "ace/Reactor.h" -# define ACE_ES_FAST_REACTOR_BASE ACE_Reactor -# endif /* ACE_WIN32 */ -#else -# if defined (ACE_WIN32) -# include "ace/WFMO_Reactor.h" -# define ACE_ES_FAST_REACTOR_BASE ACE_WFMO_Reactor -# else -# include "ace/Select_Reactor.h" -# define ACE_ES_FAST_REACTOR_BASE ACE_Select_Reactor -# endif /* ACE_WIN32 */ -#endif /* ACE_OLD_STYLE_REACTOR */ -//## end module.includes - -#include "orbsvcs/orbsvcs_export.h" - -class TAO_ORBSVCS_Export ACE_ES_Fast_Reactor : public ACE_ES_FAST_REACTOR_BASE -{ -public: - virtual int handle_events (ACE_Time_Value *max_wait_time = 0) - { - ACE_Time_Value timer_buf (0) ; - ACE_Time_Value *this_timeout = &timer_buf ; - - if (this->timer_queue_->calculate_timeout (max_wait_time, - this_timeout) == 0) - { - ACE_Time_Value t (0, 500000); - ACE_OS::select (0, 0, 0, 0, &t); - } - else - { - ACE_OS::select (0, 0, 0, 0, this_timeout); - } - - return this->timer_queue_->expire () == -1 ? -1 : 0; - } - virtual int handle_events (ACE_Time_Value &max_wait_time) - { - return this->handle_events (&max_wait_time); - } -}; - -#endif /* FAST_REACTOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/GPlot_File.cpp b/TAO/orbsvcs/orbsvcs/Event/GPlot_File.cpp deleted file mode 100644 index 8e8b1e90708..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/GPlot_File.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = FILENAME -// GPlot_File.cpp -// -// = AUTHOR -// Tim Harrison -// -// ============================================================================ - -#include "GPlot_File.h" - -#if !defined (__ACE_INLINE__) -#include "GPlot_File.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(Event, GPlot_File, "$Id$") - -int -ACE_GPlot_File::open (const char *filename) -{ - ACE_OS::strcpy (filename_, filename); - - FILE *read_file = ACE_OS::fopen (filename_, "r"); - - long entry; - char *value; - ACE_NEW_RETURN (value, char [32], -1); - - if (read_file > 0) - { - int result; - do - { - result = fscanf (read_file, - "%ld\t%s\n", - &entry, - value); - - //if ((result == -1) && (ACE_OS::last_error () != 0)) - //ACE_ERROR_RETURN ((LM_ERROR, "%p.\n", "ACE_GPlot_File::open"), -1); - - if (result > 0) - // Success. - map_.bind (entry, value); - else if (result != EOF) - // Error. - { - ACE_OS::fclose (read_file); - ACE_ERROR_RETURN - ((LM_ERROR, "Error reading GPlot file %s.\n", filename_), -1); - } - } while (result != EOF); - - fclose (read_file); - } - - write_file_ = ACE_OS::fopen (filename_, "w"); - if (write_file_ == 0) - ACE_ERROR_RETURN ((LM_ERROR, "%p: can't open\n", filename_), -1); - - closed_ = 0; - - return 0; -} - - -void -ACE_GPlot_File::close (void) -{ - if (closed_ == 0) - { - closed_ = 1; - GPLOT_ITERATOR iterator ((GPLOT_MAP &) map_); - for (GPLOT_ENTRY *entry; iterator.next (entry); iterator.advance ()) - { - ACE_OS::fprintf (write_file_, "%ld\t%s\n", - entry->ext_id_, entry->int_id_); - delete [] entry->int_id_; - } - - ACE_OS::fclose (write_file_); - } -} - - -void -ACE_GPlot_File::dump (void) -{ - GPLOT_ITERATOR iterator ((GPLOT_MAP &) map_); - for (GPLOT_ENTRY *entry; iterator.next (entry); iterator.advance ()) - { - if (entry->int_id_ != 0) - ACE_DEBUG ((LM_DEBUG, "%d\t%s\n", entry->ext_id_, entry->int_id_)); - else - { - ACE_ERROR ((LM_ERROR, "Value for entry %d is null.\n", - entry->ext_id_)); - return; - } - } -} - - -int -ACE_GPlot_File::get (long entry, long &value) -{ - char *val; - - if (map_.find (entry, val) == -1) - return -1; - else - { - ::sscanf (val, "%ld", &value); - return 0; - } -} - - -int -ACE_GPlot_File::get (long entry, float &value) -{ - char *val; - - if (map_.find (entry, val) == -1) - return -1; - else - { - ::sscanf (val, "%f", &value); - return 0; - } -} - - -void -ACE_GPlot_File::set (long entry, long value) -{ - long old_entry; - char *val; - char *old_value; - - ACE_NEW (val, char [32]); - - ::sprintf (val, "%ld", value); - map_.rebind (entry, val, old_entry, old_value); - - delete [] old_value; -} - - -void -ACE_GPlot_File::set (long entry, float value) -{ - long old_entry; - char *val; - char *old_value; - - ACE_NEW (val, char [32]); - - ::sprintf (val, "%f", value); - map_.rebind (entry, val, old_entry, old_value); - - delete [] old_value; -} - - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Map_Entry<long, char *>; -template class ACE_Map_Manager<long, char *, ACE_Null_Mutex>; -template class ACE_Map_Iterator_Base<long, char *, ACE_Null_Mutex>; -template class ACE_Map_Iterator<long, char *, ACE_Null_Mutex>; -template class ACE_Map_Reverse_Iterator<long, char *, ACE_Null_Mutex>; -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Map_Entry<long, char *> -#pragma instantiate ACE_Map_Manager<long, char *, ACE_Null_Mutex> -#pragma instantiate ACE_Map_Iterator_Base<long, char *, ACE_Null_Mutex> -#pragma instantiate ACE_Map_Iterator<long, char *, ACE_Null_Mutex> -#pragma instantiate ACE_Map_Reverse_Iterator<long, char *, ACE_Null_Mutex> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/GPlot_File.h b/TAO/orbsvcs/orbsvcs/Event/GPlot_File.h deleted file mode 100644 index c2c6f093f30..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/GPlot_File.h +++ /dev/null @@ -1,102 +0,0 @@ -// $Id$ -// -// ============================================================================ -// -// = FILENAME -// GPlot_File.h -// -// = AUTHOR -// Tim Harrison -// -// ============================================================================ - -#ifndef ACE_GPlot_File_H -#define ACE_GPlot_File_H - -#include "ace/Map_Manager.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/Synch.h" - -class TAO_ORBSVCS_Export ACE_GPlot_File -// = TITLE -// Reads and writes files in GPlot format. -// -// = DESCRIPTION -// Gplot formats are as follows: -// entry value -// entry value -// entry value -// ... -// They represent x,y pairs to be graphed by GPlot. entry's are -// type long. value's are type long or float. -{ -public: - ACE_GPlot_File (void); - // Construction. - - ~ACE_GPlot_File (void); - // Destruction. Calls this->close. - - int open (const char *filename); - // If the file does not exist, create it. If the file exists open - // the file and read all the entries into map_. Returns 0 on - // success, -1 on failure. - - void close (void); - // Close the file and sync all the contents. - - int get (long entry, long &value); - // Get the entry at this value. Returns 0 if a value was found. - // Returns -1 if no value has been set for <entry>. - - int get (long entry, float &value); - // Get the entry at this value. Returns 0 if a value was found. - // Returns -1 if no value has been set for <entry>. - - void set (long entry, long value); - // Set the entry at this value. - - void set (long entry, float value); - // Set the entry at this value. - - void set_greatest (long entry, long value); - // Compare <value> with the value at <entry>. Store the largest. - - void set_greatest (long entry, float value); - // Compare <value> with the value at <entry>. Store the largest. - - void set_least (long entry, long value); - // Compare <value> with the value at <entry>. Store the smallest. - - void set_least (long entry, float value); - // Compare <value> with the value at <entry>. Store the smallest. - - void dump (void); - // Dump state of the object. - -private: - // = map_ stores all values. It is sync'ed to file when this->close - // is called. - typedef ACE_Map_Entry <long, char *> GPLOT_ENTRY; - typedef ACE_Map_Manager<long, char *, ACE_Null_Mutex> GPLOT_MAP; - typedef ACE_Map_Iterator <long, char *, ACE_Null_Mutex> GPLOT_ITERATOR; - - GPLOT_MAP map_; - - char filename_[BUFSIZ]; - FILE *write_file_; - - int closed_; - // Only close once. -}; - -#if defined (__ACE_INLINE__) -#include "GPlot_File.i" -#endif /* __ACE_INLINE__ */ - - -#endif /* ACE_GPlot_File_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/GPlot_File.i b/TAO/orbsvcs/orbsvcs/Event/GPlot_File.i deleted file mode 100644 index ab9f235dc39..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/GPlot_File.i +++ /dev/null @@ -1,70 +0,0 @@ -// $Id$ - -ACE_INLINE -ACE_GPlot_File::ACE_GPlot_File (void) - : closed_ (1) -{ -} - - -ACE_INLINE -ACE_GPlot_File::~ACE_GPlot_File (void) -{ - this->close (); -} - - -ACE_INLINE -void -ACE_GPlot_File::set_greatest (long entry, long value) -{ - long old_value; - - // If there was no previous value, or the <value> is greater than - // the previous value, set a new value. - if (this->get (entry, old_value) == -1 || - value > old_value) - this->set (entry, value); -} - - -ACE_INLINE -void -ACE_GPlot_File::set_greatest (long entry, float value) -{ - float old_value; - - // If there was no previous value, or the <value> is greater than - // the previous value, set a new value. - if (this->get (entry, old_value) == -1 || - value > old_value) - this->set (entry, value); -} - - -ACE_INLINE -void -ACE_GPlot_File::set_least (long entry, long value) -{ - long old_value; - - // If there was no previous value, or the <value> is less than - // the previous value, set a new value. - if (this->get (entry, old_value) == -1 || - value < old_value) - this->set (entry, value); -} - - -ACE_INLINE -void -ACE_GPlot_File::set_least (long entry, float value) -{ - float old_value; - - // If there was no previous value, or the <value> is less than - // the previous value, set a new value. - if (this->get (entry, old_value) == -1 || - value < old_value) - this->set (entry, value); -} diff --git a/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.cpp b/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.cpp deleted file mode 100644 index 10cb9888350..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// -// $Id$ -// - -#include "Local_ESTypes.h" - -#if !defined (__ACE_INLINE__) -#include "Local_ESTypes.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(Event, Local_ESTypes, "$Id$") diff --git a/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.h b/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.h deleted file mode 100644 index 4ba8dbb44c9..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ORB Services -// -// = FILENAME -// Local_ESTypes.h -// -// = AUTHOR -// Tim Harrison (harrison@cs.wustl.edu) -// -// = DESCRIPTION -// Manual types that would otherwise be defined/implemented via an -// IDL compiler. -// NOTE: the file is obsolecent, we have TAO now, but we keep it -// to speed up the porting. -// -// ============================================================================ - -#ifndef ACE_LOCAL_ESTYPES_H -#define ACE_LOCAL_ESTYPES_H - -#include "tao/corba.h" - -#include "orbsvcs/Event_Service_Constants.h" - -#include "orbsvcs/CosNamingC.h" -#include "orbsvcs/RtecSchedulerC.h" -#include "orbsvcs/RtecSchedulerS.h" -#include "orbsvcs/RtecEventCommC.h" -#include "orbsvcs/RtecEventCommS.h" -#include "orbsvcs/RtecEventChannelAdminC.h" -#include "orbsvcs/RtecEventChannelAdminS.h" - -#define ACE_DEFAULT_EVENT_CHANNEL_TYPE 0 - -// These are to help MSVC++ 4.2 deal with inheritence of nested types. -// Not needed for Sun C++ or MSVC++ 5.0. - -typedef RtecEventComm::Event RtecEventComm_Event; - -#if defined (__ACE_INLINE__) -#include "Local_ESTypes.i" -#endif /* __ACE_INLINE__ */ - -#endif /* ACE_LOCAL_ESTYPES_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.i b/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.i deleted file mode 100644 index 8f8ef4cfe2d..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Local_ESTypes.i +++ /dev/null @@ -1,5 +0,0 @@ -/* -*- C++ -*- */ -// -// $Id$ -// - diff --git a/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.cpp b/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.cpp deleted file mode 100644 index 9b0da7996b3..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// $Id$ - -#include "Memory_Pools.h" -#include "Event_Channel.h" - -#if !defined (__ACE_INLINE__) -#include "Memory_Pools.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(Event, Memory_Pools, "$Id$") - -//ACE_TSS<ACE_ES_Dispatch_Request_Allocator> ACE_ES_Memory_Pools::Dispatch_Request_; - -// ************************************************************ - -int -ACE_ES_Memory_Pools::thr_init (void) -{ - // Allocate the memory pool for this thread. - //Dispatch_Request_.ts_object (); - //Event_.ts_object (); - return 0; -} - -// ************************************************************ - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) - -template class ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk>; -template class ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk>, ACE_Null_Mutex>; -template class ACE_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk> >; -template class ACE_Cached_Allocator<ACE_ES_Dispatch_Request_Chunk, ACE_MEMORY_POOL_MUTEX>; -template class ACE_Singleton<ACE_ES_Dispatch_Request_Allocator,ACE_SYNCH_MUTEX>; - -#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) - -#pragma instantiate ACE_Cached_Allocator<ACE_ES_Dispatch_Request_Chunk, ACE_MEMORY_POOL_MUTEX> -#pragma instantiate ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk> -#pragma instantiate ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk>, ACE_Null_Mutex> -#pragma instantiate ACE_Free_List<ACE_Cached_Mem_Pool_Node<ACE_ES_Dispatch_Request_Chunk> > -#pragma instantiate ACE_Singleton<ACE_ES_Dispatch_Request_Allocator,ACE_SYNCH_MUTEX> - -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.h b/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.h deleted file mode 100644 index b246930b37a..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// ORB Services -// -// = FILENAME -// Memory_Pools -// -// = AUTHOR -// Tim Harrison (harrison@cs.wustl.edu) -// -// ============================================================================ - -#ifndef ACE_MEMORY_POOLS_H -#define ACE_MEMORY_POOLS_H - -#include "ace/Synch.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "Event_Channel.h" -#include "Dispatching_Modules.h" - -// ************************************************************ - -#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION) || !defined (ACE_HAS_THREADS) - typedef ACE_Null_Mutex ACE_MEMORY_POOL_MUTEX; -#else - // Use the same object for each thread. Therefore, we have to use - // real synchronization. - typedef ACE_Thread_Mutex ACE_MEMORY_POOL_MUTEX; -#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION || !ACE_HAS_THREADS */ - -typedef char - ACE_ES_Dispatch_Request_Chunk[sizeof (ACE_ES_Dispatch_Request)]; - -typedef ACE_Cached_Allocator<ACE_ES_Dispatch_Request_Chunk, ACE_MEMORY_POOL_MUTEX> - _ACE_Dispatch_Request_Allocator; - -class TAO_ORBSVCS_Export ACE_ES_Dispatch_Request_Allocator : public _ACE_Dispatch_Request_Allocator -// = TITLE -// Dispatch Request Allocator -// -// = DESCRIPTION -// This just sets the size of the Event Container memory pool. -{ -public: - ACE_ES_Dispatch_Request_Allocator (void) : - _ACE_Dispatch_Request_Allocator (ACE_ES_DISPATCH_REQUEST_MEMORY_POOL) {} -}; - -// ************************************************************ - -typedef ACE_Malloc<ACE_LOCAL_MEMORY_POOL, ACE_SYNCH_MUTEX> ACE_ES_Event_Allocator; - -class TAO_ORBSVCS_Export ACE_ES_Memory_Pools -// = TITLE -// Event Service Memory Pools. -// -// = DESCRIPTION -// These have to be static in order to be accessed by operator -// news, right? -{ -public: - static int thr_init (void); - // This can be called by every thread that will access these memory - // pools to preallocate the thread specific allocators. It is not - // mandatory. - - static void *new_Dispatch_Request (void); - static void delete_Dispatch_Request (void *); - - typedef ACE_Singleton<ACE_ES_Dispatch_Request_Allocator,ACE_SYNCH_MUTEX> Dispatch_Request_; -}; - -#if defined (__ACE_INLINE__) -#include "Memory_Pools.i" -#endif /* __ACE_INLINE__ */ - -#endif /* ACE_MEMORY_POOLS_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.i b/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.i deleted file mode 100644 index fe240d52f02..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Memory_Pools.i +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -ACE_INLINE void * -ACE_ES_Memory_Pools::new_Dispatch_Request (void) -{ - return Dispatch_Request_::instance ()->malloc (sizeof (ACE_ES_Dispatch_Request)); -} - -ACE_INLINE void -ACE_ES_Memory_Pools::delete_Dispatch_Request (void *mem) -{ - Dispatch_Request_::instance ()->free (mem); -} diff --git a/TAO/orbsvcs/orbsvcs/Event/Module_Factory.cpp b/TAO/orbsvcs/orbsvcs/Event/Module_Factory.cpp deleted file mode 100644 index 763b40f65c6..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Module_Factory.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// $Id$ - -#include "orbsvcs/Event/Dispatching_Modules.h" -#include "orbsvcs/Event/Timer_Module.h" -#include "orbsvcs/Event/Event_Channel.h" -#include "orbsvcs/Event/Module_Factory.h" - -ACE_RCSID(Event, Module_Factory, "$Id$") - -TAO_Module_Factory::~TAO_Module_Factory (void) -{ -} - -// **************************************************************** - -TAO_Default_Module_Factory::TAO_Default_Module_Factory (void) -{ -} - -TAO_Default_Module_Factory::~TAO_Default_Module_Factory (void) -{ -} - -ACE_ES_Dispatching_Base* -TAO_Default_Module_Factory::create_dispatching_module (ACE_EventChannel* ec) -{ - return new ACE_ES_Priority_Dispatching(ec); -} - -void -TAO_Default_Module_Factory::destroy_dispatching_module (ACE_ES_Dispatching_Base* x) -{ - delete x; -} - -ACE_ES_Consumer_Module* -TAO_Default_Module_Factory::create_consumer_module (ACE_EventChannel* ec) -{ - return new ACE_ES_Consumer_Module (ec); -} - -void -TAO_Default_Module_Factory::destroy_consumer_module (ACE_ES_Consumer_Module* x) -{ - delete x; -} - -ACE_ES_Correlation_Module* -TAO_Default_Module_Factory::create_correlation_module (ACE_EventChannel* ec) -{ - return new ACE_ES_Correlation_Module (ec); -} - -void -TAO_Default_Module_Factory::destroy_correlation_module (ACE_ES_Correlation_Module* x) -{ - delete x; -} - -ACE_ES_Subscription_Module* -TAO_Default_Module_Factory::create_subscription_module (ACE_EventChannel* ec) -{ - return new ACE_ES_Subscription_Module (ec); -} - -void -TAO_Default_Module_Factory::destroy_subscription_module (ACE_ES_Subscription_Module* x) -{ - delete x; -} - -ACE_ES_Supplier_Module* -TAO_Default_Module_Factory::create_supplier_module (ACE_EventChannel* ec) -{ - return new ACE_ES_Supplier_Module (ec); -} - -void -TAO_Default_Module_Factory::destroy_supplier_module (ACE_ES_Supplier_Module* x) -{ - delete x; -} - -TAO_EC_Timer_Module* -TAO_Default_Module_Factory::create_timer_module (ACE_EventChannel* ec) -{ - return new TAO_EC_RPT_Timer_Module; -} - -void -TAO_Default_Module_Factory::destroy_timer_module (TAO_EC_Timer_Module* x) -{ - delete x; -} - -// **************************************************************** - -TAO_Reactive_Module_Factory::TAO_Reactive_Module_Factory (void) -{ -} - -TAO_Reactive_Module_Factory::~TAO_Reactive_Module_Factory (void) -{ -} - -ACE_ES_Dispatching_Base* -TAO_Reactive_Module_Factory::create_dispatching_module (ACE_EventChannel* ec) -{ - return new ACE_ES_EFD_Dispatching(ec); -} - -void -TAO_Reactive_Module_Factory::destroy_dispatching_module (ACE_ES_Dispatching_Base* x) -{ - delete x; -} - -ACE_ES_Consumer_Module* -TAO_Reactive_Module_Factory::create_consumer_module (ACE_EventChannel* ec) -{ - return new ACE_ES_Consumer_Module (ec); -} - -void -TAO_Reactive_Module_Factory::destroy_consumer_module (ACE_ES_Consumer_Module* x) -{ - delete x; -} - -ACE_ES_Correlation_Module* -TAO_Reactive_Module_Factory::create_correlation_module (ACE_EventChannel* ec) -{ - return new ACE_ES_Correlation_Module (ec); -} - -void -TAO_Reactive_Module_Factory::destroy_correlation_module (ACE_ES_Correlation_Module* x) -{ - delete x; -} - -ACE_ES_Subscription_Module* -TAO_Reactive_Module_Factory::create_subscription_module (ACE_EventChannel* ec) -{ - return new ACE_ES_Subscription_Module (ec); -} - -void -TAO_Reactive_Module_Factory::destroy_subscription_module (ACE_ES_Subscription_Module* x) -{ - delete x; -} - -ACE_ES_Supplier_Module* -TAO_Reactive_Module_Factory::create_supplier_module (ACE_EventChannel* ec) -{ - return new ACE_ES_Supplier_Module (ec); -} - -void -TAO_Reactive_Module_Factory::destroy_supplier_module (ACE_ES_Supplier_Module* x) -{ - delete x; -} - -TAO_EC_Timer_Module* -TAO_Reactive_Module_Factory::create_timer_module (ACE_EventChannel*) -{ - return new TAO_EC_ST_Timer_Module (TAO_ORB_Core_instance ()->reactor ()); -} - -void -TAO_Reactive_Module_Factory::destroy_timer_module (TAO_EC_Timer_Module* x) -{ - delete x; -} diff --git a/TAO/orbsvcs/orbsvcs/Event/Module_Factory.h b/TAO/orbsvcs/orbsvcs/Event/Module_Factory.h deleted file mode 100644 index d7fa4abf2b4..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Module_Factory.h +++ /dev/null @@ -1,171 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ -// -// ============================================================================ -// -// = LIBRARY -// TAO services -// -// = FILENAME -// Module_Factory -// -// = AUTHOR -// Carlos O'Ryan -// -// = DESCRIPTION -// The has strategies to handle several phases of the Event -// processing, for instance dispatching can be implemented using -// queues and different threads or just FIFO. -// The choice of the strategies is controlled by a Factory class -// that builds the right modules for the EC. -// -// = TODO -// Some of the strategies are still hard-coded. -// -// ============================================================================ - -#ifndef TAO_MODULE_FACTORY_H -#define TAO_MODULE_FACTORY_H - -#include "orbsvcs/orbsvcs_export.h" - -class ACE_EventChannel; - -class ACE_ES_Dispatching_Base; -class ACE_ES_Consumer_Module; -class ACE_ES_Correlation_Module; -class ACE_ES_Subscription_Module; -class ACE_ES_Supplier_Module; -class ACE_ES_Priority_Timer; -class TAO_EC_Timer_Module; - -class TAO_ORBSVCS_Export TAO_Module_Factory -{ - // = TITLE - // Factory class for the Event Channel "modules". - // - // = DESCRIPTION - // The Event Channel "modules" represent the different phases and - // strategies in event processing. Event Channel configuration is - // achieved by constructing modules with different dynamic - // types. This class encapsulates all the strategies creation in - // a single point. - // -public: - virtual ~TAO_Module_Factory (void); - - virtual ACE_ES_Dispatching_Base* - create_dispatching_module (ACE_EventChannel*) = 0; - virtual void destroy_dispatching_module (ACE_ES_Dispatching_Base*) = 0; - - virtual ACE_ES_Consumer_Module* - create_consumer_module (ACE_EventChannel*) = 0; - virtual void destroy_consumer_module (ACE_ES_Consumer_Module*) = 0; - - virtual ACE_ES_Correlation_Module* - create_correlation_module (ACE_EventChannel*) = 0; - virtual void destroy_correlation_module (ACE_ES_Correlation_Module*) = 0; - - virtual ACE_ES_Subscription_Module* - create_subscription_module (ACE_EventChannel*) = 0; - virtual void destroy_subscription_module (ACE_ES_Subscription_Module*) = 0; - - virtual ACE_ES_Supplier_Module* - create_supplier_module (ACE_EventChannel*) = 0; - virtual void destroy_supplier_module (ACE_ES_Supplier_Module*) = 0; - - virtual TAO_EC_Timer_Module* - create_timer_module (ACE_EventChannel*) = 0; - virtual void destroy_timer_module (TAO_EC_Timer_Module*) = 0; - -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_Default_Module_Factory : public TAO_Module_Factory -{ - // = TITLE - // Default factory class for the Event Channel. - // - // = DESCRIPTION - // The Event Channel "modules" represent the different phases and - // strategies in event processing. Event Channel configuration is - // achieved by constructing modules with different dynamic - // types. This class encapsulates all the strategies creation in - // a single point. - // -public: - TAO_Default_Module_Factory (void); - virtual ~TAO_Default_Module_Factory (void); - - virtual ACE_ES_Dispatching_Base* - create_dispatching_module (ACE_EventChannel*); - virtual void destroy_dispatching_module (ACE_ES_Dispatching_Base*); - - virtual ACE_ES_Consumer_Module* - create_consumer_module (ACE_EventChannel*); - virtual void destroy_consumer_module (ACE_ES_Consumer_Module*); - - virtual ACE_ES_Correlation_Module* - create_correlation_module (ACE_EventChannel*); - virtual void destroy_correlation_module (ACE_ES_Correlation_Module*); - - virtual ACE_ES_Subscription_Module* - create_subscription_module (ACE_EventChannel*); - virtual void destroy_subscription_module (ACE_ES_Subscription_Module*); - - virtual ACE_ES_Supplier_Module* - create_supplier_module (ACE_EventChannel*); - virtual void destroy_supplier_module (ACE_ES_Supplier_Module*); - - virtual TAO_EC_Timer_Module* - create_timer_module (ACE_EventChannel*); - virtual void destroy_timer_module (TAO_EC_Timer_Module*); - -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_Reactive_Module_Factory : public TAO_Module_Factory -{ - // = TITLE - // Factory class for the Event Channel "modules". - // - // = DESCRIPTION - // This class factors out modules that require no extra threads - // for event or timer dispatching. - // An Event Channel configured with this factory can exhibit high - // priority inversion, but it should provide high-performance due - // to the elimination of context switching. - // -public: - TAO_Reactive_Module_Factory (void); - virtual ~TAO_Reactive_Module_Factory (void); - - virtual ACE_ES_Dispatching_Base* - create_dispatching_module (ACE_EventChannel*); - virtual void destroy_dispatching_module (ACE_ES_Dispatching_Base*); - - virtual ACE_ES_Consumer_Module* - create_consumer_module (ACE_EventChannel*); - virtual void destroy_consumer_module (ACE_ES_Consumer_Module*); - - virtual ACE_ES_Correlation_Module* - create_correlation_module (ACE_EventChannel*); - virtual void destroy_correlation_module (ACE_ES_Correlation_Module*); - - virtual ACE_ES_Subscription_Module* - create_subscription_module (ACE_EventChannel*); - virtual void destroy_subscription_module (ACE_ES_Subscription_Module*); - - virtual ACE_ES_Supplier_Module* - create_supplier_module (ACE_EventChannel*); - virtual void destroy_supplier_module (ACE_ES_Supplier_Module*); - - virtual TAO_EC_Timer_Module* - create_timer_module (ACE_EventChannel*); - virtual void destroy_timer_module (TAO_EC_Timer_Module*); - -}; - -#endif /* ACE_EVENT_CHANNEL_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/RT_Task.cpp b/TAO/orbsvcs/orbsvcs/Event/RT_Task.cpp deleted file mode 100644 index d6d0b57a7b5..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/RT_Task.cpp +++ /dev/null @@ -1,484 +0,0 @@ -// $Id$ - -#include "ace/Sched_Params.h" -#include "orbsvcs/Scheduler_Factory.h" -#include "RT_Task.h" -#include "Debug_Macros.h" -#include "Event_Channel.h" -#include "Memory_Pools.h" - -#if !defined (__ACE_INLINE__) -#include "RT_Task.i" -#endif /* __ACE_INLINE__ */ - -#include "tao/Timeprobe.h" - -ACE_RCSID(Event, RT_Task, "$Id$") - -#if defined (ACE_ENABLE_TIMEPROBES) - -static const char *TAO_RT_Task_Timeprobe_Description[] = -{ - "RT_Task - start execute", - "RT_Task - end execute", - "synch_threads - priority requested", - "synch_threads - priority obtained" -}; - -enum -{ - // Timeprobe description table start key - TAO_RT_TASK_START_EXECUTE = 5200, - TAO_RT_TASK_END_EXECUTE, - TAO_RT_TASK_SYNCH_THREADS_PRIORITY_REQUESTED, - TAO_RT_TASK_SYNCH_THREADS_PRIORITY_OBTAINED -}; - -// Setup Timeprobes -ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_RT_Task_Timeprobe_Description, - TAO_RT_TASK_START_EXECUTE); - -#endif /* ACE_ENABLE_TIMEPROBES */ - -class ACE_RT_Task_Shutdown : public ACE_RT_Task_Command -// = TITLE -// Flush Queue Command. -// -// = DESCRIPTION -// This command object will call close on task_. This is used by -// single-threaded tasks to flush any queued messages. -{ -public: - ACE_RT_Task_Shutdown (ACE_ES_TASK *task) - : task_ (task) {} - - virtual int execute (u_long &command_action); - - ACE_ES_TASK *task_; -}; - -int -ACE_RT_Task_Shutdown::execute (u_long &command_action) -{ - ACE_UNUSED_ARG (command_action); - - if (task_ == 0) - return 1; - else - { - task_->close (0); - return 0; - } -} - -// ************************************************************ -// ************************************************************ - -ACE_RT_Task::ACE_RT_Task (void) - : closed_ (0) -{ -} - -ACE_RT_Task::~ACE_RT_Task (void) -{ - msg_queue_->deactivate (); -} - -int -ACE_RT_Task::svc (void) -{ - TAO_TRY - { - // @@ TODO It may be necessary to pass the options to this class - -#if 0 - static char* const argv[] = { - "task", - "-ORBport", "0", - }; - int argc = sizeof (argv)/sizeof (argv[0]); - CORBA::ORB_var orb = - CORBA::ORB_init (argc, argv, "", TAO_TRY_ENV); - TAO_CHECK_ENV; -#endif - - RtecScheduler::OS_Priority thread_priority; - RtecScheduler::Preemption_Subpriority_t subpriority; - RtecScheduler::Preemption_Priority_t preemption_priority; - - ACE_Scheduler_Factory::server ()->priority - (this->rt_info_, - thread_priority, - subpriority, - preemption_priority, TAO_TRY_ENV); - TAO_CHECK_ENV; - if (ACE_OS::thr_setprio (thread_priority) == -1) - { -#if defined (ACE_HAS_STHREADS) - if (thread_priority != 0 || ACE_OS::getuid () == 0) - // Solaris 2.5.1 doesn't allow setting a thread priority to 0 - // in Time Shared scheduling class. Maybe other priorities - // as well? -#endif /* ACE_HAS_STHREADS */ - ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", - "RT_Task thr_setprio failed, " - "this is OK if you don't want RT threads\n")); - - } - - int done = 0; - - ACE_hthread_t self; - ACE_OS::thr_self (self); - - int priority = 0; - if (ACE_OS::thr_getprio (self, priority) == 0) - ACE_DEBUG ((LM_DEBUG, "EC (%t) new thread priority = %d.\n", priority)); - - // Initialize channel thread-specific data. - ACE_ES_Memory_Pools::thr_init (); - - // Update the Scheduler's concept of this thread's rate group. - ACE_Scheduler_Factory::set_preemption_priority (preemption_priority); - - done = this->svc_hook (priority); - - while (!done) - { - done = this->svc_one (); - } - - ACE_DEBUG ((LM_DEBUG, "EC (%t) thread exiting.\n")); - } - TAO_CATCHANY - { - ACE_ERROR_RETURN ((LM_ERROR, "priority failed\n"), -1); - } - TAO_ENDTRY; - - return 0; -} - -int -ACE_RT_Task::svc_hook (RtecScheduler::OS_Priority) -{ - return 0; -} - -int -ACE_RT_Task::svc_one (void) -{ - // Dequeue the command. - ACE_Message_Block *mb; - - if (this->getq (mb) == -1) - { - if (ACE_OS::last_error () == ESHUTDOWN) - return 1; - else - // We'll continue in spite of this error. - ACE_ERROR ((LM_ERROR, "%p (%t) getq error.\n", "ACE_RT_Task::svc_one")); - } - - // Execute the command. - ACE_RT_Task_Command *command = (ACE_RT_Task_Command *) mb; - - int result; - u_long command_action = ACE_RT_Task_Command::RELEASE; - - { - ACE_FUNCTION_TIMEPROBE (TAO_RT_TASK_START_EXECUTE); - - // @@ Put exception handling around this! - result = command->execute (command_action); - } - - switch (command_action) - { - case ACE_RT_Task_Command::RELEASE: - // Free the message block. - if (ACE_RT_Task_Command::release (command) != 0) - ACE_ERROR ((LM_ERROR, "ACE_RT_Task::svc_one: " - "ACE_RT_Task_Command::release returned != 0!\n")); - break; - - case ACE_RT_Task_Command::UNGETQ: - this->ungetq (command); - break; - } - - return result; -} - -// A thread has exited. -int -ACE_RT_Task::close (u_long) -{ - // If we're the last one out, call threads_closed. - if (thr_count_ == 0) - this->threads_closed (); - - return 0; -} - -// All threads have exited. -void -ACE_RT_Task::threads_closed (void) -{ -} - -int -ACE_RT_Task::open_task (const char* name) -{ - const char *tempname = name; - char tempbuffer[64]; - if (tempname == 0) - { - ACE_OS::sprintf (tempbuffer, "unnamed task %d", (long) this); - tempname = tempbuffer; - } - - TAO_TRY - { - rt_info_ = - ACE_Scheduler_Factory::server()->create (tempname, - TAO_TRY_ENV); - TAO_CHECK_ENV; - // @@ TODO: We do no initialization of the new rt_info, the - // caller does, this is (IMnsHO) very error prone. - } - TAO_CATCH (RtecScheduler::DUPLICATE_NAME, dn_ex) - { - // @@ TODO: Its already registered, IMHO this should at least - // report a warning, but I'll stick to the previous code. - // ACE_ERROR_RETURN ((LM_WARNING, - // "RT_Info for %s was already createn", - // tempname), 0); - return 0; - } - TAO_ENDTRY; - - return 0; -} - -int -ACE_RT_Task::try_put (ACE_Message_Block *mb) -{ - if (!closed_) - { - return this->msg_queue ()->enqueue_prio (mb); - } - else - { - errno = EPIPE; - return -1; - } -} - -// The point of this method is to spawn or shutdown threads depending -// on any differences between the task's RT_Info::threads_ and how -// many threads are actually running. -int -ACE_RT_Task::synch_threads (size_t threads) -{ - if (threads > this->thr_count ()) - // Add threads. - { - RtecScheduler::OS_Priority thread_priority; - RtecScheduler::Preemption_Subpriority_t subpriority; - RtecScheduler::Preemption_Priority_t preemption_priority; - - TAO_TRY - { - { - // @@ TODO handle exceptions - ACE_FUNCTION_TIMEPROBE (TAO_RT_TASK_SYNCH_THREADS_PRIORITY_REQUESTED); - ACE_Scheduler_Factory::server ()->priority - (rt_info_, - thread_priority, - subpriority, - preemption_priority, TAO_TRY_ENV); - TAO_CHECK_ENV; - } - - ACE_DEBUG ((LM_DEBUG, "EC (%t) spawning %d threads at os thread" - " priority %d.\n", - threads - this->thr_count (), - thread_priority)); - - // Add the difference. - // First try real-time scheduling with specified priority. - long flags = THR_BOUND | THR_SCHED_FIFO; - if (this->activate (flags, - threads - this->thr_count (), - 1, // Force it to spawn more threads - thread_priority) == -1) - { - // That didn't work. Try default scheduling class with - // the requested priority. - flags = THR_BOUND; - if (this->activate (flags, - threads - this->thr_count (), - 1, // Force it to spawn more threads - thread_priority) == -1) - { - // That didn't work. Finally, try default - // scheduling class with minimum priority. - - // On Linux, for example, only the superuser can set - // the policy to other than ACE_SCHED_OTHER. But - // with ACE_SCHED_OTHER, there is only one thread - // priority value, for example, 0. So, let the - // superuser run an interesting test, but for other - // users use the minimum ACE_SCHED_OTHER thread - // priority. - - RtecScheduler::OS_Priority fallback_priority = - ACE_Sched_Params::priority_min (ACE_SCHED_OTHER, - ACE_SCOPE_THREAD); - - ACE_DEBUG ((LM_DEBUG, - "EC (%t) task activation at priority %d " - "with flags 0x%X failed; retry at priority %d " - "with flags 0x%X\n", - thread_priority, - flags, - fallback_priority, - THR_BOUND)); - - flags = THR_BOUND; - - if (this->activate (flags, - threads - this->thr_count (), - 1, // Force it to spawn more threads - fallback_priority) == -1) - { - ACE_DEBUG ((LM_ERROR, - "EC (%t) thread spawn at priority %d FAILED " - "(errno is %d%p)!!!!\n", - fallback_priority, - errno, - "")); - } - } - } - } - TAO_CATCHANY - { - ACE_ERROR_RETURN ((LM_ERROR, "priority failed\n"), -1); - } - TAO_ENDTRY; - - } - else - // Remove threads. - { - // kill_threads has to be off the stack in case the last thread - // deletes this RT_Task. - int kill_threads = this->thr_count () - threads; - - for (int x = kill_threads ; x > 0; x--) - { - // Create a new shutdown command with a task pointer of 0. - ACE_RT_Task_Shutdown *te = new ACE_RT_Task_Shutdown (0); - - if (te == 0) - return -1; - - ACE_DEBUG ((LM_DEBUG, "EC (%t) enqueueing thread exit.\n")); - if (this->putq (te) == -1) - { - ACE_ERROR ((LM_ERROR, "%p putq failed.\n", - "ACE_RT_Task::synch_threads")); - if (ACE_RT_Task_Shutdown::release (te) != 0) - ACE_ERROR ((LM_ERROR, "ACE_RT_Task::synch_threads: " - "ACE_RT_Task_Shutdown::release returned != 0!\n")); - return -1; - } - } - } - - return 0; -} - - -// If we are not active, we will flush the queue and then call -// this->close. Otherwise, we will send shutdown messages to each -// thread. ~ACE_Task_Exit will call this->close when each thread -// exits. -int -ACE_RT_Task::shutdown_task (void) -{ - // Be sure to only execute this once, and only if we're active. - if (closed_) - return 0; - - // This will keep any messages from entering the queue. - closed_ = 1; - - if (thr_count_ > 0) - return this->synch_threads (0); - else - { - // Create a new flush queue command. We're passive, so pass in - // a reference to the task for which close will be called. - ACE_RT_Task_Shutdown *fq = new ACE_RT_Task_Shutdown (this); - - if (fq == 0) - { - ACE_ERROR ((LM_ERROR, "%p.\n", "ACE_RT_Task::shutdown_threads")); - return -1; - } - - // Enqueue the command. - ACE_DEBUG ((LM_DEBUG, "EC (%t) enqueueing task shutdown.\n")); - if (this->putq (fq) == -1) - { - ACE_ERROR ((LM_ERROR, "%p putq failed.\n", - "ACE_RT_Task::shutdown_task")); - if (ACE_RT_Task_Shutdown::release (fq) != 0) - ACE_ERROR ((LM_ERROR, "ACE_RT_Task::shutdown_task: " - "ACE_RT_Task_Shutdown::release returned != 0!\n")); - return -1; - } - } - - return 0; -} - -// ************************************************************ - -ACE_RT_Thread_Manager::ACE_RT_Thread_Manager (void) - : flags_ (0) -{ -} - -void -ACE_RT_Thread_Manager::suspend_spawns (void) -{ - flags_ |= THR_SUSPENDED; -} - -void -ACE_RT_Thread_Manager::unsuspend_spawns (void) -{ - flags_ = 0; - this->resume_all (); -} - -int -ACE_RT_Thread_Manager::spawn_i (ACE_THR_FUNC func, - void *args, - long flags, - ACE_thread_t *t_id, - ACE_hthread_t *t_handle, - long priority, - int grp_id, - void *stack, - size_t stack_size, - ACE_Task_Base *task) -{ - flags |= flags_; - return ACE_Thread_Manager::spawn_i (func, args, flags, t_id, t_handle, - priority, grp_id, stack, stack_size, task); -} diff --git a/TAO/orbsvcs/orbsvcs/Event/RT_Task.h b/TAO/orbsvcs/orbsvcs/Event/RT_Task.h deleted file mode 100644 index be8fc01ff9e..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/RT_Task.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// ace -// -// = FILENAME -// RT_Task -// -// = AUTHOR -// Tim Harrison (harrison@cs.wustl.edu) -// -// = DESCRIPTION -// Wrapper on top of ACE Task that integrates an Active Object with -// the Event Service. -// -// ============================================================================ - -#ifndef ACE_RT_TASK_H -#define ACE_RT_TASK_H - -#include "ace/Task.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "orbsvcs/RtecSchedulerC.h" - -class TAO_ORBSVCS_Export ACE_RT_Thread_Manager : public ACE_Thread_Manager - // = TITLE - // - // = DESCRIPTION -{ -public: - ACE_RT_Thread_Manager (void); - // Default construction. - - void suspend_spawns (void); - // Any threads spawned will be suspended until <unsuspend_spawns> is - // called. - - void unsuspend_spawns (void); - // Resumes all threads. - -protected: - virtual int spawn_i (ACE_THR_FUNC func, - void *args, - long flags, - ACE_thread_t * = 0, - ACE_hthread_t *t_handle = 0, - long priority = 0, - int grp_id = -1, - void *stack = 0, - size_t stack_size = 0, - ACE_Task_Base *task = 0); - - int flags_; -}; - -// ************************************************************ - -class TAO_ORBSVCS_Export ACE_RT_Task_Command : public ACE_Message_Block -// = TITLE -// -// = DESCRIPTION -{ -public: - virtual ~ACE_RT_Task_Command (void) {} - // Guarantees that derived destructors get called. - - enum { RELEASE, UNGETQ }; - - virtual int execute (u_long &command_action) = 0; - // Execute the command. Returning 1 will make the calling thread - // exit. Returning 0 will allow the thread to continue dispatching - // commands. If <command_action> returns as RELEASE, the command - // will be released. If <command_action> == UNGETQ, then the - // command will be requeued and dispatched again. -}; - -// ************************************************************ - -typedef ACE_Task<ACE_SYNCH> ACE_ES_TASK; -typedef ACE_Message_Queue<ACE_SYNCH> ACE_ES_QUEUE; - -class TAO_ORBSVCS_Export ACE_RT_Task : public ACE_ES_TASK -{ - // = TITLE - // ACE Real-Time Task - // - // = DESCRIPTION - // Real-Time Active Object that integrates with a global - // scheduler and Event Service. For now, none of the management - // methods are synchronized. If it turns out that multiple - // threads will be calling the management methods, then we can - // add synchronization. For the most part, RT_Task threads - // should be dequeueing commands from the message queue. Only - // one thread should be calling any management methods. - friend class ACE_RT_Thread_Manager; -public: - ACE_RT_Task (void); - // Default construction. - - ~ACE_RT_Task (void); - // Deactivates the queue. - - // = Management methods. - - int open_task (const char* name = 0); - // <name> is used to look up our qos info from the scheduler. If - // <name> == 0, then we create a "unique" name and ask the scheduler - // for a new qos structure. If we find an existing qos structure, - // calls this->synch_threads and returns 1. If a qos structure is not - // found, but created returns 0 and does not call synch_threads. - // Returns -1 on failure. - - int try_put (ACE_Message_Block *mb); - // Enqueue a request. Returns 0 on success, -1 on failure. If the - // task is shutdown, -1 is returned with errno == EPIPE. - - int shutdown_task (void); - // If active, shutdown all running thread. Since this is - // accomplished via queued shutdown messages, this has the effect of - // flushing the queue. Once all threads exit, threads_closed will - // be called. If this is a passive object, then the queue will be - // flushed and threads_closed will be called. - - int synch_threads (size_t threads); - // Compare <threads> with what is actually running. If there are - // any differences, update this RT_Task. This may involve spawning - // more threads or changing thread priorities, etc. This can be - // used to close all threads by sending a 0. - - RtecScheduler::handle_t rt_info (void); - // QOS accessor. The behavior of the task can be changed by setting - // this and then calling this->synch_threads. - - virtual void threads_closed (void); - // Called when every thread has exited. This hook allows - // applications to specify semantics when all threads have exited. - // For instance, the Dispatching Module uses this hook to delete - // itself when an application is shutting down. - - virtual int svc_hook (RtecScheduler::OS_Priority priority); - // This is called the first time the thread is spawned. <priority> - // is the priority of the current thread. If this returns != 1 - // (e.g., 0), the event loop will execute (calling this->svc_one). - // If this returns 1, the event loop will not execute. - - virtual int svc_one (void); - // Call this->getq once and execute the command. Returns the result - // of command->execute (). - -protected: - RtecScheduler::handle_t rt_info_; - // Scheduling characteristics of this active object. - - int closed_; - // Set to 1 when this->shutdown_threads or this->close_queue is - // called. Keeps us from enqueuing more that one shutdown message. - - virtual int svc (void); - // Run by each thread spawned. Each thread dequeues - // ACE_RT_Task_Commands and executes them. - - virtual int close (u_long flags = 0); - // Called each time a thread exits. - - void close_all_threads (void); - // Enqueues shutdown message for every thread in the task. -}; - -#if defined (__ACE_INLINE__) -#include "RT_Task.i" -#endif /* __ACE_INLINE__ */ - -#endif /* ACE_RT_TASK_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/RT_Task.i b/TAO/orbsvcs/orbsvcs/Event/RT_Task.i deleted file mode 100644 index b6b21d50494..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/RT_Task.i +++ /dev/null @@ -1,8 +0,0 @@ -/* -*- C++ -*- */ -// $Id$ - -ACE_INLINE RtecScheduler::handle_t -ACE_RT_Task::rt_info (void) -{ - return rt_info_; -} diff --git a/TAO/orbsvcs/orbsvcs/Event/ReactorTask.cpp b/TAO/orbsvcs/orbsvcs/Event/ReactorTask.cpp deleted file mode 100644 index dfe0b8ae02e..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/ReactorTask.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// $Id$ - -#include "ace/High_Res_Timer.h" -#include "tao/Timeprobe.h" -#include "orbsvcs/Scheduler_Factory.h" - -#include "ReactorTask.h" - -ACE_RCSID(Event, ReactorTask, "$Id$") - -#if defined (ACE_ENABLE_TIMEPROBES) - -static const char *TAO_Reactor_Task_Timeprobe_Description[] = -{ - "Reactor_Task - waiting for events", - "Reactor_Task - events handled" -}; - -enum -{ - // Timeprobe description table start key - TAO_REACTOR_TASK_WAITING_FOR_EVENTS = 5300, - TAO_REACTOR_TASK_EVENTS_HANDLED -}; - -// Setup Timeprobes -ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Reactor_Task_Timeprobe_Description, - TAO_REACTOR_TASK_WAITING_FOR_EVENTS); - -#endif /* ACE_ENABLE_TIMEPROBES */ - -ACE_ES_Reactor_Task::ACE_ES_Reactor_Task() : - // reactor_ (0, &timer_queue_), - done_ (0) -{ - // Change the timer mechanism used by the reactor and the timer - // queue. - timer_queue_.gettimeofday (ACE_OS::gettimeofday); -} - -ACE_ES_Reactor_Task::~ACE_ES_Reactor_Task (void) -{ -} - -int -ACE_ES_Reactor_Task::svc_hook(RtecScheduler::OS_Priority) -{ - // Make ourselves owner of the reactor. - reactor_.owner (ACE_Thread::self()); - return 0; -} - -int -ACE_ES_Reactor_Task::open_reactor (RtecScheduler::Period_t &period) -{ - // Create a name for ourselves using the period. The period is - // in 100 ns units; first convert to usec by dividing by 10. - char temp[64]; - ACE_OS::sprintf (temp, "Reactor_Task-%u.us", period / 10); - - // Open the task. This will query the scheduler for our qos - // structure. - int result = this->open_task (temp); - - switch (result) - { - case -1: - // Error. - ACE_ERROR ((LM_ERROR, "(%t) Scheduler could not find operation %s.\n", - temp)); - return -1; - - case 0: - // @@ TODO handle exceptions - { - TAO_TRY - { - ACE_Scheduler_Factory::server()->set(rt_info_, - RtecScheduler::VERY_HIGH_CRITICALITY, - ORBSVCS_Time::zero, - ORBSVCS_Time::zero, - ORBSVCS_Time::zero, - period, - RtecScheduler::VERY_LOW_IMPORTANCE, - ORBSVCS_Time::zero, - 1, - RtecScheduler::OPERATION, - TAO_TRY_ENV); - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - ACE_ERROR_RETURN ((LM_ERROR, "set failed\n"), -1); - } - TAO_ENDTRY; - } - break; - - case 1: - // Found. - break; - } - - return this->synch_threads (1); -} - -int ACE_ES_Reactor_Task::svc_one() -{ - ACE_TIMEPROBE (" Reactor_Task - waiting for events"); - if (reactor_.handle_events() == -1) - ACE_ERROR ((LM_ERROR, "(%t) %p.\n", "ACE_ES_Reactor_Task::svc")); - ACE_TIMEPROBE (" Reactor_Task - events handled"); - - if (done_) - ACE_DEBUG ((LM_DEBUG, "EC (%t) Timer Task is done.\n")); - - return done_; -} - -void ACE_ES_Reactor_Task::threads_closed() -{ -} - -void ACE_ES_Reactor_Task::shutdown_task() -{ - done_ = 1; - reactor_.notify(); -} - -ACE_ES_Reactor_Task::Reactor& -ACE_ES_Reactor_Task::get_reactor() -{ - return reactor_; -} diff --git a/TAO/orbsvcs/orbsvcs/Event/ReactorTask.h b/TAO/orbsvcs/orbsvcs/Event/ReactorTask.h deleted file mode 100644 index d36eafc72f3..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/ReactorTask.h +++ /dev/null @@ -1,81 +0,0 @@ -// $Id$ - -#if !defined ACE_ReactorTask_H -#define ACE_ReactorTask_H - -// BBM, moved this here from UPSingleProcessorOrb.h -//## begin module.includes preserve=yes -#include "Fast_Reactor.h" -#if defined (ACE_OLD_STYLE_REACTOR) -# define ACE_ORB_REACTOR ACE_ES_Fast_Reactor -#endif /* ACE_OLD_STYLE_REACTOR */ -//## end module.includes - -// Added these. -#include "ace/Timer_Heap.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/Timer_List.h" - -#include "Local_ESTypes.h" -#include "RT_Task.h" - -class TAO_ORBSVCS_Export ACE_ES_Reactor_Task : public ACE_RT_Task -// = TITLE -// Event Service Timer Task -// -// = DESCRIPTION -// An active object that dispatches timers from its own ReactorEx. -{ -public: - // BBM, added this. -#if defined (ACE_OLD_STYLE_REACTOR) - typedef ACE_ORB_REACTOR Reactor; -#else - typedef ACE_Reactor Reactor; -#endif /* ACE_OLD_STYLE_REACTOR */ - - ACE_ES_Reactor_Task(); - // Default construction. - - ~ACE_ES_Reactor_Task(); - // Destruction. - - virtual int svc_hook(RtecScheduler::OS_Priority); - // Assume ownership of the reactor_. - - int open_reactor (RtecScheduler::Period_t &period); - // This is a hack for now. - - virtual int svc_one(); - // Calls reactor_.handle_events until done_ is set. - - void shutdown_task(); - // Sets done_ and notifies the reactor_. - - Reactor &get_reactor(); - // ReactorEx accessor. - - virtual void threads_closed(); - // Deletes this. - -private: - ACE_Timer_List timer_queue_; - // The timer storage mechanism used by reactor_. - -#ifndef ACE_OLD_STYLE_REACTOR - ACE_ES_Fast_Reactor fast_reactor_; - // The timer dispatch mechanism. -#endif /* ! ACE_OLD_STYLE_REACTOR */ - - Reactor reactor_; - // "Public" handle to fast_reactor_. - - sig_atomic_t done_; - // When set, end the event loop. -}; - -#endif /* ACE_ReactorTask_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Timer_Module.cpp b/TAO/orbsvcs/orbsvcs/Event/Timer_Module.cpp deleted file mode 100644 index 3946da1f459..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Timer_Module.cpp +++ /dev/null @@ -1,263 +0,0 @@ -// $Id$ - -#include "ace/Functor.h" - -#include "orbsvcs/orbsvcs/Event/ReactorTask.h" -#include "orbsvcs/orbsvcs/Event/Timer_Module.h" - -#if ! defined (__ACE_INLINE__) -#include "Timer_Module.i" -#endif /* __ACE_INLINE__ */ - -ACE_RCSID(Event, Timer_Module, "$Id$") - -#include "tao/Timeprobe.h" - -#if defined (ACE_ENABLE_TIMEPROBES) -static const char *TAO_Timer_Module_Timeprobe_Description[] = -{ - "Timer_Module - start execute", - "Timer_Module - end execute" -}; - -enum -{ - // Timeprobe description table start key - TAO_EC_TIMER_MODULE_START_EXECUTE = 5400, - TAO_EC_TIMER_MOUDLE_END_EXECUTE -}; - -// Setup Timeprobes -ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Timer_Module_Timeprobe_Description, - TAO_EC_TIMER_MODULE_START_EXECUTE); - -#endif /* ACE_ENABLE_TIMEPROBES */ - -// **************************************************************** - -TAO_EC_Timer_Module::~TAO_EC_Timer_Module (void) -{ -} - -// **************************************************************** - -TAO_EC_ST_Timer_Module::TAO_EC_ST_Timer_Module (ACE_Reactor* r) - : reactor_ (r) -{ -} - -TAO_EC_ST_Timer_Module::~TAO_EC_ST_Timer_Module (void) -{ -} - -void -TAO_EC_ST_Timer_Module::activate (void) -{ -} - -void -TAO_EC_ST_Timer_Module::shutdown (void) -{ - this->reactor_->cancel_timer (&this->timeout_handler_); -} - -RtecScheduler::handle_t -TAO_EC_ST_Timer_Module::rt_info (RtecScheduler::Preemption_Priority_t) -{ - // @@ TODO...... - return 0; -} - -int -TAO_EC_ST_Timer_Module::schedule_timer (RtecScheduler::Preemption_Priority_t, - ACE_Command_Base* act, - const ACE_Time_Value& delta, - const ACE_Time_Value& interval) -{ - return this->reactor_->schedule_timer (&this->timeout_handler_, - ACE_static_cast(void*,act), - delta, interval); -} - -int -TAO_EC_ST_Timer_Module::cancel_timer (RtecScheduler::Preemption_Priority_t, - int id, - ACE_Command_Base*& act) -{ - const void *vp; - - int result = - this->reactor_->cancel_timer (id, &vp); - if (result == 0) - { - ACE_ERROR ((LM_ERROR, "TAO_EC_ST_Timer_Module::cancel_timer: " - "Tried to cancel nonexistent timer.\n")); - act = 0; - } - else - act = ACE_reinterpret_cast (ACE_Command_Base *, - ACE_const_cast (void *, vp)); - - return result; -} - -int -TAO_EC_ST_Timer_Module::register_handler (RtecScheduler::Preemption_Priority_t, - ACE_Event_Handler* eh, - ACE_HANDLE handle) -{ - return this->reactor_->register_handler (eh, handle); -} - -ACE_Reactor* -TAO_EC_ST_Timer_Module::reactor (RtecScheduler::Preemption_Priority_t) -{ - return this->reactor_; -} - -// **************************************************************** - -TAO_EC_RPT_Timer_Module::TAO_EC_RPT_Timer_Module (void) - : shutdown_ (0) -{ - for (int i = 0; i < ACE_Scheduler_MAX_PRIORITIES; ++i) - this->reactorTasks[i] = 0; -} - -TAO_EC_RPT_Timer_Module::~TAO_EC_RPT_Timer_Module (void) -{ - this->shutdown (); - - for (int i = 0; i < ACE_Scheduler_MAX_PRIORITIES; ++i) - { - if (this->reactorTasks[i] != 0) - { - delete this->reactorTasks[i]; - this->reactorTasks[i] = 0; - } - } -} - -void TAO_EC_RPT_Timer_Module::activate (void) -{ - for (int i = 0; i < ACE_Scheduler_MAX_PRIORITIES; ++i) - { - if (this->reactorTasks[i] != 0) - continue; - - // Convert ACE_Scheduler_Rate (it's really a period, not a rate!) - // to a form we can easily work with. - ACE_Time_Value period_tv; - ORBSVCS_Time::TimeT_to_Time_Value (period_tv, ACE_Scheduler_Rates[i]); - - RtecScheduler::Period_t period = period_tv.sec () * 10000000 + - period_tv.usec () * 10; - - ACE_NEW (this->reactorTasks[i], ReactorTask); - - if (!this->shutdown_) - { - this->reactorTasks[i]->thr_mgr (this->ThrMgr ()); - if (this->reactorTasks[i]->open_reactor (period) == -1) - { - ACE_ERROR ((LM_ERROR, "%p\n", - "EC (%t) Timer_Module - open reactor")); - } - } - } -} - -void -TAO_EC_RPT_Timer_Module::shutdown (void) -{ - if (this->shutdown_) - return; - - this->shutdown_ = 1; - for (int i = 0; i < ACE_Scheduler_MAX_PRIORITIES; ++i) - { - if (this->reactorTasks[i] != 0) - this->reactorTasks[i]->shutdown_task (); - this->reactorTasks[i]->get_reactor ().cancel_timer (&this->timeout_handler_); - } - - if (this->ThrMgr ()->wait () == -1) - ACE_ERROR ((LM_DEBUG, "%p\n", "EC (%t) Timer_Module wait")); -} - -RtecScheduler::handle_t -TAO_EC_RPT_Timer_Module::rt_info (RtecScheduler::Preemption_Priority_t priority) -{ - return this->GetReactorTask (priority)->rt_info (); -} - -int -TAO_EC_RPT_Timer_Module::schedule_timer (RtecScheduler::Preemption_Priority_t priority, - ACE_Command_Base* act, - const ACE_Time_Value& delta, - const ACE_Time_Value& interval) -{ - ACE_Reactor& reactor = this->GetReactorTask (priority)->get_reactor (); - return reactor.schedule_timer (&this->timeout_handler_, - ACE_static_cast(void*,act), - delta, interval); -} - -int -TAO_EC_RPT_Timer_Module::cancel_timer (RtecScheduler::Preemption_Priority_t priority, - int id, - ACE_Command_Base*& act) -{ - const void* vp; - ACE_Reactor& reactor = this->GetReactorTask (priority)->get_reactor (); - - int result = - reactor.cancel_timer (id, &vp); - if (result == 0) - { - ACE_ERROR ((LM_ERROR, "TAO_EC_ST_Timer_Module::cancel_timer: " - "Tried to cancel nonexistent timer.\n")); - act = 0; - } - else - act = ACE_reinterpret_cast (ACE_Command_Base *, - ACE_const_cast (void *, vp)); - - return result; -} - -int -TAO_EC_RPT_Timer_Module::register_handler (RtecScheduler::Preemption_Priority_t priority, - ACE_Event_Handler* eh, - ACE_HANDLE handle) -{ - return this->GetReactorTask (priority)->get_reactor ().register_handler (eh, handle); -} - -ACE_Reactor* -TAO_EC_RPT_Timer_Module::reactor (RtecScheduler::Preemption_Priority_t priority) -{ - return &this->GetReactorTask (priority)->get_reactor (); -} - -// **************************************************************** - -int -TAO_EC_Timeout_Handler::handle_timeout (const ACE_Time_Value &, - const void *vp) -{ - ACE_Command_Base *act = ACE_static_cast(ACE_Command_Base*, - ACE_const_cast(void*,vp)); - - if (act == 0) - ACE_ERROR_RETURN ((LM_ERROR, "ACE_ES_Priority_Timer::handle_timeout: " - "received act == 0!!!.\n"), 0); - - { - ACE_FUNCTION_TIMEPROBE (TAO_EVENT_CHANNEL_ES_PRIORITY_QUEUE_START_EXECUTE); - - act->execute (); - } - - return 0; -} diff --git a/TAO/orbsvcs/orbsvcs/Event/Timer_Module.h b/TAO/orbsvcs/orbsvcs/Event/Timer_Module.h deleted file mode 100644 index 0f22e10b8cd..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Timer_Module.h +++ /dev/null @@ -1,202 +0,0 @@ -/* -*- C++ -*- */ -// -// $Id$ -// - -#ifndef TAO_EC_TIMER_MODULE_H -#define TAO_EC_TIMER_MODULE_H - -#include "ace/ACE.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "orbsvcs/Event_Service_Constants.h" -#include "orbsvcs/orbsvcs/Event/RT_Task.h" - -class ACE_Command_Base; - -class TAO_ORBSVCS_Export TAO_EC_Timer_Module -{ - // = TITLE - // The timer managment module. - // - // = DESCRIPTION - // The Event Channel can use several strategies to dispatch - // timers, for instance, it can use the ORB reactor or a pool of - // reactors running at different priorities or a pool of - // Thread_Timer_Queue_Adapters running at different priorities - // also. - // This class is the abstract base class to abstract this - // strategies. - // -public: - virtual ~TAO_EC_Timer_Module (void); - // The dtor - - virtual void activate (void) = 0; - // Activate the threads, it waits until the threads are up and - // running. - - virtual void shutdown (void) = 0; - // Deactivate the threads, it waits until all the threads have - // terminated. - - virtual RtecScheduler::handle_t - rt_info (RtecScheduler::OS_Priority priority) = 0; - // The RT_Info handle for the "task" at <priority> - - virtual int schedule_timer (RtecScheduler::Preemption_Priority_t priority, - ACE_Command_Base* act, - const ACE_Time_Value& delta, - const ACE_Time_Value& interval) = 0; - // Add a timer at the given priority, returns the timer ID. - - virtual int cancel_timer (RtecScheduler::Preemption_Priority_t priority, - int id, - ACE_Command_Base*& act) = 0; - // Add a timer at the given priority. - - virtual int register_handler (RtecScheduler::Preemption_Priority_t priority, - ACE_Event_Handler* eh, - ACE_HANDLE handle) = 0; - // Register a handler????? - - virtual ACE_Reactor* reactor (RtecScheduler::Preemption_Priority_t priority) = 0; - // Obtain the reactor for the given priority. - // @@ This may prove tricky to implement with timer queues not based - // on reactors. -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_EC_Timeout_Handler : public ACE_Event_Handler -{ - // = TITLE - // Event Service Timeout handler. - // - // = DESCRIPTION - // This is used by the Timer_Modules as an adaptor between the - // reactor (Event_Handler) and the Command objects. - // -public: - TAO_EC_Timeout_Handler (void); - // Default construction. - -private: - virtual int handle_timeout (const ACE_Time_Value &tv, - const void *act); - // Casts <act> to ACE_Command_Base and calls execute. -}; - -// **************************************************************** - -class TAO_ORBSVCS_Export TAO_EC_ST_Timer_Module : public TAO_EC_Timer_Module -{ - // = TITLE - // A single threaded implementation for the timer module. - // - // = DESCRIPTION - // This timer module uses a single Reactor to implement the timer, - // usually the ORB reactor is used for this purposes. - // -public: - TAO_EC_ST_Timer_Module (ACE_Reactor* reactor); - // The ctor. - - virtual ~TAO_EC_ST_Timer_Module (void); - // The dtor - - // = The TAO_EC_Timer_Module methods. - virtual void activate (void); - virtual void shutdown (void); - virtual RtecScheduler::handle_t - rt_info (RtecScheduler::Preemption_Priority_t priority); - virtual int schedule_timer (RtecScheduler::Preemption_Priority_t priority, - ACE_Command_Base* act, - const ACE_Time_Value& delta, - const ACE_Time_Value& interval); - virtual int cancel_timer (RtecScheduler::Preemption_Priority_t priority, - int id, - ACE_Command_Base*& act); - virtual int register_handler (RtecScheduler::Preemption_Priority_t priority, - ACE_Event_Handler* eh, - ACE_HANDLE handle); - virtual ACE_Reactor* reactor (RtecScheduler::Preemption_Priority_t priority); - -private: - ACE_Reactor* reactor_; - // The reactor. - - TAO_EC_Timeout_Handler timeout_handler_; - // To receive the timeouts. -}; - -// **************************************************************** - -class ACE_ES_Reactor_Task; - -class TAO_ORBSVCS_Export TAO_EC_RPT_Timer_Module : public TAO_EC_Timer_Module -{ - // - // = TITLE - // A timer module using reactor-per-thread. - // - // = DESCRIPTION - // This Timer Module uses a pool of ACE_ReactorTask to handle the - // dispatching of timeouts. In real-time multi-threaded enviroments - // each Reactor runs at a different priority. - // -public: - TAO_EC_RPT_Timer_Module (void); - // Create the Timer Module - - virtual ~TAO_EC_RPT_Timer_Module (void); - // The dtor also shutdowns the Task_Manager. - - typedef ACE_ES_Reactor_Task ReactorTask; - - ReactorTask* GetReactorTask(RtecScheduler::Preemption_Priority_t priority); - // Obtain the ReactorTask for the given priority. - // The Task must have been created already. - - ACE_RT_Thread_Manager* ThrMgr(); - // Returns a global ThreadManager for the Task pool. - - // = The TAO_EC_Timer_Module methods. - virtual void activate (void); - virtual void shutdown (void); - virtual RtecScheduler::handle_t - rt_info (RtecScheduler::Preemption_Priority_t priority); - virtual int schedule_timer (RtecScheduler::Preemption_Priority_t priority, - ACE_Command_Base* act, - const ACE_Time_Value& delta, - const ACE_Time_Value& interval); - virtual int cancel_timer (RtecScheduler::Preemption_Priority_t priority, - int id, - ACE_Command_Base*& act); - virtual int register_handler (RtecScheduler::Preemption_Priority_t priority, - ACE_Event_Handler* eh, - ACE_HANDLE handle); - virtual ACE_Reactor* reactor (RtecScheduler::Preemption_Priority_t priority); - -private: - int shutdown_; - // The reactors are shutdown, do not attempt to restart them. - - ReactorTask *reactorTasks[ACE_Scheduler_MAX_PRIORITIES]; - // The set of ReactorTasks - - ACE_RT_Thread_Manager thr_mgr; - // The thread manager. - - TAO_EC_Timeout_Handler timeout_handler_; - // To receive the timeouts. -}; - -#if defined (__ACE_INLINE__) -#include "Timer_Module.i" -#endif /* __ACE_INLINE__ */ - -#endif /* TAO_EC_TIMER_MODULE_H */ diff --git a/TAO/orbsvcs/orbsvcs/Event/Timer_Module.i b/TAO/orbsvcs/orbsvcs/Event/Timer_Module.i deleted file mode 100644 index 0ea11e7dbc0..00000000000 --- a/TAO/orbsvcs/orbsvcs/Event/Timer_Module.i +++ /dev/null @@ -1,32 +0,0 @@ -// -// $Id$ -// - -ACE_INLINE TAO_EC_RPT_Timer_Module::ReactorTask* -TAO_EC_RPT_Timer_Module::GetReactorTask(RtecScheduler::Preemption_Priority_t priority) -{ - if (reactorTasks[priority] == 0) - { - this->activate (); - //ACE_ERROR_RETURN ((LM_ERROR, - //"%p no reactor task for priority %d.\n", - //"TAO_EC_RPT_Timer_Module::GetReactor", - //priority), 0); - } - - return reactorTasks[priority]; -} - -ACE_INLINE ACE_RT_Thread_Manager* -TAO_EC_RPT_Timer_Module::ThrMgr() -{ - return &thr_mgr; -} - -// **************************************************************** - -ACE_INLINE -TAO_EC_Timeout_Handler::TAO_EC_Timeout_Handler (void) -{ -} - |