polyphony 0.43.9 → 0.43.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +1 -1
- data/TODO.md +1 -5
- data/ext/polyphony/agent.h +39 -0
- data/ext/polyphony/event.c +1 -1
- data/ext/polyphony/libev_agent.c +65 -62
- data/ext/polyphony/polyphony.c +2 -0
- data/ext/polyphony/polyphony.h +7 -11
- data/ext/polyphony/queue.c +8 -1
- data/ext/polyphony/thread.c +33 -22
- data/lib/polyphony.rb +1 -1
- data/lib/polyphony/core/sync.rb +1 -1
- data/lib/polyphony/extensions/socket.rb +1 -9
- data/lib/polyphony/extensions/thread.rb +1 -1
- data/lib/polyphony/version.rb +1 -1
- data/test/helper.rb +1 -1
- data/test/test_agent.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3000a280d995b187518c1e12f585939b4e67312db5458d105c6e6b40c784d5a
|
4
|
+
data.tar.gz: 5a582fc77ae044238521619b1d5364a0dd2aac13ca8a6b82d006ec1f23284d2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d403109b1bbf55e1b0ab799d8c74752677784ca0c12cb5b1e21f62c9bdd244245966db8020b20a8d4ed988263a9535aef5a8aff24b50587c9583a67109d7677
|
7
|
+
data.tar.gz: 205d6c9859ec8d12ddf7630cbd3893a13d3efb3537dd734e53f17efe31d52399488761da45684d0da7e5074ce950c47a7e51f4a1446577e36f7c3c7838604a7a
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/TODO.md
CHANGED
@@ -1,8 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
-- Add `Fiber#schedule_with_priority` method, aliased by `Fiber#wakeup`
|
4
|
-
- Implement agent interface is virtual function table
|
5
|
-
- Implement proxy agent for plugging in a user-provided agent class
|
1
|
+
-- Add `Fiber#schedule_with_priority` method
|
6
2
|
|
7
3
|
- Debugging
|
8
4
|
- Eat your own dogfood: need a good tool to check what's going on when some
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#ifndef AGENT_H
|
2
|
+
#define AGENT_H
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
|
6
|
+
// agent interface function signatures
|
7
|
+
|
8
|
+
// VALUE LibevAgent_accept(VALUE self, VALUE sock);
|
9
|
+
// VALUE LibevAgent_accept_loop(VALUE self, VALUE sock);
|
10
|
+
// VALUE libev_agent_await(VALUE self);
|
11
|
+
// VALUE LibevAgent_connect(VALUE self, VALUE sock, VALUE host, VALUE port);
|
12
|
+
// VALUE LibevAgent_finalize(VALUE self);
|
13
|
+
// VALUE LibevAgent_post_fork(VALUE self);
|
14
|
+
// VALUE LibevAgent_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof);
|
15
|
+
// VALUE LibevAgent_read_loop(VALUE self, VALUE io);
|
16
|
+
// VALUE LibevAgent_ref(VALUE self);
|
17
|
+
// VALUE LibevAgent_sleep(VALUE self, VALUE duration);
|
18
|
+
// VALUE LibevAgent_unref(VALUE self);
|
19
|
+
// VALUE LibevAgent_wait_io(VALUE self, VALUE io, VALUE write);
|
20
|
+
// VALUE LibevAgent_wait_pid(VALUE self, VALUE pid);
|
21
|
+
// VALUE LibevAgent_write(int argc, VALUE *argv, VALUE self);
|
22
|
+
|
23
|
+
typedef VALUE (* agent_pending_count_t)(VALUE self);
|
24
|
+
typedef VALUE (*agent_poll_t)(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue);
|
25
|
+
typedef int (* agent_ref_count_t)(VALUE self);
|
26
|
+
typedef void (* agent_reset_ref_count_t)(VALUE self);
|
27
|
+
typedef VALUE (* agent_wait_event_t)(VALUE self, VALUE raise_on_exception);
|
28
|
+
typedef VALUE (* agent_wakeup_t)(VALUE self);
|
29
|
+
|
30
|
+
typedef struct agent_interface {
|
31
|
+
agent_pending_count_t pending_count;
|
32
|
+
agent_poll_t poll;
|
33
|
+
agent_ref_count_t ref_count;
|
34
|
+
agent_reset_ref_count_t reset_ref_count;
|
35
|
+
agent_wait_event_t wait_event;
|
36
|
+
agent_wakeup_t wakeup;
|
37
|
+
} agent_interface_t;
|
38
|
+
|
39
|
+
#endif /* AGENT_H */
|
data/ext/polyphony/event.c
CHANGED
@@ -66,7 +66,7 @@ VALUE Event_await(VALUE self) {
|
|
66
66
|
|
67
67
|
VALUE agent = rb_ivar_get(rb_thread_current(), ID_ivar_agent);
|
68
68
|
event->waiting_fiber = rb_fiber_current();
|
69
|
-
VALUE switchpoint_result =
|
69
|
+
VALUE switchpoint_result = __AGENT__.wait_event(agent, Qnil);
|
70
70
|
event->waiting_fiber = Qnil;
|
71
71
|
|
72
72
|
TEST_RESUME_EXCEPTION(switchpoint_result);
|
data/ext/polyphony/libev_agent.c
CHANGED
@@ -3,11 +3,12 @@
|
|
3
3
|
#include <sys/uio.h>
|
4
4
|
#include <unistd.h>
|
5
5
|
#include <fcntl.h>
|
6
|
+
#include <netinet/in.h>
|
7
|
+
#include <arpa/inet.h>
|
6
8
|
|
7
9
|
#include "polyphony.h"
|
8
10
|
#include "../libev/ev.h"
|
9
11
|
|
10
|
-
VALUE cLibevAgent = Qnil;
|
11
12
|
VALUE cTCPSocket;
|
12
13
|
|
13
14
|
struct LibevAgent_t {
|
@@ -150,7 +151,7 @@ VALUE LibevAgent_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue
|
|
150
151
|
return self;
|
151
152
|
}
|
152
153
|
|
153
|
-
VALUE
|
154
|
+
VALUE LibevAgent_wakeup(VALUE self) {
|
154
155
|
struct LibevAgent_t *agent;
|
155
156
|
GetLibevAgent(self, agent);
|
156
157
|
|
@@ -694,46 +695,41 @@ error:
|
|
694
695
|
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
695
696
|
}
|
696
697
|
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
// RB_GC_GUARD(switchpoint_result);
|
733
|
-
// return Qnil;
|
734
|
-
// error:
|
735
|
-
// return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
736
|
-
// }
|
698
|
+
VALUE LibevAgent_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
|
699
|
+
struct LibevAgent_t *agent;
|
700
|
+
struct libev_io watcher;
|
701
|
+
rb_io_t *fptr;
|
702
|
+
struct sockaddr_in addr;
|
703
|
+
char *host_buf = StringValueCStr(host);
|
704
|
+
VALUE switchpoint_result = Qnil;
|
705
|
+
VALUE underlying_sock = rb_iv_get(sock, "@io");
|
706
|
+
if (underlying_sock != Qnil) sock = underlying_sock;
|
707
|
+
|
708
|
+
GetLibevAgent(self, agent);
|
709
|
+
GetOpenFile(sock, fptr);
|
710
|
+
io_set_nonblock(fptr, sock);
|
711
|
+
watcher.fiber = Qnil;
|
712
|
+
|
713
|
+
addr.sin_family = AF_INET;
|
714
|
+
addr.sin_addr.s_addr = inet_addr(host_buf);
|
715
|
+
addr.sin_port = htons(NUM2INT(port));
|
716
|
+
|
717
|
+
int result = connect(fptr->fd, (struct sockaddr *)&addr, sizeof(addr));
|
718
|
+
if (result < 0) {
|
719
|
+
int e = errno;
|
720
|
+
if (e != EINPROGRESS) rb_syserr_fail(e, strerror(e));
|
721
|
+
switchpoint_result = libev_io_wait(agent, &watcher, fptr, EV_WRITE);
|
722
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
723
|
+
}
|
724
|
+
else {
|
725
|
+
switchpoint_result = libev_snooze();
|
726
|
+
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
727
|
+
}
|
728
|
+
RB_GC_GUARD(switchpoint_result);
|
729
|
+
return sock;
|
730
|
+
error:
|
731
|
+
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
732
|
+
}
|
737
733
|
|
738
734
|
VALUE LibevAgent_wait_io(VALUE self, VALUE io, VALUE write) {
|
739
735
|
struct LibevAgent_t *agent;
|
@@ -853,30 +849,37 @@ void Init_LibevAgent() {
|
|
853
849
|
rb_require("socket");
|
854
850
|
cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
|
855
851
|
|
856
|
-
|
857
|
-
rb_define_alloc_func(
|
852
|
+
VALUE cAgent = rb_define_class_under(mPolyphony, "Agent", rb_cData);
|
853
|
+
rb_define_alloc_func(cAgent, LibevAgent_allocate);
|
858
854
|
|
859
|
-
rb_define_method(
|
860
|
-
rb_define_method(
|
861
|
-
rb_define_method(
|
862
|
-
rb_define_method(
|
855
|
+
rb_define_method(cAgent, "initialize", LibevAgent_initialize, 0);
|
856
|
+
rb_define_method(cAgent, "finalize", LibevAgent_finalize, 0);
|
857
|
+
rb_define_method(cAgent, "post_fork", LibevAgent_post_fork, 0);
|
858
|
+
rb_define_method(cAgent, "pending_count", LibevAgent_pending_count, 0);
|
863
859
|
|
864
|
-
rb_define_method(
|
865
|
-
rb_define_method(
|
860
|
+
rb_define_method(cAgent, "ref", LibevAgent_ref, 0);
|
861
|
+
rb_define_method(cAgent, "unref", LibevAgent_unref, 0);
|
866
862
|
|
867
|
-
rb_define_method(
|
868
|
-
rb_define_method(
|
863
|
+
rb_define_method(cAgent, "poll", LibevAgent_poll, 3);
|
864
|
+
rb_define_method(cAgent, "break", LibevAgent_wakeup, 0);
|
869
865
|
|
870
|
-
rb_define_method(
|
871
|
-
rb_define_method(
|
872
|
-
rb_define_method(
|
873
|
-
rb_define_method(
|
874
|
-
rb_define_method(
|
875
|
-
|
876
|
-
rb_define_method(
|
877
|
-
rb_define_method(
|
878
|
-
rb_define_method(
|
879
|
-
rb_define_method(
|
866
|
+
rb_define_method(cAgent, "read", LibevAgent_read, 4);
|
867
|
+
rb_define_method(cAgent, "read_loop", LibevAgent_read_loop, 1);
|
868
|
+
rb_define_method(cAgent, "write", LibevAgent_write_m, -1);
|
869
|
+
rb_define_method(cAgent, "accept", LibevAgent_accept, 1);
|
870
|
+
rb_define_method(cAgent, "accept_loop", LibevAgent_accept_loop, 1);
|
871
|
+
rb_define_method(cAgent, "connect", LibevAgent_connect, 3);
|
872
|
+
rb_define_method(cAgent, "wait_io", LibevAgent_wait_io, 2);
|
873
|
+
rb_define_method(cAgent, "sleep", LibevAgent_sleep, 1);
|
874
|
+
rb_define_method(cAgent, "waitpid", LibevAgent_waitpid, 1);
|
875
|
+
rb_define_method(cAgent, "wait_event", LibevAgent_wait_event, 1);
|
880
876
|
|
881
877
|
ID_ivar_is_nonblocking = rb_intern("@is_nonblocking");
|
878
|
+
|
879
|
+
__AGENT__.wakeup = LibevAgent_wakeup;
|
880
|
+
__AGENT__.pending_count = LibevAgent_pending_count;
|
881
|
+
__AGENT__.poll = LibevAgent_poll;
|
882
|
+
__AGENT__.ref_count = LibevAgent_ref_count;
|
883
|
+
__AGENT__.reset_ref_count = LibevAgent_reset_ref_count;
|
884
|
+
__AGENT__.wait_event = LibevAgent_wait_event;
|
882
885
|
}
|
data/ext/polyphony/polyphony.c
CHANGED
data/ext/polyphony/polyphony.h
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include "ruby.h"
|
5
5
|
#include "ruby/io.h"
|
6
6
|
#include "libev.h"
|
7
|
+
#include "agent.h"
|
7
8
|
|
8
9
|
// debugging
|
9
10
|
#define OBJ_ID(obj) (NUM2LONG(rb_funcall(obj, rb_intern("object_id"), 0)))
|
@@ -18,6 +19,12 @@
|
|
18
19
|
return rb_funcall(rb_mKernel, ID_raise, 1, ret); \
|
19
20
|
}
|
20
21
|
|
22
|
+
extern agent_interface_t agent_interface;
|
23
|
+
// #define __AGENT_PASTER__(call) (agent_interface ## . ## call)
|
24
|
+
// #define __AGENT__(call) __AGENT_PASTER__(call)
|
25
|
+
#define __AGENT__ (agent_interface)
|
26
|
+
|
27
|
+
|
21
28
|
extern VALUE mPolyphony;
|
22
29
|
extern VALUE cQueue;
|
23
30
|
extern VALUE cEvent;
|
@@ -65,17 +72,6 @@ enum {
|
|
65
72
|
VALUE Fiber_auto_watcher(VALUE self);
|
66
73
|
void Fiber_make_runnable(VALUE fiber, VALUE value);
|
67
74
|
|
68
|
-
VALUE LibevAgent_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue);
|
69
|
-
VALUE LibevAgent_break(VALUE self);
|
70
|
-
VALUE LibevAgent_pending_count(VALUE self);
|
71
|
-
VALUE LibevAgent_wait_io(VALUE self, VALUE io, VALUE write);
|
72
|
-
|
73
|
-
VALUE LibevAgent_ref(VALUE self);
|
74
|
-
VALUE LibevAgent_unref(VALUE self);
|
75
|
-
int LibevAgent_ref_count(VALUE self);
|
76
|
-
void LibevAgent_reset_ref_count(VALUE self);
|
77
|
-
VALUE LibevAgent_wait_event(VALUE self, VALUE raise);
|
78
|
-
|
79
75
|
VALUE Queue_push(VALUE self, VALUE value);
|
80
76
|
VALUE Queue_unshift(VALUE self, VALUE value);
|
81
77
|
VALUE Queue_shift(VALUE self);
|
data/ext/polyphony/queue.c
CHANGED
@@ -82,7 +82,7 @@ VALUE Queue_shift(VALUE self) {
|
|
82
82
|
VALUE fiber = rb_fiber_current();
|
83
83
|
VALUE switchpoint_result = Qnil;
|
84
84
|
ring_buffer_push(&queue->shift_queue, fiber);
|
85
|
-
switchpoint_result =
|
85
|
+
switchpoint_result = __AGENT__.wait_event(agent, Qnil);
|
86
86
|
if (RTEST(rb_obj_is_kind_of(switchpoint_result, rb_eException))) {
|
87
87
|
ring_buffer_delete(&queue->shift_queue, fiber);
|
88
88
|
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
@@ -165,6 +165,13 @@ VALUE Queue_size_m(VALUE self) {
|
|
165
165
|
return INT2NUM(queue->values.count);
|
166
166
|
}
|
167
167
|
|
168
|
+
void Queue_trace(VALUE self) {
|
169
|
+
Queue_t *queue;
|
170
|
+
GetQueue(self, queue);
|
171
|
+
|
172
|
+
printf("run queue size: %d count: %d\n", queue->values.size, queue->values.count);
|
173
|
+
}
|
174
|
+
|
168
175
|
void Init_Queue() {
|
169
176
|
cQueue = rb_define_class_under(mPolyphony, "Queue", rb_cData);
|
170
177
|
rb_define_alloc_func(cQueue, Queue_allocate);
|
data/ext/polyphony/thread.c
CHANGED
@@ -21,12 +21,12 @@ static VALUE Thread_setup_fiber_scheduling(VALUE self) {
|
|
21
21
|
|
22
22
|
int Thread_fiber_ref_count(VALUE self) {
|
23
23
|
VALUE agent = rb_ivar_get(self, ID_ivar_agent);
|
24
|
-
return NUM2INT(
|
24
|
+
return NUM2INT(__AGENT__.ref_count(agent));
|
25
25
|
}
|
26
26
|
|
27
27
|
inline void Thread_fiber_reset_ref_count(VALUE self) {
|
28
28
|
VALUE agent = rb_ivar_get(self, ID_ivar_agent);
|
29
|
-
|
29
|
+
__AGENT__.reset_ref_count(agent);
|
30
30
|
}
|
31
31
|
|
32
32
|
static VALUE SYM_scheduled_fibers;
|
@@ -41,7 +41,7 @@ static VALUE Thread_fiber_scheduling_stats(VALUE self) {
|
|
41
41
|
long scheduled_count = RARRAY_LEN(queue);
|
42
42
|
rb_hash_aset(stats, SYM_scheduled_fibers, INT2NUM(scheduled_count));
|
43
43
|
|
44
|
-
pending_count =
|
44
|
+
pending_count = __AGENT__.pending_count(agent);
|
45
45
|
rb_hash_aset(stats, SYM_pending_watchers, INT2NUM(pending_count));
|
46
46
|
|
47
47
|
return stats;
|
@@ -52,23 +52,34 @@ VALUE Thread_schedule_fiber(VALUE self, VALUE fiber, VALUE value) {
|
|
52
52
|
|
53
53
|
if (rb_fiber_alive_p(fiber) != Qtrue) return self;
|
54
54
|
|
55
|
-
|
55
|
+
int already_runnable = rb_ivar_get(fiber, ID_runnable) != Qnil;
|
56
|
+
|
57
|
+
if (already_runnable) {
|
58
|
+
VALUE current_runnable_value = rb_ivar_get(fiber, ID_runnable_value);
|
59
|
+
|
60
|
+
// If the fiber is already runnable and the runnable value is an exception,
|
61
|
+
// we don't update the value, in order to prevent a race condition where
|
62
|
+
// exceptions will be lost (see issue #33)
|
63
|
+
if (TEST_EXCEPTION(current_runnable_value)) return self;
|
64
|
+
}
|
65
|
+
|
56
66
|
rb_ivar_set(fiber, ID_runnable_value, value);
|
57
|
-
|
58
|
-
if (rb_ivar_get(fiber, ID_runnable) != Qnil) return self;
|
67
|
+
FIBER_TRACE(3, SYM_fiber_schedule, fiber, value);
|
59
68
|
|
60
|
-
|
61
|
-
|
62
|
-
|
69
|
+
if (!already_runnable) {
|
70
|
+
queue = rb_ivar_get(self, ID_run_queue);
|
71
|
+
Queue_push(queue, fiber);
|
72
|
+
rb_ivar_set(fiber, ID_runnable, Qtrue);
|
63
73
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
74
|
+
if (rb_thread_current() != self) {
|
75
|
+
// If the fiber scheduling is done across threads, we need to make sure the
|
76
|
+
// target thread is woken up in case it is in the middle of running its
|
77
|
+
// event selector. Otherwise it's gonna be stuck waiting for an event to
|
78
|
+
// happen, not knowing that it there's already a fiber ready to run in its
|
79
|
+
// run queue.
|
80
|
+
VALUE agent = rb_ivar_get(self,ID_ivar_agent);
|
81
|
+
__AGENT__.wakeup(agent);
|
82
|
+
}
|
72
83
|
}
|
73
84
|
return self;
|
74
85
|
}
|
@@ -100,7 +111,7 @@ VALUE Thread_schedule_fiber_with_priority(VALUE self, VALUE fiber, VALUE value)
|
|
100
111
|
// happen, not knowing that it there's already a fiber ready to run in its
|
101
112
|
// run queue.
|
102
113
|
VALUE agent = rb_ivar_get(self, ID_ivar_agent);
|
103
|
-
|
114
|
+
__AGENT__.wakeup(agent);
|
104
115
|
}
|
105
116
|
return self;
|
106
117
|
}
|
@@ -120,20 +131,20 @@ VALUE Thread_switch_fiber(VALUE self) {
|
|
120
131
|
}
|
121
132
|
}
|
122
133
|
|
123
|
-
ref_count =
|
134
|
+
ref_count = __AGENT__.ref_count(agent);
|
124
135
|
while (1) {
|
125
136
|
next_fiber = Queue_shift_no_wait(queue);
|
126
137
|
if (next_fiber != Qnil) {
|
127
138
|
if (agent_was_polled == 0 && ref_count > 0) {
|
128
139
|
// this mechanism prevents event starvation in case the run queue never
|
129
140
|
// empties
|
130
|
-
|
141
|
+
__AGENT__.poll(agent, Qtrue, current_fiber, queue);
|
131
142
|
}
|
132
143
|
break;
|
133
144
|
}
|
134
145
|
if (ref_count == 0) break;
|
135
146
|
|
136
|
-
|
147
|
+
__AGENT__.poll(agent, Qnil, current_fiber, queue);
|
137
148
|
agent_was_polled = 1;
|
138
149
|
}
|
139
150
|
|
@@ -169,7 +180,7 @@ VALUE Thread_fiber_break_out_of_ev_loop(VALUE self, VALUE fiber, VALUE resume_ob
|
|
169
180
|
Thread_schedule_fiber_with_priority(self, fiber, resume_obj);
|
170
181
|
}
|
171
182
|
|
172
|
-
if (
|
183
|
+
if (__AGENT__.wakeup(agent) == Qnil) {
|
173
184
|
// we're not inside the ev_loop, so we just do a switchpoint
|
174
185
|
Thread_switch_fiber(self);
|
175
186
|
}
|
data/lib/polyphony.rb
CHANGED
@@ -17,7 +17,7 @@ require_relative './polyphony/extensions/fiber'
|
|
17
17
|
require_relative './polyphony/extensions/io'
|
18
18
|
|
19
19
|
Thread.current.setup_fiber_scheduling
|
20
|
-
Thread.current.agent = Polyphony::
|
20
|
+
Thread.current.agent = Polyphony::Agent.new
|
21
21
|
|
22
22
|
require_relative './polyphony/core/global_api'
|
23
23
|
require_relative './polyphony/core/resource_pool'
|
data/lib/polyphony/core/sync.rb
CHANGED
@@ -24,15 +24,7 @@ class ::Socket
|
|
24
24
|
NO_EXCEPTION = { exception: false }.freeze
|
25
25
|
|
26
26
|
def connect(remotesockaddr)
|
27
|
-
|
28
|
-
result = connect_nonblock(remotesockaddr, **NO_EXCEPTION)
|
29
|
-
case result
|
30
|
-
when 0 then return
|
31
|
-
when :wait_writable then Thread.current.agent.wait_io(self, true)
|
32
|
-
else
|
33
|
-
raise IOError
|
34
|
-
end
|
35
|
-
end
|
27
|
+
Thread.current.agent.connect(self, remotesockaddr.ip_address, remotesockaddr.ip_port)
|
36
28
|
end
|
37
29
|
|
38
30
|
def recv(maxlen, flags = 0, outbuf = nil)
|
@@ -18,7 +18,7 @@ class ::Thread
|
|
18
18
|
def execute
|
19
19
|
# agent must be created in the context of the new thread, therefore it
|
20
20
|
# cannot be created in Thread#initialize
|
21
|
-
@agent = Polyphony::
|
21
|
+
@agent = Polyphony::Agent.new
|
22
22
|
setup
|
23
23
|
@ready = true
|
24
24
|
result = @block.(*@args)
|
data/lib/polyphony/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -31,7 +31,7 @@ class MiniTest::Test
|
|
31
31
|
end
|
32
32
|
Fiber.current.setup_main_fiber
|
33
33
|
Fiber.current.instance_variable_set(:@auto_watcher, nil)
|
34
|
-
Thread.current.agent = Polyphony::
|
34
|
+
Thread.current.agent = Polyphony::Agent.new
|
35
35
|
sleep 0 # apparently this helps with timer accuracy
|
36
36
|
end
|
37
37
|
|
data/test/test_agent.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.43.
|
4
|
+
version: 0.43.10
|
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-07-
|
11
|
+
date: 2020-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -389,6 +389,7 @@ files:
|
|
389
389
|
- ext/libev/ev_win32.c
|
390
390
|
- ext/libev/ev_wrap.h
|
391
391
|
- ext/libev/test_libev_win32.c
|
392
|
+
- ext/polyphony/agent.h
|
392
393
|
- ext/polyphony/event.c
|
393
394
|
- ext/polyphony/extconf.rb
|
394
395
|
- ext/polyphony/fiber.c
|
@@ -476,7 +477,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
476
477
|
- !ruby/object:Gem::Version
|
477
478
|
version: '0'
|
478
479
|
requirements: []
|
479
|
-
rubygems_version: 3.
|
480
|
+
rubygems_version: 3.0.8
|
480
481
|
signing_key:
|
481
482
|
specification_version: 4
|
482
483
|
summary: Fine grained concurrency for Ruby
|