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"
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"
46 TAO_SERVANT_BASE_FIND_START
= 700,
47 TAO_SERVANT_BASE_FIND_END
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 ()
65 TAO_ServantBase::TAO_ServantBase (const TAO_ServantBase
&rhs
)
66 : TAO_Abstract_ServantBase ()
68 , optable_ (rhs
.optable_
)
73 TAO_ServantBase::operator= (const TAO_ServantBase
&rhs
)
75 if (this != std::addressof(rhs
))
77 this->optable_
= rhs
.optable_
;
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 ());
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
[] =
109 _is_a_Upcall_Command
command (
113 TAO::Upcall_Wrapper upcall_wrapper
;
114 upcall_wrapper
.upcall (server_request
118 #if TAO_HAS_INTERCEPTORS == 1
122 #endif /* TAO_HAS_INTERCEPTORS == 1 */
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
[] =
140 _is_a_thru_poa_Upcall_Command
command (
142 server_request
.operation_details (),
145 TAO::Upcall_Wrapper upcall_wrapper
;
146 upcall_wrapper
.upcall (server_request
150 #if TAO_HAS_INTERCEPTORS == 1
154 #endif /* TAO_HAS_INTERCEPTORS == 1 */
159 #if (TAO_HAS_MINIMUM_CORBA == 0)
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
[] =
172 _non_existent_Upcall_Command
command (
176 TAO::Upcall_Wrapper upcall_wrapper
;
177 upcall_wrapper
.upcall (server_request
181 #if TAO_HAS_INTERCEPTORS == 1
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
[] =
200 _non_existent_thru_poa_Upcall_Command
command (
202 server_request
.operation_details (),
205 TAO::Upcall_Wrapper upcall_wrapper
;
206 upcall_wrapper
.upcall (server_request
210 #if TAO_HAS_INTERCEPTORS == 1
214 #endif /* TAO_HAS_INTERCEPTORS == 1 */
219 # if !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
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 ());
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
);
245 throw ::CORBA::MARSHAL ();
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
[] =
261 _get_component_Upcall_Command
command (
265 TAO::Upcall_Wrapper upcall_wrapper
;
266 upcall_wrapper
.upcall (server_request
270 #if TAO_HAS_INTERCEPTORS == 1
274 #endif /* TAO_HAS_INTERCEPTORS == 1 */
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
[] =
290 _get_component_thru_poa_Upcall_Command
command (
292 server_request
.operation_details (),
295 TAO::Upcall_Wrapper upcall_wrapper
;
296 upcall_wrapper
.upcall (server_request
300 #if TAO_HAS_INTERCEPTORS == 1
304 #endif /* TAO_HAS_INTERCEPTORS == 1 */
308 # endif /* !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) */
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
[] =
323 _repository_id_Upcall_Command
command (
327 TAO::Upcall_Wrapper upcall_wrapper
;
328 upcall_wrapper
.upcall (server_request
332 #if TAO_HAS_INTERCEPTORS == 1
336 #endif /* TAO_HAS_INTERCEPTORS == 1 */
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
[] =
352 _repository_id_thru_poa_Upcall_Command
command (
354 server_request
.operation_details (),
357 TAO::Upcall_Wrapper upcall_wrapper
;
358 upcall_wrapper
.upcall (server_request
362 #if TAO_HAS_INTERCEPTORS == 1
366 #endif /* TAO_HAS_INTERCEPTORS == 1 */
369 #endif /* TAO_HAS_MINIMUM_CORBA */
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)
380 TAO_ServantBase::_non_existent ()
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 ());
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)
405 TAO_ServantBase::_get_component ()
407 return CORBA::Object::_nil ();
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
,
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
,
433 ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_BASE_FIND_START
);
434 return this->optable_
->find (opname
, skelfunc
, st
,
435 static_cast<unsigned int> (length
));
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 () ;
455 poa_current_impl
->poa ()->key_to_stub (
456 poa_current_impl
->object_key (),
457 this->_interface_repository_id (),
458 poa_current_impl
->priority ());
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
);
481 TAO_ServantBase::synchronous_upcall_dispatch (
482 TAO_ServerRequest
& req
,
483 TAO::Portable_Server::Servant_Upcall
* servant_upcall
,
484 TAO_ServantBase
*derived_this
)
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
,
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
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.
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
529 if (req
.collocated ())
531 // Report the exception to the collocated client.
535 req
.tao_send_reply_exception (ex
);
541 TAO_ServantBase::asynchronous_upcall_dispatch (
542 TAO_ServerRequest
&req
,
543 TAO::Portable_Server::Servant_Upcall
*servant_upcall
,
544 TAO_ServantBase
*derived_this
)
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
,
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
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
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
);
591 TAO_ServantBase::_add_ref ()
597 TAO_ServantBase::_remove_ref ()
599 CORBA::ULong
const new_count
= --this->ref_count_
;
608 TAO_ServantBase::_refcount_value () const
610 return this->ref_count_
;
614 TAO_ServantBase::_collocated_dispatch (::CORBA::Object_ptr obj
,
615 ::CORBA::Object_out forward_obj
,
617 TAO::Argument
** args
,
621 TAO::Collocation_Strategy strategy
)
623 TAO::Direct_Collocation_Upcall_Wrapper collocation_upcall_wrapper
;
624 collocation_upcall_wrapper
.upcall (
635 TAO_END_VERSIONED_NAMESPACE_DECL