qeventdispatcher_unix.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Copyright (C) 2016 Intel Corporation.-
5** Contact: https://www.qt.io/licensing/-
6**-
7** This file is part of the QtCore module of the Qt Toolkit.-
8**-
9** $QT_BEGIN_LICENSE:LGPL$-
10** Commercial License Usage-
11** Licensees holding valid commercial Qt licenses may use this file in-
12** accordance with the commercial license agreement provided with the-
13** Software or, alternatively, in accordance with the terms contained in-
14** a written agreement between you and The Qt Company. For licensing terms-
15** and conditions see https://www.qt.io/terms-conditions. For further-
16** information use the contact form at https://www.qt.io/contact-us.-
17**-
18** GNU Lesser General Public License Usage-
19** Alternatively, this file may be used under the terms of the GNU Lesser-
20** General Public License version 3 as published by the Free Software-
21** Foundation and appearing in the file LICENSE.LGPL3 included in the-
22** packaging of this file. Please review the following information to-
23** ensure the GNU Lesser General Public License version 3 requirements-
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
25**-
26** GNU General Public License Usage-
27** Alternatively, this file may be used under the terms of the GNU-
28** General Public License version 2.0 or (at your option) the GNU General-
29** Public license version 3 or any later version approved by the KDE Free-
30** Qt Foundation. The licenses are as published by the Free Software-
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
32** included in the packaging of this file. Please review the following-
33** information to ensure the GNU General Public License requirements will-
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
35** https://www.gnu.org/licenses/gpl-3.0.html.-
36**-
37** $QT_END_LICENSE$-
38**-
39****************************************************************************/-
40-
41#include "qplatformdefs.h"-
42-
43#include "qcoreapplication.h"-
44#include "qpair.h"-
45#include "qsocketnotifier.h"-
46#include "qthread.h"-
47#include "qelapsedtimer.h"-
48-
49#include "qeventdispatcher_unix_p.h"-
50#include <private/qthread_p.h>-
51#include <private/qcoreapplication_p.h>-
52#include <private/qcore_unix_p.h>-
53-
54#include <errno.h>-
55#include <stdio.h>-
56#include <stdlib.h>-
57-
58#ifndef QT_NO_EVENTFD-
59# include <sys/eventfd.h>-
60#endif-
61-
62// VxWorks doesn't correctly set the _POSIX_... options-
63#if defined(Q_OS_VXWORKS)-
64# if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK <= 0)-
65# undef _POSIX_MONOTONIC_CLOCK-
66# define _POSIX_MONOTONIC_CLOCK 1-
67# endif-
68# include <pipeDrv.h>-
69# include <selectLibsys/time.h>-
70#endif-
71-
72#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)-
73# include <sys/times.h>-
74#endif-
75-
76QT_BEGIN_NAMESPACE-
77-
78static const char *socketType(QSocketNotifier::Type type)-
79{-
80 switch (type) {-
81 case QSocketNotifier::Read:
never executed: case QSocketNotifier::Read:
0
82 return "Read";
never executed: return "Read";
0
83 case QSocketNotifier::Write:
never executed: case QSocketNotifier::Write:
0
84 return "Write";
never executed: return "Write";
0
85 case QSocketNotifier::Exception:
never executed: case QSocketNotifier::Exception:
0
86 return "Exception";
never executed: return "Exception";
0
87 }-
88-
89 Q_UNREACHABLE();-
90}
never executed: end of block
0
91-
92QThreadPipe::QThreadPipe()-
93{-
94 fds[0] = -1;-
95 fds[1] = -1;-
96#if defined(Q_OS_INTEGRITYQ_OS_VXWORKS)-
97 ||name[0] = '\0';-
98#endif-
99}
never executed: end of block
0
100-
101QThreadPipe::~QThreadPipe()-
102{-
103 if (fds[0] >= 0)
fds[0] >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
104 close(fds[0]);
never executed: close(fds[0]);
0
105-
106 if (fds[1] >= 0)
fds[1] >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
107 close(fds[1]);
never executed: close(fds[1]);
0
108-
109#if defined(Q_OS_VXWORKS)-
110 pipeDevDelete(name, true);-
111#endif-
112}
never executed: end of block
0
113-
114#if defined(Q_OS_VXWORKS)-
115static void initThreadPipeFD(int fd)-
116{-
117 int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);-
118 if (ret == -1)-
119 perror("QEventDispatcherUNIXPrivate: Unable to init thread pipe");-
120-
121 int flags = fcntl(fd, F_GETFL);-
122 if (flags == -1)-
123 perror("QEventDispatcherUNIXPrivate: Unable to get flags on thread pipe");-
124-
125 ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);-
126 if (ret == -1)-
127 perror("QEventDispatcherUNIXPrivate: Unable to set flags on thread pipe");-
128}-
129#endif-
130-
QEventDispatcherUNIXPrivatebool QThreadPipe::QEventDispatcherUNIXPrivateinit()
132{-
extern Qt::HANDLE qt_application_thread_id;
mainThread = (QThread::currentThreadId() == qt_application_thread_id);
bool pipefail = false;
#if defined(Q_OS_NACL) || defined (Q_OS_BLACKBERRY)
134 // do nothing.-
#elif defined(Q_OS_INTEGRITY)
if (socketpair(AF_INET, SOCK_STREAM, 0, thread_pipe) == -1) {
perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair");
pipefail = true;
} else {
initThreadPipeFD(thread_pipe[0]);
initThreadPipeFD(thread_pipe[1]);
}#elif defined(Q_OS_VXWORKS)
136 char name[20];qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdSelf()));-
137-
138 // make sure there is no pipe with this name-
139 pipeDevDelete(name, true);-
140-
141 // create the pipe-
142 if (pipeDevCreate(name, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {-
143 perror("QEventDispatcherUNIXPrivate():"QThreadPipe: Unable to create thread pipe device"device %s", name);-
144 pipefail = truereturn false;-
145 }-
146-
147 else {if ((thread_pipefds[0] = open(name, O_RDWR, 0)) < 0) {-
148 perror("QEventDispatcherUNIXPrivate():"QThreadPipe: Unable to createopen threadpipe pipe"device %s", name);-
149 pipefail = truereturn false;-
150 }-
151-
152 else {initThreadPipeFD(thread_pipefds[0]);-
153 thread_pipefds[1] = thread_pipefds[0];-
}
}#else
155# ifndef QT_NO_EVENTFD-
156 thread_pipeif ((fds[0] = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
(fds[0] = even...CLOEXEC)) >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
if (thread_pipe[
(fds[0] = even...CLOEXEC)) >= 0Description
TRUEnever evaluated
FALSEnever evaluated
)) >= 0] != -1)
(fds[0] = even...CLOEXEC)) >= 0Description
TRUEnever evaluated
FALSEnever evaluated
157 thread_pipe[1] = -1return true;
never executed: return true;
0
else # endif
159 if (qt_safe_pipe(thread_pipefds, O_NONBLOCK) == -1) {
qt_safe_pipe(fds, 04000) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
160 perror("QEventDispatcherUNIXPrivate():"QThreadPipe: Unable to create thread pipe");-
161 pipefail = truereturn false;
never executed: return false;
0
162 }-
163#endif-
164-
165 if (pipefail)
never executed: return true;
0
qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
never executed: return true;
sn_highest = -1
never executed: return true;
return true;
never executed: return true;
166}-
167-
QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivatepollfd QThreadPipe::prepare() const
169{-
170 #if defined(Q_OS_NACL) || defined (Q_OS_BLACKBERRY)
never executed: return qt_make_pollfd(fds[0], 0x001);
0
#elif defined(Q_OS_VXWORKS)
never executed: return qt_make_pollfd(fds[0], 0x001);
close(thread_pipe[0]);
never executed: return qt_make_pollfd(fds[0], 0x001);
char name[20];
never executed: return qt_make_pollfd(fds[0], 0x001);
qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdSelf()));
never executed: return qt_make_pollfd(fds[0], 0x001);
pipeDevDelete(name, true);
never executed: return qt_make_pollfd(fds[0], 0x001);
#else
never executed: return qt_make_pollfd(fds[0], 0x001);
close
never executed: return qt_make_pollfd(fds[0], 0x001);
return qt_make_pollfd(thread_pipefds[0]);
never executed: return qt_make_pollfd(fds[0], 0x001);
if (thread_pipe[1] != -1)
never executed: return qt_make_pollfd(fds[0], 0x001);
close(thread_pipe[1]);
never executed: return qt_make_pollfd(fds[0], 0x001);
#endif
never executed: return qt_make_pollfd(fds[0], 0x001);
qDeleteAll(timerList
never executed: return qt_make_pollfd(fds[0], 0x001);
], POLLIN);
never executed: return qt_make_pollfd(fds[0], 0x001);
171}-
172-
int QEventDispatcherUNIXPrivate::doSelect(QEventLoopvoid QThreadPipe::ProcessEventsFlags flags, timespec *timeout)
{
Q_Q(QEventDispatcherUNIX);
timerList.updateCurrentTime();
int nsel;
dowakeUp()
174{-
175 int highest = 0;if (!(flags & QEventLoop::ExcludeSocketNotifiers) &&wakeUps.testAndSetAcquire(sn_highest >= 0)) {
wakeUps.testAn...tAcquire(0, 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
sn_vec[0].select_fds = sn_vec[
wakeUps.testAn...tAcquire(0, 1)Description
TRUEnever evaluated
FALSEnever evaluated
0].enabled_fds;
wakeUps.testAn...tAcquire(0, 1)Description
TRUEnever evaluated
FALSEnever evaluated
sn_vec[1].select_fds = sn_vec[
wakeUps.testAn...tAcquire(0, 1)Description
TRUEnever evaluated
FALSEnever evaluated
, 1].enabled_fds;
wakeUps.testAn...tAcquire(0, 1)Description
TRUEnever evaluated
FALSEnever evaluated
sn_vec[2].select_fds = sn_vec[2].enabled_fds;
wakeUps.testAn...tAcquire(0, 1)Description
TRUEnever evaluated
FALSEnever evaluated
highest = sn_highest;
wakeUps.testAn...tAcquire(0, 1)Description
TRUEnever evaluated
FALSEnever evaluated
} else
wakeUps.testAn...tAcquire(0, 1)Description
TRUEnever evaluated
FALSEnever evaluated
)) {
wakeUps.testAn...tAcquire(0, 1)Description
TRUEnever evaluated
FALSEnever evaluated
FD_ZERO(&sn_vec[0].select_fds);
FD_ZERO(&sn_vec[1].select_fds);
FD_ZERO(&sn_vec[2].select_fds);
}
int wakeUpFd = initThreadWakeUp();
highest = qMax(highest, wakeUpFd);
nsel = q->select#ifndef QT_NO_EVENTFD
177 if
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
(highest + 1,
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
&sn_vec[0].select_fds,
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
&sn_vec[1].select_fds,
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
&sn_vec
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
fds[2].select_fds,
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
timeout);
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
} while (nsel == -
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
1&& (errno == EINTR || errno == EAGAIN));
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
if (nsel
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
] == -1) {
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
if (errno == EBADF) {
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
fd_set fdset;
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
timeval tm;
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
tm.tv_sec = tm.tv_usec = 0l;
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
for (int type = 0; type < 3; ++type
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
) {
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
178 QSockNotType::List &list = sn_vec[type].list;-
if (list.size() == 0)
continue;
for (int i// eventfd
179 eventfd_t value = 01;-
180 i < list.size(); ++i) {-
QSockNot *sn = list[i];
FD_ZERO(&fdset);
FD_SET(sn->fd, &fdset);int ret= -1;
181 do {
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
switch
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
EINTR_LOOP(type) {
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
case 0:
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
ret= select(sn->fd + 1, &fdset, 0, 0, &tm);
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
break;
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
case 1: ret = select
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
eventfd_write(sn->fd + 1, 0, &fdset,fds[0, &tm);
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
break
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
], value));
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
182 return
never executed: return;
;
never executed: return;
0
183 case 2: ret}-
184#endif-
185 char c = select(sn->fd + 1, 0,0, &fdset, &tm);-
break;
186 }-
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
ifqt_safe_write(ret == -fds[1&& errno == EBADF) {
static const char *t[] = { "Read", "Write", "Exception" };
qWarning("QSocketNotifier: Invalid socket %d and type '%s', disabling...",
sn->fd], &c, t[type]);
sn->obj->setEnabled(false);
}
}
}
} else {
perror("select"1);
187 }
never executed: end of block
0
188}
never executed: end of block
0
189-
int nevents = processThreadWakeUp(nsel);
if (! (flags & QEventLoop::ExcludeSocketNotifiers) && nsel > 0 && sn_highest >= 0) {
for (int i=0; i<3; i++) {
QSockNotTypeQThreadPipe::List &list = sn_vec[i].list;
forcheck(int j = 0; j < list.size(); ++jconst pollfd &pfd)
191{-
192 QSockNot *sn = list[j];-
if (FD_ISSETQ_ASSERT(sn->pfd.fd , &sn_vec[i].select_fds))
q->setSocketNotifierPending(sn->obj);
}
}
}
return (nevents + q->activateSocketNotifiers());
}
int QEventDispatcherUNIXPrivate::initThreadWakeUp()
{
FD_SET(thread_pipe[0], &sn_vec== fds[0].select_fds);
return thread_pipe]);
193-
194 char c[016];-
195 }-
int QEventDispatcherUNIXPrivate::processThreadWakeUp(const int nsel)
{readyread = pfd.revents & POLLIN;
196-
197 if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds))readyread) {
readyreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
198 // consume the data on the thread pipe so that-
199 // poll doesn't immediately return next time-
200#if defined(Q_OS_VXWORKS)-
201 char c[16];::read(thread_pipefds[0], c, sizeof(c));-
202 ::ioctl(thread_pipefds[0], FIOFLUSH, 0);-
203#else-
204# ifndef QT_NO_EVENTFD-
205 if (thread_pipefds[1] == -1) {
fds[1] == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
206 // eventfd-
207 eventfd_t value;-
208 eventfd_read(thread_pipefds[0], &value);-
209 } else
never executed: end of block
0
210# endif-
211 {-
212 char c[16];while (::read(thread_pipefds[0], c, sizeof(c)) > 0) {
never executed: end of block
::read(fds[0],...sizeof(c)) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
}
never executed: end of block
::read(fds[0],...sizeof(c)) > 0Description
TRUEnever evaluated
FALSEnever evaluated
{}
never executed: end of block
::read(fds[0],...sizeof(c)) > 0Description
TRUEnever evaluated
FALSEnever evaluated
213 }
never executed: end of block
0
214#endif-
215-
216 if (!wakeUps.testAndSetRelease(1, 0)) {
!wakeUps.testA...tRelease(1, 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
217 // hopefully, this is dead code-
218 qWarning("QEventDispatcherUNIX"QThreadPipe: internal error, wakeUps.testAndSetRelease(1, 0) failed!");-
219 }
never executed: end of block
0
220 }
never executed: end of block
0
221-
222 return 1readyread;
never executed: return readyread;
0
223}-
224-
225QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()-
226{-
227 if (Q_UNLIKELY(threadPipe.init() == false))
__builtin_expe...false), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
228 qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
never executed: QMessageLogger(__FILE__, 228, __PRETTY_FUNCTION__).fatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
0
229}
never executed: end of block
0
230-
231QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate()-
232{-
233 // cleanup timers-
234 qDeleteAll(timerList);-
235}
never executed: end of block
0
236-
237void QEventDispatcherUNIXPrivate::setSocketNotifierPending(QSocketNotifier *notifier)-
238{-
239 Q_ASSERT(notifier);-
240-
241 if (pendingNotifiers.contains(notifier))
pendingNotifie...ains(notifier)Description
TRUEnever evaluated
FALSEnever evaluated
0
242 return;
never executed: return;
0
243-
244 pendingNotifiers << notifier;-
245}
never executed: end of block
0
246-
247int QEventDispatcherUNIXPrivate::activateTimers()-
248{-
249 return timerList.activateTimers();
never executed: return timerList.activateTimers();
0
250}-
251-
252void QEventDispatcherUNIXPrivate::markPendingSocketNotifiers()-
253{-
254 for (const pollfd &pfd : qAsConst(pollfds)) {-
255 if (pfd.fd < 0 || pfd.revents == 0)
pfd.fd < 0Description
TRUEnever evaluated
FALSEnever evaluated
pfd.revents == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
256 continue;
never executed: continue;
0
257-
258 auto it = socketNotifiers.find(pfd.fd);-
259 Q_ASSERT(it != socketNotifiers.end());-
260-
261 const QSocketNotifierSetUNIX &sn_set = it.value();-
262-
263 static const struct {-
264 QSocketNotifier::Type type;-
265 short flags;-
266 } notifiers[] = {-
267 { QSocketNotifier::Read, POLLIN | POLLHUP | POLLERR },-
268 { QSocketNotifier::Write, POLLOUT | POLLHUP | POLLERR },-
269 { QSocketNotifier::Exception, POLLPRI | POLLHUP | POLLERR }-
270 };-
271-
272 for (const auto &n : notifiers) {-
273 QSocketNotifier *notifier = sn_set.notifiers[n.type];-
274-
275 if (!notifier)
!notifierDescription
TRUEnever evaluated
FALSEnever evaluated
0
276 continue
never executed: continue;
;
never executed: continue;
0
277-
278 if (pfd.revents & POLLNVAL) {
pfd.revents & 0x020Description
TRUEnever evaluated
FALSEnever evaluated
0
279 qWarning("QSocketNotifier: Invalid socket %d with type %s, disabling...",-
280 it.key(), socketType(n.type));-
281 notifier->setEnabled(false);-
282 }
never executed: end of block
0
283-
284 if (pfd.revents & n.flags)
pfd.revents & n.flagsDescription
TRUEnever evaluated
FALSEnever evaluated
0
285 setSocketNotifierPending(notifier);
never executed: setSocketNotifierPending(notifier);
0
286 }
never executed: end of block
0
287 }
never executed: end of block
0
288-
289 pollfds.clear();-
290}
never executed: end of block
0
291-
292int QEventDispatcherUNIXPrivate::activateSocketNotifiers()-
293{-
294 markPendingSocketNotifiers();-
295-
296 if (pendingNotifiers.isEmpty())
pendingNotifiers.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
297 return 0;
never executed: return 0;
0
298-
299 int n_activated = 0;-
300 QEvent event(QEvent::SockAct);-
301-
302 while (!pendingNotifiers.isEmpty()) {
!pendingNotifiers.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
303 QSocketNotifier *notifier = pendingNotifiers.takeFirst();-
304 QCoreApplication::sendEvent(notifier, &event);-
305 ++n_activated;-
306 }
never executed: end of block
0
307-
308 return n_activated
never executed: return n_activated;
;
never executed: return n_activated;
0
309}-
310-
311QEventDispatcherUNIX::QEventDispatcherUNIX(QObject *parent)-
312 : QAbstractEventDispatcher(*new QEventDispatcherUNIXPrivate, parent)-
313{ }-
314-
315QEventDispatcherUNIX::QEventDispatcherUNIX(QEventDispatcherUNIXPrivate &dd, QObject *parent)-
316 : QAbstractEventDispatcher(dd, parent)-
317{ }-
318-
319QEventDispatcherUNIX::~QEventDispatcherUNIX()-
{
}
int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
timespec *timeout){ return qt_safe_select(nfds, readfds, writefds, exceptfds, timeout);}
321-
322/*!-
323 \internal-
324*/-
325void QEventDispatcherUNIX::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj)-
326{-
327#ifndef QT_NO_DEBUG-
328 if (timerId < 1 || interval < 0 || !obj) {-
329 qWarning("QEventDispatcherUNIX::registerTimer: invalid arguments");-
330 return;-
331 } else if (obj->thread() != thread() || thread() != QThread::currentThread()) {-
332 qWarning("QEventDispatcherUNIX::registerTimer: timers cannot be started from another thread");-
333 return;-
334 }-
335#endif-
336-
337 Q_D(QEventDispatcherUNIX);-
338 d->timerList.registerTimer(timerId, interval, timerType, obj);-
339}-
340-
341/*!-
342 \internal-
343*/-
344bool QEventDispatcherUNIX::unregisterTimer(int timerId)-
345{-
346#ifndef QT_NO_DEBUG-
347 if (timerId < 1) {-
348 qWarning("QEventDispatcherUNIX::unregisterTimer: invalid argument");-
349 return false;-
350 } else if (thread() != QThread::currentThread()) {-
351 qWarning("QEventDispatcherUNIX::unregisterTimer: timers cannot be stopped from another thread");-
352 return false;-
353 }-
354#endif-
355-
356 Q_D(QEventDispatcherUNIX);-
357 return d->timerList.unregisterTimer(timerId);-
358}-
359-
360/*!-
361 \internal-
362*/-
363bool QEventDispatcherUNIX::unregisterTimers(QObject *object)-
364{-
365#ifndef QT_NO_DEBUG-
366 if (!object) {-
367 qWarning("QEventDispatcherUNIX::unregisterTimers: invalid argument");-
368 return false;-
369 } else if (object->thread() != thread() || thread() != QThread::currentThread()) {-
370 qWarning("QEventDispatcherUNIX::unregisterTimers: timers cannot be stopped from another thread");-
371 return false;-
372 }-
373#endif-
374-
375 Q_D(QEventDispatcherUNIX);-
376 return d->timerList.unregisterTimers(object);-
377}-
378-
379QList<QEventDispatcherUNIX::TimerInfo>-
380QEventDispatcherUNIX::registeredTimers(QObject *object) const-
381{-
382 if (!object) {-
383 qWarning("QEventDispatcherUNIX:registeredTimers: invalid argument");-
384 return QList<TimerInfo>();-
385 }-
386-
387 Q_D(const QEventDispatcherUNIX);-
388 return d->timerList.registeredTimers(object);-
}
QSockNotType::QSockNotType()
{
FD_ZERO(&select_fds);
FD_ZERO(&enabled_fds);
FD_ZERO(&pending_fds);
}
QSockNotType::~QSockNotType()
{
for (int i = 0; i < list.size(); ++i)
delete list[i];}
390-
391/*****************************************************************************-
392 QEventDispatcher implementations for UNIX-
393 *****************************************************************************/-
394-
395void QEventDispatcherUNIX::registerSocketNotifier(QSocketNotifier *notifier)-
396{-
397 Q_ASSERT(notifier);-
398 int sockfd = notifier->socket();-
399 intQSocketNotifier::Type type = notifier->type();-
400#ifndef QT_NO_DEBUG-
401 if (sockfd < 0
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
0
|| unsigned(sockfd) >= FD_SETSIZE) {
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
qWarning("QSocketNotifier: Internal error");
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
return;
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
} else
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
402 qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");-
403 return;
never executed: return;
0
404 }-
405#endif-
406-
407 Q_D(QEventDispatcherUNIX);-
408 QSockNotType::List &listQSocketNotifierSetUNIX &sn_set = d->sn_vec[type].list;-
fd_set *fds = &d->sn_vecsocketNotifiers[type].enabled_fds;
QSockNot *sn;
sn = new QSockNot;
sn->obj = notifier;
sn->fd =sockfd;
sn->queue = &d->sn_vec];
409-
410 if (sn_set.notifiers
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
[type].pending_fds;
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
0
int i;
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
for (i = 0; i < list
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
] && sn_set.size(); ++i) {
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
QSockNot *p = list
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
notifiers[i];
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
if (p->fd < sockfd)
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
break;
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
if (p->fd == sockfd
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
type] != notifier)
sn_set.notifiers[type]Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
411 {
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
0
static const char *t[] = { "Read", "Write", "Exception" };
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
qWarning("QSocketNotifier"%s: Multiple socket notifiers for"
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
"same
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
same socket %d and type %s",
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
412 Q_FUNC_INFO
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
, sockfd, t[socketType(type]);
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
0
}
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
}
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
list
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
));
never executed: QMessageLogger(__FILE__, 411, __PRETTY_FUNCTION__).warning("%s: Multiple socket notifiers for same socket %d and type %s", __PRETTY_FUNCTION__, sockfd, socketType(type));
413-
414 sn_set.insert(i, sn);-
FD_SET(sockfd, fds);
d->sn_highestnotifiers[type] = qMax(d->sn_highest, sockfd);notifier;
415}
never executed: end of block
0
416-
417void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier)-
418{-
419 Q_ASSERT(notifier);-
420 int sockfd = notifier->socket();-
421 intQSocketNotifier::Type type = notifier->type();-
422#ifndef QT_NO_DEBUG-
423 if (sockfd < 0
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
0
|| unsigned(sockfd) >= FD_SETSIZE) {
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
qWarning("QSocketNotifier: Internal error");
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
return;
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
} else
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
notifier->thread() != thread()Description
TRUEnever evaluated
FALSEnever evaluated
thread() != QT...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
424 qWarning("QSocketNotifier: socket notifiersnotifier (fd %d) cannot be disabled from another thread");-
return;
}
#endif
Q_D(QEventDispatcherUNIX);
QSockNotType::List &list = d->sn_vec[type].list;
fd_set *fds = &d->sn_vec[type].enabled_fds;
QSockNot *sn = 0;
int i;
for (i = 0; i < listthread.size(); ++i) {
sn = list[i];
if\n"
425 "(sn->obj == notifier && sn->fd == sockfd)-
break;
}
ifNotifier's thread is %s(i == list.size()) return;
FD_CLR%p), event dispatcher's thread is %s(sockfd, fds); FD_CLR%p), current thread is %s(sockfd%p))",
426 sn->queue);-
d->sn_pending_list.removeAll(sn); list.removeAt(i); delete sn;
if (d->sn_highest ==sockfd) { d->sn_highest = -1;
for (int i=0; i<3; i++) {
if (!d->sn_vec[i].list.isEmpty())
d->sn_highest = qMax(d->sn_highest,
427 d->sn_vec[i].list[0]->fd);-
}
}
}
void QEventDispatcherUNIX::setSocketNotifierPending(QSocketNotifier *notifier)
{
Q_ASSERT(notifier);
int sockfd =notifier->socket();
int type =thread() ? notifier->type();
#ifndef QT_NO_DEBUG
if (sockfd < 0
|| unsigned(sockfd) >= FD_SETSIZE) {
qWarning("QSocketNotifierthread()->metaObject()->className() : Internal error");
return;
}
Q_ASSERT("QThread", notifier->thread(),
428 thread() ==? thread()->metaObject()->className() &&: "QThread", thread(),-
429 QThread::currentThread() ==? QThread::currentThread()->metaObject()->className() : "QThread", QThread::currentThread());-
430 return;
never executed: return;
0
431 }-
432#endif-
433-
434 Q_D(QEventDispatcherUNIX);-
435-
436 QSockNotType::List &list =d->sn_vec[type].list;-
QSockNot *sn = 0;
int i;
forpendingNotifiers.removeOne(notifier);
437-
438 auto i = 0; i < listd->socketNotifiers.size(); ++i) {-
sn = list[i];
iffind(sn->obj == notifier && sn->fd ==sockfd)
break;
});
439 if (i == list.size()) return;
i == d->socketNotifiers.end()Description
TRUEnever evaluated
FALSEnever evaluated
0
if (! FD_ISSET(sn->fd, sn->queue)) {
i == d->socketNotifiers.end()Description
TRUEnever evaluated
FALSEnever evaluated
if (
i == d->socketNotifiers.end()Description
TRUEnever evaluated
FALSEnever evaluated
d->sn_pending_listsocketNotifiers.isEmptyend())
i == d->socketNotifiers.end()Description
TRUEnever evaluated
FALSEnever evaluated
440 {
never executed: return;
0
d->sn_pending_list
never executed: return;
return;
never executed: return;
441-
442 QSocketNotifierSetUNIX &sn_set = i.appendvalue();-
443-
444 if
sn_set.notifie...pe] == nullptrDescription
TRUEnever evaluated
FALSEnever evaluated
(sn);
sn_set.notifie...pe] == nullptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
} else {
sn_set.notifie...pe] == nullptrDescription
TRUEnever evaluated
FALSEnever evaluated
d->sn_pending_list
sn_set.notifie...pe] == nullptrDescription
TRUEnever evaluated
FALSEnever evaluated
sn_set.insert((qrand() & 0xffnotifiers[type] == nullptr)
sn_set.notifie...pe] == nullptrDescription
TRUEnever evaluated
FALSEnever evaluated
445 %return;
never executed: return;
0
446-
447 if
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
(d->sn_pending_listsn_set.size()+1), sn);
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
0
}
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
FD_SET(sn->fd, sn->queue);
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
}
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
}
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
int QEventDispatcherUNIX::activateTimers()
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
notifiers[type] != notifier) {
sn_set.notifie...e] != notifierDescription
TRUEnever evaluated
FALSEnever evaluated
448 Q_ASSERTqWarning(thread() == QThread::currentThread());-
Q_D"%s: Multiple socket notifiers for same socket %d and type %s",
449 Q_FUNC_INFO, sockfd, socketType(QEventDispatcherUNIX);type));-
450 returnd->timerList.activateTimers();;
never executed: return;
0
451 }-
452-
453 int QEventDispatcherUNIX::activateSocketNotifiers()-
{
Q_D(QEventDispatcherUNIX);
if (d->sn_pending_listsn_set.isEmpty())
return 0;
int n_actnotifiers[type] = 0nullptr;
454-
455 QEvent eventif (QEvent::SockAct);
sn_set.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
while (!d->sn_pending_list
sn_set.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
sn_set.isEmpty())
sn_set.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
456 {
never executed: d->socketNotifiers.erase(i);
0
QSockNot *sn =
never executed: d->socketNotifiers.erase(i);
d->sn_pending_listsocketNotifiers.takeFirst();
never executed: d->socketNotifiers.erase(i);
if (FD_ISSET(sn->fd, sn->queue)) {
never executed: d->socketNotifiers.erase(i);
FD_CLR(sn->fd, sn->queue);
never executed: d->socketNotifiers.erase(i);
QCoreApplication::sendEvent
never executed: d->socketNotifiers.erase(i);
erase(sn->obj, &eventi);
never executed: d->socketNotifiers.erase(i);
++n_act;
never executed: end of block
}
never executed: end of block
}
never executed: end of block
return n_act;
never executed: end of block
}
never executed: end of block
458-
459bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)-
460{-
461 Q_D(QEventDispatcherUNIX);-
462 d->interrupt.store(0);-
463-
464 // we are awake, broadcast it-
465 emit awake();-
466 QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);-
467-
468 int neventsconst bool include_timers = (flags & QEventLoop::X11ExcludeTimers) == 0;-
469 const bool include_notifiers = (flags & QEventLoop::ExcludeSocketNotifiers) == 0;-
470 const bool wait_for_events = flags & QEventLoop::WaitForMoreEvents;-
471-
472 const bool canWait = (d->threadData->canWaitLocked()
d->threadData->canWaitLocked()Description
TRUEnever evaluated
FALSEnever evaluated
0
473 && !d->interrupt.load()
!d->interrupt.load()Description
TRUEnever evaluated
FALSEnever evaluated
0
474 && (flags & QEventLoop::WaitForMoreEvents));wait_for_events);
wait_for_eventsDescription
TRUEnever evaluated
FALSEnever evaluated
0
475-
476 if (canWait)
canWaitDescription
TRUEnever evaluated
FALSEnever evaluated
0
477 emit aboutToBlock();
never executed: aboutToBlock();
0
478-
479 if (!(d->interrupt.load())
d->interrupt.load()Description
TRUEnever evaluated
FALSEnever evaluated
0
480 {
never executed: return false;
0
never executed: return false;
return false;
never executed: return false;
481-
482 timespec *tm = 0nullptr;-
483 timespec wait_tm = { 0l0, 0l0 };-
484-
485 if (!(flags & QEventLoop::X11ExcludeTimers)) {if (!canWait || (include_timers && d->timerList.timerWait(wait_tm)))))
!canWaitDescription
TRUEnever evaluated
FALSEnever evaluated
include_timersDescription
TRUEnever evaluated
FALSEnever evaluated
d->timerList.t...rWait(wait_tm)Description
TRUEnever evaluated
FALSEnever evaluated
0
486 tm = &wait_tm;
never executed: tm = &wait_tm;
0
487-
488 }-
if (!canWait) {d->pollfds.clear();
489 d->pollfds.reserve(1 + (include_notifiers ? d->socketNotifiers.size() : 0));-
490-
491 if (!tm(include_notifiers)
include_notifiersDescription
TRUEnever evaluated
FALSEnever evaluated
0
492 tmfor (auto it = &wait_tm;
it != d->socke...tifiers.cend()Description
TRUEnever evaluated
FALSEnever evaluated
0
tm
it != d->socke...tifiers.cend()Description
TRUEnever evaluated
FALSEnever evaluated
d->tv_secsocketNotifiers.cbegin(); it != d->socketNotifiers.cend(); ++it)
it != d->socke...tifiers.cend()Description
TRUEnever evaluated
FALSEnever evaluated
493 d->pollfds.append(qt_make_pollfd(it.key(), it.value().events()));
never executed: d->pollfds.append(qt_make_pollfd(it.key(), it.value().events()));
0
494-
495 // This must be last, as it's popped off the end below-
496 d->pollfds.append(d->threadPipe.prepare());-
497-
498 int nevents = 0l0;-
499-
500 tmswitch (qt_safe_poll(d->tv_nsec = 0lpollfds.data(), d->pollfds.size(), tm)) {-
501 case -1:
never executed: case -1:
0
502 perror("qt_safe_poll");-
503 break
never executed: break;
;
never executed: break;
0
504 }case 0:
never executed: case 0:
0
505 break;
never executed: break;
0
506 default:
never executed: default:
0
507 nevents =+= d->doSelectthreadPipe.check(flags, tm);-
d->pollfds.takeLast());
508 if (!(flags & QEventLoop::X11ExcludeTimers)) {include_notifiers)
include_notifiersDescription
TRUEnever evaluated
FALSEnever evaluated
0
509 nevents += activateTimersd->activateSocketNotifiers();
never executed: nevents += d->activateSocketNotifiers();
0
510 }break;
never executed: break;
0
511 }-
512-
513 if (include_timers)
include_timersDescription
TRUEnever evaluated
FALSEnever evaluated
0
514 nevents += d->activateTimers();
never executed: nevents += d->activateTimers();
0
515-
516 // return true if we handled events, false otherwise-
517 return (nevents > 0);
never executed: return (nevents > 0);
0
518}-
519-
520bool QEventDispatcherUNIX::hasPendingEvents()-
521{-
522 extern uint qGlobalPostedEventsCount(); // from qapplication.cpp-
523 return qGlobalPostedEventsCount();-
524}-
525-
526int QEventDispatcherUNIX::remainingTime(int timerId)-
527{-
528#ifndef QT_NO_DEBUG-
529 if (timerId < 1) {-
530 qWarning("QEventDispatcherUNIX::remainingTime: invalid argument");-
531 return -1;-
532 }-
533#endif-
534-
535 Q_D(QEventDispatcherUNIX);-
536 return d->timerList.timerRemainingTime(timerId);-
537}-
538-
539void QEventDispatcherUNIX::wakeUp()-
540{-
541 Q_D(QEventDispatcherUNIX);-
542 if (d->wakeUpsthreadPipe.testAndSetAcquire(0, 1)) {-
#ifndef QT_NO_EVENTFD
if (d->thread_pipe[1] == -1) {
eventfd_t value = 1;
int ret;
EINTR_LOOP(ret, eventfd_write(d->thread_pipe[0], value));
return;
}
#endif
char c = 0;
qt_safe_write( d->thread_pipe[1], &c, 1 );
}wakeUp();
543}
never executed: end of block
0
544-
545void QEventDispatcherUNIX::interrupt()-
546{-
547 Q_D(QEventDispatcherUNIX);-
548 d->interrupt.store(1);-
549 wakeUp();-
550}-
551-
552void QEventDispatcherUNIX::flush()-
553{ }-
554-
555QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9