Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NetworkClock: unblock all waiting threads if a network reset is detected #2494

Merged
merged 1 commit into from
Mar 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions doc/release/yarp_3_4/detect_clock_reset.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
detect_clock_reset {#yarp_3_4}
-----------------------

### Libraries

#### `os`

* If in a `yarp::os::NetworkClock` a clock reset is detected, fill the gap between the waiter and the time published by the network clock port. A network clock reset is defined as a jump in the past of the time published by the network clock port. This fix avoids that all the threads that are waiting a `yarp::os::NetworkClock::delay` call on that network clock remain blocked when a time reset occurs.
10 changes: 9 additions & 1 deletion src/libYARP_os/src/yarp/os/NetworkClock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ bool NetworkClock::Private::read(ConnectionReader& reader)
}

timeMutex.lock();
double oldTime = _time;
sec = bot.get(0).asInt32();
nsec = bot.get(1).asInt32();
_time = sec + (nsec * 1e-9);
Expand All @@ -111,7 +112,14 @@ bool NetworkClock::Private::read(ConnectionReader& reader)

listMutex.lock();
auto waiter_it = waiters->begin();
while (waiter_it != waiters->end()) {
if (oldTime > _time) {
// Update the wake-up time. In case of a time reset it closes the gap
// between the waiter and _time.
waiter_it->first = _time + (waiter_it->first - oldTime);
}

while (waiter_it != waiters->end())
{
if (waiter_it->first - _time < 1E-12) {
Semaphore* waiterSemaphore = waiter_it->second;
waiter_it = waiters->erase(waiter_it);
Expand Down