Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / PortableServer / Servant_Base.cpp
blob8809dfd031a6fbd74f9e996e21b139744f89d661
1 // -*- C++ -*-
2 #include "tao/PortableServer/Servant_Base.h"
3 #include "tao/PortableServer/Root_POA.h"
4 #include "tao/PortableServer/Operation_Table.h"
5 #include "tao/PortableServer/POA_Current_Impl.h"
6 #include "tao/PortableServer/Direct_Collocation_Upcall_Wrapper.h"
8 #include "tao/PortableInterceptor.h"
9 #include "tao/PortableServer/SUpcall_commands.h"
11 #include "tao/PortableServer/SArg_Traits_T.h"
12 #include "tao/PortableServer/Basic_SArguments.h"
13 #include "tao/PortableServer/Special_Basic_SArguments.h"
14 #include "tao/PortableServer/Fixed_Size_SArgument_T.h"
15 #include "tao/PortableServer/Var_Size_SArgument_T.h"
16 #include "tao/PortableServer/Object_SArg_Traits.h"
17 #include "tao/PortableServer/UB_String_SArguments.h"
18 #include "tao/PortableServer/get_arg.h"
19 #include "tao/Object.h"
21 #include "tao/Timeprobe.h"
22 #include "tao/ORB_Core.h"
23 #include "tao/TSS_Resources.h"
24 #include "tao/Stub.h"
25 #include "tao/TAO_Server_Request.h"
26 #include "tao/IFR_Client_Adapter.h"
27 #include "tao/Basic_Types.h"
29 #include "ace/Dynamic_Service.h"
30 #include "ace/OS_NS_string.h"
32 #if !defined (__ACE_INLINE__)
33 # include "tao/PortableServer/Servant_Base.inl"
34 #endif /* ! __ACE_INLINE__ */
36 #if defined (ACE_ENABLE_TIMEPROBES)
38 static const char *TAO_ServantBase_Timeprobe_Description[] =
40 "TAO_ServantBase::_find - start",
41 "TAO_ServantBase::_find - end"
44 enum
46 TAO_SERVANT_BASE_FIND_START = 700,
47 TAO_SERVANT_BASE_FIND_END
50 // Setup Timeprobes
51 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_ServantBase_Timeprobe_Description,
52 TAO_SERVANT_BASE_FIND_START);
54 #endif /* ACE_ENABLE_TIMEPROBES */
56 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
58 TAO_ServantBase::TAO_ServantBase (TAO_Operation_Table* optable)
59 : TAO_Abstract_ServantBase ()
60 , ref_count_ (1)
61 , optable_ (optable)
65 TAO_ServantBase::TAO_ServantBase (const TAO_ServantBase &rhs)
66 : TAO_Abstract_ServantBase ()
67 , ref_count_ (1)
68 , optable_ (rhs.optable_)
72 TAO_ServantBase &
73 TAO_ServantBase::operator= (const TAO_ServantBase &rhs)
75 if (this != std::addressof(rhs))
77 this->optable_ = rhs.optable_;
79 return *this;
82 TAO_ServantBase::~TAO_ServantBase ()
86 PortableServer::POA_ptr
87 TAO_ServantBase::_default_POA ()
89 CORBA::Object_var object = TAO_ORB_Core_instance ()->root_poa ();
91 return PortableServer::POA::_narrow (object.in ());
95 void
96 TAO_ServantBase::_is_a_skel (TAO_ServerRequest & server_request,
97 TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR(servant_upcall),
98 TAO_ServantBase *servant)
100 TAO::SArg_Traits< ::ACE_InputCDR::to_boolean>::ret_val retval;
101 TAO::SArg_Traits< char *>::in_arg_val _tao_repository_id;
103 TAO::Argument * const args[] =
105 &retval,
106 &_tao_repository_id
109 _is_a_Upcall_Command command (
110 servant,
111 args);
113 TAO::Upcall_Wrapper upcall_wrapper;
114 upcall_wrapper.upcall (server_request
115 , args
117 , command
118 #if TAO_HAS_INTERCEPTORS == 1
119 , servant_upcall
120 , nullptr
122 #endif /* TAO_HAS_INTERCEPTORS == 1 */
126 void
127 TAO_ServantBase::_is_a_thru_poa_skel (TAO_ServerRequest & server_request,
128 TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall),
129 TAO_ServantBase *servant)
131 TAO::SArg_Traits< ::ACE_InputCDR::to_boolean>::ret_val retval;
132 TAO::SArg_Traits< char *>::in_arg_val _tao_repository_id;
134 TAO::Argument * const args[] =
136 &retval,
137 &_tao_repository_id
140 _is_a_thru_poa_Upcall_Command command (
141 servant,
142 server_request.operation_details (),
143 args);
145 TAO::Upcall_Wrapper upcall_wrapper;
146 upcall_wrapper.upcall (server_request
147 , args
149 , command
150 #if TAO_HAS_INTERCEPTORS == 1
151 , servant_upcall
152 , nullptr
154 #endif /* TAO_HAS_INTERCEPTORS == 1 */
159 #if (TAO_HAS_MINIMUM_CORBA == 0)
160 void
161 TAO_ServantBase::_non_existent_skel (TAO_ServerRequest & server_request,
162 TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall),
163 TAO_ServantBase *servant)
165 TAO::SArg_Traits< ::ACE_InputCDR::to_boolean>::ret_val retval;
167 TAO::Argument * const args[] =
169 &retval
172 _non_existent_Upcall_Command command (
173 servant,
174 args);
176 TAO::Upcall_Wrapper upcall_wrapper;
177 upcall_wrapper.upcall (server_request
178 , args
180 , command
181 #if TAO_HAS_INTERCEPTORS == 1
182 , servant_upcall
183 , nullptr
185 #endif /* TAO_HAS_INTERCEPTORS == 1 */
189 void TAO_ServantBase::_non_existent_thru_poa_skel (TAO_ServerRequest & server_request,
190 TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall),
191 TAO_ServantBase *servant)
193 TAO::SArg_Traits< ::ACE_InputCDR::to_boolean>::ret_val retval;
195 TAO::Argument * const args[] =
197 &retval
200 _non_existent_thru_poa_Upcall_Command command (
201 servant,
202 server_request.operation_details (),
203 args);
205 TAO::Upcall_Wrapper upcall_wrapper;
206 upcall_wrapper.upcall (server_request
207 , args
209 , command
210 #if TAO_HAS_INTERCEPTORS == 1
211 , servant_upcall
212 , nullptr
214 #endif /* TAO_HAS_INTERCEPTORS == 1 */
219 # if !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
220 void
221 TAO_ServantBase::_interface_skel (TAO_ServerRequest & server_request,
222 TAO::Portable_Server::Servant_Upcall* /* servant_upcall */,
223 TAO_ServantBase *servant)
225 TAO_IFR_Client_Adapter *_tao_adapter =
226 ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance (
227 TAO_ORB_Core::ifr_client_adapter_name ());
229 if (!_tao_adapter)
231 throw ::CORBA::INTF_REPOS (::CORBA::OMGVMCID | 1, ::CORBA::COMPLETED_NO);
234 ::CORBA::InterfaceDef_ptr _tao_retval = servant->_get_interface ();
235 server_request.init_reply ();
236 TAO_OutputCDR &_tao_out = *server_request.outgoing ();
238 ::CORBA::Boolean const _tao_result =
239 _tao_adapter->interfacedef_cdr_insert (_tao_out, _tao_retval);
241 _tao_adapter->dispose (_tao_retval);
243 if (!_tao_result)
245 throw ::CORBA::MARSHAL ();
249 void
250 TAO_ServantBase::_component_skel (TAO_ServerRequest & server_request,
251 TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall),
252 TAO_ServantBase *servant)
254 TAO::SArg_Traits< ::CORBA::Object>::ret_val retval;
256 TAO::Argument * const args[] =
258 &retval
261 _get_component_Upcall_Command command (
262 servant,
263 args);
265 TAO::Upcall_Wrapper upcall_wrapper;
266 upcall_wrapper.upcall (server_request
267 , args
269 , command
270 #if TAO_HAS_INTERCEPTORS == 1
271 , servant_upcall
272 , nullptr
274 #endif /* TAO_HAS_INTERCEPTORS == 1 */
278 void
279 TAO_ServantBase::_component_thru_poa_skel (TAO_ServerRequest & server_request,
280 TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall),
281 TAO_ServantBase *servant)
283 TAO::SArg_Traits< ::CORBA::Object>::ret_val retval;
285 TAO::Argument * const args[] =
287 &retval
290 _get_component_thru_poa_Upcall_Command command (
291 servant,
292 server_request.operation_details (),
293 args);
295 TAO::Upcall_Wrapper upcall_wrapper;
296 upcall_wrapper.upcall (server_request
297 , args
299 , command
300 #if TAO_HAS_INTERCEPTORS == 1
301 , servant_upcall
302 , nullptr
304 #endif /* TAO_HAS_INTERCEPTORS == 1 */
308 # endif /* !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) */
311 void
312 TAO_ServantBase::_repository_id_skel (TAO_ServerRequest & server_request,
313 TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall),
314 TAO_ServantBase *servant)
316 TAO::SArg_Traits< char *>::ret_val retval;
318 TAO::Argument * const args[] =
320 &retval
323 _repository_id_Upcall_Command command (
324 servant,
325 args);
327 TAO::Upcall_Wrapper upcall_wrapper;
328 upcall_wrapper.upcall (server_request
329 , args
331 , command
332 #if TAO_HAS_INTERCEPTORS == 1
333 , servant_upcall
334 , nullptr
336 #endif /* TAO_HAS_INTERCEPTORS == 1 */
340 void
341 TAO_ServantBase::_repository_id_thru_poa_skel (TAO_ServerRequest & server_request,
342 TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall),
343 TAO_ServantBase *servant)
345 TAO::SArg_Traits< char *>::ret_val retval;
347 TAO::Argument * const args[] =
349 &retval
352 _repository_id_thru_poa_Upcall_Command command (
353 servant,
354 server_request.operation_details (),
355 args);
357 TAO::Upcall_Wrapper upcall_wrapper;
358 upcall_wrapper.upcall (server_request
359 , args
361 , command
362 #if TAO_HAS_INTERCEPTORS == 1
363 , servant_upcall
364 , nullptr
366 #endif /* TAO_HAS_INTERCEPTORS == 1 */
369 #endif /* TAO_HAS_MINIMUM_CORBA */
371 CORBA::Boolean
372 TAO_ServantBase::_is_a (const char *logical_type_id)
374 static char const id[] = "IDL:omg.org/CORBA/Object:1.0";
375 return ACE_OS::strcmp (logical_type_id, id) == 0;
378 #if (TAO_HAS_MINIMUM_CORBA == 0)
379 CORBA::Boolean
380 TAO_ServantBase::_non_existent ()
382 return false;
385 CORBA::InterfaceDef_ptr
386 TAO_ServantBase::_get_interface ()
388 TAO_IFR_Client_Adapter *adapter =
389 ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance (
390 TAO_ORB_Core::ifr_client_adapter_name ());
392 if (adapter == 0)
394 throw ::CORBA::INTF_REPOS ();
397 // This doesn't take multiple ORBs into account, but it's being
398 // used only to resolve the IFR, so we should be ok.
399 return adapter->get_interface (TAO_ORB_Core_instance ()->orb (),
400 this->_interface_repository_id ());
403 #if !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
404 CORBA::Object_ptr
405 TAO_ServantBase::_get_component ()
407 return CORBA::Object::_nil ();
409 #endif
410 char *
411 TAO_ServantBase::_repository_id ()
413 return CORBA::string_dup (this->_interface_repository_id ());
415 #endif /* TAO_HAS_MINIMUM_CORBA */
418 TAO_ServantBase::_find (const char *opname,
419 TAO_Skeleton& skelfunc,
420 const size_t length)
422 ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_BASE_FIND_START);
423 return this->optable_->find (opname, skelfunc,
424 static_cast<unsigned int> (length));
428 TAO_ServantBase::_find (const char *opname,
429 TAO_Collocated_Skeleton& skelfunc,
430 TAO::Collocation_Strategy st,
431 const size_t length)
433 ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_BASE_FIND_START);
434 return this->optable_->find (opname, skelfunc, st,
435 static_cast<unsigned int> (length));
438 TAO_Stub *
439 TAO_ServantBase::_create_stub ()
441 TAO_Stub *stub = nullptr;
443 TAO::Portable_Server::POA_Current_Impl *poa_current_impl =
444 static_cast<TAO::Portable_Server::POA_Current_Impl *>
445 (TAO_TSS_Resources::instance ()->poa_current_impl_);
447 CORBA::ORB_ptr servant_orb = nullptr;
449 if (poa_current_impl != 0
450 && this == poa_current_impl->servant ())
452 servant_orb = poa_current_impl->orb_core ().orb () ;
454 stub =
455 poa_current_impl->poa ()->key_to_stub (
456 poa_current_impl->object_key (),
457 this->_interface_repository_id (),
458 poa_current_impl->priority ());
460 else
462 PortableServer::POA_var poa = this->_default_POA ();
464 CORBA::Object_var object = poa->servant_to_reference (this);
466 // Get the stub object
467 stub = object->_stubobj ();
469 // Increment the reference count since <object> will zap its
470 // stub object on deletion.
471 stub->_incr_refcnt ();
473 servant_orb = stub->orb_core ()->orb ();
476 stub->servant_orb (servant_orb);
477 return stub;
480 void
481 TAO_ServantBase::synchronous_upcall_dispatch (
482 TAO_ServerRequest & req,
483 TAO::Portable_Server::Servant_Upcall* servant_upcall,
484 TAO_ServantBase *derived_this)
486 TAO_Skeleton skel;
487 char const * const opname = req.operation ();
489 // Handle the one ways that are SYNC_WITH_SERVER and not queued
490 req.sync_after_dispatch ();
492 // Fetch the skeleton for this operation
493 if (this->_find (opname,
494 skel,
495 static_cast <unsigned int> (req.operation_length())) == -1)
497 throw ::CORBA::BAD_OPERATION ();
500 CORBA::Boolean const send_reply =
501 !req.sync_with_server ()
502 && req.response_expected ()
503 && !req.deferred_reply ();
507 // Invoke the skeleton, it will demarshal the arguments, invoke
508 // the right operation on the skeleton class, and marshal any
509 // results. De/marshaling will only occur in the not collocated
510 // case.
511 skel (req, servant_upcall, derived_this);
513 // It is our job to send the already marshaled reply, but only
514 // send if it is expected and it has not already been sent
516 // We send the reply only if it is NOT a SYNC_WITH_SERVER, a
517 // response is expected and if the reply is not deferred.
518 if (send_reply)
520 req.tao_send_reply ();
523 catch (const ::CORBA::Exception& ex)
525 // If an exception was raised we should marshal it and send
526 // the appropriate reply to the client
527 if (send_reply)
529 if (req.collocated ())
531 // Report the exception to the collocated client.
532 throw;
534 else
535 req.tao_send_reply_exception (ex);
540 void
541 TAO_ServantBase::asynchronous_upcall_dispatch (
542 TAO_ServerRequest &req,
543 TAO::Portable_Server::Servant_Upcall *servant_upcall,
544 TAO_ServantBase *derived_this)
546 TAO_Skeleton skel;
547 const char *opname = req.operation ();
549 // It seems that I might have missed s/g here. What if
550 // it is a one way that is SYNC_WITH_SERVER.
551 // Add the following line to handle this reply send as well.
553 // Handle the one ways that are SYNC_WITH_SERVER
554 if (req.sync_with_server ())
556 req.send_no_exception_reply ();
559 // Fetch the skeleton for this operation
560 if (this->_find (opname,
561 skel,
562 static_cast <unsigned int> (req.operation_length())) == -1)
564 throw ::CORBA::BAD_OPERATION ();
569 // Invoke the skeleton, it will demarshal the arguments, invoke
570 // the right operation on the skeleton class, and marshal any
571 // results. De/marshaling will only occur in the not collocated
572 // case.
573 skel (req, servant_upcall, derived_this);
575 // It is our job to send the already marshaled reply, but only
576 // send if it is expected and it has not already been sent
578 // Return immediately. Do not send a reply; this is an
579 // asynchronous upcall. (unless, of course there is a system
580 // exception.
582 catch (const ::CORBA::Exception& ex)
584 // If an exception was raised we should marshal it and send
585 // the appropriate reply to the client
586 req.tao_send_reply_exception (ex);
590 void
591 TAO_ServantBase::_add_ref ()
593 ++this->ref_count_;
596 void
597 TAO_ServantBase::_remove_ref ()
599 CORBA::ULong const new_count = --this->ref_count_;
601 if (new_count == 0)
603 delete this;
607 CORBA::ULong
608 TAO_ServantBase::_refcount_value () const
610 return this->ref_count_;
613 void
614 TAO_ServantBase::_collocated_dispatch (::CORBA::Object_ptr obj,
615 ::CORBA::Object_out forward_obj,
616 bool &is_forwarded,
617 TAO::Argument ** args,
618 int num_args,
619 const char * op,
620 size_t op_len,
621 TAO::Collocation_Strategy strategy)
623 TAO::Direct_Collocation_Upcall_Wrapper collocation_upcall_wrapper;
624 collocation_upcall_wrapper.upcall (
625 obj,
626 forward_obj,
627 is_forwarded,
628 args,
629 num_args,
631 op_len,
632 strategy);
635 TAO_END_VERSIONED_NAMESPACE_DECL