summaryrefslogtreecommitdiff
path: root/ext/dl/cfunc.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-27 17:15:09 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-27 17:15:09 +0000
commit9f3914aba6fe3df5a1c4382b655fb0a7df0cdbfa (patch)
treed2b7e665bf743738cfd41133d522a5d659aa9ff8 /ext/dl/cfunc.c
parent5c815b733d90a82d0d708d836c9a98c9704d8ad4 (diff)
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32712 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/dl/cfunc.c')
-rw-r--r--ext/dl/cfunc.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/ext/dl/cfunc.c b/ext/dl/cfunc.c
index a050ab04b37..f076c6f432c 100644
--- a/ext/dl/cfunc.c
+++ b/ext/dl/cfunc.c
@@ -41,6 +41,14 @@ rb_dl_set_win32_last_error(VALUE self, VALUE val)
}
#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 @@ dlcfunc_memsize(const void *ptr)
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 @@ rb_dlcfunc_kind_p(VALUE func)
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 @@ rb_dlcfunc_initialize(int argc, VALUE argv[], VALUE self)
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;
}