polyphony 0.19 → 0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.gitignore +1 -1
 - data/.rubocop.yml +87 -1
 - data/CHANGELOG.md +35 -0
 - data/Gemfile.lock +17 -6
 - data/README.md +200 -139
 - data/Rakefile +4 -4
 - data/TODO.md +35 -7
 - data/bin/poly +11 -0
 - data/docs/getting-started/getting-started.md +1 -1
 - data/docs/summary.md +3 -0
 - data/docs/technical-overview/exception-handling.md +94 -0
 - data/docs/technical-overview/fiber-scheduling.md +99 -0
 - data/examples/core/cancel.rb +8 -4
 - data/examples/core/channel_echo.rb +18 -17
 - data/examples/core/defer.rb +12 -0
 - data/examples/core/enumerator.rb +4 -4
 - data/examples/core/fiber_error.rb +9 -0
 - data/examples/core/fiber_error_with_backtrace.rb +73 -0
 - data/examples/core/fork.rb +6 -6
 - data/examples/core/genserver.rb +16 -8
 - data/examples/core/lock.rb +3 -3
 - data/examples/core/move_on.rb +4 -3
 - data/examples/core/move_on_twice.rb +5 -5
 - data/examples/core/move_on_with_ensure.rb +8 -11
 - data/examples/core/move_on_with_value.rb +14 -0
 - data/examples/core/{multiple_spawn.rb → multiple_spin.rb} +5 -5
 - data/examples/core/nested_cancel.rb +5 -5
 - data/examples/core/{nested_multiple_spawn.rb → nested_multiple_spin.rb} +6 -6
 - data/examples/core/nested_spin.rb +17 -0
 - data/examples/core/pingpong.rb +21 -0
 - data/examples/core/pulse.rb +4 -5
 - data/examples/core/resource.rb +6 -4
 - data/examples/core/resource_cancel.rb +6 -9
 - data/examples/core/resource_delegate.rb +3 -3
 - data/examples/core/sleep.rb +3 -3
 - data/examples/core/sleep_spin.rb +19 -0
 - data/examples/core/snooze.rb +32 -0
 - data/examples/core/spin.rb +14 -0
 - data/examples/core/{spawn_cancel.rb → spin_cancel.rb} +6 -7
 - data/examples/core/spin_error.rb +17 -0
 - data/examples/core/spin_error_backtrace.rb +30 -0
 - data/examples/core/spin_uncaught_error.rb +15 -0
 - data/examples/core/supervisor.rb +8 -8
 - data/examples/core/supervisor_with_cancel_scope.rb +7 -7
 - data/examples/core/supervisor_with_error.rb +8 -8
 - data/examples/core/supervisor_with_manual_move_on.rb +6 -7
 - data/examples/core/suspend.rb +13 -0
 - data/examples/core/thread.rb +1 -1
 - data/examples/core/thread_cancel.rb +9 -11
 - data/examples/core/thread_pool.rb +18 -14
 - data/examples/core/throttle.rb +7 -7
 - data/examples/core/timeout.rb +3 -3
 - data/examples/fs/read.rb +7 -9
 - data/examples/http/config.ru +7 -3
 - data/examples/http/cuba.ru +22 -0
 - data/examples/http/happy_eyeballs.rb +6 -4
 - data/examples/http/http_client.rb +1 -1
 - data/examples/http/http_get.rb +1 -1
 - data/examples/http/http_parse_experiment.rb +21 -16
 - data/examples/http/http_proxy.rb +28 -26
 - data/examples/http/http_server.rb +10 -10
 - data/examples/http/http_server_forked.rb +6 -5
 - data/examples/http/http_server_throttled.rb +3 -3
 - data/examples/http/http_ws_server.rb +11 -11
 - data/examples/http/https_raw_client.rb +1 -1
 - data/examples/http/https_server.rb +8 -8
 - data/examples/http/https_wss_server.rb +13 -11
 - data/examples/http/rack_server.rb +2 -2
 - data/examples/http/rack_server_https.rb +4 -4
 - data/examples/http/rack_server_https_forked.rb +5 -5
 - data/examples/http/websocket_secure_server.rb +6 -6
 - data/examples/http/websocket_server.rb +5 -5
 - data/examples/interfaces/pg_client.rb +4 -4
 - data/examples/interfaces/pg_pool.rb +13 -6
 - data/examples/interfaces/pg_transaction.rb +5 -4
 - data/examples/interfaces/redis_channels.rb +15 -11
 - data/examples/interfaces/redis_client.rb +2 -2
 - data/examples/interfaces/redis_pubsub.rb +2 -1
 - data/examples/interfaces/redis_pubsub_perf.rb +13 -9
 - data/examples/io/backticks.rb +11 -0
 - data/examples/io/cat.rb +4 -5
 - data/examples/io/echo_client.rb +9 -4
 - data/examples/io/echo_client_from_stdin.rb +20 -0
 - data/examples/io/echo_pipe.rb +7 -8
 - data/examples/io/echo_server.rb +8 -6
 - data/examples/io/echo_server_with_timeout.rb +13 -10
 - data/examples/io/echo_stdin.rb +3 -3
 - data/examples/io/httparty.rb +2 -2
 - data/examples/io/httparty_multi.rb +8 -4
 - data/examples/io/httparty_threaded.rb +6 -2
 - data/examples/io/io_read.rb +2 -2
 - data/examples/io/irb.rb +16 -4
 - data/examples/io/net-http.rb +3 -3
 - data/examples/io/open.rb +17 -0
 - data/examples/io/system.rb +3 -3
 - data/examples/io/tcpserver.rb +15 -0
 - data/examples/io/tcpsocket.rb +6 -5
 - data/examples/performance/multi_snooze.rb +29 -0
 - data/examples/performance/{perf_snooze.rb → snooze.rb} +7 -5
 - data/examples/performance/snooze_raw.rb +39 -0
 - data/ext/gyro/async.c +165 -0
 - data/ext/gyro/child.c +167 -0
 - data/ext/{ev → gyro}/extconf.rb +4 -3
 - data/ext/gyro/gyro.c +316 -0
 - data/ext/{ev/ev.h → gyro/gyro.h} +12 -7
 - data/ext/gyro/gyro_ext.c +23 -0
 - data/ext/{ev → gyro}/io.c +65 -57
 - data/ext/{ev → gyro}/libev.h +0 -0
 - data/ext/gyro/signal.c +117 -0
 - data/ext/{ev → gyro}/socket.c +61 -6
 - data/ext/gyro/timer.c +199 -0
 - data/ext/libev/Changes +35 -0
 - data/ext/libev/README +2 -1
 - data/ext/libev/ev.c +213 -151
 - data/ext/libev/ev.h +95 -88
 - data/ext/libev/ev_epoll.c +26 -15
 - data/ext/libev/ev_kqueue.c +11 -5
 - data/ext/libev/ev_linuxaio.c +642 -0
 - data/ext/libev/ev_poll.c +13 -8
 - data/ext/libev/ev_port.c +5 -2
 - data/ext/libev/ev_vars.h +14 -3
 - data/ext/libev/ev_wrap.h +16 -0
 - data/lib/ev_ext.bundle +0 -0
 - data/lib/polyphony.rb +46 -50
 - data/lib/polyphony/auto_run.rb +12 -0
 - data/lib/polyphony/core/cancel_scope.rb +11 -7
 - data/lib/polyphony/core/channel.rb +16 -9
 - data/lib/polyphony/core/coprocess.rb +101 -51
 - data/lib/polyphony/core/exceptions.rb +14 -12
 - data/lib/polyphony/core/resource_pool.rb +21 -8
 - data/lib/polyphony/core/supervisor.rb +10 -5
 - data/lib/polyphony/core/sync.rb +7 -6
 - data/lib/polyphony/core/thread.rb +4 -4
 - data/lib/polyphony/core/thread_pool.rb +4 -4
 - data/lib/polyphony/core/throttler.rb +6 -4
 - data/lib/polyphony/extensions/core.rb +253 -0
 - data/lib/polyphony/extensions/io.rb +28 -16
 - data/lib/polyphony/extensions/openssl.rb +2 -1
 - data/lib/polyphony/extensions/socket.rb +47 -52
 - data/lib/polyphony/http.rb +4 -3
 - data/lib/polyphony/http/agent.rb +68 -57
 - data/lib/polyphony/http/server.rb +5 -5
 - data/lib/polyphony/http/server/http1.rb +268 -0
 - data/lib/polyphony/http/server/http2.rb +62 -0
 - data/lib/polyphony/http/server/http2_stream.rb +104 -0
 - data/lib/polyphony/http/server/rack.rb +64 -0
 - data/lib/polyphony/http/server/request.rb +119 -0
 - data/lib/polyphony/net.rb +26 -15
 - data/lib/polyphony/postgres.rb +17 -13
 - data/lib/polyphony/redis.rb +16 -15
 - data/lib/polyphony/version.rb +1 -1
 - data/lib/polyphony/websocket.rb +11 -4
 - data/polyphony.gemspec +13 -9
 - data/test/eg.rb +27 -0
 - data/test/helper.rb +25 -0
 - data/test/run.rb +5 -0
 - data/test/test_async.rb +33 -0
 - data/test/test_coprocess.rb +239 -77
 - data/test/test_core.rb +95 -61
 - data/test/test_gyro.rb +148 -0
 - data/test/test_http_server.rb +313 -0
 - data/test/test_io.rb +79 -27
 - data/test/test_kernel.rb +22 -12
 - data/test/test_signal.rb +36 -0
 - data/test/test_timer.rb +24 -0
 - metadata +89 -33
 - data/examples/core/nested_async.rb +0 -17
 - data/examples/core/next_tick.rb +0 -12
 - data/examples/core/sleep_spawn.rb +0 -19
 - data/examples/core/spawn.rb +0 -14
 - data/examples/core/spawn_error.rb +0 -28
 - data/examples/performance/perf_multi_snooze.rb +0 -21
 - data/ext/ev/async.c +0 -168
 - data/ext/ev/child.c +0 -169
 - data/ext/ev/ev_ext.c +0 -23
 - data/ext/ev/ev_module.c +0 -242
 - data/ext/ev/signal.c +0 -119
 - data/ext/ev/timer.c +0 -197
 - data/lib/polyphony/core/fiber_pool.rb +0 -98
 - data/lib/polyphony/extensions/kernel.rb +0 -169
 - data/lib/polyphony/http/http1_adapter.rb +0 -254
 - data/lib/polyphony/http/http2_adapter.rb +0 -157
 - data/lib/polyphony/http/rack.rb +0 -25
 - data/lib/polyphony/http/request.rb +0 -66
 - data/test/test_ev.rb +0 -110
 
| 
         @@ -1,17 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require 'bundler/setup'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'polyphony'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            spin do
         
     | 
| 
       7 
     | 
    
         
            -
              puts "going to sleep"
         
     | 
| 
       8 
     | 
    
         
            -
              result = async do
         
     | 
| 
       9 
     | 
    
         
            -
                async do
         
     | 
| 
       10 
     | 
    
         
            -
                  async do
         
     | 
| 
       11 
     | 
    
         
            -
                    puts "Fiber count: #{Polyphony::FiberPool.size}"
         
     | 
| 
       12 
     | 
    
         
            -
                    sleep(1)
         
     | 
| 
       13 
     | 
    
         
            -
                  end.await
         
     | 
| 
       14 
     | 
    
         
            -
                end.await
         
     | 
| 
       15 
     | 
    
         
            -
              end.await
         
     | 
| 
       16 
     | 
    
         
            -
              puts "result: #{result}"
         
     | 
| 
       17 
     | 
    
         
            -
            end
         
     | 
    
        data/examples/core/next_tick.rb
    DELETED
    
    
    
        data/examples/core/spawn.rb
    DELETED
    
    
| 
         @@ -1,28 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require 'bundler/setup'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'polyphony'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            Polyphony.debug = true
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            def error(t)
         
     | 
| 
       9 
     | 
    
         
            -
              raise "hello #{t}"
         
     | 
| 
       10 
     | 
    
         
            -
            end
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            def spin_with_error
         
     | 
| 
       13 
     | 
    
         
            -
              spin { error(2) }
         
     | 
| 
       14 
     | 
    
         
            -
            end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            spin do
         
     | 
| 
       17 
     | 
    
         
            -
              error(1)
         
     | 
| 
       18 
     | 
    
         
            -
            rescue => e
         
     | 
| 
       19 
     | 
    
         
            -
              e.cleanup_backtrace
         
     | 
| 
       20 
     | 
    
         
            -
              puts "error: #{e.inspect}"
         
     | 
| 
       21 
     | 
    
         
            -
              puts "backtrace:"
         
     | 
| 
       22 
     | 
    
         
            -
              puts e.backtrace.reverse.join("\n")
         
     | 
| 
       23 
     | 
    
         
            -
              puts
         
     | 
| 
       24 
     | 
    
         
            -
            end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            spin_with_error
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            puts "done coprocing"
         
     | 
| 
         @@ -1,21 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require 'bundler/setup'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'polyphony'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            ITERATIONS  = 1_000
         
     | 
| 
       7 
     | 
    
         
            -
            FIBERS      = 1_000
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            spin do
         
     | 
| 
       10 
     | 
    
         
            -
              count = 0
         
     | 
| 
       11 
     | 
    
         
            -
              t0 = Time.now
         
     | 
| 
       12 
     | 
    
         
            -
              supervise do |s|
         
     | 
| 
       13 
     | 
    
         
            -
                FIBERS.times do
         
     | 
| 
       14 
     | 
    
         
            -
                  s.spin do
         
     | 
| 
       15 
     | 
    
         
            -
                    ITERATIONS.times { snooze; count += 1 }
         
     | 
| 
       16 
     | 
    
         
            -
                  end
         
     | 
| 
       17 
     | 
    
         
            -
                end
         
     | 
| 
       18 
     | 
    
         
            -
              end
         
     | 
| 
       19 
     | 
    
         
            -
              dt = Time.now - t0
         
     | 
| 
       20 
     | 
    
         
            -
              puts "count: #{count} #{count / dt.to_f}/s"
         
     | 
| 
       21 
     | 
    
         
            -
            end
         
     | 
    
        data/ext/ev/async.c
    DELETED
    
    | 
         @@ -1,168 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #include "ev.h"
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            struct EV_Async {
         
     | 
| 
       4 
     | 
    
         
            -
              struct  ev_async ev_async;
         
     | 
| 
       5 
     | 
    
         
            -
              int     active;
         
     | 
| 
       6 
     | 
    
         
            -
              VALUE   callback;
         
     | 
| 
       7 
     | 
    
         
            -
              VALUE   fiber;
         
     | 
| 
       8 
     | 
    
         
            -
            };
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
            static VALUE mEV = Qnil;
         
     | 
| 
       11 
     | 
    
         
            -
            static VALUE cEV_Async = Qnil;
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            /* Allocator/deallocator */
         
     | 
| 
       14 
     | 
    
         
            -
            static VALUE EV_Async_allocate(VALUE klass);
         
     | 
| 
       15 
     | 
    
         
            -
            static void EV_Async_mark(void *ptr);
         
     | 
| 
       16 
     | 
    
         
            -
            static void EV_Async_free(void *ptr);
         
     | 
| 
       17 
     | 
    
         
            -
            static size_t EV_Async_size(const void *ptr);
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            /* Methods */
         
     | 
| 
       20 
     | 
    
         
            -
            static VALUE EV_Async_initialize(VALUE self);
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            static VALUE EV_Async_start(VALUE self);
         
     | 
| 
       23 
     | 
    
         
            -
            static VALUE EV_Async_stop(VALUE self);
         
     | 
| 
       24 
     | 
    
         
            -
            static VALUE EV_Async_signal(VALUE self);
         
     | 
| 
       25 
     | 
    
         
            -
            static VALUE EV_Async_await(VALUE self);
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
            void EV_Async_callback(ev_loop *ev_loop, struct ev_async *async, int revents);
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            /* async encapsulates an async watcher */
         
     | 
| 
       30 
     | 
    
         
            -
            void Init_EV_Async() {
         
     | 
| 
       31 
     | 
    
         
            -
              mEV = rb_define_module("EV");
         
     | 
| 
       32 
     | 
    
         
            -
              
         
     | 
| 
       33 
     | 
    
         
            -
              cEV_Async = rb_define_class_under(mEV, "Async", rb_cData);
         
     | 
| 
       34 
     | 
    
         
            -
              rb_define_alloc_func(cEV_Async, EV_Async_allocate);
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
              rb_define_method(cEV_Async, "initialize", EV_Async_initialize, 0);
         
     | 
| 
       37 
     | 
    
         
            -
              rb_define_method(cEV_Async, "start", EV_Async_start, 0);
         
     | 
| 
       38 
     | 
    
         
            -
              rb_define_method(cEV_Async, "stop", EV_Async_stop, 0);
         
     | 
| 
       39 
     | 
    
         
            -
              rb_define_method(cEV_Async, "signal!", EV_Async_signal, 0);
         
     | 
| 
       40 
     | 
    
         
            -
              rb_define_method(cEV_Async, "await", EV_Async_await, 0);
         
     | 
| 
       41 
     | 
    
         
            -
            }
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
            static const rb_data_type_t EV_Async_type = {
         
     | 
| 
       44 
     | 
    
         
            -
                "EV_Async",
         
     | 
| 
       45 
     | 
    
         
            -
                {EV_Async_mark, EV_Async_free, EV_Async_size,},
         
     | 
| 
       46 
     | 
    
         
            -
                0, 0,
         
     | 
| 
       47 
     | 
    
         
            -
                RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
       48 
     | 
    
         
            -
            };
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
            static VALUE EV_Async_allocate(VALUE klass) {
         
     | 
| 
       51 
     | 
    
         
            -
              struct EV_Async *async = (struct EV_Async *)xmalloc(sizeof(struct EV_Async));
         
     | 
| 
       52 
     | 
    
         
            -
              return TypedData_Wrap_Struct(klass, &EV_Async_type, async);
         
     | 
| 
       53 
     | 
    
         
            -
            }
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            static void EV_Async_mark(void *ptr) {
         
     | 
| 
       56 
     | 
    
         
            -
              struct EV_Async *async = ptr;
         
     | 
| 
       57 
     | 
    
         
            -
              if (async->callback != Qnil) {
         
     | 
| 
       58 
     | 
    
         
            -
                rb_gc_mark(async->callback);
         
     | 
| 
       59 
     | 
    
         
            -
              }
         
     | 
| 
       60 
     | 
    
         
            -
              if (async->fiber != Qnil) {
         
     | 
| 
       61 
     | 
    
         
            -
                rb_gc_mark(async->fiber);
         
     | 
| 
       62 
     | 
    
         
            -
              }
         
     | 
| 
       63 
     | 
    
         
            -
            }
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
            static void EV_Async_free(void *ptr) {
         
     | 
| 
       66 
     | 
    
         
            -
              struct EV_Async *async = ptr;
         
     | 
| 
       67 
     | 
    
         
            -
              ev_async_stop(EV_DEFAULT, &async->ev_async);
         
     | 
| 
       68 
     | 
    
         
            -
              xfree(async);
         
     | 
| 
       69 
     | 
    
         
            -
            }
         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
            static size_t EV_Async_size(const void *ptr) {
         
     | 
| 
       72 
     | 
    
         
            -
              return sizeof(struct EV_Async);
         
     | 
| 
       73 
     | 
    
         
            -
            }
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
            #define GetEV_Async(obj, async) \
         
     | 
| 
       76 
     | 
    
         
            -
              TypedData_Get_Struct((obj), struct EV_Async, &EV_Async_type, (async))
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
            static VALUE EV_Async_initialize(VALUE self) {
         
     | 
| 
       79 
     | 
    
         
            -
              struct EV_Async *async;
         
     | 
| 
       80 
     | 
    
         
            -
              GetEV_Async(self, async);
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
              if (rb_block_given_p()) {
         
     | 
| 
       83 
     | 
    
         
            -
                async->callback = rb_block_proc();
         
     | 
| 
       84 
     | 
    
         
            -
              }
         
     | 
| 
       85 
     | 
    
         
            -
              async->fiber = Qnil;
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
              ev_async_init(&async->ev_async, EV_Async_callback);
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
              async->active = 1;
         
     | 
| 
       90 
     | 
    
         
            -
              ev_async_start(EV_DEFAULT, &async->ev_async);
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
              return Qnil;
         
     | 
| 
       93 
     | 
    
         
            -
            }
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
            void EV_Async_callback(ev_loop *ev_loop, struct ev_async *ev_async, int revents) {
         
     | 
| 
       96 
     | 
    
         
            -
              VALUE fiber;
         
     | 
| 
       97 
     | 
    
         
            -
              struct EV_Async *async = (struct EV_Async*)ev_async;
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
              if (async->fiber != Qnil) {
         
     | 
| 
       100 
     | 
    
         
            -
                async->active = 0;
         
     | 
| 
       101 
     | 
    
         
            -
                fiber = async->fiber;
         
     | 
| 
       102 
     | 
    
         
            -
                async->fiber = Qnil;
         
     | 
| 
       103 
     | 
    
         
            -
                SCHEDULE_FIBER(fiber, 0);
         
     | 
| 
       104 
     | 
    
         
            -
              }
         
     | 
| 
       105 
     | 
    
         
            -
              else if (async->callback != Qnil) {
         
     | 
| 
       106 
     | 
    
         
            -
                rb_funcall(async->callback, ID_call, 1, Qtrue);
         
     | 
| 
       107 
     | 
    
         
            -
              }
         
     | 
| 
       108 
     | 
    
         
            -
            }
         
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
            static VALUE EV_Async_start(VALUE self) {
         
     | 
| 
       111 
     | 
    
         
            -
              struct EV_Async *async;
         
     | 
| 
       112 
     | 
    
         
            -
              GetEV_Async(self, async);
         
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
              if (!async->active) {
         
     | 
| 
       115 
     | 
    
         
            -
                ev_async_start(EV_DEFAULT, &async->ev_async);
         
     | 
| 
       116 
     | 
    
         
            -
                async->active = 1;
         
     | 
| 
       117 
     | 
    
         
            -
              }
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
              return self;
         
     | 
| 
       120 
     | 
    
         
            -
            }
         
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
            static VALUE EV_Async_stop(VALUE self) {
         
     | 
| 
       123 
     | 
    
         
            -
              struct EV_Async *async;
         
     | 
| 
       124 
     | 
    
         
            -
              GetEV_Async(self, async);
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
              if (async->active) {
         
     | 
| 
       127 
     | 
    
         
            -
                ev_async_stop(EV_DEFAULT, &async->ev_async);
         
     | 
| 
       128 
     | 
    
         
            -
                async->active = 0;
         
     | 
| 
       129 
     | 
    
         
            -
              }
         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
              return self;
         
     | 
| 
       132 
     | 
    
         
            -
            }
         
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
            static VALUE EV_Async_signal(VALUE self) {
         
     | 
| 
       135 
     | 
    
         
            -
              struct EV_Async *async;
         
     | 
| 
       136 
     | 
    
         
            -
              GetEV_Async(self, async);
         
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
              ev_async_send(EV_DEFAULT, &async->ev_async);
         
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
              return Qnil;
         
     | 
| 
       141 
     | 
    
         
            -
            }
         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
            static VALUE EV_Async_await(VALUE self) {
         
     | 
| 
       144 
     | 
    
         
            -
              struct EV_Async *async;
         
     | 
| 
       145 
     | 
    
         
            -
              VALUE ret;
         
     | 
| 
       146 
     | 
    
         
            -
              
         
     | 
| 
       147 
     | 
    
         
            -
              GetEV_Async(self, async);
         
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
              async->fiber = rb_fiber_current();
         
     | 
| 
       150 
     | 
    
         
            -
              if (!async->active) {
         
     | 
| 
       151 
     | 
    
         
            -
                async->active = 1;
         
     | 
| 
       152 
     | 
    
         
            -
                ev_async_start(EV_DEFAULT, &async->ev_async);
         
     | 
| 
       153 
     | 
    
         
            -
              }
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
              ret = YIELD_TO_REACTOR();
         
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
              // fiber is resumed
         
     | 
| 
       158 
     | 
    
         
            -
              if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) {
         
     | 
| 
       159 
     | 
    
         
            -
                if (async->active) {
         
     | 
| 
       160 
     | 
    
         
            -
                  async->active = 0;
         
     | 
| 
       161 
     | 
    
         
            -
                  ev_async_stop(EV_DEFAULT, &async->ev_async);
         
     | 
| 
       162 
     | 
    
         
            -
                }
         
     | 
| 
       163 
     | 
    
         
            -
                return rb_funcall(ret, ID_raise, 1, ret);
         
     | 
| 
       164 
     | 
    
         
            -
              }
         
     | 
| 
       165 
     | 
    
         
            -
              else {
         
     | 
| 
       166 
     | 
    
         
            -
                return Qnil;
         
     | 
| 
       167 
     | 
    
         
            -
              }
         
     | 
| 
       168 
     | 
    
         
            -
            }
         
     | 
    
        data/ext/ev/child.c
    DELETED
    
    | 
         @@ -1,169 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #include "ev.h"
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            struct EV_Child {
         
     | 
| 
       4 
     | 
    
         
            -
              struct  ev_child ev_child;
         
     | 
| 
       5 
     | 
    
         
            -
              int     active;
         
     | 
| 
       6 
     | 
    
         
            -
              int     pid;
         
     | 
| 
       7 
     | 
    
         
            -
              VALUE   self;
         
     | 
| 
       8 
     | 
    
         
            -
              VALUE   callback;
         
     | 
| 
       9 
     | 
    
         
            -
              VALUE   fiber;
         
     | 
| 
       10 
     | 
    
         
            -
            };
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            static VALUE mEV = Qnil;
         
     | 
| 
       13 
     | 
    
         
            -
            static VALUE cEV_Child = Qnil;
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            /* Allocator/deallocator */
         
     | 
| 
       16 
     | 
    
         
            -
            static VALUE EV_Child_allocate(VALUE klass);
         
     | 
| 
       17 
     | 
    
         
            -
            static void EV_Child_mark(void *ptr);
         
     | 
| 
       18 
     | 
    
         
            -
            static void EV_Child_free(void *ptr);
         
     | 
| 
       19 
     | 
    
         
            -
            static size_t EV_Child_size(const void *ptr);
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
            /* Methods */
         
     | 
| 
       22 
     | 
    
         
            -
            static VALUE EV_Child_initialize(VALUE self, VALUE pid);
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            static VALUE EV_Child_start(VALUE self);
         
     | 
| 
       25 
     | 
    
         
            -
            static VALUE EV_Child_stop(VALUE self);
         
     | 
| 
       26 
     | 
    
         
            -
            static VALUE EV_Child_await(VALUE self);
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            void EV_Child_callback(ev_loop *ev_loop, struct ev_child *child, int revents);
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            /* Child encapsulates an child watcher */
         
     | 
| 
       31 
     | 
    
         
            -
            void Init_EV_Child() {
         
     | 
| 
       32 
     | 
    
         
            -
              mEV = rb_define_module("EV");
         
     | 
| 
       33 
     | 
    
         
            -
              cEV_Child = rb_define_class_under(mEV, "Child", rb_cData);
         
     | 
| 
       34 
     | 
    
         
            -
              rb_define_alloc_func(cEV_Child, EV_Child_allocate);
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
              rb_define_method(cEV_Child, "initialize", EV_Child_initialize, 1);
         
     | 
| 
       37 
     | 
    
         
            -
              rb_define_method(cEV_Child, "start", EV_Child_start, 0);
         
     | 
| 
       38 
     | 
    
         
            -
              rb_define_method(cEV_Child, "stop", EV_Child_stop, 0);
         
     | 
| 
       39 
     | 
    
         
            -
              rb_define_method(cEV_Child, "await", EV_Child_await, 0);
         
     | 
| 
       40 
     | 
    
         
            -
            }
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
            static const rb_data_type_t EV_Child_type = {
         
     | 
| 
       43 
     | 
    
         
            -
                "EV_Child",
         
     | 
| 
       44 
     | 
    
         
            -
                {EV_Child_mark, EV_Child_free, EV_Child_size,},
         
     | 
| 
       45 
     | 
    
         
            -
                0, 0,
         
     | 
| 
       46 
     | 
    
         
            -
                RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
       47 
     | 
    
         
            -
            };
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
            static VALUE EV_Child_allocate(VALUE klass) {
         
     | 
| 
       50 
     | 
    
         
            -
              struct EV_Child *child = (struct EV_Child *)xmalloc(sizeof(struct EV_Child));
         
     | 
| 
       51 
     | 
    
         
            -
              return TypedData_Wrap_Struct(klass, &EV_Child_type, child);
         
     | 
| 
       52 
     | 
    
         
            -
            }
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
            static void EV_Child_mark(void *ptr) {
         
     | 
| 
       55 
     | 
    
         
            -
              struct EV_Child *child = ptr;
         
     | 
| 
       56 
     | 
    
         
            -
              if (child->callback != Qnil) {
         
     | 
| 
       57 
     | 
    
         
            -
                rb_gc_mark(child->callback);
         
     | 
| 
       58 
     | 
    
         
            -
              }
         
     | 
| 
       59 
     | 
    
         
            -
              if (child->fiber != Qnil) {
         
     | 
| 
       60 
     | 
    
         
            -
                rb_gc_mark(child->fiber);
         
     | 
| 
       61 
     | 
    
         
            -
              }
         
     | 
| 
       62 
     | 
    
         
            -
            }
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
            static void EV_Child_free(void *ptr) {
         
     | 
| 
       65 
     | 
    
         
            -
              struct EV_Child *child = ptr;
         
     | 
| 
       66 
     | 
    
         
            -
              if (child->active) {
         
     | 
| 
       67 
     | 
    
         
            -
                ev_child_stop(EV_DEFAULT, &child->ev_child);
         
     | 
| 
       68 
     | 
    
         
            -
              }
         
     | 
| 
       69 
     | 
    
         
            -
              xfree(child);
         
     | 
| 
       70 
     | 
    
         
            -
            }
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
            static size_t EV_Child_size(const void *ptr) {
         
     | 
| 
       73 
     | 
    
         
            -
              return sizeof(struct EV_Child);
         
     | 
| 
       74 
     | 
    
         
            -
            }
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
            #define GetEV_Child(obj, child) \
         
     | 
| 
       77 
     | 
    
         
            -
              TypedData_Get_Struct((obj), struct EV_Child, &EV_Child_type, (child))
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
            static VALUE EV_Child_initialize(VALUE self, VALUE pid) {
         
     | 
| 
       80 
     | 
    
         
            -
              struct EV_Child *child;
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
              GetEV_Child(self, child);
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
              child->self     = self;
         
     | 
| 
       85 
     | 
    
         
            -
              child->callback = Qnil;
         
     | 
| 
       86 
     | 
    
         
            -
              child->fiber    = Qnil;
         
     | 
| 
       87 
     | 
    
         
            -
              child->pid      = NUM2INT(pid);
         
     | 
| 
       88 
     | 
    
         
            -
              child->active   = 0;
         
     | 
| 
       89 
     | 
    
         
            -
              
         
     | 
| 
       90 
     | 
    
         
            -
              ev_child_init(&child->ev_child, EV_Child_callback, child->pid, 0);
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
              return Qnil;
         
     | 
| 
       93 
     | 
    
         
            -
            }
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
            void EV_Child_callback(ev_loop *ev_loop, struct ev_child *ev_child, int revents) {
         
     | 
| 
       96 
     | 
    
         
            -
              VALUE fiber;
         
     | 
| 
       97 
     | 
    
         
            -
              VALUE resume_value;
         
     | 
| 
       98 
     | 
    
         
            -
              struct EV_Child *child = (struct EV_Child*)ev_child;
         
     | 
| 
       99 
     | 
    
         
            -
              resume_value = INT2NUM(child->pid);
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
              child->active = 0;
         
     | 
| 
       102 
     | 
    
         
            -
              ev_child_stop(EV_DEFAULT, ev_child);
         
     | 
| 
       103 
     | 
    
         
            -
              EV_del_watcher_ref(child->self);
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
              if (child->fiber != Qnil) {
         
     | 
| 
       106 
     | 
    
         
            -
                fiber = child->fiber;
         
     | 
| 
       107 
     | 
    
         
            -
                child->fiber = Qnil;
         
     | 
| 
       108 
     | 
    
         
            -
                SCHEDULE_FIBER(fiber, 1, resume_value);
         
     | 
| 
       109 
     | 
    
         
            -
              }
         
     | 
| 
       110 
     | 
    
         
            -
              else if (child->callback != Qnil) {
         
     | 
| 
       111 
     | 
    
         
            -
                rb_funcall(child->callback, ID_call, 1, resume_value);
         
     | 
| 
       112 
     | 
    
         
            -
              }
         
     | 
| 
       113 
     | 
    
         
            -
            }
         
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
            static VALUE EV_Child_start(VALUE self) {
         
     | 
| 
       116 
     | 
    
         
            -
              struct EV_Child *child;
         
     | 
| 
       117 
     | 
    
         
            -
              GetEV_Child(self, child);
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
              if (rb_block_given_p()) {
         
     | 
| 
       120 
     | 
    
         
            -
                child->callback = rb_block_proc();
         
     | 
| 
       121 
     | 
    
         
            -
              }
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
              if (!child->active) {
         
     | 
| 
       124 
     | 
    
         
            -
                ev_child_start(EV_DEFAULT, &child->ev_child);
         
     | 
| 
       125 
     | 
    
         
            -
                child->active = 1;
         
     | 
| 
       126 
     | 
    
         
            -
                EV_add_watcher_ref(self);
         
     | 
| 
       127 
     | 
    
         
            -
              }
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
              return self;
         
     | 
| 
       130 
     | 
    
         
            -
            }
         
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
            static VALUE EV_Child_stop(VALUE self) {
         
     | 
| 
       133 
     | 
    
         
            -
              struct EV_Child *child;
         
     | 
| 
       134 
     | 
    
         
            -
              GetEV_Child(self, child);
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
              if (child->active) {
         
     | 
| 
       137 
     | 
    
         
            -
                ev_child_stop(EV_DEFAULT, &child->ev_child);
         
     | 
| 
       138 
     | 
    
         
            -
                child->active = 0;
         
     | 
| 
       139 
     | 
    
         
            -
                EV_del_watcher_ref(self);
         
     | 
| 
       140 
     | 
    
         
            -
              }
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
              return self;
         
     | 
| 
       143 
     | 
    
         
            -
            }
         
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
            static VALUE EV_Child_await(VALUE self) {
         
     | 
| 
       146 
     | 
    
         
            -
              struct EV_Child *child;
         
     | 
| 
       147 
     | 
    
         
            -
              VALUE ret;
         
     | 
| 
       148 
     | 
    
         
            -
              
         
     | 
| 
       149 
     | 
    
         
            -
              GetEV_Child(self, child);
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
              child->fiber = rb_fiber_current();
         
     | 
| 
       152 
     | 
    
         
            -
              child->active = 1;
         
     | 
| 
       153 
     | 
    
         
            -
              ev_child_start(EV_DEFAULT, &child->ev_child);
         
     | 
| 
       154 
     | 
    
         
            -
              EV_add_watcher_ref(self);
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
              ret = YIELD_TO_REACTOR();
         
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
              // fiber is resumed, check if resumed value is an exception
         
     | 
| 
       159 
     | 
    
         
            -
              if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) {
         
     | 
| 
       160 
     | 
    
         
            -
                if (child->active) {
         
     | 
| 
       161 
     | 
    
         
            -
                  child->active = 0;
         
     | 
| 
       162 
     | 
    
         
            -
                  ev_child_stop(EV_DEFAULT, &child->ev_child);
         
     | 
| 
       163 
     | 
    
         
            -
                }
         
     | 
| 
       164 
     | 
    
         
            -
                return rb_funcall(ret, ID_raise, 1, ret);
         
     | 
| 
       165 
     | 
    
         
            -
              }
         
     | 
| 
       166 
     | 
    
         
            -
              else {
         
     | 
| 
       167 
     | 
    
         
            -
                return ret;
         
     | 
| 
       168 
     | 
    
         
            -
              }
         
     | 
| 
       169 
     | 
    
         
            -
            }
         
     |