It looks like a dirty hack, it probably is, but this fixes the GC

This commit is contained in:
bart@bartbes.ath.cx
2010-05-20 21:53:50 +02:00
parent a349c9f85a
commit 200d4bc653
3 changed files with 30 additions and 7 deletions
+12 -3
View File
@@ -31,10 +31,13 @@
// SDL // SDL
#include <SDL_mutex.h> #include <SDL_mutex.h>
#include <SDL_thread.h>
namespace love namespace love
{ {
static SDL_mutex *gcmutex = 0; static SDL_mutex *gcmutex = 0;
void *_gcmutex = 0;
unsigned int _gcthread = 0;
/** /**
* 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.
@@ -42,13 +45,19 @@ namespace love
static int w__gc(lua_State * L) static int w__gc(lua_State * L)
{ {
if (!gcmutex) if (!gcmutex)
{
gcmutex = SDL_CreateMutex(); gcmutex = SDL_CreateMutex();
_gcmutex = (void*) gcmutex;
}
Proxy * p = (Proxy *)lua_touserdata(L, 1); Proxy * p = (Proxy *)lua_touserdata(L, 1);
Object * t = (Object *)p->data; Object * t = (Object *)p->data;
SDL_mutexP(gcmutex);
if(p->own) if(p->own)
{
SDL_mutexP(gcmutex);
_gcthread = (unsigned int) SDL_ThreadID();
t->release(); t->release();
SDL_mutexV(gcmutex); SDL_mutexV(gcmutex);
}
return 0; return 0;
} }
@@ -274,7 +283,7 @@ namespace love
lua_replace(L, idx); // Replace the initial argument with the new object. lua_replace(L, idx); // Replace the initial argument with the new object.
return 0; return 0;
} }
int luax_convobj(lua_State * L, int idxs[], int n, const char * mod, const char * fn) int luax_convobj(lua_State * L, int idxs[], int n, const char * mod, const char * fn)
{ {
luax_getfunction(L, mod, fn); luax_getfunction(L, mod, fn);
+8 -4
View File
@@ -37,6 +37,10 @@ namespace love
class Module; class Module;
class Reference; class Reference;
// Exposed mutex of the GC
extern void *_gcmutex;
extern unsigned int _gcthread;
/** /**
* Registries represent special tables which can be accessed with * Registries represent special tables which can be accessed with
* luax_getregistry. * luax_getregistry.
@@ -219,14 +223,14 @@ namespace love
* @param function The function in the module. * @param function The function in the module.
**/ **/
int luax_convobj(lua_State * L, int idx, const char * module, const char * function); int luax_convobj(lua_State * L, int idx, const char * module, const char * function);
/** /**
* Converts an object into another object by the specified function love.module.function. * Converts an object into another object by the specified function love.module.function.
* The conversion function must accept a single object of the relevant type as its first parameter, * The conversion function must accept a single object of the relevant type as its first parameter,
* and return one value. If the function does not exist (see luax_getfunction), an error is returned. * and return one value. If the function does not exist (see luax_getfunction), an error is returned.
* *
* Note that the initial object at idx is replaced by the new object. * Note that the initial object at idx is replaced by the new object.
* *
* @param L The Lua state. * @param L The Lua state.
* @param idxs An array of indices on the stack. * @param idxs An array of indices on the stack.
* @param n How many arguments are being passed. * @param n How many arguments are being passed.
+10
View File
@@ -194,7 +194,15 @@ namespace sdl
delete[] data; delete[] data;
delete comm; delete comm;
if (handle) if (handle)
{
bool inGC = (_gcthread == SDL_GetThreadID(handle));
bool collectSelf = (inGC && _gcthread == SDL_ThreadID());
inGC = inGC && !collectSelf;
if (inGC) SDL_mutexP((SDL_mutex *) _gcmutex);
if (collectSelf) SDL_mutexV((SDL_mutex *) _gcmutex);
SDL_KillThread(handle); SDL_KillThread(handle);
if (inGC) SDL_mutexV((SDL_mutex *) _gcmutex);
}
module->unregister(name); module->unregister(name);
SDL_DestroyMutex(mutex); SDL_DestroyMutex(mutex);
SDL_DestroyCond(cond); SDL_DestroyCond(cond);
@@ -211,8 +219,10 @@ namespace sdl
{ {
if (handle) if (handle)
{ {
SDL_mutexP((SDL_mutex *) _gcmutex);
SDL_KillThread(handle); SDL_KillThread(handle);
handle = 0; handle = 0;
SDL_mutexV((SDL_mutex *) _gcmutex);
} }
} }