diff options
author | Steve Huston <shuston@riverace.com> | 2013-10-22 19:44:38 +0000 |
---|---|---|
committer | Steve Huston <shuston@riverace.com> | 2013-10-22 19:44:38 +0000 |
commit | 64baabeb14d3f4007712067fb55bbc645e4205b4 (patch) | |
tree | 18bbfd56123c5e4796664a428c1d171975a0fed7 | |
parent | c005ad796f45a473106815db650c81bb387f3468 (diff) | |
download | ATCD-64baabeb14d3f4007712067fb55bbc645e4205b4.tar.gz |
ChangeLogTag:Tue Oct 22 19:37:43 UTC 2013 Steve Huston <shuston@riverace.com>
-rw-r--r-- | ACE/ChangeLog | 13 | ||||
-rw-r--r-- | ACE/NEWS | 5 | ||||
-rw-r--r-- | ACE/ace/OS_NS_Thread.inl | 16 | ||||
-rw-r--r-- | ACE/tests/Task_Wait_Test.cpp | 19 |
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: @@ -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; |