X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=ETL%2Ftrunk%2FETL%2F_handle.h;h=6a46f85ae683cf363d88a8dbd37558bf7fa4edce;hb=5f8bb1a790e48650f65f34523efc133a140b6609;hp=0cf5af2854d39121098831818d7e5001ec919431;hpb=b3016b249333ac0ab0008d8c6c4d9029b2ff30c9;p=synfig.git diff --git a/ETL/trunk/ETL/_handle.h b/ETL/trunk/ETL/_handle.h index 0cf5af2..6a46f85 100644 --- a/ETL/trunk/ETL/_handle.h +++ b/ETL/trunk/ETL/_handle.h @@ -1,6 +1,6 @@ /* === E T L =============================================================== */ /*! \file _handle.h -** $Id: _handle.h,v 1.1.1.1 2005/01/04 01:31:47 darco Exp $ +** $Id$ ** \brief Template Object Handle Implementation ** \internal ** @@ -31,7 +31,13 @@ /* === H E A D E R S ======================================================= */ +// include the next line in an attempt to increase stability +#define ETL_LOCK_REFCOUNTS + #include +#ifdef ETL_LOCK_REFCOUNTS +#include +#endif /* === M A C R O S ========================================================= */ @@ -66,7 +72,10 @@ class shared_object { private: mutable int refcount; - +#ifdef ETL_LOCK_REFCOUNTS + mutable Glib::Mutex mutex; +#endif + protected: shared_object():refcount(0) { } @@ -75,14 +84,22 @@ protected: #else ~shared_object() { } #endif - -public: + +public: void ref()const - { assert(refcount>=0); refcount++; } - + { +#ifdef ETL_LOCK_REFCOUNTS + Glib::Mutex::Lock lock(mutex); +#endif + assert(refcount>=0); refcount++; + } + //! Returns \c false if object needs to be deleted bool unref()const { +#ifdef ETL_LOCK_REFCOUNTS + Glib::Mutex::Lock lock(mutex); +#endif assert(refcount>0); refcount--; @@ -90,6 +107,9 @@ public: if(refcount==0) { #ifdef ETL_SELF_DELETING_SHARED_OBJECT refcount=-666; +#ifdef ETL_LOCK_REFCOUNTS + lock.release(); +#endif delete this; #endif return false; @@ -97,9 +117,14 @@ public: return true; } - + int count()const - { return refcount; } + { +#ifdef ETL_LOCK_REFCOUNTS + Glib::Mutex::Lock lock(mutex); +#endif + return refcount; + } }; // END of class shared_object // ======================================================================== @@ -182,7 +207,7 @@ public: return *this; } */ - + //! Assignment operator handle & operator=(const handle &x) @@ -229,7 +254,7 @@ public: void reset() { detach(); } bool empty()const { return obj==0; } - + //! Creates a new instance of a T object and puts it in the handle. /*! Uses the default constructor */ void spawn() { operator=(handle(new T())); } @@ -257,14 +282,14 @@ public: operator->()const { assert(obj); return obj; } - //! static_cast<> overload -- Useful for implicit casts - template - operator handle()const - { return handle(static_cast(obj)); } + //! More explicit bool cast + operator bool()const + { return obj!=NULL; } operator handle()const { return handle(static_cast(obj)); } + //! static_cast\<\> wrapper template static handle cast_static(const handle &x) @@ -303,13 +328,14 @@ public: //! Returns pointer to the object that is being wrapped pointer get()const { return obj; } - //! More explicit bool cast - operator bool()const - { return obj!=NULL; } - bool operator!()const { return !obj; } + + //! static_cast<> overload -- Useful for implicit casts + template + operator handle()const + { return handle(static_cast(obj)); } }; // END of template class handle // ======================================================================== @@ -326,20 +352,20 @@ private: public: void *front_; void *back_; - + protected: rshared_object():rrefcount(0),front_(0),back_(0) { } - -public: + +public: void rref()const { rrefcount++; } - + void runref()const { assert(rrefcount>0); rrefcount--; } - + int rcount()const { return rrefcount; } }; // END of class rshared_object @@ -371,7 +397,7 @@ public: using handle::get; using handle::operator *; using handle::operator ->; - + /* operator const handle&()const { return *this; } @@ -379,7 +405,7 @@ public: private: using handle::obj; - + rhandle *prev_; rhandle *next_; @@ -390,14 +416,14 @@ private: assert(obj); obj->rref(); - // If this is the first reversable handle + // If this is the first reversible handle if(!obj->front_) { obj->front_=obj->back_=this; prev_=next_=0; return; } - + prev_=reinterpret_cast*>(obj->back_); next_=0; prev_->next_=this; @@ -410,7 +436,7 @@ private: assert(obj); obj->runref(); - // If this is the last reversable handle + // If this is the last reversible handle if(obj->front_==obj->back_) { obj->front_=obj->back_=0; @@ -428,7 +454,7 @@ private: else next_->prev_=prev_; } - + public: //! Default constructor - empty handle @@ -456,7 +482,7 @@ public: //! Handle is released on deletion ~rhandle() { detach(); } - + //! Template Assignment operator /*! \note This class may not be necessary, and may be removed ** at some point in the future. @@ -479,7 +505,7 @@ public: return *this; } */ - + //! Assignment operator rhandle & operator=(const rhandle &x) @@ -555,7 +581,7 @@ public: /*! Uses the default constructor */ void spawn() { operator=(handle(new T())); } - //! Returns number of reversable instances + //! Returns number of reversible instances count_type rcount()const { @@ -577,32 +603,32 @@ public: // value_type*& obj(handle::obj); // Required to keep gcc 3.4.2 form barfing assert(obj); assert(x.get()!=obj); - + if(x.get()==obj) return 0; - + rhandle *iter; rhandle *next; - + iter=reinterpret_cast*>(obj->front_); - assert(iter); + assert(iter); next=iter->next_; - + int i=0; #ifndef NDEBUG pointer obj_=obj; #endif - + for(;iter;iter=next,next=iter?iter->next_:0,i++) { - assert(iter->get()==obj_); + assert(iter->get()==obj_); (*iter)=x; } assert(obj==x.get()); - + return i; } @@ -710,7 +736,7 @@ public: //void release() { detach(); } void reset() { detach(); } - + bool empty()const { return obj==0; } handle clone()const { assert(obj); return obj->clone(); } @@ -781,8 +807,8 @@ template template handle handle::cast_reinterpret(const loose_handle &x) { return handle(reinterpret_cast(x.get())); } - - + + template template handle handle::cast_static(const rhandle &x) { return handle(static_cast(x.get())); } @@ -799,8 +825,8 @@ template template handle handle::cast_reinterpret(const rhandle &x) { return handle(reinterpret_cast(x.get())); } - - + + template template handle handle::cast_static(U* x) { return handle(static_cast(x)); }