diff --git a/include/chainbase/chainbase.hpp b/include/chainbase/chainbase.hpp index 70bdd922d0b..0693420aeaa 100644 --- a/include/chainbase/chainbase.hpp +++ b/include/chainbase/chainbase.hpp @@ -31,6 +31,14 @@ #define CHAINBASE_NUM_RW_LOCKS 10 #endif +#ifdef CHAINBASE_CHECK_LOCKING + #define CHAINBASE_REQUIRE_READ_LOCK() require_read_lock() + #define CHAINBASE_REQUIRE_WRITE_LOCK() require_write_lock() +#else + #define CHAINBASE_REQUIRE_READ_LOCK() + #define CHAINBASE_REQUIRE_WRITE_LOCK() +#endif + namespace chainbase { namespace bip = boost::interprocess; @@ -645,9 +653,9 @@ namespace chainbase { void close(); void flush(); void wipe( const bfs::path& dir ); -#ifdef CHAINBASE_CHECK_LOCKING void set_require_locking( bool enable_require_locking ); +#ifdef CHAINBASE_CHECK_LOCKING void require_lock_fail( const char* lock_type )const; void require_read_lock()const @@ -719,7 +727,7 @@ namespace chainbase { void set_revision( uint64_t revision ) { - require_write_lock(); + CHAINBASE_REQUIRE_WRITE_LOCK(); for( auto i : _index_list ) i->set_revision( revision ); } @@ -766,7 +774,7 @@ namespace chainbase { template const generic_index& get_index()const { - require_read_lock(); + CHAINBASE_REQUIRE_READ_LOCK(); typedef generic_index index_type; typedef index_type* index_type_ptr; assert( _index_map.size() > index_type::value_type::type_id ); @@ -777,7 +785,7 @@ namespace chainbase { template auto get_index()const -> decltype( ((generic_index*)( nullptr ))->indicies().template get() ) { - require_read_lock(); + CHAINBASE_REQUIRE_READ_LOCK(); typedef generic_index index_type; typedef index_type* index_type_ptr; assert( _index_map.size() > index_type::value_type::type_id ); @@ -788,7 +796,7 @@ namespace chainbase { template generic_index& get_mutable_index() { - require_write_lock(); + CHAINBASE_REQUIRE_WRITE_LOCK(); typedef generic_index index_type; typedef index_type* index_type_ptr; assert( _index_map.size() > index_type::value_type::type_id ); @@ -799,7 +807,7 @@ namespace chainbase { template< typename ObjectType, typename IndexedByType, typename CompatibleKey > const ObjectType* find( CompatibleKey&& key )const { - require_read_lock(); + CHAINBASE_REQUIRE_READ_LOCK(); typedef typename get_index_type< ObjectType >::type index_type; const auto& idx = get_index< index_type >().indicies().template get< IndexedByType >(); auto itr = idx.find( std::forward< CompatibleKey >( key ) ); @@ -810,7 +818,7 @@ namespace chainbase { template< typename ObjectType > const ObjectType* find( oid< ObjectType > key = oid< ObjectType >() ) const { - require_read_lock(); + CHAINBASE_REQUIRE_READ_LOCK(); typedef typename get_index_type< ObjectType >::type index_type; const auto& idx = get_index< index_type >().indices(); auto itr = idx.find( key ); @@ -821,7 +829,7 @@ namespace chainbase { template< typename ObjectType, typename IndexedByType, typename CompatibleKey > const ObjectType& get( CompatibleKey&& key )const { - require_read_lock(); + CHAINBASE_REQUIRE_READ_LOCK(); auto obj = find< ObjectType, IndexedByType >( std::forward< CompatibleKey >( key ) ); if( !obj ) BOOST_THROW_EXCEPTION( std::out_of_range( "unknown key" ) ); return *obj; @@ -830,7 +838,7 @@ namespace chainbase { template< typename ObjectType > const ObjectType& get( const oid< ObjectType >& key = oid< ObjectType >() )const { - require_read_lock(); + CHAINBASE_REQUIRE_READ_LOCK(); auto obj = find< ObjectType >( key ); if( !obj ) BOOST_THROW_EXCEPTION( std::out_of_range( "unknown key") ); return *obj; @@ -839,7 +847,7 @@ namespace chainbase { template void modify( const ObjectType& obj, Modifier&& m ) { - require_write_lock(); + CHAINBASE_REQUIRE_WRITE_LOCK(); typedef typename get_index_type::type index_type; get_mutable_index().modify( obj, m ); } @@ -847,7 +855,7 @@ namespace chainbase { template void remove( const ObjectType& obj ) { - require_write_lock(); + CHAINBASE_REQUIRE_WRITE_LOCK(); typedef typename get_index_type::type index_type; return get_mutable_index().remove( obj ); } @@ -855,7 +863,7 @@ namespace chainbase { template const ObjectType& create( Constructor&& con ) { - require_write_lock(); + CHAINBASE_REQUIRE_WRITE_LOCK(); typedef typename get_index_type::type index_type; return get_mutable_index().emplace( std::forward(con) ); } @@ -863,8 +871,8 @@ namespace chainbase { template< typename Lambda > auto with_read_lock( Lambda&& callback, uint64_t wait_micro = 1000000 ) -> decltype( (*(Lambda*)nullptr)() ) { -#ifdef CHAINBASE_CHECK_LOCKING read_lock lock( _rw_manager->current_lock(), bip::defer_lock_type() ); +#ifdef CHAINBASE_CHECK_LOCKING BOOST_ATTRIBUTE_UNUSED int_incrementer ii( _read_lock_count ); #endif @@ -889,8 +897,8 @@ namespace chainbase { if( _read_only ) BOOST_THROW_EXCEPTION( std::logic_error( "cannot acquire write lock on read-only process" ) ); -#ifdef CHAINBASE_CHECK_LOCKING write_lock lock( _rw_manager->current_lock(), boost::defer_lock_t() ); +#ifdef CHAINBASE_CHECK_LOCKING BOOST_ATTRIBUTE_UNUSED int_incrementer ii( _write_lock_count ); #endif diff --git a/src/chainbase.cpp b/src/chainbase.cpp index a7c9f01a1c8..49b72bb0323 100644 --- a/src/chainbase.cpp +++ b/src/chainbase.cpp @@ -130,12 +130,14 @@ namespace chainbase { _index_map.clear(); } -#ifdef CHAINBASE_CHECK_LOCKING void database::set_require_locking( bool enable_require_locking ) { +#ifdef CHAINBASE_CHECK_LOCKING _enable_require_locking = enable_require_locking; +#endif } +#ifdef CHAINBASE_CHECK_LOCKING void database::require_lock_fail( const char* lock_type )const { std::string err_msg = "require_" + std::string( lock_type ) + "_lock() failed";