diff options
author | iliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2006-10-27 17:05:46 +0000 |
---|---|---|
committer | iliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2006-10-27 17:05:46 +0000 |
commit | fb875df6e3a14036a6e23326f209c4efafa03f72 (patch) | |
tree | ab77aa861a9dfb35a0b7e4b2541f61abd588e492 | |
parent | 8ed2736af78b8e98ef1e01eeb7cddf384c57d1cc (diff) | |
download | ATCD-fb875df6e3a14036a6e23326f209c4efafa03f72.tar.gz |
Importing HEAD changes
32 files changed, 1522 insertions, 131 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 7f3ef65cb48..9d85cd87c03 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,114 @@ +Thu Oct 27 02:53:53 UTC 2006 Ossama Othman <ossama_othman at symantec dot com> + + * tao/GIOP_Message_Base.cpp (parse_request_id): + + Corrected GIOP version check so that the GIOP 1.{0,1} case + doesn't apply to all major versions greater than or equal to + one, i.e. {1,2,3,...,N}.{0,1}. The case in question is only + meant for GIOP 1.0 or 1.1. + +Thu Oct 27 01:59:19 UTC 2006 Ossama Othman <ossama_othman at symantec dot com> + + * tao/GIOP_Message_Base.cpp (parse_request_id): + + Simplified error return logic. Addresses "code not reached" + warning. + + * tao/ORB.cpp (ORB_init): + + Do not pass down the default CORBA::Environment from TSS in the + native C++ exception case. Simply pass a locally instantiated + CORBA::Environment. Removes an unnecessary TSS access. + + * tao/EndpointPolicy/Endpoint_Acceptor_Filter.h: + + Moved TAO_POA_Manager forward declaration into the versioned + namespace. + + * tao/PortableServer/Servant_var.h: + + Removed suggestion of adding an exception specification. + They've fallen out of favor by most C++ gurus. + + * tao/Strategies/advanced_resource.cpp: + * tao/Strategies/advanced_resource.h: + + Added support ACE_Dev_Poll_Reactor. + + * tao/Valuetype/ValueBase.cpp (_tao_write_value_header): + + Fixed Coverity DEADCODE error. + + From Russell Mora <russell_mora at symantec dot com> + * examples/Content_Server/AMI_Iterator/Content_Iterator_i.cpp: + * examples/Content_Server/SMI_Iterator/Content_Iterator_i.cpp: + * tao/Strategies/SHMIOP_Acceptor.cpp: + * tao/Strategies/SHMIOP_Acceptor.h: + * tao/Strategies/SHMIOP_Factory.h: + + Added support for 64-bit file offsets. + + From Duane Binder <duane_binder at symantec dot com> + * TAO_IDL/be/be_helper.cpp: + + Buffer I/O by removing fflush() calls. Greatly improves tao_idl + performance, particularly over networked filesystems. + + * TAO_IDL/be/be_interface.cpp (gen_gperf_lookup_methods): + + Flush the output stream. Gperf also uses it as output. Ensure + current contents are written before gperf writes. + +Thu Oct 26 14:20:12 UTC 2006 Johnny Willemsen <jwillemsen@remedy.nl> + + * orbsvcs/tests/Event/UDP/receiver.cpp: + Register the value factory + + * orbsvcs/tests/Event/UDP/run_test.pl: + Also run the test with a valuetype in the event. + +Thu Oct 26 13:30:12 UTC 2006 Johnny Willemsen <jwillemsen@remedy.nl> + + * orbsvcs/orbsvcs/Event/ECG_CDR_Message_Receiver.cpp: + Reverted the change below. Thew new UDP RTEC test showed + that the consumer was receiving duplicate events without being + able to detect that. So a single send resulted in two events + being received. The original problem needs to be resolved in + a different way because this breaks any assumptions about events + + Mon Aug 21 15:37:23 UTC 2006 Douglas C. Schmidt <schmidt@dre.vanderbilt.edu> + * orbsvcs/orbsvcs/Event/ECG_UDP_Out_Endpoint.i: + * orbsvcs/orbsvcs/Event/ECG_CDR_Message_Receiver.cpp: Made the + simplest fix to the problem where if a UDP RTEC supplier + restarts while the consumer is still running, it gets duplicate + fragment errors. The cost of this fix is that duplicate + completed requests are no longer detected. Thanks to Keith + Nicewarner for these fixes. + +Thu Oct 26 12:54:12 UTC 2006 Johnny Willemsen <jwillemsen@remedy.nl> + + * orbsvcs/orbsvcs/Event/ECG_CDR_Message_Sender.cpp: + * orbsvcs/orbsvcs/Event/ECG_Mcast_EH.cpp: + Const improvements + +Thu Oct 26 10:53:12 UTC 2006 Johnny Willemsen <jwillemsen@remedy.nl> + + * orbsvcs/tests/Event/UDP/*: + New regression test for the RTEC using UDP federations. By default + we just send the string ACE/TAO/CIAO in the Any and this works, but + when -v is passed to the run_test.pl we send a valuetype which + contains the string. With the current svn head version of today + this fails because on the receiver side we can't extract the valuetype + out of the Any + +Wed Oct 25 15:33:27 UTC 2006 Chad Elliott <elliott_c@ociweb.com> + + * tao/PortableServer/Root_POA.cpp: + + My change from Mon Oct 23 12:24:57 UTC 2006 uncovered yet another + reference counting problem. The TAO_Root_POA was not manipulating + the reference count of the TAO_POA_Manager that it held. + Mon Oct 23 12:24:57 UTC 2006 Chad Elliott <elliott_c@ociweb.com> * tao/PortableServer/Object_Adapter.h: @@ -102,14 +213,14 @@ Mon Oct 16 21:16:14 UTC 2006 Phil Mesnier <mesnier_p@ociweb.com> Mon Oct 16 10:59:12 UTC 2006 Johnny Willemsen <jwillemsen@remedy.nl> - * tests/Nested_Upcall_Crash/run_test.pl: - Check whether we could spawn the server, if not, give an error - and exit directly. + * tests/Nested_Upcall_Crash/run_test.pl: + Check whether we could spawn the server, if not, give an error + and exit directly. Mon Oct 16 08:43:12 UTC 2006 Johnny Willemsen <jwillemsen@remedy.nl> - * TAO_IDL/be/be_codegen.cpp: - Const changes + * TAO_IDL/be/be_codegen.cpp: + Const changes Sun Oct 15 23:23:53 UTC 2006 Phil Mesnier <mesnier_p@ociweb.com> @@ -132,15 +243,12 @@ Sun Oct 15 23:23:53 UTC 2006 Phil Mesnier <mesnier_p@ociweb.com> forces the race condition. Adding a small sleep along with the above fix demonstrates that the problem no longer occurs. - Thanks to Chris Reed, cr at progress dot com, for reporting this - bug. - Fri Oct 13 10:28:12 2006 Johnny Willemsen <jwillemsen@remedy.nl> - * tests/COIOP/*: - Extended this test so that we check whether a call should - succeed or not. This test requires that COIOP is the only - pluggable protocol available. + * tests/COIOP/*: + Extended this test so that we check whether a call should + succeed or not. This test requires that COIOP is the only + pluggable protocol available. Thu Oct 12 14:17:11 UTC 2006 Chad Elliott <elliott_c@ociweb.com> diff --git a/TAO/TAO_IDL/be/be_helper.cpp b/TAO/TAO_IDL/be/be_helper.cpp index 65a0a7cc4b4..3dda75f097f 100644 --- a/TAO/TAO_IDL/be/be_helper.cpp +++ b/TAO/TAO_IDL/be/be_helper.cpp @@ -154,8 +154,6 @@ TAO_OutStream::open (const char *fname, ACE_OS::fprintf (this->fp_, "%s\n", copyright); - - ACE_OS::fflush (this->fp_); } return 0; @@ -248,9 +246,6 @@ TAO_OutStream::indent (void) for (int i = 0; i < this->indent_level_; i++) { ACE_OS::fprintf (this->fp_, " "); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif } } @@ -351,9 +346,6 @@ TAO_OutStream::print (const char *format, ...) int, -1, result); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif va_end (ap); return result; @@ -363,9 +355,6 @@ TAO_OutStream & TAO_OutStream::operator<< (const char *str) { ACE_OS::fprintf (this->fp_, "%s", str); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif return *this; } @@ -376,10 +365,6 @@ TAO_OutStream::operator<< (const ACE_CDR::UShort num) "%hu", num); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif - return *this; } @@ -390,10 +375,6 @@ TAO_OutStream::operator<< (const ACE_CDR::Short num) "%hd", num); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif - return *this; } @@ -404,10 +385,6 @@ TAO_OutStream::operator<< (const ACE_CDR::ULong num) "%lu", (unsigned long) num); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif - return *this; } @@ -418,10 +395,6 @@ TAO_OutStream::operator<< (const ACE_CDR::Long num) "%ld", (long) num); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif - return *this; } @@ -433,10 +406,6 @@ TAO_OutStream::operator<< (const ACE_CDR::ULongLong num) ACE_UINT64_FORMAT_SPECIFIER, num); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif - return *this; } @@ -447,10 +416,6 @@ TAO_OutStream::operator<< (const ACE_CDR::LongLong num) ACE_INT64_FORMAT_SPECIFIER, num); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif - return *this; } #endif /* ACE_WIN64 */ @@ -462,10 +427,6 @@ TAO_OutStream::operator<< (const unsigned long num) "%lu", num); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif - return *this; } @@ -476,10 +437,6 @@ TAO_OutStream::operator<< (const long num) "%ld", num); -#if !defined (ACE_OPENVMS) - ACE_OS::fflush (this->fp_); -#endif - return *this; } diff --git a/TAO/TAO_IDL/be/be_interface.cpp b/TAO/TAO_IDL/be/be_interface.cpp index 511abe72f82..6fc79e08fe7 100644 --- a/TAO/TAO_IDL/be/be_interface.cpp +++ b/TAO/TAO_IDL/be/be_interface.cpp @@ -476,12 +476,10 @@ be_interface::redefine (AST_Interface *from) void be_interface::gen_def_ctors (TAO_OutStream *os) { - this->traverse_inheritance_graph ( + (void) this->traverse_inheritance_graph ( be_interface::gen_def_ctors_helper, os ); - - return; } @@ -1673,6 +1671,12 @@ be_interface::gen_gperf_lookup_methods (const char *flat_name) -1); } +#ifndef ACE_OPENVMS + // Flush the output stream. Gperf also uses it as output. Ensure + // current contents are written before gperf writes. + ACE_OS::fflush (this->strategy_->get_out_stream ()->file ()); +#endif /* !ACE_OPENVMS */ + // Stdout is server skeleton. Do *not* close the file, just open // again with <ACE_OS::open> with WRITE + APPEND option.. After // this, remember to update the file offset to the correct location. diff --git a/TAO/examples/Content_Server/AMI_Iterator/Content_Iterator_i.cpp b/TAO/examples/Content_Server/AMI_Iterator/Content_Iterator_i.cpp index 5f3f76cb9ba..3f8da6650f6 100644 --- a/TAO/examples/Content_Server/AMI_Iterator/Content_Iterator_i.cpp +++ b/TAO/examples/Content_Server/AMI_Iterator/Content_Iterator_i.cpp @@ -36,12 +36,12 @@ Content_Iterator_i::next_chunk (CORBA::ULongLong offset, if (offset >= this->file_size_) return false; // Applications shouldn't throw system exceptions. - off_t real_offset = + ACE_OFF_T real_offset = ACE_OS::lseek (this->file_io_.get_handle (), offset, SEEK_SET); - if (real_offset == (off_t) -1) + if (real_offset == static_cast<ACE_OFF_T> (-1)) // Invalid supplied offset? ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), diff --git a/TAO/examples/Content_Server/SMI_Iterator/Content_Iterator_i.cpp b/TAO/examples/Content_Server/SMI_Iterator/Content_Iterator_i.cpp index d5bab7f1ef8..1b32514882c 100644 --- a/TAO/examples/Content_Server/SMI_Iterator/Content_Iterator_i.cpp +++ b/TAO/examples/Content_Server/SMI_Iterator/Content_Iterator_i.cpp @@ -43,12 +43,12 @@ Content_Iterator_i::next_chunk (CORBA::ULongLong offset, if (offset >= this->file_size_) return 0; // Applications shouldn't throw system exceptions. - off_t real_offset = + ACE_OFF_T real_offset = ACE_OS::lseek (this->file_io_.get_handle (), offset, SEEK_SET); - if (real_offset == (off_t) -1) + if (real_offset == static_cast<ACE_OFF_T> (-1)) { // Invalid supplied offset? diff --git a/TAO/orbsvcs/orbsvcs/Event/ECG_CDR_Message_Receiver.cpp b/TAO/orbsvcs/orbsvcs/Event/ECG_CDR_Message_Receiver.cpp index 1195f10bba4..31e779720b7 100644 --- a/TAO/orbsvcs/orbsvcs/Event/ECG_CDR_Message_Receiver.cpp +++ b/TAO/orbsvcs/orbsvcs/Event/ECG_CDR_Message_Receiver.cpp @@ -392,7 +392,7 @@ TAO_ECG_CDR_Message_Receiver::mark_received (const ACE_INET_Addr &from, -1); } - *request = 0; + *request = &Request_Completed_; return 1; } @@ -476,7 +476,7 @@ TAO_ECG_CDR_Message_Receiver::process_fragment ( return -1; delete *request; - *request = 0; + *request = &Request_Completed_; return 1; } diff --git a/TAO/orbsvcs/orbsvcs/Event/ECG_CDR_Message_Sender.cpp b/TAO/orbsvcs/orbsvcs/Event/ECG_CDR_Message_Sender.cpp index 6a6492dd90c..7ab74bdf599 100644 --- a/TAO/orbsvcs/orbsvcs/Event/ECG_CDR_Message_Sender.cpp +++ b/TAO/orbsvcs/orbsvcs/Event/ECG_CDR_Message_Sender.cpp @@ -257,7 +257,7 @@ TAO_ECG_CDR_Message_Sender::send_fragment (const ACE_INET_Addr &addr, expected_n += iov[i].iov_len; if (n > 0 && size_t(n) != expected_n) { - ACE_DEBUG ((LM_ERROR, ("Sent only %d out of %d bytes " + ACE_ERROR ((LM_ERROR, ("Sent only %d out of %d bytes " "for mcast fragment.\n"), n, expected_n)); @@ -267,7 +267,7 @@ TAO_ECG_CDR_Message_Sender::send_fragment (const ACE_INET_Addr &addr, { if (errno == EWOULDBLOCK) { - ACE_DEBUG ((LM_ERROR, "Send of mcast fragment failed (%m).\n")); + ACE_ERROR ((LM_ERROR, "Send of mcast fragment failed (%m).\n")); // @@ TODO Use a Event Channel specific exception ACE_THROW (CORBA::COMM_FAILURE ()); } diff --git a/TAO/orbsvcs/orbsvcs/Event/ECG_Mcast_EH.cpp b/TAO/orbsvcs/orbsvcs/Event/ECG_Mcast_EH.cpp index ed3acdc46f9..9c4851c70c1 100644 --- a/TAO/orbsvcs/orbsvcs/Event/ECG_Mcast_EH.cpp +++ b/TAO/orbsvcs/orbsvcs/Event/ECG_Mcast_EH.cpp @@ -105,7 +105,7 @@ TAO_ECG_Mcast_EH::shutdown (void) this->receiver_ = 0; // Deregister from reactor, close and clean up sockets. - size_t subscriptions_size = this->subscriptions_.size (); + size_t const subscriptions_size = this->subscriptions_.size (); for (size_t i = 0; i != subscriptions_size; ++i) { (void) this->reactor ()->remove_handler ( @@ -122,7 +122,7 @@ TAO_ECG_Mcast_EH::shutdown (void) int TAO_ECG_Mcast_EH::handle_input (ACE_HANDLE fd) { - size_t subscriptions_size = this->subscriptions_.size (); + size_t const subscriptions_size = this->subscriptions_.size (); for (size_t i = 0; i != subscriptions_size; ++i) { ACE_SOCK_Dgram_Mcast *socket = this->subscriptions_[i].dgram; @@ -225,7 +225,7 @@ TAO_ECG_Mcast_EH::add_new_subscriptions (Address_Set& multicast_addresses) new_subscription.mcast_addr = *k; ACE_NEW (new_subscription.dgram, ACE_SOCK_Dgram_Mcast); - size_t subscriptions_size = this->subscriptions_.size (); + size_t const subscriptions_size = this->subscriptions_.size (); this->subscriptions_.size (subscriptions_size + 1); this->subscriptions_[subscriptions_size] = new_subscription; diff --git a/TAO/orbsvcs/tests/Event/UDP/AddrServer.cpp b/TAO/orbsvcs/tests/Event/UDP/AddrServer.cpp new file mode 100644 index 00000000000..05fd4d9c983 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/AddrServer.cpp @@ -0,0 +1,19 @@ +// $Id$ + +#include "AddrServer.h" + +ACE_RCSID(EC_Examples, AddrServer, "$Id$") + +AddrServer::AddrServer (const RtecUDPAdmin::UDP_Addr& addr) + : addr_ (addr) +{ +} + +void +AddrServer::get_addr (const RtecEventComm::EventHeader&, + RtecUDPAdmin::UDP_Addr_out addr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + addr = this->addr_; +} diff --git a/TAO/orbsvcs/tests/Event/UDP/AddrServer.h b/TAO/orbsvcs/tests/Event/UDP/AddrServer.h new file mode 100644 index 00000000000..8439914f22b --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/AddrServer.h @@ -0,0 +1,53 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Consumer +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef ADDRSERVER_H +#define ADDRSERVER_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/RtecUDPAdminS.h" + +class AddrServer : public POA_RtecUDPAdmin::AddrServer +{ + // = TITLE + // A simple AddrServer + // + // = DESCRIPTION + // The EC is able to use multiple multicast groups to transmit its + // data, the is given control over the mapping between the Event + // (type,source) pair and the (ipaddr,port) pair using a + // AddrServer. + // This class implements a very simple server that simply maps the + // <type> component to the <ipaddr> and uses a fixed <port>, + // provided at initialization time. + // +public: + AddrServer (const RtecUDPAdmin::UDP_Addr& addr); + // Constructor + + // = The RtecUDPAdmin::AddrServer methods + virtual void get_addr (const RtecEventComm::EventHeader& header, + RtecUDPAdmin::UDP_Addr_out addr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + RtecUDPAdmin::UDP_Addr addr_; + // The address +}; + +#include /**/ "ace/post.h" +#endif /* ADDRSERVER_H */ diff --git a/TAO/orbsvcs/tests/Event/UDP/Consumer.cpp b/TAO/orbsvcs/tests/Event/UDP/Consumer.cpp new file mode 100644 index 00000000000..efdc33730e2 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/Consumer.cpp @@ -0,0 +1,149 @@ +// $Id$ + +#include "Consumer.h" +#include "orbsvcs/RtecEventChannelAdminS.h" +#include "orbsvcs/Event_Service_Constants.h" + +#include "TestC.h" + +ACE_RCSID (EC_Examples, + Consumer, + "$Id$") + +Consumer::Consumer (bool valuetype) + : event_count_ (0), + valuetype_ (valuetype) +{ +} + +CORBA::ULong +Consumer::event_count (void) const +{ + return this->event_count_; +} + +void +Consumer::connect (RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin + ACE_ENV_ARG_DECL) +{ + this->proxy_ = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + RtecEventComm::PushConsumer_var me = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Simple subscription, but usually the helper classes in + // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this. + RtecEventChannelAdmin::ConsumerQOS qos; + qos.is_gateway = 0; + + qos.dependencies.length (2); + RtecEventComm::EventHeader& h0 = + qos.dependencies[0].event.header; + h0.type = ACE_ES_DISJUNCTION_DESIGNATOR; + h0.source = 1; // The disjunction has one element + + RtecEventComm::EventHeader& h1 = + qos.dependencies[1].event.header; + h1.type = ACE_ES_EVENT_UNDEFINED; // first free event type + h1.source = ACE_ES_EVENT_SOURCE_ANY; // Any source is OK + + this->proxy_->connect_push_consumer (me.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_TRY + { + // Disconnect from the proxy + this->proxy_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // Ignore exceptions + } + ACE_ENDTRY; + this->proxy_ = RtecEventChannelAdmin::ProxyPushSupplier::_nil (); + + // Deactivate this object + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + // Get the Object Id used for the servant.. + PortableServer::ObjectId_var oid = + poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + // Deactivate the object + poa->deactivate_object (oid.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer::push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (events.length () == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t) no events\n")); + return; + } + + for (size_t i = 0; i < events.length (); ++i) + { + ++this->event_count_; + + if (this->valuetype_) + { + ValueTypeData * test_data = 0; + if (events[i].data.any_value >>= test_data) + { + ACE_DEBUG ((LM_DEBUG, "Consumer (%P|%t): Received message <%d>: %s\n", + events[i].header.source, test_data->data ())); + if (ACE_OS::strcmp (test_data->data (), "ACE/TAO/CIAO") != 0) + { + ACE_ERROR ((LM_ERROR, "Consumer (%P|%t): ERROR received not expected message\n")); + } + } + else + { + ACE_ERROR ((LM_ERROR, "Consumer (%P|%t): ERROR failed to extract valuetype data\n")); + } + } + else + { + const char* mystring = 0; + if (events[i].data.any_value >>= mystring) + { + ACE_DEBUG ((LM_DEBUG, "Consumer (%P|%t): Received message <%d>: %s\n", + events[i].header.source, mystring)); + if (ACE_OS::strcmp (mystring, "ACE/TAO/CIAO") != 0) + { + ACE_ERROR ((LM_ERROR, "Consumer (%P|%t): ERROR received not expected message\n")); + } + } + else + { + ACE_ERROR ((LM_ERROR, "Consumer (%P|%t): ERROR failed to extract string data\n")); + } + } + } + + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t): %d events received\n", + this->event_count_)); +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/tests/Event/UDP/Consumer.h b/TAO/orbsvcs/tests/Event/UDP/Consumer.h new file mode 100644 index 00000000000..84de97e1df1 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/Consumer.h @@ -0,0 +1,67 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Consumer +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef CONSUMER_H +#define CONSUMER_H + +#include "orbsvcs/RtecEventCommS.h" +#include "orbsvcs/RtecEventChannelAdminC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Consumer : public POA_RtecEventComm::PushConsumer +{ + // = TITLE + // Simple consumer object + // + // = DESCRIPTION + // This class is a consumer of events. + // It simply subscribes to one event type. + // +public: + Consumer (bool valuetype); + // Constructor + + void connect (RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin + ACE_ENV_ARG_DECL); + // Connect to the Event Channel + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the event channel + + // = The RtecEventComm::PushConsumer methods + + virtual void push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + + CORBA::ULong event_count (void) const; +private: + CORBA::ULong event_count_; + // Keep track of the number of events received. + + RtecEventChannelAdmin::ProxyPushSupplier_var proxy_; + // The proxy + + bool valuetype_; +}; + +#endif /* CONSUMER_H */ diff --git a/TAO/orbsvcs/tests/Event/UDP/README b/TAO/orbsvcs/tests/Event/UDP/README new file mode 100644 index 00000000000..55aad804e20 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/README @@ -0,0 +1,26 @@ +# $Id$ + + This directory contains a very simple example of a +multicast-based federation of event services. + + The example is a single process that contains: + +1) An event service +2) A supplier +3) A consumer +4) The gateways required to send and receive data through the + multicast group. + + The tests should be executed as follows: + +$ MCast + + If you need to set the multicast group and port you can use +the -m option: + +$ MCast -m 224.100.2.1:12345 + + Run the test in multiple machines on the same network. If +there is only one process you should only receive 1000 events in the +local consumer. If there is more than one machine you should receive +more events. diff --git a/TAO/orbsvcs/tests/Event/UDP/RtEC_UDP.mpc b/TAO/orbsvcs/tests/Event/UDP/RtEC_UDP.mpc new file mode 100644 index 00000000000..caf503219e2 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/RtEC_UDP.mpc @@ -0,0 +1,26 @@ +// -*- MPC -*- +// $Id$ + +project (* sender): orbsvcsexe, rtevent_serv, rtsched { + exename = sender + Source_Files { + AddrServer.cpp + Supplier.cpp + sender.cpp + } + IDL_Files { + Test.idl + } +} + +project (* receiver) : orbsvcsexe, rtevent_serv, rtsched { + exename = receiver + Source_Files { + AddrServer.cpp + Consumer.cpp + receiver.cpp + } + IDL_Files { + Test.idl + } +} diff --git a/TAO/orbsvcs/tests/Event/UDP/Supplier.cpp b/TAO/orbsvcs/tests/Event/UDP/Supplier.cpp new file mode 100644 index 00000000000..9a1888df558 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/Supplier.cpp @@ -0,0 +1,110 @@ +// $Id$ + +#include "Supplier.h" +#include "orbsvcs/RtecEventChannelAdminS.h" +#include "orbsvcs/Event_Service_Constants.h" + +#include "TestC.h" + +ACE_RCSID (EC_Examples, + Supplier, + "$Id$") + +Supplier::Supplier (bool valuetype) : valuetype_ (valuetype), event_count_ (0) +{ +} + +void +Supplier::connect (RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin + ACE_ENV_ARG_DECL) +{ + this->proxy_ = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + RtecEventComm::PushSupplier_var me = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Simple publication, but usually the helper classes in + // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this. + RtecEventChannelAdmin::SupplierQOS qos; + qos.is_gateway = 0; + + qos.publications.length (1); + RtecEventComm::EventHeader& h0 = + qos.publications[0].event.header; + h0.type = ACE_ES_EVENT_UNDEFINED; // first free event type + h0.source = 1; // first free event source + + this->proxy_->connect_push_supplier (me.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + // Disconnect from the EC + ACE_TRY + { + this->proxy_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + } + ACE_ENDTRY; + + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + PortableServer::ObjectId_var id = + poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::perform_push (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_TRY + { + // The event type and source must match our publications + ++event_count_; + ACE_DEBUG ((LM_DEBUG, "Sending event %d\n", event_count_)); + RtecEventComm::EventSet event (1); + event.length (1); + event[0].header.type = ACE_ES_EVENT_UNDEFINED; + event[0].header.source = event_count_; + // Avoid loops throught the event channel federations + event[0].header.ttl = 1; + + if (this->valuetype_) + { + OBV_ValueTypeData * test_data = 0; + ACE_NEW (test_data, OBV_ValueTypeData ()); + test_data->data ("ACE/TAO/CIAO"); + event[0].data.any_value <<= test_data; + } + else + { + event[0].data.any_value <<= CORBA::string_dup( "ACE/TAO/CIAO"); + } + + this->proxy_->push (event ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + } + ACE_ENDTRY; +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/tests/Event/UDP/Supplier.h b/TAO/orbsvcs/tests/Event/UDP/Supplier.h new file mode 100644 index 00000000000..eae15e57257 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/Supplier.h @@ -0,0 +1,66 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Supplier +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef SUPPLIER_H +#define SUPPLIER_H + +#include "orbsvcs/RtecEventCommS.h" +#include "orbsvcs/RtecEventChannelAdminC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Supplier : public POA_RtecEventComm::PushSupplier +{ + // = TITLE + // Simple supplier object + // + // = DESCRIPTION + // This class is a supplier of events. + // It simply publishes one event type, when the perform_push() + // method is invoked it pushes the event through the event service + // +public: + Supplier (bool valuetype); + // Constructor + + void connect (RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin + ACE_ENV_ARG_DECL); + // Connect to the event channel + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the event channel + + void perform_push (ACE_ENV_SINGLE_ARG_DECL); + // Push a single event + + // = The RtecEventComm::PushSupplier methods + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + RtecEventChannelAdmin::ProxyPushConsumer_var proxy_; + // The proxy + + bool valuetype_; + + CORBA::ULong event_count_; +}; + +#endif /* SUPPLIER_H */ diff --git a/TAO/orbsvcs/tests/Event/UDP/Test.idl b/TAO/orbsvcs/tests/Event/UDP/Test.idl new file mode 100644 index 00000000000..fc7e50d4fd2 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/Test.idl @@ -0,0 +1,11 @@ +//$Id$: + +#ifndef TAO_RTEC_MCAST_TEST_IDL +#define TAO_RTEC_MCAST_TEST_IDL + +valuetype ValueTypeData +{ + public string data; +}; + +#endif /* TAO_RTEC_MCAST_TEST_IDL */ diff --git a/TAO/orbsvcs/tests/Event/UDP/receiver.cpp b/TAO/orbsvcs/tests/Event/UDP/receiver.cpp new file mode 100644 index 00000000000..3a6906100b6 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/receiver.cpp @@ -0,0 +1,366 @@ +// $Id$ + + +#include "Consumer.h" +#include "AddrServer.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/Event/EC_Event_Channel.h" +#include "orbsvcs/Event/EC_Default_Factory.h" +#include "orbsvcs/Event/ECG_Mcast_EH.h" +#include "orbsvcs/Event/ECG_UDP_Receiver.h" +#include "orbsvcs/Event/ECG_UDP_Out_Endpoint.h" +#include "tao/ORB_Core.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_unistd.h" +#include "TestC.h" + +ACE_RCSID (EC_Examples, + MCast, + "$Id$") + +const char *udp_mcast_address = + ACE_DEFAULT_MULTICAST_ADDR ":10001"; +bool valuetype = false; + +int parse_args (int argc, char *argv[]); + +int +main (int argc, char* argv[]) +{ + // Register the default factory in the Service Configurator. + // If your platform supports static constructors then you can + // simply using the ACE_STATIC_SVC_DEFINE() macro, unfortunately TAO + // must run on platforms where static constructors do not work well, + // so we have to explicitly invoke this function. + TAO_EC_Default_Factory::init_svcs (); + + // The exception macros are described in $ACE_ROOT/docs/exceptions.html + // and defined in $ACE_ROOT/ace/CORBA_macros.h. + // If your platform supports native exceptions, and TAO was compiled + // with native exception support then you can simply use try/catch + // and avoid the ACE_ENV_SINGLE_ARG_PARAMETER argument. + // Unfortunately many embedded systems cannot use exceptions due to + // the space and time overhead. + // + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // **************** HERE STARTS THE ORB SETUP + + // Create the ORB, pass the argv list for parsing. + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Parse the arguments, you usually want to do this after + // invoking ORB_init() because ORB_init() will remove all the + // -ORB options from the command line. + if (parse_args (argc, argv) == -1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Service [-m udp_mcast_addr]\n")); + return 1; + } + + if (valuetype) + { + ValueTypeData_init *vb_factory = 0; + ACE_NEW_RETURN (vb_factory, + ValueTypeData_init, + 1); // supplied by mapping + + orb->register_value_factory (vb_factory->tao_repository_id (), + vb_factory + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + vb_factory->_remove_ref (); // release ownership + } + + // This is the standard code to get access to the POA and + // activate it. + // The POA starts in the holding state, if it is not activated + // it will not process any requests. + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETS THE ORB SETUP + + // **************** HERE START THE LOCAL EVENT CHANNEL SETUP + + // This structure is used to define the startup time event + // channel configuration. + // This structure is described in + // + // $TAO_ROOT/docs/ec_options.html + // + TAO_EC_Event_Channel_Attributes attributes (poa.in (), + poa.in ()); + + // Create the Event Channel implementation class + TAO_EC_Event_Channel ec_impl (attributes); + + // Activate the Event Channel, depending on the configuration + // that may involve creating some threads. + // But it should always be invoked because several internal data + // structures are initialized at that point. + ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The event channel is activated as any other CORBA servant. + // In this case we use the simple implicit activation with the + // RootPOA + RtecEventChannelAdmin::EventChannel_var event_channel = + ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE LOCAL EVENT CHANNEL SETUP + + // **************** HERE STARTS THE FEDERATION SETUP + + // The next step is to setup the multicast gateways. + // There are two gateways involved, one sends the locally + // generated events to the federated peers, the second gateway + // receives multicast traffic and turns it into local events. + + // The sender requires a helper object to select what + // multicast group will carry what traffic, this is the + // so-called 'Address Server'. + // The intention is that advanced applications can use different + // multicast groups for different events, this can exploit + // network interfaces that filter unwanted multicast traffic. + // The helper object is accessed through an IDL interface, so it + // can reside remotely. + // In this example, and in many application, using a fixed + // multicast group is enough, and a local address server is the + // right approach. + + // First we convert the string into an INET address, then we + // convert that into the right IDL structure: + ACE_INET_Addr udp_addr (udp_mcast_address); + ACE_DEBUG ((LM_DEBUG, + "udp mcast address is: %s\n", + udp_mcast_address)); + RtecUDPAdmin::UDP_Addr addr; + addr.ipaddr = udp_addr.get_ip_address (); + addr.port = udp_addr.get_port_number (); + + // Now we create and activate the servant + AddrServer as_impl (addr); + RtecUDPAdmin::AddrServer_var address_server = + as_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + TAO_ECG_Refcounted_Endpoint endpoint(new TAO_ECG_UDP_Out_Endpoint); + + // Now we connect the sender as a consumer of events, it will + // receive any event from any source and send it to the "right" + // multicast group, as defined by the address server set above: + RtecEventChannelAdmin::ConsumerQOS sub; + sub.is_gateway = 1; + + sub.dependencies.length (1); + sub.dependencies[0].event.header.type = + ACE_ES_EVENT_ANY; // first free event type + sub.dependencies[0].event.header.source = + ACE_ES_EVENT_SOURCE_ANY; // Any source is OK + + // To receive events we need to setup an event handler: + TAO_EC_Servant_Var<TAO_ECG_UDP_Receiver> receiver = TAO_ECG_UDP_Receiver::create(); + TAO_ECG_Mcast_EH mcast_eh (&(*receiver)); + + // The event handler uses the ORB reactor to wait for multicast + // traffic: + mcast_eh.reactor (orb->orb_core ()->reactor ()); + + // The multicast Event Handler needs to know to what multicast + // groups it should listen to. To do so it becomes an observer + // with the event channel, to determine the list of events + // required by all the local consumer. + // Then it register for the multicast groups that carry those + // events: + mcast_eh.open (event_channel.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Again the receiver connects to the event channel as a + // supplier of events, using the Observer features to detect + // local consumers and their interests: + receiver->init (event_channel.in (), + endpoint, + address_server.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The Receiver is also a supplier of events. The exact type of + // events is only known to the application, because it depends + // on the traffic carried by all the multicast groups that the + // different event handlers subscribe to. + // In this example we choose to simply describe our publications + // using wilcards, any event from any source. More advanced + // application could use the Observer features in the event + // channel to update this information (and reduce the number of + // multicast groups that each receive subscribes to). + // In a future version the event channel could perform some of + // those tasks automatically + RtecEventChannelAdmin::SupplierQOS pub; + pub.publications.length (1); + pub.publications[0].event.header.type = ACE_ES_EVENT_ANY; + pub.publications[0].event.header.source = ACE_ES_EVENT_SOURCE_ANY; + pub.is_gateway = 1; + + receiver->connect (pub ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE FEDERATION SETUP + + // **************** HERE STARTS THE CLIENT SETUP + + // First let us create a consumer and connect it to the event + // channel + Consumer consumer (valuetype); + RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = + event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + consumer.connect (consumer_admin.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE CLIENT SETUP + + // **************** HERE STARTS THE EVENT LOOP + + // Wait for events, including incoming multicast data. + // We could also use orb->run(), but that will not let us + // terminate the application in a nice way. + for (int i = 0; i != 100; ++i) + { + CORBA::Boolean there_is_work = + orb->work_pending (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + if (there_is_work) + { + // We use a TAO extension. The CORBA mechanism does not + // provide any decent way to control the duration of + // perform_work() or work_pending(), so just calling + // them results in a spin loop. + ACE_Time_Value tv (0, 50000); + orb->perform_work (tv ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_Time_Value tv (0, 100000); + ACE_OS::sleep (tv); + if (consumer.event_count () == 25) + { + break; + } + } + + // **************** THAT COMPLETES THE EVENT LOOP + + // **************** HERE STARTS THE CLEANUP CODE + + consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Now let us close the Receiver + receiver->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + int const r = mcast_eh.shutdown (); + + if (r == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Closing MCast event handler\n"), 1); + } + + // The event channel must be destroyed, so it can release its + // resources, and inform all the clients that are still + // connected that it is going away. + event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Deactivating the event channel implementation is not strictly + // required, the POA will do it for us, but it is good manners: + { + // Using _this() activates with the default POA, we must gain + // access to that POA to deactivate the object. + // Notice that we 'know' that the default POA for this servant + // is the root POA, but the code is more robust if we don't + // rely on that. + PortableServer::POA_var poa = + ec_impl._default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + // Get the Object Id used for the servant.. + PortableServer::ObjectId_var oid = + poa->servant_to_id (&ec_impl ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + // Deactivate the object + poa->deactivate_object (oid.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + // Now we can destroy the POA, the flags mean that we want to + // wait until the POA is really destroyed + poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Finally destroy the ORB + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE CLEANUP CODE + + ACE_DEBUG ((LM_DEBUG, + "UDP receiver ready\n")); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +// **************************************************************** + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "vm:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'm': + udp_mcast_address = get_opts.opt_arg (); + break; + + case 'v': + valuetype = true; + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "[-m udp_mcast_address]" + "[-v]" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/tests/Event/UDP/run_test.pl b/TAO/orbsvcs/tests/Event/UDP/run_test.pl new file mode 100755 index 00000000000..6b81e5ca083 --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/run_test.pl @@ -0,0 +1,70 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; + +$status = 0; + +$S1 = new PerlACE::Process ("sender", + ""); +$R1 = new PerlACE::Process ("receiver", + ""); +$S2 = new PerlACE::Process ("sender", + "-v"); +$R2 = new PerlACE::Process ("receiver", + "-v"); + +print STDOUT "Starting receiver with plain text\n"; +$R1->Spawn (); + +sleep 1; + +print STDOUT "Starting sender with plain text\n"; +$S1->Spawn (); + +sleep 1; + +$consumer = $S1->WaitKill (150); + +if ($consumer != 0) { + print STDERR "ERROR: consumer returned $consumer\n"; + $status = 1; +} + +$receiver = $R1->WaitKill (150); + +if ($receiver != 0) { + print STDERR "ERROR: receiver returned $receiver\n"; + $status = 1; +} + +print STDOUT "Starting receiver with valuetype\n"; +$R2->Spawn (); + +sleep 1; + +print STDOUT "Starting sender with valuetype\n"; +$S2->Spawn (); + +sleep 1; + +$consumer2 = $S2->WaitKill (150); + +if ($consumer2 != 0) { + print STDERR "ERROR: consumer returned $consumer2\n"; + $status = 1; +} + +$receiver2 = $R2->WaitKill (150); + +if ($receiver2 != 0) { + print STDERR "ERROR: receiver returned $receiver2\n"; + $status = 1; +} + +exit $status; diff --git a/TAO/orbsvcs/tests/Event/UDP/sender.cpp b/TAO/orbsvcs/tests/Event/UDP/sender.cpp new file mode 100644 index 00000000000..07d00c02a6a --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/sender.cpp @@ -0,0 +1,312 @@ +// $Id$ + + +#include "Supplier.h" +#include "AddrServer.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/Event/EC_Event_Channel.h" +#include "orbsvcs/Event/EC_Default_Factory.h" +#include "orbsvcs/Event/ECG_Mcast_EH.h" +#include "orbsvcs/Event/ECG_UDP_Sender.h" +#include "orbsvcs/Event/ECG_UDP_Out_Endpoint.h" +#include "tao/ORB_Core.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID (EC_Examples, + MCast, + "$Id$") + +const char *udp_mcast_address = + ACE_DEFAULT_MULTICAST_ADDR ":10001"; +bool valuetype = false; + +int parse_args (int argc, char *argv[]); + +int +main (int argc, char* argv[]) +{ + // Register the default factory in the Service Configurator. + // If your platform supports static constructors then you can + // simply using the ACE_STATIC_SVC_DEFINE() macro, unfortunately TAO + // must run on platforms where static constructors do not work well, + // so we have to explicitly invoke this function. + TAO_EC_Default_Factory::init_svcs (); + + // The exception macros are described in $ACE_ROOT/docs/exceptions.html + // and defined in $ACE_ROOT/ace/CORBA_macros.h. + // If your platform supports native exceptions, and TAO was compiled + // with native exception support then you can simply use try/catch + // and avoid the ACE_ENV_SINGLE_ARG_PARAMETER argument. + // Unfortunately many embedded systems cannot use exceptions due to + // the space and time overhead. + // + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // **************** HERE STARTS THE ORB SETUP + + // Create the ORB, pass the argv list for parsing. + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Parse the arguments, you usually want to do this after + // invoking ORB_init() because ORB_init() will remove all the + // -ORB options from the command line. + if (parse_args (argc, argv) == -1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Service [-m udp_mcast_addr]\n")); + return 1; + } + + // This is the standard code to get access to the POA and + // activate it. + // The POA starts in the holding state, if it is not activated + // it will not process any requests. + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETS THE ORB SETUP + + // **************** HERE START THE LOCAL EVENT CHANNEL SETUP + + // This structure is used to define the startup time event + // channel configuration. + // This structure is described in + // + // $TAO_ROOT/docs/ec_options.html + // + TAO_EC_Event_Channel_Attributes attributes (poa.in (), + poa.in ()); + + // Create the Event Channel implementation class + TAO_EC_Event_Channel ec_impl (attributes); + + // Activate the Event Channel, depending on the configuration + // that may involve creating some threads. + // But it should always be invoked because several internal data + // structures are initialized at that point. + ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The event channel is activated as any other CORBA servant. + // In this case we use the simple implicit activation with the + // RootPOA + RtecEventChannelAdmin::EventChannel_var event_channel = + ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE LOCAL EVENT CHANNEL SETUP + + // **************** HERE STARTS THE FEDERATION SETUP + + // The next step is to setup the multicast gateways. + // There are two gateways involved, one sends the locally + // generated events to the federated peers, the second gateway + // receives multicast traffic and turns it into local events. + + // The sender requires a helper object to select what + // multicast group will carry what traffic, this is the + // so-called 'Address Server'. + // The intention is that advanced applications can use different + // multicast groups for different events, this can exploit + // network interfaces that filter unwanted multicast traffic. + // The helper object is accessed through an IDL interface, so it + // can reside remotely. + // In this example, and in many application, using a fixed + // multicast group is enough, and a local address server is the + // right approach. + + // First we convert the string into an INET address, then we + // convert that into the right IDL structure: + ACE_INET_Addr udp_addr (udp_mcast_address); + ACE_DEBUG ((LM_DEBUG, + "udp mcast address is: %s\n", + udp_mcast_address)); + RtecUDPAdmin::UDP_Addr addr; + addr.ipaddr = udp_addr.get_ip_address (); + addr.port = udp_addr.get_port_number (); + + // Now we create and activate the servant + AddrServer as_impl (addr); + RtecUDPAdmin::AddrServer_var address_server = + as_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // We need a local socket to send the data, open it and check + // that everything is OK: + TAO_ECG_Refcounted_Endpoint endpoint(new TAO_ECG_UDP_Out_Endpoint); + if (endpoint->dgram ().open (ACE_Addr::sap_any) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, "Cannot open send endpoint\n"), + 1); + } + + // Now we setup the sender: + TAO_EC_Servant_Var<TAO_ECG_UDP_Sender> sender = TAO_ECG_UDP_Sender::create(); + sender->init (event_channel.in (), + address_server.in (), + endpoint + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Now we connect the sender as a consumer of events, it will + // receive any event from any source and send it to the "right" + // multicast group, as defined by the address server set above: + RtecEventChannelAdmin::ConsumerQOS sub; + sub.is_gateway = 1; + + sub.dependencies.length (1); + sub.dependencies[0].event.header.type = + ACE_ES_EVENT_ANY; // first free event type + sub.dependencies[0].event.header.source = + ACE_ES_EVENT_SOURCE_ANY; // Any source is OK + + sender->connect (sub ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE FEDERATION SETUP + + // **************** HERE STARTS THE CLIENT SETUP + + // And now create a supplier + Supplier supplier (valuetype); + RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = + event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + supplier.connect (supplier_admin.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE CLIENT SETUP + + // **************** HERE STARTS THE EVENT LOOP + + // Wait for events, including incoming multicast data. + // We could also use orb->run(), but that will not let us + // terminate the application in a nice way. + for (int i = 0; i != 25; ++i) + { + CORBA::Boolean there_is_work = + orb->work_pending (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + if (there_is_work) + { + // We use a TAO extension. The CORBA mechanism does not + // provide any decent way to control the duration of + // perform_work() or work_pending(), so just calling + // them results in a spin loop. + ACE_Time_Value tv (0, 50000); + orb->perform_work (tv ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_Time_Value tv (0, 100000); + ACE_OS::sleep (tv); + supplier.perform_push (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + // **************** THAT COMPLETES THE EVENT LOOP + + // **************** HERE STARTS THE CLEANUP CODE + + // First the easy ones + supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // And also close the sender of events + sender->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The event channel must be destroyed, so it can release its + // resources, and inform all the clients that are still + // connected that it is going away. + event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Deactivating the event channel implementation is not strictly + // required, the POA will do it for us, but it is good manners: + { + // Using _this() activates with the default POA, we must gain + // access to that POA to deactivate the object. + // Notice that we 'know' that the default POA for this servant + // is the root POA, but the code is more robust if we don't + // rely on that. + PortableServer::POA_var poa = + ec_impl._default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + // Get the Object Id used for the servant.. + PortableServer::ObjectId_var oid = + poa->servant_to_id (&ec_impl ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + // Deactivate the object + poa->deactivate_object (oid.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + // Now we can destroy the POA, the flags mean that we want to + // wait until the POA is really destroyed + poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Finally destroy the ORB + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE CLEANUP CODE + + ACE_DEBUG ((LM_DEBUG, + "UDP sender ready\n")); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +// **************************************************************** + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "vm:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'm': + udp_mcast_address = get_opts.opt_arg (); + break; + + case 'v': + valuetype = true; + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "[-m udp_mcast_address]" + "[-v]" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/tests/Event/UDP/svc.conf b/TAO/orbsvcs/tests/Event/UDP/svc.conf new file mode 100644 index 00000000000..d0297d4649e --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/svc.conf @@ -0,0 +1,2 @@ +# $Id$ +static EC_Factory "-ECObserver basic -ECProxyPushConsumerCollection mt:copy_on_write:list -ECProxyPushSupplierCollection mt:copy_on_write:list -ECDispatching reactive -ECScheduling null -ECFiltering prefix -ECSupplierFilter per-supplier" diff --git a/TAO/orbsvcs/tests/Event/UDP/svc.conf.xml b/TAO/orbsvcs/tests/Event/UDP/svc.conf.xml new file mode 100644 index 00000000000..159faa97abc --- /dev/null +++ b/TAO/orbsvcs/tests/Event/UDP/svc.conf.xml @@ -0,0 +1,6 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/examples/RtEC/MCast/svc.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <static id="EC_Factory" params="-ECObserver basic -ECProxyPushConsumerCollection mt:copy_on_write:list -ECProxyPushSupplierCollection mt:copy_on_write:list -ECDispatching reactive -ECScheduling null -ECFiltering prefix -ECSupplierFilter per-supplier"/> +</ACE_Svc_Conf> diff --git a/TAO/tao/EndpointPolicy/Endpoint_Acceptor_Filter.h b/TAO/tao/EndpointPolicy/Endpoint_Acceptor_Filter.h index d198402cc5e..5eea21c1e1b 100644 --- a/TAO/tao/EndpointPolicy/Endpoint_Acceptor_Filter.h +++ b/TAO/tao/EndpointPolicy/Endpoint_Acceptor_Filter.h @@ -28,11 +28,10 @@ #include "tao/PortableServer/Default_Acceptor_Filter.h" #include "tao/EndpointPolicy/EndpointPolicyC.h" -class TAO_POA_Manager; - - TAO_BEGIN_VERSIONED_NAMESPACE_DECL +class TAO_POA_Manager; + //============================================================================= /** * @class TAO_Endpoint_Acceptor_Filter diff --git a/TAO/tao/GIOP_Message_Base.cpp b/TAO/tao/GIOP_Message_Base.cpp index 97575e5d72b..5262caa29f6 100644 --- a/TAO/tao/GIOP_Message_Base.cpp +++ b/TAO/tao/GIOP_Message_Base.cpp @@ -1797,7 +1797,6 @@ TAO_GIOP_Message_Base::parse_request_id (const TAO_Queued_Data *qd, db = qd->msg_block_->data_block ()->duplicate (); } - TAO_InputCDR input_cdr (db, flg, rd_pos, @@ -1807,7 +1806,7 @@ TAO_GIOP_Message_Base::parse_request_id (const TAO_Queued_Data *qd, qd->minor_version_, this->orb_core_); - if (qd->major_version_ >= 1 && + if (qd->major_version_ == 1 && (qd->minor_version_ == 0 || qd->minor_version_ == 1)) { if (qd->msg_type_ == TAO_PLUGGABLE_MESSAGE_REQUEST || @@ -1815,32 +1814,20 @@ TAO_GIOP_Message_Base::parse_request_id (const TAO_Queued_Data *qd, { IOP::ServiceContextList service_context; - if ( ! (input_cdr >> service_context)) - { - return -1; - } - - if ( ! (input_cdr >> request_id)) + if ((input_cdr >> service_context) + && (input_cdr >> request_id)) { - return -1; + return 0; } - - return 0; } else if (qd->msg_type_ == TAO_PLUGGABLE_MESSAGE_CANCELREQUEST || qd->msg_type_ == TAO_PLUGGABLE_MESSAGE_LOCATEREQUEST || qd->msg_type_ == TAO_PLUGGABLE_MESSAGE_LOCATEREPLY) { - if ( ! (input_cdr >> request_id) ) + if ((input_cdr >> request_id)) { - return -1; + return 0; } - - return 0; - } - else - { - return -1; } } else @@ -1852,18 +1839,14 @@ TAO_GIOP_Message_Base::parse_request_id (const TAO_Queued_Data *qd, qd->msg_type_ == TAO_PLUGGABLE_MESSAGE_LOCATEREQUEST || qd->msg_type_ == TAO_PLUGGABLE_MESSAGE_LOCATEREPLY) { - // Dealing with GIOP-1.2, the request-id is located directly behind the GIOP-Header. - // This is true for all message types that might be sent in form of fragments or cancel-requests. - if ( ! (input_cdr >> request_id) ) + // Dealing with GIOP-1.2, the request-id is located directly + // behind the GIOP-Header. This is true for all message + // types that might be sent in form of fragments or + // cancel-requests. + if ((input_cdr >> request_id)) { - return -1; + return 0; } - - return 0; - } - else - { - return -1; } } @@ -1872,7 +1855,9 @@ TAO_GIOP_Message_Base::parse_request_id (const TAO_Queued_Data *qd, /* @return -1 error, 0 ok, +1 outstanding fragments */ int -TAO_GIOP_Message_Base::consolidate_fragmented_message (TAO_Queued_Data *qd, TAO_Queued_Data *&msg) +TAO_GIOP_Message_Base::consolidate_fragmented_message ( + TAO_Queued_Data * qd, + TAO_Queued_Data *& msg) { TAO::Incoming_Message_Stack reverse_stack; diff --git a/TAO/tao/ORB.cpp b/TAO/tao/ORB.cpp index cef6cc634ab..559b128b7a6 100644 --- a/TAO/tao/ORB.cpp +++ b/TAO/tao/ORB.cpp @@ -1305,7 +1305,7 @@ TAO::ORB::init_orb_globals (ACE_ENV_SINGLE_ARG_DECL) CORBA::ORB_ptr CORBA::ORB::_tao_make_ORB (TAO_ORB_Core * orb_core) { - CORBA::ORB_ptr orb = CORBA::ORB::_nil (); + CORBA::ORB_ptr orb = CORBA::ORB_ptr (); ACE_NEW_RETURN (orb, CORBA::ORB (orb_core), @@ -1323,10 +1323,27 @@ CORBA::ORB_init (int &argc, char *argv[], const char *orb_name) { +#ifndef ACE_HAS_EXCEPTIONS + // Make sure TAO's singleton manager is initialized. + // + // We need to initialize before TAO_default_environment() is called + // since that call instantiates a TAO_TSS_Singleton. + if (TAO_Singleton_Manager::instance ()->init () == -1) + { + return CORBA::ORB::_nil (); + } + return CORBA::ORB_init (argc, argv, orb_name, TAO_default_environment ()); +#else + CORBA::Environment env; + return CORBA::ORB_init (argc, + argv, + orb_name, + env /* unused */); +#endif /* !ACE_HAS_EXCEPTIONS */ } CORBA::ORB_ptr diff --git a/TAO/tao/PortableServer/Servant_var.h b/TAO/tao/PortableServer/Servant_var.h index a734e1e018e..5004ae93159 100755 --- a/TAO/tao/PortableServer/Servant_var.h +++ b/TAO/tao/PortableServer/Servant_var.h @@ -133,8 +133,8 @@ namespace PortableServer * It is safe to pass in a null pointer, the pointer is simply * returned in that case. * - * @todo We might want to add a throw spec and catch all (potential) - * exceptions in _add_ref() + * @todo We might want to catch all (potential) exceptions in + * _add_ref(). * * @todo It might be useful to add a _release() method that handles * any potential exceptions... diff --git a/TAO/tao/Strategies/SHMIOP_Acceptor.cpp b/TAO/tao/Strategies/SHMIOP_Acceptor.cpp index 895df2ad9b2..fa502e57458 100644 --- a/TAO/tao/Strategies/SHMIOP_Acceptor.cpp +++ b/TAO/tao/Strategies/SHMIOP_Acceptor.cpp @@ -238,7 +238,7 @@ TAO_SHMIOP_Acceptor::open_default (TAO_ORB_Core *orb_core, int TAO_SHMIOP_Acceptor::set_mmap_options (const ACE_TCHAR *prefix, - off_t size) + ACE_OFF_T size) { this->mmap_file_prefix_ = prefix; this->mmap_size_ = size; diff --git a/TAO/tao/Strategies/SHMIOP_Acceptor.h b/TAO/tao/Strategies/SHMIOP_Acceptor.h index acb57ed33fe..d48b2ec0326 100644 --- a/TAO/tao/Strategies/SHMIOP_Acceptor.h +++ b/TAO/tao/Strategies/SHMIOP_Acceptor.h @@ -87,7 +87,7 @@ public: /// Set the MMAP options the MEM_Stream this acceptor creates will /// use. int set_mmap_options (const ACE_TCHAR *prefix, - off_t size); + ACE_OFF_T size); private: /// Implement the common part of the open*() methods. @@ -139,7 +139,7 @@ private: /// Determine the minimum size of mmap file. This dictate the /// maximum size of a CORBA method invocation. - off_t mmap_size_; + ACE_OFF_T mmap_size_; /// Should we use GIOP lite?? CORBA::Boolean lite_flag_; diff --git a/TAO/tao/Strategies/SHMIOP_Factory.h b/TAO/tao/Strategies/SHMIOP_Factory.h index 382282475b6..3f063f0ef4a 100644 --- a/TAO/tao/Strategies/SHMIOP_Factory.h +++ b/TAO/tao/Strategies/SHMIOP_Factory.h @@ -79,7 +79,7 @@ private: ACE_TCHAR *mmap_prefix_; /// Minimum bytes of the mmap files. - off_t min_bytes_; + ACE_OFF_T min_bytes_; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/Strategies/advanced_resource.cpp b/TAO/tao/Strategies/advanced_resource.cpp index f440e60cc8e..5108af3cdd4 100644 --- a/TAO/tao/Strategies/advanced_resource.cpp +++ b/TAO/tao/Strategies/advanced_resource.cpp @@ -29,6 +29,7 @@ #include "ace/WFMO_Reactor.h" #include "ace/Msg_WFMO_Reactor.h" #include "ace/TP_Reactor.h" +#include "ace/Dev_Poll_Reactor.h" #include "ace/Malloc_T.h" #include "ace/Local_Memory_Pool.h" #include "ace/Null_Mutex.h" @@ -164,15 +165,26 @@ TAO_Advanced_Resource_Factory::init (int argc, ACE_TCHAR** argv) #endif /* ACE_WIN32 */ else if (ACE_OS::strcasecmp (current_arg, ACE_TEXT("msg_wfmo")) == 0) -#if defined(ACE_WIN32) +#if defined(ACE_WIN32) && !defined (ACE_LACKS_MSG_WFMO) this->reactor_type_ = TAO_REACTOR_MSGWFMO; #else this->report_unsupported_error (ACE_TEXT("MsgWFMO Reactor")); -#endif /* ACE_WIN32 */ +#endif /* ACE_WIN32 && !ACE_LACKS_MSG_WFMO */ else if (ACE_OS::strcasecmp (current_arg, ACE_TEXT("tp")) == 0) this->reactor_type_ = TAO_REACTOR_TP; + + else if (ACE_OS::strcasecmp (current_arg, + ACE_TEXT("dev_poll")) == 0) + { +#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) + this->reactor_type_ = TAO_REACTOR_DEV_POLL; +#else + this->report_unsupported_error (ACE_TEXT ("Dev_Poll Reactor")); +#endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */ + } + else if (ACE_OS::strcasecmp (current_arg, ACE_TEXT("fl")) == 0) this->report_option_value_error ( @@ -431,16 +443,34 @@ TAO_Advanced_Resource_Factory::allocate_reactor_impl (void) const break; case TAO_REACTOR_WFMO: -#if defined(ACE_WIN32) && !defined (ACE_LACKS_MSG_WFMO) +#if defined(ACE_WIN32) ACE_NEW_RETURN (impl, ACE_WFMO_Reactor, 0); -#endif /* ACE_WIN32 && !ACE_LACKS_MSG_WFMO */ +#endif /* ACE_WIN32 */ break; +#if defined(ACE_WIN32) \ + && !defined (ACE_LACKS_MSG_WFMO) \ + && !defined (ACE_HAS_WINCE) \ + && !defined (ACE_HAS_PHARLAP) case TAO_REACTOR_MSGWFMO: -#if defined(ACE_WIN32) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP) ACE_NEW_RETURN (impl, ACE_Msg_WFMO_Reactor, 0); -#endif /* ACE_WIN32 && !ACE_HAS_WINCE */ break; +#endif /* ACE_WIN32 && !ACE_LACKS_MSG_WFMO */ + +#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) + case TAO_REACTOR_DEV_POLL: + ACE_NEW_RETURN (impl, + ACE_Dev_Poll_Reactor (ACE::max_handles (), + 1, // restart + (ACE_Sig_Handler*)0, + (ACE_Timer_Queue*)0, + 0, // Do not disable notify + 0, // Allocate notify handler + this->reactor_mask_signals_, + ACE_Select_Reactor_Token::LIFO), + 0); + break; +#endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */ default: case TAO_REACTOR_TP: diff --git a/TAO/tao/Strategies/advanced_resource.h b/TAO/tao/Strategies/advanced_resource.h index 98dde1143d3..d8befc55809 100644 --- a/TAO/tao/Strategies/advanced_resource.h +++ b/TAO/tao/Strategies/advanced_resource.h @@ -1,3 +1,5 @@ +// -*- C++ -*- +// // $Id$ #ifndef TAO_ADVANCED_RESOURCE_H @@ -65,7 +67,8 @@ public: TAO_REACTOR_SELECT_ST = 2, TAO_REACTOR_WFMO = 3, TAO_REACTOR_MSGWFMO = 4, - TAO_REACTOR_TP = 5 + TAO_REACTOR_TP = 5, + TAO_REACTOR_DEV_POLL = 6 }; /// Thread queueing Strategy diff --git a/TAO/tao/Valuetype/ValueBase.cpp b/TAO/tao/Valuetype/ValueBase.cpp index 58e5512d413..702fcc826b4 100644 --- a/TAO/tao/Valuetype/ValueBase.cpp +++ b/TAO/tao/Valuetype/ValueBase.cpp @@ -456,9 +456,9 @@ CORBA::ValueBase::_tao_write_value(TAO_OutputCDR &strm, CORBA::Boolean CORBA::ValueBase::_tao_write_value_header(TAO_OutputCDR &strm, - ptrdiff_t formal_type_id) const + ptrdiff_t formal_type_id) const { -#if defined (TAO_HAS_OPTIMIZED_VALUETYPE_MARSHALING) +#ifdef TAO_HAS_OPTIMIZED_VALUETYPE_MARSHALING // this case allows TAO to avoid marshaling the typeID for values // where the actual type matches the formal type (ie not a derived // type). @@ -475,15 +475,15 @@ CORBA::ValueBase::_tao_write_value_header(TAO_OutputCDR &strm, // support unmarshaling of valuetypes that did not explicitly // marshal the type id. At least it is benign to always encode the // typecode value, even if it can be a little verbose. - CORBA::Boolean const is_formal_type = - false; + CORBA::Boolean const is_formal_type = false; ACE_UNUSED_ARG (formal_type_id); #endif /* TAO_HAS_OPTIMIZED_VALUETYPE_MARSHALING */ // Get the list of repository ids for this valuetype. Repository_Id_List repository_ids; this->_tao_obv_truncatable_repo_ids (repository_ids); - CORBA::Long const num_ids = static_cast <CORBA::Long> (repository_ids.size ()); + CORBA::Long const num_ids = + static_cast <CORBA::Long> (repository_ids.size ()); // Build <value-tag>, which states if chunking is used // and if type information ((list of) repository id(s)) @@ -502,24 +502,29 @@ CORBA::ValueBase::_tao_write_value_header(TAO_OutputCDR &strm, if (num_ids > 1) valuetag |= TAO_OBV_GIOP_Flags::Type_info_list; - // Write <value-tag>. - if (!strm.write_long (valuetag)) - return false; - - if (num_ids > 1 && !strm.write_long (num_ids)) - return false; - - if (this->is_truncatable_ || - !is_formal_type || - num_ids > 1) + if (! strm.write_long (valuetag) // Write <value-tag>. + || (num_ids > 1 && !strm.write_long (num_ids))) // Write <num-ids>. { + return false; + } + +#ifndef TAO_HAS_OPTIMIMIZED_VALUETYPE_MARSHALING + if (this->is_truncatable_ + || !is_formal_type /* Always evaluates to true in the + !TAO_HAS_OPTIMIMIZED_VALUETYPE_MARSHALING + case */ + || num_ids > 1) + { +#endif /* !TAO_HAS_OPTIMIMIZED_VALUETYPE_MARSHALING */ // Marshal type information. for( CORBA::Long i = 0; i < num_ids; ++i ) { if (! strm.write_string (repository_ids[i])) return false; } +#ifndef TAO_HAS_OPTIMIMIZED_VALUETYPE_MARSHALING } +#endif /* !TAO_HAS_OPTIMIMIZED_VALUETYPE_MARSHALING */ return true; } |