polyphony 0.34 → 0.41

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +11 -2
  3. data/.gitignore +2 -2
  4. data/.rubocop.yml +30 -0
  5. data/CHANGELOG.md +34 -0
  6. data/Gemfile +0 -11
  7. data/Gemfile.lock +11 -10
  8. data/README.md +2 -1
  9. data/Rakefile +6 -2
  10. data/TODO.md +18 -95
  11. data/docs/_includes/head.html +40 -0
  12. data/docs/_includes/nav.html +5 -5
  13. data/docs/api-reference.md +1 -1
  14. data/docs/api-reference/fiber.md +18 -0
  15. data/docs/api-reference/gyro-async.md +57 -0
  16. data/docs/api-reference/gyro-child.md +29 -0
  17. data/docs/api-reference/gyro-queue.md +44 -0
  18. data/docs/api-reference/gyro-timer.md +51 -0
  19. data/docs/api-reference/gyro.md +25 -0
  20. data/docs/index.md +10 -7
  21. data/docs/main-concepts/design-principles.md +67 -9
  22. data/docs/main-concepts/extending.md +1 -1
  23. data/docs/main-concepts/fiber-scheduling.md +55 -72
  24. data/examples/core/xx-agent.rb +102 -0
  25. data/examples/core/xx-fork-cleanup.rb +22 -0
  26. data/examples/core/xx-sleeping.rb +14 -6
  27. data/examples/core/xx-timer-gc.rb +17 -0
  28. data/examples/io/tunnel.rb +48 -0
  29. data/examples/io/xx-irb.rb +1 -1
  30. data/examples/performance/thread-vs-fiber/polyphony_mt_server.rb +7 -6
  31. data/examples/performance/thread-vs-fiber/polyphony_server.rb +14 -25
  32. data/ext/{gyro → polyphony}/extconf.rb +2 -2
  33. data/ext/polyphony/fiber.c +112 -0
  34. data/ext/{gyro → polyphony}/libev.c +0 -0
  35. data/ext/{gyro → polyphony}/libev.h +0 -0
  36. data/ext/polyphony/libev_agent.c +503 -0
  37. data/ext/polyphony/libev_queue.c +214 -0
  38. data/ext/polyphony/polyphony.c +89 -0
  39. data/ext/{gyro/gyro.h → polyphony/polyphony.h} +49 -59
  40. data/ext/polyphony/polyphony_ext.c +23 -0
  41. data/ext/{gyro → polyphony}/socket.c +21 -19
  42. data/ext/{gyro → polyphony}/thread.c +55 -119
  43. data/ext/{gyro → polyphony}/tracing.c +1 -1
  44. data/lib/polyphony.rb +37 -44
  45. data/lib/polyphony/adapters/fs.rb +1 -4
  46. data/lib/polyphony/adapters/irb.rb +2 -2
  47. data/lib/polyphony/adapters/postgres.rb +6 -5
  48. data/lib/polyphony/adapters/process.rb +27 -23
  49. data/lib/polyphony/adapters/trace.rb +110 -105
  50. data/lib/polyphony/core/channel.rb +35 -35
  51. data/lib/polyphony/core/exceptions.rb +29 -29
  52. data/lib/polyphony/core/global_api.rb +94 -91
  53. data/lib/polyphony/core/resource_pool.rb +83 -83
  54. data/lib/polyphony/core/sync.rb +16 -16
  55. data/lib/polyphony/core/thread_pool.rb +49 -37
  56. data/lib/polyphony/core/throttler.rb +30 -23
  57. data/lib/polyphony/event.rb +27 -0
  58. data/lib/polyphony/extensions/core.rb +23 -14
  59. data/lib/polyphony/extensions/fiber.rb +269 -267
  60. data/lib/polyphony/extensions/io.rb +56 -26
  61. data/lib/polyphony/extensions/openssl.rb +5 -9
  62. data/lib/polyphony/extensions/socket.rb +29 -10
  63. data/lib/polyphony/extensions/thread.rb +19 -12
  64. data/lib/polyphony/net.rb +64 -60
  65. data/lib/polyphony/version.rb +1 -1
  66. data/polyphony.gemspec +3 -6
  67. data/test/helper.rb +14 -1
  68. data/test/stress.rb +17 -12
  69. data/test/test_agent.rb +77 -0
  70. data/test/{test_async.rb → test_event.rb} +17 -9
  71. data/test/test_ext.rb +25 -4
  72. data/test/test_fiber.rb +23 -14
  73. data/test/test_global_api.rb +5 -5
  74. data/test/test_io.rb +46 -24
  75. data/test/test_queue.rb +74 -0
  76. data/test/test_signal.rb +3 -40
  77. data/test/test_socket.rb +33 -0
  78. data/test/test_thread.rb +38 -16
  79. data/test/test_thread_pool.rb +3 -3
  80. data/test/test_throttler.rb +0 -1
  81. data/test/test_trace.rb +6 -5
  82. metadata +34 -39
  83. data/ext/gyro/async.c +0 -158
  84. data/ext/gyro/child.c +0 -117
  85. data/ext/gyro/gyro.c +0 -203
  86. data/ext/gyro/gyro_ext.c +0 -31
  87. data/ext/gyro/io.c +0 -447
  88. data/ext/gyro/queue.c +0 -142
  89. data/ext/gyro/selector.c +0 -183
  90. data/ext/gyro/signal.c +0 -108
  91. data/ext/gyro/timer.c +0 -154
  92. data/test/test_timer.rb +0 -56
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'helper'
4
+ require 'polyphony/adapters/trace'
4
5
 
5
6
  class TraceTest < MiniTest::Test
6
7
  def test_tracing_disabled
@@ -11,13 +12,13 @@ class TraceTest < MiniTest::Test
11
12
  assert_equal 0, records.size
12
13
  ensure
13
14
  t&.disable
14
- Gyro.trace(nil)
15
+ Polyphony.trace(nil)
15
16
  end
16
17
 
17
18
  def test_tracing_enabled
18
19
  records = []
19
20
  t = Polyphony::Trace.new(:fiber_all) { |r| records << r if r[:event] =~ /^fiber_/ }
20
- Gyro.trace(true)
21
+ Polyphony.trace(true)
21
22
  t.enable
22
23
  snooze
23
24
  t.disable
@@ -28,14 +29,14 @@ class TraceTest < MiniTest::Test
28
29
  assert_equal [Fiber.current], records.map { |r| r[:fiber] }.uniq
29
30
  ensure
30
31
  t&.disable
31
- Gyro.trace(nil)
32
+ Polyphony.trace(nil)
32
33
  end
33
34
 
34
35
  def test_2_fiber_trace
35
36
  records = []
36
37
  t = Polyphony::Trace.new(:fiber_all) { |r| records << r if r[:event] =~ /^fiber_/ }
37
38
  t.enable
38
- Gyro.trace(true)
39
+ Polyphony.trace(true)
39
40
 
40
41
  f = spin { sleep 0 }
41
42
  suspend
@@ -61,6 +62,6 @@ class TraceTest < MiniTest::Test
61
62
  ], events
62
63
  ensure
63
64
  t&.disable
64
- Gyro.trace(nil)
65
+ Polyphony.trace(nil)
65
66
  end
66
67
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polyphony
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.34'
4
+ version: '0.41'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-25 00:00:00.000000000 Z
11
+ date: 2020-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: modulation
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: httparty
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -100,28 +86,28 @@ dependencies:
100
86
  requirements:
101
87
  - - '='
102
88
  - !ruby/object:Gem::Version
103
- version: 0.80.0
89
+ version: 0.85.1
104
90
  type: :development
105
91
  prerelease: false
106
92
  version_requirements: !ruby/object:Gem::Requirement
107
93
  requirements:
108
94
  - - '='
109
95
  - !ruby/object:Gem::Version
110
- version: 0.80.0
96
+ version: 0.85.1
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: pg
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
101
  - - '='
116
102
  - !ruby/object:Gem::Version
117
- version: 1.1.3
103
+ version: 1.1.4
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
107
  requirements:
122
108
  - - '='
123
109
  - !ruby/object:Gem::Version
124
- version: 1.1.3
110
+ version: 1.1.4
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: rake-compiler
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -238,7 +224,7 @@ description:
238
224
  email: ciconia@gmail.com
239
225
  executables: []
240
226
  extensions:
241
- - ext/gyro/extconf.rb
227
+ - ext/polyphony/extconf.rb
242
228
  extra_rdoc_files:
243
229
  - README.md
244
230
  files:
@@ -256,6 +242,7 @@ files:
256
242
  - TODO.md
257
243
  - bin/polyphony-debug
258
244
  - docs/_config.yml
245
+ - docs/_includes/head.html
259
246
  - docs/_includes/nav.html
260
247
  - docs/_includes/prevnext.html
261
248
  - docs/_layouts/default.html
@@ -264,6 +251,11 @@ files:
264
251
  - docs/api-reference.md
265
252
  - docs/api-reference/exception.md
266
253
  - docs/api-reference/fiber.md
254
+ - docs/api-reference/gyro-async.md
255
+ - docs/api-reference/gyro-child.md
256
+ - docs/api-reference/gyro-queue.md
257
+ - docs/api-reference/gyro-timer.md
258
+ - docs/api-reference/gyro.md
267
259
  - docs/api-reference/io.md
268
260
  - docs/api-reference/object.md
269
261
  - docs/api-reference/polyphony-baseexception.md
@@ -306,6 +298,7 @@ files:
306
298
  - examples/core/02-awaiting-fibers.rb
307
299
  - examples/core/03-interrupting.rb
308
300
  - examples/core/forever_sleep.rb
301
+ - examples/core/xx-agent.rb
309
302
  - examples/core/xx-at_exit.rb
310
303
  - examples/core/xx-caller.rb
311
304
  - examples/core/xx-channels.rb
@@ -313,6 +306,7 @@ files:
313
306
  - examples/core/xx-deferring-an-operation.rb
314
307
  - examples/core/xx-erlang-style-genserver.rb
315
308
  - examples/core/xx-exception-backtrace.rb
309
+ - examples/core/xx-fork-cleanup.rb
316
310
  - examples/core/xx-fork-spin.rb
317
311
  - examples/core/xx-fork-terminate.rb
318
312
  - examples/core/xx-forking.rb
@@ -339,9 +333,11 @@ files:
339
333
  - examples/core/xx-thread_pool.rb
340
334
  - examples/core/xx-throttling.rb
341
335
  - examples/core/xx-timeout.rb
336
+ - examples/core/xx-timer-gc.rb
342
337
  - examples/core/xx-trace.rb
343
338
  - examples/core/xx-using-a-mutex.rb
344
339
  - examples/core/xx-worker-thread.rb
340
+ - examples/io/tunnel.rb
345
341
  - examples/io/xx-backticks.rb
346
342
  - examples/io/xx-echo_client.rb
347
343
  - examples/io/xx-echo_client_from_stdin.rb
@@ -369,22 +365,6 @@ files:
369
365
  - examples/performance/thread-vs-fiber/xx-httparty_multi.rb
370
366
  - examples/performance/thread-vs-fiber/xx-httparty_threaded.rb
371
367
  - examples/performance/thread_pool_perf.rb
372
- - ext/gyro/async.c
373
- - ext/gyro/child.c
374
- - ext/gyro/extconf.rb
375
- - ext/gyro/gyro.c
376
- - ext/gyro/gyro.h
377
- - ext/gyro/gyro_ext.c
378
- - ext/gyro/io.c
379
- - ext/gyro/libev.c
380
- - ext/gyro/libev.h
381
- - ext/gyro/queue.c
382
- - ext/gyro/selector.c
383
- - ext/gyro/signal.c
384
- - ext/gyro/socket.c
385
- - ext/gyro/thread.c
386
- - ext/gyro/timer.c
387
- - ext/gyro/tracing.c
388
368
  - ext/libev/Changes
389
369
  - ext/libev/LICENSE
390
370
  - ext/libev/README
@@ -401,6 +381,18 @@ files:
401
381
  - ext/libev/ev_win32.c
402
382
  - ext/libev/ev_wrap.h
403
383
  - ext/libev/test_libev_win32.c
384
+ - ext/polyphony/extconf.rb
385
+ - ext/polyphony/fiber.c
386
+ - ext/polyphony/libev.c
387
+ - ext/polyphony/libev.h
388
+ - ext/polyphony/libev_agent.c
389
+ - ext/polyphony/libev_queue.c
390
+ - ext/polyphony/polyphony.c
391
+ - ext/polyphony/polyphony.h
392
+ - ext/polyphony/polyphony_ext.c
393
+ - ext/polyphony/socket.c
394
+ - ext/polyphony/thread.c
395
+ - ext/polyphony/tracing.c
404
396
  - lib/polyphony.rb
405
397
  - lib/polyphony/adapters/fs.rb
406
398
  - lib/polyphony/adapters/irb.rb
@@ -415,6 +407,7 @@ files:
415
407
  - lib/polyphony/core/sync.rb
416
408
  - lib/polyphony/core/thread_pool.rb
417
409
  - lib/polyphony/core/throttler.rb
410
+ - lib/polyphony/event.rb
418
411
  - lib/polyphony/extensions/core.rb
419
412
  - lib/polyphony/extensions/fiber.rb
420
413
  - lib/polyphony/extensions/io.rb
@@ -429,20 +422,22 @@ files:
429
422
  - test/helper.rb
430
423
  - test/run.rb
431
424
  - test/stress.rb
432
- - test/test_async.rb
425
+ - test/test_agent.rb
426
+ - test/test_event.rb
433
427
  - test/test_ext.rb
434
428
  - test/test_fiber.rb
435
429
  - test/test_global_api.rb
436
430
  - test/test_io.rb
437
431
  - test/test_kernel.rb
438
432
  - test/test_process_supervision.rb
433
+ - test/test_queue.rb
439
434
  - test/test_resource_pool.rb
440
435
  - test/test_signal.rb
436
+ - test/test_socket.rb
441
437
  - test/test_supervise.rb
442
438
  - test/test_thread.rb
443
439
  - test/test_thread_pool.rb
444
440
  - test/test_throttler.rb
445
- - test/test_timer.rb
446
441
  - test/test_trace.rb
447
442
  homepage: https://digital-fabric.github.io/polyphony
448
443
  licenses:
@@ -1,158 +0,0 @@
1
- #include "gyro.h"
2
-
3
- struct Gyro_Async {
4
- struct ev_async ev_async;
5
- struct ev_loop *ev_loop;
6
- int active;
7
- VALUE fiber;
8
- VALUE value;
9
- };
10
-
11
- VALUE cGyro_Async = Qnil;
12
-
13
- static void Gyro_Async_mark(void *ptr) {
14
- struct Gyro_Async *async = ptr;
15
- if (async->fiber != Qnil) {
16
- rb_gc_mark(async->fiber);
17
- }
18
- if (async->value != Qnil) {
19
- rb_gc_mark(async->value);
20
- }
21
- }
22
-
23
- static void Gyro_Async_free(void *ptr) {
24
- struct Gyro_Async *async = ptr;
25
- if (async->active) {
26
- printf("Async watcher garbage collected while still active!\n");
27
- }
28
- xfree(async);
29
- }
30
-
31
- static size_t Gyro_Async_size(const void *ptr) {
32
- return sizeof(struct Gyro_Async);
33
- }
34
-
35
- static const rb_data_type_t Gyro_Async_type = {
36
- "Gyro_Async",
37
- {Gyro_Async_mark, Gyro_Async_free, Gyro_Async_size,},
38
- 0, 0,
39
- RUBY_TYPED_FREE_IMMEDIATELY,
40
- };
41
-
42
- static VALUE Gyro_Async_allocate(VALUE klass) {
43
- struct Gyro_Async *async = (struct Gyro_Async *)xmalloc(sizeof(struct Gyro_Async));
44
- return TypedData_Wrap_Struct(klass, &Gyro_Async_type, async);
45
- }
46
-
47
- void Gyro_Async_callback(struct ev_loop *ev_loop, struct ev_async *ev_async, int revents) {
48
- struct Gyro_Async *async = (struct Gyro_Async*)ev_async;
49
-
50
- ev_async_stop(async->ev_loop, ev_async);
51
- async->active = 0;
52
-
53
- if (async->fiber != Qnil) {
54
- Gyro_schedule_fiber(async->fiber, async->value);
55
- async->fiber = Qnil;
56
- async->value = Qnil;
57
- }
58
- }
59
-
60
- #define GetGyro_Async(obj, async) \
61
- TypedData_Get_Struct((obj), struct Gyro_Async, &Gyro_Async_type, (async))
62
-
63
- static VALUE Gyro_Async_initialize(VALUE self) {
64
- struct Gyro_Async *async;
65
- GetGyro_Async(self, async);
66
-
67
- async->fiber = Qnil;
68
- async->value = Qnil;
69
- async->active = 0;
70
-
71
- ev_async_init(&async->ev_async, Gyro_Async_callback);
72
- async->ev_loop = 0;
73
-
74
- return Qnil;
75
- }
76
-
77
- static VALUE Gyro_Async_signal(int argc, VALUE *argv, VALUE self) {
78
- struct Gyro_Async *async;
79
- GetGyro_Async(self, async);
80
-
81
- if (!async->active) {
82
- // printf("signal! called before await\n");
83
- return Qnil;
84
- }
85
-
86
- async->value = (argc == 1) ? argv[0] : Qnil;
87
- ev_async_send(async->ev_loop, &async->ev_async);
88
-
89
- return Qnil;
90
- }
91
-
92
- VALUE Gyro_Async_await(VALUE self) {
93
- struct Gyro_Async *async;
94
- VALUE ret;
95
-
96
- GetGyro_Async(self, async);
97
-
98
- async->fiber = rb_fiber_current();
99
- if (!async->active) {
100
- async->active = 1;
101
- async->ev_loop = Gyro_Selector_current_thread_ev_loop();
102
- ev_async_start(async->ev_loop, &async->ev_async);
103
- }
104
-
105
- ret = Fiber_await();
106
- RB_GC_GUARD(ret);
107
-
108
- if (async->active) {
109
- async->active = 0;
110
- async->fiber = Qnil;
111
- ev_async_stop(async->ev_loop, &async->ev_async);
112
- async->value = Qnil;
113
- }
114
-
115
- // fiber is resumed
116
- if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) {
117
- return rb_funcall(rb_mKernel, ID_raise, 1, ret);
118
- }
119
- else {
120
- return ret;
121
- }
122
- }
123
-
124
- VALUE Gyro_Async_await_no_raise(VALUE self) {
125
- struct Gyro_Async *async;
126
- VALUE ret;
127
-
128
- GetGyro_Async(self, async);
129
-
130
- async->fiber = rb_fiber_current();
131
- if (!async->active) {
132
- async->active = 1;
133
- async->ev_loop = Gyro_Selector_current_thread_ev_loop();
134
- ev_async_start(async->ev_loop, &async->ev_async);
135
- }
136
-
137
- ret = Fiber_await();
138
- RB_GC_GUARD(ret);
139
-
140
- if (async->active) {
141
- async->active = 0;
142
- async->fiber = Qnil;
143
- ev_async_stop(async->ev_loop, &async->ev_async);
144
- async->value = Qnil;
145
- }
146
-
147
- return ret;
148
- }
149
-
150
-
151
- void Init_Gyro_Async() {
152
- cGyro_Async = rb_define_class_under(mGyro, "Async", rb_cData);
153
- rb_define_alloc_func(cGyro_Async, Gyro_Async_allocate);
154
-
155
- rb_define_method(cGyro_Async, "initialize", Gyro_Async_initialize, 0);
156
- rb_define_method(cGyro_Async, "signal!", Gyro_Async_signal, -1);
157
- rb_define_method(cGyro_Async, "await", Gyro_Async_await, 0);
158
- }
@@ -1,117 +0,0 @@
1
- #include "gyro.h"
2
-
3
- struct Gyro_Child {
4
- struct ev_child ev_child;
5
- struct ev_loop *ev_loop;
6
- int active;
7
- int pid;
8
- VALUE self;
9
- VALUE fiber;
10
- };
11
-
12
- static VALUE cGyro_Child = Qnil;
13
-
14
- static void Gyro_Child_mark(void *ptr) {
15
- struct Gyro_Child *child = ptr;
16
- if (child->fiber != Qnil) {
17
- rb_gc_mark(child->fiber);
18
- }
19
- }
20
-
21
- static void Gyro_Child_free(void *ptr) {
22
- struct Gyro_Child *child = ptr;
23
- if (child->active) {
24
- printf("Child watcher garbage collected while still active!\n");
25
- }
26
- xfree(child);
27
- }
28
-
29
- static size_t Gyro_Child_size(const void *ptr) {
30
- return sizeof(struct Gyro_Child);
31
- }
32
-
33
- static const rb_data_type_t Gyro_Child_type = {
34
- "Gyro_Child",
35
- {Gyro_Child_mark, Gyro_Child_free, Gyro_Child_size,},
36
- 0, 0,
37
- RUBY_TYPED_FREE_IMMEDIATELY,
38
- };
39
-
40
- static VALUE Gyro_Child_allocate(VALUE klass) {
41
- struct Gyro_Child *child = (struct Gyro_Child *)xmalloc(sizeof(struct Gyro_Child));
42
- return TypedData_Wrap_Struct(klass, &Gyro_Child_type, child);
43
- }
44
-
45
- void Gyro_Child_callback(struct ev_loop *ev_loop, struct ev_child *ev_child, int revents) {
46
- struct Gyro_Child *child = (struct Gyro_Child*)ev_child;
47
-
48
- child->active = 0;
49
- ev_child_stop(child->ev_loop, ev_child);
50
-
51
- if (child->fiber != Qnil) {
52
- VALUE fiber = child->fiber;
53
- int exit_status = ev_child->rstatus >> 8; // weird, why should we do this?
54
-
55
- VALUE resume_value = rb_ary_new_from_args(
56
- 2, INT2NUM(ev_child->rpid), INT2NUM(exit_status)
57
- );
58
- child->fiber = Qnil;
59
- Gyro_schedule_fiber(fiber, resume_value);
60
- }
61
- }
62
-
63
- #define GetGyro_Child(obj, child) \
64
- TypedData_Get_Struct((obj), struct Gyro_Child, &Gyro_Child_type, (child))
65
-
66
- static VALUE Gyro_Child_initialize(VALUE self, VALUE pid) {
67
- struct Gyro_Child *child;
68
-
69
- GetGyro_Child(self, child);
70
-
71
- child->self = self;
72
- child->fiber = Qnil;
73
- child->pid = NUM2INT(pid);
74
- child->active = 0;
75
-
76
- ev_child_init(&child->ev_child, Gyro_Child_callback, child->pid, 0);
77
-
78
- return Qnil;
79
- }
80
-
81
- static VALUE Gyro_Child_await(VALUE self) {
82
- struct Gyro_Child *child;
83
- VALUE ret;
84
-
85
- GetGyro_Child(self, child);
86
-
87
- if (child->active)
88
- child->active = 1;
89
- child->fiber = rb_fiber_current();
90
- child->ev_loop = Gyro_Selector_current_thread_ev_loop();
91
- ev_child_start(child->ev_loop, &child->ev_child);
92
-
93
- ret = Fiber_await();
94
- RB_GC_GUARD(ret);
95
-
96
- if (child->active) {
97
- child->active = 0;
98
- child->fiber = Qnil;
99
- ev_child_stop(child->ev_loop, &child->ev_child);
100
- }
101
-
102
- // fiber is resumed, check if resumed value is an exception
103
- if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) {
104
- return rb_funcall(rb_mKernel, ID_raise, 1, ret);
105
- }
106
- else {
107
- return ret;
108
- }
109
- }
110
-
111
- void Init_Gyro_Child() {
112
- cGyro_Child = rb_define_class_under(mGyro, "Child", rb_cData);
113
- rb_define_alloc_func(cGyro_Child, Gyro_Child_allocate);
114
-
115
- rb_define_method(cGyro_Child, "initialize", Gyro_Child_initialize, 1);
116
- rb_define_method(cGyro_Child, "await", Gyro_Child_await, 0);
117
- }