summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Willemsen <jwillemsen@remedy.nl>2009-06-06 05:56:47 +0000
committerJohnny Willemsen <jwillemsen@remedy.nl>2009-06-06 05:56:47 +0000
commit38683c069fd5a08d8d7e77cd8065ab5ceb271005 (patch)
treef44d018877370db8d2f5133af80d656cc96a691d
parent4a8c897d54b84609a48f0a4f66df963b2bf02c82 (diff)
downloadATCD-38683c069fd5a08d8d7e77cd8065ab5ceb271005.tar.gz
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/Bug_3688b.mpc21
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/DllORB.cpp228
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/DllORB.h42
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestBroadcaster.cpp125
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestBroadcaster.h42
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestListener.cpp107
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestListener.h51
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/bug3688_export.h58
-rwxr-xr-xTAO/orbsvcs/tests/Notify/Bug_3688b_Regression/run_test.pl36
-rw-r--r--TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/server.cpp209
10 files changed, 919 insertions, 0 deletions
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/Bug_3688b.mpc b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/Bug_3688b.mpc
new file mode 100644
index 00000000000..5d1188492dd
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/Bug_3688b.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project (*lib): tao_notify_service, notify, taolib, portableserver, threads, avoids_corba_e_micro, avoids_corba_e_compact, avoids_minimum_corba {
+ sharedname = bug3688
+ dynamicflags += BUG3688_BUILD_DLL
+
+ Source_Files {
+ DllORB.cpp
+ TestListener.cpp
+ TestBroadcaster.cpp
+ }
+}
+
+project (*Server): notify, taoserver, tao_notify_service, threads, avoids_corba_e_micro, avoids_corba_e_compact, avoids_minimum_corba {
+ libs += bug3688
+ after += *lib
+ Source_Files {
+ server.cpp
+ }
+}
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/DllORB.cpp b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/DllORB.cpp
new file mode 100644
index 00000000000..ed3197a9021
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/DllORB.cpp
@@ -0,0 +1,228 @@
+// $Id$
+#include "DllORB.h"
+#include "ace/Barrier.h"
+#include "ace/Arg_Shifter.h"
+#include "ace/Argv_Type_Converter.h"
+#include "ace/OS_NS_unistd.h"
+#include "tao/TAO_Singleton_Manager.h"
+
+
+DllORB::DllORB ()
+ : failPrePostInit_ (3),
+ mp_barrier_ (0),
+ mv_orb_ (),
+ mv_rootPOA_ ()
+{
+}
+
+DllORB::~DllORB ()
+{
+ delete mp_barrier_;
+}
+
+int
+DllORB::init (int argc, ACE_TCHAR *argv[])
+{
+ int threadCnt = 1;
+
+ try
+ {
+ ACE_Arg_Shifter as (argc, argv);
+ const ACE_TCHAR *currentArg = 0;
+ while (as.is_anything_left ())
+ {
+ if ((currentArg = as.get_the_parameter (ACE_TEXT ("-NumThreads"))))
+ {
+ int num = ACE_OS::atoi (currentArg);
+ if (num >= 1)
+ threadCnt = num;
+ as.consume_arg ();
+ }
+ else
+ as.ignore_arg ();
+ }
+
+ if (failPrePostInit_ < 3)
+ {
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Pre-ORB initialization ...\n")));
+ // -----------------------------------------------------------------
+ // Pre-ORB initialization steps necessary for proper DLL ORB
+ // support.
+ // -----------------------------------------------------------------
+ // Make sure TAO's singleton manager is initialized, and set to not
+ // register itself with the ACE_Object_Manager since it is under the
+ // control of the Service Configurator. If we register with the
+ // ACE_Object_Manager, then the ACE_Object_Manager will still hold
+ // (dangling) references to instances of objects created by this
+ // module and destroyed by this object when it is dynamically
+ // unloaded.
+ int register_with_object_manager = 0;
+ TAO_Singleton_Manager * p_tsm = TAO_Singleton_Manager::instance ();
+ int result = p_tsm->init (register_with_object_manager);
+
+ if (result == -1)
+ {
+ if (failPrePostInit_ == 0)
+ {
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("Pre-ORB initialization failed.\n")));
+ return -1;
+ }
+ else if (failPrePostInit_ < 2)
+ {
+ ACE_DEBUG ((LM_WARNING,
+ ACE_TEXT ("Pre-ORB initialization failed (ignored due to FailPrePostInit setting).\n")));
+ }
+ else
+ {
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Pre-ORB initialization failed (ignored due to FailPrePostInit setting).\n")));
+ }
+ }
+ else
+ {
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Pre-ORB initialization done.\n")));
+ }
+ }
+
+ // Initialize the ORB
+ mv_orb_ = CORBA::ORB_init (argc, argv);
+ if (CORBA::is_nil (mv_orb_.in ()))
+ {
+ ACE_DEBUG ((LM_ERROR, ACE_TEXT ("nil ORB\n")));
+ return -1;
+ }
+
+ CORBA::Object_var v_poa =
+ mv_orb_->resolve_initial_references ("RootPOA");
+
+ mv_rootPOA_ = PortableServer::POA::_narrow (v_poa.in ());
+ if (CORBA::is_nil (mv_rootPOA_.in ()))
+ {
+ ACE_DEBUG ((LM_ERROR, ACE_TEXT ("nil RootPOA\n")));
+ return -1;
+ }
+
+ mv_poaManager_ = mv_rootPOA_->the_POAManager ();
+ if (CORBA::is_nil (mv_poaManager_.in ()))
+ {
+ ACE_DEBUG ((LM_ERROR, ACE_TEXT ("nil POAManager\n")));
+ return -1;
+ }
+
+ mv_poaManager_->activate ();
+ }
+ catch (...)
+ {
+ ACE_DEBUG ((LM_ERROR, ACE_TEXT ("ERROR: exception\n")));
+ return -1;
+ }
+
+ mp_barrier_ = new ACE_Thread_Barrier (threadCnt + 1);
+
+ this->activate (THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED, threadCnt);
+ mp_barrier_->wait ();
+
+ return 0;
+}
+
+
+int
+DllORB::fini ()
+{
+ try
+ {
+ mv_poaManager_->deactivate (1, 1);
+ mv_poaManager_ = PortableServer::POAManager::_nil ();
+
+ // attempt to protect against sporadic BAD_INV_ORDER exceptions
+ ACE_OS::sleep (ACE_Time_Value (0, 500));
+
+ mv_orb_->shutdown (1);
+ }
+ catch (...)
+ {
+ ACE_DEBUG ((LM_ERROR, ACE_TEXT ("ERROR: exception\n")));
+ return -1;
+ }
+
+ // wait for our threads to finish
+ this->wait ();
+
+ delete mp_barrier_;
+ mp_barrier_ = 0;
+
+ try
+ {
+ mv_orb_->destroy ();
+ mv_orb_ = CORBA::ORB::_nil ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Exception caught:");
+ return -1;
+ }
+
+ if (failPrePostInit_ < 3)
+ {
+ // -----------------------------------------------------------------
+ // Post-ORB finalization steps necessary for proper DLL ORB
+ // support.
+ // -----------------------------------------------------------------
+ // Explicitly clean up singletons created by TAO before
+ // unloading this module.
+ TAO_Singleton_Manager * p_tsm = TAO_Singleton_Manager::instance ();
+ int result = p_tsm->fini ();
+ if (result == -1)
+ {
+ if (failPrePostInit_ == 0)
+ {
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("Post-ORB finalization failed.\n")));
+ return -1;
+ }
+ else if (failPrePostInit_ < 2)
+ {
+ ACE_DEBUG ((LM_WARNING,
+ ACE_TEXT ("Post-ORB finalization failed (ignored due to FailPrePostInit setting).\n")));
+ }
+ else
+ {
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Post-ORB finalization failed (ignored due to FailPrePostInit setting).\n")));
+ }
+ }
+ else
+ {
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Post-ORB finalization done.\n")));
+ }
+ }
+
+ return 0;
+}
+
+
+int DllORB::svc ()
+{
+ mp_barrier_->wait ();
+
+ int result = 0;
+
+ try
+ {
+ mv_orb_->run ();
+ }
+ catch (...)
+ {
+ ACE_DEBUG ((LM_ERROR, ACE_TEXT ("ERROR: exception\n")));
+ result = 1;
+ }
+
+ return result;
+}
+
+
+ACE_FACTORY_DEFINE (bug3688, DllORB)
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/DllORB.h b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/DllORB.h
new file mode 100644
index 00000000000..4d9a562f20f
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/DllORB.h
@@ -0,0 +1,42 @@
+// $Id$
+#ifndef DLLORB_H
+#define DLLORB_H
+
+#include "ace/Task.h"
+#include "tao/ORB.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "bug3688_export.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+class ACE_Thread_Barrier;
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+class bug3688_Export DllORB: public ACE_Task_Base
+{
+public:
+ DllORB ();
+ virtual ~DllORB ();
+
+ inline CORBA::ORB_ptr orb () const
+ {
+ return CORBA::ORB::_duplicate (mv_orb_.in ());
+ }
+
+ virtual int init (int argc, ACE_TCHAR *argv[]);
+
+ virtual int fini ();
+
+protected:
+ virtual int svc ();
+
+private:
+ unsigned int failPrePostInit_;
+ ACE_Thread_Barrier* mp_barrier_;
+ CORBA::ORB_var mv_orb_;
+ PortableServer::POA_var mv_rootPOA_;
+ PortableServer::POAManager_var mv_poaManager_;
+};
+
+ACE_FACTORY_DECLARE (bug3688, DllORB)
+
+#endif /* DLLORB_H */
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestBroadcaster.cpp b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestBroadcaster.cpp
new file mode 100644
index 00000000000..f65a42384d2
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestBroadcaster.cpp
@@ -0,0 +1,125 @@
+// $Id$
+#include "TestBroadcaster.h"
+
+
+TestBroadcaster::TestBroadcaster()
+{
+} /* end of TestBroadcaster::TestBroadcaster */
+
+
+TestBroadcaster::~TestBroadcaster()
+ throw()
+{
+ // ensure nothrow guarantee
+ try
+ {
+ disconnect();
+ } /* end of try */
+ catch(...)
+ {
+ }
+} /* end of TestBroadcaster::~TestBroadcaster */
+
+
+bool TestBroadcaster::connect(
+ CORBA::ORB_ptr p_orb,
+ std::string const & rc_channelIor
+)
+{
+ try
+ {
+ CosNotifyChannelAdmin::EventChannel_var v_eventChannel;
+ CosNotifyChannelAdmin::SupplierAdmin_var v_supplierAdmin;
+ CosNotifyChannelAdmin::ProxyConsumer_var v_proxyConsumer;
+ CosNotifyChannelAdmin::AdminID supplierAdminId;
+ CosNotifyChannelAdmin::ProxyID proxyConsumerId;
+
+ CORBA::Object_var v_obj = p_orb->string_to_object(rc_channelIor.c_str());
+
+ v_eventChannel = CosNotifyChannelAdmin::EventChannel::_narrow(v_obj.in());
+
+ v_supplierAdmin =
+ v_eventChannel->new_for_suppliers (
+ CosNotifyChannelAdmin::OR_OP,
+ supplierAdminId
+ );
+
+ v_proxyConsumer = v_supplierAdmin->obtain_notification_push_consumer(
+ CosNotifyChannelAdmin::SEQUENCE_EVENT,
+ proxyConsumerId
+ );
+
+ mv_sequenceProxyPushConsumer =
+ CosNotifyChannelAdmin::SequenceProxyPushConsumer::_narrow(
+ v_proxyConsumer.in()
+ );
+
+ mv_sequenceProxyPushConsumer->connect_sequence_push_supplier(
+ CosNotifyComm::SequencePushSupplier::_nil()
+ );
+ }
+ catch(...)
+ {
+ return false;
+ }
+
+ return true;
+} /* end of TestBroadcaster::connect */
+
+
+bool TestBroadcaster::disconnect()
+{
+ try
+ {
+ if(isConnected())
+ {
+ mv_sequenceProxyPushConsumer->disconnect_sequence_push_consumer();
+ mv_sequenceProxyPushConsumer = CosNotifyChannelAdmin::SequenceProxyPushConsumer_var();
+ }
+ } /* end of try */
+ catch(...)
+ {
+ return false;
+ }
+
+ return true;
+} /* end of TestBroadcaster::disconnect */
+
+
+bool TestBroadcaster::sendData( )
+{
+ try
+ {
+ CosNotification::EventBatch events;
+ events.length(5);
+
+ for (CORBA::ULong idx = 0, max = events.length(); idx < max; ++idx)
+ {
+ events[idx].header.fixed_header.event_type.domain_name = "Test";
+ events[idx].header.fixed_header.event_type.type_name = "Data";
+ events[idx].header.fixed_header.event_name = "Info";
+ events[idx].header.variable_header.length(0);
+
+ // provide filter criteria
+ events[idx].filterable_data.length(1);
+ events[idx].filterable_data[0].name = "data";
+ events[idx].filterable_data[0].value <<= idx;
+
+ events[idx].remainder_of_body <<= idx;
+ } /* end of for */
+
+ mv_sequenceProxyPushConsumer->push_structured_events(events);
+ }
+ catch(...)
+ {
+ return false;
+ }
+
+ return true;
+} /* end of TestBroadcaster::sendData */
+
+
+bool TestBroadcaster::isConnected() const
+{
+ return !CORBA::is_nil(mv_sequenceProxyPushConsumer.in());
+} /* end of TestBroadcaster::isConnected */
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestBroadcaster.h b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestBroadcaster.h
new file mode 100644
index 00000000000..f6f8d3d0ef9
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestBroadcaster.h
@@ -0,0 +1,42 @@
+// $Id$
+#ifndef testBroadcaster_h
+#define testBroadcaster_h
+
+#include "bug3688_export.h"
+
+#include "orbsvcs/CosNotifyChannelAdminC.h"
+
+
+class bug3688_Export TestBroadcaster
+{
+ // public types and methods
+ public:
+ /// Default constructor.
+ TestBroadcaster ( );
+
+ /// Destructor.
+ ~TestBroadcaster ( )
+ throw ();
+
+ bool connect(
+ CORBA::ORB_ptr p_orb,
+ std::string const & rc_channelIor
+ );
+
+ bool disconnect( );
+
+ bool isConnected( ) const;
+
+ bool sendData( );
+
+ // protected types and methods
+ protected:
+
+ // private methods and instance variables
+ private:
+ CosNotifyChannelAdmin::SequenceProxyPushConsumer_var mv_sequenceProxyPushConsumer;
+
+}; /* end of TestBroadcaster */
+
+
+#endif /* testBroadcaster_h */
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestListener.cpp b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestListener.cpp
new file mode 100644
index 00000000000..ef196c28fe9
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestListener.cpp
@@ -0,0 +1,107 @@
+// $Id$
+#include "TestListener.h"
+
+TestListener::TestListener(
+ CORBA::ORB * p_orb,
+ std::string const & rc_channelIor,
+ std::string const & rc_filterExpression
+)
+{
+ CORBA::Object_var v_poa =
+ p_orb->resolve_initial_references("RootPOA");
+
+ mv_rootPOA = PortableServer::POA::_narrow (v_poa.in ());
+
+ PortableServer::ServantBase * p_servant = this;
+ mv_oid = mv_rootPOA->activate_object(p_servant);
+
+ mv_this = mv_rootPOA->id_to_reference(mv_oid.in());
+
+ CORBA::Object_var v_obj = p_orb->string_to_object(rc_channelIor.c_str());
+
+ mv_eventChannel = CosNotifyChannelAdmin::EventChannel::_narrow(v_obj.in());
+
+ mv_consumerAdmin = mv_eventChannel->new_for_consumers(
+ CosNotifyChannelAdmin::AND_OP,
+ m_consumerAdminId
+ );
+
+ CosNotifyFilter::FilterFactory_var v_filterFactory =
+ mv_eventChannel->default_filter_factory();
+
+ // setup a filter at the consumer admin
+ CosNotifyFilter::Filter_var v_filter =
+// v_filterFactory->create_filter("ETCL");
+ v_filterFactory->create_filter("EXTENDED_TCL");
+// v_filterFactory->create_filter("TCL");
+
+ CosNotifyFilter::ConstraintExpSeq constraintSeq(1);
+ constraintSeq.length(1);
+
+ // Set up constraint expression for new filter
+ constraintSeq[0].event_types.length(1);
+ constraintSeq[0].event_types[0].domain_name = "Test";
+ constraintSeq[0].event_types[0].type_name = "Data";
+ constraintSeq[0].constraint_expr = rc_filterExpression.c_str();
+
+ v_filter->add_constraints (constraintSeq);
+
+ mv_consumerAdmin->add_filter(v_filter.in());
+
+ v_obj = mv_rootPOA->id_to_reference(mv_oid.in());
+ mv_structuredPushConsumer = CosNotifyComm::StructuredPushConsumer::_narrow(v_obj.in());
+
+ CosNotifyChannelAdmin::ProxySupplier_var v_proxySupplier =
+ mv_consumerAdmin->obtain_notification_push_supplier(
+ CosNotifyChannelAdmin::STRUCTURED_EVENT,
+ m_proxySupplierId
+ );
+
+ mv_proxySupplier =
+ CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow(
+ v_proxySupplier.in()
+ );
+
+ mv_proxySupplier->connect_structured_push_consumer(mv_structuredPushConsumer.in());
+}
+
+
+TestListener::~TestListener()
+{
+ if(!CORBA::is_nil(mv_proxySupplier.in()))
+ {
+ // calls to disconnect_structured_push_supplier implicitely destroy
+ // the proxy, so we must set the proxy reference as nil.
+ mv_proxySupplier->disconnect_structured_push_supplier();
+ mv_proxySupplier = CosNotifyChannelAdmin::StructuredProxyPushSupplier_var();
+ }
+
+ if(!CORBA::is_nil(mv_structuredPushConsumer.in()) && !CORBA::is_nil(mv_rootPOA.in()))
+ {
+ mv_rootPOA->deactivate_object(mv_oid.in());
+ }
+}
+
+
+void TestListener::push_structured_event (
+ const CosNotification::StructuredEvent & notification
+)
+{
+ CORBA::Long data;
+ notification.remainder_of_body >>= data;
+
+ m_receivedData.push_back(data);
+}
+
+
+void TestListener::disconnect_structured_push_consumer ( )
+{
+}
+
+
+void TestListener::offer_change(
+ const CosNotification::EventTypeSeq & ,
+ const CosNotification::EventTypeSeq &
+)
+{
+}
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestListener.h b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestListener.h
new file mode 100644
index 00000000000..22d6cd3e864
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/TestListener.h
@@ -0,0 +1,51 @@
+// $Id$
+#ifndef testListener_h
+#define testListener_h
+
+#include <string>
+#include <vector>
+
+#include "bug3688_export.h"
+
+#include "orbsvcs/CosNotifyChannelAdminS.h"
+#include "orbsvcs/CosNotifyCommC.h"
+
+
+struct bug3688_Export TestListener
+:
+ public POA_CosNotifyComm::StructuredPushConsumer
+{
+ TestListener(
+ CORBA::ORB * p_orb,
+ std::string const & rc_channelIor,
+ std::string const & rc_filterExpression = ""
+ );
+
+ ~TestListener();
+
+ virtual void push_structured_event (
+ const CosNotification::StructuredEvent & notification
+ );
+
+ virtual void disconnect_structured_push_consumer ( );
+
+ virtual void offer_change(
+ const CosNotification::EventTypeSeq & added,
+ const CosNotification::EventTypeSeq & removed
+ );
+
+ PortableServer::POA_var mv_rootPOA;
+ PortableServer::ObjectId_var mv_oid;
+ CORBA::Object_var mv_this;
+ CosNotifyChannelAdmin::EventChannel_var mv_eventChannel;
+ CosNotifyChannelAdmin::ConsumerAdmin_var mv_consumerAdmin;
+ CosNotifyComm::StructuredPushConsumer_var mv_structuredPushConsumer;
+ CosNotifyChannelAdmin::StructuredProxyPushSupplier_var mv_proxySupplier;
+ CosNotifyChannelAdmin::ProxyID m_proxySupplierId;
+ CosNotifyChannelAdmin::AdminID m_consumerAdminId;
+
+ std::vector<CORBA::Long> m_receivedData;
+};
+
+
+#endif /* testListener_h */
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/bug3688_export.h b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/bug3688_export.h
new file mode 100644
index 00000000000..e21f515af82
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/bug3688_export.h
@@ -0,0 +1,58 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl bug3688
+// ------------------------------
+#ifndef BUG3688_EXPORT_H
+#define BUG3688_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (BUG3688_HAS_DLL)
+# define BUG3688_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && BUG3688_HAS_DLL */
+
+#if !defined (BUG3688_HAS_DLL)
+# define BUG3688_HAS_DLL 1
+#endif /* ! BUG3688_HAS_DLL */
+
+#if defined (BUG3688_HAS_DLL) && (BUG3688_HAS_DLL == 1)
+# if defined (BUG3688_BUILD_DLL)
+# define bug3688_Export ACE_Proper_Export_Flag
+# define BUG3688_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define BUG3688_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* BUG3688_BUILD_DLL */
+# define bug3688_Export ACE_Proper_Import_Flag
+# define BUG3688_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define BUG3688_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* BUG3688_BUILD_DLL */
+#else /* BUG3688_HAS_DLL == 1 */
+# define bug3688_Export
+# define BUG3688_SINGLETON_DECLARATION(T)
+# define BUG3688_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* BUG3688_HAS_DLL == 1 */
+
+// Set BUG3688_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (BUG3688_NTRACE)
+# if (ACE_NTRACE == 1)
+# define BUG3688_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define BUG3688_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !BUG3688_NTRACE */
+
+#if (BUG3688_NTRACE == 1)
+# define BUG3688_TRACE(X)
+#else /* (BUG3688_NTRACE == 1) */
+# if !defined (ACE_HAS_TRACE)
+# define ACE_HAS_TRACE
+# endif /* ACE_HAS_TRACE */
+# define BUG3688_TRACE(X) ACE_TRACE_IMPL(X)
+# include "ace/Trace.h"
+#endif /* (BUG3688_NTRACE == 1) */
+
+#endif /* BUG3688_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/run_test.pl b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/run_test.pl
new file mode 100755
index 00000000000..063e0f1b1df
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/run_test.pl
@@ -0,0 +1,36 @@
+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;
+$file = PerlACE::LocalFile ("test.ior");
+
+unlink $file;
+
+if (PerlACE::is_vxworks_test()) {
+ $SV = new PerlACE::ProcessVX ("server", "");
+}
+else {
+ $SV = new PerlACE::Process ("server", "");
+}
+
+print STDERR "\n\n==== Running bug 3688 regression test\n";
+
+$SV->Spawn ();
+
+$collocated = $SV->WaitKill (15);
+
+if ($collocated != 0) {
+ print STDERR "ERROR: Bug_3688_Regression returned $collocated\n";
+ $status = 1;
+}
+
+unlink $file;
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/server.cpp b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/server.cpp
new file mode 100644
index 00000000000..531b6fa61db
--- /dev/null
+++ b/TAO/orbsvcs/tests/Notify/Bug_3688b_Regression/server.cpp
@@ -0,0 +1,209 @@
+// $Id$
+
+#include "ace/Service_Config.h"
+#include "orbsvcs/Notify_Service/Notify_Service.h"
+#include "orbsvcs/CosNotifyChannelAdminC.h"
+#include "orbsvcs/CosNamingC.h"
+
+
+#include "DllORB.h"
+#include "TestListener.h"
+#include "TestBroadcaster.h"
+
+
+char const * const scpc_orbId = "testDllOrb";
+
+ACE_TCHAR const * const scpc_loadOrb = ACE_DYNAMIC_SERVICE_DIRECTIVE(
+ "testDllOrb",
+ "bug3688",
+ "_make_DllORB",
+ "testDllOrb -ORBDebugLevel 0 -ORBId testDllOrb -ORBDottedDecimalAddresses 1 -ORBInitRef NameService=file://naming.ior"
+);
+
+ACE_TCHAR const * const scpc_unloadOrb = ACE_REMOVE_SERVICE_DIRECTIVE("testDllOrb");
+
+ACE_TCHAR const * const scpc_loadNameService = ACE_DYNAMIC_SERVICE_DIRECTIVE(
+ "testNamingService",
+ "TAO_CosNaming_Serv",
+ "_make_TAO_Naming_Loader",
+ "testNameService testNameService -ORBId testDllOrb -m 0 -o naming.ior"
+);
+
+ACE_TCHAR const * const scpc_unloadNameService = ACE_REMOVE_SERVICE_DIRECTIVE("testNamingService");
+
+
+ACE_TCHAR const * const scpc_loadNotifyService = ACE_DYNAMIC_SERVICE_DIRECTIVE(
+ "testNotifyService",
+ "TAO_Notify_Service",
+ "_make_TAO_Notify_Service_Driver",
+ "-Channel -ChannelName Channel1 -ChannelName Channel2 -RunThreads 1 -ORBInitRef NameService=file://naming.ior -IORoutput notify.ior -ORBDebugLevel 10"
+);
+
+ACE_TCHAR const * const scpc_unloadNotifyService = ACE_REMOVE_SERVICE_DIRECTIVE("testNotifyService");
+
+
+
+int publish()
+{
+ int result = 0;
+
+ ACE_DEBUG((
+ LM_INFO,
+ ACE_TEXT ("(%P|%t) publish ...\n")
+ ));
+
+ DllORB * p_orb = ACE_Dynamic_Service<DllORB>::instance ("testDllOrb");
+ CORBA::ORB_var v_orb = p_orb->orb();
+
+
+ TestBroadcaster testBroadcaster;
+
+ testBroadcaster.connect(
+ v_orb.in(),
+ "corbaname:rir:#Channel1"
+ );
+
+ TestListener testListener(
+ v_orb.in(),
+ "corbaname:rir:#Channel1",
+ "$data == 1 or "
+ "$data == 2 or "
+ "$data == 4"
+ );
+
+ testBroadcaster.sendData();
+
+
+ ACE_DEBUG((
+ LM_INFO,
+ ACE_TEXT ("(%P|%t) testListener.m_receivedData.size()=%d\n"),
+ testListener.m_receivedData.size()
+ ));
+
+ result = testListener.m_receivedData.size() == 3 ? 0 : testListener.m_receivedData.size();
+
+ ACE_DEBUG((
+ LM_INFO,
+ ACE_TEXT ("(%P|%t) publish done\n")
+ ));
+
+ return result;
+}
+
+int loadunloadcycle()
+{
+ int result = 0;
+ int publish_result = 0;
+
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - loading\n")
+ ));
+
+ result = ACE_Service_Config::process_directive(scpc_loadOrb);
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - loading ORB done\n")
+ ));
+
+ DllORB * p_orb =
+ ACE_Dynamic_Service<DllORB>::instance("testDllOrb");
+
+ CORBA::ORB_var v_orb = p_orb->orb();
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - v_orb OK\n")
+ ));
+
+ CORBA::Object_var v_poa =
+ v_orb->resolve_initial_references("RootPOA");
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - v_poa OK\n")
+ ));
+
+ PortableServer::POA_var v_rootPOA =
+ PortableServer::POA::_narrow(v_poa.in ());
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - v_rootPOA OK\n")
+ ));
+
+ result = ACE_Service_Config::process_directive(scpc_loadNameService);
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - loading NamingService done\n")
+ ));
+
+ result = ACE_Service_Config::process_directive(scpc_loadNotifyService);
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - loading NotifyService done\n")
+ ));
+
+ publish_result = publish();
+
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - unloading\n")
+ ));
+
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - unloading NotifyService ...\n")
+ ));
+ result = ACE_Service_Config::process_directive(scpc_unloadNotifyService);
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - unloading NotifyService done\n")
+ ));
+
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - unloading NameService ...\n")
+ ));
+ result = ACE_Service_Config::process_directive(scpc_unloadNameService);
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - unloading NameService done\n")
+ ));
+
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - unloading ORB ...\n")
+ ));
+ result = ACE_Service_Config::process_directive(scpc_unloadOrb);
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) loadunloadcycle - unloading ORB done\n")
+ ));
+
+ return publish_result;
+}
+
+int ACE_TMAIN (int , ACE_TCHAR **)
+{
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) main - entered\n")
+ ));
+
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) main - cycle ...\n")
+ ));
+
+ int result = loadunloadcycle();
+
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) main - cycle done\n")
+ ));
+
+ ACE_DEBUG((
+ LM_DEBUG,
+ ACE_TEXT ("(%P|%t) main - leaving\n")
+ ));
+
+ return result;
+}