1 /*************************************************************************** 2 copyright : (C) 2013 by Tsuda Kageyu 3 email : [email protected] 4 ***************************************************************************/ 5 6 /*************************************************************************** 7 * This library is free software; you can redistribute it and/or modify * 8 * it under the terms of the GNU Lesser General Public License version * 9 * 2.1 as published by the Free Software Foundation. * 10 * * 11 * This library is distributed in the hope that it will be useful, but * 12 * WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 * Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with this library; if not, write to the Free Software * 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 19 * 02110-1301 USA * 20 * * 21 * Alternatively, this file is available under the Mozilla Public * 22 * License Version 1.1. You may obtain a copy of the License at * 23 * http://www.mozilla.org/MPL/ * 24 ***************************************************************************/ 25 26 #ifndef TAGLIB_REFCOUNTER_H 27 #define TAGLIB_REFCOUNTER_H 28 29 #include "taglib_export.h" 30 #include "taglib.h" 31 32 #ifdef __APPLE__ 33 # define OSATOMIC_DEPRECATED 0 34 # include <libkern/OSAtomic.h> 35 # define TAGLIB_ATOMIC_MAC 36 #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 37 # ifndef NOMINMAX 38 # define NOMINMAX 39 # endif 40 # include <windows.h> 41 # define TAGLIB_ATOMIC_WIN 42 #elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 401) \ 43 && (defined(__i386__) || defined(__i486__) || defined(__i586__) || \ 44 defined(__i686__) || defined(__x86_64) || defined(__ia64)) \ 45 && !defined(__INTEL_COMPILER) 46 # define TAGLIB_ATOMIC_GCC 47 #elif defined(__ia64) && defined(__INTEL_COMPILER) 48 # include <ia64intrin.h> 49 # define TAGLIB_ATOMIC_GCC 50 #endif 51 52 #ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class. 53 /*! 54 * \internal 55 * This is just used as a base class for shared classes in TagLib. 56 * 57 * \warning This <b>is not</b> part of the TagLib public API! 58 */ 59 namespace TagLib 60 { 61 62 class TAGLIB_EXPORT RefCounter 63 { 64 public: 65 RefCounter(); 66 virtual ~RefCounter(); 67 68 void ref(); 69 bool deref(); 70 int count() const; 71 72 private: 73 class RefCounterPrivate; 74 RefCounterPrivate *d; 75 }; 76 77 // BIC this old class is needed by tlist.tcc and tmap.tcc 78 class RefCounterOld 79 { 80 public: RefCounterOld()81 RefCounterOld() : refCount(1) {} 82 83 #ifdef TAGLIB_ATOMIC_MAC ref()84 void ref() { OSAtomicIncrement32Barrier(const_cast<int32_t*>(&refCount)); } deref()85 bool deref() { return ! OSAtomicDecrement32Barrier(const_cast<int32_t*>(&refCount)); } count()86 int32_t count() { return refCount; } 87 private: 88 volatile int32_t refCount; 89 #elif defined(TAGLIB_ATOMIC_WIN) ref()90 void ref() { InterlockedIncrement(&refCount); } deref()91 bool deref() { return ! InterlockedDecrement(&refCount); } count()92 long count() { return refCount; } 93 private: 94 volatile long refCount; 95 #elif defined(TAGLIB_ATOMIC_GCC) ref()96 void ref() { __sync_add_and_fetch(&refCount, 1); } deref()97 bool deref() { return ! __sync_sub_and_fetch(&refCount, 1); } count()98 int count() { return refCount; } 99 private: 100 volatile int refCount; 101 #else ref()102 void ref() { refCount++; } deref()103 bool deref() { return ! --refCount; } count()104 int count() { return refCount; } 105 private: 106 unsigned int refCount; 107 #endif 108 }; 109 110 } 111 112 #endif // DO_NOT_DOCUMENT 113 #endif 114 115