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

Adds time jump information to the broadcast time update callbacks. #694

Merged
merged 4 commits into from
Jul 8, 2023
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
26 changes: 19 additions & 7 deletions src/openlcb/BroadcastTime.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,16 @@ class BroadcastTime : public SimpleEventHandler
, public TimeBase
{
public:
typedef std::vector<std::function<void()>>::size_type UpdateSubscribeHandle;
/// An opaque data element that is returned from update subscriber
/// registration, and allows unregistering a subscriber.
typedef size_t UpdateSubscribeHandle;

/// Callback type used for time update subscribers.
///
/// @param old Fast clock's current time according to the pre-update state.
/// @param current Fast clock's current time according to the post-update
/// state.
typedef std::function<void(time_t old, time_t current)> TimeUpdateCallback;

/// Destructor.
virtual ~BroadcastTime()
Expand Down Expand Up @@ -127,19 +136,19 @@ public:
/// executor.
/// @param callback function callback to be called.
/// @return handle to entry that can be used in update_unsubscribe
UpdateSubscribeHandle update_subscribe_add(std::function<void()> callback)
UpdateSubscribeHandle update_subscribe_add(TimeUpdateCallback callback)
{
AtomicHolder h(this);
for (size_t i = 0; i < callbacks_.size(); ++i)
{
// atempt to garbage collect unused entries
if (callbacks_[i] == nullptr)
{
callbacks_[i] = callback;
callbacks_[i] = std::move(callback);
return i;
}
}
callbacks_.emplace_back(callback);
callbacks_.emplace_back(std::move(callback));
return callbacks_.size() - 1;
}

Expand Down Expand Up @@ -225,14 +234,17 @@ protected:

/// Service all of the attached update subscribers. These are called when
/// there are jumps in time or if the clock is stopped or started.
void service_callbacks()
/// @param old Fast clock's current time according to the pre-update state.
/// @param current Fast clock's current time according to the post-update
/// state.
void service_callbacks(time_t old, time_t current)
{
AtomicHolder h(this);
for (auto n : callbacks_)
{
if (n)
{
n();
n(old, current);
}
}
}
Expand All @@ -245,7 +257,7 @@ protected:
StateFlowTimer timer_; ///< timer helper

/// update subscribers
std::vector<std::function<void()>> callbacks_;
std::vector<TimeUpdateCallback> callbacks_;

int16_t rateRequested_; ///< pending clock rate

Expand Down
16 changes: 8 additions & 8 deletions src/openlcb/BroadcastTimeClient.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ private:
void start_stop_logic(bool started)
{
bool notify = false;
time_t val = 0;
{
AtomicHolder h(this);
if (started_ != started)
Expand All @@ -254,12 +255,13 @@ private:
}
started_ = started;
notify = true;
val = seconds_;
}
// release AtomicHolder
}
if (notify)
{
service_callbacks();
service_callbacks(val, val);
}
}

Expand Down Expand Up @@ -333,20 +335,17 @@ private:

{
bool notify = false;
time_t old_seconds = 0;
time_t new_seconds = 0;
{
AtomicHolder h(this);
time_t old_seconds;
old_seconds = time();
if (rate_ != rateRequested_ ||
(immediateUpdate_ && immediatePending_))
{
// rate changed or an immediate update was pending.
notify = true;
}
else
{
// we will need to check for jitter later
old_seconds = time();
}

// we are about to commit an updated time, reset the flags
immediateUpdate_ = false;
Expand All @@ -355,6 +354,7 @@ private:
rate_ = rateRequested_;
seconds_ = ::mktime(&tm_);
timestamp_ = OSTime::get_monotonic();
new_seconds = seconds_;
if (rolloverPending_)
{
// roll forward/back the 3 second delay for the year/date
Expand All @@ -377,7 +377,7 @@ private:
}
if (notify)
{
service_callbacks();
service_callbacks(old_seconds, new_seconds);
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/openlcb/BroadcastTimeServer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,8 @@ class BroadcastTimeServerSet
bool start_or_stop = false;
struct tm tm;
server_->gmtime_r(&tm);
time_t old_seconds = server_->time();
time_t new_seconds = 0;

uint16_t suffix = message()->data()->suffix_;

Expand Down Expand Up @@ -590,9 +592,10 @@ class BroadcastTimeServerSet
AtomicHolder h(server_);
server_->seconds_ = mktime(&tm);
server_->timestamp_ = OSTime::get_monotonic();
new_seconds = server_->seconds_;
}

server_->service_callbacks();
server_->service_callbacks(old_seconds, new_seconds);

if (start_or_stop)
{
Expand Down