EC_Sched_Filter_Builder.cpp

Go to the documentation of this file.
00001 // $Id: EC_Sched_Filter_Builder.cpp 76589 2007-01-25 18:04:11Z elliott_c $
00002 
00003 #include "orbsvcs/Event/EC_Sched_Filter.h"
00004 #include "orbsvcs/Event_Service_Constants.h"
00005 #include "orbsvcs/Event/EC_Sched_Filter_Builder.h"
00006 #include "orbsvcs/Event/EC_Type_Filter.h"
00007 #include "orbsvcs/Event/EC_Conjunction_Filter.h"
00008 #include "orbsvcs/Event/EC_Disjunction_Filter.h"
00009 #include "orbsvcs/Event/EC_Timeout_Filter.h"
00010 #include "orbsvcs/Event/EC_Event_Channel_Base.h"
00011 #include "ace/OS_NS_stdio.h"
00012 
00013 #if ! defined (__ACE_INLINE__)
00014 #include "orbsvcs/Event/EC_Sched_Filter_Builder.inl"
00015 #endif /* __ACE_INLINE__ */
00016 
00017 ACE_RCSID(Event, EC_Sched_Filter_Builder, "$Id: EC_Sched_Filter_Builder.cpp 76589 2007-01-25 18:04:11Z elliott_c $")
00018 
00019 
00020 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00021 
00022 TAO_EC_Sched_Filter_Builder::~TAO_EC_Sched_Filter_Builder (void)
00023 {
00024 }
00025 
00026 TAO_EC_Filter*
00027 TAO_EC_Sched_Filter_Builder::build (
00028     TAO_EC_ProxyPushSupplier *supplier,
00029     RtecEventChannelAdmin::ConsumerQOS& qos) const
00030 {
00031   CORBA::ULong pos = 0;
00032   CORBA::Object_var tmp =
00033     this->event_channel_->scheduler ();
00034 
00035   RtecScheduler::Scheduler_var scheduler =
00036     RtecScheduler::Scheduler::_narrow (tmp.in ());
00037 
00038   // @@ How do we figure out which parent???
00039   RtecScheduler::handle_t parent_info =
00040     scheduler->lookup ("Dispatching_Task-250000.us");
00041 
00042   return this->recursive_build (supplier, qos, pos,
00043                                 scheduler.in (),
00044                                 parent_info);
00045 }
00046 
00047 TAO_EC_Filter*
00048 TAO_EC_Sched_Filter_Builder::recursive_build (
00049     TAO_EC_ProxyPushSupplier *supplier,
00050     RtecEventChannelAdmin::ConsumerQOS& qos,
00051     CORBA::ULong& pos,
00052     RtecScheduler::Scheduler_ptr scheduler,
00053     RtecScheduler::handle_t parent_info) const
00054 {
00055   const RtecEventComm::Event& e = qos.dependencies[pos].event;
00056 
00057   if (e.header.type == ACE_ES_CONJUNCTION_DESIGNATOR)
00058     {
00059       CORBA::ULong npos = pos;
00060       ACE_CString name;
00061       this->recursive_name (qos, npos,
00062                             scheduler, name);
00063 
00064       RtecScheduler::handle_t rt_info =
00065         scheduler->create (name.c_str ());
00066 
00067       pos++; // Consume the designator
00068       CORBA::ULong n = this->count_children (qos, pos);
00069 
00070       TAO_EC_Filter** children;
00071       ACE_NEW_RETURN (children, TAO_EC_Filter*[n], 0);
00072       for (CORBA::ULong i = 0; i != n; ++i)
00073         {
00074           children[i] = this->recursive_build (supplier, qos, pos,
00075                                                scheduler,
00076                                                rt_info);
00077         }
00078 
00079       TAO_EC_Sched_Filter *filter;
00080       ACE_NEW_RETURN (filter,
00081                       TAO_EC_Sched_Filter (name.c_str (),
00082                                            rt_info,
00083                                            scheduler,
00084                                            new TAO_EC_Conjunction_Filter(children,
00085                                                                          n),
00086                                            rt_info,
00087                                            parent_info,
00088                                            RtecScheduler::CONJUNCTION),
00089                       0);
00090       TAO_EC_QOS_Info qos_info;
00091       filter->get_qos_info (qos_info);
00092       // @@
00093       return filter;
00094     }
00095 
00096   else if (e.header.type == ACE_ES_DISJUNCTION_DESIGNATOR)
00097     {
00098       CORBA::ULong npos = pos;
00099       ACE_CString name;
00100       this->recursive_name (qos, npos,
00101                             scheduler, name);
00102 
00103       RtecScheduler::handle_t rt_info =
00104         scheduler->create (name.c_str ());
00105 
00106       pos++; // Consume the designator
00107       CORBA::ULong n = this->count_children (qos, pos);
00108 
00109       TAO_EC_Filter** children;
00110       ACE_NEW_RETURN (children, TAO_EC_Filter*[n], 0);
00111       for (CORBA::ULong i = 0; i != n; ++i)
00112         {
00113           children[i] = this->recursive_build (supplier, qos, pos,
00114                                                scheduler,
00115                                                rt_info);
00116         }
00117       TAO_EC_Sched_Filter *filter;
00118       ACE_NEW_RETURN (filter,
00119                       TAO_EC_Sched_Filter (name.c_str (),
00120                                            rt_info,
00121                                            scheduler,
00122                                            new TAO_EC_Disjunction_Filter (children,
00123                                                                           n),
00124                                            rt_info,
00125                                            parent_info,
00126                                            RtecScheduler::DISJUNCTION),
00127                       0);
00128 
00129       TAO_EC_QOS_Info qos_info;
00130       filter->get_qos_info (qos_info);
00131       // @@
00132       return filter;
00133     }
00134 
00135   else if (e.header.type == ACE_ES_EVENT_TIMEOUT
00136            || e.header.type == ACE_ES_EVENT_INTERVAL_TIMEOUT
00137            || e.header.type == ACE_ES_EVENT_DEADLINE_TIMEOUT)
00138     {
00139       pos++;
00140 
00141       // @@ We need a unique name for each timeout, assigned by the
00142       //    application?
00143       char buf[64];
00144       ACE_OS::sprintf (buf, "TIMEOUT:%u",
00145                        static_cast<u_int> ((e.header.creation_time / 10000)));
00146       ACE_CString name = buf;
00147 
00148       TAO_EC_QOS_Info qos_info;
00149       qos_info.rt_info =
00150         scheduler->create (name.c_str ());
00151 
00152       // Convert the time to the proper units....
00153       RtecScheduler::Period_t period =
00154         static_cast<RtecScheduler::Period_t> (e.header.creation_time / 10);
00155 
00156       scheduler->set (qos_info.rt_info,
00157                       RtecScheduler::VERY_LOW_CRITICALITY,
00158                       0, // worst_cast_execution_time
00159                       0, // typical_cast_execution_time
00160                       0, // cached_cast_execution_time
00161                       period,
00162                       RtecScheduler::VERY_LOW_IMPORTANCE,
00163                       0, // quantum
00164                       1, // threads
00165                       RtecScheduler::OPERATION);
00166 
00167       scheduler->add_dependency (qos_info.rt_info,
00168                                  parent_info,
00169                                  1,
00170                                  RtecBase::TWO_WAY_CALL);
00171 
00172       return new TAO_EC_Timeout_Filter (this->event_channel_,
00173                                         supplier,
00174                                         qos_info,
00175                                         e.header.type,
00176                                         e.header.creation_time);
00177     }
00178 
00179   RtecScheduler::handle_t body_info = qos.dependencies[pos].rt_info;
00180 
00181   RtecScheduler::RT_Info_var info =
00182     scheduler->get (body_info);
00183 
00184   ACE_CString name = info->entry_point.in ();
00185   name += "#rep";
00186 
00187   RtecScheduler::handle_t rt_info =
00188     scheduler->create (name.c_str ());
00189 
00190   pos++;
00191   TAO_EC_Sched_Filter *filter;
00192   ACE_NEW_RETURN (filter,
00193                   TAO_EC_Sched_Filter (name.c_str (),
00194                                        rt_info,
00195                                        scheduler,
00196                                        new TAO_EC_Type_Filter (e.header),
00197                                        body_info,
00198                                        parent_info,
00199                                        RtecScheduler::OPERATION),
00200                   0);
00201 
00202   TAO_EC_QOS_Info qos_info;
00203   filter->get_qos_info (qos_info);
00204   // @@
00205   return filter;
00206 }
00207 
00208 void
00209 TAO_EC_Sched_Filter_Builder:: recursive_name (
00210     RtecEventChannelAdmin::ConsumerQOS& qos,
00211     CORBA::ULong& pos,
00212     RtecScheduler::Scheduler_ptr scheduler,
00213     ACE_CString& name) const
00214 {
00215   const RtecEventComm::Event& e = qos.dependencies[pos].event;
00216 
00217   if (e.header.type == ACE_ES_CONJUNCTION_DESIGNATOR)
00218     {
00219       pos++; // Consume the designator
00220       CORBA::ULong n = this->count_children (qos, pos);
00221 
00222       for (CORBA::ULong i = 0; i != n; ++i)
00223         {
00224           ACE_CString child_name;
00225           this->recursive_name (qos, pos,
00226                                 scheduler,
00227                                 child_name);
00228 
00229           if (i == 0)
00230             name += "(";
00231           else
00232             name += "&&";
00233           name += child_name;
00234         }
00235       name += ")";
00236       return;
00237     }
00238 
00239   else if (e.header.type == ACE_ES_DISJUNCTION_DESIGNATOR)
00240     {
00241       pos++; // Consume the designator
00242       CORBA::ULong n = this->count_children (qos, pos);
00243 
00244       for (CORBA::ULong i = 0; i != n; ++i)
00245         {
00246           ACE_CString child_name;
00247 
00248           this->recursive_name (qos, pos,
00249                                 scheduler,
00250                                 child_name);
00251 
00252           if (i == 0)
00253             name += "(";
00254           else
00255             name += "||";
00256           name += child_name;
00257         }
00258       name += ")";
00259       return;
00260     }
00261 
00262   else if (e.header.type == ACE_ES_EVENT_TIMEOUT
00263            || e.header.type == ACE_ES_EVENT_INTERVAL_TIMEOUT
00264            || e.header.type == ACE_ES_EVENT_DEADLINE_TIMEOUT)
00265     {
00266       pos++;
00267 
00268       char buf[64];
00269       ACE_OS::sprintf (buf, "TIMEOUT:%u",
00270                        static_cast<u_int> ((e.header.creation_time / 10000)));
00271       name = buf;
00272 
00273       return;
00274     }
00275 
00276   RtecScheduler::handle_t body_info = qos.dependencies[pos].rt_info;
00277 
00278   RtecScheduler::RT_Info_var info =
00279     scheduler->get (body_info);
00280 
00281   name = info->entry_point.in ();
00282   name += "#rep";
00283 
00284   pos++;
00285 }
00286 
00287 CORBA::ULong
00288 TAO_EC_Sched_Filter_Builder::
00289     count_children (RtecEventChannelAdmin::ConsumerQOS& qos,
00290                     CORBA::ULong pos) const
00291 {
00292   CORBA::ULong l = qos.dependencies.length ();
00293   CORBA::ULong i;
00294   for (i = pos; i != l; ++i)
00295     {
00296       const RtecEventComm::Event& e = qos.dependencies[i].event;
00297       if (e.header.type == ACE_ES_CONJUNCTION_DESIGNATOR
00298           || e.header.type == ACE_ES_DISJUNCTION_DESIGNATOR)
00299         break;
00300     }
00301   return i - 1;
00302 }
00303 
00304 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:44:06 2010 for TAO_RTEvent by  doxygen 1.4.7