Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:20

0001 /* Copyright 2023 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See https://www.boost.org/libs/unordered for library home page.
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   /* not used but VS in pre-C++17 mode needs to see it for RVO */
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 } /* namespace foa */
0134 } /* namespace detail */
0135 } /* namespace unordered */
0136 } /* namespace boost */
0137 
0138 #endif