summaryrefslogtreecommitdiff
path: root/ACE
diff options
context:
space:
mode:
authorcbeaulac <cbeaulac@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2011-05-04 15:15:38 +0000
committercbeaulac <cbeaulac@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2011-05-04 15:15:38 +0000
commit0c3d7d489ff19e13c4f5e3d82e0ac00ab0b61202 (patch)
tree8cdf88d537fb981116aa4251c8e76eecc427e695 /ACE
parent1c9566997efef1c0c62f8705bd4d21638eb20e00 (diff)
downloadATCD-0c3d7d489ff19e13c4f5e3d82e0ac00ab0b61202.tar.gz
Wed May 4 15:07:46 UTC 2011 Chad Beaulac <chad.beaulac@objectivesolutions.com>
* ace/Stream.cpp: Modified ACE_Stream::remove(name,flags) so close is always called on the module that's removed regardless of the flags. Close needs to be called to ensure proper lifecycle management when the ACE_Service_Repository shuts down in its fini method. Bugzilla #3912 * tests/Bug_3912_Regression_Test.conf: * tests/Bug_3912_Regression_Test.cpp: * tests/run_test.lst * tests/test.mpc Added test to assert that close is called.
Diffstat (limited to 'ACE')
-rw-r--r--ACE/ace/Stream.cpp6
-rw-r--r--ACE/tests/Bug_3912_Regression_Test.conf5
-rw-r--r--ACE/tests/Bug_3912_Regression_Test.cpp129
-rw-r--r--ACE/tests/run_test.lst1
-rw-r--r--ACE/tests/tests.mpc9
5 files changed, 147 insertions, 3 deletions
diff --git a/ACE/ace/Stream.cpp b/ACE/ace/Stream.cpp
index 1346e0dda20..74185923911 100644
--- a/ACE/ace/Stream.cpp
+++ b/ACE/ace/Stream.cpp
@@ -260,12 +260,12 @@ ACE_Stream<ACE_SYNCH_USE>::remove (const ACE_TCHAR *name,
else
prev->link (mod->next ());
+ // Close down the module.
+ mod->close (flags);
+
// Don't delete the Module unless the flags request this.
if (flags != ACE_Module<ACE_SYNCH_USE>::M_DELETE_NONE)
{
- // Close down the module.
- mod->close (flags);
-
// Release the memory.
delete mod;
}
diff --git a/ACE/tests/Bug_3912_Regression_Test.conf b/ACE/tests/Bug_3912_Regression_Test.conf
new file mode 100644
index 00000000000..3095958ffe9
--- /dev/null
+++ b/ACE/tests/Bug_3912_Regression_Test.conf
@@ -0,0 +1,5 @@
+stream dynamic Close_Test_Stream STREAM *Service_Config_Stream_DLL:make_stream() active
+{
+ dynamic Close_Test_Module Module *Service_Config_Stream_DLL:make_close()
+}
+
diff --git a/ACE/tests/Bug_3912_Regression_Test.cpp b/ACE/tests/Bug_3912_Regression_Test.cpp
new file mode 100644
index 00000000000..4824f4b3d6b
--- /dev/null
+++ b/ACE/tests/Bug_3912_Regression_Test.cpp
@@ -0,0 +1,129 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = DESCRIPTION
+// This test asserts that close is called on Modules during
+// ACE_Service_Repository shutdown
+//
+// = AUTHOR
+// Chad Beaulac <chad@objectivesolutions.com>
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "Service_Config_Stream_DLL.h"
+
+#include "ace/Log_Msg.h"
+#include "ace/Service_Config.h"
+#include "ace/Service_Repository.h"
+#include "ace/Service_Object.h"
+#include "ace/Service_Types.h"
+
+
+/**
+ * We use this Task to track if close was called.
+ */
+class Close_Handler : public virtual MT_Task
+{
+public:
+
+ Close_Handler(int* close_called_arg) : close_called(close_called_arg)
+ {
+ }
+
+ virtual int
+ close(u_long flags)
+ {
+ *close_called = 1;
+ }
+
+private:
+ int* close_called;
+
+};
+
+int
+run_main(int, ACE_TCHAR *argv[])
+{
+ ACE_START_TEST (ACE_TEXT ("Bug_3912_Regression_Test"));
+
+ ACE_TCHAR * _argv[3] = {argv[0],
+ const_cast<ACE_TCHAR*> (ACE_TEXT ("-f")),
+ const_cast<ACE_TCHAR*>
+ (ACE_TEXT ("Bug_3912_Regression_Test.conf"))};
+ int status = 0;
+
+ int close_called = 0;
+ Close_Handler* close_handler = new Close_Handler (&close_called);
+
+ 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));
+
+ const ACE_Service_Type* st = 0;
+ if (ACE_Service_Repository::instance ()->find ("Close_Test_Module", &st) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("Couldn't find Close_Test_Module in ASR"),
+ 1));
+ status++;
+ }
+ else
+ {
+ //
+ // Put our Close_Handler Task into the Module
+ //
+ MT_Module* close_test_module = (MT_Module*) (st->type ()->object ());
+ close_test_module->reader (close_handler);
+ }
+ //
+ // Find the Stream that the Module is in.
+ //
+ const ACE_Service_Type* st2 = 0;
+ if (ACE_Service_Repository::instance ()->find ("Close_Test_Stream", &st2) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("Couldn't find Close_Test_Stream in ASR"),
+ 1));
+ status++;
+ }
+ else
+ {
+ //
+ // Remove the Module from the Stream.
+ // This is what happens during ACE_Service_Repository::fini
+ // We want to make sure that close is called on Modules and their Tasks
+ // at this time to ensure proper cleanup during the shutdown sequence
+ // by getting the close methods called so user shutdown hooks can fire.
+ //
+ ACE_Stream_Type* close_test_stream = (ACE_Stream_Type*) (st2->type ());
+
+ close_test_stream->remove ((ACE_Module_Type*)(st->type ()));
+
+ if (close_called != 1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("Module::close not called"),
+ 1));
+ status++;
+ }
+ }
+
+ ACE_Service_Config::fini_svcs ();
+
+ ACE_END_TEST;
+ return status;
+}
diff --git a/ACE/tests/run_test.lst b/ACE/tests/run_test.lst
index d14ea58d1a0..47bacd10444 100644
--- a/ACE/tests/run_test.lst
+++ b/ACE/tests/run_test.lst
@@ -62,6 +62,7 @@ Bug_3744_Regression_Test: !FIXED_BUGS_ONLY
Bug_3758_Regression_Test: !FIXED_BUGS_ONLY
Bug_3878_Regression_Test
Bug_3911_Regression_Test: !FIXED_BUGS_ONLY !ACE_FOR_TAO
+Bug_3912_Regression_Test: !STATIC
Bug_3943_Regression_Test: !ACE_FOR_TAO
CDR_Array_Test: !ACE_FOR_TAO
CDR_File_Test: !ACE_FOR_TAO
diff --git a/ACE/tests/tests.mpc b/ACE/tests/tests.mpc
index 4905347d2df..46bb67f3228 100644
--- a/ACE/tests/tests.mpc
+++ b/ACE/tests/tests.mpc
@@ -1956,6 +1956,15 @@ project(Bug_3334_Regression_Test) : acetest {
}
}
+project(Bug_3912_Regression_Test) : acetest {
+ after += Service_Config_Stream_DLL
+ libs += Service_Config_Stream_DLL
+ exename = Bug_3912_Regression_Test
+ Source_Files {
+ Bug_3912_Regression_Test.cpp
+ }
+}
+
project(Missing_Svc_Conf_Test) : acetest {
exename = Missing_Svc_Conf_Test
Source_Files {