[前][次][番号順一覧][スレッド一覧]

ruby-changes:73900

From: Sutou <ko1@a...>
Date: Fri, 7 Oct 2022 15:21:00 +0900 (JST)
Subject: [ruby-changes:73900] a4ad6bd9aa (master): [ruby/fiddle] closuRe: free resources when an exception is raised in Closure.new

https://git.ruby-lang.org/ruby.git/commit/?id=a4ad6bd9aa

From a4ad6bd9aac564e93219284c912b26a72f9e82fc Mon Sep 17 00:00:00 2001
From: Sutou Kouhei <kou@c...>
Date: Thu, 15 Sep 2022 07:08:20 +0900
Subject: [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(-)

diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c
index 694ef90b7f..9a6c5ede3f 100644
--- a/ext/fiddle/closure.c
+++ b/ext/fiddle/closure.c
@@ -235,9 +235,16 @@ get_raw(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/closure.c#L235
     return closure;
 }
 
+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;
@@ -248,14 +255,14 @@ initialize(int rbargc, VALUE argv[], VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/closure.c#L255
     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 *));
 
@@ -268,8 +275,8 @@ initialize(int rbargc, VALUE argv[], VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/closure.c#L275
     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;
@@ -280,25 +287,48 @@ initialize(int rbargc, VALUE argv[], VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/closure.c#L287
                           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 *)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
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]