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 <bradley.hughes@nokia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
ba90d5cc8b
commit
d2aaa13820
@ -922,8 +922,9 @@ QObject::~QObject()
|
|||||||
|
|
||||||
QObjectPrivate::Connection::~Connection()
|
QObjectPrivate::Connection::~Connection()
|
||||||
{
|
{
|
||||||
if (argumentTypes != &DIRECT_CONNECTION_ONLY)
|
int *v = argumentTypes.load();
|
||||||
delete [] static_cast<int *>(argumentTypes);
|
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)
|
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);
|
QMetaMethod m = sender->metaObject()->method(signal);
|
||||||
int *tmp = queuedConnectionTypes(m.parameterTypes());
|
argumentTypes = queuedConnectionTypes(m.parameterTypes());
|
||||||
if (!tmp) // cannot queue arguments
|
if (!argumentTypes) // cannot queue arguments
|
||||||
tmp = &DIRECT_CONNECTION_ONLY;
|
argumentTypes = &DIRECT_CONNECTION_ONLY;
|
||||||
if (!c->argumentTypes.testAndSetOrdered(0, tmp)) {
|
if (!c->argumentTypes.testAndSetOrdered(0, argumentTypes)) {
|
||||||
if (tmp != &DIRECT_CONNECTION_ONLY)
|
if (argumentTypes != &DIRECT_CONNECTION_ONLY)
|
||||||
delete [] tmp;
|
delete [] argumentTypes;
|
||||||
|
argumentTypes = c->argumentTypes.load();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c->argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate
|
if (argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate
|
||||||
return;
|
return;
|
||||||
int nargs = 1; // include return type
|
int nargs = 1; // include return type
|
||||||
while (c->argumentTypes[nargs-1])
|
while (argumentTypes[nargs-1])
|
||||||
++nargs;
|
++nargs;
|
||||||
int *types = (int *) qMalloc(nargs*sizeof(int));
|
int *types = (int *) qMalloc(nargs*sizeof(int));
|
||||||
Q_CHECK_PTR(types);
|
Q_CHECK_PTR(types);
|
||||||
@ -3242,7 +3245,7 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
|
|||||||
types[0] = 0; // return type
|
types[0] = 0; // return type
|
||||||
args[0] = 0; // return value
|
args[0] = 0; // return value
|
||||||
for (int n = 1; n < nargs; ++n)
|
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,
|
QCoreApplication::postEvent(c->receiver, new QMetaCallEvent(c->method_offset,
|
||||||
c->method_relative,
|
c->method_relative,
|
||||||
c->callFunction,
|
c->callFunction,
|
||||||
|
Loading…
Reference in New Issue
Block a user