From d2aaa13820e400de73e3b0a12af6b7b7c6393d32 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 28 Sep 2011 12:03:17 +0200 Subject: Use load() instead of implicit cast when using QueuedConnection queued_activate() sets the argumentTypes atomic pointer on first use, which mixes a load, memory initialization, test-and-set-ordered, and another load. The explicit memory ordering is necessary to ensure that the memory stores happen in program order. Change-Id: Id1f8641f9cd081ce81aa8e830692f7af8261e84b Reviewed-by: Bradley T. Hughes Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobject.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index a50d5a92ce..4c969c8f4a 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -922,8 +922,9 @@ QObject::~QObject() QObjectPrivate::Connection::~Connection() { - if (argumentTypes != &DIRECT_CONNECTION_ONLY) - delete [] static_cast(argumentTypes); + int *v = argumentTypes.load(); + if (v != &DIRECT_CONNECTION_ONLY) + delete [] v; } @@ -3220,20 +3221,22 @@ void QMetaObject::connectSlotsByName(QObject *o) static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv) { - if (!c->argumentTypes && c->argumentTypes != &DIRECT_CONNECTION_ONLY) { + int *argumentTypes = c->argumentTypes.load(); + if (!argumentTypes && argumentTypes != &DIRECT_CONNECTION_ONLY) { QMetaMethod m = sender->metaObject()->method(signal); - int *tmp = queuedConnectionTypes(m.parameterTypes()); - if (!tmp) // cannot queue arguments - tmp = &DIRECT_CONNECTION_ONLY; - if (!c->argumentTypes.testAndSetOrdered(0, tmp)) { - if (tmp != &DIRECT_CONNECTION_ONLY) - delete [] tmp; + argumentTypes = queuedConnectionTypes(m.parameterTypes()); + if (!argumentTypes) // cannot queue arguments + argumentTypes = &DIRECT_CONNECTION_ONLY; + if (!c->argumentTypes.testAndSetOrdered(0, argumentTypes)) { + if (argumentTypes != &DIRECT_CONNECTION_ONLY) + delete [] argumentTypes; + argumentTypes = c->argumentTypes.load(); } } - if (c->argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate + if (argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate return; int nargs = 1; // include return type - while (c->argumentTypes[nargs-1]) + while (argumentTypes[nargs-1]) ++nargs; int *types = (int *) qMalloc(nargs*sizeof(int)); Q_CHECK_PTR(types); @@ -3242,7 +3245,7 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect types[0] = 0; // return type args[0] = 0; // return value for (int n = 1; n < nargs; ++n) - args[n] = QMetaType::create((types[n] = c->argumentTypes[n-1]), argv[n]); + args[n] = QMetaType::create((types[n] = argumentTypes[n-1]), argv[n]); QCoreApplication::postEvent(c->receiver, new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, -- cgit v1.2.3