Skip to content

Commit

Permalink
Use a std::promise/std::future to avoid busy waiting the step ack mes…
Browse files Browse the repository at this point in the history
…sages in NetworkManagerPrimary (#470)

Signed-off-by: Ivan Santiago Paunovic <[email protected]>
Signed-off-by: Louise Poubel <[email protected]>

Co-authored-by: Louise Poubel <[email protected]>
  • Loading branch information
ivanpauno and chapulina authored Dec 10, 2020
1 parent 8c4f7e1 commit b81fc34
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 9 deletions.
19 changes: 10 additions & 9 deletions src/network/NetworkManagerPrimary.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "NetworkManagerPrimary.hh"

#include <algorithm>
#include <future>
#include <set>
#include <string>
#include <utility>
Expand All @@ -41,6 +42,7 @@

using namespace ignition;
using namespace gazebo;
using namespace std::chrono_literals;

//////////////////////////////////////////////////
NetworkManagerPrimary::NetworkManagerPrimary(
Expand Down Expand Up @@ -142,21 +144,17 @@ bool NetworkManagerPrimary::Step(const UpdateInfo &_info)

// Send step to all secondaries
this->secondaryStates.clear();
this->secondaryStatesPromise = std::promise<void>{};
auto future = this->secondaryStatesPromise.get_future();
this->simStepPub.Publish(step);

// Block until all secondaries are done
{
IGN_PROFILE("Waiting for secondaries");

int sleep = 0;
int maxSleep = 10 * 1000 * 1000;
for (; sleep < maxSleep &&
(this->secondaryStates.size() < this->secondaries.size()); ++sleep)
{
std::this_thread::sleep_for(std::chrono::nanoseconds(1));
}
auto result = future.wait_for(10s);

if (sleep == maxSleep)
if (std::future_status::ready != result)
{
ignerr << "Waited 10 s and got only [" << this->secondaryStates.size()
<< " / " << this->secondaries.size()
Expand Down Expand Up @@ -202,6 +200,10 @@ std::map<std::string, SecondaryControl::Ptr>
void NetworkManagerPrimary::OnStepAck(const msgs::SerializedStateMap &_msg)
{
this->secondaryStates.push_back(_msg);
if (this->secondaryStates.size() == this->secondaries.size())
{
this->secondaryStatesPromise.set_value();
}
}

//////////////////////////////////////////////////
Expand Down Expand Up @@ -316,4 +318,3 @@ void NetworkManagerPrimary::SetAffinity(Entity _performer,
auto newAffinity = components::PerformerAffinity(_secondary);
this->dataPtr->ecm->CreateComponent(_performer, newAffinity);
}

4 changes: 4 additions & 0 deletions src/network/NetworkManagerPrimary.hh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define IGNITION_GAZEBO_NETWORK_NETWORKMANAGERPRIMARY_HH_

#include <atomic>
#include <future>
#include <map>
#include <memory>
#include <string>
Expand Down Expand Up @@ -117,6 +118,9 @@ namespace ignition

/// \brief Keep track of states received from secondaries.
private: std::vector<msgs::SerializedStateMap> secondaryStates;

/// \brief Promise used to notify when all secondaryStates where received.
private: std::promise<void> secondaryStatesPromise;
};
}
} // namespace gazebo
Expand Down

0 comments on commit b81fc34

Please sign in to comment.