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
 
    
        data/ext/{ev/ev.h → gyro/gyro.h}
    RENAMED
    
    | 
         @@ -5,29 +5,34 @@ 
     | 
|
| 
       5 
5 
     | 
    
         
             
            #include "ruby/io.h"
         
     | 
| 
       6 
6 
     | 
    
         
             
            #include "libev.h"
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            void  
     | 
| 
       9 
     | 
    
         
            -
            void  
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
      
 8 
     | 
    
         
            +
            void Gyro_add_watcher_ref(VALUE obj);
         
     | 
| 
      
 9 
     | 
    
         
            +
            void Gyro_del_watcher_ref(VALUE obj);
         
     | 
| 
      
 10 
     | 
    
         
            +
            VALUE Gyro_snooze(VALUE self);
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            VALUE IO_read_watcher(VALUE io);
         
     | 
| 
       13 
13 
     | 
    
         
             
            VALUE IO_write_watcher(VALUE io);
         
     | 
| 
       14 
     | 
    
         
            -
            VALUE  
     | 
| 
      
 14 
     | 
    
         
            +
            VALUE Gyro_IO_await(VALUE self);
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
            int io_setstrbuf(VALUE *str, long len);
         
     | 
| 
       17 
17 
     | 
    
         
             
            void io_set_read_length(VALUE str, long n, int shrinkable);
         
     | 
| 
       18 
18 
     | 
    
         
             
            VALUE io_enc_str(VALUE str, rb_io_t *fptr);
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
            #define SCHEDULE_FIBER(obj, args...) rb_funcall(obj, ID_transfer, args)
         
     | 
| 
       21 
     | 
    
         
            -
            #define YIELD_TO_REACTOR() rb_funcall( 
     | 
| 
      
 21 
     | 
    
         
            +
            #define YIELD_TO_REACTOR() rb_funcall(Gyro_reactor_fiber, ID_transfer, 0)
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
      
 23 
     | 
    
         
            +
            #define OBJ_ID(obj) (NUM2LONG(rb_funcall(obj, rb_intern("object_id"), 0)))
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            extern VALUE mGyro;
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            extern VALUE Gyro_reactor_fiber;
         
     | 
| 
      
 28 
     | 
    
         
            +
            extern VALUE Gyro_root_fiber;
         
     | 
| 
       25 
29 
     | 
    
         | 
| 
       26 
30 
     | 
    
         
             
            extern ID ID_call;
         
     | 
| 
       27 
31 
     | 
    
         
             
            extern ID ID_caller;
         
     | 
| 
       28 
32 
     | 
    
         
             
            extern ID ID_clear;
         
     | 
| 
       29 
33 
     | 
    
         
             
            extern ID ID_each;
         
     | 
| 
       30 
34 
     | 
    
         
             
            extern ID ID_inspect;
         
     | 
| 
      
 35 
     | 
    
         
            +
            extern ID ID_next_deferred;
         
     | 
| 
       31 
36 
     | 
    
         
             
            extern ID ID_raise;
         
     | 
| 
       32 
37 
     | 
    
         
             
            extern ID ID_read_watcher;
         
     | 
| 
       33 
38 
     | 
    
         
             
            extern ID ID_scheduled_value;
         
     | 
    
        data/ext/gyro/gyro_ext.c
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "gyro.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include "../libev/ev.c"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            void Init_Gyro();
         
     | 
| 
      
 5 
     | 
    
         
            +
            void Init_Gyro_Async();
         
     | 
| 
      
 6 
     | 
    
         
            +
            void Init_Gyro_Child();
         
     | 
| 
      
 7 
     | 
    
         
            +
            void Init_Gyro_IO();
         
     | 
| 
      
 8 
     | 
    
         
            +
            void Init_Gyro_Signal();
         
     | 
| 
      
 9 
     | 
    
         
            +
            void Init_Gyro_Timer();
         
     | 
| 
      
 10 
     | 
    
         
            +
            void Init_Socket();
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            void Init_gyro_ext() {
         
     | 
| 
      
 13 
     | 
    
         
            +
              ev_set_allocator(xrealloc);
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              Init_Gyro();
         
     | 
| 
      
 16 
     | 
    
         
            +
              Init_Gyro_Async();
         
     | 
| 
      
 17 
     | 
    
         
            +
              Init_Gyro_Child();
         
     | 
| 
      
 18 
     | 
    
         
            +
              Init_Gyro_IO();
         
     | 
| 
      
 19 
     | 
    
         
            +
              Init_Gyro_Signal();
         
     | 
| 
      
 20 
     | 
    
         
            +
              Init_Gyro_Timer();
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              Init_Socket();
         
     | 
| 
      
 23 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/{ev → gyro}/io.c
    RENAMED
    
    | 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #include " 
     | 
| 
      
 1 
     | 
    
         
            +
            #include "gyro.h"
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            #ifdef GetReadFile
         
     | 
| 
       4 
4 
     | 
    
         
             
            # define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
         
     | 
| 
         @@ -6,7 +6,7 @@ 
     | 
|
| 
       6 
6 
     | 
    
         
             
            # define FPTR_TO_FD(fptr) fptr->fd
         
     | 
| 
       7 
7 
     | 
    
         
             
            #endif /* GetReadFile */
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
            struct  
     | 
| 
      
 9 
     | 
    
         
            +
            struct Gyro_IO {
         
     | 
| 
       10 
10 
     | 
    
         
             
              struct  ev_io ev_io;
         
     | 
| 
       11 
11 
     | 
    
         
             
              int     active;
         
     | 
| 
       12 
12 
     | 
    
         
             
              int     event_mask;
         
     | 
| 
         @@ -14,22 +14,21 @@ struct EV_IO { 
     | 
|
| 
       14 
14 
     | 
    
         
             
              VALUE   fiber;
         
     | 
| 
       15 
15 
     | 
    
         
             
            };
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
            static VALUE  
     | 
| 
       18 
     | 
    
         
            -
            static VALUE cEV_IO = Qnil;
         
     | 
| 
      
 17 
     | 
    
         
            +
            static VALUE cGyro_IO = Qnil;
         
     | 
| 
       19 
18 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
            static VALUE  
     | 
| 
       21 
     | 
    
         
            -
            static void  
     | 
| 
       22 
     | 
    
         
            -
            static void  
     | 
| 
       23 
     | 
    
         
            -
            static size_t  
     | 
| 
      
 19 
     | 
    
         
            +
            static VALUE Gyro_IO_allocate(VALUE klass);
         
     | 
| 
      
 20 
     | 
    
         
            +
            static void Gyro_IO_mark(void *ptr);
         
     | 
| 
      
 21 
     | 
    
         
            +
            static void Gyro_IO_free(void *ptr);
         
     | 
| 
      
 22 
     | 
    
         
            +
            static size_t Gyro_IO_size(const void *ptr);
         
     | 
| 
       24 
23 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
            static VALUE  
     | 
| 
      
 24 
     | 
    
         
            +
            static VALUE Gyro_IO_initialize(VALUE self, VALUE io, VALUE event_mask);
         
     | 
| 
       26 
25 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
            static VALUE  
     | 
| 
       28 
     | 
    
         
            -
            static VALUE  
     | 
| 
      
 26 
     | 
    
         
            +
            static VALUE Gyro_IO_start(VALUE self);
         
     | 
| 
      
 27 
     | 
    
         
            +
            static VALUE Gyro_IO_stop(VALUE self);
         
     | 
| 
       29 
28 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
            void  
     | 
| 
      
 29 
     | 
    
         
            +
            void Gyro_IO_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
         
     | 
| 
       31 
30 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
            static int  
     | 
| 
      
 31 
     | 
    
         
            +
            static int Gyro_IO_symbol2event_mask(VALUE sym);
         
     | 
| 
       33 
32 
     | 
    
         | 
| 
       34 
33 
     | 
    
         
             
            // static VALUE IO_gets(int argc, VALUE *argv, VALUE io);
         
     | 
| 
       35 
34 
     | 
    
         
             
            static VALUE IO_read(int argc, VALUE *argv, VALUE io);
         
     | 
| 
         @@ -37,15 +36,14 @@ static VALUE IO_readpartial(int argc, VALUE *argv, VALUE io); 
     | 
|
| 
       37 
36 
     | 
    
         
             
            static VALUE IO_write(int argc, VALUE *argv, VALUE io);
         
     | 
| 
       38 
37 
     | 
    
         
             
            static VALUE IO_write_chevron(VALUE io, VALUE str);
         
     | 
| 
       39 
38 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
            void  
     | 
| 
       41 
     | 
    
         
            -
               
     | 
| 
       42 
     | 
    
         
            -
               
     | 
| 
       43 
     | 
    
         
            -
              rb_define_alloc_func(cEV_IO, EV_IO_allocate);
         
     | 
| 
      
 39 
     | 
    
         
            +
            void Init_Gyro_IO() {
         
     | 
| 
      
 40 
     | 
    
         
            +
              cGyro_IO = rb_define_class_under(mGyro, "IO", rb_cData);
         
     | 
| 
      
 41 
     | 
    
         
            +
              rb_define_alloc_func(cGyro_IO, Gyro_IO_allocate);
         
     | 
| 
       44 
42 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
              rb_define_method( 
     | 
| 
       46 
     | 
    
         
            -
              rb_define_method( 
     | 
| 
       47 
     | 
    
         
            -
              rb_define_method( 
     | 
| 
       48 
     | 
    
         
            -
              rb_define_method( 
     | 
| 
      
 43 
     | 
    
         
            +
              rb_define_method(cGyro_IO, "initialize", Gyro_IO_initialize, 2);
         
     | 
| 
      
 44 
     | 
    
         
            +
              rb_define_method(cGyro_IO, "start", Gyro_IO_start, 0);
         
     | 
| 
      
 45 
     | 
    
         
            +
              rb_define_method(cGyro_IO, "stop", Gyro_IO_stop, 0);
         
     | 
| 
      
 46 
     | 
    
         
            +
              rb_define_method(cGyro_IO, "await", Gyro_IO_await, 0);
         
     | 
| 
       49 
47 
     | 
    
         | 
| 
       50 
48 
     | 
    
         
             
              VALUE cIO = rb_const_get(rb_cObject, rb_intern("IO"));
         
     | 
| 
       51 
49 
     | 
    
         
             
              // rb_define_method(cIO, "gets", IO_gets, -1);
         
     | 
| 
         @@ -58,21 +56,21 @@ void Init_EV_IO() { 
     | 
|
| 
       58 
56 
     | 
    
         
             
              rb_define_method(cIO, "write_watcher", IO_write_watcher, 0);
         
     | 
| 
       59 
57 
     | 
    
         
             
            }
         
     | 
| 
       60 
58 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
            static const rb_data_type_t  
     | 
| 
       62 
     | 
    
         
            -
                " 
     | 
| 
       63 
     | 
    
         
            -
                { 
     | 
| 
      
 59 
     | 
    
         
            +
            static const rb_data_type_t Gyro_IO_type = {
         
     | 
| 
      
 60 
     | 
    
         
            +
                "Gyro_IO",
         
     | 
| 
      
 61 
     | 
    
         
            +
                {Gyro_IO_mark, Gyro_IO_free, Gyro_IO_size,},
         
     | 
| 
       64 
62 
     | 
    
         
             
                0, 0,
         
     | 
| 
       65 
63 
     | 
    
         
             
                RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
       66 
64 
     | 
    
         
             
            };
         
     | 
| 
       67 
65 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
            static VALUE  
     | 
| 
       69 
     | 
    
         
            -
              struct  
     | 
| 
      
 66 
     | 
    
         
            +
            static VALUE Gyro_IO_allocate(VALUE klass) {
         
     | 
| 
      
 67 
     | 
    
         
            +
              struct Gyro_IO *io = (struct Gyro_IO *)xmalloc(sizeof(struct Gyro_IO));
         
     | 
| 
       70 
68 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
              return TypedData_Wrap_Struct(klass, & 
     | 
| 
      
 69 
     | 
    
         
            +
              return TypedData_Wrap_Struct(klass, &Gyro_IO_type, io);
         
     | 
| 
       72 
70 
     | 
    
         
             
            }
         
     | 
| 
       73 
71 
     | 
    
         | 
| 
       74 
     | 
    
         
            -
            static void  
     | 
| 
       75 
     | 
    
         
            -
              struct  
     | 
| 
      
 72 
     | 
    
         
            +
            static void Gyro_IO_mark(void *ptr) {
         
     | 
| 
      
 73 
     | 
    
         
            +
              struct Gyro_IO *io = ptr;
         
     | 
| 
       76 
74 
     | 
    
         
             
              if (io->callback != Qnil) {
         
     | 
| 
       77 
75 
     | 
    
         
             
                rb_gc_mark(io->callback);
         
     | 
| 
       78 
76 
     | 
    
         
             
              }
         
     | 
| 
         @@ -81,41 +79,41 @@ static void EV_IO_mark(void *ptr) { 
     | 
|
| 
       81 
79 
     | 
    
         
             
              }
         
     | 
| 
       82 
80 
     | 
    
         
             
            }
         
     | 
| 
       83 
81 
     | 
    
         | 
| 
       84 
     | 
    
         
            -
            static void  
     | 
| 
       85 
     | 
    
         
            -
              struct  
     | 
| 
      
 82 
     | 
    
         
            +
            static void Gyro_IO_free(void *ptr) {
         
     | 
| 
      
 83 
     | 
    
         
            +
              struct Gyro_IO *io = ptr;
         
     | 
| 
       86 
84 
     | 
    
         
             
              ev_io_stop(EV_DEFAULT, &io->ev_io);
         
     | 
| 
       87 
85 
     | 
    
         
             
              xfree(io);
         
     | 
| 
       88 
86 
     | 
    
         
             
            }
         
     | 
| 
       89 
87 
     | 
    
         | 
| 
       90 
     | 
    
         
            -
            static size_t  
     | 
| 
       91 
     | 
    
         
            -
              return sizeof(struct  
     | 
| 
      
 88 
     | 
    
         
            +
            static size_t Gyro_IO_size(const void *ptr) {
         
     | 
| 
      
 89 
     | 
    
         
            +
              return sizeof(struct Gyro_IO);
         
     | 
| 
       92 
90 
     | 
    
         
             
            }
         
     | 
| 
       93 
91 
     | 
    
         | 
| 
       94 
92 
     | 
    
         
             
            static const char * S_IO = "IO";
         
     | 
| 
       95 
93 
     | 
    
         
             
            static const char * S_to_io = "to_io";
         
     | 
| 
       96 
94 
     | 
    
         | 
| 
       97 
     | 
    
         
            -
            #define  
     | 
| 
      
 95 
     | 
    
         
            +
            #define GetGyro_IO(obj, io) TypedData_Get_Struct((obj), struct Gyro_IO, &Gyro_IO_type, (io))
         
     | 
| 
       98 
96 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
            static VALUE  
     | 
| 
       100 
     | 
    
         
            -
              struct  
     | 
| 
      
 97 
     | 
    
         
            +
            static VALUE Gyro_IO_initialize(VALUE self, VALUE io_obj, VALUE event_mask) {
         
     | 
| 
      
 98 
     | 
    
         
            +
              struct Gyro_IO *io;
         
     | 
| 
       101 
99 
     | 
    
         
             
              rb_io_t *fptr;
         
     | 
| 
       102 
100 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
               
     | 
| 
      
 101 
     | 
    
         
            +
              GetGyro_IO(self, io);
         
     | 
| 
       104 
102 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
              io->event_mask =  
     | 
| 
      
 103 
     | 
    
         
            +
              io->event_mask = Gyro_IO_symbol2event_mask(event_mask);
         
     | 
| 
       106 
104 
     | 
    
         
             
              io->callback = Qnil;
         
     | 
| 
       107 
105 
     | 
    
         
             
              io->fiber = Qnil;
         
     | 
| 
       108 
106 
     | 
    
         
             
              io->active = 0;
         
     | 
| 
       109 
107 
     | 
    
         | 
| 
       110 
108 
     | 
    
         
             
              GetOpenFile(rb_convert_type(io_obj, T_FILE, S_IO, S_to_io), fptr);
         
     | 
| 
       111 
     | 
    
         
            -
              ev_io_init(&io->ev_io,  
     | 
| 
      
 109 
     | 
    
         
            +
              ev_io_init(&io->ev_io, Gyro_IO_callback, FPTR_TO_FD(fptr), io->event_mask);
         
     | 
| 
       112 
110 
     | 
    
         | 
| 
       113 
111 
     | 
    
         
             
              return Qnil;
         
     | 
| 
       114 
112 
     | 
    
         
             
            }
         
     | 
| 
       115 
113 
     | 
    
         | 
| 
       116 
     | 
    
         
            -
            void  
     | 
| 
      
 114 
     | 
    
         
            +
            void Gyro_IO_callback(struct ev_loop *ev_loop, struct ev_io *ev_io, int revents) {
         
     | 
| 
       117 
115 
     | 
    
         
             
              VALUE fiber;
         
     | 
| 
       118 
     | 
    
         
            -
              struct  
     | 
| 
      
 116 
     | 
    
         
            +
              struct Gyro_IO *io = (struct Gyro_IO*)ev_io;
         
     | 
| 
       119 
117 
     | 
    
         | 
| 
       120 
118 
     | 
    
         
             
              if (io->fiber != Qnil) {
         
     | 
| 
       121 
119 
     | 
    
         
             
                ev_io_stop(EV_DEFAULT, ev_io);
         
     | 
| 
         @@ -132,9 +130,9 @@ void EV_IO_callback(ev_loop *ev_loop, struct ev_io *ev_io, int revents) { 
     | 
|
| 
       132 
130 
     | 
    
         
             
              }
         
     | 
| 
       133 
131 
     | 
    
         
             
            }
         
     | 
| 
       134 
132 
     | 
    
         | 
| 
       135 
     | 
    
         
            -
            static VALUE  
     | 
| 
       136 
     | 
    
         
            -
              struct  
     | 
| 
       137 
     | 
    
         
            -
               
     | 
| 
      
 133 
     | 
    
         
            +
            static VALUE Gyro_IO_start(VALUE self) {
         
     | 
| 
      
 134 
     | 
    
         
            +
              struct Gyro_IO *io;
         
     | 
| 
      
 135 
     | 
    
         
            +
              GetGyro_IO(self, io);
         
     | 
| 
       138 
136 
     | 
    
         | 
| 
       139 
137 
     | 
    
         
             
              if (rb_block_given_p()) {
         
     | 
| 
       140 
138 
     | 
    
         
             
                io->callback = rb_block_proc();
         
     | 
| 
         @@ -148,9 +146,9 @@ static VALUE EV_IO_start(VALUE self) { 
     | 
|
| 
       148 
146 
     | 
    
         
             
              return self;
         
     | 
| 
       149 
147 
     | 
    
         
             
            }
         
     | 
| 
       150 
148 
     | 
    
         | 
| 
       151 
     | 
    
         
            -
            static VALUE  
     | 
| 
       152 
     | 
    
         
            -
              struct  
     | 
| 
       153 
     | 
    
         
            -
               
     | 
| 
      
 149 
     | 
    
         
            +
            static VALUE Gyro_IO_stop(VALUE self) {
         
     | 
| 
      
 150 
     | 
    
         
            +
              struct Gyro_IO *io;
         
     | 
| 
      
 151 
     | 
    
         
            +
              GetGyro_IO(self, io);
         
     | 
| 
       154 
152 
     | 
    
         | 
| 
       155 
153 
     | 
    
         
             
              if (io->active) {
         
     | 
| 
       156 
154 
     | 
    
         
             
                ev_io_stop(EV_DEFAULT, &io->ev_io);
         
     | 
| 
         @@ -160,11 +158,11 @@ static VALUE EV_IO_stop(VALUE self) { 
     | 
|
| 
       160 
158 
     | 
    
         
             
              return self;
         
     | 
| 
       161 
159 
     | 
    
         
             
            }
         
     | 
| 
       162 
160 
     | 
    
         | 
| 
       163 
     | 
    
         
            -
            VALUE  
     | 
| 
       164 
     | 
    
         
            -
              struct  
     | 
| 
      
 161 
     | 
    
         
            +
            VALUE Gyro_IO_await(VALUE self) {
         
     | 
| 
      
 162 
     | 
    
         
            +
              struct Gyro_IO *io;
         
     | 
| 
       165 
163 
     | 
    
         
             
              VALUE ret;
         
     | 
| 
       166 
164 
     | 
    
         | 
| 
       167 
     | 
    
         
            -
               
     | 
| 
      
 165 
     | 
    
         
            +
              GetGyro_IO(self, io);
         
     | 
| 
       168 
166 
     | 
    
         | 
| 
       169 
167 
     | 
    
         
             
              io->fiber = rb_fiber_current();
         
     | 
| 
       170 
168 
     | 
    
         
             
              io->active = 1;
         
     | 
| 
         @@ -186,7 +184,7 @@ VALUE EV_IO_await(VALUE self) { 
     | 
|
| 
       186 
184 
     | 
    
         
             
              }
         
     | 
| 
       187 
185 
     | 
    
         
             
            }
         
     | 
| 
       188 
186 
     | 
    
         | 
| 
       189 
     | 
    
         
            -
            static int  
     | 
| 
      
 187 
     | 
    
         
            +
            static int Gyro_IO_symbol2event_mask(VALUE sym) {
         
     | 
| 
       190 
188 
     | 
    
         
             
              ID sym_id;
         
     | 
| 
       191 
189 
     | 
    
         | 
| 
       192 
190 
     | 
    
         
             
              if (NIL_P(sym)) {
         
     | 
| 
         @@ -273,7 +271,7 @@ static VALUE IO_read(int argc, VALUE *argv, VALUE io) { 
     | 
|
| 
       273 
271 
     | 
    
         
             
              VALUE underlying_io = rb_iv_get(io, "@io");
         
     | 
| 
       274 
272 
     | 
    
         
             
              if (!NIL_P(underlying_io)) io = underlying_io;
         
     | 
| 
       275 
273 
     | 
    
         | 
| 
       276 
     | 
    
         
            -
              long len = argc == 1 ? NUM2LONG(argv[0]) :  
     | 
| 
      
 274 
     | 
    
         
            +
              long len = argc == 1 ? NUM2LONG(argv[0]) : (1 << 30);
         
     | 
| 
       277 
275 
     | 
    
         | 
| 
       278 
276 
     | 
    
         
             
              rb_io_t *fptr;
         
     | 
| 
       279 
277 
     | 
    
         
             
              long n;
         
     | 
| 
         @@ -305,7 +303,7 @@ static VALUE IO_read(int argc, VALUE *argv, VALUE io) { 
     | 
|
| 
       305 
303 
     | 
    
         
             
                  if ((e == EWOULDBLOCK || e == EAGAIN)) {
         
     | 
| 
       306 
304 
     | 
    
         
             
                    if (read_watcher == Qnil)
         
     | 
| 
       307 
305 
     | 
    
         
             
                      read_watcher = IO_read_watcher(io);
         
     | 
| 
       308 
     | 
    
         
            -
                     
     | 
| 
      
 306 
     | 
    
         
            +
                    Gyro_IO_await(read_watcher);
         
     | 
| 
       309 
307 
     | 
    
         
             
                  }
         
     | 
| 
       310 
308 
     | 
    
         
             
                  else
         
     | 
| 
       311 
309 
     | 
    
         
             
                    rb_syserr_fail(e, strerror(e));
         
     | 
| 
         @@ -364,7 +362,7 @@ static VALUE IO_readpartial(int argc, VALUE *argv, VALUE io) { 
     | 
|
| 
       364 
362 
     | 
    
         
             
                  if (e == EWOULDBLOCK || e == EAGAIN) {
         
     | 
| 
       365 
363 
     | 
    
         
             
                    if (read_watcher == Qnil)
         
     | 
| 
       366 
364 
     | 
    
         
             
                      read_watcher = IO_read_watcher(io);
         
     | 
| 
       367 
     | 
    
         
            -
                     
     | 
| 
      
 365 
     | 
    
         
            +
                    Gyro_IO_await(read_watcher);
         
     | 
| 
       368 
366 
     | 
    
         
             
                  }
         
     | 
| 
       369 
367 
     | 
    
         
             
                  else
         
     | 
| 
       370 
368 
     | 
    
         
             
                    rb_syserr_fail(e, strerror(e));
         
     | 
| 
         @@ -377,6 +375,11 @@ static VALUE IO_readpartial(int argc, VALUE *argv, VALUE io) { 
     | 
|
| 
       377 
375 
     | 
    
         
             
              io_set_read_length(str, n, shrinkable);
         
     | 
| 
       378 
376 
     | 
    
         
             
              io_enc_str(str, fptr);
         
     | 
| 
       379 
377 
     | 
    
         | 
| 
      
 378 
     | 
    
         
            +
              // ensure yielding to reactor if haven't yielded while reading
         
     | 
| 
      
 379 
     | 
    
         
            +
              // if (read_watcher == Qnil) {
         
     | 
| 
      
 380 
     | 
    
         
            +
              //   Gyro_snooze(Qnil);
         
     | 
| 
      
 381 
     | 
    
         
            +
              // }
         
     | 
| 
      
 382 
     | 
    
         
            +
             
     | 
| 
       380 
383 
     | 
    
         
             
              if (n == 0)
         
     | 
| 
       381 
384 
     | 
    
         
             
                return Qnil;
         
     | 
| 
       382 
385 
     | 
    
         | 
| 
         @@ -415,7 +418,7 @@ static VALUE IO_write(int argc, VALUE *argv, VALUE io) { 
     | 
|
| 
       415 
418 
     | 
    
         
             
                      if (write_watcher == Qnil)
         
     | 
| 
       416 
419 
     | 
    
         
             
                        write_watcher = IO_write_watcher(io);
         
     | 
| 
       417 
420 
     | 
    
         
             
                        // write_watcher = rb_funcall(io, ID_write_watcher, 0);
         
     | 
| 
       418 
     | 
    
         
            -
                       
     | 
| 
      
 421 
     | 
    
         
            +
                      Gyro_IO_await(write_watcher);
         
     | 
| 
       419 
422 
     | 
    
         
             
                    }
         
     | 
| 
       420 
423 
     | 
    
         
             
                    else {
         
     | 
| 
       421 
424 
     | 
    
         
             
                      rb_syserr_fail(e, strerror(e));
         
     | 
| 
         @@ -433,6 +436,11 @@ static VALUE IO_write(int argc, VALUE *argv, VALUE io) { 
     | 
|
| 
       433 
436 
     | 
    
         
             
                }
         
     | 
| 
       434 
437 
     | 
    
         
             
              }
         
     | 
| 
       435 
438 
     | 
    
         | 
| 
      
 439 
     | 
    
         
            +
              // ensure yielding to reactor if haven't yielded while writing
         
     | 
| 
      
 440 
     | 
    
         
            +
              // if (write_watcher == Qnil) {
         
     | 
| 
      
 441 
     | 
    
         
            +
              //   Gyro_snooze(Qnil);
         
     | 
| 
      
 442 
     | 
    
         
            +
              // }
         
     | 
| 
      
 443 
     | 
    
         
            +
             
     | 
| 
       436 
444 
     | 
    
         
             
              return LONG2FIX(total);
         
     | 
| 
       437 
445 
     | 
    
         
             
            }
         
     | 
| 
       438 
446 
     | 
    
         | 
| 
         @@ -444,7 +452,7 @@ static VALUE IO_write_chevron(VALUE io, VALUE str) { 
     | 
|
| 
       444 
452 
     | 
    
         
             
            VALUE IO_read_watcher(VALUE self) {
         
     | 
| 
       445 
453 
     | 
    
         
             
              VALUE watcher = rb_iv_get(self, "@read_watcher");
         
     | 
| 
       446 
454 
     | 
    
         
             
              if (watcher == Qnil) {
         
     | 
| 
       447 
     | 
    
         
            -
                watcher = rb_funcall( 
     | 
| 
      
 455 
     | 
    
         
            +
                watcher = rb_funcall(cGyro_IO, rb_intern("new"), 2, self, ID2SYM(rb_intern("r")));
         
     | 
| 
       448 
456 
     | 
    
         
             
                rb_iv_set(self, "@read_watcher", watcher);
         
     | 
| 
       449 
457 
     | 
    
         
             
              }
         
     | 
| 
       450 
458 
     | 
    
         
             
              return watcher;
         
     | 
| 
         @@ -453,7 +461,7 @@ VALUE IO_read_watcher(VALUE self) { 
     | 
|
| 
       453 
461 
     | 
    
         
             
            VALUE IO_write_watcher(VALUE self) {
         
     | 
| 
       454 
462 
     | 
    
         
             
              VALUE watcher = rb_iv_get(self, "@write_watcher");
         
     | 
| 
       455 
463 
     | 
    
         
             
              if (watcher == Qnil) {
         
     | 
| 
       456 
     | 
    
         
            -
                watcher = rb_funcall( 
     | 
| 
      
 464 
     | 
    
         
            +
                watcher = rb_funcall(cGyro_IO, rb_intern("new"), 2, self, ID2SYM(rb_intern("w")));
         
     | 
| 
       457 
465 
     | 
    
         
             
                rb_iv_set(self, "@write_watcher", watcher);
         
     | 
| 
       458 
466 
     | 
    
         
             
              }
         
     | 
| 
       459 
467 
     | 
    
         
             
              return watcher;
         
     | 
    
        data/ext/{ev → gyro}/libev.h
    RENAMED
    
    | 
         
            File without changes
         
     | 
    
        data/ext/gyro/signal.c
    ADDED
    
    | 
         @@ -0,0 +1,117 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "gyro.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            struct Gyro_Signal {
         
     | 
| 
      
 4 
     | 
    
         
            +
              struct  ev_signal ev_signal;
         
     | 
| 
      
 5 
     | 
    
         
            +
              int     active;
         
     | 
| 
      
 6 
     | 
    
         
            +
              int     signum;
         
     | 
| 
      
 7 
     | 
    
         
            +
              VALUE   callback;
         
     | 
| 
      
 8 
     | 
    
         
            +
            };
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            static VALUE cGyro_Signal = Qnil;
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            /* Allocator/deallocator */
         
     | 
| 
      
 13 
     | 
    
         
            +
            static VALUE Gyro_Signal_allocate(VALUE klass);
         
     | 
| 
      
 14 
     | 
    
         
            +
            static void Gyro_Signal_mark(void *ptr);
         
     | 
| 
      
 15 
     | 
    
         
            +
            static void Gyro_Signal_free(void *ptr);
         
     | 
| 
      
 16 
     | 
    
         
            +
            static size_t Gyro_Signal_size(const void *ptr);
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            /* Methods */
         
     | 
| 
      
 19 
     | 
    
         
            +
            static VALUE Gyro_Signal_initialize(VALUE self, VALUE sig);
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            static VALUE Gyro_Signal_start(VALUE self);
         
     | 
| 
      
 22 
     | 
    
         
            +
            static VALUE Gyro_Signal_stop(VALUE self);
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            void Gyro_Signal_callback(struct ev_loop *ev_loop, struct ev_signal *signal, int revents);
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            /* Signal encapsulates a signal watcher */
         
     | 
| 
      
 27 
     | 
    
         
            +
            void Init_Gyro_Signal() {
         
     | 
| 
      
 28 
     | 
    
         
            +
              cGyro_Signal = rb_define_class_under(mGyro, "Signal", rb_cData);
         
     | 
| 
      
 29 
     | 
    
         
            +
              rb_define_alloc_func(cGyro_Signal, Gyro_Signal_allocate);
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              rb_define_method(cGyro_Signal, "initialize", Gyro_Signal_initialize, 1);
         
     | 
| 
      
 32 
     | 
    
         
            +
              rb_define_method(cGyro_Signal, "start", Gyro_Signal_start, 0);
         
     | 
| 
      
 33 
     | 
    
         
            +
              rb_define_method(cGyro_Signal, "stop", Gyro_Signal_stop, 0);
         
     | 
| 
      
 34 
     | 
    
         
            +
            }
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            static const rb_data_type_t Gyro_Signal_type = {
         
     | 
| 
      
 37 
     | 
    
         
            +
                "Gyro_Signal",
         
     | 
| 
      
 38 
     | 
    
         
            +
                {Gyro_Signal_mark, Gyro_Signal_free, Gyro_Signal_size,},
         
     | 
| 
      
 39 
     | 
    
         
            +
                0, 0,
         
     | 
| 
      
 40 
     | 
    
         
            +
                RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
      
 41 
     | 
    
         
            +
            };
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            static VALUE Gyro_Signal_allocate(VALUE klass) {
         
     | 
| 
      
 44 
     | 
    
         
            +
              struct Gyro_Signal *signal = (struct Gyro_Signal *)xmalloc(sizeof(struct Gyro_Signal));
         
     | 
| 
      
 45 
     | 
    
         
            +
              return TypedData_Wrap_Struct(klass, &Gyro_Signal_type, signal);
         
     | 
| 
      
 46 
     | 
    
         
            +
            }
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            static void Gyro_Signal_mark(void *ptr) {
         
     | 
| 
      
 49 
     | 
    
         
            +
              struct Gyro_Signal *signal = ptr;
         
     | 
| 
      
 50 
     | 
    
         
            +
              if (signal->callback != Qnil) {
         
     | 
| 
      
 51 
     | 
    
         
            +
                rb_gc_mark(signal->callback);
         
     | 
| 
      
 52 
     | 
    
         
            +
              }
         
     | 
| 
      
 53 
     | 
    
         
            +
            }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            static void Gyro_Signal_free(void *ptr) {
         
     | 
| 
      
 56 
     | 
    
         
            +
              struct Gyro_Signal *signal = ptr;
         
     | 
| 
      
 57 
     | 
    
         
            +
              ev_signal_stop(EV_DEFAULT, &signal->ev_signal);
         
     | 
| 
      
 58 
     | 
    
         
            +
              xfree(signal);
         
     | 
| 
      
 59 
     | 
    
         
            +
            }
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            static size_t Gyro_Signal_size(const void *ptr) {
         
     | 
| 
      
 62 
     | 
    
         
            +
              return sizeof(struct Gyro_Signal);
         
     | 
| 
      
 63 
     | 
    
         
            +
            }
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            #define GetGyro_Signal(obj, signal) \
         
     | 
| 
      
 66 
     | 
    
         
            +
              TypedData_Get_Struct((obj), struct Gyro_Signal, &Gyro_Signal_type, (signal))
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            static VALUE Gyro_Signal_initialize(VALUE self, VALUE sig) {
         
     | 
| 
      
 69 
     | 
    
         
            +
              struct Gyro_Signal *signal;
         
     | 
| 
      
 70 
     | 
    
         
            +
              VALUE signum = sig;
         
     | 
| 
      
 71 
     | 
    
         
            +
             
         
     | 
| 
      
 72 
     | 
    
         
            +
              GetGyro_Signal(self, signal);
         
     | 
| 
      
 73 
     | 
    
         
            +
              signal->signum = NUM2INT(signum);
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              if (rb_block_given_p()) {
         
     | 
| 
      
 76 
     | 
    
         
            +
                signal->callback = rb_block_proc();
         
     | 
| 
      
 77 
     | 
    
         
            +
              }
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              ev_signal_init(&signal->ev_signal, Gyro_Signal_callback, signal->signum);
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              signal->active = 1;
         
     | 
| 
      
 82 
     | 
    
         
            +
              ev_signal_start(EV_DEFAULT, &signal->ev_signal);
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
              return Qnil;
         
     | 
| 
      
 85 
     | 
    
         
            +
            }
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            void Gyro_Signal_callback(struct ev_loop *ev_loop, struct ev_signal *ev_signal, int revents) {
         
     | 
| 
      
 88 
     | 
    
         
            +
              struct Gyro_Signal *signal = (struct Gyro_Signal*)ev_signal;
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              if (signal->callback != Qnil) {
         
     | 
| 
      
 91 
     | 
    
         
            +
                rb_funcall(signal->callback, ID_call, 1, INT2NUM(signal->signum));
         
     | 
| 
      
 92 
     | 
    
         
            +
              }
         
     | 
| 
      
 93 
     | 
    
         
            +
            }
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            static VALUE Gyro_Signal_start(VALUE self) {
         
     | 
| 
      
 96 
     | 
    
         
            +
              struct Gyro_Signal *signal;
         
     | 
| 
      
 97 
     | 
    
         
            +
              GetGyro_Signal(self, signal);
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
              if (!signal->active) {
         
     | 
| 
      
 100 
     | 
    
         
            +
                ev_signal_start(EV_DEFAULT, &signal->ev_signal);
         
     | 
| 
      
 101 
     | 
    
         
            +
                signal->active = 1;
         
     | 
| 
      
 102 
     | 
    
         
            +
              }
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
              return self;
         
     | 
| 
      
 105 
     | 
    
         
            +
            }
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            static VALUE Gyro_Signal_stop(VALUE self) {
         
     | 
| 
      
 108 
     | 
    
         
            +
              struct Gyro_Signal *signal;
         
     | 
| 
      
 109 
     | 
    
         
            +
              GetGyro_Signal(self, signal);
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
              if (signal->active) {
         
     | 
| 
      
 112 
     | 
    
         
            +
                ev_signal_stop(EV_DEFAULT, &signal->ev_signal);
         
     | 
| 
      
 113 
     | 
    
         
            +
                signal->active = 0;
         
     | 
| 
      
 114 
     | 
    
         
            +
              }
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
              return self;
         
     | 
| 
      
 117 
     | 
    
         
            +
            }
         
     |