Do not abort when unlinking non-data ruby objects

Fixes issue #1168.
Remove a call to abort() (introduced by commit
0e725b5d9b) made when SWIG_RubyUnlinkObjects()
is called on non T_DATA objects. It can happen when the destruction of T_DATA
objects is deferred: the Ruby GC first turn them to T_ZOMBIE, then calls their
free method (SWIG_RubyUnlinkObjects()).
This commit is contained in:
Cyrille Faucheux 2017-12-05 21:52:47 +01:00
commit a4884e45e1
2 changed files with 12 additions and 7 deletions

View file

@ -39,7 +39,11 @@ GC.start
# C++ object # C++ object
ok = false ok = false
begin begin
puts tiger2.get_name # Let's stress the GC a bit, a single pass might not be enough.
10.times {
GC.start
puts tiger2.get_name
}
rescue ObjectPreviouslyDeleted => error rescue ObjectPreviouslyDeleted => error
ok = true ok = true
end end

View file

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* rubytracking.swg * rubytracking.swg
* *
* This file contains support for tracking mappings from * This file contains support for tracking mappings from
* Ruby objects to C++ objects. This functionality is needed * Ruby objects to C++ objects. This functionality is needed
* to implement mark functions for Ruby's mark and sweep * to implement mark functions for Ruby's mark and sweep
* garbage collector. * garbage collector.
@ -28,7 +28,7 @@ extern "C" {
#endif #endif
/* Global hash table to store Trackings from C/C++ /* Global hash table to store Trackings from C/C++
structs to Ruby Objects. structs to Ruby Objects.
*/ */
static st_table* swig_ruby_trackings = NULL; static st_table* swig_ruby_trackings = NULL;
@ -42,7 +42,7 @@ SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
/* Create a hash table to store Trackings from C++ /* Create a hash table to store Trackings from C++
objects to Ruby objects. */ objects to Ruby objects. */
/* Try to see if some other .so has already created a /* Try to see if some other .so has already created a
tracking hash table, which we keep hidden in an instance var tracking hash table, which we keep hidden in an instance var
in the SWIG module. in the SWIG module.
This is done to allow multiple DSOs to share the same This is done to allow multiple DSOs to share the same
@ -101,13 +101,14 @@ SWIGRUNTIME void SWIG_RubyRemoveTracking(void* ptr) {
/* This is a helper method that unlinks a Ruby object from its /* This is a helper method that unlinks a Ruby object from its
underlying C++ object. This is needed if the lifetime of the underlying C++ object. This is needed if the lifetime of the
Ruby object is longer than the C++ object */ Ruby object is longer than the C++ object. */
SWIGRUNTIME void SWIG_RubyUnlinkObjects(void* ptr) { SWIGRUNTIME void SWIG_RubyUnlinkObjects(void* ptr) {
VALUE object = SWIG_RubyInstanceFor(ptr); VALUE object = SWIG_RubyInstanceFor(ptr);
if (object != Qnil) { if (object != Qnil) {
if (TYPE(object) != T_DATA) // object might have the T_ZOMBIE type, but that's just
abort(); // because the GC has flagged it as such for a deferred
// destruction. Until then, it's still a T_DATA object.
DATA_PTR(object) = 0; DATA_PTR(object) = 0;
} }
} }