summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorWater-Team <water@pad.test.qt.nokia.com>2011-06-29 21:42:03 (GMT)
committerWater-Team <water@pad.test.qt.nokia.com>2011-06-29 21:42:03 (GMT)
commit0a8daa8845325fba9cf2ec973eb6bab8a2853dd5 (patch)
tree504c698037ee6283f1b5dbc6fa658bb2bfffb99a /src/corelib
parent680023c4921019614948c277cde5498645836cb9 (diff)
parent6b3f2a3b96d01dc339d07a076300d29616603b28 (diff)
downloadQt-0a8daa8845325fba9cf2ec973eb6bab8a2853dd5.zip
Qt-0a8daa8845325fba9cf2ec973eb6bab8a2853dd5.tar.gz
Qt-0a8daa8845325fba9cf2ec973eb6bab8a2853dd5.tar.bz2
Merge branch '4.8-upstream' into master-water
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qglobal.cpp63
-rw-r--r--src/corelib/global/qglobal.h12
-rw-r--r--src/corelib/io/qbuffer.cpp17
-rw-r--r--src/corelib/io/qdatastream.cpp3
-rw-r--r--src/corelib/io/qfile.cpp2
-rw-r--r--src/corelib/io/qfilesystemengine.cpp2
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp11
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.cpp24
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents_p.h4
-rw-r--r--src/corelib/io/qfsfileengine.cpp2
-rw-r--r--src/corelib/io/qprocess.cpp10
-rw-r--r--src/corelib/io/qprocess_p.h8
-rw-r--r--src/corelib/io/qprocess_unix.cpp183
-rw-r--r--src/corelib/io/qurl.cpp2
-rw-r--r--src/corelib/kernel/qcore_mac.cpp79
-rw-r--r--src/corelib/kernel/qcore_mac_p.h10
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp39
-rw-r--r--src/corelib/kernel/qobject.cpp58
-rw-r--r--src/corelib/kernel/qobject.h5
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp5
-rw-r--r--src/corelib/kernel/qsharedmemory_p.h4
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp143
-rw-r--r--src/corelib/kernel/qsystemsemaphore.cpp7
-rw-r--r--src/corelib/kernel/qsystemsemaphore_p.h9
-rw-r--r--src/corelib/kernel/qsystemsemaphore_unix.cpp124
-rw-r--r--src/corelib/kernel/qtimer.cpp9
-rw-r--r--src/corelib/kernel/qtranslator.cpp8
-rw-r--r--src/corelib/thread/qmutexpool.cpp3
-rw-r--r--src/corelib/thread/qthread.cpp6
-rw-r--r--src/corelib/thread/qthread_p.h21
-rw-r--r--src/corelib/thread/qthread_unix.cpp5
-rw-r--r--src/corelib/tools/qlist.cpp4
-rw-r--r--src/corelib/tools/qlocale.cpp2
-rw-r--r--src/corelib/tools/qlocale.qdoc2
-rw-r--r--src/corelib/tools/qpoint.h2
-rw-r--r--src/corelib/tools/qscopedpointer.cpp5
-rw-r--r--src/corelib/tools/qscopedvaluerollback.cpp4
-rw-r--r--src/corelib/tools/qstring.cpp44
-rw-r--r--src/corelib/tools/qstring.h1
-rw-r--r--src/corelib/tools/qstringbuilder.cpp5
-rw-r--r--src/corelib/tools/qstringbuilder.h2
-rw-r--r--src/corelib/tools/qstringlist.cpp2
-rw-r--r--src/corelib/tools/qvarlengtharray.qdoc18
-rw-r--r--src/corelib/tools/qvector.cpp2
-rw-r--r--src/corelib/xml/qxmlstream.cpp5
45 files changed, 765 insertions, 211 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index c144871..84d68e5 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1648,64 +1648,13 @@ static const unsigned int qt_one = 1;
const int QSysInfo::ByteOrder = ((*((unsigned char *) &qt_one) == 0) ? BigEndian : LittleEndian);
#endif
-#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC)
+#if !defined(QWS) && defined(Q_OS_MAC)
QT_BEGIN_INCLUDE_NAMESPACE
#include "private/qcore_mac_p.h"
#include "qnamespace.h"
QT_END_INCLUDE_NAMESPACE
-Q_CORE_EXPORT OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref)
-{
- return FSPathMakeRef(reinterpret_cast<const UInt8 *>(file.toUtf8().constData()), fsref, 0);
-}
-
-// Don't use this function, it won't work in 10.5 (Leopard) and up
-Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &file, FSSpec *spec)
-{
- FSRef fsref;
- OSErr ret = qt_mac_create_fsref(file, &fsref);
- if (ret == noErr)
- ret = FSGetCatalogInfo(&fsref, kFSCatInfoNone, 0, 0, spec, 0);
- return ret;
-}
-
-Q_CORE_EXPORT void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1)
-{
- if(len == -1)
- len = s.length();
-#if 0
- UnicodeMapping mapping;
- mapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
- kTextEncodingDefaultVariant,
- kUnicode16BitFormat);
- mapping.otherEncoding = (encoding ? encoding : );
- mapping.mappingVersion = kUnicodeUseLatestMapping;
-
- UnicodeToTextInfo info;
- OSStatus err = CreateUnicodeToTextInfo(&mapping, &info);
- if(err != noErr) {
- qDebug("Qt: internal: Unable to create pascal string '%s'::%d [%ld]",
- s.left(len).latin1(), (int)encoding, err);
- return;
- }
- const int unilen = len * 2;
- const UniChar *unibuf = (UniChar *)s.unicode();
- ConvertFromUnicodeToPString(info, unilen, unibuf, str);
- DisposeUnicodeToTextInfo(&info);
-#else
- Q_UNUSED(encoding);
- CFStringGetPascalString(QCFString(s), str, 256, CFStringGetSystemEncoding());
-#endif
-}
-
-Q_CORE_EXPORT QString qt_mac_from_pascal_string(const Str255 pstr) {
- return QCFString(CFStringCreateWithPascalString(0, pstr, CFStringGetSystemEncoding()));
-}
-#endif //!defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC)
-
-#if !defined(QWS) && defined(Q_OS_MAC)
-
static QSysInfo::MacVersion macVersion()
{
#ifndef QT_NO_CORESERVICES
@@ -2105,7 +2054,7 @@ static void mac_default_handler(const char *msg)
{
if (qt_is_gui_used) {
Str255 pmsg;
- qt_mac_to_pascal_string(msg, pmsg);
+ qt_mac_to_pascal_string(QString::fromAscii(msg), pmsg);
DebugStr(pmsg);
} else {
fprintf(stderr, msg);
@@ -2883,8 +2832,8 @@ int qrand()
\relates <QtGlobal>
\since 4.8
- \brief Hints the compiler that the enclosed condition is likely to evaluate
- to \c true.
+ \brief Hints to the compiler that the enclosed condition, \a expr, is
+ likely to evaluate to \c true.
Use of this macro can help the compiler to optimize the code.
@@ -2900,8 +2849,8 @@ int qrand()
\relates <QtGlobal>
\since 4.8
- \brief Hints the compiler that the enclosed condition is likely to evaluate
- to \c false.
+ \brief Hints to the compiler that the enclosed condition, \a expr, is
+ likely to evaluate to \c false.
Use of this macro can help the compiler to optimize the code.
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 32b3e6b..1f5f537 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -173,7 +173,6 @@ namespace QT_NAMESPACE {}
RELIANT - Reliant UNIX
DYNIX - DYNIX/ptx
QNX - QNX
- QNX6 - QNX RTP 6.1
LYNX - LynxOS
BSD4 - Any BSD 4.4 system
UNIX - Any UNIX BSD/SYSV system
@@ -2746,17 +2745,6 @@ QT_LICENSED_MODULE(DBus)
# define QT_NO_CONCURRENT_FILTER
#endif
-#ifdef Q_OS_QNX
-// QNX doesn't have SYSV style shared memory. Multiprocess QWS apps,
-// shared fonts and QSystemSemaphore + QSharedMemory are not available
-# define QT_NO_QWS_MULTIPROCESS
-# define QT_NO_QWS_SHARE_FONTS
-# define QT_NO_SYSTEMSEMAPHORE
-# define QT_NO_SHAREDMEMORY
-// QNX currently doesn't support forking in a thread, so disable QProcess
-# define QT_NO_PROCESS
-#endif
-
#if defined (__ELF__)
# if defined (Q_OS_LINUX) || defined (Q_OS_SOLARIS) || defined (Q_OS_FREEBSD) || defined (Q_OS_OPENBSD) || defined (Q_OS_IRIX)
# define Q_OF_ELF
diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp
index 38e406b..35e7b68 100644
--- a/src/corelib/io/qbuffer.cpp
+++ b/src/corelib/io/qbuffer.cpp
@@ -333,23 +333,18 @@ bool QBuffer::open(OpenMode flags)
{
Q_D(QBuffer);
- if ((flags & Append) == Append)
+ if ((flags & (Append | Truncate)) != 0)
flags |= WriteOnly;
- setOpenMode(flags);
- if (!(isReadable() || isWritable())) {
- qWarning("QFile::open: File access not specified");
+ if ((flags & (ReadOnly | WriteOnly)) == 0) {
+ qWarning("QBuffer::open: Buffer access not specified");
return false;
}
- if ((flags & QIODevice::Truncate) == QIODevice::Truncate) {
+ if ((flags & Truncate) == Truncate)
d->buf->resize(0);
- }
- if ((flags & QIODevice::Append) == QIODevice::Append) // append to end of buffer
- seek(d->buf->size());
- else
- seek(0);
+ d->ioIndex = (flags & Append) == Append ? d->buf->size() : 0;
- return true;
+ return QIODevice::open(flags);
}
/*!
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index 8c27430..b397c1a 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -584,8 +584,9 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_4_3 Version 9 (Qt 4.3)
\value Qt_4_4 Version 10 (Qt 4.4)
\value Qt_4_5 Version 11 (Qt 4.5)
- \value Qt_4_6 Version 12 (Qt 4.6)
+ \value Qt_4_6 Version 12 (Qt 4.6, Qt 4.7, Qt 4.8)
\value Qt_4_7 Same as Qt_4_6.
+ \value Qt_4_8 Same as Qt_4_6.
\sa setVersion(), version()
*/
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 9d6641c..66edf58 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -1656,6 +1656,8 @@ bool QFile::atEnd() const
}
/*!
+ \fn bool QFile::seek(qint64 pos)
+
For random-access devices, this function sets the current position
to \a pos, returning true on success, or false if an error occurred.
For sequential devices, the default behavior is to do nothing and
diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp
index 9590e39..97669ac 100644
--- a/src/corelib/io/qfilesystemengine.cpp
+++ b/src/corelib/io/qfilesystemengine.cpp
@@ -196,7 +196,7 @@ static bool _q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry &ent
Resolves the \a entry (see QDir::searchPaths) and returns an engine for
it, but never a QFSFileEngine.
- \returns a file engine that can be used to access the entry. Returns 0 if
+ Returns a file engine that can be used to access the entry. Returns 0 if
QFileSystemEngine API should be used to query and interact with the file
system object.
*/
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index f1e0758..b0ebfbd 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -180,7 +180,8 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath()));
#else
char *ret = 0;
-# if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES)
+# if defined(Q_OS_MAC)
+# if !defined(QT_NO_CORESERVICES)
// Mac OS X 10.5.x doesn't support the realpath(X,0) extension we use here.
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
ret = realpath(entry.nativeFilePath().constData(), (char*)0);
@@ -197,9 +198,13 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
return QFileSystemEntry(ret);
}
}
-# else
+# else
+ ret = (char*)malloc(PATH_MAX);
+ realpath(entry.nativeFilePath().constData(), (char*)ret);
+# endif //!defined(QT_NO_CORESERVICES)
+# else
ret = realpath(entry.nativeFilePath().constData(), (char*)0);
-# endif
+# endif //defined(Q_OS_MAC)
if (ret) {
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
data.entryFlags |= QFileSystemMetaData::ExistsAttribute;
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.cpp b/src/corelib/io/qfilesystemwatcher_fsevents.cpp
index 6ae6e38..4ae7cf8 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.cpp
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.cpp
@@ -57,13 +57,15 @@
#include <sys/types.h>
#include <CoreFoundation/CFRunLoop.h>
#include <CoreFoundation/CFUUID.h>
+#if !defined( QT_NO_CORESERVICES )
#include <CoreServices/CoreServices.h>
+#endif
#include <AvailabilityMacros.h>
#include <private/qcore_mac_p.h>
QT_BEGIN_NAMESPACE
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
// Static operator overloading so for the sake of some convieniece.
// They only live in this compilation unit to avoid polluting Qt in general.
static bool operator==(const struct ::timespec &left, const struct ::timespec &right)
@@ -152,7 +154,7 @@ QFSEventsFileSystemWatcherEngine::QFSEventsFileSystemWatcherEngine()
QFSEventsFileSystemWatcherEngine::~QFSEventsFileSystemWatcherEngine()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
// I assume that at this point, QFileSystemWatcher has already called stop
// on me, so I don't need to invalidate or stop my stream, simply
// release it.
@@ -171,7 +173,7 @@ QStringList QFSEventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *files,
QStringList *directories)
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
stop();
wait();
QMutexLocker locker(&mutex);
@@ -257,7 +259,7 @@ QStringList QFSEventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
void QFSEventsFileSystemWatcherEngine::warmUpFSEvents()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
// This function assumes that the mutex has already been grabbed before calling it.
// It exits with the mutex still locked (Q_ASSERT(mutex.isLocked()) ;-).
start();
@@ -269,7 +271,7 @@ QStringList QFSEventsFileSystemWatcherEngine::removePaths(const QStringList &pat
QStringList *files,
QStringList *directories)
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
stop();
wait();
QMutexLocker locker(&mutex);
@@ -336,7 +338,7 @@ QStringList QFSEventsFileSystemWatcherEngine::removePaths(const QStringList &pat
#endif
}
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
void QFSEventsFileSystemWatcherEngine::updateList(PathInfoList &list, bool directory, bool emitSignals)
{
PathInfoList::iterator End = list.end();
@@ -396,7 +398,7 @@ void QFSEventsFileSystemWatcherEngine::fseventsCallback(ConstFSEventStreamRef ,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId [])
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
QFSEventsFileSystemWatcherEngine *watcher = static_cast<QFSEventsFileSystemWatcherEngine *>(clientCallBackInfo);
QMutexLocker locker(&watcher->mutex);
CFArrayRef paths = static_cast<CFArrayRef>(eventPaths);
@@ -431,7 +433,7 @@ void QFSEventsFileSystemWatcherEngine::fseventsCallback(ConstFSEventStreamRef ,
void QFSEventsFileSystemWatcherEngine::stop()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
QMutexLocker locker(&mutex);
stopFSStream(fsStream);
if (threadsRunLoop) {
@@ -443,13 +445,13 @@ void QFSEventsFileSystemWatcherEngine::stop()
void QFSEventsFileSystemWatcherEngine::updateFiles()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
QMutexLocker locker(&mutex);
updateHash(filePathInfoHash);
updateHash(dirPathInfoHash);
if (filePathInfoHash.isEmpty() && dirPathInfoHash.isEmpty()) {
// Everything disappeared before we got to start, don't bother.
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
// Code duplicated from stop(), with the exception that we
// don't wait on waitForStop here. Doing this will lead to
// a deadlock since this function is called from the worker
@@ -467,7 +469,7 @@ void QFSEventsFileSystemWatcherEngine::updateFiles()
void QFSEventsFileSystemWatcherEngine::run()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
threadsRunLoop = CFRunLoopGetCurrent();
FSEventStreamScheduleWithRunLoop(fsStream, threadsRunLoop, kCFRunLoopDefaultMode);
bool startedOK = FSEventStreamStart(fsStream);
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents_p.h b/src/corelib/io/qfilesystemwatcher_fsevents_p.h
index 2466a6e..515c32e 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents_p.h
+++ b/src/corelib/io/qfilesystemwatcher_fsevents_p.h
@@ -74,7 +74,7 @@ typedef uint64_t FSEventStreamEventId;
QT_BEGIN_NAMESPACE
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined(QT_NO_CORESERVICES)
// Yes, I use a stat64 element here. QFileInfo requires too much knowledge about implementation
// details to be used as a long-standing record. Since I'm going to have to store this information, I can
// do the stat myself too.
@@ -117,7 +117,7 @@ private:
QMutex mutex;
QWaitCondition waitCondition;
QWaitCondition waitForStop;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
PathHash filePathInfoHash;
PathHash dirPathInfoHash;
void updateHash(PathHash &pathHash);
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 4894754..0d23a27 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -472,10 +472,10 @@ qint64 QFSFileEngine::size() const
return d->nativeSize();
}
+#ifndef Q_OS_WIN
/*!
\internal
*/
-#ifndef Q_OS_WIN
qint64 QFSFileEnginePrivate::sizeFdFh() const
{
Q_Q(const QFSFileEngine);
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 70a70c2..4b689c5 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -751,12 +751,16 @@ QProcessPrivate::QProcessPrivate()
sequenceNumber = 0;
exitCode = 0;
exitStatus = QProcess::NormalExit;
+#ifndef Q_OS_QNX
startupSocketNotifier = 0;
+#endif
deathNotifier = 0;
notifier = 0;
pipeWriter = 0;
+#ifndef Q_OS_QNX
childStartedPipe[0] = INVALID_Q_PIPE;
childStartedPipe[1] = INVALID_Q_PIPE;
+#endif
deathPipe[0] = INVALID_Q_PIPE;
deathPipe[1] = INVALID_Q_PIPE;
exitCode = 0;
@@ -825,11 +829,13 @@ void QProcessPrivate::cleanup()
qDeleteInEventHandler(stdinChannel.notifier);
stdinChannel.notifier = 0;
}
+#ifndef Q_OS_QNX
if (startupSocketNotifier) {
startupSocketNotifier->setEnabled(false);
qDeleteInEventHandler(startupSocketNotifier);
startupSocketNotifier = 0;
}
+#endif
if (deathNotifier) {
deathNotifier->setEnabled(false);
qDeleteInEventHandler(deathNotifier);
@@ -842,7 +848,9 @@ void QProcessPrivate::cleanup()
destroyPipe(stdoutChannel.pipe);
destroyPipe(stderrChannel.pipe);
destroyPipe(stdinChannel.pipe);
+#ifndef Q_OS_QNX
destroyPipe(childStartedPipe);
+#endif
destroyPipe(deathPipe);
#ifdef Q_OS_UNIX
serial = 0;
@@ -1077,8 +1085,10 @@ bool QProcessPrivate::_q_startupNotification()
qDebug("QProcessPrivate::startupNotification()");
#endif
+#ifndef Q_OS_QNX
if (startupSocketNotifier)
startupSocketNotifier->setEnabled(false);
+#endif
if (processStarted()) {
q->setProcessState(QProcess::Running);
emit q->started();
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 9adb331..f24a7bc 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -288,11 +288,15 @@ public:
QRingBuffer errorReadBuffer;
QRingBuffer writeBuffer;
+#ifndef Q_OS_QNX
Q_PIPE childStartedPipe[2];
+#endif
Q_PIPE deathPipe[2];
void destroyPipe(Q_PIPE pipe[2]);
+#ifndef Q_OS_QNX
QSocketNotifier *startupSocketNotifier;
+#endif
QSocketNotifier *deathNotifier;
// the wonderful windows notifier
@@ -301,8 +305,10 @@ public:
QWinEventNotifier *processFinishedNotifier;
void startProcess();
-#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) && !defined(Q_OS_QNX)
void execChild(const char *workingDirectory, char **path, char **argv, char **envp);
+#elif defined(Q_OS_QNX)
+ pid_t spawnChild(const char *workingDirectory, char **argv, char **envp);
#endif
bool processStarted();
void terminateProcess();
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 07e3087..725e4c5 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -105,6 +105,10 @@ QT_END_NAMESPACE
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#ifdef Q_OS_QNX
+# include <spawn.h>
+#endif
+
QT_BEGIN_NAMESPACE
@@ -521,16 +525,6 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm
return envp;
}
-// under QNX RTOS we have to use vfork() when multithreading
-inline pid_t qt_fork()
-{
-#if defined(Q_OS_QNX)
- return vfork();
-#else
- return fork();
-#endif
-}
-
#ifdef Q_OS_MAC
Q_GLOBAL_STATIC(QMutex, cfbundleMutex);
#endif
@@ -550,15 +544,18 @@ void QProcessPrivate::startProcess()
!createChannel(stdoutChannel) ||
!createChannel(stderrChannel))
return;
+#if !defined(Q_OS_QNX)
qt_create_pipe(childStartedPipe);
+#endif
qt_create_pipe(deathPipe);
if (threadData->eventDispatcher) {
+#if !defined(Q_OS_QNX)
startupSocketNotifier = new QSocketNotifier(childStartedPipe[0],
QSocketNotifier::Read, q);
QObject::connect(startupSocketNotifier, SIGNAL(activated(int)),
q, SLOT(_q_startupNotification()));
-
+#endif
deathNotifier = new QSocketNotifier(deathPipe[0],
QSocketNotifier::Read, q);
QObject::connect(deathNotifier, SIGNAL(activated(int)),
@@ -650,7 +647,11 @@ void QProcessPrivate::startProcess()
// Start the process manager, and fork off the child process.
processManager()->lock();
- pid_t childPid = qt_fork();
+#if defined(Q_OS_QNX)
+ pid_t childPid = spawnChild(workingDirPtr, argv, envp);
+#else
+ pid_t childPid = fork();
+#endif
int lastForkErrno = errno;
if (childPid != 0) {
// Clean up duplicated memory.
@@ -668,7 +669,7 @@ void QProcessPrivate::startProcess()
if (childPid < 0) {
// Cleanup, report error and return
#if defined (QPROCESS_DEBUG)
- qDebug("qt_fork failed: %s", qPrintable(qt_error_string(lastForkErrno)));
+ qDebug("fork() failed: %s", qPrintable(qt_error_string(lastForkErrno)));
#endif
processManager()->unlock();
q->setProcessState(QProcess::NotRunning);
@@ -679,11 +680,13 @@ void QProcessPrivate::startProcess()
return;
}
+#if !defined(Q_OS_QNX)
// Start the child.
if (childPid == 0) {
execChild(workingDirPtr, path, argv, envp);
::_exit(-1);
}
+#endif
// Register the child. In the mean time, we can get a SIGCHLD, so we need
// to keep the lock held to avoid a race to catch the child.
@@ -694,14 +697,15 @@ void QProcessPrivate::startProcess()
// parent
// close the ends we don't use and make all pipes non-blocking
::fcntl(deathPipe[0], F_SETFL, ::fcntl(deathPipe[0], F_GETFL) | O_NONBLOCK);
+#if !defined(Q_OS_QNX)
qt_safe_close(childStartedPipe[1]);
childStartedPipe[1] = -1;
+#endif
if (stdinChannel.pipe[0] != -1) {
qt_safe_close(stdinChannel.pipe[0]);
stdinChannel.pipe[0] = -1;
}
-
if (stdinChannel.pipe[1] != -1)
::fcntl(stdinChannel.pipe[1], F_SETFL, ::fcntl(stdinChannel.pipe[1], F_GETFL) | O_NONBLOCK);
@@ -709,7 +713,6 @@ void QProcessPrivate::startProcess()
qt_safe_close(stdoutChannel.pipe[1]);
stdoutChannel.pipe[1] = -1;
}
-
if (stdoutChannel.pipe[0] != -1)
::fcntl(stdoutChannel.pipe[0], F_SETFL, ::fcntl(stdoutChannel.pipe[0], F_GETFL) | O_NONBLOCK);
@@ -721,6 +724,7 @@ void QProcessPrivate::startProcess()
::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK);
}
+#if !defined(Q_OS_QNX)
void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv, char **envp)
{
::signal(SIGPIPE, SIG_DFL); // reset the signal that we ignored
@@ -728,17 +732,17 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
Q_Q(QProcess);
// copy the stdin socket (without closing on exec)
- qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0);
+ qt_safe_dup2(stdinChannel.pipe[0], QT_FILENO(stdin), 0);
// copy the stdout and stderr if asked to
if (processChannelMode != QProcess::ForwardedChannels) {
- qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0);
+ qt_safe_dup2(stdoutChannel.pipe[1], QT_FILENO(stdout), 0);
// merge stdout and stderr if asked to
if (processChannelMode == QProcess::MergedChannels) {
- qt_safe_dup2(fileno(stdout), fileno(stderr), 0);
+ qt_safe_dup2(QT_FILENO(stdout), QT_FILENO(stderr), 0);
} else {
- qt_safe_dup2(stderrChannel.pipe[1], fileno(stderr), 0);
+ qt_safe_dup2(stderrChannel.pipe[1], QT_FILENO(stderr), 0);
}
}
@@ -807,6 +811,87 @@ bool QProcessPrivate::processStarted()
return i <= 0;
}
+#else // Q_OS_QNX
+
+static pid_t doSpawn(int fd_count, int fd_map[], char **argv, char **envp, bool spawn_detached)
+{
+ // A multi threaded QNX Process can't fork so we call spawn() instead.
+
+ struct inheritance inherit;
+ memset(&inherit, 0, sizeof(inherit));
+ inherit.flags |= SPAWN_SETSID;
+ inherit.flags |= SPAWN_CHECK_SCRIPT;
+ if (spawn_detached)
+ inherit.flags |= SPAWN_NOZOMBIE;
+ inherit.flags |= SPAWN_SETSIGDEF;
+ sigaddset(&inherit.sigdefault, SIGPIPE); // reset the signal that we ignored
+
+ pid_t childPid;
+ EINTR_LOOP(childPid, ::spawn(argv[0], fd_count, fd_map, &inherit, argv, envp));
+ if (childPid == -1) {
+ inherit.flags |= SPAWN_SEARCH_PATH;
+ EINTR_LOOP(childPid, ::spawn(argv[0], fd_count, fd_map, &inherit, argv, envp));
+ }
+
+ return childPid;
+}
+
+pid_t QProcessPrivate::spawnChild(const char *workingDir, char **argv, char **envp)
+{
+ Q_Q(QProcess);
+
+ const int fd_count = 3;
+ int fd_map[fd_count];
+ switch (processChannelMode) {
+ case QProcess::ForwardedChannels:
+ fd_map[0] = stdinChannel.pipe[0];
+ fd_map[1] = QT_FILENO(stdout);
+ fd_map[2] = QT_FILENO(stderr);
+ break;
+ case QProcess::MergedChannels:
+ fd_map[0] = stdinChannel.pipe[0];
+ fd_map[1] = stdoutChannel.pipe[1];
+ fd_map[2] = stdoutChannel.pipe[1];
+ break;
+ case QProcess::SeparateChannels:
+ fd_map[0] = stdinChannel.pipe[0];
+ fd_map[1] = stdoutChannel.pipe[1];
+ fd_map[2] = stderrChannel.pipe[1];
+ break;
+ }
+
+ // enter the working directory
+ char *oldWorkingDir = 0;
+ char buff[PATH_MAX + 1];
+ if (workingDir) {
+ oldWorkingDir = QT_GETCWD(buff, PATH_MAX + 1);
+ QT_CHDIR(workingDir);
+ }
+
+ pid_t childPid = doSpawn(fd_count, fd_map, argv, envp, false);
+
+ if (oldWorkingDir)
+ QT_CHDIR(oldWorkingDir);
+
+ if (childPid != -1) {
+ q->setProcessState(QProcess::Running);
+ QMetaObject::invokeMethod(q, "_q_startupNotification", Qt::QueuedConnection);
+ }
+
+ return childPid;
+}
+
+bool QProcessPrivate::processStarted()
+{
+ return processState == QProcess::Running;
+}
+
+bool QProcessPrivate::waitForStarted(int /*msecs*/)
+{
+ return processStarted();
+}
+#endif // Q_OS_QNX
+
qint64 QProcessPrivate::bytesAvailableFromStdout() const
{
int nbytes = 0;
@@ -924,6 +1009,7 @@ static int qt_timeout_value(int msecs, int elapsed)
return timeout < 0 ? 0 : timeout;
}
+#if !defined(Q_OS_QNX)
bool QProcessPrivate::waitForStarted(int msecs)
{
Q_Q(QProcess);
@@ -951,6 +1037,7 @@ bool QProcessPrivate::waitForStarted(int msecs)
#endif
return startedEmitted;
}
+#endif // Q_OS_QNX
bool QProcessPrivate::waitForReadyRead(int msecs)
{
@@ -972,8 +1059,10 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
int nfds = deathPipe[0];
FD_SET(deathPipe[0], &fdread);
+#if !defined(Q_OS_QNX)
if (processState == QProcess::Starting)
add_fd(nfds, childStartedPipe[0], &fdread);
+#endif
if (stdoutChannel.pipe[0] != -1)
add_fd(nfds, stdoutChannel.pipe[0], &fdread);
@@ -994,10 +1083,12 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
return false;
}
+#if !defined(Q_OS_QNX)
if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
if (!_q_startupNotification())
return false;
}
+#endif
bool readyReadEmitted = false;
if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) {
@@ -1044,8 +1135,10 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
int nfds = deathPipe[0];
FD_SET(deathPipe[0], &fdread);
+#if !defined(Q_OS_QNX)
if (processState == QProcess::Starting)
add_fd(nfds, childStartedPipe[0], &fdread);
+#endif
if (stdoutChannel.pipe[0] != -1)
add_fd(nfds, stdoutChannel.pipe[0], &fdread);
@@ -1068,10 +1161,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
return false;
}
+#if !defined(Q_OS_QNX)
if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
if (!_q_startupNotification())
return false;
}
+#endif
if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
return _q_canWrite();
@@ -1109,8 +1204,10 @@ bool QProcessPrivate::waitForFinished(int msecs)
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
+#if !defined(Q_OS_QNX)
if (processState == QProcess::Starting)
add_fd(nfds, childStartedPipe[0], &fdread);
+#endif
if (stdoutChannel.pipe[0] != -1)
add_fd(nfds, stdoutChannel.pipe[0], &fdread);
@@ -1134,10 +1231,12 @@ bool QProcessPrivate::waitForFinished(int msecs)
return false;
}
+#if !defined(Q_OS_QNX)
if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
if (!_q_startupNotification())
return false;
}
+#endif
if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
_q_canWrite();
@@ -1199,6 +1298,47 @@ void QProcessPrivate::_q_notified()
{
}
+#if defined(Q_OS_QNX)
+bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
+{
+ QByteArray encodedWorkingDirectory = QFile::encodeName(workingDirectory);
+
+ // enter the working directory
+ char *oldWorkingDir = 0;
+ char buff[PATH_MAX + 1];
+ if (!encodedWorkingDirectory.isEmpty()) {
+ oldWorkingDir = QT_GETCWD(buff, PATH_MAX + 1);
+ QT_CHDIR(encodedWorkingDirectory.constData());
+ }
+
+ const int fd_count = 3;
+ int fd_map[fd_count] = { QT_FILENO(stdin), QT_FILENO(stdout), QT_FILENO(stderr) };
+
+ QList<QByteArray> enc_args;
+ enc_args.append(QFile::encodeName(program));
+ for (int i = 0; i < arguments.size(); ++i)
+ enc_args.append(arguments.at(i).toLocal8Bit());
+
+ const int argc = enc_args.size();
+ QScopedArrayPointer<char*> raw_argv(new char*[argc + 1]);
+ for (int i = 0; i < argc; ++i)
+ raw_argv[i] = const_cast<char *>(enc_args.at(i).data());
+ raw_argv[argc] = 0;
+
+ char **envp = 0; // inherit environment
+
+ pid_t childPid = doSpawn(fd_count, fd_map, raw_argv.data(), envp, true);
+ if (pid && childPid != -1)
+ *pid = childPid;
+
+ if (oldWorkingDir)
+ QT_CHDIR(oldWorkingDir);
+
+ return childPid != -1;
+}
+
+#else
+
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
{
processManager()->start();
@@ -1212,7 +1352,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
int pidPipe[2];
qt_safe_pipe(pidPipe);
- pid_t childPid = qt_fork();
+ pid_t childPid = fork();
if (childPid == 0) {
struct sigaction noaction;
memset(&noaction, 0, sizeof(noaction));
@@ -1224,7 +1364,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
qt_safe_close(startedPipe[0]);
qt_safe_close(pidPipe[0]);
- pid_t doubleForkPid = qt_fork();
+ pid_t doubleForkPid = fork();
if (doubleForkPid == 0) {
qt_safe_close(pidPipe[1]);
@@ -1312,6 +1452,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
qt_safe_close(pidPipe[0]);
return success;
}
+#endif // Q_OS_QNX
void QProcessPrivate::initializeProcessManager()
{
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 83b49ce..8813656 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -6105,7 +6105,7 @@ bool QUrl::isDetached() const
"//servername/path/to/file.txt". Note that only certain platforms can
actually open this file using QFile::open().
- \sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators
+ \sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators()
*/
QUrl QUrl::fromLocalFile(const QString &localFile)
{
diff --git a/src/corelib/kernel/qcore_mac.cpp b/src/corelib/kernel/qcore_mac.cpp
index 0814c1a..490031f 100644
--- a/src/corelib/kernel/qcore_mac.cpp
+++ b/src/corelib/kernel/qcore_mac.cpp
@@ -41,22 +41,22 @@
#include <private/qcore_mac_p.h>
#include <new>
-#include "qvarlengtharray.h"
QT_BEGIN_NAMESPACE
QString QCFString::toQString(CFStringRef str)
{
- if(!str)
+ if (!str)
return QString();
+
CFIndex length = CFStringGetLength(str);
- const UniChar *chars = CFStringGetCharactersPtr(str);
- if (chars)
- return QString(reinterpret_cast<const QChar *>(chars), length);
+ if (length == 0)
+ return QString();
+
+ QString string(length, Qt::Uninitialized);
+ CFStringGetCharacters(str, CFRangeMake(0, length), reinterpret_cast<UniChar *>(const_cast<QChar *>(string.unicode())));
- QVarLengthArray<UniChar> buffer(length);
- CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
- return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
+ return string;
}
QCFString::operator QString() const
@@ -74,9 +74,68 @@ CFStringRef QCFString::toCFStringRef(const QString &string)
QCFString::operator CFStringRef() const
{
- if (!type)
- const_cast<QCFString*>(this)->type = toCFStringRef(string);
+ if (!type) {
+ if (string.d->data != string.d->array)
+ const_cast<QCFString*>(this)->string.realloc(); // ### Qt5: do we really need this stupid user protection?
+ const_cast<QCFString*>(this)->type =
+ CFStringCreateWithCharactersNoCopy(0,
+ reinterpret_cast<const UniChar *>(string.unicode()),
+ string.length(),
+ kCFAllocatorNull);
+ }
return type;
}
+
+#ifndef QT_NO_CORESERVICES
+void qt_mac_to_pascal_string(const QString &s, Str255 str, TextEncoding encoding, int len)
+{
+ if(len == -1)
+ len = s.length();
+#if 0
+ UnicodeMapping mapping;
+ mapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kTextEncodingDefaultVariant,
+ kUnicode16BitFormat);
+ mapping.otherEncoding = (encoding ? encoding : );
+ mapping.mappingVersion = kUnicodeUseLatestMapping;
+
+ UnicodeToTextInfo info;
+ OSStatus err = CreateUnicodeToTextInfo(&mapping, &info);
+ if(err != noErr) {
+ qDebug("Qt: internal: Unable to create pascal string '%s'::%d [%ld]",
+ s.left(len).latin1(), (int)encoding, err);
+ return;
+ }
+ const int unilen = len * 2;
+ const UniChar *unibuf = (UniChar *)s.unicode();
+ ConvertFromUnicodeToPString(info, unilen, unibuf, str);
+ DisposeUnicodeToTextInfo(&info);
+#else
+ Q_UNUSED(encoding);
+ CFStringGetPascalString(QCFString(s), str, 256, CFStringGetSystemEncoding());
+#endif
+}
+
+QString qt_mac_from_pascal_string(const Str255 pstr)
+{
+ return QCFString(CFStringCreateWithPascalString(0, pstr, CFStringGetSystemEncoding()));
+}
+
+OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref)
+{
+ return FSPathMakeRef(reinterpret_cast<const UInt8 *>(file.toUtf8().constData()), fsref, 0);
+}
+
+// Don't use this function, it won't work in 10.5 (Leopard) and up
+OSErr qt_mac_create_fsspec(const QString &file, FSSpec *spec)
+{
+ FSRef fsref;
+ OSErr ret = qt_mac_create_fsref(file, &fsref);
+ if (ret == noErr)
+ ret = FSGetCatalogInfo(&fsref, kFSCatInfoNone, 0, 0, spec, 0);
+ return ret;
+}
+#endif // QT_NO_CORESERVICES
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index adbad83..df269ec 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -148,6 +148,16 @@ private:
QString string;
};
+
+#ifndef QT_NO_CORESERVICES
+Q_CORE_EXPORT void qt_mac_to_pascal_string(const QString &s, Str255 str, TextEncoding encoding = 0, int len = -1);
+Q_CORE_EXPORT QString qt_mac_from_pascal_string(const Str255 pstr);
+
+Q_CORE_EXPORT OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref);
+// Don't use this function, it won't work in 10.5 (Leopard) and up
+Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &file, FSSpec *spec);
+#endif // QT_NO_CORESERVICES
+
QT_END_NAMESPACE
#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 7694a0f..18a5eae 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -98,6 +98,12 @@
# include <taskLib.h>
#endif
+#ifdef Q_OS_QNX
+# include <sys/neutrino.h>
+# include <pthread.h>
+# include <sched.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QMutexUnlocker
@@ -353,6 +359,22 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
qt_application_thread_id = QThread::currentThreadId();
#endif
+#ifdef Q_OS_QNX
+ // make the kernel attempt to emulate an instruction with a misaligned access
+ // if the attempt fails, it faults with a SIGBUS
+ int tv = -1;
+ ThreadCtl(_NTO_TCTL_ALIGN_FAULT, &tv);
+
+ // without Round Robin drawn intensive apps will hog the cpu
+ // and make the system appear frozen
+ int sched_policy;
+ sched_param param;
+ if (pthread_getschedparam(0, &sched_policy, &param) == 0 && sched_policy != SCHED_RR) {
+ sched_policy = SCHED_RR;
+ pthread_setschedparam(0, sched_policy, &param);
+ }
+#endif
+
// note: this call to QThread::currentThread() may end up setting theMainThread!
if (QThread::currentThread() != theMainThread)
qWarning("WARNING: QApplication was not created in the main() thread.");
@@ -1266,20 +1288,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
// delete the event on exceptions to protect against memory leaks till the event is
// properly owned in the postEventList
QScopedPointer<QEvent> eventDeleter(event);
- if (data->postEventList.isEmpty() || data->postEventList.last().priority >= priority) {
- // optimization: we can simply append if the last event in
- // the queue has higher or equal priority
- data->postEventList.append(QPostEvent(receiver, event, priority));
- } else {
- // insert event in descending priority order, using upper
- // bound for a given priority (to ensure proper ordering
- // of events with the same priority)
- QPostEventList::iterator begin = data->postEventList.begin()
- + data->postEventList.insertionOffset,
- end = data->postEventList.end();
- QPostEventList::iterator at = qUpperBound(begin, end, priority);
- data->postEventList.insert(at, QPostEvent(receiver, event, priority));
- }
+ data->postEventList.addEvent(QPostEvent(receiver, event, priority));
eventDeleter.take();
event->posted = true;
++receiver->d_func()->postedEvents;
@@ -1439,7 +1448,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
// cannot send deferred delete
if (!event_type && !receiver) {
// don't lose the event
- data->postEventList.append(pe);
+ data->postEventList.addEvent(pe);
const_cast<QPostEvent &>(pe).event = 0;
}
continue;
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index a4948c1..88618c3 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1482,7 +1482,7 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
continue;
if (pe.receiver == q) {
// move this post event to the targetList
- targetData->postEventList.append(pe);
+ targetData->postEventList.addEvent(pe);
const_cast<QPostEvent &>(pe).event = 0;
++eventsMoved;
}
@@ -1790,6 +1790,7 @@ QObjectList QObject::queryList(const char *inheritsClass,
/*!
\fn T qFindChild(const QObject *obj, const QString &name)
\relates QObject
+ \overload qFindChildren()
\obsolete
This function is equivalent to
@@ -1805,6 +1806,7 @@ QObjectList QObject::queryList(const char *inheritsClass,
/*!
\fn QList<T> qFindChildren(const QObject *obj, const QString &name)
\relates QObject
+ \overload qFindChildren()
\obsolete
This function is equivalent to
@@ -1834,38 +1836,6 @@ QObjectList QObject::queryList(const char *inheritsClass,
/*!
\internal
- \fn T qFindChild(const QObject *obj, const QString &name = QString(), T dummy = 0)
- \relates QObject
- \overload qFindChildren()
-
- This function is equivalent to
- \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name).
-
- \note This function was provided as a workaround for MSVC 6
- which did not support member template functions. It is advised
- to use the other form in new code.
-
- \sa QObject::findChild()
-*/
-
-/*!
- \internal
- \fn QList<T> qFindChildren(const QObject *obj, const QString &name = QString(), T dummy = 0)
- \relates QObject
- \overload qFindChildren()
-
- This function is equivalent to
- \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name).
-
- \note This function was provided as a workaround for MSVC 6
- which did not support member template functions. It is advised
- to use the other form in new code.
-
- \sa QObject::findChildren()
-*/
-
-/*!
- \internal
*/
void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
const QMetaObject &mo, QList<void*> *list)
@@ -2419,20 +2389,22 @@ int QObject::receivers(const char *signal) const
This helper function calculates signal and method index for the given
member in the specified class.
- \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
+ \list
+ \o If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
- \li If specified member is not a member of obj instance class (or one of
+ \o If specified member is not a member of obj instance class (or one of
its parent classes) then both signalIndex and methodIndex are set to -1.
+ \endlist
This function is used by QObject::connect and QObject::disconnect which
are working with QMetaMethod.
- \param[out] signalIndex is set to the signal index of member. If the member
+ \a signalIndex is set to the signal index of member. If the member
specified is not signal this variable is set to -1.
- \param[out] methodIndex is set to the method index of the member. If the
- member is not a method of the object specified by obj param this variable
- is set to -1.
+ \a methodIndex is set to the method index of the member. If the
+ member is not a method of the object specified by the \a obj argument this
+ variable is set to -1.
*/
void QMetaObjectPrivate::memberIndexes(const QObject *obj,
const QMetaMethod &member,
@@ -2689,9 +2661,9 @@ bool QObject::connect(const QObject *sender, const char *signal,
Qt::ConnectionType type)
but it uses QMetaMethod to specify signal and method.
- \see connect(const QObject *sender, const char *signal,
- const QObject *receiver, const char *method,
- Qt::ConnectionType type)
+ \sa connect(const QObject *sender, const char *signal,
+ const QObject *receiver, const char *method,
+ Qt::ConnectionType type)
*/
bool QObject::connect(const QObject *sender, const QMetaMethod &signal,
const QObject *receiver, const QMetaMethod &method,
@@ -2987,7 +2959,7 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
method shoud also be QMetaMethod(). \a sender parameter should be never 0.
- \see disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
+ \sa disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
*/
bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
const QObject *receiver, const QMetaMethod &method)
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index d274fa3..15d81b9 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -345,6 +345,11 @@ public:
};
#endif
+#ifdef qdoc
+T qFindChild(const QObject *o, const QString &name = QString());
+QList<T> qFindChildren(const QObject *oobj, const QString &name = QString());
+QList<T> qFindChildren(const QObject *o, const QRegExp &re);
+#endif
#ifdef QT_DEPRECATED
template<typename T>
inline QT_DEPRECATED T qFindChild(const QObject *o, const QString &name = QString())
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index 2882279..371974c 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -80,6 +80,8 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
return result;
#elif defined(Q_OS_SYMBIAN)
return result.left(KMaxKernelName);
+#elif defined(QT_POSIX_IPC)
+ return QLatin1Char('/') + result;
#else
return QDir::tempPath() + QLatin1Char('/') + result;
#endif
@@ -117,6 +119,9 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
process crashes without running the QSharedMemory destructor, the
shared memory segment survives the crash.
+ \o QNX: Due to possible race conditions in the POSIX IPC implementation, create()
+ should be called prior to any attach() calls (even across multiple threads).
+
\o HP-UX: Only one attach to a shared memory segment is allowed per
process. This means that QSharedMemory should not be used across
multiple threads in the same process in HP-UX.
diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h
index 21b8612..780e52e 100644
--- a/src/corelib/kernel/qsharedmemory_p.h
+++ b/src/corelib/kernel/qsharedmemory_p.h
@@ -135,6 +135,8 @@ public:
const QString &prefix = QLatin1String("qipc_sharedmemory_"));
#ifdef Q_OS_WIN
HANDLE handle();
+#elif defined(QT_POSIX_IPC)
+ int handle();
#else
key_t handle();
#endif
@@ -166,6 +168,8 @@ private:
HANDLE hand;
#elif defined(Q_OS_SYMBIAN)
RChunk chunk;
+#elif defined(QT_POSIX_IPC)
+ int hand;
#else
key_t unix_key;
#endif
diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp
index e991ce9..a086acd 100644
--- a/src/corelib/kernel/qsharedmemory_unix.cpp
+++ b/src/corelib/kernel/qsharedmemory_unix.cpp
@@ -50,8 +50,12 @@
#ifndef QT_NO_SHAREDMEMORY
#include <sys/types.h>
#include <sys/ipc.h>
+#ifndef QT_POSIX_IPC
#include <sys/shm.h>
+#else
+#include <sys/mman.h>
#include <sys/stat.h>
+#endif
#include <fcntl.h>
#include <unistd.h>
#endif // QT_NO_SHAREDMEMORY
@@ -70,7 +74,11 @@ QSharedMemoryPrivate::QSharedMemoryPrivate()
#ifndef QT_NO_SYSTEMSEMAPHORE
systemSemaphore(QString()), lockedByMe(false),
#endif
+#ifndef QT_POSIX_IPC
unix_key(0)
+#else
+ hand(0)
+#endif
{
}
@@ -91,12 +99,18 @@ void QSharedMemoryPrivate::setErrorString(const QString &function)
errorString = QSharedMemory::tr("%1: doesn't exist").arg(function);
error = QSharedMemory::NotFound;
break;
+ case EAGAIN:
case EMFILE:
+ case ENFILE:
case ENOMEM:
case ENOSPC:
errorString = QSharedMemory::tr("%1: out of resources").arg(function);
error = QSharedMemory::OutOfResources;
break;
+ case EOVERFLOW:
+ errorString = QSharedMemory::tr("%1: invalid size").arg(function);
+ error = QSharedMemory::InvalidSize;
+ break;
default:
errorString = QSharedMemory::tr("%1: unknown error %2").arg(function).arg(errno);
error = QSharedMemory::UnknownError;
@@ -112,6 +126,7 @@ void QSharedMemoryPrivate::setErrorString(const QString &function)
If not already made create the handle used for accessing the shared memory.
*/
+#ifndef QT_POSIX_IPC
key_t QSharedMemoryPrivate::handle()
{
// already made
@@ -140,6 +155,20 @@ key_t QSharedMemoryPrivate::handle()
}
return unix_key;
}
+#else
+int QSharedMemoryPrivate::handle()
+{
+ // don't allow making handles on empty keys
+ QString safeKey = makePlatformSafeKey(key);
+ if (safeKey.isEmpty()) {
+ errorString = QSharedMemory::tr("%1: key is empty").arg(QLatin1String("QSharedMemory::handle"));
+ error = QSharedMemory::KeyError;
+ return 0;
+ }
+
+ return 1;
+}
+#endif // QT_POSIX_IPC
#endif // QT_NO_SHAREDMEMORY
@@ -155,6 +184,7 @@ key_t QSharedMemoryPrivate::handle()
*/
int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName)
{
+#ifndef QT_POSIX_IPC
if (QFile::exists(fileName))
return 0;
@@ -168,6 +198,11 @@ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName)
qt_safe_close(fd);
}
return 1;
+#else
+ Q_UNUSED(fileName);
+ // nothing to do
+ return -1;
+#endif
}
#endif // QT_NO_SHAREDMEMORY && QT_NO_SYSTEMSEMAPHORE
@@ -175,11 +210,17 @@ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName)
void QSharedMemoryPrivate::cleanHandle()
{
+#ifndef QT_POSIX_IPC
unix_key = 0;
+#else
+ qt_safe_close(hand);
+ hand = 0;
+#endif
}
bool QSharedMemoryPrivate::create(int size)
{
+#ifndef QT_POSIX_IPC
// build file if needed
int built = createUnixKeyFile(nativeKey);
if (built == -1) {
@@ -211,12 +252,46 @@ bool QSharedMemoryPrivate::create(int size)
QFile::remove(nativeKey);
return false;
}
+#else
+ if (!handle())
+ return false;
+
+ QByteArray shmName = QFile::encodeName(makePlatformSafeKey(key));
+
+ int fd;
+ EINTR_LOOP(fd, shm_open(shmName.constData(), O_RDWR | O_CREAT | O_EXCL, 0666));
+ if (fd == -1) {
+ QString function = QLatin1String("QSharedMemory::create");
+ switch (errno) {
+ case ENAMETOOLONG:
+ case EINVAL:
+ errorString = QSharedMemory::tr("%1: bad name").arg(function);
+ error = QSharedMemory::KeyError;
+ break;
+ default:
+ setErrorString(function);
+ }
+ return false;
+ }
+
+ // the size may only be set once; ignore errors
+ int ret;
+ EINTR_LOOP(ret, ftruncate(fd, size));
+ if (ret == -1) {
+ setErrorString(QLatin1String("QSharedMemory::create (ftruncate)"));
+ qt_safe_close(fd);
+ return false;
+ }
+
+ qt_safe_close(fd);
+#endif // QT_POSIX_IPC
return true;
}
bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode)
{
+#ifndef QT_POSIX_IPC
// grab the shared memory segment id
int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0444 : 0660));
if (-1 == id) {
@@ -240,12 +315,55 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode)
setErrorString(QLatin1String("QSharedMemory::attach (shmctl)"));
return false;
}
+#else
+ QByteArray shmName = QFile::encodeName(makePlatformSafeKey(key));
+
+ int oflag = (mode == QSharedMemory::ReadOnly ? O_RDONLY : O_RDWR);
+ mode_t omode = (mode == QSharedMemory::ReadOnly ? 0444 : 0660);
+
+ EINTR_LOOP(hand, shm_open(shmName.constData(), oflag, omode));
+ if (hand == -1) {
+ QString function = QLatin1String("QSharedMemory::attach (shm_open)");
+ switch (errno) {
+ case ENAMETOOLONG:
+ case EINVAL:
+ errorString = QSharedMemory::tr("%1: bad name").arg(function);
+ error = QSharedMemory::KeyError;
+ break;
+ default:
+ setErrorString(function);
+ }
+ hand = 0;
+ return false;
+ }
+
+ // grab the size
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) == -1) {
+ setErrorString(QLatin1String("QSharedMemory::attach (fstat)"));
+ cleanHandle();
+ return false;
+ }
+ size = st.st_size;
+
+ // grab the memory
+ int mprot = (mode == QSharedMemory::ReadOnly ? PROT_READ : PROT_READ | PROT_WRITE);
+ memory = mmap(0, size, mprot, MAP_SHARED, hand, 0);
+ if (memory == MAP_FAILED || !memory) {
+ setErrorString(QLatin1String("QSharedMemory::attach (mmap)"));
+ cleanHandle();
+ memory = 0;
+ size = 0;
+ return false;
+ }
+#endif // QT_POSIX_IPC
return true;
}
bool QSharedMemoryPrivate::detach()
{
+#ifndef QT_POSIX_IPC
// detach from the memory segment
if (-1 == shmdt(memory)) {
QString function = QLatin1String("QSharedMemory::detach");
@@ -292,6 +410,31 @@ bool QSharedMemoryPrivate::detach()
if (!QFile::remove(nativeKey))
return false;
}
+#else
+ // detach from the memory segment
+ if (munmap(memory, size) == -1) {
+ setErrorString(QLatin1String("QSharedMemory::detach (munmap)"));
+ return false;
+ }
+ memory = 0;
+ size = 0;
+
+ // get the number of current attachments
+ int shm_nattch = 0;
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) == 0) {
+ // subtract 2 from linkcount: one for our own open and one for the dir entry
+ shm_nattch = st.st_nlink - 2;
+ }
+ cleanHandle();
+ // if there are no attachments then unlink the shared memory
+ if (shm_nattch == 0) {
+ QByteArray shmName = QFile::encodeName(makePlatformSafeKey(key));
+ if (shm_unlink(shmName.constData()) == -1 && errno != ENOENT)
+ setErrorString(QLatin1String("QSharedMemory::detach (shm_unlink)"));
+ }
+#endif // QT_POSIX_IPC
+
return true;
}
diff --git a/src/corelib/kernel/qsystemsemaphore.cpp b/src/corelib/kernel/qsystemsemaphore.cpp
index 98ee6f4..ae30348 100644
--- a/src/corelib/kernel/qsystemsemaphore.cpp
+++ b/src/corelib/kernel/qsystemsemaphore.cpp
@@ -151,6 +151,11 @@ QT_BEGIN_NAMESPACE
creates a new semaphore for that key and sets its resource count to
\a initialValue.
+ In QNX, if the \a mode is \l {QSystemSemaphore::} {Create} and the
+ system already has a semaphore identified by \a key, that semaphore
+ will be deleted and the new one will be created for that key with
+ a resource count set to \a initialValue.
+
In Windows and in Symbian, \a mode is ignored, and the system always tries to
create a semaphore for the specified \a key. If the system does not
already have a semaphore identified as \a key, it creates the
@@ -234,7 +239,7 @@ void QSystemSemaphore::setKey(const QString &key, int initialValue, AccessMode m
return;
d->error = NoError;
d->errorString = QString();
-#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
+#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN) && !defined(QT_POSIX_IPC)
// optimization to not destroy/create the file & semaphore
if (key == d->key && mode == Create && d->createdSemaphore && d->createdFile) {
d->initialValue = initialValue;
diff --git a/src/corelib/kernel/qsystemsemaphore_p.h b/src/corelib/kernel/qsystemsemaphore_p.h
index 3e5f737..d84d416 100644
--- a/src/corelib/kernel/qsystemsemaphore_p.h
+++ b/src/corelib/kernel/qsystemsemaphore_p.h
@@ -61,6 +61,9 @@
#ifndef Q_OS_WINCE
# include <sys/types.h>
#endif
+#ifdef QT_POSIX_IPC
+# include <semaphore.h>
+#endif
#ifdef Q_OS_SYMBIAN
class RSemaphore;
@@ -84,6 +87,9 @@ public:
#elif defined(Q_OS_SYMBIAN)
int handle(QSystemSemaphore::AccessMode mode = QSystemSemaphore::Open);
void setErrorString(const QString &function,int err = 0);
+#elif defined(QT_POSIX_IPC)
+ bool handle(QSystemSemaphore::AccessMode mode = QSystemSemaphore::Open);
+ void setErrorString(const QString &function);
#else
key_t handle(QSystemSemaphore::AccessMode mode = QSystemSemaphore::Open);
void setErrorString(const QString &function);
@@ -99,6 +105,9 @@ public:
HANDLE semaphoreLock;
#elif defined(Q_OS_SYMBIAN)
RSemaphore semaphore;
+#elif defined(QT_POSIX_IPC)
+ sem_t *semaphore;
+ bool createdSemaphore;
#else
key_t unix_key;
int semaphore;
diff --git a/src/corelib/kernel/qsystemsemaphore_unix.cpp b/src/corelib/kernel/qsystemsemaphore_unix.cpp
index 704afaf..e060eb2 100644
--- a/src/corelib/kernel/qsystemsemaphore_unix.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_unix.cpp
@@ -50,7 +50,9 @@
#include <sys/types.h>
#include <sys/ipc.h>
+#ifndef QT_POSIX_IPC
#include <sys/sem.h>
+#endif
#include <fcntl.h>
#include <errno.h>
@@ -67,7 +69,11 @@
QT_BEGIN_NAMESPACE
QSystemSemaphorePrivate::QSystemSemaphorePrivate() :
+#ifndef QT_POSIX_IPC
unix_key(-1), semaphore(-1), createdFile(false),
+#else
+ semaphore(SEM_FAILED),
+#endif
createdSemaphore(false), error(QSystemSemaphore::NoError)
{
}
@@ -90,10 +96,18 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function)
error = QSystemSemaphore::NotFound;
break;
case ERANGE:
+ case ENOMEM:
case ENOSPC:
+ case EMFILE:
+ case ENFILE:
+ case EOVERFLOW:
errorString = QCoreApplication::translate("QSystemSemaphore", "%1: out of resources").arg(function);
error = QSystemSemaphore::OutOfResources;
break;
+ case ENAMETOOLONG:
+ errorString = QCoreApplication::translate("QSystemSemaphore", "%1: name error").arg(function);
+ error = QSystemSemaphore::KeyError;
+ break;
default:
errorString = QCoreApplication::translate("QSystemSemaphore", "%1: unknown error %2").arg(function).arg(errno);
error = QSystemSemaphore::UnknownError;
@@ -109,6 +123,7 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function)
Initialise the semaphore
*/
+#ifndef QT_POSIX_IPC
key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
{
if (-1 != unix_key)
@@ -170,6 +185,54 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
return unix_key;
}
+#else
+bool QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
+{
+ if (semaphore != SEM_FAILED)
+ return true; // we already have a semaphore
+
+ if (fileName.isEmpty()) {
+ errorString = QCoreApplication::tr("%1: key is empty", "QSystemSemaphore").arg(QLatin1String("QSystemSemaphore::handle"));
+ error = QSystemSemaphore::KeyError;
+ return false;
+ }
+
+ QByteArray semName = QFile::encodeName(fileName);
+
+ // Always try with O_EXCL so we know whether we created the semaphore.
+ int oflag = O_CREAT | O_EXCL;
+ for (int tryNum = 0, maxTries = 1; tryNum < maxTries; ++tryNum) {
+ do {
+ semaphore = sem_open(semName.constData(), oflag, 0666, initialValue);
+ } while (semaphore == SEM_FAILED && errno == EINTR);
+ if (semaphore == SEM_FAILED && errno == EEXIST) {
+ if (mode == QSystemSemaphore::Create) {
+ if (sem_unlink(semName.constData()) == -1 && errno != ENOENT) {
+ setErrorString(QLatin1String("QSystemSemaphore::handle (sem_unlink)"));
+ return false;
+ }
+ // Race condition: the semaphore might be recreated before
+ // we call sem_open again, so we'll retry several times.
+ maxTries = 3;
+ } else {
+ // Race condition: if it no longer exists at the next sem_open
+ // call, we won't realize we created it, so we'll leak it later.
+ oflag &= ~O_EXCL;
+ maxTries = 2;
+ }
+ } else {
+ break;
+ }
+ }
+ if (semaphore == SEM_FAILED) {
+ setErrorString(QLatin1String("QSystemSemaphore::handle"));
+ return false;
+ }
+
+ createdSemaphore = (oflag & O_EXCL) != 0;
+ return true;
+}
+#endif // QT_POSIX_IPC
/*!
\internal
@@ -178,6 +241,7 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
*/
void QSystemSemaphorePrivate::cleanHandle()
{
+#ifndef QT_POSIX_IPC
unix_key = -1;
// remove the file if we made it
@@ -198,6 +262,27 @@ void QSystemSemaphorePrivate::cleanHandle()
}
createdSemaphore = false;
}
+#else
+ if (semaphore != SEM_FAILED) {
+ if (sem_close(semaphore) == -1) {
+ setErrorString(QLatin1String("QSystemSemaphore::cleanHandle (sem_close)"));
+#ifdef QSYSTEMSEMAPHORE_DEBUG
+ qDebug() << QLatin1String("QSystemSemaphore::cleanHandle sem_close failed.");
+#endif
+ }
+ semaphore = SEM_FAILED;
+ }
+
+ if (createdSemaphore) {
+ if (sem_unlink(QFile::encodeName(fileName).constData()) == -1 && errno != ENOENT) {
+ setErrorString(QLatin1String("QSystemSemaphore::cleanHandle (sem_unlink)"));
+#ifdef QSYSTEMSEMAPHORE_DEBUG
+ qDebug() << QLatin1String("QSystemSemaphore::cleanHandle sem_unlink failed.");
+#endif
+ }
+ createdSemaphore = false;
+ }
+#endif // QT_POSIX_IPC
}
/*!
@@ -205,6 +290,7 @@ void QSystemSemaphorePrivate::cleanHandle()
*/
bool QSystemSemaphorePrivate::modifySemaphore(int count)
{
+#ifndef QT_POSIX_IPC
if (-1 == handle())
return false;
@@ -229,6 +315,44 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
#endif
return false;
}
+#else
+ if (!handle())
+ return false;
+
+ if (count > 0) {
+ int cnt = count;
+ do {
+ if (sem_post(semaphore) == -1) {
+ setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore (sem_post)"));
+#ifdef QSYSTEMSEMAPHORE_DEBUG
+ qDebug() << QLatin1String("QSystemSemaphore::modify sem_post failed") << count << errno;
+#endif
+ // rollback changes to preserve the SysV semaphore behavior
+ for ( ; cnt < count; ++cnt) {
+ register int res;
+ EINTR_LOOP(res, sem_wait(semaphore));
+ }
+ return false;
+ }
+ --cnt;
+ } while (cnt > 0);
+ } else {
+ register int res;
+ EINTR_LOOP(res, sem_wait(semaphore));
+ if (res == -1) {
+ // If the semaphore was removed be nice and create it and then modifySemaphore again
+ if (errno == EINVAL || errno == EIDRM) {
+ semaphore = SEM_FAILED;
+ return modifySemaphore(count);
+ }
+ setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore (sem_wait)"));
+#ifdef QSYSTEMSEMAPHORE_DEBUG
+ qDebug() << QLatin1String("QSystemSemaphore::modify sem_wait failed") << count << errno;
+#endif
+ return false;
+ }
+ }
+#endif // QT_POSIX_IPC
return true;
}
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 3c8704c..0edcb3b 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -205,6 +205,9 @@ QTimer::~QTimer()
Starts or restarts the timer with the timeout specified in \l interval.
+ If the timer is already running, it will be
+ \l{QTimer::stop()}{stopped} and restarted.
+
If \l singleShot is true, the timer will be activated only once.
*/
void QTimer::start()
@@ -218,6 +221,12 @@ void QTimer::start()
/*!
Starts or restarts the timer with a timeout interval of \a msec
milliseconds.
+
+ If the timer is already running, it will be
+ \l{QTimer::stop()}{stopped} and restarted.
+
+ If \l singleShot is true, the timer will be activated only once.
+
*/
void QTimer::start(int msec)
{
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 4504eab..d255422 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -600,7 +600,7 @@ static QString find_translation(const QLocale & locale,
/*!
\since 4.8
- Loads \a filename + \a prefix + \a \l{QLocale::uiLanguages()}{ui language
+ Loads \a filename + \a prefix + \l{QLocale::uiLanguages()}{ui language
name} + \a suffix (".qm" if the \a suffix is not specified), which may be
an absolute file name or relative to \a directory. Returns true if the
translation is successfully loaded; otherwise returns false.
@@ -618,7 +618,7 @@ static QString find_translation(const QLocale & locale,
\endlist
For example, an application running in the locale with the following
- l{QLocale::uiLanguages()}{ui languages} - "es", "fr-CA", "de" might call
+ \l{QLocale::uiLanguages()}{ui languages} - "es", "fr-CA", "de" might call
load(QLocale::system(), "foo", ".", "/opt/foolib", ".qm"). load() would
replace '-' (dash) with '_' (underscore) in the ui language and then try to
open the first existing readable file from this list:
@@ -637,8 +637,8 @@ static QString find_translation(const QLocale & locale,
\o \c /opt/foolib/foo
\endlist
- For OSs where file system is case sensitive, QTranslator also tries to load
- a lower-cased version of the locale name.
+ On operating systems where file system is case sensitive, QTranslator also
+ tries to load a lower-cased version of the locale name.
*/
bool QTranslator::load(const QLocale & locale,
const QString & filename,
diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp
index 03ab047..49fb46b 100644
--- a/src/corelib/thread/qmutexpool.cpp
+++ b/src/corelib/thread/qmutexpool.cpp
@@ -123,7 +123,8 @@ QMutexPool *QMutexPool::instance()
return globalMutexPool();
}
-/*! \fn QMutexPool::get(void *address)
+/*!
+ \fn QMutexPool::get(const void *address)
Returns a QMutex from the pool. QMutexPool uses the value \a address
to determine which mutex is returned from the pool.
*/
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 02a63bb..5dfc946 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -434,6 +434,12 @@ bool QThread::isRunning() const
{
Q_D(const QThread);
QMutexLocker locker(&d->mutex);
+#ifdef Q_OS_SYMBIAN
+ // app shutdown on Symbian can terminate threads and invalidate their stacks without notification,
+ // check the thread is still alive.
+ if (d->data->symbian_thread_handle.Handle() && d->data->symbian_thread_handle.ExitType() != EExitPending)
+ return false;
+#endif
return d->running;
}
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 13df3e6..461d93d 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -93,6 +93,8 @@ inline bool operator<(const QPostEvent &pe, int priority)
return priority < pe.priority;
}
+// This class holds the list of posted events.
+// The list has to be kept sorted by priority
class QPostEventList : public QList<QPostEvent>
{
public:
@@ -109,6 +111,25 @@ public:
inline QPostEventList()
: QList<QPostEvent>(), recursion(0), startOffset(0), insertionOffset(0)
{ }
+
+ void addEvent(const QPostEvent &ev) {
+ int priority = ev.priority;
+ if (isEmpty() || last().priority >= priority) {
+ // optimization: we can simply append if the last event in
+ // the queue has higher or equal priority
+ append(ev);
+ } else {
+ // insert event in descending priority order, using upper
+ // bound for a given priority (to ensure proper ordering
+ // of events with the same priority)
+ QPostEventList::iterator at = qUpperBound(begin() + insertionOffset, end(), priority);
+ insert(at, ev);
+ }
+ }
+private:
+ //hides because they do not keep that list sorted. addEvent must be used
+ using QList<QPostEvent>::append;
+ using QList<QPostEvent>::insert;
};
#ifndef QT_NO_THREAD
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 839a396..765969e 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -479,6 +479,11 @@ void QThread::usleep(unsigned long usecs)
// sched_priority is OUT only
static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority)
{
+#ifdef Q_OS_QNX
+ // without Round Robin drawn intensive apps will hog the cpu
+ // and make the system appear frozen
+ *sched_policy = SCHED_RR;
+#endif
#ifdef SCHED_IDLE
if (priority == QThread::IdlePriority) {
*sched_policy = SCHED_IDLE;
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 1c1d684..36a9c60 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -590,10 +590,10 @@ void **QListData::erase(void **xi)
\sa operator=()
*/
-/*! \fn QList::QList(std::initializer_list<T> args)
+/*! \fn inline QList::QList(std::initializer_list<T> args)
\since 4.8
- Construct a list from a std::initilizer_list.
+ Construct a list from the std::initializer_list specified by \a args.
This constructor is only enabled if the compiler supports C++0x
*/
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 5a2e153..d791529 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -934,7 +934,7 @@ QLocale::Country QLocale::country() const
name() will not contain it for compatibility reasons. Use bcp47Name() instead
if you need a full locale name.
- \sa QLocale(const QString &), language(), script(), country(), bcp47Name()
+ \sa QLocale(), language(), script(), country(), bcp47Name()
*/
QString QLocale::name() const
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index 34e4fb3..fd139c3 100644
--- a/src/corelib/tools/qlocale.qdoc
+++ b/src/corelib/tools/qlocale.qdoc
@@ -769,6 +769,8 @@
\value Weekdays a QList<Qt::DayOfWeek> specifying the regular weekdays
\value LocaleChanged this type is queried whenever the system locale is changed.
\value ListToSeparatedString a string that represents a join of a given QStringList with a locale-defined separator.
+ \value NativeLanguageName a string that represents the name of the native language.
+ \value NativeCountryName a string that represents the name of the native country.
*/
/*!
diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h
index c0cf219..9f03606 100644
--- a/src/corelib/tools/qpoint.h
+++ b/src/corelib/tools/qpoint.h
@@ -93,7 +93,7 @@ public:
private:
friend class QTransform;
// ### Qt 5; remove the ifdef and just have the same order on all platforms.
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES)
int yp;
int xp;
#else
diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp
index 8ce6b57..9277a3e 100644
--- a/src/corelib/tools/qscopedpointer.cpp
+++ b/src/corelib/tools/qscopedpointer.cpp
@@ -252,10 +252,9 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QScopedArrayPointer::QScopedArrayPointer(T *p = 0)
+ \fn QScopedArrayPointer::QScopedArrayPointer()
- Constructs this QScopedArrayPointer instance and sets its pointer
- to \a p.
+ Constructs a QScopedArrayPointer instance.
*/
/*!
diff --git a/src/corelib/tools/qscopedvaluerollback.cpp b/src/corelib/tools/qscopedvaluerollback.cpp
index a9bbdb3..1ad47f4 100644
--- a/src/corelib/tools/qscopedvaluerollback.cpp
+++ b/src/corelib/tools/qscopedvaluerollback.cpp
@@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QScopedValueRollback
- \brief The QScopedValueRollback resets a variable to its previous value on destruction
+ \brief The QScopedValueRollback class resets a variable to its previous value on destruction.
\since 4.8
\ingroup misc
@@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE
/*!
\fn QScopedValueRollback::QScopedValueRollback(T &var)
- Stores the previous value of var internally, for revert on destruction.
+ Stores the previous value of \a var internally, for revert on destruction.
*/
/*!
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 0edf291..ee45cfd 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -837,6 +837,25 @@ int QString::grow(int size)
\sa QString::const_iterator
*/
+/*!
+ \typedef QString::const_reference
+
+ The QString::const_reference typedef provides an STL-style
+ const reference for QString.
+*/
+/*!
+ \typedef QString::reference
+
+ The QString::const_reference typedef provides an STL-style
+ reference for QString.
+*/
+/*!
+ \typedef QString::value_type
+
+ The QString::const_reference typedef provides an STL-style
+ value type for QString.
+*/
+
/*! \fn QString::iterator QString::begin()
Returns an \l{STL-style iterator} pointing to the first character in
@@ -3561,6 +3580,28 @@ static inline __m128i mergeQuestionMarks(__m128i chunk)
{
const __m128i questionMark = _mm_set1_epi16('?');
+# ifdef __SSE4_2__
+ // compare the unsigned shorts for the range 0x0100-0xFFFF
+ // note on the use of _mm_cmpestrm:
+ // The MSDN documentation online (http://technet.microsoft.com/en-us/library/bb514080.aspx)
+ // says for range search the following:
+ // For each character c in a, determine whether b0 <= c <= b1 or b2 <= c <= b3
+ //
+ // However, all examples on the Internet, including from Intel
+ // (see http://software.intel.com/en-us/articles/xml-parsing-accelerator-with-intel-streaming-simd-extensions-4-intel-sse4/)
+ // put the range to be searched first
+ //
+ // Disassembly and instruction-level debugging with GCC and ICC show
+ // that they are doing the right thing. Inverting the arguments in the
+ // instruction does cause a bunch of test failures.
+
+ const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK;
+ const __m128i rangeMatch = _mm_cvtsi32_si128(0xffff0100);
+ const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8, mode);
+
+ // replace the non-Latin 1 characters in the chunk with question marks
+ chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
+# else
// SSE has no compare instruction for unsigned comparison.
// The variables must be shiffted + 0x8000 to be compared
const __m128i signedBitOffset = _mm_set1_epi16(0x8000);
@@ -3584,6 +3625,7 @@ static inline __m128i mergeQuestionMarks(__m128i chunk)
// merge offLimitQuestionMark and correctBytes to have the result
chunk = _mm_or_si128(correctBytes, offLimitQuestionMark);
# endif
+# endif
return chunk;
}
#endif
@@ -9117,7 +9159,7 @@ QByteArray QStringRef::toUtf8() const
UCS-4 is a Unicode codec and is lossless. All characters from this string
can be encoded in UCS-4.
- \sa fromUtf8(), toAscii(), toLatin1(), toLocal8Bit(), QTextCodec, fromUcs4(), toWCharArray()
+ \sa toAscii(), toLatin1(), toLocal8Bit(), QTextCodec
*/
QVector<uint> QStringRef::toUcs4() const
{
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index c61d09e..bf0a0ad 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -639,6 +639,7 @@ private:
static Data *fromAscii_helper(const char *str, int size = -1);
void replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen);
friend class QCharRef;
+ friend class QCFString;
friend class QTextCodec;
friend class QStringRef;
friend struct QAbstractConcatenable;
diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp
index fb06736..1cc7e5d 100644
--- a/src/corelib/tools/qstringbuilder.cpp
+++ b/src/corelib/tools/qstringbuilder.cpp
@@ -142,7 +142,8 @@ QT_BEGIN_NAMESPACE
characters.
*/
-/*! \fn QStringBuilder::operator QString() const
+/*!
+ \fn operator QStringBuilder::QString() const
Converts the \c QLatin1Literal into a \c QString object.
*/
@@ -161,6 +162,8 @@ void QAbstractConcatenable::convertFromAscii(const char *a, int len, QChar *&out
}
#endif
if (len == -1) {
+ if (!a)
+ return;
while (*a)
*out++ = QLatin1Char(*a++);
} else {
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index 709d84a..594ab2f 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -352,6 +352,8 @@ template <> struct QConcatenable<const char *> : private QAbstractConcatenable
#endif
static inline void appendTo(const char *a, char *&out)
{
+ if (!a)
+ return;
while (*a)
*out++ = *a++;
}
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
index 5997574..8b47137 100644
--- a/src/corelib/tools/qstringlist.cpp
+++ b/src/corelib/tools/qstringlist.cpp
@@ -683,7 +683,7 @@ int QtPrivate::QStringList_removeDuplicates(QStringList *that)
/*! \fn QStringList::QStringList(std::initializer_list<QString> args)
\since 4.8
- Construct a list from a std::initilizer_list.
+ Construct a list from a std::initializer_list given by \a args.
This constructor is only enabled if the compiler supports C++0x
*/
diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc
index b2dc7d6..b1d7a1a 100644
--- a/src/corelib/tools/qvarlengtharray.qdoc
+++ b/src/corelib/tools/qvarlengtharray.qdoc
@@ -337,6 +337,20 @@
Typedef for const T &. Provided for STL compatibility.
*/
+/*!
+ \typedef QVarLengthArray::const_iterator
+ \since 4.7
+
+ Typedef for const T *. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QVarLengthArray::iterator
+ \since 4.7
+
+ Typedef for T *. Provided for STL compatibility.
+*/
+
/*! \fn void QVarLengthArray::prepend(const T &value)
\since 4.8
@@ -501,7 +515,7 @@
\relates QVarLengthArray
\since 4.8
- Returns true if the two array are equal;
+ Returns true if the two arrays, specified by \a left and \a right, are equal.
Two arrays are considered equal if they contain the same values
in the same order.
@@ -516,7 +530,7 @@
\relates QVarLengthArray
\since 4.8
- Returns true if the two array are different;
+ Returns true if the two arrays, specified by \a left and \a right, are \e not equal.
Two arrays are considered equal if they contain the same values
in the same order.
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index 8c4dd06..98a2412 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -277,7 +277,7 @@ int QVectorData::grow(int sizeofTypedData, int size, int sizeofT, bool excessive
/*! \fn QVector::QVector(std::initializer_list<T> args)
\since 4.8
- Construct a vector from a std::initilizer_list.
+ Construct a vector from the std::initilizer_list given by \a args.
This constructor is only enabled if the compiler supports C++0x
*/
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index 19626af..caaffd3 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -646,6 +646,11 @@ QXmlStreamReader::TokenType QXmlStreamReader::tokenType() const
parser has reached the end element, the current element becomes the parent
element.
+ You can traverse a document by repeatedly calling this function while
+ ensuring that the stream reader is not at the end of the document:
+
+ \snippet doc/src/snippets/xml/streamreader/traverse.cpp traverse document
+
This is a convenience function for when you're only concerned with parsing
XML elements. The \l{QXmlStream Bookmarks Example} makes extensive use of
this function.