mirror of
https://github.com/love2d/love.git
synced 2026-08-16 16:20:42 +02:00
Reference counting for love objects is now atomic.
--HG-- branch : minor
This commit is contained in:
+12
-4
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user