added wxThreadHelper class (patch 756906)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21862 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2003-07-10 12:36:05 +00:00
parent 0148248250
commit 78ee6a4750
6 changed files with 257 additions and 0 deletions

View 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:

View 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}

View File

@ -295,6 +295,8 @@
\input txtstrm.tex
\input valtext.tex
\input thread.tex
\input threadh.tex
\input threadht.tex
\input timer.tex
\input timespan.tex
\input tipprov.tex

100
docs/latex/wx/threadh.tex Normal file
View File

@ -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.

View File

@ -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.

View 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
// ----------------------------------------------------------------------------