summaryrefslogtreecommitdiffstats
path: root/src/dbus
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2009-03-27 18:10:36 +0100
committerThiago Macieira <thiago.macieira@nokia.com>2009-03-27 21:55:28 +0100
commitb410a39fad176593ed75b742a486f8710c6ef60f (patch)
treeb4559d7bb3335feb60c95cff37787900a66c9c69 /src/dbus
parentec24cf81e231974fde2bb4903a00e63abce6465b (diff)
Fix crashes in D-Bus due to race conditions.
This happens in heavily threaded applications: libdbus-1 asks us to add and remove timers (and watches, but those less often) from any thread. Since QObject's model requires that timers and QSocketDescriptors be added only in the object's own thread, we have to sync back to the main thread. However, since D-Bus keeps adding and removing the timers, we have to keep a queue of timers to be added and that list is accessed by any thread. Make sure that list is only accessed in locked conditions. Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Diffstat (limited to 'src/dbus')
-rw-r--r--src/dbus/qdbusintegrator.cpp6
-rw-r--r--src/dbus/qdbusthreaddebug_p.h7
2 files changed, 8 insertions, 5 deletions
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 7ed0cd53cb..674426b179 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -137,6 +137,7 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
if (!q_dbus_timeout_get_enabled(timeout))
return true;
+ QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d);
if (QCoreApplication::instance() && QThread::currentThread() == d->thread()) {
// correct thread
return qDBusRealAddTimeout(d, timeout, q_dbus_timeout_get_interval(timeout));
@@ -152,7 +153,6 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
static bool qDBusRealAddTimeout(QDBusConnectionPrivate *d, DBusTimeout *timeout, int ms)
{
- QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d);
Q_ASSERT(d->timeouts.keys(timeout).isEmpty());
int timerId = d->startTimer(ms);
@@ -1035,12 +1035,14 @@ void QDBusConnectionPrivate::customEvent(QEvent *e)
QDBusLockerBase::BeforeDeliver, this);
switch (ev->subtype)
{
- case QDBusConnectionCallbackEvent::AddTimeout:
+ case QDBusConnectionCallbackEvent::AddTimeout: {
+ QDBusWatchAndTimeoutLocker locker(RealAddTimeoutAction, this);
while (!timeoutsPendingAdd.isEmpty()) {
QPair<DBusTimeout *, int> entry = timeoutsPendingAdd.takeFirst();
qDBusRealAddTimeout(this, entry.first, entry.second);
}
break;
+ }
case QDBusConnectionCallbackEvent::KillTimer:
qDebug() << QThread::currentThread() << "RemoveTimeout: killing timer" << (ev->timerId & 0xffffff);
diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h
index 715bd6fee3..20d819f425 100644
--- a/src/dbus/qdbusthreaddebug_p.h
+++ b/src/dbus/qdbusthreaddebug_p.h
@@ -92,9 +92,10 @@ enum ThreadAction {
PendingCallBlockAction = 28,
AddTimeoutAction = 50,
- RemoveTimeoutAction = 51,
- KillTimerAction = 52,
- TimerEventAction = 53,
+ RealAddTimeoutAction = 51,
+ RemoveTimeoutAction = 52,
+ KillTimerAction = 58,
+ TimerEventAction = 59,
AddWatchAction = 60,
RemoveWatchAction = 61,
ToggleWatchAction = 62,