Changeset 700

Show
Ignore:
Timestamp:
06/16/08 05:05:44 (4 months ago)
Author:
raggi
Message:
  • Merge forward trunk into branches/raggi
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/raggi/docs/ChangeLog

    r699 r700  
    11711715May08: Supported EM#get_sockname for acceptors (TCP server sockets). 
    118118        Requested by Roger Pack. 
     11915Jun08: Supported nested calls to EM#run. Many people contributed ideas to  
     120        this, notable raggi and tmm1. 
  • branches/raggi/lib/eventmachine.rb

    r683 r700  
    214214        # a C++ runtime error. 
    215215        # 
    216         def EventMachine::run &block 
    217                 @conns = {} 
    218                 @acceptors = {} 
    219                 @timers = {} 
    220                 begin 
    221                         @reactor_running = true 
    222                         initialize_event_machine 
    223                         block and add_timer 0, block 
    224                         run_machine 
    225                 ensure 
    226                         release_machine 
    227                         @reactor_running = false 
     216        def EventMachine::run blk=nil, tail=nil, &block 
     217                @tails ||= [] 
     218                tail and @tails.unshift(tail) 
     219 
     220                if reactor_running? 
     221                        (b = blk || block) and next_tick(b) 
     222                else 
     223                        @conns = {} 
     224                        @acceptors = {} 
     225                        @timers = {} 
     226                        begin 
     227                                @reactor_running = true 
     228                                initialize_event_machine 
     229                                (b = blk || block) and add_timer(0, b) 
     230                                run_machine 
     231                        ensure 
     232                                release_machine 
     233                                @reactor_running = false 
     234                        end 
     235 
     236                        until @tails.empty? 
     237                                @tails.pop.call 
     238                        end 
    228239                end 
    229240        end 
  • branches/raggi/tests/test_next_tick.rb

    r668 r700  
    5656                assert true 
    5757        end 
     58 
     59        # This illustrates the solution to a long-standing problem. 
     60        # It's now possible to correctly nest calls to EM#run. 
     61        # See the source code commentary for EM#run for more info. 
     62        # 
     63        def test_run_run 
     64                EM.run { 
     65                        EM.run { 
     66                                EM.next_tick {EM.stop} 
     67                        } 
     68                } 
     69        end 
     70 
     71        # We now support an additional parameter for EM#run. 
     72        # You can pass two procs to EM#run now. The first is executed as the normal 
     73        # run block. The second (if given) is scheduled for execution after the 
     74        # reactor loop completes. 
     75        # The reason for supporting this is subtle. There has always been an expectation 
     76        # that EM#run doesn't return until after the reactor loop ends. But now it's 
     77        # possible to nest calls to EM#run, which means that a nested call WILL 
     78        # RETURN. In order to write code that will run correctly either way, it's 
     79        # recommended to put any code which must execute after the reactor completes 
     80        # in the second parameter. 
     81        # 
     82        def test_run_run_2 
     83                a = proc {EM.stop} 
     84                b = proc {assert true} 
     85                EM.run a, b 
     86        end 
     87 
     88 
     89        # This illustrates that EM#run returns when it's called nested. 
     90        # This isn't a feature, rather it's something to be wary of when writing code 
     91        # that must run correctly even if EM#run is called while a reactor is already 
     92        # running. 
     93        def test_run_run_3 
     94                a = [] 
     95                EM.run { 
     96                        EM.run proc {EM.stop}, proc {a << 2} 
     97                        a << 1 
     98                } 
     99                assert_equal( [1,2], a ) 
     100        end 
     101 
    58102end