polyphony 0.44.0 → 0.45.0

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -1
  3. data/CHANGELOG.md +7 -0
  4. data/Gemfile.lock +9 -11
  5. data/Rakefile +1 -1
  6. data/TODO.md +12 -7
  7. data/docs/_posts/2020-07-26-polyphony-0.44.md +77 -0
  8. data/docs/api-reference/thread.md +1 -1
  9. data/docs/getting-started/overview.md +14 -14
  10. data/docs/getting-started/tutorial.md +1 -1
  11. data/examples/core/{xx-agent.rb → xx-backend.rb} +5 -5
  12. data/examples/io/xx-pry.rb +18 -0
  13. data/examples/io/xx-rack_server.rb +71 -0
  14. data/examples/performance/thread-vs-fiber/polyphony_server_read_loop.rb +1 -1
  15. data/ext/polyphony/backend.h +41 -0
  16. data/ext/polyphony/event.c +3 -3
  17. data/ext/polyphony/extconf.rb +1 -1
  18. data/ext/polyphony/{libev_agent.c → libev_backend.c} +175 -175
  19. data/ext/polyphony/polyphony.c +1 -1
  20. data/ext/polyphony/polyphony.h +4 -4
  21. data/ext/polyphony/polyphony_ext.c +2 -2
  22. data/ext/polyphony/queue.c +2 -2
  23. data/ext/polyphony/thread.c +21 -21
  24. data/lib/polyphony.rb +13 -12
  25. data/lib/polyphony/adapters/irb.rb +2 -17
  26. data/lib/polyphony/adapters/mysql2.rb +1 -1
  27. data/lib/polyphony/adapters/postgres.rb +5 -5
  28. data/lib/polyphony/adapters/process.rb +2 -2
  29. data/lib/polyphony/adapters/readline.rb +17 -0
  30. data/lib/polyphony/adapters/sequel.rb +1 -1
  31. data/lib/polyphony/core/global_api.rb +11 -6
  32. data/lib/polyphony/core/resource_pool.rb +2 -2
  33. data/lib/polyphony/core/sync.rb +38 -2
  34. data/lib/polyphony/core/throttler.rb +1 -1
  35. data/lib/polyphony/extensions/core.rb +31 -20
  36. data/lib/polyphony/extensions/fiber.rb +1 -1
  37. data/lib/polyphony/extensions/io.rb +7 -8
  38. data/lib/polyphony/extensions/openssl.rb +6 -6
  39. data/lib/polyphony/extensions/socket.rb +4 -14
  40. data/lib/polyphony/extensions/thread.rb +6 -5
  41. data/lib/polyphony/version.rb +1 -1
  42. data/polyphony.gemspec +4 -3
  43. data/test/helper.rb +1 -1
  44. data/test/{test_agent.rb → test_backend.rb} +22 -22
  45. data/test/test_fiber.rb +4 -4
  46. data/test/test_io.rb +1 -1
  47. data/test/test_kernel.rb +5 -0
  48. data/test/test_signal.rb +3 -3
  49. data/test/test_sync.rb +52 -0
  50. metadata +40 -30
  51. data/.gitbook.yaml +0 -4
  52. data/ext/polyphony/agent.h +0 -41
@@ -37,7 +37,7 @@ spin do
37
37
  server = TCPServer.open('0.0.0.0', 1234)
38
38
  puts "listening on port 1234"
39
39
 
40
- Thread.current.agent.accept_loop(server) do |client|
40
+ Thread.current.backend.accept_loop(server) do |client|
41
41
  spin { handle_client(client) }
42
42
  end
43
43
  # loop do
@@ -0,0 +1,41 @@
1
+ #ifndef BACKEND_H
2
+ #define BACKEND_H
3
+
4
+ #include "ruby.h"
5
+
6
+ // backend interface function signatures
7
+
8
+ // VALUE LibevBackend_accept(VALUE self, VALUE sock);
9
+ // VALUE LibevBackend_accept_loop(VALUE self, VALUE sock);
10
+ // VALUE libev_backend_await(VALUE self);
11
+ // VALUE LibevBackend_connect(VALUE self, VALUE sock, VALUE host, VALUE port);
12
+ // VALUE LibevBackend_finalize(VALUE self);
13
+ // VALUE LibevBackend_post_fork(VALUE self);
14
+ // VALUE LibevBackend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof);
15
+ // VALUE LibevBackend_read_loop(VALUE self, VALUE io);
16
+ // VALUE LibevBackend_sleep(VALUE self, VALUE duration);
17
+ // VALUE LibevBackend_wait_io(VALUE self, VALUE io, VALUE write);
18
+ // VALUE LibevBackend_wait_pid(VALUE self, VALUE pid);
19
+ // VALUE LibevBackend_write(int argc, VALUE *argv, VALUE self);
20
+
21
+ typedef VALUE (* backend_pending_count_t)(VALUE self);
22
+ typedef VALUE (*backend_poll_t)(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue);
23
+ typedef VALUE (* backend_ref_t)(VALUE self);
24
+ typedef int (* backend_ref_count_t)(VALUE self);
25
+ typedef void (* backend_reset_ref_count_t)(VALUE self);
26
+ typedef VALUE (* backend_unref_t)(VALUE self);
27
+ typedef VALUE (* backend_wait_event_t)(VALUE self, VALUE raise_on_exception);
28
+ typedef VALUE (* backend_wakeup_t)(VALUE self);
29
+
30
+ typedef struct backend_interface {
31
+ backend_pending_count_t pending_count;
32
+ backend_poll_t poll;
33
+ backend_ref_t ref;
34
+ backend_ref_count_t ref_count;
35
+ backend_reset_ref_count_t reset_ref_count;
36
+ backend_unref_t unref;
37
+ backend_wait_event_t wait_event;
38
+ backend_wakeup_t wakeup;
39
+ } backend_interface_t;
40
+
41
+ #endif /* BACKEND_H */
@@ -64,13 +64,13 @@ VALUE Event_await(VALUE self) {
64
64
  if (event->waiting_fiber != Qnil)
65
65
  rb_raise(rb_eRuntimeError, "Event is already awaited by another fiber");
66
66
 
67
- VALUE agent = rb_ivar_get(rb_thread_current(), ID_ivar_agent);
67
+ VALUE backend = rb_ivar_get(rb_thread_current(), ID_ivar_backend);
68
68
  event->waiting_fiber = rb_fiber_current();
69
- VALUE switchpoint_result = __AGENT__.wait_event(agent, Qnil);
69
+ VALUE switchpoint_result = __BACKEND__.wait_event(backend, Qnil);
70
70
  event->waiting_fiber = Qnil;
71
71
 
72
72
  TEST_RESUME_EXCEPTION(switchpoint_result);
73
- RB_GC_GUARD(agent);
73
+ RB_GC_GUARD(backend);
74
74
  RB_GC_GUARD(switchpoint_result);
75
75
 
76
76
  return switchpoint_result;
@@ -17,4 +17,4 @@ $defs << "-DHAVE_SYS_RESOURCE_H" if have_header("sys/resource.h")
17
17
  CONFIG["optflags"] << " -fno-strict-aliasing" unless RUBY_PLATFORM =~ /mswin/
18
18
 
19
19
  dir_config "polyphony_ext"
20
- create_makefile "polyphony_ext"
20
+ create_makefile "polyphony_ext"
@@ -11,155 +11,155 @@
11
11
 
12
12
  VALUE cTCPSocket;
13
13
 
14
- typedef struct LibevAgent_t {
14
+ typedef struct LibevBackend_t {
15
15
  struct ev_loop *ev_loop;
16
16
  struct ev_async break_async;
17
17
  int running;
18
18
  int ref_count;
19
19
  int run_no_wait_count;
20
- } LibevAgent_t;
20
+ } LibevBackend_t;
21
21
 
22
- static size_t LibevAgent_size(const void *ptr) {
23
- return sizeof(LibevAgent_t);
22
+ static size_t LibevBackend_size(const void *ptr) {
23
+ return sizeof(LibevBackend_t);
24
24
  }
25
25
 
26
- static const rb_data_type_t LibevAgent_type = {
26
+ static const rb_data_type_t LibevBackend_type = {
27
27
  "Libev",
28
- {0, 0, LibevAgent_size,},
28
+ {0, 0, LibevBackend_size,},
29
29
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY
30
30
  };
31
31
 
32
- static VALUE LibevAgent_allocate(VALUE klass) {
33
- LibevAgent_t *agent = ALLOC(LibevAgent_t);
32
+ static VALUE LibevBackend_allocate(VALUE klass) {
33
+ LibevBackend_t *backend = ALLOC(LibevBackend_t);
34
34
 
35
- return TypedData_Wrap_Struct(klass, &LibevAgent_type, agent);
35
+ return TypedData_Wrap_Struct(klass, &LibevBackend_type, backend);
36
36
  }
37
37
 
38
- #define GetLibevAgent(obj, agent) \
39
- TypedData_Get_Struct((obj), LibevAgent_t, &LibevAgent_type, (agent))
38
+ #define GetLibevBackend(obj, backend) \
39
+ TypedData_Get_Struct((obj), LibevBackend_t, &LibevBackend_type, (backend))
40
40
 
41
41
  void break_async_callback(struct ev_loop *ev_loop, struct ev_async *ev_async, int revents) {
42
42
  // This callback does nothing, the break async is used solely for breaking out
43
43
  // of a *blocking* event loop (waking it up) in a thread-safe, signal-safe manner
44
44
  }
45
45
 
46
- static VALUE LibevAgent_initialize(VALUE self) {
47
- LibevAgent_t *agent;
46
+ static VALUE LibevBackend_initialize(VALUE self) {
47
+ LibevBackend_t *backend;
48
48
  VALUE thread = rb_thread_current();
49
49
  int is_main_thread = (thread == rb_thread_main());
50
50
 
51
- GetLibevAgent(self, agent);
52
- agent->ev_loop = is_main_thread ? EV_DEFAULT : ev_loop_new(EVFLAG_NOSIGMASK);
51
+ GetLibevBackend(self, backend);
52
+ backend->ev_loop = is_main_thread ? EV_DEFAULT : ev_loop_new(EVFLAG_NOSIGMASK);
53
53
 
54
- ev_async_init(&agent->break_async, break_async_callback);
55
- ev_async_start(agent->ev_loop, &agent->break_async);
56
- ev_unref(agent->ev_loop); // don't count the break_async watcher
54
+ ev_async_init(&backend->break_async, break_async_callback);
55
+ ev_async_start(backend->ev_loop, &backend->break_async);
56
+ ev_unref(backend->ev_loop); // don't count the break_async watcher
57
57
 
58
- agent->running = 0;
59
- agent->ref_count = 0;
60
- agent->run_no_wait_count = 0;
58
+ backend->running = 0;
59
+ backend->ref_count = 0;
60
+ backend->run_no_wait_count = 0;
61
61
 
62
62
  return Qnil;
63
63
  }
64
64
 
65
- VALUE LibevAgent_finalize(VALUE self) {
66
- LibevAgent_t *agent;
67
- GetLibevAgent(self, agent);
65
+ VALUE LibevBackend_finalize(VALUE self) {
66
+ LibevBackend_t *backend;
67
+ GetLibevBackend(self, backend);
68
68
 
69
- ev_async_stop(agent->ev_loop, &agent->break_async);
69
+ ev_async_stop(backend->ev_loop, &backend->break_async);
70
70
 
71
- if (!ev_is_default_loop(agent->ev_loop)) ev_loop_destroy(agent->ev_loop);
71
+ if (!ev_is_default_loop(backend->ev_loop)) ev_loop_destroy(backend->ev_loop);
72
72
 
73
73
  return self;
74
74
  }
75
75
 
76
- VALUE LibevAgent_post_fork(VALUE self) {
77
- LibevAgent_t *agent;
78
- GetLibevAgent(self, agent);
76
+ VALUE LibevBackend_post_fork(VALUE self) {
77
+ LibevBackend_t *backend;
78
+ GetLibevBackend(self, backend);
79
79
 
80
80
  // After fork there may be some watchers still active left over from the
81
81
  // parent, so we destroy the loop, even if it's the default one, then use the
82
82
  // default one, as post_fork is called only from the main thread of the forked
83
83
  // process. That way we don't need to call ev_loop_fork, since the loop is
84
84
  // always a fresh one.
85
- ev_loop_destroy(agent->ev_loop);
86
- agent->ev_loop = EV_DEFAULT;
85
+ ev_loop_destroy(backend->ev_loop);
86
+ backend->ev_loop = EV_DEFAULT;
87
87
 
88
88
  return self;
89
89
  }
90
90
 
91
- VALUE LibevAgent_ref(VALUE self) {
92
- LibevAgent_t *agent;
93
- GetLibevAgent(self, agent);
91
+ VALUE LibevBackend_ref(VALUE self) {
92
+ LibevBackend_t *backend;
93
+ GetLibevBackend(self, backend);
94
94
 
95
- agent->ref_count++;
95
+ backend->ref_count++;
96
96
  return self;
97
97
  }
98
98
 
99
- VALUE LibevAgent_unref(VALUE self) {
100
- LibevAgent_t *agent;
101
- GetLibevAgent(self, agent);
99
+ VALUE LibevBackend_unref(VALUE self) {
100
+ LibevBackend_t *backend;
101
+ GetLibevBackend(self, backend);
102
102
 
103
- agent->ref_count--;
103
+ backend->ref_count--;
104
104
  return self;
105
105
  }
106
106
 
107
- int LibevAgent_ref_count(VALUE self) {
108
- LibevAgent_t *agent;
109
- GetLibevAgent(self, agent);
107
+ int LibevBackend_ref_count(VALUE self) {
108
+ LibevBackend_t *backend;
109
+ GetLibevBackend(self, backend);
110
110
 
111
- return agent->ref_count;
111
+ return backend->ref_count;
112
112
  }
113
113
 
114
- void LibevAgent_reset_ref_count(VALUE self) {
115
- LibevAgent_t *agent;
116
- GetLibevAgent(self, agent);
114
+ void LibevBackend_reset_ref_count(VALUE self) {
115
+ LibevBackend_t *backend;
116
+ GetLibevBackend(self, backend);
117
117
 
118
- agent->ref_count = 0;
118
+ backend->ref_count = 0;
119
119
  }
120
120
 
121
- VALUE LibevAgent_pending_count(VALUE self) {
121
+ VALUE LibevBackend_pending_count(VALUE self) {
122
122
  int count;
123
- LibevAgent_t *agent;
124
- GetLibevAgent(self, agent);
125
- count = ev_pending_count(agent->ev_loop);
123
+ LibevBackend_t *backend;
124
+ GetLibevBackend(self, backend);
125
+ count = ev_pending_count(backend->ev_loop);
126
126
  return INT2NUM(count);
127
127
  }
128
128
 
129
- VALUE LibevAgent_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue) {
129
+ VALUE LibevBackend_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue) {
130
130
  int is_nowait = nowait == Qtrue;
131
- LibevAgent_t *agent;
132
- GetLibevAgent(self, agent);
131
+ LibevBackend_t *backend;
132
+ GetLibevBackend(self, backend);
133
133
 
134
134
  if (is_nowait) {
135
135
  long runnable_count = Queue_len(queue);
136
- agent->run_no_wait_count++;
137
- if (agent->run_no_wait_count < runnable_count || agent->run_no_wait_count < 10)
136
+ backend->run_no_wait_count++;
137
+ if (backend->run_no_wait_count < runnable_count || backend->run_no_wait_count < 10)
138
138
  return self;
139
139
  }
140
140
 
141
- agent->run_no_wait_count = 0;
141
+ backend->run_no_wait_count = 0;
142
142
 
143
143
  COND_TRACE(2, SYM_fiber_ev_loop_enter, current_fiber);
144
- agent->running = 1;
145
- ev_run(agent->ev_loop, is_nowait ? EVRUN_NOWAIT : EVRUN_ONCE);
146
- agent->running = 0;
144
+ backend->running = 1;
145
+ ev_run(backend->ev_loop, is_nowait ? EVRUN_NOWAIT : EVRUN_ONCE);
146
+ backend->running = 0;
147
147
  COND_TRACE(2, SYM_fiber_ev_loop_leave, current_fiber);
148
148
 
149
149
  return self;
150
150
  }
151
151
 
152
- VALUE LibevAgent_wakeup(VALUE self) {
153
- LibevAgent_t *agent;
154
- GetLibevAgent(self, agent);
152
+ VALUE LibevBackend_wakeup(VALUE self) {
153
+ LibevBackend_t *backend;
154
+ GetLibevBackend(self, backend);
155
155
 
156
- if (agent->running) {
156
+ if (backend->running) {
157
157
  // Since the loop will run until at least one event has occurred, we signal
158
158
  // the selector's associated async watcher, which will cause the ev loop to
159
159
  // return. In contrast to using `ev_break` to break out of the loop, which
160
160
  // should be called from the same thread (from within the ev_loop), using an
161
161
  // `ev_async` allows us to interrupt the event loop across threads.
162
- ev_async_send(agent->ev_loop, &agent->break_async);
162
+ ev_async_send(backend->ev_loop, &backend->break_async);
163
163
  return Qtrue;
164
164
  }
165
165
 
@@ -238,37 +238,37 @@ struct libev_io {
238
238
  VALUE fiber;
239
239
  };
240
240
 
241
- void LibevAgent_io_callback(EV_P_ ev_io *w, int revents)
241
+ void LibevBackend_io_callback(EV_P_ ev_io *w, int revents)
242
242
  {
243
243
  struct libev_io *watcher = (struct libev_io *)w;
244
244
  Fiber_make_runnable(watcher->fiber, Qnil);
245
245
  }
246
246
 
247
- inline VALUE libev_await(LibevAgent_t *agent) {
247
+ inline VALUE libev_await(LibevBackend_t *backend) {
248
248
  VALUE ret;
249
- agent->ref_count++;
249
+ backend->ref_count++;
250
250
  ret = Thread_switch_fiber(rb_thread_current());
251
- agent->ref_count--;
251
+ backend->ref_count--;
252
252
  RB_GC_GUARD(ret);
253
253
  return ret;
254
254
  }
255
255
 
256
- VALUE libev_agent_await(VALUE self) {
257
- LibevAgent_t *agent;
258
- GetLibevAgent(self, agent);
259
- return libev_await(agent);
256
+ VALUE libev_backend_await(VALUE self) {
257
+ LibevBackend_t *backend;
258
+ GetLibevBackend(self, backend);
259
+ return libev_await(backend);
260
260
  }
261
261
 
262
- VALUE libev_io_wait(LibevAgent_t *agent, struct libev_io *watcher, rb_io_t *fptr, int flags) {
262
+ VALUE libev_io_wait(LibevBackend_t *backend, struct libev_io *watcher, rb_io_t *fptr, int flags) {
263
263
  VALUE switchpoint_result;
264
264
 
265
265
  if (watcher->fiber == Qnil) {
266
266
  watcher->fiber = rb_fiber_current();
267
- ev_io_init(&watcher->io, LibevAgent_io_callback, fptr->fd, flags);
267
+ ev_io_init(&watcher->io, LibevBackend_io_callback, fptr->fd, flags);
268
268
  }
269
- ev_io_start(agent->ev_loop, &watcher->io);
270
- switchpoint_result = libev_await(agent);
271
- ev_io_stop(agent->ev_loop, &watcher->io);
269
+ ev_io_start(backend->ev_loop, &watcher->io);
270
+ switchpoint_result = libev_await(backend);
271
+ ev_io_stop(backend->ev_loop, &watcher->io);
272
272
 
273
273
  RB_GC_GUARD(switchpoint_result);
274
274
  return switchpoint_result;
@@ -304,8 +304,8 @@ inline void io_set_nonblock(rb_io_t *fptr, VALUE io) {
304
304
  return;
305
305
  }
306
306
 
307
- VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof) {
308
- LibevAgent_t *agent;
307
+ VALUE LibevBackend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof) {
308
+ LibevBackend_t *backend;
309
309
  struct libev_io watcher;
310
310
  rb_io_t *fptr;
311
311
  long dynamic_len = length == Qnil;
@@ -317,7 +317,7 @@ VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eo
317
317
  int read_to_eof = RTEST(to_eof);
318
318
  VALUE underlying_io = rb_iv_get(io, "@io");
319
319
 
320
- GetLibevAgent(self, agent);
320
+ GetLibevBackend(self, backend);
321
321
  if (underlying_io != Qnil) io = underlying_io;
322
322
  GetOpenFile(io, fptr);
323
323
  rb_io_check_byte_readable(fptr);
@@ -341,7 +341,7 @@ VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eo
341
341
  int e = errno;
342
342
  if (e != EWOULDBLOCK && e != EAGAIN) rb_syserr_fail(e, strerror(e));
343
343
 
344
- switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
344
+ switchpoint_result = libev_io_wait(backend, &watcher, fptr, EV_READ);
345
345
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
346
346
  }
347
347
  else {
@@ -377,7 +377,7 @@ error:
377
377
  return RAISE_EXCEPTION(switchpoint_result);
378
378
  }
379
379
 
380
- VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
380
+ VALUE LibevBackend_read_loop(VALUE self, VALUE io) {
381
381
 
382
382
  #define PREPARE_STR() { \
383
383
  str = Qnil; \
@@ -394,7 +394,7 @@ VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
394
394
  PREPARE_STR(); \
395
395
  }
396
396
 
397
- LibevAgent_t *agent;
397
+ LibevBackend_t *backend;
398
398
  struct libev_io watcher;
399
399
  rb_io_t *fptr;
400
400
  VALUE str;
@@ -407,7 +407,7 @@ VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
407
407
 
408
408
  PREPARE_STR();
409
409
 
410
- GetLibevAgent(self, agent);
410
+ GetLibevBackend(self, backend);
411
411
  if (underlying_io != Qnil) io = underlying_io;
412
412
  GetOpenFile(io, fptr);
413
413
  rb_io_check_byte_readable(fptr);
@@ -429,7 +429,7 @@ VALUE LibevAgent_read_loop(VALUE self, VALUE io) {
429
429
  int e = errno;
430
430
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
431
431
 
432
- switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
432
+ switchpoint_result = libev_io_wait(backend, &watcher, fptr, EV_READ);
433
433
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
434
434
  }
435
435
  else {
@@ -457,8 +457,8 @@ error:
457
457
  return RAISE_EXCEPTION(switchpoint_result);
458
458
  }
459
459
 
460
- VALUE LibevAgent_write(VALUE self, VALUE io, VALUE str) {
461
- LibevAgent_t *agent;
460
+ VALUE LibevBackend_write(VALUE self, VALUE io, VALUE str) {
461
+ LibevBackend_t *backend;
462
462
  struct libev_io watcher;
463
463
  rb_io_t *fptr;
464
464
  VALUE switchpoint_result = Qnil;
@@ -469,7 +469,7 @@ VALUE LibevAgent_write(VALUE self, VALUE io, VALUE str) {
469
469
 
470
470
  underlying_io = rb_iv_get(io, "@io");
471
471
  if (underlying_io != Qnil) io = underlying_io;
472
- GetLibevAgent(self, agent);
472
+ GetLibevBackend(self, backend);
473
473
  io = rb_io_get_write_io(io);
474
474
  GetOpenFile(io, fptr);
475
475
  watcher.fiber = Qnil;
@@ -479,7 +479,7 @@ VALUE LibevAgent_write(VALUE self, VALUE io, VALUE str) {
479
479
  if (n < 0) {
480
480
  int e = errno;
481
481
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
482
- switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
482
+ switchpoint_result = libev_io_wait(backend, &watcher, fptr, EV_WRITE);
483
483
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
484
484
  }
485
485
  else {
@@ -501,8 +501,8 @@ error:
501
501
  return RAISE_EXCEPTION(switchpoint_result);
502
502
  }
503
503
 
504
- VALUE LibevAgent_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
505
- LibevAgent_t *agent;
504
+ VALUE LibevBackend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
505
+ LibevBackend_t *backend;
506
506
  struct libev_io watcher;
507
507
  rb_io_t *fptr;
508
508
  VALUE switchpoint_result = Qnil;
@@ -515,7 +515,7 @@ VALUE LibevAgent_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
515
515
 
516
516
  underlying_io = rb_iv_get(io, "@io");
517
517
  if (underlying_io != Qnil) io = underlying_io;
518
- GetLibevAgent(self, agent);
518
+ GetLibevBackend(self, backend);
519
519
  io = rb_io_get_write_io(io);
520
520
  GetOpenFile(io, fptr);
521
521
  watcher.fiber = Qnil;
@@ -535,7 +535,7 @@ VALUE LibevAgent_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
535
535
  int e = errno;
536
536
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
537
537
 
538
- switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
538
+ switchpoint_result = libev_io_wait(backend, &watcher, fptr, EV_WRITE);
539
539
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
540
540
  }
541
541
  else {
@@ -571,20 +571,20 @@ error:
571
571
  return RAISE_EXCEPTION(switchpoint_result);
572
572
  }
573
573
 
574
- VALUE LibevAgent_write_m(int argc, VALUE *argv, VALUE self) {
574
+ VALUE LibevBackend_write_m(int argc, VALUE *argv, VALUE self) {
575
575
  if (argc < 2)
576
576
  // TODO: raise ArgumentError
577
577
  rb_raise(rb_eRuntimeError, "(wrong number of arguments (expected 2 or more))");
578
578
 
579
579
  return (argc == 2) ?
580
- LibevAgent_write(self, argv[0], argv[1]) :
581
- LibevAgent_writev(self, argv[0], argc - 1, argv + 1);
580
+ LibevBackend_write(self, argv[0], argv[1]) :
581
+ LibevBackend_writev(self, argv[0], argc - 1, argv + 1);
582
582
  }
583
583
 
584
584
  ///////////////////////////////////////////////////////////////////////////
585
585
 
586
- VALUE LibevAgent_accept(VALUE self, VALUE sock) {
587
- LibevAgent_t *agent;
586
+ VALUE LibevBackend_accept(VALUE self, VALUE sock) {
587
+ LibevBackend_t *backend;
588
588
  struct libev_io watcher;
589
589
  rb_io_t *fptr;
590
590
  int fd;
@@ -594,7 +594,7 @@ VALUE LibevAgent_accept(VALUE self, VALUE sock) {
594
594
  VALUE underlying_sock = rb_iv_get(sock, "@io");
595
595
  if (underlying_sock != Qnil) sock = underlying_sock;
596
596
 
597
- GetLibevAgent(self, agent);
597
+ GetLibevBackend(self, backend);
598
598
  GetOpenFile(sock, fptr);
599
599
  io_set_nonblock(fptr, sock);
600
600
  watcher.fiber = Qnil;
@@ -604,7 +604,7 @@ VALUE LibevAgent_accept(VALUE self, VALUE sock) {
604
604
  int e = errno;
605
605
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
606
606
 
607
- switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
607
+ switchpoint_result = libev_io_wait(backend, &watcher, fptr, EV_READ);
608
608
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
609
609
  }
610
610
  else {
@@ -637,8 +637,8 @@ error:
637
637
  return RAISE_EXCEPTION(switchpoint_result);
638
638
  }
639
639
 
640
- VALUE LibevAgent_accept_loop(VALUE self, VALUE sock) {
641
- LibevAgent_t *agent;
640
+ VALUE LibevBackend_accept_loop(VALUE self, VALUE sock) {
641
+ LibevBackend_t *backend;
642
642
  struct libev_io watcher;
643
643
  rb_io_t *fptr;
644
644
  int fd;
@@ -649,7 +649,7 @@ VALUE LibevAgent_accept_loop(VALUE self, VALUE sock) {
649
649
  VALUE underlying_sock = rb_iv_get(sock, "@io");
650
650
  if (underlying_sock != Qnil) sock = underlying_sock;
651
651
 
652
- GetLibevAgent(self, agent);
652
+ GetLibevBackend(self, backend);
653
653
  GetOpenFile(sock, fptr);
654
654
  io_set_nonblock(fptr, sock);
655
655
  watcher.fiber = Qnil;
@@ -660,7 +660,7 @@ VALUE LibevAgent_accept_loop(VALUE self, VALUE sock) {
660
660
  int e = errno;
661
661
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
662
662
 
663
- switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_READ);
663
+ switchpoint_result = libev_io_wait(backend, &watcher, fptr, EV_READ);
664
664
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
665
665
  }
666
666
  else {
@@ -693,8 +693,8 @@ error:
693
693
  return RAISE_EXCEPTION(switchpoint_result);
694
694
  }
695
695
 
696
- VALUE LibevAgent_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
697
- LibevAgent_t *agent;
696
+ VALUE LibevBackend_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
697
+ LibevBackend_t *backend;
698
698
  struct libev_io watcher;
699
699
  rb_io_t *fptr;
700
700
  struct sockaddr_in addr;
@@ -703,7 +703,7 @@ VALUE LibevAgent_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
703
703
  VALUE underlying_sock = rb_iv_get(sock, "@io");
704
704
  if (underlying_sock != Qnil) sock = underlying_sock;
705
705
 
706
- GetLibevAgent(self, agent);
706
+ GetLibevBackend(self, backend);
707
707
  GetOpenFile(sock, fptr);
708
708
  io_set_nonblock(fptr, sock);
709
709
  watcher.fiber = Qnil;
@@ -716,7 +716,7 @@ VALUE LibevAgent_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
716
716
  if (result < 0) {
717
717
  int e = errno;
718
718
  if (e != EINPROGRESS) rb_syserr_fail(e, strerror(e));
719
- switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
719
+ switchpoint_result = libev_io_wait(backend, &watcher, fptr, EV_WRITE);
720
720
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
721
721
  }
722
722
  else {
@@ -729,31 +729,31 @@ error:
729
729
  return RAISE_EXCEPTION(switchpoint_result);
730
730
  }
731
731
 
732
- VALUE libev_wait_fd(LibevAgent_t *agent, int fd, int events, int raise_exception) {
732
+ VALUE libev_wait_fd(LibevBackend_t *backend, int fd, int events, int raise_exception) {
733
733
  struct libev_io watcher;
734
734
  VALUE switchpoint_result = Qnil;
735
735
 
736
736
  watcher.fiber = rb_fiber_current();
737
- ev_io_init(&watcher.io, LibevAgent_io_callback, fd, events);
738
- ev_io_start(agent->ev_loop, &watcher.io);
739
- switchpoint_result = libev_await(agent);
740
- ev_io_stop(agent->ev_loop, &watcher.io);
737
+ ev_io_init(&watcher.io, LibevBackend_io_callback, fd, events);
738
+ ev_io_start(backend->ev_loop, &watcher.io);
739
+ switchpoint_result = libev_await(backend);
740
+ ev_io_stop(backend->ev_loop, &watcher.io);
741
741
 
742
742
  if (raise_exception) TEST_RESUME_EXCEPTION(switchpoint_result);
743
743
  RB_GC_GUARD(switchpoint_result);
744
744
  return switchpoint_result;
745
745
  }
746
746
 
747
- VALUE LibevAgent_wait_io(VALUE self, VALUE io, VALUE write) {
748
- LibevAgent_t *agent;
747
+ VALUE LibevBackend_wait_io(VALUE self, VALUE io, VALUE write) {
748
+ LibevBackend_t *backend;
749
749
  rb_io_t *fptr;
750
750
  int events = RTEST(write) ? EV_WRITE : EV_READ;
751
751
  VALUE underlying_io = rb_iv_get(io, "@io");
752
752
  if (underlying_io != Qnil) io = underlying_io;
753
- GetLibevAgent(self, agent);
753
+ GetLibevBackend(self, backend);
754
754
  GetOpenFile(io, fptr);
755
755
 
756
- return libev_wait_fd(agent, fptr->fd, events, 1);
756
+ return libev_wait_fd(backend, fptr->fd, events, 1);
757
757
  }
758
758
 
759
759
  struct libev_timer {
@@ -761,25 +761,25 @@ struct libev_timer {
761
761
  VALUE fiber;
762
762
  };
763
763
 
764
- void LibevAgent_timer_callback(EV_P_ ev_timer *w, int revents)
764
+ void LibevBackend_timer_callback(EV_P_ ev_timer *w, int revents)
765
765
  {
766
766
  struct libev_timer *watcher = (struct libev_timer *)w;
767
767
  Fiber_make_runnable(watcher->fiber, Qnil);
768
768
  }
769
769
 
770
- VALUE LibevAgent_sleep(VALUE self, VALUE duration) {
771
- LibevAgent_t *agent;
770
+ VALUE LibevBackend_sleep(VALUE self, VALUE duration) {
771
+ LibevBackend_t *backend;
772
772
  struct libev_timer watcher;
773
773
  VALUE switchpoint_result = Qnil;
774
774
 
775
- GetLibevAgent(self, agent);
775
+ GetLibevBackend(self, backend);
776
776
  watcher.fiber = rb_fiber_current();
777
- ev_timer_init(&watcher.timer, LibevAgent_timer_callback, NUM2DBL(duration), 0.);
778
- ev_timer_start(agent->ev_loop, &watcher.timer);
777
+ ev_timer_init(&watcher.timer, LibevBackend_timer_callback, NUM2DBL(duration), 0.);
778
+ ev_timer_start(backend->ev_loop, &watcher.timer);
779
779
 
780
- switchpoint_result = libev_await(agent);
780
+ switchpoint_result = libev_await(backend);
781
781
 
782
- ev_timer_stop(agent->ev_loop, &watcher.timer);
782
+ ev_timer_stop(backend->ev_loop, &watcher.timer);
783
783
 
784
784
  TEST_RESUME_EXCEPTION(switchpoint_result);
785
785
  RB_GC_GUARD(watcher.fiber);
@@ -792,7 +792,7 @@ struct libev_child {
792
792
  VALUE fiber;
793
793
  };
794
794
 
795
- void LibevAgent_child_callback(EV_P_ ev_child *w, int revents)
795
+ void LibevBackend_child_callback(EV_P_ ev_child *w, int revents)
796
796
  {
797
797
  struct libev_child *watcher = (struct libev_child *)w;
798
798
  int exit_status = w->rstatus >> 8; // weird, why should we do this?
@@ -802,18 +802,18 @@ void LibevAgent_child_callback(EV_P_ ev_child *w, int revents)
802
802
  Fiber_make_runnable(watcher->fiber, status);
803
803
  }
804
804
 
805
- VALUE LibevAgent_waitpid(VALUE self, VALUE pid) {
806
- LibevAgent_t *agent;
805
+ VALUE LibevBackend_waitpid(VALUE self, VALUE pid) {
806
+ LibevBackend_t *backend;
807
807
  struct libev_child watcher;
808
808
  VALUE switchpoint_result = Qnil;
809
- GetLibevAgent(self, agent);
809
+ GetLibevBackend(self, backend);
810
810
 
811
811
  watcher.fiber = rb_fiber_current();
812
- ev_child_init(&watcher.child, LibevAgent_child_callback, NUM2INT(pid), 0);
813
- ev_child_start(agent->ev_loop, &watcher.child);
812
+ ev_child_init(&watcher.child, LibevBackend_child_callback, NUM2INT(pid), 0);
813
+ ev_child_start(backend->ev_loop, &watcher.child);
814
814
 
815
- switchpoint_result = libev_await(agent);
816
- ev_child_stop(agent->ev_loop, &watcher.child);
815
+ switchpoint_result = libev_await(backend);
816
+ ev_child_stop(backend->ev_loop, &watcher.child);
817
817
 
818
818
  TEST_RESUME_EXCEPTION(switchpoint_result);
819
819
  RB_GC_GUARD(watcher.fiber);
@@ -821,68 +821,68 @@ VALUE LibevAgent_waitpid(VALUE self, VALUE pid) {
821
821
  return switchpoint_result;
822
822
  }
823
823
 
824
- struct ev_loop *LibevAgent_ev_loop(VALUE self) {
825
- LibevAgent_t *agent;
826
- GetLibevAgent(self, agent);
827
- return agent->ev_loop;
824
+ struct ev_loop *LibevBackend_ev_loop(VALUE self) {
825
+ LibevBackend_t *backend;
826
+ GetLibevBackend(self, backend);
827
+ return backend->ev_loop;
828
828
  }
829
829
 
830
- void LibevAgent_async_callback(EV_P_ ev_async *w, int revents) { }
830
+ void LibevBackend_async_callback(EV_P_ ev_async *w, int revents) { }
831
831
 
832
- VALUE LibevAgent_wait_event(VALUE self, VALUE raise) {
833
- LibevAgent_t *agent;
832
+ VALUE LibevBackend_wait_event(VALUE self, VALUE raise) {
833
+ LibevBackend_t *backend;
834
834
  VALUE switchpoint_result = Qnil;
835
- GetLibevAgent(self, agent);
835
+ GetLibevBackend(self, backend);
836
836
 
837
837
  struct ev_async async;
838
838
 
839
- ev_async_init(&async, LibevAgent_async_callback);
840
- ev_async_start(agent->ev_loop, &async);
841
- switchpoint_result = libev_await(agent);
842
- ev_async_stop(agent->ev_loop, &async);
839
+ ev_async_init(&async, LibevBackend_async_callback);
840
+ ev_async_start(backend->ev_loop, &async);
841
+ switchpoint_result = libev_await(backend);
842
+ ev_async_stop(backend->ev_loop, &async);
843
843
 
844
844
  if (RTEST(raise)) TEST_RESUME_EXCEPTION(switchpoint_result);
845
845
  RB_GC_GUARD(switchpoint_result);
846
846
  return switchpoint_result;
847
847
  }
848
848
 
849
- void Init_LibevAgent() {
849
+ void Init_LibevBackend() {
850
850
  rb_require("socket");
851
851
  cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
852
852
 
853
- VALUE cAgent = rb_define_class_under(mPolyphony, "Agent", rb_cData);
854
- rb_define_alloc_func(cAgent, LibevAgent_allocate);
853
+ VALUE cBackend = rb_define_class_under(mPolyphony, "Backend", rb_cData);
854
+ rb_define_alloc_func(cBackend, LibevBackend_allocate);
855
855
 
856
- rb_define_method(cAgent, "initialize", LibevAgent_initialize, 0);
857
- rb_define_method(cAgent, "finalize", LibevAgent_finalize, 0);
858
- rb_define_method(cAgent, "post_fork", LibevAgent_post_fork, 0);
859
- rb_define_method(cAgent, "pending_count", LibevAgent_pending_count, 0);
856
+ rb_define_method(cBackend, "initialize", LibevBackend_initialize, 0);
857
+ rb_define_method(cBackend, "finalize", LibevBackend_finalize, 0);
858
+ rb_define_method(cBackend, "post_fork", LibevBackend_post_fork, 0);
859
+ rb_define_method(cBackend, "pending_count", LibevBackend_pending_count, 0);
860
860
 
861
- rb_define_method(cAgent, "ref", LibevAgent_ref, 0);
862
- rb_define_method(cAgent, "unref", LibevAgent_unref, 0);
861
+ rb_define_method(cBackend, "ref", LibevBackend_ref, 0);
862
+ rb_define_method(cBackend, "unref", LibevBackend_unref, 0);
863
863
 
864
- rb_define_method(cAgent, "poll", LibevAgent_poll, 3);
865
- rb_define_method(cAgent, "break", LibevAgent_wakeup, 0);
864
+ rb_define_method(cBackend, "poll", LibevBackend_poll, 3);
865
+ rb_define_method(cBackend, "break", LibevBackend_wakeup, 0);
866
866
 
867
- rb_define_method(cAgent, "read", LibevAgent_read, 4);
868
- rb_define_method(cAgent, "read_loop", LibevAgent_read_loop, 1);
869
- rb_define_method(cAgent, "write", LibevAgent_write_m, -1);
870
- rb_define_method(cAgent, "accept", LibevAgent_accept, 1);
871
- rb_define_method(cAgent, "accept_loop", LibevAgent_accept_loop, 1);
872
- rb_define_method(cAgent, "connect", LibevAgent_connect, 3);
873
- rb_define_method(cAgent, "wait_io", LibevAgent_wait_io, 2);
874
- rb_define_method(cAgent, "sleep", LibevAgent_sleep, 1);
875
- rb_define_method(cAgent, "waitpid", LibevAgent_waitpid, 1);
876
- rb_define_method(cAgent, "wait_event", LibevAgent_wait_event, 1);
867
+ rb_define_method(cBackend, "read", LibevBackend_read, 4);
868
+ rb_define_method(cBackend, "read_loop", LibevBackend_read_loop, 1);
869
+ rb_define_method(cBackend, "write", LibevBackend_write_m, -1);
870
+ rb_define_method(cBackend, "accept", LibevBackend_accept, 1);
871
+ rb_define_method(cBackend, "accept_loop", LibevBackend_accept_loop, 1);
872
+ rb_define_method(cBackend, "connect", LibevBackend_connect, 3);
873
+ rb_define_method(cBackend, "wait_io", LibevBackend_wait_io, 2);
874
+ rb_define_method(cBackend, "sleep", LibevBackend_sleep, 1);
875
+ rb_define_method(cBackend, "waitpid", LibevBackend_waitpid, 1);
876
+ rb_define_method(cBackend, "wait_event", LibevBackend_wait_event, 1);
877
877
 
878
878
  ID_ivar_is_nonblocking = rb_intern("@is_nonblocking");
879
879
 
880
- __AGENT__.pending_count = LibevAgent_pending_count;
881
- __AGENT__.poll = LibevAgent_poll;
882
- __AGENT__.ref = LibevAgent_ref;
883
- __AGENT__.ref_count = LibevAgent_ref_count;
884
- __AGENT__.reset_ref_count = LibevAgent_reset_ref_count;
885
- __AGENT__.unref = LibevAgent_unref;
886
- __AGENT__.wait_event = LibevAgent_wait_event;
887
- __AGENT__.wakeup = LibevAgent_wakeup;
880
+ __BACKEND__.pending_count = LibevBackend_pending_count;
881
+ __BACKEND__.poll = LibevBackend_poll;
882
+ __BACKEND__.ref = LibevBackend_ref;
883
+ __BACKEND__.ref_count = LibevBackend_ref_count;
884
+ __BACKEND__.reset_ref_count = LibevBackend_reset_ref_count;
885
+ __BACKEND__.unref = LibevBackend_unref;
886
+ __BACKEND__.wait_event = LibevBackend_wait_event;
887
+ __BACKEND__.wakeup = LibevBackend_wakeup;
888
888
  }