Merge lp:~albaguirre/media-hub/fix-1371454 into lp:media-hub

Proposed by Alberto Aguirre
Status: Merged
Approved by: Jim Hodapp
Approved revision: 71
Merged at revision: 69
Proposed branch: lp:~albaguirre/media-hub/fix-1371454
Merge into: lp:media-hub
Diff against target: 52 lines (+16/-3)
1 file modified
src/core/media/service_implementation.cpp (+16/-3)
To merge this branch: bzr merge lp:~albaguirre/media-hub/fix-1371454
Reviewer Review Type Date Requested Status
Jim Hodapp (community) code Approve
Thomas Voß (community) Approve
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+235893@code.launchpad.net

Commit message

Fix self deadlock when clients disconnect from media::Player

When receiving a media::PlayerImplementation on_client_disconnected signal, avoid calling
remove_player_for_key within the same context as the player object may be deleted (which owns
the signal object whose destructor waits until all slots are dispatched).

Description of the change

Fix self deadlock when clients disconnect from media::Player

When receiving a media::PlayerImplementation on_client_disconnected signal, avoid calling
remove_player_for_key within the same context as the player object may be deleted (which owns
the signal object whose destructor waits until all slots are dispatched).

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Leo Arias (elopio) wrote :

Is there a way to add a regression test for this fix?
If not, is there a manual sequence of steps that would expose it that can be added to the test plan so it's less likely that it will regress?

The test suite in unity exposes the issue, but by the time the unity test suite runs, the feedback comes too late.

lp:~albaguirre/media-hub/fix-1371454 updated
69. By Alberto Aguirre

simplify weak_ptr assignment; document issue

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

> Is there a way to add a regression test for this fix?
> If not, is there a manual sequence of steps that would expose it that can be
> added to the test plan so it's less likely that it will regress?
>
> The test suite in unity exposes the issue, but by the time the unity test
> suite runs, the feedback comes too late.

Yes ideally should be part of the acceptance tests...but I see all those are disabled here...Not sure why.

Manually you could run this stress test:
http://pastebin.ubuntu.com/8423451

It will stop playing video after the 17 iteration (since all 16 binder threads are exhausted).

Revision history for this message
Thomas Voß (thomas-voss) wrote :

Thanks for the change. It is fine to land to address the immediate issues. However:

  http://paste.ubuntu.com/8424830/

is an alternate way of postponing execution without the need to start up a new thread. Would be great if you could adjust this MP to follow the pastebin example. Thanks :)

review: Approve
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

> Thanks for the change. It is fine to land to address the immediate issues.
> However:
>
> http://paste.ubuntu.com/8424830/
>
> is an alternate way of postponing execution without the need to start up a new
> thread. Would be great if you could adjust this MP to follow the pastebin
> example. Thanks :)

OK, let me try.

Revision history for this message
Leo Arias (elopio) wrote :

> Yes ideally should be part of the acceptance tests...but I see all those are
> disabled here...Not sure why.
>
> Manually you could run this stress test:
> http://pastebin.ubuntu.com/8423451
>
> It will stop playing video after the 17 iteration (since all 16 binder threads
> are exhausted).

Great :) When you are ready to land it, please add that test to https://wiki.ubuntu.com/Process/Merges/TestPlan/media-hub
I will make a note to check what's going on with the disabled tests next week. Thanks.

lp:~albaguirre/media-hub/fix-1371454 updated
70. By Alberto Aguirre

Use io_service instead of launching a thread

71. By Alberto Aguirre

remove empty line

Revision history for this message
Jim Hodapp (jhodapp) wrote :

Looks good, thanks.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/core/media/service_implementation.cpp'
2--- src/core/media/service_implementation.cpp 2014-09-09 21:27:29 +0000
3+++ src/core/media/service_implementation.cpp 2014-09-25 17:23:52 +0000
4@@ -23,6 +23,8 @@
5 #include "player_configuration.h"
6 #include "player_implementation.h"
7
8+#include <boost/asio.hpp>
9+
10 #include <cstdint>
11 #include <map>
12 #include <memory>
13@@ -35,10 +37,11 @@
14 struct media::ServiceImplementation::Private
15 {
16 Private()
17- : resume_key(std::numeric_limits<std::uint32_t>::max())
18+ : resume_key(std::numeric_limits<std::uint32_t>::max()),
19+ keep_alive(io_service)
20 {
21 bus = std::shared_ptr<dbus::Bus>(new dbus::Bus(core::dbus::WellKnownBus::session));
22- bus->install_executor(dbus::asio::make_executor(bus));
23+ bus->install_executor(dbus::asio::make_executor(bus, io_service));
24 worker = std::move(std::thread([this]()
25 {
26 bus->run();
27@@ -65,6 +68,8 @@
28 media::Player::PlayerKey resume_key;
29 std::thread worker;
30 dbus::Bus::Ptr bus;
31+ boost::asio::io_service io_service;
32+ boost::asio::io_service::work keep_alive;
33 std::shared_ptr<dbus::Object> indicator_power_session;
34 std::shared_ptr<core::dbus::Property<core::IndicatorPower::PowerLevel>> power_level;
35 std::shared_ptr<core::dbus::Property<core::IndicatorPower::IsWarning>> is_warning;
36@@ -104,7 +109,15 @@
37 auto key = conf.key;
38 player->on_client_disconnected().connect([this, key]()
39 {
40- remove_player_for_key(key);
41+ // Call remove_player_for_key asynchronously otherwise deadlock can occur
42+ // if called within this dispatcher context.
43+ // remove_player_for_key can destroy the player instance which in turn
44+ // destroys the "on_client_disconnected" signal whose destructor will wait
45+ // until all dispatches are done
46+ d->io_service.post([this, key]()
47+ {
48+ remove_player_for_key(key);
49+ });
50 });
51
52 return player;

Subscribers

People subscribed via source and target branches