]> git.saurik.com Git - wxWidgets.git/blobdiff - docs/latex/wx/conditn.tex
cleanup (mainly wrapping lines to be < 80 chars); added IsExpanded()
[wxWidgets.git] / docs / latex / wx / conditn.tex
index bb71a7e7d70671685ed1760b45d0319f7ea952ed..1c31d62d801f5b7b4d6f9fc1c1d2a9b46e302797 100644 (file)
@@ -13,8 +13,12 @@ worker threads it already makes much more sense).
 
 Note that a call to \helpref{Signal()}{wxconditionsignal} may happen before the
 other thread calls \helpref{Wait()}{wxconditionwait} and, just as with the
-pthread conditions, the signal is then lost and so if you want to be sure to
-get it you must use a mutex together with the condition variable.
+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 
+\helpref{Signal()}{wxconditionsignal}. Of course, this means that this call is
+going to block until \helpref{Wait()}{wxconditionwait} is called by another
+thread.
 
 \wxheading{Example}
 
@@ -22,10 +26,10 @@ 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:
 
 \begin{verbatim}
-class MyWaitingThread : public wxThread
+class MySignallingThread : public wxThread
 {
 public:
-    MyWaitingThread(wxMutex *mutex, wxCondition *condition)
+    MySignallingThread(wxMutex *mutex, wxCondition *condition)
     {
         m_mutex = mutex;
         m_condition = condition;
@@ -35,45 +39,64 @@ public:
 
     virtual ExitCode Entry()
     {
-        // wait for the signal from the main thread: it is absolutely necessary
-        // to look the mutex before doing it!
-        m_mutex->Lock();
-        m_condition->Signal();
-        m_mutex->Unlock();
-
         ... 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);
-
-    for ( int i = 0; i < 10; i++ )
-    {
-        MyWaitingThread *thread = new MyWaitingThread(&mutex, &condition);
+    wxCondition condition(mutex);
 
-        thread->Run();
-    }
+    // the mutex should be initially locked
+    mutex.Lock();
 
-    // wake up one of the threads
-    condition.Signal();
+    // 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);
 
-    // wake up all the other ones
-    condition.Broadcast();
+    thread->Run();
 
-    ... wait until they terminate or do something else ...
+    // 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;
 }
 \end{verbatim}
 
+Of course, here it would be much better to simply use a joinable thread and
+call \helpref{wxThread::Wait}{wxthreadwait} on it, but this example does
+illustrate the importance of properly locking the mutex when using
+wxCondition.
+
+\wxheading{Constants}
+
+The following return codes are returned by wxCondition member functions:
+
+\begin{verbatim}
+enum wxCondError
+{
+    wxCOND_NO_ERROR = 0,    // successful completion
+    wxCOND_INVALID,         // object hasn't been initialized successfully
+    wxCOND_TIMEOUT,         // WaitTimeout() has timed out
+    wxCOND_MISC_ERROR       // some other error
+};
+\end{verbatim}
+
 \wxheading{Derived from}
 
 None.
@@ -88,13 +111,17 @@ None.
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
-\membersection{wxCondition::wxCondition}\label{wxconditionconstr}
+\membersection{wxCondition::wxCondition}\label{wxconditionctor}
+
+\func{}{wxCondition}{\param{wxMutex\& }{mutex}}
 
-\func{}{wxCondition}{\param{wxMutex }{*mutex}}
+Default and only constructor. The {\it mutex} must be locked by the caller
+before calling \helpref{Wait}{wxconditionwait} function.
 
-Default and only constructor. The {\it mutex} must be non {\tt NULL}.
+Use \helpref{IsOk}{wxconditionisok} to check if the object was successfully
+initialized.
 
-\membersection{wxCondition::\destruct{wxCondition}}
+\membersection{wxCondition::\destruct{wxCondition}}\label{wxconditiondtor}
 
 \func{}{\destruct{wxCondition}}{\void}
 
@@ -113,6 +140,13 @@ not.
 
 \helpref{wxCondition::Signal}{wxconditionsignal}
 
+\membersection{wxCondition::IsOk}\label{wxconditionisok}
+
+\constfunc{bool}{IsOk}{\void}
+
+Returns {\tt true} if the object had been initialized successfully, {\tt false} 
+if an error occurred.
+
 \membersection{wxCondition::Signal}\label{wxconditionsignal}
 
 \func{void}{Signal}{\void}
@@ -131,26 +165,47 @@ condition is locked or not.
 
 \membersection{wxCondition::Wait}\label{wxconditionwait}
 
-\func{void}{Wait}{\void}
+\func{wxCondError}{Wait}{\void}
 
 Waits until the condition is signalled.
 
-\func{bool}{Wait}{\param{unsigned long}{ sec}, \param{unsigned long}{ nsec}}
+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 \helpref{Signal}{wxconditionsignal} or 
+\helpref{Broadcast}{wxconditionbroadcast} is called. It then locks the mutex
+again and returns.
+
+Note that even if \helpref{Signal}{wxconditionsignal} 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.
+
+\wxheading{Return value}
+
+Returns {\tt wxCOND\_NO\_ERROR} on success, another value if an error occurred.
+
+\wxheading{See also}
+
+\helpref{WaitTimeout}{wxconditionwaittimeout}
+
+
+\membersection{wxCondition::WaitTimeout}\label{wxconditionwaittimeout}
+
+\func{wxCondError}{WaitTimeout}{\param{unsigned long}{ milliseconds}}
 
 Waits until the condition is signalled or the timeout has elapsed.
 
-Note that the mutex associated with this condition {\bf must} be acquired by
-the thread before calling this method.
+This method is identical to \helpref{Wait}{wxconditionwait} except that it
+returns, with the return code of {\tt wxCOND\_TIMEOUT} as soon as the given
+timeout expires.
 
 \wxheading{Parameters}
 
-\docparam{sec}{Timeout in seconds}
-
-\docparam{nsec}{Timeout nanoseconds component (added to {\it sec}).}
+\docparam{milliseconds}{Timeout in milliseconds}
 
 \wxheading{Return value}
 
-The second form returns {\tt TRUE} if the condition has been signalled, or
-{\tt FALSE} if it returned because the timeout has elapsed.
-
+Returns {\tt wxCOND\_NO\_ERROR} if the condition was signalled, 
+{\tt wxCOND\_TIMEOUT} if the timeout elapsed before this happened or another
+error code from wxCondError enum.