class wxFDIODispatcher;
class wxUnixEventLoopSource;
-class wxWakeUpPipe;
+class wxWakeUpPipeMT;
class WXDLLIMPEXP_BASE wxConsoleEventLoop
#ifdef __WXOSX__
private:
// pipe used for wake up messages: when a child thread wants to wake up
// the event loop in the main thread it writes to this pipe
- wxWakeUpPipe *m_wakeupPipe;
+ wxWakeUpPipeMT *m_wakeupPipe;
// either wxSelectDispatcher or wxEpollDispatcher
wxFDIODispatcher *m_dispatcher;
// wxWakeUpPipe: allows to wake up the event loop by writing to it
// ----------------------------------------------------------------------------
+// This class is not MT-safe, see wxWakeUpPipeMT below for a wake up pipe
+// usable from other threads.
+
class wxWakeUpPipe : public wxFDIOHandler
{
public:
//
// It simply writes to the write end of the pipe.
//
- // Notice that this method can be, and often is, called from another
- // thread.
- void WakeUp();
+ // As indicated by its name, this method does no locking and so can be
+ // called only from the main thread.
+ void WakeUpNoLock();
+
+ // Same as WakeUp() but without locking.
// Return the read end of the pipe.
int GetReadFd() { return m_pipe[wxPipe::Read]; }
private:
wxPipe m_pipe;
- // Protects access to m_pipeIsEmpty.
- wxCriticalSection m_pipeLock;
-
// This flag is set to true after writing to the pipe and reset to false
// after reading from it in the main thread. Having it allows us to avoid
// overflowing the pipe with too many writes if the main thread can't keep
bool m_pipeIsEmpty;
};
+// ----------------------------------------------------------------------------
+// wxWakeUpPipeMT: thread-safe version of wxWakeUpPipe
+// ----------------------------------------------------------------------------
+
+// This class can be used from multiple threads, i.e. its WakeUp() can be
+// called concurrently.
+
+class wxWakeUpPipeMT : public wxWakeUpPipe
+{
+public:
+ wxWakeUpPipeMT() { }
+
+ // Thread-safe wrapper around WakeUpNoLock(): can be called from another
+ // thread to wake up the main one.
+ void WakeUp()
+ {
+ wxCriticalSectionLocker lock(m_pipeLock);
+
+ WakeUpNoLock();
+ }
+
+ virtual void OnReadWaiting()
+ {
+ wxCriticalSectionLocker lock(m_pipeLock);
+
+ wxWakeUpPipe::OnReadWaiting();
+ }
+
+private:
+ // Protects access to m_pipeIsEmpty.
+ wxCriticalSection m_pipeLock;
+};
+
#endif // _WX_UNIX_PRIVATE_WAKEUPPIPE_H_
// wakeup handling
// ----------------------------------------------------------------------------
-void wxWakeUpPipe::WakeUp()
+void wxWakeUpPipe::WakeUpNoLock()
{
- wxCriticalSectionLocker lock(m_pipeLock);
-
// No need to do anything if the pipe already contains something.
if ( !m_pipeIsEmpty )
return;
// got wakeup from child thread, remove the data that provoked it from the
// pipe
- wxCriticalSectionLocker lock(m_pipeLock);
-
char buf[4];
for ( ;; )
{