31#include <jau/test/catch2_ext.hpp>
54 serviceInitDone.count_down();
63 void service01FastStopWork(jau::service_runner& sr)
noexcept {
67 serviceWorkDone.count_down();
71 void service10CounterWork(jau::service_runner& sr)
noexcept {
73 serviceWorkDone.count_down();
74 std::this_thread::sleep_for(std::chrono::milliseconds(10));
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());
104 REQUIRE_MSG(
"service10_init_complete",
true == serviceInitDone.wait_for(100_ms) );
105 REQUIRE(
true == serviceWorkDone.wait_for(2_s) );
106 REQUIRE_MSG(
"service10_end_complete",
true == serviceEndDone.wait_for(100_ms) );
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());
165 REQUIRE_MSG(
"service10_init_complete",
true == serviceInitDone.wait_for(100_ms) );
166 REQUIRE_MSG(
"service10_work_complete",
true == serviceWorkDone.wait_for(500_ms) );
167 REQUIRE_MSG(
"service10_end_complete",
true == serviceEndDone.wait_for(100_ms) );
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() );
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.
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.
ordered_atomic< int, std::memory_order_seq_cst > sc_atomic_int
SC atomic integral scalar integer.
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.
METHOD_AS_TEST_CASE(TestServiceRunner01::test01_service01_fast_stop, "test01_service01_fast_stop")