Page Menu
Home
Search
Configure Global Search
Log In
Files
F19054
aud_reference-shared_ptr-impl.patch
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Wander Lairson Costa (walac)
Nov 13 2013, 4:13 PM
Size
10 KB
Subscribers
None
aud_reference-shared_ptr-impl.patch
View Options
Index: intern/audaspace/intern/AUD_Reference.h
===================================================================
--- intern/audaspace/intern/AUD_Reference.h (revisão 46420)
+++ intern/audaspace/intern/AUD_Reference.h (cópia de trabalho)
@@ -31,81 +31,30 @@
#include <map>
#include <cstddef>
-#include <pthread.h>
+#include <boost/smart_ptr/shared_ptr.hpp>
-// #define MEM_DEBUG
-
-#ifdef MEM_DEBUG
-#include <iostream>
-#include <typeinfo>
-#endif
-
/**
- * This class handles the reference counting.
- */
-class AUD_ReferenceHandler
-{
-private:
- /**
- * Saves the reference counts.
- */
- static std::map<void*, unsigned int> m_references;
- static pthread_mutex_t m_mutex;
- static bool m_mutex_initialised;
-
-public:
-
- static pthread_mutex_t* getMutex();
-
- /**
- * Reference increment.
- * \param reference The reference.
- */
- static inline void incref(void* reference)
- {
- if(!reference)
- return;
-
- std::map<void*, unsigned int>::iterator result = m_references.find(reference);
- if(result != m_references.end())
- {
- m_references[reference]++;
- }
- else
- {
- m_references[reference] = 1;
- }
- }
-
- /**
- * Reference decrement.
- * \param reference The reference.
- * \return Whether the reference has to be deleted.
- */
- static inline bool decref(void* reference)
- {
- if(!reference)
- return false;
-
- if(!--m_references[reference])
- {
- m_references.erase(reference);
- return true;
- }
- return false;
- }
-};
-
-template <class T>
-/**
* This class provides reference counting functionality.
+ *
+ * Important:
+ *
+ * AUD_Reference used to have a global reference count table,
+ * which caused the following code be valid:
+ *
+ * class A {};
+ *
+ * A *pa = new A();
+ * AUD_Reference<A> r1(a);
+ * AUD_Reference<A> r2(a);
+ *
+ * Now with the new implementation using boost:shared_ptr, the
+ * above code will result in a double delete, so it is no longer
+ * valid. Existing code must be revised to check against this
+ * situation.
*/
+template <class T>
class AUD_Reference
{
-private:
- /// The reference.
- T* m_reference;
- void* m_original;
public:
/**
* Creates a new reference counter.
@@ -113,22 +62,12 @@
*/
template <class U>
AUD_Reference(U* reference)
+ : m_reference(reference)
{
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
- m_original = reference;
- m_reference = dynamic_cast<T*>(reference);
- AUD_ReferenceHandler::incref(m_original);
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "+" << typeid(*m_reference).name() << std::endl;
-#endif
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
}
AUD_Reference()
{
- m_original = NULL;
- m_reference = NULL;
}
/**
@@ -136,95 +75,22 @@
* \param ref The AUD_Reference object to copy.
*/
AUD_Reference(const AUD_Reference& ref)
+ : m_reference(ref.m_reference)
{
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
- m_original = ref.m_original;
- m_reference = ref.m_reference;
- AUD_ReferenceHandler::incref(m_original);
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "+" << typeid(*m_reference).name() << std::endl;
-#endif
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
}
template <class U>
explicit AUD_Reference(const AUD_Reference<U>& ref)
+ : m_reference(boost::dynamic_pointer_cast<T>(ref.m_reference))
{
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
- m_original = ref.get();
- m_reference = dynamic_cast<T*>(ref.get());
- AUD_ReferenceHandler::incref(m_original);
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "+" << typeid(*m_reference).name() << std::endl;
-#endif
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
}
/**
- * Destroys a AUD_Reference object, if there's no furthere reference on the
- * reference, it is destroyed as well.
- */
- ~AUD_Reference()
- {
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "-" << typeid(*m_reference).name() << std::endl;
-#endif
- if(AUD_ReferenceHandler::decref(m_original))
- {
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
- delete m_reference;
- }
- else
- {
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
- }
- }
-
- /**
- * Assigns an AUD_Reference to this object.
- * \param ref The AUD_Reference object to assign.
- */
- AUD_Reference& operator=(const AUD_Reference& ref)
- {
- if(&ref == this)
- return *this;
-
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
-
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "-" << typeid(*m_reference).name() << std::endl;
-#endif
- if(AUD_ReferenceHandler::decref(m_original))
- {
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
- delete m_reference;
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
- }
-
- m_original = ref.m_original;
- m_reference = ref.m_reference;
- AUD_ReferenceHandler::incref(m_original);
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "+" << typeid(*m_reference).name() << std::endl;
-#endif
-
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
-
- return *this;
- }
-
- /**
* Returns whether the reference is NULL.
*/
inline bool isNull() const
{
- return m_reference == NULL;
+ return !m_reference;
}
/**
@@ -232,18 +98,10 @@
*/
inline T* get() const
{
- return m_reference;
+ return m_reference.get();
}
/**
- * Returns the original pointer.
- */
- inline void* getOriginal() const
- {
- return m_original;
- }
-
- /**
* Returns the reference.
*/
inline T& operator*() const
@@ -256,20 +114,27 @@
*/
inline T* operator->() const
{
- return m_reference;
+ return get();
}
+
+private:
+ template <typename U> friend class AUD_Reference;
+ template <typename U, typename V> friend bool operator==(const AUD_Reference<U> &a, const AUD_Reference<V> &b);
+ template <typename U, typename V> friend bool operator!=(const AUD_Reference<U> &a, const AUD_Reference<V> &b);
+
+ boost::shared_ptr<T> m_reference;
};
template<class T, class U>
inline bool operator==(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
{
- return a.getOriginal() == b.getOriginal();
+ return a.m_reference == b.m_reference;
}
template<class T, class U>
inline bool operator!=(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
{
- return a.getOriginal() != b.getOriginal();
+ return a.m_reference != b.m_reference;
}
#endif // __AUD_REFERENCE_H__
Index: intern/audaspace/intern/AUD_ReferenceHandler.cpp
===================================================================
--- intern/audaspace/intern/AUD_ReferenceHandler.cpp (revisão 46420)
+++ intern/audaspace/intern/AUD_ReferenceHandler.cpp (cópia de trabalho)
@@ -28,25 +28,5 @@
#include "AUD_Reference.h"
-std::map<void*, unsigned int> AUD_ReferenceHandler::m_references;
-pthread_mutex_t AUD_ReferenceHandler::m_mutex;
-bool AUD_ReferenceHandler::m_mutex_initialised = false;
-pthread_mutex_t *AUD_ReferenceHandler::getMutex()
-{
- if(!m_mutex_initialised)
- {
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&m_mutex, &attr);
-
- pthread_mutexattr_destroy(&attr);
-
- m_mutex_initialised = true;
- }
-
- return &m_mutex;
-}
-
Index: intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
===================================================================
--- intern/audaspace/OpenAL/AUD_OpenALDevice.cpp (revisão 46420)
+++ intern/audaspace/OpenAL/AUD_OpenALDevice.cpp (cópia de trabalho)
@@ -41,6 +41,10 @@
#include <unistd.h>
#endif
+#include <algorithm>
+#include <utility>
+#include <boost/bind.hpp>
+
/*struct AUD_OpenALBufferedFactory
{
/// The factory.
@@ -52,7 +56,6 @@
//typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
-
/******************************************************************************/
/*********************** AUD_OpenALHandle Handle Code *************************/
/******************************************************************************/
@@ -169,6 +172,25 @@
return false;
}
+template<typename InputIterator>
+InputIterator AUD_OpenALDevice::AUD_OpenALHandle::findSound(InputIterator first, InputIterator end)
+{
+ using boost::bind;
+
+ typedef AUD_Reference<AUD_OpenALHandle> reference_type;
+
+ /*
+ * As the handle's are stored wrapped by an AUD_Reference object and we have
+ * only the raw pointer, we have to manually do a linear search in the container
+ * comparing the pointers.
+ */
+ return std::find_if(first,
+ end,
+ // element.get() == this
+ bind(std::equal_to<AUD_OpenALHandle*>(),
+ bind(&reference_type::get, _1), this));
+}
+
bool AUD_OpenALDevice::AUD_OpenALHandle::stop()
{
if(!m_status)
@@ -178,12 +200,22 @@
// AUD_XXX Create a reference of our own object so that it doesn't get
// deleted before the end of this function
- AUD_Reference<AUD_OpenALHandle> This = this;
+ AUD_Reference<AUD_OpenALHandle> This;
if(m_status == AUD_STATUS_PLAYING)
- m_device->m_playingSounds.remove(This);
+ {
+ AUD_HandleIterator it = findSound(m_device->m_playingSounds.begin(),
+ m_device->m_playingSounds.end());
+ This = *it;
+ m_device->m_playingSounds.erase(it);
+ }
else
- m_device->m_pausedSounds.remove(This);
+ {
+ AUD_HandleIterator it = findSound(m_device->m_pausedSounds.begin(),
+ m_device->m_pausedSounds.end());
+ This = *it;
+ m_device->m_pausedSounds.erase(it);
+ }
m_device->unlock();
Index: intern/audaspace/OpenAL/AUD_OpenALDevice.h
===================================================================
--- intern/audaspace/OpenAL/AUD_OpenALDevice.h (revisão 46420)
+++ intern/audaspace/OpenAL/AUD_OpenALDevice.h (cópia de trabalho)
@@ -148,6 +148,12 @@
virtual bool setConeAngleInner(float angle);
virtual float getConeVolumeOuter();
virtual bool setConeVolumeOuter(float volume);
+
+ private:
+
+ // only used in the implementation module, no need to be defined in the header file
+ template<typename InputIterator>
+ InputIterator findSound(InputIterator first, InputIterator end);
};
typedef std::list<AUD_Reference<AUD_OpenALHandle> >::iterator AUD_HandleIterator;
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
22/80/955932257dc1d5104a24324073b6
Event Timeline
Log In to Comment