#include <EC_Sched_Filter_Builder.h>
Inheritance diagram for TAO_EC_Sched_Filter_Builder:
Public Member Functions | |
TAO_EC_Sched_Filter_Builder (TAO_EC_Event_Channel_Base *ec) | |
constructor. | |
virtual | ~TAO_EC_Sched_Filter_Builder (void) |
destructor... | |
TAO_EC_Filter * | build (TAO_EC_ProxyPushSupplier *supplier, RtecEventChannelAdmin::ConsumerQOS &qos) const |
Private Member Functions | |
TAO_EC_Filter * | recursive_build (TAO_EC_ProxyPushSupplier *supplier, RtecEventChannelAdmin::ConsumerQOS &qos, CORBA::ULong &pos, RtecScheduler::Scheduler_ptr scheduler, RtecScheduler::handle_t parent_info) const |
Recursively build the filter tree. | |
void | recursive_name (RtecEventChannelAdmin::ConsumerQOS &qos, CORBA::ULong &pos, RtecScheduler::Scheduler_ptr scheduler, ACE_CString &name) const |
Build the name recursively... | |
CORBA::ULong | count_children (RtecEventChannelAdmin::ConsumerQOS &qos, CORBA::ULong pos) const |
Private Attributes | |
TAO_EC_Event_Channel_Base * | event_channel_ |
The event channel. |
The sched filtering mechanisms in the Event channel (source/type based filtering + disjunctions and conjunctions) are constructed using this class.
Definition at line 42 of file EC_Sched_Filter_Builder.h.
TAO_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE TAO_EC_Sched_Filter_Builder::TAO_EC_Sched_Filter_Builder | ( | TAO_EC_Event_Channel_Base * | ec | ) |
constructor.
Definition at line 9 of file EC_Sched_Filter_Builder.inl.
00010 : event_channel_ (ec) 00011 { 00012 }
TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_EC_Sched_Filter_Builder::~TAO_EC_Sched_Filter_Builder | ( | void | ) | [virtual] |
TAO_EC_Filter * TAO_EC_Sched_Filter_Builder::build | ( | TAO_EC_ProxyPushSupplier * | supplier, | |
RtecEventChannelAdmin::ConsumerQOS & | qos | |||
) | const [virtual] |
Create the filter, the caller must assume ownership of the filter returned.
Implements TAO_EC_Filter_Builder.
Definition at line 27 of file EC_Sched_Filter_Builder.cpp.
References event_channel_, TAO_Pseudo_Var_T< T >::in(), recursive_build(), and TAO_EC_Event_Channel_Base::scheduler().
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 }
CORBA::ULong TAO_EC_Sched_Filter_Builder::count_children | ( | RtecEventChannelAdmin::ConsumerQOS & | qos, | |
CORBA::ULong | pos | |||
) | const [private] |
Count the number of children of the current node, i.e. until a conjunction or disjunction starts.
Definition at line 289 of file EC_Sched_Filter_Builder.cpp.
References ACE_ES_CONJUNCTION_DESIGNATOR, ACE_ES_DISJUNCTION_DESIGNATOR, and RtecEventChannelAdmin::ConsumerQOS::dependencies.
Referenced by recursive_build(), and recursive_name().
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 }
TAO_EC_Filter * TAO_EC_Sched_Filter_Builder::recursive_build | ( | TAO_EC_ProxyPushSupplier * | supplier, | |
RtecEventChannelAdmin::ConsumerQOS & | qos, | |||
CORBA::ULong & | pos, | |||
RtecScheduler::Scheduler_ptr | scheduler, | |||
RtecScheduler::handle_t | parent_info | |||
) | const [private] |
Recursively build the filter tree.
Definition at line 48 of file EC_Sched_Filter_Builder.cpp.
References ACE_ES_CONJUNCTION_DESIGNATOR, ACE_ES_DISJUNCTION_DESIGNATOR, ACE_ES_EVENT_DEADLINE_TIMEOUT, ACE_ES_EVENT_INTERVAL_TIMEOUT, ACE_ES_EVENT_TIMEOUT, ACE_NEW_RETURN, ACE_String_Base< CHAR >::c_str(), count_children(), RtecEventChannelAdmin::ConsumerQOS::dependencies, TAO_EC_Sched_Filter::get_qos_info(), RtecEventComm::Event::header, recursive_name(), TAO_EC_QOS_Info::rt_info, ACE_OS::sprintf(), and RtecBase::TWO_WAY_CALL.
Referenced by build().
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 }
void TAO_EC_Sched_Filter_Builder::recursive_name | ( | RtecEventChannelAdmin::ConsumerQOS & | qos, | |
CORBA::ULong & | pos, | |||
RtecScheduler::Scheduler_ptr | scheduler, | |||
ACE_CString & | name | |||
) | const [private] |
Build the name recursively...
Definition at line 209 of file EC_Sched_Filter_Builder.cpp.
References ACE_ES_CONJUNCTION_DESIGNATOR, ACE_ES_DISJUNCTION_DESIGNATOR, ACE_ES_EVENT_DEADLINE_TIMEOUT, ACE_ES_EVENT_INTERVAL_TIMEOUT, ACE_ES_EVENT_TIMEOUT, count_children(), RtecEventChannelAdmin::ConsumerQOS::dependencies, RtecEventComm::Event::header, and ACE_OS::sprintf().
Referenced by recursive_build().
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 }