5#include "qplatformdefs.h"
14#include <private/qthread_p.h>
15#include <private/qcoreapplication_p.h>
16#include <private/qcore_unix_p.h>
23# include <sys/eventfd.h>
27#if defined(Q_OS_VXWORKS)
28# if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK <= 0)
29# undef _POSIX_MONOTONIC_CLOCK
30# define _POSIX_MONOTONIC_CLOCK 1
36#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)
37# include <sys/times.h>
60#if defined(Q_OS_VXWORKS)
73#if defined(Q_OS_VXWORKS)
74 pipeDevDelete(
name,
true);
78#if defined(Q_OS_VXWORKS)
79static void initThreadPipeFD(
int fd)
81 int ret = fcntl(
fd, F_SETFD, FD_CLOEXEC);
83 perror(
"QEventDispatcherUNIXPrivate: Unable to init thread pipe");
87 perror(
"QEventDispatcherUNIXPrivate: Unable to get flags on thread pipe");
91 perror(
"QEventDispatcherUNIXPrivate: Unable to set flags on thread pipe");
99#elif defined(Q_OS_VXWORKS)
103 pipeDevDelete(
name,
true);
106 if (pipeDevCreate(
name, 128 , 1 ) != OK) {
107 perror(
"QThreadPipe: Unable to create thread pipe device %s",
name);
112 perror(
"QThreadPipe: Unable to open pipe device %s",
name);
116 initThreadPipeFD(
fds[0]);
119# ifndef QT_NO_EVENTFD
120 if ((
fds[0] = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC)) >= 0)
124 perror(
"QThreadPipe: Unable to create pipe");
159 const int readyread = pfd.revents & POLLIN;
164#if defined(Q_OS_VXWORKS)
166 ::ioctl(
fds[0], FIOFLUSH, 0);
168# ifndef QT_NO_EVENTFD
182 qWarning(
"QThreadPipe: internal error, wakeUps.testAndSetRelease(1, 0) failed!");
192 qFatal(
"QEventDispatcherUNIXPrivate(): Cannot continue without a thread pipe");
218 for (
const pollfd &pfd : std::as_const(
pollfds)) {
219 if (pfd.fd < 0 || pfd.revents == 0)
227 static const struct {
236 for (
const auto &
n : notifiers) {
242 if (pfd.revents & POLLNVAL) {
243 qWarning(
"QSocketNotifier: Invalid socket %d with type %s, disabling...",
248 if (pfd.revents &
n.flags)
292 if (timerId < 1 || interval < 0 || !
obj) {
293 qWarning(
"QEventDispatcherUNIX::registerTimer: invalid arguments");
296 qWarning(
"QEventDispatcherUNIX::registerTimer: timers cannot be started from another thread");
302 d->timerList.registerTimer(timerId, std::chrono::milliseconds{ interval }, timerType,
obj);
312 qWarning(
"QEventDispatcherUNIX::unregisterTimer: invalid argument");
315 qWarning(
"QEventDispatcherUNIX::unregisterTimer: timers cannot be stopped from another thread");
321 return d->timerList.unregisterTimer(timerId);
331 qWarning(
"QEventDispatcherUNIX::unregisterTimers: invalid argument");
334 qWarning(
"QEventDispatcherUNIX::unregisterTimers: timers cannot be stopped from another thread");
340 return d->timerList.unregisterTimers(
object);
347 qWarning(
"QEventDispatcherUNIX:registeredTimers: invalid argument");
352 return d->timerList.registeredTimers(
object);
366 qWarning(
"QSocketNotifier: socket notifiers cannot be enabled from another thread");
375 qWarning(
"%s: Multiple socket notifiers for same socket %d and type %s",
388 qWarning(
"QSocketNotifier: socket notifier (fd %d) cannot be disabled from another thread.\n"
389 "(Notifier's thread is %s(%p), event dispatcher's thread is %s(%p), current thread is %s(%p))",
402 auto i =
d->socketNotifiers.find(sockfd);
403 if (
i ==
d->socketNotifiers.end())
412 qWarning(
"%s: Multiple socket notifiers for same socket %d and type %s",
420 d->socketNotifiers.erase(
i);
426 d->interrupt.storeRelaxed(0);
431 auto threadData =
d->threadData.loadRelaxed();
438 const bool canWait = (threadData->canWaitLocked()
439 && !
d->interrupt.loadRelaxed()
445 if (
d->interrupt.loadRelaxed())
448 timespec *tm =
nullptr;
449 timespec wait_tm = { 0, 0 };
451 if (!canWait || (include_timers &&
d->timerList.timerWait(wait_tm)))
455 d->pollfds.reserve(1 + (include_notifiers ?
d->socketNotifiers.size() : 0));
457 if (include_notifiers)
458 for (
auto it =
d->socketNotifiers.cbegin();
it !=
d->socketNotifiers.cend(); ++
it)
462 d->pollfds.append(
d->threadPipe.prepare());
475 nevents +=
d->threadPipe.check(
d->pollfds.takeLast());
476 if (include_notifiers)
477 nevents +=
d->activateSocketNotifiers();
482 nevents +=
d->activateTimers();
485 return (nevents > 0);
492 qWarning(
"QEventDispatcherUNIX::remainingTime: invalid argument");
498 return d->timerList.timerRemainingTime(timerId);
504 d->threadPipe.wakeUp();
510 d->interrupt.storeRelaxed(1);
516#include "moc_qeventdispatcher_unix_p.cpp"
DarwinBluetooth::LECBManagerNotifier * notifier
void aboutToBlock()
This signal is emitted before the event loop calls a function that could block.
void awake()
This signal is emitted after the event loop returns from a function that could block.
bool testAndSetAcquire(T expectedValue, T newValue) noexcept
bool testAndSetRelease(T expectedValue, T newValue) noexcept
static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data)
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
void markPendingSocketNotifiers()
int activateSocketNotifiers()
QHash< int, QSocketNotifierSetUNIX > socketNotifiers
QList< QSocketNotifier * > pendingNotifiers
~QEventDispatcherUNIXPrivate()
void setSocketNotifierPending(QSocketNotifier *notifier)
QEventDispatcherUNIXPrivate()
QEventDispatcherUNIX(QObject *parent=nullptr)
bool unregisterTimers(QObject *object) final
bool processEvents(QEventLoop::ProcessEventsFlags flags) override
Processes pending events that match flags until there are no more events to process.
void registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object) final
bool unregisterTimer(int timerId) final
void interrupt() final
Interrupts event dispatching.
QList< TimerInfo > registeredTimers(QObject *object) const final
Returns a list of registered timers for object.
void wakeUp() override
\threadsafe
void registerSocketNotifier(QSocketNotifier *notifier) final
Registers notifier with the event loop.
void unregisterSocketNotifier(QSocketNotifier *notifier) final
Unregisters notifier from the event dispatcher.
int remainingTime(int timerId) final
Returns the remaining time in milliseconds with the given timerId.
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
bool isEmpty() const noexcept
QThread * thread() const
Returns the thread in which the object lives.
Type
This enum describes the various types of events that a socket notifier can recognize.
static QThread * currentThread()
EGLint EGLint EGLint EGLint int int int int * fds
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
Q_CORE_EXPORT int qsnprintf(char *str, size_t n, const char *fmt,...)
int qt_safe_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts)
static qint64 qt_safe_write(int fd, const void *data, qint64 len)
static struct pollfd qt_make_pollfd(int fd, short events)
#define EINTR_LOOP(var, cmd)
static int qt_safe_pipe(int pipefd[2], int flags=0)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static QT_BEGIN_NAMESPACE const char * socketType(QSocketNotifier::Type type)
#define QT_CONFIG(feature)
ReturnedValue read(const char *data)
file open(QIODevice::ReadOnly)
bool contains(const AT &t) const noexcept
QSocketNotifier * notifiers[3]
bool isEmpty() const noexcept
int check(const pollfd &pfd)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent