1 | // Copyright (C) 2024 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qautoresetevent_pipe_p.h" |
5 | |
6 | #include <QtCore/private/qcore_unix_p.h> |
7 | #include <QtCore/qdebug.h> |
8 | |
9 | #include <unistd.h> |
10 | #include <cstdint> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | namespace QtPrivate { |
15 | |
16 | QAutoResetEventPipe::QAutoResetEventPipe(QObject *parent) |
17 | : QObject{ |
18 | parent, |
19 | }, |
20 | m_notifier{ |
21 | QSocketNotifier::Type::Read, |
22 | } |
23 | { |
24 | int pipedes[2]; |
25 | int status = pipe(pipedes: pipedes); |
26 | if (status == -1) { |
27 | qCritical() << "pipe failed:" << qt_error_string(errno); |
28 | return; |
29 | } |
30 | |
31 | m_fdConsumer = pipedes[0]; |
32 | m_fdProducer = pipedes[1]; |
33 | |
34 | connect(sender: &m_notifier, signal: &QSocketNotifier::activated, context: this, slot: [this] { |
35 | QT_WARNING_PUSH |
36 | QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized" ) |
37 | std::array<char, 1024> buffer; |
38 | |
39 | qint64 bytesRead = qt_safe_read(fd: m_fdConsumer, data: buffer.data(), maxlen: buffer.size()); |
40 | Q_ASSERT(bytesRead > 0); |
41 | |
42 | m_consumePending.clear(); |
43 | emit activated(); |
44 | QT_WARNING_POP |
45 | }); |
46 | m_notifier.setSocket(m_fdConsumer); |
47 | m_notifier.setEnabled(true); |
48 | } |
49 | |
50 | QAutoResetEventPipe::~QAutoResetEventPipe() |
51 | { |
52 | if (m_fdConsumer != -1) { |
53 | qt_safe_close(fd: m_fdConsumer); |
54 | qt_safe_close(fd: m_fdProducer); |
55 | } |
56 | } |
57 | |
58 | void QAutoResetEventPipe::set() |
59 | { |
60 | Q_ASSERT(isValid()); |
61 | |
62 | bool consumePending = m_consumePending.test_and_set(); |
63 | if (consumePending) |
64 | return; |
65 | |
66 | constexpr uint8_t dummy{ 1 }; |
67 | |
68 | qint64 bytesWritten = qt_safe_write(fd: m_fdProducer, data: &dummy, len: sizeof(dummy)); |
69 | if (bytesWritten == -1) |
70 | qCritical(msg: "QAutoResetEvent::set failed" ); |
71 | } |
72 | |
73 | } // namespace QtPrivate |
74 | |
75 | QT_END_NAMESPACE |
76 | |
77 | #include "moc_qautoresetevent_pipe_p.cpp" |
78 | |