File indexing completed on 2025-01-18 09:53:20
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_UNORDERED_DETAIL_FOA_REENTRANCY_CHECK_HPP
0010 #define BOOST_UNORDERED_DETAIL_FOA_REENTRANCY_CHECK_HPP
0011
0012 #include <boost/assert.hpp>
0013 #include <utility>
0014
0015 #if !defined(BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK)&& \
0016 !defined(BOOST_ASSERT_IS_VOID)
0017 #define BOOST_UNORDERED_REENTRANCY_CHECK
0018 #endif
0019
0020 namespace boost{
0021 namespace unordered{
0022 namespace detail{
0023 namespace foa{
0024
0025 #if defined(BOOST_UNORDERED_REENTRANCY_CHECK)
0026
0027 class entry_trace
0028 {
0029 public:
0030 entry_trace(const void* px_):px{px_}
0031 {
0032 if(px){
0033 BOOST_ASSERT_MSG(!find(px),"reentrancy not allowed");
0034 header()=this;
0035 }
0036 }
0037
0038
0039 entry_trace(const entry_trace&);
0040
0041 ~entry_trace(){clear();}
0042
0043 void clear()
0044 {
0045 if(px){
0046 header()=next;
0047 px=nullptr;
0048 }
0049 }
0050
0051 private:
0052 static entry_trace*& header()
0053 {
0054 thread_local entry_trace *pe=nullptr;
0055 return pe;
0056 }
0057
0058 static bool find(const void* px)
0059 {
0060 for(auto pe=header();pe;pe=pe->next){
0061 if(pe->px==px)return true;
0062 }
0063 return false;
0064 }
0065
0066 const void *px;
0067 entry_trace *next=header();
0068 };
0069
0070 template<typename LockGuard>
0071 struct reentrancy_checked
0072 {
0073 template<typename... Args>
0074 reentrancy_checked(const void* px,Args&&... args):
0075 tr{px},lck{std::forward<Args>(args)...}{}
0076
0077 void unlock()
0078 {
0079 lck.unlock();
0080 tr.clear();
0081 }
0082
0083 entry_trace tr;
0084 LockGuard lck;
0085 };
0086
0087 template<typename LockGuard>
0088 struct reentrancy_bichecked
0089 {
0090 template<typename... Args>
0091 reentrancy_bichecked(const void* px,const void* py,Args&&... args):
0092 tr1{px},tr2{py!=px?py:nullptr},lck{std::forward<Args>(args)...}{}
0093
0094 void unlock()
0095 {
0096 lck.unlock();
0097 tr2.clear();
0098 tr1.clear();
0099 }
0100
0101 entry_trace tr1,tr2;
0102 LockGuard lck;
0103 };
0104
0105 #else
0106
0107 template<typename LockGuard>
0108 struct reentrancy_checked
0109 {
0110 template<typename... Args>
0111 reentrancy_checked(const void*,Args&&... args):
0112 lck{std::forward<Args>(args)...}{}
0113
0114 void unlock(){lck.unlock();}
0115
0116 LockGuard lck;
0117 };
0118
0119 template<typename LockGuard>
0120 struct reentrancy_bichecked
0121 {
0122 template<typename... Args>
0123 reentrancy_bichecked(const void*,const void*,Args&&... args):
0124 lck{std::forward<Args>(args)...}{}
0125
0126 void unlock(){lck.unlock();}
0127
0128 LockGuard lck;
0129 };
0130
0131 #endif
0132
0133 }
0134 }
0135 }
0136 }
0137
0138 #endif