You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.7 KiB
129 lines
3.7 KiB
5 months ago
|
From beb0358d90ad77e59cf5d13cc2469de94fe06331 Mon Sep 17 00:00:00 2001
|
||
|
From: Sutou Kouhei <kou@clear-code.com>
|
||
|
Date: Thu, 15 Sep 2022 07:08:20 +0900
|
||
|
Subject: [PATCH] merge revision(s) a4ad6bd9aac564e93219284c912b26a72f9e82fc:
|
||
|
|
||
|
[ruby/fiddle] closure: free resources when an exception is raised in
|
||
|
Closure.new
|
||
|
|
||
|
GitHub: GH-102
|
||
|
|
||
|
https://github.com/ruby/fiddle/commit/81a8a56239
|
||
|
---
|
||
|
ext/fiddle/closure.c | 56 ++++++++++++++++++++++++++++++++++++++++------------
|
||
|
1 file changed, 43 insertions(+), 13 deletions(-)
|
||
|
---
|
||
|
ext/fiddle/closure.c | 56 ++++++++++++++++++++++++++++++++++----------
|
||
|
1 file changed, 43 insertions(+), 13 deletions(-)
|
||
|
|
||
|
diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c
|
||
|
index 27f448a24f..c08ec5940d 100644
|
||
|
--- a/ext/fiddle/closure.c
|
||
|
+++ b/ext/fiddle/closure.c
|
||
|
@@ -224,9 +224,16 @@ allocate(VALUE klass)
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
+typedef struct {
|
||
|
+ VALUE self;
|
||
|
+ int argc;
|
||
|
+ VALUE *argv;
|
||
|
+} initialize_data;
|
||
|
+
|
||
|
static VALUE
|
||
|
-initialize(int rbargc, VALUE argv[], VALUE self)
|
||
|
+initialize_body(VALUE user_data)
|
||
|
{
|
||
|
+ initialize_data *data = (initialize_data *)user_data;
|
||
|
VALUE ret;
|
||
|
VALUE args;
|
||
|
VALUE normalized_args;
|
||
|
@@ -237,14 +244,14 @@ initialize(int rbargc, VALUE argv[], VALUE self)
|
||
|
ffi_status result;
|
||
|
int i, argc;
|
||
|
|
||
|
- if (2 == rb_scan_args(rbargc, argv, "21", &ret, &args, &abi))
|
||
|
- abi = INT2NUM(FFI_DEFAULT_ABI);
|
||
|
+ if (2 == rb_scan_args(data->argc, data->argv, "21", &ret, &args, &abi))
|
||
|
+ abi = INT2NUM(FFI_DEFAULT_ABI);
|
||
|
|
||
|
Check_Type(args, T_ARRAY);
|
||
|
|
||
|
argc = RARRAY_LENINT(args);
|
||
|
|
||
|
- TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl);
|
||
|
+ TypedData_Get_Struct(data->self, fiddle_closure, &closure_data_type, cl);
|
||
|
|
||
|
cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));
|
||
|
|
||
|
@@ -257,8 +264,8 @@ initialize(int rbargc, VALUE argv[], VALUE self)
|
||
|
cl->argv[argc] = NULL;
|
||
|
|
||
|
ret = rb_fiddle_type_ensure(ret);
|
||
|
- rb_iv_set(self, "@ctype", ret);
|
||
|
- rb_iv_set(self, "@args", normalized_args);
|
||
|
+ rb_iv_set(data->self, "@ctype", ret);
|
||
|
+ rb_iv_set(data->self, "@args", normalized_args);
|
||
|
|
||
|
cif = &cl->cif;
|
||
|
pcl = cl->pcl;
|
||
|
@@ -269,25 +276,48 @@ initialize(int rbargc, VALUE argv[], VALUE self)
|
||
|
rb_fiddle_int_to_ffi_type(NUM2INT(ret)),
|
||
|
cl->argv);
|
||
|
|
||
|
- if (FFI_OK != result)
|
||
|
- rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
|
||
|
+ if (FFI_OK != result) {
|
||
|
+ rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
|
||
|
+ }
|
||
|
|
||
|
#if USE_FFI_CLOSURE_ALLOC
|
||
|
result = ffi_prep_closure_loc(pcl, cif, callback,
|
||
|
- (void *)self, cl->code);
|
||
|
+ (void *)(data->self), cl->code);
|
||
|
#else
|
||
|
result = ffi_prep_closure(pcl, cif, callback, (void *)(data->self));
|
||
|
cl->code = (void *)pcl;
|
||
|
i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC);
|
||
|
if (i) {
|
||
|
- rb_sys_fail("mprotect");
|
||
|
+ rb_sys_fail("mprotect");
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
- if (FFI_OK != result)
|
||
|
- rb_raise(rb_eRuntimeError, "error prepping closure %d", result);
|
||
|
+ if (FFI_OK != result) {
|
||
|
+ rb_raise(rb_eRuntimeError, "error prepping closure %d", result);
|
||
|
+ }
|
||
|
+
|
||
|
+ return data->self;
|
||
|
+}
|
||
|
|
||
|
- return self;
|
||
|
+static VALUE
|
||
|
+initialize_rescue(VALUE user_data, VALUE exception)
|
||
|
+{
|
||
|
+ initialize_data *data = (initialize_data *)user_data;
|
||
|
+ dealloc(RTYPEDDATA_DATA(data->self));
|
||
|
+ RTYPEDDATA_DATA(data->self) = NULL;
|
||
|
+ rb_exc_raise(exception);
|
||
|
+ return data->self;
|
||
|
+}
|
||
|
+
|
||
|
+static VALUE
|
||
|
+initialize(int argc, VALUE *argv, VALUE self)
|
||
|
+{
|
||
|
+ initialize_data data;
|
||
|
+ data.self = self;
|
||
|
+ data.argc = argc;
|
||
|
+ data.argv = argv;
|
||
|
+ return rb_rescue(initialize_body, (VALUE)&data,
|
||
|
+ initialize_rescue, (VALUE)&data);
|
||
|
}
|
||
|
|
||
|
static VALUE
|
||
|
--
|
||
|
2.44.0
|
||
|
|