diff --git a/src/nds/mmap_ptr.hh b/src/nds/mmap_ptr.hh index e9a6555df683017ba6180f09252aa73b741acc11..e7cd807272137fb25f0fa64bc950df601fc230ae 100644 --- a/src/nds/mmap_ptr.hh +++ b/src/nds/mmap_ptr.hh @@ -42,6 +42,7 @@ #include "mmap.hh" #include <memory> +#include "raii.hh" namespace gdsbase { @@ -71,12 +72,15 @@ namespace gdsbase /// Size type typedef mmap::size_type size_type; - typedef std::shared_ptr<mmap> ref_pointer; + typedef std::unique_ptr<mmap> ref_pointer; + + mmap_ptr(const mmap_ptr&) = delete; + mmap_ptr& operator=(const mmap_ptr&) = delete; /** Creates a NULL pointer. @memo Default constructor ******************************************************************/ - mmap_ptr( ) : fMmap( 0 ) + mmap_ptr( ) : fMmap( nullptr ) { } /** Creates an pointer and mappes it to a file. @@ -85,7 +89,7 @@ namespace gdsbase mmap_ptr( const char* filename, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) - : fMmap( 0 ) + : fMmap( nullptr ) { set( filename, which ); } @@ -93,7 +97,7 @@ namespace gdsbase Does not own the data! @memo Constructor ******************************************************************/ - mmap_ptr( pointer_type p, size_type len ) : fMmap( 0 ) + mmap_ptr( pointer_type p, size_type len ) : fMmap( nullptr ) { set( p, len ); } @@ -183,7 +187,7 @@ namespace gdsbase inline bool mmap_ptr< T >::set( const char* filename, std::ios_base::openmode which ) { - fMmap = std::make_shared<mmap>(filename, which); + fMmap = raii::make_unique_ptr<mmap>(filename, which); return true; } @@ -192,7 +196,7 @@ namespace gdsbase inline bool mmap_ptr< T >::set( pointer_type p, size_type len ) { - fMmap = std::make_shared<mmap>((gdsbase::mmap::pointer_type)p, len * element_size( )); + fMmap = raii::make_unique_ptr<mmap>((gdsbase::mmap::pointer_type)p, len * element_size( )); return true; } diff --git a/src/nds/raii.hh b/src/nds/raii.hh new file mode 100644 index 0000000000000000000000000000000000000000..edabebe952cf6ac461776bc6031798035b191ec7 --- /dev/null +++ b/src/nds/raii.hh @@ -0,0 +1,160 @@ +#ifndef RAII_HH +#define RAII_HH + +#include <unistd.h> +#include <memory> + +/** + * Some 'smart' resource wrappers using the raii technique. + * This should be cleaned up and foled into C++11 code as + * it becomes feasible. + */ + +namespace raii +{ + + template < typename T > + class array_ptr + { + T* _p; + + array_ptr( array_ptr< T >& other ); + array_ptr< T > operator=( const array_ptr< T >& other ); + + void + clean_up( ) + { + if ( _p ) + delete[] _p; + _p = 0; + } + + public: + array_ptr( T* p = 0 ) : _p( p ) + { + } + ~array_ptr( ) + { + clean_up( ); + } + T* + get( ) const + { + return _p; + } + void + reset( T* p ) + { + if ( p != _p ) + { + clean_up( ); + _p == p; + } + } + T* + release( ) + { + T* tmp( _p ); + _p = 0; + return tmp; + } + }; + + template < typename T > + class lock_guard + { + lock_guard( lock_guard< T >& other ); + lock_guard operator=( lock_guard< T >& other ); + T& _m; + + public: + lock_guard( T& m ) : _m( m ) + { + _m.lock( ); + } + ~lock_guard( ) + { + _m.unlock( ); + } + }; + + template <> + class lock_guard< pthread_mutex_t > + { + lock_guard( lock_guard< pthread_mutex_t >& other ); + lock_guard operator=( lock_guard< pthread_mutex_t > ); + pthread_mutex_t& _m; + + public: + lock_guard( pthread_mutex_t& m ) : _m( m ) + { + pthread_mutex_lock( &_m ); + } + ~lock_guard( ) + { + pthread_mutex_unlock( &_m ); + } + }; + + class file_handle + { + int _fd; + file_handle( const file_handle& other ); + file_handle operator=( const file_handle& other ); + + public: + file_handle( int fd ) : _fd( fd ) + { + } + ~file_handle( ) + { + reset( ); + } + + int + get( ) const + { + return _fd; + } + int + release( ) + { + int tmp = _fd; + _fd = -1; + return tmp; + } + void + reset( ) + { + if ( _fd >= 0 ) + { + ::close( _fd ); + _fd = -1; + } + } + }; + + // std::make_unique didn't make it into C++11, so + // to allow this to work in a pre C++14 world, we + // provide a simple replacement. + // + // A make_unique<> for C++11. Taken from + // "Effective Modern C++ by Scott Meyers (O'Reilly). + // Copyright 2015 Scott Meyers, 978-1-491-90399-5" + // + // Permission given in the book to reuse code segments. + // + // @tparam T The type of the object to be managed by the unique_ptr + // @tparam Ts The type of the arguments to T's constructor + // @param params The arguments to forward to the constructor + // @return a std::unique_ptr<T> + template < typename T, typename... Ts > + std::unique_ptr< T > + make_unique_ptr( Ts&&... params ) + { + return std::unique_ptr< T >( new T( std::forward< Ts >( params )... ) ); + } + +} // namespace raii + +#endif // RAII_HH