summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp20
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf.mm12
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf_p.h2
-rw-r--r--src/corelib/kernel/qmetaobject_p.h10
-rw-r--r--src/corelib/kernel/qobject.cpp49
5 files changed, 64 insertions, 29 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 6ccc7b729b..330a1eb0f5 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2497,6 +2497,26 @@ QStringList QCoreApplication::libraryPaths()
}
}
+#ifdef Q_OS_DARWIN
+ // Check the main bundle's PlugIns directory as this is a standard location for Apple OSes.
+ // Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value
+ // but with a different casing, so it can't be relied upon when the underlying filesystem
+ // is case sensitive (and this is always the case on newer OSes like iOS).
+ if (CFBundleRef bundleRef = CFBundleGetMainBundle()) {
+ if (QCFType<CFURLRef> urlRef = CFBundleCopyBuiltInPlugInsURL(bundleRef)) {
+ if (QCFType<CFURLRef> absoluteUrlRef = CFURLCopyAbsoluteURL(urlRef)) {
+ if (QCFString path = CFURLCopyFileSystemPath(absoluteUrlRef, kCFURLPOSIXPathStyle)) {
+ if (QFile::exists(path)) {
+ path = QDir(path).canonicalPath();
+ if (!app_libpaths->contains(path))
+ app_libpaths->append(path);
+ }
+ }
+ }
+ }
+ }
+#endif // Q_OS_DARWIN
+
QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
if (QFile::exists(installPathPlugins)) {
// Make sure we convert from backslashes to slashes.
diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm
index 55f27a5b60..437e4062ad 100644
--- a/src/corelib/kernel/qeventdispatcher_cf.mm
+++ b/src/corelib/kernel/qeventdispatcher_cf.mm
@@ -210,6 +210,13 @@ QEventDispatcherCoreFoundation::~QEventDispatcherCoreFoundation()
m_cfSocketNotifier.removeSocketNotifiers();
}
+QEventLoop *QEventDispatcherCoreFoundation::currentEventLoop() const
+{
+ QEventLoop *eventLoop = QThreadData::current()->eventLoops.top();
+ Q_ASSERT(eventLoop);
+ return eventLoop;
+}
+
/*!
Processes all pending events that match \a flags until there are no
more events to process. Returns \c true if pending events were handled;
@@ -302,10 +309,7 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
// to exit, and then unwind back to the previous event loop which will break
// immediately, since it has already been exited.
- QEventLoop *currentEventLoop = QThreadData::current()->eventLoops.top();
- Q_ASSERT(currentEventLoop);
-
- if (!currentEventLoop->isRunning()) {
+ if (!currentEventLoop()->isRunning()) {
qEventDispatcherDebug() << "Top level event loop was exited";
break;
} else {
diff --git a/src/corelib/kernel/qeventdispatcher_cf_p.h b/src/corelib/kernel/qeventdispatcher_cf_p.h
index c2592cacc8..e6581e2bac 100644
--- a/src/corelib/kernel/qeventdispatcher_cf_p.h
+++ b/src/corelib/kernel/qeventdispatcher_cf_p.h
@@ -228,6 +228,8 @@ public:
void flush();
protected:
+ QEventLoop *currentEventLoop() const;
+
virtual bool processPostedEvents();
struct ProcessEventsState
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 69f884f4ed..54cc9d33c3 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -167,6 +167,7 @@ class QMutex;
struct QMetaObjectPrivate
{
+ // revision 7 is Qt 5.0 everything lower is not supported
enum { OutputRevision = 7 }; // Used by moc, qmetaobjectbuilder and qdbus
int revision;
@@ -175,12 +176,9 @@ struct QMetaObjectPrivate
int methodCount, methodData;
int propertyCount, propertyData;
int enumeratorCount, enumeratorData;
- int constructorCount, constructorData; //since revision 2
- int flags; //since revision 3
- int signalCount; //since revision 4
- // revision 5 introduces changes in normalized signatures, no new members
- // revision 6 added qt_static_metacall as a member of each Q_OBJECT and inside QMetaObject itself
- // revision 7 is Qt 5
+ int constructorCount, constructorData;
+ int flags;
+ int signalCount;
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
{ return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index e3e536d7e1..a6baff8a49 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -3662,15 +3662,31 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
return;
}
- const QObjectPrivate::ConnectionList *list;
- if (signal_index < connectionLists->count())
- list = &connectionLists->at(signal_index);
- else
- list = &connectionLists->allsignals;
+ // contains the non-empty connection lists
+ const QObjectPrivate::ConnectionList *lists[2];
+ int numLists = 0;
+ if (signal_index < connectionLists->count()) {
+ const auto *list = &connectionLists->at(signal_index);
+ if (list->first) // only add if non-empty
+ lists[numLists++] = list;
+ }
+ if (connectionLists->allsignals.first) // only add if non-empty
+ lists[numLists++] = &connectionLists->allsignals;
+
+ for (int i = 0; i < numLists; ++i) {
+ const auto *list = lists[i];
+ if (i == 0) {
+ // on the first iteration, the mutex must be locked already
+ Q_ASSERT(!locker.mutex()->tryLock());
+ } else {
+ // otherwise the mutex is unlocked and must be relocked
+ locker.relock();
+ if (connectionLists->orphaned)
+ break;
+ }
- do {
QObjectPrivate::Connection *c = list->first;
- if (!c) continue;
+ Q_ASSERT(c);
// We need to check against last here to ensure that signals added
// during the signal emission are not emitted in this emission.
QObjectPrivate::Connection *last = list->last;
@@ -3723,8 +3739,6 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
// destructor of the slot object might also lock a mutex from the signalSlotLock() mutex pool,
// and that would deadlock if the pool happens to return the same mutex.
obj.reset();
-
- locker.relock();
} else if (c->callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
//we compare the vtable to make sure we are not in the destructor of the object.
const int methodIndex = c->method();
@@ -3738,7 +3752,6 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
if (qt_signal_spy_callback_set.slot_end_callback != 0)
qt_signal_spy_callback_set.slot_end_callback(receiver, methodIndex);
- locker.relock();
} else {
const int method = c->method_relative + c->method_offset;
locker.unlock();
@@ -3753,19 +3766,17 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
if (qt_signal_spy_callback_set.slot_end_callback != 0)
qt_signal_spy_callback_set.slot_end_callback(receiver, method);
-
- locker.relock();
}
- if (connectionLists->orphaned)
+ if (c == last) // early break without relock for the last signal
break;
- } while (c != last && (c = c->nextConnectionList) != 0);
- if (connectionLists->orphaned)
- break;
- } while (list != &connectionLists->allsignals &&
- //start over for all signals;
- ((list = &connectionLists->allsignals), true));
+ locker.relock();
+
+ if (connectionLists->orphaned)
+ break;
+ } while ((c = c->nextConnectionList) != 0);
+ }
}