Hi Phil.

> I'm trying to create processes that can wait for certain events to
> occur before continuing on.  I'm using continuations (callcc) to do
> this, but it seems like the continuation is carrying a lot more
> context around than I would like it to.

I used continuations in some of my classes but I still sometimes 
have problems to really understand them. So I don't know exactly 
what's wrong with your code. But here's a variation of your 
T_process class that seems to do what you want with a slightly 
different interface. Maybe you can tweak it to your needs. It uses 
two continuations, a technique shown in [ruby-talk:20212] and 
[ruby-talk:20270].

Below is the code and some unit tests.

Regards,
Pit

---------------- file tprocess.rb

class T_process

  def initialize( &callable )
    @callable = callable
  end

  def call
    callcc do
      | @return_from_call |
      if @retry_wait
        @retry_wait.call
      else
        @callable.call( self )
      end
      @return_from_call.call
    end
    @return_from_call = nil
  end

  def wait( &cond )
    until cond.call
      callcc do
        | @retry_wait |
        @return_from_call.call
      end
      @retry_wait = nil
    end
  end

end

---------------- file tprocess_test.rb

require 'test/unit'
require 'tprocess'

class T_process_test < Test::Unit::TestCase

  def test01_no_wait
    out = []
    process = T_process.new do
      out << 1
    end
    assert_equal( [], out, 'before call' )
    process.call
    assert_equal( [ 1 ], out, 'after call' )
  end

  def test02_single_wait
    out = []
    process = T_process.new do
      | pr |
      out << 1
      pr.wait { true }
      out << 2
    end
    assert_equal( [], out, 'before call' )
    process.call
    assert_equal( [ 1, 2 ], out, 'after call' )
  end

  def test03_multiple_waits
    out = []
    continue_flag = false
    process = T_process.new do
      | pr |
      out << 1
      pr.wait do
        out << 2
        continue_flag
      end
      out << 3
    end
    assert_equal( [], out, 'before call' )
    process.call
    assert_equal( [ 1, 2 ], out, 'after 1. call' )
    process.call
    assert_equal( [ 1, 2, 2 ], out, 'after 2. call' )
    process.call
    assert_equal( [ 1, 2, 2, 2 ], out, 'after 3. call' )
    continue_flag = true
    process.call
    assert_equal( [ 1, 2, 2, 2, 2, 3 ], out, 'after 4. call' )
  end
  
  def test04_multiple_calls
    out = []
    continue_flag = false
    process = T_process.new do
      | pr |
      out << 1
      pr.wait do
        out << 2
        continue_flag
      end
      out << 3
    end
    assert_equal( [], out, 'before call' )
    process.call
    assert_equal( [ 1, 2 ], out, 'after 1. call' )
    process.call
    assert_equal( [ 1, 2, 2 ], out, 'after 2. call' )
    continue_flag = true
    process.call
    assert_equal( [ 1, 2, 2, 2, 3 ], out, 'after 3. call' )
    continue_flag = false
    process.call
    assert_equal( [ 1, 2, 2, 2, 3, 1, 2 ], out, 'after 4. call' )
    continue_flag = true
    process.call
    assert_equal( [ 1, 2, 2, 2, 3, 1, 2, 2, 3 ], out, 'after 5. call' )
  end

end