From 6434c3b970e987b8a2f311d67b359506eaeed4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Thu, 1 May 2014 16:37:28 +0200 Subject: Make sure the window is never released before the renderer Tentative fix for an OSX VM crash when the owner process dies. --- c_src/nif_helpers.h | 6 +++++- c_src/sdl_renderer.c | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/c_src/nif_helpers.h b/c_src/nif_helpers.h index ab61998..c1d4131 100644 --- a/c_src/nif_helpers.h +++ b/c_src/nif_helpers.h @@ -53,15 +53,19 @@ void dtor_ ## r(ErlNifEnv*, void*); \ typedef struct { \ NIF_RES_TYPE(r)* v; \ + void* dep; \ } obj_ ## r; #define NIF_RES_INIT(r) \ res_ ## r = enif_open_resource_type(env, NULL, TO_STRING(NIF_RES_TYPE(r)), dtor_ ## r, ERL_NIF_RT_CREATE, NULL); \ if (!res_ ## r) return -1; #define NIF_RES_GET(r, obj) (((obj_ ## r*)obj)->v) -#define NIF_RES_TO_TERM(r, val, term) { \ +#define NIF_RES_DEP(r, obj) (((obj_ ## r*)obj)->dep) +#define NIF_RES_TO_TERM(r, val, term) NIF_RES_TO_TERM_WITH_DEP(r, val, term, NULL) +#define NIF_RES_TO_TERM_WITH_DEP(r, val, term, dep_res) { \ obj_ ## r* res = enif_alloc_resource(res_ ## r, sizeof(obj_ ## r)); \ res->v = val; \ + res->dep = dep_res; \ term = enif_make_resource(env, res); \ enif_release_resource(res); \ } diff --git a/c_src/sdl_renderer.c b/c_src/sdl_renderer.c index 9aa5f95..99a947d 100644 --- a/c_src/sdl_renderer.c +++ b/c_src/sdl_renderer.c @@ -17,6 +17,7 @@ void dtor_Renderer(ErlNifEnv* env, void* obj) { SDL_DestroyRenderer(NIF_RES_GET(Renderer, obj)); + enif_release_resource(NIF_RES_DEP(Renderer, obj)); } #define RENDERER_FLAGS(F) \ @@ -92,11 +93,12 @@ NIF_CALL_HANDLER(thread_create_renderer) SDL_Renderer* renderer; ERL_NIF_TERM term; - renderer = SDL_CreateRenderer(args[0], (long)args[1], (long)args[2]); + renderer = SDL_CreateRenderer(NIF_RES_GET(Window, args[0]), (long)args[1], (long)args[2]); if (!renderer) return sdl_error_tuple(env); - NIF_RES_TO_TERM(Renderer, renderer, term); + enif_keep_resource(args[0]); + NIF_RES_TO_TERM_WITH_DEP(Renderer, renderer, term, args[0]); return enif_make_tuple2(env, atom_ok, @@ -115,7 +117,7 @@ NIF_FUNCTION(create_renderer) BADARG_IF(!list_to_renderer_flags(env, argv[2], &flags)); return nif_thread_call(env, thread_create_renderer, 3, - NIF_RES_GET(Window, window_res), index, flags); + window_res, index, flags); } // get_num_render_drivers -- cgit v1.2.3