diff --git a/ext/fox16_c/gvl_wrappers.cpp b/ext/fox16_c/gvl_wrappers.cpp index ed27611754679087a41927249fc0d0181127a4a0..5cea2fb27adefbe6aba136d6e7312090ed209aa6 100644 --- a/ext/fox16_c/gvl_wrappers.cpp +++ b/ext/fox16_c/gvl_wrappers.cpp @@ -10,3 +10,7 @@ __thread int g_fxrb_thread_has_gvl = 1; FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT ); FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON ); FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB ); +FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT ); +FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_SKELETON ); +FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_SKELETON2 ); +FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB ); diff --git a/ext/fox16_c/include/FXRbDrawable.h b/ext/fox16_c/include/FXRbDrawable.h index 74c864036807ae3085770030b9ff37c493e164e8..f4891ae49185f6efd64b9ff9338feac43c35e5e6 100644 --- a/ext/fox16_c/include/FXRbDrawable.h +++ b/ext/fox16_c/include/FXRbDrawable.h @@ -35,7 +35,7 @@ inline void klass ## _resize(klass* self,FXint w,FXint h){ \ #define IMPLEMENT_FXDRAWABLE_STUBS(cls) \ void cls::resize(FXint w,FXint h){ \ - FXRbCallVoidMethod(this,rb_intern("resize"),w,h); \ + FXDrawable_resize_gvlcb1(this, w, h); \ } diff --git a/ext/fox16_c/include/gvl_wrappers.h b/ext/fox16_c/include/gvl_wrappers.h index b814b8b40506143b0fdb33504fa675a088ef79b4..df7dc149b010f393f6b99d961d3feb2cbe374879 100644 --- a/ext/fox16_c/include/gvl_wrappers.h +++ b/ext/fox16_c/include/gvl_wrappers.h @@ -15,14 +15,16 @@ #ifndef __gvl_wrappers_h #define __gvl_wrappers_h -#if defined(HAVE_RB_THREAD_CALL_WITH_GVL) -extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1); -#endif +extern "C" { + #if defined(HAVE_RB_THREAD_CALL_WITH_GVL) + extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1); + #endif -#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) -extern "C" void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1, - rb_unblock_function_t *ubf, void *data2); -#endif + #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) + extern "C" void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1, + rb_unblock_function_t *ubf, void *data2); + #endif +} #define DEFINE_PARAM_LIST1(type, name) \ , name @@ -76,6 +78,45 @@ extern __thread int g_fxrb_thread_has_gvl; #define DEFINE_GVL_STUB_DECL(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ rettype klass##_##name( firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)); +#define DEFINE_GVLCB_STUB_DECL1(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ + rettype klass##_##name##_gvlcb1( firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)); + +#define DEFINE_GVLCB_STUB_DECL2(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ + rettype klass##_##name##_gvlcb2( firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)); + +#define DEFINE_GVLCB_SKELETON2(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ + void klass##_##name##_gvlcb2( firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)){ \ + FXRbCallVoidMethod(firstparamname,rb_intern(#name) FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1)); \ + } + +#define DEFINE_GVLCB_SKELETON(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ + static void * gvl_##klass##_##name##_skeleton( void *data ){ \ + struct gvl_wrapper_##klass##_##name##_params *p = (struct gvl_wrapper_##klass##_##name##_params*)data; \ + when_non_void( p->retval = ) \ + klass##_##name##_gvlcb2( p->params.firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST2) ); \ + return NULL; \ + } + +#if defined(HAVE_RB_THREAD_CALL_WITH_GVL) + #define DEFINE_GVLCB_STUB(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ + rettype klass##_##name##_gvlcb1(firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)){ \ + if( g_fxrb_thread_has_gvl ){ \ + return klass##_##name##_gvlcb2( firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1) ); \ + } else { \ + struct gvl_wrapper_##klass##_##name##_params params = { \ + {firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1)}, when_non_void((rettype)0) \ + }; \ + rb_thread_call_with_gvl(gvl_##klass##_##name##_skeleton, ¶ms); \ + when_non_void( return params.retval; ) \ + } \ + } +#else + #define DEFINE_GVLCB_STUB(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ + rettype klass##_##name##_gvlcb1(firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)){ \ + return klass##_##name##_gvlcb2( firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1) ); \ + } +#endif + #define GVL_TYPE_VOID(string) #define GVL_TYPE_NONVOID(string) string @@ -147,4 +188,19 @@ extern __thread int g_fxrb_thread_has_gvl; FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL ) +/* + * Definitions of callback functions and their parameters + */ + +#define FOR_EACH_PARAM_OF_FXDrawable_resize(param) \ + param(FXint, w) \ + param(FXint, h) + +/* function( class, name, baseclass, void_or_nonvoid, returntype, firstparamtype, firstparamname ) */ +#define FOR_EACH_CALLBACK_FUNCTION(function) \ + function(FXDrawable, resize, FXDrawable, GVL_TYPE_VOID, void, FXDrawable*, self) + +FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB_DECL1 ); +FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB_DECL2 ); + #endif /* end __gvl_wrappers_h */