Commits

Alex Szpakowski committed d74a6db

Reference counting for love objects is now atomic.

Comments (0)

Files changed (3)

src/common/Object.cpp

 // LOVE
 #include "Object.h"
 
-#include <stdio.h>
-
 namespace love
 {
 
 {
 }
 
+Object::Object(const Object & /*other*/)
+	// New objects should always have a reference count of 1.
+	: count(1)
+{
+}
+
 Object::~Object()
 {
 }
 
 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

src/common/Object.h

 #ifndef LOVE_OBJECT_H
 #define LOVE_OBJECT_H
 
+#include <atomic>
+
 namespace love
 {
 
 	 * Constructor. Sets reference count to one.
 	 **/
 	Object();
+	Object(const Object &other);
 
 	/**
 	 * Destructor.
 private:
 
 	// The reference count.
-	int count;
+	std::atomic<int> count;
 
 }; // Object
 

src/common/runtime.cpp

 #include "Object.h"
 #include "Reference.h"
 #include "StringMap.h"
-#include <thread/threads.h>
 
 // C++
 #include <algorithm>
 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;