| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806 | 
							- /////////////////////////////////////////////////////////////////////////////
 
- // Name:        thread.h
 
- // Purpose:     interface of all thread-related wxWidgets classes
 
- // Author:      wxWidgets team
 
- // Licence:     wxWindows licence
 
- /////////////////////////////////////////////////////////////////////////////
 
- /** See wxCondition. */
 
- enum wxCondError
 
- {
 
-     wxCOND_NO_ERROR = 0,
 
-     wxCOND_INVALID,
 
-     wxCOND_TIMEOUT,         //!< WaitTimeout() has timed out
 
-     wxCOND_MISC_ERROR
 
- };
 
- /**
 
-     @class wxCondition
 
-     wxCondition variables correspond to pthread conditions or to Win32 event objects.
 
-     They may be used in a multithreaded application to wait until the given condition
 
-     becomes @true which happens when the condition becomes signaled.
 
-     For example, if a worker thread is doing some long task and another thread has
 
-     to wait until it is finished, the latter thread will wait on the condition
 
-     object and the worker thread will signal it on exit (this example is not
 
-     perfect because in this particular case it would be much better to just
 
-     wxThread::Wait for the worker thread, but if there are several worker threads
 
-     it already makes much more sense).
 
-     Note that a call to wxCondition::Signal may happen before the other thread calls
 
-     wxCondition::Wait and, just as with the pthread conditions, the signal is then
 
-     lost and so if you want to be sure that you don't miss it you must keep the
 
-     mutex associated with the condition initially locked and lock it again before calling
 
-     wxCondition::Signal. Of course, this means that this call is going to block
 
-     until wxCondition::Wait is called by another thread.
 
-     @section condition_example Example
 
-     This example shows how a main thread may launch a worker thread which starts
 
-     running and then waits until the main thread signals it to continue:
 
-     @code
 
-     class MySignallingThread : public wxThread
 
-     {
 
-     public:
 
-         MySignallingThread(wxMutex *mutex, wxCondition *condition)
 
-         {
 
-             m_mutex = mutex;
 
-             m_condition = condition;
 
-         }
 
-         virtual ExitCode Entry()
 
-         {
 
-             ... do our job ...
 
-             // tell the other(s) thread(s) that we're about to terminate: we must
 
-             // lock the mutex first or we might signal the condition before the
 
-             // waiting threads start waiting on it!
 
-             wxMutexLocker lock(*m_mutex);
 
-             m_condition->Broadcast(); // same as Signal() here -- one waiter only
 
-             return 0;
 
-         }
 
-     private:
 
-         wxCondition *m_condition;
 
-         wxMutex *m_mutex;
 
-     };
 
-     int main()
 
-     {
 
-         wxMutex mutex;
 
-         wxCondition condition(mutex);
 
-         // the mutex should be initially locked
 
-         mutex.Lock();
 
-         // create and run the thread but notice that it won't be able to
 
-         // exit (and signal its exit) before we unlock the mutex below
 
-         MySignallingThread *thread = new MySignallingThread(&mutex, &condition);
 
-         thread->Run();
 
-         // wait for the thread termination: Wait() atomically unlocks the mutex
 
-         // which allows the thread to continue and starts waiting
 
-         condition.Wait();
 
-         // now we can exit
 
-         return 0;
 
-     }
 
-     @endcode
 
-     Of course, here it would be much better to simply use a joinable thread and
 
-     call wxThread::Wait on it, but this example does illustrate the importance of
 
-     properly locking the mutex when using wxCondition.
 
-     @library{wxbase}
 
-     @category{threading}
 
-     @see wxThread, wxMutex
 
- */
 
- class wxCondition
 
- {
 
- public:
 
-     /**
 
-         Default and only constructor.
 
-         The @a mutex must be locked by the caller before calling Wait() function.
 
-         Use IsOk() to check if the object was successfully initialized.
 
-     */
 
-     wxCondition(wxMutex& mutex);
 
-     /**
 
-         Destroys the wxCondition object.
 
-         The destructor is not virtual so this class should not be used polymorphically.
 
-     */
 
-     ~wxCondition();
 
-     /**
 
-         Broadcasts to all waiting threads, waking all of them up.
 
-         Note that this method may be called whether the mutex associated with
 
-         this condition is locked or not.
 
-         @see Signal()
 
-     */
 
-     wxCondError Broadcast();
 
-     /**
 
-         Returns @true if the object had been initialized successfully, @false
 
-         if an error occurred.
 
-     */
 
-     bool IsOk() const;
 
-     /**
 
-         Signals the object waking up at most one thread.
 
-         If several threads are waiting on the same condition, the exact thread
 
-         which is woken up is undefined. If no threads are waiting, the signal is
 
-         lost and the condition would have to be signalled again to wake up any
 
-         thread which may start waiting on it later.
 
-         Note that this method may be called whether the mutex associated with this
 
-         condition is locked or not.
 
-         @see Broadcast()
 
-     */
 
-     wxCondError Signal();
 
-     /**
 
-         Waits until the condition is signalled.
 
-         This method atomically releases the lock on the mutex associated with this
 
-         condition (this is why it must be locked prior to calling Wait()) and puts the
 
-         thread to sleep until Signal() or  Broadcast() is called.
 
-         It then locks the mutex again and returns.
 
-         Note that even if Signal() had been called before Wait() without waking
 
-         up any thread, the thread would still wait for another one and so it is
 
-         important to ensure that the condition will be signalled after
 
-         Wait() or the thread may sleep forever.
 
-         @return Returns wxCOND_NO_ERROR on success, another value if an error occurred.
 
-         @see WaitTimeout()
 
-     */
 
-     wxCondError Wait();
 
-     /**
 
-         Waits until the condition is signalled and the associated condition true.
 
-         This is a convenience overload that may be used to ignore spurious
 
-         awakenings while waiting for a specific condition to become true.
 
-         Equivalent to
 
-         @code
 
-         while ( !predicate() )
 
-         {
 
-             wxCondError e = Wait();
 
-             if ( e != wxCOND_NO_ERROR )
 
-                 return e;
 
-         }
 
-         return wxCOND_NO_ERROR;
 
-         @endcode
 
-         The predicate would typically be a C++11 lambda:
 
-         @code
 
-         condvar.Wait([]{return value == 1;});
 
-         @endcode
 
-         @since 3.0
 
-     */
 
-     template<typename Functor>
 
-     wxCondError Wait(const Functor& predicate);
 
-     /**
 
-         Waits until the condition is signalled or the timeout has elapsed.
 
-         This method is identical to Wait() except that it returns, with the
 
-         return code of @c wxCOND_TIMEOUT as soon as the given timeout expires.
 
-         @param milliseconds
 
-             Timeout in milliseconds
 
-         @return Returns wxCOND_NO_ERROR if the condition was signalled,
 
-                 wxCOND_TIMEOUT if the timeout elapsed before this happened or
 
-                 another error code from wxCondError enum.
 
-     */
 
-     wxCondError WaitTimeout(unsigned long milliseconds);
 
- };
 
- /**
 
-     @class wxCriticalSectionLocker
 
-     This is a small helper class to be used with wxCriticalSection objects.
 
-     A wxCriticalSectionLocker enters the critical section in the constructor and
 
-     leaves it in the destructor making it much more difficult to forget to leave
 
-     a critical section (which, in general, will lead to serious and difficult
 
-     to debug problems).
 
-     Example of using it:
 
-     @code
 
-     void Set Foo()
 
-     {
 
-         // gs_critSect is some (global) critical section guarding access to the
 
-         // object "foo"
 
-         wxCriticalSectionLocker locker(gs_critSect);
 
-         if ( ... )
 
-         {
 
-             // do something
 
-             ...
 
-             return;
 
-         }
 
-         // do something else
 
-         ...
 
-         return;
 
-     }
 
-     @endcode
 
-     Without wxCriticalSectionLocker, you would need to remember to manually leave
 
-     the critical section before each @c return.
 
-     @library{wxbase}
 
-     @category{threading}
 
-     @see wxCriticalSection, wxMutexLocker
 
- */
 
- class wxCriticalSectionLocker
 
- {
 
- public:
 
-     /**
 
-         Constructs a wxCriticalSectionLocker object associated with given
 
-         @a criticalsection and enters it.
 
-     */
 
-     wxCriticalSectionLocker(wxCriticalSection& criticalsection);
 
-     /**
 
-         Destructor leaves the critical section.
 
-     */
 
-     ~wxCriticalSectionLocker();
 
- };
 
- /**
 
-     @class wxThreadHelper
 
-     The wxThreadHelper class is a mix-in class that manages a single background
 
-     thread, either detached or joinable (see wxThread for the differences).
 
-     By deriving from wxThreadHelper, a class can implement the thread
 
-     code in its own wxThreadHelper::Entry() method and easily share data and
 
-     synchronization objects between the main thread and the worker thread.
 
-     Doing this prevents the awkward passing of pointers that is needed when the
 
-     original object in the main thread needs to synchronize with its worker thread
 
-     in its own wxThread derived object.
 
-     For example, wxFrame may need to make some calculations in a background thread
 
-     and then display the results of those calculations in the main window.
 
-     Ordinarily, a wxThread derived object would be created with the calculation
 
-     code implemented in wxThread::Entry. To access the inputs to the calculation,
 
-     the frame object would often need to pass a pointer to itself to the thread object.
 
-     Similarly, the frame object would hold a pointer to the thread object.
 
-     Shared data and synchronization objects could be stored in either object
 
-     though the object without the data would have to access the data through
 
-     a pointer.
 
-     However with wxThreadHelper the frame object and the thread object are
 
-     treated as the same object. Shared data and synchronization variables are
 
-     stored in the single object, eliminating a layer of indirection and the
 
-     associated pointers.
 
-     Example:
 
-     @code
 
-         wxDECLARE_EVENT(myEVT_THREAD_UPDATE, wxThreadEvent);
 
-         class MyFrame : public wxFrame, public wxThreadHelper
 
-         {
 
-         public:
 
-             MyFrame(...) { ... }
 
-             ~MyFrame()
 
-             {
 
-                 // it's better to do any thread cleanup in the OnClose()
 
-                 // event handler, rather than in the destructor.
 
-                 // This is because the event loop for a top-level window is not
 
-                 // active anymore when its destructor is called and if the thread
 
-                 // sends events when ending, they won't be processed unless
 
-                 // you ended the thread from OnClose.
 
-                 // See @ref overview_windowdeletion for more info.
 
-             }
 
-             ...
 
-             void DoStartALongTask();
 
-             void OnThreadUpdate(wxThreadEvent& evt);
 
-             void OnClose(wxCloseEvent& evt);
 
-             ...
 
-         protected:
 
-             virtual wxThread::ExitCode Entry();
 
-             // the output data of the Entry() routine:
 
-             char m_data[1024];
 
-             wxCriticalSection m_dataCS; // protects field above
 
-             wxDECLARE_EVENT_TABLE();
 
-         };
 
-         wxDEFINE_EVENT(myEVT_THREAD_UPDATE, wxThreadEvent)
 
-         wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
 
-             EVT_THREAD(wxID_ANY, myEVT_THREAD_UPDATE, MyFrame::OnThreadUpdate)
 
-             EVT_CLOSE(MyFrame::OnClose)
 
-         wxEND_EVENT_TABLE()
 
-         void MyFrame::DoStartALongTask()
 
-         {
 
-             // we want to start a long task, but we don't want our GUI to block
 
-             // while it's executed, so we use a thread to do it.
 
-             if (CreateThread(wxTHREAD_JOINABLE) != wxTHREAD_NO_ERROR)
 
-             {
 
-                 wxLogError("Could not create the worker thread!");
 
-                 return;
 
-             }
 
-             // go!
 
-             if (GetThread()->Run() != wxTHREAD_NO_ERROR)
 
-             {
 
-                 wxLogError("Could not run the worker thread!");
 
-                 return;
 
-             }
 
-         }
 
-         wxThread::ExitCode MyFrame::Entry()
 
-         {
 
-             // IMPORTANT:
 
-             // this function gets executed in the secondary thread context!
 
-             int offset = 0;
 
-             // here we do our long task, periodically calling TestDestroy():
 
-             while (!GetThread()->TestDestroy())
 
-             {
 
-                 // since this Entry() is implemented in MyFrame context we don't
 
-                 // need any pointer to access the m_data, m_processedData, m_dataCS
 
-                 // variables... very nice!
 
-                 // this is an example of the generic structure of a download thread:
 
-                 char buffer[1024];
 
-                 download_chunk(buffer, 1024);     // this takes time...
 
-                 {
 
-                     // ensure no one reads m_data while we write it
 
-                     wxCriticalSectionLocker lock(m_dataCS);
 
-                     memcpy(m_data+offset, buffer, 1024);
 
-                     offset += 1024;
 
-                 }
 
-                 // VERY IMPORTANT: do not call any GUI function inside this
 
-                 //                 function; rather use wxQueueEvent():
 
-                 wxQueueEvent(this, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_UPDATE));
 
-                     // we used pointer 'this' assuming it's safe; see OnClose()
 
-             }
 
-             // TestDestroy() returned true (which means the main thread asked us
 
-             // to terminate as soon as possible) or we ended the long task...
 
-             return (wxThread::ExitCode)0;
 
-         }
 
-         void MyFrame::OnClose(wxCloseEvent&)
 
-         {
 
-             // important: before terminating, we _must_ wait for our joinable
 
-             // thread to end, if it's running; in fact it uses variables of this
 
-             // instance and posts events to *this event handler
 
-             if (GetThread() &&      // DoStartALongTask() may have not been called
 
-                 GetThread()->IsRunning())
 
-                 GetThread()->Wait();
 
-             Destroy();
 
-         }
 
-         void MyFrame::OnThreadUpdate(wxThreadEvent& evt)
 
-         {
 
-             // ...do something... e.g. m_pGauge->Pulse();
 
-             // read some parts of m_data just for fun:
 
-             wxCriticalSectionLocker lock(m_dataCS);
 
-             wxPrintf("%c", m_data[100]);
 
-         }
 
-     @endcode
 
-     @library{wxbase}
 
-     @category{threading}
 
-     @see wxThread, wxThreadEvent
 
- */
 
- class wxThreadHelper
 
- {
 
- public:
 
-     /**
 
-         This constructor simply initializes internal member variables and tells
 
-         wxThreadHelper which type the thread internally managed should be.
 
-     */
 
-     wxThreadHelper(wxThreadKind kind = wxTHREAD_JOINABLE);
 
-     /**
 
-         The destructor frees the resources associated with the thread, forcing
 
-         it to terminate (it uses wxThread::Kill function).
 
-         Because of the wxThread::Kill unsafety, you should always wait
 
-         (with wxThread::Wait) for joinable threads to end or call wxThread::Delete
 
-         on detached threads, instead of relying on this destructor for stopping
 
-         the thread.
 
-     */
 
-     virtual ~wxThreadHelper();
 
-     /**
 
-         This is the entry point of the thread.
 
-         This function is pure virtual and must be implemented by any derived class.
 
-         The thread execution will start here.
 
-         You'll typically want your Entry() to look like:
 
-         @code
 
-             wxThread::ExitCode Entry()
 
-             {
 
-                 while (!GetThread()->TestDestroy())
 
-                 {
 
-                     // ... do some work ...
 
-                     if (IsWorkCompleted)
 
-                         break;
 
-                     if (HappenedStoppingError)
 
-                         return (wxThread::ExitCode)1;   // failure
 
-                 }
 
-                 return (wxThread::ExitCode)0;           // success
 
-             }
 
-         @endcode
 
-         The returned value is the thread exit code which is only useful for
 
-         joinable threads and is the value returned by @c "GetThread()->Wait()".
 
-         This function is called by wxWidgets itself and should never be called
 
-         directly.
 
-     */
 
-     virtual ExitCode Entry() = 0;
 
-     /**
 
-         Callback called by Delete() before actually deleting the thread.
 
-         This function can be overridden by the derived class to perform some
 
-         specific task when the thread is gracefully destroyed. Notice that it
 
-         will be executed in the context of the thread that called Delete() and
 
-         <b>not</b> in this thread's context.
 
-         TestDestroy() will be true for the thread before OnDelete() gets
 
-         executed.
 
-         @since 2.9.2
 
-         @see OnKill()
 
-     */
 
-     virtual void OnDelete();
 
-     /**
 
-         Callback called by Kill() before actually killing the thread.
 
-         This function can be overridden by the derived class to perform some
 
-         specific task when the thread is terminated. Notice that it will be
 
-         executed in the context of the thread that called Kill() and <b>not</b>
 
-         in this thread's context.
 
-         @since 2.9.2
 
-         @see OnDelete()
 
-     */
 
-     virtual void OnKill();
 
-     /**
 
-         @deprecated
 
-         Use CreateThread() instead.
 
-     */
 
-     wxThreadError Create(unsigned int stackSize = 0);
 
-     /**
 
-         Creates a new thread of the given @a kind.
 
-         The thread object is created in the suspended state, and you
 
-         should call @ref wxThread::Run "GetThread()->Run()" to start running it.
 
-         You may optionally specify the stack size to be allocated to it (ignored
 
-         on platforms that don't support setting it explicitly, e.g. Unix).
 
-         @return One of the ::wxThreadError enum values.
 
-     */
 
-     wxThreadError CreateThread(wxThreadKind kind = wxTHREAD_JOINABLE,
 
-                                unsigned int stackSize = 0);
 
-     /**
 
-         This is a public function that returns the wxThread object associated with
 
-         the thread.
 
-     */
 
-     wxThread* GetThread() const;
 
-     /**
 
-         Returns the last type of thread given to the CreateThread() function
 
-         or to the constructor.
 
-     */
 
-     wxThreadKind GetThreadKind() const;
 
- };
 
- /**
 
-    Possible critical section types
 
- */
 
- enum wxCriticalSectionType
 
- {
 
-     wxCRITSEC_DEFAULT,
 
-       /** Recursive critical section under both Windows and Unix */
 
-     wxCRITSEC_NON_RECURSIVE
 
-       /** Non-recursive critical section under Unix, recursive under Windows */
 
- };
 
- /**
 
-     @class wxCriticalSection
 
-     A critical section object is used for exactly the same purpose as a wxMutex.
 
-     The only difference is that under Windows platform critical sections are only
 
-     visible inside one process, while mutexes may be shared among processes,
 
-     so using critical sections is slightly more efficient.
 
-     The terminology is also slightly different: mutex may be locked (or acquired)
 
-     and unlocked (or released) while critical section is entered and left by the program.
 
-     Finally, you should try to use wxCriticalSectionLocker class whenever
 
-     possible instead of directly using wxCriticalSection for the same reasons
 
-     wxMutexLocker is preferable to wxMutex - please see wxMutex for an example.
 
-     @library{wxbase}
 
-     @category{threading}
 
-     @note Critical sections can be used before the wxWidgets library is fully
 
-           initialized. In particular, it's safe to create global
 
-           wxCriticalSection instances.
 
-     @see wxThread, wxCondition, wxCriticalSectionLocker
 
- */
 
- class wxCriticalSection
 
- {
 
- public:
 
-     /**
 
-         Default constructor initializes critical section object.
 
-         By default critical sections are recursive under Unix and Windows.
 
-     */
 
-     wxCriticalSection( wxCriticalSectionType critSecType = wxCRITSEC_DEFAULT );
 
-     /**
 
-         Destructor frees the resources.
 
-     */
 
-     ~wxCriticalSection();
 
-     /**
 
-         Enter the critical section (same as locking a mutex): if another thread
 
-         has already entered it, this call will block until the other thread
 
-         calls Leave().
 
-         There is no error return for this function.
 
-         After entering the critical section protecting a data variable,
 
-         the thread running inside the critical section may safely use/modify it.
 
-         Note that entering the same critical section twice or more from the same
 
-         thread doesn't result in a deadlock; in this case in fact this function will
 
-         immediately return.
 
-     */
 
-     void Enter();
 
-     /**
 
-         Try to enter the critical section (same as trying to lock a mutex).
 
-         If it can't, immediately returns false.
 
-         @since 2.9.3
 
-     */
 
-     bool TryEnter();
 
-     /**
 
-         Leave the critical section allowing other threads use the global data
 
-         protected by it. There is no error return for this function.
 
-     */
 
-     void Leave();
 
- };
 
- /**
 
-     The possible thread wait types.
 
-     @since 2.9.2
 
- */
 
- enum wxThreadWait
 
- {
 
-     /**
 
-         No events are processed while waiting.
 
-         This is the default under all platforms except for wxMSW.
 
-      */
 
-     wxTHREAD_WAIT_BLOCK,
 
-     /**
 
-         Yield for event dispatching while waiting.
 
-         This flag is dangerous as it exposes the program using it to unexpected
 
-         reentrancies in the same way as calling wxYield() function does so you
 
-         are strongly advised to avoid its use and not wait for the thread
 
-         termination from the main (GUI) thread at all to avoid making your
 
-         application unresponsive.
 
-         Also notice that this flag is not portable as it is only implemented in
 
-         wxMSW and simply ignored under the other platforms.
 
-      */
 
-     wxTHREAD_WAIT_YIELD,
 
-     /**
 
-         Default wait mode for wxThread::Wait() and wxThread::Delete().
 
-         For compatibility reasons, the default wait mode is currently
 
-         wxTHREAD_WAIT_YIELD if WXWIN_COMPATIBILITY_2_8 is defined (and it is
 
-         by default). However, as mentioned above, you're strongly encouraged to
 
-         not use wxTHREAD_WAIT_YIELD and pass wxTHREAD_WAIT_BLOCK to wxThread
 
-         method explicitly.
 
-      */
 
-     wxTHREAD_WAIT_DEFAULT = wxTHREAD_WAIT_YIELD
 
- };
 
- /**
 
-   The possible thread kinds.
 
- */
 
- enum wxThreadKind
 
- {
 
-     /** Detached thread */
 
-     wxTHREAD_DETACHED,
 
-     /** Joinable thread */
 
-     wxTHREAD_JOINABLE
 
- };
 
- /**
 
-   The possible thread errors.
 
- */
 
- enum wxThreadError
 
- {
 
-     /** No error */
 
-     wxTHREAD_NO_ERROR = 0,
 
-     /** No resource left to create a new thread. */
 
-     wxTHREAD_NO_RESOURCE,
 
-     /** The thread is already running. */
 
-     wxTHREAD_RUNNING,
 
-     /** The thread isn't running. */
 
-     wxTHREAD_NOT_RUNNING,
 
-     /** Thread we waited for had to be killed. */
 
-     wxTHREAD_KILLED,
 
-     /** Some other error */
 
-     wxTHREAD_MISC_ERROR
 
- };
 
- /**
 
-     @class wxThread
 
-     A thread is basically a path of execution through a program.
 
-     Threads are sometimes called @e light-weight processes, but the fundamental difference
 
-     between threads and processes is that memory spaces of different processes are
 
-     separated while all threads share the same address space.
 
-     While it makes it much easier to share common data between several threads, it
 
-     also makes it much easier to shoot oneself in the foot, so careful use of
 
-     synchronization objects such as mutexes (see wxMutex) or critical sections
 
-     (see wxCriticalSection) is recommended.
 
-     In addition, don't create global thread objects because they allocate memory
 
-     in their constructor, which will cause problems for the memory checking system.
 
-     @section thread_types Types of wxThreads
 
-     There are two types of threads in wxWidgets: @e detached and @e joinable,
 
-     modeled after the POSIX thread API. This is different from the Win32 API
 
-     where all threads are joinable.
 
-     By default wxThreads in wxWidgets use the @b detached behaviour.
 
-     Detached threads delete themselves once they have completed, either by themselves
 
-     when they complete processing or through a call to Delete(), and thus
 
-     @b must be created on the heap (through the new operator, for example).
 
-     Typically you'll want to store the instances of the detached wxThreads you
 
-     allocate, so that you can call functions on them.
 
-     Because of their nature however you'll need to always use a critical section
 
-     when accessing them:
 
-     @code
 
-     // declare a new type of event, to be used by our MyThread class:
 
-     wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent);
 
-     wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
 
-     class MyFrame;
 
-     class MyThread : public wxThread
 
-     {
 
-     public:
 
-         MyThread(MyFrame *handler)
 
-             : wxThread(wxTHREAD_DETACHED)
 
-             { m_pHandler = handler }
 
-         ~MyThread();
 
-     protected:
 
-         virtual ExitCode Entry();
 
-         MyFrame *m_pHandler;
 
-     };
 
-     class MyFrame : public wxFrame
 
-     {
 
-     public:
 
-         ...
 
-         ~MyFrame()
 
-         {
 
-             // it's better to do any thread cleanup in the OnClose()
 
-             // event handler, rather than in the destructor.
 
-             // This is because the event loop for a top-level window is not
 
-             // active anymore when its destructor is called and if the thread
 
-             // sends events when ending, they won't be processed unless
 
-             // you ended the thread from OnClose.
 
-             // See @ref overview_windowdeletion for more info.
 
-         }
 
-         ...
 
-         void DoStartThread();
 
-         void DoPauseThread();
 
-         // a resume routine would be nearly identic to DoPauseThread()
 
-         void DoResumeThread() { ... }
 
-         void OnThreadUpdate(wxThreadEvent&);
 
-         void OnThreadCompletion(wxThreadEvent&);
 
-         void OnClose(wxCloseEvent&);
 
-     protected:
 
-         MyThread *m_pThread;
 
-         wxCriticalSection m_pThreadCS;    // protects the m_pThread pointer
 
-         wxDECLARE_EVENT_TABLE();
 
-     };
 
-     wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
 
-         EVT_CLOSE(MyFrame::OnClose)
 
-         EVT_MENU(Minimal_Start,  MyFrame::DoStartThread)
 
-         EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate)
 
-         EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_COMPLETED, MyFrame::OnThreadCompletion)
 
-     wxEND_EVENT_TABLE()
 
-     wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent)
 
-     wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent)
 
-     void MyFrame::DoStartThread()
 
-     {
 
-         m_pThread = new MyThread(this);
 
-         if ( m_pThread->Run() != wxTHREAD_NO_ERROR )
 
-         {
 
-             wxLogError("Can't create the thread!");
 
-             delete m_pThread;
 
-             m_pThread = NULL;
 
-         }
 
-         // after the call to wxThread::Run(), the m_pThread pointer is "unsafe":
 
-         // at any moment the thread may cease to exist (because it completes its work).
 
-         // To avoid dangling pointers OnThreadExit() will set m_pThread
 
-         // to NULL when the thread dies.
 
-     }
 
-     wxThread::ExitCode MyThread::Entry()
 
-     {
 
-         while (!TestDestroy())
 
-         {
 
-             // ... do a bit of work...
 
-             wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_UPDATE));
 
-         }
 
-         // signal the event handler that this thread is going to be destroyed
 
-         // NOTE: here we assume that using the m_pHandler pointer is safe,
 
-         //       (in this case this is assured by the MyFrame destructor)
 
-         wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_COMPLETED));
 
-         return (wxThread::ExitCode)0;     // success
 
-     }
 
-     MyThread::~MyThread()
 
-     {
 
-         wxCriticalSectionLocker enter(m_pHandler->m_pThreadCS);
 
-         // the thread is being destroyed; make sure not to leave dangling pointers around
 
-         m_pHandler->m_pThread = NULL;
 
-     }
 
-     void MyFrame::OnThreadCompletion(wxThreadEvent&)
 
-     {
 
-         wxMessageOutputDebug().Printf("MYFRAME: MyThread exited!\n");
 
-     }
 
-     void MyFrame::OnThreadUpdate(wxThreadEvent&)
 
-     {
 
-         wxMessageOutputDebug().Printf("MYFRAME: MyThread update...\n");
 
-     }
 
-     void MyFrame::DoPauseThread()
 
-     {
 
-         // anytime we access the m_pThread pointer we must ensure that it won't
 
-         // be modified in the meanwhile; since only a single thread may be
 
-         // inside a given critical section at a given time, the following code
 
-         // is safe:
 
-         wxCriticalSectionLocker enter(m_pThreadCS);
 
-         if (m_pThread)         // does the thread still exist?
 
-         {
 
-             // without a critical section, once reached this point it may happen
 
-             // that the OS scheduler gives control to the MyThread::Entry() function,
 
-             // which in turn may return (because it completes its work) making
 
-             // invalid the m_pThread pointer
 
-             if (m_pThread->Pause() != wxTHREAD_NO_ERROR )
 
-                 wxLogError("Can't pause the thread!");
 
-         }
 
-     }
 
-     void MyFrame::OnClose(wxCloseEvent&)
 
-     {
 
-         {
 
-             wxCriticalSectionLocker enter(m_pThreadCS);
 
-             if (m_pThread)         // does the thread still exist?
 
-             {
 
-                 wxMessageOutputDebug().Printf("MYFRAME: deleting thread");
 
-                 if (m_pThread->Delete() != wxTHREAD_NO_ERROR )
 
-                     wxLogError("Can't delete the thread!");
 
-             }
 
-         }       // exit from the critical section to give the thread
 
-                 // the possibility to enter its destructor
 
-                 // (which is guarded with m_pThreadCS critical section!)
 
-         while (1)
 
-         {
 
-             { // was the ~MyThread() function executed?
 
-                 wxCriticalSectionLocker enter(m_pThreadCS);
 
-                 if (!m_pThread) break;
 
-             }
 
-             // wait for thread completion
 
-             wxThread::This()->Sleep(1);
 
-         }
 
-         Destroy();
 
-     }
 
-     @endcode
 
-     For a more detailed and comprehensive example, see @sample{thread}.
 
-     For a simpler way to share data and synchronization objects between
 
-     the main and the secondary thread see wxThreadHelper.
 
-     Conversely, @b joinable threads do not delete themselves when they are done
 
-     processing and as such are safe to create on the stack. Joinable threads
 
-     also provide the ability for one to get value it returned from Entry()
 
-     through Wait().
 
-     You shouldn't hurry to create all the threads joinable, however, because this
 
-     has a disadvantage as well: you @b must Wait() for a joinable thread or the
 
-     system resources used by it will never be freed, and you also must delete the
 
-     corresponding wxThread object yourself if you did not create it on the stack.
 
-     In contrast, detached threads are of the "fire-and-forget" kind: you only have
 
-     to start a detached thread and it will terminate and destroy itself.
 
-     @section thread_deletion wxThread Deletion
 
-     Regardless of whether it has terminated or not, you should call Wait() on a
 
-     @b joinable thread to release its memory, as outlined in @ref thread_types.
 
-     If you created a joinable thread on the heap, remember to delete it manually
 
-     with the @c delete operator or similar means as only detached threads handle
 
-     this type of memory management.
 
-     Since @b detached threads delete themselves when they are finished processing,
 
-     you should take care when calling a routine on one. If you are certain the
 
-     thread is still running and would like to end it, you may call Delete()
 
-     to gracefully end it (which implies that the thread will be deleted after
 
-     that call to Delete()). It should be implied that you should @b never attempt
 
-     to delete a detached thread with the @c delete operator or similar means.
 
-     As mentioned, Wait() or Delete() functions attempt to gracefully terminate a
 
-     joinable and a detached thread, respectively. They do this by waiting until
 
-     the thread in question calls TestDestroy() or ends processing (i.e. returns
 
-     from wxThread::Entry).
 
-     Obviously, if the thread does call TestDestroy() and does not end, the
 
-     thread which called Wait() or Delete() will come to halt.
 
-     This is why it's important to call TestDestroy() in the Entry() routine of
 
-     your threads as often as possible and immediately exit when it returns @true.
 
-     As a last resort you can end the thread immediately through Kill(). It is
 
-     strongly recommended that you do not do this, however, as it does not free
 
-     the resources associated with the object (although the wxThread object of
 
-     detached threads will still be deleted) and could leave the C runtime
 
-     library in an undefined state.
 
-     @section thread_secondary wxWidgets Calls in Secondary Threads
 
-     All threads other than the "main application thread" (the one running
 
-     wxApp::OnInit() or the one your main function runs in, for example) are
 
-     considered "secondary threads".
 
-     GUI calls, such as those to a wxWindow or wxBitmap are explicitly not safe
 
-     at all in secondary threads and could end your application prematurely.
 
-     This is due to several reasons, including the underlying native API and
 
-     the fact that wxThread does not run a GUI event loop similar to other APIs
 
-     as MFC.
 
-     A workaround for some wxWidgets ports is calling wxMutexGUIEnter()
 
-     before any GUI calls and then calling wxMutexGUILeave() afterwords.
 
-     However, the recommended way is to simply process the GUI calls in the main
 
-     thread through an event that is posted by wxQueueEvent().
 
-     This does not imply that calls to these classes are thread-safe, however,
 
-     as most wxWidgets classes are not thread-safe, including wxString.
 
-     @section thread_poll Don't Poll a wxThread
 
-     A common problem users experience with wxThread is that in their main thread
 
-     they will check the thread every now and then to see if it has ended through
 
-     IsRunning(), only to find that their application has run into problems
 
-     because the thread is using the default behaviour (i.e. it's @b detached) and
 
-     has already deleted itself.
 
-     Naturally, they instead attempt to use joinable threads in place of the previous
 
-     behaviour. However, polling a wxThread for when it has ended is in general a
 
-     bad idea - in fact calling a routine on any running wxThread should be avoided
 
-     if possible. Instead, find a way to notify yourself when the thread has ended.
 
-     Usually you only need to notify the main thread, in which case you can
 
-     post an event to it via wxQueueEvent().
 
-     In the case of secondary threads you can call a routine of another class
 
-     when the thread is about to complete processing and/or set the value of
 
-     a variable, possibly using mutexes (see wxMutex) and/or other synchronization
 
-     means if necessary.
 
-     @library{wxbase}
 
-     @category{threading}
 
-     @see wxThreadHelper, wxMutex, wxCondition, wxCriticalSection,
 
-          @ref overview_thread
 
- */
 
- class wxThread
 
- {
 
- public:
 
-     /**
 
-         The return type for the thread functions.
 
-     */
 
-     typedef void* ExitCode;
 
-     /**
 
-         This constructor creates a new detached (default) or joinable C++
 
-         thread object. It does not create or start execution of the real thread -
 
-         for this you should use the Run() method.
 
-         The possible values for @a kind parameters are:
 
-           - @b wxTHREAD_DETACHED - Creates a detached thread.
 
-           - @b wxTHREAD_JOINABLE - Creates a joinable thread.
 
-     */
 
-     wxThread(wxThreadKind kind = wxTHREAD_DETACHED);
 
-     /**
 
-         The destructor frees the resources associated with the thread.
 
-         Notice that you should never delete a detached thread -- you may only call
 
-         Delete() on it or wait until it terminates (and auto destructs) itself.
 
-         Because the detached threads delete themselves, they can only be allocated on the heap.
 
-         Joinable threads should be deleted explicitly. The Delete() and Kill() functions
 
-         will not delete the C++ thread object. It is also safe to allocate them on stack.
 
-     */
 
-     virtual ~wxThread();
 
-     /**
 
-         Creates a new thread.
 
-         The thread object is created in the suspended state, and you should call Run()
 
-         to start running it. You may optionally specify the stack size to be allocated
 
-         to it (Ignored on platforms that don't support setting it explicitly,
 
-         eg. Unix system without @c pthread_attr_setstacksize).
 
-         If you do not specify the stack size, the system's default value is used.
 
-         @note
 
-             It is not necessary to call this method since 2.9.5, Run() will create
 
-             the thread internally. You only need to call Create() if you need to do
 
-             something with the thread (e.g. pass its ID to an external library)
 
-             before it starts.
 
-         @warning
 
-             It is a good idea to explicitly specify a value as systems'
 
-             default values vary from just a couple of KB on some systems (BSD and
 
-             OS/2 systems) to one or several MB (Windows, Solaris, Linux).
 
-             So, if you have a thread that requires more than just a few KB of memory, you
 
-             will have mysterious problems on some platforms but not on the common ones.
 
-             On the other hand, just indicating a large stack size by default will give you
 
-             performance issues on those systems with small default stack since those
 
-             typically use fully committed memory for the stack.
 
-             On the contrary, if you use a lot of threads (say several hundred),
 
-             virtual address space can get tight unless you explicitly specify a
 
-             smaller amount of thread stack space for each thread.
 
-         @return One of:
 
-           - @b wxTHREAD_NO_ERROR - No error.
 
-           - @b wxTHREAD_NO_RESOURCE - There were insufficient resources to create the thread.
 
-           - @b wxTHREAD_NO_RUNNING - The thread is already running
 
-     */
 
-     wxThreadError Create(unsigned int stackSize = 0);
 
-     /**
 
-         Calling Delete() gracefully terminates a @b detached thread, either when
 
-         the thread calls TestDestroy() or when it finishes processing.
 
-         @param rc
 
-             The thread exit code, if rc is not NULL.
 
-         @param waitMode
 
-             As described in wxThreadWait documentation, wxTHREAD_WAIT_BLOCK
 
-             should be used as the wait mode even although currently
 
-             wxTHREAD_WAIT_YIELD is for compatibility reasons. This parameter is
 
-             new in wxWidgets 2.9.2.
 
-         @note
 
-             This function works on a joinable thread but in that case makes
 
-             the TestDestroy() function of the thread return @true and then
 
-             waits for its completion (i.e. it differs from Wait() because
 
-             it asks the thread to terminate before waiting).
 
-         See @ref thread_deletion for a broader explanation of this routine.
 
-     */
 
-     wxThreadError Delete(ExitCode *rc = NULL,
 
-                          wxThreadWait waitMode = wxTHREAD_WAIT_BLOCK);
 
-     /**
 
-         Returns the number of system CPUs or -1 if the value is unknown.
 
-         For multi-core systems the returned value is typically the total number
 
-         of @e cores, since the OS usually abstract a single N-core CPU
 
-         as N different cores.
 
-         @see SetConcurrency()
 
-     */
 
-     static int GetCPUCount();
 
-     /**
 
-         Returns the platform specific thread ID of the current thread as a long.
 
-         This can be used to uniquely identify threads, even if they are not wxThreads.
 
-         @see GetMainId()
 
-     */
 
-     static wxThreadIdType GetCurrentId();
 
-     /**
 
-         Gets the thread identifier: this is a platform dependent number that uniquely
 
-         identifies the thread throughout the system during its existence
 
-         (i.e.\ the thread identifiers may be reused).
 
-     */
 
-     wxThreadIdType GetId() const;
 
-     /**
 
-         Returns the thread kind as it was given in the ctor.
 
-         @since 2.9.0
 
-     */
 
-     wxThreadKind GetKind() const;
 
-     /**
 
-         Returns the thread ID of the main thread.
 
-         @see IsMain()
 
-         @since 2.9.1
 
-      */
 
-     static wxThreadIdType GetMainId();
 
-     /**
 
-         Gets the priority of the thread, between 0 (lowest) and 100 (highest).
 
-         @see SetPriority()
 
-     */
 
-     unsigned int GetPriority() const;
 
-     /**
 
-         Returns @true if the thread is alive (i.e.\ started and not terminating).
 
-         Note that this function can only safely be used with joinable threads, not
 
-         detached ones as the latter delete themselves and so when the real thread is
 
-         no longer alive, it is not possible to call this function because
 
-         the wxThread object no longer exists.
 
-     */
 
-     bool IsAlive() const;
 
-     /**
 
-         Returns @true if the thread is of the detached kind, @false if it is a
 
-         joinable one.
 
-     */
 
-     bool IsDetached() const;
 
-     /**
 
-         Returns @true if the calling thread is the main application thread.
 
-         Main thread in the context of wxWidgets is the one which initialized
 
-         the library.
 
-         @see GetMainId(), GetCurrentId()
 
-     */
 
-     static bool IsMain();
 
-     /**
 
-         Returns @true if the thread is paused.
 
-     */
 
-     bool IsPaused() const;
 
-     /**
 
-         Returns @true if the thread is running.
 
-         This method may only be safely used for joinable threads, see the remark in
 
-         IsAlive().
 
-     */
 
-     bool IsRunning() const;
 
-     /**
 
-         Immediately terminates the target thread.
 
-         @b "This function is dangerous and should be used with extreme care"
 
-         (and not used at all whenever possible)! The resources allocated to the
 
-         thread will not be freed and the state of the C runtime library may become
 
-         inconsistent. Use Delete() for detached threads or Wait() for joinable
 
-         threads instead.
 
-         For detached threads Kill() will also delete the associated C++ object.
 
-         However this will not happen for joinable threads and this means that you will
 
-         still have to delete the wxThread object yourself to avoid memory leaks.
 
-         In neither case OnExit() of the dying thread will be called, so no
 
-         thread-specific cleanup will be performed.
 
-         This function can only be called from another thread context, i.e. a thread
 
-         cannot kill itself.
 
-         It is also an error to call this function for a thread which is not running or
 
-         paused (in the latter case, the thread will be resumed first) -- if you do it,
 
-         a @b wxTHREAD_NOT_RUNNING error will be returned.
 
-     */
 
-     wxThreadError Kill();
 
-     /**
 
-         Suspends the thread.
 
-         Under some implementations (Win32), the thread is suspended immediately,
 
-         under others it will only be suspended when it calls TestDestroy() for
 
-         the next time (hence, if the thread doesn't call it at all, it won't be
 
-         suspended).
 
-         This function can only be called from another thread context.
 
-     */
 
-     wxThreadError Pause();
 
-     /**
 
-         Resumes a thread suspended by the call to Pause().
 
-         This function can only be called from another thread context.
 
-     */
 
-     wxThreadError Resume();
 
-     /**
 
-         Starts the thread execution.
 
-         Note that once you Run() a @b detached thread, @e any function call you do
 
-         on the thread pointer (you must allocate it on the heap) is @e "unsafe";
 
-         i.e. the thread may have terminated at any moment after Run() and your pointer
 
-         may be dangling. See @ref thread_types for an example of safe manipulation
 
-         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();
 
-     /**
 
-         Sets the thread concurrency level for this process.
 
-         This is, roughly, the number of threads that the system tries to schedule
 
-         to run in parallel.
 
-         The value of 0 for @a level may be used to set the default one.
 
-         @return @true on success or @false otherwise (for example, if this function is
 
-                 not implemented for this platform -- currently everything except Solaris).
 
-     */
 
-     static bool SetConcurrency(size_t level);
 
-     /**
 
-         Sets the priority of the thread, between 0 (lowest) and 100 (highest).
 
-         The following symbolic constants can be used in addition to raw
 
-         values in 0..100 range:
 
-           - @c wxPRIORITY_MIN: 0
 
-           - @c wxPRIORITY_DEFAULT: 50
 
-           - @c wxPRIORITY_MAX: 100
 
-     */
 
-     void SetPriority(unsigned int priority);
 
-     /**
 
-         Pauses the thread execution for the given amount of time.
 
-         This is the same as wxMilliSleep().
 
-     */
 
-     static void Sleep(unsigned long milliseconds);
 
-     /**
 
-         This function should be called periodically by the thread to ensure that
 
-         calls to Pause() and Delete() will work.
 
-         If it returns @true, the thread should exit as soon as possible.
 
-         Notice that under some platforms (POSIX), implementation of Pause() also
 
-         relies on this function being called, so not calling it would prevent
 
-         both stopping and suspending thread from working.
 
-     */
 
-     virtual bool TestDestroy();
 
-     /**
 
-         Return the thread object for the calling thread.
 
-         @NULL is returned if the calling thread is the main (GUI) thread, but
 
-         IsMain() should be used to test whether the thread is really the main one
 
-         because @NULL may also be returned for the thread not created with wxThread
 
-         class. Generally speaking, the return value for such a thread is undefined.
 
-     */
 
-     static wxThread* This();
 
-     /**
 
-         Waits for a @b joinable thread to terminate and returns the value the thread
 
-         returned from Entry() or @c "(ExitCode)-1" on error. Notice that, unlike
 
-         Delete(), this function doesn't cancel the thread in any way so the caller
 
-         waits for as long as it takes to the thread to exit.
 
-         You can only Wait() for @b joinable (not detached) threads.
 
-         This function can only be called from another thread context.
 
-         @param flags
 
-             As described in wxThreadWait documentation, wxTHREAD_WAIT_BLOCK
 
-             should be used as the wait mode even although currently
 
-             wxTHREAD_WAIT_YIELD is for compatibility reasons. This parameter is
 
-             new in wxWidgets 2.9.2.
 
-         See @ref thread_deletion for a broader explanation of this routine.
 
-     */
 
-     ExitCode Wait(wxThreadWait flags = wxTHREAD_WAIT_BLOCK);
 
-     /**
 
-         Give the rest of the thread's time-slice to the system allowing the other
 
-         threads to run.
 
-         Note that using this function is @b strongly discouraged, since in
 
-         many cases it indicates a design weakness of your threading model
 
-         (as does using Sleep() functions).
 
-         Threads should use the CPU in an efficient manner, i.e. they should
 
-         do their current work efficiently, then as soon as the work is done block
 
-         on a wakeup event (wxCondition, wxMutex, select(), poll(), ...) which will
 
-         get signalled e.g. by other threads or a user device once further thread
 
-         work is available.
 
-         Using Yield() or Sleep() indicates polling-type behaviour, since we're
 
-         fuzzily giving up our timeslice and wait until sometime later we'll get
 
-         reactivated, at which time we realize that there isn't really much to do
 
-         and Yield() again...
 
-         The most critical characteristic of Yield() is that it's operating system
 
-         specific: there may be scheduler changes which cause your thread to not
 
-         wake up relatively soon again, but instead many seconds later,
 
-         causing huge performance issues for your application.
 
-         <strong>
 
-         With a well-behaving, CPU-efficient thread the operating system is likely
 
-         to properly care for its reactivation the moment it needs it, whereas with
 
-         non-deterministic, Yield-using threads all bets are off and the system
 
-         scheduler is free to penalize them drastically</strong>, and this effect
 
-         gets worse with increasing system load due to less free CPU resources available.
 
-         You may refer to various Linux kernel @c sched_yield discussions for more
 
-         information.
 
-         See also Sleep().
 
-     */
 
-     static void Yield();
 
- protected:
 
-     /**
 
-         This is the entry point of the thread.
 
-         This function is pure virtual and must be implemented by any derived class.
 
-         The thread execution will start here.
 
-         The returned value is the thread exit code which is only useful for
 
-         joinable threads and is the value returned by Wait().
 
-         This function is called by wxWidgets itself and should never be called
 
-         directly.
 
-     */
 
-     virtual ExitCode Entry() = 0;
 
-     /**
 
-         This is a protected function of the wxThread class and thus can only be called
 
-         from a derived class. It also can only be called in the context of this
 
-         thread, i.e. a thread can only exit from itself, not from another thread.
 
-         This function will terminate the OS thread (i.e. stop the associated path of
 
-         execution) and also delete the associated C++ object for detached threads.
 
-         OnExit() will be called just before exiting.
 
-     */
 
-     void Exit(ExitCode exitcode = 0);
 
- private:
 
-     /**
 
-         Called when the thread exits.
 
-         This function is called in the context of the thread associated with the
 
-         wxThread object, not in the context of the main thread.
 
-         This function will not be called if the thread was @ref Kill() killed.
 
-         This function should never be called directly.
 
-     */
 
-     virtual void OnExit();
 
- };
 
- /** See wxSemaphore. */
 
- enum wxSemaError
 
- {
 
-     wxSEMA_NO_ERROR = 0,
 
-     wxSEMA_INVALID,         //!< semaphore hasn't been initialized successfully
 
-     wxSEMA_BUSY,            //!< returned by TryWait() if Wait() would block
 
-     wxSEMA_TIMEOUT,         //!< returned by WaitTimeout()
 
-     wxSEMA_OVERFLOW,        //!< Post() would increase counter past the max
 
-     wxSEMA_MISC_ERROR
 
- };
 
- /**
 
-     @class wxSemaphore
 
-     wxSemaphore is a counter limiting the number of threads concurrently accessing
 
-     a shared resource. This counter is always between 0 and the maximum value
 
-     specified during the semaphore creation. When the counter is strictly greater
 
-     than 0, a call to wxSemaphore::Wait() returns immediately and decrements the
 
-     counter. As soon as it reaches 0, any subsequent calls to wxSemaphore::Wait
 
-     block and only return when the semaphore counter becomes strictly positive
 
-     again as the result of calling wxSemaphore::Post which increments the counter.
 
-     In general, semaphores are useful to restrict access to a shared resource
 
-     which can only be accessed by some fixed number of clients at the same time.
 
-     For example, when modeling a hotel reservation system a semaphore with the counter
 
-     equal to the total number of available rooms could be created. Each time a room
 
-     is reserved, the semaphore should be acquired by calling wxSemaphore::Wait
 
-     and each time a room is freed it should be released by calling wxSemaphore::Post.
 
-     @library{wxbase}
 
-     @category{threading}
 
- */
 
- class wxSemaphore
 
- {
 
- public:
 
-     /**
 
-         Specifying a @a maxcount of 0 actually makes wxSemaphore behave as if
 
-         there is no upper limit. If @a maxcount is 1, the semaphore behaves almost as a
 
-         mutex (but unlike a mutex it can be released by a thread different from the one
 
-         which acquired it).
 
-         @a initialcount is the initial value of the semaphore which must be between
 
-         0 and @a maxcount (if it is not set to 0).
 
-     */
 
-     wxSemaphore(int initialcount = 0, int maxcount = 0);
 
-     /**
 
-         Destructor is not virtual, don't use this class polymorphically.
 
-     */
 
-     ~wxSemaphore();
 
-     /**
 
-         Increments the semaphore count and signals one of the waiting
 
-         threads in an atomic way. Returns @e wxSEMA_OVERFLOW if the count
 
-         would increase the counter past the maximum.
 
-         @return One of:
 
-             - wxSEMA_NO_ERROR: There was no error.
 
-             - wxSEMA_INVALID : Semaphore hasn't been initialized successfully.
 
-             - wxSEMA_OVERFLOW: Post() would increase counter past the max.
 
-             - wxSEMA_MISC_ERROR: Miscellaneous error.
 
-     */
 
-     wxSemaError Post();
 
-     /**
 
-         Same as Wait(), but returns immediately.
 
-         @return One of:
 
-             - wxSEMA_NO_ERROR: There was no error.
 
-             - wxSEMA_INVALID: Semaphore hasn't been initialized successfully.
 
-             - wxSEMA_BUSY: Returned by TryWait() if Wait() would block, i.e. the count is zero.
 
-             - wxSEMA_MISC_ERROR: Miscellaneous error.
 
-     */
 
-     wxSemaError TryWait();
 
-     /**
 
-         Wait indefinitely until the semaphore count becomes strictly positive
 
-         and then decrement it and return.
 
-         @return One of:
 
-             - wxSEMA_NO_ERROR: There was no error.
 
-             - wxSEMA_INVALID: Semaphore hasn't been initialized successfully.
 
-             - wxSEMA_MISC_ERROR: Miscellaneous error.
 
-     */
 
-     wxSemaError Wait();
 
-     /**
 
-         Same as Wait(), but with a timeout limit.
 
-         @return One of:
 
-             - wxSEMA_NO_ERROR: There was no error.
 
-             - wxSEMA_INVALID: Semaphore hasn't been initialized successfully.
 
-             - wxSEMA_TIMEOUT: Timeout occurred without receiving semaphore.
 
-             - wxSEMA_MISC_ERROR: Miscellaneous error.
 
-     */
 
-     wxSemaError WaitTimeout(unsigned long timeout_millis);
 
- };
 
- /**
 
-     @class wxMutexLocker
 
-     This is a small helper class to be used with wxMutex objects.
 
-     A wxMutexLocker acquires a mutex lock in the constructor and releases
 
-     (or unlocks) the mutex in the destructor making it much more difficult to
 
-     forget to release a mutex (which, in general, will promptly lead to serious
 
-     problems). See wxMutex for an example of wxMutexLocker usage.
 
-     @library{wxbase}
 
-     @category{threading}
 
-     @see wxMutex, wxCriticalSectionLocker
 
- */
 
- class wxMutexLocker
 
- {
 
- public:
 
-     /**
 
-         Constructs a wxMutexLocker object associated with mutex and locks it.
 
-         Call IsOk() to check if the mutex was successfully locked.
 
-     */
 
-     wxMutexLocker(wxMutex& mutex);
 
-     /**
 
-         Destructor releases the mutex if it was successfully acquired in the ctor.
 
-     */
 
-     ~wxMutexLocker();
 
-     /**
 
-         Returns @true if mutex was acquired in the constructor, @false otherwise.
 
-     */
 
-     bool IsOk() const;
 
- };
 
- /**
 
-     The possible wxMutex kinds.
 
- */
 
- enum wxMutexType
 
- {
 
-     /** Normal non-recursive mutex: try to always use this one. */
 
-     wxMUTEX_DEFAULT,
 
-     /** Recursive mutex: don't use these ones with wxCondition. */
 
-     wxMUTEX_RECURSIVE
 
- };
 
- /**
 
-     The possible wxMutex errors.
 
- */
 
- enum wxMutexError
 
- {
 
-     /** The operation completed successfully. */
 
-     wxMUTEX_NO_ERROR = 0,
 
-     /** The mutex hasn't been initialized. */
 
-     wxMUTEX_INVALID,
 
-      /** The mutex is already locked by the calling thread. */
 
-     wxMUTEX_DEAD_LOCK,
 
-     /** The mutex is already locked by another thread. */
 
-     wxMUTEX_BUSY,
 
-     /** An attempt to unlock a mutex which is not locked. */
 
-     wxMUTEX_UNLOCKED,
 
-     /** wxMutex::LockTimeout() has timed out. */
 
-     wxMUTEX_TIMEOUT,
 
-     /** Any other error */
 
-     wxMUTEX_MISC_ERROR
 
- };
 
- /**
 
-     @class wxMutex
 
-     A mutex object is a synchronization object whose state is set to signaled when
 
-     it is not owned by any thread, and nonsignaled when it is owned. Its name comes
 
-     from its usefulness in coordinating mutually-exclusive access to a shared
 
-     resource as only one thread at a time can own a mutex object.
 
-     Mutexes may be recursive in the sense that a thread can lock a mutex which it
 
-     had already locked before (instead of dead locking the entire process in this
 
-     situation by starting to wait on a mutex which will never be released while the
 
-     thread is waiting) but using them is not recommended under Unix and they are
 
-     @b not recursive by default. The reason for this is that recursive
 
-     mutexes are not supported by all Unix flavours and, worse, they cannot be used
 
-     with wxCondition.
 
-     For example, when several threads use the data stored in the linked list,
 
-     modifications to the list should only be allowed to one thread at a time
 
-     because during a new node addition the list integrity is temporarily broken
 
-     (this is also called @e program @e invariant).
 
-     @code
 
-     // this variable has an "s_" prefix because it is static: seeing an "s_" in
 
-     // a multithreaded program is in general a good sign that you should use a
 
-     // mutex (or a critical section)
 
-     static wxMutex *s_mutexProtectingTheGlobalData;
 
-     // we store some numbers in this global array which is presumably used by
 
-     // several threads simultaneously
 
-     wxArrayInt s_data;
 
-     void MyThread::AddNewNode(int num)
 
-     {
 
-         // ensure that no other thread accesses the list
 
-         s_mutexProtectingTheGlobalList->Lock();
 
-         s_data.Add(num);
 
-         s_mutexProtectingTheGlobalList->Unlock();
 
-     }
 
-     // return true if the given number is greater than all array elements
 
-     bool MyThread::IsGreater(int num)
 
-     {
 
-         // before using the list we must acquire the mutex
 
-         wxMutexLocker lock(s_mutexProtectingTheGlobalData);
 
-         size_t count = s_data.Count();
 
-         for ( size_t n = 0; n < count; n++ )
 
-         {
 
-             if ( s_data[n] > num )
 
-                 return false;
 
-         }
 
-         return true;
 
-     }
 
-     @endcode
 
-     Notice how wxMutexLocker was used in the second function to ensure that the
 
-     mutex is unlocked in any case: whether the function returns true or false
 
-     (because the destructor of the local object @e lock is always called).
 
-     Using this class instead of directly using wxMutex is, in general, safer
 
-     and is even more so if your program uses C++ exceptions.
 
-     @library{wxbase}
 
-     @category{threading}
 
-     @see wxThread, wxCondition, wxMutexLocker, wxCriticalSection
 
- */
 
- class wxMutex
 
- {
 
- public:
 
-     /**
 
-         Default constructor.
 
-     */
 
-     wxMutex(wxMutexType type = wxMUTEX_DEFAULT);
 
-     /**
 
-         Destroys the wxMutex object.
 
-     */
 
-     ~wxMutex();
 
-     /**
 
-         Locks the mutex object.
 
-         This is equivalent to LockTimeout() with infinite timeout.
 
-         Note that if this mutex is already locked by the caller thread,
 
-         this function doesn't block but rather immediately returns.
 
-         @return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_DEAD_LOCK.
 
-     */
 
-     wxMutexError Lock();
 
-     /**
 
-         Try to lock the mutex object during the specified time interval.
 
-         @return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_DEAD_LOCK, @c wxMUTEX_TIMEOUT.
 
-     */
 
-     wxMutexError LockTimeout(unsigned long msec);
 
-     /**
 
-         Tries to lock the mutex object. If it can't, returns immediately with an error.
 
-         @return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_BUSY.
 
-     */
 
-     wxMutexError TryLock();
 
-     /**
 
-         Unlocks the mutex object.
 
-         @return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_UNLOCKED.
 
-     */
 
-     wxMutexError Unlock();
 
- };
 
- // ============================================================================
 
- // Global functions/macros
 
- // ============================================================================
 
- /** @addtogroup group_funcmacro_thread */
 
- //@{
 
- /**
 
-     This macro declares a (static) critical section object named @a cs if
 
-     @c wxUSE_THREADS is 1 and does nothing if it is 0.
 
-     @header{wx/thread.h}
 
- */
 
- #define wxCRIT_SECT_DECLARE(cs)
 
- /**
 
-     This macro declares a critical section object named @a cs if
 
-     @c wxUSE_THREADS is 1 and does nothing if it is 0. As it doesn't include
 
-     the @c static keyword (unlike wxCRIT_SECT_DECLARE()), it can be used to
 
-     declare a class or struct member which explains its name.
 
-     @header{wx/thread.h}
 
- */
 
- #define wxCRIT_SECT_DECLARE_MEMBER(cs)
 
- /**
 
-     This macro creates a wxCriticalSectionLocker named @a name and associated
 
-     with the critical section @a cs if @c wxUSE_THREADS is 1 and does nothing
 
-     if it is 0.
 
-     @header{wx/thread.h}
 
- */
 
- #define wxCRIT_SECT_LOCKER(name, cs)
 
- /**
 
-     This macro combines wxCRIT_SECT_DECLARE() and wxCRIT_SECT_LOCKER(): it
 
-     creates a static critical section object and also the lock object
 
-     associated with it. Because of this, it can be only used inside a function,
 
-     not at global scope. For example:
 
-     @code
 
-     int IncCount()
 
-     {
 
-         static int s_counter = 0;
 
-         wxCRITICAL_SECTION(counter);
 
-         return ++s_counter;
 
-     }
 
-     @endcode
 
-     Note that this example assumes that the function is called the first time
 
-     from the main thread so that the critical section object is initialized
 
-     correctly by the time other threads start calling it, if this is not the
 
-     case this approach can @b not be used and the critical section must be made
 
-     a global instead.
 
-     @header{wx/thread.h}
 
- */
 
- #define wxCRITICAL_SECTION(name)
 
- /**
 
-     This macro is equivalent to
 
-     @ref wxCriticalSection::Leave "critical_section.Leave()" if
 
-     @c wxUSE_THREADS is 1 and does nothing if it is 0.
 
-     @header{wx/thread.h}
 
- */
 
- #define wxLEAVE_CRIT_SECT(critical_section)
 
- /**
 
-     This macro is equivalent to
 
-     @ref wxCriticalSection::Enter "critical_section.Enter()" if
 
-     @c wxUSE_THREADS is 1 and does nothing if it is 0.
 
-     @header{wx/thread.h}
 
- */
 
- #define wxENTER_CRIT_SECT(critical_section)
 
- /**
 
-     Returns @true if this thread is the main one. Always returns @true if
 
-     @c wxUSE_THREADS is 0.
 
-     @header{wx/thread.h}
 
- */
 
- bool wxIsMainThread();
 
- /**
 
-     This function must be called when any thread other than the main GUI thread
 
-     wants to get access to the GUI library. This function will block the
 
-     execution of the calling thread until the main thread (or any other thread
 
-     holding the main GUI lock) leaves the GUI library and no other thread will
 
-     enter the GUI library until the calling thread calls wxMutexGuiLeave().
 
-     Typically, these functions are used like this:
 
-     @code
 
-     void MyThread::Foo(void)
 
-     {
 
-         // before doing any GUI calls we must ensure that
 
-         // this thread is the only one doing it!
 
-         wxMutexGuiEnter();
 
-         // Call GUI here:
 
-         my_window->DrawSomething();
 
-         wxMutexGuiLeave();
 
-     }
 
-     @endcode
 
-     This function is only defined on platforms which support preemptive
 
-     threads and only works under some ports (wxMSW currently).
 
-     @note Under GTK, no creation of top-level windows is allowed in any thread
 
-           but the main one.
 
-     @header{wx/thread.h}
 
- */
 
- void wxMutexGuiEnter();
 
- /**
 
-     This function is only defined on platforms which support preemptive
 
-     threads.
 
-     @see wxMutexGuiEnter()
 
-     @header{wx/thread.h}
 
- */
 
- void wxMutexGuiLeave();
 
- //@}
 
 
  |