]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/unix/wakeuppipe.cpp
Move wx/msw/gccpriv.h inclusion back to wx/platform.h from wx/compiler.h.
[wxWidgets.git] / src / unix / wakeuppipe.cpp
... / ...
CommitLineData
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
47wxWakeUpPipe::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
72void wxWakeUpPipe::WakeUpNoLock()
73{
74 // No need to do anything if the pipe already contains something.
75 if ( !m_pipeIsEmpty )
76 return;
77
78 if ( write(m_pipe[wxPipe::Write], "s", 1) != 1 )
79 {
80 // don't use wxLog here, we can be in another thread and this could
81 // result in dead locks
82 perror("write(wake up pipe)");
83 }
84 else
85 {
86 // We just wrote to it, so it's not empty any more.
87 m_pipeIsEmpty = false;
88 }
89}
90
91void wxWakeUpPipe::OnReadWaiting()
92{
93 // got wakeup from child thread, remove the data that provoked it from the
94 // pipe
95
96 char buf[4];
97 for ( ;; )
98 {
99 const int size = read(GetReadFd(), buf, WXSIZEOF(buf));
100
101 if ( size > 0 )
102 {
103 wxASSERT_MSG( size == 1, "Too many writes to wake-up pipe?" );
104
105 break;
106 }
107
108 if ( size == 0 || (size == -1 && errno == EAGAIN) )
109 {
110 // No data available, not an error (but still surprising,
111 // spurious wakeup?)
112 break;
113 }
114
115 if ( errno == EINTR )
116 {
117 // We were interrupted, try again.
118 continue;
119 }
120
121 wxLogSysError(_("Failed to read from wake-up pipe"));
122
123 return;
124 }
125
126 // The pipe is empty now, so future calls to WakeUp() would need to write
127 // to it again.
128 m_pipeIsEmpty = true;
129}