diff options
author | Chris Cleeland <chris.cleeland@gmail.com> | 1997-04-08 02:41:48 +0000 |
---|---|---|
committer | Chris Cleeland <chris.cleeland@gmail.com> | 1997-04-08 02:41:48 +0000 |
commit | c8ac79d552196471aa9f030b1273266a5f518a22 (patch) | |
tree | 736c7e41ba6412b0f343ee6efa5040f02dcf895f | |
parent | c309d4f3c4dbc757a9440662712002d3211a18dd (diff) | |
download | ATCD-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.hh | 3 | ||||
-rw-r--r-- | TAO/IIOP/lib/giop.cpp | 7 | ||||
-rw-r--r-- | TAO/IIOP/lib/invoke.cpp | 2 | ||||
-rw-r--r-- | TAO/IIOP/lib/roa.cpp | 92 | ||||
-rw-r--r-- | TAO/IIOP/lib/roa.hh | 71 | ||||
-rw-r--r-- | TAO/IIOP/lib/roa.i | 13 | ||||
-rw-r--r-- | TAO/IIOP/lib/tcpoa.cpp | 408 | ||||
-rw-r--r-- | TAO/IIOP/lib/tcpoa.hh | 378 | ||||
-rw-r--r-- | TAO/IIOP/lib/toa.cpp | 5 | ||||
-rw-r--r-- | TAO/IIOP/lib/toa.hh | 3 | ||||
-rw-r--r-- | TAO/IIOP/test/Makefile | 2 | ||||
-rw-r--r-- | TAO/IIOP/test/svr.cpp | 236 | ||||
-rw-r--r-- | TAO/IIOP/test/test1_clnt.cpp | 16 | ||||
-rw-r--r-- | TAO/IIOP/test/test1_svr.cpp | 8 |
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 |