mirror of
https://github.com/love2d/love.git
synced 2026-08-20 20:49:54 +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
|
// 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
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user