diff options
Diffstat (limited to 'TAO/tao/CSD_Framework')
27 files changed, 2498 insertions, 0 deletions
diff --git a/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.cpp b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.cpp new file mode 100644 index 00000000000..2eb88cc49d3 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.cpp @@ -0,0 +1,70 @@ +// $Id$ + +#include "tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h" +#include "tao/CSD_Framework/CSD_POA.h" +#include "tao/CSD_Framework/CSD_Strategy_Repository.h" +#include "ace/Dynamic_Service.h" + +ACE_RCSID(CSD_Framework, + CSD_Default_Servant_Dispatcher, + "$Id$") + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_CSD_Default_Servant_Dispatcher::~TAO_CSD_Default_Servant_Dispatcher (void) +{ +} + + +TAO_Root_POA * +TAO_CSD_Default_Servant_Dispatcher::create_Root_POA (const ACE_CString &name, + PortableServer::POAManager_ptr poa_manager, + const TAO_POA_Policy_Set &policies, + ACE_Lock &lock, + TAO_SYNCH_MUTEX &thread_lock, + TAO_ORB_Core &orb_core, + TAO_Object_Adapter *object_adapter + ACE_ENV_ARG_DECL) + { + TAO_CSD_POA *poa = 0; + + ACE_NEW_THROW_EX (poa, + TAO_CSD_POA (name, + poa_manager, + policies, + 0, + lock, + thread_lock, + orb_core, + object_adapter + ACE_ENV_ARG_PARAMETER), + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (0); + + + TAO_CSD_Strategy_Repository *repo = + ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance ("TAO_CSD_Strategy_Repository"); + + if (repo == 0) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("(%P|%t) CSD_Default_Servant_Dispatcher::") + ACE_TEXT("create_POA could not find ") + ACE_TEXT("TAO_CSD_Strategy_Repository\n"))); + return 0; + } + + CSD_Framework::Strategy_var strategy = repo->find (name); + + if (! ::CORBA::is_nil (strategy.in ())) + { + poa->set_csd_strategy (strategy.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + + return poa; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h new file mode 100644 index 00000000000..1d041331e99 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h @@ -0,0 +1,53 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CSD_Default_Servant_Dispatcher.h + * + * $Id$ + * + * @author Yan Dai (dai_y@ociweb.com) + */ +//============================================================================= + +#ifndef TAO_CSD_DEFAULT_SERVANT_DISPATCHER_H +#define TAO_CSD_DEFAULT_SERVANT_DISPATCHER_H +#include /**/ "ace/pre.h" + +#include "tao/CSD_Framework/CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PortableServer/Default_Servant_Dispatcher.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class TAO_CSD_Default_Servant_Dispatcher + * + * @brief Interface for CSD_POA servant dispatching strategies. + */ +class TAO_CSD_FW_Export TAO_CSD_Default_Servant_Dispatcher + : public virtual TAO_Default_Servant_Dispatcher +{ +public: + virtual ~TAO_CSD_Default_Servant_Dispatcher (void); + + + /// Factory method for creating new CSD Root POA. + virtual TAO_Root_POA *create_Root_POA (const ACE_CString &name, + PortableServer::POAManager_ptr poa_manager, + const TAO_POA_Policy_Set &policies, + ACE_Lock &lock, + TAO_SYNCH_MUTEX &thread_lock, + TAO_ORB_Core &orb_core, + TAO_Object_Adapter *object_adapter + ACE_ENV_ARG_DECL); +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* TAO_CSD_DEFAULT_SERVANT_DISPATCHER_H */ diff --git a/TAO/tao/CSD_Framework/CSD_FW_Export.h b/TAO/tao/CSD_Framework/CSD_FW_Export.h new file mode 100644 index 00000000000..edeb9119dc4 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FW_Export.h @@ -0,0 +1,58 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl -s TAO_CSD_FW +// ------------------------------ +#ifndef TAO_CSD_FW_EXPORT_H +#define TAO_CSD_FW_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (TAO_CSD_FW_HAS_DLL) +# define TAO_CSD_FW_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && TAO_CSD_FW_HAS_DLL */ + +#if !defined (TAO_CSD_FW_HAS_DLL) +# define TAO_CSD_FW_HAS_DLL 1 +#endif /* ! TAO_CSD_FW_HAS_DLL */ + +#if defined (TAO_CSD_FW_HAS_DLL) && (TAO_CSD_FW_HAS_DLL == 1) +# if defined (TAO_CSD_FW_BUILD_DLL) +# define TAO_CSD_FW_Export ACE_Proper_Export_Flag +# define TAO_CSD_FW_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TAO_CSD_FW_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TAO_CSD_FW_BUILD_DLL */ +# define TAO_CSD_FW_Export ACE_Proper_Import_Flag +# define TAO_CSD_FW_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TAO_CSD_FW_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TAO_CSD_FW_BUILD_DLL */ +#else /* TAO_CSD_FW_HAS_DLL == 1 */ +# define TAO_CSD_FW_Export +# define TAO_CSD_FW_SINGLETON_DECLARATION(T) +# define TAO_CSD_FW_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TAO_CSD_FW_HAS_DLL == 1 */ + +// Set TAO_CSD_FW_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (TAO_CSD_FW_NTRACE) +# if (ACE_NTRACE == 1) +# define TAO_CSD_FW_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define TAO_CSD_FW_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !TAO_CSD_FW_NTRACE */ + +#if (TAO_CSD_FW_NTRACE == 1) +# define TAO_CSD_FW_TRACE(X) +#else /* (TAO_CSD_FW_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define TAO_CSD_FW_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (TAO_CSD_FW_NTRACE == 1) */ + +#endif /* TAO_CSD_FW_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp new file mode 100644 index 00000000000..24684bf7866 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp @@ -0,0 +1,474 @@ +// $Id$ +#include "tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h" +#include "tao/debug.h" +#include "tao/ORB_Constants.h" +#include "tao/ORB_Core.h" +#include "tao/Transport.h" +#include "tao/CDR.h" + + +ACE_RCSID (CSD_Framework, + FW_Server_Request_Wrapper, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl" +#endif /* ! __ACE_INLINE__ */ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO::CSD::FW_Server_Request_Wrapper::~FW_Server_Request_Wrapper() +{ + // Only delete the request if we cloned it. + if (this->is_clone_) + { + // The TAO_Tagged_Profile type_id_ may have been duplicated. + if (this->request_->profile_.type_id_ != 0) + CORBA::string_free ( + const_cast<char*> (this->request_->profile_.type_id_)); + + // Since this TAO_ServerRequest object is a clone, it + // "owns" the input and output CDR objects held by the + // incoming_ and outgoing_ data members, respectfully. + // Thus, for the clone case, the TAO_ServerRequest dtor + // needs to release (aka, delete) the CDR objects. + delete this->request_->incoming_; + + // Get the start message block that reference to the data allocated + // on the heap. + if (this->request_->outgoing_ != 0) + { + char* buffer = this->request_->outgoing_->begin ()->base (); + delete [] buffer; + delete this->request_->outgoing_; + } + if (this->request_->operation_details_ != 0) + { + char* opname = (char*)this->request_->operation_details_->opname_; + delete [] opname; + delete this->request_->operation_details_; + } + + if (this->request_->transport_ != 0) + this->request_->transport_->remove_reference (); + + delete this->request_; + } +} + + +// Assumes that the servant argument is not a NULL pointer. +void +TAO::CSD::FW_Server_Request_Wrapper::dispatch + (PortableServer::Servant servant + ACE_ENV_ARG_DECL) +{ + ACE_TRY + { + servant->_dispatch(*this->request_, 0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + // Only CORBA exceptions are caught here. + ACE_CATCHANY + { + if (this->request_->collocated()) + { + // For collocated requests, we re-throw the exception. + ACE_RE_THROW; + } + else if (!this->request_->sync_with_server() && + this->request_->response_expected() && + !this->request_->deferred_reply()) + { + // The request is a remote request that is expecting a reply. + this->request_->tao_send_reply_exception(ACE_ANY_EXCEPTION); + } + else if (TAO_debug_level > 0) + { + // It is unfortunate that an exception (probably a system + // exception) was thrown by the dispatch code (even by the + // user) when the client was not expecting a response. + // However, in this case, we cannot close the connection + // down, since it really isn't the client's fault. + + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) exception thrown ") + ACE_TEXT ("but client is not waiting a response\n"))); + + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + "FW_Server_Request_Wrapper::dispatch ()"); + } + } +#if defined (TAO_HAS_EXCEPTIONS) + ACE_CATCHALL + { + // @@ TODO some c++ exception or another, but what do we do with + // it? + // We are supposed to map it into a CORBA::UNKNOWN exception. + // BTW, this cannot be detected if using the <env> mapping. If + // we have native exceptions but no support for them in the ORB + // we should still be able to catch it. If we don't have native + // exceptions it couldn't have been raised in the first place! + CORBA::UNKNOWN exception (CORBA::SystemException::_tao_minor_code + (TAO_UNHANDLED_SERVER_CXX_EXCEPTION, 0), + CORBA::COMPLETED_MAYBE); + + if (this->request_->collocated()) + { + // For collocated requests, we re-throw the exception. + ACE_RE_THROW; + } + else if (!this->request_->sync_with_server() && + this->request_->response_expected() && + !this->request_->deferred_reply()) + { + // The request is a remote request that is expecting a reply. + this->request_->tao_send_reply_exception(exception); + } + else if (TAO_debug_level > 0) + { + // It is unfortunate that an exception (probably a system + // exception) was thrown by the dispatch code (even by the + // user) when the client was not expecting a response. + // However, in this case, we cannot close the connection + // down, since it really isn't the client's fault. + + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) exception thrown ") + ACE_TEXT ("but client is not waiting a response\n"))); + + ACE_PRINT_EXCEPTION ( + exception, + "FW_Server_Request_Wrapper::dispatch ()"); + } + } +#endif /* TAO_HAS_EXCEPTIONS */ + + ACE_ENDTRY; +} + + +TAO_ServerRequest* +TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_ServerRequest*& request) +{ + // TBD-CSD: Ultimately add an argument for an allocator. + TAO_ServerRequest* clone_obj; + ACE_NEW_RETURN (clone_obj, + TAO_ServerRequest (), + 0); + + if (clone_obj == 0) + { + return 0; + } + + // TYPE: TAO_Pluggable_Messaging* + // ACTION: Assuming that a shallow-copy is ok here. + clone_obj->mesg_base_ = request->mesg_base_; + + // TYPE: const char* + // ACTION: Method performs deep-copy of string contents. + clone_obj->operation (CORBA::string_dup (request->operation ()), + request->operation_length (), + 1); + + // TYPE: CORBA::Object_var + // ACTION: Assignment performs reference-counted copy of object ref. + clone_obj->forward_location_ = request->forward_location_; + + // TYPE: TAO_InputCDR* + // ACTION: This *must* be "cloned". + if (request->incoming_ != 0) + { + clone_obj->incoming_ = this->clone (request->incoming_); + } + + // TYPE: TAO_OutputCDR* + // ACTION: This *must* be "cloned". + if (request->outgoing_ != 0) + { + clone_obj->outgoing_ = this->create_new_output_cdr (); + } + + // TYPE: TAO_Transport* + // ACTION: Assuming that a shallow-copy is ok here. + clone_obj->transport_ = request->transport_; + if (clone_obj->transport_ != 0) + clone_obj->transport_->add_reference (); + + // TYPE: CORBA::Boolean + // ACTION: Primitive data type assignment. + clone_obj->response_expected_ = request->response_expected_; + + // TYPE: CORBA::Boolean + // ACTION: Primitive data type assignment. + clone_obj->deferred_reply_ = request->deferred_reply_; + + // TYPE: CORBA::Boolean + // ACTION: Primitive data type assignment. + clone_obj->sync_with_server_ = request->sync_with_server_; + + // TYPE: CORBA::Boolean + // ACTION: Primitive data type assignment. + clone_obj->is_dsi_ = request->is_dsi_; + + // TYPE: CORBA::ULong + // ACTION: Primitive data type assignment. + clone_obj->exception_type_ = request->exception_type_; + + // TYPE: TAO_ORB_Core* + // ACTION: Assuming that a shallow-copy is ok here. + clone_obj->orb_core_ = request->orb_core_; + + // TYPE: TAO_Service_Context + // ACTION: No copy/assignment operator, so adding/using a clone operation. + this->clone (request->request_service_context_, clone_obj->request_service_context_); + + // TYPE: TAO_Service_Context + // ACTION: No copy/assignment operator, so adding/using a clone operation. + this->clone (request->reply_service_context_, clone_obj->reply_service_context_); + + // TYPE: CORBA::ULong + // ACTION: Primitive data type assignment. + clone_obj->request_id_ = request->request_id_; + + // TYPE: TAO_Tagged_Profile + // ACTION: No copy/assignment operator, so adding/using a clone operation. + this->clone (request->profile_, clone_obj->profile_); + + // TYPE: CORBA::OctetSeq_var + // ACTION: Assignment performs reference-counted copy of sequence. + clone_obj->requesting_principal_ = request->requesting_principal_; + + // TYPE: ptrdiff_t + // ACTION: Primitive data type assignment (unsigned integral type). + clone_obj->dsi_nvlist_align_ = request->dsi_nvlist_align_; + + // TYPE: TAO_Operation_Details const * const + // ACTION: Need to clone this. + if (request->operation_details_ != 0) + { + ACE_ASSERT (request->incoming_ == 0); + if (this->clone (request->operation_details_, + clone_obj->operation_details_, + clone_obj->incoming_) == false) + { + return 0; + } + } + + // TYPE: CORBA::Boolean + // ACTION: Primitive data type assignment. + clone_obj->argument_flag_ = request->argument_flag_; + + //#if TAO_HAS_INTERCEPTORS == 1 + // TYPE: size_t + // ACTION: Primitive data type assignment. + // Just leave this alone for a clone. + // + //clone_obj->interceptor_count_ = request->interceptor_count_; + + // TYPE: TAO::PICurrent_Impl + // ACTION: Copy/assignment operator disabled on purpose. + // Just leave this alone for a clone. + // + // clone_obj->rs_pi_current_ + + // TYPE: CORBA::OctetSeq_var + // ACTION: Assignment performs reference-counted copy of sequence. + // Assuming that this is ok. + // Just leave this alone for a clone. + // + //clone_obj->result_seq_ = request->result_seq_; + //#endif /* TAO_HAS_INTERCEPTORS == 1 */ + + if (clone_obj->transport_ != 0) + { + clone_obj->transport_->assign_translators(clone_obj->incoming_, + clone_obj->outgoing_); + } + return clone_obj; +} + + +TAO_InputCDR* +TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_InputCDR*& from) +{ + TAO_InputCDR* clone_ptr = 0; + ACE_NEW_RETURN (clone_ptr, + TAO_InputCDR(*from), + 0); + return clone_ptr; +} + + +bool +TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Operation_Details const *& from, + TAO_Operation_Details const *& to, + TAO_InputCDR*& cdr) +{ + TAO_Operation_Details *& from_non_const + = const_cast <TAO_Operation_Details *&>(from); + + char* cloned_op_name; + ACE_NEW_RETURN (cloned_op_name, + char[from_non_const->opname_len_ + 1], + false); + ACE_OS::strncpy(cloned_op_name, from_non_const->opname_, from_non_const->opname_len_); + cloned_op_name[from_non_const->opname_len_] = '\0'; + + static const size_t mb_size = 2048; + ACE_NEW_RETURN (cdr, + TAO_InputCDR (mb_size), + false); + + // To avoid duplicating and copying the data block, allow the + // TAO_OutputCDR to share the data block of TAO_InputCDR's message block. + ACE_Message_Block* mb = const_cast<ACE_Message_Block*> (cdr->start ()); + TAO_OutputCDR outcdr (mb); + + if (! from_non_const->marshal_args (outcdr)) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT("(%P|%T) TAO::CSD::FW_Server_Request_Wrapper::") + ACE_TEXT("clone TAO_Operation_Details failed\n"))); + return false; + } + + // The TAO_OutputCDR made a new message block around the data block + // held by the message block owned by the TAO_InputCDR. We need to + // make sure that the results of marshaling are propagated back to the + // message block in the TAO_InputCDR. + const ACE_Message_Block* begin = outcdr.begin (); + if (begin == outcdr.current ()) + { + // A chain was not made, so we can just adjust the read and write + // pointers + mb->rd_ptr (begin->rd_ptr ()); + mb->wr_ptr (begin->wr_ptr ()); + } + else + { + // A costly, but necessary, copying of data blocks. This shouldn't + // happen that often assuming that the size of the message block + // allocated during the allocation of TAO_InputCDR is "big enough" + // for most operation parameters. + cdr->reset (begin, outcdr.byte_order ()); + } + + // CSD-TBD: Eventually need to use allocators. + + // CSD-TBD: Assert that this->ex_data_ and this->ex_count_ are both == 0 + TAO_Operation_Details* to_non_const; + ACE_NEW_RETURN (to_non_const, + TAO_Operation_Details(cloned_op_name, + from_non_const->opname_len_, + from_non_const->argument_flag_, + 0, + 0, + 0, + 0), + false); + + + // DATA MEMBER: const char *opname_; + // DATA MEMBER: CORBA::ULong opname_len_; + // DATA MEMBER: CORBA::Boolean argument_flag_; + // DATA MEMBER: TAO::Argument **args_; + // DATA MEMBER: CORBA::ULong num_args_; + // DATA MEMBER: TAO::Exception_Data *ex_data_; + // DATA MEMBER: CORBA::ULong ex_count_; + // + // ACTION: None - handled in ctor + // + + // DATA MEMBER: CORBA::ULong request_id_; + // DATA MEMBER: CORBA::Octet response_flags_; + // DATA MEMBER: TAO_Target_Specification::TAO_Target_Address addressing_mode_; + // DATA MEMBER: TAO_Service_Context request_service_info_; + // DATA MEMBER: TAO_Service_Context reply_service_info_; + // + // ACTION: Use assignment op to copy from "this" object to the clone. + // + to_non_const->request_id_ = from->request_id_; + to_non_const->response_flags_ = from->response_flags_; + to_non_const->addressing_mode_ = from->addressing_mode_; + + // DATA MEMBER: TAO_Service_Context request_service_info_; + // DATA MEMBER: TAO_Service_Context reply_service_info_; + // + // ACTION: Use the TAO_Service_Context clone() method. + // + this->clone (from_non_const->request_service_info_, to_non_const->request_service_info_); + this->clone (from_non_const->reply_service_info_, to_non_const->reply_service_info_); + + to = to_non_const; + + return true; +} + + +void +TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Tagged_Profile& from, + TAO_Tagged_Profile& to) +{ + to.orb_core_ = from.orb_core_; + to.discriminator_ = from.discriminator_; + to.object_key_extracted_ = from.object_key_extracted_; + to.object_key_ = from.object_key_; + to.profile_ = from.profile_; + to.profile_index_ = from.profile_index_; + to.type_id_ = from.type_id_ == 0 ? 0 : + CORBA::string_dup (from.type_id_); +} + + +void +TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Service_Context& from, + TAO_Service_Context& to) +{ + to.service_context_ = from.service_context_; +} + +TAO_OutputCDR* +TAO::CSD::FW_Server_Request_Wrapper::create_new_output_cdr () +{ + TAO_OutputCDR* cdr = 0; + + // A buffer that we will use to initialise the CDR stream + char* repbuf; + ACE_NEW_RETURN (repbuf, + char[ACE_CDR::DEFAULT_BUFSIZE], + 0); + + ACE_CDR::Octet major; + ACE_CDR::Octet minor; + this->request_->outgoing_->get_version (major, minor); + + // Initialze an output CDR on the stack + // NOTE: Don't jump to a conclusion as to why we are using the + // input_cdr and hence the global pool here. These pools will move + // to the lanes anyway at some point of time. Further, it would have + // been awesome to have this in TSS. But for some reason the cloning + // that happens when the ORB gets flow controlled while writing a + // reply is messing things up. We crash horribly. Doing this adds a + // lock, we need to set things like this -- put stuff in TSS here + // and transfer to global memory when we get flow controlled. We + // need to work on the message block to get it right! + ACE_NEW_RETURN (cdr, + TAO_OutputCDR (repbuf, + ACE_CDR::DEFAULT_BUFSIZE, + TAO_ENCAP_BYTE_ORDER, + this->request_->orb_core_->input_cdr_buffer_allocator (), + this->request_->orb_core_->input_cdr_dblock_allocator (), + this->request_->orb_core_->input_cdr_msgblock_allocator (), + this->request_->orb_core_->orb_params ()->cdr_memcpy_tradeoff (), + major, + minor), + 0); + + return cdr; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h new file mode 100644 index 00000000000..5268fb8a357 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h @@ -0,0 +1,128 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CSD_FW_Server_Request_Wrapper.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_FW_SERVER_REQUEST_WRAPPER_H +#define TAO_CSD_FW_SERVER_REQUEST_WRAPPER_H + +#include /**/ "ace/pre.h" + +#include "tao/CSD_Framework/CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/TAO_Server_Request.h" +#include "tao/operation_details.h" +#include "tao/PortableServer/Servant_Base.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace TAO +{ + namespace CSD + { + + /** + * @class FW_Server_Request_Wrapper + * + * @brief Wrapper around a TAO_Server_Request that will be cloned + * at the proper time. + * + * This CSD Framework class is used to provide an interface to a + * TAO_ServerRequest object such that it can be used for CSD strategies + * that need to clone TAO_Server_Requests (ie, so that they may be + * placed on a queue to be dispatched by another thread). + * + * There are several purposes for this class, with the main thing being + * that the TAO_ServerRequest object is not used directly by the + * CSD Strategies since it is, after all, an internal TAO class that was + * never meant to be exposed. Future changes to TAO's internal design + * may cause disruption in the TAO_ServerRequest class. These changes + * would only need to be accounted for here in this + * FW_Server_Request_Wrapper class' implementation, and all CSD + * Strategies will work again. It's a maintenance issue. + * + * @note: The CSD namespace is inside of TAO namespace in current + * implementation. This can be changed but, at least for now, it's + * already been delivered to some customs, we leave it as-is. If it + * needs to change, we will make this change. + */ + class TAO_CSD_FW_Export FW_Server_Request_Wrapper + { + public: + + /// Constructor. + FW_Server_Request_Wrapper(TAO_ServerRequest& server_request); + + /// Destructor. + ~FW_Server_Request_Wrapper(); + + /// Perform the clone operation. + void clone(); + + /// Dispatch the request to the servant. + void dispatch(PortableServer::Servant servant ACE_ENV_ARG_DECL); + + /// Cancel the request. + void cancel(); + + + private: + + /// Create a deep copy of the request_ object. + /// The other clone methods are used to support the TAO_ServerRequest clone. + TAO_ServerRequest* clone (TAO_ServerRequest*& from); + + /// Clone an input cdr stream. + TAO_InputCDR* clone (TAO_InputCDR*& from); + + /// Create a deep copy of a TAO_Operation_Details object and marshall + /// the arguments into a TAO_InputCDR stream. The cloned TAO_Operation_Details + /// object is created without any arguments. This would help the skeleton + /// code to determine whether the arguments are in the operation_details_ + /// object or should be demarshalled from the incoming_ stream in the request_ + /// object. + bool clone (TAO_Operation_Details const *& from, + TAO_Operation_Details const *& to, + TAO_InputCDR* & cdr); + + /// Clone the TAO_Tagged_Profile object. + void clone (TAO_Tagged_Profile& from, TAO_Tagged_Profile& to); + + /// Clone the TAO_Service_Context object. + void clone (TAO_Service_Context& from, TAO_Service_Context& to); + + /// Create a TAO_OutputCDR stream initialized with a heap allocated + /// buffer. + TAO_OutputCDR* create_new_output_cdr (); + + /// A flag that indicates that the TAO_ServerRequest object + /// is already cloned. + bool is_clone_; + + /// Pointer to the underlying TAO_ServerRequest object. + TAO_ServerRequest* request_; + }; + + } +} + +TAO_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_FW_SERVER_REQUEST_WRAPPER_H */ diff --git a/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl new file mode 100644 index 00000000000..13d78a1664c --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl @@ -0,0 +1,46 @@ +// -*- C++ -*- +// +// $Id$ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +TAO::CSD::FW_Server_Request_Wrapper::FW_Server_Request_Wrapper + (TAO_ServerRequest& server_request) + : is_clone_(false), + request_(&server_request) +{ +} + + +ACE_INLINE +void +TAO::CSD::FW_Server_Request_Wrapper::clone() +{ + // Only clone the TAO_Server_Request object if we have not performed the + // clone already. This really should only be called once, but this code + // makes sure that we do not introduce a leak. + if (!this->is_clone_) + { + this->request_ = this->clone (this->request_); + this->is_clone_ = true; + } +} + + +ACE_INLINE +void +TAO::CSD::FW_Server_Request_Wrapper::cancel() +{ + // We only need to handle remote requests that are expecting a reply. + if (!this->request_->collocated() && + !this->request_->sync_with_server() && + this->request_->response_expected() && + !this->request_->deferred_reply()) + { + CORBA::NO_IMPLEMENT ex; + this->request_->tao_send_reply_exception(ex); + } +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_Framework.pidl b/TAO/tao/CSD_Framework/CSD_Framework.pidl new file mode 100644 index 00000000000..f0ab5b1a1fe --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Framework.pidl @@ -0,0 +1,53 @@ +// -*- IDL -*- +/** + * @file CSD_Framework.pidl + * + * $Id$ + * + * @brief Pre-compiled IDL source for the CSD_Framework module. + * + * This file was used to generate the code in + * CSD_FrameworkC.{h,inl,cpp}, using the following command: + * + * $ACE_ROOT/bin/tao_idl \ + * -o orig -Gp -Gd -Ge 1 -Gt -GA -I$TAO_ROOT -Sci \ + * -Wb,export_macro=TAO_CSD_FW_Export \ + * -Wb,export_include="CSD_FW_Export.h" \ + * -Wb,pre_include="ace/pre.h" \ + * -Wb,post_include="ace/post.h" \ + * -Wb,versioning_begin=TAO_BEGIN_VERSIONED_NAMESPACE_DECL \ + * -Wb,versioning_end=TAO_END_VERSIONED_NAMESPACE_DECL \ + * CSD_Framework.pidl + */ + +#ifndef CSD_FRAMEWORK_PIDL +#define CSD_FRAMEWORK_PIDL + +#include "tao/PortableServer/PortableServer_include.pidl" + +module CSD_Framework { + + # pragma version CSD_Framework 2.3 + + // This is a common base interface for all CSD strategy + // implementations + local interface Strategy { + + # pragma version Strategy 2.3 + + // This is support for a legacy method of supplying a strategy to a + // POA. + boolean apply_to(in PortableServer::POA p); + }; + + // Specialized POA providing a method to supply a strategy object to + // the POA. + local interface POA : PortableServer::POA { + + # pragma version POA 2.3 + + void set_csd_strategy (in Strategy s); + }; +}; + +#endif //CSD_FRAMEWORK_PIDL diff --git a/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp b/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp new file mode 100644 index 00000000000..dcdcc711e48 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp @@ -0,0 +1,32 @@ +// $Id$ + +#include "tao/CSD_Framework/CSD_Framework_Loader.h" +#include "tao/CSD_Framework/CSD_Object_Adapter_Factory.h" +#include "tao/CSD_Framework/CSD_Strategy_Repository.h" +#include "ace/Dynamic_Service.h" +#include "ace/Service_Gestalt.h" + +ACE_RCSID (CSD_Framework, + CSD_Framework_Loader, + "$Id$") + +#include "tao/ORB_Core.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +int +TAO_CSD_Framework_Loader::init (void) +{ + ACE_Service_Config::process_directive + (ace_svc_desc_TAO_CSD_Object_Adapter_Factory); + + ACE_Service_Config::process_directive + (ace_svc_desc_TAO_CSD_Strategy_Repository); + + TAO_ORB_Core::set_poa_factory ("TAO_CSD_Object_Adapter_Factory", + "dynamic TAO_CSD_Object_Adapter_Factory Service_Object * TAO_CSD_Framework:_make_TAO_CSD_Object_Adapter_Factory()"); + + return 0; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_Framework_Loader.h b/TAO/tao/CSD_Framework/CSD_Framework_Loader.h new file mode 100644 index 00000000000..44aa1f5c73c --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Framework_Loader.h @@ -0,0 +1,47 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file CSD_Framework_Loader.h + * + * $Id$ + * + * Header file for loading CSD framework service objects. + * + * @author Yan Dai (dai_y@ociweb.com) + */ +//============================================================================= + +#ifndef TAO_CSD_FRAMEWORK_LOADER_H +#define TAO_CSD_FRAMEWORK_LOADER_H +#include /**/ "ace/pre.h" + +#include "tao/CSD_Framework/CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/Versioned_Namespace.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class TAO_CSD_Framework_Loader + * + * @brief TAO_CSD_Framework_Loader. + * + * This class acts as a facade for the CSD_Framework library to the + * ORB. + */ +class TAO_CSD_FW_Export TAO_CSD_Framework_Loader +{ + public: + /// Used to force the initialization of the ORB code. + static int init (void); +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* TAO_CSD_FRAMEWORK_LOADER_H */ diff --git a/TAO/tao/CSD_Framework/CSD_ORBInitializer.cpp b/TAO/tao/CSD_Framework/CSD_ORBInitializer.cpp new file mode 100644 index 00000000000..b67ea4bbc08 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_ORBInitializer.cpp @@ -0,0 +1,36 @@ +// $Id$ +#include "tao/CSD_Framework/CSD_ORBInitializer.h" + +#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 + +ACE_RCSID (CSD_Framework, + CSD_ORBInitializer, + "$Id$") + +#include "tao/CSD_Framework/CSD_Object_Adapter_Factory.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_CSD_ORBInitializer::TAO_CSD_ORBInitializer () +{ +} + +void +TAO_CSD_ORBInitializer::pre_init ( + PortableInterceptor::ORBInitInfo_ptr + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +TAO_CSD_ORBInitializer::post_init ( + PortableInterceptor::ORBInitInfo_ptr + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +TAO_END_VERSIONED_NAMESPACE_DECL + +#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */ diff --git a/TAO/tao/CSD_Framework/CSD_ORBInitializer.h b/TAO/tao/CSD_Framework/CSD_ORBInitializer.h new file mode 100644 index 00000000000..8d6aa8a03e5 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_ORBInitializer.h @@ -0,0 +1,70 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CSD_ORBInitializer.h + * + * $Id$ + * + * @author Yan Dai (dai_y@ociweb.com) + */ +//============================================================================= + + +#ifndef TAO_CSD_ORB_INITIALIZER_H +#define TAO_CSD_ORB_INITIALIZER_H + +#include /**/ "ace/pre.h" + +#include "tao/orbconf.h" + +#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 + +#include "tao/CSD_Framework/CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +//#include "tao/PortableInterceptorC.h" +#include "tao/LocalObject.h" +#include "tao/PI/ORBInitializerC.h" + +// This is to remove "inherits via dominance" warnings from MSVC. +// MSVC is being a little too paranoid. +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +/// CSD ORB initializer. +class TAO_CSD_ORBInitializer + : public virtual PortableInterceptor::ORBInitializer + , public virtual TAO_Local_RefCounted_Object +{ +public: + + TAO_CSD_ORBInitializer (); + + virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_ORB_INITIALIZER_H */ diff --git a/TAO/tao/CSD_Framework/CSD_Object_Adapter.cpp b/TAO/tao/CSD_Framework/CSD_Object_Adapter.cpp new file mode 100644 index 00000000000..ed74e7c413b --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter.cpp @@ -0,0 +1,45 @@ +// $Id$ + +#include "tao/CSD_Framework/CSD_Object_Adapter.h" +#include "tao/CSD_Framework/CSD_Strategy_Proxy.h" +#include "tao/CSD_Framework/CSD_POA.h" + +ACE_RCSID (CSD_Framework, + CSD_Object_Adapter, + "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_CSD_Object_Adapter::TAO_CSD_Object_Adapter ( + const TAO_Server_Strategy_Factory::Active_Object_Map_Creation_Parameters &creation_parameters, + TAO_ORB_Core &orb_core) + : TAO_Object_Adapter (creation_parameters, orb_core) +{ + +} + +TAO_CSD_Object_Adapter::~TAO_CSD_Object_Adapter () +{ +} + +void +TAO_CSD_Object_Adapter::do_dispatch ( + TAO_ServerRequest& req, + TAO::Portable_Server::Servant_Upcall& upcall + ACE_ENV_ARG_DECL) +{ + TAO_Root_POA& poa = upcall.poa (); + TAO_CSD_POA* csd_poa = dynamic_cast<TAO_CSD_POA*> (&poa); + + if (csd_poa == 0) + { + ACE_THROW (CORBA::BAD_PARAM ()); + } + + TAO::CSD::Strategy_Proxy& proxy + = csd_poa->servant_dispatching_strategy_proxy (); + proxy.dispatch_request (req, upcall ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_Object_Adapter.h b/TAO/tao/CSD_Framework/CSD_Object_Adapter.h new file mode 100644 index 00000000000..34016654cba --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter.h @@ -0,0 +1,57 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CSD_Object_Adapter.h + * + * $Id$ + * + * @author Yan Dai (dai_y@ociweb.com) + */ +//============================================================================= + + +#ifndef TAO_CSD_OBJECT_ADAPTER_H +#define TAO_CSD_OBJECT_ADAPTER_H +#include /**/ "ace/pre.h" + +#include "tao/CSD_Framework/CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PortableServer/Object_Adapter.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class TAO_CSD_Object_Adapter + * + * @brief Defines the CSD version Object Adapter which overrides + * default dispatch implementation. + * + * This class will be used as a facade for the CSD POAs in a server + */ +class TAO_CSD_FW_Export TAO_CSD_Object_Adapter : public TAO_Object_Adapter +{ +public: + + /// Constructor + TAO_CSD_Object_Adapter (const TAO_Server_Strategy_Factory::Active_Object_Map_Creation_Parameters &creation_parameters, + TAO_ORB_Core &orb_core); + + /// Destructor + virtual ~TAO_CSD_Object_Adapter (void); + + /// Hand the request to the Service_Dispatching_Strategy_Proxy for + /// dispatching. + virtual void do_dispatch (TAO_ServerRequest& req, + TAO::Portable_Server::Servant_Upcall& upcall + ACE_ENV_ARG_DECL); +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* TAO_CSD_OBJECT_ADAPTER_H */ diff --git a/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.cpp b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.cpp new file mode 100644 index 00000000000..fa06817ec2c --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.cpp @@ -0,0 +1,96 @@ +// $Id$ + +#include "tao/CSD_Framework/CSD_Object_Adapter_Factory.h" +#include "tao/CSD_Framework/CSD_Strategy_Repository.h" +#include "tao/CSD_Framework/CSD_Object_Adapter.h" +#include "tao/CSD_Framework/CSD_ORBInitializer.h" +#include "tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h" +#include "tao/ORB_Core.h" +#include "tao/ORBInitializer_Registry.h" +#include "ace/Dynamic_Service.h" + +ACE_RCSID (CSD_Framework, + CSD_Object_Adapter_Factory, + "$Id$") + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_CSD_Object_Adapter_Factory::TAO_CSD_Object_Adapter_Factory (void) +{ +} + +TAO_Adapter* +TAO_CSD_Object_Adapter_Factory::create (TAO_ORB_Core *oc) +{ + // Create the CSD object adapter. + TAO_CSD_Object_Adapter *object_adapter = 0; + ACE_NEW_RETURN (object_adapter, + TAO_CSD_Object_Adapter (oc->server_factory ()-> + active_object_map_creation_parameters (), + *oc), + 0); + + // Create and register the CSD servant dispatcher. + TAO_CSD_Default_Servant_Dispatcher * csd_servant_dispatcher = 0; + ACE_NEW_RETURN (csd_servant_dispatcher, + TAO_CSD_Default_Servant_Dispatcher, + 0); + object_adapter->servant_dispatcher (csd_servant_dispatcher); + + return object_adapter; +} + +int +TAO_CSD_Object_Adapter_Factory::init (int /* argc */, + ACE_TCHAR* /* argv */ []) +{ + TAO_CSD_Strategy_Repository *repo = + ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance ("TAO_CSD_Strategy_Repository"); + + if (repo != 0) + repo->init(0,0); + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + /// Register the Messaging ORBInitializer. + PortableInterceptor::ORBInitializer_ptr temp_orb_initializer = + PortableInterceptor::ORBInitializer::_nil (); + + ACE_NEW_THROW_EX (temp_orb_initializer, + TAO_CSD_ORBInitializer, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_TRY_CHECK; + + PortableInterceptor::ORBInitializer_var orb_initializer = + temp_orb_initializer; + + PortableInterceptor::register_orb_initializer (orb_initializer.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return -1; + } + ACE_ENDTRY; + + return 0; +} + +TAO_END_VERSIONED_NAMESPACE_DECL + +ACE_FACTORY_DEFINE (TAO_CSD_FW, TAO_CSD_Object_Adapter_Factory) +ACE_STATIC_SVC_DEFINE (TAO_CSD_Object_Adapter_Factory, + ACE_TEXT ("TAO_CSD_Object_Adapter_Factory"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (TAO_CSD_Object_Adapter_Factory), + ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ, + 0) diff --git a/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.h b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.h new file mode 100644 index 00000000000..cda859315bf --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.h @@ -0,0 +1,50 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CSD_Object_Adapter_Factory.h + * + * $Id$ + * + * @author Yan Dai (dai_y@ociweb.com) + */ +//============================================================================= + + +#ifndef TAO_CSD_OBJECT_ADAPTER_FACTORY_H +#define TAO_CSD_OBJECT_ADAPTER_FACTORY_H +#include /**/ "ace/pre.h" + +#include "tao/CSD_Framework/CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PI/PI.h" +#include "tao/Adapter_Factory.h" +#include "ace/Service_Config.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +class TAO_CSD_FW_Export TAO_CSD_Object_Adapter_Factory : public TAO_Adapter_Factory +{ +public: + /// Constructor + TAO_CSD_Object_Adapter_Factory (void); + + // = The TAO_Adapter_Factory methods, please read tao/Adapter.h for + // details. + virtual TAO_Adapter *create (TAO_ORB_Core *orb_core); + + virtual int init (int argc, + ACE_TCHAR* argv[]); +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +ACE_STATIC_SVC_DECLARE_EXPORT (TAO_CSD_FW, TAO_CSD_Object_Adapter_Factory) +ACE_FACTORY_DECLARE (TAO_CSD_FW, TAO_CSD_Object_Adapter_Factory) + +#include /**/ "ace/post.h" +#endif /* TAO_CSD_OBJECT_ADAPTER_FACTORY_H */ diff --git a/TAO/tao/CSD_Framework/CSD_POA.cpp b/TAO/tao/CSD_Framework/CSD_POA.cpp new file mode 100644 index 00000000000..f3cc8e605f5 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_POA.cpp @@ -0,0 +1,134 @@ +// $Id$ + +#include "tao/CSD_Framework/CSD_POA.h" +#include "tao/CSD_Framework/CSD_Strategy_Repository.h" +#include "tao/CSD_Framework/CSD_Strategy_Base.h" + +#include "ace/Dynamic_Service.h" + +ACE_RCSID (CSD_Framework, + CSD_POA, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "tao/CSD_Framework/CSD_POA.inl" +#endif /* ! __ACE_INLINE__ */ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +// Implementation skeleton constructor +TAO_CSD_POA::TAO_CSD_POA (const String &name, + PortableServer::POAManager_ptr poa_manager, + const TAO_POA_Policy_Set &policies, + TAO_Root_POA *parent, + ACE_Lock &lock, + TAO_SYNCH_MUTEX &thread_lock, + TAO_ORB_Core &orb_core, + TAO_Object_Adapter *object_adapter + ACE_ENV_ARG_DECL) +: TAO_Regular_POA (name, + poa_manager, + policies, + parent, + lock, + thread_lock, + orb_core, + object_adapter + ACE_ENV_ARG_PARAMETER) +{ + ACE_NEW_THROW_EX (this->sds_proxy_, + TAO::CSD::Strategy_Proxy (), + CORBA::NO_MEMORY ()); + ACE_CHECK; +} + + +// Implementation skeleton destructor +TAO_CSD_POA::~TAO_CSD_POA (void) +{ + delete this->sds_proxy_; +} + +void TAO_CSD_POA::set_csd_strategy ( + ::CSD_Framework::Strategy_ptr strategy + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + if (CORBA::is_nil (strategy)) + { + ACE_THROW (CORBA::BAD_PARAM ()); + } + this->sds_proxy_->custom_strategy (strategy); +} + +TAO_Root_POA * +TAO_CSD_POA::new_POA (const String &name, + PortableServer::POAManager_ptr poa_manager, + const TAO_POA_Policy_Set &policies, + TAO_Root_POA *parent, + ACE_Lock &lock, + TAO_SYNCH_MUTEX &thread_lock, + TAO_ORB_Core &orb_core, + TAO_Object_Adapter *object_adapter + ACE_ENV_ARG_DECL) +{ + TAO_CSD_POA *poa = 0; + + ACE_NEW_THROW_EX (poa, + TAO_CSD_POA (name, + poa_manager, + policies, + parent, + lock, + thread_lock, + orb_core, + object_adapter + ACE_ENV_ARG_PARAMETER), + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (0); + + TAO_CSD_Strategy_Repository *repo = + ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance ("TAO_CSD_Strategy_Repository"); + + + CSD_Framework::Strategy_var strategy = repo->find (name); + + if (! ::CORBA::is_nil (strategy.in ())) + { + poa->set_csd_strategy (strategy.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + + return poa; +} + +void TAO_CSD_POA::poa_activated_hook () +{ + this->sds_proxy_->poa_activated_event (); +} + +void TAO_CSD_POA::poa_deactivated_hook () +{ + this->sds_proxy_->poa_deactivated_event (); +} + +void TAO_CSD_POA::servant_activated_hook (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + this->sds_proxy_->servant_activated_event (servant, oid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void TAO_CSD_POA::servant_deactivated_hook (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + this->sds_proxy_->servant_deactivated_event (servant, oid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_POA.h b/TAO/tao/CSD_Framework/CSD_POA.h new file mode 100644 index 00000000000..bcbf2e0495f --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_POA.h @@ -0,0 +1,111 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CSD_POA.h + * + * $Id$ + * + * @author Yan Dai (dai_y@ociweb.com) + */ +//============================================================================= + +#ifndef TAO_CSD_POA_H +#define TAO_CSD_POA_H + +#include /**/ "ace/pre.h" + +#include "tao/CSD_Framework/CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PortableServer/Regular_POA.h" +#include "tao/CSD_Framework/CSD_Strategy_Proxy.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class TAO_CSD_POA + * + * @brief Implementation of the CSD_Framework::POA interface. + * + * Implementation of the CSD_Framework::POA interface. + */ +class TAO_CSD_FW_Export TAO_CSD_POA + : public virtual CSD_Framework::POA, + public virtual TAO_Regular_POA +{ +public: + //Constructor + TAO_CSD_POA (const String &name, + PortableServer::POAManager_ptr poa_manager, + const TAO_POA_Policy_Set &policies, + TAO_Root_POA *parent, + ACE_Lock &lock, + TAO_SYNCH_MUTEX &thread_lock, + TAO_ORB_Core &orb_core, + TAO_Object_Adapter *object_adapter + ACE_ENV_ARG_DECL); + + //Destructor + virtual ~TAO_CSD_POA (void); + + /// Pass the Strategy object reference to the CSD poa. + virtual + void set_csd_strategy ( + ::CSD_Framework::Strategy_ptr s + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + /// Hook - The POA has been (or is being) activated. + virtual void poa_activated_hook (); + + /// Hook - The POA has been deactivated. + virtual void poa_deactivated_hook (); + + /// Hook - A servant has been activated. + virtual void servant_activated_hook (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL); + + /// Hook - A servant has been deactivated. + virtual void servant_deactivated_hook (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL); + + ///Method for creating new CSD POA. + TAO_Root_POA * new_POA (const String &name, + PortableServer::POAManager_ptr poa_manager, + const TAO_POA_Policy_Set &policies, + TAO_Root_POA *parent, + ACE_Lock &lock, + TAO_SYNCH_MUTEX &thread_lock, + TAO_ORB_Core &orb_core, + TAO_Object_Adapter *object_adapter + ACE_ENV_ARG_DECL); + + /// Servant Dispatching Strategy proxy accessor. + TAO::CSD::Strategy_Proxy& + servant_dispatching_strategy_proxy (void) const; + +private: + + TAO::CSD::Strategy_Proxy* sds_proxy_; +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + + +#if defined (__ACE_INLINE__) +# include "tao/CSD_Framework/CSD_POA.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_POA_H */ + diff --git a/TAO/tao/CSD_Framework/CSD_POA.inl b/TAO/tao/CSD_Framework/CSD_POA.inl new file mode 100644 index 00000000000..5e94cf5401e --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_POA.inl @@ -0,0 +1,14 @@ +// -*- C++ -*- +// +// $Id$ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +TAO::CSD::Strategy_Proxy& +TAO_CSD_POA::servant_dispatching_strategy_proxy (void) const +{ + return *sds_proxy_; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Base.cpp b/TAO/tao/CSD_Framework/CSD_Strategy_Base.cpp new file mode 100644 index 00000000000..aa641fe9bc7 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Base.cpp @@ -0,0 +1,132 @@ +// $Id$ + +#include "tao/CSD_Framework/CSD_Strategy_Base.h" +#include "tao/CSD_Framework/CSD_POA.h" +#include "tao/CSD_Framework/CSD_Strategy_Proxy.h" +#include "tao/PortableServer/Root_POA.h" +#include "tao/PortableServer/POAManager.h" +#include "tao/PortableServer/Servant_Base.h" +#include "tao/TAO_Server_Request.h" + +ACE_RCSID (CSD_Framework, + CSD_Strategy_Base, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "tao/CSD_Framework/CSD_Strategy_Base.inl" +#endif /* ! __ACE_INLINE__ */ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO::CSD::Strategy_Base::~Strategy_Base() +{ +} + +CORBA::Boolean +TAO::CSD::Strategy_Base::apply_to (PortableServer::POA_ptr poa + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (CORBA::is_nil(poa)) + { + if (TAO_debug_level > 0) + ACE_ERROR((LM_ERROR, + ACE_TEXT("(%P|%t) CSD Strategy cannot ") + ACE_TEXT("be applied to a nil POA.\n"))); + return false; + } + + if (!CORBA::is_nil(this->poa_.in())) + { + if (TAO_debug_level > 0) + ACE_ERROR((LM_ERROR, + ACE_TEXT("(%P|%t) CSD Strategy already ") + ACE_TEXT("applied to a POA.\n"))); + return false; + } + + // The POA is a local interface (IDL terminology), and thus we know that + // we can downcast the POA_ptr to its (TAO) implementation type. + TAO_CSD_POA* poa_impl = dynamic_cast<TAO_CSD_POA*>(poa); + + if (poa_impl == 0) + { + if (TAO_debug_level > 0) + ACE_ERROR((LM_ERROR, + ACE_TEXT("(%P|%t) CSD Strategy cannot ") + ACE_TEXT("be applied to a non CSD POA.\n"))); + return false; + } + + // We need to check to see if the POA is already "active". If this is + // the case, then we need to handle the poa_activated_event() right now. + // If the POA is not already "active", then we can just wait until it + // does get activated, and we (the strategy) will be informed of the + // poa_activated_event() at that time. + if (poa_impl->tao_poa_manager().get_state() == + PortableServer::POAManager::ACTIVE) + { + // The POA is already "active" (since its POAManager is active). + // We need to "raise" the poa_activated_event() now. Otherwise, + // the event will be raised when the POAManager does become active. + if (!this->poa_activated_event()) + { + // An error has been already been reported to the log with + // the detailed reason for the failure to handle the event. + return false; + } + } + + // Set the CSD Strategy_Base on the strategy proxy object owned by the POA. + bool strategy_set = false; + ACE_TRY_NEW_ENV + { + poa_impl->set_csd_strategy (this ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + strategy_set = true; + } + ACE_CATCHANY + { + } + ACE_ENDTRY; + + if (! strategy_set) + { + // We need to make sure that we raise a poa_deactivated_event() if + // we earlier raised a poa_activated_event(). + this->poa_deactivated_event(); + + // An error has been already been reported to the log with + // the detailed reason why the proxy will not accept the + // custom strategy. + return false; + } + + // Save a duplicate of the poa into our data member. + this->poa_ = PortableServer::POA::_duplicate (poa); + + // Success + return true; +} + + +void +TAO::CSD::Strategy_Base::servant_activated_event_i + (PortableServer::Servant , + const PortableServer::ObjectId& + ACE_ENV_ARG_DECL) +{ + // do nothing. +} + + +void +TAO::CSD::Strategy_Base::servant_deactivated_event_i + (PortableServer::Servant, + const PortableServer::ObjectId& + ACE_ENV_ARG_DECL) +{ + // do nothing. +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Base.h b/TAO/tao/CSD_Framework/CSD_Strategy_Base.h new file mode 100644 index 00000000000..d65753a27f7 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Base.h @@ -0,0 +1,174 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CSD_Strategy_Base.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_FW_CUSTOM_SERVANT_DISPATCHING_STRATEGY_H +#define TAO_CSD_FW_CUSTOM_SERVANT_DISPATCHING_STRATEGY_H + +#include /**/ "ace/pre.h" + +#include "tao/CSD_Framework/CSD_FW_Export.h" + +#include "tao/PortableServer/PortableServer.h" +#include "tao/PortableServer/Servant_Upcall.h" +#include "tao/PortableServer/Servant_Base.h" +#include "tao/TAO_Server_Request.h" +#include "tao/LocalObject.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/CSD_Framework/CSD_FrameworkC.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +class TAO_Root_POA; +namespace PortableServer +{ + class POAManager; +} + +namespace TAO +{ + namespace CSD + { + /** + * @class Strategy_Base + * + * @brief Base class for all Custom Servant Dispatching Strategies. + * + * This class serves as the base class for all "custom" strategies that + * perform servant dispatching. An instance of (a subclass of) this class + * can be applied to a POA object. Any servant requests for the POA will + * be "dispatched" to this strategy object. + * + */ + class TAO_CSD_FW_Export Strategy_Base + : public CSD_Framework::Strategy, + public TAO_Local_RefCounted_Object + { + public: + + /// Result Type for dispatching method(s). + enum DispatchResult + { + // The request dispatching has been handled. + DISPATCH_HANDLED, + + // The request dispatching has been rejected. + DISPATCH_REJECTED, + + // Defer to "default" dispatching strategy (use the caller's thread). + DISPATCH_DEFERRED + }; + + /// Virtual Destructor. + virtual ~Strategy_Base(); + + /// This method is invoked to "attach" this strategy object to + /// the supplied POA. Returns true for success, and false for failure. + CORBA::Boolean apply_to(PortableServer::POA_ptr poa ACE_ENV_ARG_DECL) + ACE_THROW_SPEC((CORBA::SystemException)); + + protected: + /// Default Constructor. + Strategy_Base(); + + /// Subclass provides implementation to dispatch a remote request. + virtual DispatchResult dispatch_remote_request_i + (TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant + ACE_ENV_ARG_DECL) = 0; + + /// Subclass provides implementation to dispatch a collocated request. + virtual DispatchResult dispatch_collocated_request_i + (TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant + ACE_ENV_ARG_DECL) = 0; + + /// Event - The POA has been activated. + virtual bool poa_activated_event_i() = 0; + + /// Event - The POA has been deactivated. + virtual void poa_deactivated_event_i() = 0; + + /// Event - A servant has been activated. + virtual void servant_activated_event_i + (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL); + + /// Event - A servant has been deactivated. + virtual void servant_deactivated_event_i + (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL); + + private: + + /// Only our friend, the proxy, is allowed to invoke our private operations. + /// This allows us to not pollute the public interface of the CSD Strategy_Base + /// subclasses with methods that should never be called (except by the + /// proxy, of course). + friend class Strategy_Proxy; + + /// This CSD Strategy_Base has been asked to dispatch a (collocated or remote) + /// request. + void dispatch_request(TAO_ServerRequest& server_request, + ::TAO::Portable_Server::Servant_Upcall& upcall + ACE_ENV_ARG_DECL); + + /// Event - The POA has been activated. This happens when the POA_Manager + /// is activated. + bool poa_activated_event(); + + /// Event - The POA has been deactivated. This happens when the + /// POAManager is deactivated, or when the POA is destroyed. + void poa_deactivated_event(); + + /// Event - A servant has been activated. + void servant_activated_event(PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL); + + /// Event - A servant has been deactivated. This also occurs when + /// the POA is destroyed. + void servant_deactivated_event(PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL); + + /// The POA to which this strategy has been applied. + ::PortableServer::POA_var poa_; + + /// This flag indicates that the POA is currently active (true) or + /// currently inactive (false). + bool poa_activated_; + }; + } +} + +TAO_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "tao/CSD_Framework/CSD_Strategy_Base.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_FW_CUSTOM_SERVANT_DISPATCHING_STRATEGY_H */ diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Base.inl b/TAO/tao/CSD_Framework/CSD_Strategy_Base.inl new file mode 100644 index 00000000000..6dce0cf7397 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Base.inl @@ -0,0 +1,144 @@ +// -*- C++ -*- +// +// $Id$ + +#include "tao/debug.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +TAO::CSD::Strategy_Base::Strategy_Base() + : poa_activated_(false) +{ +} + +ACE_INLINE +void +TAO::CSD::Strategy_Base::dispatch_request + (TAO_ServerRequest& server_request, + TAO::Portable_Server::Servant_Upcall& upcall + ACE_ENV_ARG_DECL) +{ + DispatchResult result; + + if (server_request.collocated()) + { + result = this->dispatch_collocated_request_i(server_request, + upcall.user_id(), + this->poa_.in(), + server_request.operation(), + upcall.servant() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + result = this->dispatch_remote_request_i(server_request, + upcall.user_id(), + this->poa_.in(), + server_request.operation(), + upcall.servant() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + switch (result) + { + case DISPATCH_HANDLED: + // Do nothing. Everything has been handled. + break; + + case DISPATCH_REJECTED: + if (server_request.collocated ()) + { + CORBA::NO_IMPLEMENT ex; + ex._raise (); + } + else + { + // Raise an appropriate SystemException if the request is expecting + // a reply. + if (!server_request.sync_with_server() && + server_request.response_expected() && + !server_request.deferred_reply()) + { + CORBA::NO_IMPLEMENT ex; + server_request.tao_send_reply_exception(ex); + } + } + break; + + case DISPATCH_DEFERRED: + // Perform the "default" dispatching strategy logic for this request + // right now, using the current thread. + upcall.servant()->_dispatch(server_request, + (void*)&upcall + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + break; + + default: + if (TAO_debug_level > 0) + ACE_ERROR((LM_ERROR, + ACE_TEXT("(%P|%t) Unknown result (%d) from call to ") + ACE_TEXT("dispatch_remote_request_i().\n"), result)); + // Since we do not know what to do here, just do the minimum, which + // treats this case just like the DISPATCH_HANDLED case, for better + // or worse. Hitting this default case means a coding error. + break; + } +} + + +ACE_INLINE +bool +TAO::CSD::Strategy_Base::poa_activated_event() +{ + // Notify the subclass of the event, saving the result. + this->poa_activated_ = this->poa_activated_event_i(); + + // Return the result + return this->poa_activated_; +} + +ACE_INLINE +void +TAO::CSD::Strategy_Base::poa_deactivated_event() +{ + if (this->poa_activated_) + { + this->poa_activated_ = false; + + // Notify the subclass of the event. + this->poa_deactivated_event_i(); + + // Reset the poa to nil to decrement the reference count. + // This will break the circular dependency of the deletion + // of the CSD POA. + this->poa_ = 0; + } +} + +ACE_INLINE +void +TAO::CSD::Strategy_Base::servant_activated_event + (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + this->servant_activated_event_i(servant, oid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +ACE_INLINE +void +TAO::CSD::Strategy_Base::servant_deactivated_event + (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + this->servant_deactivated_event_i(servant, oid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.cpp b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.cpp new file mode 100644 index 00000000000..b163134be56 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.cpp @@ -0,0 +1,50 @@ +// $Id$ + +#include "tao/CSD_Framework/CSD_Strategy_Proxy.h" +#include "tao/TAO_Server_Request.h" +#include "tao/debug.h" + +ACE_RCSID (CSD_Framework, + CSD_Strategy_Base, + "$Id$") + + +#if !defined (__ACE_INLINE__) +# include "tao/CSD_Framework/CSD_Strategy_Proxy.inl" +#endif /* ! __ACE_INLINE__ */ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +bool +TAO::CSD::Strategy_Proxy::custom_strategy + (CSD_Framework::Strategy_ptr strategy) +{ + if (this->strategy_impl_) + { + if (TAO_debug_level > 0) + ACE_ERROR((LM_ERROR, + ACE_TEXT("(%P|%t) Error - TAO::CSD::Strategy_Proxy ") + ACE_TEXT("object already has a custom strategy.\n"))); + + return false; + } + + if (CORBA::is_nil(strategy)) + { + if (TAO_debug_level > 0) + ACE_ERROR((LM_ERROR, + ACE_TEXT("(%P|%t) Error - TAO::CSD::Strategy_Proxy ") + ACE_TEXT("supplied with a NIL custom strategy.\n"))); + + return false; + } + + // We need to bump up the reference count of the strategy before saving + // it off into our handle (smart pointer) data member. + this->strategy_ = CSD_Framework::Strategy::_duplicate(strategy); + this->strategy_impl_ = dynamic_cast <TAO::CSD::Strategy_Base*> (strategy); + + return true; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.h b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.h new file mode 100644 index 00000000000..959a7cb9ebb --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.h @@ -0,0 +1,114 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CSD_Strategy_Proxy.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_SERVANT_DISPATCHING_STRATEGY_PROXY_H +#define TAO_SERVANT_DISPATCHING_STRATEGY_PROXY_H + +#include /**/ "ace/pre.h" + +#include "tao/CSD_Framework/CSD_FW_Export.h" + +#include "tao/PortableServer/PortableServer.h" +#include "tao/PortableServer/Servant_Upcall.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/CSD_Framework/CSD_Strategy_Base.h" + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +class TAO_ServerRequest; + +namespace TAO +{ + namespace CSD + { + /** + * @class Strategy_Proxy + * + * @brief Proxy class for the Custom Servant Dispatching Strategy. + * + * If no custom servant dispatching strategy is provided to the proxy, + * then the "default servant dispatching strategy" logic is used. + */ + class TAO_CSD_FW_Export Strategy_Proxy + { + public: + + /// Default Constructor. + Strategy_Proxy(); + + /// Destructor. + ~Strategy_Proxy(); + + /// Mutator to provide the proxy with a CSD Strategy object. + /// A return value of true indicates success, and false indicates + /// failure to set the custom strategy on the proxy object. + bool custom_strategy(CSD_Framework::Strategy_ptr strategy); + + /// Invoked by the Object_Adapter using an ORB thread. + /// + /// If the proxy object holds a custom strategy object, then this method + /// will simply delegate to the custom strategy object. Otherwise, + /// this method will perform the "default servant dispatching strategy" + /// logic, preserving the original logic path as it was prior to the + /// introduction of the Custom Servant Dispatching feature. + /// + /// This method will be inlined (if inlining is turned on during the build). + /// + /// The added cost to the original logic path will be this method + /// invocation + one conditional (an is_nil() call/comparison for truth on + /// the smart pointer to the custom dispatching strategy object). + void dispatch_request(TAO_ServerRequest& server_request, + TAO::Portable_Server::Servant_Upcall& upcall + ACE_ENV_ARG_DECL); + + + /// Event - The POA has been (or is being) activated. + bool poa_activated_event(); + + /// Event - The POA has been deactivated. + void poa_deactivated_event(); + + /// Event - A servant has been activated. + void servant_activated_event(PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL); + + /// Event - A servant has been deactivated. + void servant_deactivated_event(PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL); + + private: + + /// Smart Pointer to a custom servant dispatching strategy object. + /// This smart pointer will be in the "nil" state when the "default" + /// strategy is to be applied. + CSD_Framework::Strategy_var strategy_; + TAO::CSD::Strategy_Base *strategy_impl_; + }; + } +} + +TAO_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +# include "tao/CSD_Framework/CSD_Strategy_Proxy.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.inl b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.inl new file mode 100644 index 00000000000..957852e6517 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.inl @@ -0,0 +1,104 @@ +// -*- C++ -*- +// +// $Id$ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +ACE_INLINE +TAO::CSD::Strategy_Proxy::Strategy_Proxy() + : strategy_impl_(0) +{ +} + +ACE_INLINE +TAO::CSD::Strategy_Proxy::~Strategy_Proxy() +{ + strategy_impl_ = 0; // don't delete it! The var will do it for us. +} + +ACE_INLINE +void +TAO::CSD::Strategy_Proxy::dispatch_request + (TAO_ServerRequest& server_request, + TAO::Portable_Server::Servant_Upcall& upcall + ACE_ENV_ARG_DECL) +{ + + if (this->strategy_impl_ == 0) + { + // This is the "default" strategy implementation. + upcall.servant()->_dispatch(server_request, + (void*)&upcall + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + // Delegate to the custom strategy object. + this->strategy_impl_->dispatch_request(server_request, + upcall + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +} + +ACE_INLINE +bool +TAO::CSD::Strategy_Proxy::poa_activated_event() +{ + // Delegate to the custom strategy object (or return true if this proxy + // is not holding a custom strategy). + return (this->strategy_impl_ == 0) ? true + : this->strategy_impl_->poa_activated_event(); +} + + +ACE_INLINE +void +TAO::CSD::Strategy_Proxy::poa_deactivated_event() +{ + // We only need to do something if this proxy holds a custom strategy. + if (this->strategy_impl_) + { + // Delegate to the custom strategy object. + this->strategy_impl_->poa_deactivated_event(); + } +} + +ACE_INLINE +void +TAO::CSD::Strategy_Proxy::servant_activated_event + (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + // We only need to do something if this proxy holds a custom strategy. + if (this->strategy_impl_) + { + // Delegate to the custom strategy object. + this->strategy_impl_->servant_activated_event(servant, + oid + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +} + +ACE_INLINE +void +TAO::CSD::Strategy_Proxy::servant_deactivated_event + (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + // We only need to do something if this proxy holds a custom strategy. + if (this->strategy_impl_) + { + // Delegate to the custom strategy object. + this->strategy_impl_->servant_deactivated_event(servant, + oid + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Repository.cpp b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.cpp new file mode 100644 index 00000000000..5a169516bf5 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.cpp @@ -0,0 +1,117 @@ +// $Id$ + +#include "tao/CSD_Framework/CSD_Strategy_Repository.h" +#include "tao/debug.h" + +ACE_RCSID (CSD_Framework, + CSD_Strategy_Factory, + "$Id$") + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_CSD_Strategy_Repository::TAO_CSD_Strategy_Repository() +{ +} + + +TAO_CSD_Strategy_Repository::~TAO_CSD_Strategy_Repository() +{ + delete this->strategy_list_head_; +} + +int +TAO_CSD_Strategy_Repository::init(int, ACE_TCHAR **) +{ + + static int initialized = 0; + + // Only allow initialization once. + if (initialized) + return 0; + + initialized = 1; + this->strategy_list_head_ = 0; + return 0; +} + +CSD_Framework::Strategy_ptr +TAO_CSD_Strategy_Repository::find (const ACE_CString& name) +{ + + if (this->strategy_list_head_ != 0) + { + Strategy_Node *node = this->strategy_list_head_->find(name); + if (node != 0) + return CSD_Framework::Strategy::_duplicate (node->strategy_.in()); + } + + return CSD_Framework::Strategy::_nil(); +} + + +int +TAO_CSD_Strategy_Repository::add_strategy (const ACE_CString& name, + CSD_Framework::Strategy_ptr strat) +{ + Strategy_Node *node = 0; + ACE_NEW_RETURN (node, Strategy_Node(name,strat),-1); + if (this->strategy_list_head_ == 0) + this->strategy_list_head_ = node; + else + this->strategy_list_head_->add_node(node); + + if (TAO_debug_level > 3) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("Strategy_Repository::add_strategy for %s \n"), + name.c_str ())); + } + return 0; +} + +TAO_CSD_Strategy_Repository::Strategy_Node::Strategy_Node (const ACE_CString& name, + CSD_Framework::Strategy_ptr strat) + : poa_name_(name), + strategy_(CSD_Framework::Strategy::_duplicate(strat)), + next_(0) +{ +} + +TAO_CSD_Strategy_Repository::Strategy_Node::~Strategy_Node () +{ + if (this->next_) + delete this->next_; +} + +void +TAO_CSD_Strategy_Repository::Strategy_Node::add_node(Strategy_Node *node) +{ + if (this->next_) + this->next_->add_node(node); + else + this->next_ = node; +} + +TAO_CSD_Strategy_Repository::Strategy_Node * +TAO_CSD_Strategy_Repository::Strategy_Node::find(const ACE_CString &name) +{ + if (this->poa_name_ == name) + return this; + if (this->next_) + return this->next_->find(name); + return 0; +} + +TAO_END_VERSIONED_NAMESPACE_DECL + +///////////////////////////////////////////////////////////////////// + +ACE_FACTORY_DEFINE (TAO_CSD_FW, TAO_CSD_Strategy_Repository) +ACE_STATIC_SVC_DEFINE (TAO_CSD_Strategy_Repository, + ACE_TEXT ("TAO_CSD_Strategy_Repository"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (TAO_CSD_Strategy_Repository), + ACE_Service_Type::DELETE_THIS + | ACE_Service_Type::DELETE_OBJ, + 0) diff --git a/TAO/tao/CSD_Framework/CSD_Strategy_Repository.h b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.h new file mode 100644 index 00000000000..7e50fe5f62f --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.h @@ -0,0 +1,78 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CSD_Strategy_Repository.h + * + * $Id$ + * + * @author Yan Dai <dai_y@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_STRATEGY_FACTORY_H +#define TAO_CSD_STRATEGY_FACTORY_H + +#include /**/ "ace/pre.h" + +#include "tao/CSD_Framework/CSD_FW_Export.h" +#include "tao/CSD_Framework/CSD_FrameworkC.h" +#include "ace/Service_Object.h" +#include "ace/Service_Config.h" +#include "ace/Synch.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class TAO_CSD_Strategy_Factory + * + * @brief An ACE_Service_Object capable of creating TP_Strategy objects. + * + * TBD - Explain in more detail. + * + */ +class TAO_CSD_FW_Export TAO_CSD_Strategy_Repository : public ACE_Service_Object +{ +public: + + /// Constructor. + TAO_CSD_Strategy_Repository(); + + /// Virtual Destructor. + virtual ~TAO_CSD_Strategy_Repository(); + + int init (int argc, ACE_TCHAR ** argv); + + /// Factory method used to create a CSD_Strategy object. + CSD_Framework::Strategy_ptr find (const ACE_CString& poa_name); + + int add_strategy (const ACE_CString& poa_name, + CSD_Framework::Strategy_ptr strategy); + +private: + struct Strategy_Node { + Strategy_Node(const ACE_CString& poa_name, + CSD_Framework::Strategy_ptr strategy); + ~Strategy_Node(); + void add_node (Strategy_Node *); + Strategy_Node *find(const ACE_CString& name); + + ACE_CString poa_name_; + CSD_Framework::Strategy_var strategy_; + Strategy_Node * next_; + }; + Strategy_Node * strategy_list_head_; +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +ACE_STATIC_SVC_DECLARE_EXPORT (TAO_CSD_FW, TAO_CSD_Strategy_Repository) +ACE_FACTORY_DECLARE (TAO_CSD_FW, TAO_CSD_Strategy_Repository) + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_STRATEGY_FACTORY_H */ diff --git a/TAO/tao/CSD_Framework/TAO_CSD_Framework.pc.in b/TAO/tao/CSD_Framework/TAO_CSD_Framework.pc.in new file mode 100644 index 00000000000..bef4a93f175 --- /dev/null +++ b/TAO/tao/CSD_Framework/TAO_CSD_Framework.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: TAO_CSD_Framework +Description: TAO CSD Framework Library +Requires: TAO_PortableServer, TAO_PI, TAO +Version: @VERSION@ +Libs: -L${libdir} -lTAO +Cflags: -I${includedir} |