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, &params, 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, &params, 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