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