Skip to content
Snippets Groups Projects
  • Jonathan Hanks's avatar
    66ac6b7e
    Updates to the work queues and how they are used/passed. · 66ac6b7e
    Jonathan Hanks authored
    This is to help properly track lifetimes of the work queues.
    
    Put in a wrapper around pthread_create to allow specifying an arbitrary job to run in the guise of a std::function.  This keeps the flexibility (scheduler, stack size, ...) of pthreads but gives the us the ability to call more than just a void* (*)(void*).
    
    With these changes the work queues have been moved out of object scope for both the producer and the daqd objects.  A few small static routines that were used to start worker threads in the producer/daqd are removed.
    66ac6b7e
    History
    Updates to the work queues and how they are used/passed.
    Jonathan Hanks authored
    This is to help properly track lifetimes of the work queues.
    
    Put in a wrapper around pthread_create to allow specifying an arbitrary job to run in the guise of a std::function.  This keeps the flexibility (scheduler, stack size, ...) of pthreads but gives the us the ability to call more than just a void* (*)(void*).
    
    With these changes the work queues have been moved out of object scope for both the producer and the daqd objects.  A few small static routines that were used to start worker threads in the producer/daqd are removed.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
raii.hh 3.29 KiB
#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