From 89a76d5d2c1620f8118780f0a29030f2b2a45023 Mon Sep 17 00:00:00 2001 From: Francesco Montorsi Date: Sun, 25 Jul 2010 13:55:36 +0000 Subject: [PATCH] make POSIX and Windows implementation of wxThread::Run() coherently assert when trying to Run() a thread twice; add a test for it. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65106 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- interface/wx/thread.h | 6 +++++- src/msw/thread.cpp | 7 ++----- tests/thread/misc.cpp | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/interface/wx/thread.h b/interface/wx/thread.h index 9966730..34d9846 100644 --- a/interface/wx/thread.h +++ b/interface/wx/thread.h @@ -788,7 +788,7 @@ enum if (m_pThread) // does the thread still exist? { - m_out.Printf("MYFRAME: deleting thread"); + wxMessageOutputDebug().Printf("MYFRAME: deleting thread"); if (m_pThread->Delete() != wxTHREAD_NO_ERROR ) wxLogError("Can't delete the thread!"); @@ -1125,6 +1125,10 @@ public: of detached threads. This function can only be called from another thread context. + + Finally, note that once a thread has completed and its Entry() function + returns, you cannot call Run() on it again (an assert will fail in debug + builds or @c wxTHREAD_RUNNING will be returned in release builds). */ wxThreadError Run(); diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index 6fe0d3b..5871564 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -1077,11 +1077,8 @@ wxThreadError wxThread::Run() { wxCriticalSectionLocker lock(m_critsect); - if ( m_internal->GetState() != STATE_NEW ) - { - // actually, it may be almost any state at all, not only STATE_RUNNING - return wxTHREAD_RUNNING; - } + wxCHECK_MSG( m_internal->GetState() == STATE_NEW, wxTHREAD_RUNNING, + wxT("thread may only be started once after Create()") ); // the thread has just been created and is still suspended - let it run return Resume(); diff --git a/tests/thread/misc.cpp b/tests/thread/misc.cpp index 38473a7..5dcab15 100644 --- a/tests/thread/misc.cpp +++ b/tests/thread/misc.cpp @@ -208,6 +208,7 @@ private: CPPUNIT_TEST( TestDetached ); CPPUNIT_TEST( TestThreadSuspend ); CPPUNIT_TEST( TestThreadDelete ); + CPPUNIT_TEST( TestThreadRun ); CPPUNIT_TEST( TestThreadConditions ); CPPUNIT_TEST( TestSemaphore ); CPPUNIT_TEST_SUITE_END(); @@ -218,6 +219,7 @@ private: void TestThreadSuspend(); void TestThreadDelete(); + void TestThreadRun(); void TestThreadConditions(); DECLARE_NO_COPY_CLASS(MiscThreadTestCase) @@ -320,6 +322,7 @@ void MiscThreadTestCase::TestThreadSuspend() void MiscThreadTestCase::TestThreadDelete() { + // FIXME: // As above, using Sleep() is only for testing here - we must use some // synchronisation object instead to ensure that the thread is still // running when we delete it - deleting a detached thread which already @@ -345,7 +348,7 @@ void MiscThreadTestCase::TestThreadDelete() MyJoinableThread thread3(20); CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread3.Run() ); CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread3.Delete() ); - // delete a joinable thread + // delete a joinable running thread MyJoinableThread thread4(2); CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread4.Run() ); @@ -354,6 +357,16 @@ void MiscThreadTestCase::TestThreadDelete() // delete a joinable thread which already terminated } +void MiscThreadTestCase::TestThreadRun() +{ + MyJoinableThread thread1(2); + CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread1.Run() ); + thread1.Wait(); // wait until the thread ends + + // verify that running twice the same thread fails + WX_ASSERT_FAILS_WITH_ASSERT( thread1.Run() ); +} + void MiscThreadTestCase::TestThreadConditions() { wxMutex mutex; -- 2.7.4