75 if( 0 == serviceWorkDone.
value() ) {
84 fprintf(stderr,
"\n\ntest01\n");
87 serviceInitDone.
set(1);
88 serviceEndDone.
set(1);
89 serviceWorkDone.
set(1);
96 REQUIRE( 0 == ping_count.
load() );
97 REQUIRE( 1 == serviceInitDone.
value());
98 REQUIRE( 1 == serviceWorkDone.
value());
99 REQUIRE( 1 == serviceEndDone.
value());
101 fprintf(stderr,
"test01: start: %s\n", service.
toString().c_str());
105 REQUIRE(
true == serviceWorkDone.
wait_for(2_s) );
107 fprintf(stderr,
"test01: latched: %zu\n", serviceWorkDone.
value());
108 fprintf(stderr,
"test01: latched: %s\n", service.
toString().c_str());
109 REQUIRE( 1 == ping_count.
load() );
110 REQUIRE( 0 == serviceInitDone.
value());
111 REQUIRE( 0 == serviceWorkDone.
value());
112 REQUIRE( 0 == serviceEndDone.
value());
114 REQUIRE(
true == service.
stop() );
119 fprintf(stderr,
"\n\ntest02\n");
121 const int loops = 10000;
122 for(
int i=0; i<
loops; ++i) {
124 serviceWorkDone.
set(1);
129 REQUIRE( 0 == ping_count.
load() );
130 REQUIRE( 1 == serviceWorkDone.
value());
135 REQUIRE(
true == serviceWorkDone.
wait_for(2_s) );
136 REQUIRE( 1 == ping_count.
load() );
137 REQUIRE( 0 == serviceWorkDone.
value());
139 REQUIRE(
true == service.
stop() );
145 fprintf(stderr,
"\n\ntest10\n");
148 serviceInitDone.
set(1);
149 serviceEndDone.
set(1);
150 serviceWorkDone.
set(10);
157 REQUIRE( 0 == ping_count.
load() );
158 REQUIRE( 1 == serviceInitDone.
value());
159 REQUIRE( 10 == serviceWorkDone.
value());
160 REQUIRE( 1 == serviceEndDone.
value());
162 fprintf(stderr,
"test10: start: %s\n", service.
toString().c_str());
168 fprintf(stderr,
"test10: latched: %zu\n", serviceWorkDone.
value());
169 fprintf(stderr,
"test10: latched: %s\n", service.
toString().c_str());
170 REQUIRE( 10 == ping_count.
load() );
171 REQUIRE( 0 == serviceInitDone.
value());
172 REQUIRE( 0 == serviceWorkDone.
value());
173 REQUIRE( 0 == serviceEndDone.
value());
175 REQUIRE(
true == service.
stop() );
#define REQUIRE_MSG(MSG,...)
void test10_service01_self_stop()
const bool sighandler_once
void test01_service01_fast_stop()
void test02_service01_fast_stop()
Inspired by std::latch of C++20.
size_t value() const noexcept
Return the current atomic internal counter.
void set(const size_t n) noexcept
Atomically set the internal counter by n.
bool wait_for(const fraction_i64 &timeout_duration) const noexcept
Blocks the calling thread until the internal counter reaches 0 or the given timeout duration has expi...
void count_down(const size_t n=1) noexcept
Atomically decrements the internal counter by n and notifies all blocked wait() threads if zero is re...
Service runner, a reusable dedicated thread performing custom user services.
bool stop() noexcept
Stops this service, if running.
static bool singleton_sighandler() noexcept
Install the singleton SIGALRM sighandler instance.
std::string toString() const noexcept
Returns a string representation of this service.
void start() noexcept
Starts this service, if not running already.
jau::function< R(A...)> bind_member(C1 *base, R(C0::*mfunc)(A...)) noexcept
Bind given class instance and non-void member function to an anonymous function using func_member_tar...
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
bool sleep_for(const fraction_timespec &relative_time, const bool monotonic=true, const bool ignore_irq=true) noexcept
sleep_for causes the current thread to block until a specific amount of time has passed.
CXX_ALWAYS_INLINE _Tp load() const noexcept
METHOD_AS_TEST_CASE(TestServiceRunner01::test01_service01_fast_stop, "test01_service01_fast_stop")