Browse Source

Reference counting for love objects is now atomic.

--HG--
branch : minor
Alex Szpakowski 11 years ago
parent
commit
0c1b73e2ca
3 changed files with 16 additions and 13 deletions
  1. 12 4
      src/common/Object.cpp
  2. 4 1
      src/common/Object.h
  3. 0 8
      src/common/runtime.cpp

+ 12 - 4
src/common/Object.cpp

@@ -21,8 +21,6 @@
 // LOVE
 #include "Object.h"
 
-#include <stdio.h>
-
 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()
 {
 }
@@ -42,13 +46,17 @@ int Object::getReferenceCount() const
 
 void Object::retain()
 {
-	++count;
+	std::atomic_fetch_add_explicit(&count, 1, std::memory_order_relaxed);
 }
 
 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;
+	}
 }
 
 } // love

+ 4 - 1
src/common/Object.h

@@ -21,6 +21,8 @@
 #ifndef LOVE_OBJECT_H
 #define LOVE_OBJECT_H
 
+#include <atomic>
+
 namespace love
 {
 
@@ -40,6 +42,7 @@ public:
 	 * Constructor. Sets reference count to one.
 	 **/
 	Object();
+	Object(const Object &other);
 
 	/**
 	 * Destructor.
@@ -155,7 +158,7 @@ public:
 private:
 
 	// The reference count.
-	int count;
+	std::atomic<int> count;
 
 }; // Object
 

+ 0 - 8
src/common/runtime.cpp

@@ -26,7 +26,6 @@
 #include "Object.h"
 #include "Reference.h"
 #include "StringMap.h"
-#include <thread/threads.h>
 
 // C++
 #include <algorithm>
@@ -36,22 +35,15 @@
 namespace love
 {
 
-static thread::Mutex *gcmutex = nullptr;
-
 /**
  * Called when an object is collected. The object is released
  * once in this function, possibly deleting it.
  **/
 static int w__gc(lua_State *L)
 {
-	if (!gcmutex)
-		gcmutex = thread::newMutex();
-
 	Proxy *p = (Proxy *) lua_touserdata(L, 1);
 	Object *object = (Object *) p->data;
 
-	thread::Lock lock(gcmutex);
-
 	object->release();
 
 	return 0;