]> git.saurik.com Git - wxWidgets.git/commitdiff
Extract PipeIOHandler class into a header and rename to wxWakeUpPipe.
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 3 Jul 2013 00:27:28 +0000 (00:27 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 3 Jul 2013 00:27:28 +0000 (00:27 +0000)
No real changes to the class, just make it possible to reuse it outside of
Unix wxEventLoop code.

See #10258.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74338 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

Makefile.in
build/bakefiles/files.bkl
include/wx/unix/evtloop.h
include/wx/unix/private/wakeuppipe.h [new file with mode: 0644]
src/unix/evtloopunix.cpp
src/unix/wakeuppipe.cpp [new file with mode: 0644]

index 0e81d7b435434b5c9e1957c329f0e3085527a8b7..6ab453d691438fe6096767230c4b02ec9cc4dfb8 100644 (file)
@@ -836,6 +836,7 @@ ALL_BASE_SOURCES =  \
        src/unix/timerunx.cpp \
        src/unix/threadpsx.cpp \
        src/unix/utilsunx.cpp \
+       src/unix/wakeuppipe.cpp \
        src/unix/fswatcher_kqueue.cpp \
        src/unix/mimetype.cpp \
        src/unix/fswatcher_inotify.cpp \
@@ -2240,6 +2241,7 @@ COND_TOOLKIT_OSX_CARBON_BASE_OSX_SRC =  \
        src/unix/timerunx.cpp \
        src/unix/threadpsx.cpp \
        src/unix/utilsunx.cpp \
+       src/unix/wakeuppipe.cpp \
        src/unix/fswatcher_kqueue.cpp
 @COND_TOOLKIT_OSX_CARBON@BASE_OSX_SRC = $(COND_TOOLKIT_OSX_CARBON_BASE_OSX_SRC)
 COND_TOOLKIT_OSX_COCOA_BASE_OSX_SRC =  \
@@ -2263,6 +2265,7 @@ COND_TOOLKIT_OSX_COCOA_BASE_OSX_SRC =  \
        src/unix/timerunx.cpp \
        src/unix/threadpsx.cpp \
        src/unix/utilsunx.cpp \
+       src/unix/wakeuppipe.cpp \
        src/unix/fswatcher_kqueue.cpp
 @COND_TOOLKIT_OSX_COCOA@BASE_OSX_SRC = $(COND_TOOLKIT_OSX_COCOA_BASE_OSX_SRC)
 COND_TOOLKIT_OSX_IPHONE_BASE_OSX_SRC =  \
@@ -2286,6 +2289,7 @@ COND_TOOLKIT_OSX_IPHONE_BASE_OSX_SRC =  \
        src/unix/timerunx.cpp \
        src/unix/threadpsx.cpp \
        src/unix/utilsunx.cpp \
+       src/unix/wakeuppipe.cpp \
        src/unix/fswatcher_kqueue.cpp
 @COND_TOOLKIT_OSX_IPHONE@BASE_OSX_SRC = $(COND_TOOLKIT_OSX_IPHONE_BASE_OSX_SRC)
 COND_TOOLKIT_COCOA_BASE_OSX_SRC =  \
@@ -2303,6 +2307,7 @@ COND_TOOLKIT_COCOA_BASE_OSX_SRC =  \
        src/unix/timerunx.cpp \
        src/unix/threadpsx.cpp \
        src/unix/utilsunx.cpp \
+       src/unix/wakeuppipe.cpp \
        src/unix/fswatcher_kqueue.cpp \
        src/unix/mimetype.cpp \
        src/osx/core/cfstring.cpp \
@@ -2326,6 +2331,7 @@ COND_TOOLKIT_GTK_BASE_OSX_SRC =  \
        src/unix/timerunx.cpp \
        src/unix/threadpsx.cpp \
        src/unix/utilsunx.cpp \
+       src/unix/wakeuppipe.cpp \
        src/unix/fswatcher_kqueue.cpp \
        src/unix/mimetype.cpp \
        src/osx/core/cfstring.cpp \
@@ -2349,6 +2355,7 @@ COND_TOOLKIT_X11_BASE_OSX_SRC =  \
        src/unix/timerunx.cpp \
        src/unix/threadpsx.cpp \
        src/unix/utilsunx.cpp \
+       src/unix/wakeuppipe.cpp \
        src/unix/fswatcher_kqueue.cpp \
        src/unix/mimetype.cpp \
        src/osx/core/cfstring.cpp \
@@ -2372,6 +2379,7 @@ COND_TOOLKIT_MOTIF_BASE_OSX_SRC =  \
        src/unix/timerunx.cpp \
        src/unix/threadpsx.cpp \
        src/unix/utilsunx.cpp \
+       src/unix/wakeuppipe.cpp \
        src/unix/fswatcher_kqueue.cpp \
        src/unix/mimetype.cpp \
        src/osx/core/cfstring.cpp \
@@ -2395,6 +2403,7 @@ COND_TOOLKIT__BASE_OSX_SRC =  \
        src/unix/timerunx.cpp \
        src/unix/threadpsx.cpp \
        src/unix/utilsunx.cpp \
+       src/unix/wakeuppipe.cpp \
        src/unix/fswatcher_kqueue.cpp \
        src/unix/mimetype.cpp \
        src/osx/core/cfstring.cpp \
@@ -4499,6 +4508,7 @@ COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS =  \
        monodll_timerunx.o \
        monodll_threadpsx.o \
        monodll_utilsunx.o \
+       monodll_wakeuppipe.o \
        monodll_fswatcher_kqueue.o
 @COND_PLATFORM_MACOSX_1@__BASE_PLATFORM_SRC_OBJECTS = $(COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS)
 @COND_PLATFORM_MSDOS_1@__BASE_PLATFORM_SRC_OBJECTS = \
@@ -4533,6 +4543,7 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS =  \
        monodll_timerunx.o \
        monodll_threadpsx.o \
        monodll_utilsunx.o \
+       monodll_wakeuppipe.o \
        monodll_fswatcher_kqueue.o \
        monodll_unix_mimetype.o \
        monodll_fswatcher_inotify.o
@@ -6745,6 +6756,7 @@ COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_1 =  \
        monolib_timerunx.o \
        monolib_threadpsx.o \
        monolib_utilsunx.o \
+       monolib_wakeuppipe.o \
        monolib_fswatcher_kqueue.o
 @COND_PLATFORM_MACOSX_1@__BASE_PLATFORM_SRC_OBJECTS_1 = $(COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_1)
 @COND_PLATFORM_MSDOS_1@__BASE_PLATFORM_SRC_OBJECTS_1 \
@@ -6779,6 +6791,7 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_1 =  \
        monolib_timerunx.o \
        monolib_threadpsx.o \
        monolib_utilsunx.o \
+       monolib_wakeuppipe.o \
        monolib_fswatcher_kqueue.o \
        monolib_unix_mimetype.o \
        monolib_fswatcher_inotify.o
@@ -9044,6 +9057,7 @@ COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_2 =  \
        basedll_timerunx.o \
        basedll_threadpsx.o \
        basedll_utilsunx.o \
+       basedll_wakeuppipe.o \
        basedll_fswatcher_kqueue.o
 @COND_PLATFORM_MACOSX_1@__BASE_PLATFORM_SRC_OBJECTS_2 = $(COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_2)
 @COND_PLATFORM_MSDOS_1@__BASE_PLATFORM_SRC_OBJECTS_2 \
@@ -9078,6 +9092,7 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_2 =  \
        basedll_timerunx.o \
        basedll_threadpsx.o \
        basedll_utilsunx.o \
+       basedll_wakeuppipe.o \
        basedll_fswatcher_kqueue.o \
        basedll_unix_mimetype.o \
        basedll_fswatcher_inotify.o
@@ -9144,6 +9159,7 @@ COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_3 =  \
        baselib_timerunx.o \
        baselib_threadpsx.o \
        baselib_utilsunx.o \
+       baselib_wakeuppipe.o \
        baselib_fswatcher_kqueue.o
 @COND_PLATFORM_MACOSX_1@__BASE_PLATFORM_SRC_OBJECTS_3 = $(COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_3)
 @COND_PLATFORM_MSDOS_1@__BASE_PLATFORM_SRC_OBJECTS_3 \
@@ -9178,6 +9194,7 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_3 =  \
        baselib_timerunx.o \
        baselib_threadpsx.o \
        baselib_utilsunx.o \
+       baselib_wakeuppipe.o \
        baselib_fswatcher_kqueue.o \
        baselib_unix_mimetype.o \
        baselib_fswatcher_inotify.o
@@ -18931,6 +18948,12 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP)
 @COND_PLATFORM_MACOSX_1@monodll_utilsunx.o: $(srcdir)/src/unix/utilsunx.cpp $(MONODLL_ODEP)
 @COND_PLATFORM_MACOSX_1@       $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/unix/utilsunx.cpp
 
+@COND_PLATFORM_UNIX_1@monodll_wakeuppipe.o: $(srcdir)/src/unix/wakeuppipe.cpp $(MONODLL_ODEP)
+@COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/unix/wakeuppipe.cpp
+
+@COND_PLATFORM_MACOSX_1@monodll_wakeuppipe.o: $(srcdir)/src/unix/wakeuppipe.cpp $(MONODLL_ODEP)
+@COND_PLATFORM_MACOSX_1@       $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/unix/wakeuppipe.cpp
+
 @COND_PLATFORM_UNIX_1@monodll_fswatcher_kqueue.o: $(srcdir)/src/unix/fswatcher_kqueue.cpp $(MONODLL_ODEP)
 @COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/unix/fswatcher_kqueue.cpp
 
@@ -24790,6 +24813,12 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP)
 @COND_PLATFORM_MACOSX_1@monolib_utilsunx.o: $(srcdir)/src/unix/utilsunx.cpp $(MONOLIB_ODEP)
 @COND_PLATFORM_MACOSX_1@       $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/unix/utilsunx.cpp
 
+@COND_PLATFORM_UNIX_1@monolib_wakeuppipe.o: $(srcdir)/src/unix/wakeuppipe.cpp $(MONOLIB_ODEP)
+@COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/unix/wakeuppipe.cpp
+
+@COND_PLATFORM_MACOSX_1@monolib_wakeuppipe.o: $(srcdir)/src/unix/wakeuppipe.cpp $(MONOLIB_ODEP)
+@COND_PLATFORM_MACOSX_1@       $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/unix/wakeuppipe.cpp
+
 @COND_PLATFORM_UNIX_1@monolib_fswatcher_kqueue.o: $(srcdir)/src/unix/fswatcher_kqueue.cpp $(MONOLIB_ODEP)
 @COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/unix/fswatcher_kqueue.cpp
 
@@ -29062,6 +29091,12 @@ basedll_cocoa_utils.o: $(srcdir)/src/osx/cocoa/utils.mm $(BASEDLL_ODEP)
 @COND_PLATFORM_MACOSX_1@basedll_utilsunx.o: $(srcdir)/src/unix/utilsunx.cpp $(BASEDLL_ODEP)
 @COND_PLATFORM_MACOSX_1@       $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/unix/utilsunx.cpp
 
+@COND_PLATFORM_UNIX_1@basedll_wakeuppipe.o: $(srcdir)/src/unix/wakeuppipe.cpp $(BASEDLL_ODEP)
+@COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/unix/wakeuppipe.cpp
+
+@COND_PLATFORM_MACOSX_1@basedll_wakeuppipe.o: $(srcdir)/src/unix/wakeuppipe.cpp $(BASEDLL_ODEP)
+@COND_PLATFORM_MACOSX_1@       $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/unix/wakeuppipe.cpp
+
 @COND_PLATFORM_UNIX_1@basedll_fswatcher_kqueue.o: $(srcdir)/src/unix/fswatcher_kqueue.cpp $(BASEDLL_ODEP)
 @COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/unix/fswatcher_kqueue.cpp
 
@@ -29569,6 +29604,12 @@ baselib_cocoa_utils.o: $(srcdir)/src/osx/cocoa/utils.mm $(BASELIB_ODEP)
 @COND_PLATFORM_MACOSX_1@baselib_utilsunx.o: $(srcdir)/src/unix/utilsunx.cpp $(BASELIB_ODEP)
 @COND_PLATFORM_MACOSX_1@       $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/unix/utilsunx.cpp
 
+@COND_PLATFORM_UNIX_1@baselib_wakeuppipe.o: $(srcdir)/src/unix/wakeuppipe.cpp $(BASELIB_ODEP)
+@COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/unix/wakeuppipe.cpp
+
+@COND_PLATFORM_MACOSX_1@baselib_wakeuppipe.o: $(srcdir)/src/unix/wakeuppipe.cpp $(BASELIB_ODEP)
+@COND_PLATFORM_MACOSX_1@       $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/unix/wakeuppipe.cpp
+
 @COND_PLATFORM_UNIX_1@baselib_fswatcher_kqueue.o: $(srcdir)/src/unix/fswatcher_kqueue.cpp $(BASELIB_ODEP)
 @COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/unix/fswatcher_kqueue.cpp
 
index befd8fe351c8a524d791a173a82d54fb20984b68..9a12df6afd0d9047a050f75e5296325406fead68 100644 (file)
@@ -73,6 +73,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
     src/unix/timerunx.cpp
     src/unix/threadpsx.cpp
     src/unix/utilsunx.cpp
+    src/unix/wakeuppipe.cpp
     src/unix/fswatcher_kqueue.cpp
 </set>
 
index f2b0a102c88c8fe9eec8c4d1e704296433eb18a8..972b3f7838fb2807a233af21ef317f7842c4dcd9 100644 (file)
 
 class wxFDIODispatcher;
 class wxUnixEventLoopSource;
-
-namespace wxPrivate
-{
-    class PipeIOHandler;
-}
+class wxWakeUpPipe;
 
 class WXDLLIMPEXP_BASE wxConsoleEventLoop
 #ifdef __WXOSX__
@@ -56,7 +52,7 @@ protected:
 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
-    wxPrivate::PipeIOHandler *m_wakeupPipe;
+    wxWakeUpPipe *m_wakeupPipe;
 
     // either wxSelectDispatcher or wxEpollDispatcher
     wxFDIODispatcher *m_dispatcher;
diff --git a/include/wx/unix/private/wakeuppipe.h b/include/wx/unix/private/wakeuppipe.h
new file mode 100644 (file)
index 0000000..2a942d0
--- /dev/null
@@ -0,0 +1,61 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/unix/private/wakeuppipe.h
+// Purpose:     Helper class allowing to wake up the main thread.
+// Author:      Vadim Zeitlin
+// Created:     2013-06-09 (extracted from src/unix/evtloopunix.cpp)
+// RCS-ID:      $Id$
+// Copyright:   (c) 2013 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_UNIX_PRIVATE_WAKEUPPIPE_H_
+#define _WX_UNIX_PRIVATE_WAKEUPPIPE_H_
+
+#include "wx/private/fdiohandler.h"
+
+#include "wx/unix/pipe.h"
+
+// ----------------------------------------------------------------------------
+// wxWakeUpPipe: allows to wake up the event loop by writing to it
+// ----------------------------------------------------------------------------
+
+class wxWakeUpPipe : public wxFDIOHandler
+{
+public:
+    // Create and initialize the pipe.
+    //
+    // It's the callers responsibility to add the read end of this pipe,
+    // returned by GetReadFd(), to the code blocking on input.
+    wxWakeUpPipe();
+
+    // Wake up the blocking operation involving this pipe.
+    //
+    // 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();
+
+    // Return the read end of the pipe.
+    int GetReadFd() { return m_pipe[wxPipe::Read]; }
+
+
+    // implement wxFDIOHandler pure virtual methods
+    virtual void OnReadWaiting();
+    virtual void OnWriteWaiting() { }
+    virtual void OnExceptionWaiting() { }
+
+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
+    // up with reading from it.
+    bool m_pipeIsEmpty;
+};
+
+#endif // _WX_UNIX_PRIVATE_WAKEUPPIPE_H_
index a4f67ecad633248127db883e71f257f4a511ad50..b26c7a5950ff4260c529b96acc88f192c09b0c5a 100644 (file)
     #include "wx/log.h"
 #endif
 
-#include <errno.h>
 #include "wx/apptrait.h"
 #include "wx/scopedptr.h"
 #include "wx/thread.h"
 #include "wx/module.h"
-#include "wx/unix/pipe.h"
 #include "wx/unix/private/timer.h"
 #include "wx/unix/private/epolldispatcher.h"
+#include "wx/unix/private/wakeuppipe.h"
 #include "wx/private/selectdispatcher.h"
 
 #if wxUSE_EVENTLOOP_SOURCE
     #include "wx/evtloopsrc.h"
 #endif // wxUSE_EVENTLOOP_SOURCE
 
-#define TRACE_EVENTS wxT("events")
-
-// ===========================================================================
-// wxEventLoop::PipeIOHandler implementation
-// ===========================================================================
-
-namespace wxPrivate
-{
-
-// 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
-class PipeIOHandler : public wxFDIOHandler
-{
-public:
-    // default ctor does nothing, call Create() to really initialize the
-    // object
-    PipeIOHandler() : m_pipeIsEmpty(true) { }
-
-    bool Create();
-
-    // this method can be, and normally is, called from another thread
-    void WakeUp();
-
-    int GetReadFd() { return m_pipe[wxPipe::Read]; }
-
-    // implement wxFDIOHandler pure virtual methods
-    virtual void OnReadWaiting();
-    virtual void OnWriteWaiting() { }
-    virtual void OnExceptionWaiting() { }
-
-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
-    // up with reading from it.
-    bool m_pipeIsEmpty;
-};
-
-// ----------------------------------------------------------------------------
-// initialization
-// ----------------------------------------------------------------------------
-
-bool PipeIOHandler::Create()
-{
-    if ( !m_pipe.Create() )
-    {
-        wxLogError(_("Failed to create wake up pipe used by event loop."));
-        return false;
-    }
-
-
-    if ( !m_pipe.MakeNonBlocking(wxPipe::Read) )
-    {
-        wxLogSysError(_("Failed to switch wake up pipe to non-blocking mode"));
-        return false;
-    }
-
-    wxLogTrace(TRACE_EVENTS, wxT("Wake up pipe (%d, %d) created"),
-               m_pipe[wxPipe::Read], m_pipe[wxPipe::Write]);
-
-    return true;
-}
-
-// ----------------------------------------------------------------------------
-// wakeup handling
-// ----------------------------------------------------------------------------
-
-void PipeIOHandler::WakeUp()
-{
-    wxCriticalSectionLocker lock(m_pipeLock);
-
-    // No need to do anything if the pipe already contains something.
-    if ( !m_pipeIsEmpty )
-      return;
-
-    if ( write(m_pipe[wxPipe::Write], "s", 1) != 1 )
-    {
-        // don't use wxLog here, we can be in another thread and this could
-        // result in dead locks
-        perror("write(wake up pipe)");
-    }
-    else
-    {
-        // We just wrote to it, so it's not empty any more.
-        m_pipeIsEmpty = false;
-    }
-}
-
-void PipeIOHandler::OnReadWaiting()
-{
-    // got wakeup from child thread, remove the data that provoked it from the
-    // pipe
-
-    wxCriticalSectionLocker lock(m_pipeLock);
-
-    char buf[4];
-    for ( ;; )
-    {
-        const int size = read(GetReadFd(), buf, WXSIZEOF(buf));
-
-        if ( size > 0 )
-        {
-            wxASSERT_MSG( size == 1, "Too many writes to wake-up pipe?" );
-
-            break;
-        }
-
-        if ( size == 0 || (size == -1 && errno == EAGAIN) )
-        {
-            // No data available, not an error (but still surprising,
-            // spurious wakeup?)
-            break;
-        }
-
-        if ( errno == EINTR )
-        {
-            // We were interrupted, try again.
-            continue;
-        }
-
-        wxLogSysError(_("Failed to read from wake-up pipe"));
-
-        return;
-    }
-
-    // The pipe is empty now, so future calls to WakeUp() would need to write
-    // to it again.
-    m_pipeIsEmpty = true;
-
-    // writing to the wake up pipe will make wxConsoleEventLoop return from
-    // wxFDIODispatcher::Dispatch() it might be currently blocking in, nothing
-    // else needs to be done
-}
-
-} // namespace wxPrivate
-
 // ===========================================================================
 // wxEventLoop implementation
 // ===========================================================================
@@ -193,8 +51,9 @@ void PipeIOHandler::OnReadWaiting()
 
 wxConsoleEventLoop::wxConsoleEventLoop()
 {
-    m_wakeupPipe = new wxPrivate::PipeIOHandler();
-    if ( !m_wakeupPipe->Create() )
+    m_wakeupPipe = new wxWakeUpPipe;
+    const int pipeFD = m_wakeupPipe->GetReadFd();
+    if ( pipeFD == wxPipe::INVALID_FD )
     {
         wxDELETE(m_wakeupPipe);
         m_dispatcher = NULL;
@@ -205,12 +64,7 @@ wxConsoleEventLoop::wxConsoleEventLoop()
     if ( !m_dispatcher )
         return;
 
-    m_dispatcher->RegisterFD
-                  (
-                    m_wakeupPipe->GetReadFd(),
-                    m_wakeupPipe,
-                    wxFDIO_INPUT
-                  );
+    m_dispatcher->RegisterFD(pipeFD, m_wakeupPipe, wxFDIO_INPUT);
 }
 
 wxConsoleEventLoop::~wxConsoleEventLoop()
diff --git a/src/unix/wakeuppipe.cpp b/src/unix/wakeuppipe.cpp
new file mode 100644 (file)
index 0000000..b8ff1f1
--- /dev/null
@@ -0,0 +1,137 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        src/unix/wakeuppipe.cpp
+// Purpose:     Implementation of wxWakeUpPipe class.
+// Author:      Vadim Zeitlin
+// Created:     2013-06-09 (extracted from src/unix/evtloopunix.cpp)
+// RCS-ID:      $Id$
+// Copyright:   (c) 2013 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#endif // WX_PRECOMP
+
+#include "wx/unix/private/wakeuppipe.h"
+
+#include <errno.h>
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+#define TRACE_EVENTS wxT("events")
+
+// ============================================================================
+// wxWakeUpPipe implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// initialization
+// ----------------------------------------------------------------------------
+
+wxWakeUpPipe::wxWakeUpPipe()
+{
+    m_pipeIsEmpty = true;
+
+    if ( !m_pipe.Create() )
+    {
+        wxLogError(_("Failed to create wake up pipe used by event loop."));
+        return;
+    }
+
+
+    if ( !m_pipe.MakeNonBlocking(wxPipe::Read) )
+    {
+        wxLogSysError(_("Failed to switch wake up pipe to non-blocking mode"));
+        return;
+    }
+
+    wxLogTrace(TRACE_EVENTS, wxT("Wake up pipe (%d, %d) created"),
+               m_pipe[wxPipe::Read], m_pipe[wxPipe::Write]);
+}
+
+// ----------------------------------------------------------------------------
+// wakeup handling
+// ----------------------------------------------------------------------------
+
+void wxWakeUpPipe::WakeUp()
+{
+    wxCriticalSectionLocker lock(m_pipeLock);
+
+    // No need to do anything if the pipe already contains something.
+    if ( !m_pipeIsEmpty )
+      return;
+
+    if ( write(m_pipe[wxPipe::Write], "s", 1) != 1 )
+    {
+        // don't use wxLog here, we can be in another thread and this could
+        // result in dead locks
+        perror("write(wake up pipe)");
+    }
+    else
+    {
+        // We just wrote to it, so it's not empty any more.
+        m_pipeIsEmpty = false;
+    }
+}
+
+void wxWakeUpPipe::OnReadWaiting()
+{
+    // got wakeup from child thread, remove the data that provoked it from the
+    // pipe
+
+    wxCriticalSectionLocker lock(m_pipeLock);
+
+    char buf[4];
+    for ( ;; )
+    {
+        const int size = read(GetReadFd(), buf, WXSIZEOF(buf));
+
+        if ( size > 0 )
+        {
+            wxASSERT_MSG( size == 1, "Too many writes to wake-up pipe?" );
+
+            break;
+        }
+
+        if ( size == 0 || (size == -1 && errno == EAGAIN) )
+        {
+            // No data available, not an error (but still surprising,
+            // spurious wakeup?)
+            break;
+        }
+
+        if ( errno == EINTR )
+        {
+            // We were interrupted, try again.
+            continue;
+        }
+
+        wxLogSysError(_("Failed to read from wake-up pipe"));
+
+        return;
+    }
+
+    // The pipe is empty now, so future calls to WakeUp() would need to write
+    // to it again.
+    m_pipeIsEmpty = true;
+
+    // writing to the wake up pipe will make wxConsoleEventLoop return from
+    // wxFDIODispatcher::Dispatch() it might be currently blocking in, nothing
+    // else needs to be done
+}