Coverage Report

Created: 2024-03-18 06:28

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