]> git.saurik.com Git - wxWidgets.git/commitdiff
added wxThreadHelper class (patch 756906)
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 10 Jul 2003 12:36:05 +0000 (12:36 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 10 Jul 2003 12:36:05 +0000 (12:36 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21862 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
docs/latex/wx/category.tex
docs/latex/wx/classes.tex
docs/latex/wx/threadh.tex [new file with mode: 0644]
docs/latex/wx/threadht.tex [new file with mode: 0644]
include/wx/thread.h

index 7a74e203cdf8b7a31a41b8f8b07a9c7a914f2bdd..955902973e0f77095722dbfd831c18028f9c0811 100644 (file)
@@ -59,6 +59,7 @@ All:
 - added support for POST method and alt ports to wxHTTP (Roger Chickering)
 - added wxSocket::IPAddress() (Chris Mellon)
 - wxDataStreams can read/write many elements at once (Mickael Gilabert)
+- added wxThreadHelper class (Daniel Howard)
 
 wxBase:
 
index 0959dd071b3ebdb36c85ca51eab765c343e34bf7..d7a3979c84ab4e44c4314d64ed6bb5b1f3a30acf 100644 (file)
@@ -500,6 +500,7 @@ capabilities of the various platforms.
 \twocolwidtha{6cm}
 \begin{twocollist}\itemsep=0pt
 \twocolitem{\helpref{wxThread}{wxthread}}{Thread class}
+\twocolitem{\helpref{wxThreadHelper}{wxthreadhelper}}{Manages background threads easily}
 \twocolitem{\helpref{wxMutex}{wxmutex}}{Mutex class}
 \twocolitem{\helpref{wxMutexLocker}{wxmutexlocker}}{Mutex locker utility class}
 \twocolitem{\helpref{wxCriticalSection}{wxcriticalsection}}{Critical section class}
index a8d555ce31a9e0c2f93316c005408a9dafcf2fb8..d39d3372eeba36acb8952db163d38cd16f8c0f1c 100644 (file)
 \input txtstrm.tex
 \input valtext.tex
 \input thread.tex
+\input threadh.tex
+\input threadht.tex
 \input timer.tex
 \input timespan.tex
 \input tipprov.tex
diff --git a/docs/latex/wx/threadh.tex b/docs/latex/wx/threadh.tex
new file mode 100644 (file)
index 0000000..729f510
--- /dev/null
@@ -0,0 +1,100 @@
+\section{\class{wxThreadHelper}}\label{wxthreadhelper}
+
+The wxThreadHelper class is a mix-in class that manages a single background
+thread.  By deriving from wxThreadHelper, a class can implement the thread
+code in its own \helpref{wxThreadHelper::Entry}{wxthreadhelperentry} 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, \helpref{wxFrame}{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 \helpref{wxThread}{wxthread} derived object would be created
+with the calculation code implemented in
+\helpref{wxThread::Entry}{wxthreadentry}.  To access the inputs to the
+calculation, the frame object would often to pass a pointer to itself to the
+thread object.  Similiarly, 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.
+
+\wxheading{Derived from}
+
+None.
+
+\wxheading{Include files}
+
+<wx/thread.h>
+
+\wxheading{See also}
+
+\helpref{wxThread}{wxthread}, \helpref{wxThreadHelperThread}{wxthreadhelperthread}
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+\membersection{wxThreadHelper::wxThreadHelper}\label{wxthreadhelperctor}
+
+\func{}{wxThreadHelper}{\void}
+
+This constructor simply initializes a member variable.
+
+\membersection{wxThreadHelper::m\_thread}
+
+\member{wxThread *}{m\_thread}
+
+the actual \helpref{wxThread}{wxthread} object.
+
+\membersection{wxThread::\destruct{wxThreadHelper}}
+
+\func{}{\destruct{wxThreadHelper}}{\void}
+
+The destructor frees the resources associated with the thread.
+
+\membersection{wxThreadHelper::Create}\label{wxthreadhelpercreate}
+
+\func{wxThreadError}{Create}{\param{unsigned int }{stackSize = 0}}
+
+Creates a new thread. The thread object is created in the suspended state, and you
+should call \helpref{GetThread()->Run()}{wxthreadhelperthreadrun} 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).
+
+\wxheading{Return value}
+
+One of:
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf wxTHREAD\_NO\_ERROR}}{There was no error.}
+\twocolitem{{\bf wxTHREAD\_NO\_RESOURCE}}{There were insufficient resources to create a new thread.}
+\twocolitem{{\bf wxTHREAD\_RUNNING}}{The thread is already running.}
+\end{twocollist}
+
+\membersection{wxThreadHelper::Entry}\label{wxthreadhelperentry}
+
+\func{virtual ExitCode}{Entry}{\void}
+
+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
+\helpref{GetThread()->Wait()}{wxthreadwait}.
+
+This function is called by wxWindows itself and should never be called
+directly.
+
+\membersection{wxThreadHelper::GetThread}\label{wxthreadhelpergetthread}
+
+\func{wxThread *}{GetThread}{\void}
+
+This is a public function that returns the \helpref{wxThread}{wxthread} object
+associated with the thread.
diff --git a/docs/latex/wx/threadht.tex b/docs/latex/wx/threadht.tex
new file mode 100644 (file)
index 0000000..8798766
--- /dev/null
@@ -0,0 +1,74 @@
+\section{\class{wxThreadHelperThread}}\label{wxThreadHelperThread}
+
+The wxThreadHelperThread class is used internally by the
+\helpref{wxThreadHelper}{wxthreadhelper} mix-in class.  This class simply
+turns around and calls \helpref{wxThreadHelper::Entry}{wxthreadhelperentry}
+in its owner class when the thread runs.
+
+\wxheading{Derived from}
+
+\helpref{wxThread}{wxthread}
+
+\wxheading{Include files}
+
+<wx/thread.h>
+
+\wxheading{See also}
+
+\helpref{wxThread}{wxthread}, \helpref{wxThreadHelper}{wxthreadhelper}
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+\membersection{wxThreadHelperThread::wxThreadHelperThread}\label{wxthreadctor}
+
+\func{}{wxThreadHelperThread}{\void}
+
+This constructor simply initializes member variables.
+
+\membersection{wxThreadHelperThread::m\_owner}
+
+\member{wxThreadHelperThread\& }{m\_owner}
+
+the \helpref{wxThreadHelper}{wxthreadhelper} object which holds the code to
+run inside the thread.
+
+\membersection{wxThreadHelperThread::Entry}\label{wxthreadhelperthreadentry}
+
+\func{virtual ExitCode}{Entry}{\void}
+
+This is the entry point of the thread.  This function eventually calls
+\helpref{wxThreadHelper::Entry}{wxthreadhelperentry}.  The actual worker
+thread code should be implemented in
+\helpref{wxThreadHelper::Entry}{wxthreadhelperentry}, not here, so all
+shared data and synchronization objects can be shared easily between the
+main thread and the worker thread.
+
+The returned value is the thread exit code which is the value returned by
+\helpref{Wait()}{wxthreadwait}.
+
+This function is called by wxWindows itself and should never be called
+directly.
+
+\membersection{wxThreadHelperThread::CallEntry}\label{wxthreadhelperthreadcallentry}
+
+\func{virtual ExitCode}{CallEntry}{\void}
+
+This is a convenience method that actually calls
+\helpref{wxThreadHelper::Entry}{wxthreadhelperentry}.  This function
+eventually calls \helpref{wxThreadHelper::Entry}{wxthreadhelperentry}.
+The actual worker thread code should be implemented in
+\helpref{wxThreadHelper::Entry}{wxthreadhelperentry}, not here, so all
+shared data and synchronization objects can be shared easily between the
+main thread and the worker thread.
+
+It must be declared after \helpref{wxThreadHelper}{wxthreadhelper} so it
+can access \helpref{wxThreadHelper::Entry}{wxthreadhelperentry} and avoid
+circular dependencies.  Thus, it uses the inline keyword to allow its
+definition outside of the class definition.  To avoid any conflicts
+between the virtual and inline keywords, it is a non-virtual method.
+
+The returned value is the thread exit code which is the value returned by
+\helpref{Wait()}{wxthreadwait}.
+
+This function is called by wxWindows itself and should never be called
+directly.
index 24046e1d5af73c57c1875898518b7c09cd5d0ac0..543f16cedaf9620d56d3206f4b50e1d142e05de3 100644 (file)
@@ -114,6 +114,7 @@ enum wxMutexType
 };
 
 // forward declarations
+class WXDLLIMPEXP_BASE wxThreadHelper;
 class WXDLLIMPEXP_BASE wxConditionInternal;
 class WXDLLIMPEXP_BASE wxMutexInternal;
 class WXDLLIMPEXP_BASE wxSemaphoreInternal;
@@ -581,6 +582,84 @@ private:
     bool m_isDetached;
 };
 
+// wxThreadHelperThread class
+// --------------------------
+
+class WXDLLIMPEXP_BASE wxThreadHelperThread : public wxThread
+{
+public:
+    // constructor only creates the C++ thread object and doesn't create (or
+    // start) the real thread
+    wxThreadHelperThread(wxThreadHelper& owner)
+        : wxThread(wxTHREAD_JOINABLE), m_owner(owner)
+        { }
+
+protected:
+    // entry point for the thread -- calls Entry() in owner.
+    virtual void *Entry();
+
+private:
+    // the owner of the thread
+    wxThreadHelper& m_owner;
+
+    // no copy ctor/assignment operator
+    wxThreadHelperThread(const wxThreadHelperThread&);
+    wxThreadHelperThread& operator=(const wxThreadHelperThread&);
+};
+
+// ----------------------------------------------------------------------------
+// wxThreadHelper: this class implements the threading logic to run a
+// background task in another object (such as a window).  It is a mix-in: just
+// derive from it to implement a threading background task in your class.
+// ----------------------------------------------------------------------------
+
+class WXDLLIMPEXP_BASE wxThreadHelper
+{
+private:
+    void KillThread()
+    {
+        if ( m_thread )
+        {
+            m_thread->Kill();
+            delete m_thread;
+        }
+    }
+
+public:
+    // constructor only initializes m_thread to NULL
+    wxThreadHelper() : m_thread(NULL) { }
+
+    // destructor deletes m_thread
+    virtual ~wxThreadHelper() { KillThread(); }
+
+    // create a new thread (and optionally set the stack size on platforms that
+    // support/need that), call Run() to start it
+    wxThreadError Create(unsigned int stackSize = 0)
+    {
+        KillThread();
+
+        m_thread = new wxThreadHelperThread(*this);
+
+        return m_thread->Create(stackSize);
+    }
+
+    // entry point for the thread - called by Run() and executes in the context
+    // of this thread.
+    virtual void *Entry() = 0;
+
+    // returns a pointer to the thread which can be used to call Run()
+    wxThread *GetThread() const { return m_thread; }
+
+protected:
+    wxThread *m_thread;
+};
+
+// call Entry() in owner, put it down here to avoid circular declarations
+inline void *wxThreadHelperThread::Entry()
+{
+    return m_owner.Entry();
+}
+
 // ----------------------------------------------------------------------------
 // Automatic initialization
 // ----------------------------------------------------------------------------