[saferecl.rcu.base] # 32 Concurrency support library [[thread]](./#thread) ## 32.11 Safe reclamation [[saferecl]](saferecl#rcu.base) ### 32.11.2 Read-copy update (RCU) [[saferecl.rcu]](saferecl.rcu#base) #### 32.11.2.3 Class template rcu_obj_base [saferecl.rcu.base] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12992) Objects of type T to be protected by RCU inherit from a specialization rcu_obj_base for some D[.](#1.sentence-1) namespace std {template>class rcu_obj_base {public:void retire(D d = D(), rcu_domain& dom = rcu_default_domain()) noexcept; protected: rcu_obj_base() = default; rcu_obj_base(const rcu_obj_base&) = default; rcu_obj_base(rcu_obj_base&&) = default; rcu_obj_base& operator=(const rcu_obj_base&) = default; rcu_obj_base& operator=(rcu_obj_base&&) = default; ~rcu_obj_base() = default; private: D *deleter*; // *exposition only*};} [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13015) The behavior of a program that adds specializations for rcu_obj_base is undefined[.](#2.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13019) T may be an incomplete type[.](#3.sentence-1) It shall be complete before any member of the resulting specialization ofrcu_obj_base is referenced[.](#3.sentence-2) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13024) D shall be a function object type ([[function.objects]](function.objects "22.10 Function objects")) for which, given a value d of type D and a value ptr of type T*, the expression d(ptr) is valid[.](#4.sentence-1) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13031) D shall meet the requirements for[*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17MoveAssignable*](utility.arg.requirements#:Cpp17MoveAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#5.sentence-1) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13035) If D is trivially copyable, all specializations of rcu_obj_base are trivially copyable[.](#6.sentence-1) [🔗](#itemdecl:1) `void retire(D d = D(), rcu_domain& dom = rcu_default_domain()) noexcept; ` [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13044) *Mandates*: T is an rcu-protectable type[.](#7.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13048) *Preconditions*: *this is a base class subobject of an object x of type T[.](#8.sentence-1) The member function rcu_obj_base​::​retire was not invoked on x before[.](#8.sentence-2) The assignment to *deleter* does not exit via an exception[.](#8.sentence-3) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13056) *Effects*: Evaluates *deleter* = std​::​move(d) and schedules the evaluation of the expression *deleter*( addressof(x)) in the domain dom; the behavior is undefined if that evaluation exits via an exception[.](#9.sentence-1) May invoke scheduled evaluations in dom[.](#9.sentence-2) [*Note [1](#note-1)*: If such evaluations acquire resources held across any invocation ofretire on dom, deadlock can occur[.](#9.sentence-3) — *end note*]