| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 | 
							- ///////////////////////////////////////////////////////////////////////////////
 
- // Name:        tests/thread/queue.cpp
 
- // Purpose:     Unit test for wxMessageQueue
 
- // Author:      Evgeniy Tarassov
 
- // Created:     31/10/2007
 
- // Copyright:   (c) 2007 Evgeniy Tarassov
 
- // Licence:     wxWindows licence
 
- ///////////////////////////////////////////////////////////////////////////////
 
- // ----------------------------------------------------------------------------
 
- // headers
 
- // ----------------------------------------------------------------------------
 
- #include "testprec.h"
 
- #ifdef __BORLANDC__
 
-     #pragma hdrstop
 
- #endif
 
- #ifndef WX_PRECOMP
 
-     #include "wx/dynarray.h"
 
-     #include "wx/thread.h"
 
- #endif // WX_PRECOMP
 
- #include "wx/msgqueue.h"
 
- // ----------------------------------------------------------------------------
 
- // test class
 
- // ----------------------------------------------------------------------------
 
- class QueueTestCase : public CppUnit::TestCase
 
- {
 
- public:
 
-     QueueTestCase() { }
 
-     enum WaitTestType
 
-     {
 
-         WaitWithTimeout = 0,
 
-         WaitInfinitlyLong
 
-     };
 
- private:
 
-     typedef wxMessageQueue<int> Queue;
 
-     // This class represents a thread that waits (following WaitTestType type)
 
-     // for exactly maxMsgCount messages from its message queue and if another
 
-     // MyThread is specified, then every message received is posted
 
-     // to that next thread.
 
-     class MyThread : public wxThread
 
-     {
 
-     public:
 
-         MyThread(WaitTestType type, MyThread *next, int maxMsgCount)
 
-            : wxThread(wxTHREAD_JOINABLE),
 
-              m_type(type), m_nextThread(next), m_maxMsgCount(maxMsgCount)
 
-         {}
 
-         // thread execution starts here
 
-         virtual void *Entry();
 
-         // Thread message queue
 
-         Queue& GetQueue()
 
-         {
 
-             return m_queue;
 
-         }
 
-     private:
 
-         WaitTestType m_type;
 
-         MyThread*    m_nextThread;
 
-         int          m_maxMsgCount;
 
-         Queue        m_queue;
 
-     };
 
-     WX_DEFINE_ARRAY_PTR(MyThread *, ArrayThread);
 
-     CPPUNIT_TEST_SUITE( QueueTestCase );
 
-         CPPUNIT_TEST( TestReceive );
 
-         CPPUNIT_TEST( TestReceiveTimeout );
 
-     CPPUNIT_TEST_SUITE_END();
 
-     void TestReceive();
 
-     void TestReceiveTimeout();
 
-     DECLARE_NO_COPY_CLASS(QueueTestCase)
 
- };
 
- // register in the unnamed registry so that these tests are run by default
 
- CPPUNIT_TEST_SUITE_REGISTRATION( QueueTestCase );
 
- // also include in its own registry so that these tests can be run alone
 
- CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( QueueTestCase, "QueueTestCase" );
 
- // this function creates the given number of threads and posts msgCount
 
- // messages to the last created thread which, in turn, posts all the messages
 
- // it receives to the previously created thread which does the same and so on
 
- // in cascade -- at the end, each thread will have received all msgCount
 
- // messages directly or indirectly
 
- void QueueTestCase::TestReceive()
 
- {
 
-     const int msgCount = 100;
 
-     const int threadCount = 10;
 
-     ArrayThread threads;
 
-     int i;
 
-     for ( i = 0; i < threadCount; ++i )
 
-     {
 
-         MyThread *previousThread = i == 0 ? NULL : threads[i-1];
 
-         MyThread *thread =
 
-             new MyThread(WaitInfinitlyLong, previousThread, msgCount);
 
-         CPPUNIT_ASSERT_EQUAL ( thread->Create(), wxTHREAD_NO_ERROR );
 
-         threads.Add(thread);
 
-     }
 
-     for ( i = 0; i < threadCount; ++i )
 
-     {
 
-         threads[i]->Run();
 
-     }
 
-     MyThread* lastThread = threads[threadCount - 1];
 
-     for ( i = 0; i < msgCount; ++i )
 
-     {
 
-         lastThread->GetQueue().Post(i);
 
-     }
 
-     for ( i = 0; i < threadCount; ++i )
 
-     {
 
-         // each thread should return the number of messages received.
 
-         // if it returns a negative, then it detected some problem.
 
-         wxThread::ExitCode code = threads[i]->Wait();
 
-         CPPUNIT_ASSERT_EQUAL( code, (wxThread::ExitCode)wxMSGQUEUE_NO_ERROR );
 
-     }
 
- }
 
- // this function creates two threads, each one waiting (with a timeout) for
 
- // exactly two messages.
 
- // Exactly to messages are posted into first thread queue, but
 
- // only one message is posted to the second thread queue.
 
- // Therefore first thread should return with wxMSGQUEUE_NO_ERROR, but the second
 
- // should return wxMSGQUEUUE_TIMEOUT.
 
- void QueueTestCase::TestReceiveTimeout()
 
- {
 
-     MyThread* thread1 = new MyThread(WaitWithTimeout, NULL, 2);
 
-     MyThread* thread2 = new MyThread(WaitWithTimeout, NULL, 2);
 
-     CPPUNIT_ASSERT_EQUAL ( thread1->Create(), wxTHREAD_NO_ERROR );
 
-     CPPUNIT_ASSERT_EQUAL ( thread2->Create(), wxTHREAD_NO_ERROR );
 
-     thread1->Run();
 
-     thread2->Run();
 
-     // Post two messages to the first thread
 
-     CPPUNIT_ASSERT_EQUAL( thread1->GetQueue().Post(0), wxMSGQUEUE_NO_ERROR );
 
-     CPPUNIT_ASSERT_EQUAL( thread1->GetQueue().Post(1), wxMSGQUEUE_NO_ERROR );
 
-     // ...but only one message to the second
 
-     CPPUNIT_ASSERT_EQUAL( thread2->GetQueue().Post(0), wxMSGQUEUE_NO_ERROR );
 
-     wxThread::ExitCode code1 = thread1->Wait();
 
-     wxThread::ExitCode code2 = thread2->Wait();
 
-     CPPUNIT_ASSERT_EQUAL( code1, (wxThread::ExitCode)wxMSGQUEUE_NO_ERROR );
 
-     CPPUNIT_ASSERT_EQUAL( code2, (wxThread::ExitCode)wxMSGQUEUE_TIMEOUT );
 
- }
 
- // every thread tries to read exactly m_maxMsgCount messages from its queue
 
- // following the waiting strategy specified in m_type. If it succeeds then it
 
- // returns 0. Otherwise it returns the error code - one of wxMessageQueueError.
 
- void *QueueTestCase::MyThread::Entry()
 
- {
 
-     int messagesReceived = 0;
 
-     while ( messagesReceived < m_maxMsgCount )
 
-     {
 
-         wxMessageQueueError result;
 
-         int msg = -1; // just to suppress "possibly uninitialized" warnings
 
-         if ( m_type == WaitWithTimeout )
 
-             result = m_queue.ReceiveTimeout(1000, msg);
 
-         else
 
-             result = m_queue.Receive(msg);
 
-         if ( result == wxMSGQUEUE_MISC_ERROR )
 
-             return (wxThread::ExitCode)wxMSGQUEUE_MISC_ERROR;
 
-         if ( result == wxMSGQUEUE_NO_ERROR )
 
-         {
 
-             if ( m_nextThread != NULL )
 
-             {
 
-                 wxMessageQueueError res = m_nextThread->GetQueue().Post(msg);
 
-                 if ( res == wxMSGQUEUE_MISC_ERROR )
 
-                     return (wxThread::ExitCode)wxMSGQUEUE_MISC_ERROR;
 
-                 CPPUNIT_ASSERT_EQUAL( wxMSGQUEUE_NO_ERROR, res );
 
-             }
 
-             ++messagesReceived;
 
-             continue;
 
-         }
 
-         CPPUNIT_ASSERT_EQUAL ( result, wxMSGQUEUE_TIMEOUT );
 
-         break;
 
-     }
 
-     if ( messagesReceived != m_maxMsgCount )
 
-     {
 
-         CPPUNIT_ASSERT_EQUAL( m_type, WaitWithTimeout );
 
-         return (wxThread::ExitCode)wxMSGQUEUE_TIMEOUT;
 
-     }
 
-     return (wxThread::ExitCode)wxMSGQUEUE_NO_ERROR;
 
- }
 
 
  |