Merge pull request #1551 from DOCGroup/plm_jira_333
[ACE_TAO.git] / TAO / tao / RTScheduling / Request_Interceptor.cpp
blob985e219d14afedb06f38c6aca774f25f5b1a062d
1 #include "tao/AnyTypeCode/Any.h"
2 #include "tao/AnyTypeCode/TypeCode.h"
4 #include "tao/RTScheduling/Request_Interceptor.h"
5 #include "tao/RTScheduling/Current.h"
6 #include "tao/RTScheduling/Distributable_Thread.h"
8 #include "tao/TSS_Resources.h"
9 #include "tao/debug.h"
10 #include "tao/ORB_Constants.h"
11 #include "ace/OS_NS_string.h"
13 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
15 const IOP::ServiceId
16 Client_Interceptor::SchedulingInfo = 30;
18 void
19 Client_Interceptor::send_request (PortableInterceptor::ClientRequestInfo_ptr ri)
21 if (TAO_debug_level > 0)
22 TAOLIB_DEBUG ((LM_DEBUG,
23 "Client_Interceptor::send_request\n"));
25 // Temporary current.
26 TAO_RTScheduler_Current_i *new_current = 0;
27 TAO_RTScheduler_Current_i *current = 0;
29 TAO_TSS_Resources *tss = TAO_TSS_Resources::instance ();
31 current = static_cast<TAO_RTScheduler_Current_i *> (tss->rtscheduler_current_impl_);
33 if (current != 0)
35 // If this is a one way request
36 if (!ri->response_expected ())
38 // Generate GUID.
39 RTScheduling::Current::IdType guid;
40 guid.length (sizeof(size_t));
42 size_t temp = ++TAO_RTScheduler_Current::guid_counter;
43 ACE_OS::memcpy (guid.get_buffer (),
44 &temp,
45 sizeof(size_t));
47 size_t id;
48 ACE_OS::memcpy (&id,
49 guid.get_buffer (),
50 guid.length ());
52 if (TAO_debug_level > 0)
53 TAOLIB_DEBUG ((LM_DEBUG,
54 "The Guid is %d %d\n",
55 id,
56 TAO_RTScheduler_Current::guid_counter.value_i ()));
58 // Create new DT.
59 RTScheduling::DistributableThread_var dt =
60 TAO_DistributableThread_Factory::create_DT ();
62 // Add new DT to map.
63 int result = current->dt_hash ()->bind (guid, dt);
64 if (result != 0)
66 TAOLIB_DEBUG ((LM_DEBUG,
67 "No Scheduling Segment Context\n"));
68 throw ::CORBA::INTERNAL ();
72 // @@ Store implicit_sched_param in a var
74 // Create new temporary current. Note that
75 // the new <sched_param> is the current
76 // <implicit_sched_param> and there is no
77 // segment name.
78 CORBA::Policy_var implicit_sched_param =
79 current->implicit_scheduling_parameter ();
80 ACE_NEW (new_current,
81 TAO_RTScheduler_Current_i (current->orb (),
82 current->dt_hash (),
83 guid,
85 implicit_sched_param.in (),
87 dt.in (),
88 current));
90 // Install new current in the ORB.
91 //current->implementation (new_current);
92 tss->rtscheduler_current_impl_ = new_current;
96 // Scheduler populates the service context with
97 // scheduling parameters.
98 RTScheduling::Scheduler_var scheduler = current->scheduler ();
99 scheduler->send_request (ri);
101 // If this is a one way request
102 if (!ri->response_expected ())
104 // Cleanup temporary DT.
105 new_current->cleanup_DT ();
107 //Restore old current
108 new_current->cleanup_current ();
113 void
114 Client_Interceptor::send_poll (PortableInterceptor::ClientRequestInfo_ptr ri)
116 if (TAO_debug_level > 0)
117 TAOLIB_DEBUG ((LM_DEBUG,
118 "Client_Interceptor::send_poll\n"));
120 TAO_RTScheduler_Current_i *current = 0;
122 TAO_TSS_Resources *tss = TAO_TSS_Resources::instance ();
124 current = static_cast<TAO_RTScheduler_Current_i *> (tss->rtscheduler_current_impl_);
125 if (current != 0)
127 RTScheduling::Scheduler_var scheduler = current->scheduler ();
128 scheduler->send_poll (ri);
132 void
133 Client_Interceptor::receive_reply (PortableInterceptor::ClientRequestInfo_ptr ri)
135 if (TAO_debug_level > 0)
136 TAOLIB_DEBUG ((LM_DEBUG,
137 "Client_Interceptor::receive_reply\n"));
139 TAO_RTScheduler_Current_i *current = 0;
141 TAO_TSS_Resources *tss = TAO_TSS_Resources::instance ();
143 current = static_cast<TAO_RTScheduler_Current_i *> (tss->rtscheduler_current_impl_);
144 if (current != 0)
146 RTScheduling::Scheduler_var scheduler = current->scheduler ();
147 scheduler->receive_reply (ri);
151 void
152 Client_Interceptor::receive_exception (PortableInterceptor::ClientRequestInfo_ptr ri)
154 if (TAO_debug_level > 0)
155 TAOLIB_DEBUG ((LM_DEBUG,
156 "Client_Interceptor::receive_exception\n"));
158 TAO_TSS_Resources *tss = TAO_TSS_Resources::instance ();
160 TAO_RTScheduler_Current_i *current =
161 static_cast<TAO_RTScheduler_Current_i *> (tss->rtscheduler_current_impl_);
163 if (current != 0)
165 if (ri == 0)
167 TAOLIB_ERROR ((LM_ERROR,
168 "ri = 0\n"));
169 return;
172 CORBA::Any_var ex = ri->received_exception ();
173 CORBA::TypeCode_var type = ex->type ();
175 if (CORBA::is_nil (type.in ()))
177 TAOLIB_ERROR ((LM_ERROR,
178 "type = 0\n"));
179 return;
181 const char * id = type->id ();
183 if (TAO_debug_level > 0)
184 TAOLIB_DEBUG ((LM_DEBUG,
185 "Received Exception %C\n",
186 id));
188 // If the remote host threw a THREAD_CANCELLED
189 // exception, make sure to take the appropriate
190 // local action.
191 if (ACE_OS::strstr (id, "CORBA::THREAD_CANCELLED") == 0)
193 // Perform the necessary cleanup as the
194 // thread was cancelled.
195 current->cancel_thread ();
197 else
199 // Inform scheduler that exception was
200 // received.
201 RTScheduling::Scheduler_var scheduler = current->scheduler ();
202 scheduler->receive_exception (ri);
207 void
208 Client_Interceptor::receive_other (PortableInterceptor::ClientRequestInfo_ptr ri)
210 if (TAO_debug_level > 0)
211 TAOLIB_DEBUG ((LM_DEBUG,
212 "Client_Interceptor::receive_other\n"));
214 TAO_RTScheduler_Current_i *current = 0;
216 TAO_TSS_Resources *tss = TAO_TSS_Resources::instance ();
218 current = static_cast<TAO_RTScheduler_Current_i *> (tss->rtscheduler_current_impl_);
219 if (current != 0)
221 RTScheduling::Scheduler_var scheduler = current->scheduler ();
222 scheduler->receive_other (ri);
226 char*
227 Client_Interceptor::name (void)
229 return CORBA::string_dup ("RTSchdeuler_Client_Interceptor");
232 void
233 Client_Interceptor::destroy (void)
237 const IOP::ServiceId
238 Server_Interceptor::SchedulingInfo = 30;
240 Server_Interceptor::Server_Interceptor (TAO_RTScheduler_Current_ptr current)
242 this->current_ = TAO_RTScheduler_Current::_duplicate (current);
245 void
246 Server_Interceptor::receive_request_service_contexts (
247 PortableInterceptor::ServerRequestInfo_ptr)
249 if (TAO_debug_level > 0)
250 TAOLIB_DEBUG ((LM_DEBUG,
251 "Server_Interceptor::receive_request_service_contexts\n"));
255 void
256 Server_Interceptor::receive_request (PortableInterceptor::ServerRequestInfo_ptr ri)
258 if (TAO_debug_level > 0)
259 TAOLIB_DEBUG ((LM_DEBUG,
260 "Server_Interceptor::receive_request\n"));
262 IOP::ServiceContext_var serv_cxt;
266 serv_cxt =
267 ri->get_request_service_context (Server_Interceptor::SchedulingInfo);
269 catch (const ::CORBA::Exception&)
271 if (TAO_debug_level > 0)
272 TAOLIB_DEBUG ((LM_DEBUG,
273 "Invalid Service Request\n"));
274 return;
277 if (TAO_debug_level > 0)
278 TAOLIB_DEBUG ((LM_DEBUG,
279 "Request from Distributable Thread\n"));
281 RTScheduling::Current::IdType_var guid_var;
282 char* name = 0;
283 CORBA::Policy_var sched_param = 0;
284 CORBA::Policy_var implicit_sched_param = 0;
286 TAO_RTScheduler_Current_i* new_current = 0;
287 ACE_NEW_THROW_EX (new_current,
288 TAO_RTScheduler_Current_i (this->current_->orb (),
289 this->current_->dt_hash ()),
290 CORBA::NO_MEMORY (
291 CORBA::SystemException::_tao_minor_code (
292 TAO::VMCID,
293 ENOMEM),
294 CORBA::COMPLETED_NO));
296 // Scheduler retrieves scheduling parameters
297 // from request and populates the out
298 // parameters.
299 RTScheduling::Scheduler_var scheduler = new_current->scheduler();
300 scheduler->receive_request (ri,
301 guid_var.out (),
302 name,
303 sched_param.out (),
304 implicit_sched_param.out ());
306 if (guid_var->length () == 0)
308 TAOLIB_ERROR ((LM_ERROR,
309 "The scheduler MUST retrieve and return the "
310 "GUID from the service context\n"));
311 return;
313 RTScheduling::Current::IdType guid;
314 guid.length (sizeof (size_t));
315 ACE_OS::memcpy (guid.get_buffer (),
316 guid_var->get_buffer (),
317 sizeof (size_t));
319 size_t id;
320 ACE_OS::memcpy (&id,
321 guid.get_buffer (),
322 guid.length ());
324 if (TAO_debug_level > 0)
325 TAOLIB_DEBUG ((LM_DEBUG,
326 "The Guid is %d\n",
327 id));
329 // Create new DT.
330 RTScheduling::DistributableThread_var dt = TAO_DistributableThread_Factory::create_DT ();
332 // Add new DT to map.
333 int result = new_current->dt_hash ()->bind (guid, dt);
335 if (result != 0)
337 throw ::CORBA::INTERNAL ();
340 // Create new temporary current. Note that the new <sched_param> is
341 // the current <implicit_sched_param> and there is no segment name.
342 new_current->id (guid);
343 new_current->name (name);
344 new_current->scheduling_parameter (sched_param.in ());
345 new_current->implicit_scheduling_parameter (implicit_sched_param.in ());
346 new_current->DT (dt.in ());
348 // Install new current in the ORB and store the previous current
349 // implementation
350 // current->implementation (new_current)
351 TAO_TSS_Resources *tss = TAO_TSS_Resources::instance ();
353 tss->rtscheduler_previous_current_impl_ = this->current_->implementation (new_current);
356 void
357 Server_Interceptor::send_reply (PortableInterceptor::ServerRequestInfo_ptr ri)
359 if (TAO_debug_level > 0)
360 TAOLIB_DEBUG ((LM_DEBUG,
361 "Server_Interceptor::send_reply\n"));
363 TAO_RTScheduler_Current_i *current = 0;
364 TAO_RTScheduler_Current_i *prev_current = 0;
366 TAO_TSS_Resources *tss = TAO_TSS_Resources::instance ();
368 current = static_cast<TAO_RTScheduler_Current_i *> (tss->rtscheduler_current_impl_);
369 if (current != 0)
371 RTScheduling::DistributableThread_var dt = current->DT ();
372 if (dt->state () == RTScheduling::DistributableThread::CANCELLED)
374 current->cancel_thread ();
376 return;
378 else TAOLIB_DEBUG ((LM_DEBUG,
379 "Thread Not Cancelled\n"));
382 // Inform scheduler that upcall is complete.
383 RTScheduling::Scheduler_var scheduler = current->scheduler ();
384 scheduler->send_reply (ri);
386 current->cleanup_DT ();
387 current->cleanup_current ();
389 // Get the previous current if any.
390 prev_current = static_cast<TAO_RTScheduler_Current_i *> (tss->rtscheduler_previous_current_impl_);
392 // Restore the previous current.
393 tss->rtscheduler_current_impl_ = prev_current;
395 // Reset the previous current pointer.
396 tss->rtscheduler_previous_current_impl_ = 0;
399 else TAOLIB_DEBUG ((LM_DEBUG,
400 "Send Reply Current is 0\n"));
403 void
404 Server_Interceptor::send_exception (PortableInterceptor::ServerRequestInfo_ptr ri)
406 if (TAO_debug_level > 0)
407 TAOLIB_DEBUG ((LM_DEBUG,
408 "Server_Interceptor::send_exception\n"));
410 TAO_RTScheduler_Current_i *current = 0;
412 TAO_TSS_Resources *tss = TAO_TSS_Resources::instance ();
414 current = static_cast<TAO_RTScheduler_Current_i *> (tss->rtscheduler_current_impl_);
415 if (current != 0)
417 // Inform scheduler that upcall is complete.
418 RTScheduling::Scheduler_var scheduler = current->scheduler ();
419 scheduler->send_exception (ri);
421 current->cleanup_DT ();
422 current->cleanup_current ();
426 void
427 Server_Interceptor::send_other (PortableInterceptor::ServerRequestInfo_ptr ri)
429 if (TAO_debug_level > 0)
430 TAOLIB_DEBUG ((LM_DEBUG,
431 "Server_Interceptor::send_other\n"));
433 TAO_RTScheduler_Current_i *current = 0;
435 TAO_TSS_Resources *tss = TAO_TSS_Resources::instance ();
437 current = static_cast<TAO_RTScheduler_Current_i *> (tss->rtscheduler_current_impl_);
438 if (current != 0)
440 // Inform scheduler that upcall is complete.
441 RTScheduling::Scheduler_var scheduler = current->scheduler ();
442 scheduler->send_other (ri);
444 current->cleanup_DT ();
445 current->cleanup_current ();
449 char*
450 Server_Interceptor::name (void)
452 return CORBA::string_dup ("RTSchdeuler_Server_Interceptor");
455 void
456 Server_Interceptor::destroy (void)
460 TAO_END_VERSIONED_NAMESPACE_DECL