diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2009-07-29 14:23:36 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2009-07-29 14:23:36 +0800 |
commit | 511a99232b217b625b8ba88d1cb73698ac842b42 (patch) | |
tree | a950c7fbbff1f3095752a527af6e0f0b59c57e9d | |
parent | 7eb03463c82f7951994f1aaf005032fb19fa1da2 (diff) |
Atomically increment and decrement the refcounts for Audiere objects.
-rw-r--r-- | src/audiere.h | 83 | ||||
-rw-r--r-- | src/utility.cpp | 29 |
2 files changed, 76 insertions, 36 deletions
diff --git a/src/audiere.h b/src/audiere.h index dca64cf..bbeee49 100644 --- a/src/audiere.h +++ b/src/audiere.h @@ -187,39 +187,6 @@ namespace audiere { /** - * A basic implementation of the RefCounted interface. Derive - * your implementations from RefImplementation<YourInterface>. - */ - template<class Interface> - class RefImplementation : public Interface { - protected: - RefImplementation() { - m_ref_count = 0; - } - - /** - * So the implementation can put its destruction logic in the destructor, - * as natural C++ code does. - */ - virtual ~RefImplementation() { } - - public: - void ADR_CALL ref() { - ++m_ref_count; - } - - void ADR_CALL unref() { - if (--m_ref_count == 0) { - delete this; - } - } - - private: - int m_ref_count; - }; - - - /** * Represents a random-access file, usually stored on a disk. Files * are always binary: that is, they do no end-of-line * transformations. File objects are roughly analogous to ANSI C @@ -1047,6 +1014,9 @@ namespace audiere { ADR_FUNCTION(const char*) AdrGetVersion(); + ADR_FUNCTION(long) AdrAtomicIncrement(volatile long& var); + ADR_FUNCTION(long) AdrAtomicDecrement(volatile long& var); + /** * Returns a formatted string that lists the file formats that Audiere * supports. This function is DLL-safe. @@ -1139,6 +1109,20 @@ namespace audiere { } + /** + * Atomically increments a counter. Returns incremented value. + */ + inline long AtomicIncrement(volatile long& var) { + return hidden::AdrAtomicIncrement(var); + } + + /** + * Atomically decrements a counter. Returns decremented value. + */ + inline long AtomicDecrement(volatile long& var) { + return hidden::AdrAtomicDecrement(var); + } + inline void SplitString( std::vector<std::string>& out, const char* in, @@ -1560,6 +1544,39 @@ namespace audiere { return hidden::AdrOpenMIDIDevice(device); } + + /** + * A basic implementation of the RefCounted interface. Derive + * your implementations from RefImplementation<YourInterface>. + */ + template<class Interface> + class RefImplementation : public Interface { + protected: + RefImplementation() { + m_ref_count = 0; + } + + /** + * So the implementation can put its destruction logic in the destructor, + * as natural C++ code does. + */ + virtual ~RefImplementation() { } + + public: + void ADR_CALL ref() { + AtomicIncrement(m_ref_count); + } + + void ADR_CALL unref() { + if (AtomicDecrement(m_ref_count) == 0) { + delete this; + } + } + + private: + volatile long m_ref_count; + }; + } diff --git a/src/utility.cpp b/src/utility.cpp index fd220d6..1a5e295 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -2,11 +2,11 @@ #pragma warning(disable : 4786) #endif +#ifdef WIN32 +#include <windows.h> +#endif #include <ctype.h> -#include <stdlib.h> -#include <stdio.h> - #include "utility.h" #include "internal.h" @@ -89,6 +89,29 @@ namespace audiere { } +#ifdef WIN32 + + ADR_EXPORT(long) AdrAtomicIncrement(volatile long& var) { + return InterlockedIncrement(&var); + + } + + ADR_EXPORT(long) AdrAtomicDecrement(volatile long& var) { + return InterlockedDecrement(&var); + } + +#else + + ADR_EXPORT(long) AdrAtomicIncrement(volatile long& var) { + return ++var; + } + + ADR_EXPORT(long) AdrAtomicDecrement(volatile long& var) { + return --var; + } + +#endif + ADR_EXPORT(int) AdrGetSampleSize(SampleFormat format) { switch (format) { case SF_U8: return 1; |