diff --git a/project/src/graphics/cairo/CairoBindings.cpp b/project/src/graphics/cairo/CairoBindings.cpp index cbc43e5c2..65e6445f2 100644 --- a/project/src/graphics/cairo/CairoBindings.cpp +++ b/project/src/graphics/cairo/CairoBindings.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -17,6 +18,7 @@ namespace lime { static bool init = false; cairo_user_data_key_t userData; std::map 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; } diff --git a/project/src/media/openal/OpenALBindings.cpp b/project/src/media/openal/OpenALBindings.cpp index 08e19dfe3..4df485705 100644 --- a/project/src/media/openal/OpenALBindings.cpp +++ b/project/src/media/openal/OpenALBindings.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -21,6 +22,7 @@ namespace lime { std::map alObjects; std::map 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; } diff --git a/project/src/net/curl/CURLBindings.cpp b/project/src/net/curl/CURLBindings.cpp index 0093fa079..98446bdae 100644 --- a/project/src/net/curl/CURLBindings.cpp +++ b/project/src/net/curl/CURLBindings.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -17,12 +18,15 @@ namespace lime { std::map writeBytes; std::map writeBytesRoot; std::map 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; }