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

ruby-changes:22555

From: naruse <ko1@a...>
Date: Wed, 15 Feb 2012 05:09:38 +0900 (JST)
Subject: [ruby-changes:22555] naruse:r34604 (ruby_1_9_3): merge revision(s) 32712,32718,32719: [Backport #6014]

naruse	2012-02-15 05:09:27 +0900 (Wed, 15 Feb 2012)

  New Revision: 34604

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=34604

  Log:
    merge revision(s) 32712,32718,32719: [Backport #6014]
    
    * ext/dl/cfunc.c (dlcfunc_mark), ext/dl/cptr.c (dlptr_mark):
      workaround to mark wrapped object.  this is not a true fix,
      because [Bug #4929] is caused by the interface design of DL.
    
    * ext/dl/cptr.c (rb_dlptr_s_to_ptr): fix wrapping condition.
    
    * ext/dl/cptr.c (rb_dlptr_s_to_ptr): fix wrapping condition.
    
    * ext/dl/cptr.c (rb_dlptr_s_to_ptr): use rb_check_funcall.

  Modified files:
    branches/ruby_1_9_3/ChangeLog
    branches/ruby_1_9_3/ext/dl/cfunc.c
    branches/ruby_1_9_3/ext/dl/cptr.c
    branches/ruby_1_9_3/ext/dl/dl.h
    branches/ruby_1_9_3/test/dl/test_func.rb
    branches/ruby_1_9_3/version.h

Index: ruby_1_9_3/ChangeLog
===================================================================
--- ruby_1_9_3/ChangeLog	(revision 34603)
+++ ruby_1_9_3/ChangeLog	(revision 34604)
@@ -1,3 +1,11 @@
+Wed Feb 15 05:08:25 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/dl/cptr.c (rb_dlptr_s_to_ptr): use rb_check_funcall.
+
+	* ext/dl/cfunc.c (dlcfunc_mark), ext/dl/cptr.c (dlptr_mark):
+	  workaround to mark wrapped object.  this is not a true fix,
+	  because [Bug #4929] is caused by the interface design of DL.
+
 Wed Feb 15 05:04:47 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/dl/cptr.c (rb_dlptr_aref, rb_dlptr_aset): check NULL pointer
Index: ruby_1_9_3/ext/dl/cfunc.c
===================================================================
--- ruby_1_9_3/ext/dl/cfunc.c	(revision 34603)
+++ ruby_1_9_3/ext/dl/cfunc.c	(revision 34604)
@@ -41,6 +41,14 @@
 }
 #endif
 
+static void
+dlcfunc_mark(void *ptr)
+{
+    struct cfunc_data *data = ptr;
+    if (data->wrap) {
+	rb_gc_mark(data->wrap);
+    }
+}
 
 static void
 dlcfunc_free(void *ptr)
@@ -68,7 +76,7 @@
 
 const rb_data_type_t dlcfunc_data_type = {
     "dl/cfunc",
-    {0, dlcfunc_free, dlcfunc_memsize,},
+    {dlcfunc_mark, dlcfunc_free, dlcfunc_memsize,},
 };
 
 VALUE
@@ -143,14 +151,15 @@
 static VALUE
 rb_dlcfunc_initialize(int argc, VALUE argv[], VALUE self)
 {
-    VALUE addr, name, type, calltype;
+    VALUE addr, name, type, calltype, addrnum;
     struct cfunc_data *data;
     void *saddr;
     const char *sname;
 
     rb_scan_args(argc, argv, "13", &addr, &type, &name, &calltype);
 
-    saddr = (void*)(NUM2PTR(rb_Integer(addr)));
+    addrnum = rb_Integer(addr);
+    saddr = (void*)(NUM2PTR(addrnum));
     sname = NIL_P(name) ? NULL : StringValuePtr(name);
 
     TypedData_Get_Struct(self, struct cfunc_data, &dlcfunc_data_type, data);
@@ -159,6 +168,7 @@
     data->name = sname ? strdup(sname) : 0;
     data->type = NIL_P(type) ? DLTYPE_VOID : NUM2INT(type);
     data->calltype = NIL_P(calltype) ? CFUNC_CDECL : SYM2ID(calltype);
+    data->wrap = (addrnum == addr) ? 0 : addr;
 
     return Qnil;
 }
Index: ruby_1_9_3/ext/dl/dl.h
===================================================================
--- ruby_1_9_3/ext/dl/dl.h	(revision 34603)
+++ ruby_1_9_3/ext/dl/dl.h	(revision 34604)
@@ -199,6 +199,7 @@
     char *name;
     int  type;
     ID   calltype;
+    VALUE wrap;
 };
 extern ID rbdl_id_cdecl;
 extern ID rbdl_id_stdcall;
@@ -209,6 +210,7 @@
     void *ptr;
     long size;
     freefunc_t free;
+    VALUE wrap[2];
 };
 
 #define RDL_HANDLE(obj) ((struct dl_handle *)(DATA_PTR(obj)))
Index: ruby_1_9_3/ext/dl/cptr.c
===================================================================
--- ruby_1_9_3/ext/dl/cptr.c	(revision 34603)
+++ ruby_1_9_3/ext/dl/cptr.c	(revision 34604)
@@ -10,20 +10,37 @@
 VALUE rb_cDLCPtr;
 
 static inline freefunc_t
-get_freefunc(VALUE func)
+get_freefunc(VALUE func, volatile VALUE *wrap)
 {
+    VALUE addrnum;
     if (NIL_P(func)) {
+	*wrap = 0;
 	return NULL;
     }
     if (rb_dlcfunc_kind_p(func)) {
+	*wrap = func;
 	return (freefunc_t)(VALUE)RCFUNC_DATA(func)->ptr;
     }
-    return (freefunc_t)(VALUE)NUM2PTR(rb_Integer(func));
+    addrnum = rb_Integer(func);
+    *wrap = (addrnum != func) ? func : 0;
+    return (freefunc_t)(VALUE)NUM2PTR(addrnum);
 }
 
 static ID id_to_ptr;
 
 static void
+dlptr_mark(void *ptr)
+{
+    struct ptr_data *data = ptr;
+    if (data->wrap[0]) {
+	rb_gc_mark(data->wrap[0]);
+    }
+    if (data->wrap[1]) {
+	rb_gc_mark(data->wrap[1]);
+    }
+}
+
+static void
 dlptr_free(void *ptr)
 {
     struct ptr_data *data = ptr;
@@ -43,7 +60,7 @@
 
 static const rb_data_type_t dlptr_data_type = {
     "dl/ptr",
-    {0, dlptr_free, dlptr_memsize,},
+    {dlptr_mark, dlptr_free, dlptr_memsize,},
 };
 
 void
@@ -135,28 +152,23 @@
 static VALUE
 rb_dlptr_initialize(int argc, VALUE argv[], VALUE self)
 {
-    VALUE ptr, sym, size;
+    VALUE ptr, sym, size, wrap = 0, funcwrap = 0;
     struct ptr_data *data;
     void *p = NULL;
     freefunc_t f = NULL;
     long s = 0;
 
-    switch (rb_scan_args(argc, argv, "12", &ptr, &size, &sym)) {
-      case 1:
-	p = (void*)(NUM2PTR(rb_Integer(ptr)));
-	break;
-      case 2:
-	p = (void*)(NUM2PTR(rb_Integer(ptr)));
+    if (rb_scan_args(argc, argv, "12", &ptr, &size, &sym) >= 1) {
+	VALUE addrnum = rb_Integer(ptr);
+	if (addrnum != ptr) wrap = ptr;
+	p = NUM2PTR(addrnum);
+    }
+    if (argc >= 2) {
 	s = NUM2LONG(size);
-	break;
-      case 3:
-	p = (void*)(NUM2PTR(rb_Integer(ptr)));
-	s = NUM2LONG(size);
-	f = get_freefunc(sym);
-	break;
-      default:
-	rb_bug("rb_dlptr_initialize");
     }
+    if (argc >= 3) {
+	f = get_freefunc(sym, &funcwrap);
+    }
 
     if (p) {
 	TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
@@ -164,6 +176,8 @@
 	    /* Free previous memory. Use of inappropriate initialize may cause SEGV. */
 	    (*(data->free))(data->ptr);
 	}
+	data->wrap[0] = wrap;
+	data->wrap[1] = funcwrap;
 	data->ptr  = p;
 	data->size = s;
 	data->free = f;
@@ -185,7 +199,7 @@
 static VALUE
 rb_dlptr_s_malloc(int argc, VALUE argv[], VALUE klass)
 {
-    VALUE size, sym, obj;
+    VALUE size, sym, obj, wrap = 0;
     long s;
     freefunc_t f;
 
@@ -196,13 +210,14 @@
 	break;
       case 2:
 	s = NUM2LONG(size);
-	f = get_freefunc(sym);
+	f = get_freefunc(sym, &wrap);
 	break;
       default:
 	rb_bug("rb_dlptr_s_malloc");
     }
 
     obj = rb_dlptr_malloc(s,f);
+    if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;
 
     return obj;
 }
@@ -289,7 +304,7 @@
     struct ptr_data *data;
 
     TypedData_Get_Struct(self, struct ptr_data, &dlptr_data_type, data);
-    data->free = get_freefunc(val);
+    data->free = get_freefunc(val, &data->wrap[1]);
 
     return Qnil;
 }
@@ -588,7 +603,7 @@
 static VALUE
 rb_dlptr_s_to_ptr(VALUE self, VALUE val)
 {
-    VALUE ptr;
+    VALUE ptr, wrap = val, vptr;
 
     if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){
 	rb_io_t *fptr;
@@ -601,20 +616,22 @@
 	char *str = StringValuePtr(val);
 	ptr = rb_dlptr_new(str, RSTRING_LEN(val), NULL);
     }
-    else if (rb_respond_to(val, id_to_ptr)){
-	VALUE vptr = rb_funcall(val, id_to_ptr, 0);
+    else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){
 	if (rb_obj_is_kind_of(vptr, rb_cDLCPtr)){
 	    ptr = vptr;
+	    wrap = 0;
 	}
 	else{
 	    rb_raise(rb_eDLError, "to_ptr should return a CPtr object");
 	}
     }
     else{
-	ptr = rb_dlptr_new(NUM2PTR(rb_Integer(val)), 0, NULL);
+	VALUE num = rb_Integer(val);
+	if (num == val) wrap = 0;
+	ptr = rb_dlptr_new(NUM2PTR(num), 0, NULL);
     }
     OBJ_INFECT(ptr, val);
-    rb_iv_set(ptr, "wrapping", val);
+    if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
     return ptr;
 }
 
Index: ruby_1_9_3/version.h
===================================================================
--- ruby_1_9_3/version.h	(revision 34603)
+++ ruby_1_9_3/version.h	(revision 34604)
@@ -1,5 +1,5 @@
 #define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 114
+#define RUBY_PATCHLEVEL 115
 
 #define RUBY_RELEASE_DATE "2012-02-15"
 #define RUBY_RELEASE_YEAR 2012
Index: ruby_1_9_3/test/dl/test_func.rb
===================================================================
--- ruby_1_9_3/test/dl/test_func.rb	(revision 34603)
+++ ruby_1_9_3/test/dl/test_func.rb	(revision 34604)
@@ -95,6 +95,11 @@
       buff = "9341"
       qsort.call(buff, buff.size, 1, cb)
       assert_equal("1349", buff)
+
+      bug4929 = '[ruby-core:37395]'
+      buff = "9341"
+      EnvUtil.under_gc_stress {qsort.call(buff, buff.size, 1, cb)}
+      assert_equal("1349", buff, bug4929)
     end
 
     def test_qsort2()

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

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