Improve support for multiple threads in AL, Cairo and cURL GC

This commit is contained in:
Joshua Granick
2018-04-02 12:19:48 -07:00
parent ca843d9429
commit 8edcc8ff82
3 changed files with 100 additions and 4 deletions

View File

@@ -5,6 +5,7 @@
#include <math/Vector2.h>
#include <hx/CFFIPrime.h>
#include <system/CFFIPointer.h>
#include <system/Mutex.h>
#include <text/Font.h>
@@ -17,6 +18,7 @@ namespace lime {
static bool init = false;
cairo_user_data_key_t userData;
std::map<void*, value> cairoObjects;
Mutex cairoObjects_Mutex;
void gc_cairo (value handle) {
@@ -24,7 +26,9 @@ namespace lime {
if (!val_is_null (handle)) {
cairo_t* cairo = (cairo_t*)val_data (handle);
cairoObjects_Mutex.Lock ();
cairoObjects.erase (cairo);
cairoObjects_Mutex.Unlock ();
cairo_destroy (cairo);
}
@@ -37,7 +41,9 @@ namespace lime {
if (!val_is_null (handle)) {
cairo_font_face_t* face = (cairo_font_face_t*)val_data (handle);
cairoObjects_Mutex.Lock ();
cairoObjects.erase (face);
cairoObjects_Mutex.Unlock ();
cairo_font_face_destroy (face);
}
@@ -62,7 +68,9 @@ namespace lime {
if (!val_is_null (handle)) {
cairo_pattern_t* pattern = (cairo_pattern_t*)val_data (handle);
cairoObjects_Mutex.Lock ();
cairoObjects.erase (pattern);
cairoObjects_Mutex.Unlock ();
cairo_pattern_destroy (pattern);
}
@@ -75,7 +83,9 @@ namespace lime {
if (!val_is_null (handle)) {
cairo_surface_t* surface = (cairo_surface_t*)val_data (handle);
cairoObjects_Mutex.Lock ();
cairoObjects.erase (surface);
cairoObjects_Mutex.Unlock ();
cairo_surface_destroy (surface);
}
@@ -145,7 +155,9 @@ namespace lime {
cairo_t* cairo = cairo_create ((cairo_surface_t*)val_data (surface));
value object = CFFIPointer (cairo, gc_cairo);
cairoObjects_Mutex.Lock ();
cairoObjects[cairo] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -260,7 +272,9 @@ namespace lime {
cairo_font_face_set_user_data (cairoFont, &userData, fontReference, gc_user_data);
value object = CFFIPointer (cairoFont, gc_cairo_font_face);
cairoObjects_Mutex.Lock ();
cairoObjects[cairoFont] = object;
cairoObjects_Mutex.Unlock ();
return object;
#else
return 0;
@@ -336,7 +350,9 @@ namespace lime {
cairo_font_face_reference (face);
value object = CFFIPointer (face, gc_cairo_font_face);
cairoObjects_Mutex.Lock ();
cairoObjects[face] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -366,7 +382,9 @@ namespace lime {
cairo_surface_reference (surface);
value object = CFFIPointer (surface, gc_cairo_surface);
cairoObjects_Mutex.Lock ();
cairoObjects[surface] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -432,7 +450,9 @@ namespace lime {
cairo_pattern_reference (pattern);
value object = CFFIPointer (pattern, gc_cairo_pattern);
cairoObjects_Mutex.Lock ();
cairoObjects[pattern] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -453,7 +473,9 @@ namespace lime {
cairo_surface_reference (surface);
value object = CFFIPointer (surface, gc_cairo_surface);
cairoObjects_Mutex.Lock ();
cairoObjects[surface] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -487,7 +509,9 @@ namespace lime {
cairo_surface_t* surface = cairo_image_surface_create ((cairo_format_t)format, width, height);
value object = CFFIPointer (surface, gc_cairo_surface);
cairoObjects_Mutex.Lock ();
cairoObjects[surface] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -498,7 +522,9 @@ namespace lime {
cairo_surface_t* surface = cairo_image_surface_create_for_data ((unsigned char*)(uintptr_t)data, (cairo_format_t)format, width, height, stride);
value object = CFFIPointer (surface, gc_cairo_surface);
cairoObjects_Mutex.Lock ();
cairoObjects[surface] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -628,7 +654,9 @@ namespace lime {
cairo_pattern_t* pattern = cairo_pattern_create_for_surface ((cairo_surface_t*)val_data (surface));
value object = CFFIPointer (pattern, gc_cairo_pattern);
cairoObjects_Mutex.Lock ();
cairoObjects[pattern] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -639,7 +667,9 @@ namespace lime {
cairo_pattern_t* pattern = cairo_pattern_create_linear (x0, y0, x1, y1);
value object = CFFIPointer (pattern, gc_cairo_pattern);
cairoObjects_Mutex.Lock ();
cairoObjects[pattern] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -650,7 +680,9 @@ namespace lime {
cairo_pattern_t* pattern = cairo_pattern_create_radial (cx0, cy0, radius0, cx1, cy1, radius1);
value object = CFFIPointer (pattern, gc_cairo_pattern);
cairoObjects_Mutex.Lock ();
cairoObjects[pattern] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -661,7 +693,9 @@ namespace lime {
cairo_pattern_t* pattern = cairo_pattern_create_rgb (r, g, b);
value object = CFFIPointer (pattern, gc_cairo_pattern);
cairoObjects_Mutex.Lock ();
cairoObjects[pattern] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -672,7 +706,9 @@ namespace lime {
cairo_pattern_t* pattern = cairo_pattern_create_rgba (r, g, b, a);
value object = CFFIPointer (pattern, gc_cairo_pattern);
cairoObjects_Mutex.Lock ();
cairoObjects[pattern] = object;
cairoObjects_Mutex.Unlock ();
return object;
}
@@ -750,7 +786,9 @@ namespace lime {
cairo_pattern_reference (pattern);
value object = CFFIPointer (pattern, gc_cairo_pattern);
cairoObjects_Mutex.Lock ();
cairoObjects[pattern] = object;
cairoObjects_Mutex.Unlock ();
return object;
}

View File

@@ -12,6 +12,7 @@
#include <hx/CFFIPrime.h>
#include <system/CFFIPointer.h>
#include <system/Mutex.h>
#include <utils/ArrayBufferView.h>
#include <map>
@@ -21,6 +22,7 @@ namespace lime {
std::map<ALuint, value> alObjects;
std::map<void*, value> alcObjects;
Mutex al_gc_mutex;
#ifdef LIME_OPENALSOFT
@@ -75,7 +77,9 @@ namespace lime {
void gc_alc_object (value object) {
al_gc_mutex.Lock ();
alcObjects.erase (val_data (object));
al_gc_mutex.Unlock ();
}
@@ -276,10 +280,12 @@ namespace lime {
#ifdef LIME_OPENALSOFT
if (!val_is_null (aux)) {
al_gc_mutex.Lock ();
ALuint data = (ALuint)(uintptr_t)val_data (aux);
val_gc (aux, 0);
alDeleteAuxiliaryEffectSlots ((ALuint)1, &data);
alObjects.erase (data);
al_gc_mutex.Unlock ();
}
#endif
@@ -291,10 +297,12 @@ namespace lime {
if (!val_is_null (buffer)) {
al_gc_mutex.Lock ();
ALuint data = (ALuint)(uintptr_t)val_data (buffer);
val_gc (buffer, 0);
alDeleteBuffers ((ALuint)1, &data);
alObjects.erase (data);
al_gc_mutex.Unlock ();
}
@@ -309,6 +317,7 @@ namespace lime {
ALuint* data = new ALuint[size];
value buffer;
al_gc_mutex.Lock ();
for (int i = 0; i < size; ++i) {
buffer = val_array_i (buffers, i);
@@ -317,6 +326,7 @@ namespace lime {
alObjects.erase (data[i]);
}
al_gc_mutex.Unlock ();
alDeleteBuffers (n, data);
delete[] data;
@@ -537,10 +547,12 @@ namespace lime {
value lime_al_gen_buffer () {
al_gc_mutex.Lock ();
ALuint buffer;
alGenBuffers ((ALuint)1, &buffer);
value ptr = CFFIPointer ((void*)(uintptr_t)buffer, gc_al_buffer);
alObjects[buffer] = ptr;
al_gc_mutex.Unlock ();
return ptr;
}
@@ -556,6 +568,7 @@ namespace lime {
ALuint buffer;
value ptr;
al_gc_mutex.Lock ();
for (int i = 0; i < n; i++) {
buffer = buffers[i];
@@ -565,6 +578,7 @@ namespace lime {
val_array_set_i (result, i, ptr);
}
al_gc_mutex.Unlock ();
delete[] buffers;
return result;
@@ -1019,8 +1033,10 @@ namespace lime {
} else {
al_gc_mutex.Lock ();
value ptr = CFFIPointer ((void*)(uintptr_t)data, gc_al_buffer);
alObjects[data] = ptr;
al_gc_mutex.Unlock ();
return ptr;
}
@@ -1381,8 +1397,10 @@ namespace lime {
} else {
al_gc_mutex.Lock ();
ptr = CFFIPointer ((void*)(uintptr_t)buffer, gc_al_buffer);
alObjects[buffer] = ptr;
al_gc_mutex.Unlock ();
}
@@ -1523,8 +1541,11 @@ namespace lime {
bool lime_alc_close_device (value device) {
al_gc_mutex.Lock ();
ALCdevice* alcDevice = (ALCdevice*)val_data (device);
alcObjects.erase (alcDevice);
al_gc_mutex.Unlock ();
return alcCloseDevice (alcDevice);
}
@@ -1556,8 +1577,10 @@ namespace lime {
}
al_gc_mutex.Lock ();
value object = CFFIPointer (alcContext, gc_alc_object);
alcObjects[alcContext] = object;
al_gc_mutex.Unlock ();
return object;
}
@@ -1565,9 +1588,11 @@ namespace lime {
void lime_alc_destroy_context (value context) {
al_gc_mutex.Lock ();
ALCcontext* alcContext = (ALCcontext*)val_data (context);
alcObjects.erase (alcContext);
alcDestroyContext (alcContext);
al_gc_mutex.Unlock ();
}
@@ -1577,17 +1602,21 @@ namespace lime {
ALCcontext* alcContext = (ALCcontext*)val_data (context);
ALCdevice* alcDevice = alcGetContextsDevice (alcContext);
value result;
al_gc_mutex.Lock ();
if (alcObjects.find (alcDevice) != alcObjects.end ()) {
return alcObjects[alcDevice];
result = alcObjects[alcDevice];
} else {
value object = CFFIPointer (alcDevice, gc_alc_object);
alcObjects[alcDevice] = object;
return object;
result = object;
}
al_gc_mutex.Unlock ();
return result;
}
@@ -1596,17 +1625,21 @@ namespace lime {
ALCcontext* alcContext = alcGetCurrentContext ();
value result;
al_gc_mutex.Lock ();
if (alcObjects.find (alcContext) != alcObjects.end ()) {
return alcObjects[alcContext];
result = alcObjects[alcContext];
} else {
value object = CFFIPointer (alcContext, gc_alc_object);
alcObjects[alcContext] = object;
return object;
result = object;
}
al_gc_mutex.Unlock ();
return result;
}

View File

@@ -1,6 +1,7 @@
#include <curl/curl.h>
#include <hx/CFFIPrime.h>
#include <system/CFFIPointer.h>
#include <system/Mutex.h>
#include <utils/Bytes.h>
#include <string.h>
#include <map>
@@ -17,12 +18,15 @@ namespace lime {
std::map<AutoGCRoot*, Bytes*> writeBytes;
std::map<AutoGCRoot*, AutoGCRoot*> writeBytesRoot;
std::map<value, AutoGCRoot*> writeCallbacks;
Mutex curl_gc_mutex;
void gc_curl (value handle) {
if (!val_is_null (handle)) {
curl_gc_mutex.Lock ();
if (curlValid.find (handle) != curlValid.end ()) {
curlValid.erase (handle);
@@ -101,6 +105,8 @@ namespace lime {
val_gc (handle, 0);
//handle = alloc_null ();
curl_gc_mutex.Unlock ();
}
}
@@ -127,6 +133,8 @@ namespace lime {
value lime_curl_easy_duphandle (value handle) {
curl_gc_mutex.Lock ();
value duphandle = CFFIPointer (curl_easy_duphandle ((CURL*)val_data(handle)), gc_curl);
curlValid[duphandle] = true;
@@ -157,6 +165,8 @@ namespace lime {
writeCallbacks[duphandle] = new AutoGCRoot (writeCallbacks[handle]->get());
}
curl_gc_mutex.Unlock ();
return duphandle;
}
@@ -273,6 +283,8 @@ namespace lime {
value lime_curl_easy_init () {
curl_gc_mutex.Lock ();
value handle = CFFIPointer (curl_easy_init (), gc_curl);
if (curlValid.find (handle) != curlValid.end ()) {
@@ -306,6 +318,9 @@ namespace lime {
}
curlValid[handle] = true;
curl_gc_mutex.Unlock ();
return handle;
}
@@ -701,14 +716,17 @@ namespace lime {
case CURLOPT_READFUNCTION:
{
curl_gc_mutex.Lock ();
AutoGCRoot* callback = new AutoGCRoot (parameter);
readCallbacks[handle] = callback;
code = curl_easy_setopt (curl, type, read_callback);
curl_easy_setopt (curl, CURLOPT_READDATA, callback);
curl_gc_mutex.Unlock ();
break;
}
case CURLOPT_WRITEFUNCTION:
{
curl_gc_mutex.Lock ();
AutoGCRoot* callback = new AutoGCRoot (parameter);
writeCallbacks[handle] = callback;
Bytes* _writeBytes = new Bytes (bytes);
@@ -716,10 +734,12 @@ namespace lime {
writeBytesRoot[callback] = new AutoGCRoot (bytes);
code = curl_easy_setopt (curl, type, write_callback);
curl_easy_setopt (curl, CURLOPT_WRITEDATA, callback);
curl_gc_mutex.Unlock ();
break;
}
case CURLOPT_HEADERFUNCTION:
{
curl_gc_mutex.Lock ();
AutoGCRoot* callback = new AutoGCRoot (parameter);
headerCallbacks[handle] = callback;
Bytes* _writeBytes = new Bytes (bytes);
@@ -727,20 +747,24 @@ namespace lime {
writeBytesRoot[callback] = new AutoGCRoot (bytes);
code = curl_easy_setopt (curl, type, write_callback);
curl_easy_setopt (curl, CURLOPT_HEADERDATA, callback);
curl_gc_mutex.Unlock ();
break;
}
case CURLOPT_PROGRESSFUNCTION:
{
curl_gc_mutex.Lock ();
AutoGCRoot* callback = new AutoGCRoot (parameter);
progressCallbacks[handle] = callback;
code = curl_easy_setopt (curl, type, progress_callback);
curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, callback);
curl_easy_setopt (curl, CURLOPT_NOPROGRESS, false);
curl_gc_mutex.Unlock ();
break;
}
case CURLOPT_HTTPHEADER:
{
curl_gc_mutex.Lock ();
if (headerSLists.find (handle) != headerSLists.end ()) {
curl_slist_free_all (headerSLists[handle]);
@@ -759,6 +783,7 @@ namespace lime {
headerSLists[handle] = chunk;
code = curl_easy_setopt (curl, type, chunk);
curl_gc_mutex.Unlock ();
break;
}