00001
00002
00003 #include "orbsvcs/Event/EC_Kokyu_Filter.h"
00004 #include "orbsvcs/Event_Service_Constants.h"
00005 #include "orbsvcs/Event/EC_Kokyu_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_Kokyu_Filter_Builder.inl"
00015 #endif
00016
00017 ACE_RCSID (Event,
00018 EC_Kokyu_Filter_Builder,
00019 "$Id: EC_Kokyu_Filter_Builder.cpp 76589 2007-01-25 18:04:11Z elliott_c $")
00020
00021 const char* designator (long dsgn)
00022 {
00023 switch(dsgn)
00024 {
00025 case ACE_ES_GLOBAL_DESIGNATOR: return "GLOBAL";
00026 case ACE_ES_CONJUNCTION_DESIGNATOR: return "CONJ";
00027 case ACE_ES_DISJUNCTION_DESIGNATOR: return "DISJ";
00028 case ACE_ES_NEGATION_DESIGNATOR: return "NEG";
00029 case ACE_ES_LOGICAL_AND_DESIGNATOR: return "LOG_AND";
00030 case ACE_ES_BITMASK_DESIGNATOR: return "BITMASK";
00031 case ACE_ES_MASKED_TYPE_DESIGNATOR: return "MASKED_TYPE";
00032 case ACE_ES_NULL_DESIGNATOR: return "NULL";
00033 }
00034
00035 return "---";
00036 }
00037
00038 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00039
00040 TAO_EC_Kokyu_Filter_Builder::~TAO_EC_Kokyu_Filter_Builder (void)
00041 {
00042 }
00043
00044 TAO_EC_Filter*
00045 TAO_EC_Kokyu_Filter_Builder::build (
00046 TAO_EC_ProxyPushSupplier *supplier,
00047 RtecEventChannelAdmin::ConsumerQOS& qos) const
00048 {
00049 CORBA::ULong i=0,found=0;
00050 CORBA::ULong pos = 0;
00051 CORBA::Long npos = -1;
00052 int establish_final_consumer_dependency=0;
00053
00054 CORBA::Object_var tmp =
00055 this->event_channel_->scheduler ();
00056
00057 RtecScheduler::Scheduler_var scheduler =
00058 RtecScheduler::Scheduler::_narrow (tmp.in ());
00059
00060 #ifdef EC_KOKYU_LOGGING
00061 for (i=0; i<qos.dependencies.length (); ++i)
00062 {
00063 ACE_DEBUG ((LM_DEBUG,
00064 "consumerqos[%d] event.header.type = %s,"
00065 "rt_info = %d\n",
00066 i,
00067 designator (qos.dependencies[i].event.header.type),
00068 qos.dependencies[i].rt_info));
00069 }
00070 #endif
00071
00072
00073
00074
00075 for (i=0; !found && i<qos.dependencies.length (); ++i)
00076 {
00077 switch (qos.dependencies[i].event.header.type)
00078 {
00079 case ACE_ES_CONJUNCTION_DESIGNATOR:
00080 case ACE_ES_DISJUNCTION_DESIGNATOR:
00081 case ACE_ES_NEGATION_DESIGNATOR:
00082 case ACE_ES_LOGICAL_AND_DESIGNATOR:
00083 case ACE_ES_BITMASK_DESIGNATOR:
00084 case ACE_ES_MASKED_TYPE_DESIGNATOR:
00085 case ACE_ES_NULL_DESIGNATOR:
00086 establish_final_consumer_dependency = 1;
00087 continue;
00088
00089 case ACE_ES_GLOBAL_DESIGNATOR:
00090 case ACE_ES_EVENT_TIMEOUT:
00091 case ACE_ES_EVENT_INTERVAL_TIMEOUT:
00092 case ACE_ES_EVENT_DEADLINE_TIMEOUT:
00093 continue;
00094
00095 default:
00096 npos = i;
00097 found = 1;
00098 break;
00099 }
00100 }
00101
00102 ACE_CString final_consumer_rep_name;
00103 RtecScheduler::handle_t h_final_consumer_rt_info = 0;
00104 RtecScheduler::handle_t h_final_consumer_rep_rt_info = 0;
00105
00106 #ifdef EC_KOKYU_LOGGING
00107 ACE_DEBUG ((LM_DEBUG, "consumer rt_info found in consumerqos[%d] \n", npos));
00108 #endif
00109
00110 if (npos >= 0 && establish_final_consumer_dependency == 1)
00111 {
00112
00113 h_final_consumer_rt_info = qos.dependencies[npos].rt_info;
00114
00115 #ifdef EC_KOKYU_LOGGING
00116 ACE_DEBUG ((LM_DEBUG, "about to get rt_info = %d\n",
00117 h_final_consumer_rep_rt_info));
00118 #endif
00119
00120 RtecScheduler::RT_Info_var final_consumer_rt_info =
00121 scheduler->get ( h_final_consumer_rt_info);
00122
00123 final_consumer_rep_name = final_consumer_rt_info->entry_point.in ();
00124 final_consumer_rep_name += "#rep";
00125
00126 #ifdef EC_KOKYU_LOGGING
00127 ACE_DEBUG ((LM_DEBUG, "about to create consumer rep %s\n",
00128 final_consumer_rep_name.c_str ()));
00129 #endif
00130
00131
00132 h_final_consumer_rep_rt_info =
00133 scheduler->create (final_consumer_rep_name.c_str ());
00134 #ifdef EC_KOKYU_LOGGING
00135 ACE_DEBUG ((LM_DEBUG, "consumer rep created\n"));
00136 #endif
00137
00138 }
00139
00140
00141
00142
00143
00144 TAO_EC_Filter* filter =
00145 this->recursive_build (supplier, qos, pos,
00146 scheduler.in (),
00147 h_final_consumer_rep_rt_info
00148 );
00149
00150 #ifdef EC_KOKYU_LOGGING
00151 ACE_DEBUG ((LM_DEBUG,
00152 "Filter_Builder::Verifying whether root filter"
00153 " dependency can be established\n"));
00154 #endif
00155
00156 if (npos >= 0 && establish_final_consumer_dependency == 1)
00157 {
00158 #ifdef EC_KOKYU_LOGGING
00159 ACE_DEBUG ((LM_DEBUG,
00160 "Filter_Builder::root filter dependency "
00161 "can be established\n"));
00162 #endif
00163 TAO_EC_Kokyu_Filter* kokyu_filter =
00164 dynamic_cast<TAO_EC_Kokyu_Filter*> (filter);
00165
00166
00167
00168 TAO_EC_QOS_Info qos_info;
00169 kokyu_filter->get_qos_info (qos_info);
00170
00171 scheduler->add_dependency (h_final_consumer_rt_info,
00172 qos_info.rt_info,
00173 1,
00174 RtecBase::ONE_WAY_CALL);
00175 }
00176 return filter;
00177 }
00178
00179 TAO_EC_Filter*
00180 TAO_EC_Kokyu_Filter_Builder::recursive_build (
00181 TAO_EC_ProxyPushSupplier *supplier,
00182 RtecEventChannelAdmin::ConsumerQOS& qos,
00183 CORBA::ULong& pos,
00184 RtecScheduler::Scheduler_ptr scheduler,
00185 RtecScheduler::handle_t parent_info) const
00186 {
00187 const RtecEventComm::Event& e = qos.dependencies[pos].event;
00188
00189 #ifdef EC_KOKYU_LOGGING
00190 ACE_DEBUG ((LM_DEBUG, "Filter_Builder::In recursive build\n"));
00191 #endif
00192
00193 if (e.header.type == ACE_ES_CONJUNCTION_DESIGNATOR)
00194 {
00195 #ifdef EC_KOKYU_LOGGING
00196 ACE_DEBUG ((LM_DEBUG, "Filter_Builder::Conjuction designator\n"));
00197 #endif
00198 CORBA::ULong npos = pos;
00199 ACE_CString name;
00200 this->recursive_name (qos, npos,
00201 scheduler, name);
00202
00203 pos++;
00204
00205 CORBA::ULong n = this->count_children (qos, pos);
00206
00207 RtecBase::handle_t conj_rt_info = parent_info;
00208
00209 TAO_EC_Filter** children;
00210 ACE_NEW_RETURN (children, TAO_EC_Filter*[n], 0);
00211 for (CORBA::ULong i = 0; i != n; ++i)
00212 {
00213 children[i] = this->recursive_build (supplier, qos, pos,
00214 scheduler,
00215 conj_rt_info);
00216 }
00217
00218 TAO_EC_Kokyu_Filter *filter;
00219 ACE_NEW_RETURN (filter,
00220 TAO_EC_Kokyu_Filter (name.c_str (),
00221 conj_rt_info,
00222 scheduler,
00223 new TAO_EC_Conjunction_Filter(children,
00224 n),
00225 conj_rt_info,
00226 conj_rt_info,
00227 RtecScheduler::CONJUNCTION),
00228 0);
00229 TAO_EC_QOS_Info qos_info;
00230 filter->get_qos_info (qos_info);
00231
00232 return filter;
00233 }
00234
00235 else if (e.header.type == ACE_ES_DISJUNCTION_DESIGNATOR)
00236 {
00237 #ifdef EC_KOKYU_LOGGING
00238 ACE_DEBUG ((LM_DEBUG, "Filter_Builder::Disjunction designator\n"));
00239 #endif
00240 CORBA::ULong npos = pos;
00241 ACE_CString name;
00242 this->recursive_name (qos, npos,
00243 scheduler, name);
00244
00245 pos++;
00246
00247 RtecBase::handle_t disj_rt_info = parent_info;
00248
00249 CORBA::ULong n = this->count_children (qos, pos);
00250
00251 TAO_EC_Filter** children;
00252 ACE_NEW_RETURN (children, TAO_EC_Filter*[n], 0);
00253 for (CORBA::ULong i = 0; i != n; ++i)
00254 {
00255 children[i] = this->recursive_build (supplier, qos, pos,
00256 scheduler,
00257 disj_rt_info);
00258 }
00259 TAO_EC_Kokyu_Filter *filter;
00260 ACE_NEW_RETURN (filter,
00261 TAO_EC_Kokyu_Filter (name.c_str (),
00262 disj_rt_info,
00263 scheduler,
00264 new TAO_EC_Disjunction_Filter (children,
00265 n),
00266 disj_rt_info,
00267 disj_rt_info,
00268 RtecScheduler::DISJUNCTION),
00269 0);
00270
00271 TAO_EC_QOS_Info qos_info;
00272 filter->get_qos_info (qos_info);
00273
00274 return filter;
00275 }
00276 else if (e.header.type == ACE_ES_EVENT_TIMEOUT
00277 || e.header.type == ACE_ES_EVENT_INTERVAL_TIMEOUT
00278 || e.header.type == ACE_ES_EVENT_DEADLINE_TIMEOUT)
00279 {
00280 #ifdef EC_KOKYU_LOGGING
00281 ACE_DEBUG ((LM_DEBUG, "Filter_Builder::Timeout designator\n"));
00282 #endif
00283
00284
00285 char buf[64];
00286
00287
00288 RtecBase::handle_t h_consumer_rt_info = qos.dependencies[pos].rt_info;
00289
00290
00291 ACE_OS::sprintf (buf, "TIMEOUT:%umsec:%d",
00292 static_cast<u_int> ((e.header.creation_time / 10000)),
00293 h_consumer_rt_info);
00294 ACE_CString name = buf;
00295
00296 TAO_EC_QOS_Info qos_info;
00297 qos_info.rt_info =
00298 scheduler->create (name.c_str ());
00299
00300
00301 RtecScheduler::Period_t period =
00302 static_cast<RtecScheduler::Period_t> (e.header.creation_time);
00303
00304 #if 1 //by VS original code replaced with this
00305 RtecScheduler::RT_Info* consumer_rt_info_ptr;
00306
00307 consumer_rt_info_ptr = scheduler->get (h_consumer_rt_info);
00308 scheduler->set (qos_info.rt_info,
00309 consumer_rt_info_ptr->criticality,
00310 0,
00311 0,
00312 0,
00313 period,
00314 consumer_rt_info_ptr->importance,
00315 0,
00316 1,
00317 RtecScheduler::OPERATION);
00318
00319 scheduler->add_dependency (qos_info.rt_info,
00320 h_consumer_rt_info,
00321 1,
00322 RtecBase::TWO_WAY_CALL);
00323 #endif //by VS
00324
00325 pos++;
00326 return new TAO_EC_Timeout_Filter (this->event_channel_,
00327 supplier,
00328 qos_info,
00329 e.header.type,
00330 e.header.creation_time);
00331 }
00332
00333 #if 1 //added by VS
00334 else if (e.header.type == ACE_ES_GLOBAL_DESIGNATOR)
00335 {
00336 pos++;
00337 return this->recursive_build (supplier, qos, pos,
00338 scheduler,
00339 parent_info);
00340 }
00341 else
00342 {
00343 #ifdef EC_KOKYU_LOGGING
00344 ACE_DEBUG ((LM_DEBUG,
00345 "Kokyu_Filter_Builder::No designator for this entry. "
00346 "Must be a body\n"));
00347 #endif
00348 }
00349 #endif
00350
00351
00352 if (parent_info == 0)
00353 {
00354
00355
00356 parent_info = qos.dependencies[pos].rt_info;
00357 }
00358
00359 RtecScheduler::RT_Info_var info =
00360 scheduler->get (parent_info);
00361
00362 ACE_CString name = info->entry_point.in ();
00363
00364 pos++;
00365 TAO_EC_Kokyu_Filter *filter;
00366 ACE_NEW_RETURN (filter,
00367 TAO_EC_Kokyu_Filter (name.c_str (),
00368 parent_info,
00369 scheduler,
00370 new TAO_EC_Type_Filter (e.header),
00371 parent_info,
00372 parent_info,
00373 RtecScheduler::OPERATION),
00374 0);
00375
00376 TAO_EC_QOS_Info qos_info;
00377 filter->get_qos_info (qos_info);
00378
00379 return filter;
00380 }
00381
00382 void
00383 TAO_EC_Kokyu_Filter_Builder:: recursive_name (
00384 RtecEventChannelAdmin::ConsumerQOS& qos,
00385 CORBA::ULong& pos,
00386 RtecScheduler::Scheduler_ptr scheduler,
00387 ACE_CString& name) const
00388 {
00389 const RtecEventComm::Event& e = qos.dependencies[pos].event;
00390
00391 if (e.header.type == ACE_ES_CONJUNCTION_DESIGNATOR)
00392 {
00393 pos++;
00394 CORBA::ULong n = this->count_children (qos, pos);
00395
00396 for (CORBA::ULong i = 0; i != n; ++i)
00397 {
00398 ACE_CString child_name;
00399 this->recursive_name (qos, pos,
00400 scheduler,
00401 child_name);
00402
00403 if (i == 0)
00404 name += "(";
00405 else
00406 name += "&&";
00407 name += child_name;
00408 }
00409 name += ")";
00410 return;
00411 }
00412
00413 else if (e.header.type == ACE_ES_DISJUNCTION_DESIGNATOR)
00414 {
00415 pos++;
00416 CORBA::ULong n = this->count_children (qos, pos);
00417
00418 for (CORBA::ULong i = 0; i != n; ++i)
00419 {
00420 ACE_CString child_name;
00421
00422 this->recursive_name (qos, pos,
00423 scheduler,
00424 child_name);
00425
00426 if (i == 0)
00427 name += "(";
00428 else
00429 name += "||";
00430 name += child_name;
00431 }
00432 name += ")";
00433 return;
00434 }
00435
00436 else if (e.header.type == ACE_ES_EVENT_TIMEOUT
00437 || e.header.type == ACE_ES_EVENT_INTERVAL_TIMEOUT
00438 || e.header.type == ACE_ES_EVENT_DEADLINE_TIMEOUT)
00439 {
00440 pos++;
00441
00442 char buf[64];
00443 ACE_OS::sprintf (buf, "TIMEOUT:%umsec",
00444 static_cast<u_int> ((e.header.creation_time / 10000)));
00445 name = buf;
00446
00447 return;
00448 }
00449
00450 RtecScheduler::handle_t body_info = qos.dependencies[pos].rt_info;
00451
00452 RtecScheduler::RT_Info_var info =
00453 scheduler->get (body_info);
00454
00455 name = info->entry_point.in ();
00456 name += "#rep";
00457
00458 pos++;
00459 }
00460
00461 CORBA::ULong
00462 TAO_EC_Kokyu_Filter_Builder::
00463 count_children (RtecEventChannelAdmin::ConsumerQOS& qos,
00464 CORBA::ULong pos) const
00465 {
00466 CORBA::ULong l = qos.dependencies.length ();
00467 CORBA::ULong i;
00468 for (i = pos; i != l; ++i)
00469 {
00470 const RtecEventComm::Event& e = qos.dependencies[i].event;
00471 if (e.header.type == ACE_ES_CONJUNCTION_DESIGNATOR
00472 || e.header.type == ACE_ES_DISJUNCTION_DESIGNATOR)
00473 break;
00474 }
00475 return i - 1;
00476 }
00477
00478 TAO_END_VERSIONED_NAMESPACE_DECL