#if wxUSE_THREADS
// only for wxUSE_THREADS - otherwise we'd get undefined symbols
-#if defined(__GNUG__) && !defined(__APPLE__)
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma interface "thread.h"
#endif
};
// forward declarations
+class WXDLLIMPEXP_BASE wxThreadHelper;
class WXDLLIMPEXP_BASE wxConditionInternal;
class WXDLLIMPEXP_BASE wxMutexInternal;
class WXDLLIMPEXP_BASE wxSemaphoreInternal;
// in order to avoid any overhead under platforms where critical sections are
// just mutexes make all wxCriticalSection class functions inline
-#if !defined(__WXMSW__) && !defined(__WXPM__)
+#if !defined(__WXMSW__)
#define wxCRITSECT_IS_MUTEX 1
#define wxCRITSECT_INLINE inline
-#else // MSW || OS2
+#else // MSW
#define wxCRITSECT_IS_MUTEX 0
#define wxCRITSECT_INLINE
wxCritSectBuffer m_buffer;
};
-#else
- // nothing for OS/2
-#endif // Unix/Win32/OS2
+#endif // Unix&OS2/Win32
DECLARE_NO_COPY_CLASS(wxCriticalSection)
};
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
// ----------------------------------------------------------------------------
#if wxUSE_THREADS
-#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXPM__)
+#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXPM__) || defined(__EMX__)
// unlock GUI if there are threads waiting for and lock it back when
// there are no more of them - should be called periodically by the main
// thread