101#elif defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
103 rtpInfoGet((RTP_ID)NULL, &rtpStruct);
105 QByteArray pipeName(
"/pipe/qevloop_");
106 QByteArray path(rtpStruct.pathName);
107 pipeName.append(path.mid(path.lastIndexOf(QDir::separator().toLatin1())+1, path.size()));
108 pipeName.append(
"_");
109 pipeName.append(QByteArray::number((uint)rtpStruct.entrAddr, 16));
110 pipeName.append(
"_");
111 pipeName.append(QByteArray::number((uint)QThread::currentThreadId(), 16));
112 pipeName.append(
"_");
113 QRandomGenerator rg(QTime::currentTime().msecsSinceStartOfDay());
114 pipeName.append(QByteArray::number(rg.generate()));
117 pipeDevDelete(pipeName,
true);
120 if (pipeDevCreate(pipeName, 128 , 1 ) != OK) {
121 qCritical(
"QThreadPipe: Unable to create thread pipe device %s : %s", name, std::strerror(errno));
125 if ((fds[0] = open(pipeName, O_RDWR, 0)) < 0) {
126 qCritical(
"QThreadPipe: Unable to open pipe device %s : %s", name, std::strerror(errno));
130 initThreadPipeFD(fds[0]);
135 ret =
fds[0] = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
138 ret = qt_safe_pipe(fds, O_NONBLOCK);
140 perror(
"QThreadPipe: Unable to create pipe");
224void QEventDispatcherUNIXPrivate::markPendingSocketNotifiers()
226 for (
const pollfd &pfd : std::as_const(pollfds)) {
227 if (pfd.fd < 0 || pfd.revents == 0)
230 auto it = socketNotifiers.find(pfd.fd);
231 Q_ASSERT(it != socketNotifiers.end());
233 const QSocketNotifierSetUNIX &sn_set = it.value();
235 static const struct {
236 QSocketNotifier::Type type;
239 { QSocketNotifier::Read, POLLIN | POLLHUP | POLLERR },
240 { QSocketNotifier::Write, POLLOUT | POLLHUP | POLLERR },
241 { QSocketNotifier::Exception, POLLPRI | POLLHUP | POLLERR }
244 for (
const auto &n : notifiers) {
245 QSocketNotifier *notifier = sn_set.notifiers[n.type];
250 if (pfd.revents & POLLNVAL) {
251 qWarning(
"QSocketNotifier: Invalid socket %d with type %s, disabling...",
252 it.key(), socketType(n.type));
253 notifier->setEnabled(
false);
256 if (pfd.revents & n.flags)
257 setSocketNotifierPending(notifier);
264int QEventDispatcherUNIXPrivate::activateSocketNotifiers()
266 markPendingSocketNotifiers();
268 if (pendingNotifiers.isEmpty())
272 QEvent event(QEvent::SockAct);
274 while (!pendingNotifiers.isEmpty()) {
275 QSocketNotifier *notifier = pendingNotifiers.takeFirst();
276 QCoreApplication::sendEvent(notifier, &event);
297void QEventDispatcherUNIX::registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType, QObject *obj)
300 if (qToUnderlying(timerId) < 1 || interval.count() < 0 || !obj) {
301 qWarning(
"QEventDispatcherUNIX::registerTimer: invalid arguments");
303 }
else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
304 qWarning(
"QEventDispatcherUNIX::registerTimer: timers cannot be started from another thread");
309 Q_D(QEventDispatcherUNIX);
310 d->timerList.registerTimer(timerId, interval, timerType, obj);
316bool QEventDispatcherUNIX::unregisterTimer(Qt::TimerId timerId)
319 if (qToUnderlying(timerId) < 1) {
320 qWarning(
"QEventDispatcherUNIX::unregisterTimer: invalid argument");
322 }
else if (thread() != QThread::currentThread()) {
323 qWarning(
"QEventDispatcherUNIX::unregisterTimer: timers cannot be stopped from another thread");
328 Q_D(QEventDispatcherUNIX);
329 return d->timerList.unregisterTimer(timerId);
367void QEventDispatcherUNIX::registerSocketNotifier(QSocketNotifier *notifier)
370 int sockfd = notifier->socket();
371 QSocketNotifier::Type type = notifier->type();
373 if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
374 qWarning(
"QSocketNotifier: socket notifiers cannot be enabled from another thread");
379 Q_D(QEventDispatcherUNIX);
380 QSocketNotifierSetUNIX &sn_set = d->socketNotifiers[sockfd];
382 if (sn_set.notifiers[type] && sn_set.notifiers[type] != notifier)
383 qWarning(
"%s: Multiple socket notifiers for same socket %d and type %s",
384 Q_FUNC_INFO, sockfd, socketType(type));
386 sn_set.notifiers[type] = notifier;
389void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier)
392 int sockfd = notifier->socket();
393 QSocketNotifier::Type type = notifier->type();
395 if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
396 qWarning(
"QSocketNotifier: socket notifier (fd %d) cannot be disabled from another thread.\n"
397 "(Notifier's thread is %s(%p), event dispatcher's thread is %s(%p), current thread is %s(%p))",
399 notifier->thread() ? notifier->thread()->metaObject()->className() :
"QThread", notifier->thread(),
400 thread() ? thread()->metaObject()->className() :
"QThread", thread(),
401 QThread::currentThread() ? QThread::currentThread()->metaObject()->className() :
"QThread", QThread::currentThread());
406 Q_D(QEventDispatcherUNIX);
408 d->pendingNotifiers.removeOne(notifier);
410 auto i = d->socketNotifiers.find(sockfd);
411 if (i == d->socketNotifiers.end())
414 QSocketNotifierSetUNIX &sn_set = i.value();
416 if (sn_set.notifiers[type] ==
nullptr)
419 if (sn_set.notifiers[type] != notifier) {
420 qWarning(
"%s: Multiple socket notifiers for same socket %d and type %s",
421 Q_FUNC_INFO, sockfd, socketType(type));
425 sn_set.notifiers[type] =
nullptr;
427 if (sn_set.isEmpty())
428 d->socketNotifiers.erase(i);
431bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
433 Q_D(QEventDispatcherUNIX);
434 d->interrupt.storeRelaxed(0);
439 auto threadData = d->threadData.loadRelaxed();
440 QCoreApplicationPrivate::sendPostedEvents(
nullptr, 0, threadData);
442 const bool include_timers = (flags & QEventLoop::X11ExcludeTimers) == 0;
443 const bool include_notifiers = (flags & QEventLoop::ExcludeSocketNotifiers) == 0;
444 const bool wait_for_events = (flags & QEventLoop::WaitForMoreEvents) != 0;
446 const bool canWait = (threadData->canWaitLocked()
447 && !d->interrupt.loadRelaxed()
453 if (d->interrupt.loadRelaxed())
456 QDeadlineTimer deadline;
458 if (include_timers) {
459 std::optional<nanoseconds> remaining = d->timerList.timerWait();
460 deadline = remaining ? QDeadlineTimer{*remaining}
461 : QDeadlineTimer(QDeadlineTimer::Forever);
463 deadline = QDeadlineTimer(QDeadlineTimer::Forever);
471 d->pollfds.reserve(1 + (include_notifiers ? d->socketNotifiers.size() : 0));
473 if (include_notifiers)
474 for (
auto it = d->socketNotifiers.cbegin(); it != d->socketNotifiers.cend(); ++it)
475 d->pollfds.append(qt_make_pollfd(it.key(), it.value().events()));
478 d->pollfds.append(d->threadPipe.prepare());
481 switch (qt_safe_poll(d->pollfds.data(), d->pollfds.size(), deadline)) {
483 qErrnoWarning(
"qt_safe_poll");
484#if defined(Q_OS_VXWORKS) && defined(EDOOM)
485 if (errno == EDOOM) {
490 if (QT_CONFIG(poll_exit_on_error))
496 nevents += d->threadPipe.check(d->pollfds.takeLast());
497 if (include_notifiers)
498 nevents += d->activateSocketNotifiers();
503 nevents += d->activateTimers();
506 return (nevents > 0);