summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-01-16 23:51:11 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-01-16 23:51:11 +0100
commite3a10e15ff5a015de28528b5f73316d7aa0de116 (patch)
tree57e5bae55b627af2fa372b9de4e530305cb43cce /src/corelib
parent34572dadc6a4efce87a639f38a989a3117c8ca9f (diff)
parent7075e291998612a3c0a530bb37a515dd07739e28 (diff)
Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/corelib.pro2
-rw-r--r--src/corelib/doc/src/objectmodel/properties.qdoc2
-rw-r--r--src/corelib/global/qcompilerdetection.h37
-rw-r--r--src/corelib/global/qglobal.cpp4
-rw-r--r--src/corelib/global/qnamespace.qdoc2
-rw-r--r--src/corelib/io/qdir.cpp4
-rw-r--r--src/corelib/io/qfile.cpp15
-rw-r--r--src/corelib/io/qfilesystemengine_p.h1
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp27
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp75
-rw-r--r--src/corelib/kernel/qmetatype.cpp36
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp6
-rw-r--r--src/corelib/kernel/qsystemsemaphore_unix.cpp4
-rw-r--r--src/corelib/tools/qlocale_p.h5
-rw-r--r--src/corelib/tools/qlocale_unix.cpp27
15 files changed, 211 insertions, 36 deletions
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index f95ee545c0..bf2fd3c84a 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -50,7 +50,7 @@ QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtCore.dynlist
contains(DEFINES,QT_EVAL):include(eval.pri)
-HOST_BINS = $$[QT_HOST_BINS]
+HOST_BINS = $$[QT_HOST_BINS/raw]
host_bins.name = host_bins
host_bins.variable = HOST_BINS
diff --git a/src/corelib/doc/src/objectmodel/properties.qdoc b/src/corelib/doc/src/objectmodel/properties.qdoc
index d818d1154c..1e88a67a90 100644
--- a/src/corelib/doc/src/objectmodel/properties.qdoc
+++ b/src/corelib/doc/src/objectmodel/properties.qdoc
@@ -83,7 +83,7 @@
existing signal in that class that is emitted whenever the value
of the property changes.
- \li A \c REVISION number is optional. If included, it defines the
+ \li A \c REVISION number is optional. If included, it defines
the property and its notifier signal to be used in a particular
revision of the API that is exposed to QML.
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 2c471bdfc3..b88309d1e7 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -94,8 +94,8 @@
# define Q_FUNC_INFO __FUNCSIG__
# define Q_ALIGNOF(type) __alignof(type)
# define Q_DECL_ALIGN(n) __declspec(align(n))
-# define Q_ASSUME(expr) __assume(expr)
-# define Q_UNREACHABLE() __assume(0)
+# define Q_ASSUME_IMPL(expr) __assume(expr)
+# define Q_UNREACHABLE_IMPL() __assume(0)
# define Q_NORETURN __declspec(noreturn)
# define Q_DECL_DEPRECATED __declspec(deprecated)
# define Q_DECL_EXPORT __declspec(dllexport)
@@ -150,18 +150,18 @@
# if defined(__INTEL_COMPILER)
/* Intel C++ also masquerades as GCC */
# define Q_CC_INTEL
-# define Q_ASSUME(expr) __assume(expr)
-# define Q_UNREACHABLE() __assume(0)
+# define Q_ASSUME_IMPL(expr) __assume(expr)
+# define Q_UNREACHABLE_IMPL() __assume(0)
# elif defined(__clang__)
/* Clang also masquerades as GCC */
# define Q_CC_CLANG
-# define Q_ASSUME(expr) if (expr){} else __builtin_unreachable()
-# define Q_UNREACHABLE() __builtin_unreachable()
+# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
+# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
# else
/* Plain GCC */
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
-# define Q_ASSUME(expr) if (expr){} else __builtin_unreachable()
-# define Q_UNREACHABLE() __builtin_unreachable()
+# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
+# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
# endif
# endif
@@ -789,11 +789,11 @@
#ifndef Q_UNLIKELY
# define Q_UNLIKELY(x) (x)
#endif
-#ifndef Q_ASSUME
-# define Q_ASSUME(expr) qt_noop()
+#ifndef Q_ASSUME_IMPL
+# define Q_ASSUME_IMPL(expr) qt_noop()
#endif
-#ifndef Q_UNREACHABLE
-# define Q_UNREACHABLE() qt_noop()
+#ifndef Q_UNREACHABLE_IMPL
+# define Q_UNREACHABLE_IMPL() qt_noop()
#endif
#ifndef Q_ALLOC_SIZE
# define Q_ALLOC_SIZE(x)
@@ -851,4 +851,17 @@
#define qMove(x) (x)
#endif
+#define Q_UNREACHABLE() \
+ do {\
+ Q_ASSERT_X(false, "Q_UNREACHABLE()", "Q_UNREACHABLE was reached");\
+ Q_UNREACHABLE_IMPL();\
+ } while (0)
+
+#define Q_ASSUME(Expr) \
+ do {\
+ const bool valueOfExpression = Expr;\
+ Q_ASSERT_X(valueOfExpression, "Q_ASSUME()", "Assumption in Q_ASSUME(\"" #Expr "\") was not correct");\
+ Q_ASSUME_IMPL(valueOfExpression);\
+ } while (0)
+
#endif // QCOMPILERDETECTION_H
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 3881b166b1..6818b1d64d 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1829,6 +1829,8 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
that the current code execution cannot be reached. That is, Q_ASSUME(false)
is equivalent to Q_UNREACHABLE().
+ In debug builds the condition is enforced by an assert to facilitate debugging.
+
\note Q_LIKELY() tells the compiler that the expression is likely, but not
the only possibility. Q_ASSUME tells the compiler that it is the only
possibility.
@@ -1863,6 +1865,8 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
By using this macro in impossible conditions, code coverage may be improved
as dead code paths may be eliminated.
+ In debug builds the condition is enforced by an assert to facilitate debugging.
+
\sa Q_ASSERT(), Q_ASSUME(), qFatal()
*/
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 0b0d089ba5..3937076664 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -2341,7 +2341,7 @@
\enum Qt::InputMethodQuery
\value ImEnabled The widget accepts input method input.
- \value ImMicroFocus \obsolete replaced by \c ImCursorRectangle
+ \value ImMicroFocus This query is obsolete. Use \c ImCursorRectangle instead.
\value ImCursorRectangle The rectangle covering the area of the input cursor in widget coordinates.
\value ImFont The currently used font for text input.
\value ImCursorPosition The logical position of the cursor within the text surrounding the input area
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 5463adaeb9..cb334ed741 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2005,8 +2005,8 @@ bool QDir::match(const QString &filter, const QString &fileName)
#endif // QT_NO_REGEXP
/*!
- Removes all multiple directory separators "/" and resolves any
- "."s or ".."s found in the path, \a path.
+ Returns \a path with directory separators normalized (converted to "/") and
+ redundant ones removed, and "."s and ".."s resolved (as far as possible).
Symbolic links are kept. This function does not return the
canonical path, but rather the simplest version of the input.
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index d9f2c5c605..24f0eba1b7 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -48,6 +48,7 @@
#include "qfileinfo.h"
#include "private/qiodevice_p.h"
#include "private/qfile_p.h"
+#include "private/qfilesystemengine_p.h"
#include "private/qsystemerror_p.h"
#if defined(QT_BUILD_CORE_LIB)
# include "qcoreapplication.h"
@@ -548,7 +549,19 @@ QFile::rename(const QString &newName)
qWarning("QFile::rename: Empty or null file name");
return false;
}
- if (QFile(newName).exists()) {
+ if (d->fileName == newName) {
+ d->setError(QFile::RenameError, tr("Destination file is the same file."));
+ return false;
+ }
+ if (!exists()) {
+ d->setError(QFile::RenameError, tr("Source file does not exist."));
+ return false;
+ }
+ // If the file exists and it is a case-changing rename ("foo" -> "Foo"),
+ // compare Ids to make sure it really is a different file.
+ if (QFile::exists(newName)
+ && (d->fileName.compare(newName, Qt::CaseInsensitive)
+ || QFileSystemEngine::id(QFileSystemEntry(d->fileName)) != QFileSystemEngine::id(QFileSystemEntry(newName)))) {
// ### Race condition. If a file is moved in after this, it /will/ be
// overwritten. On Unix, the proper solution is to use hardlinks:
// return ::link(old, new) && ::remove(old);
diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h
index bb91cf1142..9d03a6b459 100644
--- a/src/corelib/io/qfilesystemengine_p.h
+++ b/src/corelib/io/qfilesystemengine_p.h
@@ -75,6 +75,7 @@ public:
static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data);
static QFileSystemEntry canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data);
static QFileSystemEntry absoluteName(const QFileSystemEntry &entry);
+ static QByteArray id(const QFileSystemEntry &entry);
static QString resolveUserName(const QFileSystemEntry &entry, QFileSystemMetaData &data);
static QString resolveGroupName(const QFileSystemEntry &entry, QFileSystemMetaData &data);
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 5870cdf7de..fa0e07b045 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -46,6 +46,8 @@
#include <QtCore/qvarlengtharray.h>
#include <stdlib.h> // for realpath()
+#include <sys/types.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
@@ -174,9 +176,16 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
#else
char *ret = 0;
# if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
- // Mac OS X 10.5.x doesn't support the realpath(X,0) extension we use here.
+ // When using -mmacosx-version-min=10.4, we get the legacy realpath implementation,
+ // which does not work properly with the realpath(X,0) form. See QTBUG-28282.
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
- ret = realpath(entry.nativeFilePath().constData(), (char*)0);
+ ret = (char*)malloc(PATH_MAX + 1);
+ if (ret && realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) {
+ const int savedErrno = errno; // errno is checked below, and free() might change it
+ free(ret);
+ errno = savedErrno;
+ ret = 0;
+ }
} else {
// on 10.5 we can use FSRef to resolve the file path.
QString path = QDir::cleanPath(entry.filePath());
@@ -252,6 +261,20 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
}
//static
+QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry)
+{
+ struct stat statResult;
+ if (stat(entry.nativeFilePath().constData(), &statResult)) {
+ qErrnoWarning("stat() failed for '%s'", entry.nativeFilePath().constData());
+ return QByteArray();
+ }
+ QByteArray result = QByteArray::number(quint64(statResult.st_dev), 16);
+ result += ':';
+ result += QByteArray::number(quint64(statResult.st_ino), 16);
+ return result;
+}
+
+//static
QString QFileSystemEngine::resolveUserName(uint userId)
{
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 5364a44f91..cc40d4af3f 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -42,6 +42,7 @@
#include "qfilesystemengine_p.h"
#include "qplatformdefs.h"
+#include "qsysinfo.h"
#include "private/qabstractfileengine_p.h"
#include "private/qfsfileengine_p.h"
#include <private/qsystemlibrary_p.h>
@@ -563,6 +564,80 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
}
+#ifndef Q_OS_WINCE
+
+// FILE_INFO_BY_HANDLE_CLASS has been extended by FileIdInfo = 18 as of VS2012.
+typedef enum { Q_FileIdInfo = 18 } Q_FILE_INFO_BY_HANDLE_CLASS;
+
+# if defined(Q_CC_MINGW) || (defined(Q_CC_MSVC) && _MSC_VER < 1700)
+
+typedef struct _FILE_ID_128 {
+ BYTE Identifier[16];
+} FILE_ID_128, *PFILE_ID_128;
+
+typedef struct _FILE_ID_INFO {
+ ULONGLONG VolumeSerialNumber;
+ FILE_ID_128 FileId;
+} FILE_ID_INFO, *PFILE_ID_INFO;
+# endif // if defined (Q_CC_MINGW) || (defined(Q_CC_MSVC) && _MSC_VER < 1700))
+
+// File ID for Windows up to version 7.
+static inline QByteArray fileId(HANDLE handle)
+{
+ QByteArray result;
+ BY_HANDLE_FILE_INFORMATION info;
+ if (GetFileInformationByHandle(handle, &info)) {
+ result = QByteArray::number(uint(info.nFileIndexLow), 16);
+ result += ':';
+ result += QByteArray::number(uint(info.nFileIndexHigh), 16);
+ }
+ return result;
+}
+
+// File ID for Windows starting from version 8.
+QByteArray fileIdWin8(HANDLE handle)
+{
+ typedef BOOL (WINAPI* GetFileInformationByHandleExType)(HANDLE, Q_FILE_INFO_BY_HANDLE_CLASS, void *, DWORD);
+
+ // Dynamically resolve GetFileInformationByHandleEx (Vista onwards).
+ static GetFileInformationByHandleExType getFileInformationByHandleEx = 0;
+ if (!getFileInformationByHandleEx) {
+ QSystemLibrary library(QLatin1String("kernel32"));
+ getFileInformationByHandleEx = (GetFileInformationByHandleExType)library.resolve("GetFileInformationByHandleEx");
+ }
+ QByteArray result;
+ if (getFileInformationByHandleEx) {
+ FILE_ID_INFO infoEx;
+ if (getFileInformationByHandleEx(handle, Q_FileIdInfo,
+ &infoEx, sizeof(FILE_ID_INFO))) {
+ result = QByteArray::number(infoEx.VolumeSerialNumber, 16);
+ result += ':';
+ result += QByteArray((char *)infoEx.FileId.Identifier, sizeof(infoEx.FileId.Identifier)).toHex();
+ }
+ }
+ return result;
+}
+#endif // !Q_OS_WINCE
+
+//static
+QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry)
+{
+#ifndef Q_OS_WINCE
+ QByteArray result;
+ const HANDLE handle =
+ CreateFile((wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ,
+ FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (handle) {
+ result = QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS8 ?
+ fileIdWin8(handle) : fileId(handle);
+ CloseHandle(handle);
+ }
+ return result;
+#else // !Q_OS_WINCE
+ return entry.nativeFilePath().toLower().toLatin1();
+#endif
+}
+
//static
QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own)
{
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 82b6ed54d1..c47270b83b 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -646,11 +646,26 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
"size %i, now registering size %i.",
normalizedTypeName.constData(), idx, previousSize, size);
}
+
+ // Ignore WasDeclaredAsMetaType inconsitency, to many users were hitting the problem
+ previousFlags |= WasDeclaredAsMetaType;
+ flags |= WasDeclaredAsMetaType;
+
if (previousFlags != flags) {
- qFatal("QMetaType::registerType: Binary compatibility break "
- "-- Type flags for type '%s' [%i] don't match. Previously "
- "registered TypeFlags(0x%x), now registering TypeFlags(0x%x).",
- normalizedTypeName.constData(), idx, previousFlags, int(flags));
+ const int maskForTypeInfo = NeedsConstruction | NeedsDestruction | MovableType;
+ const char *msg = "QMetaType::registerType: Binary compatibility break. "
+ "\nType flags for type '%s' [%i] don't match. Previously "
+ "registered TypeFlags(0x%x), now registering TypeFlags(0x%x). "
+ "This is an ODR break, which means that your application depends on a C++ undefined behavior."
+ "\nHint: %s";
+ QT_PREPEND_NAMESPACE(QByteArray) hint;
+ if ((previousFlags & maskForTypeInfo) != (flags & maskForTypeInfo)) {
+ hint += "\nIt seems that the type was registered at least twice in a different translation units, "
+ "but Q_DECLARE_TYPEINFO is not visible from all the translations unit or different flags were used."
+ "Remember that Q_DECLARE_TYPEINFO should be declared before QMetaType registration, "
+ "preferably it should be placed just after the type declaration and before Q_DECLARE_METATYPE";
+ }
+ qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags), hint.constData());
}
return idx;
@@ -1722,6 +1737,9 @@ const QMetaObject *QMetaType::metaObjectForType(int type)
\snippet code/src_corelib_kernel_qmetatype.cpp 9
+ \warning This function is useful only for registering an alias (typedef)
+ for every other use case Q_DECLARE_METATYPE and qMetaTypeId() should be used instead.
+
\sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(),
Q_DECLARE_METATYPE()
*/
@@ -1767,7 +1785,7 @@ const QMetaObject *QMetaType::metaObjectForType(int type)
*/
/*!
- \fn int qRegisterMetaType(const char *typeName)
+ \fn int qRegisterMetaType()
\relates QMetaType
\threadsafe
\since 4.2
@@ -1779,6 +1797,14 @@ const QMetaObject *QMetaType::metaObjectForType(int type)
\snippet code/src_corelib_kernel_qmetatype.cpp 7
+ This function requires that \c{T} is a fully defined type at the point
+ where the function is called. For pointer types, it also requires that the
+ pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able
+ to register pointers to forward declared types.
+
+ After a type has been registered, you can create and destroy
+ objects of that type dynamically at run-time.
+
To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is
sufficient. To use the type \c T in queued signal and slot connections,
\c{qRegisterMetaType<T>()} must be called before the first connection
diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp
index fd2bc97b2d..6bcb4076b4 100644
--- a/src/corelib/kernel/qsharedmemory_unix.cpp
+++ b/src/corelib/kernel/qsharedmemory_unix.cpp
@@ -197,7 +197,7 @@ bool QSharedMemoryPrivate::create(int size)
}
// create
- if (-1 == shmget(unix_key, size, 0666 | IPC_CREAT | IPC_EXCL)) {
+ if (-1 == shmget(unix_key, size, 0600 | IPC_CREAT | IPC_EXCL)) {
QString function = QLatin1String("QSharedMemory::create");
switch (errno) {
case EINVAL:
@@ -218,7 +218,7 @@ bool QSharedMemoryPrivate::create(int size)
bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode)
{
// grab the shared memory segment id
- int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0444 : 0660));
+ int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0400 : 0600));
if (-1 == id) {
setErrorString(QLatin1String("QSharedMemory::attach (shmget)"));
return false;
@@ -263,7 +263,7 @@ bool QSharedMemoryPrivate::detach()
size = 0;
// Get the number of current attachments
- int id = shmget(unix_key, 0, 0444);
+ int id = shmget(unix_key, 0, 0400);
cleanHandle();
struct shmid_ds shmid_ds;
diff --git a/src/corelib/kernel/qsystemsemaphore_unix.cpp b/src/corelib/kernel/qsystemsemaphore_unix.cpp
index e67fb42285..303f0c7725 100644
--- a/src/corelib/kernel/qsystemsemaphore_unix.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_unix.cpp
@@ -136,10 +136,10 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
}
// Get semaphore
- semaphore = semget(unix_key, 1, 0666 | IPC_CREAT | IPC_EXCL);
+ semaphore = semget(unix_key, 1, 0600 | IPC_CREAT | IPC_EXCL);
if (-1 == semaphore) {
if (errno == EEXIST)
- semaphore = semget(unix_key, 1, 0666 | IPC_CREAT);
+ semaphore = semget(unix_key, 1, 0600 | IPC_CREAT);
if (-1 == semaphore) {
setErrorString(QLatin1String("QSystemSemaphore::handle"));
cleanHandle();
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 65201374a9..ca1b6f8b07 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -380,10 +380,13 @@ class QQNXLocaleData: public QObject
public:
QQNXLocaleData();
virtual ~QQNXLocaleData();
- void readPPSLocale();
public Q_SLOTS:
void updateMeasurementSystem();
+ void installSocketNotifier();
+
+private:
+ void initialize();
public:
uint ppsMeasurement;
diff --git a/src/corelib/tools/qlocale_unix.cpp b/src/corelib/tools/qlocale_unix.cpp
index 088e40b176..49bed37075 100644
--- a/src/corelib/tools/qlocale_unix.cpp
+++ b/src/corelib/tools/qlocale_unix.cpp
@@ -66,7 +66,12 @@ QQNXLocaleData::QQNXLocaleData()
:ppsNotifier(0)
,ppsFd(-1)
{
- readPPSLocale();
+ initialize();
+
+ // we cannot call this directly, because by the time this constructor is
+ // called, the event dispatcher has not yet been created, causing the
+ // subsequent call to QSocketNotifier constructor to fail.
+ QMetaObject::invokeMethod(this, "installSocketNotifier", Qt::QueuedConnection);
}
QQNXLocaleData::~QQNXLocaleData()
@@ -106,7 +111,7 @@ void QQNXLocaleData::updateMeasurementSystem()
ppsMeasurement = QLocale::MetricSystem;
}
-void QQNXLocaleData::readPPSLocale()
+void QQNXLocaleData::initialize()
{
errno = 0;
ppsFd = qt_safe_open(ppsServicePath, O_RDONLY);
@@ -116,10 +121,22 @@ void QQNXLocaleData::readPPSLocale()
}
updateMeasurementSystem();
- if (QCoreApplication::instance()) {
- ppsNotifier = new QSocketNotifier(ppsFd, QSocketNotifier::Read, this);
- QObject::connect(ppsNotifier, SIGNAL(activated(int)), this, SLOT(updateMeasurementSystem()));
+}
+
+void QQNXLocaleData::installSocketNotifier()
+{
+ if (!QCoreApplication::instance() || ppsFd == -1) {
+ qWarning("QQNXLocaleData: Failed to create socket notifier, locale updates may not work.");
+ return;
}
+
+ if (ppsNotifier) {
+ qWarning("QQNXLocaleData: socket notifier already created.");
+ return;
+ }
+
+ ppsNotifier = new QSocketNotifier(ppsFd, QSocketNotifier::Read, this);
+ QObject::connect(ppsNotifier, SIGNAL(activated(int)), this, SLOT(updateMeasurementSystem()));
}
#endif