summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2013-10-22 19:44:38 +0000
committerSteve Huston <shuston@riverace.com>2013-10-22 19:44:38 +0000
commit64baabeb14d3f4007712067fb55bbc645e4205b4 (patch)
tree18bbfd56123c5e4796664a428c1d171975a0fed7
parentc005ad796f45a473106815db650c81bb387f3468 (diff)
downloadATCD-64baabeb14d3f4007712067fb55bbc645e4205b4.tar.gz
ChangeLogTag:Tue Oct 22 19:37:43 UTC 2013 Steve Huston <shuston@riverace.com>
-rw-r--r--ACE/ChangeLog13
-rw-r--r--ACE/NEWS5
-rw-r--r--ACE/ace/OS_NS_Thread.inl16
-rw-r--r--ACE/tests/Task_Wait_Test.cpp19
4 files changed, 48 insertions, 5 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog
index 250a993ae09..1deddd2fd9a 100644
--- a/ACE/ChangeLog
+++ b/ACE/ChangeLog
@@ -1,3 +1,16 @@
+Tue Oct 22 19:37:43 UTC 2013 Steve Huston <shuston@riverace.com>
+
+ * ace/OS_NS_Thread.inl (thr_join): Add deadlock detection for Windows
+ at Vista/WinSvr2003 or higher. Prevents a thread calling join on
+ itself from deadlocking, making the behavior similar to that of
+ Pthreads, etc.
+
+ * tests/Task_Wait_Test.cpp: Don't try this test on Windows systems
+ without the deadlock detection available above. It hangs and there's
+ little to be done about it.
+
+ * NEWS: Added the deadlock feature description.
+
Tue Oct 22 17:20:09 UTC 2013 Johnny Willemsen <jwillemsen@remedy.nl>
* include/makeinclude/platform_g++_common.GNU:
diff --git a/ACE/NEWS b/ACE/NEWS
index 053ae5429be..37a1fd73498 100644
--- a/ACE/NEWS
+++ b/ACE/NEWS
@@ -1,6 +1,11 @@
USER VISIBLE CHANGES BETWEEN ACE-6.2.2 and ACE-6.2.3
====================================================
+. The ACE_OS::thr_join() method will detect if the thread to be waited on is
+ the calling thread and avert that deadlock. The support needed for this
+ method is available at Vista/Windows Server 2003 and higher; to enable
+ the deadlock prevention, compile ACE with _WIN32_WINNT=0x0502 or higher.
+
. Ended maintenance and support for FC12 CEEL
USER VISIBLE CHANGES BETWEEN ACE-6.2.1 and ACE-6.2.2
diff --git a/ACE/ace/OS_NS_Thread.inl b/ACE/ace/OS_NS_Thread.inl
index f7593d93be7..4977c416908 100644
--- a/ACE/ace/OS_NS_Thread.inl
+++ b/ACE/ace/OS_NS_Thread.inl
@@ -2942,6 +2942,22 @@ ACE_OS::thr_join (ACE_hthread_t thr_handle,
ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_join (thr_handle, status), result),
int, -1);
# elif defined (ACE_HAS_WTHREADS)
+ // Waiting on the calling thread will deadlock, so try to avoid that. The
+ // direct access to the needed info (GetThreadId) was added at Vista.
+ // Win Server 2003 is 5.2; Vista is 6.0
+# if defined (_WIN32_WINNT) && (_WIN32_WINNT >= 0x0502)
+ const ACE_TEXT_OSVERSIONINFO &info = ACE_OS::get_win32_versioninfo ();
+ if (info.dwMajorVersion >= 6 ||
+ (info.dwMajorVersion == 5 && info.dwMinorVersion == 2))
+ {
+ if (::GetThreadId (thr_handle) == ::GetCurrentThreadId ())
+ {
+ errno = ERROR_POSSIBLE_DEADLOCK;
+ return -1;
+ }
+ }
+# endif /* _WIN32_WINNT */
+
ACE_THR_FUNC_RETURN local_status = 0;
// Make sure that status is non-NULL.
diff --git a/ACE/tests/Task_Wait_Test.cpp b/ACE/tests/Task_Wait_Test.cpp
index 95df9a87f5b..8eb1cab736d 100644
--- a/ACE/tests/Task_Wait_Test.cpp
+++ b/ACE/tests/Task_Wait_Test.cpp
@@ -18,7 +18,16 @@
#include "ace/Task.h"
#include "ace/OS_NS_unistd.h"
-#if defined (ACE_HAS_THREADS)
+// On Windows, this test will deadlock because a thread tries to join with
+// itself. Pthreads, et al, have deadlock protection in join; Windows Vista
+// and Server 2003 have API to access the info needed to check for deadlock
+// in ACE_OS::thr_join() - don't run this test on earlier Windows versions
+// because it will hang/time out and there's little to be done about it.
+#if defined (ACE_HAS_THREADS) && ((defined (_WIN32_WINNT) && (_WIN32_WINNT >= 0x0502)) || !defined (WIN32))
+# define RUN_THIS_TEST
+#endif
+
+#ifdef RUN_THIS_TEST
static ACE_Event TaskDone;
@@ -57,7 +66,7 @@ Do_Nothing_Task::svc (void)
return 0;
}
-#endif /* ACE_HAS_THREADS */
+#endif /* RUN_THIS_TEST */
int
run_main (int, ACE_TCHAR *[])
@@ -65,7 +74,7 @@ run_main (int, ACE_TCHAR *[])
ACE_START_TEST (ACE_TEXT ("Task_Wait_Test"));
int status = 0;
-#if defined (ACE_HAS_THREADS)
+#if defined (RUN_THIS_TEST)
Do_Nothing_Task t;
status = t.activate ();
@@ -73,8 +82,8 @@ run_main (int, ACE_TCHAR *[])
#else
ACE_ERROR ((LM_INFO,
- ACE_TEXT ("threads not supported on this platform\n")));
-#endif /* ACE_HAS_THREADS */
+ ACE_TEXT ("inadequate thread support on this platform\n")));
+#endif /* RUN_THIS_TEST */
ACE_END_TEST;
return status;