LCOV - code coverage report
Current view: top level - lunchbox - request.h (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 26 32 81.2 %
Date: 2014-10-01 Functions: 24 30 80.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2013-2014, Stefan.Eilemann@epfl.ch
       3             :  *
       4             :  * This library is free software; you can redistribute it and/or modify it under
       5             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       6             :  * by the Free Software Foundation.
       7             :  *
       8             :  * This library is distributed in the hope that it will be useful, but WITHOUT
       9             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      10             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      11             :  * details.
      12             :  *
      13             :  * You should have received a copy of the GNU Lesser General Public License
      14             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      15             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      16             :  */
      17             : 
      18             : #ifndef LUNCHBOX_REQUEST_H
      19             : #define LUNCHBOX_REQUEST_H
      20             : 
      21             : #include <lunchbox/future.h>
      22             : #include <boost/mpl/if.hpp>
      23             : #include <boost/type_traits/is_same.hpp>
      24             : 
      25             : namespace lunchbox
      26             : {
      27             : 
      28             : /**
      29             :  * A Future implementation for a RequestHandler request.
      30             :  * @version 1.9.1
      31             :  */
      32             : template< class T > class Request : public Future< T >
      33             : {
      34             :     class Impl;
      35             : 
      36             : public:
      37             :     /** Construct a new request. */
      38             :     Request( RequestHandler& handler, const uint32_t request );
      39             : 
      40             :     /**
      41             :      * Destruct and wait for completion of the request, unless relinquished.
      42             :      * @version 1.9.1
      43             :      */
      44             :     virtual ~Request();
      45             : 
      46             :     /** @return the identifier of the request. @version 1.9.1 */
      47             :     uint32_t getID() const;
      48             : 
      49             :     /**
      50             :      * Abandon the request.
      51             :      *
      52             :      * If called, wait will not be called at destruction and wait() will throw.
      53             :      * If the future has already been resolved this function has no effect.
      54             :      * @version 1.9.1
      55             :      */
      56             :     void relinquish();
      57             : };
      58             : 
      59             : }
      60             : 
      61             : // Implementation: Here be dragons
      62             : 
      63             : #include <lunchbox/requestHandler.h>
      64             : namespace lunchbox
      65             : {
      66             : template< class T > class Request< T >::Impl : public FutureImpl< T >
      67             : {
      68             :     typedef typename
      69             :     boost::mpl::if_< boost::is_same< T, void >, void*, T >::type value_t;
      70             : 
      71             : public:
      72           3 :     Impl( RequestHandler& handler, const uint32_t req )
      73             :         : request( req )
      74             :         , result( 0 )
      75             :         , handler_( handler )
      76             :         , done_( false )
      77           3 :         , relinquished_( false )
      78           3 :     {}
      79           6 :     virtual ~Impl() {}
      80             : 
      81             :     const uint32_t request;
      82             :     value_t result;
      83             : 
      84             :     void relinquish() { relinquished_ = true; }
      85           3 :     bool isRelinquished() const { return relinquished_; }
      86             : 
      87             : protected:
      88           5 :     T wait( const uint32_t timeout ) final
      89             :     {
      90           5 :         if( !done_ )
      91             :         {
      92           2 :             if( relinquished_ )
      93           0 :                 LBUNREACHABLE;
      94             : 
      95           2 :             if ( !handler_.waitRequest( request, result, timeout ))
      96           0 :                 throw FutureTimeout();
      97           2 :             done_ = true;
      98             :         }
      99           5 :         return result;
     100             :     }
     101             : 
     102           0 :     bool isReady() const final
     103             :     {
     104           0 :         return done_ || ( !relinquished_ && handler_.isRequestReady( request ));
     105             :     }
     106             : 
     107             : private:
     108             :     RequestHandler& handler_;
     109             :     bool done_; //!< waitRequest finished
     110             :     bool relinquished_;
     111             : };
     112             : 
     113           1 : template<> inline void Request< void >::Impl::wait( const uint32_t timeout )
     114             : {
     115           1 :     if( !done_ )
     116             :     {
     117           1 :         if( relinquished_ )
     118           0 :             LBUNREACHABLE;
     119             : 
     120           1 :         if ( !handler_.waitRequest( request, result, timeout ))
     121           0 :             throw FutureTimeout();
     122           1 :         done_ = true;
     123             :     }
     124           1 : }
     125             : 
     126             : template< class T > inline
     127           3 : Request< T >::Request( RequestHandler& handler, const uint32_t request )
     128           3 :     : Future< T >( new Impl( handler, request ))
     129           3 : {}
     130             : 
     131           3 : template< class T > inline Request< T >::~Request()
     132             : {
     133           3 :     if( !static_cast< const Impl* >( this->impl_.get( ))->isRelinquished( ))
     134           3 :         this->wait();
     135           6 : }
     136             : 
     137           4 : template< class T > inline uint32_t Request< T >::getID() const
     138             : {
     139           4 :     return static_cast< const Impl* >( this->impl_.get( ))->request;
     140             : }
     141             : 
     142             : template< class T > inline void Request< T >::relinquish()
     143             : {
     144             :     static_cast< Impl* >( this->impl_.get( ))->relinquish();
     145             : }
     146             : 
     147             : }
     148             : 
     149             : #endif //LUNCHBOX_REQUEST_H

Generated by: LCOV version 1.10