Add POSIX Pipe feature to VxWorks
VxWorks has POSIX pipe2 functions, but doesn't pass threadsafe-cloexec because it doesn't have threadsafe-cloexec dup3. By default on VxWorks POSIX pipes are used, but now it's possible to switch to PipeDrv pipes using "configure -feature-vxpipedrv ...". dup3 and accept4 test are now separated from threadsafe-cloexec test. Task-number: QTBUG-132889 Pick-to: 6.8 6.9 Change-Id: I9e4514e2795917e8f3685a1760ea82a0022e9ca2 Reviewed-by: Alexey Edelev <alexey.edelev@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
5ff542493d
commit
53756dcfbc
@ -132,6 +132,46 @@ int pipes[2];
|
||||
}
|
||||
")
|
||||
|
||||
# dup3
|
||||
qt_config_compile_test(dup3
|
||||
LABEL "dup3"
|
||||
CODE
|
||||
"#define _GNU_SOURCE 1
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* BEGIN TEST: */
|
||||
(void) dup3(0, 3, O_CLOEXEC);
|
||||
/* END TEST: */
|
||||
return 0;
|
||||
}
|
||||
")
|
||||
|
||||
# acccept4
|
||||
qt_config_compile_test(accept4
|
||||
LABEL "accept4"
|
||||
CODE
|
||||
"#define _GNU_SOURCE 1
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* BEGIN TEST: */
|
||||
#if defined(__NetBSD__)
|
||||
(void) paccept(0, 0, 0, NULL, SOCK_CLOEXEC | SOCK_NONBLOCK);
|
||||
#else
|
||||
(void) accept4(0, 0, 0, SOCK_CLOEXEC | SOCK_NONBLOCK);
|
||||
#endif
|
||||
/* END TEST: */
|
||||
return 0;
|
||||
}
|
||||
")
|
||||
|
||||
# copy_file_range
|
||||
qt_config_compile_test(copy_file_range
|
||||
LABEL "copy_file_range()"
|
||||
@ -866,6 +906,19 @@ qt_feature("threadsafe-cloexec"
|
||||
)
|
||||
qt_feature_definition("threadsafe-cloexec" "QT_THREADSAFE_CLOEXEC" VALUE "1")
|
||||
qt_feature_config("threadsafe-cloexec" QMAKE_PUBLIC_QT_CONFIG)
|
||||
qt_feature("dup3" PRIVATE
|
||||
LABEL "dup3 support"
|
||||
CONDITION TEST_dup3
|
||||
)
|
||||
qt_feature("accept4" PRIVATE
|
||||
LABEL "accept4 support"
|
||||
CONDITION TEST_accept4
|
||||
)
|
||||
qt_feature("vxpipedrv" PRIVATE
|
||||
LABEL "Use pipedrv pipes on VxWorks"
|
||||
AUTODETECT OFF
|
||||
CONDITION VXWORKS
|
||||
)
|
||||
qt_feature("regularexpression" PUBLIC
|
||||
SECTION "Kernel"
|
||||
LABEL "QRegularExpression"
|
||||
|
@ -52,6 +52,7 @@
|
||||
#define QT_NO_DATASTREAM
|
||||
#define QT_FEATURE_datestring 1
|
||||
#define QT_FEATURE_datetimeparser -1
|
||||
#define QT_FEATURE_dup3 -1
|
||||
#define QT_FEATURE_easingcurve -1
|
||||
#define QT_FEATURE_etw -1
|
||||
#define QT_FEATURE_futimens -1
|
||||
|
@ -270,7 +270,6 @@ static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 07
|
||||
#undef QT_OPEN
|
||||
#define QT_OPEN qt_safe_open
|
||||
|
||||
#ifndef Q_OS_VXWORKS // no POSIX pipes in VxWorks
|
||||
// don't call ::pipe
|
||||
// call qt_safe_pipe
|
||||
static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
|
||||
@ -299,8 +298,6 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // Q_OS_VXWORKS
|
||||
|
||||
// don't call dup or fcntl(F_DUPFD)
|
||||
static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC)
|
||||
{
|
||||
@ -328,7 +325,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC)
|
||||
Q_ASSERT(flags == FD_CLOEXEC || flags == 0);
|
||||
|
||||
int ret;
|
||||
#ifdef QT_THREADSAFE_CLOEXEC
|
||||
#if QT_CONFIG(dup3)
|
||||
// use dup3
|
||||
QT_EINTR_LOOP(ret, ::dup3(oldfd, newfd, flags ? O_CLOEXEC : 0));
|
||||
return ret;
|
||||
|
@ -27,8 +27,16 @@ static constexpr bool UsingEventfd = true;
|
||||
static constexpr bool UsingEventfd = false;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_VXWORKS)
|
||||
#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
|
||||
# include "qbytearray.h"
|
||||
# include "qdatetime.h"
|
||||
# include "qdir.h" // to get application name
|
||||
# include "qrandom.h"
|
||||
# include <pipeDrv.h>
|
||||
# include <selectLib.h>
|
||||
# include <taskLib.h>
|
||||
# include <rtpLib.h>
|
||||
# include <sysLib.h>
|
||||
#endif
|
||||
|
||||
using namespace std::chrono;
|
||||
@ -62,12 +70,12 @@ QThreadPipe::~QThreadPipe()
|
||||
if (!UsingEventfd && fds[1] >= 0)
|
||||
close(fds[1]);
|
||||
|
||||
#if defined(Q_OS_VXWORKS)
|
||||
#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
|
||||
pipeDevDelete(name, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(Q_OS_VXWORKS)
|
||||
#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
|
||||
static void initThreadPipeFD(int fd)
|
||||
{
|
||||
int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
@ -88,20 +96,32 @@ bool QThreadPipe::init()
|
||||
{
|
||||
#if defined(Q_OS_WASM)
|
||||
// do nothing.
|
||||
#elif defined(Q_OS_VXWORKS)
|
||||
std::snprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdSelf()));
|
||||
#elif defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
|
||||
RTP_DESC rtpStruct;
|
||||
rtpInfoGet((RTP_ID)NULL, &rtpStruct);
|
||||
|
||||
QByteArray pipeName("/pipe/qevloop_");
|
||||
QByteArray path(rtpStruct.pathName);
|
||||
pipeName.append(path.mid(path.lastIndexOf(QDir::separator().toLatin1())+1, path.size()));
|
||||
pipeName.append("_");
|
||||
pipeName.append(QByteArray::number((uint)rtpStruct.entrAddr, 16));
|
||||
pipeName.append("_");
|
||||
pipeName.append(QByteArray::number((uint)QThread::currentThreadId(), 16));
|
||||
pipeName.append("_");
|
||||
QRandomGenerator rg(QTime::currentTime().msecsSinceStartOfDay());
|
||||
pipeName.append(QByteArray::number(rg.generate()));
|
||||
|
||||
// make sure there is no pipe with this name
|
||||
pipeDevDelete(name, true);
|
||||
pipeDevDelete(pipeName, true);
|
||||
|
||||
// create the pipe
|
||||
if (pipeDevCreate(name, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
|
||||
perror("QThreadPipe: Unable to create thread pipe device");
|
||||
if (pipeDevCreate(pipeName, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
|
||||
qCritical("QThreadPipe: Unable to create thread pipe device %s : %s", name, std::strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((fds[0] = open(name, O_RDWR, 0)) < 0) {
|
||||
perror("QThreadPipe: Unable to open pipe device");
|
||||
if ((fds[0] = open(pipeName, O_RDWR, 0)) < 0) {
|
||||
qCritical("QThreadPipe: Unable to open pipe device %s : %s", name, std::strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -150,7 +170,7 @@ int QThreadPipe::check(const pollfd &pfd)
|
||||
if (readyread) {
|
||||
// consume the data on the thread pipe so that
|
||||
// poll doesn't immediately return next time
|
||||
#if defined(Q_OS_VXWORKS)
|
||||
#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
|
||||
::read(fds[0], c, sizeof(c));
|
||||
::ioctl(fds[0], FIOFLUSH, 0);
|
||||
#else
|
||||
|
@ -73,7 +73,7 @@ static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *add
|
||||
Q_ASSERT((flags & ~O_NONBLOCK) == 0);
|
||||
|
||||
int fd;
|
||||
#ifdef QT_THREADSAFE_CLOEXEC
|
||||
#if QT_CONFIG(accept4)
|
||||
// use accept4
|
||||
int sockflags = SOCK_CLOEXEC;
|
||||
if (flags & O_NONBLOCK)
|
||||
|
Loading…
x
Reference in New Issue
Block a user