From 0b693175e4e70cead730a245cffa66304998196a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Sun, 7 Apr 2019 12:32:51 +0200 Subject: wasm: make idealThreadCount() work on all threads navigator.hardwareConcurrency can be accessed from the main thread only. Read and cache the value on QCoreApplication initialization. Change-Id: I731f7f356ce106c7107977783d4b763326af06b6 Reviewed-by: Lorn Potter --- src/corelib/kernel/qcoreapplication.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 69b2a9bf41..5c0bf93acc 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -119,6 +119,7 @@ #ifdef Q_OS_WASM #include +#include #endif #ifdef QT_BOOTSTRAPPED @@ -800,6 +801,10 @@ void QCoreApplicationPrivate::init() Module.print(err); }); ); + +#if QT_CONFIG(thread) + QThreadPrivate::idealThreadCount = emscripten::val::global("navigator")["hardwareConcurrency"].as(); +#endif #endif // Store app name/version (so they're still available after QCoreApplication is destroyed) -- cgit v1.2.3 From 69f6cab0af78285472deb8d91c862c600685e618 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 28 Apr 2019 12:52:19 +0200 Subject: Doc: replace even more null/0/nullptr with \nullptr macro Try to replace all wordings like '.. to 0' with '.. to \nullptr'. Also checked for 'null pointer' and similar. Change-Id: I73341f59ba51e0798e816a8b1a532c7c7374b74a Reviewed-by: Edward Welbourne --- src/corelib/kernel/qcoreapplication.cpp | 2 +- src/corelib/kernel/qobject.cpp | 4 ++-- src/corelib/kernel/qpointer.cpp | 8 ++++---- src/corelib/kernel/qvariant.cpp | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 69b2a9bf41..9a3d5c6ef4 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -699,7 +699,7 @@ void QCoreApplicationPrivate::initLocale() Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance. - If no instance has been allocated, \c null is returned. + If no instance has been allocated, \nullptr is returned. */ /*! diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index e6b313863f..94b7ccd761 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -797,7 +797,7 @@ static bool check_parent_thread(QObject *parent, The destructor of a parent object destroys all child objects. - Setting \a parent to 0 constructs an object with no parent. If the + Setting \a parent to \nullptr constructs an object with no parent. If the object is a widget, it will become a top-level window. \sa parent(), findChild(), findChildren() @@ -3382,7 +3382,7 @@ bool QMetaObject::disconnectOne(const QObject *sender, int signal_index, /*! \internal - Helper function to remove the connection from the senders list and setting the receivers to 0 + Helper function to remove the connection from the senders list and set the receivers to \nullptr */ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c, const QObject *receiver, int method_index, void **slot, diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp index c3dee7989e..068314633b 100644 --- a/src/corelib/kernel/qpointer.cpp +++ b/src/corelib/kernel/qpointer.cpp @@ -45,7 +45,7 @@ \ingroup objectmodel A guarded pointer, QPointer, behaves like a normal C++ - pointer \c{T *}, except that it is automatically set to 0 when the + pointer \c{T *}, except that it is automatically cleared when the referenced object is destroyed (unlike normal C++ pointers, which become "dangling pointers" in such cases). \c T must be a subclass of QObject. @@ -79,7 +79,7 @@ \snippet pointer/pointer.cpp 2 If the QLabel is deleted in the meantime, the \c label variable - will hold 0 instead of an invalid address, and the last line will + will hold \nullptr instead of an invalid address, and the last line will never be executed. The functions and operators available with a QPointer are the @@ -93,7 +93,7 @@ For creating guarded pointers, you can construct or assign to them from a T* or from another guarded pointer of the same type. You can compare them with each other using operator==() and - operator!=(), or test for 0 with isNull(). You can dereference + operator!=(), or test for \nullptr with isNull(). You can dereference them using either the \c *x or the \c x->member notation. A guarded pointer will automatically cast to a \c T *, so you can @@ -113,7 +113,7 @@ /*! \fn template QPointer::QPointer() - Constructs a 0 guarded pointer. + Constructs a guarded pointer with value \nullptr. \sa isNull() */ diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 18c7f7648d..3b7be3d12f 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2408,7 +2408,7 @@ void QVariant::clear() Converts the int representation of the storage type, \a typeId, to its string representation. - Returns a null pointer if the type is QMetaType::UnknownType or doesn't exist. + Returns \nullptr if the type is QMetaType::UnknownType or doesn't exist. */ const char *QVariant::typeToName(int typeId) { @@ -4144,7 +4144,7 @@ void* QVariant::data() /*! Returns \c true if this is a null variant, false otherwise. A variant is considered null if it contains no initialized value, or the contained value - is a null pointer or is an instance of a built-in type that has an isNull + is \nullptr or is an instance of a built-in type that has an isNull method, in which case the result would be the same as calling isNull on the wrapped object. @@ -4224,7 +4224,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p) If the QVariant contains a pointer to a type derived from QObject then \c{T} may be any QObject type. If the pointer stored in the QVariant can be - qobject_cast to T, then that result is returned. Otherwise a null pointer is + qobject_cast to T, then that result is returned. Otherwise \nullptr is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro. -- cgit v1.2.3 From 98cb9275d064d8b996dcd78324c4249f69a981a9 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 5 Dec 2018 13:18:50 +0100 Subject: doc: clang reported two fake declarations to be the same These declarations are provided for qdoc, but clang says they are the same: template QMetaObject::Connection callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); template QMetaObject::Connection callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection); clang accepts this one, but is it ok for the documentation? template QMetaObject::Connection callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection); Change-Id: I9d63b1bccfa8d73dbc17ab70c4415eb7891fbbe2 Reviewed-by: Martin Smith --- src/corelib/kernel/qtimer.cpp | 2 +- src/corelib/kernel/qtimer.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 13f027074a..9d3bd5fdbf 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -599,7 +599,7 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv */ /*! - \fn template QMetaObject::Connection QTimer::callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection) + \fn template QMetaObject::Connection QTimer::callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection) \since 5.12 \overload callOnTimeout() diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index 66f317c567..336b814b27 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -100,8 +100,8 @@ public: QMetaObject::Connection callOnTimeout(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); template QMetaObject::Connection callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); - template - QMetaObject::Connection callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection); + template + QMetaObject::Connection callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection); #else // singleShot to a QObject slot template -- cgit v1.2.3 From c66c4a844f7fcdc071fb5b57474a3d1cd54047c0 Mon Sep 17 00:00:00 2001 From: Mikhail Svetkin Date: Tue, 20 Mar 2018 14:41:48 +0100 Subject: rtems: Fix detection bad file descriptor RTEMS does not support poll/select and etc for files and fcntl(fd, F_GETFD) can not say that. Change-Id: If5ad160cd81e347fac72d2bafcb5b5bb815ed059 Reviewed-by: Ryan Chu Reviewed-by: Volker Hilsheimer --- src/corelib/kernel/qpoll.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qpoll.cpp b/src/corelib/kernel/qpoll.cpp index 8e93c4d363..8b87bfe79d 100644 --- a/src/corelib/kernel/qpoll.cpp +++ b/src/corelib/kernel/qpoll.cpp @@ -39,6 +39,10 @@ #include "qcore_unix_p.h" +#ifdef Q_OS_RTEMS +#include +#endif + QT_BEGIN_NAMESPACE #define QT_POLL_READ_MASK (POLLIN | POLLRDNORM) @@ -135,6 +139,11 @@ static inline int qt_poll_sweep(struct pollfd *fds, nfds_t nfds, static inline bool qt_poll_is_bad_fd(int fd) { +#ifdef Q_OS_RTEMS + if (!rtems_bsdnet_fdToSocket(fd)) + return true; +#endif + int ret; EINTR_LOOP(ret, fcntl(fd, F_GETFD)); return (ret == -1 && errno == EBADF); -- cgit v1.2.3 From b4ead572501179244aa036e7a590fa7536929f2b Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 14 May 2019 15:04:18 +0200 Subject: Move away from using 0 as a pointer constant Cleans up most of corelib to use nullptr or default enums where appropriate. Change-Id: Ifcaac14ecdaaee730f87f10941db3ce407d71ef9 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qcoreapplication.cpp | 22 +++++------ src/corelib/kernel/qcoreglobaldata.cpp | 4 +- src/corelib/kernel/qmetatype.cpp | 66 ++++++++++++++++++-------------- src/corelib/kernel/qmetatype_p.h | 16 ++++---- src/corelib/kernel/qmetatypeswitcher_p.h | 2 +- src/corelib/kernel/qsystemerror.cpp | 2 +- src/corelib/kernel/qvariant.cpp | 44 ++++++++++----------- 7 files changed, 82 insertions(+), 74 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 72aaac44a6..a48a7c80f2 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -216,11 +216,11 @@ QString QCoreApplicationPrivate::appVersion() const } #endif -QString *QCoreApplicationPrivate::cachedApplicationFilePath = 0; +QString *QCoreApplicationPrivate::cachedApplicationFilePath = nullptr; bool QCoreApplicationPrivate::checkInstance(const char *function) { - bool b = (QCoreApplication::self != 0); + bool b = (QCoreApplication::self != nullptr); if (!b) qWarning("QApplication::%s: Please instantiate the QApplication object first", function); return b; @@ -257,7 +257,7 @@ void QCoreApplicationPrivate::processCommandLineArguments() } if (j < argc) { - argv[j] = 0; + argv[j] = nullptr; argc = j; } } @@ -367,11 +367,11 @@ Q_CORE_EXPORT uint qGlobalPostedEventsCount() return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset; } -QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0; +QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = nullptr; #endif // QT_NO_QOBJECT -QCoreApplication *QCoreApplication::self = 0; +QCoreApplication *QCoreApplication::self = nullptr; uint QCoreApplicationPrivate::attribs = (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) | (1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents); @@ -455,12 +455,12 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint , aboutToQuitEmitted(false) , threadData_clean(false) #else - , q_ptr(0) + , q_ptr(nullptr) #endif { app_compile_version = flags & 0xffffff; static const char *const empty = ""; - if (argc == 0 || argv == 0) { + if (argc == 0 || argv == nullptr) { argc = 0; argv = const_cast(&empty); } @@ -886,7 +886,7 @@ QCoreApplication::~QCoreApplication() { qt_call_post_routines(); - self = 0; + self = nullptr; #ifndef QT_NO_QOBJECT QCoreApplicationPrivate::is_app_closing = true; QCoreApplicationPrivate::is_app_running = false; @@ -894,7 +894,7 @@ QCoreApplication::~QCoreApplication() #if QT_CONFIG(thread) // Synchronize and stop the global thread pool threads. - QThreadPool *globalThreadPool = 0; + QThreadPool *globalThreadPool = nullptr; QT_TRY { globalThreadPool = QThreadPool::globalInstance(); } QT_CATCH (...) { @@ -905,10 +905,10 @@ QCoreApplication::~QCoreApplication() #endif #ifndef QT_NO_QOBJECT - d_func()->threadData->eventDispatcher = 0; + d_func()->threadData->eventDispatcher = nullptr; if (QCoreApplicationPrivate::eventDispatcher) QCoreApplicationPrivate::eventDispatcher->closingDown(); - QCoreApplicationPrivate::eventDispatcher = 0; + QCoreApplicationPrivate::eventDispatcher = nullptr; #endif #if QT_CONFIG(library) diff --git a/src/corelib/kernel/qcoreglobaldata.cpp b/src/corelib/kernel/qcoreglobaldata.cpp index 104be1b87b..7ff222f170 100644 --- a/src/corelib/kernel/qcoreglobaldata.cpp +++ b/src/corelib/kernel/qcoreglobaldata.cpp @@ -48,7 +48,7 @@ Q_GLOBAL_STATIC(QCoreGlobalData, globalInstance) QCoreGlobalData::QCoreGlobalData() #if QT_CONFIG(textcodec) - : codecForLocale(0) + : codecForLocale(nullptr) #endif { } @@ -56,7 +56,7 @@ QCoreGlobalData::QCoreGlobalData() QCoreGlobalData::~QCoreGlobalData() { #if QT_CONFIG(textcodec) - codecForLocale = 0; + codecForLocale = nullptr; QList tmp = allCodecs; allCodecs.clear(); codecCache.clear(); diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 855d36794d..311fb01fd0 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -517,12 +517,12 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE) QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER) QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER) - {0, 0, QMetaType::UnknownType} + {nullptr, 0, QMetaType::UnknownType} }; -Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0; -Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = 0; -Q_CORE_EXPORT const QMetaObject *qMetaObjectWidgetsHelper = 0; +Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = nullptr; +Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = nullptr; +Q_CORE_EXPORT const QMetaObject *qMetaObjectWidgetsHelper = nullptr; class QCustomTypeInfo : public QMetaTypeInterface { @@ -557,7 +557,7 @@ public: { const QWriteLocker locker(&lock); const T* &fun = map[k]; - if (fun != 0) + if (fun) return false; fun = f; return true; @@ -566,7 +566,7 @@ public: const T *function(Key k) const { const QReadLocker locker(&lock); - return map.value(k, 0); + return map.value(k, nullptr); } void remove(int from, int to) @@ -973,7 +973,7 @@ static inline int qMetaTypeStaticType(const char *typeName, int length) The extra \a firstInvalidIndex parameter is an easy way to avoid iterating over customTypes() a second time in registerNormalizedType(). */ -static int qMetaTypeCustomType_unlocked(const char *typeName, int length, int *firstInvalidIndex = 0) +static int qMetaTypeCustomType_unlocked(const char *typeName, int length, int *firstInvalidIndex = nullptr) { const QVector * const ct = customTypes(); if (!ct) @@ -1006,7 +1006,7 @@ int QMetaType::registerType(const char *typeName, Deleter deleter, { return registerType(typeName, deleter, creator, QtMetaTypePrivate::QMetaTypeFunctionHelper::Destruct, - QtMetaTypePrivate::QMetaTypeFunctionHelper::Construct, 0, TypeFlags(), 0); + QtMetaTypePrivate::QMetaTypeFunctionHelper::Construct, 0, TypeFlags(), nullptr); } /*! @@ -1613,7 +1613,7 @@ void *QMetaType::create(int type, const void *copy) QMetaType info(type); if (int size = info.sizeOf()) return info.construct(operator new(size), copy); - return 0; + return nullptr; } /*! @@ -1639,14 +1639,18 @@ class TypeConstructor { static void *Construct(const int type, void *where, const void *copy) { if (QModulesPrivate::QTypeModuleInfo::IsGui) - return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy) : 0; + return Q_LIKELY(qMetaTypeGuiHelper) + ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy) + : nullptr; if (QModulesPrivate::QTypeModuleInfo::IsWidget) - return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy) : 0; + return Q_LIKELY(qMetaTypeWidgetsHelper) + ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy) + : nullptr; // This point can be reached only for known types that definition is not available, for example // in bootstrap mode. We have no other choice then ignore it. - return 0; + return nullptr; } }; public: @@ -1670,7 +1674,7 @@ private: { QReadLocker locker(customTypesLock()); if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)) - return 0; + return nullptr; const auto &typeInfo = ct->at(type - QMetaType::User); ctor = typeInfo.constructor; tctor = typeInfo.typedConstructor; @@ -1715,7 +1719,7 @@ private: void *QMetaType::construct(int type, void *where, const void *copy) { if (!where) - return 0; + return nullptr; TypeConstructor constructor(type, where); return QMetaTypeSwitcher::switcher(constructor, type, copy); } @@ -1861,7 +1865,7 @@ private: int QMetaType::sizeOf(int type) { SizeOf sizeOf(type); - return QMetaTypeSwitcher::switcher(sizeOf, type, 0); + return QMetaTypeSwitcher::switcher(sizeOf, type); } namespace { @@ -1925,7 +1929,7 @@ private: QMetaType::TypeFlags QMetaType::typeFlags(int type) { Flags flags(type); - return static_cast(QMetaTypeSwitcher::switcher(flags, type, 0)); + return static_cast(QMetaTypeSwitcher::switcher(flags, type)); } #ifndef QT_BOOTSTRAPPED @@ -1948,17 +1952,21 @@ public: { static const QMetaObject *MetaObject(int type) { if (QModulesPrivate::QTypeModuleInfo::IsGui) - return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].metaObject : 0; + return Q_LIKELY(qMetaTypeGuiHelper) + ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].metaObject + : nullptr; if (QModulesPrivate::QTypeModuleInfo::IsWidget) - return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].metaObject : 0; + return Q_LIKELY(qMetaTypeWidgetsHelper) + ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].metaObject + : nullptr; return 0; } }; template const QMetaObject *delegate(const T *) { return MetaObjectImpl::MetaObject(m_type); } - const QMetaObject *delegate(const void*) { return 0; } - const QMetaObject *delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; } + const QMetaObject *delegate(const void*) { return nullptr; } + const QMetaObject *delegate(const QMetaTypeSwitcher::UnknownType*) { return nullptr; } const QMetaObject *delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customMetaObject(m_type); } private: const int m_type; @@ -1966,10 +1974,10 @@ private: { const QVector * const ct = customTypes(); if (Q_UNLIKELY(!ct || type < QMetaType::User)) - return 0; + return nullptr; QReadLocker locker(customTypesLock()); if (Q_UNLIKELY(ct->count() <= type - QMetaType::User)) - return 0; + return nullptr; return ct->at(type - QMetaType::User).metaObject; } }; @@ -1987,10 +1995,10 @@ const QMetaObject *QMetaType::metaObjectForType(int type) { #ifndef QT_BOOTSTRAPPED MetaObject mo(type); - return QMetaTypeSwitcher::switcher(mo, type, 0); + return QMetaTypeSwitcher::switcher(mo, type); #else Q_UNUSED(type); - return 0; + return nullptr; #endif } @@ -2187,7 +2195,7 @@ private: QMetaType QMetaType::typeInfo(const int type) { TypeInfo typeInfo(type); - QMetaTypeSwitcher::switcher(typeInfo, type, 0); + QMetaTypeSwitcher::switcher(typeInfo, type); return (typeInfo.info.constructor || typeInfo.info.typedConstructor) ? QMetaType(static_cast(QMetaType::CreateEx | QMetaType::DestroyEx | (typeInfo.info.typedConstructor ? QMetaType::ConstructEx | QMetaType::DestructEx : 0)) @@ -2307,7 +2315,7 @@ void QMetaType::dtor() void *QMetaType::createExtended(const void *copy) const { if (m_typeId == QMetaType::UnknownType) - return 0; + return nullptr; if (Q_UNLIKELY(m_typedConstructor && !m_constructor)) return m_typedConstructor(m_typeId, operator new(m_size), copy); return m_constructor(operator new(m_size), copy); @@ -2387,7 +2395,7 @@ uint QMetaType::sizeExtended() const */ QMetaType::TypeFlags QMetaType::flagsExtended() const { - return 0; + return { }; } /*! @@ -2400,7 +2408,7 @@ QMetaType::TypeFlags QMetaType::flagsExtended() const */ const QMetaObject *QMetaType::metaObjectExtended() const { - return 0; + return nullptr; } @@ -2409,7 +2417,7 @@ namespace QtPrivate const QMetaObject *metaObjectForQWidget() { if (!qMetaTypeWidgetsHelper) - return 0; + return nullptr; return qMetaObjectWidgetsHelper; } } diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 0846193e66..97d6001937 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -140,12 +140,12 @@ public: /*saveOp*/(QtMetaTypePrivate::QMetaTypeFunctionHelper::IsAvailable>::Save), \ /*loadOp*/(QtMetaTypePrivate::QMetaTypeFunctionHelper::IsAvailable>::Load), # define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \ - /*saveOp*/ 0, \ - /*loadOp*/ 0, + /*saveOp*/ nullptr, \ + /*loadOp*/ nullptr, #else # define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \ - /*saveOp*/ 0, \ - /*loadOp*/ 0, + /*saveOp*/ nullptr, \ + /*loadOp*/ nullptr, # define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \ QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) #endif @@ -153,7 +153,7 @@ public: #ifndef QT_BOOTSTRAPPED #define METAOBJECT_DELEGATE(Type) (QtPrivate::MetaObjectForType::value()) #else -#define METAOBJECT_DELEGATE(Type) 0 +#define METAOBJECT_DELEGATE(Type) nullptr #endif #define QT_METATYPE_INTERFACE_INIT_IMPL(Type, DATASTREAM_DELEGATE) \ @@ -184,11 +184,11 @@ public: #define QT_METATYPE_INTERFACE_INIT_EMPTY() \ { \ QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(void) \ - /*constructor*/ 0, \ - /*destructor*/ 0, \ + /*constructor*/ nullptr, \ + /*destructor*/ nullptr, \ /*size*/ 0, \ /*flags*/ 0, \ - /*metaObject*/ 0 , \ + /*metaObject*/ nullptr , \ /*typedConstructor*/ nullptr, \ /*typedDestructor*/ nullptr \ } diff --git a/src/corelib/kernel/qmetatypeswitcher_p.h b/src/corelib/kernel/qmetatypeswitcher_p.h index 154fb8ab7f..dabc70f4b0 100644 --- a/src/corelib/kernel/qmetatypeswitcher_p.h +++ b/src/corelib/kernel/qmetatypeswitcher_p.h @@ -60,7 +60,7 @@ public: class NotBuiltinType; // type is not a built-in type, but it may be a custom type or an unknown type class UnknownType; // type not known to QMetaType system template - static ReturnType switcher(DelegateObject &logic, int type, const void *data); + static ReturnType switcher(DelegateObject &logic, int type, const void *data = nullptr); }; diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp index 9d0394e4a5..a735e12925 100644 --- a/src/corelib/kernel/qsystemerror.cpp +++ b/src/corelib/kernel/qsystemerror.cpp @@ -112,7 +112,7 @@ static QString windowsErrorString(int errorCode) static QString standardLibraryErrorString(int errorCode) { - const char *s = 0; + const char *s = nullptr; QString ret; switch (errorCode) { case 0: diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 1ac47f3972..b9563b8395 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -119,19 +119,19 @@ namespace { // annonymous used to hide QVariant handlers static void construct(QVariant::Private *x, const void *copy) { QVariantConstructor constructor(x, copy); - QMetaTypeSwitcher::switcher(constructor, x->type, 0); + QMetaTypeSwitcher::switcher(constructor, x->type); } static void clear(QVariant::Private *d) { QVariantDestructor cleaner(d); - QMetaTypeSwitcher::switcher(cleaner, d->type, 0); + QMetaTypeSwitcher::switcher(cleaner, d->type); } static bool isNull(const QVariant::Private *d) { QVariantIsNull isNull(d); - return QMetaTypeSwitcher::switcher(isNull, d->type, 0); + return QMetaTypeSwitcher::switcher(isNull, d->type); } /*! @@ -143,7 +143,7 @@ static bool isNull(const QVariant::Private *d) static bool compare(const QVariant::Private *a, const QVariant::Private *b) { QVariantComparator comparator(a, b); - return QMetaTypeSwitcher::switcher(comparator, a->type, 0); + return QMetaTypeSwitcher::switcher(comparator, a->type); } /*! @@ -1401,7 +1401,7 @@ static void streamDebug(QDebug dbg, const QVariant &v) { QVariant::Private *d = const_cast(&v.data_ptr()); QVariantDebugStream stream(dbg, d); - QMetaTypeSwitcher::switcher(stream, d->type, 0); + QMetaTypeSwitcher::switcher(stream, d->type); } #endif @@ -1410,16 +1410,16 @@ const QVariant::Handler qt_kernel_variant_handler = { clear, isNull, #ifndef QT_NO_DATASTREAM - 0, - 0, + nullptr, + nullptr, #endif compare, convert, - 0, + nullptr, #if !defined(QT_NO_DEBUG_STREAM) streamDebug #else - 0 + nullptr #endif }; @@ -1436,16 +1436,16 @@ const QVariant::Handler qt_dummy_variant_handler = { dummyClear, dummyIsNull, #ifndef QT_NO_DATASTREAM - 0, - 0, + nullptr, + nullptr, #endif dummyCompare, dummyConvert, - 0, + nullptr, #if !defined(QT_NO_DEBUG_STREAM) dummyStreamDebug #else - 0 + nullptr #endif }; @@ -1555,16 +1555,16 @@ const QVariant::Handler qt_custom_variant_handler = { customClear, customIsNull, #ifndef QT_NO_DATASTREAM - 0, - 0, + nullptr, + nullptr, #endif customCompare, customConvert, - 0, + nullptr, #if !defined(QT_NO_DEBUG_STREAM) customStreamDebug #else - 0 + nullptr #endif }; @@ -2125,7 +2125,7 @@ QVariant::QVariant(const char *val) */ QVariant::QVariant(Type type) -{ create(type, 0); } +{ create(type, nullptr); } QVariant::QVariant(int typeId, const void *copy) { create(typeId, copy); d.is_null = false; } @@ -2667,7 +2667,7 @@ inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &han return ret; } - handlerManager[d.type]->convert(&d, targetType, &ret, 0); + handlerManager[d.type]->convert(&d, targetType, &ret, nullptr); return ret; } @@ -3217,7 +3217,7 @@ bool QVariant::toBool() const return d.data.b; bool res = false; - handlerManager[d.type]->convert(&d, Bool, &res, 0); + handlerManager[d.type]->convert(&d, Bool, &res, nullptr); return res; } @@ -3735,7 +3735,7 @@ bool QVariant::convert(int targetTypeId) if (!oldValue.canConvert(targetTypeId)) return false; - create(targetTypeId, 0); + create(targetTypeId, nullptr); // Fail if the value is not initialized or was forced null by a previous failed convert. if (oldValue.d.is_null && oldValue.d.type != QMetaType::Nullptr) return false; @@ -3760,7 +3760,7 @@ bool QVariant::convert(int targetTypeId) */ bool QVariant::convert(const int type, void *ptr) const { - return handlerManager[type]->convert(&d, type, ptr, 0); + return handlerManager[type]->convert(&d, type, ptr, nullptr); } -- cgit v1.2.3 From fafae936a68bac1231b2de69b58e8248ae5dca2f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 7 Jun 2019 23:00:53 +0200 Subject: QMetaType: fix an is_pod test that C++11 broke C++11 allows non-POD-types in unions, so the test didn't test anything. Use a static_assert over std::is_pod instead. Change-Id: Ida7ef0551ae6ae07357a987a409294d2a386be2f Reviewed-by: Ville Voutilainen --- src/corelib/kernel/qmetatype.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 311fb01fd0..754f5a13e4 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -587,13 +587,7 @@ QMetaTypeComparatorRegistry; typedef QMetaTypeFunctionRegistry QMetaTypeDebugStreamRegistry; -namespace -{ -union CheckThatItIsPod -{ // This should break if QMetaTypeInterface is not a POD type - QMetaTypeInterface iface; -}; -} +Q_STATIC_ASSERT(std::is_pod::value); Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE); Q_GLOBAL_STATIC(QVector, customTypes) -- cgit v1.2.3 From 242bc539ab6d9e76e1f67f2a51918c79970c2788 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 6 Jun 2019 12:52:15 +0200 Subject: QWeakPointer: use an alternative work-round for internalData() users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous work-around fails, probably because of cross-dependencies. E.g. we have this in QtScXml: In file included from /home/qt/work/install/include/QtCore/qsharedpointer.h:48:0, from ../../src/scxml/qscxmltabledata_p.h:55, from ../../src/scxml/qscxmltabledata.cpp:40: /home/qt/work/install/include/QtCore/qsharedpointer_impl.h:687:12: error: ‘QPointer’ does not name a type; did you mean ‘pointer’? friend QPointer ^~~~~~~~ pointer /home/qt/work/install/include/QtCore/qsharedpointer_impl.h:689:23: error: ‘QSmartPointerConvertFunctor’ in namespace ‘QtPrivate’ does not name a template type friend QtPrivate::QSmartPointerConvertFunctor; ^~~~~~~~~~~~~~~~~~~~~~~~~~~ To fix, grand friendship only to a non-template class with a templated static method that returns internalData(). This fixes most users, except in qmetatype.h, which does not include qsharedpointer.h. In order to use the non-template class in there, we need to delay its name lookup to instantiation time. We do this by artificially making it a dependent name, by using a class template that inherits from our befrieded class. Change-Id: I12b427f1fe9503df819ea5436d780972d6402e68 Reviewed-by: Ville Voutilainen --- src/corelib/kernel/qmetatype.h | 7 ++++++- src/corelib/kernel/qpointer.h | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 154ccf62bb..fef25a32c4 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1715,12 +1715,17 @@ namespace QtPrivate { } }; + // hack to delay name lookup to instantiation time by making + // EnableInternalData a dependent name: + template + struct EnableInternalDataWrap; + template struct QSmartPointerConvertFunctor > { QObject* operator()(const QWeakPointer &p) const { - return p.internalData(); + return QtPrivate::EnableInternalDataWrap::internalData(p); } }; } diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h index 80faef2990..7052bcf0d4 100644 --- a/src/corelib/kernel/qpointer.h +++ b/src/corelib/kernel/qpointer.h @@ -143,7 +143,8 @@ template QPointer qPointerFromVariant(const QVariant &variant) { - return QPointer(qobject_cast(QtSharedPointer::weakPointerFromVariant_internal(variant).internalData())); + const auto wp = QtSharedPointer::weakPointerFromVariant_internal(variant); + return QPointer{qobject_cast(QtPrivate::EnableInternalData::internalData(wp))}; } template -- cgit v1.2.3 From dd3229e6724f05c7c61d6ffc92b5ebfa8ece0b23 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 7 Jun 2019 13:02:03 +0200 Subject: Remove a few usages of deprecated API Change-Id: I94bad0b8d3891c6b4a55178836cfff2a4312e330 Reviewed-by: Marc Mutz --- src/corelib/kernel/qbasictimer.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qbasictimer.cpp b/src/corelib/kernel/qbasictimer.cpp index b16833b34c..ea8f8e2c77 100644 --- a/src/corelib/kernel/qbasictimer.cpp +++ b/src/corelib/kernel/qbasictimer.cpp @@ -105,6 +105,7 @@ QT_BEGIN_NAMESPACE \sa stop(), isActive(), swap() */ +#if QT_DEPRECATED_SINCE(5, 14) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) /*! \internal @@ -125,6 +126,7 @@ QBasicTimer &QBasicTimer::operator=(const QBasicTimer &other) return *this; } #endif +#endif /*! \fn QBasicTimer::~QBasicTimer() -- cgit v1.2.3 From 8d2df3002b3a252686bf094566746cd31dc5d99b Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 12 Jun 2019 15:37:06 +0200 Subject: doc: Fix tr() documentation issue The declaration of tr() in the Q_OBJECT macro interferes with the tr() declaration in the QObject class. This update fixes that bug by resetting QT_TR_FUNCTIONS to be empty and by ensuring that the tr() declaration in class QObject is seen by clang when qdoc is running. Change-Id: If55339fc417f3eee1a1e1ce3df75a18af443d630 Task-number: QTBUG-75864 Reviewed-by: Paul Wicking --- src/corelib/kernel/qobject.h | 3 ++- src/corelib/kernel/qobjectdefs.h | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 63c5a9ad73..fc1d7c956c 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -117,6 +117,7 @@ public: class Q_CORE_EXPORT QObject { Q_OBJECT + Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged) Q_DECLARE_PRIVATE(QObject) @@ -127,7 +128,7 @@ public: virtual bool event(QEvent *event); virtual bool eventFilter(QObject *watched, QEvent *event); -#if defined(QT_NO_TRANSLATION) +#if defined(QT_NO_TRANSLATION) || defined(Q_CLANG_QDOC) static QString tr(const char *sourceText, const char * = nullptr, int = -1) { return QString::fromUtf8(sourceText); } #if QT_DEPRECATED_SINCE(5, 0) diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 059bb44e10..b84e87959a 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -146,6 +146,10 @@ class QString; # define QT_TR_FUNCTIONS #endif +#ifdef Q_CLANG_QDOC +#define QT_TR_FUNCTIONS +#endif + // ### Qt6: remove #define Q_OBJECT_CHECK /* empty, unused since Qt 5.2 */ -- cgit v1.2.3 From d73497cf770c92e38903850267fd8737df3578ca Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 2 May 2019 14:45:35 +0200 Subject: QObject/QWidget::setParent: add assertions to prevent loops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is perfectly possible to accidentally create a parent/child loop. This can happens by direct means (a->setParent(b); b->setParent(a);), or some more subtle means, e.g. class MyClass : public QObject { MyClass() : QObject(this) {} }; Since this is UB, add a few robustness checks to make sure the code above crashes right away (at least in debug builds). Change-Id: I6583c8514b4c1f8a90677b04c77b8e8f0c15dba3 Reviewed-by: Liang Qi Reviewed-by: Sérgio Martins --- src/corelib/kernel/qobject.cpp | 22 ++++++++++++++++++++++ src/corelib/kernel/qobject.h | 4 ++++ 2 files changed, 26 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 965857d408..b4e7568a23 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include #if QT_CONFIG(thread) #include @@ -851,6 +852,8 @@ static bool check_parent_thread(QObject *parent, QObject::QObject(QObject *parent) : d_ptr(new QObjectPrivate) { + Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QObject to itself"); + Q_D(QObject); d_ptr->q_ptr = this; d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current(); @@ -879,6 +882,8 @@ QObject::QObject(QObject *parent) QObject::QObject(QObjectPrivate &dd, QObject *parent) : d_ptr(&dd) { + Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QObject to itself"); + Q_D(QObject); d_ptr->q_ptr = this; d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current(); @@ -2069,8 +2074,25 @@ void QObjectPrivate::deleteChildren() void QObjectPrivate::setParent_helper(QObject *o) { Q_Q(QObject); + Q_ASSERT_X(q != o, Q_FUNC_INFO, "Cannot parent a QObject to itself"); +#ifdef QT_DEBUG + const auto checkForParentChildLoops = qScopeGuard([&](){ + int depth = 0; + auto p = parent; + while (p) { + if (++depth == CheckForParentChildLoopsWarnDepth) { + qWarning("QObject %p (class: '%s', object name: '%s') may have a loop in its parent-child chain; " + "this is undefined behavior", + q, q->metaObject()->className(), qPrintable(q->objectName())); + } + p = p->parent(); + } + }); +#endif + if (o == parent) return; + if (parent) { QObjectPrivate *parentD = parent->d_func(); if (parentD->isDeletingChildren && wasDeleted diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index ad5e1163bf..7f72b69c1a 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -113,6 +113,10 @@ public: int postedEvents; QDynamicMetaObjectData *metaObject; QMetaObject *dynamicMetaObject() const; + +#ifdef QT_DEBUG + enum { CheckForParentChildLoopsWarnDepth = 4096 }; +#endif }; -- cgit v1.2.3 From 079dafc42fdfddbc6bff7d343463e16151afeb2d Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 6 Jun 2019 15:29:01 +0300 Subject: Run prebuilt android test APKs androidtestrunner now checks is the apk is build and if it is, it will skip the build phase. Now we can build the apks in parallel (which takes most of the time) and run them sequentially. This way running tests on Android is much faster. Change-Id: I82f34723ac08f7728cc0daab3366e03821335eed Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/kernel/qsharedmemory.cpp | 19 ++++++++++++++++++- src/corelib/kernel/qsharedmemory.h | 29 ++++++++++++++++++++++++++--- src/corelib/kernel/qsharedmemory_p.h | 12 ++++++++++-- src/corelib/kernel/qsharedmemory_unix.cpp | 7 +++++-- src/corelib/kernel/qsharedmemory_win.cpp | 5 ++++- 5 files changed, 63 insertions(+), 9 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp index c952655cb8..39f3002394 100644 --- a/src/corelib/kernel/qsharedmemory.cpp +++ b/src/corelib/kernel/qsharedmemory.cpp @@ -150,11 +150,18 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key, \sa setKey() */ + +#ifndef QT_NO_QOBJECT QSharedMemory::QSharedMemory(QObject *parent) : QObject(*new QSharedMemoryPrivate, parent) { } - +#else +QSharedMemory::QSharedMemory() + : d_ptr(new QSharedMemoryPrivate) +{ +} +#endif /*! Constructs a shared memory object with the given \a parent and with its key set to \a key. Because its key is set, its create() and @@ -162,11 +169,19 @@ QSharedMemory::QSharedMemory(QObject *parent) \sa setKey(), create(), attach() */ +#ifndef QT_NO_QOBJECT QSharedMemory::QSharedMemory(const QString &key, QObject *parent) : QObject(*new QSharedMemoryPrivate, parent) { setKey(key); } +#else +QSharedMemory::QSharedMemory(const QString &key) + : d_ptr(new QSharedMemoryPrivate) +{ + setKey(key); +} +#endif /*! The destructor clears the key, which forces the shared memory object @@ -604,4 +619,6 @@ QString QSharedMemory::errorString() const QT_END_NAMESPACE +#ifndef QT_NO_QOBJECT #include "moc_qsharedmemory.cpp" +#endif diff --git a/src/corelib/kernel/qsharedmemory.h b/src/corelib/kernel/qsharedmemory.h index 67cf52ac17..6236c6aa4c 100644 --- a/src/corelib/kernel/qsharedmemory.h +++ b/src/corelib/kernel/qsharedmemory.h @@ -40,8 +40,14 @@ #ifndef QSHAREDMEMORY_H #define QSHAREDMEMORY_H -#include - +#include +#ifndef QT_NO_QOBJECT +# include +#else +# include +# include +# include +#endif QT_BEGIN_NAMESPACE @@ -49,9 +55,14 @@ QT_BEGIN_NAMESPACE class QSharedMemoryPrivate; -class Q_CORE_EXPORT QSharedMemory : public QObject +class Q_CORE_EXPORT QSharedMemory +#ifndef QT_NO_QOBJECT + : public QObject +#endif { +#ifndef QT_NO_QOBJECT Q_OBJECT +#endif Q_DECLARE_PRIVATE(QSharedMemory) public: @@ -74,8 +85,17 @@ public: UnknownError }; +#ifndef QT_NO_QOBJECT QSharedMemory(QObject *parent = nullptr); QSharedMemory(const QString &key, QObject *parent = nullptr); +#else + QSharedMemory(); + QSharedMemory(const QString &key); + static QString tr(const char * str) + { + return QString::fromLatin1(str); + } +#endif ~QSharedMemory(); void setKey(const QString &key); @@ -104,6 +124,9 @@ public: private: Q_DISABLE_COPY(QSharedMemory) +#ifdef QT_NO_QOBJECT + QScopedPointer d_ptr; +#endif }; #endif // QT_NO_SHAREDMEMORY diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h index bf7c42dc62..e6e989abda 100644 --- a/src/corelib/kernel/qsharedmemory_p.h +++ b/src/corelib/kernel/qsharedmemory_p.h @@ -67,7 +67,10 @@ namespace QSharedMemoryPrivate #else #include "qsystemsemaphore.h" -#include "private/qobject_p.h" + +#ifndef QT_NO_QOBJECT +# include "private/qobject_p.h" +#endif #if !defined(Q_OS_WIN) && !defined(Q_OS_ANDROID) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_RTEMS) # include @@ -107,9 +110,14 @@ private: }; #endif // QT_NO_SYSTEMSEMAPHORE -class Q_AUTOTEST_EXPORT QSharedMemoryPrivate : public QObjectPrivate +class Q_AUTOTEST_EXPORT QSharedMemoryPrivate +#ifndef QT_NO_QOBJECT + : public QObjectPrivate +#endif { +#ifndef QT_NO_QOBJECT Q_DECLARE_PUBLIC(QSharedMemory) +#endif public: QSharedMemoryPrivate(); diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp index d1d44747e0..f6d7e78441 100644 --- a/src/corelib/kernel/qsharedmemory_unix.cpp +++ b/src/corelib/kernel/qsharedmemory_unix.cpp @@ -64,8 +64,11 @@ #ifndef QT_NO_SHAREDMEMORY QT_BEGIN_NAMESPACE -QSharedMemoryPrivate::QSharedMemoryPrivate() - : QObjectPrivate(), memory(0), size(0), error(QSharedMemory::NoError), +QSharedMemoryPrivate::QSharedMemoryPrivate() : +#ifndef QT_NO_QOBJECT + QObjectPrivate(), +#endif + memory(0), size(0), error(QSharedMemory::NoError), #ifndef QT_NO_SYSTEMSEMAPHORE systemSemaphore(QString()), lockedByMe(false), #endif diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp index c1dba30e2b..02de2339a5 100644 --- a/src/corelib/kernel/qsharedmemory_win.cpp +++ b/src/corelib/kernel/qsharedmemory_win.cpp @@ -47,7 +47,10 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_SHAREDMEMORY -QSharedMemoryPrivate::QSharedMemoryPrivate() : QObjectPrivate(), +QSharedMemoryPrivate::QSharedMemoryPrivate() : +#ifndef QT_NO_QOBJECT + QObjectPrivate(), +#endif memory(0), size(0), error(QSharedMemory::NoError), systemSemaphore(QString()), lockedByMe(false), hand(0) { -- cgit v1.2.3 From a1516c3b93174af25fe2bb4fe7f1ec1973cebe81 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 6 May 2019 09:47:19 +0200 Subject: Windows: Add debug output for message WM_DPICHANGED Add it to the name lookup and add verbose formatting to the debug operator. Task-number: QTBUG-73014 Change-Id: I31ee31bc28ef563fdbc0adedcea03546ced5faad Reviewed-by: Oliver Wolff --- src/corelib/kernel/qcoreapplication_win.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index b373267fcb..75cc813298 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -48,6 +48,7 @@ #include "qmutex.h" #include #endif +#include "qtextstream.h" #include #include @@ -480,6 +481,7 @@ static const char *findWMstr(uint msg) { 0x02DD, "WM_TABLET_FIRST + 29" }, { 0x02DE, "WM_TABLET_FIRST + 30" }, { 0x02DF, "WM_TABLET_LAST" }, + { 0x02E0, "WM_DPICHANGED" }, { 0x0300, "WM_CUT" }, { 0x0301, "WM_COPY" }, { 0x0302, "WM_PASTE" }, @@ -765,6 +767,13 @@ QString decodeMSG(const MSG& msg) case WM_DESTROY: parameters = QLatin1String("Destroy hwnd ") + hwndS; break; + case 0x02E0u: { // WM_DPICHANGED + auto rect = reinterpret_cast(lParam); + QTextStream(¶meters) << "DPI: " << HIWORD(wParam) << ',' + << LOWORD(wParam) << ' ' << (rect->right - rect->left) << 'x' + << (rect->bottom - rect->top) << forcesign << rect->left << rect->top; + } + break; case WM_IME_NOTIFY: { parameters = QLatin1String("Command("); -- cgit v1.2.3 From c6bee8e4b2c48775247c67ef8e7569f623655c61 Mon Sep 17 00:00:00 2001 From: Konstantin Shegunov Date: Wed, 1 Aug 2018 00:50:14 +0300 Subject: Fix integer overflows in QDeadlineTimer If the deadline is far in the future, the conversions to nanoseconds or internal arithmetic may overflow and give an invalid object, thus the deadline may end up in the past. Added a test to the testlib selftest for sleep. [ChangeLog][QtCore][QDeadlineTimer] Fixed integer overflows leading to immediate timeouts. Task-number: QTBUG-69750 Change-Id: I9814eccdf9f9b3add9ca66ec3e27e10cd5ad54a8 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qdeadlinetimer.cpp | 440 +++++++++++++++++++++++++++++----- src/corelib/kernel/qdeadlinetimer.h | 3 +- 2 files changed, 383 insertions(+), 60 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index 6aa886cfe1..49874b94b4 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -39,18 +39,294 @@ #include "qdeadlinetimer.h" #include "qdeadlinetimer_p.h" +#include "private/qnumeric_p.h" QT_BEGIN_NAMESPACE -Q_DECL_CONST_FUNCTION static inline QPair toSecsAndNSecs(qint64 nsecs) +namespace { + class TimeReference + { + enum : unsigned { + umega = 1000 * 1000, + ugiga = umega * 1000 + }; + + enum : qint64 { + kilo = 1000, + mega = kilo * 1000, + giga = mega * 1000 + }; + + public: + enum RoundingStrategy { + RoundDown, + RoundUp, + RoundDefault = RoundDown + }; + + static constexpr qint64 Min = std::numeric_limits::min(); + static constexpr qint64 Max = std::numeric_limits::max(); + + inline TimeReference(qint64 = 0, unsigned = 0); + inline void updateTimer(qint64 &, unsigned &); + + inline bool addNanoseconds(qint64); + inline bool addMilliseconds(qint64); + bool addSecsAndNSecs(qint64, qint64); + + inline bool subtract(const qint64, const unsigned); + + inline bool toMilliseconds(qint64 *, RoundingStrategy = RoundDefault) const; + inline bool toNanoseconds(qint64 *) const; + + inline void saturate(bool toMax); + static bool sign(qint64, qint64); + + private: + bool adjust(const qint64, const unsigned, qint64 = 0); + + private: + qint64 secs; + unsigned nsecs; + }; +} + +inline TimeReference::TimeReference(qint64 t1, unsigned t2) + : secs(t1), nsecs(t2) +{ +} + +inline void TimeReference::updateTimer(qint64 &t1, unsigned &t2) +{ + t1 = secs; + t2 = nsecs; +} + +inline void TimeReference::saturate(bool toMax) +{ + secs = toMax ? Max : Min; +} + +/*! + * \internal + * + * Determines the sign of a (seconds, nanoseconds) pair + * for differentiating overflow from underflow. It doesn't + * deal with equality as it shouldn't ever be called in that case. + * + * Returns true if the pair represents a positive time offset + * false otherwise. + */ +bool TimeReference::sign(qint64 secs, qint64 nsecs) +{ + if (secs > 0) { + if (nsecs > 0) + return true; + } else { + if (nsecs < 0) + return false; + } + + // They are different in sign + secs += nsecs / giga; + if (secs > 0) + return true; + else if (secs < 0) + return false; + + // We should never get over|underflow out of + // the case: secs * giga == -nsecs + // So the sign of nsecs is the deciding factor + Q_ASSERT(nsecs % giga != 0); + return nsecs > 0; +} + +#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) +inline bool TimeReference::addNanoseconds(qint64 arg) +{ + return addSecsAndNSecs(arg / giga, arg % giga); +} + +inline bool TimeReference::addMilliseconds(qint64 arg) +{ + return addSecsAndNSecs(arg / kilo, (arg % kilo) * mega); +} + +/*! + * \internal + * + * Adds \a t1 addSecs seconds and \a addNSecs nanoseconds to the + * time reference. The arguments are normalized to seconds (qint64) + * and nanoseconds (unsigned) before the actual calculation is + * delegated to adjust(). If the nanoseconds are negative the + * owed second used for the normalization is passed on to adjust() + * as third argument. + * + * Returns true if operation was successful, false on over|underflow + */ +bool TimeReference::addSecsAndNSecs(qint64 addSecs, qint64 addNSecs) +{ + // Normalize the arguments + if (qAbs(addNSecs) >= giga) { + if (add_overflow(addSecs, addNSecs / giga, &addSecs)) + return false; + + addNSecs %= giga; + } + + if (addNSecs < 0) + return adjust(addSecs, ugiga - unsigned(-addNSecs), -1); + + return adjust(addSecs, unsigned(addNSecs)); +} + +/*! + * \internal + * + * Adds \a t1 seconds and \a t2 nanoseconds to the internal members. + * Takes into account the additional \a carrySeconds we may owe or need to carry over. + * + * Returns true if operation was successful, false on over|underflow + */ +bool TimeReference::adjust(const qint64 t1, const unsigned t2, qint64 carrySeconds) +{ + Q_STATIC_ASSERT(QDeadlineTimerNanosecondsInT2); + nsecs += t2; + if (nsecs >= ugiga) { + nsecs -= ugiga; + carrySeconds++; + } + + // We don't worry about the order of addition, because the result returned by + // callers of this function is unchanged regardless of us over|underflowing. + // If we do, we do so by no more than a second, thus saturating the timer to + // Forever has the same effect as if we did the arithmetic exactly and salvaged + // the overflow. + return !add_overflow(secs, t1, &secs) && !add_overflow(secs, carrySeconds, &secs); +} + +/*! + * \internal + * + * Subtracts \a t1 seconds and \a t2 nanoseconds from the time reference. + * When normalizing the nanoseconds to a positive number the owed seconds is + * passed as third argument to adjust() as the seconds may over|underflow + * if we do the calculation directly. There is little sense to check the + * seconds for over|underflow here in case we are going to need to carry + * over a second _after_ we add the nanoseconds. + * + * Returns true if operation was successful, false on over|underflow + */ +inline bool TimeReference::subtract(const qint64 t1, const unsigned t2) +{ + Q_ASSERT(t2 < ugiga); + return adjust(-t1, ugiga - t2, -1); +} + +/*! + * \internal + * + * Converts the time reference to milliseconds. + * + * Checks are done without making use of mul_overflow because it may + * not be implemented on some 32bit platforms. + * + * Returns true if operation was successful, false on over|underflow + */ +inline bool TimeReference::toMilliseconds(qint64 *result, RoundingStrategy rounding) const +{ + static constexpr qint64 maxSeconds = Max / kilo; + static constexpr qint64 minSeconds = Min / kilo; + if (secs > maxSeconds || secs < minSeconds) + return false; + + unsigned ns = rounding == RoundDown ? nsecs : nsecs + umega - 1; + + return !add_overflow(secs * kilo, ns / umega, result); +} + +/*! + * \internal + * + * Converts the time reference to nanoseconds. + * + * Checks are done without making use of mul_overflow because it may + * not be implemented on some 32bit platforms. + * + * Returns true if operation was successful, false on over|underflow + */ +inline bool TimeReference::toNanoseconds(qint64 *result) const +{ + static constexpr qint64 maxSeconds = Max / giga; + static constexpr qint64 minSeconds = Min / giga; + if (secs > maxSeconds || secs < minSeconds) + return false; + + return !add_overflow(secs * giga, nsecs, result); +} +#else +inline bool TimeReference::addNanoseconds(qint64 arg) +{ + return adjust(arg, 0); +} + +inline bool TimeReference::addMilliseconds(qint64 arg) +{ + static constexpr qint64 maxMilliseconds = Max / mega; + if (qAbs(arg) > maxMilliseconds) + return false; + + return addNanoseconds(arg * mega); +} + +inline bool TimeReference::addSecsAndNSecs(qint64 addSecs, qint64 addNSecs) { - qint64 secs = nsecs / (1000*1000*1000); - if (nsecs < 0) - --secs; - nsecs -= secs * 1000*1000*1000; - return qMakePair(secs, nsecs); + static constexpr qint64 maxSeconds = Max / giga; + static constexpr qint64 minSeconds = Min / giga; + if (addSecs > maxSeconds || addSecs < minSeconds || add_overflow(addSecs * giga, addNSecs, &addNSecs)) + return false; + + return addNanoseconds(addNSecs); } +inline bool TimeReference::adjust(const qint64 t1, const unsigned t2, qint64 carrySeconds) +{ + Q_STATIC_ASSERT(!QDeadlineTimerNanosecondsInT2); + Q_UNUSED(t2); + Q_UNUSED(carrySeconds); + + return !add_overflow(secs, t1, &secs); +} + +inline bool TimeReference::subtract(const qint64 t1, const unsigned t2) +{ + Q_UNUSED(t2); + + return addNanoseconds(-t1); +} + +inline bool TimeReference::toMilliseconds(qint64 *result, RoundingStrategy rounding) const +{ + // Force QDeadlineTimer to treat the border cases as + // over|underflow and saturate the results returned to the user. + // We don't want to get valid milliseconds out of saturated timers. + if (secs == Max || secs == Min) + return false; + + *result = secs / mega; + if (rounding == RoundUp && secs > *result * mega) + (*result)++; + + return true; +} + +inline bool TimeReference::toNanoseconds(qint64 *result) const +{ + *result = secs; + return true; +} +#endif + /*! \class QDeadlineTimer \inmodule QtCore @@ -262,10 +538,17 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW */ void QDeadlineTimer::setRemainingTime(qint64 msecs, Qt::TimerType timerType) Q_DECL_NOTHROW { - if (msecs == -1) + if (msecs == -1) { *this = QDeadlineTimer(Forever, timerType); - else - setPreciseRemainingTime(0, msecs * 1000 * 1000, timerType); + return; + } + + *this = current(timerType); + + TimeReference ref(t1, t2); + if (!ref.addMilliseconds(msecs)) + ref.saturate(msecs > 0); + ref.updateTimer(t1, t2); } /*! @@ -287,16 +570,10 @@ void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::Time } *this = current(timerType); - if (QDeadlineTimerNanosecondsInT2) { - t1 += secs + toSecsAndNSecs(nsecs).first; - t2 += toSecsAndNSecs(nsecs).second; - if (t2 > 1000*1000*1000) { - t2 -= 1000*1000*1000; - ++t1; - } - } else { - t1 += secs * 1000 * 1000 * 1000 + nsecs; - } + TimeReference ref(t1, t2); + if (!ref.addSecsAndNSecs(secs, nsecs)) + ref.saturate(TimeReference::sign(secs, nsecs)); + ref.updateTimer(t1, t2); } /*! @@ -391,8 +668,22 @@ void QDeadlineTimer::setTimerType(Qt::TimerType timerType) */ qint64 QDeadlineTimer::remainingTime() const Q_DECL_NOTHROW { - qint64 ns = remainingTimeNSecs(); - return ns <= 0 ? ns : (ns + 999999) / (1000 * 1000); + if (isForever()) + return -1; + + QDeadlineTimer now = current(timerType()); + TimeReference ref(t1, t2); + + qint64 msecs; + if (!ref.subtract(now.t1, now.t2)) + return 0; // We can only underflow here + + // If we fail the conversion, t1 < now.t1 means we underflowed, + // thus the deadline had long expired + if (!ref.toMilliseconds(&msecs, TimeReference::RoundUp)) + return t1 < now.t1 ? 0 : -1; + + return msecs < 0 ? 0 : msecs; } /*! @@ -414,14 +705,23 @@ qint64 QDeadlineTimer::remainingTimeNSecs() const Q_DECL_NOTHROW /*! \internal Same as remainingTimeNSecs, but may return negative remaining times. Does - not deal with Forever. + not deal with Forever. In case of underflow the result is saturated to + the minimum possible value, on overflow - the maximum possible value. */ qint64 QDeadlineTimer::rawRemainingTimeNSecs() const Q_DECL_NOTHROW { QDeadlineTimer now = current(timerType()); - if (QDeadlineTimerNanosecondsInT2) - return (t1 - now.t1) * (1000*1000*1000) + t2 - now.t2; - return t1 - now.t1; + TimeReference ref(t1, t2); + + qint64 nsecs; + if (!ref.subtract(now.t1, now.t2)) + return TimeReference::Min; // We can only underflow here + + // If we fail the conversion, t1 < now.t1 means we underflowed, + // thus the deadline had long expired + if (!ref.toNanoseconds(&nsecs)) + return t1 < now.t1 ? TimeReference::Min : TimeReference::Max; + return nsecs; } /*! @@ -447,8 +747,13 @@ qint64 QDeadlineTimer::rawRemainingTimeNSecs() const Q_DECL_NOTHROW qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW { if (isForever()) - return t1; - return deadlineNSecs() / (1000 * 1000); + return TimeReference::Max; + + qint64 result; + if (!TimeReference(t1, t2).toMilliseconds(&result)) + return t1 < 0 ? TimeReference::Min : TimeReference::Max; + + return result; } /*! @@ -457,7 +762,8 @@ qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW same as QElapsedTimer::msecsSinceReference(). The value will be in the past if this QDeadlineTimer has expired. - If this QDeadlineTimer never expires, this function returns + If this QDeadlineTimer never expires or the number of nanoseconds until the + deadline can't be accommodated in the return type, this function returns \c{std::numeric_limits::max()}. This function can be used to calculate the amount of time a timer is @@ -474,10 +780,13 @@ qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW qint64 QDeadlineTimer::deadlineNSecs() const Q_DECL_NOTHROW { if (isForever()) - return t1; - if (QDeadlineTimerNanosecondsInT2) - return t1 * 1000 * 1000 * 1000 + t2; - return t1; + return TimeReference::Max; + + qint64 result; + if (!TimeReference(t1, t2).toNanoseconds(&result)) + return t1 < 0 ? TimeReference::Min : TimeReference::Max; + + return result; } /*! @@ -487,18 +796,25 @@ qint64 QDeadlineTimer::deadlineNSecs() const Q_DECL_NOTHROW timerType. If the value is in the past, this QDeadlineTimer will be marked as expired. - If \a msecs is \c{std::numeric_limits::max()}, this QDeadlineTimer - will be set to never expire. + If \a msecs is \c{std::numeric_limits::max()} or the deadline is + beyond a representable point in the future, this QDeadlineTimer will be set + to never expire. \sa setPreciseDeadline(), deadline(), deadlineNSecs(), setRemainingTime() */ void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) Q_DECL_NOTHROW { - if (msecs == (std::numeric_limits::max)()) { - setPreciseDeadline(msecs, 0, timerType); // msecs == MAX implies Forever - } else { - setPreciseDeadline(msecs / 1000, msecs % 1000 * 1000 * 1000, timerType); + if (msecs == TimeReference::Max) { + *this = QDeadlineTimer(Forever, timerType); + return; } + + type = timerType; + + TimeReference ref; + if (!ref.addMilliseconds(msecs)) + ref.saturate(msecs > 0); + ref.updateTimer(t1, t2); } /*! @@ -516,14 +832,13 @@ void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) Q_DECL_N void QDeadlineTimer::setPreciseDeadline(qint64 secs, qint64 nsecs, Qt::TimerType timerType) Q_DECL_NOTHROW { type = timerType; - if (secs == (std::numeric_limits::max)() || nsecs == (std::numeric_limits::max)()) { - *this = QDeadlineTimer(Forever, timerType); - } else if (QDeadlineTimerNanosecondsInT2) { - t1 = secs + toSecsAndNSecs(nsecs).first; - t2 = toSecsAndNSecs(nsecs).second; - } else { - t1 = secs * (1000*1000*1000) + nsecs; - } + + // We don't pass the seconds to the constructor, because we don't know + // at this point if t1 holds the seconds or nanoseconds; it's platform specific. + TimeReference ref; + if (!ref.addSecsAndNSecs(secs, nsecs)) + ref.saturate(TimeReference::sign(secs, nsecs)); + ref.updateTimer(t1, t2); } /*! @@ -536,18 +851,14 @@ void QDeadlineTimer::setPreciseDeadline(qint64 secs, qint64 nsecs, Qt::TimerType */ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_NOTHROW { - if (dt.isForever() || nsecs == (std::numeric_limits::max)()) { - dt = QDeadlineTimer(Forever, dt.timerType()); - } else if (QDeadlineTimerNanosecondsInT2) { - dt.t1 += toSecsAndNSecs(nsecs).first; - dt.t2 += toSecsAndNSecs(nsecs).second; - if (dt.t2 > 1000*1000*1000) { - dt.t2 -= 1000*1000*1000; - ++dt.t1; - } - } else { - dt.t1 += nsecs; - } + if (dt.isForever()) + return dt; + + TimeReference ref(dt.t1, dt.t2); + if (!ref.addNanoseconds(nsecs)) + ref.saturate(nsecs > 0); + ref.updateTimer(dt.t1, dt.t2); + return dt; } @@ -656,6 +967,19 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ To add times of precision greater than 1 millisecond, use addNSecs(). */ +QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs) +{ + if (dt.isForever()) + return dt; + + TimeReference ref(dt.t1, dt.t2); + if (!ref.addMilliseconds(msecs)) + ref.saturate(msecs > 0); + ref.updateTimer(dt.t1, dt.t2); + + return dt; +} + /*! \fn QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt) \relates QDeadlineTimer diff --git a/src/corelib/kernel/qdeadlinetimer.h b/src/corelib/kernel/qdeadlinetimer.h index 1a4ee04a96..f9ad4063e5 100644 --- a/src/corelib/kernel/qdeadlinetimer.h +++ b/src/corelib/kernel/qdeadlinetimer.h @@ -108,8 +108,7 @@ public: friend bool operator>=(QDeadlineTimer d1, QDeadlineTimer d2) Q_DECL_NOTHROW { return !(d1 < d2); } - friend QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs) - { return QDeadlineTimer::addNSecs(dt, msecs * 1000 * 1000); } + friend Q_CORE_EXPORT QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs); friend QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt) { return dt + msecs; } friend QDeadlineTimer operator-(QDeadlineTimer dt, qint64 msecs) -- cgit v1.2.3 From e9e16c7464364fd15f69e3f37a9ed3edb15b633b Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Mon, 3 Dec 2018 17:00:53 +0000 Subject: Warn when setting attributes after QCoreApplication is created It's a recurring bug seen in user code and a warning will help reduce it. Warns only for the attributes that have such requirement in the docs, but maybe we should be more strict and warn for any attribute. Change-Id: I68148521953221ad0e8be1028181f52a7f22d2cc Reviewed-by: Giuseppe D'Angelo --- src/corelib/kernel/qcoreapplication.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e5f39a8d35..8652c45634 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -46,6 +46,7 @@ #include "qcoreevent.h" #include "qeventloop.h" #endif +#include "qmetaobject.h" #include "qcorecmdlineargs_p.h" #include #include @@ -966,6 +967,10 @@ bool QCoreApplication::isSetuidAllowed() Sets the attribute \a attribute if \a on is true; otherwise clears the attribute. + \note Some application attributes must be set \b before creating a + QCoreApplication instance. Refer to the Qt::ApplicationAttribute + documentation for more information. + \sa testAttribute() */ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on) @@ -974,6 +979,27 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on) QCoreApplicationPrivate::attribs |= 1 << attribute; else QCoreApplicationPrivate::attribs &= ~(1 << attribute); + if (Q_UNLIKELY(qApp)) { + switch (attribute) { + case Qt::AA_EnableHighDpiScaling: + case Qt::AA_DisableHighDpiScaling: + case Qt::AA_PluginApplication: + case Qt::AA_UseDesktopOpenGL: + case Qt::AA_UseOpenGLES: + case Qt::AA_UseSoftwareOpenGL: + case Qt::AA_ShareOpenGLContexts: +#ifdef QT_BOOTSTRAPPED + qWarning("Attribute %d must be set before QCoreApplication is created.", + attribute); +#else + qWarning("Attribute Qt::%s must be set before QCoreApplication is created.", + QMetaEnum::fromType().valueToKey(attribute)); +#endif + break; + default: + break; + } + } } /*! -- cgit v1.2.3 From 2ed4fcca196ac3fd34a3e41f2e0b3d346a5470b9 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 15 May 2019 11:33:57 +0200 Subject: Update QMetaEnum::fromType()'s static assert's error message QMetaEnum fromType() also works for enums declared with Q_{ENUM,FLAG}_NS. This hadn't been added to the message when we added Q_{ENUM,FLAG}_NS. Fixes: QTBUG-75829 Change-Id: Ib71dae83dd8d837adf46b73cd299b8e61bdb1f64 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetaobject.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 51ace3d5f7..1efb49017f 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -230,7 +230,8 @@ public: template static QMetaEnum fromType() { Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper::Value, - "QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG"); + "QMetaEnum::fromType only works with enums declared as " + "Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS"); const QMetaObject *metaObject = qt_getEnumMetaObject(T()); const char *name = qt_getEnumName(T()); return metaObject->enumerator(metaObject->indexOfEnumerator(name)); -- cgit v1.2.3 From a67b25067ee78e0c2bc4e77a4c61af43528d9bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 27 May 2019 18:36:13 +0200 Subject: Rename QMacScopedObserver to the more fittingly QMacNotificationObserver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1d8280fe88871572a3a27e612de49717b3b9ef77 Reviewed-by: Tor Arne Vestbø --- src/corelib/kernel/qcore_mac_p.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index f96e7358a2..2428faed15 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -295,13 +295,13 @@ QT_MAC_WEAK_IMPORT(_os_activity_current); // ------------------------------------------------------------------------- #if defined( __OBJC__) -class QMacScopedObserver +class QMacNotificationObserver { public: - QMacScopedObserver() {} + QMacNotificationObserver() {} template - QMacScopedObserver(id object, NSNotificationName name, Functor callback) { + QMacNotificationObserver(id object, NSNotificationName name, Functor callback) { observer = [[NSNotificationCenter defaultCenter] addObserverForName:name object:object queue:nil usingBlock:^(NSNotification *) { callback(); @@ -309,13 +309,13 @@ public: ]; } - QMacScopedObserver(const QMacScopedObserver& other) = delete; - QMacScopedObserver(QMacScopedObserver&& other) : observer(other.observer) { + QMacNotificationObserver(const QMacNotificationObserver& other) = delete; + QMacNotificationObserver(QMacNotificationObserver&& other) : observer(other.observer) { other.observer = nil; } - QMacScopedObserver &operator=(const QMacScopedObserver& other) = delete; - QMacScopedObserver &operator=(QMacScopedObserver&& other) { + QMacNotificationObserver &operator=(const QMacNotificationObserver& other) = delete; + QMacNotificationObserver &operator=(QMacNotificationObserver&& other) { if (this != &other) { remove(); observer = other.observer; @@ -329,7 +329,7 @@ public: [[NSNotificationCenter defaultCenter] removeObserver:observer]; observer = nil; } - ~QMacScopedObserver() { remove(); } + ~QMacNotificationObserver() { remove(); } private: id observer = nil; -- cgit v1.2.3 From 2dfe0f8f6854f518e8ffb23e17cc99400355cc3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 29 May 2019 17:00:40 +0200 Subject: macOS: Introduce QMacKeyValueObserver and use in theme and style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2d21c883628933543ae5a66b694ff7503119bc4a Reviewed-by: Tor Arne Vestbø --- src/corelib/kernel/qcore_mac_objc.mm | 31 ++++++++++++++++++++ src/corelib/kernel/qcore_mac_p.h | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 4550891e2a..9139b372a8 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -514,5 +514,36 @@ Q_CONSTRUCTOR_FUNCTION(qt_apple_check_os_version); // ------------------------------------------------------------------------- +void QMacKeyValueObserver::addObserver() +{ + [object addObserver:observer forKeyPath:keyPath + options:NSKeyValueObservingOptionNew context:callback.get()]; +} + +void QMacKeyValueObserver::removeObserver() { + if (object) + [object removeObserver:observer forKeyPath:keyPath context:callback.get()]; + object = nil; +} + +KeyValueObserver *QMacKeyValueObserver::observer = [[KeyValueObserver alloc] init]; + +QT_END_NAMESPACE +@implementation KeyValueObserver +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object + change:(NSDictionary *)change context:(void *)context +{ + Q_UNUSED(keyPath); + Q_UNUSED(object); + Q_UNUSED(change); + + (*reinterpret_cast(context))(); +} +@end +QT_BEGIN_NAMESPACE + +// ------------------------------------------------------------------------- + + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index 2428faed15..8f4c96bbd6 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -67,6 +67,7 @@ #ifdef __OBJC__ #include +#include #endif #include "qstring.h" @@ -334,6 +335,60 @@ public: private: id observer = nil; }; + +QT_END_NAMESPACE +@interface QT_MANGLE_NAMESPACE(KeyValueObserver) : NSObject +@end +QT_NAMESPACE_ALIAS_OBJC_CLASS(KeyValueObserver); +QT_BEGIN_NAMESPACE + +class Q_CORE_EXPORT QMacKeyValueObserver +{ +public: + using Callback = std::function; + + QMacKeyValueObserver() {} + + // Note: QMacKeyValueObserver must not outlive the object observed! + QMacKeyValueObserver(id object, NSString *keyPath, Callback callback) + : object(object), keyPath(keyPath), callback(new Callback(callback)) { addObserver(); } + + QMacKeyValueObserver(const QMacKeyValueObserver &other) + : QMacKeyValueObserver(other.object, other.keyPath, *other.callback.get()) {} + + QMacKeyValueObserver(QMacKeyValueObserver &&other) { swap(other, *this); } + + ~QMacKeyValueObserver() { removeObserver(); } + + QMacKeyValueObserver &operator=(const QMacKeyValueObserver &other) { + QMacKeyValueObserver tmp(other); + swap(tmp, *this); + return *this; + } + + QMacKeyValueObserver &operator=(QMacKeyValueObserver &&other) { + QMacKeyValueObserver tmp(std::move(other)); + swap(tmp, *this); + return *this; + } + + void removeObserver(); + +private: + void swap(QMacKeyValueObserver &first, QMacKeyValueObserver &second) { + std::swap(first.object, second.object); + std::swap(first.keyPath, second.keyPath); + std::swap(first.callback, second.callback); + } + + void addObserver(); + + id object = nil; + NSString *keyPath = nullptr; + std::unique_ptr callback; + + static KeyValueObserver *observer; +}; #endif // ------------------------------------------------------------------------- -- cgit v1.2.3 From 84e89c1e9e00d4fab576b876cfa80e92b5602982 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 12 Jun 2019 18:06:23 +0200 Subject: Convert uses of QTime as a timer to QElapsedTimer Change-Id: I2297f61efa5adf9ea5194c7f3ff68574cbcf452c Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qelapsedtimer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qelapsedtimer.cpp b/src/corelib/kernel/qelapsedtimer.cpp index adb554b624..57825583dd 100644 --- a/src/corelib/kernel/qelapsedtimer.cpp +++ b/src/corelib/kernel/qelapsedtimer.cpp @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE \snippet qelapsedtimer/main.cpp 0 In this example, the timer is started by a call to start() and the - elapsed timer is calculated by the elapsed() function. + elapsed time is calculated by the elapsed() function. The time elapsed can also be used to recalculate the time available for another operation, after the first one is complete. This is useful when -- cgit v1.2.3 From 34fe9232dbf6a9fe58ebc4c7680bb67d2f642c40 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Mon, 10 Jun 2019 11:08:29 +0200 Subject: Port from QAtomic::load() to loadRelaxed() Semi-automated, just needed ~20 manual fixes: $ find \( -iname \*.cpp -or -iname \*.h \) -exec perl -pe 's/(\.|->)load\(\)/$1loadRelaxed\(\)/g' -i \{\} + $ find \( -iname \*.cpp -or -iname \*.h \) -exec perl -pe 's/(\.|->)store\(/$1storeRelaxed\(/g' -i \{\} + It can be easily improved (e.g. for store check that there are no commas after the opening parens). The most common offender is QLibrary::load, and some code using std::atomic directly. Change-Id: I07c38a3c8ed32c924ef4999e85c7e45cf48f0f6c Reviewed-by: Marc Mutz --- src/corelib/kernel/qabstracteventdispatcher.cpp | 2 +- src/corelib/kernel/qcore_unix_p.h | 4 +- src/corelib/kernel/qcoreapplication.cpp | 16 +- src/corelib/kernel/qcoreevent.cpp | 6 +- src/corelib/kernel/qeventdispatcher_glib.cpp | 6 +- src/corelib/kernel/qeventdispatcher_unix.cpp | 8 +- src/corelib/kernel/qeventdispatcher_win.cpp | 14 +- src/corelib/kernel/qeventloop.cpp | 10 +- src/corelib/kernel/qeventloop_p.h | 4 +- src/corelib/kernel/qmetatype.h | 2 +- src/corelib/kernel/qobject.cpp | 256 ++++++++++++------------ src/corelib/kernel/qobject_p.h | 28 +-- src/corelib/kernel/qsocketnotifier.cpp | 6 +- src/corelib/kernel/qvariant.cpp | 2 +- src/corelib/kernel/qvariant.h | 2 +- src/corelib/kernel/qwineventnotifier.cpp | 6 +- 16 files changed, 186 insertions(+), 186 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 186c2e743b..7215b3f2bd 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -170,7 +170,7 @@ QAbstractEventDispatcher::~QAbstractEventDispatcher() QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread) { QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current(); - return data->eventDispatcher.load(); + return data->eventDispatcher.loadRelaxed(); } /*! diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 7f58813535..b56c2b9732 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -164,7 +164,7 @@ inline void qt_ignore_sigpipe() { // Set to ignore SIGPIPE once only. static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0); - if (!atom.load()) { + if (!atom.loadRelaxed()) { // More than one thread could turn off SIGPIPE at the same time // But that's acceptable because they all would be doing the same // action @@ -172,7 +172,7 @@ inline void qt_ignore_sigpipe() memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; ::sigaction(SIGPIPE, &noaction, nullptr); - atom.store(1); + atom.storeRelaxed(1); } } diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index d62188a49c..2a17642ba7 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -552,8 +552,8 @@ void QCoreApplicationPrivate::eventDispatcherReady() QBasicAtomicPointer QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(0); QThread *QCoreApplicationPrivate::mainThread() { - Q_ASSERT(theMainThread.load() != 0); - return theMainThread.load(); + Q_ASSERT(theMainThread.loadRelaxed() != 0); + return theMainThread.loadRelaxed(); } bool QCoreApplicationPrivate::threadRequiresCoreApplication() @@ -854,7 +854,7 @@ void QCoreApplicationPrivate::init() #ifndef QT_NO_QOBJECT // use the event dispatcher created by the app programmer (if any) Q_ASSERT(!eventDispatcher); - eventDispatcher = threadData->eventDispatcher.load(); + eventDispatcher = threadData->eventDispatcher.loadRelaxed(); // otherwise we create one if (!eventDispatcher) @@ -1302,7 +1302,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags) QThreadData *data = QThreadData::current(); if (!data->hasEventDispatcher()) return; - data->eventDispatcher.load()->processEvents(flags); + data->eventDispatcher.loadRelaxed()->processEvents(flags); } /*! @@ -1334,7 +1334,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m return; QElapsedTimer start; start.start(); - while (data->eventDispatcher.load()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) { + while (data->eventDispatcher.loadRelaxed()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) { if (start.elapsed() > ms) break; } @@ -1738,7 +1738,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type --data->postEventList.recursion; if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher()) - data->eventDispatcher.load()->wakeUp(); + data->eventDispatcher.loadRelaxed()->wakeUp(); // clear the global list, i.e. remove everything that was // delivered. @@ -1989,7 +1989,7 @@ void QCoreApplicationPrivate::deref() void QCoreApplicationPrivate::maybeQuit() { - if (quitLockRef.load() == 0 && in_exec && quitLockRefEnabled && shouldQuit()) + if (quitLockRef.loadRelaxed() == 0 && in_exec && quitLockRefEnabled && shouldQuit()) QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::Quit)); } @@ -2958,7 +2958,7 @@ bool QCoreApplication::hasPendingEvents() QAbstractEventDispatcher *QCoreApplication::eventDispatcher() { if (QCoreApplicationPrivate::theMainThread) - return QCoreApplicationPrivate::theMainThread.load()->eventDispatcher(); + return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher(); return 0; } diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index aabd32b4a8..4cfc749386 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -424,7 +424,7 @@ struct QBasicAtomicBitField { bool allocateSpecific(int which) noexcept { QBasicAtomicInteger &entry = data[which / BitsPerInt]; - const uint old = entry.load(); + const uint old = entry.loadRelaxed(); const uint bit = 1U << (which % BitsPerInt); return !(old & bit) // wasn't taken && entry.testAndSetRelaxed(old, old | bit); // still wasn't taken @@ -445,10 +445,10 @@ struct QBasicAtomicBitField { // Then again, this should never execute many iterations, so // leave like this for now: - for (uint i = next.load(); i < NumBits; ++i) { + for (uint i = next.loadRelaxed(); i < NumBits; ++i) { if (allocateSpecific(i)) { // remember next (possibly) free id: - const uint oldNext = next.load(); + const uint oldNext = next.loadRelaxed(); next.testAndSetRelaxed(oldNext, qMax(i + 1, oldNext)); return i; } diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index 34c2dde6a8..d9746ef6e2 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -261,7 +261,7 @@ static gboolean postEventSourcePrepare(GSource *s, gint *timeout) *timeout = canWait ? -1 : 0; GPostEventSource *source = reinterpret_cast(s); - source->d->wakeUpCalled = source->serialNumber.load() != source->lastSerialNumber; + source->d->wakeUpCalled = source->serialNumber.loadRelaxed() != source->lastSerialNumber; return !canWait || source->d->wakeUpCalled; } @@ -273,7 +273,7 @@ static gboolean postEventSourceCheck(GSource *source) static gboolean postEventSourceDispatch(GSource *s, GSourceFunc, gpointer) { GPostEventSource *source = reinterpret_cast(s); - source->lastSerialNumber = source->serialNumber.load(); + source->lastSerialNumber = source->serialNumber.loadRelaxed(); QCoreApplication::sendPostedEvents(); source->d->runTimersOnceWithNormalPriority(); return true; // i dunno, george... @@ -320,7 +320,7 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context) // setup post event source postEventSource = reinterpret_cast(g_source_new(&postEventSourceFuncs, sizeof(GPostEventSource))); - postEventSource->serialNumber.store(1); + postEventSource->serialNumber.storeRelaxed(1); postEventSource->d = this; g_source_set_can_recurse(&postEventSource->source, true); g_source_attach(&postEventSource->source, mainContext); diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index df0cac0239..5bc65b7110 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -459,7 +459,7 @@ void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier) bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_D(QEventDispatcherUNIX); - d->interrupt.store(0); + d->interrupt.storeRelaxed(0); // we are awake, broadcast it emit awake(); @@ -470,13 +470,13 @@ bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags) const bool wait_for_events = flags & QEventLoop::WaitForMoreEvents; const bool canWait = (d->threadData->canWaitLocked() - && !d->interrupt.load() + && !d->interrupt.loadRelaxed() && wait_for_events); if (canWait) emit aboutToBlock(); - if (d->interrupt.load()) + if (d->interrupt.loadRelaxed()) return false; timespec *tm = nullptr; @@ -545,7 +545,7 @@ void QEventDispatcherUNIX::wakeUp() void QEventDispatcherUNIX::interrupt() { Q_D(QEventDispatcherUNIX); - d->interrupt.store(1); + d->interrupt.storeRelaxed(1); wakeUp(); } diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index e0641a0282..c2e57a7924 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -247,7 +247,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA Q_ASSERT(d != 0); // Allow posting WM_QT_SENDPOSTEDEVENTS message. - d->wakeUps.store(0); + d->wakeUps.storeRelaxed(0); // We send posted events manually, if the window procedure was invoked // by the foreign event loop (e.g. from the native modal dialog). @@ -526,7 +526,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) wakeUp(); // trigger a call to sendPostedEvents() } - d->interrupt.store(false); + d->interrupt.storeRelaxed(false); emit awake(); // To prevent livelocks, send posted events once per iteration. @@ -545,7 +545,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) pHandles = &d->winEventNotifierActivatedEvent; } QVarLengthArray processedTimers; - while (!d->interrupt.load()) { + while (!d->interrupt.loadRelaxed()) { MSG msg; bool haveMessage; @@ -590,7 +590,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) { // Set result to 'true', if the message was sent by wakeUp(). if (msg.wParam == WMWP_QT_FROMWAKEUP) { - d->wakeUps.store(0); + d->wakeUps.storeRelaxed(0); retVal = true; } needWM_QT_SENDPOSTEDEVENTS = true; @@ -639,7 +639,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) // still nothing - wait for message or signalled objects canWait = (!retVal - && !d->interrupt.load() + && !d->interrupt.loadRelaxed() && (flags & QEventLoop::WaitForMoreEvents)); if (canWait) { emit aboutToBlock(); @@ -949,7 +949,7 @@ void QEventDispatcherWin32::activateEventNotifiers() for (int i = 0; i < d->winEventNotifierList.count(); ++i) { QWinEventNotifier *notifier = d->winEventNotifierList.at(i); QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier); - if (nd->signaledCount.load() != 0) { + if (nd->signaledCount.loadRelaxed() != 0) { --nd->signaledCount; nd->unregisterWaitObject(); d->activateEventNotifier(notifier); @@ -1014,7 +1014,7 @@ void QEventDispatcherWin32::wakeUp() void QEventDispatcherWin32::interrupt() { Q_D(QEventDispatcherWin32); - d->interrupt.store(true); + d->interrupt.storeRelaxed(true); wakeUp(); } diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index a6cc51621a..2104b22095 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -135,7 +135,7 @@ bool QEventLoop::processEvents(ProcessEventsFlags flags) Q_D(QEventLoop); if (!d->threadData->hasEventDispatcher()) return false; - return d->threadData->eventDispatcher.load()->processEvents(flags); + return d->threadData->eventDispatcher.loadRelaxed()->processEvents(flags); } /*! @@ -225,7 +225,7 @@ int QEventLoop::exec(ProcessEventsFlags flags) processEvents(flags | WaitForMoreEvents | EventLoopExec); ref.exceptionCaught = false; - return d->returnCode.load(); + return d->returnCode.loadRelaxed(); } /*! @@ -279,9 +279,9 @@ void QEventLoop::exit(int returnCode) if (!d->threadData->hasEventDispatcher()) return; - d->returnCode.store(returnCode); + d->returnCode.storeRelaxed(returnCode); d->exit.storeRelease(true); - d->threadData->eventDispatcher.load()->interrupt(); + d->threadData->eventDispatcher.loadRelaxed()->interrupt(); #ifdef Q_OS_WASM // QEventLoop::exec() never returns in emscripten. We implement approximate behavior here. @@ -318,7 +318,7 @@ void QEventLoop::wakeUp() Q_D(QEventLoop); if (!d->threadData->hasEventDispatcher()) return; - d->threadData->eventDispatcher.load()->wakeUp(); + d->threadData->eventDispatcher.loadRelaxed()->wakeUp(); } diff --git a/src/corelib/kernel/qeventloop_p.h b/src/corelib/kernel/qeventloop_p.h index dcbb5c63c6..4ad6d92007 100644 --- a/src/corelib/kernel/qeventloop_p.h +++ b/src/corelib/kernel/qeventloop_p.h @@ -63,8 +63,8 @@ public: inline QEventLoopPrivate() : inExec(false) { - returnCode.store(-1); - exit.store(true); + returnCode.storeRelaxed(-1); + exit.storeRelaxed(true); } QAtomicInt quitLockRef; diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index fef25a32c4..9fe2b9733b 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1999,7 +1999,7 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE > \ static int qt_metatype_id() \ { \ static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \ - if (const int id = metatype_id.load()) \ + if (const int id = metatype_id.loadRelaxed()) \ return id; \ const char *tName = QMetaType::typeName(qMetaTypeId()); \ Q_ASSERT(tName); \ diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index b4e7568a23..7eba9b05ff 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -222,7 +222,7 @@ QObjectPrivate::~QObjectPrivate() if (Q_LIKELY(threadData->thread == QThread::currentThread())) { // unregister pending timers if (threadData->hasEventDispatcher()) - threadData->eventDispatcher.load()->unregisterTimers(q_ptr); + threadData->eventDispatcher.loadRelaxed()->unregisterTimers(q_ptr); // release the timer ids back to the pool for (int i = 0; i < extraData->runningTimers.size(); ++i) @@ -268,17 +268,17 @@ bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const { Q_Q(const QObject); int signal_index = signalIndex(signal); - ConnectionData *cd = connections.load(); + ConnectionData *cd = connections.loadRelaxed(); if (signal_index < 0 || !cd) return false; QBasicMutexLocker locker(signalSlotLock(q)); if (signal_index < cd->signalVectorCount()) { - const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load(); + const QObjectPrivate::Connection *c = cd->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed(); while (c) { - if (c->receiver.load() == receiver) + if (c->receiver.loadRelaxed() == receiver) return true; - c = c->nextConnectionList.load(); + c = c->nextConnectionList.loadRelaxed(); } } return false; @@ -289,17 +289,17 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const { QObjectList returnValue; int signal_index = signalIndex(signal); - ConnectionData *cd = connections.load(); + ConnectionData *cd = connections.loadRelaxed(); if (signal_index < 0 || !cd) return returnValue; if (signal_index < cd->signalVectorCount()) { - const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load(); + const QObjectPrivate::Connection *c = cd->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed(); while (c) { - QObject *r = c->receiver.load(); + QObject *r = c->receiver.loadRelaxed(); if (r) returnValue << r; - c = c->nextConnectionList.load(); + c = c->nextConnectionList.loadRelaxed(); } } return returnValue; @@ -309,7 +309,7 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const QObjectList QObjectPrivate::senderList() const { QObjectList returnValue; - ConnectionData *cd = connections.load(); + ConnectionData *cd = connections.loadRelaxed(); if (cd) { QBasicMutexLocker locker(signalSlotLock(q_func())); for (Connection *c = cd->senders; c; c = c->next) @@ -332,24 +332,24 @@ void QObjectPrivate::addConnection(int signal, Connection *c) { Q_ASSERT(c->sender == q_ptr); ensureConnectionData(); - ConnectionData *cd = connections.load(); + ConnectionData *cd = connections.loadRelaxed(); cd->resizeSignalVector(signal + 1); ConnectionList &connectionList = cd->connectionsForSignal(signal); - if (connectionList.last.load()) { - Q_ASSERT(connectionList.last.load()->receiver.load()); - connectionList.last.load()->nextConnectionList.store(c); + if (connectionList.last.loadRelaxed()) { + Q_ASSERT(connectionList.last.loadRelaxed()->receiver.loadRelaxed()); + connectionList.last.loadRelaxed()->nextConnectionList.storeRelaxed(c); } else { - connectionList.first.store(c); + connectionList.first.storeRelaxed(c); } c->id = ++cd->currentConnectionId; - c->prevConnectionList = connectionList.last.load(); - connectionList.last.store(c); + c->prevConnectionList = connectionList.last.loadRelaxed(); + connectionList.last.storeRelaxed(c); - QObjectPrivate *rd = QObjectPrivate::get(c->receiver.load()); + QObjectPrivate *rd = QObjectPrivate::get(c->receiver.loadRelaxed()); rd->ensureConnectionData(); - c->prev = &(rd->connections.load()->senders); + c->prev = &(rd->connections.loadRelaxed()->senders); c->next = *c->prev; *c->prev = c; if (c->next) @@ -358,17 +358,17 @@ void QObjectPrivate::addConnection(int signal, Connection *c) void QObjectPrivate::ConnectionData::removeConnection(QObjectPrivate::Connection *c) { - Q_ASSERT(c->receiver.load()); - ConnectionList &connections = signalVector.load()->at(c->signal_index); - c->receiver.store(nullptr); - QThreadData *td = c->receiverThreadData.load(); + Q_ASSERT(c->receiver.loadRelaxed()); + ConnectionList &connections = signalVector.loadRelaxed()->at(c->signal_index); + c->receiver.storeRelaxed(nullptr); + QThreadData *td = c->receiverThreadData.loadRelaxed(); if (td) td->deref(); - c->receiverThreadData.store(nullptr); + c->receiverThreadData.storeRelaxed(nullptr); #ifndef QT_NO_DEBUG bool found = false; - for (Connection *cc = connections.first.load(); cc; cc = cc->nextConnectionList.load()) { + for (Connection *cc = connections.first.loadRelaxed(); cc; cc = cc->nextConnectionList.loadRelaxed()) { if (cc == c) { found = true; break; @@ -383,29 +383,29 @@ void QObjectPrivate::ConnectionData::removeConnection(QObjectPrivate::Connection c->next->prev = c->prev; c->prev = nullptr; - if (connections.first.load() == c) - connections.first.store(c->nextConnectionList.load()); - if (connections.last.load() == c) - connections.last.store(c->prevConnectionList); - Q_ASSERT(signalVector.load()->at(c->signal_index).first.load() != c); - Q_ASSERT(signalVector.load()->at(c->signal_index).last.load() != c); + if (connections.first.loadRelaxed() == c) + connections.first.storeRelaxed(c->nextConnectionList.loadRelaxed()); + if (connections.last.loadRelaxed() == c) + connections.last.storeRelaxed(c->prevConnectionList); + Q_ASSERT(signalVector.loadRelaxed()->at(c->signal_index).first.loadRelaxed() != c); + Q_ASSERT(signalVector.loadRelaxed()->at(c->signal_index).last.loadRelaxed() != c); // keep c->nextConnectionList intact, as it might still get accessed by activate - Connection *n = c->nextConnectionList.load(); + Connection *n = c->nextConnectionList.loadRelaxed(); if (n) n->prevConnectionList = c->prevConnectionList; if (c->prevConnectionList) - c->prevConnectionList->nextConnectionList.store(n); + c->prevConnectionList->nextConnectionList.storeRelaxed(n); c->prevConnectionList = nullptr; - Q_ASSERT(c != orphaned.load()); + Q_ASSERT(c != orphaned.loadRelaxed()); // add c to orphanedConnections - c->nextInOrphanList = orphaned.load(); - orphaned.store(c); + c->nextInOrphanList = orphaned.loadRelaxed(); + orphaned.storeRelaxed(c); #ifndef QT_NO_DEBUG found = false; - for (Connection *cc = connections.first.load(); cc; cc = cc->nextConnectionList.load()) { + for (Connection *cc = connections.first.loadRelaxed(); cc; cc = cc->nextConnectionList.loadRelaxed()) { if (cc == c) { found = true; break; @@ -427,8 +427,8 @@ void QObjectPrivate::ConnectionData::cleanOrphanedConnectionsImpl(QObject *sende // Since ref == 1, no activate() is in process since we locked the mutex. That implies, // that nothing can reference the orphaned connection objects anymore and they can // be safely deleted - c = orphaned.load(); - orphaned.store(nullptr); + c = orphaned.loadRelaxed(); + orphaned.storeRelaxed(nullptr); } deleteOrphaned(c); } @@ -443,7 +443,7 @@ void QObjectPrivate::ConnectionData::deleteOrphaned(QObjectPrivate::ConnectionOr } else { QObjectPrivate::Connection *c = static_cast(o); next = c->nextInOrphanList; - Q_ASSERT(!c->receiver.load()); + Q_ASSERT(!c->receiver.loadRelaxed()); Q_ASSERT(!c->prev); c->freeSlotObject(); c->deref(); @@ -463,22 +463,22 @@ bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative) if (checkDeclarative && isDeclarativeSignalConnected(signalIndex)) return true; - ConnectionData *cd = connections.load(); + ConnectionData *cd = connections.loadRelaxed(); if (!cd) return false; - SignalVector *signalVector = cd->signalVector.load(); + SignalVector *signalVector = cd->signalVector.loadRelaxed(); if (!signalVector) return false; - if (signalVector->at(-1).first.load()) + if (signalVector->at(-1).first.loadRelaxed()) return true; if (signalIndex < uint(cd->signalVectorCount())) { - const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first.load(); + const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first.loadRelaxed(); while (c) { - if (c->receiver.load()) + if (c->receiver.loadRelaxed()) return true; - c = c->nextConnectionList.load(); + c = c->nextConnectionList.loadRelaxed(); } } return false; @@ -486,10 +486,10 @@ bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative) bool QObjectPrivate::maybeSignalConnected(uint signalIndex) const { - ConnectionData *cd = connections.load(); + ConnectionData *cd = connections.loadRelaxed(); if (!cd) return false; - SignalVector *signalVector = cd->signalVector.load(); + SignalVector *signalVector = cd->signalVector.loadRelaxed(); if (!signalVector) return false; @@ -944,15 +944,15 @@ QObject::~QObject() d->wasDeleted = true; d->blockSig = 0; // unblock signals so we always emit destroyed() - QtSharedPointer::ExternalRefCountData *sharedRefcount = d->sharedRefcount.load(); + QtSharedPointer::ExternalRefCountData *sharedRefcount = d->sharedRefcount.loadRelaxed(); if (sharedRefcount) { - if (sharedRefcount->strongref.load() > 0) { + if (sharedRefcount->strongref.loadRelaxed() > 0) { qWarning("QObject: shared QObject was deleted directly. The program is malformed and may crash."); // but continue deleting, it's too late to stop anyway } // indicate to all QWeakPointers that this QObject has now been deleted - sharedRefcount->strongref.store(0); + sharedRefcount->strongref.storeRelaxed(0); if (!sharedRefcount->weakref.deref()) delete sharedRefcount; } @@ -971,7 +971,7 @@ QObject::~QObject() } } - QObjectPrivate::ConnectionData *cd = d->connections.load(); + QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed(); if (cd) { if (cd->currentSender) { cd->currentSender->receiverDeleted(); @@ -986,14 +986,14 @@ QObject::~QObject() for (int signal = -1; signal < receiverCount; ++signal) { QObjectPrivate::ConnectionList &connectionList = cd->connectionsForSignal(signal); - while (QObjectPrivate::Connection *c = connectionList.first.load()) { + while (QObjectPrivate::Connection *c = connectionList.first.loadRelaxed()) { Q_ASSERT(c->receiver); - QBasicMutex *m = signalSlotLock(c->receiver.load()); + QBasicMutex *m = signalSlotLock(c->receiver.loadRelaxed()); bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m); if (c->receiver) { cd->removeConnection(c); - Q_ASSERT(connectionList.first.load() != c); + Q_ASSERT(connectionList.first.loadRelaxed() != c); } if (needToUnlock) m->unlock(); @@ -1019,7 +1019,7 @@ QObject::~QObject() continue; } - QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections.load(); + QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections.loadRelaxed(); Q_ASSERT(senderData); QtPrivate::QSlotObjectBase *slotObj = nullptr; @@ -1041,11 +1041,11 @@ QObject::~QObject() // invalidate all connections on the object and make sure // activate() will skip them - cd->currentConnectionId.store(0); + cd->currentConnectionId.storeRelaxed(0); } if (cd && !cd->ref.deref()) delete cd; - d->connections.store(nullptr); + d->connections.storeRelaxed(nullptr); if (!d->children.isEmpty()) d->deleteChildren(); @@ -1065,7 +1065,7 @@ QObject::~QObject() QObjectPrivate::Connection::~Connection() { if (ownArgumentTypes) { - const int *v = argumentTypes.load(); + const int *v = argumentTypes.loadRelaxed(); if (v != &DIRECT_CONNECTION_ONLY) delete [] v; } @@ -1274,7 +1274,7 @@ bool QObject::event(QEvent *e) { QAbstractMetaCallEvent *mce = static_cast(e); - if (!d_func()->connections.load()) { + if (!d_func()->connections.loadRelaxed()) { QBasicMutexLocker locker(signalSlotLock(this)); d_func()->ensureConnectionData(); } @@ -1287,7 +1287,7 @@ bool QObject::event(QEvent *e) case QEvent::ThreadChange: { Q_D(QObject); QThreadData *threadData = d->threadData; - QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load(); + QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.loadRelaxed(); if (eventDispatcher) { QList timers = eventDispatcher->registeredTimers(this); if (!timers.isEmpty()) { @@ -1522,7 +1522,7 @@ void QObject::moveToThread(QThread *targetThread) } else if (d->threadData != currentData) { qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n" "Cannot move to target thread (%p)\n", - currentData->thread.load(), d->threadData->thread.load(), targetData ? targetData->thread.load() : nullptr); + currentData->thread.loadRelaxed(), d->threadData->thread.loadRelaxed(), targetData ? targetData->thread.loadRelaxed() : nullptr); #ifdef Q_OS_MAC qWarning("You might be loading two sets of Qt binaries into the same process. " @@ -1587,11 +1587,11 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData } if (eventsMoved > 0 && targetData->hasEventDispatcher()) { targetData->canWait = false; - targetData->eventDispatcher.load()->wakeUp(); + targetData->eventDispatcher.loadRelaxed()->wakeUp(); } // the current emitting thread shouldn't restore currentSender after calling moveToThread() - ConnectionData *cd = connections.load(); + ConnectionData *cd = connections.loadRelaxed(); if (cd) { if (cd->currentSender) { cd->currentSender->receiverDeleted(); @@ -1602,14 +1602,14 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData if (cd) { auto *c = cd->senders; while (c) { - QObject *r = c->receiver.load(); + QObject *r = c->receiver.loadRelaxed(); if (r) { Q_ASSERT(r == q); targetData->ref(); - QThreadData *old = c->receiverThreadData.load(); + QThreadData *old = c->receiverThreadData.loadRelaxed(); if (old) old->deref(); - c->receiverThreadData.store(targetData); + c->receiverThreadData.storeRelaxed(targetData); } c = c->next; } @@ -1632,7 +1632,7 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer) { Q_Q(QObject); QList *timerList = reinterpret_cast *>(pointer); - QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load(); + QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.loadRelaxed(); for (int i = 0; i < timerList->size(); ++i) { const QAbstractEventDispatcher::TimerInfo &ti = timerList->at(i); eventDispatcher->registerTimer(ti.timerId, ti.interval, ti.timerType, q); @@ -1698,7 +1698,7 @@ int QObject::startTimer(int interval, Qt::TimerType timerType) qWarning("QObject::startTimer: Timers cannot be started from another thread"); return 0; } - int timerId = d->threadData->eventDispatcher.load()->registerTimer(interval, timerType, this); + int timerId = d->threadData->eventDispatcher.loadRelaxed()->registerTimer(interval, timerType, this); if (!d->extraData) d->extraData = new QObjectPrivate::ExtraData; d->extraData->runningTimers.append(timerId); @@ -1773,7 +1773,7 @@ void QObject::killTimer(int id) } if (d->threadData->hasEventDispatcher()) - d->threadData->eventDispatcher.load()->unregisterTimer(id); + d->threadData->eventDispatcher.loadRelaxed()->unregisterTimer(id); d->extraData->runningTimers.remove(at); QAbstractEventDispatcherPrivate::releaseTimerId(id); @@ -2442,7 +2442,7 @@ QObject *QObject::sender() const Q_D(const QObject); QBasicMutexLocker locker(signalSlotLock(this)); - QObjectPrivate::ConnectionData *cd = d->connections.load(); + QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed(); if (!cd || !cd->currentSender) return nullptr; @@ -2484,7 +2484,7 @@ int QObject::senderSignalIndex() const Q_D(const QObject); QBasicMutexLocker locker(signalSlotLock(this)); - QObjectPrivate::ConnectionData *cd = d->connections.load(); + QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed(); if (!cd || !cd->currentSender) return -1; @@ -2547,13 +2547,13 @@ int QObject::receivers(const char *signal) const signal_index); } - QObjectPrivate::ConnectionData *cd = d->connections.load(); + QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed(); QBasicMutexLocker locker(signalSlotLock(this)); if (cd && signal_index < cd->signalVectorCount()) { - const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load(); + const QObjectPrivate::Connection *c = cd->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed(); while (c) { - receivers += c->receiver.load() ? 1 : 0; - c = c->nextConnectionList.load(); + receivers += c->receiver.loadRelaxed() ? 1 : 0; + c = c->nextConnectionList.loadRelaxed(); } } } @@ -3362,17 +3362,17 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender, QOrderedMutexLocker locker(signalSlotLock(sender), signalSlotLock(receiver)); - QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load(); + QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.loadRelaxed(); if (type & Qt::UniqueConnection && scd) { if (scd->signalVectorCount() > signal_index) { - const QObjectPrivate::Connection *c2 = scd->signalVector.load()->at(signal_index).first.load(); + const QObjectPrivate::Connection *c2 = scd->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed(); int method_index_absolute = method_index + method_offset; while (c2) { - if (!c2->isSlotObject && c2->receiver.load() == receiver && c2->method() == method_index_absolute) + if (!c2->isSlotObject && c2->receiver.loadRelaxed() == receiver && c2->method() == method_index_absolute) return nullptr; - c2 = c2->nextConnectionList.load(); + c2 = c2->nextConnectionList.loadRelaxed(); } } type &= Qt::UniqueConnection - 1; @@ -3381,15 +3381,15 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender, QScopedPointer c(new QObjectPrivate::Connection); c->sender = s; c->signal_index = signal_index; - c->receiver.store(r); + c->receiver.storeRelaxed(r); QThreadData *td = r->d_func()->threadData; td->ref(); - c->receiverThreadData.store(td); + c->receiverThreadData.storeRelaxed(td); c->method_relative = method_index; c->method_offset = method_offset; c->connectionType = type; c->isSlotObject = false; - c->argumentTypes.store(types); + c->argumentTypes.storeRelaxed(types); c->callFunction = callFunction; QObjectPrivate::get(s)->addConnection(signal_index, c.data()); @@ -3442,9 +3442,9 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::ConnectionData *connec bool success = false; auto &connectionList = connections->connectionsForSignal(signalIndex); - auto *c = connectionList.first.load(); + auto *c = connectionList.first.loadRelaxed(); while (c) { - QObject *r = c->receiver.load(); + QObject *r = c->receiver.loadRelaxed(); if (r && (receiver == nullptr || (r == receiver && (method_index < 0 || (!c->isSlotObject && c->method() == method_index)) && (slot == nullptr || (c->isSlotObject && c->slotObj->compare(slot)))))) { @@ -3455,7 +3455,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::ConnectionData *connec // need to relock this receiver and sender in the correct order needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex); } - if (c->receiver.load()) + if (c->receiver.loadRelaxed()) connections->removeConnection(c); if (needToUnlock) @@ -3466,7 +3466,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::ConnectionData *connec if (disconnectType == DisconnectOne) return success; } - c = c->nextConnectionList.load(); + c = c->nextConnectionList.loadRelaxed(); } return success; } @@ -3488,7 +3488,7 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender, QBasicMutex *senderMutex = signalSlotLock(sender); QBasicMutexLocker locker(senderMutex); - QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load(); + QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.loadRelaxed(); if (!scd) return false; @@ -3630,7 +3630,7 @@ void QMetaObject::connectSlotsByName(QObject *o) */ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv) { - const int *argumentTypes = c->argumentTypes.load(); + const int *argumentTypes = c->argumentTypes.loadRelaxed(); if (!argumentTypes) { QMetaMethod m = QMetaObjectPrivate::signal(sender->metaObject(), signal); argumentTypes = queuedConnectionTypes(m.parameterTypes()); @@ -3639,7 +3639,7 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect if (!c->argumentTypes.testAndSetOrdered(0, argumentTypes)) { if (argumentTypes != &DIRECT_CONNECTION_ONLY) delete [] argumentTypes; - argumentTypes = c->argumentTypes.load(); + argumentTypes = c->argumentTypes.loadRelaxed(); } } if (argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate @@ -3662,8 +3662,8 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect args[n] = QMetaType::create(types[n], argv[n]); } - QBasicMutexLocker locker(signalSlotLock(c->receiver.load())); - if (!c->receiver.load()) { + QBasicMutexLocker locker(signalSlotLock(c->receiver.loadRelaxed())); + if (!c->receiver.loadRelaxed()) { // the connection has been disconnected before we got the lock locker.unlock(); for (int n = 1; n < nargs; ++n) @@ -3676,7 +3676,7 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect QMetaCallEvent *ev = c->isSlotObject ? new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) : new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args); - QCoreApplication::postEvent(c->receiver.load(), ev); + QCoreApplication::postEvent(c->receiver.loadRelaxed(), ev); } template @@ -3717,8 +3717,8 @@ void doActivate(QObject *sender, int signal_index, void **argv) bool senderDeleted = false; { Q_ASSERT(sp->connections); - QObjectPrivate::ConnectionDataPointer connections(sp->connections.load()); - QObjectPrivate::SignalVector *signalVector = connections->signalVector.load(); + QObjectPrivate::ConnectionDataPointer connections(sp->connections.loadRelaxed()); + QObjectPrivate::SignalVector *signalVector = connections->signalVector.loadRelaxed(); const QObjectPrivate::ConnectionList *list; if (signal_index < signalVector->count()) @@ -3727,32 +3727,32 @@ void doActivate(QObject *sender, int signal_index, void **argv) list = &signalVector->at(-1); Qt::HANDLE currentThreadId = QThread::currentThreadId(); - bool inSenderThread = currentThreadId == QObjectPrivate::get(sender)->threadData->threadId.load(); + bool inSenderThread = currentThreadId == QObjectPrivate::get(sender)->threadData->threadId.loadRelaxed(); // We need to check against the highest connection id to ensure that signals added // during the signal emission are not emitted in this emission. - uint highestConnectionId = connections->currentConnectionId.load(); + uint highestConnectionId = connections->currentConnectionId.loadRelaxed(); do { - QObjectPrivate::Connection *c = list->first.load(); + QObjectPrivate::Connection *c = list->first.loadRelaxed(); if (!c) continue; do { - QObject * const receiver = c->receiver.load(); + QObject * const receiver = c->receiver.loadRelaxed(); if (!receiver) continue; - QThreadData *td = c->receiverThreadData.load(); + QThreadData *td = c->receiverThreadData.loadRelaxed(); if (!td) continue; bool receiverInSameThread; if (inSenderThread) { - receiverInSameThread = currentThreadId == td->threadId.load(); + receiverInSameThread = currentThreadId == td->threadId.loadRelaxed(); } else { // need to lock before reading the threadId, because moveToThread() could interfere QMutexLocker lock(signalSlotLock(receiver)); - receiverInSameThread = currentThreadId == td->threadId.load(); + receiverInSameThread = currentThreadId == td->threadId.loadRelaxed(); } @@ -3825,17 +3825,17 @@ void doActivate(QObject *sender, int signal_index, void **argv) if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr) signal_spy_set->slot_end_callback(receiver, method); } - } while ((c = c->nextConnectionList.load()) != nullptr && c->id <= highestConnectionId); + } while ((c = c->nextConnectionList.loadRelaxed()) != nullptr && c->id <= highestConnectionId); } while (list != &signalVector->at(-1) && //start over for all signals; ((list = &signalVector->at(-1)), true)); - if (connections->currentConnectionId.load() == 0) + if (connections->currentConnectionId.loadRelaxed() == 0) senderDeleted = true; } if (!senderDeleted) - sp->connections.load()->cleanOrphanedConnections(sender); + sp->connections.loadRelaxed()->cleanOrphanedConnections(sender); if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr) signal_spy_set->signal_end_callback(sender, signal_index); @@ -3849,7 +3849,7 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign { int signal_index = local_signal_index + QMetaObjectPrivate::signalOffset(m); - if (Q_UNLIKELY(qt_signal_spy_callback_set.load())) + if (Q_UNLIKELY(qt_signal_spy_callback_set.loadRelaxed())) doActivate(sender, signal_index, argv); else doActivate(sender, signal_index, argv); @@ -3862,7 +3862,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i { int signal_index = signalOffset + local_signal_index; - if (Q_UNLIKELY(qt_signal_spy_callback_set.load())) + if (Q_UNLIKELY(qt_signal_spy_callback_set.loadRelaxed())) doActivate(sender, signal_index, argv); else doActivate(sender, signal_index, argv); @@ -4131,11 +4131,11 @@ void QObject::dumpObjectInfo() const // first, look for connections where this object is the sender qDebug(" SIGNALS OUT"); - QObjectPrivate::ConnectionData *cd = d->connections.load(); + QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed(); if (cd && cd->signalVectorCount()) { - QObjectPrivate::SignalVector *signalVector = cd->signalVector.load(); + QObjectPrivate::SignalVector *signalVector = cd->signalVector.loadRelaxed(); for (int signal_index = 0; signal_index < signalVector->count(); ++signal_index) { - const QObjectPrivate::Connection *c = signalVector->at(signal_index).first.load(); + const QObjectPrivate::Connection *c = signalVector->at(signal_index).first.loadRelaxed(); if (!c) continue; const QMetaMethod signal = QMetaObjectPrivate::signal(metaObject(), signal_index); @@ -4143,23 +4143,23 @@ void QObject::dumpObjectInfo() const // receivers while (c) { - if (!c->receiver.load()) { + if (!c->receiver.loadRelaxed()) { qDebug(" "); - c = c->nextConnectionList.load(); + c = c->nextConnectionList.loadRelaxed(); continue; } if (c->isSlotObject) { qDebug(" "); - c = c->nextConnectionList.load(); + c = c->nextConnectionList.loadRelaxed(); continue; } - const QMetaObject *receiverMetaObject = c->receiver.load()->metaObject(); + const QMetaObject *receiverMetaObject = c->receiver.loadRelaxed()->metaObject(); const QMetaMethod method = receiverMetaObject->method(c->method()); qDebug(" --> %s::%s %s", receiverMetaObject->className(), - c->receiver.load()->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver.load()->objectName()), + c->receiver.loadRelaxed()->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver.loadRelaxed()->objectName()), method.methodSignature().constData()); - c = c->nextConnectionList.load(); + c = c->nextConnectionList.loadRelaxed(); } } } else { @@ -4910,17 +4910,17 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s QOrderedMutexLocker locker(signalSlotLock(sender), signalSlotLock(receiver)); - if (type & Qt::UniqueConnection && slot && QObjectPrivate::get(s)->connections.load()) { - QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(s)->connections.load(); + if (type & Qt::UniqueConnection && slot && QObjectPrivate::get(s)->connections.loadRelaxed()) { + QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(s)->connections.loadRelaxed(); if (connections->signalVectorCount() > signal_index) { - const QObjectPrivate::Connection *c2 = connections->signalVector.load()->at(signal_index).first.load(); + const QObjectPrivate::Connection *c2 = connections->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed(); while (c2) { - if (c2->receiver.load() == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) { + if (c2->receiver.loadRelaxed() == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) { slotObj->destroyIfLastRef(); return QMetaObject::Connection(); } - c2 = c2->nextConnectionList.load(); + c2 = c2->nextConnectionList.loadRelaxed(); } } type = static_cast(type ^ Qt::UniqueConnection); @@ -4931,13 +4931,13 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s c->signal_index = signal_index; QThreadData *td = r->d_func()->threadData; td->ref(); - c->receiverThreadData.store(td); - c->receiver.store(r); + c->receiverThreadData.storeRelaxed(td); + c->receiver.storeRelaxed(r); c->slotObj = slotObj; c->connectionType = type; c->isSlotObject = true; if (types) { - c->argumentTypes.store(types); + c->argumentTypes.storeRelaxed(types); c->ownArgumentTypes = false; } @@ -4966,7 +4966,7 @@ bool QObject::disconnect(const QMetaObject::Connection &connection) if (!c) return false; - QObject *receiver = c->receiver.load(); + QObject *receiver = c->receiver.loadRelaxed(); if (!receiver) return false; @@ -4978,11 +4978,11 @@ bool QObject::disconnect(const QMetaObject::Connection &connection) QOrderedMutexLocker locker(senderMutex, receiverMutex); // load receiver once again and recheck to ensure nobody else has removed the connection in the meantime - receiver = c->receiver.load(); + receiver = c->receiver.loadRelaxed(); if (!receiver) return false; - connections = QObjectPrivate::get(c->sender)->connections.load(); + connections = QObjectPrivate::get(c->sender)->connections.loadRelaxed(); Q_ASSERT(connections); connections->removeConnection(c); } @@ -5174,7 +5174,7 @@ bool QMetaObject::Connection::isConnected_helper() const Q_ASSERT(d_ptr); // we're only called from operator RestrictedBool() const QObjectPrivate::Connection *c = static_cast(d_ptr); - return c->receiver.load(); + return c->receiver.loadRelaxed(); } diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index e6e57b29b9..1953aea21e 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -184,7 +184,7 @@ public: } void deref() { if (!ref_.deref()) { - Q_ASSERT(!receiver.load()); + Q_ASSERT(!receiver.loadRelaxed()); Q_ASSERT(!isSlotObject); delete this; } @@ -202,7 +202,7 @@ public: : receiver(receiver), sender(sender), signal(signal) { if (receiver) { - ConnectionData *cd = receiver->d_func()->connections.load(); + ConnectionData *cd = receiver->d_func()->connections.loadRelaxed(); previous = cd->currentSender; cd->currentSender = this; } @@ -210,7 +210,7 @@ public: ~Sender() { if (receiver) - receiver->d_func()->connections.load()->currentSender = previous; + receiver->d_func()->connections.loadRelaxed()->currentSender = previous; } void receiverDeleted() { @@ -268,8 +268,8 @@ public: ~ConnectionData() { - deleteOrphaned(orphaned.load()); - SignalVector *v = signalVector.load(); + deleteOrphaned(orphaned.loadRelaxed()); + SignalVector *v = signalVector.loadRelaxed(); if (v) free(v); } @@ -279,18 +279,18 @@ public: void removeConnection(Connection *c); void cleanOrphanedConnections(QObject *sender) { - if (orphaned.load() && ref == 1) + if (orphaned.loadRelaxed() && ref == 1) cleanOrphanedConnectionsImpl(sender); } void cleanOrphanedConnectionsImpl(QObject *sender); ConnectionList &connectionsForSignal(int signal) { - return signalVector.load()->at(signal); + return signalVector.loadRelaxed()->at(signal); } void resizeSignalVector(uint size) { - SignalVector *vector = this->signalVector.load(); + SignalVector *vector = this->signalVector.loadRelaxed(); if (vector && vector->allocated > size) return; size = (size + 7) & ~7; @@ -305,14 +305,14 @@ public: newVector->next = nullptr; newVector->allocated = size; - signalVector.store(newVector); + signalVector.storeRelaxed(newVector); if (vector) { - vector->nextInOrphanList = orphaned.load(); - orphaned.store(ConnectionOrSignalVector::fromSignalVector(vector)); + vector->nextInOrphanList = orphaned.loadRelaxed(); + orphaned.storeRelaxed(ConnectionOrSignalVector::fromSignalVector(vector)); } } int signalVectorCount() const { - return signalVector ? signalVector.load()->count() : -1; + return signalVector ? signalVector.loadRelaxed()->count() : -1; } static void deleteOrphaned(ConnectionOrSignalVector *c); @@ -366,11 +366,11 @@ public: void ensureConnectionData() { - if (connections.load()) + if (connections.loadRelaxed()) return; ConnectionData *cd = new ConnectionData; cd->ref.ref(); - connections.store(cd); + connections.storeRelaxed(cd); } public: ExtraData *extraData; // extra data set by the user diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp index 6ff8268978..2a246b1204 100644 --- a/src/corelib/kernel/qsocketnotifier.cpp +++ b/src/corelib/kernel/qsocketnotifier.cpp @@ -152,7 +152,7 @@ QSocketNotifier::QSocketNotifier(qintptr socket, Type type, QObject *parent) else if (!d->threadData->hasEventDispatcher()) qWarning("QSocketNotifier: Can only be used with threads started with QThread"); else - d->threadData->eventDispatcher.load()->registerSocketNotifier(this); + d->threadData->eventDispatcher.loadRelaxed()->registerSocketNotifier(this); } /*! @@ -241,9 +241,9 @@ void QSocketNotifier::setEnabled(bool enable) return; } if (d->snenabled) - d->threadData->eventDispatcher.load()->registerSocketNotifier(this); + d->threadData->eventDispatcher.loadRelaxed()->registerSocketNotifier(this); else - d->threadData->eventDispatcher.load()->unregisterSocketNotifier(this); + d->threadData->eventDispatcher.loadRelaxed()->unregisterSocketNotifier(this); } diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index b9563b8395..511dc3c81c 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2366,7 +2366,7 @@ QVariant& QVariant::operator=(const QVariant &variant) void QVariant::detach() { - if (!d.is_shared || d.data.shared->ref.load() == 1) + if (!d.is_shared || d.data.shared->ref.loadRelaxed() == 1) return; Private dd; diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index e094ebff52..c8cb551863 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -577,7 +577,7 @@ Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant::Type p); #endif inline bool QVariant::isDetached() const -{ return !d.is_shared || d.data.shared->ref.load() == 1; } +{ return !d.is_shared || d.data.shared->ref.loadRelaxed() == 1; } #ifdef Q_QDOC diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp index 3c73c0b851..d2ae9668fe 100644 --- a/src/corelib/kernel/qwineventnotifier.cpp +++ b/src/corelib/kernel/qwineventnotifier.cpp @@ -124,7 +124,7 @@ QWinEventNotifier::QWinEventNotifier(HANDLE hEvent, QObject *parent) : QObject(*new QWinEventNotifierPrivate(hEvent, false), parent) { Q_D(QWinEventNotifier); - QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.load(); + QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.loadRelaxed(); if (Q_UNLIKELY(!eventDispatcher)) { qWarning("QWinEventNotifier: Can only be used with threads started with QThread"); return; @@ -197,7 +197,7 @@ void QWinEventNotifier::setEnabled(bool enable) return; d->enabled = enable; - QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.load(); + QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.loadRelaxed(); if (!eventDispatcher) { // perhaps application is shutting down if (!enable && d->waitHandle != nullptr) d->unregisterWaitObject(); @@ -256,7 +256,7 @@ void QWinEventNotifierPrivate::unregisterWaitObject() static void CALLBACK wfsoCallback(void *context, BOOLEAN /*ignore*/) { QWinEventNotifierPrivate *nd = reinterpret_cast(context); - QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.load(); + QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.loadRelaxed(); // Happens when Q(Core)Application is destroyed before QWinEventNotifier. // https://bugreports.qt.io/browse/QTBUG-70214 -- cgit v1.2.3 From 322ac729450351c4f1faf5a96a564f16bfbc6547 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 20 Jun 2019 02:13:12 +0200 Subject: QObject: fix memory order on load/store of signal spy callback set QSignalSpyCallbackSet is a set of pointers, so when we store a pointer to it for later dereferencing, we need to use a release fence for the store and a corresponding acquire on load, lest the two don't synchronize with each other and we end up with a data race. Amends a65752c71bd25bbb66bf33d3a82f7901419c5d95. Change-Id: Ic2983d76237c5c5b00eb2a3575b10beb84d57190 Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobject.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 7eba9b05ff..8f80be30bd 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -82,7 +82,7 @@ Q_CORE_EXPORT QBasicAtomicPointer qt_signal_spy_callback_ void qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set) { - qt_signal_spy_callback_set.store(callback_set); + qt_signal_spy_callback_set.storeRelease(callback_set); } QDynamicMetaObjectData::~QDynamicMetaObjectData() @@ -3696,7 +3696,7 @@ void doActivate(QObject *sender, int signal_index, void **argv) signal_index, argv); } - const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.load() : nullptr; + const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.loadAcquire() : nullptr; void *empty_argv[] = { nullptr }; if (!argv) -- cgit v1.2.3 From 9c357d64db3aedba6802e9a508abbbdc67f3ef8d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 3 Jun 2019 23:08:05 +0200 Subject: QtCore: use new QLatin1String::arg() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Saves ~600B in text size on optimized GCC 9.1 Linux AMD64 builds. Change-Id: I12f4e7c8d28af9549b481859bc96a155aeb6f15c Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- src/corelib/kernel/qjni.cpp | 8 ++++---- src/corelib/kernel/qsystemsemaphore_systemv.cpp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 75a2436d9d..5f652d70e3 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -47,9 +47,9 @@ QT_BEGIN_NAMESPACE -static inline QString keyBase() +static inline QLatin1String keyBase() { - return QStringLiteral("%1%2:%3"); + return QLatin1String("%1%2:%3"); } static QString qt_convertJString(jstring string) @@ -154,7 +154,7 @@ static jmethodID getCachedMethodID(JNIEnv *env, if (className.isEmpty()) return getMethodID(env, clazz, name, sig, isStatic); - const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + const QString key = keyBase().arg(QLatin1String(className), QLatin1String(name), QLatin1String(sig)); QHash::const_iterator it; { @@ -206,7 +206,7 @@ static jfieldID getCachedFieldID(JNIEnv *env, if (className.isNull()) return getFieldID(env, clazz, name, sig, isStatic); - const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + const QString key = keyBase().arg(QLatin1String(className), QLatin1String(name), QLatin1String(sig)); QHash::const_iterator it; { diff --git a/src/corelib/kernel/qsystemsemaphore_systemv.cpp b/src/corelib/kernel/qsystemsemaphore_systemv.cpp index 9e438ae2a6..2c38d74d2d 100644 --- a/src/corelib/kernel/qsystemsemaphore_systemv.cpp +++ b/src/corelib/kernel/qsystemsemaphore_systemv.cpp @@ -76,7 +76,7 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode) #if QT_CONFIG(translation) QCoreApplication::tr("%1: key is empty", "QSystemSemaphore") #else - QString::fromLatin1("%1: key is empty") + QLatin1String("%1: key is empty") #endif .arg(QLatin1String("QSystemSemaphore::handle:")); error = QSystemSemaphore::KeyError; @@ -94,7 +94,7 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode) #if QT_CONFIG(translation) QCoreApplication::tr("%1: unable to make key", "QSystemSemaphore") #else - QString::fromLatin1("%1: unable to make key") + QLatin1String("%1: unable to make key") #endif .arg(QLatin1String("QSystemSemaphore::handle:")); error = QSystemSemaphore::KeyError; @@ -111,7 +111,7 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode) #if QT_CONFIG(translation) QCoreApplication::tr("%1: ftok failed", "QSystemSemaphore") #else - QString::fromLatin1("%1: ftok failed") + QLatin1String("%1: ftok failed") #endif .arg(QLatin1String("QSystemSemaphore::handle:")); error = QSystemSemaphore::KeyError; -- cgit v1.2.3 From b68a9df076a5f821b1a1b49207fad9ec9ac8a251 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Mon, 3 Jun 2019 13:40:01 +0200 Subject: Fix bogus setAttribute setter warning Since e9e16c74643 running webengine application you can get warning "Attribute Qt::AA_ShareOpenGLContexts must be set before QCoreApplication is created." WebEngine set shared open gl context on qt_call_pre_routines, so when QCoreApplicationPrivate init() runs. Fixes: QTBUG-76391 Change-Id: I5fc146ed70054b0c1597fe06615cea2d7a8969d8 Reviewed-by: Kai Koehne --- src/corelib/kernel/qcoreapplication.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 8652c45634..db6546028a 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -979,7 +979,11 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on) QCoreApplicationPrivate::attribs |= 1 << attribute; else QCoreApplicationPrivate::attribs &= ~(1 << attribute); +#if defined(QT_NO_QOBJECT) if (Q_UNLIKELY(qApp)) { +#else + if (Q_UNLIKELY(QCoreApplicationPrivate::is_app_running)) { +#endif switch (attribute) { case Qt::AA_EnableHighDpiScaling: case Qt::AA_DisableHighDpiScaling: -- cgit v1.2.3 From 47691260ca623643107ace846352a3604436e428 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Thu, 13 Jun 2019 11:05:12 +0200 Subject: move ENDSESSION_* compat defines to before they are actually used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit amends 144d33df72e5ca905b1d64134784923d5c. Change-Id: Ic6bc475c9d8c3bb727ee209dbab437a18e219b6d Reviewed-by: Jörg Bornemann --- src/corelib/kernel/qcoreapplication_win.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 75cc813298..4f4a29b41b 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -694,6 +694,12 @@ static const char *winPosInsertAfter(quintptr h) static const char *sessionMgrLogOffOption(uint p) { +#ifndef ENDSESSION_CLOSEAPP +#define ENDSESSION_CLOSEAPP 0x00000001 +#endif +#ifndef ENDSESSION_CRITICAL +#define ENDSESSION_CRITICAL 0x40000000 +#endif static const QWinMessageMapping values[] = { {ENDSESSION_CLOSEAPP, "Close application"}, {ENDSESSION_CRITICAL, "Force application end"}, @@ -887,12 +893,6 @@ QString decodeMSG(const MSG& msg) parameters += QLatin1Char(')'); } break; -#ifndef ENDSESSION_CLOSEAPP -#define ENDSESSION_CLOSEAPP 0x00000001 -#endif -#ifndef ENDSESSION_CRITICAL -#define ENDSESSION_CRITICAL 0x40000000 -#endif case WM_QUERYENDSESSION: parameters = QLatin1String("End session: "); if (const char *logoffOption = sessionMgrLogOffOption(uint(wParam))) -- cgit v1.2.3