diff options
author | zhangw <zhangw@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2007-02-16 00:02:37 +0000 |
---|---|---|
committer | zhangw <zhangw@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2007-02-16 00:02:37 +0000 |
commit | 98aa2a31107f9a4333e64102ae498e68b5440074 (patch) | |
tree | 8df8146983bcb2d3f368d9fdb5d4e797b1d11595 | |
parent | e4913e348e0d268abfd446100492003cd8d7e13f (diff) | |
download | ATCD-98aa2a31107f9a4333e64102ae498e68b5440074.tar.gz |
Fri Feb 16 00:00:49 UTC 2007 Wallace Zhang <zhang_w@ociweb.com>
* orbsvcs/orbsvcs/AsynchProxyTools:
* orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.h:
* orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.cpp:
* orbsvcs/orbsvcs/AsynchProxyTools/ProxyReplyHandler.h:
* orbsvcs/orbsvcs/AsynchProxyTools/ProxyServant.h:
Intial code for this new library.
-rw-r--r-- | TAO/ChangeLog.oci_rt9734 | 10 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.cpp | 534 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.h | 202 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyReplyHandler.h | 23 | ||||
-rw-r--r-- | TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyServant.h | 11 |
5 files changed, 780 insertions, 0 deletions
diff --git a/TAO/ChangeLog.oci_rt9734 b/TAO/ChangeLog.oci_rt9734 index 1420bf3a1fa..23d70d94cba 100644 --- a/TAO/ChangeLog.oci_rt9734 +++ b/TAO/ChangeLog.oci_rt9734 @@ -1,3 +1,13 @@ +Fri Feb 16 00:00:49 UTC 2007 Wallace Zhang <zhang_w@ociweb.com> + + * orbsvcs/orbsvcs/AsynchProxyTools: + * orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.h: + * orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.cpp: + * orbsvcs/orbsvcs/AsynchProxyTools/ProxyReplyHandler.h: + * orbsvcs/orbsvcs/AsynchProxyTools/ProxyServant.h: + + Intial code for this new library. + Fri Jan 26 16:15:57 UTC 2007 Wallace Zhang <zhang_w@ociweb.com> * tests/DSI_AMH/DSI_AMH.mpc: diff --git a/TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.cpp b/TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.cpp new file mode 100644 index 00000000000..446a4fbbe6b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.cpp @@ -0,0 +1,534 @@ +// $Id$ +// +// Operation Table impl + +#include "OperationTable.h" +#include "tao/IFR_Client/IFR_BasicC.h" +#include "tao/corbafwd.h" +#include "tao/CORBA_String.h" +#include "tao/Any_Unknown_IDL_Type.h" +#include "ace/OS_NS_string.h" + + +//--------------------------------------------------------------------------- + +Arg::Arg () + : tc_ (CORBA::TypeCode::_nil ()), + mode_ (0), + must_proxy_ (-1) +{ +} + +Arg::~Arg (void) +{ + CORBA::release (this->tc_); +} + +void +Arg::init (CORBA::TypeCode_ptr tc, CORBA::Flags m) +{ + CORBA::release (this->tc_); + this->tc_ = CORBA::TypeCode::_duplicate (tc); + this->mode_ = m; + this->must_proxy_ = -1; +} + +//--------------------------------------------------------------------------- + +ArgList::ArgList () + : result_ (), + num_args_ (0), + args_ (0), + num_exceptions_ (0), + exceptions_ (0), + is_oneway_ (0), + refcount_ (1) +{ + this->must_proxy_[0] = this->must_proxy_[1] = -1; +} + +ArgList::ArgList (CORBA::ULong argc, + CORBA::ULong excepc, + int oneway) + : result_ (), + num_args_ (0), + args_ (0), + num_exceptions_ (0), + exceptions_ (0), + is_oneway_ (0), + refcount_ (1) +{ + this->must_proxy_[0] = this->must_proxy_[1] = -1; + this->init (argc, + excepc, oneway); +} + +ArgList::~ArgList (void) +{ + delete [] args_; + delete [] exceptions_; +} + +void +ArgList::init (CORBA::ULong argc, + CORBA::ULong excepc, + int oneway) +{ + this->args_ = new Arg [argc]; + this->num_args_ = argc; + this->exceptions_ = new Arg [excepc]; + this->num_exceptions_ = excepc; + this->is_oneway_ = oneway; +} + +void +ArgList::prepare_request(CORBA::NVList_ptr args, + CORBA::TypeCode_ptr &result_tc, + int &is_oneway) +{ + is_oneway = this->is_oneway_; + if (!is_oneway) + result_tc = CORBA::TypeCode::_duplicate (this->result_.tc_); + for (CORBA::ULong i = 0; i < this->num_args_; i++) + { + TAO::Unknown_IDL_Type *ut = 0; + ACE_NEW(ut, TAO::Unknown_IDL_Type(this->args_[i].tc_)); + CORBA::Any_var value = new CORBA::Any; + value->replace(ut); + args->add_value("",value.in(), this->args_[i].mode_); + } +} + +Arg * +ArgList::find_exception (const char *id, + CORBA::Any *& value) +{ + Arg *result = 0; + ACE_NEW_RETURN (value,CORBA::Any,0); + + for (CORBA::ULong i = 0; i < this->num_exceptions_; i++) + { + ACE_DEBUG ((LM_DEBUG, " exceps[%d] = %s\n", + i, this->exceptions_[i].tc_->id())); + if (ACE_OS::strcmp(id, + this->exceptions_[i].tc_->id()) == 0) + { + result = &this->exceptions_[i]; + ACE_DEBUG ((LM_DEBUG, " got a match\n")); + TAO::Unknown_IDL_Type *ut = 0; + ACE_NEW_RETURN(ut, + TAO::Unknown_IDL_Type(this->exceptions_[i].tc_), + 0); + value->replace (ut); + } + } + return result; +} + + // Reference count manipulators. Object will destroy self when count + // goes to zero +int +ArgList::add_ref (void) +{ + return ++this->refcount_; +} + +int +ArgList::remove_ref (void) +{ + int r = --this->refcount_; + if (r == 0) + delete this; + return r; +} + +int +ArgList::must_proxy(CORBA::Flags mode) const +{ + return this->must_proxy_[mode == CORBA::ARG_IN ? 0 : 1]; +} + +void +ArgList::must_proxy (CORBA::Flags mode, int p) +{ + this->must_proxy_[mode == CORBA::ARG_IN ? 0 : 1] = p; +} + +int +ArgList::is_oneway (void) const +{ + return this->is_oneway_; +} + + +// notice that this assignment takes ownership of the value. +void +ArgList::result (CORBA::TypeCode_ptr tc) +{ + this->result_.init(tc,0); +} + +Arg & +ArgList::result () +{ + return this->result_; +} + +CORBA::ULong +ArgList::num_args(void) const +{ + return this->num_args_; +} + +void +ArgList::set_arg (CORBA::ULong ndx, + CORBA::TypeCode_ptr tc, + CORBA::Flags mode) +{ + this->args_[ndx].init(tc,mode); +} + +Arg * +ArgList::args () +{ + return this->args_; +} + +CORBA::ULong +ArgList::num_exceps(void) const +{ + return this->num_exceptions_; +} + +void +ArgList::set_excep (CORBA::ULong ndx, + CORBA::TypeCode_ptr tc) +{ + this->exceptions_[ndx].init(tc,0); +} + +Arg * +ArgList::exceps () +{ + return this->exceptions_; +} + +//--------------------------------------------------------------------------- + +OpArgs::OpArgs (const char *ref_id, ArgList *args) + :next_ (0), + args_(0), + id_(0) +{ + if (args != 0) + { + args_ = args; + args_->add_ref(); + } + id_ = ACE_OS::strdup (ref_id); +} + +OpArgs::~OpArgs (void) +{ + args_->remove_ref(); + free (id_); + delete this->next_; +} + +ArgList * +OpArgs::args (void) +{ + this->args_->add_ref(); + return this->args_; +} + +const char * +OpArgs::id () const +{ + return this->id_; +} + +OpArgs * +OpArgs::next () +{ + return this->next_; +} + +void +OpArgs::next (OpArgs *n) +{ + this->next_ = n; +} + +//--------------------------------------------------------------------------- + +Operation::Operation (const char *opname) + : name_(0), + left_(0), + right_(0), + arg_set_ (0) +{ + if (opname) + name_ = ACE_OS::strdup(opname); +} + +Operation::~Operation() +{ + if (name_) + free(name_); + delete left_; + delete right_; + delete arg_set_; +} + +ArgList * +Operation::arg_list (const char * rep_id) +{ + OpArgs *a = this->args (rep_id); + if (a == 0) + return 0; + return a->args(); +} + +const char * +Operation::name() const +{ + return this->name_; +} + +Operation * +Operation::left() +{ + return this->left_; +} + +Operation * +Operation::right () +{ + return this->right_; +} + +void +Operation::left(Operation *o) +{ + this->left_ = o; +} + +void +Operation::right (Operation *o) +{ + this->right_ = o; +} + +OpArgs * +Operation::args (const char *rep_id) +{ + OpArgs *a = this->arg_set_; + while (a != 0) + { + if (ACE_OS::strcmp (rep_id,a->id()) == 0) + return a; + a = a->next(); + } + return a; +} + +// this assignment takes ownership of argument. +void +Operation::add_set (OpArgs *arglist) +{ + if (this->arg_set_ == 0) + { + this->arg_set_ = arglist; + return; + } + + OpArgs *a = this->arg_set_; + while (a->next() != 0) + a = a->next(); + a->next (arglist); +} + +//---------------------------------------------------------------------------- +OperationTable::OperationTable (/* const char * persistence_file? */) + : head_ (0) +{ + ArgList *al = this->add_is_a("IDL:org.omg/CORBA/Object:1.0"); + al->remove_ref(); + al = this->add_non_existent ("IDL:org.omg/CORBA/Object:1.0"); + al->remove_ref(); +} + +OperationTable::~OperationTable () +{ + delete head_; +} + +ArgList * +OperationTable::find (const char *opname, + const char *rep_id) +{ + ACE_Read_Guard<ACE_RW_Thread_Mutex>(this->lock_); + Operation *op = head_; + while (op != 0) + { + int match = ACE_OS::strcmp(opname,op->name()); + if (match == 0) + { + OpArgs *oa = op->args (rep_id); + if (oa == 0) + return 0; + return oa->args(); + } + op = match == 1 ? op->right() : op->left(); + } + return 0; +} + +Operation * +OperationTable::find_or_add (const char *opname) +{ + if (head_ == 0) + { + head_ = new Operation (opname); + return head_; + } + Operation *result = head_; + while (result != 0) + { + int match = ACE_OS::strcmp(opname,result->name()); + if (match == 0) + return result; + if (match == 1) + if (result->right() == 0) + { + Operation *temp = new Operation(opname); + result->right(temp); + return temp; + } + else + result = result->right(); + else + if (result->left() == 0) + { + Operation *temp = new Operation(opname); + result->left(temp); + return temp; + } + else + result = result->left(); + } + return result; +} + +ArgList * +OperationTable::add_interface (CORBA::InterfaceDef_ptr intDef, + const char * desired_op) +{ + ACE_Write_Guard<ACE_RW_Thread_Mutex>(this->lock_); + ArgList *result = 0; + CORBA::InterfaceDefSeq_var bases = intDef->base_interfaces (); + CORBA::String_var *derived = new CORBA::String_var[bases->length()]; + CORBA::ULong n_bases = bases->length(); + CORBA::ULong i = 0; + for (; i <= n_bases; i++) + { + CORBA::String_var rep_id = intDef->id(); + if (i == 0) + { + ArgList *al = this->add_is_a (rep_id.in()); + if (desired_op && ACE_OS::strcmp("_is_a",desired_op) == 0) + result = al; + else + al->remove_ref(); + + al = this->add_non_existent (rep_id.in()); + if (desired_op && ACE_OS::strcmp("_non_existent",desired_op) == 0) + result = al; + else + al->remove_ref(); + } + CORBA::ContainedSeq_var operations = + intDef->contents (CORBA::dk_Operation,1); + + CORBA::ULong n_ops = operations->length (); + for (CORBA::ULong op = 0; op < n_ops; ++op) + { + CORBA::String_var op_name = operations[op]->name(); + Operation *op = this->find_or_add(op_name.in()); + + CORBA::OperationDef_var opDef = + CORBA::OperationDef::_narrow (operations[op]); + CORBA::ParDescriptionSeq_var params = opDef->params (); + CORBA::ExceptionDefSeq_var excepts = opDef->exceptions(); + + int is_oneway = opDef->mode() == CORBA::OP_ONEWAY; + ArgList *arg_list = new ArgList (params->length(), + excepts->length(), + is_oneway); + if (!is_oneway) + arg_list->result (opDef->result()); + + for (CORBA::ULong p = 0; p < params->length (); ++p) + { + CORBA::Flags mode = CORBA::ARG_IN; + if (params[p].mode == CORBA::PARAM_OUT) + mode = CORBA::ARG_OUT; + else if (params[p].mode == CORBA::PARAM_INOUT) + mode = CORBA::ARG_INOUT; + + arg_list->set_arg(p, params[p].type.in(),mode); + } + + for (CORBA::ULong e = 0; e < excepts->length (); ++e) + { + CORBA::TypeCode_var tc = excepts[e]->type(); + arg_list->set_excep(e, tc.in()); + } + + if (desired_op && ACE_OS::strcmp(op_name,desired_op) == 0) + { + arg_list->add_ref(); + result = arg_list; + } + + op->add_set (new OpArgs(rep_id.in(),arg_list)); + for (CORBA::ULong d = 0; d < i; d++) + op->add_set (new OpArgs(derived[d],arg_list)); + arg_list->remove_ref(); + } + + if (i < bases->length()) + { + derived[i] = rep_id; + intDef = bases[i]; + } + } + delete [] derived; + return result; +} + +ArgList * +OperationTable::add_is_a (const char *rep_id) +{ + Operation *op = this->find_or_add("_is_a"); + int is_oneway = 0; + ArgList *arg_list = new ArgList (1,0, is_oneway); + arg_list->result (CORBA::_tc_boolean); + + arg_list->set_arg(0, CORBA::_tc_string,CORBA::ARG_IN); + op->add_set (new OpArgs(rep_id,arg_list)); + return arg_list; +} + +ArgList * +OperationTable::add_non_existent (const char *rep_id) +{ + Operation *op = this->find_or_add("_non_existent"); + int is_oneway = 0; + ArgList *arg_list = new ArgList (0,0, is_oneway); + arg_list->result (CORBA::_tc_boolean); + + op->add_set (new OpArgs(rep_id,arg_list)); + return arg_list; +} diff --git a/TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.h b/TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.h new file mode 100644 index 00000000000..fb9080a46b7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.h @@ -0,0 +1,202 @@ +// -*- C++ -*- + +#ifndef OPERATION_TABLE_H +#define OPERATION_TABLE_H + +#include <ace/Synch.h> +#include <tao/NVList.h> +#include <tao/Typecode.h> +// +#include "tao/IFR_Client/IFR_BasicC.h" + +//*************************************************************************** +// +// Arg encapuslates a single argument's details. + +class Arg +{ +public: + Arg (); + ~Arg (void); + + void init (CORBA::TypeCode_ptr tc, CORBA::Flags m); + + // tc_ is the type code for the arugment. It may be arbirarily complex. + // In the future, it might be resonable to further pre-evaluate complex + // type codes to tag individual elements as having an object reference + // or not, but for now we just maintain that for the whole argument. + CORBA::TypeCode_ptr tc_; + + // mode_ is the data-direction flag. It is set for IN, INOUT, OUT args. + // It is not set for return values. Mode_ is used along with tc_ to + // populate arg NVLists to handle requests. + CORBA::Flags mode_; + + // This flag is set by the ObjectMap class. If negative, then the + // status is unknown and must be set. If positive, then the argument + // must be processed to proxify a contained object reference. Complex + // types (structs, unions, etc.) must be traversed at parse time to + // locate the object references within. + int must_proxy_; +}; + +//*************************************************************************** +// +// ArgList is a reference counted object, it may be associated with more +// than one interface/operation. Such a multiplicity will happen whenever +// an interface is a known base of other interfaces, in which case two or +// more interfaces will have the same operation with the same arguments. + +class ArgList +{ +public: + ArgList (); + ArgList (CORBA::ULong argc, + CORBA::ULong excepc, + int oneway); + ~ArgList (void); + + void init (CORBA::ULong argc, + CORBA::ULong excepc, + int oneway); + + void prepare_request(CORBA::NVList_ptr args, + CORBA::TypeCode_ptr &result_tc, + int &is_oneway); + + Arg * find_exception (const char * id, + CORBA::Any *& value); + + // Reference count manipulators. Object will destroy self when count + // goes to zero + int add_ref (void); + int remove_ref (void); + + // The must_proxy flag is a short-hand way to determine if *any* arguments + // need to be proxified. This isn't known until the first time the operation + // is actually traversed by the ObjectMap. Since all operations on an + // interface are added to this collection whenever the interface repository + // is queried, it is possible that any particular operation is never + // invoked. + int must_proxy(CORBA::Flags) const; + void must_proxy (CORBA::Flags,int ); + + // Returns true if the associated operation is a one-way + int is_oneway (void) const; + + // The details for the return type, which may be null. + void result (CORBA::TypeCode_ptr tc); + Arg& result (); + + // Access to the list of arguments for this operation + CORBA::ULong num_args(void) const; + void set_arg (CORBA::ULong ndx, CORBA::TypeCode_ptr, CORBA::Flags); + Arg *args (void); + + // Access to the list of user exceptions for this operation + CORBA::ULong num_exceps(void) const; + void set_excep (CORBA::ULong ndx, CORBA::TypeCode_ptr); + Arg *exceps (void); + +private: + int must_proxy_[2]; + Arg result_; + CORBA::ULong num_args_; + Arg *args_; + CORBA::ULong num_exceptions_; + Arg *exceptions_; + + int is_oneway_; + + int refcount_; +}; + +//*************************************************************************** +// +// OpArgs is keyed by interface repository name, and includes the +// particulars of an operation in an interface, including the oneway flag, +// result value typecode, arg mode & type. Also, the OpArgs contains the +// proxification requirements for the arguments. +// + +class OpArgs +{ +public: + OpArgs (const char *ref_id, ArgList *args = 0); + ~OpArgs (void); + + ArgList *args (void); + + const char * id (void) const; + + OpArgs *next (void); + void next (OpArgs *); + +private: + OpArgs *next_; + ArgList *args_; + char * id_; + +}; + +//*************************************************************************** +// +// Operation has a name, and participates in a balanced tree. The +// operation also has a collection interfaces that have an operation by +// this name. This includes base interfaces and happenstance names +// + +class Operation +{ +public: + Operation (const char *name); + ~Operation (void); + + ArgList *arg_list (const char * rep_id); + + const char * name(void) const; + Operation *left(void); + Operation *right(void); + + void left (Operation *o); + void right (Operation *o); + + OpArgs *args (const char *rep_id); + void add_set (OpArgs *arglist); + +private: + char *name_; + Operation *left_; + Operation *right_; + OpArgs *arg_set_; +}; + +//*************************************************************************** +// +// OperationTable is a collection Operation objects, sorted by opname +// with a few helper methods. + +class OperationTable +{ +public: + OperationTable (); + ~OperationTable (); + + ArgList * find (const char * opname, + const char * rep_id); + + ArgList * add_interface (CORBA::InterfaceDef_ptr intDef, + const char * opname = 0); + +private: + ArgList * add_is_a (const char *rep_id); + ArgList * add_non_existent (const char *rep_id); + + Operation * find_or_add (const char *opname); + + Operation *head_; + ACE_RW_Thread_Mutex lock_; +}; + + +#endif diff --git a/TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyReplyHandler.h b/TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyReplyHandler.h new file mode 100644 index 00000000000..782a9be2fdb --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyReplyHandler.h @@ -0,0 +1,23 @@ +// +// $Id$ +// +#include "tao/DynamicInterface/DII_Reply_Handler.h" +#include "tao/DynamicInterface/Server_Request.h" +#include "tao/DynamicInterface/AMH_DSI_Response_Handler.h" +#include "tao/DynamicInterface/Dynamic_Implementation.h" +#include "tao/DynamicInterface/Request.h" +class ProxyReplyHandler : public virtual TAO_DII_Reply_Handler + , public virtual Messaging::ReplyHandler +{ + public: + ProxyReplyHandler (); + virtual ~ProxyReplyHandler (); + + // Callback method for deferred synchronous requests. + virtual void handle_response (TAO_InputCDR &incoming); + virtual void handle_excep (TAO_InputCDR &incoming, + CORBA::ULong reply_status); + + virtual handle_response_i () = 0; + virtual handle_excep_i () = 0; +}; diff --git a/TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyServant.h b/TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyServant.h new file mode 100644 index 00000000000..e6e5f7db86b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyServant.h @@ -0,0 +1,11 @@ +// +//$Id$ +// +class ProxyServant : public virtual TAO_DynamicImplementation +{ +public: + ProxyServant(); + void invoke (CORBA::ServerRequest_ptr request, + TAO_AMH_DSI_Response_Handler_ptr rh); + virtual void invoke_i () = 0; +}; |