diff options
author | Steve Huston <shuston@riverace.com> | 2010-04-20 19:01:24 +0000 |
---|---|---|
committer | Steve Huston <shuston@riverace.com> | 2010-04-20 19:01:24 +0000 |
commit | 369c0bf707c1520baf496fb4c8c467f7c4a03374 (patch) | |
tree | 01471c1a8794c7e1aecd1380c4a1e32bd1e56964 | |
parent | 89e1b5e60ea84c3caebbbf8d106689f0e375655c (diff) | |
download | ATCD-369c0bf707c1520baf496fb4c8c467f7c4a03374.tar.gz |
Tue Apr 20 18:46:38 UTC 2010 Steve Huston <shuston@riverace.com>
* tests/Service_Config_Stream_Test.{cp conf}: Brought this test over
from hte dev stream as well as Bug_3334_Regression_Test.cpp.
Mon Apr 19 18:17:30 UTC 2010 UTC 2010 Chad Beaulac <chad@objectivesolutions.com>
* ace/Service_Repository.cpp
Modified ASR::fini to print debug info for empty
service entries and handle empty service entries.
This fixes the ASR remove functionality that was
one of the reasons SC_Server was crashing at shutdown.
* examples/ASX/CCM_App/SC_Server.cpp
Removing signal handler before main exit to present SEGV
This fixes Bugzilla #2916 and #3205.
Mon Apr 19 12:44:56 UTC 2010 Chad Beaulac <chad@objectivesolutions.com>
* ace/Service_Types.h
* ace/Service_Types.inl
* ace/Service_Types.cpp
Added service_type_ attr to expose the type of service being
managed to the ACE_Service_Repository. This allows the ASR to
manage the lifecycle of the ACE_Module and ACE_Stream in order to
avoid a double delete of ACE_Module at shutdown.
ACE_Stream_Type::fini was modified to not call ACE_Module_Type::fini
as this will results in a double delete when
ACE_Service_Repository::fini is called.
ACE_Stream_Type::remove(module_name) was modified to not call
ACE_Module_Type::fini as this will results in a double delete
when ACE_Service_Repository::fini is called also.
* ace/Service_Repository.cpp
Modified ASR::fini to iterate over the service_array_ twice.
ACE_Service_Type::fini is called on all ACE_Stream_Type and
ACE_Service_Object_Type instances first. Then, fini is called on
all ACE_Modules_Type instances. All calls to fini are done in the
order the services appear in the ASR::service_array_ except for
the grouping described here. The calls to ACE_Module_Type::fini
must be done last because ACE_Stream_Type::fini accesses the Modules
so they must not be deleted by a call to ACE_Module_Type::fini
before that.
* tests/Bug_3334_Regresssion_Test.cpp
Added call to ACE_Service_Repository::fini_svcs() to capture all
debug output before the application exits.
* tests/run_tests.lst
Removed !FIXED_BUGS_ONLY from Bug_3334_Regression_Test
This fixes Bugzilla #3334
-rw-r--r-- | ChangeLog | 55 | ||||
-rw-r--r-- | ace/Service_Repository.cpp | 90 | ||||
-rw-r--r-- | ace/Service_Types.cpp | 39 | ||||
-rw-r--r-- | ace/Service_Types.h | 23 | ||||
-rw-r--r-- | ace/Service_Types.inl | 11 | ||||
-rw-r--r-- | examples/ASX/CCM_App/SC_Server.cpp | 1 | ||||
-rw-r--r-- | tests/Bug_3334_Regression_Test.conf | 7 | ||||
-rw-r--r-- | tests/Bug_3334_Regression_Test.cpp | 48 | ||||
-rw-r--r-- | tests/Service_Config_Stream_DLL.h | 44 | ||||
-rw-r--r-- | tests/Service_Config_Stream_DLL_Export.h | 38 | ||||
-rw-r--r-- | tests/Service_Config_Stream_Test.conf | 25 | ||||
-rw-r--r-- | tests/Service_Config_Stream_Test.cpp | 131 | ||||
-rw-r--r-- | tests/run_test.lst | 1 | ||||
-rw-r--r-- | tests/tests.mpc | 32 |
14 files changed, 499 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog index 7dc732d1b3b..72a8596b079 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,58 @@ +Tue Apr 20 18:46:38 UTC 2010 Steve Huston <shuston@riverace.com> + + * tests/Service_Config_Stream_Test.{cp conf}: Brought this test over + from hte dev stream as well as Bug_3334_Regression_Test.cpp. + +Mon Apr 19 18:17:30 UTC 2010 UTC 2010 Chad Beaulac <chad@objectivesolutions.com> + + * ace/Service_Repository.cpp + Modified ASR::fini to print debug info for empty + service entries and handle empty service entries. + This fixes the ASR remove functionality that was + one of the reasons SC_Server was crashing at shutdown. + + * examples/ASX/CCM_App/SC_Server.cpp + Removing signal handler before main exit to present SEGV + + This fixes Bugzilla #2916 and #3205. + +Mon Apr 19 12:44:56 UTC 2010 Chad Beaulac <chad@objectivesolutions.com> + + * ace/Service_Types.h + * ace/Service_Types.inl + * ace/Service_Types.cpp + Added service_type_ attr to expose the type of service being + managed to the ACE_Service_Repository. This allows the ASR to + manage the lifecycle of the ACE_Module and ACE_Stream in order to + avoid a double delete of ACE_Module at shutdown. + + ACE_Stream_Type::fini was modified to not call ACE_Module_Type::fini + as this will results in a double delete when + ACE_Service_Repository::fini is called. + ACE_Stream_Type::remove(module_name) was modified to not call + ACE_Module_Type::fini as this will results in a double delete + when ACE_Service_Repository::fini is called also. + + * ace/Service_Repository.cpp + Modified ASR::fini to iterate over the service_array_ twice. + ACE_Service_Type::fini is called on all ACE_Stream_Type and + ACE_Service_Object_Type instances first. Then, fini is called on + all ACE_Modules_Type instances. All calls to fini are done in the + order the services appear in the ASR::service_array_ except for + the grouping described here. The calls to ACE_Module_Type::fini + must be done last because ACE_Stream_Type::fini accesses the Modules + so they must not be deleted by a call to ACE_Module_Type::fini + before that. + + * tests/Bug_3334_Regresssion_Test.cpp + Added call to ACE_Service_Repository::fini_svcs() to capture all + debug output before the application exits. + + * tests/run_tests.lst + Removed !FIXED_BUGS_ONLY from Bug_3334_Regression_Test + + This fixes Bugzilla #3334 + Tue Apr 13 19:34:40 UTC 2010 Steve Huston <shuston@riverace.com> * ace/Dev_Poll_Reactor.{h cpp}: Reorder the enqueue/pipe operations diff --git a/ace/Service_Repository.cpp b/ace/Service_Repository.cpp index 60f6b6fe831..d997c5e61cc 100644 --- a/ace/Service_Repository.cpp +++ b/ace/Service_Repository.cpp @@ -113,7 +113,9 @@ ACE_Service_Repository::ACE_Service_Repository (size_t size) ACE_TRACE ("ACE_Service_Repository::ACE_Service_Repository"); } + /// Finalize (call fini() and possibly delete) all the services. + int ACE_Service_Repository::fini (void) { @@ -121,45 +123,89 @@ ACE_Service_Repository::fini (void) ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); int retval = 0; - // Do not be tempted to use the prefix decrement operator. Use // postfix decrement operator since the index is unsigned and may // wrap around the 0 - for (size_t i = this->service_array_.size(); i-- != 0; ) + // + // debug output for empty service entries +#ifndef ACE_NLOGGING + if (ACE::debug ()) + { + for (size_t i = this->service_array_.size (); i-- != 0;) { - // <fini> the services in reverse order. ACE_Service_Type *s = const_cast<ACE_Service_Type *> (this->service_array_[i]); + if (s == 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] -> 0\n"), + this, + i)); + } + } +#endif + // + // Remove all the Service_Object and Stream instances + // + for (size_t i = this->service_array_.size (); i-- != 0;) + { + // <fini> the services in reverse order. + ACE_Service_Type *s = + const_cast<ACE_Service_Type *> (this->service_array_[i]); + if (s != 0 && (s->type ()->service_type () != ACE_Service_Type::MODULE)) + { #ifndef ACE_NLOGGING if (ACE::debug ()) - { - if (s != 0) - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ") - ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), - this, - i, - s->name(), - s->type (), - (s->type () != 0) ? s->type ()->object () : 0, - s->active ())); - else - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] -> 0\n"), - this, - i)); - } + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ") + ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), + this, + i, + s->name (), + s->type (), + (s->type () != 0) ? s->type ()->object () : 0, + s->active ())); + } #endif // Collect any errors. - if (s != 0) - retval += s->fini (); + retval += s->fini (); } + } + // + // Remove all the Module instances + // + for (size_t i = this->service_array_.size (); i-- != 0;) + { + // <fini> the services in reverse order. + ACE_Service_Type *s = + const_cast<ACE_Service_Type *> (this->service_array_[i]); + if (s != 0 && (s->type ()->service_type () == ACE_Service_Type::MODULE)) + { +#ifndef ACE_NLOGGING + if (ACE::debug ()) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ") + ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), + this, + i, + s->name (), + s->type (), + (s->type () != 0) ? s->type ()->object () : 0, + s->active ())); + } +#endif + // Collect any errors. + retval += s->fini (); + } + } return (retval == 0) ? 0 : -1; } + /// Close down all the services. int ACE_Service_Repository::close (void) diff --git a/ace/Service_Types.cpp b/ace/Service_Types.cpp index 4552607640e..5c2c2fae3b7 100644 --- a/ace/Service_Types.cpp +++ b/ace/Service_Types.cpp @@ -35,11 +35,13 @@ ACE_Service_Type_Impl::dump (void) const ACE_Service_Type_Impl::ACE_Service_Type_Impl (void *so, const ACE_TCHAR *s_name, u_int f, - ACE_Service_Object_Exterminator gobbler) + ACE_Service_Object_Exterminator gobbler, + int stype) : name_ (0), obj_ (so), gobbler_ (gobbler), - flags_ (f) + flags_ (f), + service_type_ (stype) { ACE_TRACE ("ACE_Service_Type_Impl::ACE_Service_Type_Impl"); this->name (s_name); @@ -82,8 +84,9 @@ ACE_Service_Type_Impl::fini (void) const ACE_Service_Object_Type::ACE_Service_Object_Type (void *so, const ACE_TCHAR *s_name, u_int f, - ACE_Service_Object_Exterminator gobbler) - : ACE_Service_Type_Impl (so, s_name, f, gobbler) + ACE_Service_Object_Exterminator gobbler, + int stype) + : ACE_Service_Type_Impl (so, s_name, f, gobbler, stype) , initialized_ (-1) { ACE_TRACE ("ACE_Service_Object_Type::ACE_Service_Object_Type"); @@ -164,8 +167,9 @@ ACE_Module_Type::dump (void) const ACE_Module_Type::ACE_Module_Type (void *m, const ACE_TCHAR *m_name, - u_int f) - : ACE_Service_Type_Impl (m, m_name, f) + u_int f, + int stype) + : ACE_Service_Type_Impl (m, m_name, f, 0, stype) { ACE_TRACE ("ACE_Module_Type::ACE_Module_Type"); } @@ -230,7 +234,6 @@ int ACE_Module_Type::fini (void) const { ACE_TRACE ("ACE_Module_Type::fini"); - void *obj = this->object (); MT_Module *mod = (MT_Module *) obj; MT_Task *reader = mod->reader (); @@ -324,8 +327,9 @@ ACE_Stream_Type::resume (void) const ACE_Stream_Type::ACE_Stream_Type (void *s, const ACE_TCHAR *s_name, - u_int f) - : ACE_Service_Type_Impl (s, s_name, f), + u_int f, + int stype) + : ACE_Service_Type_Impl (s, s_name, f, 0, stype), head_ (0) { ACE_TRACE ("ACE_Stream_Type::ACE_Stream_Type"); @@ -361,17 +365,13 @@ ACE_Stream_Type::fini (void) const void *obj = this->object (); MT_Stream *str = (MT_Stream *) obj; - for (ACE_Module_Type *m = this->head_; m != 0; ) - { - ACE_Module_Type *t = m->link (); + for (ACE_Module_Type *m = this->head_; m != 0;) + { + ACE_Module_Type *t = m->link (); // Final arg is an indication to *not* delete the Module. str->remove (m->name (), - MT_Module::M_DELETE_NONE); - - // Finalize the Module (this may delete it, but we don't really - // care since we don't access it again). - m->fini (); + MT_Module::M_DELETE_NONE); m = t; } str->close (); @@ -408,9 +408,8 @@ ACE_Stream_Type::remove (ACE_Module_Type *mod) MT_Module::M_DELETE_NONE) == -1) result = -1; - // This call may end up deleting m, which is ok since we - // don't access it again! - m->fini (); + // Do not call m->fini (); as this will result in a double delete + // of the ACE_Module_type when ACE_Service_Repository::fini is called } else prev = m; diff --git a/ace/Service_Types.h b/ace/Service_Types.h index e741561d965..de442a6b431 100644 --- a/ace/Service_Types.h +++ b/ace/Service_Types.h @@ -43,7 +43,8 @@ public: ACE_Service_Type_Impl (void *object, const ACE_TCHAR *s_name, u_int flags = 0, - ACE_Service_Object_Exterminator gobbler = 0); + ACE_Service_Object_Exterminator gobbler = 0, + int stype = ACE_Service_Type::INVALID_TYPE); virtual ~ACE_Service_Type_Impl (void); // = Pure virtual interface (must be defined by the subclass). @@ -65,6 +66,12 @@ public: /// Dump the state of an object. void dump (void) const; + /// get the service_type of this service + int service_type (void) const; + + /// set the service_type of this service + void service_type (int stype); + /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; @@ -81,6 +88,11 @@ protected: /// Flags that control serivce behavior (particularly deletion). u_int flags_; + + /// type of this service + /// Used to properly manage the lifecycle of ACE_Modules and ACE_Streams + /// during shutdown + int service_type_; }; /** @@ -96,7 +108,8 @@ public: ACE_Service_Object_Type (void *so, const ACE_TCHAR *name, u_int flags = 0, - ACE_Service_Object_Exterminator gobbler = 0); + ACE_Service_Object_Exterminator gobbler = 0, + int stype = ACE_Service_Type::SERVICE_OBJECT); ~ACE_Service_Object_Type (void); @@ -124,7 +137,8 @@ public: // = Initialization method. ACE_Module_Type (void *m, // Really an ACE_Module *. const ACE_TCHAR *identifier, - u_int flags = 0); + u_int flags = 0, + int stype = ACE_Service_Type::MODULE); ~ACE_Module_Type (void); @@ -164,7 +178,8 @@ public: // = Initialization method. ACE_Stream_Type (void *s, // Really an ACE_Stream *. const ACE_TCHAR *identifier, - u_int flags = 0); + u_int flags = 0, + int stype = ACE_Service_Type::STREAM); ~ACE_Stream_Type (void); diff --git a/ace/Service_Types.inl b/ace/Service_Types.inl index 9ebfd705ced..02b2d3c6c41 100644 --- a/ace/Service_Types.inl +++ b/ace/Service_Types.inl @@ -29,4 +29,15 @@ ACE_Service_Type_Impl::name (const ACE_TCHAR *n) this->name_ = ACE::strnew (n); } +ACE_INLINE int +ACE_Service_Type_Impl::service_type (void) const +{ + return service_type_; +} + +ACE_INLINE void +ACE_Service_Type_Impl::service_type (int stype) +{ + service_type_ = stype; +} ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/examples/ASX/CCM_App/SC_Server.cpp b/examples/ASX/CCM_App/SC_Server.cpp index 4a1256cf7f4..e133c3db614 100644 --- a/examples/ASX/CCM_App/SC_Server.cpp +++ b/examples/ASX/CCM_App/SC_Server.cpp @@ -82,5 +82,6 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) // Perform logging service until we receive SIGINT. ACE_Reactor::instance ()->run_reactor_event_loop (); + handler.remove_stdin_handler (ACE_Reactor::instance (),ACE_Thread_Manager::instance ()); return 0; } diff --git a/tests/Bug_3334_Regression_Test.conf b/tests/Bug_3334_Regression_Test.conf new file mode 100644 index 00000000000..1e863ef9fe9 --- /dev/null +++ b/tests/Bug_3334_Regression_Test.conf @@ -0,0 +1,7 @@ +stream dynamic Svc_Conf_Stream STREAM *Service_Config_Stream_DLL:make_stream() active +{ + dynamic Device_Adapter Module *Service_Config_Stream_DLL:make_da() + dynamic Event_Analyzer Module *Service_Config_Stream_DLL:make_ea() + dynamic Multicast_Router Module *Service_Config_Stream_DLL:make_mr() +} + diff --git a/tests/Bug_3334_Regression_Test.cpp b/tests/Bug_3334_Regression_Test.cpp new file mode 100644 index 00000000000..fe348154f80 --- /dev/null +++ b/tests/Bug_3334_Regression_Test.cpp @@ -0,0 +1,48 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = DESCRIPTION +// This test exercises ACE_Service_Config SEGV during shutdown when +// Modules get double deleted. Once by Stream parent, +// once by ACE_Service_Repository +// +// = AUTHOR +// Chad Beaulac <chad@objectivesolutions.com> +// +// ============================================================================ + +#include "test_config.h" +#include "ace/Log_Msg.h" +#include "ace/Service_Config.h" + +ACE_RCSID(tests, Bug_3334_Regression_Test, "$Id$") + +int +run_main (int, ACE_TCHAR *argv[]) +{ + ACE_START_TEST (ACE_TEXT ("Bug_3334_Regression_Test")); + + ACE_TCHAR *_argv[3] = { argv[0], + const_cast<ACE_TCHAR*> (ACE_TEXT ("-f")), + const_cast<ACE_TCHAR*> + (ACE_TEXT ("Bug_3334_Regression_Test.conf")) }; + int status; + if ((status = ACE_Service_Config::open (3, + _argv, + ACE_DEFAULT_LOGGER_KEY, + true, + true /*ignore def svc.conf*/)) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("open"), + 1)); + + ACE_Service_Config::fini_svcs (); + + ACE_END_TEST; + return status; +} diff --git a/tests/Service_Config_Stream_DLL.h b/tests/Service_Config_Stream_DLL.h new file mode 100644 index 00000000000..417ddb30894 --- /dev/null +++ b/tests/Service_Config_Stream_DLL.h @@ -0,0 +1,44 @@ +// $Id$ + +#ifndef SERVICE_CONFIG_STREAM_DLL_H +#define SERVICE_CONFIG_STREAM_DLL_H + +#include /**/ "ace/pre.h" + +#include "Service_Config_Stream_DLL_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Task.h" +#include "ace/Stream.h" +#include "ace/Module.h" + +typedef ACE_Task<ACE_SYNCH> MT_Task; +typedef ACE_Stream<ACE_SYNCH> MT_Stream; +typedef ACE_Module<ACE_SYNCH> MT_Module; + +class Service_Config_Stream_DLL_Export Test_Task : public MT_Task +{ +public: + //FUZZ: disable check_for_lack_ACE_OS + virtual int open (void *); + virtual int close (u_long); + //FUZZ: enable check_for_lack_ACE_OS + + virtual int init (int, ACE_TCHAR *[]); + virtual int fini (void); +}; + +// Task to verify the order and operation of the stream assembly +// Command line args give the stream name (to look it up) and the names +// of the tasks that should be there, from head to tail. +class Service_Config_Stream_DLL_Export Stream_Order_Test : public MT_Task +{ +public: + virtual int init (int, ACE_TCHAR *[]); +}; + +#include /**/ "ace/post.h" +#endif /* SERVICE_CONFIG_STREAM_DLL_H */ diff --git a/tests/Service_Config_Stream_DLL_Export.h b/tests/Service_Config_Stream_DLL_Export.h new file mode 100644 index 00000000000..9ef0f6caad6 --- /dev/null +++ b/tests/Service_Config_Stream_DLL_Export.h @@ -0,0 +1,38 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl +// ------------------------------ +#ifndef SERVICE_CONFIG_STREAM_DLL_EXPORT_H +#define SERVICE_CONFIG_STREAM_DLL_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (SERVICE_CONFIG_STREAM_DLL_HAS_DLL) +# define SERVICE_CONFIG_STREAM_DLL_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && ! SERVICE_CONFIG_STREAM_DLL_HAS_DLL */ + +#if !defined (SERVICE_CONFIG_STREAM_DLL_HAS_DLL) +# define SERVICE_CONFIG_STREAM_DLL_HAS_DLL 1 +#endif /* ! TEST_HAS_DLL */ + +#if defined (SERVICE_CONFIG_STREAM_DLL_HAS_DLL) && (SERVICE_CONFIG_STREAM_DLL_HAS_DLL == 1) +# if defined (SERVICE_CONFIG_STREAM_DLL_BUILD_DLL) +# define Service_Config_Stream_DLL_Export ACE_Proper_Export_Flag +# define TEST_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* SERVICE_CONFIG_STREAM_DLL_BUILD_DLL */ +# define Service_Config_Stream_DLL_Export ACE_Proper_Import_Flag +# define TEST_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* SERVICE_CONFIG_STREAM_DLL_BUILD_DLL */ +#else /* SERVICE_CONFIG_STREAM_DLL_HAS_DLL == 1 */ +# define Service_Config_Stream_DLL_Export +# define TEST_SINGLETON_DECLARATION(T) +# define TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* SERVICE_CONFIG_STREAM_DLL_HAS_DLL == 1 */ + +#endif /* SERVICE_CONFIG_STREAM_DLL_EXPORT_H */ + +// End of auto generated file. diff --git a/tests/Service_Config_Stream_Test.conf b/tests/Service_Config_Stream_Test.conf new file mode 100644 index 00000000000..26128c925d0 --- /dev/null +++ b/tests/Service_Config_Stream_Test.conf @@ -0,0 +1,25 @@ +stream dynamic Svc_Conf_Stream STREAM *Service_Config_Stream_DLL:make_stream() active +{ + dynamic Device_Adapter Module *Service_Config_Stream_DLL:make_da() +# static Decrypter + dynamic Event_Analyzer Module *Service_Config_Stream_DLL:make_ea() + dynamic Multicast_Router Module *Service_Config_Stream_DLL:make_mr() +} + +#dynamic Stream_Order_Test Service_Object *Service_Config_Stream_DLL:_make_Stream_Order_Test() "Svc_Conf_Stream Multicast_Router Event_Analyzer Decrypter Device_Adapter" +dynamic Stream_Order_Test Service_Object *Service_Config_Stream_DLL:_make_Stream_Order_Test() "Svc_Conf_Stream Multicast_Router Event_Analyzer Device_Adapter" + +stream Svc_Conf_Stream +{ + remove Device_Adapter + remove Event_Analyzer + remove Multicast_Router +} +#stream Svc_Conf_Stream +#{ +# remove Decrypter +#} + +remove Svc_Conf_Stream +remove Stream_Order_Test + diff --git a/tests/Service_Config_Stream_Test.cpp b/tests/Service_Config_Stream_Test.cpp new file mode 100644 index 00000000000..3ec0ab11516 --- /dev/null +++ b/tests/Service_Config_Stream_Test.cpp @@ -0,0 +1,131 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = DESCRIPTION +// This test exercises ACE_Service_Config assembling a stream. +// +// = AUTHOR +// Steve Huston <shuston@riverace.com> +// +// ============================================================================ + +#include "test_config.h" +#include "ace/Log_Msg.h" +#include "ace/Module.h" +#include "ace/Service_Config.h" +#include "ace/Task.h" + +ACE_RCSID(tests, Service_Config_Stream_Test, "$Id$") + +/* + * The Decrypter service is static and is configured into a stream + * dynamically. + * + * NOTE! This code is here, and it will trip up while being loaded. If + * "static Decrypter" is inserted into the .conf file's module list, this + * test will barf. This is arguably a weird test, but I don't know any + * reason it should not work; however, this behavior has never been tested + * and may not have ever worked... but if someone is feeling ambitious, + * please go ahead and make this work. I'm out of time and energy. + * -Steve Huston + */ +class Static_Task : public ACE_Task<ACE_SYNCH> +{ +public: + Static_Task() : ACE_Task<ACE_SYNCH>() {} + + int open (void *) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("opening %s\n"), + this->name () ? this->name () : ACE_TEXT ("Static_Task"))); + return 0; + } + + int close (u_long) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("closing %s\n"), + this->name () ? this->name () : ACE_TEXT ("Static_Task"))); + return 0; + } + + int init (int, ACE_TCHAR *[]) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("initializing %s\n"), + this->name () ? this->name () : ACE_TEXT ("Static_Task"))); + return 0; + } + + int fini (void) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("finalizing %s\n"), + this->name () ? this->name () : ACE_TEXT ("Static_Task"))); + return 0; + } +}; + +class Decrypter : public ACE_Service_Object, public ACE_Module<ACE_SYNCH> +{ +public: + Decrypter () + : writer_(), reader_(), + ACE_Module<ACE_SYNCH> (ACE_TEXT ("Decrypter"), + &writer_, &reader_, + 0, + M_DELETE_NONE) // Tasks are members; don't delete + {} + +private: + Static_Task writer_; + Static_Task reader_; +}; + +ACE_FACTORY_DEFINE (ACE_Local_Service, Decrypter) +ACE_STATIC_SVC_DEFINE (Decrypter_Descriptor, + ACE_TEXT ("Decrypter"), + ACE_MODULE_T, + &ACE_SVC_NAME (Decrypter), + (ACE_Service_Type::DELETE_THIS | + ACE_Service_Type::DELETE_OBJ), + 1) +ACE_STATIC_SVC_REQUIRE (Decrypter_Descriptor) + + +int +run_main (int, ACE_TCHAR *argv[]) +{ + ACE_START_TEST (ACE_TEXT ("Service_Config_Stream_Test")); + + ACE_STATIC_SVC_REGISTER (Decrypter); + + // If you want to try the static module in the stream test (comments at + // the top of this file) it needs the -y in the argv list which enables + // static services. Otherwise it's not really needed. Same with the + // 'false' 4th arg to open() below - it allows static services. + ACE_TCHAR *_argv[5] = { argv[0], + const_cast<ACE_TCHAR*> (ACE_TEXT ("-d")), + const_cast<ACE_TCHAR*> (ACE_TEXT ("-y")), + const_cast<ACE_TCHAR*> (ACE_TEXT ("-f")), + const_cast<ACE_TCHAR*> + (ACE_TEXT ("Service_Config_Stream_Test.conf")) }; + int status; + if ((status = ACE_Service_Config::open (5, + _argv, + ACE_DEFAULT_LOGGER_KEY, + false, + true /*ignore def svc.conf*/)) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("open"), + 1)); + + ACE_END_TEST; + return status; +} diff --git a/tests/run_test.lst b/tests/run_test.lst index 100cb827e71..2de272d3682 100644 --- a/tests/run_test.lst +++ b/tests/run_test.lst @@ -45,6 +45,7 @@ Bug_2820_Regression_Test Bug_2980_Regression_Test: !STATIC !Win32 !VxWorks !WCHAR Bug_3102_Regression_Test Bug_3319_Regression_Test +Bug_3334_Regression_Test: !STATIC Bug_3432_Regression_Test Bug_3500_Regression_Test Bug_3532_Regression_Test diff --git a/tests/tests.mpc b/tests/tests.mpc index 9629e91fd7e..16f69453a1d 100644 --- a/tests/tests.mpc +++ b/tests/tests.mpc @@ -1696,3 +1696,35 @@ project(Wild_Match_Test) : acetest { Wild_Match_Test.cpp } } + +project(Service Config Stream DLL) : acelib { + libout = . + sharedname = Service_Config_Stream_DLL + dynamicflags = SERVICE_CONFIG_STREAM_DLL_BUILD_DLL + + Source_Files { + Service_Config_Stream_DLL.cpp + } + Header_Files { + Service_Config_Stream_DLL.h + Service_Config_Stream_DLL_Export.h + } + Resource_Files { + } +} + +project(Service Config Stream Test) : acetest { + after += Service_Config_Stream_DLL + exename = Service_Config_Stream_Test + Source_Files { + Service_Config_Stream_Test.cpp + } +} + +project(Bug_3334_Regression_Test) : acetest { + after += Service_Config_Stream_DLL + exename = Bug_3334_Regression_Test + Source_Files { + Bug_3334_Regression_Test.cpp + } +} |