mirror of
https://github.com/BlackMATov/promise.hpp.git
synced 2025-12-13 03:46:29 +07:00
@@ -277,7 +277,7 @@ namespace jobber_hpp
|
|||||||
tasks_.emplace_back(priority, std::move(task));
|
tasks_.emplace_back(priority, std::move(task));
|
||||||
std::push_heap(tasks_.begin(), tasks_.end());
|
std::push_heap(tasks_.begin(), tasks_.end());
|
||||||
++active_task_count_;
|
++active_task_count_;
|
||||||
cond_var_.notify_all();
|
cond_var_.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline jobber::task_ptr jobber::pop_task_() noexcept {
|
inline jobber::task_ptr jobber::pop_task_() noexcept {
|
||||||
|
|||||||
130
promise.hpp
130
promise.hpp
@@ -280,7 +280,8 @@ namespace promise_hpp
|
|||||||
state_->attach(
|
state_->attach(
|
||||||
next,
|
next,
|
||||||
std::forward<ResolveF>(on_resolve),
|
std::forward<ResolveF>(on_resolve),
|
||||||
std::forward<RejectF>(on_reject));
|
std::forward<RejectF>(on_reject),
|
||||||
|
true);
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,9 +291,15 @@ namespace promise_hpp
|
|||||||
!is_promise<ResolveFR>::value,
|
!is_promise<ResolveFR>::value,
|
||||||
promise<ResolveFR>>
|
promise<ResolveFR>>
|
||||||
then(ResolveF&& on_resolve) {
|
then(ResolveF&& on_resolve) {
|
||||||
return then(
|
promise<ResolveFR> next;
|
||||||
|
state_->attach(
|
||||||
|
next,
|
||||||
std::forward<ResolveF>(on_resolve),
|
std::forward<ResolveF>(on_resolve),
|
||||||
[](std::exception_ptr){});
|
[](std::exception_ptr e) -> ResolveFR {
|
||||||
|
std::rethrow_exception(e);
|
||||||
|
},
|
||||||
|
false);
|
||||||
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename RejectF >
|
template < typename RejectF >
|
||||||
@@ -422,18 +429,28 @@ namespace promise_hpp
|
|||||||
|
|
||||||
template < typename U, typename ResolveF, typename RejectF >
|
template < typename U, typename ResolveF, typename RejectF >
|
||||||
std::enable_if_t<std::is_void<U>::value, void>
|
std::enable_if_t<std::is_void<U>::value, void>
|
||||||
attach(promise<U>& next, ResolveF&& on_resolve, RejectF&& on_reject) {
|
attach(
|
||||||
|
promise<U>& next,
|
||||||
|
ResolveF&& on_resolve,
|
||||||
|
RejectF&& on_reject,
|
||||||
|
bool has_reject)
|
||||||
|
{
|
||||||
auto reject_h = [
|
auto reject_h = [
|
||||||
n = next,
|
n = next,
|
||||||
f = std::forward<RejectF>(on_reject)
|
f = std::forward<RejectF>(on_reject),
|
||||||
|
has_reject
|
||||||
](std::exception_ptr e) mutable {
|
](std::exception_ptr e) mutable {
|
||||||
try {
|
if ( has_reject ) {
|
||||||
invoke_hpp::invoke(
|
try {
|
||||||
std::forward<decltype(f)>(f),
|
invoke_hpp::invoke(
|
||||||
e);
|
std::forward<decltype(f)>(f),
|
||||||
|
e);
|
||||||
|
n.resolve();
|
||||||
|
} catch (...) {
|
||||||
|
n.reject(std::current_exception());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
n.reject(e);
|
n.reject(e);
|
||||||
} catch (...) {
|
|
||||||
n.reject(std::current_exception());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -457,18 +474,28 @@ namespace promise_hpp
|
|||||||
|
|
||||||
template < typename U, typename ResolveF, typename RejectF >
|
template < typename U, typename ResolveF, typename RejectF >
|
||||||
std::enable_if_t<!std::is_void<U>::value, void>
|
std::enable_if_t<!std::is_void<U>::value, void>
|
||||||
attach(promise<U>& next, ResolveF&& on_resolve, RejectF&& on_reject) {
|
attach(
|
||||||
|
promise<U>& next,
|
||||||
|
ResolveF&& on_resolve,
|
||||||
|
RejectF&& on_reject,
|
||||||
|
bool has_reject)
|
||||||
|
{
|
||||||
auto reject_h = [
|
auto reject_h = [
|
||||||
n = next,
|
n = next,
|
||||||
f = std::forward<RejectF>(on_reject)
|
f = std::forward<RejectF>(on_reject),
|
||||||
|
has_reject
|
||||||
](std::exception_ptr e) mutable {
|
](std::exception_ptr e) mutable {
|
||||||
try {
|
if ( has_reject ) {
|
||||||
invoke_hpp::invoke(
|
try {
|
||||||
std::forward<decltype(f)>(f),
|
auto r = invoke_hpp::invoke(
|
||||||
e);
|
std::forward<decltype(f)>(f),
|
||||||
|
e);
|
||||||
|
n.resolve(std::move(r));
|
||||||
|
} catch (...) {
|
||||||
|
n.reject(std::current_exception());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
n.reject(e);
|
n.reject(e);
|
||||||
} catch (...) {
|
|
||||||
n.reject(std::current_exception());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -683,7 +710,8 @@ namespace promise_hpp
|
|||||||
state_->attach(
|
state_->attach(
|
||||||
next,
|
next,
|
||||||
std::forward<ResolveF>(on_resolve),
|
std::forward<ResolveF>(on_resolve),
|
||||||
std::forward<RejectF>(on_reject));
|
std::forward<RejectF>(on_reject),
|
||||||
|
true);
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,9 +721,15 @@ namespace promise_hpp
|
|||||||
!is_promise<ResolveFR>::value,
|
!is_promise<ResolveFR>::value,
|
||||||
promise<ResolveFR>>
|
promise<ResolveFR>>
|
||||||
then(ResolveF&& on_resolve) {
|
then(ResolveF&& on_resolve) {
|
||||||
return then(
|
promise<ResolveFR> next;
|
||||||
|
state_->attach(
|
||||||
|
next,
|
||||||
std::forward<ResolveF>(on_resolve),
|
std::forward<ResolveF>(on_resolve),
|
||||||
[](std::exception_ptr){});
|
[](std::exception_ptr e) -> ResolveFR {
|
||||||
|
std::rethrow_exception(e);
|
||||||
|
},
|
||||||
|
false);
|
||||||
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename RejectF >
|
template < typename RejectF >
|
||||||
@@ -821,18 +855,28 @@ namespace promise_hpp
|
|||||||
|
|
||||||
template < typename U, typename ResolveF, typename RejectF >
|
template < typename U, typename ResolveF, typename RejectF >
|
||||||
std::enable_if_t<std::is_void<U>::value, void>
|
std::enable_if_t<std::is_void<U>::value, void>
|
||||||
attach(promise<U>& next, ResolveF&& on_resolve, RejectF&& on_reject) {
|
attach(
|
||||||
|
promise<U>& next,
|
||||||
|
ResolveF&& on_resolve,
|
||||||
|
RejectF&& on_reject,
|
||||||
|
bool has_reject)
|
||||||
|
{
|
||||||
auto reject_h = [
|
auto reject_h = [
|
||||||
n = next,
|
n = next,
|
||||||
f = std::forward<RejectF>(on_reject)
|
f = std::forward<RejectF>(on_reject),
|
||||||
|
has_reject
|
||||||
](std::exception_ptr e) mutable {
|
](std::exception_ptr e) mutable {
|
||||||
try {
|
if ( has_reject ) {
|
||||||
invoke_hpp::invoke(
|
try {
|
||||||
std::forward<decltype(f)>(f),
|
invoke_hpp::invoke(
|
||||||
e);
|
std::forward<decltype(f)>(f),
|
||||||
|
e);
|
||||||
|
n.resolve();
|
||||||
|
} catch (...) {
|
||||||
|
n.reject(std::current_exception());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
n.reject(e);
|
n.reject(e);
|
||||||
} catch (...) {
|
|
||||||
n.reject(std::current_exception());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -855,18 +899,28 @@ namespace promise_hpp
|
|||||||
|
|
||||||
template < typename U, typename ResolveF, typename RejectF >
|
template < typename U, typename ResolveF, typename RejectF >
|
||||||
std::enable_if_t<!std::is_void<U>::value, void>
|
std::enable_if_t<!std::is_void<U>::value, void>
|
||||||
attach(promise<U>& next, ResolveF&& on_resolve, RejectF&& on_reject) {
|
attach(
|
||||||
|
promise<U>& next,
|
||||||
|
ResolveF&& on_resolve,
|
||||||
|
RejectF&& on_reject,
|
||||||
|
bool has_reject)
|
||||||
|
{
|
||||||
auto reject_h = [
|
auto reject_h = [
|
||||||
n = next,
|
n = next,
|
||||||
f = std::forward<RejectF>(on_reject)
|
f = std::forward<RejectF>(on_reject),
|
||||||
|
has_reject
|
||||||
](std::exception_ptr e) mutable {
|
](std::exception_ptr e) mutable {
|
||||||
try {
|
if ( has_reject ) {
|
||||||
invoke_hpp::invoke(
|
try {
|
||||||
std::forward<decltype(f)>(f),
|
auto r = invoke_hpp::invoke(
|
||||||
e);
|
std::forward<decltype(f)>(f),
|
||||||
|
e);
|
||||||
|
n.resolve(std::move(r));
|
||||||
|
} catch (...) {
|
||||||
|
n.reject(std::current_exception());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
n.reject(e);
|
n.reject(e);
|
||||||
} catch (...) {
|
|
||||||
n.reject(std::current_exception());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -179,16 +179,6 @@ TEST_CASE("promise") {
|
|||||||
});
|
});
|
||||||
REQUIRE(check_42_int == 42);
|
REQUIRE(check_42_int == 42);
|
||||||
}
|
}
|
||||||
{
|
|
||||||
int check_42_int = 0;
|
|
||||||
auto p = pr::promise<int>();
|
|
||||||
p.resolve(42);
|
|
||||||
p.except([](std::exception_ptr){
|
|
||||||
}).then([&check_42_int](int value){
|
|
||||||
check_42_int = value;
|
|
||||||
});
|
|
||||||
REQUIRE(check_42_int == 42);
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
int check_84_int = 0;
|
int check_84_int = 0;
|
||||||
bool check_void_call = false;
|
bool check_void_call = false;
|
||||||
@@ -252,8 +242,9 @@ TEST_CASE("promise") {
|
|||||||
int check_multi_fail = 0;
|
int check_multi_fail = 0;
|
||||||
auto p = pr::promise<>();
|
auto p = pr::promise<>();
|
||||||
p.reject(std::logic_error("hello fail"));
|
p.reject(std::logic_error("hello fail"));
|
||||||
p.except([&check_multi_fail](std::exception_ptr){
|
p.except([&check_multi_fail](std::exception_ptr e){
|
||||||
++check_multi_fail;
|
++check_multi_fail;
|
||||||
|
std::rethrow_exception(e);
|
||||||
}).except([&check_multi_fail](std::exception_ptr){
|
}).except([&check_multi_fail](std::exception_ptr){
|
||||||
++check_multi_fail;
|
++check_multi_fail;
|
||||||
});
|
});
|
||||||
@@ -316,6 +307,7 @@ TEST_CASE("promise") {
|
|||||||
});
|
});
|
||||||
p.except([&call_fail_with_logic_error](std::exception_ptr e){
|
p.except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
call_fail_with_logic_error = check_hello_fail_exception(e);
|
call_fail_with_logic_error = check_hello_fail_exception(e);
|
||||||
|
return 0;
|
||||||
});
|
});
|
||||||
REQUIRE(call_fail_with_logic_error);
|
REQUIRE(call_fail_with_logic_error);
|
||||||
}
|
}
|
||||||
@@ -328,6 +320,7 @@ TEST_CASE("promise") {
|
|||||||
});
|
});
|
||||||
p.except([&call_fail_with_logic_error](std::exception_ptr e){
|
p.except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
call_fail_with_logic_error = check_hello_fail_exception(e);
|
call_fail_with_logic_error = check_hello_fail_exception(e);
|
||||||
|
return 0;
|
||||||
});
|
});
|
||||||
REQUIRE(call_fail_with_logic_error);
|
REQUIRE(call_fail_with_logic_error);
|
||||||
}
|
}
|
||||||
@@ -356,6 +349,7 @@ TEST_CASE("promise") {
|
|||||||
pr::make_rejected_promise<int>(std::logic_error("hello fail"))
|
pr::make_rejected_promise<int>(std::logic_error("hello fail"))
|
||||||
.except([&call_fail_with_logic_error](std::exception_ptr e){
|
.except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
call_fail_with_logic_error = check_hello_fail_exception(e);
|
call_fail_with_logic_error = check_hello_fail_exception(e);
|
||||||
|
return 0;
|
||||||
});
|
});
|
||||||
REQUIRE(call_fail_with_logic_error);
|
REQUIRE(call_fail_with_logic_error);
|
||||||
}
|
}
|
||||||
@@ -703,7 +697,7 @@ TEST_CASE("promise") {
|
|||||||
class o_t {
|
class o_t {
|
||||||
public:
|
public:
|
||||||
o_t() = delete;
|
o_t() = delete;
|
||||||
o_t(int) {}
|
o_t(int i) { (void)i; }
|
||||||
};
|
};
|
||||||
|
|
||||||
pr::promise<>()
|
pr::promise<>()
|
||||||
@@ -759,7 +753,7 @@ TEST_CASE("promise") {
|
|||||||
class o_t {
|
class o_t {
|
||||||
public:
|
public:
|
||||||
o_t() = delete;
|
o_t() = delete;
|
||||||
o_t(int) {}
|
o_t(int i) { (void)i; }
|
||||||
};
|
};
|
||||||
|
|
||||||
pr::promise<>()
|
pr::promise<>()
|
||||||
@@ -988,6 +982,7 @@ TEST_CASE("promise") {
|
|||||||
pr::make_resolved_promise(42)};
|
pr::make_resolved_promise(42)};
|
||||||
}).except([&call_fail_with_logic_error](std::exception_ptr e){
|
}).except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
call_fail_with_logic_error = check_hello_fail_exception(e);
|
call_fail_with_logic_error = check_hello_fail_exception(e);
|
||||||
|
return 0;
|
||||||
});
|
});
|
||||||
REQUIRE(call_fail_with_logic_error);
|
REQUIRE(call_fail_with_logic_error);
|
||||||
}
|
}
|
||||||
@@ -1044,6 +1039,7 @@ TEST_CASE("promise") {
|
|||||||
pr::make_rejected_promise<float>(std::logic_error("hello fail")));
|
pr::make_rejected_promise<float>(std::logic_error("hello fail")));
|
||||||
}).except([&call_fail_with_logic_error](std::exception_ptr e){
|
}).except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
call_fail_with_logic_error = check_hello_fail_exception(e);
|
call_fail_with_logic_error = check_hello_fail_exception(e);
|
||||||
|
return std::make_tuple(0, 0.f);
|
||||||
});
|
});
|
||||||
REQUIRE(call_fail_with_logic_error);
|
REQUIRE(call_fail_with_logic_error);
|
||||||
}
|
}
|
||||||
@@ -1077,6 +1073,25 @@ TEST_CASE("get_and_wait") {
|
|||||||
}};
|
}};
|
||||||
REQUIRE_NOTHROW(p.get());
|
REQUIRE_NOTHROW(p.get());
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const auto time_now = [](){
|
||||||
|
return std::chrono::high_resolution_clock::now();
|
||||||
|
};
|
||||||
|
|
||||||
|
auto p1 = pr::make_resolved_promise();
|
||||||
|
REQUIRE_NOTHROW(p1.wait());
|
||||||
|
REQUIRE(p1.wait_for(std::chrono::milliseconds(-1)) == pr::promise_wait_status::no_timeout);
|
||||||
|
REQUIRE(p1.wait_for(std::chrono::milliseconds(0)) == pr::promise_wait_status::no_timeout);
|
||||||
|
REQUIRE(p1.wait_until(time_now() + std::chrono::milliseconds(-1)) == pr::promise_wait_status::no_timeout);
|
||||||
|
REQUIRE(p1.wait_until(time_now() + std::chrono::milliseconds(0)) == pr::promise_wait_status::no_timeout);
|
||||||
|
|
||||||
|
auto p2 = pr::make_resolved_promise<int>(5);
|
||||||
|
REQUIRE_NOTHROW(p2.wait());
|
||||||
|
REQUIRE(p2.wait_for(std::chrono::milliseconds(-1)) == pr::promise_wait_status::no_timeout);
|
||||||
|
REQUIRE(p2.wait_for(std::chrono::milliseconds(0)) == pr::promise_wait_status::no_timeout);
|
||||||
|
REQUIRE(p2.wait_until(time_now() + std::chrono::milliseconds(-1)) == pr::promise_wait_status::no_timeout);
|
||||||
|
REQUIRE(p2.wait_until(time_now() + std::chrono::milliseconds(0)) == pr::promise_wait_status::no_timeout);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
auto p = pr::promise<void>();
|
auto p = pr::promise<void>();
|
||||||
auto_thread t{[p]() mutable {
|
auto_thread t{[p]() mutable {
|
||||||
@@ -1242,7 +1257,9 @@ TEST_CASE("promise_transformations") {
|
|||||||
.then([](int)->int{
|
.then([](int)->int{
|
||||||
throw std::logic_error("hello fail");
|
throw std::logic_error("hello fail");
|
||||||
})
|
})
|
||||||
.except([](std::exception_ptr){});
|
.except([](std::exception_ptr){
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same<decltype(p_v)::value_type, int>::value,
|
std::is_same<decltype(p_v)::value_type, int>::value,
|
||||||
"unit test fail");
|
"unit test fail");
|
||||||
@@ -1253,6 +1270,7 @@ TEST_CASE("promise_transformations") {
|
|||||||
throw std::logic_error("hello fail");
|
throw std::logic_error("hello fail");
|
||||||
})
|
})
|
||||||
.except([](std::exception_ptr){
|
.except([](std::exception_ptr){
|
||||||
|
return 0;
|
||||||
});
|
});
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same<decltype(p_v)::value_type, int>::value,
|
std::is_same<decltype(p_v)::value_type, int>::value,
|
||||||
@@ -1260,3 +1278,76 @@ TEST_CASE("promise_transformations") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("life_after_except") {
|
||||||
|
{
|
||||||
|
int check_42_int = 0;
|
||||||
|
bool call_fail_with_logic_error = false;
|
||||||
|
auto p = pr::make_rejected_promise<int>(std::logic_error("hello fail"));
|
||||||
|
p.then([](int v){
|
||||||
|
return v;
|
||||||
|
})
|
||||||
|
.except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
|
call_fail_with_logic_error = check_hello_fail_exception(e);
|
||||||
|
return 42;
|
||||||
|
})
|
||||||
|
.then([&check_42_int](int value){
|
||||||
|
check_42_int = value;
|
||||||
|
});
|
||||||
|
REQUIRE(check_42_int == 42);
|
||||||
|
REQUIRE(call_fail_with_logic_error);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int check_42_int = 0;
|
||||||
|
bool call_fail_with_logic_error = false;
|
||||||
|
auto p = pr::make_rejected_promise<int>(std::logic_error("hello fail"));
|
||||||
|
p.then([](int v){
|
||||||
|
return v;
|
||||||
|
})
|
||||||
|
.except([&call_fail_with_logic_error](std::exception_ptr e) -> int {
|
||||||
|
call_fail_with_logic_error = check_hello_fail_exception(e);
|
||||||
|
std::rethrow_exception(e);
|
||||||
|
})
|
||||||
|
.except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
|
call_fail_with_logic_error = call_fail_with_logic_error && check_hello_fail_exception(e);
|
||||||
|
return 42;
|
||||||
|
})
|
||||||
|
.then([&check_42_int](int value){
|
||||||
|
check_42_int = value;
|
||||||
|
});
|
||||||
|
REQUIRE(check_42_int == 42);
|
||||||
|
REQUIRE(call_fail_with_logic_error);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
bool call_then_after_except = false;
|
||||||
|
bool call_fail_with_logic_error = false;
|
||||||
|
auto p = pr::make_rejected_promise(std::logic_error("hello fail"));
|
||||||
|
p.then([](){})
|
||||||
|
.except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
|
call_fail_with_logic_error = check_hello_fail_exception(e);
|
||||||
|
})
|
||||||
|
.then([&call_then_after_except](){
|
||||||
|
call_then_after_except = true;
|
||||||
|
});
|
||||||
|
REQUIRE(call_then_after_except);
|
||||||
|
REQUIRE(call_fail_with_logic_error);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
bool call_fail_with_logic_error = false;
|
||||||
|
bool call_then_after_multi_except = false;
|
||||||
|
auto p = pr::make_rejected_promise(std::logic_error("hello fail"));
|
||||||
|
p.then([](){})
|
||||||
|
.except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
|
call_fail_with_logic_error = check_hello_fail_exception(e);
|
||||||
|
std::rethrow_exception(e);
|
||||||
|
})
|
||||||
|
.except([&call_fail_with_logic_error](std::exception_ptr e){
|
||||||
|
call_fail_with_logic_error = call_fail_with_logic_error && check_hello_fail_exception(e);
|
||||||
|
})
|
||||||
|
.then([&call_then_after_multi_except](){
|
||||||
|
call_then_after_multi_except = true;
|
||||||
|
});
|
||||||
|
REQUIRE(call_fail_with_logic_error);
|
||||||
|
REQUIRE(call_then_after_multi_except);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ namespace scheduler_hpp
|
|||||||
, typename R = schedule_invoke_result_t<F, Args...> >
|
, typename R = schedule_invoke_result_t<F, Args...> >
|
||||||
promise<R> schedule(scheduler_priority scheduler_priority, F&& f, Args&&... args);
|
promise<R> schedule(scheduler_priority scheduler_priority, F&& f, Args&&... args);
|
||||||
|
|
||||||
|
bool process_one_task() noexcept;
|
||||||
scheduler_wait_status process_all_tasks() noexcept;
|
scheduler_wait_status process_all_tasks() noexcept;
|
||||||
|
|
||||||
template < typename Rep, typename Period >
|
template < typename Rep, typename Period >
|
||||||
@@ -157,6 +158,15 @@ namespace scheduler_hpp
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool scheduler::process_one_task() noexcept {
|
||||||
|
std::unique_lock<std::mutex> lock(tasks_mutex_);
|
||||||
|
if ( tasks_.empty() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
process_task_(std::move(lock));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
inline scheduler_wait_status scheduler::process_all_tasks() noexcept {
|
inline scheduler_wait_status scheduler::process_all_tasks() noexcept {
|
||||||
while ( !cancelled_ && active_task_count_ ) {
|
while ( !cancelled_ && active_task_count_ ) {
|
||||||
std::unique_lock<std::mutex> lock(tasks_mutex_);
|
std::unique_lock<std::mutex> lock(tasks_mutex_);
|
||||||
@@ -237,6 +247,7 @@ namespace scheduler_hpp
|
|||||||
if ( task ) {
|
if ( task ) {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
task->run();
|
task->run();
|
||||||
|
lock.lock();
|
||||||
--active_task_count_;
|
--active_task_count_;
|
||||||
cond_var_.notify_all();
|
cond_var_.notify_all();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,22 @@ TEST_CASE("scheduler") {
|
|||||||
s.process_all_tasks();
|
s.process_all_tasks();
|
||||||
REQUIRE(counter == 3);
|
REQUIRE(counter == 3);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
sd::scheduler s;
|
||||||
|
int counter = 0;
|
||||||
|
s.schedule([&counter](){ ++counter; });
|
||||||
|
s.schedule([&counter](){ ++counter; });
|
||||||
|
s.schedule([&counter](){ ++counter; });
|
||||||
|
REQUIRE(counter == 0);
|
||||||
|
REQUIRE(s.process_one_task());
|
||||||
|
REQUIRE(counter == 1);
|
||||||
|
REQUIRE(s.process_one_task());
|
||||||
|
REQUIRE(counter == 2);
|
||||||
|
REQUIRE(s.process_one_task());
|
||||||
|
REQUIRE(counter == 3);
|
||||||
|
REQUIRE_FALSE(s.process_one_task());
|
||||||
|
REQUIRE(counter == 3);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
sd::scheduler s;
|
sd::scheduler s;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user