Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef TAGLIB_REFCOUNTER_H
00027 #define TAGLIB_REFCOUNTER_H
00028
00029 #include "taglib_export.h"
00030 #include "taglib.h"
00031
00032 #ifdef __APPLE__
00033 # include <libkern/OSAtomic.h>
00034 # define TAGLIB_ATOMIC_MAC
00035 #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
00036 # define NOMINMAX
00037 # include <windows.h>
00038 # define TAGLIB_ATOMIC_WIN
00039 #elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 401) \
00040 && (defined(__i386__) || defined(__i486__) || defined(__i586__) || \
00041 defined(__i686__) || defined(__x86_64) || defined(__ia64)) \
00042 && !defined(__INTEL_COMPILER)
00043 # define TAGLIB_ATOMIC_GCC
00044 #elif defined(__ia64) && defined(__INTEL_COMPILER)
00045 # include <ia64intrin.h>
00046 # define TAGLIB_ATOMIC_GCC
00047 #endif
00048
00049 #ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class.
00050
00056 namespace TagLib
00057 {
00058
00059 class TAGLIB_EXPORT RefCounter
00060 {
00061 public:
00062 RefCounter();
00063 virtual ~RefCounter();
00064
00065 void ref();
00066 bool deref();
00067 int count() const;
00068
00069 private:
00070 class RefCounterPrivate;
00071 RefCounterPrivate *d;
00072 };
00073
00074
00075 class RefCounterOld
00076 {
00077 public:
00078 RefCounterOld() : refCount(1) {}
00079
00080 #ifdef TAGLIB_ATOMIC_MAC
00081 void ref() { OSAtomicIncrement32Barrier(const_cast<int32_t*>(&refCount)); }
00082 bool deref() { return ! OSAtomicDecrement32Barrier(const_cast<int32_t*>(&refCount)); }
00083 int32_t count() { return refCount; }
00084 private:
00085 volatile int32_t refCount;
00086 #elif defined(TAGLIB_ATOMIC_WIN)
00087 void ref() { InterlockedIncrement(&refCount); }
00088 bool deref() { return ! InterlockedDecrement(&refCount); }
00089 long count() { return refCount; }
00090 private:
00091 volatile long refCount;
00092 #elif defined(TAGLIB_ATOMIC_GCC)
00093 void ref() { __sync_add_and_fetch(&refCount, 1); }
00094 bool deref() { return ! __sync_sub_and_fetch(&refCount, 1); }
00095 int count() { return refCount; }
00096 private:
00097 volatile int refCount;
00098 #else
00099 void ref() { refCount++; }
00100 bool deref() { return ! --refCount; }
00101 int count() { return refCount; }
00102 private:
00103 uint refCount;
00104 #endif
00105 };
00106
00107 }
00108
00109 #endif // DO_NOT_DOCUMENT
00110 #endif
00111