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
This commit is contained in:
Francesco Montorsi
2010-07-25 13:55:36 +00:00
parent 79b7701c0b
commit 89a76d5d2c
3 changed files with 21 additions and 7 deletions

View File

@@ -788,7 +788,7 @@ enum
if (m_pThread) // does the thread still exist? 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 ) if (m_pThread->Delete() != wxTHREAD_NO_ERROR )
wxLogError("Can't delete the thread!"); wxLogError("Can't delete the thread!");
@@ -1125,6 +1125,10 @@ public:
of detached threads. of detached threads.
This function can only be called from another thread context. 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(); wxThreadError Run();

View File

@@ -1077,11 +1077,8 @@ wxThreadError wxThread::Run()
{ {
wxCriticalSectionLocker lock(m_critsect); wxCriticalSectionLocker lock(m_critsect);
if ( m_internal->GetState() != STATE_NEW ) wxCHECK_MSG( m_internal->GetState() == STATE_NEW, wxTHREAD_RUNNING,
{ wxT("thread may only be started once after Create()") );
// actually, it may be almost any state at all, not only STATE_RUNNING
return wxTHREAD_RUNNING;
}
// the thread has just been created and is still suspended - let it run // the thread has just been created and is still suspended - let it run
return Resume(); return Resume();

View File

@@ -208,6 +208,7 @@ private:
CPPUNIT_TEST( TestDetached ); CPPUNIT_TEST( TestDetached );
CPPUNIT_TEST( TestThreadSuspend ); CPPUNIT_TEST( TestThreadSuspend );
CPPUNIT_TEST( TestThreadDelete ); CPPUNIT_TEST( TestThreadDelete );
CPPUNIT_TEST( TestThreadRun );
CPPUNIT_TEST( TestThreadConditions ); CPPUNIT_TEST( TestThreadConditions );
CPPUNIT_TEST( TestSemaphore ); CPPUNIT_TEST( TestSemaphore );
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
@@ -218,6 +219,7 @@ private:
void TestThreadSuspend(); void TestThreadSuspend();
void TestThreadDelete(); void TestThreadDelete();
void TestThreadRun();
void TestThreadConditions(); void TestThreadConditions();
DECLARE_NO_COPY_CLASS(MiscThreadTestCase) DECLARE_NO_COPY_CLASS(MiscThreadTestCase)
@@ -320,6 +322,7 @@ void MiscThreadTestCase::TestThreadSuspend()
void MiscThreadTestCase::TestThreadDelete() void MiscThreadTestCase::TestThreadDelete()
{ {
// FIXME:
// As above, using Sleep() is only for testing here - we must use some // As above, using Sleep() is only for testing here - we must use some
// synchronisation object instead to ensure that the thread is still // synchronisation object instead to ensure that the thread is still
// running when we delete it - deleting a detached thread which already // running when we delete it - deleting a detached thread which already
@@ -345,7 +348,7 @@ void MiscThreadTestCase::TestThreadDelete()
MyJoinableThread thread3(20); MyJoinableThread thread3(20);
CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread3.Run() ); CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread3.Run() );
CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread3.Delete() ); CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread3.Delete() );
// delete a joinable thread // delete a joinable running thread
MyJoinableThread thread4(2); MyJoinableThread thread4(2);
CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread4.Run() ); CPPUNIT_ASSERT_EQUAL( wxTHREAD_NO_ERROR, thread4.Run() );
@@ -354,6 +357,16 @@ void MiscThreadTestCase::TestThreadDelete()
// delete a joinable thread which already terminated // 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() void MiscThreadTestCase::TestThreadConditions()
{ {
wxMutex mutex; wxMutex mutex;