Skip to content

Commit

Permalink
[MessageControl] Avoid deadlock on multiple Activated notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
sebaszm committed Oct 30, 2023
1 parent 0dbb462 commit 0a92f6d
Showing 1 changed file with 46 additions and 27 deletions.
73 changes: 46 additions & 27 deletions MessageControl/MessageControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace Plugin {
private:
MessageControl& _parent;
};

private:
struct ICollect {

Expand Down Expand Up @@ -169,14 +169,13 @@ namespace Plugin {
// Seems the ID is already in here, thats odd, and impossible :-)
Observers::iterator index = _observing.find(id);

ASSERT(index == _observing.end());

if (index == _observing.end()) {
_observing.emplace(std::piecewise_construct,
std::make_tuple(id),
std::make_tuple(state::ATTACHING));
}
else if (index->second == state::DETACHING) {
index->second = state::OBSERVING;
}

_adminLock.Unlock();

Expand All @@ -185,8 +184,10 @@ namespace Plugin {

void Deactivated(RPC::IRemoteConnection* connection) override
{
ASSERT(connection != nullptr);

RPC::IMonitorableProcess* controlled (connection->QueryInterface<RPC::IMonitorableProcess>());

if (controlled != nullptr) {
// This is a connection that is controleld by WPEFramework. For this we can wait till we
// receive a terminated.
Expand All @@ -201,6 +202,7 @@ namespace Plugin {

void Terminated(RPC::IRemoteConnection* connection) override
{
ASSERT(connection != nullptr);
Drop(connection->Id());
}

Expand All @@ -218,6 +220,8 @@ namespace Plugin {
// Seems the ID is already in here, thats odd, and impossible :-)
Observers::iterator index = _observing.find(id);

ASSERT(index != _observing.end());

if (index != _observing.end()) {
if (index->second == state::ATTACHING) {
_observing.erase(index);
Expand All @@ -236,20 +240,35 @@ namespace Plugin {
{
_adminLock.Lock();

Observers::iterator index = _observing.begin();

while (index != _observing.end()) {
if (index->second == state::ATTACHING) {
index->second = state::OBSERVING;
_parent.Attach(index->first);
index++;
}
else if (index->second == state::DETACHING) {
_parent.Detach(index->first);
index = _observing.erase(index);
}
else {
index++;
bool done = false;

while (done == false) {
Observers::iterator index = _observing.begin();

while (done == false) {
if (index->second == state::ATTACHING) {
const uint32_t id = index->first;
index->second = state::OBSERVING;
_adminLock.Unlock();
_parent.Attach(id);
_adminLock.Lock();
break;
}
else if (index->second == state::DETACHING) {
const uint32_t id = index->first;
_observing.erase(index);
_adminLock.Unlock();
_parent.Detach(id);
_adminLock.Lock();
break;
}
else {
index++;

if (index == _observing.end()) {
done = true;
}
}
}
}

Expand Down Expand Up @@ -319,7 +338,7 @@ namespace Plugin {

_outputLock.Unlock();
}

public:
uint32_t Callback(Plugin::MessageControl::ICollect::ICallback* callback)
{
Expand Down Expand Up @@ -355,15 +374,15 @@ namespace Plugin {

_adminLock.Unlock();
}

void Detach(const uint32_t id)
{
_adminLock.Lock();

_client.RemoveInstance(id);
_cleaning.emplace_back(id);
Cleanup();

_adminLock.Unlock();
}

Expand All @@ -384,7 +403,7 @@ namespace Plugin {
}

if (destructed == true) {
index = _cleaning.erase(index);
index = _cleaning.erase(index);
}
else {
index++;
Expand All @@ -395,7 +414,7 @@ namespace Plugin {
uint32_t Enable(const messagetype type, const string& category, const string& module, const bool enabled) override
{
_client.Enable({static_cast<Core::Messaging::Metadata::type>(type), category, module}, enabled);

return (Core::ERROR_NONE);
}

Expand All @@ -404,14 +423,14 @@ namespace Plugin {
std::list<Exchange::IMessageControl::Control> list;
Messaging::MessageUnit::Iterator index;
_client.Controls(index);

while (index.Next() == true) {
list.push_back( { static_cast<messagetype>(index.Type()), index.Category(), index.Module(), index.Enabled() } );
}

using Implementation = RPC::IteratorType<Exchange::IMessageControl::IControlIterator>;
controls = Core::Service<Implementation>::Create<Exchange::IMessageControl::IControlIterator>(list);

return (Core::ERROR_NONE);
}

Expand Down

0 comments on commit 0a92f6d

Please sign in to comment.