LCOV - code coverage report
Current view: top level - eq/fabric - object.h (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 36 52 69.2 %
Date: 2014-06-18 Functions: 49 68 72.1 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2009-2014, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                    2012, Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #ifndef EQFABRIC_OBJECT_H
      20             : #define EQFABRIC_OBJECT_H
      21             : 
      22             : #include <eq/fabric/api.h>
      23             : #include <eq/fabric/error.h>        // enum
      24             : #include <eq/fabric/types.h>
      25             : #include <co/objectOCommand.h>      // used inline send()
      26             : #include <co/objectVersion.h>       // member
      27             : #include <co/serializable.h>        // base class
      28             : 
      29             : namespace eq
      30             : {
      31             : namespace fabric
      32             : {
      33             : namespace detail { class Object; }
      34             : 
      35             : /**
      36             :  * Internal base class for all distributed, inheritable Equalizer objects.
      37             :  *
      38             :  * This class provides common data storage used by all Equalizer resource
      39             :  * entities. Do not subclass directly.
      40             :  */
      41             : class Object : public co::Serializable
      42             : {
      43             : public:
      44             :     /** @name Data Access. */
      45             :     //@{
      46             :     /** Set the name of the object. @version 1.0 */
      47             :     EQFABRIC_API virtual void setName( const std::string& name );
      48             : 
      49             :     /** @return the name of the object. @version 1.0 */
      50             :     EQFABRIC_API const std::string& getName() const;
      51             : 
      52             :     /**
      53             :      * Set user-specific data.
      54             :      *
      55             :      * Registration, mapping, commit and sync of the user data object are
      56             :      * automatically executed when committing and syncing this object. Not all
      57             :      * instances of the object have to set a user data object. All instances
      58             :      * have to set the same type of object.
      59             :      * @version 1.0
      60             :      */
      61             :     EQFABRIC_API void setUserData( co::Object* userData );
      62             : 
      63             :     /** @return the user-specific data. @version 1.0 */
      64             :     EQFABRIC_API co::Object* getUserData();
      65             : 
      66             :     /** @return the user-specific data. @version 1.0 */
      67             :     EQFABRIC_API const co::Object* getUserData() const;
      68             :     //@}
      69             : 
      70             :     /** @name Data Access */
      71             :     //@{
      72             :     /**
      73             :      * Return the set of tasks this channel might execute in the worst case.
      74             :      *
      75             :      * It is not guaranteed that all the tasks will be actually executed during
      76             :      * rendering.
      77             :      *
      78             :      * @return the tasks.
      79             :      * @warning Experimental - may not be supported in the future
      80             :      */
      81             :     EQFABRIC_API uint32_t getTasks() const;
      82             : 
      83             :     EQFABRIC_API uint32_t getSerial() const;
      84             :     //@}
      85             : 
      86             :     /** @return true if the object has data to commit. @version 1.0 */
      87             :     EQFABRIC_API virtual bool isDirty() const;
      88             : 
      89             :     /** @internal */
      90             :     EQFABRIC_API virtual uint128_t commit( const uint32_t incarnation =
      91             :                                            CO_COMMIT_NEXT );
      92             : 
      93             :     /** @internal Back up app-specific data, excluding child data. */
      94             :     EQFABRIC_API virtual void backup();
      95             : 
      96             :     /** @internal Restore the last backup. */
      97             :     EQFABRIC_API virtual void restore();
      98             : 
      99             :     /**
     100             :      * The changed parts of the object since the last pack().
     101             :      *
     102             :      * Subclasses should define their own bits, starting at DIRTY_CUSTOM.
     103             :      */
     104             :     enum DirtyBits
     105             :     {
     106             :         DIRTY_NAME       = Serializable::DIRTY_CUSTOM << 0, // 1
     107             :         DIRTY_USERDATA   = Serializable::DIRTY_CUSTOM << 1, // 2
     108             :         DIRTY_TASKS      = Serializable::DIRTY_CUSTOM << 2, // 4
     109             :         DIRTY_REMOVED    = Serializable::DIRTY_CUSTOM << 3, // 8
     110             :         DIRTY_SERIAL     = Serializable::DIRTY_CUSTOM << 4, // 16
     111             :         // Leave room for binary-compatible patches
     112             :         DIRTY_CUSTOM     = Serializable::DIRTY_CUSTOM << 6, // 64
     113             :         DIRTY_OBJECT_BITS = DIRTY_NAME | DIRTY_USERDATA
     114             :     };
     115             : 
     116             : protected:
     117             :     /** Construct a new Object. */
     118             :     EQFABRIC_API Object();
     119             : 
     120             :     /** Construct an unmapped, unregistered copy of an object. */
     121             :     EQFABRIC_API Object( const Object& );
     122             : 
     123             :     /** Destruct the object. */
     124             :     EQFABRIC_API virtual ~Object();
     125             : 
     126             :     /** NOP assignment operator. @version 1.1.1 */
     127             :     EQFABRIC_API Object& operator = ( const Object& from );
     128             : 
     129             :     /**
     130             :      * @return true if this instance shall hold the master instance of the
     131             :      *         user data object, false otherwise.
     132             :      */
     133           0 :     virtual bool hasMasterUserData() { return false; }
     134             : 
     135             :     /** @return the latency to be used for keeping user data versions. */
     136           0 :     virtual uint32_t getUserDataLatency() const { return 0; }
     137             : 
     138             :     /** @internal Set the tasks this entity might potentially execute. */
     139             :     EQFABRIC_API void setTasks( const uint32_t tasks );
     140             : 
     141             :     EQFABRIC_API virtual void notifyDetach();
     142             : 
     143             :     EQFABRIC_API virtual void serialize( co::DataOStream& os,
     144             :                                          const uint64_t dirtyBits );
     145             :     EQFABRIC_API virtual void deserialize( co::DataIStream& is,
     146             :                                            const uint64_t dirtyBits );
     147             : 
     148             :     /** @internal @return the bits to be re-committed by the master. */
     149           0 :     virtual uint64_t getRedistributableBits() const
     150           0 :         { return DIRTY_OBJECT_BITS; }
     151             : 
     152             :     /**
     153             :      * @internal
     154             :      * Remove the given child on the master during the next commit.
     155             :      * @sa removeChild
     156             :      */
     157             :     EQFABRIC_API void postRemove( Object* child );
     158             : 
     159             :     /** @internal Execute the slave remove request. @sa postRemove */
     160           0 :     virtual void removeChild( const uint128_t& ) { LBUNIMPLEMENTED; }
     161             : 
     162             :     /** @internal commit, register child slave instance with the server. */
     163             :     template< class C, class S >
     164             :     void commitChild( C* child, S* sender, uint32_t cmd,
     165             :                       const uint32_t incarnation );
     166             : 
     167             :     /** @internal commit slave instance to the server. */
     168             :     template< class C > inline
     169           0 :     void commitChild( C* child, const uint32_t incarnation )
     170             :         {
     171           0 :             LBASSERT( child->isAttached( ));
     172           0 :             child->commit( incarnation );
     173           0 :         }
     174             : 
     175             :     /** @internal commit, register child slave instances with the server. */
     176             :     template< class C, class S >
     177             :     void commitChildren( const std::vector< C* >& children, S* sender,
     178             :                          uint32_t cmd, const uint32_t incarnation );
     179             : 
     180             :     /** @internal commit, register child slave instances with the server. */
     181             :     template< class C >
     182       73586 :     void commitChildren( const std::vector< C* >& children, uint32_t cmd,
     183             :                          const uint32_t incarnation )
     184       73586 :         { commitChildren< C, Object >( children, this, cmd, incarnation ); }
     185             : 
     186             :     /** @internal commit all children. */
     187             :     template< class C >
     188             :     void commitChildren( const std::vector< C* >& children,
     189             :                          const uint32_t incarnation );
     190             : 
     191             :     /** @internal sync all children to head version. */
     192             :     template< class C >
     193             :     void syncChildren( const std::vector< C* >& children );
     194             : 
     195             :     /** @internal unmap/deregister all children. */
     196             :     template< class P, class C >
     197             :     inline void releaseChildren( const std::vector< C* >& children );
     198             : 
     199             :     /** @internal sync master object to the given slave commit. */
     200             :     EQFABRIC_API bool _cmdSync( co::ICommand& command );
     201             : 
     202             : private:
     203             :     detail::Object* const _impl;
     204             : };
     205             : 
     206             : // Template Implementation
     207             : template< class C, class S > inline void
     208      156437 : Object::commitChild( C* child, S* sender, uint32_t cmd,
     209             :                      const uint32_t incarnation )
     210             : {
     211      156437 :     if( !child->isAttached( ))
     212             :     {
     213           0 :         LBASSERT( !isMaster( ));
     214           0 :         co::LocalNodePtr localNode = child->getConfig()->getLocalNode();
     215             :         lunchbox::Request< uint128_t > request =
     216           0 :             localNode->registerRequest< uint128_t >();
     217           0 :         co::NodePtr node = child->getServer().get();
     218           0 :         sender->send( node, cmd ) << request;
     219             : 
     220           0 :         LBCHECK( localNode->mapObject( child, request.wait(),
     221           0 :                                        co::VERSION_NONE ));
     222             :     }
     223      156437 :     child->commit( incarnation );
     224      156437 : }
     225             : 
     226             : template< class C, class S > inline void
     227       92023 : Object::commitChildren( const std::vector< C* >& children, S* sender,
     228             :                         uint32_t cmd, const uint32_t incarnation )
     229             : {
     230             :     // TODO Opt: async register and commit
     231      745380 :     for( typename std::vector< C* >::const_iterator i = children.begin();
     232      496920 :          i != children.end(); ++i )
     233             :     {
     234      156437 :         C* child = *i;
     235      156437 :         commitChild< C, S >( child, sender, cmd, incarnation );
     236             :     }
     237       92023 : }
     238             : 
     239             : template< class C >
     240          47 : inline void Object::commitChildren( const std::vector< C* >& children,
     241             :                                     const uint32_t incarnation )
     242             : {
     243             :     // TODO Opt: async commit
     244         360 :     for( typename std::vector< C* >::const_iterator i = children.begin();
     245         240 :          i != children.end(); ++i )
     246             :     {
     247          73 :         C* child = *i;
     248          73 :         LBASSERT( child->isAttached( ));
     249          73 :         child->commit( incarnation );
     250             :     }
     251          47 : }
     252             : 
     253             : template< class C >
     254          99 : inline void Object::syncChildren( const std::vector< C* >& children )
     255             : {
     256         798 :     for( typename std::vector< C* >::const_iterator i = children.begin();
     257         532 :          i != children.end(); ++i )
     258             :     {
     259         167 :         C* child = *i;
     260         167 :         LBASSERT( child->isMaster( )); // slaves are synced using version
     261         167 :         child->sync();
     262             :     }
     263          99 : }
     264             : 
     265             : template< class P, class C >
     266         146 : inline void Object::releaseChildren( const std::vector< C* >& children )
     267             : {
     268         292 :     for( size_t i = children.size(); i > 0; --i )
     269             :     {
     270         146 :         C* child = children[ i - 1 ];
     271             : 
     272         146 :         if( child->isAttached( ))
     273             :         {
     274          73 :             getLocalNode()->releaseObject( child );
     275          73 :             if( !isMaster( ))
     276             :             {
     277          73 :                 static_cast< P* >( this )->_removeChild( child );
     278          73 :                 static_cast< P* >( this )->release( child );
     279             :             }
     280             :         }
     281             :         else
     282             :         {
     283          73 :             LBASSERT( isMaster( ));
     284             :         }
     285             :     }
     286         146 : }
     287             : }
     288             : }
     289             : #endif // EQFABRIC_OBJECT_H

Generated by: LCOV version 1.10