#include "qplatformdefs.h"
#include "qcoreapplication.h"
#include "qpair.h"
#include "qsocketnotifier.h"
#include "qthread.h"
#include "qelapsedtimer.h"
#include "qeventdispatcher_unix_p.h"
#include <private/qthread_p.h>
#include <private/qcoreapplication_p.h>
#include <private/qcore_unix_p.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
// VxWorks doesn't correctly set the _POSIX_... options
#if defined(Q_OS_VXWORKS)
# if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK <= 0)
# undef _POSIX_MONOTONIC_CLOCK
# define _POSIX_MONOTONIC_CLOCK 1
# endif
# include <pipeDrv.h>
# include <selectLib.h>
#endif
#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)
# include <sys/times.h>
#endif
QT_BEGIN_NAMESPACE
Q_CORE_EXPORT bool qt_disable_lowpriority_timers=false;
/*****************************************************************************
UNIX signal handling
*****************************************************************************/
static sig_atomic_t signal_received;
static sig_atomic_t signals_fired[NSIG];
static void signalHandler(int sig)
{
signals_fired[sig] = 1;
signal_received = 1;
}
#if defined(Q_OS_INTEGRITY) || defined(Q_OS_VXWORKS)
static void initThreadPipeFD(int fd)
{
int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
if (ret == -1)
perror("QEventDispatcherUNIXPrivate: Unable to init thread pipe");
int flags = fcntl(fd, F_GETFL);
if (flags == -1)
perror("QEventDispatcherUNIXPrivate: Unable to get flags on thread pipe");
ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
if (ret == -1)
perror("QEventDispatcherUNIXPrivate: Unable to set flags on thread pipe");
}
#endif
QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
{
extern Qt::HANDLE qt_application_thread_id;
mainThread = (QThread::currentThreadId() == qt_application_thread_id);
bool pipefail = false;
// initialize the common parts of the event loop
#if defined(Q_OS_INTEGRITY)
// INTEGRITY doesn't like a "select" on pipes, so use socketpair instead
if (socketpair(AF_INET, SOCK_STREAM, PF_INET, 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)
char name[20];
qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent));
// make sure there is no pipe with this name
pipeDevDelete(name, true);
// create the pipe
if (pipeDevCreate(name, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe device");
pipefail = true;
} else {
if ((thread_pipe[0] = open(name, O_RDWR, 0)) < 0) {
perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe");
pipefail = true;
} else {
initThreadPipeFD(thread_pipe[0]);
thread_pipe[1] = thread_pipe[0];
}
}
#else
if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1) {
perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe");
pipefail = true;
}
#endif
if (pipefail)
qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
sn_highest = -1;
interrupt = false;
}
QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate()
{
#if defined(Q_OS_VXWORKS)
close(thread_pipe[0]);
char name[20];
qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent));
pipeDevDelete(name, true);
#else
// cleanup the common parts of the event loop
close(thread_pipe[0]);
close(thread_pipe[1]);
#endif
// cleanup timers
qDeleteAll(timerList);
}
int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, timeval *timeout)
{
Q_Q(QEventDispatcherUNIX);
// needed in QEventDispatcherUNIX::select()
timerList.updateCurrentTime();
int nsel;
do {
if (mainThread) {
while (signal_received) {
signal_received = 0;
for (int i = 0; i < NSIG; ++i) {
if (signals_fired[i]) {
signals_fired[i] = 0;
emit QCoreApplication::instance()->unixSignal(i);
}
}
}
}
// Process timers and socket notifiers - the common UNIX stuff
int highest = 0;
if (! (flags & QEventLoop::ExcludeSocketNotifiers) && (sn_highest >= 0)) {
// return the highest fd we can wait for input on
sn_vec[0].select_fds = sn_vec[0].enabled_fds;
sn_vec[1].select_fds = sn_vec[1].enabled_fds;
sn_vec[2].select_fds = sn_vec[2].enabled_fds;
highest = sn_highest;
} else {
FD_ZERO(&sn_vec[0].select_fds);
FD_ZERO(&sn_vec[1].select_fds);
FD_ZERO(&sn_vec[2].select_fds);
}
FD_SET(thread_pipe[0], &sn_vec[0].select_fds);
highest = qMax(highest, thread_pipe[0]);
nsel = q->select(highest + 1,
&sn_vec[0].select_fds,
&sn_vec[1].select_fds,
&sn_vec[2].select_fds,
timeout);
} while (nsel == -1 && (errno == EINTR || errno == EAGAIN));
if (nsel == -1) {
if (errno == EBADF) {
// it seems a socket notifier has a bad fd... find out
// which one it is and disable it
fd_set fdset;
timeval tm;
tm.tv_sec = tm.tv_usec = 0l;
for (int type = 0; type < 3; ++type) {
QSockNotType::List &list = sn_vec[type].list;
if (list.size() == 0)
continue;
for (int i = 0; i < list.size(); ++i) {
QSockNot *sn = list[i];
FD_ZERO(&fdset);
FD_SET(sn->fd, &fdset);
int ret = -1;
do {
switch (type) {
case 0: // read
ret = select(sn->fd + 1, &fdset, 0, 0, &tm);
break;
case 1: // write
ret = select(sn->fd + 1, 0, &fdset, 0, &tm);
break;
case 2: // except
ret = select(sn->fd + 1, 0, 0, &fdset, &tm);
break;
}
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
if (ret == -1 && errno == EBADF) {
// disable the invalid socket notifier
static const char *t[] = { "Read", "Write", "Exception" };
qWarning("QSocketNotifier: Invalid socket %d and type '%s', disabling...",
sn->fd, t[type]);
sn->obj->setEnabled(false);
}
}
}
} else {
// EINVAL... shouldn't happen, so let's complain to stderr
// and hope someone sends us a bug report
perror("select");
}
}
// some other thread woke us up... consume the data on the thread pipe so that
// select doesn't immediately return next time
int nevents = 0;
if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) {
#if defined(Q_OS_VXWORKS)
char c[16];
::read(thread_pipe[0], c, sizeof(c));
::ioctl(thread_pipe[0], FIOFLUSH, 0);
#else
char c[16];
while (::read(thread_pipe[0], c, sizeof(c)) > 0)
;
#endif
if (!wakeUps.testAndSetRelease(1, 0)) {
// hopefully, this is dead code
qWarning("QEventDispatcherUNIX: internal error, wakeUps.testAn
qeventdispatcher_unix.rar_UNIX
版权申诉
194 浏览量
2022-09-19
20:40:03
上传
评论
收藏 7KB RAR 举报
四散
- 粉丝: 51
- 资源: 1万+
最新资源
- 7777端口抓包数据集
- IMG_0694.GIF
- 基于图像的三维模型重建C++源代码+文档说明(高分课程设计)
- 基于聚焦法的工件立体测量方案,根据数据进行三维重建 使用HALCON处理图像,MATLAB拟合数据+源代码+数据集+效果图
- 锄战三国村 修改:货币使用不减 v1.10(2) 原创 (中文).apk
- 基于python实现的单目双目视觉三维重建+源代码+图像图片(高分课程设计)
- 基于C+++OPENCV的全景图像拼接源码(课程设计)
- 基于Python+OpenCV对多张图片进行全景图像拼接,消除鬼影,消除裂缝+源代码+文档说明+界面截图(高分课程设计)
- 基于C++实现的全景图像拼接源码(课程设计)
- 基于SIFT特征点提取和RASIC算法实现全景图像拼接python源码+文档说明+界面截图+详细注释(95分以上课程大作业)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈