sf.net ticket 2905915 - Fix dbus signal handler deadlock

From: sf.net user 'nabertech'
This commit is contained in:
Andreas Volz 2011-11-28 08:23:32 +01:00
parent d1ec2544d5
commit 82c63b289d
2 changed files with 53 additions and 12 deletions

View file

@ -174,8 +174,11 @@ public:
struct Private; struct Private;
private: private:
void dispatch_pending(Connection::PrivatePList& pending_queue);
DefaultMutex _mutex_p; DefaultMutex _mutex_p;
DefaultMutex _mutex_p_copy;
Connection::PrivatePList _pending_queue; Connection::PrivatePList _pending_queue;
}; };

View file

@ -181,29 +181,67 @@ bool Dispatcher::has_something_to_dispatch()
void Dispatcher::dispatch_pending() void Dispatcher::dispatch_pending()
{ {
_mutex_p.lock(); while (1)
{
_mutex_p.lock();
if (_pending_queue.empty())
{
_mutex_p.unlock();
break;
}
Connection::PrivatePList pending_queue_copy(_pending_queue);
_mutex_p.unlock();
size_t copy_elem_num(pending_queue_copy.size());
dispatch_pending(pending_queue_copy);
//only push_back on list is mandatory!
_mutex_p.lock();
Connection::PrivatePList::iterator i, j;
i = _pending_queue.begin();
size_t counter = 0;
while (counter < copy_elem_num && i != _pending_queue.end())
{
j = i;
++j;
_pending_queue.erase(i);
i = j;
++counter;
}
_mutex_p.unlock();
}
}
void Dispatcher::dispatch_pending(Connection::PrivatePList& pending_queue)
{
// SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things... // SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things...
while (_pending_queue.size() > 0) _mutex_p_copy.lock();
while (pending_queue.size() > 0)
{ {
Connection::PrivatePList::iterator i, j; Connection::PrivatePList::iterator i, j;
i = _pending_queue.begin(); i = pending_queue.begin();
while (i != _pending_queue.end()) while (i != pending_queue.end())
{ {
j = i; j = i;
++j; ++j;
if ((*i)->do_dispatch()) if ((*i)->do_dispatch())
_pending_queue.erase(i); pending_queue.erase(i);
else
debug_log("dispatch_pending_private: do_dispatch error");
i = j; i = j;
} }
} }
_mutex_p.unlock(); _mutex_p_copy.unlock();
} }
void DBus::_init_threading() void DBus::_init_threading()