rmagick 4.2.2 → 5.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +14 -0
  3. data/.devcontainer/ImageMagick6/devcontainer.json +11 -0
  4. data/.devcontainer/devcontainer.json +11 -0
  5. data/.devcontainer/setup-repo.sh +10 -0
  6. data/.devcontainer/setup-user.sh +45 -0
  7. data/.editorconfig +1 -1
  8. data/.github/workflows/ci.yml +59 -24
  9. data/.gitignore +3 -0
  10. data/.rubocop_todo.yml +0 -1
  11. data/.yardopts +1 -1
  12. data/CHANGELOG.md +131 -0
  13. data/README.md +12 -17
  14. data/Rakefile +53 -81
  15. data/before_install_linux.sh +4 -4
  16. data/before_install_osx.sh +7 -6
  17. data/ext/RMagick/extconf.rb +94 -45
  18. data/ext/RMagick/{rmagick.c → rmagick.cpp} +19 -22
  19. data/ext/RMagick/rmagick.h +90 -60
  20. data/ext/RMagick/rmagick_gvl.h +224 -0
  21. data/ext/RMagick/{rmdraw.c → rmdraw.cpp} +160 -146
  22. data/ext/RMagick/{rmenum.c → rmenum.cpp} +69 -50
  23. data/ext/RMagick/{rmfill.c → rmfill.cpp} +81 -20
  24. data/ext/RMagick/{rmilist.c → rmilist.cpp} +184 -93
  25. data/ext/RMagick/{rmimage.c → rmimage.cpp} +1276 -731
  26. data/ext/RMagick/{rminfo.c → rminfo.cpp} +119 -131
  27. data/ext/RMagick/{rmkinfo.c → rmkinfo.cpp} +41 -16
  28. data/ext/RMagick/rmmain.cpp +1957 -0
  29. data/ext/RMagick/{rmmontage.c → rmmontage.cpp} +49 -28
  30. data/ext/RMagick/{rmpixel.c → rmpixel.cpp} +109 -84
  31. data/ext/RMagick/{rmstruct.c → rmstruct.cpp} +12 -12
  32. data/ext/RMagick/{rmutil.c → rmutil.cpp} +52 -91
  33. data/lib/rmagick/version.rb +3 -1
  34. data/lib/rmagick.rb +2 -0
  35. data/lib/rmagick_internal.rb +9 -48
  36. data/lib/rvg/rvg.rb +2 -2
  37. data/rmagick.gemspec +8 -7
  38. metadata +54 -23
  39. data/.codeclimate.yml +0 -63
  40. data/deprecated/RMagick.rb +0 -6
  41. data/ext/RMagick/rmmain.c +0 -1951
@@ -16,14 +16,21 @@
16
16
  //! Suppress warnings about deprecated functions on Windows
17
17
  #define _CRT_SECURE_NO_DEPRECATE 1
18
18
 
19
- #include <assert.h>
20
- #include <stdio.h>
21
- #include <ctype.h>
22
- #include <stdlib.h>
23
- #include <math.h>
24
- #include <sys/types.h>
25
- #include "ruby.h"
26
- #include "ruby/io.h"
19
+ // ruby.h contains a C++ template, which cannot be included in extern "C".
20
+ // Therefore, it includes the header in advance.
21
+ #include "ruby/defines.h"
22
+
23
+ extern "C" {
24
+ #include <assert.h>
25
+ #include <stdio.h>
26
+ #include <ctype.h>
27
+ #include <stdlib.h>
28
+ #include <math.h>
29
+ #include <sys/types.h>
30
+ #include "ruby.h"
31
+ #include "ruby/io.h"
32
+ #include "rmagick_gvl.h"
33
+ }
27
34
 
28
35
  #if defined(__MINGW32__)
29
36
  // Ruby defines wrong format specifiers for MinGW. So this defines original macro in here.
@@ -44,10 +51,6 @@
44
51
  #endif
45
52
 
46
53
  #if defined(__GNUC__)
47
- #pragma GCC diagnostic push
48
- #pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
49
- #pragma GCC diagnostic ignored "-Wunknown-pragmas"
50
-
51
54
  #if __GNUC__ > 6
52
55
  #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
53
56
  #endif
@@ -61,6 +64,11 @@
61
64
  #undef PACKAGE_TARNAME
62
65
  #undef WORDS_BIGENDIAN
63
66
 
67
+ #ifndef HAVE_RB_EXT_RACTOR_SAFE
68
+ #undef RUBY_TYPED_FROZEN_SHAREABLE
69
+ #define RUBY_TYPED_FROZEN_SHAREABLE 0
70
+ #endif
71
+
64
72
  #include "extconf.h"
65
73
 
66
74
  #if defined(IMAGEMAGICK_7)
@@ -90,8 +98,8 @@
90
98
 
91
99
  //! Trace new image creation in bang methods
92
100
  #define UPDATE_DATA_PTR(_obj_, _new_) \
93
- do { (void) rm_trace_creation(_new_);\
94
- DATA_PTR(_obj_) = (void *)(_new_);\
101
+ do { \
102
+ DATA_PTR(_obj_) = (void *)(_new_); \
95
103
  } while(0)
96
104
 
97
105
 
@@ -310,7 +318,7 @@ typedef enum _QuantumExpressionOperator
310
318
 
311
319
 
312
320
  /** This implements the "omitted storage class model" for external variables.
313
- * (Ref: Harbison & Steele.) The rmmain.c file defines MAIN, which causes
321
+ * (Ref: Harbison & Steele.) The rmmain.cpp file defines MAIN, which causes
314
322
  * the single defining declarations to be generated. No other source files
315
323
  * define MAIN and therefore generate referencing declarations.
316
324
  */
@@ -396,7 +404,6 @@ EXTERN VALUE Class_KernelInfoType;
396
404
  /**
397
405
  * Commonly-used IDs
398
406
  */
399
- EXTERN ID rm_ID_trace_proc; /**< "@trace_proc" */
400
407
  EXTERN ID rm_ID_call; /**< "call" */
401
408
  EXTERN ID rm_ID_changed; /**< "changed" */
402
409
  EXTERN ID rm_ID_cur_image; /**< "cur_image" */
@@ -411,7 +418,13 @@ EXTERN ID rm_ID_push; /**< "push" */
411
418
  EXTERN ID rm_ID_values; /**< "values" */
412
419
  EXTERN ID rm_ID_width; /**< "width" */
413
420
 
414
- EXTERN unsigned long long rm_main_thread_id;
421
+ extern const rb_data_type_t rm_enum_data_type;
422
+ extern const rb_data_type_t rm_info_data_type;
423
+ extern const rb_data_type_t rm_image_data_type;
424
+ extern const rb_data_type_t rm_draw_data_type;
425
+ extern const rb_data_type_t rm_pixel_data_type;
426
+ extern const rb_data_type_t rm_montage_data_type;
427
+ extern const rb_data_type_t rm_kernel_info_data_type;
415
428
 
416
429
  #if !defined(min)
417
430
  #define min(a, b) ((a)<(b)?(a):(b)) /**< min of two values */
@@ -431,59 +444,59 @@ EXTERN unsigned long long rm_main_thread_id;
431
444
  Define simple attribute accessor methods (boolean, int, string, and double types)
432
445
  */
433
446
  #define C_boolean_to_R_boolean(attr) (attr) ? Qtrue : Qfalse /**< C boolean -> Ruby boolean */
434
- #define R_boolean_to_C_boolean(attr) RTEST(attr) /**< C boolean <- Ruby boolean */
447
+ #define R_boolean_to_C_boolean(attr) (MagickBooleanType)RTEST(attr) /**< C boolean <- Ruby boolean */
435
448
  #define C_int_to_R_int(attr) INT2FIX(attr) /**< C int -> Ruby int */
436
449
  #define R_int_to_C_int(attr) NUM2INT(attr) /**< C int <- Ruby int */
437
- #define C_long_to_R_long(attr) INT2NUM(attr) /**< C long -> Ruby long */
450
+ #define C_long_to_R_long(attr) LONG2NUM(attr) /**< C long -> Ruby long */
438
451
  #define R_long_to_C_long(attr) NUM2LONG(attr) /**< C long <- Ruby long */
439
- #define C_ulong_to_R_ulong(attr) UINT2NUM(attr) /**< C unsigned long -> Ruby unsigned long */
452
+ #define C_ulong_to_R_ulong(attr) ULONG2NUM(attr) /**< C unsigned long -> Ruby unsigned long */
440
453
  #define R_ulong_to_C_ulong(attr) NUM2ULONG(attr) /**< C unsigned long <- Ruby unsigned long */
441
454
  #define C_str_to_R_str(attr) attr ? rb_str_new2(attr) : Qnil /**< C string -> Ruby string */
442
455
  #define C_dbl_to_R_dbl(attr) rb_float_new(attr) /**< C double -> Ruby double */
443
456
  #define R_dbl_to_C_dbl(attr) NUM2DBL(attr) /**< C double <- Ruby double */
444
457
 
445
458
  //! define attribute reader
446
- #define IMPLEMENT_ATTR_READER(class, attr, type) \
459
+ #define IMPLEMENT_TYPED_ATTR_READER(klass, attr, type, data_type) \
447
460
  {\
448
- class *ptr;\
461
+ klass *ptr;\
449
462
  if (rb_obj_is_kind_of(self, Class_Image) == Qtrue) {\
450
463
  rm_check_destroyed(self); \
451
464
  }\
452
- Data_Get_Struct(self, class, ptr);\
465
+ TypedData_Get_Struct(self, klass, data_type, ptr);\
453
466
  return C_##type##_to_R_##type(ptr->attr);\
454
467
  }
455
468
 
456
469
  //! define attribute reader when attribute name is different from the field name
457
- #define IMPLEMENT_ATTR_READERF(class, attr, field, type) \
470
+ #define IMPLEMENT_TYPED_ATTR_READERF(klass, attr, field, type, data_type) \
458
471
  {\
459
- class *ptr;\
472
+ klass *ptr;\
460
473
  rm_check_destroyed(self); \
461
- Data_Get_Struct(self, class, ptr);\
474
+ TypedData_Get_Struct(self, klass, data_type, ptr);\
462
475
  return C_##type##_to_R_##type(ptr->field);\
463
476
  }
464
477
 
465
478
  //! define attribute writer
466
- #define IMPLEMENT_ATTR_WRITER(class, attr, type) \
479
+ #define IMPLEMENT_TYPED_ATTR_WRITER(klass, attr, type, data_type) \
467
480
  {\
468
- class *ptr;\
481
+ klass *ptr;\
469
482
  if (rb_obj_is_kind_of(self, Class_Image) == Qtrue) {\
470
483
  rm_check_destroyed(self); \
471
484
  }\
472
485
  rb_check_frozen(self);\
473
- Data_Get_Struct(self, class, ptr);\
486
+ TypedData_Get_Struct(self, klass, data_type, ptr);\
474
487
  ptr->attr = R_##type##_to_C_##type(val);\
475
488
  return val;\
476
489
  }
477
490
 
478
491
  //! define attribute writer when attribute name is different from the field name
479
- #define IMPLEMENT_ATTR_WRITERF(class, attr, field, type) \
492
+ #define IMPLEMENT_TYPED_ATTR_WRITERF(klass, attr, field, type, data_type) \
480
493
  {\
481
- class *ptr;\
494
+ klass *ptr;\
482
495
  if (rb_obj_is_kind_of(self, Class_Image) == Qtrue) {\
483
496
  rm_check_destroyed(self); \
484
497
  }\
485
498
  rb_check_frozen(self);\
486
- Data_Get_Struct(self, class, ptr);\
499
+ TypedData_Get_Struct(self, klass, data_type, ptr);\
487
500
  ptr->field = R_##type##_to_C_##type(val);\
488
501
  return self;\
489
502
  }
@@ -493,15 +506,15 @@ EXTERN unsigned long long rm_main_thread_id;
493
506
  * Declare attribute accessors
494
507
  */
495
508
  //! declare attribute reader
496
- #define ATTR_READER(class, attr) \
497
- extern VALUE class##_##attr(VALUE);
509
+ #define ATTR_READER(klass, attr) \
510
+ extern VALUE klass##_##attr(VALUE);
498
511
  //! declare attribute writer
499
- #define ATTR_WRITER(class, attr) \
500
- extern VALUE class##_##attr##_eq(VALUE, VALUE);
512
+ #define ATTR_WRITER(klass, attr) \
513
+ extern VALUE klass##_##attr##_eq(VALUE, VALUE);
501
514
  //! declare attribute accessor
502
- #define ATTR_ACCESSOR(class, attr) \
503
- ATTR_READER(class, attr)\
504
- ATTR_WRITER(class, attr)
515
+ #define ATTR_ACCESSOR(klass, attr) \
516
+ ATTR_READER(klass, attr)\
517
+ ATTR_WRITER(klass, attr)
505
518
 
506
519
 
507
520
  //! Define a Magick module constant
@@ -513,7 +526,6 @@ EXTERN unsigned long long rm_main_thread_id;
513
526
  #define DEF_CONSTV(constant, val) rb_define_const(Module_Magick, #constant, UINT2NUM(val))
514
527
  #endif
515
528
 
516
-
517
529
  //! Convert a Ruby enum constant back to a C enum member.
518
530
  #define VALUE_TO_ENUM(value, e, type) \
519
531
  do {\
@@ -521,7 +533,7 @@ EXTERN unsigned long long rm_main_thread_id;
521
533
  if (CLASS_OF(value) != Class_##type)\
522
534
  rb_raise(rb_eTypeError, "wrong enumeration type - expected %s, got %s", \
523
535
  rb_class2name(Class_##type), rb_class2name(CLASS_OF(value)));\
524
- Data_Get_Struct(value, MagickEnum, magick_enum);\
536
+ TypedData_Get_Struct(value, MagickEnum, &rm_enum_data_type, magick_enum);\
525
537
  e = (type)(magick_enum->val);\
526
538
  } while(0)
527
539
 
@@ -534,11 +546,13 @@ EXTERN unsigned long long rm_main_thread_id;
534
546
  // the same source file.
535
547
 
536
548
 
537
- // rmmain.c
549
+ extern "C" {
550
+
551
+ // rmmain.cpp
538
552
  extern void Init_RMagick2(void);
539
553
 
540
554
 
541
- // rmagick.c
555
+ // rmagick.cpp
542
556
  extern VALUE Magick_colors(VALUE);
543
557
  extern VALUE Magick_fonts(VALUE);
544
558
  extern VALUE Magick_init_formats(VALUE);
@@ -547,7 +561,7 @@ extern VALUE Magick_set_cache_threshold(VALUE, VALUE);
547
561
  extern VALUE Magick_set_log_event_mask(int, VALUE *, VALUE);
548
562
  extern VALUE Magick_set_log_format(VALUE, VALUE);
549
563
 
550
- // rmdraw.c
564
+ // rmdraw.cpp
551
565
  ATTR_WRITER(Draw, affine)
552
566
  ATTR_WRITER(Draw, align)
553
567
  ATTR_WRITER(Draw, border_color)
@@ -598,7 +612,7 @@ ATTR_WRITER(PolaroidOptions, shadow_color);
598
612
  ATTR_WRITER(PolaroidOptions, border_color);
599
613
 
600
614
 
601
- // rmmontage.c
615
+ // rmmontage.cpp
602
616
  ATTR_WRITER(Montage, background_color)
603
617
  ATTR_WRITER(Montage, border_color)
604
618
  ATTR_WRITER(Montage, border_width)
@@ -621,7 +635,7 @@ extern VALUE Montage_alloc(VALUE);
621
635
  extern VALUE rm_montage_new(void);
622
636
 
623
637
 
624
- // rmilist.c
638
+ // rmilist.cpp
625
639
  extern VALUE ImageList_animate(int, VALUE *, VALUE);
626
640
  extern VALUE ImageList_append(VALUE, VALUE);
627
641
  extern VALUE ImageList_average(VALUE);
@@ -643,7 +657,7 @@ extern VALUE ImageList_write(VALUE, VALUE);
643
657
  extern VALUE rm_imagelist_from_images(Image *);
644
658
 
645
659
 
646
- // rminfo.c
660
+ // rminfo.cpp
647
661
  ATTR_ACCESSOR(Info, antialias)
648
662
  ATTR_ACCESSOR(Info, attenuate)
649
663
  ATTR_ACCESSOR(Info, authenticate)
@@ -705,7 +719,7 @@ extern VALUE rm_info_new(void);
705
719
  extern DisposeType rm_dispose_to_enum(const char *);
706
720
  extern GravityType rm_gravity_to_enum(const char *);
707
721
 
708
- // rmkinfo.c
722
+ // rmkinfo.cpp
709
723
 
710
724
  extern VALUE KernelInfo_alloc(VALUE);
711
725
 
@@ -718,7 +732,7 @@ extern VALUE KernelInfo_clone(VALUE);
718
732
  extern VALUE KernelInfo_builtin(VALUE, VALUE, VALUE);
719
733
 
720
734
 
721
- // rmimage.c
735
+ // rmimage.cpp
722
736
  ATTR_ACCESSOR(Image, background_color)
723
737
  ATTR_READER(Image, base_columns)
724
738
  ATTR_READER(Image, base_filename)
@@ -1019,10 +1033,9 @@ extern VALUE Image_write(VALUE, VALUE);
1019
1033
 
1020
1034
  extern VALUE rm_image_new(Image *);
1021
1035
  extern void rm_image_destroy(void *);
1022
- extern void rm_trace_creation(Image *);
1023
1036
 
1024
1037
 
1025
- // rmfill.c
1038
+ // rmfill.cpp
1026
1039
  extern VALUE GradientFill_alloc(VALUE);
1027
1040
  extern VALUE GradientFill_initialize(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
1028
1041
  extern VALUE GradientFill_fill(VALUE, VALUE);
@@ -1032,7 +1045,7 @@ extern VALUE TextureFill_initialize(VALUE, VALUE);
1032
1045
  extern VALUE TextureFill_fill(VALUE, VALUE);
1033
1046
 
1034
1047
 
1035
- // rmpixel.c
1048
+ // rmpixel.cpp
1036
1049
 
1037
1050
 
1038
1051
  ATTR_ACCESSOR(Pixel, red)
@@ -1043,7 +1056,6 @@ ATTR_ACCESSOR(Pixel, cyan)
1043
1056
  ATTR_ACCESSOR(Pixel, magenta)
1044
1057
  ATTR_ACCESSOR(Pixel, yellow)
1045
1058
  ATTR_ACCESSOR(Pixel, black)
1046
- extern void destroy_Pixel(Pixel *);
1047
1059
  extern VALUE Pixel_alloc(VALUE);
1048
1060
  extern VALUE Pixel_case_eq(VALUE, VALUE);
1049
1061
  extern VALUE Pixel_clone(VALUE);
@@ -1064,7 +1076,7 @@ extern VALUE Pixel_to_hsla(VALUE);
1064
1076
  extern VALUE Pixel_to_s(VALUE);
1065
1077
 
1066
1078
 
1067
- // rmenum.c
1079
+ // rmenum.cpp
1068
1080
  extern VALUE Enum_alloc(VALUE);
1069
1081
  extern VALUE Enum_initialize(VALUE, VALUE, VALUE);
1070
1082
  extern VALUE Enum_to_s(VALUE);
@@ -1073,7 +1085,7 @@ extern VALUE Enum_spaceship(VALUE, VALUE);
1073
1085
  extern VALUE Enum_bitwise_or(VALUE, VALUE);
1074
1086
  extern VALUE Enum_case_eq(VALUE, VALUE);
1075
1087
  extern VALUE Enum_type_initialize(VALUE, VALUE, VALUE);
1076
- extern VALUE Enum_find(VALUE class, int val);
1088
+ extern VALUE Enum_find(VALUE, int);
1077
1089
  extern VALUE Enum_type_each(VALUE);
1078
1090
  extern VALUE rm_enum_new(VALUE, VALUE, VALUE);
1079
1091
  extern VALUE ClassType_find(ClassType);
@@ -1100,7 +1112,7 @@ extern const char *StyleType_name(StyleType);
1100
1112
  extern VALUE VirtualPixelMethod_find(VirtualPixelMethod);
1101
1113
 
1102
1114
 
1103
- // rmstruct.c
1115
+ // rmstruct.cpp
1104
1116
  extern VALUE ChromaticityInfo_to_s(VALUE);
1105
1117
  extern VALUE ChromaticityInfo_new(ChromaticityInfo *);
1106
1118
  extern void Color_to_PixelColor(PixelColor *, VALUE);
@@ -1135,7 +1147,7 @@ extern void Export_TypeInfo(TypeInfo *, VALUE);
1135
1147
  extern VALUE Import_TypeMetric(TypeMetric *);
1136
1148
 
1137
1149
 
1138
- // rmutil.c
1150
+ // rmutil.cpp
1139
1151
  extern VALUE ImageMagickError_initialize(int, VALUE *, VALUE);
1140
1152
  extern void *magick_malloc(const size_t);
1141
1153
  extern void *magick_safe_malloc(const size_t, const size_t);
@@ -1156,7 +1168,7 @@ extern void rm_check_ary_len(VALUE, long);
1156
1168
  extern VALUE rm_check_ary_type(VALUE ary);
1157
1169
  extern Image *rm_check_destroyed(VALUE);
1158
1170
  extern Image *rm_check_frozen(VALUE);
1159
- extern char *rm_str2cstr(VALUE, long *);
1171
+ extern char *rm_str2cstr(VALUE, size_t *);
1160
1172
  extern int rm_check_num2dbl(VALUE);
1161
1173
  extern double rm_fuzz_to_dbl(VALUE);
1162
1174
  extern Quantum rm_app2quantum(VALUE);
@@ -1173,6 +1185,9 @@ extern void rm_set_user_artifact(Image *, Info *);
1173
1185
  extern void rm_sync_image_options(Image *, Info *);
1174
1186
  extern void rm_split(Image *);
1175
1187
  extern void rm_magick_error(const char *);
1188
+ #if defined(IMAGEMAGICK_7)
1189
+ extern void rm_set_pixelinfo_alpha(PixelInfo *, const MagickRealType);
1190
+ #endif
1176
1191
 
1177
1192
  //! whether to retain on errors
1178
1193
  typedef enum
@@ -1190,7 +1205,6 @@ typedef enum
1190
1205
  extern void rm_check_exception(ExceptionInfo *, Image *, ErrorRetention);
1191
1206
  extern void rm_ensure_result(Image *);
1192
1207
  extern Image *rm_clone_image(Image *);
1193
- extern MagickBooleanType rm_progress_monitor(const char *, const MagickOffsetType, const MagickSizeType, void *);
1194
1208
  extern VALUE rm_exif_by_entry(Image *);
1195
1209
  extern VALUE rm_exif_by_number(Image *);
1196
1210
  extern void rm_get_optional_arguments(VALUE);
@@ -1199,10 +1213,26 @@ extern void rm_error_handler(const ExceptionType, const char *, const char *);
1199
1213
  extern void rm_warning_handler(const ExceptionType, const char *, const char *);
1200
1214
  extern MagickBooleanType rm_should_raise_exception(ExceptionInfo *, const ExceptionRetention);
1201
1215
  extern void rm_raise_exception(ExceptionInfo *);
1202
- extern unsigned long long rm_current_thread_id();
1216
+ extern VALUE rm_io_path(VALUE);
1203
1217
  #if defined(IMAGEMAGICK_6)
1204
1218
  extern void rm_check_image_exception(Image *, ErrorRetention);
1205
1219
  #endif
1206
1220
 
1221
+ #if !defined(IMAGEMAGICK_GREATER_THAN_EQUAL_6_9_0)
1222
+ /* UnityAddKernelInfo() was private function until IM 6.9 */
1223
+ MagickExport void UnityAddKernelInfo(KernelInfo *kernel, const double scale);
1224
+ /* ScaleKernelInfo() was private function until IM 6.9 */
1225
+ MagickExport void ScaleKernelInfo(KernelInfo *kernel, const double scaling_factor, const GeometryFlags normalize_flags);
1226
+ #endif
1227
+
1228
+ #if (RUBY_VERSION_MAJOR == 2 && RUBY_VERSION_MINOR < 7)
1229
+ #define RESCUE_FUNC(func) (VALUE (*)(ANYARGS))(func)
1230
+ #define RESCUE_EXCEPTION_HANDLER_FUNC(func) (VALUE (*)(ANYARGS))(func)
1231
+ #else
1232
+ #define RESCUE_FUNC(func) (VALUE(*)(VALUE))(func)
1233
+ #define RESCUE_EXCEPTION_HANDLER_FUNC(func) (VALUE(*)(VALUE, VALUE))(func)
1207
1234
  #endif
1208
1235
 
1236
+ } // extern "C"
1237
+
1238
+ #endif
@@ -0,0 +1,224 @@
1
+ #ifndef _RMAGICK_GVL_H_
2
+ #define _RMAGICK_GVL_H_
3
+
4
+ #include "ruby/thread.h"
5
+
6
+ typedef void *(gvl_function_t)(void *);
7
+
8
+ #define GVL_FUNC(name) name##_gvl
9
+ #define GVL_STRUCT_TYPE(name) name##_args_t
10
+ #define CALL_FUNC_WITHOUT_GVL(fp, args) \
11
+ rb_thread_call_without_gvl(fp, args, RUBY_UBF_PROCESS, NULL)
12
+
13
+
14
+ #define DEFINE_GVL_STRUCT1(name, type1) \
15
+ typedef struct { \
16
+ type1 arg1; \
17
+ } GVL_STRUCT_TYPE(name)
18
+ #define DEFINE_GVL_FUNC1(func_name, struct_name) \
19
+ static void *func_name##_gvl(void *p) \
20
+ { \
21
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
22
+ return (void *)func_name(args->arg1); \
23
+ }
24
+
25
+ #define DEFINE_GVL_STUB1(name, type1) \
26
+ DEFINE_GVL_STRUCT1(name, type1); \
27
+ DEFINE_GVL_FUNC1(name, name)
28
+
29
+
30
+ #define DEFINE_GVL_STRUCT2(name, type1, type2) \
31
+ typedef struct { \
32
+ type1 arg1; \
33
+ type2 arg2; \
34
+ } GVL_STRUCT_TYPE(name)
35
+ #define DEFINE_GVL_FUNC2(func_name, struct_name) \
36
+ static void *func_name##_gvl(void *p) \
37
+ { \
38
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
39
+ return (void *)func_name(args->arg1, args->arg2); \
40
+ }
41
+
42
+ #define DEFINE_GVL_STUB2(name, type1, type2) \
43
+ DEFINE_GVL_STRUCT2(name, type1, type2); \
44
+ DEFINE_GVL_FUNC2(name, name)
45
+
46
+
47
+ #define DEFINE_GVL_STRUCT3(name, type1, type2, type3) \
48
+ typedef struct { \
49
+ type1 arg1; \
50
+ type2 arg2; \
51
+ type3 arg3; \
52
+ } GVL_STRUCT_TYPE(name)
53
+ #define DEFINE_GVL_FUNC3(func_name, struct_name) \
54
+ static void *func_name##_gvl(void *p) \
55
+ { \
56
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
57
+ return (void *)func_name(args->arg1, args->arg2, args->arg3); \
58
+ }
59
+
60
+ #define DEFINE_GVL_STUB3(name, type1, type2, type3) \
61
+ DEFINE_GVL_STRUCT3(name, type1, type2, type3); \
62
+ DEFINE_GVL_FUNC3(name, name)
63
+
64
+
65
+ #define DEFINE_GVL_STRUCT4(name, type1, type2, type3, type4) \
66
+ typedef struct { \
67
+ type1 arg1; \
68
+ type2 arg2; \
69
+ type3 arg3; \
70
+ type4 arg4; \
71
+ } GVL_STRUCT_TYPE(name)
72
+ #define DEFINE_GVL_FUNC4(func_name, struct_name) \
73
+ static void *func_name##_gvl(void *p) \
74
+ { \
75
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
76
+ return (void *)func_name(args->arg1, args->arg2, args->arg3, args->arg4); \
77
+ }
78
+
79
+ #define DEFINE_GVL_STUB4(name, type1, type2, type3, type4) \
80
+ DEFINE_GVL_STRUCT4(name, type1, type2, type3, type4); \
81
+ DEFINE_GVL_FUNC4(name, name)
82
+
83
+
84
+ #define DEFINE_GVL_STRUCT5(name, type1, type2, type3, type4, type5) \
85
+ typedef struct { \
86
+ type1 arg1; \
87
+ type2 arg2; \
88
+ type3 arg3; \
89
+ type4 arg4; \
90
+ type5 arg5; \
91
+ } GVL_STRUCT_TYPE(name)
92
+ #define DEFINE_GVL_FUNC5(func_name, struct_name) \
93
+ static void *func_name##_gvl(void *p) \
94
+ { \
95
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
96
+ return (void *)func_name(args->arg1, args->arg2, args->arg3, args->arg4, args->arg5); \
97
+ }
98
+ #define DEFINE_GVL_STUB5(name, type1, type2, type3, type4, type5) \
99
+ DEFINE_GVL_STRUCT5(name, type1, type2, type3, type4, type5); \
100
+ DEFINE_GVL_FUNC5(name, name)
101
+
102
+
103
+ #define DEFINE_GVL_STRUCT6(name, type1, type2, type3, type4, type5, type6) \
104
+ typedef struct { \
105
+ type1 arg1; \
106
+ type2 arg2; \
107
+ type3 arg3; \
108
+ type4 arg4; \
109
+ type5 arg5; \
110
+ type6 arg6; \
111
+ } GVL_STRUCT_TYPE(name)
112
+ #define DEFINE_GVL_FUNC6(func_name, struct_name) \
113
+ static void *func_name##_gvl(void *p) \
114
+ { \
115
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
116
+ return (void *)func_name(args->arg1, args->arg2, args->arg3, args->arg4, args->arg5, args->arg6); \
117
+ }
118
+ #define DEFINE_GVL_STUB6(name, type1, type2, type3, type4, type5, type6) \
119
+ DEFINE_GVL_STRUCT6(name, type1, type2, type3, type4, type5, type6); \
120
+ DEFINE_GVL_FUNC6(name, name)
121
+
122
+
123
+ #define DEFINE_GVL_STRUCT7(name, type1, type2, type3, type4, type5, type6, type7) \
124
+ typedef struct { \
125
+ type1 arg1; \
126
+ type2 arg2; \
127
+ type3 arg3; \
128
+ type4 arg4; \
129
+ type5 arg5; \
130
+ type6 arg6; \
131
+ type7 arg7; \
132
+ } GVL_STRUCT_TYPE(name)
133
+ #define DEFINE_GVL_FUNC7(func_name, struct_name) \
134
+ static void *func_name##_gvl(void *p) \
135
+ { \
136
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
137
+ return (void *)func_name(args->arg1, args->arg2, args->arg3, args->arg4, args->arg5, args->arg6, args->arg7); \
138
+ }
139
+ #define DEFINE_GVL_STUB7(name, type1, type2, type3, type4, type5, type6, type7) \
140
+ DEFINE_GVL_STRUCT7(name, type1, type2, type3, type4, type5, type6, type7); \
141
+ DEFINE_GVL_FUNC7(name, name)
142
+
143
+
144
+ #define DEFINE_GVL_STRUCT8(name, type1, type2, type3, type4, type5, type6, type7, type8) \
145
+ typedef struct { \
146
+ type1 arg1; \
147
+ type2 arg2; \
148
+ type3 arg3; \
149
+ type4 arg4; \
150
+ type5 arg5; \
151
+ type6 arg6; \
152
+ type7 arg7; \
153
+ type8 arg8; \
154
+ } GVL_STRUCT_TYPE(name)
155
+ #define DEFINE_GVL_FUNC8(func_name, struct_name) \
156
+ static void *func_name##_gvl(void *p) \
157
+ { \
158
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
159
+ return (void *)func_name(args->arg1, args->arg2, args->arg3, args->arg4, args->arg5, args->arg6, args->arg7, args->arg8); \
160
+ }
161
+ #define DEFINE_GVL_STUB8(name, type1, type2, type3, type4, type5, type6, type7, type8) \
162
+ DEFINE_GVL_STRUCT8(name, type1, type2, type3, type4, type5, type6, type7, type8); \
163
+ DEFINE_GVL_FUNC8(name, name)
164
+
165
+
166
+ #define DEFINE_GVL_STRUCT9(name, type1, type2, type3, type4, type5, type6, type7, type8, type9) \
167
+ typedef struct { \
168
+ type1 arg1; \
169
+ type2 arg2; \
170
+ type3 arg3; \
171
+ type4 arg4; \
172
+ type5 arg5; \
173
+ type6 arg6; \
174
+ type7 arg7; \
175
+ type8 arg8; \
176
+ type9 arg9; \
177
+ } GVL_STRUCT_TYPE(name)
178
+ #define DEFINE_GVL_FUNC9(func_name, struct_name) \
179
+ static void *func_name##_gvl(void *p) \
180
+ { \
181
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
182
+ return (void *)func_name(args->arg1, args->arg2, args->arg3, args->arg4, args->arg5, args->arg6, args->arg7, args->arg8, args->arg9); \
183
+ }
184
+ #define DEFINE_GVL_STUB9(name, type1, type2, type3, type4, type5, type6, type7, type8, type9) \
185
+ DEFINE_GVL_STRUCT9(name, type1, type2, type3, type4, type5, type6, type7, type8, type9); \
186
+ DEFINE_GVL_FUNC9(name, name)
187
+
188
+
189
+ #define DEFINE_GVL_VOID_FUNC2(func_name, struct_name) \
190
+ static void *func_name##_gvl(void *p) \
191
+ { \
192
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
193
+ func_name(args->arg1, args->arg2); \
194
+ return NULL; \
195
+ }
196
+ #define DEFINE_GVL_VOID_STUB2(name, type1, type2) \
197
+ DEFINE_GVL_STRUCT2(name, type1, type2); \
198
+ DEFINE_GVL_VOID_FUNC2(name, name)
199
+
200
+
201
+ #define DEFINE_GVL_VOID_FUNC3(func_name, struct_name) \
202
+ static void *func_name##_gvl(void *p) \
203
+ { \
204
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
205
+ func_name(args->arg1, args->arg2, args->arg3); \
206
+ return NULL; \
207
+ }
208
+ #define DEFINE_GVL_VOID_STUB3(name, type1, type2, type3) \
209
+ DEFINE_GVL_STRUCT3(name, type1, type2, type3); \
210
+ DEFINE_GVL_VOID_FUNC3(name, name)
211
+
212
+
213
+ #define DEFINE_GVL_VOID_FUNC6(func_name, struct_name) \
214
+ static void *func_name##_gvl(void *p) \
215
+ { \
216
+ GVL_STRUCT_TYPE(struct_name) *args = (GVL_STRUCT_TYPE(struct_name) *)p; \
217
+ func_name(args->arg1, args->arg2, args->arg3, args->arg4, args->arg5, args->arg6); \
218
+ return NULL; \
219
+ }
220
+ #define DEFINE_GVL_VOID_STUB6(name, type1, type2, type3, type4, type5, type6) \
221
+ DEFINE_GVL_STRUCT6(name, type1, type2, type3, type4, type5, type6); \
222
+ DEFINE_GVL_VOID_FUNC6(name, name)
223
+
224
+ #endif