Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qpoll.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 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
// Qt-Security score:significant reason:default
4
5
#
include
"qcore_unix_p.h"
6
7
#
ifdef
Q_OS_RTEMS
8
#
include
<
rtems
/
rtems_bsdnet_internal
.
h
>
9
#
endif
10
11
QT_BEGIN_NAMESPACE
12
13
#
define
QT_POLL_READ_MASK
(
POLLIN
|
POLLRDNORM
)
14
#
define
QT_POLL_WRITE_MASK
(
POLLOUT
|
POLLWRNORM
|
POLLWRBAND
)
15
#
define
QT_POLL_EXCEPT_MASK
(
POLLPRI
|
POLLRDBAND
)
16
#
define
QT_POLL_ERROR_MASK
(
POLLERR
|
POLLNVAL
)
17
#
define
QT_POLL_EVENTS_MASK
(
QT_POLL_READ_MASK
|
QT_POLL_WRITE_MASK
|
QT_POLL_EXCEPT_MASK
)
18
19
static
inline
int
qt_poll_prepare
(
struct
pollfd *fds, nfds_t nfds,
20
fd_set *read_fds, fd_set *write_fds, fd_set *except_fds)
21
{
22
int
max_fd = -1;
23
24
FD_ZERO(read_fds);
25
FD_ZERO(write_fds);
26
FD_ZERO(except_fds);
27
28
for
(nfds_t i = 0; i < nfds; i++) {
29
if
(fds[i].fd >= FD_SETSIZE) {
30
errno = EINVAL;
31
return
-1;
32
}
33
34
if
((fds[i].fd < 0) || (fds[i].revents &
QT_POLL_ERROR_MASK
))
35
continue
;
36
37
if
(fds[i].events &
QT_POLL_READ_MASK
)
38
FD_SET(fds[i].fd, read_fds);
39
40
if
(fds[i].events &
QT_POLL_WRITE_MASK
)
41
FD_SET(fds[i].fd, write_fds);
42
43
if
(fds[i].events &
QT_POLL_EXCEPT_MASK
)
44
FD_SET(fds[i].fd, except_fds);
45
46
if
(fds[i].events &
QT_POLL_EVENTS_MASK
)
47
max_fd = qMax(max_fd, fds[i].fd);
48
}
49
50
return
max_fd + 1;
51
}
52
53
static
inline
void
qt_poll_examine_ready_read
(
struct
pollfd &pfd)
54
{
55
int
res;
56
char
data;
57
58
QT_EINTR_LOOP
(res, ::recv(pfd.fd, &data,
sizeof
(data), MSG_PEEK));
59
const
int
error = (res < 0) ? errno : 0;
60
61
if
(res == 0) {
62
pfd.revents |= POLLHUP;
63
}
else
if
(res > 0 || error == ENOTSOCK || error == ENOTCONN) {
64
pfd.revents |=
QT_POLL_READ_MASK
& pfd.events;
65
}
else
{
66
switch
(error) {
67
case
ESHUTDOWN:
68
case
ECONNRESET:
69
case
ECONNABORTED:
70
case
ENETRESET:
71
pfd.revents |= POLLHUP;
72
break
;
73
default
:
74
pfd.revents |= POLLERR;
75
break
;
76
}
77
}
78
}
79
80
static
inline
int
qt_poll_sweep
(
struct
pollfd *fds, nfds_t nfds,
81
fd_set *read_fds, fd_set *write_fds, fd_set *except_fds)
82
{
83
int
result = 0;
84
85
for
(nfds_t i = 0; i < nfds; i++) {
86
if
(fds[i].fd < 0)
87
continue
;
88
89
if
(FD_ISSET(fds[i].fd, read_fds))
90
qt_poll_examine_ready_read
(
fds[i]
)
;
91
92
if
(FD_ISSET(fds[i].fd, write_fds))
93
fds[i].revents |=
QT_POLL_WRITE_MASK
& fds[i].events;
94
95
if
(FD_ISSET(fds[i].fd, except_fds))
96
fds[i].revents |=
QT_POLL_EXCEPT_MASK
& fds[i].events;
97
98
if
(fds[i].revents != 0)
99
result++;
100
}
101
102
return
result;
103
}
104
105
static
inline
bool
qt_poll_is_bad_fd
(
int
fd)
106
{
107
#
ifdef
Q_OS_RTEMS
108
if
(!rtems_bsdnet_fdToSocket(fd))
109
return
true
;
110
#
endif
111
112
int
ret;
113
QT_EINTR_LOOP
(ret, fcntl(fd, F_GETFD));
114
return
(ret == -1 && errno == EBADF);
115
}
116
117
static
inline
int
qt_poll_mark_bad_fds
(
struct
pollfd *fds,
const
nfds_t nfds)
118
{
119
int
n_marked = 0;
120
121
for
(nfds_t i = 0; i < nfds; i++) {
122
if
(fds[i].fd < 0)
123
continue
;
124
125
if
(fds[i].revents &
QT_POLL_ERROR_MASK
)
126
continue
;
127
128
if
(
qt_poll_is_bad_fd
(
fds[i].fd
)
) {
129
fds[i].revents |= POLLNVAL;
130
n_marked++;
131
}
132
}
133
134
return
n_marked;
135
}
136
137
int
qt_poll
(
struct
pollfd *fds, nfds_t nfds,
const
struct
timespec *timeout_ts)
138
{
139
if
(!fds && nfds) {
140
errno = EFAULT;
141
return
-1;
142
}
143
144
fd_set read_fds, write_fds, except_fds;
145
struct
timeval tv, *ptv =
nullptr
;
146
147
if
(timeout_ts) {
148
tv =
timespecToTimeval
(
*timeout_ts
)
;
149
ptv = &tv;
150
}
151
152
int
n_bad_fds = 0;
153
154
for
(nfds_t i = 0; i < nfds; i++) {
155
fds[i].revents = 0;
156
157
if
(fds[i].fd < 0)
158
continue
;
159
160
if
(fds[i].fd > FD_SETSIZE) {
161
errno = EINVAL;
162
return
-1;
163
}
164
165
if
(fds[i].events &
QT_POLL_EVENTS_MASK
)
166
continue
;
167
168
if
(
qt_poll_is_bad_fd
(
fds[i].fd
)
) {
169
// Mark bad file descriptors that have no event flags set
170
// here, as we won't be passing them to select below and therefore
171
// need to do the check ourselves
172
fds[i].revents = POLLNVAL;
173
n_bad_fds++;
174
}
175
}
176
177
forever {
178
const
int
max_fd = qt_poll_prepare(fds, nfds, &read_fds, &write_fds, &except_fds);
179
180
if
(max_fd < 0)
181
return
max_fd;
182
183
if
(n_bad_fds > 0) {
184
tv.tv_sec = 0;
185
tv.tv_usec = 0;
186
ptv = &tv;
187
}
188
189
const
int
ret = ::select(max_fd, &read_fds, &write_fds, &except_fds, ptv);
190
191
if
(ret == 0)
192
return
n_bad_fds;
193
194
if
(ret > 0)
195
return
qt_poll_sweep(fds, nfds, &read_fds, &write_fds, &except_fds);
196
197
if
(errno != EBADF)
198
return
-1;
199
200
// We have at least one bad file descriptor that we waited on, find out which and try again
201
n_bad_fds += qt_poll_mark_bad_fds(fds, nfds);
202
}
203
}
204
205
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qt_poll
int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts)
Definition
qpoll.cpp:137
QT_EINTR_LOOP
#define QT_EINTR_LOOP(var, cmd)
Definition
qcore_unix_p.h:60
timespecToTimeval
timeval timespecToTimeval(timespec ts)
Definition
qcore_unix_p.h:143
qt_poll_prepare
static int qt_poll_prepare(struct pollfd *fds, nfds_t nfds, fd_set *read_fds, fd_set *write_fds, fd_set *except_fds)
Definition
qpoll.cpp:19
qt_poll_examine_ready_read
static void qt_poll_examine_ready_read(struct pollfd &pfd)
Definition
qpoll.cpp:53
QT_POLL_READ_MASK
#define QT_POLL_READ_MASK
Definition
qpoll.cpp:13
QT_POLL_ERROR_MASK
#define QT_POLL_ERROR_MASK
Definition
qpoll.cpp:16
QT_POLL_EVENTS_MASK
#define QT_POLL_EVENTS_MASK
Definition
qpoll.cpp:17
QT_POLL_EXCEPT_MASK
#define QT_POLL_EXCEPT_MASK
Definition
qpoll.cpp:15
qt_poll_mark_bad_fds
static int qt_poll_mark_bad_fds(struct pollfd *fds, const nfds_t nfds)
Definition
qpoll.cpp:117
qt_poll_sweep
static int qt_poll_sweep(struct pollfd *fds, nfds_t nfds, fd_set *read_fds, fd_set *write_fds, fd_set *except_fds)
Definition
qpoll.cpp:80
qt_poll_is_bad_fd
static bool qt_poll_is_bad_fd(int fd)
Definition
qpoll.cpp:105
QT_POLL_WRITE_MASK
#define QT_POLL_WRITE_MASK
Definition
qpoll.cpp:14
qtbase
src
corelib
kernel
qpoll.cpp
Generated on
for Qt by
1.18.0