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
|
# copy_file_range
|
||||||
qt_config_compile_test(copy_file_range
|
qt_config_compile_test(copy_file_range
|
||||||
LABEL "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_definition("threadsafe-cloexec" "QT_THREADSAFE_CLOEXEC" VALUE "1")
|
||||||
qt_feature_config("threadsafe-cloexec" QMAKE_PUBLIC_QT_CONFIG)
|
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
|
qt_feature("regularexpression" PUBLIC
|
||||||
SECTION "Kernel"
|
SECTION "Kernel"
|
||||||
LABEL "QRegularExpression"
|
LABEL "QRegularExpression"
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#define QT_NO_DATASTREAM
|
#define QT_NO_DATASTREAM
|
||||||
#define QT_FEATURE_datestring 1
|
#define QT_FEATURE_datestring 1
|
||||||
#define QT_FEATURE_datetimeparser -1
|
#define QT_FEATURE_datetimeparser -1
|
||||||
|
#define QT_FEATURE_dup3 -1
|
||||||
#define QT_FEATURE_easingcurve -1
|
#define QT_FEATURE_easingcurve -1
|
||||||
#define QT_FEATURE_etw -1
|
#define QT_FEATURE_etw -1
|
||||||
#define QT_FEATURE_futimens -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
|
#undef QT_OPEN
|
||||||
#define QT_OPEN qt_safe_open
|
#define QT_OPEN qt_safe_open
|
||||||
|
|
||||||
#ifndef Q_OS_VXWORKS // no POSIX pipes in VxWorks
|
|
||||||
// don't call ::pipe
|
// don't call ::pipe
|
||||||
// call qt_safe_pipe
|
// call qt_safe_pipe
|
||||||
static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // Q_OS_VXWORKS
|
|
||||||
|
|
||||||
// don't call dup or fcntl(F_DUPFD)
|
// don't call dup or fcntl(F_DUPFD)
|
||||||
static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC)
|
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);
|
Q_ASSERT(flags == FD_CLOEXEC || flags == 0);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
#ifdef QT_THREADSAFE_CLOEXEC
|
#if QT_CONFIG(dup3)
|
||||||
// use dup3
|
// use dup3
|
||||||
QT_EINTR_LOOP(ret, ::dup3(oldfd, newfd, flags ? O_CLOEXEC : 0));
|
QT_EINTR_LOOP(ret, ::dup3(oldfd, newfd, flags ? O_CLOEXEC : 0));
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -27,8 +27,16 @@ static constexpr bool UsingEventfd = true;
|
|||||||
static constexpr bool UsingEventfd = false;
|
static constexpr bool UsingEventfd = false;
|
||||||
#endif
|
#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 <pipeDrv.h>
|
||||||
|
# include <selectLib.h>
|
||||||
|
# include <taskLib.h>
|
||||||
|
# include <rtpLib.h>
|
||||||
|
# include <sysLib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
@ -62,12 +70,12 @@ QThreadPipe::~QThreadPipe()
|
|||||||
if (!UsingEventfd && fds[1] >= 0)
|
if (!UsingEventfd && fds[1] >= 0)
|
||||||
close(fds[1]);
|
close(fds[1]);
|
||||||
|
|
||||||
#if defined(Q_OS_VXWORKS)
|
#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
|
||||||
pipeDevDelete(name, true);
|
pipeDevDelete(name, true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(Q_OS_VXWORKS)
|
#if defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
|
||||||
static void initThreadPipeFD(int fd)
|
static void initThreadPipeFD(int fd)
|
||||||
{
|
{
|
||||||
int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
|
int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
@ -88,20 +96,32 @@ bool QThreadPipe::init()
|
|||||||
{
|
{
|
||||||
#if defined(Q_OS_WASM)
|
#if defined(Q_OS_WASM)
|
||||||
// do nothing.
|
// do nothing.
|
||||||
#elif defined(Q_OS_VXWORKS)
|
#elif defined(Q_OS_VXWORKS) && QT_CONFIG(vxpipedrv)
|
||||||
std::snprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdSelf()));
|
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
|
// make sure there is no pipe with this name
|
||||||
pipeDevDelete(name, true);
|
pipeDevDelete(pipeName, true);
|
||||||
|
|
||||||
// create the pipe
|
// create the pipe
|
||||||
if (pipeDevCreate(name, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
|
if (pipeDevCreate(pipeName, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
|
||||||
perror("QThreadPipe: Unable to create thread pipe device");
|
qCritical("QThreadPipe: Unable to create thread pipe device %s : %s", name, std::strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fds[0] = open(name, O_RDWR, 0)) < 0) {
|
if ((fds[0] = open(pipeName, O_RDWR, 0)) < 0) {
|
||||||
perror("QThreadPipe: Unable to open pipe device");
|
qCritical("QThreadPipe: Unable to open pipe device %s : %s", name, std::strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +170,7 @@ int QThreadPipe::check(const pollfd &pfd)
|
|||||||
if (readyread) {
|
if (readyread) {
|
||||||
// consume the data on the thread pipe so that
|
// consume the data on the thread pipe so that
|
||||||
// poll doesn't immediately return next time
|
// 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));
|
::read(fds[0], c, sizeof(c));
|
||||||
::ioctl(fds[0], FIOFLUSH, 0);
|
::ioctl(fds[0], FIOFLUSH, 0);
|
||||||
#else
|
#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);
|
Q_ASSERT((flags & ~O_NONBLOCK) == 0);
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
#ifdef QT_THREADSAFE_CLOEXEC
|
#if QT_CONFIG(accept4)
|
||||||
// use accept4
|
// use accept4
|
||||||
int sockflags = SOCK_CLOEXEC;
|
int sockflags = SOCK_CLOEXEC;
|
||||||
if (flags & O_NONBLOCK)
|
if (flags & O_NONBLOCK)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user