diff options
Diffstat (limited to 'TAO/tao')
113 files changed, 8045 insertions, 5 deletions
diff --git a/TAO/tao/CSD_Framework.mpc b/TAO/tao/CSD_Framework.mpc new file mode 100644 index 00000000000..d80d59483e5 --- /dev/null +++ b/TAO/tao/CSD_Framework.mpc @@ -0,0 +1,34 @@ +//$Id$ +project : taolib, portableserver, core, pi { + sharedname = TAO_CSD_Framework + dynamicflags = TAO_CSD_FW_BUILD_DLL + includes += $(TAO_ROOT)/tao + + Source_Files { + CSD_Framework + } + + Header_Files { + CSD_Framework + } + + Inline_Files { + CSD_Framework + } + + Template_Files { + CSD_Framework + } + + Resource_Files { + CSD_Framework + } + + IDL_Files { + CSD_Framework + } + + PIDL_Files { + CSD_Framework + } +} 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..63513ba304d --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.cpp @@ -0,0 +1,56 @@ +// @(#) $Id$ + +#include "CSD_Default_Servant_Dispatcher.h" +#include "CSD_POA.h" +#include "CSD_Strategy_Repository.h" +#include "ace/Dynamic_Service.h" + +ACE_RCSID(CSD_Framework, + CSD_Default_Servant_Dispatcher, + "$Id$") + + +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, + TAO_POA_Manager &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"); + + 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; +} 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..120630c123b --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Default_Servant_Dispatcher.h @@ -0,0 +1,49 @@ +/* -*- 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 "CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PortableServer/Default_Servant_Dispatcher.h" + +/** + * @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, + TAO_POA_Manager &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); +}; + +#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..94d71cb86af --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.cpp @@ -0,0 +1,462 @@ +// $Id$ +#include "CSD_FW_Server_Request_Wrapper.h" +#include "tao/debug.h" +#include "tao/ORB_Constants.h" +#include "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 "CSD_FW_Server_Request_Wrapper.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::FW_Server_Request_Wrapper::~FW_Server_Request_Wrapper() +{ + // Only delete the request if we cloned it. + if (this->is_clone_) + { + // 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_; + } +} + + +// 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_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 = this->create_new_request (); + + 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: ACE_CString + // ACTION: Assignment performs deep-copy of string contents. + clone_obj->operation_ = request->operation_; + + // 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_; + + // 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: TAO::PICurrent_Copy_Callback + // ACTION: No copy/assignment operator. + // Just leave this alone for a clone. + // + // clone_obj->pi_current_copy_callback_ + + // 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 = new char[from_non_const->opname_len_ + 1]; + ACE_OS::strncpy(cloned_op_name, from_non_const->opname_, from_non_const->opname_len_); + cloned_op_name[from_non_const->opname_len_] = '\0'; + + TAO_OutputCDR outcdr; + + 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; + } + + ACE_NEW_RETURN (cdr, + TAO_InputCDR (outcdr), + false); + + + // 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_; +} + + +void +TAO::CSD::FW_Server_Request_Wrapper::clone (TAO_Service_Context& from, + TAO_Service_Context& to) +{ + to.service_context_ = from.service_context_; +} + +TAO_ServerRequest* +TAO::CSD::FW_Server_Request_Wrapper::create_new_request () +{ + // Use one of constructor to create the TAO_ServerRequest object then + // reset the data members. This reduces the footprint due to a default + // TAO_ServerRequest constructor. + // + //TAO_ServerRequest (TAO_Pluggable_Messaging *mesg_base, + // TAO_InputCDR &input, + // TAO_OutputCDR &output, + // TAO_Transport *transport, + // TAO_ORB_Core *orb_core); + + TAO_ServerRequest* request = 0; + + TAO_InputCDR dummy_input ((ACE_Message_Block *)0); // empty input cdr stream + TAO_OutputCDR dummy_output ((char *)0, (size_t) 0); // empty output cdr stream + ACE_NEW_RETURN (request, + TAO_ServerRequest (0, + dummy_input, + dummy_output, + 0, + 0), + 0); + + request->incoming_ = 0; + request->outgoing_ = 0; + + return request; +} + + +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 = new char[ACE_CDR::DEFAULT_BUFSIZE]; + + 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; +} + 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..945a921ca99 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h @@ -0,0 +1,127 @@ +/* -*- 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 "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" + +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 new TAO_ServerRequest with default initial values. + TAO_ServerRequest* create_new_request (); + + /// 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_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "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..a259de116ab --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.inl @@ -0,0 +1,42 @@ +// $Id$ + + +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); + } +} + diff --git a/TAO/tao/CSD_Framework/CSD_Framework.pidl b/TAO/tao/CSD_Framework/CSD_Framework.pidl new file mode 100644 index 00000000000..ba1940df02e --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Framework.pidl @@ -0,0 +1,75 @@ +// -*- 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 -Sc -GA -I$TAO_ROOT \ + -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" \ + CSD_Framework.pidl + * + * After the file is generated a patch from the diffs directory must + * be applied. The patch: + * + * - Disables parts of the code under certain configurations. + * + * - Eliminates cycles in the include dependencies. + * + * - Adds non-idl components of CSD_Framework to the namespace. + * This includes (a) Servant (b) ServantBase (c) RefCountServantBase + * (d) Cookie (e) ObjectId_to_string (f) string_to_ObjectId (g) + * ObjectId_to_wstring (h) wstring_to_ObjectId (i) ServantBase_var + * (j) DynamicImplementation (k) LocalServantBase + * + * Apply patches using the following command: + * + * patch < diffs/CSD_Framework.diff + * + * Note: The diffs were generated using: + * + * rm diffs/CSD_Framework.diff + * for i in CSD_FrameworkC.{h,i,cpp}; do + * diff -wub orig/$i $i >> diffs/CSD_Framework.diff + * done + */ + +#ifndef _CSD_FRAMEWORK_IDL_ +#define _CSD_FRAMEWORK_IDL_ + +#include <tao/PortableServer/PortableServer.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_IDL_ diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkA.cpp b/TAO/tao/CSD_Framework/CSD_FrameworkA.cpp new file mode 100644 index 00000000000..9045084e4bc --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FrameworkA.cpp @@ -0,0 +1,73 @@ +// -*- C++ -*- +// +// $Id$ + +// **** Code generated by the The ACE ORB (TAO) IDL Compiler **** +// TAO and the TAO IDL Compiler have been developed by: +// Center for Distributed Object Computing +// Washington University +// St. Louis, MO +// USA +// http://www.cs.wustl.edu/~schmidt/doc-center.html +// and +// Distributed Object Computing Laboratory +// University of California at Irvine +// Irvine, CA +// USA +// http://doc.ece.uci.edu/ +// and +// Institute for Software Integrated Systems +// Vanderbilt University +// Nashville, TN +// USA +// http://www.isis.vanderbilt.edu/ +// +// Information about TAO is available at: +// http://www.cs.wustl.edu/~schmidt/TAO.html + +#include "CSD_FrameworkA.h" +#include "tao/AnyTypeCode/Null_RefCount_Policy.h" +#include "tao/AnyTypeCode/TypeCode_Constants.h" +#include "tao/AnyTypeCode/Alias_TypeCode_Static.h" +#include "tao/AnyTypeCode/Objref_TypeCode_Static.h" +#include "tao/AnyTypeCode/String_TypeCode_Static.h" +#include "tao/AnyTypeCode/Any.h" +#include "tao/CDR.h" +#include "tao/AnyTypeCode/Any.h" +#include "tao/AnyTypeCode/Any_Impl_T.h" + +// TAO_IDL - Generated from +// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_typecode/objref_typecode.cpp:76 + +static TAO::TypeCode::Objref<char const *, + TAO::Null_RefCount_Policy> + _tao_tc_CSD_Framework_Strategy ( + ::CORBA::tk_local_interface, + "IDL:CSD_Framework/Strategy:1.0", + "Strategy"); + +namespace CSD_Framework +{ + ::CORBA::TypeCode_ptr const _tc_Strategy = + &_tao_tc_CSD_Framework_Strategy; +} + + + +// TAO_IDL - Generated from +// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_typecode/objref_typecode.cpp:76 + +static TAO::TypeCode::Objref<char const *, + TAO::Null_RefCount_Policy> + _tao_tc_CSD_Framework_POA ( + ::CORBA::tk_local_interface, + "IDL:CSD_Framework/POA:1.0", + "POA"); + +namespace CSD_Framework +{ + ::CORBA::TypeCode_ptr const _tc_POA = + &_tao_tc_CSD_Framework_POA; +} + + diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkA.h b/TAO/tao/CSD_Framework/CSD_FrameworkA.h new file mode 100644 index 00000000000..db88e7a79d6 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FrameworkA.h @@ -0,0 +1,64 @@ +// -*- C++ -*- +// +// $Id$ + +// **** Code generated by the The ACE ORB (TAO) IDL Compiler **** +// TAO and the TAO IDL Compiler have been developed by: +// Center for Distributed Object Computing +// Washington University +// St. Louis, MO +// USA +// http://www.cs.wustl.edu/~schmidt/doc-center.html +// and +// Distributed Object Computing Laboratory +// University of California at Irvine +// Irvine, CA +// USA +// http://doc.ece.uci.edu/ +// and +// Institute for Software Integrated Systems +// Vanderbilt University +// Nashville, TN +// USA +// http://www.isis.vanderbilt.edu/ +// +// Information about TAO is available at: +// http://www.cs.wustl.edu/~schmidt/TAO.html + +// TAO_IDL - Generated from +// .\be\be_codegen.cpp:754 + +#ifndef _TAO_IDL_ORIG_CSD_FRAMEWORKA_H_ +#define _TAO_IDL_ORIG_CSD_FRAMEWORKA_H_ + +#include /**/ "ace/pre.h" + +#include "CSD_FW_Export.h" +#include "CSD_FrameworkC.h" +//#include "tao/PortableServer/PortableServerA.h" + + +// TAO_IDL - Generated from +// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_module/module_ch.cpp:59 + +namespace CSD_Framework +{ + + // TAO_IDL - Generated from + // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_typecode/typecode_decl.cpp:49 + + extern TAO_CSD_FW_Export ::CORBA::TypeCode_ptr const _tc_Strategy; + + // TAO_IDL - Generated from + // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_typecode/typecode_decl.cpp:49 + + extern TAO_CSD_FW_Export ::CORBA::TypeCode_ptr const _tc_POA; + +// TAO_IDL - Generated from +// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_module/module_ch.cpp:86 + +} // module CSD_Framework + +#include /**/ "ace/post.h" + +#endif /* ifndef */ diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkC.cpp b/TAO/tao/CSD_Framework/CSD_FrameworkC.cpp new file mode 100644 index 00000000000..12b91dd79cc --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FrameworkC.cpp @@ -0,0 +1,293 @@ +// -*- C++ -*- +// +// $Id$ + +// **** Code generated by the The ACE ORB (TAO) IDL Compiler **** +// TAO and the TAO IDL Compiler have been developed by: +// Center for Distributed Object Computing +// Washington University +// St. Louis, MO +// USA +// http://www.cs.wustl.edu/~schmidt/doc-center.html +// and +// Distributed Object Computing Laboratory +// University of California at Irvine +// Irvine, CA +// USA +// http://doc.ece.uci.edu/ +// and +// Institute for Software Integrated Systems +// Vanderbilt University +// Nashville, TN +// USA +// http://www.isis.vanderbilt.edu/ +// +// Information about TAO is available at: +// http://www.cs.wustl.edu/~schmidt/TAO.html + +// TAO_IDL - Generated from +// .\be\be_codegen.cpp:277 + + +#include "CSD_FrameworkC.h" +#include "tao/CDR.h" +#include "ace/OS_NS_string.h" + +#if !defined (__ACE_INLINE__) +#include "CSD_FrameworkC.inl" +#endif /* !defined INLINE */ + +// TAO_IDL - Generated from +// .\be\be_visitor_arg_traits.cpp:70 + +// Arg traits specializations. +namespace TAO +{ +} + + +// TAO_IDL - Generated from +// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_cs.cpp:60 + +// Traits specializations for CSD_Framework::Strategy. + +CSD_Framework::Strategy_ptr +TAO::Objref_Traits<CSD_Framework::Strategy>::duplicate ( + CSD_Framework::Strategy_ptr p + ) +{ + return CSD_Framework::Strategy::_duplicate (p); +} + +void +TAO::Objref_Traits<CSD_Framework::Strategy>::release ( + CSD_Framework::Strategy_ptr p + ) +{ + CORBA::release (p); +} + +CSD_Framework::Strategy_ptr +TAO::Objref_Traits<CSD_Framework::Strategy>::nil (void) +{ + return CSD_Framework::Strategy::_nil (); +} + +::CORBA::Boolean +TAO::Objref_Traits<CSD_Framework::Strategy>::marshal ( + CSD_Framework::Strategy_ptr p, + TAO_OutputCDR & cdr + ) +{ + return ::CORBA::Object::marshal (p, cdr); +} + +CSD_Framework::Strategy::Strategy (void) +{} + +CSD_Framework::Strategy::~Strategy (void) +{} + +CSD_Framework::Strategy_ptr +CSD_Framework::Strategy::_narrow ( + ::CORBA::Object_ptr _tao_objref + ACE_ENV_ARG_DECL_NOT_USED + ) +{ + return Strategy::_duplicate ( + dynamic_cast<Strategy_ptr> (_tao_objref) + ); +} + +CSD_Framework::Strategy_ptr +CSD_Framework::Strategy::_unchecked_narrow ( + ::CORBA::Object_ptr _tao_objref + ACE_ENV_ARG_DECL_NOT_USED + ) +{ + return Strategy::_duplicate ( + dynamic_cast<Strategy_ptr> (_tao_objref) + ); +} + +CSD_Framework::Strategy_ptr +CSD_Framework::Strategy::_duplicate (Strategy_ptr obj) +{ + if (! CORBA::is_nil (obj)) + { + obj->_add_ref (); + } + + return obj; +} + +void +CSD_Framework::Strategy::_tao_release (Strategy_ptr obj) +{ + CORBA::release (obj); +} + +::CORBA::Boolean +CSD_Framework::Strategy::_is_a ( + const char *value + ACE_ENV_ARG_DECL_NOT_USED + ) +{ + if ( + !ACE_OS::strcmp ( + value, + "IDL:CSD_Framework/Strategy:1.0" + ) || + !ACE_OS::strcmp ( + value, + "IDL:omg.org/CORBA/LocalObject:1.0" + ) || + !ACE_OS::strcmp ( + value, + "IDL:omg.org/CORBA/Object:1.0" + ) + ) + { + return true; // success using local knowledge + } + else + { + return false; + } +} + +const char* CSD_Framework::Strategy::_interface_repository_id (void) const +{ + return "IDL:CSD_Framework/Strategy:1.0"; +} + +::CORBA::Boolean +CSD_Framework::Strategy::marshal (TAO_OutputCDR &) +{ + return false; +} + +// TAO_IDL - Generated from +// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_cs.cpp:60 + +// Traits specializations for CSD_Framework::POA. + +CSD_Framework::POA_ptr +TAO::Objref_Traits<CSD_Framework::POA>::duplicate ( + CSD_Framework::POA_ptr p + ) +{ + return CSD_Framework::POA::_duplicate (p); +} + +void +TAO::Objref_Traits<CSD_Framework::POA>::release ( + CSD_Framework::POA_ptr p + ) +{ + CORBA::release (p); +} + +CSD_Framework::POA_ptr +TAO::Objref_Traits<CSD_Framework::POA>::nil (void) +{ + return CSD_Framework::POA::_nil (); +} + +::CORBA::Boolean +TAO::Objref_Traits<CSD_Framework::POA>::marshal ( + CSD_Framework::POA_ptr p, + TAO_OutputCDR & cdr + ) +{ + return ::CORBA::Object::marshal (p, cdr); +} + +CSD_Framework::POA::POA (void) +{} + +CSD_Framework::POA::~POA (void) +{} + +CSD_Framework::POA_ptr +CSD_Framework::POA::_narrow ( + ::CORBA::Object_ptr _tao_objref + ACE_ENV_ARG_DECL_NOT_USED + ) +{ + return POA::_duplicate ( + dynamic_cast<POA_ptr> (_tao_objref) + ); +} + +CSD_Framework::POA_ptr +CSD_Framework::POA::_unchecked_narrow ( + ::CORBA::Object_ptr _tao_objref + ACE_ENV_ARG_DECL_NOT_USED + ) +{ + return POA::_duplicate ( + dynamic_cast<POA_ptr> (_tao_objref) + ); +} + +CSD_Framework::POA_ptr +CSD_Framework::POA::_duplicate (POA_ptr obj) +{ + if (! CORBA::is_nil (obj)) + { + obj->_add_ref (); + } + + return obj; +} + +void +CSD_Framework::POA::_tao_release (POA_ptr obj) +{ + CORBA::release (obj); +} + +::CORBA::Boolean +CSD_Framework::POA::_is_a ( + const char *value + ACE_ENV_ARG_DECL_NOT_USED + ) +{ + if ( + !ACE_OS::strcmp ( + value, + "IDL:omg.org/PortableServer/POA:1.0" + ) || + !ACE_OS::strcmp ( + value, + "IDL:CSD_Framework/POA:1.0" + ) || + !ACE_OS::strcmp ( + value, + "IDL:omg.org/CORBA/LocalObject:1.0" + ) || + !ACE_OS::strcmp ( + value, + "IDL:omg.org/CORBA/Object:1.0" + ) + ) + { + return true; // success using local knowledge + } + else + { + return false; + } +} + +const char* CSD_Framework::POA::_interface_repository_id (void) const +{ + return "IDL:CSD_Framework/POA:1.0"; +} + +::CORBA::Boolean +CSD_Framework::POA::marshal (TAO_OutputCDR &) +{ + return false; +} diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkC.h b/TAO/tao/CSD_Framework/CSD_FrameworkC.h new file mode 100644 index 00000000000..832eae8ffe0 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FrameworkC.h @@ -0,0 +1,312 @@ +// -*- C++ -*- +// +// $Id$ + +// **** Code generated by the The ACE ORB (TAO) IDL Compiler **** +// TAO and the TAO IDL Compiler have been developed by: +// Center for Distributed Object Computing +// Washington University +// St. Louis, MO +// USA +// http://www.cs.wustl.edu/~schmidt/doc-center.html +// and +// Distributed Object Computing Laboratory +// University of California at Irvine +// Irvine, CA +// USA +// http://doc.ece.uci.edu/ +// and +// Institute for Software Integrated Systems +// Vanderbilt University +// Nashville, TN +// USA +// http://www.isis.vanderbilt.edu/ +// +// Information about TAO is available at: +// http://www.cs.wustl.edu/~schmidt/TAO.html + +// TAO_IDL - Generated from +// .\be\be_codegen.cpp:154 + +#ifndef _TAO_IDL_ORIG_CSD_FRAMEWORKC_H_ +#define _TAO_IDL_ORIG_CSD_FRAMEWORKC_H_ + +#include /**/ "ace/pre.h" + + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_FW_Export.h" +#include "tao/ORB.h" +#include "tao/SystemException.h" +#include "tao/Environment.h" +#include "tao/Object.h" +#include "tao/Objref_VarOut_T.h" + +#include "tao/PortableServer/PortableServer.h" + +#if defined (TAO_EXPORT_MACRO) +#undef TAO_EXPORT_MACRO +#endif +#define TAO_EXPORT_MACRO TAO_CSD_FW_Export + +// TAO_IDL - Generated from +// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_module/module_ch.cpp:49 + +namespace CSD_Framework +{ + + // TAO_IDL - Generated from + // .\be\be_interface.cpp:646 + +#if !defined (_CSD_FRAMEWORK_STRATEGY__VAR_OUT_CH_) +#define _CSD_FRAMEWORK_STRATEGY__VAR_OUT_CH_ + + class Strategy; + typedef Strategy *Strategy_ptr; + + typedef + TAO_Objref_Var_T< + Strategy + > + Strategy_var; + + typedef + TAO_Objref_Out_T< + Strategy + > + Strategy_out; + +#endif /* end #if !defined */ + + // TAO_IDL - Generated from + // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_ch.cpp:54 + +#if !defined (_CSD_FRAMEWORK_STRATEGY_CH_) +#define _CSD_FRAMEWORK_STRATEGY_CH_ + + class TAO_CSD_FW_Export Strategy + : public virtual ::CORBA::Object + { + public: + typedef Strategy_ptr _ptr_type; + typedef Strategy_var _var_type; + + // The static operations. + static Strategy_ptr _duplicate (Strategy_ptr obj); + + static void _tao_release (Strategy_ptr obj); + + static Strategy_ptr _narrow ( + ::CORBA::Object_ptr obj + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ); + + static Strategy_ptr _unchecked_narrow ( + ::CORBA::Object_ptr obj + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ); + + static Strategy_ptr _nil (void) + { + return static_cast<Strategy_ptr> (0); + } + + + + // TAO_IDL - Generated from + // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_operation/operation_ch.cpp:46 + + virtual ::CORBA::Boolean apply_to ( + ::PortableServer::POA_ptr p + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + ::CORBA::SystemException + )) = 0; + + // TAO_IDL - Generated from + // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_ch.cpp:210 + + virtual ::CORBA::Boolean _is_a ( + const char *type_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ); + + virtual const char* _interface_repository_id (void) const; + virtual ::CORBA::Boolean marshal (TAO_OutputCDR &cdr); + + protected: + // Abstract or local interface only. + Strategy (void); + + virtual ~Strategy (void); + + private: + // Private and unimplemented for concrete interfaces. + Strategy (const Strategy &); + + void operator= (const Strategy &); + }; + +#endif /* end #if !defined */ + + // TAO_IDL - Generated from + // .\be\be_interface.cpp:646 + +#if !defined (_CSD_FRAMEWORK_POA__VAR_OUT_CH_) +#define _CSD_FRAMEWORK_POA__VAR_OUT_CH_ + + class POA; + typedef POA *POA_ptr; + + typedef + TAO_Objref_Var_T< + POA + > + POA_var; + + typedef + TAO_Objref_Out_T< + POA + > + POA_out; + +#endif /* end #if !defined */ + + // TAO_IDL - Generated from + // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_ch.cpp:54 + +#if !defined (_CSD_FRAMEWORK_POA_CH_) +#define _CSD_FRAMEWORK_POA_CH_ + + class TAO_CSD_FW_Export POA + : public virtual ::PortableServer::POA + { + public: + typedef POA_ptr _ptr_type; + typedef POA_var _var_type; + + // The static operations. + static POA_ptr _duplicate (POA_ptr obj); + + static void _tao_release (POA_ptr obj); + + static POA_ptr _narrow ( + ::CORBA::Object_ptr obj + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ); + + static POA_ptr _unchecked_narrow ( + ::CORBA::Object_ptr obj + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ); + + static POA_ptr _nil (void) + { + return static_cast<POA_ptr> (0); + } + + + + // TAO_IDL - Generated from + // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_operation/operation_ch.cpp:46 + + virtual void set_csd_strategy ( + ::CSD_Framework::Strategy_ptr s + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + ::CORBA::SystemException + )) = 0; + + // TAO_IDL - Generated from + // c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_interface/interface_ch.cpp:210 + + virtual ::CORBA::Boolean _is_a ( + const char *type_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ); + + virtual const char* _interface_repository_id (void) const; + virtual ::CORBA::Boolean marshal (TAO_OutputCDR &cdr); + + protected: + // Abstract or local interface only. + POA (void); + + virtual ~POA (void); + + private: + // Private and unimplemented for concrete interfaces. + POA (const POA &); + + void operator= (const POA &); + }; + +#endif /* end #if !defined */ + +// TAO_IDL - Generated from +// c:\csd\code\doc\ace_wrappers\tao\tao_idl\be\be_visitor_module/module_ch.cpp:78 + +} // module CSD_Framework + +// TAO_IDL - Generated from +// .\be\be_visitor_traits.cpp:61 + +// Traits specializations. +namespace TAO +{ + +#if !defined (_CSD_FRAMEWORK_STRATEGY__TRAITS_) +#define _CSD_FRAMEWORK_STRATEGY__TRAITS_ + + template<> + struct TAO_CSD_FW_Export Objref_Traits< ::CSD_Framework::Strategy> + { + static ::CSD_Framework::Strategy_ptr duplicate ( + ::CSD_Framework::Strategy_ptr + ); + static void release ( + ::CSD_Framework::Strategy_ptr + ); + static ::CSD_Framework::Strategy_ptr nil (void); + static ::CORBA::Boolean marshal ( + ::CSD_Framework::Strategy_ptr p, + TAO_OutputCDR & cdr + ); + }; + +#endif /* end #if !defined */ + +#if !defined (_CSD_FRAMEWORK_POA__TRAITS_) +#define _CSD_FRAMEWORK_POA__TRAITS_ + + template<> + struct TAO_CSD_FW_Export Objref_Traits< ::CSD_Framework::POA> + { + static ::CSD_Framework::POA_ptr duplicate ( + ::CSD_Framework::POA_ptr + ); + static void release ( + ::CSD_Framework::POA_ptr + ); + static ::CSD_Framework::POA_ptr nil (void); + static ::CORBA::Boolean marshal ( + ::CSD_Framework::POA_ptr p, + TAO_OutputCDR & cdr + ); + }; + +#endif /* end #if !defined */ +} + +#include /**/ "ace/post.h" + +#endif /* ifndef */ + + diff --git a/TAO/tao/CSD_Framework/CSD_FrameworkC.inl b/TAO/tao/CSD_Framework/CSD_FrameworkC.inl new file mode 100644 index 00000000000..c944d806c1f --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_FrameworkC.inl @@ -0,0 +1,27 @@ +// -*- C++ -*- +// +// $Id$ + +// **** Code generated by the The ACE ORB (TAO) IDL Compiler **** +// TAO and the TAO IDL Compiler have been developed by: +// Center for Distributed Object Computing +// Washington University +// St. Louis, MO +// USA +// http://www.cs.wustl.edu/~schmidt/doc-center.html +// and +// Distributed Object Computing Laboratory +// University of California at Irvine +// Irvine, CA +// USA +// http://doc.ece.uci.edu/ +// and +// Institute for Software Integrated Systems +// Vanderbilt University +// Nashville, TN +// USA +// http://www.isis.vanderbilt.edu/ +// +// Information about TAO is available at: +// http://www.cs.wustl.edu/~schmidt/TAO.html + 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..9163e6995dc --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Framework_Loader.cpp @@ -0,0 +1,26 @@ +// $Id$ + +#include "CSD_Framework_Loader.h" +#include "CSD_Object_Adapter_Factory.h" +#include "CSD_Strategy_Repository.h" +#include "ace/Dynamic_Service.h" + +ACE_RCSID (CSD_Framework, + CSD_Framework_Loader, + "$Id$") + +#include "tao/ORB_Core.h" + +int +TAO_CSD_Framework_Loader::init (void) +{ + ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_Object_Adapter_Factory); + + TAO_ORB_Core::set_poa_factory ("TAO_CSD_Object_Adapter_Factory", + "dynamic TAO_CSD_Object_Adapter_Factory Service_Object * _make_TAO_CSD_Object_Adapter_Factory()"); + + + ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_Strategy_Repository); + + return 0; +} 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..5a13ed5f13f --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Framework_Loader.h @@ -0,0 +1,41 @@ +/* -*- 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 "CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @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); +}; + +#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..56a46b61c18 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_ORBInitializer.cpp @@ -0,0 +1,33 @@ +// $Id$ +#include "CSD_ORBInitializer.h" + +#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 + +ACE_RCSID (CSD_Framework, + CSD_ORBInitializer, + "$Id$") + +#include "CSD_Object_Adapter_Factory.h" + +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)) +{ +} + + +#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..0b661e2dd7c --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_ORBInitializer.h @@ -0,0 +1,66 @@ +/* -*- 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 "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 */ + +/// CSD ORB initializer. +class TAO_CSD_FW_Export 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)); +}; + +#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..cd599fd37e2 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter.cpp @@ -0,0 +1,42 @@ +// $Id$ + +#include "CSD_Object_Adapter.h" +#include "CSD_Strategy_Proxy.h" +#include "CSD_POA.h" + +ACE_RCSID (CSD_Framework, + CSD_Object_Adapter, + "$Id$") + +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; +} + 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..83deb3c96b6 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter.h @@ -0,0 +1,54 @@ +/* -*- 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 "CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PortableServer/Object_Adapter.h" + +/** + * @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); +}; + + +#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..7943eda6a5d --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.cpp @@ -0,0 +1,93 @@ +// $Id$ + +#include "CSD_Object_Adapter_Factory.h" +#include "CSD_Strategy_Repository.h" +#include "CSD_Object_Adapter.h" +#include "CSD_ORBInitializer.h" +#include "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_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, + "(%P | %t) Caught exception:"); + return -1; + } + ACE_ENDTRY; + + return 0; +} + + +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..9deab152daf --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Object_Adapter_Factory.h @@ -0,0 +1,46 @@ +/* -*- 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 "CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/Adapter_Factory.h" +#include "ace/Service_Config.h" + + +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[]); +}; + +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..98ec63d864e --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_POA.cpp @@ -0,0 +1,131 @@ +// $Id$ + + +#include "CSD_POA.h" +#include "CSD_Strategy_Repository.h" +#include "CSD_Strategy_Base.h" + +#include "ace/Dynamic_Service.h" + +ACE_RCSID (CSD_Framework, + CSD_POA, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_POA.inl" +#endif /* ! __ACE_INLINE__ */ + +// Implementation skeleton constructor +TAO_CSD_POA::TAO_CSD_POA (const String &name, + TAO_POA_Manager &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, + TAO_POA_Manager &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; +} diff --git a/TAO/tao/CSD_Framework/CSD_POA.h b/TAO/tao/CSD_Framework/CSD_POA.h new file mode 100644 index 00000000000..8038537b45d --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_POA.h @@ -0,0 +1,108 @@ +/* -*- 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 "CSD_FW_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PortableServer/Regular_POA.h" +#include "CSD_Strategy_Proxy.h" + + +/** + * @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, + TAO_POA_Manager &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, + TAO_POA_Manager &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_; +}; + + +#if defined (__ACE_INLINE__) +# include "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..7a9aef6f63a --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_POA.inl @@ -0,0 +1,11 @@ +// $Id$ + + + +ACE_INLINE +TAO::CSD::Strategy_Proxy& +TAO_CSD_POA::servant_dispatching_strategy_proxy (void) const +{ + return *sds_proxy_; +} + 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..de6524c3b04 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Base.cpp @@ -0,0 +1,133 @@ +// $Id$ + +#include "CSD_Strategy_Base.h" +#include "CSD_POA.h" +#include "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 "CSD_Strategy_Base.inl" +#endif /* ! __ACE_INLINE__ */ + + +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 servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + ACE_UNUSED_ARG(servant); + ACE_UNUSED_ARG(oid); + // do nothing. +} + + +void +TAO::CSD::Strategy_Base::servant_deactivated_event_i + (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + ACE_UNUSED_ARG(servant); + ACE_UNUSED_ARG(oid); + // do nothing. +} 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..9650a914a45 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Base.h @@ -0,0 +1,172 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file Custom_Servant_Dispatching_Strategy.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 "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 "CSD_FrameworkC.h" + +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_; + }; + } +} + + +#if defined (__ACE_INLINE__) +# include "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..1f31a6cdcf4 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Base.inl @@ -0,0 +1,138 @@ +// -*- C++ -*- +// $Id$ +#include "tao/debug.h" + +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; +} 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..063ec14f9aa --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.cpp @@ -0,0 +1,47 @@ +// $Id$ + +#include "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 "CSD_Strategy_Proxy.inl" +#endif /* ! __ACE_INLINE__ */ + + +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; +} 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..78ffea92778 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.h @@ -0,0 +1,110 @@ +// This may look like C, but it's really -*- 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 "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 "CSD_Strategy_Base.h" + +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_; + }; + } +} + +#if defined (__ACE_INLINE__) +# include "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..320fd6dca8f --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Proxy.inl @@ -0,0 +1,104 @@ +// -*- C++ -*- +// $Id$ + + +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; + } +} 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..2a98495e301 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.cpp @@ -0,0 +1,114 @@ +// $Id$ + +#include "CSD_Strategy_Repository.h" +#include "tao/debug.h" + +ACE_RCSID (CSD_Framework, + CSD_Strategy_Factory, + "$Id$") + + +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; +} + + +///////////////////////////////////////////////////////////////////// + +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..d9b1ef773d0 --- /dev/null +++ b/TAO/tao/CSD_Framework/CSD_Strategy_Repository.h @@ -0,0 +1,75 @@ +// This may look like C, but it's really -*- 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 "CSD_FW_Export.h" +#include "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 */ + + +/** + * @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_; +}; + +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/diffs/CSD_Framework.diff b/TAO/tao/CSD_Framework/diffs/CSD_Framework.diff new file mode 100644 index 00000000000..4d5e2989f73 --- /dev/null +++ b/TAO/tao/CSD_Framework/diffs/CSD_Framework.diff @@ -0,0 +1,38 @@ +--- CSD_FrameworkA.h 2005-10-03 16:07:54.484375000 -0700 ++++ orig/CSD_FrameworkA.h 2005-10-03 13:11:38.312500000 -0700 +@@ -34,8 +34,8 @@ + #include /**/ "ace/pre.h" + + #include "CSD_FW_Export.h" +-#include "CSD_FrameworkC.h" +-//#include "tao/PortableServer/PortableServerA.h" ++#include "tao/orig/CSD_FrameworkC.h" ++#include "tao/PortableServer/PortableServerA.h" + + + // TAO_IDL - Generated from +--- CSD_FrameworkC.h 2005-10-03 16:08:02.500000000 -0700 ++++ orig/CSD_FrameworkC.h 2005-10-03 13:11:38.312500000 -0700 +@@ -47,7 +47,7 @@ + #include "tao/Object.h" + #include "tao/Objref_VarOut_T.h" + +-#include "tao/PortableServer/PortableServer.h" ++#include "tao/PortableServer/PortableServerC.h" + + #if defined (TAO_EXPORT_MACRO) + #undef TAO_EXPORT_MACRO +@@ -305,6 +305,13 @@ + #endif /* end #if !defined */ + } + ++// TAO_IDL - Generated from ++// .\be\be_codegen.cpp:1040 ++ ++#if defined (__ACE_INLINE__) ++#include "CSD_FrameworkC.inl" ++#endif /* defined INLINE */ ++ + #include /**/ "ace/post.h" + + #endif /* ifndef */ diff --git a/TAO/tao/CSD_ThreadPool.mpc b/TAO/tao/CSD_ThreadPool.mpc new file mode 100644 index 00000000000..54a6dffc681 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool.mpc @@ -0,0 +1,34 @@ +//$Id$ +project : csd_framework { + sharedname = TAO_CSD_ThreadPool + dynamicflags = TAO_CSD_TP_BUILD_DLL + includes += $(TAO_ROOT)/tao + + Source_Files { + CSD_ThreadPool + } + + Header_Files { + CSD_ThreadPool + } + + Inline_Files { + CSD_ThreadPool + } + + Template_Files { + CSD_ThreadPool + } + + Resource_Files { + CSD_ThreadPool + } + + IDL_Files { + CSD_ThreadPool + } + + PIDL_Files { + CSD_ThreadPool + } +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.cpp new file mode 100644 index 00000000000..9117ad0b690 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.cpp @@ -0,0 +1,44 @@ +// $Id$ + +#include "CSD_TP_Cancel_Visitor.h" +#include "CSD_TP_Request.h" + +ACE_RCSID (CSD_TP, + Cancel_Visitor, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Cancel_Visitor.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Cancel_Visitor::~TP_Cancel_Visitor() +{ +} + + +bool +TAO::CSD::TP_Cancel_Visitor::visit_request(TP_Request* request, + bool& remove_flag) +{ + // If our servant_ data member is in the 'nil' state, then + // we are supposed to cancel *ALL* requests that we visit. + // + // Otherwise, if our servant_ data member is not in the 'nil' state, + // we are supposed to cancel only requests that target our specific + // servant_. + + if ((this->servant_.in() == 0) || (request->is_target(this->servant_.in()))) + { + // Set the remove_flag to true so that this request is removed + // (and released) from the queue when we finish our visit. + remove_flag = true; + + // Cancel the request + request->cancel(); + } + + // Since we are either cancelling requests to any servant or a + // specific servant, always continue visitation. + return true; +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h new file mode 100644 index 00000000000..538f6899979 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.h @@ -0,0 +1,85 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Cancel_Visitor.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_CANCEL_VISITOR_H +#define TAO_CSD_TP_CANCEL_VISITOR_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" +#include "tao/PortableServer/Servant_Base.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Queue_Visitor.h" + + +namespace TAO +{ + namespace CSD + { + + /** + * @class TP_Cancel_Visitor + * + * @brief Used to extract/cancel request(s) from the queue. + * + * This visitor is used to cancel certain requests in the queue + * as they are visited. + * + * Note that this is currently implemented to cancel *all* + * requests in the queue, or requests that are targeted for a specific + * servant. This could be extended in the future to perhaps + * cancel all requests that have the same operation name, or something + * else. + * + */ + class TAO_CSD_TP_Export TP_Cancel_Visitor : public TP_Queue_Visitor + { + public: + + /// Default Constructor - cancel *all* requests. + TP_Cancel_Visitor(); + + /// Constructor with provided servant - cancel requests that + /// target the supplied servant. + TP_Cancel_Visitor(PortableServer::Servant servant); + + /// Virtual Destructor. + virtual ~TP_Cancel_Visitor(); + + /// Returns true to continue visitation. Returns false to stop + /// visitation. Sets the remove_flag to true if the request should + /// be removed from the queue as a result of the visit. Leaves the + /// remove_flag alone otherwise. + virtual bool visit_request(TP_Request* request, bool& remove_flag); + + + private: + + /// Left as nil if we are to cancel all requests, or set to a specific + /// servant if only requests targeting that servant should be cancelled. + PortableServer::ServantBase_var servant_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Cancel_Visitor.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_DISPATCHABLE_VISITOR_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.inl new file mode 100644 index 00000000000..b5d698f1f7a --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Cancel_Visitor.inl @@ -0,0 +1,28 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Cancel_Visitor::TP_Cancel_Visitor() +{ +} + + +ACE_INLINE +TAO::CSD::TP_Cancel_Visitor::TP_Cancel_Visitor(PortableServer::Servant servant) + : servant_(servant) +{ + // This try-catch block is not really necessary for current implementation + // since the _add_ref does not throw exception, but we have to add it to + // satisfy the non-exception builds. If _add_ref really throws an exception + // then this constructor needs deal with the exception. + ACE_TRY_NEW_ENV + { + this->servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHALL + { + } + ACE_ENDTRY; +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.cpp new file mode 100644 index 00000000000..b43ec670d51 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.cpp @@ -0,0 +1,57 @@ +// $Id$ + +#include "CSD_TP_Collocated_Asynch_Request.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Collocated_Asynch_Request, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Collocated_Asynch_Request.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Collocated_Asynch_Request::~TP_Collocated_Asynch_Request() +{ +} + + +void +TAO::CSD::TP_Collocated_Asynch_Request::prepare_for_queue_i() +{ + this->do_clone(); +} + + +void +TAO::CSD::TP_Collocated_Asynch_Request::dispatch_i() +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->do_dispatch(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // Eat these. We probably should log these, but since we have already + // unblocked the requesting thread there is no point in saving it or + // doing anything with it. + } +#if defined (TAO_HAS_EXCEPTIONS) + ACE_CATCHALL + { + // Eat these. We probably should log these, but since we have already + // unblocked the requesting thread there is no point in saving it or + // doing anything with it. + } +#endif + ACE_ENDTRY; +} + + +void +TAO::CSD::TP_Collocated_Asynch_Request::cancel_i() +{ + this->do_cancel(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h new file mode 100644 index 00000000000..bf7b2a17b37 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.h @@ -0,0 +1,87 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Collocated_Asynch_Request.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_COLLOCATED_ASYNCH_REQUEST_H +#define TAO_CSD_TP_COLLOCATED_ASYNCH_REQUEST_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Corba_Request.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Collocated_Asynch_Request; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Collocated_Asynch_Request> + TP_Collocated_Asynch_Request_Handle; + + /** + * @class TP_Collocated_Asynch_Request + * + * @brief Represents a "queue-able", collocated, asynchronous, + * CORBA request. + * + * This kind request is one-way collocated request with the default + * SYNC_SCOPE policy (SYNC_WITH_TRANSPORT) applied. It is cloned + * before enqueuing and the "enqueuing" thread never blocks. + */ + class TAO_CSD_TP_Export TP_Collocated_Asynch_Request + : public TP_Corba_Request + { + public: + + /// Constructor. + TP_Collocated_Asynch_Request + (TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state); + + /// Virtual Destructor. + virtual ~TP_Collocated_Asynch_Request(); + + + protected: + + /// Prepare this TP_Collocated_Asynch_Request object to be placed + /// into the request queue. This will cause the underlying + /// TAO_ServerRequest object to be cloned. + virtual void prepare_for_queue_i(); + + /// Dispatch the request to the servant. + virtual void dispatch_i(); + + /// Cancel the request. + virtual void cancel_i(); + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Collocated_Asynch_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_COLLOCATED_ASYNCH_REQUEST_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.inl new file mode 100644 index 00000000000..94a7238bd46 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Asynch_Request.inl @@ -0,0 +1,20 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Collocated_Asynch_Request::TP_Collocated_Asynch_Request + (TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state) + : TP_Corba_Request(object_id, + poa, + operation, + servant, + servant_state, + server_request) +{ +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.cpp new file mode 100644 index 00000000000..58e868c835a --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.cpp @@ -0,0 +1,55 @@ +// $Id$ + +#include "CSD_TP_Collocated_Synch_Request.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Collocated_Synch_Request, + "$Id$") + +#include "tao/ORB_Core.h" + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Collocated_Synch_Request.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Collocated_Synch_Request::~TP_Collocated_Synch_Request() +{ +} + + +void +TAO::CSD::TP_Collocated_Synch_Request::dispatch_i() +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->do_dispatch(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // We need to save off a copy of the exception. + this->exception_ = ACE_ANY_EXCEPTION._tao_duplicate(); + } +#if defined (TAO_HAS_EXCEPTIONS) + ACE_CATCHALL + { + this->exception_ + = new CORBA::UNKNOWN (CORBA::SystemException::_tao_minor_code + (TAO_UNHANDLED_SERVER_CXX_EXCEPTION, 0), + CORBA::COMPLETED_MAYBE); + } +#endif + ACE_ENDTRY; + + this->synch_helper_.dispatched(); +} + + +void +TAO::CSD::TP_Collocated_Synch_Request::cancel_i() +{ + this->synch_helper_.cancelled(); +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h new file mode 100644 index 00000000000..732158e3c02 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.h @@ -0,0 +1,106 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Collocated_Synch_Request.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_COLLOCATED_SYNCH_REQUEST_H +#define TAO_CSD_TP_COLLOCATED_SYNCH_REQUEST_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Corba_Request.h" +#include "CSD_TP_Synch_Helper.h" +#include "tao/Exception.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Collocated_Synch_Request; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Collocated_Synch_Request> + TP_Collocated_Synch_Request_Handle; + + /** + * @class TP_Collocated_Synch_Request + * + * @brief Represents a "queue-able", synchronous, collocated, + * CORBA request. + * + * This kind request is the two-way or oneway(with SYNC_WITH_TARGET + * policy applied) collocated request. It is NOT cloned before + * enqueuing and the "enqueuing" thread will block until the request + * is dispatched/handled or cancelled. + */ + class TAO_CSD_TP_Export TP_Collocated_Synch_Request + : public TP_Corba_Request + { + public: + + /// Constructor. + TP_Collocated_Synch_Request + (TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state); + + /// Virtual Destructor. + virtual ~TP_Collocated_Synch_Request(); + + /// Wait until the request has been dispatched (and completed), or + /// until it has been cancelled. + /// Returns true if the request has been dispatched, and returns + /// false if the request has been cancelled. + bool wait(ACE_ENV_SINGLE_ARG_DECL); + + + protected: + + /// Note that we do not override our base class implementation of + /// prepare_for_queue_i() (which does nothing), because we don't + /// need to clone the Server Request object. + + /// Dispatch the request to the servant. + virtual void dispatch_i(); + + /// Cancel the request. + virtual void cancel_i(); + + + private: + + /// Helper used to block and unblock the thread that invokes our + /// wait() method. + TP_Synch_Helper synch_helper_; + + /// Set to NULL initially, and will only be set thereafter if an + /// exception is raised from the dispatch() call on the server_request_. + CORBA::Exception* exception_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Collocated_Synch_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_COLLOCATED_SYNCH_REQUEST_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.inl new file mode 100644 index 00000000000..4481a463c1e --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_Request.inl @@ -0,0 +1,52 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Collocated_Synch_Request::TP_Collocated_Synch_Request + (TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state) + : TP_Corba_Request(object_id, + poa, + operation, + servant, + servant_state, + server_request), + exception_(0) +{ +} + + +ACE_INLINE +bool +TAO::CSD::TP_Collocated_Synch_Request::wait(ACE_ENV_SINGLE_ARG_DECL) +{ + bool dispatched = this->synch_helper_.wait_while_pending(); + + if (dispatched) + { + // Check to see if the dispatching caused an exception to be raised. + if (this->exception_ != 0) + { + // An exception was raised during the actual dispatching to + // the servant. We need to raise the exception to our caller, + // which is the thread that made the collocated request in the + // first place. + CORBA::Exception* ex = this->exception_; + this->exception_ = 0; + +#if defined (TAO_HAS_EXCEPTIONS) + ACE_Auto_Basic_Ptr<CORBA::Exception> ex_holder(ex); + ex->_raise (); +#else + ACE_TRY_ENV.exception (ex); +#endif /* ACE_HAS_EXCEPTIONS */ + } + } + + return dispatched; + +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.cpp new file mode 100644 index 00000000000..657cac81be0 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.cpp @@ -0,0 +1,71 @@ +// $Id$ + +#include "CSD_TP_Collocated_Synch_With_Server_Request.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Collocated_Synch_With_Server_Request, + "$Id$") + +#include "tao/Exception.h" + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Collocated_Synch_With_Server_Request.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Collocated_Synch_With_Server_Request::~TP_Collocated_Synch_With_Server_Request() +{ +} + + +void +TAO::CSD::TP_Collocated_Synch_With_Server_Request::prepare_for_queue_i() +{ + // NOTE: We *NEED* clone the TAO_ServerRequest for a collocated, + // one-way SYNC_WITH_SERVER request. This is because the + // calling thread is signalled just *before* the request is + // dispatched. It's (very) possible that the calling thread + // will destroy the underlying TAO_ServerRequest object while + // the request is dispatching to servant. This is why we make + // a clone - so that we have our own copy that won't be destroyed + // while we are using it. + this->do_clone(); +} + + +void +TAO::CSD::TP_Collocated_Synch_With_Server_Request::dispatch_i() +{ + // This is done *before* we do_dispatch(). + this->synch_helper_.dispatched(); + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->do_dispatch(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // Eat these. We probably should log these, but since we have already + // unblocked the requesting thread there is no point in saving it or + // doing anything with it. + } +#if defined (TAO_HAS_EXCEPTIONS) + ACE_CATCHALL + { + // Eat these. We probably should log these, but since we have already + // unblocked the requesting thread there is no point in saving it or + // doing anything with it. + } +#endif + ACE_ENDTRY; +} + + +void +TAO::CSD::TP_Collocated_Synch_With_Server_Request::cancel_i() +{ + this->synch_helper_.cancelled(); +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h new file mode 100644 index 00000000000..39748db1853 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.h @@ -0,0 +1,107 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Collocated_Synch_With_Server_Request.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_COLLOCATED_SYNCH_WITH_SERVER_REQUEST_H +#define TAO_CSD_TP_COLLOCATED_SYNCH_WITH_SERVER_REQUEST_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Corba_Request.h" +#include "CSD_TP_Synch_Helper.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Collocated_Synch_With_Server_Request; + typedef TAO_Intrusive_Ref_Count_Handle + <TP_Collocated_Synch_With_Server_Request> + TP_Collocated_Synch_With_Server_Request_Handle; + + /** + * @class TP_Collocated_Synch_With_Server_Request + * + * @brief Represents a "queue-able", one-way, collocated, CORBA + * request with a "Synch Scope" policy of SYNC_WITH_SERVER. + * + * This kind of request is one-way request with the SYNC_WITH_SERVER + * policy applied. It is cloned before enqueuing and the "enqueuing" + * thread will block until it is signalled by the TP_Task thread that + * will happen just before the request is dispatched or the request + * is cancelled. + */ + class TAO_CSD_TP_Export TP_Collocated_Synch_With_Server_Request + : public TP_Corba_Request + { + public: + + /// Constructor. + TP_Collocated_Synch_With_Server_Request + (TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state); + + /// Virtual Destructor. + virtual ~TP_Collocated_Synch_With_Server_Request(); + + /// Wait until the request has been dispatched (but not completed), or + /// until it has been cancelled. Note that this will wait until just + /// *before* the request is dispatched by a worker thread. This is + /// different than the TP_Collocated_Synch_Request which waits until + /// just *after* the request is dispatched by a worker thread. + /// Returns true if the request has been dispatched, and returns + /// false if the request has been cancelled. + bool wait(ACE_ENV_SINGLE_ARG_DECL); + + + protected: + + /// Prepare this TP_Collocated_Synch_With_Server_Request object to be + /// placed into the request queue. This will cause the underlying + /// TAO_ServerRequest object to be cloned. + virtual void prepare_for_queue_i(); + + /// Dispatch the request to the servant. + virtual void dispatch_i(); + + /// Cancel the request. + virtual void cancel_i(); + + + private: + + /// Helper used to block and unblock the thread that invokes our + /// wait() method. + TP_Synch_Helper synch_helper_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Collocated_Synch_With_Server_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_COLLOCATED_SYNCH_WITH_SERVER_REQUEST_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.inl new file mode 100644 index 00000000000..08dc5141fae --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Collocated_Synch_With_Server_Request.inl @@ -0,0 +1,27 @@ +// $Id$ + +ACE_INLINE +TAO::CSD::TP_Collocated_Synch_With_Server_Request::TP_Collocated_Synch_With_Server_Request + (TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state) + : TP_Corba_Request(object_id, + poa, + operation, + servant, + servant_state, + server_request) +{ +} + + +ACE_INLINE +bool +TAO::CSD::TP_Collocated_Synch_With_Server_Request::wait(ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + return this->synch_helper_.wait_while_pending(); +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.cpp new file mode 100644 index 00000000000..a4a40ba6091 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.cpp @@ -0,0 +1,16 @@ +// $Id$ + +#include "CSD_TP_Corba_Request.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Corba_Request, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Corba_Request.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Corba_Request::~TP_Corba_Request() +{ +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.h new file mode 100644 index 00000000000..d6343e20935 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.h @@ -0,0 +1,100 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Corba_Request.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_CORBA_REQUEST_H +#define TAO_CSD_TP_CORBA_REQUEST_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Request.h" +#include "tao/CSD_Framework/CSD_FW_Server_Request_Wrapper.h" +#include "tao/PortableServer/PortableServer.h" +#include "tao/PortableServer/Servant_Base.h" +#include "ace/SString.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Corba_Request; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Corba_Request> + TP_Corba_Request_Handle; + + /** + * @class TP_Corba_Request + * + * @brief Base class for "queue-able" CORBA requests. + * + * TBD - Add description + * + */ + class TAO_CSD_TP_Export TP_Corba_Request : public TP_Request + { + public: + + /// Virtual Destructor. + virtual ~TP_Corba_Request(); + + + protected: + + /// Constructor. + TP_Corba_Request(const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state, + TAO_ServerRequest& server_request); + + /// Delegate to the FW_Server_Request_Wrapper clone() method. + void do_clone(); + + /// Delegate to the FW_Server_Request_Wrapper dispatch() method. + void do_dispatch(ACE_ENV_SINGLE_ARG_DECL); + + /// Delegate to the FW_Server_Request_Wrapper cancel() method. + void do_cancel(); + + + private: + + /// The ObjectId for the target servant. + PortableServer::ObjectId object_id_; + + /// The POA. + PortableServer::POA_var poa_; + + /// The name of the IDL operation. + ACE_CString operation_; + + /// The TAO_ServerRequest object wrapper. + FW_Server_Request_Wrapper server_request_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Corba_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_CORBA_REQUEST_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.inl new file mode 100644 index 00000000000..2047ad845d3 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Corba_Request.inl @@ -0,0 +1,42 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Corba_Request::TP_Corba_Request + (const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state, + TAO_ServerRequest& server_request) + : TP_Request(servant,servant_state), + object_id_(object_id), + operation_(operation), + server_request_(server_request) +{ + this->poa_ = PortableServer::POA::_duplicate(poa); +} + + +ACE_INLINE +void +TAO::CSD::TP_Corba_Request::do_clone() +{ + this->server_request_.clone(); +} + +ACE_INLINE +void +TAO::CSD::TP_Corba_Request::do_dispatch(ACE_ENV_SINGLE_ARG_DECL) +{ + this->server_request_.dispatch(this->servant() ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + + +ACE_INLINE +void +TAO::CSD::TP_Corba_Request::do_cancel() +{ + this->server_request_.cancel(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.cpp new file mode 100644 index 00000000000..4ac59c6f1fa --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.cpp @@ -0,0 +1,50 @@ +// $Id$ + +#include "CSD_TP_Custom_Asynch_Request.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Custom_Asynch_Request, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Custom_Asynch_Request.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Custom_Asynch_Request::~TP_Custom_Asynch_Request() +{ +} + + +void +TAO::CSD::TP_Custom_Asynch_Request::dispatch_i() +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->execute_op(); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // Eat these. We probably should log these, but since we have already + // unblocked the requesting thread there is no point in saving it or + // doing anything with it. + } +#if defined (TAO_HAS_EXCEPTIONS) + ACE_CATCHALL + { + // Eat these. We probably should log these, but since we have already + // unblocked the requesting thread there is no point in saving it or + // doing anything with it. + } +#endif + ACE_ENDTRY; +} + + +void +TAO::CSD::TP_Custom_Asynch_Request::cancel_i() +{ + this->cancel_op(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h new file mode 100644 index 00000000000..ee3479c2e9c --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.h @@ -0,0 +1,76 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Custom_Asynch_Request.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_CUSTOM_ASYNCH_REQUEST_H +#define TAO_CSD_TP_CUSTOM_ASYNCH_REQUEST_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Custom_Request.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Custom_Asynch_Request; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Custom_Asynch_Request> + TP_Custom_Asynch_Request_Handle; + + /** + * @class TP_Custom_Asynch_Request + * + * @brief Base class for "queue-able", Custom (non-CORBA), + * Synchronous requests. + * + * TBD - Add description + * + */ + class TAO_CSD_TP_Export TP_Custom_Asynch_Request + : public TP_Custom_Request + { + public: + + /// Constructor. + TP_Custom_Asynch_Request(TP_Custom_Request_Operation* op, + TP_Servant_State* servant_state); + + /// Virtual Destructor. + virtual ~TP_Custom_Asynch_Request(); + + + protected: + + /// Dispatch the request to the servant. + virtual void dispatch_i(); + + /// Cancel the request. + virtual void cancel_i(); + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Custom_Asynch_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_CUSTOM_ASYNCH_REQUEST_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.inl new file mode 100644 index 00000000000..7281af45b9a --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Asynch_Request.inl @@ -0,0 +1,11 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Custom_Asynch_Request::TP_Custom_Asynch_Request + (TP_Custom_Request_Operation* op, + TP_Servant_State* servant_state) + : TP_Custom_Request(op,servant_state) +{ +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.cpp new file mode 100644 index 00000000000..810858cca79 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.cpp @@ -0,0 +1,16 @@ +// $Id$ + +#include "CSD_TP_Custom_Request.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Custom_Request, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Custom_Request.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Custom_Request::~TP_Custom_Request() +{ +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.h new file mode 100644 index 00000000000..e4d89f40e15 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.h @@ -0,0 +1,78 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Custom_Request.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_CUSTOM_REQUEST_H +#define TAO_CSD_TP_CUSTOM_REQUEST_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Request.h" +#include "CSD_TP_Custom_Request_Operation.h" +#include "tao/PortableServer/Servant_Base.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Custom_Request; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Custom_Request> + TP_Custom_Request_Handle; + + /** + * @class TP_Custom_Request + * + * @brief Base class for "queue-able" Custom (non-CORBA) requests. + * + * TBD - Add description + * + */ + class TAO_CSD_TP_Export TP_Custom_Request : public TP_Request + { + public: + + /// Virtual Destructor. + virtual ~TP_Custom_Request(); + + + protected: + + /// Constructor. + TP_Custom_Request(TP_Custom_Request_Operation* op, + TP_Servant_State* servant_state); + + void execute_op(); + void cancel_op(); + + + private: + + TP_Custom_Request_Operation_Handle op_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Custom_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_CUSTOM_REQUEST_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.inl new file mode 100644 index 00000000000..6b53f3cbf78 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request.inl @@ -0,0 +1,44 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Custom_Request::TP_Custom_Request + (TP_Custom_Request_Operation* op, + TP_Servant_State* servant_state) + : TP_Request(op->servant(),servant_state), + op_(op, false) +{ +} + + +ACE_INLINE +void +TAO::CSD::TP_Custom_Request::execute_op() +{ + this->op_->execute(); + + // Now drop the reference to the custom operation object. + // This is necessary so that custom operation objects can be created + // on the stack for synchronous custom requests. If we do not do this, + // then there is a race condition which could result in the stack-created + // custom operation object having a reference count of 2 when it falls + // out of scope (and destructs). Our op_ data member would be the one + // that held the other reference, and when our op_ data member destructs, + // it attempts to perform a _remove_ref() on the underlying operation + // object - which has already been destructed! Thus, we reset the op_ + // data member here to the 'nil' state - causing the _remove_ref() to + // be performed now. + this->op_ = 0; +} + + +ACE_INLINE +void +TAO::CSD::TP_Custom_Request::cancel_op() +{ + this->op_->cancel(); + + // See comments in the execute_op() method. + this->op_ = 0; +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.cpp new file mode 100644 index 00000000000..49617f39ea3 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.cpp @@ -0,0 +1,16 @@ +// $Id$ + +#include "CSD_TP_Custom_Request_Operation.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Custom_Request_Operation, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Custom_Request_Operation.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Custom_Request_Operation::~TP_Custom_Request_Operation() +{ +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h new file mode 100644 index 00000000000..50673612536 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.h @@ -0,0 +1,96 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Custom_Request_Operation.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_CUSTOM_REQUEST_OPERATION_H +#define TAO_CSD_TP_CUSTOM_REQUEST_OPERATION_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/Intrusive_Ref_Count_Base_T.h" +#include "tao/Intrusive_Ref_Count_Handle_T.h" +#include "tao/PortableServer/Servant_Base.h" +#include "ace/Synch.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Custom_Request_Operation; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Custom_Request_Operation> + TP_Custom_Request_Operation_Handle; + + + /** + * @class TP_Custom_Request_Operation + * + * @brief Base class for all custom request operations. + * + * @note The caller that creates a new TP_Custom_Request_Operation + * object needs call _add_ref () on the servant before + * constructing it and the TP_Custom_Request_Operation object + * is responsible to decrement the reference count. + * + * TBD - Add description + */ + class TAO_CSD_TP_Export TP_Custom_Request_Operation + : public TAO_Intrusive_Ref_Count_Base<ACE_SYNCH_MUTEX> + { + public: + + /// Virtual Destructor. + virtual ~TP_Custom_Request_Operation(); + + /// Invoked by a worker thread to perform the operation. + void execute(); + + /// Invoked when the request has been cancelled. + void cancel(); + + /// Used by the TP_Strategy to obtain the target servant in order + /// to construct the custom request object. Returns the servant as + /// an "in" argument (the caller does not get a new 'copy'). This + /// is useful for chaining. + PortableServer::Servant servant(); + + + protected: + + /// Constructor. + TP_Custom_Request_Operation(PortableServer::Servant servant); + + virtual void execute_i() = 0; + virtual void cancel_i() = 0; + + + private: + + PortableServer::ServantBase_var servant_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Custom_Request_Operation.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_CUSTOM_REQUEST_OPERATION_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.inl new file mode 100644 index 00000000000..cfdcc74f1c6 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Request_Operation.inl @@ -0,0 +1,47 @@ +// -*- C++ -*- +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Custom_Request_Operation::TP_Custom_Request_Operation + (PortableServer::Servant servant) +: servant_ (servant) +{ + // This try-catch block is not really necessary for current implementation + // since the _add_ref does not throw exception, but we have to add it to + // satisfy the non-exception builds. If _add_ref really throws an exception + // then this constructor needs deal with the exception. + ACE_TRY_NEW_ENV + { + this->servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHALL + { + } + ACE_ENDTRY; +} + + +ACE_INLINE +void +TAO::CSD::TP_Custom_Request_Operation::execute() +{ + this->execute_i(); +} + + +ACE_INLINE +void +TAO::CSD::TP_Custom_Request_Operation::cancel() +{ + this->cancel_i(); +} + + +ACE_INLINE +PortableServer::Servant +TAO::CSD::TP_Custom_Request_Operation::servant() +{ + return this->servant_.in(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.cpp new file mode 100644 index 00000000000..dd9162bea02 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.cpp @@ -0,0 +1,32 @@ +// $Id$ + +#include "CSD_TP_Custom_Synch_Request.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Custom_Synch_Request, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Custom_Synch_Request.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Custom_Synch_Request::~TP_Custom_Synch_Request() +{ +} + + +void +TAO::CSD::TP_Custom_Synch_Request::dispatch_i() +{ + this->execute_op(); + this->synch_helper_.dispatched(); +} + + +void +TAO::CSD::TP_Custom_Synch_Request::cancel_i() +{ + this->cancel_op(); + this->synch_helper_.cancelled(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h new file mode 100644 index 00000000000..a4c5e059e40 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.h @@ -0,0 +1,89 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Custom_Synch_Request.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_CUSTOM_SYNCH_REQUEST_H +#define TAO_CSD_TP_CUSTOM_SYNCH_REQUEST_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Custom_Request.h" +#include "CSD_TP_Synch_Helper.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Custom_Synch_Request; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Custom_Synch_Request> + TP_Custom_Synch_Request_Handle; + + /** + * @class TP_Custom_Synch_Request + * + * @brief Base class for "queue-able", Custom (non-CORBA), + * Synchronous requests. + * + * TBD - Add description + * + */ + class TAO_CSD_TP_Export TP_Custom_Synch_Request : public TP_Custom_Request + { + public: + + /// Constructor. + TP_Custom_Synch_Request(TP_Custom_Request_Operation* op, + TP_Servant_State* servant_state); + + /// Virtual Destructor. + virtual ~TP_Custom_Synch_Request(); + + /// Wait until the request has been executed (and completes), or + /// until it has been cancelled. Returns true if the request has + /// been executed/completed, and returns false if the request has + /// been cancelled. + bool wait(); + + + protected: + + /// Dispatch the request to the servant. + virtual void dispatch_i(); + + /// Cancel the request. + virtual void cancel_i(); + + + private: + + /// Helper used to block and unblock the thread that invokes our + /// wait() method. + TP_Synch_Helper synch_helper_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Custom_Synch_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_CUSTOM_SYNCH_REQUEST_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.inl new file mode 100644 index 00000000000..18cb942160c --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Custom_Synch_Request.inl @@ -0,0 +1,18 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Custom_Synch_Request::TP_Custom_Synch_Request + (TP_Custom_Request_Operation* op, + TP_Servant_State* servant_state) + : TP_Custom_Request(op,servant_state) +{ +} + + +ACE_INLINE +bool +TAO::CSD::TP_Custom_Synch_Request::wait() +{ + return this->synch_helper_.wait_while_pending(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.cpp new file mode 100644 index 00000000000..c10b11aa53b --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.cpp @@ -0,0 +1,50 @@ +// $Id$ + +#include "CSD_TP_Dispatchable_Visitor.h" + +ACE_RCSID (CSD_TP, + Dispatchable_Visitor, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Dispatchable_Visitor.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Dispatchable_Visitor::~TP_Dispatchable_Visitor() +{ +} + + +bool +TAO::CSD::TP_Dispatchable_Visitor::visit_request(TP_Request* request, + bool& remove_flag) +{ + // Ask the request object if the target servant is "ready" to accept + // a request being dispatched to it. + if (request->is_ready()) + { + // Ok. This request is a "dispatchable" request. It is what we were + // hoping to find. + + // Save a copy of the request in our handle data member. + request->_add_ref(); + this->request_ = request; + + // Make sure that the queue will extract the request from the queue + // upon our return. + remove_flag = true; + + // Mark the target servant as being "busy". + request->mark_as_busy(); + + // Stop the visitation by returning false. + return false; + } + + // The target servant object of the request isn't ready, so the request + // is not considered to be a "dispatchable" request. + + // Return true to visit the next request in the queue (if there is one). + return true; +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h new file mode 100644 index 00000000000..9f639a5e8a9 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.h @@ -0,0 +1,91 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Dispatchable_Visitor.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_DISPATCHABLE_VISITOR_H +#define TAO_CSD_TP_DISPATCHABLE_VISITOR_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Queue_Visitor.h" +#include "CSD_TP_Request.h" + + +namespace TAO +{ + namespace CSD + { + + /** + * @class TP_Dispatchable_Visitor + * + * @brief Used to extract the first "dispatchable" request from the queue. + * + * An instance of this visitor class is used by one of the worker + * threads to locate the first "dispatchable" request in the queue. If + * such a request is visited, then this visitor will save a "copy" of + * the request, indicate that the request should be removed from the + * queue, and indicate that visitation should stop. + * + * An method is provided to retrieve a "copy" of the "dispatchable" + * request that was saved off during visitation. A nil reference + * (ie, a NULL pointer) will be returned if no dispatchable request + * was found. + * + */ + class TAO_CSD_TP_Export TP_Dispatchable_Visitor : public TP_Queue_Visitor + { + public: + + /// Default Constructor. + TP_Dispatchable_Visitor(); + + /// Virtual Destructor. + virtual ~TP_Dispatchable_Visitor(); + + /// Reset this visitor object in order to re-use it for another + /// visitation of the request queue. This sets the vistor's "result" + /// (the TP_Request* data member) to its default value (a nil handle). + void reset(); + + /// Returns true to continue visitation. Returns false to stop + /// visitation. Sets the remove_flag to true if the request should + /// be removed from the queue as a result of the visit. Leaves the + /// remove_flag alone otherwise. + virtual bool visit_request(TP_Request* request, bool& remove_flag); + + /// This returns a "copy" of the located request, or 0 if no request + /// was located. + TP_Request* request(); + + + private: + + /// A handle to the located request. + TP_Request_Handle request_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Dispatchable_Visitor.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_DISPATCHABLE_VISITOR_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.inl new file mode 100644 index 00000000000..ac66587e2a7 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Dispatchable_Visitor.inl @@ -0,0 +1,26 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Dispatchable_Visitor::TP_Dispatchable_Visitor() +{ +} + + +ACE_INLINE +void +TAO::CSD::TP_Dispatchable_Visitor::reset() +{ + // Set the handle to 0 to have it release any request it may currently + // be referencing. + this->request_ = 0; +} + + +ACE_INLINE +TAO::CSD::TP_Request* +TAO::CSD::TP_Dispatchable_Visitor::request() +{ + TP_Request_Handle handle(this->request_.in(), false); + return handle._retn(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Export.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Export.h new file mode 100644 index 00000000000..1eeb556e4f8 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_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_TP +// ------------------------------ +#ifndef TAO_CSD_TP_EXPORT_H +#define TAO_CSD_TP_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (TAO_CSD_TP_HAS_DLL) +# define TAO_CSD_TP_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && TAO_CSD_TP_HAS_DLL */ + +#if !defined (TAO_CSD_TP_HAS_DLL) +# define TAO_CSD_TP_HAS_DLL 1 +#endif /* ! TAO_CSD_TP_HAS_DLL */ + +#if defined (TAO_CSD_TP_HAS_DLL) && (TAO_CSD_TP_HAS_DLL == 1) +# if defined (TAO_CSD_TP_BUILD_DLL) +# define TAO_CSD_TP_Export ACE_Proper_Export_Flag +# define TAO_CSD_TP_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TAO_CSD_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TAO_CSD_TP_BUILD_DLL */ +# define TAO_CSD_TP_Export ACE_Proper_Import_Flag +# define TAO_CSD_TP_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TAO_CSD_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TAO_CSD_TP_BUILD_DLL */ +#else /* TAO_CSD_TP_HAS_DLL == 1 */ +# define TAO_CSD_TP_Export +# define TAO_CSD_TP_SINGLETON_DECLARATION(T) +# define TAO_CSD_TP_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TAO_CSD_TP_HAS_DLL == 1 */ + +// Set TAO_CSD_TP_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (TAO_CSD_TP_NTRACE) +# if (ACE_NTRACE == 1) +# define TAO_CSD_TP_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define TAO_CSD_TP_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !TAO_CSD_TP_NTRACE */ + +#if (TAO_CSD_TP_NTRACE == 1) +# define TAO_CSD_TP_TRACE(X) +#else /* (TAO_CSD_TP_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define TAO_CSD_TP_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (TAO_CSD_TP_NTRACE == 1) */ + +#endif /* TAO_CSD_TP_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp new file mode 100644 index 00000000000..7253794cf0b --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.cpp @@ -0,0 +1,124 @@ +// $Id$ + +#include "CSD_TP_Queue.h" +#include "CSD_TP_Request.h" +#include "CSD_TP_Queue_Visitor.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Queue, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Queue.inl" +#endif /* ! __ACE_INLINE__ */ + + +void +TAO::CSD::TP_Queue::put(TP_Request* request) +{ + // The request is passed in as an "in" argument, and we would like to + // hold on to a "copy" within the queue (the linked list). We will + // perform an _add_ref() on the request now to make the queue's "copy". + request->_add_ref(); + + if (this->tail_ == 0) + { + // The tail_ is a NULL pointer only when the queue is empty. + // Make the request be the only element in the queue. + this->head_ = this->tail_ = request; + + // Make sure the request's prev_ and next_ pointers are set to NULL. + request->prev_ = request->next_ = 0; + } + else + { + // There is at least one request already in the queue. "Append" the + // supplied request object to the end of the queue. + request->prev_ = this->tail_; + request->next_ = 0; + this->tail_->next_ = request; + this->tail_ = request; + } +} + + +void +TAO::CSD::TP_Queue::accept_visitor(TP_Queue_Visitor& visitor) +{ + TP_Request* cur = this->head_; + + while (cur != 0) + { + TP_Request* prev = cur->prev_; + TP_Request* next = cur->next_; + + // Pass the current request to the visitor. Also pass-in a reference + // to the remove_from_queue flag. The visitor may decide that it + // wants to keep the current request for itself, and desires that the + // request be (surgically) removed from the queue. The visitor also + // gets to decide, via its return value, whether or not visitation + // should continue (or cease to continue). + bool remove_from_queue = false; + + bool continue_visitation = visitor.visit_request(cur,remove_from_queue); + + if (remove_from_queue) + { + // Create a local handle to release the current request once + // the handle falls out of scope. We need to do this because the + // queue "owns" a "copy" of each request in the queue. + TP_Request_Handle handle = cur; + + if (this->head_ == cur) + { + // The current request is at the front (the head_) of the queue. + + // Move the head_ to the next request in the queue. + this->head_ = next; + + if (this->head_ == 0) + { + // Not only was the current request at the front of the + // queue - it was the *only* request in the queue. + // Update the tail_ pointer now that the queue is empty. + this->tail_ = 0; + } + else + { + // Set the (new) head_ request's prev_ pointer to be NULL. + this->head_->prev_ = 0; + } + } + else if (this->tail_ == cur) + { + // The current request is not at the front of the queue, + // but it is at the back of the queue. This implies that + // the queue currently contains at least two requests - + // the current request (cur), and the previous request (prev). + // The point is that we can now assume that the 'prev' pointer + // is never NULL in this case. + this->tail_ = prev; + this->tail_->next_ = 0; + } + else + { + // The current request is not at the front or at the back. + // This implies that there are at least three requests in + // the queue. We can assume that the 'next' and 'prev' + // pointers are never NULL in this case. + prev->next_ = next; + next->prev_ = prev; + } + } + + if (!continue_visitation) + { + // The visitor doesn't want to procede with any further visitation. + // Break out of the visitation loop now. + break; + } + + // Move on to the next request in the queue. + cur = next; + } +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h new file mode 100644 index 00000000000..7b42cfeda59 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.h @@ -0,0 +1,96 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Queue.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_QUEUE_H +#define TAO_CSD_TP_QUEUE_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +namespace TAO +{ + namespace CSD + { + + class TP_Request; + class TP_Queue_Visitor; + + /** + * @class TP_Queue + * + * @brief Queue of servant requests that need to be dispatched. + * + * This is the queue of pending servant requests that is "owned" + * by a TP_Strategy object. When an ORB thread dispatches + * a servant request to the strategy object, it will create the + * appropriate (subclass of) TP_Request object to "wrap" + * the servant request in a "queue-friendly" wrapper. The ORB thread + * will then place the TP_Request object on to the queue. Note that + * this scenario pertains to what are being called "remote requests". + * There are other scenarios in which other types of requests can + * get added to this queue. + * + * The strategy object will employ a set of worker threads that are + * responsible for "servicing" the servant requests in the queue. + * + * Note: In the future, support will be added to allow the client + * application inject "custom" TP_Request objects into + * a TP_Strategy object, causing them to be placed in + * the queue. + */ + class TAO_CSD_TP_Export TP_Queue + { + public: + + /// Default Constructor. + TP_Queue(); + + /// Destructor. + ~TP_Queue(); + + /// Place a request at the end of the queue. + void put(TP_Request* request); + + /// Returns true if the queue is empty. Returns false otherwise. + bool is_empty() const; + + /// Visitors will visit each request in the queue, from front to back, + /// and have the ability to stop visiting at any time (ie, before + /// visiting every request). + void accept_visitor(TP_Queue_Visitor& visitor); + + + private: + + /// The request at the front of the queue. + TP_Request* head_; + + /// The request at the end of the queue. + TP_Request* tail_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Queue.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_QUEUE_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.inl new file mode 100644 index 00000000000..58adcec4744 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue.inl @@ -0,0 +1,23 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Queue::TP_Queue() + : head_(0), + tail_(0) +{ +} + + +ACE_INLINE +TAO::CSD::TP_Queue::~TP_Queue() +{ +} + + +ACE_INLINE +bool +TAO::CSD::TP_Queue::is_empty() const +{ + return (this->head_ == 0); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.cpp new file mode 100644 index 00000000000..95d3c39f750 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.cpp @@ -0,0 +1,16 @@ +// $Id$ + +#include "CSD_TP_Queue_Visitor.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Queue_Visitor, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Queue_Visitor.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Queue_Visitor::~TP_Queue_Visitor() +{ +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.h new file mode 100644 index 00000000000..cece3e7ffbc --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.h @@ -0,0 +1,74 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Queue_Visitor.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_QUEUE_VISITOR_H +#define TAO_CSD_TP_QUEUE_VISITOR_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +namespace TAO +{ + namespace CSD + { + + class TP_Request; + + + /** + * @class TP_Queue_Visitor + * + * @brief Base class for vistors of the elements in the TP_Queue. + * + * Provides a way to perform thread-safe iteration over the + * TP_Request objects contained within a TP_Queue object. + * + * This also provides a means to encapsulate each distinct algorithm + * within a distinct subclass of TP_Queue_Visitor. + * + */ + class TAO_CSD_TP_Export TP_Queue_Visitor + { + public: + + /// Virtual Destructor. + virtual ~TP_Queue_Visitor(); + + /// Returns true to continue visitation. Return false to stop + /// visitation. Sets the remove_flag to true if the request should + /// be removed from the queue as a result of the visit. Leaves the + /// remove_flag alone otherwise. + virtual bool visit_request(TP_Request* request, bool& remove_flag) = 0; + + + protected: + + /// Default Constructor. + TP_Queue_Visitor(); + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Queue_Visitor.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_QUEUE_VISITOR_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.inl new file mode 100644 index 00000000000..77567843234 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Queue_Visitor.inl @@ -0,0 +1,7 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Queue_Visitor::TP_Queue_Visitor() +{ +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.cpp new file mode 100644 index 00000000000..cf7f2642505 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.cpp @@ -0,0 +1,57 @@ +// $Id$ + +#include "CSD_TP_Remote_Request.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Remote_Request, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Remote_Request.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Remote_Request::~TP_Remote_Request() +{ +} + + +void +TAO::CSD::TP_Remote_Request::prepare_for_queue_i() +{ + this->do_clone(); +} + + +void +TAO::CSD::TP_Remote_Request::dispatch_i() +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->do_dispatch(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // Eat these. We probably should log these, but since we have already + // unblocked the requesting thread there is no point in saving it or + // doing anything with it. + } +#if defined (TAO_HAS_EXCEPTIONS) + ACE_CATCHALL + { + // Eat these. We probably should log these, but since we have already + // unblocked the requesting thread there is no point in saving it or + // doing anything with it. + } +#endif + ACE_ENDTRY; +} + + +void +TAO::CSD::TP_Remote_Request::cancel_i() +{ + this->do_cancel(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.h new file mode 100644 index 00000000000..c80dec5c992 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.h @@ -0,0 +1,99 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Remote_Request.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_REMOTE_REQUEST_H +#define TAO_CSD_TP_REMOTE_REQUEST_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Corba_Request.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Remote_Request; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Remote_Request> + TP_Remote_Request_Handle; + + /** + * @class TP_Remote_Request + * + * @brief Represents a "queue-able", remote, CORBA request. + * Both syncronous and asynchronous remote CORBA requests + * are represented by the class. + * + * TBD - Go over the following comments and clean up. + * + * Since this class derives from the TP_Request class, it can be + * added to a TP_Queue (ie, it is a "queueable" request). It + * represents a servant request that has been made by a remote + * CORBA client (as opposed to a collocated CORBA client). The + * term "CORBA client" is being used here to distinguish CORBA + * servant requests (those made thru a CORBA object reference), and + * "Custom" servant requests that can be "dispatched" to the strategy + * directly by the client application code (ie, not thru a CORBA + * object reference). Thus, there are "CORBA clients" and + * "Direct clients". + * + * In summary, this class represents a servant request made when a + * remote client invokes a method on a CORBA object reference. + * + */ + class TAO_CSD_TP_Export TP_Remote_Request : public TP_Corba_Request + { + public: + + /// Constructor. + TP_Remote_Request(TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state); + + /// Virtual Destructor. + virtual ~TP_Remote_Request(); + + + protected: + + /// Prepare this TP_Remote_Request object to be placed into the + /// request queue. This will cause the underlying TAO_ServerRequest + /// object to be cloned. + virtual void prepare_for_queue_i(); + + /// Dispatch the request to the servant. + virtual void dispatch_i(); + + /// Cancel the request. + virtual void cancel_i(); + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Remote_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_REMOTE_REQUEST_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.inl new file mode 100644 index 00000000000..baa56a9ea08 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Remote_Request.inl @@ -0,0 +1,20 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Remote_Request::TP_Remote_Request + (TAO_ServerRequest& server_request, + const PortableServer::ObjectId& object_id, + PortableServer::POA_ptr poa, + const char* operation, + PortableServer::Servant servant, + TP_Servant_State* servant_state) + : TP_Corba_Request(object_id, + poa, + operation, + servant, + servant_state, + server_request) +{ +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Request.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.cpp new file mode 100644 index 00000000000..a01d18f19dd --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.cpp @@ -0,0 +1,24 @@ +// $Id$ + +#include "CSD_TP_Request.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Request, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Request.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Request::~TP_Request() +{ +} + + +void +TAO::CSD::TP_Request::prepare_for_queue_i() +{ + // Default implementation is to do nothing. Subclasses can provide + // their own implementation if needed. +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Request.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.h new file mode 100644 index 00000000000..4e7c61e9b09 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.h @@ -0,0 +1,133 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Request.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_REQUEST_H +#define TAO_CSD_TP_REQUEST_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Servant_State.h" +#include "tao/PortableServer/Servant_Base.h" +#include "tao/Intrusive_Ref_Count_Base_T.h" +#include "tao/Intrusive_Ref_Count_Handle_T.h" + + +namespace TAO +{ + namespace CSD + { + + class TP_Request; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Request> TP_Request_Handle; + + class TP_Queue; + + + /** + * @class TP_Request + * + * @brief Base class for "queue-able" requests. + * + * This class serves as the abstract base class for all types of + * "servant requests" that can be inserted into a TP_Queue + * object. + */ + class TAO_CSD_TP_Export TP_Request + : public TAO_Intrusive_Ref_Count_Base<ACE_SYNCH_MUTEX> + { + public: + + /// Virtual Destructor. + virtual ~TP_Request(); + + /// Prepare the request to be placed into the request queue. + void prepare_for_queue(); + + /// Invoked to dispatch the request to the servant. + void dispatch(); + + /// Invoked to cancel the request. + void cancel(); + + /// Is the target servant ready to accept a request? + bool is_ready() const; + + /// Mark the target servant as being busy. + void mark_as_busy(); + + /// Mark the target servant as being ready (ie, not busy). + void mark_as_ready(); + + /// This method returns true if this request targets the supplied + /// servant object. + bool is_target(PortableServer::Servant servant); + + + protected: + + /// Constructor. + TP_Request(PortableServer::Servant servant, + TP_Servant_State* servant_state); + + /// Accessor for the servant. Does not return a new (ref counted) + /// reference! This is used for chaining. + PortableServer::Servant servant(); + + /// The subclass knows if it needs to do anything in preparation + /// of being placed into the request queue. The default implementation + /// does nothing, so only subclasses that have something to do + /// need to provide their own implementation. + virtual void prepare_for_queue_i(); + + /// The subclass knows how to carry out its own way of dispatching + /// the request to the servant. + virtual void dispatch_i() = 0; + + /// Ask the subclass to perform its duties to carry out the cancellation. + virtual void cancel_i() = 0; + + + private: + + /// The TP_Queue class is our friend since it needs access to + /// the prev_ and next_ (private) data members. + friend class TP_Queue; + + /// The previous TP_Request object (in the queue). + TP_Request* prev_; + + /// The next TP_Request object (in the queue). + TP_Request* next_; + + /// Reference to the servant object. + PortableServer::ServantBase_var servant_; + + /// Reference to the servant "state" object (contains the busy flag). + TP_Servant_State::HandleType servant_state_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Request.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_REQUEST_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Request.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.inl new file mode 100644 index 00000000000..7181678ecde --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Request.inl @@ -0,0 +1,92 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Request::TP_Request(PortableServer::Servant servant, + TP_Servant_State* servant_state) + : prev_(0), + next_(0), + servant_ (servant), + servant_state_(servant_state, false) +{ + // This try-catch block is not really necessary for current implementation + // since the _add_ref does not throw exception, but we have to add it to + // satisfy the non-exception builds. If _add_ref really throws an exception + // then this constructor needs deal with the exception. + ACE_TRY_NEW_ENV + { + this->servant_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHALL + { + } + ACE_ENDTRY; +} + + +ACE_INLINE +void +TAO::CSD::TP_Request::prepare_for_queue() +{ + this->prepare_for_queue_i(); +} + + +ACE_INLINE +PortableServer::Servant +TAO::CSD::TP_Request::servant() +{ + // Used for chaining so we do not return a new "copy". + return this->servant_.in(); +} + + +ACE_INLINE +bool +TAO::CSD::TP_Request::is_ready() const +{ + return !this->servant_state_->busy_flag(); +} + + +ACE_INLINE +void +TAO::CSD::TP_Request::mark_as_busy() +{ + this->servant_state_->busy_flag(true); +} + + +ACE_INLINE +void +TAO::CSD::TP_Request::mark_as_ready() +{ + this->servant_state_->busy_flag(false); +} + + +ACE_INLINE +bool +TAO::CSD::TP_Request::is_target(PortableServer::Servant servant) +{ + // Compare pointers. Return true only if these are the exact same object. + return (servant == this->servant_.in()); +} + + +ACE_INLINE +void +TAO::CSD::TP_Request::dispatch() +{ + this->dispatch_i(); + +} + + +ACE_INLINE +void +TAO::CSD::TP_Request::cancel() +{ + this->cancel_i(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.cpp new file mode 100644 index 00000000000..bd7413d3fd2 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.cpp @@ -0,0 +1,16 @@ +// $Id$ + +#include "CSD_TP_Servant_State.h" + +ACE_RCSID (CSD_TP, + Servant_State, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Servant_State.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Servant_State::~TP_Servant_State() +{ +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.h new file mode 100644 index 00000000000..fca7d321f1d --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.h @@ -0,0 +1,89 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Servant_State.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_SERVANT_STATE_H +#define TAO_CSD_TP_SERVANT_STATE_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/Intrusive_Ref_Count_Base_T.h" +#include "tao/Intrusive_Ref_Count_Handle_T.h" +#include "ace/Synch.h" + + +namespace TAO +{ + namespace CSD + { + + /** + * @class TP_Servant_State + * + * @brief Maintains state information for a particular servant. + * + * This TP_Servant_State class is an intrusively reference-counted + * class. This allows it to be held in a "smart pointer" (aka, handle) + * object that will manage the reference-counting automagically. + * + * One TP_Servant_State object is created for each servant object for + * which a request is to be dispatched. The servant state objects are + * held (via smart pointers) in a TP_Servant_State_Map object. In turn, + * the TP_Servant_State_Map object is a data member of the TP_Stategy + * class. Each request placed on to the request queue will hold a + * reference (via a smart pointer) to the servant state object. + * + * Currently, the only "state" info held in this TP_Servant_State class + * is the servant's busy flag. + * + */ + class TAO_CSD_TP_Export TP_Servant_State + : public TAO_Intrusive_Ref_Count_Base<ACE_SYNCH_MUTEX> + { + public: + + /// Handle Type (aka, Smart Pointer Type). + typedef TAO_Intrusive_Ref_Count_Handle<TP_Servant_State> HandleType; + + /// Default Constructor. + TP_Servant_State(); + + /// Virtual Destructor. + virtual ~TP_Servant_State(); + + /// Accessor for the servant busy flag. + bool busy_flag() const; + + /// Mutator for the servant busy flag. + void busy_flag(bool new_value); + + private: + + /// The servant's current "busy" state (true == busy, false == not busy) + bool busy_flag_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Servant_State.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_SERVANT_STATE_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.inl new file mode 100644 index 00000000000..ba67f809131 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State.inl @@ -0,0 +1,24 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Servant_State::TP_Servant_State() + : busy_flag_(false) +{ +} + + +ACE_INLINE +bool +TAO::CSD::TP_Servant_State::busy_flag() const +{ + return this->busy_flag_; +} + + +ACE_INLINE +void +TAO::CSD::TP_Servant_State::busy_flag(bool new_value) +{ + this->busy_flag_ = new_value; +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.cpp new file mode 100644 index 00000000000..d6d34c6c6c2 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.cpp @@ -0,0 +1,11 @@ +// $Id$ + +#include "CSD_TP_Servant_State_Map.h" + +ACE_RCSID (CSD_TP, + Servant_State_Map, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Servant_State_Map.inl" +#endif /* ! __ACE_INLINE__ */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h new file mode 100644 index 00000000000..667b836006c --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.h @@ -0,0 +1,92 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Servant_State_Map.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_SERVANT_STATE_MAP_H +#define TAO_CSD_TP_SERVANT_STATE_MAP_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "CSD_TP_Servant_State.h" +#include "tao/PortableServer/PortableServer.h" +#include "ace/Hash_Map_Manager.h" +#include "ace/Synch.h" + + +namespace TAO +{ + namespace CSD + { + + /** + * @class TP_Servant_State_Map + * + * @brief Map of Servant_State objects - one per servant. + * + * A TP_Stategy object holds an instance of a TP_Servant_State_Map object + * as a (held-by-value) data member. The strategy uses this map to + * find or create the TP_Servant_State object for a particular servant + * object. + * + */ + class TAO_CSD_TP_Export TP_Servant_State_Map + { + public: + + /// Default Constructor. + TP_Servant_State_Map(); + + /// Destructor. + ~TP_Servant_State_Map(); + + /// Accessor for the servant busy flag. + TP_Servant_State* find(PortableServer::Servant servant + ACE_ENV_ARG_DECL); + + /// Insert the servant to map. + void insert(PortableServer::Servant servant + ACE_ENV_ARG_DECL); + + /// Remove the servant from map. + void remove(PortableServer::Servant servant + ACE_ENV_ARG_DECL); + + + private: + + /// Underlying Map Type - Hash-Based - + /// Key Type: void*, Value Type: TP_Servant_State::HandleType + typedef ACE_Hash_Map_Manager_Ex<void*, + TP_Servant_State::HandleType, + ACE_Hash<void*>, + ACE_Equal_To<void*>, + ACE_SYNCH_MUTEX> MapType; + + /// The underlying map of servant state objects. + MapType map_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Servant_State_Map.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_SERVANT_STATE_MAP_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.inl new file mode 100644 index 00000000000..0d0e40f54f3 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Servant_State_Map.inl @@ -0,0 +1,66 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Servant_State_Map::TP_Servant_State_Map() +{ +} + + +ACE_INLINE +TAO::CSD::TP_Servant_State_Map::~TP_Servant_State_Map() +{ +} + + +ACE_INLINE +TAO::CSD::TP_Servant_State* +TAO::CSD::TP_Servant_State_Map::find(PortableServer::Servant servant + ACE_ENV_ARG_DECL) +{ + void* key = servant; + + TP_Servant_State::HandleType value; + + if (this->map_.find(key, value) != 0) + { + ACE_THROW_RETURN (PortableServer::POA::ServantNotActive (), 0); + } + + return value._retn(); +} + + +ACE_INLINE +void +TAO::CSD::TP_Servant_State_Map::insert(PortableServer::Servant servant + ACE_ENV_ARG_DECL) +{ + void* key = servant; + + TP_Servant_State::HandleType value = new TP_Servant_State (); + + int result = this->map_.bind(key, value); + + if (result == 1) + { + ACE_THROW (PortableServer::POA::ServantAlreadyActive ()); + } + + ACE_ASSERT (result == 0); +} + + +ACE_INLINE +void +TAO::CSD::TP_Servant_State_Map::remove(PortableServer::Servant servant + ACE_ENV_ARG_DECL) +{ + void* key = servant; + + if (this->map_.unbind(key) == -1) + { + ACE_THROW (PortableServer::POA::ServantNotActive ()); + } +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.cpp new file mode 100644 index 00000000000..6968234d673 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.cpp @@ -0,0 +1,270 @@ +// $Id$ + +#include "CSD_TP_Strategy.h" +#include "CSD_TP_Remote_Request.h" +#include "CSD_TP_Collocated_Synch_Request.h" +#include "CSD_TP_Collocated_Asynch_Request.h" +#include "CSD_TP_Custom_Synch_Request.h" +#include "CSD_TP_Custom_Asynch_Request.h" +#include "CSD_TP_Collocated_Synch_With_Server_Request.h" +#include "ace/Trace.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Strategy, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Strategy.inl" +#endif /* ! __ACE_INLINE__ */ + + +TAO::CSD::TP_Strategy::~TP_Strategy() +{ +} + + + +TAO::CSD::TP_Strategy::CustomRequestOutcome +TAO::CSD::TP_Strategy::custom_synch_request(TP_Custom_Request_Operation* op + ACE_ENV_ARG_DECL) +{ + TP_Servant_State::HandleType servant_state + = this->servant_state_map_.find(op->servant() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (REQUEST_REJECTED); + + TP_Custom_Synch_Request_Handle request = new + TP_Custom_Synch_Request(op, servant_state.in()); + + if (!this->task_.add_request(request.in())) + { + // The request was rejected by the task. + return REQUEST_REJECTED; + } + + // Now we wait until the request is handled (executed or cancelled). + return (request->wait()) ? REQUEST_EXECUTED : REQUEST_CANCELLED; +} + + +TAO::CSD::TP_Strategy::CustomRequestOutcome +TAO::CSD::TP_Strategy::custom_asynch_request(TP_Custom_Request_Operation* op + ACE_ENV_ARG_DECL) +{ + TP_Servant_State::HandleType servant_state + = this->servant_state_map_.find(op->servant() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (REQUEST_REJECTED); + + TP_Custom_Asynch_Request_Handle request = new + TP_Custom_Asynch_Request(op, servant_state.in()); + + return (this->task_.add_request(request.in())) + ? REQUEST_DISPATCHED : REQUEST_REJECTED; +} + + +bool +TAO::CSD::TP_Strategy::poa_activated_event_i() +{ + // Activates the worker threads, and waits until all have been started. + return (this->task_.open(&(this->num_threads_)) == 0); +} + + +void +TAO::CSD::TP_Strategy::poa_deactivated_event_i() +{ + // Passing in a value of 1 means that we want to shutdown the task, which + // equates to causing all worker threads to shutdown. The worker threads + // themselves will also invoke the close() method, but the passed-in value + // will be 0. So, a 1 means "shutdown", and a 0 means "a single worker + // thread is going away". + this->task_.close(1); +} + + +TAO::CSD::Strategy_Base::DispatchResult +TAO::CSD::TP_Strategy::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) +{ + // Obtain the TP_Servant_State object associated with the servant object. + // The find() either return a non nil handle or already thrown + // ServantNotActive exception. + + TP_Servant_State::HandleType servant_state + = this->servant_state_map_.find(servant ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (DISPATCH_REJECTED); + + // Now we can create the TP_Remote_Request object, and then add it to our + // task_'s "request queue". + // + // TBD-CSD: Need to use a Cached Allocator to "create" the + // TP_Remote_Request objects. For now, use the heap. + TP_Remote_Request_Handle request = + new TP_Remote_Request(server_request, + object_id, + poa, + operation, + servant, + servant_state.in()); + + // Hand the request object to our task so that it can add the request + // to its "request queue". + if (!this->task_.add_request(request.in())) + { + // Return the DISPATCH_REJECTED return code so that the caller (our + // base class' dispatch_request() method) knows that we did + // not handle the request, and that it should be rejected. + return TAO::CSD::Strategy_Base::DISPATCH_REJECTED; + } + + return TAO::CSD::Strategy_Base::DISPATCH_HANDLED; +} + + +TAO::CSD::Strategy_Base::DispatchResult +TAO::CSD::TP_Strategy::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) +{ + // Obtain the TP_Servant_State object associated with the servant object. + // The find() either return a non nil handle or already thrown + // ServantNotActive exception. + + TP_Servant_State::HandleType servant_state + = this->servant_state_map_.find(servant ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (DISPATCH_REJECTED); + + bool is_sync_with_server = server_request.sync_with_server(); + bool is_synchronous = server_request.response_expected(); + + TP_Collocated_Synch_Request_Handle synch_request; + TP_Collocated_Synch_With_Server_Request_Handle synch_with_server_request; + TP_Request_Handle request; + + // Create the request object using the appropriate concrete type. + if (is_sync_with_server) + { + synch_with_server_request = + new TP_Collocated_Synch_With_Server_Request + (server_request, + object_id, + poa, + operation, + servant, + servant_state.in()); + + // Give the request handle its own "copy". + synch_with_server_request->_add_ref(); + request = synch_with_server_request.in(); + } + else if (is_synchronous) + { + synch_request = new TP_Collocated_Synch_Request(server_request, + object_id, + poa, + operation, + servant, + servant_state.in()); + + // Give the request handle its own "copy". + synch_request->_add_ref(); + request = synch_request.in(); + } + else + { + // Just use the (base) request handle to hold the request object. + request = new TP_Collocated_Asynch_Request(server_request, + object_id, + poa, + operation, + servant, + servant_state.in()); + } + + // Hand the request object to our task so that it can add the request + // to its "request queue". + if (!this->task_.add_request(request.in())) + { + // Return the DISPATCH_REJECTED return code so that the caller (our + // base class' dispatch_request() method) knows that we did + // not handle the request, and that it should be rejected. + return DISPATCH_REJECTED; + } + + // We need to wait on the request object if the request type is a + // synchronous request. + if (!synch_request.is_nil()) + { + int srw = synch_request->wait(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (DISPATCH_REJECTED); + if (srw == false) + { + // Raise exception when request was cancelled. + ACE_THROW_RETURN(CORBA::NO_IMPLEMENT(), DISPATCH_REJECTED); + } + } + else if (!synch_with_server_request.is_nil()) + { + bool swsr = synch_with_server_request->wait(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (DISPATCH_REJECTED); + if (swsr == false) + { + // Raise exception when request was cancelled. + ACE_THROW_RETURN(CORBA::NO_IMPLEMENT(), DISPATCH_REJECTED); + } + } + + return DISPATCH_HANDLED; +} + + +void +TAO::CSD::TP_Strategy::servant_activated_event_i + (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + ACE_UNUSED_ARG(oid); + + // Add the servant to the servant state map. + this->servant_state_map_.insert(servant ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + + +void +TAO::CSD::TP_Strategy::servant_deactivated_event_i + (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + ACE_UNUSED_ARG(oid); + + // Cancel all requests stuck in the queue for the specified servant. + this->task_.cancel_servant(servant ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Remove the servant from the servant state map. + this->servant_state_map_.remove(servant ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + + +void +TAO::CSD::TP_Strategy::cancel_requests(PortableServer::Servant servant + ACE_ENV_ARG_DECL) +{ + // Cancel all requests stuck in the queue for the specified servant. + this->task_.cancel_servant(servant ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.h new file mode 100644 index 00000000000..ff96daa2788 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.h @@ -0,0 +1,180 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Strategy.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_STRATEGY_H +#define TAO_CSD_TP_STRATEGY_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#include "CSD_TP_Task.h" +#include "CSD_TP_Servant_State_Map.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/CSD_Framework/CSD_Strategy_Base.h" +#include "tao/Intrusive_Ref_Count_Handle_T.h" + + + +namespace TAO +{ + namespace CSD + { + + class TP_Strategy; + typedef TAO_Intrusive_Ref_Count_Handle<TP_Strategy> TP_Strategy_Handle; + + class TP_Custom_Request_Operation; + + /** + * @class TP_Strategy + * + * @brief A simple custom Thread-Pool servant dispatching strategy class. + * + * This class represents a concrete implementation of a "Custom + * Servant Dispatching Strategy". This implementation is being called + * the "Thread Pool Strategy" reference implementation. + * + * A custom servant dispatching strategy object can be applied to a + * POA object in order to carry out the servant dispatching duties + * for that POA. + * + */ + class TAO_CSD_TP_Export TP_Strategy + : public Strategy_Base + { + public: + + /// Constructor. + TP_Strategy(unsigned num_threads = 1); + + /// Virtual Destructor. + virtual ~TP_Strategy(); + + /// Set the number of threads in the pool (must be > 0). + void set_num_threads(unsigned num_threads); + + /// Return codes for the custom dispatch_request() methods. + enum CustomRequestOutcome + { + /// The request was successfully put on the request queue. + REQUEST_DISPATCHED, + /// The request has been executed/completed by a worker thread. + REQUEST_EXECUTED, + /// The request was removed from the queue and cancelled. + REQUEST_CANCELLED, + /// The request queue rejected the request + REQUEST_REJECTED + }; + + /// Inject a synchronous, custom request into the request queue. + /// This will block the calling thread until the request is handled + /// (dispatched or cancelled) or rejected. + /// Will return REQUEST_EXECUTED, REQUEST_CANCELLED, or REQUEST_REJECTED. + CustomRequestOutcome custom_synch_request + (TP_Custom_Request_Operation* op + ACE_ENV_ARG_DECL); + + /// Inject an asynchronous, custom request into the request queue. + /// This will return control to the calling thread once the request + /// has been placed into the queue (or rejected). + /// Will return REQUEST_DISPATCHED or REQUEST_REJECTED. + CustomRequestOutcome custom_asynch_request + (TP_Custom_Request_Operation* op + ACE_ENV_ARG_DECL); + + /// Cancel all requests that are targeted for the provided servant. + /// This is requested on the user application level. + void cancel_requests(PortableServer::Servant servant + ACE_ENV_ARG_DECL); + + protected: + + /// Handle the dispatching of a remote request. + /// + /// This will cause a new "request" object to be created and pushed + /// on to a "request queue". The worker threads are responsible for + /// servicing the queue, and performing the actual dispatch logic. + virtual Strategy_Base::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); + + /// Handle the dispatching of a collocated request. + /// + /// This will cause a new "request" object to be created and pushed + /// on to a "request queue". The worker threads are responsible for + /// servicing the queue, and performing the actual dispatch logic. + virtual Strategy_Base::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); + + /// Event - The POA has been activated. + /// This will activate the worker thread(s). + /// Returns true if the worker threads were activated successfully. + /// Otherwise, returns false. + virtual bool poa_activated_event_i(); + + /// Event - The POA has been deactivated. + /// This will shutdown the worker thread(s). + virtual void poa_deactivated_event_i(); + + /// 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: + + /// This is the active object used by the worker threads. + /// The request queue is owned/managed by the task object. + /// The strategy object puts requests into the task's request + /// queue, and the worker threads service the queued requests + /// by performing the actual servant request dispatching logic. + TP_Task task_; + + /// The number of worker threads to use for the task. + unsigned num_threads_; + + /// The map of servant state objects. + TP_Servant_State_Map servant_state_map_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Strategy.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_STRATEGY_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.inl new file mode 100644 index 00000000000..ac2f95e3586 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy.inl @@ -0,0 +1,17 @@ +// $Id$ + +ACE_INLINE +TAO::CSD::TP_Strategy::TP_Strategy(unsigned num_threads) + : num_threads_(num_threads) +{ + // Assumes that num_threads > 0. +} + + +ACE_INLINE +void +TAO::CSD::TP_Strategy::set_num_threads(unsigned num_threads) +{ + // Simple Mutator. Assumes that num_threads > 0. + this->num_threads_ = num_threads; +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp new file mode 100644 index 00000000000..0ec186f2f6d --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.cpp @@ -0,0 +1,108 @@ +// $Id$ + +#include "CSD_TP_Strategy_Factory.h" +#include "CSD_TP_Strategy.h" +#include "CSD_ThreadPool.h" +#include "tao/CSD_Framework/CSD_Strategy_Repository.h" +#include "tao/debug.h" +#include "ace/Dynamic_Service.h" +#include "ace/OS_NS_strings.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Strategy_Factory, + "$Id$") + + +TAO::CSD::TP_Strategy_Factory::TP_Strategy_Factory() +{ +} + + +TAO::CSD::TP_Strategy_Factory::~TP_Strategy_Factory() +{ +} + + +int +TAO::CSD::TP_Strategy_Factory::init (int argc, + ACE_TCHAR* argv[]) +{ + ACE_TRACE ("TAO::CSD::TP_Strategy_Factory::init"); + + static int initialized = 0; + + // Only allow initialization once. + if (initialized) + return 0; + + initialized = 1; + 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_CString poa_name; + unsigned num_threads = 1; + + // Parse any service configurator parameters. + for (int curarg = 0; curarg < argc; curarg++) + if (ACE_OS::strcasecmp (argv[curarg], + ACE_TEXT("-CSDtp")) == 0) + { + curarg++; + if (curarg < argc) + { + // Parse the parameter + ACE_CString arg ((const char *)argv[curarg]); + ssize_t pos = arg.find (':'); + poa_name = arg.substr (0, pos); + ACE_CString num_thread_str = arg.substr (pos + 1, arg.length () - pos); + num_threads = ACE_OS::strtoul (num_thread_str.c_str (), 0, 10); + + // Create the ThreadPool strategy for each named poa. + TP_Strategy* strategy = 0; + ACE_NEW_RETURN (strategy, TP_Strategy (num_threads), -1); + CSD_Framework::Strategy_var objref = strategy; + + TAO_CSD_Strategy_Repository *repo = + ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance + ("TAO_CSD_Strategy_Repository"); + + if (repo == 0) + { + TAO_CSD_ThreadPool::init (); + repo = ACE_Dynamic_Service<TAO_CSD_Strategy_Repository>::instance ( + "TAO_CSD_Strategy_Repository" + ); + } + + + repo->add_strategy (poa_name, strategy); + } + } + else + { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT("CSD_ORB_Loader: Unknown option ") + ACE_TEXT("<%s>.\n"), + argv[curarg])); + } + } + + + return 0; +} + +ACE_FACTORY_NAMESPACE_DEFINE(TAO_CSD_TP, + TAO_CSD_TP_Strategy_Factory, + TAO::CSD::TP_Strategy_Factory) + +ACE_STATIC_SVC_DEFINE(TAO_CSD_TP_Strategy_Factory, + ACE_TEXT("TAO_CSD_TP_Strategy_Factory"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME(TAO_CSD_TP_Strategy_Factory), + ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ, + 0) diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.h new file mode 100644 index 00000000000..e51346befbf --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Strategy_Factory.h @@ -0,0 +1,61 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Strategy_Factory.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_STRATEGY_FACTORY_H +#define TAO_CSD_TP_STRATEGY_FACTORY_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" +#include "ace/Service_Object.h" +#include "ace/Service_Config.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +namespace TAO +{ + namespace CSD + { + + /** + * @class TP_Strategy_Factory + * + * @brief An ACE_Service_Object capable of creating TP_Strategy objects. + * + * TBD - Explain in more detail. + * + */ + class TAO_CSD_TP_Export TP_Strategy_Factory : public ACE_Service_Object + { + public: + + /// Constructor. + TP_Strategy_Factory(); + + /// Virtual Destructor. + virtual ~TP_Strategy_Factory(); + + int init (int argc, ACE_TCHAR* argv[]); + }; + } +} + +ACE_STATIC_SVC_DECLARE_EXPORT(TAO_CSD_TP, TAO_CSD_TP_Strategy_Factory) +ACE_FACTORY_DECLARE(TAO_CSD_TP, TAO_CSD_TP_Strategy_Factory) + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_STRATEGY_FACTORY_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.cpp new file mode 100644 index 00000000000..b3b241ec8f8 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.cpp @@ -0,0 +1,11 @@ +// $Id$ + +#include "CSD_TP_Synch_Helper.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Synch_Helper, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Synch_Helper.inl" +#endif /* ! __ACE_INLINE__ */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.h new file mode 100644 index 00000000000..80c8aaff2ec --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.h @@ -0,0 +1,107 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Synch_Helper.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_SYNCH_HELPER_H +#define TAO_CSD_TP_SYNCH_HELPER_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" +#include "tao/Condition.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Synch.h" + + +namespace TAO +{ + namespace CSD + { + + /** + * @class TP_Synch_Helper + * + * @brief Helper class for synchronous requests to block the requesting + * thread until the appropriate time (when it will be un-blocked). + * + * TBD - Description here + * + */ + class TAO_CSD_TP_Export TP_Synch_Helper + { + public: + + /// Constructor. Sets initial state to PENDING. + TP_Synch_Helper(); + + /// Destructor. + ~TP_Synch_Helper(); + + /// Returns true if the helper state is DISPATCHED, and false if + /// the helper state is CANCELLED. However, if the helper state + /// is PENDING, then this method will block the calling thread + /// until the state changes to something other than PENDING + /// (ie, DISPATCHED or CANCELLED). + bool wait_while_pending(); + + /// Change the state of this helper to DISPATCHED, which will cause + /// wait_while_pending() to unblock. + void dispatched(); + + /// Change the state of this helper to CANCELLED, which will cause + /// wait_while_pending() to unblock. + void cancelled(); + + + private: + + /// Enumeration Type for all possible states of this helper object. + enum HelperState + { + PENDING, + DISPATCHED, + CANCELLED + }; + + /// Thread lock type + typedef ACE_SYNCH_MUTEX LockType; + + /// Thread guard type + typedef ACE_Guard<LockType> GuardType; + + /// Thread condition type + typedef TAO_Condition<LockType> ConditionType; + + /// Lock used to protect the state and condition. + LockType lock_; + + /// Used to denote the state of the request dispatching. + HelperState state_; + + /// The condition used to block the calling thread until the + /// state is something other than the PENDING state. + ConditionType condition_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Synch_Helper.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_SYNCH_HELPER_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.inl new file mode 100644 index 00000000000..8a54320afb4 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Synch_Helper.inl @@ -0,0 +1,50 @@ +// $Id$ + + +ACE_INLINE +TAO::CSD::TP_Synch_Helper::TP_Synch_Helper() + : state_(PENDING), + condition_(this->lock_) +{ +} + + +ACE_INLINE +TAO::CSD::TP_Synch_Helper::~TP_Synch_Helper() +{ +} + + +ACE_INLINE +bool +TAO::CSD::TP_Synch_Helper::wait_while_pending() +{ + GuardType guard(this->lock_); + + while (this->state_ == PENDING) + { + this->condition_.wait(); + } + + return (this->state_ == DISPATCHED); +} + + +ACE_INLINE +void +TAO::CSD::TP_Synch_Helper::dispatched() +{ + GuardType guard(this->lock_); + this->state_ = DISPATCHED; + this->condition_.signal(); +} + + +ACE_INLINE +void +TAO::CSD::TP_Synch_Helper::cancelled() +{ + GuardType guard(this->lock_); + this->state_ = CANCELLED; + this->condition_.signal(); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp new file mode 100644 index 00000000000..4a3874a4b82 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.cpp @@ -0,0 +1,310 @@ +// $Id$ + +#include "CSD_TP_Task.h" +#include "CSD_TP_Request.h" +#include "CSD_TP_Dispatchable_Visitor.h" +#include "CSD_TP_Cancel_Visitor.h" + +ACE_RCSID (CSD_ThreadPool, + TP_Task, + "$Id$") + +#if !defined (__ACE_INLINE__) +# include "CSD_TP_Task.inl" +#endif /* ! __ACE_INLINE__ */ + +TAO::CSD::TP_Task::~TP_Task() +{ +} + + +bool +TAO::CSD::TP_Task::add_request(TP_Request* request) +{ + GuardType guard(this->lock_); + + if (!this->accepting_requests_) + { + ACE_DEBUG((LM_DEBUG,"(%P|%t) TP_Task::add_request() - " + "not accepting requests\n")); + return false; + } + + // We have made the decision that the request is going to be placed upon + // the queue_. Inform the request that it is about to be placed into + // a request queue. Some requests may not need to do anything in + // preparation of being placed into a queue. Others, however, may need + // to perfom a "clone" operation on some underlying request data before + // the request can be properly placed into a queue. + request->prepare_for_queue(); + + this->queue_.put(request); + + this->work_available_.signal(); + + return true; +} + + +int +TAO::CSD::TP_Task::open(void* num_threads_ptr) +{ + unsigned num = 1; + + if (num_threads_ptr != 0) + { + unsigned* tmp = ACE_static_cast(unsigned*, num_threads_ptr); + + if (tmp == 0) + { + ACE_ERROR_RETURN((LM_ERROR, + "(%P|%t) TP_Task failed to open. " + "Invalid argument type passed to open().\n"), + -1); + } + + num = *tmp; + } + + // We can't activate 0 threads. Make sure this isn't the case. + if (num < 1) + { + ACE_ERROR_RETURN((LM_ERROR, + "(%P|%t) TP_Task failed to open. " + "num_threads_ (%u) is less-than 1.\n", + num), + -1); + } + + // Likewise, we can't activate too many. Make sure this isn't the case. + if (num > MAX_THREADPOOL_TASK_WORKER_THREADS) + { + ACE_ERROR_RETURN((LM_ERROR, + "(%P|%t) TP_Task failed to open. " + "num_threads_ (%u) is too large. Max is %d.\n", + num, MAX_THREADPOOL_TASK_WORKER_THREADS), + -1); + } + + // We need the lock acquired from here on out. + GuardType guard(this->lock_); + + // We can assume that we are in the proper state to handle this open() + // call as long as we haven't been open()'ed before. + if (this->opened_) + { + ACE_ERROR_RETURN((LM_ERROR, + "(%P|%t) TP_Task failed to open. " + "Task has previously been open()'ed.\n"), + -1); + } + + // Activate this task object with 'num' worker threads. + if (this->activate(THR_NEW_LWP | THR_JOINABLE, num) != 0) + { + // Assumes that when activate returns non-zero return code that + // no threads were activated. + ACE_ERROR_RETURN((LM_ERROR, + "(%P|%t) TP_Task failed to activate " + "(%d) worker threads.\n", + num), + -1); + } + + // Now we have past the point where we can say we've been open()'ed before. + this->opened_ = true; + + // Now we wait until all of the threads have started. + while (this->num_threads_ != num) + { + this->active_workers_.wait(); + } + + // We can now accept requests (via our add_request() method). + this->accepting_requests_ = true; + + return 0; +} + + +int +TAO::CSD::TP_Task::svc() +{ + // Account for this current worker thread having started the + // execution of this svc() method. + { + GuardType guard(this->lock_); + // Put the thread id into a collection which is used to check whether + // the orb shutdown is called by one of the threads in the pool. + ACE_thread_t thr_id = ACE_OS::thr_self (); + if (this->activated_threads_.set(thr_id, this->num_threads_) == -1) + { + ACE_ERROR_RETURN((LM_ERROR, + ACE_TEXT("(%P|%t)TP_Task::svc: number of threads is out of range \n")), + 0); + } + ++this->num_threads_; + this->active_workers_.signal(); + } + + // This visitor object will be re-used over and over again as part of + // the "GetWork" logic below. + TP_Dispatchable_Visitor dispatchable_visitor; + + // Start the "GetWork-And-PerformWork" loop for the current worker thread. + while (1) + { + TP_Request_Handle request; + + // Do the "GetWork" step. + { + // Acquire the lock until just before we decide to "PerformWork". + GuardType guard(this->lock_); + + // Start the "GetWork" loop. + while (request.is_nil()) + { + if (this->shutdown_initiated_) + { + // This breaks us out of all loops with one fell swoop. + return 0; + } + + // There is no need to visit the queue if it is empty. + if (!this->queue_.is_empty()) + { + // Reset the visitor since we use it over and over. This + // will cause the visitor to drop any reference to + // a request that it may still be holding from a prior + // call to accept_visitor(). + dispatchable_visitor.reset(); + + // Visit the requests in the queue in hopes of + // locating the first "dispatchable" (ie, not busy) request. + // If a dispatchable request is located, it is extracted + // from the queue and saved in a handle data member in the + // visitor object. + this->queue_.accept_visitor(dispatchable_visitor); + + // If a dispatchable request is located, it is extracted + // from the queue and saved in a handle data member in the + // visitor object. Let's get a "copy" (or a NULL pointer + // if the visitor didn't locate/extract one). + request = dispatchable_visitor.request(); + } + + // Either the queue is empty or we couldn't find any dispatchable + // requests in the queue at this time. + if (request.is_nil()) + { + // Let's wait until we hear about the possibility of + // work before we go look again. + this->work_available_.wait(); + } + } + + // We have dropped out of the "while (request.is_nil())" loop. + // We only get here is we located/extracted a dispatchable request + // from the queue. Note that the visitor will have already + // marked the target servant as now being busy (because of us). + // We can now safely release the lock. + } + + // Do the "PerformWork" step. We don't need the lock_ to do this. + request->dispatch(); + + // Now that the request has been dispatched, we need to mark the target + // servant as no longer being busy, and we need to signal any wait()'ing + // worker threads that there may be some dispatchable requests in the + // queue now for this not-busy servant. We need the lock_ to do this. + { + GuardType guard(this->lock_); + request->mark_as_ready(); + this->work_available_.signal(); + } + + // Note that the request will be "released" here when the request + // handle falls out of scope and its destructor performs the + // _remove_ref() call on the underlying TP_Request object. + } + + // This will never get executed. + return 0; +} + + +int +TAO::CSD::TP_Task::close(u_long flag) +{ + GuardType guard(this->lock_); + + if (flag == 0) + { + // Worker thread is closing. + --this->num_threads_; + this->active_workers_.signal(); + } + else + { + // Strategy object is shutting down the task. + + // Do nothing if this task has never been open()'ed. + if (!this->opened_) + { + return 0; + } + + // Set the shutdown flag to true. + this->shutdown_initiated_ = true; + + // Stop accepting requests. + this->accepting_requests_ = false; + + // Signal all worker threads waiting on the work_available_ condition. + this->work_available_.broadcast(); + + size_t num_waiting_threads = 0; + + ACE_thread_t my_thr_id = ACE_OS::thr_self (); + + // Check whether the calling thread(calling orb shutdown) is one of the + // threads in the pool. If it is then it should not wait itself. + size_t size = this->activated_threads_.size (); + + for (size_t i = 0; i < size; i ++) + { + ACE_thread_t thr_id = 0; + if (activated_threads_.get (thr_id, i) == 0 && thr_id == my_thr_id) + { + num_waiting_threads = 1; + break; + } + } + + // Wait until all worker threads have shutdown. + while (this->num_threads_ != num_waiting_threads) + { + this->active_workers_.wait(); + } + + // Cancel all requests. + TP_Cancel_Visitor cancel_visitor; + this->queue_.accept_visitor(cancel_visitor); + } + + return 0; +} + + + +void +TAO::CSD::TP_Task::cancel_servant (PortableServer::Servant servant + ACE_ENV_ARG_DECL) +{ + GuardType guard(this->lock_); + + // Cancel the requests targeted for the provided servant. + TP_Cancel_Visitor cancel_visitor(servant); + this->queue_.accept_visitor(cancel_visitor); +} + diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h new file mode 100644 index 00000000000..25fa02f2fda --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.h @@ -0,0 +1,158 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_TP_Task.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_TP_TASK_H +#define TAO_CSD_TP_TASK_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" + +#include "CSD_TP_Queue.h" +#include "tao/PortableServer/PortableServer.h" +#include "tao/Condition.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Task.h" +#include "ace/Synch.h" +#include "ace/Containers_T.h" + +namespace TAO +{ + namespace CSD + { + + /** + * @class TP_Task + * + * @brief Active Object managing a queue of request objects. + * + * There are two types of "users" of a TP_Task object: + * + * 1) The TP_Strategy object that "owns" this task object. + * 2) The worker threads that "run" this task object as an + * "active object". + * + * The TP_Strategy object that "owns" this task object dictates + * when the worker threads are activated and when they are shutdown. It + * also injects requests into this task's queue via calls to the + * add_request() method. It is also the TP_Strategy object that + * dictates the number of worker threads to be activated via a call to + * the set_num_threads() method. + * + * The active object pattern is implemented via the use of the + * the ACE_Task_Base base class, and each worker thread will + * invoke this task's svc() method, and when the svc() returns, the + * worker thread will invoke this task's close() method (with the + * flag argument equal to 0). + * + * @note I just wanted to document an idea... When the pool consists + * of only one worker thread, we could care less about checking + * if target servant objects are busy or not. The simple fact + * that only one thread will be dispatching all requests means + * that servant objects will never be busy when the thread + * tests to see if a request is "ready_for_dispatch()". I'm + * just wondering if this knowledge can be applied to the + * implementation such that the "pool with one worker thread" case + * performs more efficiently. This is STP vs SSTP. + * + */ + class TAO_CSD_TP_Export TP_Task : public ACE_Task_Base + { + public: + + /// Default Constructor. + TP_Task(); + + /// Virtual Destructor. + virtual ~TP_Task(); + + /// Put a request object on to the request queue. + /// Returns true if successful, false otherwise (it has been "rejected"). + bool add_request(TP_Request* request); + + /// Activate the worker threads + virtual int open(void* num_threads_ptr = 0); + + /// The "mainline" executed by each worker thread. + virtual int svc(); + + /// Multi-purpose: argument value is used to differentiate purpose. + /// + /// 0) Invoked by each worker thread after its invocation of the + /// svc() method has completed (ie, returned). + /// 1) Invoked by the strategy object to shutdown all worker threads. + virtual int close(u_long flag = 0); + + /// Cancel all requests that are targeted for the provided servant. + void cancel_servant (PortableServer::Servant servant + ACE_ENV_ARG_DECL); + + + private: + + typedef TAO_SYNCH_MUTEX LockType; + typedef ACE_Guard<LockType> GuardType; + typedef TAO_Condition<LockType> ConditionType; + + + /// Lock to protect the "state" (all of the data members) of this object. + LockType lock_; + + /// Condition used to signal worker threads that they may be able to + /// find a request in the queue_ that needs to be dispatched to a + /// servant that is currently "not busy". + /// This condition will be signal()'ed each time a new request is + /// added to the queue_, and also when a servant has become "not busy". + ConditionType work_available_; + + /// This condition will be signal()'ed each time the num_threads_ + /// data member has its value changed. This is used to keep the + /// close(1) invocation (ie, a shutdown request) blocked until all + /// of the worker threads have stopped running. + ConditionType active_workers_; + + /// Flag used to indicate when this task will (or will not) accept + /// requests via the the add_request() method. + bool accepting_requests_; + + /// Flag used to initiate a shutdown request to all worker threads. + bool shutdown_initiated_; + + /// Flag used to avoid multiple open() calls. + bool opened_; + + /// The number of currently active worker threads. + unsigned num_threads_; + + /// The queue of pending servant requests (a.k.a. the "request queue"). + TP_Queue queue_; + + typedef ACE_Array <ACE_thread_t> Thread_Ids; + + /// The list of ids for the threads launched by this task. + Thread_Ids activated_threads_; + }; + + } +} + +#if defined (__ACE_INLINE__) +# include "CSD_TP_Task.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_TP_TASK_H */ diff --git a/TAO/tao/CSD_ThreadPool/CSD_TP_Task.inl b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.inl new file mode 100644 index 00000000000..5d9744d2afb --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_TP_Task.inl @@ -0,0 +1,17 @@ +// $Id$ + +namespace { enum { MAX_THREADPOOL_TASK_WORKER_THREADS = 50 }; } +namespace { const ACE_thread_t default_thread_id = 0; } + + +ACE_INLINE +TAO::CSD::TP_Task::TP_Task() + : work_available_(this->lock_), + active_workers_(this->lock_), + accepting_requests_(false), + shutdown_initiated_(false), + opened_(false), + num_threads_(0), + activated_threads_ ((size_t)MAX_THREADPOOL_TASK_WORKER_THREADS, default_thread_id) +{ +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp new file mode 100644 index 00000000000..6797bd315e9 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.cpp @@ -0,0 +1,19 @@ +// $Id$ + +#include "CSD_ThreadPool.h" +#include "CSD_TP_Strategy_Factory.h" +#include "tao/CSD_Framework/CSD_Framework_Loader.h" +#include "tao/debug.h" +#include "ace/Dynamic_Service.h" + +int +TAO_CSD_ThreadPool::init (void) +{ + static int initialized = 0; + if (initialized == 1) + return 0; + initialized = 1; + + TAO_CSD_Framework_Loader::init(); + return ACE_Service_Config::process_directive (ace_svc_desc_TAO_CSD_TP_Strategy_Factory); +} diff --git a/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h new file mode 100644 index 00000000000..e227bce3023 --- /dev/null +++ b/TAO/tao/CSD_ThreadPool/CSD_ThreadPool.h @@ -0,0 +1,60 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file CSD_Threadpool.h + * + * $Id$ + * + * @author Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_CSD_THREADPOOL_H +#define TAO_CSD_THREADPOOL_H + +#include /**/ "ace/pre.h" + +#include "CSD_TP_Export.h" +#include "ace/Service_Object.h" +#include "ace/Service_Config.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class TP_Strategy_Factory + * + * @brief An ACE_Service_Object capable of creating TP_Strategy objects. + * + * TBD - Explain in more detail. + * + */ +class TAO_CSD_TP_Export TAO_CSD_ThreadPool +{ + public: + /// Used to force the initialization of the ORB code. + static int init (void); +}; + +#if defined(ACE_HAS_BROKEN_STATIC_CONSTRUCTORS) + +typedef int (*TAO_CSD_Threadpool) (void); + +static TAO_CSD_Threadpool +TAO_Requires_CSD_Threadpool = + &TAO_CSD_ThreadPool::init; + +#else + +static int +TAO_Requires_CSD_Threadpool = + TAO_CSD_ThreadPool::init (); + +#endif /* ACE_HAS_BROKEN_STATIC_CONSTRUCTORS */ + +#include /**/ "ace/post.h" + +#endif /* TAO_CSD_THREADPOOL_H */ diff --git a/TAO/tao/Intrusive_Ref_Count_Base_T.cpp b/TAO/tao/Intrusive_Ref_Count_Base_T.cpp new file mode 100644 index 00000000000..e7776d3fd91 --- /dev/null +++ b/TAO/tao/Intrusive_Ref_Count_Base_T.cpp @@ -0,0 +1,21 @@ +// $Id$ + +#ifndef TAO_INTRUSIVE_REF_COUNT_BASE_T_C +#define TAO_INTRUSIVE_REF_COUNT_BASE_T_C + +#include "Intrusive_Ref_Count_Base_T.h" + +#if !defined (__ACE_INLINE__) +#include "tao/Intrusive_Ref_Count_Base_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (tao, + Intrusive_Ref_Count_Base_T, + "$Id$") + +template <typename T> +TAO_Intrusive_Ref_Count_Base<T>::~TAO_Intrusive_Ref_Count_Base() +{ +} + +#endif /* TAO_INTRUSIVE_REF_COUNT_BASE_T_C */ diff --git a/TAO/tao/Intrusive_Ref_Count_Base_T.h b/TAO/tao/Intrusive_Ref_Count_Base_T.h new file mode 100644 index 00000000000..f37041bd02c --- /dev/null +++ b/TAO/tao/Intrusive_Ref_Count_Base_T.h @@ -0,0 +1,75 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file Intrusive_Ref_Count_Base_T.h + * + * $Id$ + * + * @authors Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_INTRUSIVE_REF_COUNT_BASE_T_H +#define TAO_INTRUSIVE_REF_COUNT_BASE_T_H + +#include /**/ "ace/pre.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Atomic_Op.h" + + +/** + * @class TAO_Intrusive_Ref_Count_Base<ACE_LOCK> + * + * @brief Template base class to provide intrusive reference-counting + * to subclasses. This makes the subclass capable of using a + * TAO_Intrusive_Ref_Count_Handle<X> class as a smart-pointer + * to an X object. In this case, X is a sub-class of this class, + * TAO_Intrusive_Ref_Count_Base<ACE_LOCK>. The ACE_LOCK type is + * used to protect the atomic reference count data member. + * + */ +template <class ACE_LOCK> +class TAO_Intrusive_Ref_Count_Base +{ +public: + + virtual ~TAO_Intrusive_Ref_Count_Base(); + + void _add_ref(); + void _remove_ref(); + + +protected: + + TAO_Intrusive_Ref_Count_Base(); + + +private: + + ACE_Atomic_Op<ACE_LOCK, long> ref_count_; + + // Not implemented. + TAO_Intrusive_Ref_Count_Base(const TAO_Intrusive_Ref_Count_Base&); + TAO_Intrusive_Ref_Count_Base& operator=(const TAO_Intrusive_Ref_Count_Base&); +}; + +#if defined (__ACE_INLINE__) +#include "Intrusive_Ref_Count_Base_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "Intrusive_Ref_Count_Base_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Intrusive_Ref_Count_Base_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_INTRUSIVE_REF_COUNT_BASE_T_H */ diff --git a/TAO/tao/Intrusive_Ref_Count_Base_T.inl b/TAO/tao/Intrusive_Ref_Count_Base_T.inl new file mode 100644 index 00000000000..448763b6c74 --- /dev/null +++ b/TAO/tao/Intrusive_Ref_Count_Base_T.inl @@ -0,0 +1,32 @@ +// $Id$ + +template <typename T> +ACE_INLINE +TAO_Intrusive_Ref_Count_Base<T>::TAO_Intrusive_Ref_Count_Base () + : ref_count_(1) +{} + + +template <typename T> +ACE_INLINE +void +TAO_Intrusive_Ref_Count_Base<T>::_add_ref() +{ + ++this->ref_count_; +} + + +template <typename T> +ACE_INLINE +void +TAO_Intrusive_Ref_Count_Base<T>::_remove_ref() +{ + long new_count = --this->ref_count_; + + if (new_count != 0) + { + return; + } + + delete this; +} diff --git a/TAO/tao/Intrusive_Ref_Count_Handle_T.cpp b/TAO/tao/Intrusive_Ref_Count_Handle_T.cpp new file mode 100644 index 00000000000..f66b1177c48 --- /dev/null +++ b/TAO/tao/Intrusive_Ref_Count_Handle_T.cpp @@ -0,0 +1,16 @@ +// $Id$ + +#ifndef TAO_INTRUSIVE_REF_COUNT_HANDLE_T_C +#define TAO_INTRUSIVE_REF_COUNT_HANDLE_T_C + +#include "Intrusive_Ref_Count_Handle_T.h" + +#if !defined (__ACE_INLINE__) +#include "tao/Intrusive_Ref_Count_Handle_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (tao, + Intrusive_Ref_Count_Handle_T, + "$Id$") + +#endif /* TAO_INTRUSIVE_REF_COUNT_HANDLE_T_C */ diff --git a/TAO/tao/Intrusive_Ref_Count_Handle_T.h b/TAO/tao/Intrusive_Ref_Count_Handle_T.h new file mode 100644 index 00000000000..ce9a64dc694 --- /dev/null +++ b/TAO/tao/Intrusive_Ref_Count_Handle_T.h @@ -0,0 +1,152 @@ +// This may look like C, but it's really -*- C++ -*- + +//============================================================================= +/** + * @file Intrusive_Ref_Count_Handle_T.h + * + * $Id$ + * + * @authors Tim Bradley <bradley_t@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_INTRUSIVE_REF_COUNT_HANDLE_T_H +#define TAO_INTRUSIVE_REF_COUNT_HANDLE_T_H + +#include /**/ "ace/pre.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +/** + * @class TAO_Intrusive_Ref_Count_Handle<T> + * + * @brief Template class for smart-pointer to (intrusively) ref-counted object. + * + * This class behaves just like a xxx_var type behaves. The only significant + * difference is that this class provides a "bool is_nil() const" method, + * and xxx_var types don't (they use the "bool CORBA::is_nil(xxx_ptr ptr)" + * method instead). For example, + * + * typedef TAO_Intrusive_Ref_Count_Handle<PortableServer::ServantBase> + * MyServantBase_var; + * + * The MyServantBase_var and the PortableServer::ServantBase_var are + * nearly idenitical. The only difference is that the MyServantBase_var + * has a "isNil()" method that indicates whether or not the smart pointer + * is in the 'nil' state or not. + * + * This class can be used to "safely" deal with an instance of a servant. + * For example, we can use a single variable + * TAO_Intrusive_Ref_Count_Handle<Foo_i> + * + * typedef TAO_Intrusive_Ref_Count_Handle<Foo_i> Foo_i_var; + * Foo_i_var servant_; + * + * instead of using two variables + * + * PortableServer::ServantBase_var servant_holder_; + * Foo_i* servant_; + + * to deal with the servant memory. + * + * The Foo_i_var type does everything that the PortableServer::ServantBase_var + * type does. In addition, the Foo_i_var type can provide access to the servant + * as derived class via the arrow operator. + */ +template <typename T> +class TAO_Intrusive_Ref_Count_Handle +{ +public: + + /// Default Ctor - enters the "nil" state. + TAO_Intrusive_Ref_Count_Handle(); + + /// Ctor - By default, takes ownership of passed-in "copy" of reference + /// to T. But the second argument (bool) can be changed from + /// the default value of 'true' to the non-default value of 'false'. + /// The second argument dictates whether or not this handle object + /// should take ownership of the passed-in pointer to the T object. + /// By default, it takes ownership, leaving the reference counter + /// of the T object unchanged. When it is instructed to not take + /// ownership (false value for second arg), then the reference + /// counter of the T object will be incremented so that this + /// handle object has its own "copy". + TAO_Intrusive_Ref_Count_Handle(T* p, bool take_ownership = true); + + /// Copy Ctor - claims a "copy" of rhs object's reference to T. + TAO_Intrusive_Ref_Count_Handle(const TAO_Intrusive_Ref_Count_Handle& b); + + /// Dtor + ~TAO_Intrusive_Ref_Count_Handle(); + + /// Assignment Operator with T* argument. + /// Takes ownership of passed-in "copy" of reference to T. + TAO_Intrusive_Ref_Count_Handle& operator=(T* p); + + /// Assignment Operator with const TAO_Smart_Ptr<T>& argument. + /// Claims a "copy" of rhs object's reference to T. + TAO_Intrusive_Ref_Count_Handle& operator= + (const TAO_Intrusive_Ref_Count_Handle& b); + + /// Const Accessor to underlying pointer (T*) using arrow (->) operator. + T* operator->() const; + + /// Returns true if underlying pointer is NULL (0). + /// Returns false otherwise. + bool is_nil() const; + + /// Used to pass the underlying pointer as an "IN" argument to a method. + T* in() const; + + /// Used to pass the underlying pointer as an "IN/OUT" argument to a method. + T*& inout(); + + /// Used to pass the underlying pointer as an "OUT" argument to a method. + T*& out(); + + /// Used to take-away the underlying pointer from this smart pointer object. + /// Caller becomes responsibe for the returned "copy" to the reference. + /// Always leaves the smart pointer in the "nil" state upon return. + T* _retn(); + + +private: + + /// Claim a "copy" of the reference-counted object by adding + /// one to its reference counter. Do nothing if this smart pointer + /// object is currently in the "nil" state. + void claim(); + + /// Drop our "copy" of the reference-counted object by removing + /// one from its reference counter. Do nothing if this smart pointer + /// object is currently in the "nil" state. + /// Note that this method will always leave this smart pointer + /// in the "nil" state upon its return. + void drop(); + + + /// The underlying pointer to the (intrusively) reference-counted object. + /// Set to 0 when this smart pointer is in the "nil" state. Otherwise, + /// this smart pointer always owns a (reference-counted) "copy" of the + /// object pointed to by the ptr_ data member. + T* ptr_; +}; + +#if defined (__ACE_INLINE__) +#include "Intrusive_Ref_Count_Handle_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "Intrusive_Ref_Count_Handle_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Intrusive_Ref_Count_Handle_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_INTRUSIVE_REF_COUNT_HANDLE_T_H */ diff --git a/TAO/tao/Intrusive_Ref_Count_Handle_T.inl b/TAO/tao/Intrusive_Ref_Count_Handle_T.inl new file mode 100644 index 00000000000..9c3a1fbe48b --- /dev/null +++ b/TAO/tao/Intrusive_Ref_Count_Handle_T.inl @@ -0,0 +1,155 @@ +// $Id$ + + +template <typename T> +ACE_INLINE +TAO_Intrusive_Ref_Count_Handle<T>::TAO_Intrusive_Ref_Count_Handle() + : ptr_(0) +{ +} + + +template <typename T> +ACE_INLINE +TAO_Intrusive_Ref_Count_Handle<T>::TAO_Intrusive_Ref_Count_Handle + (T* p, + bool take_ownership) + : ptr_(p) +{ + if (!take_ownership) + { + this->claim(); + } +} + + +template <typename T> +ACE_INLINE +TAO_Intrusive_Ref_Count_Handle<T>::TAO_Intrusive_Ref_Count_Handle + (const TAO_Intrusive_Ref_Count_Handle<T>& b) + : ptr_(b.ptr_) +{ + this->claim(); +} + + +template <typename T> +ACE_INLINE +TAO_Intrusive_Ref_Count_Handle<T>::~TAO_Intrusive_Ref_Count_Handle() +{ + this->drop(); +} + + +template <typename T> +ACE_INLINE +TAO_Intrusive_Ref_Count_Handle<T>& +TAO_Intrusive_Ref_Count_Handle<T>::operator=(T* p) +{ + if (this->ptr_ != p) + { + this->drop(); + this->ptr_ = p; + } + + return *this; +} + + +template <typename T> +ACE_INLINE +TAO_Intrusive_Ref_Count_Handle<T>& +TAO_Intrusive_Ref_Count_Handle<T>::operator= + (const TAO_Intrusive_Ref_Count_Handle<T>& b) +{ + if (this->ptr_ != b.ptr_) + { + this->drop(); + this->ptr_ = b.ptr_; + this->claim(); + } + + return *this; +} + + +template <typename T> +ACE_INLINE +T* +TAO_Intrusive_Ref_Count_Handle<T>::operator->() const +{ + return this->ptr_; +} + + +template <typename T> +ACE_INLINE +bool +TAO_Intrusive_Ref_Count_Handle<T>::is_nil() const +{ + return this->ptr_ == 0; +} + + +template <typename T> +ACE_INLINE +T* +TAO_Intrusive_Ref_Count_Handle<T>::in() const +{ + return this->ptr_; +} + + +template <typename T> +ACE_INLINE +T*& +TAO_Intrusive_Ref_Count_Handle<T>::inout() +{ + return this->ptr_; +} + + +template <typename T> +ACE_INLINE +T*& +TAO_Intrusive_Ref_Count_Handle<T>::out() +{ + this->drop(); + return this->ptr_; +} + + +template <typename T> +ACE_INLINE +T* +TAO_Intrusive_Ref_Count_Handle<T>::_retn() +{ + T* retval = this->ptr_; + this->ptr_ = 0; + return retval; +} + + +template <typename T> +ACE_INLINE +void +TAO_Intrusive_Ref_Count_Handle<T>::claim() +{ + if (this->ptr_ != 0) + { + this->ptr_->_add_ref(); + } +} + + +template <typename T> +ACE_INLINE +void +TAO_Intrusive_Ref_Count_Handle<T>::drop() +{ + if (this->ptr_ != 0) + { + this->ptr_->_remove_ref(); + this->ptr_ = 0; + } +} diff --git a/TAO/tao/PortableServer/Object_Adapter.cpp b/TAO/tao/PortableServer/Object_Adapter.cpp index 6ad3cc7ad62..c1a6c27d759 100644 --- a/TAO/tao/PortableServer/Object_Adapter.cpp +++ b/TAO/tao/PortableServer/Object_Adapter.cpp @@ -355,9 +355,7 @@ TAO_Object_Adapter::dispatch_servant (const TAO::ObjectKey &key, { ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_DISPATCH_START); - servant_upcall.servant ()->_dispatch (req, - &servant_upcall - ACE_ENV_ARG_PARAMETER); + do_dispatch (req, servant_upcall ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (result); } @@ -1242,3 +1240,14 @@ TAO_Object_Adapter::servant_dispatcher (TAO_Servant_Dispatcher *dispatcher) this->servant_dispatcher_ = dispatcher; } +void +TAO_Object_Adapter::do_dispatch (TAO_ServerRequest& req, + TAO::Portable_Server::Servant_Upcall& upcall + ACE_ENV_ARG_DECL) +{ + upcall.servant ()->_dispatch(req, + &upcall + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + diff --git a/TAO/tao/PortableServer/Object_Adapter.h b/TAO/tao/PortableServer/Object_Adapter.h index a3605dc2f11..85587c99c0f 100644 --- a/TAO/tao/PortableServer/Object_Adapter.h +++ b/TAO/tao/PortableServer/Object_Adapter.h @@ -217,6 +217,10 @@ protected: static ACE_Lock *create_lock (int enable_locking, TAO_SYNCH_MUTEX &thread_lock); + virtual void do_dispatch (TAO_ServerRequest& req, + TAO::Portable_Server::Servant_Upcall& upcall + ACE_ENV_ARG_DECL); + public: /** diff --git a/TAO/tao/PortableServer/POAManager.cpp b/TAO/tao/PortableServer/POAManager.cpp index 539f5d0cd9d..186b51c9163 100644 --- a/TAO/tao/PortableServer/POAManager.cpp +++ b/TAO/tao/PortableServer/POAManager.cpp @@ -51,6 +51,15 @@ TAO_POA_Manager::activate_i (ACE_ENV_SINGLE_ARG_DECL) else { this->state_ = PortableServer::POAManager::ACTIVE; + // Find the poas that applied the custom servant dispatching + // strategy to launch the dispatching threads. + + for (POA_COLLECTION::iterator iterator = this->poa_collection_.begin (); + iterator != this->poa_collection_.end (); + ++iterator) + { + (*iterator)->poa_activated_hook (); + } } this->adapter_manager_state_changed (this->state_ @@ -117,6 +126,10 @@ TAO_POA_Manager::deactivate_i (CORBA::Boolean etherealize_objects, ++iterator) { TAO_Root_POA *poa = *iterator; + // Notify the poas that applied the custom servant dispatching + // strategy to stop the dispatching threads. + poa->poa_deactivated_hook (); + poa->deactivate_all_objects_i (etherealize_objects, wait_for_completion ACE_ENV_ARG_PARAMETER); diff --git a/TAO/tao/PortableServer/Root_POA.cpp b/TAO/tao/PortableServer/Root_POA.cpp index 4a132bd1766..4d51829d9e4 100644 --- a/TAO/tao/PortableServer/Root_POA.cpp +++ b/TAO/tao/PortableServer/Root_POA.cpp @@ -822,6 +822,10 @@ TAO_Root_POA::destroy_i (CORBA::Boolean etherealize_objects, this->cleanup_in_progress_ = 1; + // Inform the custom servant dispatching strategy to stop the working + // threads when the poa is destroyed. + this->poa_deactivated_hook (); + // This operation destroys the POA and all descendant POAs. The POA // so destroyed (that is, the POA with its name) may be re-created // later in the same process. (This differs from the @@ -2892,3 +2896,35 @@ TAO_POA_Static_Resources::TAO_POA_Static_Resources (void) { } +void +TAO_Root_POA::poa_activated_hook () +{ + //no-ops +} + +void +TAO_Root_POA::poa_deactivated_hook () +{ + //no-ops +} + +void +TAO_Root_POA::servant_activated_hook (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + //no-ops + ACE_UNUSED_ARG (servant); + ACE_UNUSED_ARG (oid); +} + +void +TAO_Root_POA::servant_deactivated_hook (PortableServer::Servant servant, + const PortableServer::ObjectId& oid + ACE_ENV_ARG_DECL) +{ + //no-ops + ACE_UNUSED_ARG (servant); + ACE_UNUSED_ARG (oid); +} + diff --git a/TAO/tao/PortableServer/Root_POA.h b/TAO/tao/PortableServer/Root_POA.h index 7fcd071f9f7..313bd5bb093 100644 --- a/TAO/tao/PortableServer/Root_POA.h +++ b/TAO/tao/PortableServer/Root_POA.h @@ -561,6 +561,25 @@ public: ACE_ENV_SINGLE_ARG_DECL ); + /// These hooks are needed by the CSD strategy to override + /// and no-ops by default. + + /// 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); + protected: #if (TAO_HAS_MINIMUM_POA == 0) diff --git a/TAO/tao/PortableServer/ServantRetentionStrategyRetain.cpp b/TAO/tao/PortableServer/ServantRetentionStrategyRetain.cpp index 87cf5b4defe..3e054666f24 100644 --- a/TAO/tao/PortableServer/ServantRetentionStrategyRetain.cpp +++ b/TAO/tao/PortableServer/ServantRetentionStrategyRetain.cpp @@ -105,6 +105,18 @@ namespace TAO // Decrement the reference count. CORBA::UShort new_count = --active_object_map_entry->reference_count_; + // Inform the custom servant dispatching (CSD) strategy that the + // servant is deactivated. This would be called just once when the + // servant is deactivated the first time. + if (active_object_map_entry->deactivated_ == 0) + { + this->poa_->servant_deactivated_hook ( + active_object_map_entry->servant_, + active_object_map_entry->user_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + if (new_count == 0) { this->poa_->cleanup_servant (active_object_map_entry->servant_, @@ -557,6 +569,13 @@ namespace TAO // Everything is finally ok // + // Inform the custom servant dispatching (CSD) strategy that the + // sevant is activated. + this->poa_->servant_activated_hook (servant, + user_id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); @@ -635,6 +654,13 @@ namespace TAO // Everything is finally ok // + // Inform the custom servant dispatching (CSD) strategy that the + // sevant is activated. + this->poa_->servant_activated_hook (servant, + system_id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); @@ -758,6 +784,13 @@ namespace TAO // Everything is finally ok // + // Inform the custom servant dispatching (CSD) strategy that the + // sevant is activated. + this->poa_->servant_activated_hook (servant, + user_id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); @@ -865,6 +898,13 @@ namespace TAO // Everything is finally ok // + // Inform the custom servant dispatching (CSD) strategy that the + // sevant is activated. + this->poa_->servant_activated_hook (servant, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); diff --git a/TAO/tao/PortableServer/get_arg.h b/TAO/tao/PortableServer/get_arg.h index bf7a2fc892f..498035b3ed8 100644 --- a/TAO/tao/PortableServer/get_arg.h +++ b/TAO/tao/PortableServer/get_arg.h @@ -79,7 +79,7 @@ namespace TAO size_t i) { return - details + (details != 0 && details->args () != 0) ? static_cast<typename TAO::Arg_Traits<T>::in_arg_val *> ( details->args ()[i])->arg () : static_cast<typename TAO::SArg_Traits<T>::in_arg_val *> ( diff --git a/TAO/tao/Service_Context.h b/TAO/tao/Service_Context.h index 348bec7c061..b5ac3727b15 100644 --- a/TAO/tao/Service_Context.h +++ b/TAO/tao/Service_Context.h @@ -23,6 +23,14 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +namespace TAO +{ + namespace CSD + { + class FW_Server_Request_Wrapper; + } +} + /** * @class TAO_Service_Context * @@ -52,6 +60,11 @@ class TAO_Export TAO_Service_Context { public: + /// Declare FW_Server_Request_Wrapper a friend + /// This friendship makes the FW_Server_Request_Wrapper be able to + /// clone the TAO_Service_Context data member in TAO_ServerRequest. + friend class TAO::CSD::FW_Server_Request_Wrapper; + /// Constructor TAO_Service_Context (void); diff --git a/TAO/tao/TAO_Server_Request.h b/TAO/tao/TAO_Server_Request.h index 288fd4a2723..29b11e2503a 100644 --- a/TAO/tao/TAO_Server_Request.h +++ b/TAO/tao/TAO_Server_Request.h @@ -52,6 +52,14 @@ namespace CORBA class Exception; } +namespace TAO +{ + namespace CSD + { + class FW_Server_Request_Wrapper; + } +} + class TAO_Operation_Details; /** @@ -65,6 +73,12 @@ class TAO_Operation_Details; class TAO_Export TAO_ServerRequest { public: + + /// Declare FW_Server_Request_Wrapper a friend + /// This friendship makes the FW_Server_Request_Wrapper be able to + /// clone the TAO_ServerRequest. + friend class TAO::CSD::FW_Server_Request_Wrapper; + /// Declare TAO_AMH_Response_Handler a friend /** * The TAO_AMH_Response_Handler class needs to copy part of the @@ -319,7 +333,7 @@ private: /// Used to pad CDR stream if we have used DSI. ptrdiff_t dsi_nvlist_align_; - TAO_Operation_Details const * const operation_details_; + TAO_Operation_Details const * operation_details_; /** * An argument flag to indicate whether there is any data that is diff --git a/TAO/tao/Tagged_Profile.h b/TAO/tao/Tagged_Profile.h index 5e9e10f8348..b7706dca0c7 100644 --- a/TAO/tao/Tagged_Profile.h +++ b/TAO/tao/Tagged_Profile.h @@ -24,6 +24,14 @@ #include "tao/Object_KeyC.h" #include "ace/SString.h" +namespace TAO +{ + namespace CSD + { + class FW_Server_Request_Wrapper; + } +} + /** * @class TAO_Tagged_Profile * @@ -34,6 +42,12 @@ class TAO_Export TAO_Tagged_Profile { public: + + /// Declare FW_Server_Request_Wrapper a friend + /// This friendship makes the FW_Server_Request_Wrapper be able to + /// clone the TAO_Tagged_Profile data member in TAO_ServerRequest. + friend class TAO::CSD::FW_Server_Request_Wrapper; + /// Ctor TAO_Tagged_Profile (TAO_ORB_Core *orb_core); diff --git a/TAO/tao/operation_details.h b/TAO/tao/operation_details.h index 8748d0f6147..55df7ee8328 100644 --- a/TAO/tao/operation_details.h +++ b/TAO/tao/operation_details.h @@ -37,6 +37,14 @@ namespace TAO struct Exception_Data; } +namespace TAO +{ + namespace CSD + { + class FW_Server_Request_Wrapper; + } +} + /** * @class TAO_Operation_Details * @@ -53,6 +61,11 @@ class TAO_Export TAO_Operation_Details { public: + /// Declare FW_Server_Request_Wrapper a friend + /// This friendship makes the FW_Server_Request_Wrapper be able to + /// clone the TAO_Operation_Details data member in TAO_ServerRequest. + friend class TAO::CSD::FW_Server_Request_Wrapper; + /// Constructor TAO_Operation_Details (const char *name, CORBA::ULong len, |