Reference counting for love objects is now atomic.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2014-08-13 02:43:50 -03:00
parent df5e48a082
commit 0c1b73e2ca
3 changed files with 16 additions and 13 deletions
+12 -4
View File
@@ -21,8 +21,6 @@
// LOVE // LOVE
#include "Object.h" #include "Object.h"
#include <stdio.h>
namespace love namespace love
{ {
@@ -31,6 +29,12 @@ Object::Object()
{ {
} }
Object::Object(const Object & /*other*/)
// New objects should always have a reference count of 1.
: count(1)
{
}
Object::~Object() Object::~Object()
{ {
} }
@@ -42,13 +46,17 @@ int Object::getReferenceCount() const
void Object::retain() void Object::retain()
{ {
++count; std::atomic_fetch_add_explicit(&count, 1, std::memory_order_relaxed);
} }
void Object::release() void Object::release()
{ {
if (--count <= 0) // http://www.boost.org/doc/libs/1_56_0/doc/html/atomic/usage_examples.html
if (std::atomic_fetch_sub_explicit(&count, 1, std::memory_order_release) == 1)
{
std::atomic_thread_fence(std::memory_order_acquire);
delete this; delete this;
}
} }
} // love } // love
+4 -1
View File
@@ -21,6 +21,8 @@
#ifndef LOVE_OBJECT_H #ifndef LOVE_OBJECT_H
#define LOVE_OBJECT_H #define LOVE_OBJECT_H
#include <atomic>
namespace love namespace love
{ {
@@ -40,6 +42,7 @@ public:
* Constructor. Sets reference count to one. * Constructor. Sets reference count to one.
**/ **/
Object(); Object();
Object(const Object &other);
/** /**
* Destructor. * Destructor.
@@ -155,7 +158,7 @@ public:
private: private:
// The reference count. // The reference count.
int count; std::atomic<int> count;
}; // Object }; // Object
-8
View File
@@ -26,7 +26,6 @@
#include "Object.h" #include "Object.h"
#include "Reference.h" #include "Reference.h"
#include "StringMap.h" #include "StringMap.h"
#include <thread/threads.h>
// C++ // C++
#include <algorithm> #include <algorithm>
@@ -36,22 +35,15 @@
namespace love namespace love
{ {
static thread::Mutex *gcmutex = nullptr;
/** /**
* Called when an object is collected. The object is released * Called when an object is collected. The object is released
* once in this function, possibly deleting it. * once in this function, possibly deleting it.
**/ **/
static int w__gc(lua_State *L) static int w__gc(lua_State *L)
{ {
if (!gcmutex)
gcmutex = thread::newMutex();
Proxy *p = (Proxy *) lua_touserdata(L, 1); Proxy *p = (Proxy *) lua_touserdata(L, 1);
Object *object = (Object *) p->data; Object *object = (Object *) p->data;
thread::Lock lock(gcmutex);
object->release(); object->release();
return 0; return 0;