Skip to content

Commit 45aa38a

Browse files
authored
throw_helper - a unified way to throw null pointer exceptions and shutdown exceptions. (#175)
1 parent e4b2cf4 commit 45aa38a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+948
-736
lines changed

.github/workflows/test_matrix.json

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
11
[
22
{
3-
"os": "ubuntu-20.04",
3+
"os": "ubuntu-24.04",
44
"clang-version": 11,
55
"stdlib": "libc++",
66
"tsan": false,
77
"shared": false,
8-
"name" : "ubuntu-20.04, clang-11, libc++, shared=false, tsan=false"
8+
"name" : "ubuntu-24.04, clang-11, libc++, shared=false, tsan=false"
99
},
1010
{
11-
"os": "ubuntu-20.04",
11+
"os": "ubuntu-24.04",
1212
"clang-version": 11,
1313
"stdlib": "libc++",
1414
"tsan": false,
1515
"shared": true,
16-
"name" : "ubuntu-20.04, clang-11, libc++, shared=true, tsan=false"
16+
"name" : "ubuntu-24.04, clang-11, libc++, shared=true, tsan=false"
1717
},
1818
{
19-
"os": "ubuntu-20.04",
19+
"os": "ubuntu-24.04",
2020
"clang-version": 12,
2121
"stdlib": "libc++",
2222
"tsan": false,
2323
"shared": false,
24-
"name" : "ubuntu-20.04, clang-12, libc++, shared=false, tsan=false"
24+
"name" : "ubuntu-24.04, clang-12, libc++, shared=false, tsan=false"
2525
},
2626
{
27-
"os": "ubuntu-20.04",
27+
"os": "ubuntu-24.04",
2828
"clang-version": 12,
2929
"stdlib": "libc++",
3030
"tsan": false,
3131
"shared": true,
32-
"name" : "ubuntu-20.04, clang-12, libc++, shared=true, tsan=false"
32+
"name" : "ubuntu-24.04, clang-12, libc++, shared=true, tsan=false"
3333
},
3434
{
35-
"os": "ubuntu-20.04",
35+
"os": "ubuntu-24.04",
3636
"clang-version": 13,
3737
"stdlib": "libc++",
3838
"tsan": false,
3939
"shared": false,
40-
"name" : "ubuntu-20.04, clang-13, libc++, shared=false, tsan=false"
40+
"name" : "ubuntu-24.04, clang-13, libc++, shared=false, tsan=false"
4141
},
4242
{
43-
"os": "ubuntu-20.04",
43+
"os": "ubuntu-24.04",
4444
"clang-version": 13,
4545
"stdlib": "libc++",
4646
"tsan": false,
4747
"shared": true,
48-
"name" : "ubuntu-20.04, clang-13, libc++, shared=true, tsan=false"
48+
"name" : "ubuntu-24.04, clang-13, libc++, shared=true, tsan=false"
4949
},
5050
{
5151
"os": "ubuntu-22.04",
@@ -250,40 +250,40 @@
250250
"name" : "windows-2022, clang-16, msvc-stl, shared=true, tsan=false"
251251
},
252252
{
253-
"os": "macos-12",
253+
"os": "macos-15",
254254
"stdlib": "libc++",
255255
"tsan": false,
256256
"shared": false,
257-
"name" : "macos-12, clang, libc++, shared=false, tsan=false"
257+
"name" : "macos-15, clang, libc++, shared=false, tsan=false"
258258
},
259259
{
260-
"os": "macos-12",
260+
"os": "macos-15",
261261
"stdlib": "libc++",
262262
"tsan": false,
263263
"shared": true,
264-
"name" : "macos-12, clang, libc++, shared=true, tsan=false"
264+
"name" : "macos-15, clang, libc++, shared=true, tsan=false"
265265
},
266266
{
267-
"os": "macos-12",
267+
"os": "macos-15",
268268
"stdlib": "libc++",
269269
"tsan": true,
270270
"shared": false,
271-
"name" : "macos-12, clang, libc++, shared=false, tsan=true"
271+
"name" : "macos-15, clang, libc++, shared=false, tsan=true"
272272
},
273273
{
274-
"os": "macos-12",
274+
"os": "macos-15",
275275
"gcc-version": 13,
276276
"stdlib": "libstdc++",
277277
"tsan": false,
278278
"shared": false,
279-
"name" : "macos-12, gcc-13, libstdc++-13, shared=false, tsan=false"
279+
"name" : "macos-15, gcc-13, libstdc++-13, shared=false, tsan=false"
280280
},
281281
{
282-
"os": "macos-12",
282+
"os": "macos-15",
283283
"gcc-version": 13,
284284
"stdlib": "libstdc++",
285285
"tsan": false,
286286
"shared": true,
287-
"name" : "macos-12, gcc-13, libstdc++-13, shared=true, tsan=false"
287+
"name" : "macos-15, gcc-13, libstdc++-13, shared=true, tsan=false"
288288
}
289289
]

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ set(concurrencpp_sources
3333
source/threads/thread.cpp
3434
source/timers/timer.cpp
3535
source/timers/timer_queue.cpp
36+
source/utils/throw_helper.cpp
3637
source/utils/math_helper.cpp)
3738

3839
set(concurrencpp_headers
@@ -78,10 +79,10 @@ set(concurrencpp_headers
7879
include/concurrencpp/threads/async_condition_variable.h
7980
include/concurrencpp/threads/thread.h
8081
include/concurrencpp/threads/cache_line.h
81-
include/concurrencpp/timers/constants.h
8282
include/concurrencpp/timers/timer.h
8383
include/concurrencpp/timers/timer_queue.h
8484
include/concurrencpp/utils/bind.h
85+
include/concurrencpp/utils/throw_helper.h
8586
include/concurrencpp/utils/math_helper.h
8687
include/concurrencpp/utils/slist.h
8788
include/concurrencpp/utils/dlist.h)

include/concurrencpp/errors.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef CONCURRENCPP_ERRORS_H
22
#define CONCURRENCPP_ERRORS_H
33

4+
#include "concurrencpp/platform_defs.h"
5+
46
#include <stdexcept>
57

68
namespace concurrencpp::errors {

include/concurrencpp/executors/constants.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@
55
#include <numeric>
66

77
namespace concurrencpp::details::consts {
8-
inline const char* k_inline_executor_name = "concurrencpp::inline_executor";
8+
inline const char* k_inline_executor_name = "inline_executor";
99
constexpr int k_inline_executor_max_concurrency_level = 0;
1010

11-
inline const char* k_thread_executor_name = "concurrencpp::thread_executor";
11+
inline const char* k_thread_executor_name = "thread_executor";
1212
constexpr int k_thread_executor_max_concurrency_level = std::numeric_limits<int>::max();
1313

14-
inline const char* k_thread_pool_executor_name = "concurrencpp::thread_pool_executor";
15-
inline const char* k_background_executor_name = "concurrencpp::background_executor";
14+
inline const char* k_thread_pool_executor_name = "thread_pool_executor";
15+
inline const char* k_background_executor_name = "background_executor";
1616

1717
constexpr int k_worker_thread_max_concurrency_level = 1;
18-
inline const char* k_worker_thread_executor_name = "concurrencpp::worker_thread_executor";
18+
inline const char* k_worker_thread_executor_name = "worker_thread_executor";
1919

20-
inline const char* k_manual_executor_name = "concurrencpp::manual_executor";
20+
inline const char* k_manual_executor_name = "manual_executor";
2121
constexpr int k_manual_executor_max_concurrency_level = std::numeric_limits<int>::max();
2222

23-
inline const char* k_timer_queue_name = "concurrencpp::timer_queue";
23+
inline const char* k_timer_queue_name = "timer_queue";
2424

2525
inline const char* k_executor_shutdown_err_msg = " - shutdown has been called on this executor.";
2626
} // namespace concurrencpp::details::consts

include/concurrencpp/executors/executor.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <string_view>
1111

1212
namespace concurrencpp::details {
13-
[[noreturn]] CRCPP_API void throw_runtime_shutdown_exception(std::string_view executor_name);
1413
CRCPP_API std::string make_executor_worker_name(std::string_view executor_name);
1514
} // namespace concurrencpp::details
1615

@@ -111,12 +110,12 @@ namespace concurrencpp {
111110
}
112111

113112
public:
113+
const std::string name;
114+
114115
executor(std::string_view name) : name(name) {}
115116

116117
virtual ~executor() noexcept = default;
117118

118-
const std::string name;
119-
120119
virtual void enqueue(concurrencpp::task task) = 0;
121120
virtual void enqueue(std::span<concurrencpp::task> tasks) = 0;
122121

include/concurrencpp/executors/inline_executor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace concurrencpp {
1212

1313
void throw_if_aborted() const {
1414
if (m_abort.load(std::memory_order_relaxed)) {
15-
details::throw_runtime_shutdown_exception(name);
15+
details::throw_helper::throw_worker_shutdown_exception(name, "enqueue");
1616
}
1717
}
1818

include/concurrencpp/executors/manual_executor.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@ namespace concurrencpp {
3131
return std::chrono::system_clock::now() + ms;
3232
}
3333

34-
size_t loop_impl(size_t max_count);
35-
size_t loop_until_impl(size_t max_count, std::chrono::time_point<std::chrono::system_clock> deadline);
34+
size_t loop_impl(size_t max_count, const char* calling_method);
35+
size_t loop_until_impl(size_t max_count,
36+
std::chrono::time_point<std::chrono::system_clock> deadline,
37+
const char* calling_method);
3638

37-
void wait_for_tasks_impl(size_t count);
38-
size_t wait_for_tasks_impl(size_t count, std::chrono::time_point<std::chrono::system_clock> deadline);
39+
void wait_for_tasks_impl(size_t count, const char* calling_method);
40+
size_t wait_for_tasks_impl(size_t count,
41+
std::chrono::time_point<std::chrono::system_clock> deadline,
42+
const char* calling_method);
3943

4044
public:
4145
manual_executor();
@@ -58,31 +62,31 @@ namespace concurrencpp {
5862

5963
template<class clock_type, class duration_type>
6064
bool loop_once_until(std::chrono::time_point<clock_type, duration_type> timeout_time) {
61-
return loop_until_impl(1, to_system_time_point(timeout_time));
65+
return loop_until_impl(1, to_system_time_point(timeout_time), "loop_once_until");
6266
}
6367

6468
size_t loop(size_t max_count);
6569
size_t loop_for(size_t max_count, std::chrono::milliseconds max_waiting_time);
6670

6771
template<class clock_type, class duration_type>
6872
size_t loop_until(size_t max_count, std::chrono::time_point<clock_type, duration_type> timeout_time) {
69-
return loop_until_impl(max_count, to_system_time_point(timeout_time));
73+
return loop_until_impl(max_count, to_system_time_point(timeout_time), "loop_until");
7074
}
7175

7276
void wait_for_task();
7377
bool wait_for_task_for(std::chrono::milliseconds max_waiting_time);
7478

7579
template<class clock_type, class duration_type>
7680
bool wait_for_task_until(std::chrono::time_point<clock_type, duration_type> timeout_time) {
77-
return wait_for_tasks_impl(1, to_system_time_point(timeout_time)) == 1;
81+
return wait_for_tasks_impl(1, to_system_time_point(timeout_time), "wait_for_task_until") == 1;
7882
}
7983

8084
void wait_for_tasks(size_t count);
8185
size_t wait_for_tasks_for(size_t count, std::chrono::milliseconds max_waiting_time);
8286

8387
template<class clock_type, class duration_type>
8488
size_t wait_for_tasks_until(size_t count, std::chrono::time_point<clock_type, duration_type> timeout_time) {
85-
return wait_for_tasks_impl(count, to_system_time_point(timeout_time));
89+
return wait_for_tasks_impl(count, to_system_time_point(timeout_time), "wait_for_tasks_until");
8690
}
8791
};
8892
} // namespace concurrencpp

include/concurrencpp/results/constants.h

Lines changed: 1 addition & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -6,113 +6,21 @@ namespace concurrencpp::details::consts {
66
* result_promise
77
*/
88

9-
inline const char* k_result_promise_set_result_error_msg = "concurrencpp::result_promise::set_result() - empty result_promise.";
10-
11-
inline const char* k_result_promise_set_exception_error_msg =
12-
"concurrencpp::result_promise::set_exception() - empty result_promise.";
13-
14-
inline const char* k_result_promise_set_exception_null_exception_error_msg =
15-
"concurrencpp::result_promise::set_exception() - exception pointer is null.";
16-
17-
inline const char* k_result_promise_set_from_function_error_msg =
18-
"concurrencpp::result_promise::set_from_function() - empty result_promise.";
19-
20-
inline const char* k_result_promise_get_result_error_msg = "concurrencpp::result_promise::get_result() - empty result_promise.";
21-
229
inline const char* k_result_promise_get_result_already_retrieved_error_msg =
2310
"concurrencpp::result_promise::get_result() - result was already retrieved.";
2411

2512
/*
2613
* result
2714
*/
28-
29-
inline const char* k_result_status_error_msg = "concurrencpp::result::status() - result is empty.";
30-
31-
inline const char* k_result_get_error_msg = "concurrencpp::result::get() - result is empty.";
32-
33-
inline const char* k_result_wait_error_msg = "concurrencpp::result::wait() - result is empty.";
34-
35-
inline const char* k_result_wait_for_error_msg = "concurrencpp::result::wait_for() - result is empty.";
36-
37-
inline const char* k_result_wait_until_error_msg = "concurrencpp::result::wait_until() - result is empty.";
38-
39-
inline const char* k_result_operator_co_await_error_msg = "concurrencpp::result::operator co_await() - result is empty.";
40-
41-
inline const char* k_result_resolve_error_msg = "concurrencpp::result::resolve() - result is empty.";
42-
43-
inline const char* k_executor_exception_error_msg =
44-
"concurrencpp::concurrencpp::result - an exception was thrown while trying to enqueue result continuation.";
45-
15+
4616
inline const char* k_broken_task_exception_error_msg = "concurrencpp::result - associated task was interrupted abnormally";
4717

4818
/*
4919
* when_xxx
5020
*/
5121

52-
inline const char* k_make_exceptional_result_exception_null_error_msg =
53-
"concurrencpp::make_exceptional_result() - given exception_ptr is null.";
54-
55-
inline const char* k_make_exceptional_lazy_result_exception_null_error_msg =
56-
"concurrencpp::make_exceptional_lazy_result() - given exception_ptr is null.";
57-
58-
inline const char* k_when_all_empty_result_error_msg = "concurrencpp::when_all() - one of the result objects is empty.";
59-
60-
inline const char* k_when_all_null_resume_executor_error_msg = "concurrencpp::when_all() - given resume_executor is null.";
61-
62-
inline const char* k_when_any_empty_result_error_msg = "concurrencpp::when_any() - one of the result objects is empty.";
63-
6422
inline const char* k_when_any_empty_range_error_msg = "concurrencpp::when_any() - given range contains no elements.";
6523

66-
inline const char* k_when_any_null_resume_executor_error_msg = "concurrencpp::when_any() - given resume_executor is null.";
67-
68-
/*
69-
* shared_result
70-
*/
71-
72-
inline const char* k_shared_result_status_error_msg = "concurrencpp::shared_result::status() - result is empty.";
73-
74-
inline const char* k_shared_result_get_error_msg = "concurrencpp::shared_result::get() - result is empty.";
75-
76-
inline const char* k_shared_result_wait_error_msg = "concurrencpp::shared_result::wait() - result is empty.";
77-
78-
inline const char* k_shared_result_wait_for_error_msg = "concurrencpp::shared_result::wait_for() - result is empty.";
79-
80-
inline const char* k_shared_result_wait_until_error_msg = "concurrencpp::shared_result::wait_until() - result is empty.";
81-
82-
inline const char* k_shared_result_operator_co_await_error_msg =
83-
"concurrencpp::shared_result::operator co_await() - result is empty.";
84-
85-
inline const char* k_shared_result_resolve_error_msg = "concurrencpp::shared_result::resolve() - result is empty.";
86-
87-
/*
88-
* lazy_result
89-
*/
90-
91-
inline const char* k_empty_lazy_result_status_err_msg = "concurrencpp::lazy_result::status - result is empty.";
92-
93-
inline const char* k_empty_lazy_result_operator_co_await_err_msg =
94-
"concurrencpp::lazy_result::operator co_await - result is empty.";
95-
96-
inline const char* k_empty_lazy_result_resolve_err_msg = "concurrencpp::lazy_result::resolve - result is empty.";
97-
98-
inline const char* k_empty_lazy_result_run_err_msg = "concurrencpp::lazy_result::run - result is empty.";
99-
100-
/*
101-
* resume_on
102-
*/
103-
104-
inline const char* k_resume_on_null_exception_err_msg = "concurrencpp::resume_on - given executor is null.";
105-
106-
/*
107-
* generator
108-
*/
109-
inline const char* k_empty_generator_begin_err_msg = "concurrencpp::generator::begin - generator is empty.";
110-
111-
/*
112-
* parallel-coroutine
113-
*/
114-
inline const char* k_parallel_coroutine_null_exception_err_msg = "concurrencpp::parallel-coroutine - given executor is null.";
115-
11624
} // namespace concurrencpp::details::consts
11725

11826
#endif

0 commit comments

Comments
 (0)