]> git.saurik.com Git - wxWidgets.git/blob - src/unix/wakeuppipe.cpp
Extract PipeIOHandler class into a header and rename to wxWakeUpPipe.
[wxWidgets.git] / src / unix / wakeuppipe.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/wakeuppipe.cpp
3 // Purpose: Implementation of wxWakeUpPipe class.
4 // Author: Vadim Zeitlin
5 // Created: 2013-06-09 (extracted from src/unix/evtloopunix.cpp)
6 // RCS-ID: $Id$
7 // Copyright: (c) 2013 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #endif // WX_PRECOMP
28
29 #include "wx/unix/private/wakeuppipe.h"
30
31 #include <errno.h>
32
33 // ----------------------------------------------------------------------------
34 // constants
35 // ----------------------------------------------------------------------------
36
37 #define TRACE_EVENTS wxT("events")
38
39 // ============================================================================
40 // wxWakeUpPipe implementation
41 // ============================================================================
42
43 // ----------------------------------------------------------------------------
44 // initialization
45 // ----------------------------------------------------------------------------
46
47 wxWakeUpPipe::wxWakeUpPipe()
48 {
49 m_pipeIsEmpty = true;
50
51 if ( !m_pipe.Create() )
52 {
53 wxLogError(_("Failed to create wake up pipe used by event loop."));
54 return;
55 }
56
57
58 if ( !m_pipe.MakeNonBlocking(wxPipe::Read) )
59 {
60 wxLogSysError(_("Failed to switch wake up pipe to non-blocking mode"));
61 return;
62 }
63
64 wxLogTrace(TRACE_EVENTS, wxT("Wake up pipe (%d, %d) created"),
65 m_pipe[wxPipe::Read], m_pipe[wxPipe::Write]);
66 }
67
68 // ----------------------------------------------------------------------------
69 // wakeup handling
70 // ----------------------------------------------------------------------------
71
72 void wxWakeUpPipe::WakeUp()
73 {
74 wxCriticalSectionLocker lock(m_pipeLock);
75
76 // No need to do anything if the pipe already contains something.
77 if ( !m_pipeIsEmpty )
78 return;
79
80 if ( write(m_pipe[wxPipe::Write], "s", 1) != 1 )
81 {
82 // don't use wxLog here, we can be in another thread and this could
83 // result in dead locks
84 perror("write(wake up pipe)");
85 }
86 else
87 {
88 // We just wrote to it, so it's not empty any more.
89 m_pipeIsEmpty = false;
90 }
91 }
92
93 void wxWakeUpPipe::OnReadWaiting()
94 {
95 // got wakeup from child thread, remove the data that provoked it from the
96 // pipe
97
98 wxCriticalSectionLocker lock(m_pipeLock);
99
100 char buf[4];
101 for ( ;; )
102 {
103 const int size = read(GetReadFd(), buf, WXSIZEOF(buf));
104
105 if ( size > 0 )
106 {
107 wxASSERT_MSG( size == 1, "Too many writes to wake-up pipe?" );
108
109 break;
110 }
111
112 if ( size == 0 || (size == -1 && errno == EAGAIN) )
113 {
114 // No data available, not an error (but still surprising,
115 // spurious wakeup?)
116 break;
117 }
118
119 if ( errno == EINTR )
120 {
121 // We were interrupted, try again.
122 continue;
123 }
124
125 wxLogSysError(_("Failed to read from wake-up pipe"));
126
127 return;
128 }
129
130 // The pipe is empty now, so future calls to WakeUp() would need to write
131 // to it again.
132 m_pipeIsEmpty = true;
133
134 // writing to the wake up pipe will make wxConsoleEventLoop return from
135 // wxFDIODispatcher::Dispatch() it might be currently blocking in, nothing
136 // else needs to be done
137 }