Skip to content

Commit c3be807

Browse files
committed
Use boost::compressed_pair for EBO in rcu_obj_base
This fixes a discrepancy between nonempty deleters, which will get constructed when the rcu_obj_base is constructed, and empty deleters, which were only getting constructed when retire() is run. Signed-off-by: Lance Roy <[email protected]>
1 parent 5a8e75d commit c3be807

File tree

1 file changed

+12
-23
lines changed

1 file changed

+12
-23
lines changed

Test/paulmck/rcu.hpp

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,34 @@
33
#include <cstddef>
44
#include <memory>
55
#include <mutex>
6+
#include <tuple>
67
#include <utility>
8+
#include <boost/compressed_pair.hpp>
79

810
// Derived-type approach. All RCU-protected data structures using this
911
// approach must derive from std::rcu_obj_base, which in turn derives
1012
// from std::rcu_head. No idea what happens in case of multiple inheritance.
1113

1214
namespace std {
13-
template<typename T, typename D = default_delete<T>, bool E = is_empty<D>::value>
14-
class rcu_obj_base: private rcu_head {
15-
D deleter;
16-
public:
17-
void retire(D d = {})
18-
{
19-
deleter = std::move(d);
20-
::call_rcu(
21-
static_cast<rcu_head *>(this),
22-
[](rcu_head *rhp) {
23-
auto rhdp = static_cast<rcu_obj_base *>(rhp);
24-
auto obj = static_cast<T *>(rhdp);
25-
rhdp->deleter(obj);
26-
}
27-
);
28-
}
29-
};
3015

16+
namespace detail {
17+
struct rcu_obj_base_empty_type {};
18+
}
3119

32-
// Specialization for when D is an empty type.
33-
34-
template<typename T, typename D>
35-
class rcu_obj_base<T,D,true>: private rcu_head {
20+
template<typename T, typename D = default_delete<T>>
21+
class rcu_obj_base:
22+
private rcu_head,
23+
private boost::compressed_pair<D, detail::rcu_obj_base_empty_type> {
3624
public:
37-
void retire(D = {})
25+
void retire(D d = {})
3826
{
27+
this->first() = std::move(d);
3928
::call_rcu(
4029
static_cast<rcu_head *>(this),
4130
[](rcu_head *rhp) {
4231
auto rhdp = static_cast<rcu_obj_base *>(rhp);
4332
auto obj = static_cast<T *>(rhdp);
44-
D()(obj);
33+
rhdp->first()(obj);
4534
}
4635
);
4736
}

0 commit comments

Comments
 (0)