Skip to content
This repository was archived by the owner on Mar 22, 2023. It is now read-only.

Commit 1185a85

Browse files
Merge pull request #1189 from igchor/exceptions_generic2
Make exception_with_errormsg take arbitrary num of params
2 parents 88467f7 + f102f3c commit 1185a85

File tree

7 files changed

+80
-82
lines changed

7 files changed

+80
-82
lines changed

include/libpmemobj++/condition_variable.hpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,9 @@ class condition_variable {
7373
{
7474
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
7575
if (int ret = pmemobj_cond_signal(pop, &this->pcond))
76-
throw pmem::lock_error(
76+
throw detail::exception_with_errormsg<lock_error>(
7777
ret, std::system_category(),
78-
"Error notifying one on a condition variable.")
79-
.with_pmemobj_errormsg();
78+
"Error notifying one on a condition variable.");
8079
}
8180

8281
/**
@@ -89,10 +88,9 @@ class condition_variable {
8988
{
9089
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
9190
if (int ret = pmemobj_cond_broadcast(pop, &this->pcond))
92-
throw pmem::lock_error(
91+
throw detail::exception_with_errormsg<lock_error>(
9392
ret, std::system_category(),
94-
"Error notifying all on a condition variable.")
95-
.with_pmemobj_errormsg();
93+
"Error notifying all on a condition variable.");
9694
}
9795

9896
/**
@@ -479,10 +477,9 @@ class condition_variable {
479477
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
480478
if (int ret = pmemobj_cond_wait(pop, &this->pcond,
481479
lock.native_handle()))
482-
throw pmem::lock_error(
480+
throw detail::exception_with_errormsg<lock_error>(
483481
ret, std::system_category(),
484-
"Error waiting on a condition variable.")
485-
.with_pmemobj_errormsg();
482+
"Error waiting on a condition variable.");
486483
}
487484

488485
/**
@@ -523,10 +520,9 @@ class condition_variable {
523520
else if (ret == ETIMEDOUT)
524521
return std::cv_status::timeout;
525522
else
526-
throw pmem::lock_error(
523+
throw detail::exception_with_errormsg<lock_error>(
527524
ret, std::system_category(),
528-
"Error waiting on a condition variable.")
529-
.with_pmemobj_errormsg();
525+
"Error waiting on a condition variable.");
530526
}
531527

532528
/**

include/libpmemobj++/detail/common.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,6 @@ static constexpr size_t CACHELINE_SIZE = 128ULL;
159159
#error unable to recognize architecture at compile time
160160
#endif
161161

162-
/**
163-
* Generic error message decorator for pmemobj-based exceptions.
164-
*/
165-
template <class ExcT, typename MsgT>
166-
ExcT
167-
exception_with_errormsg(const MsgT &msg)
168-
{
169-
return ExcT(msg + std::string(": ") + detail::errormsg());
170-
}
171-
172162
/**
173163
* Conditionally add 'count' objects to a transaction.
174164
*

include/libpmemobj++/mutex.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ class mutex {
7171
{
7272
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
7373
if (int ret = pmemobj_mutex_lock(pop, &this->plock))
74-
throw pmem::lock_error(ret, std::system_category(),
75-
"Failed to lock a mutex.")
76-
.with_pmemobj_errormsg();
74+
throw detail::exception_with_errormsg<lock_error>(
75+
ret, std::system_category(),
76+
"Failed to lock a mutex.");
7777
}
7878

7979
/**
@@ -101,9 +101,9 @@ class mutex {
101101
else if (ret == EBUSY)
102102
return false;
103103
else
104-
throw pmem::lock_error(ret, std::system_category(),
105-
"Failed to lock a mutex.")
106-
.with_pmemobj_errormsg();
104+
throw detail::exception_with_errormsg<lock_error>(
105+
ret, std::system_category(),
106+
"Failed to lock a mutex.");
107107
}
108108

109109
/**
@@ -119,9 +119,9 @@ class mutex {
119119
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
120120
int ret = pmemobj_mutex_unlock(pop, &this->plock);
121121
if (ret)
122-
throw pmem::lock_error(ret, std::system_category(),
123-
"Failed to unlock a mutex.")
124-
.with_pmemobj_errormsg();
122+
throw detail::exception_with_errormsg<lock_error>(
123+
ret, std::system_category(),
124+
"Failed to unlock a mutex.");
125125
}
126126

127127
/**

include/libpmemobj++/pexceptions.hpp

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
#include <stdexcept>
1313
#include <string>
1414
#include <system_error>
15+
#include <tuple>
1516

1617
#include <libpmemobj/atomic_base.h>
1718
#include <libpmemobj/base.h>
1819

20+
#include <libpmemobj++/detail/integer_sequence.hpp>
21+
1922
namespace pmem
2023
{
2124

@@ -34,6 +37,41 @@ errormsg(void)
3437
return std::string(pmemobj_errormsg());
3538
#endif
3639
}
40+
41+
/**
42+
* Helper for exception_with_errormsg.
43+
*
44+
* Accepts tuple with arguments and index_sequence which correspond
45+
* to all but last argument. The last element in tuple is assumed to
46+
* be an error message. Before passing it to ExcT constructor it is merged
47+
* with detail::errormsg()
48+
*/
49+
template <typename ExcT, size_t... I, typename Tuple>
50+
ExcT
51+
exception_with_errormsg_helper(index_sequence<I...>, Tuple &&args)
52+
{
53+
static_assert(std::is_rvalue_reference<decltype(args)>::value,
54+
"args should be rvalue reference!");
55+
56+
auto msg = std::get<sizeof...(I)>(std::move(args)) + std::string(": ") +
57+
detail::errormsg();
58+
return ExcT(std::get<I>(std::move(args))..., std::move(msg));
59+
}
60+
61+
/**
62+
* Generic error message decorator for pmemobj-based exceptions.
63+
*
64+
* It accepts arbitrary number of parameters. The last parameter must be an
65+
* error message.
66+
*/
67+
template <class ExcT, typename... Args>
68+
ExcT
69+
exception_with_errormsg(Args &&... args)
70+
{
71+
return exception_with_errormsg_helper<ExcT>(
72+
make_index_sequence<sizeof...(Args) - 1>{},
73+
std::forward_as_tuple(std::forward<Args>(args)...));
74+
}
3775
} /* namespace detail */
3876

3977
/**
@@ -80,19 +118,6 @@ class transaction_error : public std::runtime_error {
80118
class lock_error : public std::system_error {
81119
public:
82120
using std::system_error::system_error;
83-
84-
/**
85-
* Retrieves last error message from libpmemobj
86-
* and adds it to the current error.
87-
*/
88-
lock_error &
89-
with_pmemobj_errormsg()
90-
{
91-
(*this) = lock_error(code(),
92-
what() + std::string(": ") +
93-
detail::errormsg());
94-
return *this;
95-
}
96121
};
97122

98123
/**
@@ -196,18 +221,6 @@ class defrag_error : public std::runtime_error {
196221
{
197222
}
198223

199-
/**
200-
* Append partial results.
201-
*
202-
* @param result potential partial results of the defragmentation
203-
*/
204-
defrag_error &
205-
append_result(pobj_defrag_result result)
206-
{
207-
this->result = result;
208-
return *this;
209-
}
210-
211224
/**
212225
* Results of the defragmentation run.
213226
*

include/libpmemobj++/pool.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,7 @@ class pool_base {
425425

426426
if (ret != 0)
427427
throw detail::exception_with_errormsg<defrag_error>(
428-
"Defragmentation failed")
429-
.append_result(result);
428+
result, "Defragmentation failed");
430429
return result;
431430
}
432431

include/libpmemobj++/shared_mutex.hpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ class shared_mutex {
7272
{
7373
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
7474
if (int ret = pmemobj_rwlock_wrlock(pop, &this->plock))
75-
throw pmem::lock_error(ret, std::system_category(),
76-
"Failed to lock a shared mutex.")
77-
.with_pmemobj_errormsg();
75+
throw detail::exception_with_errormsg<lock_error>(
76+
ret, std::system_category(),
77+
"Failed to lock a shared mutex.");
7878
}
7979

8080
/**
@@ -97,7 +97,7 @@ class shared_mutex {
9797
{
9898
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
9999
if (int ret = pmemobj_rwlock_rdlock(pop, &this->plock))
100-
throw pmem::lock_error(
100+
throw detail::exception_with_errormsg<lock_error>(
101101
ret, std::system_category(),
102102
"Failed to shared lock a shared mutex.");
103103
}
@@ -127,9 +127,9 @@ class shared_mutex {
127127
else if (ret == EBUSY)
128128
return false;
129129
else
130-
throw pmem::lock_error(ret, std::system_category(),
131-
"Failed to lock a shared mutex.")
132-
.with_pmemobj_errormsg();
130+
throw detail::exception_with_errormsg<lock_error>(
131+
ret, std::system_category(),
132+
"Failed to lock a shared mutex.");
133133
}
134134

135135
/**
@@ -159,9 +159,9 @@ class shared_mutex {
159159
else if (ret == EBUSY)
160160
return false;
161161
else
162-
throw pmem::lock_error(ret, std::system_category(),
163-
"Failed to lock a shared mutex.")
164-
.with_pmemobj_errormsg();
162+
throw detail::exception_with_errormsg<lock_error>(
163+
ret, std::system_category(),
164+
"Failed to lock a shared mutex.");
165165
}
166166

167167
/**
@@ -176,10 +176,9 @@ class shared_mutex {
176176
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
177177
int ret = pmemobj_rwlock_unlock(pop, &this->plock);
178178
if (ret)
179-
throw pmem::lock_error(
179+
throw detail::exception_with_errormsg<lock_error>(
180180
ret, std::system_category(),
181-
"Failed to unlock a shared mutex.")
182-
.with_pmemobj_errormsg();
181+
"Failed to unlock a shared mutex.");
183182
}
184183

185184
/**

include/libpmemobj++/timed_mutex.hpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ class timed_mutex {
7474
{
7575
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
7676
if (int ret = pmemobj_mutex_lock(pop, &this->plock))
77-
throw pmem::lock_error(ret, std::system_category(),
78-
"Failed to lock a mutex.")
79-
.with_pmemobj_errormsg();
77+
throw detail::exception_with_errormsg<lock_error>(
78+
ret, std::system_category(),
79+
"Failed to lock a mutex.");
8080
}
8181

8282
/**
@@ -104,9 +104,9 @@ class timed_mutex {
104104
else if (ret == EBUSY)
105105
return false;
106106
else
107-
throw pmem::lock_error(ret, std::system_category(),
108-
"Failed to lock a mutex.")
109-
.with_pmemobj_errormsg();
107+
throw detail::exception_with_errormsg<lock_error>(
108+
ret, std::system_category(),
109+
"Failed to lock a mutex.");
110110
}
111111

112112
/**
@@ -171,9 +171,9 @@ class timed_mutex {
171171
PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
172172
int ret = pmemobj_mutex_unlock(pop, &this->plock);
173173
if (ret)
174-
throw pmem::lock_error(ret, std::system_category(),
175-
"Failed to unlock a mutex.")
176-
.with_pmemobj_errormsg();
174+
throw detail::exception_with_errormsg<lock_error>(
175+
ret, std::system_category(),
176+
"Failed to unlock a mutex.");
177177
}
178178

179179
/**
@@ -222,8 +222,9 @@ class timed_mutex {
222222
else if (ret == ETIMEDOUT)
223223
return false;
224224
else
225-
throw pmem::lock_error(ret, std::system_category(),
226-
"Failed to lock a mutex");
225+
throw detail::exception_with_errormsg<lock_error>(
226+
ret, std::system_category(),
227+
"Failed to lock a mutex");
227228
}
228229

229230
/** A POSIX style PMEM-resident timed_mutex.*/

0 commit comments

Comments
 (0)