Return-Path: X-Original-To: apmail-activemq-commits-archive@www.apache.org Delivered-To: apmail-activemq-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 16207950E for ; Mon, 14 May 2012 22:06:18 +0000 (UTC) Received: (qmail 24731 invoked by uid 500); 14 May 2012 22:06:18 -0000 Delivered-To: apmail-activemq-commits-archive@activemq.apache.org Received: (qmail 24680 invoked by uid 500); 14 May 2012 22:06:18 -0000 Mailing-List: contact commits-help@activemq.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@activemq.apache.org Delivered-To: mailing list commits@activemq.apache.org Received: (qmail 24673 invoked by uid 99); 14 May 2012 22:06:17 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 14 May 2012 22:06:17 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 14 May 2012 22:06:16 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id E003223889E1 for ; Mon, 14 May 2012 22:05:55 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1338452 - /activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h Date: Mon, 14 May 2012 22:05:55 -0000 To: commits@activemq.apache.org From: tabish@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120514220555.E003223889E1@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: tabish Date: Mon May 14 22:05:55 2012 New Revision: 1338452 URL: http://svn.apache.org/viewvc?rev=1338452&view=rev Log: Refactor to make this more thread safe. Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h?rev=1338452&r1=1338451&r2=1338452&view=diff ============================================================================== --- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h (original) +++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h Mon May 14 22:05:55 2012 @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,16 +47,17 @@ namespace lang { * * @since 1.0 */ - template< typename T, typename REFCOUNTER = decaf::util::concurrent::atomic::AtomicRefCounter > - class ArrayPointer : public REFCOUNTER { + template< typename T > + class ArrayPointer { private: struct ArrayData { T* value; int length; + decaf::util::concurrent::atomic::AtomicInteger refs; - ArrayData() : value( NULL ), length( 0 ) {} - ArrayData( T* value, int length ) : value( value ), length( length ) { + ArrayData() : value(NULL), length(0), refs(1) {} + ArrayData(T* value, int length) : value(value), length(length), refs(1) { if( value != NULL && length <= 0 ) { throw decaf::lang::exceptions::IllegalArgumentException( __FILE__, __LINE__, "Non-NULL array pointer cannot have a size <= zero" ); @@ -67,6 +68,13 @@ namespace lang { __FILE__, __LINE__, "NULL array pointer cannot have a size > zero" ); } } + + bool release() { + if (this->refs.decrementAndGet() < 1) { + return true; + } + return false; + } }; typedef void (*deletionFuncPtr)(ArrayData* p); @@ -83,7 +91,6 @@ namespace lang { typedef T* PointerType; // type returned by operator-> typedef T& ReferenceType; // type returned by operator* typedef const T& ConstReferenceType; // type returned by const operator* - typedef REFCOUNTER CounterType; // Type of the Reference Counter public: @@ -93,7 +100,7 @@ namespace lang { * Initialized the contained array pointer to NULL, using the subscript operator * results in an exception unless reset to contain a real value. */ - ArrayPointer() : REFCOUNTER(), array( new ArrayData() ), onDelete( onDeleteFunc ) {} + ArrayPointer() : array(new ArrayData()), onDelete(onDeleteFunc) {} /** * Create a new ArrayPointer instance and allocates an internal array that is sized @@ -102,21 +109,18 @@ namespace lang { * @param size * The size of the array to allocate for this ArrayPointer instance. */ - ArrayPointer( int size ) : - REFCOUNTER(), array( NULL ), onDelete( onDeleteFunc ) { + ArrayPointer(int size) : array(NULL), onDelete(onDeleteFunc) { - if( size == 0 ) { + if (size == 0) { return; } - try{ + try { T* value = new T[size]; - this->array = new ArrayData( value, size ); - } catch( std::exception& ex ) { - REFCOUNTER::release(); + this->array = new ArrayData(value, size); + } catch (std::exception& ex) { throw ex; - } catch(...) { - REFCOUNTER::release(); + } catch (...) { throw std::bad_alloc(); } } @@ -131,22 +135,19 @@ namespace lang { * @param fillWith * The value to initialize each element of the newly allocated array with. */ - ArrayPointer( int size, const T& fillWith ) : - REFCOUNTER(), array( NULL ), onDelete( onDeleteFunc ) { + ArrayPointer(int size, const T& fillWith) : array(NULL), onDelete(onDeleteFunc) { - if( size == 0 ) { + if (size == 0) { return; } - try{ + try { T* value = new T[size]; - decaf::util::Arrays::fill( value, size, 0, size, fillWith ); - this->array = new ArrayData( value, size ); - } catch( std::exception& ex ) { - REFCOUNTER::release(); + decaf::util::Arrays::fill(value, size, 0, size, fillWith); + this->array = new ArrayData(value, size); + } catch (std::exception& ex) { throw ex; - } catch(...) { - REFCOUNTER::release(); + } catch (...) { throw std::bad_alloc(); } } @@ -160,16 +161,13 @@ namespace lang { * @param size * The size of the array this object is taking ownership of. */ - explicit ArrayPointer( const PointerType value, int size ) : - REFCOUNTER(), array( NULL ), onDelete( onDeleteFunc ) { + explicit ArrayPointer(const PointerType value, int size) : array(NULL), onDelete(onDeleteFunc) { - try{ - this->array = new ArrayData( value, size ); - } catch( std::exception& ex ) { - REFCOUNTER::release(); + try { + this->array = new ArrayData(value, size); + } catch (std::exception& ex) { throw ex; - } catch(...) { - REFCOUNTER::release(); + } catch (...) { throw std::bad_alloc(); } } @@ -178,12 +176,13 @@ namespace lang { * Copy constructor. Copies the value contained in the ArrayPointer to the new * instance and increments the reference counter. */ - ArrayPointer( const ArrayPointer& value ) : - REFCOUNTER( value ), array( value.array ), onDelete( onDeleteFunc ) {} + ArrayPointer(const ArrayPointer& value) : array(value.array), onDelete(onDeleteFunc) { + this->array->refs.incrementAndGet(); + } virtual ~ArrayPointer() { - if( REFCOUNTER::release() == true ) { - onDelete( this->array ); + if (this->array->release() == true) { + onDelete(this->array); } } @@ -198,8 +197,8 @@ namespace lang { * @param size * The size of the new array value this object now contains. */ - void reset( T* value, int size = 0 ) { - ArrayPointer( value, size ).swap( *this ); + void reset(T* value, int size = 0) { + ArrayPointer(value, size).swap(*this); } /** @@ -217,6 +216,7 @@ namespace lang { T* temp = this->array->value; this->array->value = NULL; this->array->length = 0; + this->array->refs.set(1); return temp; } @@ -246,9 +246,8 @@ namespace lang { * Exception Safe Swap Function * @param value - the value to swap with this. */ - void swap( ArrayPointer& value ) { - std::swap( this->array, value.array ); - REFCOUNTER::swap( value ); + void swap(ArrayPointer& value) { + std::swap(this->array, value.array); } /** @@ -259,12 +258,12 @@ namespace lang { */ ArrayPointer clone() const { - if( this->array->length == 0 ){ + if (this->array->length == 0) { return ArrayPointer(); } - ArrayPointer copy( this->array->length ); - decaf::lang::System::arraycopy( this->array->value, 0, copy.get(), 0, this->array->length ); + ArrayPointer copy(this->array->length); + decaf::lang::System::arraycopy(this->array->value, 0, copy.get(), 0, this->array->length); return copy; } @@ -272,23 +271,23 @@ namespace lang { * Assigns the value of right to this Pointer and increments the reference Count. * @param right - Pointer on the right hand side of an operator= call to this. */ - ArrayPointer& operator= ( const ArrayPointer& right ) { - if( this == (void*)&right ) { + ArrayPointer& operator=(const ArrayPointer& right) { + if (this == (void*) &right) { return *this; } - ArrayPointer temp( right ); - temp.swap( *this ); + ArrayPointer temp(right); + temp.swap(*this); return *this; } - template< typename T1, typename R1> - ArrayPointer& operator= ( const ArrayPointer& right ) { - if( this == (void*)&right ) { + template< typename T1> + ArrayPointer& operator=(const ArrayPointer& right) { + if (this == (void*) &right) { return *this; } - ArrayPointer temp( right ); - temp.swap( *this ); + ArrayPointer temp(right); + temp.swap(*this); return *this; } @@ -300,20 +299,20 @@ namespace lang { * * @throws NullPointerException if the contained value is Null */ - ReferenceType operator[]( int index ) { - if( this->array->value == NULL ) { + ReferenceType operator[](int index) { + if (this->array->value == NULL) { throw decaf::lang::exceptions::NullPointerException( __FILE__, __LINE__, "ArrayPointer operator& - Pointee is NULL." ); } - if( index < 0 || this->array->length <= index ) { + if (index < 0 || this->array->length <= index) { throw decaf::lang::exceptions::IndexOutOfBoundsException( __FILE__, __LINE__, "Array Index %d is out of bounds for this array.", this->array->length ); } return this->array->value[index]; } - ConstReferenceType operator[]( int index ) const { + ConstReferenceType operator[](int index) const { if( this->array->value == NULL ) { throw decaf::lang::exceptions::NullPointerException( __FILE__, __LINE__, "ArrayPointer operator& - Pointee is NULL." ); @@ -331,36 +330,36 @@ namespace lang { return this->array->value == NULL; } - inline friend bool operator==( const ArrayPointer& left, const T* right ) { + inline friend bool operator==(const ArrayPointer& left, const T* right) { return left.get() == right; } - inline friend bool operator==( const T* left, const ArrayPointer& right ) { + inline friend bool operator==(const T* left, const ArrayPointer& right) { return left == right.get(); } - inline friend bool operator!=( const ArrayPointer& left, const T* right ) { + inline friend bool operator!=(const ArrayPointer& left, const T* right) { return left.get() != right; } - inline friend bool operator!=( const T* left, const ArrayPointer& right ) { + inline friend bool operator!=(const T* left, const ArrayPointer& right) { return left != right.get(); } - template< typename T1, typename R1 > - bool operator==( const ArrayPointer& right ) const { + template + bool operator==(const ArrayPointer& right) const { return this->array->value == right.get(); } - template< typename T1, typename R1 > - bool operator!=( const ArrayPointer& right ) const { + template + bool operator!=(const ArrayPointer& right) const { return this->array->value != right.get(); } private: // Internal Static deletion function. - static void onDeleteFunc( ArrayData* value ) { + static void onDeleteFunc(ArrayData* value) { delete [] value->value; delete value; } @@ -368,26 +367,26 @@ namespace lang { }; //////////////////////////////////////////////////////////////////////////// - template< typename T, typename R, typename U > - inline bool operator==( const ArrayPointer& left, const U* right ) { + template + inline bool operator==(const ArrayPointer& left, const U* right) { return left.get() == right; } //////////////////////////////////////////////////////////////////////////// - template< typename T, typename R, typename U > - inline bool operator==( const U* left, const ArrayPointer& right ) { + template + inline bool operator==(const U* left, const ArrayPointer& right) { return right.get() == left; } //////////////////////////////////////////////////////////////////////////// - template< typename T, typename R, typename U > - inline bool operator!=( const ArrayPointer& left, const U* right ) { - return !( left.get() == right ); + template + inline bool operator!=(const ArrayPointer& left, const U* right) { + return !(left.get() == right); } //////////////////////////////////////////////////////////////////////////// - template< typename T, typename R, typename U > - inline bool operator!=( const U* left, const ArrayPointer& right ) { + template + inline bool operator!=(const U* left, const ArrayPointer& right) { return right.get() != left; } @@ -400,20 +399,20 @@ namespace lang { * Custom implementations are possible where an array of some type has a logical natural * ordering such as array of integers where the sum of all ints in the array is used. */ - template< typename T, typename R = decaf::util::concurrent::atomic::AtomicRefCounter > - class ArrayPointerComparator : public decaf::util::Comparator< ArrayPointer > { + template< typename T > + class ArrayPointerComparator : public decaf::util::Comparator< ArrayPointer > { public: virtual ~ArrayPointerComparator() {} // Allows for operator less on types that implement Comparable or provide // a workable operator < - virtual bool operator() ( const ArrayPointer& left, const ArrayPointer& right ) const { + virtual bool operator() ( const ArrayPointer& left, const ArrayPointer& right ) const { return left.get() < right.get(); } // Requires that the type in the pointer is an instance of a Comparable. - virtual int compare( const ArrayPointer& left, const ArrayPointer& right ) const { + virtual int compare(const ArrayPointer& left, const ArrayPointer& right) const { return left.get() < right.get() ? -1 : right.get() < left.get() ? 1 : 0; } @@ -430,13 +429,13 @@ namespace std{ */ template< typename T > struct less< decaf::lang::ArrayPointer > : - public binary_function< decaf::lang::ArrayPointer, - decaf::lang::ArrayPointer, bool> + public binary_function, + decaf::lang::ArrayPointer, bool> { - bool operator()( const decaf::lang::ArrayPointer& left, - const decaf::lang::ArrayPointer& right ) const + bool operator()(const decaf::lang::ArrayPointer& left, + const decaf::lang::ArrayPointer& right) const { - return less()( left.get(), right.get() ); + return less()(left.get(), right.get()); } }; }