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
@@ -0,0 +1,214 @@
1
+ #include "polyphony.h"
2
+
3
+ struct async_watcher {
4
+ ev_async async;
5
+ struct ev_loop *ev_loop;
6
+ VALUE fiber;
7
+ };
8
+
9
+ struct async_queue {
10
+ struct async_watcher **queue;
11
+ unsigned int len;
12
+ unsigned int count;
13
+ unsigned int push_idx;
14
+ unsigned int pop_idx;
15
+ };
16
+
17
+ void async_queue_init(struct async_queue *queue) {
18
+ queue->len = 4;
19
+ queue->count = 0;
20
+ queue->queue = malloc(sizeof(struct async_watcher *) * queue->len);
21
+ queue->push_idx = 0;
22
+ queue->pop_idx = 0;
23
+ }
24
+
25
+ void async_queue_free(struct async_queue *queue) {
26
+ free(queue->queue);
27
+ }
28
+
29
+ void async_queue_push(struct async_queue *queue, struct async_watcher *watcher) {
30
+ if (queue->push_idx == queue->len) {
31
+ queue->len = queue->len * 2;
32
+ queue->queue = realloc(queue->queue, sizeof(struct async_watcher *) * queue->len);
33
+ }
34
+ if (queue->count == 0) {
35
+ queue->push_idx = 0;
36
+ queue->pop_idx = 0;
37
+ }
38
+ queue->count++;
39
+ queue->queue[queue->push_idx++] = watcher;
40
+ }
41
+
42
+ struct async_watcher *async_queue_pop(struct async_queue *queue) {
43
+ if (queue->count == 0) return 0;
44
+
45
+ queue->count--;
46
+
47
+ return queue->queue[queue->pop_idx++];
48
+ }
49
+
50
+ void async_queue_remove_at_idx(struct async_queue *queue, unsigned int remove_idx) {
51
+ queue->count--;
52
+ queue->push_idx--;
53
+ if (remove_idx < queue->push_idx)
54
+ memmove(
55
+ queue->queue + remove_idx,
56
+ queue->queue + remove_idx + 1,
57
+ (queue->push_idx - remove_idx) * sizeof(struct async_watcher *)
58
+ );
59
+ }
60
+
61
+ void async_queue_remove_by_fiber(struct async_queue *queue, VALUE fiber) {
62
+ if (queue->count == 0) return;
63
+
64
+ for (unsigned idx = queue->pop_idx; idx < queue->push_idx; idx++) {
65
+ if (queue->queue[idx]->fiber == fiber) {
66
+ async_queue_remove_at_idx(queue, idx);
67
+ return;
68
+ }
69
+ }
70
+ }
71
+
72
+ typedef struct queue {
73
+ VALUE items;
74
+ struct async_queue shift_queue;
75
+ } LibevQueue_t;
76
+
77
+
78
+ VALUE cLibevQueue = Qnil;
79
+
80
+ static void LibevQueue_mark(void *ptr) {
81
+ LibevQueue_t *queue = ptr;
82
+ rb_gc_mark(queue->items);
83
+ }
84
+
85
+ static void LibevQueue_free(void *ptr) {
86
+ LibevQueue_t *queue = ptr;
87
+ async_queue_free(&queue->shift_queue);
88
+ xfree(ptr);
89
+ }
90
+
91
+ static size_t LibevQueue_size(const void *ptr) {
92
+ return sizeof(LibevQueue_t);
93
+ }
94
+
95
+ static const rb_data_type_t LibevQueue_type = {
96
+ "Queue",
97
+ {LibevQueue_mark, LibevQueue_free, LibevQueue_size,},
98
+ 0, 0, 0
99
+ };
100
+
101
+ static VALUE LibevQueue_allocate(VALUE klass) {
102
+ LibevQueue_t *queue;
103
+
104
+ queue = ALLOC(LibevQueue_t);
105
+ return TypedData_Wrap_Struct(klass, &LibevQueue_type, queue);
106
+ }
107
+
108
+ #define GetQueue(obj, queue) \
109
+ TypedData_Get_Struct((obj), LibevQueue_t, &LibevQueue_type, (queue))
110
+
111
+ static VALUE LibevQueue_initialize(VALUE self) {
112
+ LibevQueue_t *queue;
113
+ GetQueue(self, queue);
114
+
115
+ queue->items = rb_ary_new();
116
+ async_queue_init(&queue->shift_queue);
117
+
118
+ return self;
119
+ }
120
+
121
+ VALUE LibevQueue_push(VALUE self, VALUE value) {
122
+ LibevQueue_t *queue;
123
+ struct async_watcher *watcher;
124
+ GetQueue(self, queue);
125
+ watcher = async_queue_pop(&queue->shift_queue);
126
+ if (watcher) {
127
+ ev_async_send(watcher->ev_loop, &watcher->async);
128
+ }
129
+ rb_ary_push(queue->items, value);
130
+ return self;
131
+ }
132
+
133
+ struct ev_loop *LibevAgent_ev_loop(VALUE self);
134
+
135
+ void async_queue_callback(struct ev_loop *ev_loop, struct ev_async *ev_async, int revents) {
136
+ struct async_watcher *watcher = (struct async_watcher *)ev_async;
137
+ Fiber_make_runnable(watcher->fiber, Qnil);
138
+ }
139
+
140
+ VALUE LibevQueue_shift(VALUE self) {
141
+ LibevQueue_t *queue;
142
+ GetQueue(self, queue);
143
+
144
+ if (RARRAY_LEN(queue->items) == 0) {
145
+ struct async_watcher watcher;
146
+ VALUE agent = rb_ivar_get(rb_thread_current(), ID_ivar_agent);
147
+ VALUE switchpoint_result = Qnil;
148
+
149
+ watcher.ev_loop = LibevAgent_ev_loop(agent);
150
+ watcher.fiber = rb_fiber_current();
151
+ async_queue_push(&queue->shift_queue, &watcher);
152
+ ev_async_init(&watcher.async, async_queue_callback);
153
+ ev_async_start(watcher.ev_loop, &watcher.async);
154
+
155
+ switchpoint_result = Polyphony_switchpoint();
156
+ ev_async_stop(watcher.ev_loop, &watcher.async);
157
+
158
+ if (RTEST(rb_obj_is_kind_of(switchpoint_result, rb_eException))) {
159
+ async_queue_remove_by_fiber(&queue->shift_queue, watcher.fiber);
160
+ return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
161
+ }
162
+ RB_GC_GUARD(watcher.fiber);
163
+ RB_GC_GUARD(agent);
164
+ RB_GC_GUARD(switchpoint_result);
165
+ }
166
+
167
+ return rb_ary_shift(queue->items);
168
+ }
169
+
170
+ VALUE LibevQueue_shift_each(VALUE self) {
171
+ LibevQueue_t *queue;
172
+ VALUE old_queue;
173
+ GetQueue(self, queue);
174
+ old_queue = queue->items;
175
+ queue->items = rb_ary_new();
176
+
177
+ if (rb_block_given_p()) {
178
+ long len = RARRAY_LEN(old_queue);
179
+ long i;
180
+ for (i = 0; i < len; i++) {
181
+ rb_yield(RARRAY_AREF(old_queue, i));
182
+ }
183
+ RB_GC_GUARD(old_queue);
184
+ return self;
185
+ }
186
+ else {
187
+ RB_GC_GUARD(old_queue);
188
+ return old_queue;
189
+ }
190
+ }
191
+
192
+ VALUE LibevQueue_empty_p(VALUE self) {
193
+ LibevQueue_t *queue;
194
+ GetQueue(self, queue);
195
+
196
+ return (RARRAY_LEN(queue->items) == 0) ? Qtrue : Qfalse;
197
+ }
198
+
199
+ void Init_LibevQueue() {
200
+ cLibevQueue = rb_define_class_under(mPolyphony, "LibevQueue", rb_cData);
201
+ rb_define_alloc_func(cLibevQueue, LibevQueue_allocate);
202
+
203
+ rb_define_method(cLibevQueue, "initialize", LibevQueue_initialize, 0);
204
+ rb_define_method(cLibevQueue, "push", LibevQueue_push, 1);
205
+ rb_define_method(cLibevQueue, "<<", LibevQueue_push, 1);
206
+
207
+ rb_define_method(cLibevQueue, "pop", LibevQueue_shift, 0);
208
+ rb_define_method(cLibevQueue, "shift", LibevQueue_shift, 0);
209
+
210
+ rb_define_method(cLibevQueue, "shift_each", LibevQueue_shift_each, 0);
211
+ rb_define_method(cLibevQueue, "empty?", LibevQueue_empty_p, 0);
212
+ }
213
+
214
+
@@ -0,0 +1,89 @@
1
+ #include "polyphony.h"
2
+
3
+ VALUE mPolyphony;
4
+
5
+ ID ID_await_no_raise;
6
+ ID ID_call;
7
+ ID ID_caller;
8
+ ID ID_clear;
9
+ ID ID_each;
10
+ ID ID_empty;
11
+ ID ID_inspect;
12
+ ID ID_new;
13
+ ID ID_pop;
14
+ ID ID_push;
15
+ ID ID_raise;
16
+ ID ID_ivar_running;
17
+ ID ID_ivar_thread;
18
+ ID ID_runnable;
19
+ ID ID_runnable_value;
20
+ ID ID_size;
21
+ ID ID_signal;
22
+ ID ID_switch_fiber;
23
+ ID ID_transfer;
24
+ ID ID_R;
25
+ ID ID_W;
26
+ ID ID_RW;
27
+
28
+ VALUE Polyphony_snooze(VALUE self) {
29
+ VALUE ret;
30
+ VALUE fiber = rb_fiber_current();
31
+
32
+ Fiber_make_runnable(fiber, Qnil);
33
+ ret = Thread_switch_fiber(rb_thread_current());
34
+ TEST_RESUME_EXCEPTION(ret);
35
+ RB_GC_GUARD(ret);
36
+ return ret;
37
+ }
38
+
39
+ static VALUE Polyphony_ref(VALUE self) {
40
+ return Thread_ref(rb_thread_current());
41
+ }
42
+
43
+ static VALUE Polyphony_unref(VALUE self) {
44
+ return Thread_unref(rb_thread_current());
45
+ }
46
+
47
+ static VALUE Polyphony_suspend(VALUE self) {
48
+ VALUE ret = Thread_switch_fiber(rb_thread_current());
49
+
50
+ TEST_RESUME_EXCEPTION(ret);
51
+ RB_GC_GUARD(ret);
52
+ return ret;
53
+ }
54
+
55
+ VALUE Polyphony_trace(VALUE self, VALUE enabled) {
56
+ __tracing_enabled__ = RTEST(enabled) ? 1 : 0;
57
+ return Qnil;
58
+ }
59
+
60
+ void Init_Polyphony() {
61
+ mPolyphony = rb_define_module("Polyphony");
62
+
63
+ rb_define_singleton_method(mPolyphony, "ref", Polyphony_ref, 0);
64
+ rb_define_singleton_method(mPolyphony, "trace", Polyphony_trace, 1);
65
+ rb_define_singleton_method(mPolyphony, "unref", Polyphony_unref, 0);
66
+
67
+ rb_define_global_function("snooze", Polyphony_snooze, 0);
68
+ rb_define_global_function("suspend", Polyphony_suspend, 0);
69
+
70
+ ID_await_no_raise = rb_intern("await_no_raise");
71
+ ID_call = rb_intern("call");
72
+ ID_caller = rb_intern("caller");
73
+ ID_clear = rb_intern("clear");
74
+ ID_each = rb_intern("each");
75
+ ID_empty = rb_intern("empty?");
76
+ ID_inspect = rb_intern("inspect");
77
+ ID_ivar_running = rb_intern("@running");
78
+ ID_ivar_thread = rb_intern("@thread");
79
+ ID_new = rb_intern("new");
80
+ ID_pop = rb_intern("pop");
81
+ ID_push = rb_intern("push");
82
+ ID_raise = rb_intern("raise");
83
+ ID_runnable = rb_intern("runnable");
84
+ ID_runnable_value = rb_intern("runnable_value");
85
+ ID_signal = rb_intern("signal");
86
+ ID_size = rb_intern("size");
87
+ ID_switch_fiber = rb_intern("switch_fiber");
88
+ ID_transfer = rb_intern("transfer");
89
+ }
@@ -5,87 +5,41 @@
5
5
  #include "ruby/io.h"
6
6
  #include "libev.h"
7
7
 
8
- enum {
9
- FIBER_STATE_NOT_SCHEDULED = 0,
10
- FIBER_STATE_WAITING = 1,
11
- FIBER_STATE_SCHEDULED = 2
12
- };
13
-
14
- // void Gyro_add_watcher_ref(VALUE obj);
15
- // void Gyro_del_watcher_ref(VALUE obj);
16
- VALUE Gyro_snooze(VALUE self);
17
-
18
- void Gyro_schedule_fiber(VALUE fiber, VALUE value);
19
-
20
- int Gyro_ref_count();
21
- void Gyro_ref_count_incr();
22
- void Gyro_ref_count_decr();
23
-
24
- VALUE Gyro_Async_await(VALUE async);
25
- VALUE Gyro_Async_await_no_raise(VALUE async);
26
-
27
- VALUE IO_read_watcher(VALUE io);
28
- VALUE IO_write_watcher(VALUE io);
29
- VALUE Gyro_IO_await(VALUE self);
30
-
31
- VALUE Gyro_Selector_run(VALUE self, VALUE current_fiber);
32
- void Gyro_Selector_run_no_wait(VALUE self, VALUE current_fiber, long runnable_count);
33
-
34
- VALUE Gyro_Timer_await(VALUE self);
35
-
36
- int io_setstrbuf(VALUE *str, long len);
37
- void io_set_read_length(VALUE str, long n, int shrinkable);
38
- VALUE io_enc_str(VALUE str, rb_io_t *fptr);
39
-
40
- struct ev_loop *Gyro_Selector_ev_loop(VALUE selector);
41
- ev_tstamp Gyro_Selector_now(VALUE selector);
42
- struct ev_loop *Gyro_Selector_current_thread_ev_loop();
43
- long Gyro_Selector_pending_count(VALUE self);
44
- VALUE Gyro_Selector_post_fork(VALUE self);
45
-
46
- VALUE Thread_current_event_selector();
47
- VALUE Thread_ref(VALUE thread);
48
- VALUE Thread_unref(VALUE thread);
49
- VALUE Thread_switch_fiber(VALUE thread);
50
- VALUE Fiber_await();
51
- VALUE Thread_schedule_fiber(VALUE thread, VALUE fiber, VALUE value);
52
- VALUE Thread_post_fork(VALUE thread);
53
- VALUE Gyro_Selector_break_out_of_ev_loop(VALUE self);
54
-
55
- VALUE Gyro_Queue_push(VALUE self, VALUE value);
56
-
8
+ // debugging
57
9
  #define OBJ_ID(obj) (NUM2LONG(rb_funcall(obj, rb_intern("object_id"), 0)))
58
10
  #define INSPECT(...) (rb_funcall(rb_cObject, rb_intern("p"), __VA_ARGS__))
59
11
  #define FIBER_TRACE(...) if (__tracing_enabled__) { \
60
12
  rb_funcall(rb_cObject, ID_fiber_trace, __VA_ARGS__); \
61
13
  }
62
14
 
63
- extern VALUE mGyro;
64
- extern VALUE cGyro_Async;
65
- extern VALUE cGyro_IO;
66
- extern VALUE cGyro_Queue;
67
- extern VALUE cGyro_Selector;
68
- extern VALUE cGyro_Timer;
15
+ #define TEST_EXCEPTION(ret) (RTEST(rb_obj_is_kind_of(ret, rb_eException)))
16
+
17
+ #define TEST_RESUME_EXCEPTION(ret) if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) { \
18
+ return rb_funcall(rb_mKernel, ID_raise, 1, ret); \
19
+ }
20
+
21
+ extern VALUE mPolyphony;
22
+ extern VALUE cLibevQueue;
23
+ extern VALUE cEvent;
69
24
 
25
+ extern ID ID_await_no_raise;
70
26
  extern ID ID_call;
71
27
  extern ID ID_caller;
72
28
  extern ID ID_clear;
73
29
  extern ID ID_each;
74
30
  extern ID ID_fiber_trace;
75
31
  extern ID ID_inspect;
32
+ extern ID ID_ivar_agent;
76
33
  extern ID ID_ivar_running;
77
34
  extern ID ID_ivar_thread;
78
35
  extern ID ID_new;
79
36
  extern ID ID_raise;
80
37
  extern ID ID_runnable;
81
38
  extern ID ID_runnable_value;
82
- extern ID ID_signal_bang;
39
+ extern ID ID_signal;
83
40
  extern ID ID_size;
84
41
  extern ID ID_switch_fiber;
85
42
  extern ID ID_transfer;
86
- extern ID ID_R;
87
- extern ID ID_W;
88
- extern ID ID_RW;
89
43
 
90
44
  extern VALUE SYM_fiber_create;
91
45
  extern VALUE SYM_fiber_ev_loop_enter;
@@ -97,4 +51,40 @@ extern VALUE SYM_fiber_terminate;
97
51
 
98
52
  extern int __tracing_enabled__;
99
53
 
54
+ enum {
55
+ FIBER_STATE_NOT_SCHEDULED = 0,
56
+ FIBER_STATE_WAITING = 1,
57
+ FIBER_STATE_SCHEDULED = 2
58
+ };
59
+
60
+ // watcher flags
61
+ enum {
62
+ // a watcher's active field will be set to this after fork
63
+ GYRO_WATCHER_POST_FORK = 0xFF
64
+ };
65
+
66
+ VALUE Fiber_auto_watcher(VALUE self);
67
+ void Fiber_make_runnable(VALUE fiber, VALUE value);
68
+
69
+ VALUE Polyphony_switchpoint();
70
+
71
+ VALUE LibevAgent_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue);
72
+ VALUE LibevAgent_break(VALUE self);
73
+ VALUE LibevAgent_pending_count(VALUE self);
74
+ VALUE LibevAgent_wait_io(VALUE self, VALUE io, VALUE write);
75
+
76
+ VALUE Polyphony_snooze(VALUE self);
77
+
78
+ VALUE Polyphony_Queue_push(VALUE self, VALUE value);
79
+
80
+ VALUE Thread_post_fork(VALUE thread);
81
+ VALUE Thread_ref(VALUE thread);
82
+ VALUE Thread_schedule_fiber(VALUE thread, VALUE fiber, VALUE value);
83
+ VALUE Thread_switch_fiber(VALUE thread);
84
+ VALUE Thread_unref(VALUE thread);
85
+
86
+ int io_setstrbuf(VALUE *str, long len);
87
+ void io_set_read_length(VALUE str, long n, int shrinkable);
88
+ VALUE io_enc_str(VALUE str, rb_io_t *fptr);
89
+
100
90
  #endif /* RUBY_EV_H */
@@ -0,0 +1,23 @@
1
+ #include "polyphony.h"
2
+
3
+ void Init_Fiber();
4
+ void Init_Polyphony();
5
+ void Init_LibevAgent();
6
+ void Init_LibevQueue();
7
+ void Init_Socket();
8
+ void Init_Thread();
9
+ void Init_Tracing();
10
+
11
+ void Init_polyphony_ext() {
12
+ ev_set_allocator(xrealloc);
13
+
14
+ Init_Polyphony();
15
+ Init_LibevAgent();
16
+ Init_LibevQueue();
17
+
18
+ Init_Fiber();
19
+ Init_Socket();
20
+ Init_Thread();
21
+
22
+ Init_Tracing();
23
+ }