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))};
60 template <
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()),
167 thread_name_(std::
to_string(thread_id_)),
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()))
266 template <
typename Config,
typename TransporterType>
270 template <
typename Config,
typename TransporterType>
274 template <
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();