00001
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
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
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++;
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++;
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
00142
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
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,
00159 0,
00160 0,
00161 period,
00162 RtecScheduler::VERY_LOW_IMPORTANCE,
00163 0,
00164 1,
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++;
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++;
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