diff --git a/ext/fox16_c/gvl_wrappers.cpp b/ext/fox16_c/gvl_wrappers.cpp index c55ee58b23943c52bc2a835a99618c9f9b5584f2..ed27611754679087a41927249fc0d0181127a4a0 100644 --- a/ext/fox16_c/gvl_wrappers.cpp +++ b/ext/fox16_c/gvl_wrappers.cpp @@ -5,6 +5,8 @@ #include "FXRbCommon.h" +__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 ); diff --git a/ext/fox16_c/include/gvl_wrappers.h b/ext/fox16_c/include/gvl_wrappers.h index b4bd2f69428cbfe51ae9d9891c6a60b990de5f29..44caf974063c62ec0227a1fd3bbc1130745597dd 100644 --- a/ext/fox16_c/include/gvl_wrappers.h +++ b/ext/fox16_c/include/gvl_wrappers.h @@ -17,164 +17,130 @@ #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); + rb_unblock_function_t *ubf, void *data2); #endif #define DEFINE_PARAM_LIST1(type, name) \ - name, + , name #define DEFINE_PARAM_LIST2(type, name) \ - p->params.name, + , p->params.name #define DEFINE_PARAM_LIST3(type, name) \ - type name, + , type name #define DEFINE_PARAM_DECL(type, name) \ - type name; - -#define DEFINE_GVL_WRAPPER_STRUCT(name, when_non_void, rettype, lastparamtype, lastparamname) \ - struct gvl_wrapper_##name##_params { \ - struct { \ - FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_DECL) \ - lastparamtype lastparamname; \ - } params; \ - when_non_void( rettype retval; ) \ - }; - -#define DEFINE_GVL_SKELETON(name, when_non_void, rettype, lastparamtype, lastparamname) \ - static void * gvl_##name##_skeleton( void *data ){ \ - struct gvl_wrapper_##name##_params *p = (struct gvl_wrapper_##name##_params*)data; \ - when_non_void( p->retval = ) \ - name##_gvl( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST2) p->params.lastparamname ); \ - return NULL; \ - } + type name; + +#define DEFINE_GVL_WRAPPER_STRUCT(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ + struct gvl_wrapper_##klass##_##name##_params { \ + struct { \ + firstparamtype firstparamname; \ + FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_DECL) \ + } params; \ + when_non_void( rettype retval; ) \ + }; + +extern __thread int g_fxrb_thread_has_gvl; + +#define DEFINE_GVL_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; \ + g_fxrb_thread_has_gvl = 0; \ + when_non_void( p->retval = ) \ + klass##_##name##_gvl( p->params.firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST2) ); \ + g_fxrb_thread_has_gvl = 1; \ + return NULL; \ + } #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) - #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \ - rettype name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \ - struct gvl_wrapper_##name##_params params = { \ - {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \ - }; \ - rb_thread_call_without_gvl(gvl_##name##_skeleton, ¶ms, RUBY_UBF_IO, 0); \ - when_non_void( return params.retval; ) \ - } + #define DEFINE_GVL_STUB(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ + rettype klass##_##name(firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)){ \ + 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_without_gvl(gvl_##klass##_##name##_skeleton, ¶ms, RUBY_UBF_IO, 0); \ + when_non_void( return params.retval; ) \ + } #else - #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \ - rettype name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \ - return name##_gvl( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \ - } + #define DEFINE_GVL_STUB(klass, name, baseclass, when_non_void, rettype, firstparamtype, firstparamname) \ + rettype klass##_##name(firstparamtype firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST3)){ \ + return klass##_##name##_gvl(firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1)); \ + } #endif -#define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \ - rettype name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname); - -#define DEFINE_GVL_TARGET_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \ - rettype name##_gvl(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname); +#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 GVL_TYPE_VOID(string) #define GVL_TYPE_NONVOID(string) string /* - * Definitions of blocking functions and their parameters - */ +* Definitions of blocking functions and their parameters +*/ #define FOR_EACH_PARAM_OF_FXImage_loadPixels(param) \ - param(FXImage *, self) + param(FXStream&, store) #define FOR_EACH_PARAM_OF_FXImage_savePixels(param) \ - param(const FXImage *, self) - -#define FOR_EACH_PARAM_OF_FXBMPImage_loadPixels(param) \ - param(FXBMPImage *, self) -#define FOR_EACH_PARAM_OF_FXBMPImage_savePixels(param) \ - param(const FXBMPImage *, self) - -#define FOR_EACH_PARAM_OF_FXJPGImage_loadPixels(param) \ - param(FXJPGImage *, self) -#define FOR_EACH_PARAM_OF_FXJPGImage_savePixels(param) \ - param(const FXJPGImage *, self) - -#define FOR_EACH_PARAM_OF_FXGIFImage_loadPixels(param) \ - param(FXGIFImage *, self) -#define FOR_EACH_PARAM_OF_FXGIFImage_savePixels(param) \ - param(const FXGIFImage *, self) - -#define FOR_EACH_PARAM_OF_FXICOImage_loadPixels(param) \ - param(FXICOImage *, self) -#define FOR_EACH_PARAM_OF_FXICOImage_savePixels(param) \ - param(const FXICOImage *, self) - -#define FOR_EACH_PARAM_OF_FXPNGImage_loadPixels(param) \ - param(FXPNGImage *, self) -#define FOR_EACH_PARAM_OF_FXPNGImage_savePixels(param) \ - param(const FXPNGImage *, self) - -#define FOR_EACH_PARAM_OF_FXPPMImage_loadPixels(param) \ - param(FXPPMImage *, self) -#define FOR_EACH_PARAM_OF_FXPPMImage_savePixels(param) \ - param(const FXPPMImage *, self) - -#define FOR_EACH_PARAM_OF_FXPCXImage_loadPixels(param) \ - param(FXPCXImage *, self) -#define FOR_EACH_PARAM_OF_FXPCXImage_savePixels(param) \ - param(const FXPCXImage *, self) - -#define FOR_EACH_PARAM_OF_FXRGBImage_loadPixels(param) \ - param(FXRGBImage *, self) -#define FOR_EACH_PARAM_OF_FXRGBImage_savePixels(param) \ - param(const FXRGBImage *, self) - -#define FOR_EACH_PARAM_OF_FXTGAImage_loadPixels(param) \ - param(FXTGAImage *, self) -#define FOR_EACH_PARAM_OF_FXTGAImage_savePixels(param) \ - param(const FXTGAImage *, self) - -#define FOR_EACH_PARAM_OF_FXTIFImage_loadPixels(param) \ - param(FXTIFImage *, self) -#define FOR_EACH_PARAM_OF_FXTIFImage_savePixels(param) \ - param(const FXTIFImage *, self) - -#define FOR_EACH_PARAM_OF_FXXBMImage_loadPixels(param) \ - param(FXXBMImage *, self) -#define FOR_EACH_PARAM_OF_FXXBMImage_savePixels(param) \ - param(const FXXBMImage *, self) - -#define FOR_EACH_PARAM_OF_FXXPMImage_loadPixels(param) \ - param(FXXPMImage *, self) -#define FOR_EACH_PARAM_OF_FXXPMImage_savePixels(param) \ - param(const FXXPMImage *, self) - -/* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */ + param(FXStream&, store) + +/* function( name, void_or_nonvoid, returntype, firstparamtype, firstparamname ) */ #define FOR_EACH_BLOCKING_FUNCTION(function) \ - function(FXImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXBMPImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXBMPImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXJPGImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXJPGImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXGIFImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXGIFImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXICOImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXICOImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXPNGImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXPNGImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXPPMImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXPPMImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXPCXImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXPCXImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXRGBImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXRGBImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXTGAImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXTGAImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXTIFImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXTIFImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXXBMImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXXBMImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXXPMImage_loadPixels, GVL_TYPE_NONVOID, bool, FXStream&, store) \ - function(FXXPMImage_savePixels, GVL_TYPE_NONVOID, bool, FXStream&, store) + function(FXImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXImage *, self) \ + function(FXImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXImage *, self) \ + function(FXBMPImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXBMPImage *, self) \ + function(FXBMPImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXBMPImage *, self) \ + function(FXJPGImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXJPGImage *, self) \ + function(FXJPGImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXJPGImage *, self) \ + function(FXGIFImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXGIFImage *, self) \ + function(FXGIFImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXGIFImage *, self) \ + function(FXICOImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXICOImage *, self) \ + function(FXICOImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXICOImage *, self) \ + function(FXPNGImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPNGImage *, self) \ + function(FXPNGImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPNGImage *, self) \ + function(FXPPMImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPPMImage *, self) \ + function(FXPPMImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPPMImage *, self) \ + function(FXPCXImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPCXImage *, self) \ + function(FXPCXImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPCXImage *, self) \ + function(FXRGBImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXRGBImage *, self) \ + function(FXRGBImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXRGBImage *, self) \ + function(FXTGAImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTGAImage *, self) \ + function(FXTGAImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTGAImage *, self) \ + function(FXTIFImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTIFImage *, self) \ + function(FXTIFImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTIFImage *, self) \ + function(FXXBMImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXBMImage *, self) \ + function(FXXBMImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXBMImage *, self) \ + function(FXXPMImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXPMImage *, self) \ + function(FXXPMImage, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXPMImage *, self) \ + function(FXIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXIcon *, self) \ + function(FXIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXIcon *, self) \ + function(FXBMPIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXBMPIcon *, self) \ + function(FXBMPIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXBMPIcon *, self) \ + function(FXJPGIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXJPGIcon *, self) \ + function(FXJPGIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXJPGIcon *, self) \ + function(FXGIFIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXGIFIcon *, self) \ + function(FXGIFIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXGIFIcon *, self) \ + function(FXICOIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXICOIcon *, self) \ + function(FXICOIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXICOIcon *, self) \ + function(FXPNGIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPNGIcon *, self) \ + function(FXPNGIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPNGIcon *, self) \ + function(FXPPMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPPMIcon *, self) \ + function(FXPPMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPPMIcon *, self) \ + function(FXPCXIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXPCXIcon *, self) \ + function(FXPCXIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXPCXIcon *, self) \ + function(FXRGBIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXRGBIcon *, self) \ + function(FXRGBIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXRGBIcon *, self) \ + function(FXTGAIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTGAIcon *, self) \ + function(FXTGAIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTGAIcon *, self) \ + function(FXTIFIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXTIFIcon *, self) \ + function(FXTIFIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXTIFIcon *, self) \ + function(FXXBMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXBMIcon *, self) \ + function(FXXBMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXBMIcon *, self) \ + function(FXXPMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXPMIcon *, self) \ + function(FXXPMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXPMIcon *, self) FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL ) -FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_TARGET_DECL ) #endif /* end __gvl_wrappers_h */ diff --git a/test/TC_FXJPGImage.rb b/test/TC_FXJPGImage.rb index ea016e6799a77c0ed0c03814d9c423a1c4f81882..6224a0b1e62cd89b70aac8dd52e6443fe670d559 100644 --- a/test/TC_FXJPGImage.rb +++ b/test/TC_FXJPGImage.rb @@ -17,7 +17,7 @@ class TC_FXJPGImage < Fox::TestCase count = 0 th = Thread.new do loop do - sleep 0.01 + sleep 0.001 count += 1 end end @@ -26,13 +26,23 @@ class TC_FXJPGImage < Fox::TestCase img.setPixels( img_data, 0, w, h ) jpeg_data = FXMemoryStream.open(FXStreamSave, nil) do |outfile| - img.savePixels(outfile) + img.savePixels(outfile) outfile.takeBuffer end + assert_operator(count, :>=, 10) + assert_operator(jpeg_data.bytesize, :>=, 1000) + + count = 0 + img = FXJPGImage.new(app) + FXMemoryStream.open(FXStreamLoad, jpeg_data) do |infile| + img.loadPixels(infile) + end + th.kill + assert_equal 4000, img.width + assert_equal 3000, img.height assert_operator(count, :>=, 10) - assert_operator(jpeg_data.bytesize, :>=, 1000) end end