+
+ // true if the thread is detached, false if it is joinable
+ 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, wxThreadKind kind)
+ : wxThread(kind), 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 wxThreadHelperThread is detached and is about to finish, it will
+ // set m_thread to NULL so don't delete it then.
+ // But if KillThread is called before wxThreadHelperThread (in detached mode)
+ // sets it to NULL, then the thread object still exists and can be killed
+ wxCriticalSectionLocker locker(m_critSection);
+
+ if ( m_thread )
+ {
+ m_thread->Kill();
+
+ if ( m_kind == wxTHREAD_JOINABLE )
+ delete m_thread;
+
+ m_thread = NULL;
+ }
+ }
+
+public:
+ // constructor only initializes m_thread to NULL
+ wxThreadHelper(wxThreadKind kind = wxTHREAD_JOINABLE)
+ : m_thread(NULL), m_kind(kind) { }
+
+ // destructor deletes m_thread
+ virtual ~wxThreadHelper() { KillThread(); }
+
+#if WXWIN_COMPATIBILITY_2_8
+ wxDEPRECATED( wxThreadError Create(unsigned int stackSize = 0) );
+#endif
+
+ // create a new thread (and optionally set the stack size on platforms that
+ // support/need that), call Run() to start it
+ wxThreadError CreateThread(wxThreadKind kind = wxTHREAD_JOINABLE,
+ unsigned int stackSize = 0)
+ {
+ KillThread();
+
+ m_kind = kind;
+ m_thread = new wxThreadHelperThread(*this, m_kind);
+
+ 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
+ {
+ wxCriticalSectionLocker locker((wxCriticalSection&)m_critSection);
+
+ wxThread* thread = m_thread;
+
+ return thread;
+ }
+
+protected:
+ wxThread *m_thread;
+ wxThreadKind m_kind;
+ wxCriticalSection m_critSection; // To guard the m_thread variable
+
+ friend class wxThreadHelperThread;