100#if defined(Q_OS_WASM)
102#elif defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
104 rtpInfoGet((RTP_ID)NULL, &rtpStruct);
106 QByteArray pipeName(
"/pipe/qevloop_");
107 QByteArray path(rtpStruct.pathName);
108 pipeName.append(path.mid(path.lastIndexOf(QDir::separator().toLatin1())+1, path.size()));
109 pipeName.append(
"_");
110 pipeName.append(QByteArray::number((uint)rtpStruct.entrAddr, 16));
111 pipeName.append(
"_");
112 pipeName.append(QByteArray::number((uint)QThread::currentThreadId(), 16));
113 pipeName.append(
"_");
114 QRandomGenerator rg(QTime::currentTime().msecsSinceStartOfDay());
115 pipeName.append(QByteArray::number(rg.generate()));
118 pipeDevDelete(pipeName,
true);
121 if (pipeDevCreate(pipeName, 128 , 1 ) != OK) {
122 qCritical(
"QThreadPipe: Unable to create thread pipe device %s : %s", name, std::strerror(errno));
126 if ((fds[0] = open(pipeName, O_RDWR, 0)) < 0) {
127 qCritical(
"QThreadPipe: Unable to open pipe device %s : %s", name, std::strerror(errno));
131 initThreadPipeFD(fds[0]);
136 ret =
fds[0] = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
139 ret = qt_safe_pipe(
fds, O_NONBLOCK);
141 perror(
"QThreadPipe: Unable to create pipe");
225void QEventDispatcherUNIXPrivate::markPendingSocketNotifiers()
227 for (
const pollfd &pfd : std::as_const(pollfds)) {
228 if (pfd.fd < 0 || pfd.revents == 0)
231 auto it = socketNotifiers.find(pfd.fd);
232 Q_ASSERT(it != socketNotifiers.end());
234 const QSocketNotifierSetUNIX &sn_set = it.value();
236 static const struct {
237 QSocketNotifier::Type type;
240 { QSocketNotifier::Read, POLLIN | POLLHUP | POLLERR },
241 { QSocketNotifier::Write, POLLOUT | POLLHUP | POLLERR },
242 { QSocketNotifier::Exception, POLLPRI | POLLHUP | POLLERR }
245 for (
const auto &n : notifiers) {
246 QSocketNotifier *notifier = sn_set.notifiers[n.type];
251 if (pfd.revents & POLLNVAL) {
252 qWarning(
"QSocketNotifier: Invalid socket %d with type %s, disabling...",
253 it.key(), socketType(n.type));
254 notifier->setEnabled(
false);
257 if (pfd.revents & n.flags)
258 setSocketNotifierPending(notifier);
265int QEventDispatcherUNIXPrivate::activateSocketNotifiers()
267 markPendingSocketNotifiers();
269 if (pendingNotifiers.isEmpty())
273 QEvent event(QEvent::SockAct);
275 while (!pendingNotifiers.isEmpty()) {
276 QSocketNotifier *notifier = pendingNotifiers.takeFirst();
277 QCoreApplication::sendEvent(notifier, &event);
298void QEventDispatcherUNIX::registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType, QObject *obj)
301 if (qToUnderlying(timerId) < 1 || interval.count() < 0 || !obj) {
302 qWarning(
"QEventDispatcherUNIX::registerTimer: invalid arguments");
304 }
else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
305 qWarning(
"QEventDispatcherUNIX::registerTimer: timers cannot be started from another thread");
310 Q_D(QEventDispatcherUNIX);
311 d->timerList.registerTimer(timerId, interval, timerType, obj);
317bool QEventDispatcherUNIX::unregisterTimer(Qt::TimerId timerId)
320 if (qToUnderlying(timerId) < 1) {
321 qWarning(
"QEventDispatcherUNIX::unregisterTimer: invalid argument");
323 }
else if (thread() != QThread::currentThread()) {
324 qWarning(
"QEventDispatcherUNIX::unregisterTimer: timers cannot be stopped from another thread");
329 Q_D(QEventDispatcherUNIX);
330 return d->timerList.unregisterTimer(timerId);
368void QEventDispatcherUNIX::registerSocketNotifier(QSocketNotifier *notifier)
371 int sockfd = notifier->socket();
372 QSocketNotifier::Type type = notifier->type();
374 if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
375 qWarning(
"QSocketNotifier: socket notifiers cannot be enabled from another thread");
380 Q_D(QEventDispatcherUNIX);
381 QSocketNotifierSetUNIX &sn_set = d->socketNotifiers[sockfd];
383 if (sn_set.notifiers[type] && sn_set.notifiers[type] != notifier)
384 qWarning(
"%s: Multiple socket notifiers for same socket %d and type %s",
385 Q_FUNC_INFO, sockfd, socketType(type));
387 sn_set.notifiers[type] = notifier;
390void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier)
393 int sockfd = notifier->socket();
394 QSocketNotifier::Type type = notifier->type();
396 if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
397 qWarning(
"QSocketNotifier: socket notifier (fd %d) cannot be disabled from another thread.\n"
398 "(Notifier's thread is %s(%p), event dispatcher's thread is %s(%p), current thread is %s(%p))",
400 notifier->thread() ? notifier->thread()->metaObject()->className() :
"QThread", notifier->thread(),
401 thread() ? thread()->metaObject()->className() :
"QThread", thread(),
402 QThread::currentThread() ? QThread::currentThread()->metaObject()->className() :
"QThread", QThread::currentThread());
407 Q_D(QEventDispatcherUNIX);
409 d->pendingNotifiers.removeOne(notifier);
411 auto i = d->socketNotifiers.find(sockfd);
412 if (i == d->socketNotifiers.end())
415 QSocketNotifierSetUNIX &sn_set = i.value();
417 if (sn_set.notifiers[type] ==
nullptr)
420 if (sn_set.notifiers[type] != notifier) {
421 qWarning(
"%s: Multiple socket notifiers for same socket %d and type %s",
422 Q_FUNC_INFO, sockfd, socketType(type));
426 sn_set.notifiers[type] =
nullptr;
428 if (sn_set.isEmpty())
429 d->socketNotifiers.erase(i);
432bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
434 Q_D(QEventDispatcherUNIX);
435 d->interrupt.storeRelaxed(0);
440 auto threadData = d->threadData.loadRelaxed();
441 QCoreApplicationPrivate::sendPostedEvents(
nullptr, 0, threadData);
443 const bool include_timers = (flags & QEventLoop::X11ExcludeTimers) == 0;
444 const bool include_notifiers = (flags & QEventLoop::ExcludeSocketNotifiers) == 0;
445 const bool wait_for_events = (flags & QEventLoop::WaitForMoreEvents) != 0;
447 const bool canWait = (threadData->canWaitLocked()
448 && !d->interrupt.loadRelaxed()
454 if (d->interrupt.loadRelaxed())
457 QDeadlineTimer deadline;
459 if (include_timers) {
460 std::optional<nanoseconds> remaining = d->timerList.timerWait();
461 deadline = remaining ? QDeadlineTimer{*remaining}
462 : QDeadlineTimer(QDeadlineTimer::Forever);
464 deadline = QDeadlineTimer(QDeadlineTimer::Forever);
472 d->pollfds.reserve(1 + (include_notifiers ? d->socketNotifiers.size() : 0));
474 if (include_notifiers)
475 for (
auto it = d->socketNotifiers.cbegin(); it != d->socketNotifiers.cend(); ++it)
476 d->pollfds.append(qt_make_pollfd(it.key(), it.value().events()));
479 d->pollfds.append(d->threadPipe.prepare());
482 switch (qt_safe_poll(d->pollfds.data(), d->pollfds.size(), deadline)) {
484 qErrnoWarning(
"qt_safe_poll");
485#if defined(Q_OS_VXWORKS) && defined(EDOOM)
486 if (errno == EDOOM) {
491 if (QT_CONFIG(poll_exit_on_error))
497 nevents += d->threadPipe.check(d->pollfds.takeLast());
498 if (include_notifiers)
499 nevents += d->activateSocketNotifiers();
504 nevents += d->activateTimers();
507 return (nevents > 0);