Improve support for multiple threads in AL, Cairo and cURL GC
This commit is contained in:
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user