25#ifndef GOBY_MIDDLEWARE_APPLICATION_THREAD_H
26#define GOBY_MIDDLEWARE_APPLICATION_THREAD_H
34#include <boost/units/systems/si.hpp>
50 std::type_index
type_i{std::type_index(
typeid(
void))};
60template <
typename Config,
typename TransporterType>
class Thread
63 TransporterType* transporter_{
nullptr};
65 boost::units::quantity<boost::units::si::frequency> loop_frequency_;
66 std::chrono::steady_clock::time_point loop_time_;
67 unsigned long long loop_count_{0};
70 std::atomic<bool>* alive_{
nullptr};
71 std::type_index type_i_{std::type_index(
typeid(
void))};
80 std::string thread_name_;
85 bool finalize_run_{
false};
120 boost::units::quantity<boost::units::si::frequency> loop_freq,
int index = -1)
140 finalize_run_ =
true;
145 int index()
const {
return index_; }
150 std::string
name() {
return thread_name_; }
153 int uid() {
return uid_; }
160 Thread(
const Config&
cfg, boost::units::quantity<boost::units::si::frequency> loop_freq,
162 : loop_frequency_(loop_freq),
163 loop_time_(
std::chrono::steady_clock::now()),
166 thread_id_(
goby::middleware::gettid()),
173 unsigned long long microsec_interval =
176 unsigned long long ticks_since_epoch =
177 std::chrono::duration_cast<std::chrono::microseconds>(loop_time_.time_since_epoch())
181 loop_time_ = std::chrono::steady_clock::time_point(
182 std::chrono::microseconds((ticks_since_epoch + 1) * microsec_interval));
190 throw(std::runtime_error(
191 "void Thread::loop() must be overridden for non-zero loop frequencies"));
201 const Config&
cfg()
const {
return cfg_; }
211 health.set_name(thread_name_);
213 health.set_thread_id_apple(thread_id_);
215 health.set_thread_id(thread_id_);
236 finalize_run_ =
true;
240 bool alive() {
return alive_ && *alive_; }
248 "Thread::transporter_ is null. Must set_transporter() before using"));
253 .template subscribe<shutdown_group_, ThreadIdentifier, MarshallingScheme::CXX_OBJECT>(
254 [
this](
const ThreadIdentifier ti) {
255 if (ti.all_threads ||
256 (ti.type_i == this->type_index() && ti.index == this->index()))
266template <
typename Config,
typename TransporterType>
270template <
typename Config,
typename TransporterType>
274template <
typename Config,
typename TransporterType>
280 if (loop_frequency_hertz() == std::numeric_limits<double>::infinity())
283 transporter_->poll(std::chrono::seconds(0));
286 else if (loop_frequency_hertz() > 0)
288 int events = transporter_->poll(loop_time_);
295 loop_time_ += std::chrono::nanoseconds(
296 (
unsigned long long)(1000000000ull / (loop_frequency_hertz() *
303 transporter_->poll();
simple exception class for goby applications
Class for grouping publications in the Goby middleware. Analogous to "topics" in ROS,...
Represents a thread of execution within the Goby middleware, interleaving periodic events (loop()) wi...
Thread(const Config &cfg, boost::units::quantity< boost::units::si::frequency > loop_freq, int index=-1)
Thread(const Config &cfg, TransporterType *transporter, double loop_freq_hertz=0, int index=-1)
Construct a thread with all possible metadata (using double to specify frequency in Hertz)
static constexpr goby::middleware::Group shutdown_group_
virtual void initialize()
decltype(loop_frequency_) loop_frequency() const
static constexpr goby::middleware::Group joinable_group_
Thread(const Config &cfg, TransporterType *transporter, int index)
Construct a thread with a given configuration, underlying transporter, and index (for multiple instan...
double loop_max_frequency() const
void set_transporter(TransporterType *transporter)
void set_type_index(std::type_index type_i)
TransporterType & transporter() const
TransporterType Transporter
std::type_index type_index()
void set_name(const std::string &name)
virtual void health(goby::middleware::protobuf::ThreadHealth &health)
Called when HealthRequest is made by goby_coroner.
Thread(const Config &cfg, TransporterType *transporter, boost::units::quantity< boost::units::si::frequency > loop_freq, int index=-1)
Construct a thread with all possible metadata (using boost::units to specify frequency)
void thread_health(goby::middleware::protobuf::ThreadHealth &health)
const Config & cfg() const
double loop_frequency_hertz() const
void run(std::atomic< bool > &alive)
Run the thread until the boolean reference passed is set false. This call blocks, and should be run i...
std::string to_string(goby::middleware::protobuf::Layer layer)
The global namespace for the Goby project.
static int warp_factor
Warp factor to speed up (or slow time) the time values returned by SteadyClock::now() and SystemClock...