polyphony 0.34 → 0.41

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.
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
- }