summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhangw <zhangw@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2007-02-16 00:02:37 +0000
committerzhangw <zhangw@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2007-02-16 00:02:37 +0000
commit98aa2a31107f9a4333e64102ae498e68b5440074 (patch)
tree8df8146983bcb2d3f368d9fdb5d4e797b1d11595
parente4913e348e0d268abfd446100492003cd8d7e13f (diff)
downloadATCD-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_rt973410
-rw-r--r--TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.cpp534
-rw-r--r--TAO/orbsvcs/orbsvcs/AsynchProxyTools/OperationTable.h202
-rw-r--r--TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyReplyHandler.h23
-rw-r--r--TAO/orbsvcs/orbsvcs/AsynchProxyTools/ProxyServant.h11
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;
+};