From: "Christoffer Lernö" Date: 2006-02-18T20:24:31+09:00 Subject: Still trying to grok GC & continuations Hello continuation gurus and others! I still don't understand why I keep having so many non-gc:ed continuations in my code. Below is some sample code where each coroutine seem intent on hogging 3 continuations each. I don't see why I shouldn't be able to cut that number down to a single continuation each. Cutting and pasting the code below and running it should give a printout of continuations------------------------------------- wait<3> wait<2> exit exit init init Currently using: 6 continuations -------------------------------------------------- I would prefer to only keep the first 2, but I can't seem to make that happen. *sigh* /Christoffer 8<----------------------------- ugly test code starts here ----------------------------------- class StateLess end class Continuation attr_accessor :tag def to_s "#{tag}" end end class TestStateLess < StateLess attr_reader :value def initialize @value = "" callcc do |continuation| continuation.tag = "init" @continuation = continuation return end run end def run(*arg) @value += "retry;" while wait(1) !~ /password/ @value += "passed;" wait(2) @value +="passed2;" wait(3) end def wait(position) @value += "waiting_at_#{position};" @continuation = nil callcc do |continuation| continuation.tag = "wait<#{position}>" @continuation = continuation @exit.call end end def go(*arg) callcc do |exit| exit.tag = "exit<#{arg}>" @exit = exit @continuation.call(*arg) end @exit = nil end end include ObjectSpace def count_cc garbage_collect i = 0 puts "continuations-------------------------------------" ObjectSpace.each_object(Continuation) {|x| puts x; i += 1 } puts "Currently using: " + i.to_s + " continuations" puts "--------------------------------------------------" end require 'test/unit' class Tests < Test::Unit::TestCase def test_twin a = TestStateLess.new b = TestStateLess.new assert_equal("", a.value) a.go('a') assert_equal("waiting_at_1;", a.value) b.go('b') a.go("passvoid") assert_equal("waiting_at_1;retry;waiting_at_1;", a.value) b.go("password") assert_equal("waiting_at_1;passed;waiting_at_2;", b.value) a.go("password") assert_equal ("waiting_at_1;retry;waiting_at_1;passed;waiting_at_2;", a.value) b.go("spam") assert_equal ("waiting_at_1;passed;waiting_at_2;passed2;waiting_at_3;", b.value) count_cc end end