aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2014-05-01 16:37:28 +0200
committerLoïc Hoguin <[email protected]>2014-05-01 16:37:28 +0200
commit6434c3b970e987b8a2f311d67b359506eaeed4eb (patch)
treeaf7ea05b87d98f1363846142f79924ee6aee3266
parentc087ef30ab6b40e331863f90b1f067f1c3a7a5d2 (diff)
downloadesdl2-6434c3b970e987b8a2f311d67b359506eaeed4eb.tar.gz
esdl2-6434c3b970e987b8a2f311d67b359506eaeed4eb.tar.bz2
esdl2-6434c3b970e987b8a2f311d67b359506eaeed4eb.zip
Make sure the window is never released before the renderer
Tentative fix for an OSX VM crash when the owner process dies.
-rw-r--r--c_src/nif_helpers.h6
-rw-r--r--c_src/sdl_renderer.c8
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