summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog39
-rw-r--r--ace/OS_NS_Thread.cpp16
-rw-r--r--ace/OS_NS_Thread.h14
-rw-r--r--ace/OS_NS_dlfcn.inl4
-rw-r--r--ace/OS_NS_string.cpp1
-rw-r--r--ace/OS_NS_sys_utsname.cpp5
-rw-r--r--ace/Pipe.cpp1
-rw-r--r--ace/SV_Message_Queue.h1
-rw-r--r--ace/SV_Semaphore_Simple.h1
-rw-r--r--ace/SV_Shared_Memory.h1
-rw-r--r--ace/config-lite.h1
-rw-r--r--ace/config-vxworks5.x.h5
-rw-r--r--ace/os_include/os_signal.h2
-rw-r--r--ace/os_include/os_unistd.h2
-rw-r--r--tests/TSS_Static_Test.cpp113
-rw-r--r--tests/run_test.lst1
-rw-r--r--tests/tests.mpc7
17 files changed, 207 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 32ef183a69b..3151cd0ead5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+Tue Dec 9 09:23:06 2003 Chad Elliott <elliott_c@ociweb.com>
+
+ * ace/OS_NS_Thread.h:
+ * ace/OS_NS_Thread.cpp:
+
+ Worked around a bug in the VxWorks OS loader that caused complex
+ objects to be constructed multiple times. Instead of having a
+ static ACE_TSS_Keys object within the ACE_TSS_Emulation class, we
+ have a static pointer that is allocated upon the first call of
+ ACE_TSS_Emulation::next_key().
+
+ * ace/OS_NS_dlfcn.inl:
+ * ace/OS_NS_string.cpp:
+ * ace/OS_NS_sys_utsname.cpp:
+ * ace/Pipe.cpp:
+ * ace/SV_Message_Queue.h:
+ * ace/SV_Semaphore_Simple.h:
+ * ace/SV_Shared_Memory.h:
+ * ace/config-lite.h:
+ * ace/config-vxworks5.x.h:
+
+ Added #includes necessary for building on VxWorks.
+
+ * ace/os_include/os_signal.h:
+
+ Changed NSIG to ACE_NSIG.
+
+ * ace/os_include/os_unistd.h:
+
+ Added #include <hostLib.h> for gethostname().
+
+ * tests/TSS_Static_Test.cpp:
+ * tests/run_test.lst:
+ * tests/tests.mpc:
+
+ Added a test to ensure that TSS used during static construction
+ functions properly. This test only performs a test if TSS
+ emulation is used.
+
Tue Dec 9 15:09:55 UTC 2003 Don Hinton <dhinton@dresystems.com>
Thanks to Bruce Jones <bruce.jones@cubic.com> for the
diff --git a/ace/OS_NS_Thread.cpp b/ace/OS_NS_Thread.cpp
index b11a9e4ee74..ead5b571151 100644
--- a/ace/OS_NS_Thread.cpp
+++ b/ace/OS_NS_Thread.cpp
@@ -16,6 +16,7 @@ ACE_RCSID(ace, OS_NS_Thread, "$Id$")
#include "ace/Min_Max.h"
#include "ace/Object_Manager_Base.h"
#include "ace/OS_NS_errno.h"
+#include "ace/OS_NS_ctype.h"
// This is necessary to work around nasty problems with MVS C++.
@@ -206,7 +207,7 @@ ACE_Thread_ID::operator!= (const ACE_Thread_ID &rhs) const
#if defined (ACE_HAS_TSS_EMULATION)
u_int ACE_TSS_Emulation::total_keys_ = 0;
-ACE_TSS_Keys ACE_TSS_Emulation::tss_keys_used_;
+ACE_TSS_Keys* ACE_TSS_Emulation::tss_keys_used_ = 0;
ACE_TSS_Emulation::ACE_TSS_DESTRUCTOR
ACE_TSS_Emulation::tss_destructor_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX]
@@ -334,6 +335,12 @@ ACE_TSS_Emulation::next_key (ACE_thread_key_t &key)
ACE_OS_Object_Manager::preallocated_object[
ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
+ // Initialize the tss_keys_used_ pointer on first use.
+ if (tss_keys_used_ == 0)
+ {
+ ACE_NEW_RETURN (tss_keys_used_, ACE_TSS_Keys, -1);
+ }
+
if (total_keys_ < ACE_TSS_THREAD_KEYS_MAX)
{
u_int counter = 0;
@@ -349,9 +356,9 @@ ACE_TSS_Emulation::next_key (ACE_thread_key_t &key)
# endif /* ACE_HAS_NONSCALAR_THREAD_KEY_T */
// If the key is not set as used, we can give out this key, if not
// we have to search further
- if (tss_keys_used_.is_set(localkey) == 0)
+ if (tss_keys_used_->is_set(localkey) == 0)
{
- tss_keys_used_.test_and_set(localkey);
+ tss_keys_used_->test_and_set(localkey);
key = localkey;
break;
}
@@ -375,7 +382,8 @@ ACE_TSS_Emulation::release_key (ACE_thread_key_t key)
ACE_OS_Object_Manager::preallocated_object[
ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
- if (tss_keys_used_.test_and_clear (key) == 0)
+ if (tss_keys_used_ != 0 &&
+ tss_keys_used_->test_and_clear (key) == 0)
{
--total_keys_;
return 0;
diff --git a/ace/OS_NS_Thread.h b/ace/OS_NS_Thread.h
index d68d1ac372f..08663a51a52 100644
--- a/ace/OS_NS_Thread.h
+++ b/ace/OS_NS_Thread.h
@@ -842,8 +842,18 @@ private:
static ACE_TSS_DESTRUCTOR tss_destructor_ [ACE_TSS_THREAD_KEYS_MAX];
/// TSS_Keys instance to administrate whether a specific key is in used
- /// or not
- static ACE_TSS_Keys tss_keys_used_;
+ /// or not.
+ /// or not.
+ // Static construction in VxWorks 5.4 and later is slightly broken.
+ // If the static object is more complex than an integral type, static
+ // construction will occur twice. The tss_keys_used_ object is
+ // statically constructed and then modified by ACE_Log_Msg::instance()
+ // when two keys are created and TSS data is stored. However, at
+ // the end of static construction the tss_keys_used_ object is again
+ // initialized and therefore it will appear to next_key() that no
+ // TSS keys have been handed out. That is all true unless the
+ // tss_keys_used object is a static pointer instead of a static object.
+ static ACE_TSS_Keys* tss_keys_used_;
# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
/// Location of current thread's TSS array.
diff --git a/ace/OS_NS_dlfcn.inl b/ace/OS_NS_dlfcn.inl
index 6899497ffa4..d39908d1718 100644
--- a/ace/OS_NS_dlfcn.inl
+++ b/ace/OS_NS_dlfcn.inl
@@ -3,6 +3,10 @@
#include "ace/OS_NS_macros.h"
#include "ace/OS_NS_errno.h"
+#include "ace/OS.h"
+#include "ace/Default_Constants.h"
+#include "ace/os_include/os_fcntl.h"
+#include "ace/os_include/os_string.h"
#if defined (ACE_USES_ASM_SYMBOL_IN_DLSYM)
# include "ace/OS_Memory.h"
diff --git a/ace/OS_NS_string.cpp b/ace/OS_NS_string.cpp
index f0f593ab27c..d2182415a74 100644
--- a/ace/OS_NS_string.cpp
+++ b/ace/OS_NS_string.cpp
@@ -2,6 +2,7 @@
// $Id$
#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_stdlib.h"
ACE_RCSID(ace, OS_NS_string, "$Id$")
diff --git a/ace/OS_NS_sys_utsname.cpp b/ace/OS_NS_sys_utsname.cpp
index 50fe478633c..62d8476b53a 100644
--- a/ace/OS_NS_sys_utsname.cpp
+++ b/ace/OS_NS_sys_utsname.cpp
@@ -13,6 +13,11 @@ ACE_RCSID(ace, OS_NS_sys_utsname, "$Id$")
#include "ace/OS_NS_stdio.h"
#include "ace/OS_NS_unistd.h"
+#if defined (VXWORKS)
+// for sysBspRev(), sysModel()
+# include /**/ <sysLib.h>
+#endif /* VXWORKS */
+
#if defined (ACE_WIN32) || defined (VXWORKS) || defined (CHORUS) || defined (ACE_PSOS)
// Don't inline on those platforms because this function contains
// string literals, and some compilers, e.g., g++, don't handle those
diff --git a/ace/Pipe.cpp b/ace/Pipe.cpp
index b1f9d240acc..44798756127 100644
--- a/ace/Pipe.cpp
+++ b/ace/Pipe.cpp
@@ -4,6 +4,7 @@
#include "ace/SOCK_Acceptor.h"
#include "ace/SOCK_Connector.h"
#include "ace/Log_Msg.h"
+#include "ace/os_include/netinet/os_tcp.h"
#if defined (ACE_LACKS_INLINE_FUNCTIONS)
#include "ace/Pipe.i"
diff --git a/ace/SV_Message_Queue.h b/ace/SV_Message_Queue.h
index 5c813805573..0fcbeaf0751 100644
--- a/ace/SV_Message_Queue.h
+++ b/ace/SV_Message_Queue.h
@@ -22,6 +22,7 @@
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/SV_Message.h"
+#include "ace/os_include/sys/os_stat.h"
#include "ace/os_include/sys/os_ipc.h"
#include "ace/Default_Constants.h"
diff --git a/ace/SV_Semaphore_Simple.h b/ace/SV_Semaphore_Simple.h
index b2471d03a9a..a7d34ea7d3c 100644
--- a/ace/SV_Semaphore_Simple.h
+++ b/ace/SV_Semaphore_Simple.h
@@ -21,6 +21,7 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+#include "ace/os_include/sys/os_stat.h"
#include "ace/os_include/sys/os_ipc.h"
#include "ace/os_include/sys/os_sem.h"
#include "ace/Default_Constants.h"
diff --git a/ace/SV_Shared_Memory.h b/ace/SV_Shared_Memory.h
index 71faf4e8b4d..63d72c4fa1c 100644
--- a/ace/SV_Shared_Memory.h
+++ b/ace/SV_Shared_Memory.h
@@ -21,6 +21,7 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+#include "ace/os_include/sys/os_stat.h"
#include "ace/os_include/sys/os_ipc.h"
#include "ace/Default_Constants.h"
diff --git a/ace/config-lite.h b/ace/config-lite.h
index f9d1eed04cf..c048cbbf575 100644
--- a/ace/config-lite.h
+++ b/ace/config-lite.h
@@ -583,6 +583,7 @@ typedef ACE_HANDLE ACE_SOCKET;
// everywhere to deal with the possibility of no return type.
# if defined (VXWORKS)
//typedef FUNCPTR ACE_THR_FUNC; // where typedef int (*FUNCPTR) (...)
+# include <taskLib.h>
typedef int ACE_THR_FUNC_RETURN;
# elif defined (ACE_PSOS)
typedef int ACE_THR_FUNC_RETURN;
diff --git a/ace/config-vxworks5.x.h b/ace/config-vxworks5.x.h
index 7f3b61198d2..181cec392fa 100644
--- a/ace/config-vxworks5.x.h
+++ b/ace/config-vxworks5.x.h
@@ -189,6 +189,11 @@
#define ACE_LACKS_SYS_MSG_H
#define ACE_LACKS_WCHAR_H
#define ACE_LACKS_PWD_H
+#define ACE_LACKS_SEARCH_H
+#define ACE_LACKS_SYS_SHM_H
+#define ACE_LACKS_STRINGS_H
+#define ACE_LACKS_TERMIOS_H
+#define ACE_LACKS_POLL_H
// Not sure if these should always be defined.
#define ACE_LACKS_SYS_UN_H
diff --git a/ace/os_include/os_signal.h b/ace/os_include/os_signal.h
index 1f5d53453cd..b3426bf0add 100644
--- a/ace/os_include/os_signal.h
+++ b/ace/os_include/os_signal.h
@@ -195,7 +195,7 @@ extern "C"
#endif /* ACE_PSOS && !ACE_PSOSIM */
#if defined (VXWORKS)
-# define NSIG (_NSIGS + 1)
+# define ACE_NSIG (_NSIGS + 1)
#elif defined (__Lynx__)
// LynxOS Neutrino sets NSIG to the highest-numbered signal.
# define ACE_NSIG (NSIG + 1)
diff --git a/ace/os_include/os_unistd.h b/ace/os_include/os_unistd.h
index c7d7aafc3a5..e8a8e69407b 100644
--- a/ace/os_include/os_unistd.h
+++ b/ace/os_include/os_unistd.h
@@ -48,6 +48,8 @@
// for unlink(), close(), read(), write(), lseek(), chdir(), getcwd(), getwd(),
// and isatty()
# include /**/ <ioLib.h>
+// for gethostname()
+# include /**/ <hostLib.h>
#endif /* VXWORKS */
// Place all additions (especially function declarations) within extern "C" {}
diff --git a/tests/TSS_Static_Test.cpp b/tests/TSS_Static_Test.cpp
new file mode 100644
index 00000000000..40e0b6d9e57
--- /dev/null
+++ b/tests/TSS_Static_Test.cpp
@@ -0,0 +1,113 @@
+// $Id$
+
+// ============================================================================
+//
+// = FILENAME
+// TSS_Static_Test.cpp
+//
+// = DESCRIPTION
+// This program tests the interaction between TSS and thread keys
+// created during static construction. VxWorks static construction
+// is quite broken. This test is designed to test changes to work
+// around a bug in the VxWorks loader that constructs static objects
+// multiple times. It sounds hard to believe, but I've seen it!
+//
+// = AUTHOR
+// Chad Elliott <elliott_c@ociweb.com>
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "ace/ACE.h"
+#include "ace/Thread.h"
+
+ACE_RCSID(tests, TSS_Static_Test, "$Id$")
+
+#if defined (ACE_HAS_TSS_EMULATION)
+
+class Some_Object
+{
+public:
+ Some_Object (void);
+ ~Some_Object (void);
+};
+
+Some_Object::Some_Object (void)
+{
+ ACE::init ();
+
+ // Cause the ACE_Log_Msg to be constructed during static construction
+ ACE_DEBUG ((LM_DEBUG, ""));
+
+ // Assign something to TSS during static construction
+ ACE_thread_key_t key;
+ if (ACE_Thread::keycreate (&key, 0) == 0)
+ {
+ ACE_Thread::setspecific (key, this);
+ }
+}
+
+
+Some_Object::~Some_Object (void)
+{
+ ACE::fini ();
+}
+
+
+static Some_Object sobject;
+
+int
+run_main (int, ACE_TCHAR *[])
+{
+ ACE_START_TEST (ACE_TEXT ("TSS_Static_Test"));
+
+ int status = 0;
+ ACE_thread_key_t key;
+ if (ACE_Thread::keycreate (&key, 0) == 0)
+ {
+ void* specific = 0;
+ if (ACE_Thread::getspecific (key, &specific) == 0)
+ {
+ if (specific == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Got back pointer: %x from key: %d. "
+ "Good!\n",
+ (size_t)specific, key));
+ }
+ else
+ {
+ ++status;
+ ACE_ERROR ((LM_ERROR, "Something (%x) was found in tss "
+ "slot %d.\n"
+ "Nothing should be stored in our "
+ "TSS slot!\n",
+ (size_t)specific, key));
+ }
+ }
+ else
+ {
+ ++status;
+ ACE_ERROR ((LM_ERROR, "Unable to get the thread specific "
+ "storage.\n"));
+ }
+ }
+ else
+ {
+ ++status;
+ ACE_ERROR ((LM_ERROR, "Unable to create the thread specific "
+ "storage key.\n"));
+ }
+ ACE_END_TEST;
+ return status;
+}
+#else
+int
+run_main (int, ACE_TCHAR *[])
+{
+ ACE_START_TEST (ACE_TEXT ("TSS_Static_Test"));
+ ACE_DEBUG ((LM_INFO, ACE_TEXT ("This test requires TSS Emulation.\n")));
+ ACE_END_TEST;
+ return 0;
+}
+#endif /* ACE_HAS_TSS_EMULATION */
+
diff --git a/tests/run_test.lst b/tests/run_test.lst
index cc1486e92b1..67a894cab9e 100644
--- a/tests/run_test.lst
+++ b/tests/run_test.lst
@@ -123,6 +123,7 @@ Simple_Message_Block_Test: !chorus
Svc_Handler_Test
TP_Reactor_Test: ALL
TSS_Test
+TSS_Static_Test
Task_Test
Task_Ex_Test
Thread_Manager_Test: !Unicos
diff --git a/tests/tests.mpc b/tests/tests.mpc
index 03c2c9cee7e..df94787eb86 100644
--- a/tests/tests.mpc
+++ b/tests/tests.mpc
@@ -839,6 +839,13 @@ project(TSS Test) : acetest {
}
}
+project(TSS Static Test) : acetest {
+ exename = TSS_Static_Test
+ Source_Files {
+ TSS_Static_Test.cpp
+ }
+}
+
project(Vector Test) : acetest {
exename = Vector_Test
Source_Files {