Coverage Report

Created: 2026-04-09 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/connectedhomeip/src/system/WakeEvent.cpp
Line
Count
Source
1
/*
2
 *
3
 *    Copyright (c) 2020-2021 Project CHIP Authors
4
 *
5
 *    Licensed under the Apache License, Version 2.0 (the "License");
6
 *    you may not use this file except in compliance with the License.
7
 *    You may obtain a copy of the License at
8
 *
9
 *        http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 *    Unless required by applicable law or agreed to in writing, software
12
 *    distributed under the License is distributed on an "AS IS" BASIS,
13
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 *    See the License for the specific language governing permissions and
15
 *    limitations under the License.
16
 */
17
18
/**
19
 *    @file
20
 *      This file declares the abstraction of one-directional, anonymous
21
 *      data stream built on top of two file descriptors.
22
 */
23
24
#include <system/SystemConfig.h>
25
26
#if !CHIP_SYSTEM_CONFIG_USE_LIBEV
27
28
#include <system/WakeEvent.h>
29
30
// Include additional CHIP headers
31
#include <lib/support/CodeUtils.h>
32
#include <system/SystemError.h>
33
#include <system/SystemLayer.h>
34
35
// Include system and language headers
36
#include <errno.h>
37
#include <fcntl.h>
38
#include <unistd.h>
39
40
#if !CHIP_SYSTEM_CONFIG_USE_POSIX_PIPE
41
#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_EVENTFD
42
#include <zephyr/posix/sys/eventfd.h>
43
#else
44
#include <sys/eventfd.h>
45
#endif
46
#endif // !CHIP_SYSTEM_CONFIG_USE_POSIX_PIPE
47
48
namespace chip {
49
namespace System {
50
51
#if CHIP_SYSTEM_CONFIG_USE_POSIX_PIPE
52
53
namespace {
54
inline int SetNonBlockingMode(int fd)
55
0
{
56
0
    int flags = ::fcntl(fd, F_GETFL, 0);
57
0
    return ::fcntl(fd, F_SETFL, flags | O_NONBLOCK);
58
0
}
59
} // anonymous namespace
60
61
CHIP_ERROR WakeEvent::Open()
62
0
{
63
0
    enum
64
0
    {
65
0
        FD_READ  = 0,
66
0
        FD_WRITE = 1
67
0
    };
68
0
    int fds[2];
69
70
0
    if (::pipe(fds) < 0)
71
0
        return CHIP_ERROR_POSIX(errno);
72
73
0
    if (SetNonBlockingMode(fds[FD_READ]) < 0)
74
0
        return CHIP_ERROR_POSIX(errno);
75
76
0
    if (SetNonBlockingMode(fds[FD_WRITE]) < 0)
77
0
        return CHIP_ERROR_POSIX(errno);
78
79
0
    mReadFD  = fds[FD_READ];
80
0
    mWriteFD = fds[FD_WRITE];
81
82
0
    return CHIP_NO_ERROR;
83
0
}
84
85
void WakeEvent::Close()
86
0
{
87
0
    VerifyOrDie(::close(mReadFD) == 0);
88
0
    VerifyOrDie(::close(mWriteFD) == 0);
89
0
    mReadFD  = -1;
90
0
    mWriteFD = -1;
91
0
}
92
93
void WakeEvent::Confirm() const
94
0
{
95
0
    uint8_t buffer[128];
96
0
    ssize_t res;
97
98
0
    do
99
0
    {
100
0
        res = ::read(mReadFD, buffer, sizeof(buffer));
101
0
        if (res < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
102
0
        {
103
0
            ChipLogError(chipSystemLayer, "System wake event confirm failed: %" CHIP_ERROR_FORMAT,
104
0
                         CHIP_ERROR_POSIX(errno).Format());
105
0
            return;
106
0
        }
107
0
    } while (res == sizeof(buffer));
108
0
}
109
110
CHIP_ERROR WakeEvent::Notify() const
111
0
{
112
0
    char byte = 1;
113
114
0
    if (::write(mWriteFD, &byte, 1) < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
115
0
    {
116
0
        return CHIP_ERROR_POSIX(errno);
117
0
    }
118
119
0
    return CHIP_NO_ERROR;
120
0
}
121
122
#else // CHIP_SYSTEM_CONFIG_USE_POSIX_PIPE
123
124
namespace {
125
126
#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_EVENTFD
127
128
int ReadEvent(int eventFd)
129
{
130
    eventfd_t value;
131
132
    return eventfd_read(eventFd, &value);
133
}
134
135
int WriteEvent(int eventFd)
136
{
137
    return eventfd_write(eventFd, 1);
138
}
139
140
#else
141
142
ssize_t ReadEvent(int eventFd)
143
{
144
    uint64_t value;
145
146
    return ::read(eventFd, &value, sizeof(value));
147
}
148
149
ssize_t WriteEvent(int eventFd)
150
{
151
    uint64_t value = 1;
152
153
    return ::write(eventFd, &value, sizeof(value));
154
}
155
156
#endif
157
158
} // namespace
159
160
CHIP_ERROR WakeEvent::Open()
161
{
162
    mReadFD = ::eventfd(0, 0);
163
    if (mReadFD == -1)
164
    {
165
        return CHIP_ERROR_POSIX(errno);
166
    }
167
168
    return CHIP_NO_ERROR;
169
}
170
171
void WakeEvent::Close()
172
{
173
    VerifyOrDie(::close(mReadFD) == 0);
174
    mReadFD = -1;
175
}
176
177
void WakeEvent::Confirm() const
178
{
179
    if (ReadEvent(mReadFD) < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
180
    {
181
        ChipLogError(chipSystemLayer, "System wake event confirm failed: %" CHIP_ERROR_FORMAT, CHIP_ERROR_POSIX(errno).Format());
182
    }
183
}
184
185
CHIP_ERROR WakeEvent::Notify() const
186
{
187
    if (WriteEvent(mReadFD) < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
188
    {
189
        return CHIP_ERROR_POSIX(errno);
190
    }
191
192
    return CHIP_NO_ERROR;
193
}
194
195
#endif // CHIP_SYSTEM_CONFIG_USE_POSIX_PIPE
196
197
} // namespace System
198
} // namespace chip
199
200
#endif // !CHIP_SYSTEM_CONFIG_USE_LIBEV