summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Cleeland <chris.cleeland@gmail.com>1997-04-08 02:41:48 +0000
committerChris Cleeland <chris.cleeland@gmail.com>1997-04-08 02:41:48 +0000
commitc8ac79d552196471aa9f030b1273266a5f518a22 (patch)
tree736c7e41ba6412b0f343ee6efa5040f02dcf895f
parentc309d4f3c4dbc757a9440662712002d3211a18dd (diff)
downloadATCD-c8ac79d552196471aa9f030b1273266a5f518a22.tar.gz
* IIOP/test/svr.cpp: Global function ::OA_listen() no longer
exists; its functionality is now fully contained within ::main(). If USE_ACE_EVENT_HANDLING is defined, a Reactor-based event loop is used. The original intent was to allow conditional compilation to select btw. the original method and a Reactor-based method. However, weaving that into the library proved far more difficult than anticipated, so more than likely not defining USE_ACE_EVENT_HANDLING will cause massive grief. * IIOP/lib/toa.cpp: Changed call to TCP_OA::init() to reflect new ACE_INET_Addr argument type. * IIOP/lib/tcpoa.cpp (TCP_OA): All initialization methods were changed, specifically the CTOR and TCP_OA::init, to reflect the introduction of ACE_INET_Addr. Two side-effects of using ACE_INET_Addr are that (1) a server can specify the address on which it wants to listen and (2) best that I can tell, the server MUST specify the address on which it wants to listen because otherwise it won't be able to publish a rational IOR. The event loop is now changed to simply loop on Reactor::handle_events(). * IIOP/lib/tcpoa.hh (TCP_OA): Removed vestiges of this component's use of the original connection management scheme. Where appropriate, hostnames and ports were replaces by ACE_INET_Addr, endpoints by ACE_HANDLEs, etc. One particularly nasty thing done was to declare ROA_Handler as a friend so that handle_message() can be called from ROA_Handler::handle_input(), which to me exposes a hole in the original architecture wherein input is "pulled" rather than waited-for. We might need to re-think how this is handled within TAO. * IIOP/lib/roa.{hh,i,cpp}: These files contain the required components to support the new server-side ACE-based connection/event substrate. The client side remains, as always, using the connection mgmt scheme used by the original Sun IIOP code. * IIOP/lib/giop.cpp: Added explicit template instantiation for when this is needed. * IIOP/lib/corbacom.hh: Now protects itself from multiple inclusion. * IIOP/lib/Makefile: Added roa.* where appropriate. * IIOP/test/test1_{clnt,svr}.cpp: THESE HAVE NOT BEEN CONVERTED TO USE ACE EVENT HANDLING!! This round of changes explicitly instantiates templates where required.
-rw-r--r--TAO/IIOP/lib/corbacom.hh3
-rw-r--r--TAO/IIOP/lib/giop.cpp7
-rw-r--r--TAO/IIOP/lib/invoke.cpp2
-rw-r--r--TAO/IIOP/lib/roa.cpp92
-rw-r--r--TAO/IIOP/lib/roa.hh71
-rw-r--r--TAO/IIOP/lib/roa.i13
-rw-r--r--TAO/IIOP/lib/tcpoa.cpp408
-rw-r--r--TAO/IIOP/lib/tcpoa.hh378
-rw-r--r--TAO/IIOP/lib/toa.cpp5
-rw-r--r--TAO/IIOP/lib/toa.hh3
-rw-r--r--TAO/IIOP/test/Makefile2
-rw-r--r--TAO/IIOP/test/svr.cpp236
-rw-r--r--TAO/IIOP/test/test1_clnt.cpp16
-rw-r--r--TAO/IIOP/test/test1_svr.cpp8
14 files changed, 686 insertions, 558 deletions
diff --git a/TAO/IIOP/lib/corbacom.hh b/TAO/IIOP/lib/corbacom.hh
index 2a8ea5e23c2..4bb550ece6a 100644
--- a/TAO/IIOP/lib/corbacom.hh
+++ b/TAO/IIOP/lib/corbacom.hh
@@ -5,6 +5,8 @@
// CORBA C/C++/COM mapping for Win32
//
+#ifndef CORBACOM_INC
+# define CORBACOM_INC
#include <objbase.h> // Win32 name for "compobj.h"
#if SIZEOF_BOOL != 0
@@ -106,3 +108,4 @@ CORBA_WString CORBA_wstring_alloc (CORBA_ULong len);
CORBA_WString CORBA_wstring_copy (const CORBA_WChar *const);
void CORBA_wstring_free (CORBA_WChar *const);
+#endif
diff --git a/TAO/IIOP/lib/giop.cpp b/TAO/IIOP/lib/giop.cpp
index 590f7ea8e69..a4a879a4809 100644
--- a/TAO/IIOP/lib/giop.cpp
+++ b/TAO/IIOP/lib/giop.cpp
@@ -1351,3 +1351,10 @@ GIOP::incoming_message (
// ... error if unconsumed data remains; is this the spot to test that?
}
+
+#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION)
+template class autorelease<client_endpoint>;
+template class CORBA_SEQUENCE<GIOP::ServiceContext>;
+template class CORBA_SEQUENCE<CORBA_Octet>;
+template class CORBA_SEQUENCE<CORBA_TypeCode*>;
+#endif
diff --git a/TAO/IIOP/lib/invoke.cpp b/TAO/IIOP/lib/invoke.cpp
index 8f1b67d5b3d..beaa47a71b8 100644
--- a/TAO/IIOP/lib/invoke.cpp
+++ b/TAO/IIOP/lib/invoke.cpp
@@ -36,7 +36,7 @@
#include "thread.hh"
#include "debug.hh"
#include "giop.hh"
-#include "connmgr.hh"
+#include "connmgr.hh"
//
diff --git a/TAO/IIOP/lib/roa.cpp b/TAO/IIOP/lib/roa.cpp
new file mode 100644
index 00000000000..821cb244be5
--- /dev/null
+++ b/TAO/IIOP/lib/roa.cpp
@@ -0,0 +1,92 @@
+#include "roa.hh"
+#include "tcpoa.hh"
+#include "debug.hh"
+
+int ACE_ROA::end_reactor_event_loop_ = 0;
+ACE_Reactor ACE_ROA::theReactor;
+int ACE_ROA::usingThreads_ = 0;
+void* ACE_ROA::context_p = 0;
+ACE_ROA::UpcallFunc ACE_ROA::theUpcall = 0;
+TCP_OA_ptr ACE_ROA::theOA = 0;
+
+ROA_Handler::ROA_Handler()
+{
+}
+
+int
+ROA_Handler::open(void*)
+{
+ ACE_INET_Addr addr;
+
+ if (this->peer().get_remote_addr(addr) == -1)
+ return -1;
+ else
+ {
+ if (ACE_ROA::reactor()->register_handler(this, ACE_Event_Handler::READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) can't register with reactor\n"), -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) connection from client %s\n",
+ addr.get_host_name()));
+ return 0;
+ }
+}
+
+int
+ROA_Handler::handle_close(ACE_HANDLE fd, ACE_Reactor_Mask rm)
+{
+}
+
+int
+ROA_Handler::handle_input(ACE_HANDLE fd)
+{
+ //
+ // Handle it in this thread. We can do it without any need
+ // to dynamically allocate memory.
+ //
+ CORBA_Environment env;
+ TCP_OA::dispatch_context ctx;
+
+ ctx.skeleton = ACE_ROA::upcall();
+ ctx.context = ACE_ROA::context();
+ // For right now, the value here doesn't matter. But, when we do
+ // threads, we'll need to figure out some way to get commute a
+ // handle to the OA to the handling mechanism (i.e., thread).
+ ctx.oa = ACE_ROA::oa();
+ ctx.endpoint = fd;
+
+#ifdef _POSIX_THREADS
+ ctx.aggressive = CORBA_B_FALSE;
+#endif
+
+ // Need to have a handle to a TCP_OA instance to make this call!!
+ ACE_ROA::oa()->handle_message (ctx, env);
+
+ //
+ // Don't report any errors from the application/skeleton back to the
+ // top level ... the application already has a variety of means to
+ // pass whatever data needs passing, and we don't need to confuse
+ // things by mixing ORB and application errors here.
+ //
+ if (env.exception () != 0) {
+ dexc (env, "ROA_Handler, handle incoming message");
+ env.clear ();
+ }
+}
+
+#if ! defined(__ACE_INLINE__)
+# include "roa.i"
+#endif
+
+#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION)
+// Direct
+template class ACE_Acceptor<ROA_Handler, ACE_SOCK_ACCEPTOR>;
+template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+// Indirect
+template class ACE_Task<ACE_NULL_SYNCH>;// ACE_Svc_Handler
+template class ACE_TSS<ACE_Dynamic>; // ACE_Svc_Handler
+template class ACE_Message_Queue<ACE_NULL_SYNCH>; // ACE_Task
+template class ACE_Module<ACE_NULL_SYNCH>; // ACE_Task
+template class ACE_Thru_Task<ACE_NULL_SYNCH>; // ACE_Module
+#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */
diff --git a/TAO/IIOP/lib/roa.hh b/TAO/IIOP/lib/roa.hh
new file mode 100644
index 00000000000..58939fd7b98
--- /dev/null
+++ b/TAO/IIOP/lib/roa.hh
@@ -0,0 +1,71 @@
+/* This may look like C, but it's really -*- C++ -*- */
+
+#ifndef ACE_ROA_GLOBALS
+# define ACE_ROA_GLOBALS
+
+# include <ace/Reactor.h>
+# include <ace/Acceptor.h>
+# include <ace/SOCK_Acceptor.h>
+# include <ace/Synch.h>
+# include <ace/Svc_Handler.h>
+
+# if defined(__IIOP_BUILD)
+# include "toa.hh"
+# else
+# include <corba/toa.hh>
+# endif
+
+class TCP_OA;
+typedef TCP_OA* TCP_OA_ptr;
+
+// Provide a namespace/scope for singletons and other things
+// WARNING! Not thread-safe yet!
+class ACE_ROA
+{
+public:
+ typedef TOA::dsi_handler UpcallFunc;
+ static ACE_Reactor* reactor();
+
+ static int usingThreads();
+ static void usingThreads(int i);
+
+ // This should probably be replaced with fields that are a bit more
+ // meaningful, but I need to dig through the code to find out what
+ // "more meaningful" really means first.
+ static void* context();
+ static void context(void* p);
+
+ // In our first test case, this will always be set to tcpoa_dispatcher
+ static UpcallFunc upcall();
+ static void upcall(UpcallFunc f);
+
+ static TCP_OA_ptr oa();
+ static void oa(TCP_OA_ptr anOA);
+
+ static int end_reactor_event_loop_;
+
+private:
+ static ACE_Reactor theReactor;
+ static int usingThreads_;
+ static void* context_p;
+ static UpcallFunc theUpcall;
+ static TCP_OA_ptr theOA;
+};
+
+class ROA_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+{
+public:
+ ROA_Handler();
+ virtual int open(void*);
+protected:
+ virtual int handle_input(ACE_HANDLE);
+ virtual int handle_close(ACE_HANDLE, ACE_Reactor_Mask);
+};
+
+typedef ACE_Acceptor<ROA_Handler, ACE_SOCK_ACCEPTOR> ROA_Acceptor;
+
+# if defined(__ACE_INLINE__)
+# include "roa.i"
+# endif
+
+#endif /* ACE_ROA_GLOBALS */
diff --git a/TAO/IIOP/lib/roa.i b/TAO/IIOP/lib/roa.i
new file mode 100644
index 00000000000..4266f884360
--- /dev/null
+++ b/TAO/IIOP/lib/roa.i
@@ -0,0 +1,13 @@
+ACE_INLINE ACE_Reactor* ACE_ROA::reactor() { return &theReactor; }
+
+ACE_INLINE int ACE_ROA::usingThreads() { return usingThreads_; }
+ACE_INLINE void ACE_ROA::usingThreads(int i) { usingThreads_ = i; }
+
+ACE_INLINE void* ACE_ROA::context() { return context_p; }
+ACE_INLINE void ACE_ROA::context(void* p) { context_p = p; }
+
+ACE_INLINE ACE_ROA::UpcallFunc ACE_ROA::upcall() { return theUpcall; }
+ACE_INLINE void ACE_ROA::upcall(ACE_ROA::UpcallFunc f) { theUpcall = f; }
+
+ACE_INLINE TCP_OA_ptr ACE_ROA::oa() { return theOA; }
+ACE_INLINE void ACE_ROA::oa(TCP_OA_ptr anOA) { theOA = anOA; }
diff --git a/TAO/IIOP/lib/tcpoa.cpp b/TAO/IIOP/lib/tcpoa.cpp
index 145149df64f..44a2f2c7ad5 100644
--- a/TAO/IIOP/lib/tcpoa.cpp
+++ b/TAO/IIOP/lib/tcpoa.cpp
@@ -33,25 +33,15 @@
#include "cdr.hh"
#include "debug.hh"
-#include "connmgr.hh"
+#include "connmgr.hh"
#include "tcpoa.hh"
#include "giop.hh"
#include "svrrqst.hh"
+#include "roa.hh"
#include <initguid.h>
-
-#ifdef NO_HOSTNAMES
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif // NO_HOSTNAMES
-
-
-
static TCP_OA *the_oa;
-static short tcp_port;
-static char namebuf [65];
-
#ifdef _POSIX_THREADS
static pthread_key_t request_key;
@@ -60,100 +50,182 @@ static pthread_mutex_t tcpoa_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_attr_t thread_attr;
#endif // _POSIX_THREADS
-
-TCP_OA::TCP_OA (
- CORBA_ORB_ptr owning_orb,
- CORBA_UShort _port,
- CORBA_Environment &env
+//
+// Dispatch routine that provides most of the IIOP glue ... constructs
+// a dynamic ServerRequest and any reply message that's needed.
+//
+static void
+tcp_oa_dispatcher (
+ GIOP::RequestHeader &req,
+ CDR &request_body,
+ CDR *reply,
+ void *context,
+ CORBA_Environment &env
)
{
- assert (the_oa == 0);
+ IIOP_ServerRequest svr_req (&request_body,
+ the_oa->orb (),
+ the_oa);
+
+ //
+ // ServerRequest is what does the unmarshaling, driven by typecodes
+ // that the DSI user provides. Create the ServerRequest, store away
+ // information that'll be needed by some methods, and call the dispatch
+ // routine that the user supplied. Then release the reference so it
+ // can be safely destroyed sometime later.
+ //
+ svr_req._opname = req.operation;
- port = _port;
- do_exit = CORBA_B_FALSE;
- _orb = owning_orb;
- call_count = 0;
- skeleton = 0;
+#ifdef _POSIX_THREADS
+ (void) pthread_setspecific (request_key, &req);
+#else
+ request_tsd = &req;
+#endif // _POSIX_THREADS
- if (ACE_OS::hostname (namebuf, sizeof namebuf) < 0) {
- dsockerr ("gethostname");
- return;
- }
+ TCP_OA::dispatch_context* helper;
+
+ helper = (TCP_OA::dispatch_context*) context;
+ helper->skeleton (req.object_key, svr_req, helper->context, env);
+
+ svr_req.release ();
+
+ //
+ // If reply is null, this was a oneway request ... return!
+ //
+ if (reply == 0)
+ return;
+
+ //
+ // Otherwise check for correct parameter handling, and reply as
+ // appropriate.
+ //
+ // NOTE: if "env" is set, it takes precedence over exceptions
+ // reported using the mechanism of the ServerRequest. Only system
+ // exceptions are reported that way ...
+ //
+ // XXX Exception reporting is ambiguous; it can be cleaner than
+ // this. With both language-mapped and dynamic/explicit reporting
+ // mechanisms, one of must be tested "first" ... so an exception
+ // reported using the other mechanism could be "lost". Perhaps only
+ // the language mapped one should be used for system exceptions.
+ //
+ CORBA_TypeCode_ptr tc;
+ const void *value;
+
+ if (!svr_req._params && env.exception () == 0) {
+ dmsg ("DSI user error, didn't supply params");
+ env.exception (new CORBA_BAD_INV_ORDER (COMPLETED_NO));
+ }
+
+ if (env.exception () != 0) { // standard exceptions only
+ CORBA_Environment env2;
+ CORBA_Exception *x = env.exception ();
+ CORBA_TypeCode_ptr except_tc = x->type ();
+
+ reply->put_ulong (GIOP::SYSTEM_EXCEPTION);
+ (void) CDR::encoder (except_tc, x, 0, reply, env2);
+
+ } else if (svr_req._exception) { // any exception at all
+ CORBA_Exception *x;
+ CORBA_TypeCode_ptr except_tc;
+
+ x = (CORBA_Exception *) svr_req._exception->value ();
+ except_tc = svr_req._exception->type ();
-#ifdef NO_HOSTNAMES
//
- // In some highly static environments, or where even the most basic
- // Internet services are unavailable, it's desirable to use IP addresses
- // rather than host names in object references. IP addresses are
- // normally bad to use since they need to change.
+ // Finish the GIOP Reply header, then marshal the exception.
//
- // In general, TCP OA initialization options are needed to control at
- // least three kinds of host identifiers to embed in objrefs:
+ // XXX x->type() someday ...
//
- // (a) unqualified host names, which is what gethostname() returns
- // at most sites;
+ if (svr_req._ex_type == SYSTEM_EXCEPTION)
+ reply->put_ulong (GIOP::SYSTEM_EXCEPTION);
+ else
+ reply->put_ulong (GIOP::USER_EXCEPTION);
+
+ (void) CDR::encoder (except_tc, x, 0, reply, env);
+
+ } else { // normal reply
//
- // (b) qualified host names (including fully qualified ones, also
- // ones with just subdomain qualification) which are hard to
- // discover in a portable way;
+ // First finish the GIOP header ...
//
- // (c) "Dot notation" IP addresses, which can get stale after a short
- // while ... hosts move between networks, network numbers change,
- // and so on. These will also cause problems in the upcoming
- // evolution of the Internet to IPv6.
+ reply->put_ulong (GIOP::NO_EXCEPTION);
+
//
- // At this time, no general framework is available to control the choice
- // of these kinds of identifiers. A remotely administerable framework
- // (e.g. Win32 registry) seems like it'd be most appropriate.
+ // ... then send any return value ...
//
- // NOTE: gethostbyname() is MT-unsafe, call only in one thread!!
+ if (svr_req._retval) {
+ tc = svr_req._retval->type ();
+ value = svr_req._retval->value ();
+ (void) CDR::encoder (tc, value, 0, reply, env);
+ }
+
//
- hostent *hp;
- char *dot_notation;
+ // ... followed by "inout" and "out" parameters, left to right
+ //
+ unsigned i;
- hp = ACE_OS::gethostbyname (namebuf);
- assert (hp != 0);
+ for (i = 0; i < svr_req._params->count (); i++) {
+ CORBA_NamedValue_ptr nv = svr_req._params->item (i);
+ CORBA_Any_ptr any;
- dot_notation = ACE_OS::inet_ntoa (*(in_addr *)hp->h_addr);
- assert (dot_notation != 0);
+ if (!(nv->flags () & (CORBA_ARG_INOUT|CORBA_ARG_OUT)))
+ continue;
- (void) ACE_OS::strcpy (namebuf, dot_notation);
-#endif // NO_HOSTNAMES
+ any = nv->value ();
+ tc = any->type ();
+ value = any->value ();
+ (void) CDR::encoder (tc, value, 0, reply, env);
+ }
+ }
+}
- //
- // Initialize the endpoint ... or try!
- //
- // NOTE that this sets "port" if it was originally zero. An
- // original value of zero indicates that the OS should select
- // a port on which this OA will listen.
- //
- endpoint = server_endpoint::initialize (port, env);
- tcp_port = port;
+TCP_OA::TCP_OA (CORBA_ORB_ptr owning_orb,
+ ACE_INET_Addr& rendesvous,
+ CORBA_Environment &env)
+ : do_exit(CORBA_B_FALSE),
+ _orb(owning_orb), call_count(0), skeleton(0)
+{
+ assert (the_oa == 0);
- if (env.exception () != 0) {
- dmsg2 ("TCP OA: '%s', port %u", namebuf, port);
- the_oa = this;
+ //
+ // Initialize the endpoint ... or try!
+ //
+ if (clientAcceptor_.open(rendesvous, ACE_ROA::reactor()) == -1)
+ {
+ // XXXCJC Need to return an error somehow!!
}
+
+ else if (ACE_ROA::reactor()->register_handler(&clientAcceptor_,
+ ACE_Event_Handler::ACCEPT_MASK) == -1)
+ {
+ // XXXCJC Need to return an error somehow!!
+ }
+
+ clientAcceptor_.acceptor().get_local_addr(addr);
+
+ // Set the callback for our implementation (cheesy!!!)
+ ACE_ROA::upcall((TOA::dsi_handler)tcp_oa_dispatcher);
+
+ if (env.exception () != 0) {
+ dmsg2 ("TCP OA: '%s', port %u", namebuf, port);
+ the_oa = this;
+ }
}
TCP_OA::~TCP_OA ()
{
- if (endpoint) {
- endpoint->shutdown_connections (GIOP::close_connection, 0);
- endpoint = 0;
- }
}
//
// Public initialisation routine for this OA.
+// XXX This should really be scoped as CORBA_TCP_OA_init()!!!!! -cjc
+
//
TCP_OA_ptr
-TCP_OA::init (
- CORBA_ORB_ptr parent,
- char *oa_name,
- CORBA_Environment &env
-)
+TCP_OA::init (CORBA_ORB_ptr parent,
+ ACE_INET_Addr& rendesvous,
+ CORBA_Environment& env)
{
env.clear ();
@@ -186,29 +258,7 @@ TCP_OA::init (
#endif // _POSIX_THREADS
-
- //
- // The "OA Name" is either the service name (normally listed in the
- // /etc/services file) or is the string form of the port number.
- // These are both controlled by local administration, though in some
- // cases the IETF will register port numbers. If the OA name is
- // unspecified (null pointer) or zero, the OS assigns some port
- // which is currently unused.
- //
- // XXX getservent() is MT-unsafe; use getservent_r() where it exists
- // on the target platform
- //
- unsigned short port;
- struct servent *sp;
-
- if (oa_name && (sp = ACE_OS::getservbyname (oa_name, "tcp")) != 0)
- port = (unsigned short) sp->s_port;
- else if (oa_name != 0 && ACE_OS::atoi (oa_name) != -1)
- port = (unsigned short) ACE_OS::atoi (oa_name);
- else
- port = 0;
-
- the_oa = new TCP_OA (parent, port, env);
+ the_oa = new TCP_OA (parent, rendesvous, env);
return the_oa;
}
@@ -243,8 +293,8 @@ TCP_OA::create (
data->profile.iiop_version.major = IIOP::MY_MAJOR;
data->profile.iiop_version.minor = IIOP::MY_MINOR;
- data->profile.host = ACE_OS::strdup (namebuf);
- data->profile.port = port;
+ data->profile.host = ACE_OS::strdup(addr.get_host_name());
+ data->profile.port = addr.get_port_number();
data->profile.object_key.length = key.length;
data->profile.object_key.maximum = key.length;
data->profile.object_key.buffer = new CORBA_Octet [(size_t) key.length];
@@ -341,8 +391,6 @@ _this ()
data->profile.iiop_version.major = IIOP::MY_MAJOR;
data->profile.iiop_version.minor = IIOP::MY_MINOR;
- data->profile.host = ACE_OS::strdup (namebuf);
- data->profile.port = tcp_port;
data->profile.object_key.length = key->length;
data->profile.object_key.maximum = key->length;
data->profile.object_key.buffer = new CORBA_Octet [(size_t) key->length];
@@ -399,139 +447,6 @@ TCP_OA::get_client_principal (
return request_tsd->requesting_principal;
}
-
-//
-// Dispatch routine that provides most of the IIOP glue ... constructs
-// a dynamic ServerRequest and any reply message that's needed.
-//
-static void
-tcp_oa_dispatcher (
- GIOP::RequestHeader &req,
- CDR &request_body,
- CDR *reply,
- void *context,
- CORBA_Environment &env
-)
-{
- IIOP_ServerRequest svr_req (
- &request_body,
- the_oa->orb (),
- the_oa
- );
-
- //
- // ServerRequest is what does the unmarshaling, driven by typecodes
- // that the DSI user provides. Create the ServerRequest, store away
- // information that'll be needed by some methods, and call the dispatch
- // routine that the user supplied. Then release the reference so it
- // can be safely destroyed sometime later.
- //
- svr_req._opname = req.operation;
-
-#ifdef _POSIX_THREADS
- (void) pthread_setspecific (request_key, &req);
-#else
- request_tsd = &req;
-#endif // _POSIX_THREADS
-
- TCP_OA::dispatch_context *helper;
-
- helper = (TCP_OA::dispatch_context *) context;
- helper->skeleton (req.object_key, svr_req, helper->context, env);
-
- svr_req.release ();
-
- //
- // If reply is null, this was a oneway request ... return!
- //
- if (reply == 0)
- return;
-
- //
- // Otherwise check for correct parameter handling, and reply as
- // appropriate.
- //
- // NOTE: if "env" is set, it takes precedence over exceptions
- // reported using the mechanism of the ServerRequest. Only system
- // exceptions are reported that way ...
- //
- // XXX Exception reporting is ambiguous; it can be cleaner than
- // this. With both language-mapped and dynamic/explicit reporting
- // mechanisms, one of must be tested "first" ... so an exception
- // reported using the other mechanism could be "lost". Perhaps only
- // the language mapped one should be used for system exceptions.
- //
- CORBA_TypeCode_ptr tc;
- const void *value;
-
- if (!svr_req._params && env.exception () == 0) {
- dmsg ("DSI user error, didn't supply params");
- env.exception (new CORBA_BAD_INV_ORDER (COMPLETED_NO));
- }
-
- if (env.exception () != 0) { // standard exceptions only
- CORBA_Environment env2;
- CORBA_Exception *x = env.exception ();
- CORBA_TypeCode_ptr except_tc = x->type ();
-
- reply->put_ulong (GIOP::SYSTEM_EXCEPTION);
- (void) CDR::encoder (except_tc, x, 0, reply, env2);
-
- } else if (svr_req._exception) { // any exception at all
- CORBA_Exception *x;
- CORBA_TypeCode_ptr except_tc;
-
- x = (CORBA_Exception *) svr_req._exception->value ();
- except_tc = svr_req._exception->type ();
-
- //
- // Finish the GIOP Reply header, then marshal the exception.
- //
- // XXX x->type() someday ...
- //
- if (svr_req._ex_type == SYSTEM_EXCEPTION)
- reply->put_ulong (GIOP::SYSTEM_EXCEPTION);
- else
- reply->put_ulong (GIOP::USER_EXCEPTION);
-
- (void) CDR::encoder (except_tc, x, 0, reply, env);
-
- } else { // normal reply
- //
- // First finish the GIOP header ...
- //
- reply->put_ulong (GIOP::NO_EXCEPTION);
-
- //
- // ... then send any return value ...
- //
- if (svr_req._retval) {
- tc = svr_req._retval->type ();
- value = svr_req._retval->value ();
- (void) CDR::encoder (tc, value, 0, reply, env);
- }
-
- //
- // ... followed by "inout" and "out" parameters, left to right
- //
- unsigned i;
-
- for (i = 0; i < svr_req._params->count (); i++) {
- CORBA_NamedValue_ptr nv = svr_req._params->item (i);
- CORBA_Any_ptr any;
-
- if (!(nv->flags () & (CORBA_ARG_INOUT|CORBA_ARG_OUT)))
- continue;
-
- any = nv->value ();
- tc = any->type ();
- value = any->value ();
- (void) CDR::encoder (tc, value, 0, reply, env);
- }
- }
-}
-
-
//
// Helper routine that provides IIOP glue for forwarding requests
// to specific objects from one process to another.
@@ -563,20 +478,17 @@ tcp_oa_forwarder (
// Generic routine to handle a message.
//
void
-TCP_OA::handle_message (
- dispatch_context &ctx,
- CORBA_Environment &env
-)
+TCP_OA::handle_message (dispatch_context& ctx, CORBA_Environment& env)
{
- GIOP::incoming_message (ctx.endpoint->fd,
- ctx.check_forward ? tcp_oa_forwarder : 0,
- tcp_oa_dispatcher, &ctx, env);
+ GIOP::incoming_message (ctx.endpoint,
+ ctx.check_forward ? tcp_oa_forwarder : 0,
+ tcp_oa_dispatcher, &ctx, env);
#ifdef _POSIX_THREADS
- Critical region (&tcpoa_mutex);
+ Critical region (&tcpoa_mutex);
#endif // _POSIX_THREADS
- call_count--;
+ call_count--;
}
@@ -611,7 +523,7 @@ TCP_OA::worker (void *arg)
dexc (env, "TCP_OA, worker");
env.clear ();
}
- } while (context->aggressive && context->endpoint->fd != -1);
+ } while (context->aggressive && context->endpoint != -1);
delete context;
return 0;
@@ -752,7 +664,9 @@ TCP_OA::get_request (
// handle GIOP::CancelRequest messages.
//
+#if 0
fd = endpoint->block_for_connection (do_thr_create, timeout, env);
+#endif
#ifdef _POSIX_THREADS
region.enter ();
@@ -906,8 +820,10 @@ TCP_OA::clean_shutdown (
return;
}
+#if 0
endpoint->shutdown_connections (GIOP::close_connection, 0);
endpoint = 0;
+#endif
}
diff --git a/TAO/IIOP/lib/tcpoa.hh b/TAO/IIOP/lib/tcpoa.hh
index 74f2977735e..69da4d9c2d7 100644
--- a/TAO/IIOP/lib/tcpoa.hh
+++ b/TAO/IIOP/lib/tcpoa.hh
@@ -28,230 +28,202 @@
#ifndef _TCPOA_HH
#define _TCPOA_HH
+# include <ace/INET_Addr.h>
+
class _EXPCLASS TCP_OA;
typedef TCP_OA *TCP_OA_ptr;
+# include "roa.hh"
+
extern const IID IID_TCP_OA;
-class _EXPCLASS TCP_OA : public TOA {
- public:
- ////////////////////////////////////////////////////////////////////////
- //
- // TOA support ... TOA is intended to be a public API that anyone can
- // use, including skeletons.
- //
- ////////////////////////////////////////////////////////////////////////
-
- CORBA_Object_ptr __stdcall create (
- CORBA_OctetSeq &obj_id,
- CORBA_String type_id,
- CORBA_Environment &env
- );
-
- void __stdcall register_dir (
- TOA::dsi_handler handler,
- void *context,
- CORBA_Environment &env
- );
+class _EXPCLASS TCP_OA : public TOA
+{
+public:
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // TOA support ... TOA is intended to be a public API that anyone can
+ // use, including skeletons.
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ CORBA_Object_ptr __stdcall create(CORBA_OctetSeq& obj_id, CORBA_String type_id, CORBA_Environment& env);
+
+ void __stdcall register_dir(TOA::dsi_handler handler, void* context, CORBA_Environment& env);
- void __stdcall get_request (
- CORBA_Boolean use_threads,
- struct timeval *tvp,
- CORBA_Environment &env
- );
-
- void __stdcall please_shutdown (
- CORBA_Environment &env
- );
-
- //
- // Stuff required for COM IUnknown support
- //
- ULONG __stdcall AddRef ();
- ULONG __stdcall Release ();
- HRESULT __stdcall QueryInterface (
- REFIID riid,
- void **ppv
- );
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // TCP_OA SPECIFIC from here on down ... all of this is subject to
- // change and simplification. It's intended to be an internal API
- // providing efficient access to all basic IIOP functionality.
- //
- ////////////////////////////////////////////////////////////////////////
-
- //
- // OA initialisation, per the template in OMG TC doc 94-9-46
- //
- // NOTE that since this OA is not defined by OMG, it doesn't
- // go into the CORBA (and hence ORB) scope and acquiring this
- // OA is not an operation on any particular ORB.
- //
- // Also, this needs no configuration beyond which OA is used;
- // there's no need for argc/argv to control any initialization
- // options.
- //
- static TCP_OA_ptr init (
- CORBA_ORB_ptr which_orb,
- char *oa_name,
- CORBA_Environment &env
- );
-
- //
- // Block till some request comes in, or "timeout" passes. Handle any
- // requests with "handle_request", passing it "context" for access to
- // non-global application state.
- //
- // If the "do_thr_create" flag is set, "handle_request" is invoked in
- // a new thread rather than by the calling thread.
- //
- // If "check_forward" is null, all incoming requests are passed to
- // handle_request() and requests for objects can't be forwarded so
- // they arrive at any other process.
- //
- // If "check_forward" is non-null, the function is called when the OA
- // needs to establish whether a request for a particular object (as
- // identified by "key") are handled in this process. If it returns an
- // exception, the object is deemed not to exist (this is authoritative).
- // If the "fwd_ref" returned is non-null, the request is forwarded to
- // that object reference. Otherwise (no exception, null "fwd_ref")
- // requests for that object may arrive via handle_request().
- //
- // This routine returns after a request arrives, regardless of whether
- // a thread started processing.
- //
- void __stdcall get_request (
- TOA::dsi_handler handle_request,
- void check_forward (
- CORBA_OctetSeq &key,
- CORBA_Object_ptr &fwd_ref,
- void *context,
- CORBA_Environment &env
- ),
- CORBA_Boolean do_thr_create,
- void *context,
- timeval *timeout,
- CORBA_Environment &env
- );
-
- //
- // OA user asks for a clean shutdown of the OA after currently
- // active calls complete. OA "requester" (calls get_request)
- // asks if we're shutting down, and if so closes down transport
- // cleanly.
- //
- CORBA_Boolean shutting_down ()
- { return do_exit; }
-
- void __stdcall clean_shutdown (
- CORBA_Environment &env
- );
-
- //
- // When dispatching a request to an object, you need to be able to get
- // the object key you used to create the reference. It's the main way
- // servers distinguish two object references from each other.
- //
- CORBA_OctetSeq *__stdcall get_key (
- CORBA_Object_ptr obj,
- CORBA_Environment &env
- );
+ void __stdcall get_request(CORBA_Boolean use_threads, struct timeval* tvp, CORBA_Environment& env);
+
+ void __stdcall please_shutdown(CORBA_Environment& env);
+
+ //
+ // Stuff required for COM IUnknown support
+ //
+ ULONG __stdcall AddRef ();
+ ULONG __stdcall Release ();
+ HRESULT __stdcall QueryInterface (REFIID riid, void** ppv);
+
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // TCP_OA SPECIFIC from here on down ... all of this is subject to
+ // change and simplification. It's intended to be an internal API
+ // providing efficient access to all basic IIOP functionality.
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ //
+ // OA initialisation, per the template in OMG TC doc 94-9-46
+ //
+ // NOTE that since this OA is not defined by OMG, it doesn't
+ // go into the CORBA (and hence ORB) scope and acquiring this
+ // OA is not an operation on any particular ORB.
+ //
+ // Also, this needs no configuration beyond which OA is used;
+ // there's no need for argc/argv to control any initialization
+ // options.
+ //
+
+ static TCP_OA_ptr init(CORBA_ORB_ptr which_orb,
+ ACE_INET_Addr& addr,
+ CORBA_Environment& env);
+
+ //
+ // Block till some request comes in, or "timeout" passes. Handle any
+ // requests with "handle_request", passing it "context" for access to
+ // non-global application state.
+ //
+ // If the "do_thr_create" flag is set, "handle_request" is invoked in
+ // a new thread rather than by the calling thread.
+ //
+ // If "check_forward" is null, all incoming requests are passed to
+ // handle_request() and requests for objects can't be forwarded so
+ // they arrive at any other process.
+ //
+ // If "check_forward" is non-null, the function is called when the OA
+ // needs to establish whether a request for a particular object (as
+ // identified by "key") are handled in this process. If it returns an
+ // exception, the object is deemed not to exist (this is authoritative).
+ // If the "fwd_ref" returned is non-null, the request is forwarded to
+ // that object reference. Otherwise (no exception, null "fwd_ref")
+ // requests for that object may arrive via handle_request().
+ //
+ // This routine returns after a request arrives, regardless of whether
+ // a thread started processing.
+ //
+
+ // XXX This is not used when we use the ACE substrate!
+ void __stdcall get_request(TOA::dsi_handler handle_request,
+ void check_forward (CORBA_OctetSeq& key,
+ CORBA_Object_ptr& fwd_ref,
+ void* context,
+ CORBA_Environment& env),
+ CORBA_Boolean do_thr_create,
+ void* context,
+ timeval* timeout,
+ CORBA_Environment& env);
+
+ //
+ // OA user asks for a clean shutdown of the OA after currently
+ // active calls complete. OA "requester" (calls get_request)
+ // asks if we're shutting down, and if so closes down transport
+ // cleanly.
+ //
+ CORBA_Boolean shutting_down() {
+ return do_exit;
+ }
+
+ void __stdcall clean_shutdown(CORBA_Environment& env);
+
+ //
+ // When dispatching a request to an object, you need to be able to get
+ // the object key you used to create the reference. It's the main way
+ // servers distinguish two object references from each other.
+ //
+ CORBA_OctetSeq* __stdcall get_key(CORBA_Object_ptr obj, CORBA_Environment& env);
- //
- // OA-specific state
- //
- CORBA_ORB_ptr orb () const { return _orb; }
-
- //
- // Various request-specific state.
- //
- CORBA_OctetSeq *__stdcall get_target_key (
- CORBA_Environment &env
- );
- CORBA_Principal_ptr __stdcall get_client_principal (
- CORBA_Environment &env
- );
+ //
+ // OA-specific state
+ //
+ CORBA_ORB_ptr orb() const {
+ return _orb;
+ }
+
+ //
+ // Various request-specific state.
+ //
+ CORBA_OctetSeq* __stdcall get_target_key(CORBA_Environment& env);
+ CORBA_Principal_ptr __stdcall get_client_principal(CORBA_Environment& env);
// PRIVATE:
- //
- // Data structure passed as "context" to the GIOP code, which then
- // calls back one of the two helper routines as part of handling any
- // particular incoming request.
- //
- struct dispatch_context {
- TOA::dsi_handler skeleton;
- void (*check_forward) (
- CORBA_OctetSeq &key,
- CORBA_Object_ptr &fwd_ref,
- void *context,
- CORBA_Environment &env
- );
- void *context;
- TCP_OA *oa;
- autorelease <server_endpoint>
- endpoint;
+ //
+ // Data structure passed as "context" to the GIOP code, which then
+ // calls back one of the two helper routines as part of handling any
+ // particular incoming request.
+ //
+ struct dispatch_context
+ {
+ TOA::dsi_handler skeleton;
+ void (*check_forward) (CORBA_OctetSeq& key,
+ CORBA_Object_ptr& fwd_ref,
+ void* context,
+ CORBA_Environment& env);
+ void* context;
+ TCP_OA* oa;
+ ACE_HANDLE endpoint;
#ifdef _POSIX_THREADS
- CORBA_Boolean aggressive;
+ CORBA_Boolean aggressive;
#endif // _POSIX_THREADS
- };
-
- private:
- CORBA_UShort port;
- CORBA_Boolean do_exit;
- CORBA_ORB_ptr _orb;
- unsigned call_count;
- unsigned refcount;
- server_endpoint *endpoint;
-
- TOA::dsi_handler skeleton;
- void *context;
-
- //
- // Used internally by threaded (and unthreaded) code to
- // dispatch incoming GIOP messages
- //
- void handle_message (
- dispatch_context &context,
- CORBA_Environment &env
- );
+ };
+
+private:
+ friend class ROA_Handler; // needed so it can call handle_message()
+
+ ACE_INET_Addr addr;
+ CORBA_Boolean do_exit;
+ CORBA_ORB_ptr _orb;
+ unsigned call_count;
+ unsigned refcount;
+ ROA_Acceptor clientAcceptor_;
+
+ TOA::dsi_handler skeleton;
+ void* context; // what the hell is this for? --cjc
+
+ //
+ // Used internally by threaded (and unthreaded) code to
+ // dispatch incoming GIOP messages
+ //
+ void handle_message (dispatch_context& context, CORBA_Environment& env);
#ifdef _POSIX_THREADS
- //
- // Used internally by threaded code to process incoming messages.
- //
- static void *worker (void *arg);
+ //
+ // Used internally by threaded code to process incoming messages.
+ //
+ static void* worker(void* arg);
#endif // _POSIX_THREADS
- //
- // Constructor -- build it with a port number to listen to
- //
- TCP_OA (
- CORBA_ORB_ptr orb_arg,
- CORBA_UShort port,
- CORBA_Environment &env
- );
- virtual ~TCP_OA ();
-
- //
- // Copy and assignment: just say no
- //
- TCP_OA (const TCP_OA &src);
- TCP_OA &operator = (const TCP_OA &src);
+ //
+ // Constructor -- build it with a port number to listen to
+ //
+ TCP_OA(CORBA_ORB_ptr orb_arg, ACE_INET_Addr& rendesvous, CORBA_Environment& env);
+ virtual ~TCP_OA();
+
+ //
+ // Copy and assignment: just say no
+ //
+ TCP_OA (const TCP_OA& src);
+ TCP_OA& operator=(const TCP_OA& src);
#if defined (__GNUG__)
- //
- // G++ (even 2.6.3) stupidly thinks instances can't be
- // created. This de-warns.
- //
- friend class everyone_needs_a_friend;
+ //
+ // G++ (even 2.6.3) stupidly thinks instances can't be
+ // created. This de-warns.
+ //
+ friend class everyone_needs_a_friend;
#endif
};
-typedef TCP_OA *TCP_OA_ptr;
+typedef TCP_OA* TCP_OA_ptr;
//
diff --git a/TAO/IIOP/lib/toa.cpp b/TAO/IIOP/lib/toa.cpp
index 7dc95c1368e..956207dcf7c 100644
--- a/TAO/IIOP/lib/toa.cpp
+++ b/TAO/IIOP/lib/toa.cpp
@@ -33,7 +33,7 @@
// protocol modules! This is an implementation shortcut only.
#include "iioporb.hh"
-#include "connmgr.hh"
+#include "connmgr.hh"
#include "tcpoa.hh"
#include <initguid.h>
@@ -130,7 +130,8 @@ TOA::get_toa (
//
// TCP_OA initialization with null name means anonymous OA
//
- tcp_oa = TCP_OA::init (orb, 0, env);
+ ACE_INET_Addr anonymous((unsigned short)0, INADDR_ANY);
+ tcp_oa = TCP_OA::init (orb, anonymous, env);
if (env.exception () != 0)
return 0;
else
diff --git a/TAO/IIOP/lib/toa.hh b/TAO/IIOP/lib/toa.hh
index 635a93444df..9259fe3ca09 100644
--- a/TAO/IIOP/lib/toa.hh
+++ b/TAO/IIOP/lib/toa.hh
@@ -12,6 +12,9 @@
#ifndef _TOA_HH
#define _TOA_HH
+# include "orb.hh"
+# include "corbacom.hh"
+
typedef class TOA *TOA_ptr;
CORBA_Boolean is_nil (TOA_ptr obj);
diff --git a/TAO/IIOP/test/Makefile b/TAO/IIOP/test/Makefile
index 6650e549dec..14a361ade7a 100644
--- a/TAO/IIOP/test/Makefile
+++ b/TAO/IIOP/test/Makefile
@@ -43,7 +43,7 @@ include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU
# Local modifications to variables imported by includes above.
LDFLAGS += -L../proto/lib
-CPPFLAGS += -I../proto/include
+CPPFLAGS += -I../proto/include -DUSE_ACE_EVENT_HANDLING
svr: $(addprefix $(VDIR),$(CUBIT_SVR_OBJS))
$(LINK.cc) $(LDFLAGS) -o $@ $^ $(VLDLIBS)
diff --git a/TAO/IIOP/test/svr.cpp b/TAO/IIOP/test/svr.cpp
index 3e32c4c160e..f0648fa40c3 100644
--- a/TAO/IIOP/test/svr.cpp
+++ b/TAO/IIOP/test/svr.cpp
@@ -192,26 +192,134 @@ tcpoa_forwarder (
//
// Socket-based passive OA entry point
//
+
+
+//
+// Standard command line parsing utilities used.
+//
int
-OA_listen (
- CORBA_ORB_ptr orb_ptr,
- TCP_OA_ptr oa_ptr,
- CORBA_String key,
- int idle,
- CORBA_Boolean do_fork,
- CORBA_Boolean do_threads
+main (
+ int argc,
+ char *argv[]
)
{
+ CORBA_Environment env;
+ CORBA_ORB_ptr orb_ptr;
+ TCP_OA_ptr oa_ptr;
+ CORBA_Boolean do_fork = CORBA_B_FALSE;
+ CORBA_Boolean do_threads = CORBA_B_FALSE;
+ CORBA_String key = (CORBA_String) "key0";
+ char *oa_name = 0;
+ char *orb_name = "internet";
+ int idle = -1;
+
+ //
+ // Parse the command line, get options
+ //
+ ACE_Get_Opt opts (argc, argv, "di:fk:o:p:t");
+ int c;
+
+ while ((c = opts()) != -1)
+ switch (c) {
+ case 'd': // more debug noise
+ debug_level++;
+ continue;
+
+ case 'i': // idle seconds b4 exit
+ idle = ACE_OS::atoi (opts.optarg);
+ continue;
+
+ case 'f': // fork child server
+ do_fork = CORBA_B_TRUE;
+ continue;
+
+ case 'k': // key (str)
+ key = (CORBA_String) opts.optarg;
+ continue;
+
+ case 'o': // orb name
+ orb_name = opts.optarg;
+ continue;
+
+ case 'p': // portnum
+ oa_name = opts.optarg;
+ continue;
+
+ case 't': // create thread-per-request
+ do_threads = CORBA_B_TRUE;
+ continue;
+
+ // XXX set debug filters ...
+
+ //
+ // XXX ignore OMG-specified options ... hope nobody ever tries
+ // to use that "-ORB* param" and "-OA* param" syntax, it flies
+ // in the face of standard command parsing algorithms which
+ // require single-character option specifiers.
+ //
+
+ case '?':
+ default:
+ ACE_OS::fprintf (stderr, "usage: %s"
+ " [-d]"
+ " [-f]"
+ " [-i idle_seconds]"
+ " [-k]"
+ " [-k object_key=key0]"
+ " [-o orb_name=internet]"
+ " [-p portnum=5555]"
+ " [-t]"
+ "\n", argv [0]
+ );
+ return 1;
+ }
+
+ orb_ptr = CORBA_ORB_init (argc, argv, orb_name, env);
+ if (env.exception () != 0) {
+ print_exception (env.exception (), "ORB init");
+ return 1;
+ }
+
+ ACE_INET_Addr svraddr;
+ if (oa_name == 0)
+ svraddr.set((u_short)0, "watusi");
+ else
+ svraddr.set(oa_name);
+
+ oa_ptr = TCP_OA::init (orb_ptr, svraddr, env);
+ if (env.exception () != 0) {
+ print_exception (env.exception (), "OA init");
+ return 1;
+ }
+ // Register the OA with ACE_ROA
+ ACE_ROA::oa(oa_ptr); // Should this be done in TCP_OA's CTOR?
+
+#if 0
+ // This is the old call and syntax
+ return OA_listen (orb_ptr, oa_ptr, key, idle, do_fork, do_threads);
+ int
+ OA_listen (
+ CORBA_ORB_ptr orb_ptr,
+ TCP_OA_ptr oa_ptr,
+ CORBA_String key,
+ int idle,
+ CORBA_Boolean do_fork,
+ CORBA_Boolean do_threads
+ )
+ {
+ return 0;
+ }
+#endif
//
// Create the object we'll be implementing.
//
CORBA_OctetSeq obj_key;
CORBA_Object_ptr obj;
- CORBA_Environment env;
obj_key.buffer = (CORBA_Octet *) key;
obj_key.length = obj_key.maximum = ACE_OS::strlen ((char *)key);
+ env.clear();
obj = oa_ptr->create (obj_key, (CORBA_String) "", env);
if (env.exception () != 0) {
print_exception (env.exception (), "TCP_OA::create");
@@ -286,6 +394,19 @@ OA_listen (
// period (e.g. 10 minutes), and reclaiming the thread used by that
// connection.
//
+ int terminationStatus = 0;
+#if defined(USE_ACE_EVENT_HANDLING)
+ while (ACE_ROA::end_reactor_event_loop_ == 0)
+ {
+ int result = ACE_ROA::reactor()->handle_events ();
+
+ if (result == -1)
+ {
+ terminationStatus = -1;
+ break;
+ }
+ }
+#else
while (oa_ptr->shutting_down () != CORBA_B_TRUE) {
if (idle == -1)
oa_ptr->get_request (tcpoa_dispatch,
@@ -315,107 +436,12 @@ OA_listen (
}
env.clear ();
}
+#endif
//
// Shut down the OA -- recycles all underlying resources (e.g. file
// descriptors, etc).
//
oa_ptr->clean_shutdown (env);
- return 0;
-}
-
-
-//
-// Standard command line parsing utilities used.
-//
-int
-main (
- int argc,
- char *argv[]
-)
-{
- CORBA_Environment env;
- CORBA_ORB_ptr orb_ptr;
- TCP_OA_ptr oa_ptr;
- CORBA_Boolean do_fork = CORBA_B_FALSE;
- CORBA_Boolean do_threads = CORBA_B_FALSE;
- CORBA_String key = (CORBA_String) "key0";
- char *oa_name = 0;
- char *orb_name = "internet";
- int idle = -1;
-
- //
- // Parse the command line, get options
- //
- ACE_Get_Opt opts (argc, argv, "di:fk:o:p:t");
- int c;
-
- while ((c = opts()) != -1)
- switch (c) {
- case 'd': // more debug noise
- debug_level++;
- continue;
-
- case 'i': // idle seconds b4 exit
- idle = ACE_OS::atoi (opts.optarg);
- continue;
-
- case 'f': // fork child server
- do_fork = CORBA_B_TRUE;
- continue;
-
- case 'k': // key (str)
- key = (CORBA_String) opts.optarg;
- continue;
-
- case 'o': // orb name
- orb_name = opts.optarg;
- continue;
-
- case 'p': // portnum
- oa_name = opts.optarg;
- continue;
-
- case 't': // create thread-per-request
- do_threads = CORBA_B_TRUE;
- continue;
-
- // XXX set debug filters ...
-
- //
- // XXX ignore OMG-specified options ... hope nobody ever tries
- // to use that "-ORB* param" and "-OA* param" syntax, it flies
- // in the face of standard command parsing algorithms which
- // require single-character option specifiers.
- //
-
- case '?':
- default:
- ACE_OS::fprintf (stderr, "usage: %s"
- " [-d]"
- " [-f]"
- " [-i idle_seconds]"
- " [-k]"
- " [-k object_key=key0]"
- " [-o orb_name=internet]"
- " [-p portnum=5555]"
- " [-t]"
- "\n", argv [0]
- );
- return 1;
- }
-
- orb_ptr = CORBA_ORB_init (argc, argv, orb_name, env);
- if (env.exception () != 0) {
- print_exception (env.exception (), "ORB init");
- return 1;
- }
-
- oa_ptr = TCP_OA::init (orb_ptr, oa_name, env);
- if (env.exception () != 0) {
- print_exception (env.exception (), "OA init");
- return 1;
- }
-
- return OA_listen (orb_ptr, oa_ptr, key, idle, do_fork, do_threads);
+ return terminationStatus;
}
diff --git a/TAO/IIOP/test/test1_clnt.cpp b/TAO/IIOP/test/test1_clnt.cpp
index 4583818105e..3a3603b5c2c 100644
--- a/TAO/IIOP/test/test1_clnt.cpp
+++ b/TAO/IIOP/test/test1_clnt.cpp
@@ -141,6 +141,21 @@ Type cube (Type arg)
return temp;
}
+#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION)
+#define TEMPLATE_DECL(t) template CORBA_ ## t cube(CORBA_ ## t)
+TEMPLATE_DECL(Octet);
+TEMPLATE_DECL(Short);
+TEMPLATE_DECL(UShort);
+TEMPLATE_DECL(Long);
+TEMPLATE_DECL(ULong);
+TEMPLATE_DECL(LongLong);
+TEMPLATE_DECL(ULongLong);
+TEMPLATE_DECL(Float);
+TEMPLATE_DECL(Double);
+# if !defined(NONNATIVE_LONGDOUBLE)
+TEMPLATE_DECL(LongDouble);
+# endif
+#endif
static int skip_longdouble = 0;
@@ -231,6 +246,7 @@ do_tests (
//
// Boolean -- negation
//
+#undef TEMPLATE_DECL
#define EXPVAL(type,original_value) (!(type)(original_value))
#define COMPARE(type,retval,original_value) \
(((type)(retval)) == EXPVAL(type,original_value))
diff --git a/TAO/IIOP/test/test1_svr.cpp b/TAO/IIOP/test/test1_svr.cpp
index 0531aaa03cb..2a944acc682 100644
--- a/TAO/IIOP/test/test1_svr.cpp
+++ b/TAO/IIOP/test/test1_svr.cpp
@@ -52,6 +52,7 @@ extern char *optarg; // missing on some platforms
// also get a public constructor, and a way to provide the buffer.)
//
#define DEFINE_SKEL3(name,truetype,truetypename) \
+ TEMPLATE_DECL(CORBA_ ## truetype); \
static void \
_test1_test_ ## name ( \
CORBA_ServerRequest &req, \
@@ -142,6 +143,11 @@ Type cube (Type arg)
}
#define OPERATION(n) cube(n)
+#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION)
+# define TEMPLATE_DECL(t) template t cube(t)
+#else
+# define TEMPLATE_DECL(t)
+#endif
DEFINE_SKEL3 (octet, Octet, Octet)
@@ -174,6 +180,8 @@ DEFINE_SKEL3 (longdouble, LongDouble, LongDouble)
// parameters
//
#define OPERATION(x) (!(x))
+#undef TEMPLATE_DECL
+#define TEMPLATE_DECL(t)
DEFINE_SKEL3 (boolean, Boolean, Boolean)
#undef OPERATION