@@ -2954,6 +2954,42 @@ should_be_finalizable(VALUE obj)
29542954 rb_check_frozen (obj );
29552955}
29562956
2957+ struct should_not_capture_data {
2958+ VALUE obj ;
2959+ VALUE set ;
2960+ bool found ;
2961+ };
2962+
2963+ static void
2964+ should_not_capture_callback (const VALUE child , struct should_not_capture_data * data )
2965+ {
2966+ if (child == data -> obj )
2967+ data -> found = true;
2968+
2969+ if (data -> found )
2970+ return ;
2971+
2972+ // Maintain a set of objects already searched, so that we don't follow a cycle
2973+ VALUE key = rb_obj_id (child );
2974+ if (rb_hash_has_key (data -> set , key ))
2975+ return ;
2976+ rb_hash_aset (data -> set , key , Qtrue );
2977+
2978+ rb_objspace_reachable_objects_from (child , (void (* )(unsigned long , void * )) & should_not_capture_callback , (void * )data );
2979+ }
2980+
2981+ static void
2982+ should_not_capture (VALUE block , VALUE obj )
2983+ {
2984+ struct should_not_capture_data data ;
2985+ data .obj = obj ;
2986+ data .set = rb_hash_new ();
2987+ data .found = false;
2988+ rb_objspace_reachable_objects_from (block , (void (* )(unsigned long , void * )) & should_not_capture_callback , (void * )& data );
2989+ if (data .found )
2990+ rb_warn ("object is reachable from finalizer - it may never be run" );
2991+ }
2992+
29572993/*
29582994 * call-seq:
29592995 * ObjectSpace.define_finalizer(obj, aProc=proc())
@@ -2963,6 +2999,10 @@ should_be_finalizable(VALUE obj)
29632999 * as an argument to <i>aProc</i>. If <i>aProc</i> is a lambda or
29643000 * method, make sure it can be called with a single argument.
29653001 *
3002+ * In verbose mode (<code>-w</code>) a warning will be issued if
3003+ * the object is reachable from <i>aProc</i>, which may prevent
3004+ * finalization.
3005+ *
29663006 */
29673007
29683008static VALUE
@@ -2979,6 +3019,9 @@ define_final(int argc, VALUE *argv, VALUE os)
29793019 should_be_callable (block );
29803020 }
29813021
3022+ if (ruby_verbose )
3023+ should_not_capture (block , obj );
3024+
29823025 return define_final0 (obj , block );
29833026}
29843027
0 commit comments