polyphony 0.99.4 → 0.99.6
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/.rubocop.yml +11 -0
- data/.yardopts +0 -2
- data/README.md +1 -1
- data/docs/readme.md +1 -1
- data/docs/tutorial.md +2 -2
- data/examples/pipes/gzip_http_server.rb +2 -2
- data/examples/pipes/http_server.rb +1 -1
- data/examples/pipes/tcp_proxy.rb +1 -1
- data/ext/polyphony/backend_common.c +4 -4
- data/ext/polyphony/backend_io_uring.c +8 -8
- data/ext/polyphony/backend_libev.c +5 -5
- data/ext/polyphony/fiber.c +33 -42
- data/ext/polyphony/io_extensions.c +50 -37
- data/ext/polyphony/pipe.c +6 -20
- data/ext/polyphony/polyphony.c +72 -144
- data/ext/polyphony/queue.c +23 -63
- data/ext/polyphony/thread.c +4 -13
- data/lib/polyphony/adapters/process.rb +2 -5
- data/lib/polyphony/adapters/sequel.rb +2 -2
- data/lib/polyphony/core/debug.rb +1 -4
- data/lib/polyphony/core/exceptions.rb +1 -5
- data/lib/polyphony/core/resource_pool.rb +7 -8
- data/lib/polyphony/core/sync.rb +5 -8
- data/lib/polyphony/core/thread_pool.rb +3 -10
- data/lib/polyphony/core/throttler.rb +1 -5
- data/lib/polyphony/core/timer.rb +23 -30
- data/lib/polyphony/extensions/fiber.rb +513 -543
- data/lib/polyphony/extensions/io.rb +5 -14
- data/lib/polyphony/extensions/object.rb +283 -2
- data/lib/polyphony/extensions/openssl.rb +5 -26
- data/lib/polyphony/extensions/pipe.rb +6 -17
- data/lib/polyphony/extensions/socket.rb +24 -118
- data/lib/polyphony/extensions/thread.rb +3 -18
- data/lib/polyphony/extensions/timeout.rb +0 -1
- data/lib/polyphony/net.rb +5 -9
- data/lib/polyphony/version.rb +1 -1
- data/lib/polyphony.rb +2 -6
- data/test/test_io.rb +221 -221
- data/test/test_socket.rb +3 -3
- data/test/test_trace.rb +2 -2
- metadata +5 -9
- data/docs/index.md +0 -94
- data/docs/link_rewriter.rb +0 -17
- data/docs/main-concepts/index.md +0 -9
- data/lib/polyphony/core/global_api.rb +0 -309
- /data/{assets → docs/assets}/echo-fibers.svg +0 -0
- /data/{assets → docs/assets}/polyphony-logo.png +0 -0
- /data/{assets → docs/assets}/sleeping-fiber.svg +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a2733c956cab37dac192c107c4c2def808595601cca177dfbfcbd23b3b291e7
|
4
|
+
data.tar.gz: 417aacff2dac6ec2f4cfe85c8afc0bab21a5d20ac8748a3a5ceca42ec7950b8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c5d41ad9927a1b3770b76b702bc3f7695d4fb0c87601df3a5fd9d25cdc3e121881ec4e9dbbe618234864c73b8ac67cf1f9156a5bc031a7186d9633a03d70e00
|
7
|
+
data.tar.gz: ad66aab4d2fb6b60f702791036fa8883b6e262eadee7170dc285d68903b2447d17160aec9e382c336ace24e3e0379d25683ba736084df6c61c36858b465513e4
|
data/.rubocop.yml
CHANGED
@@ -85,6 +85,7 @@ Metrics/MethodLength:
|
|
85
85
|
Exclude:
|
86
86
|
- lib/polyphony/http/server/rack.rb
|
87
87
|
- lib/polyphony/extensions/io.rb
|
88
|
+
- lib/polyphony/extensions/fiber.rb
|
88
89
|
- test/**/*.rb
|
89
90
|
- examples/**/*.rb
|
90
91
|
|
@@ -97,9 +98,19 @@ Metrics/ClassLength:
|
|
97
98
|
Exclude:
|
98
99
|
- lib/polyphony/http/server/http1.rb
|
99
100
|
- lib/polyphony/extensions/io.rb
|
101
|
+
- lib/polyphony/extensions/fiber.rb
|
102
|
+
- lib/polyphony/extensions/object.rb
|
100
103
|
- test/**/*.rb
|
101
104
|
- examples/**/*.rb
|
102
105
|
|
106
|
+
Metrics/CyclomaticComplexity:
|
107
|
+
Exclude:
|
108
|
+
- lib/polyphony/extensions/fiber.rb
|
109
|
+
|
110
|
+
Metrics/PerceivedComplexity:
|
111
|
+
Exclude:
|
112
|
+
- lib/polyphony/extensions/fiber.rb
|
113
|
+
|
103
114
|
Style/RegexpLiteral:
|
104
115
|
Enabled: false
|
105
116
|
|
data/.yardopts
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
--verbose
|
4
4
|
--protected
|
5
5
|
--no-private
|
6
|
-
--asset assets/:assets
|
7
6
|
--exclude debugger.rb
|
8
7
|
--exclude redis.rb
|
9
8
|
--exclude readline.rb
|
@@ -14,7 +13,6 @@
|
|
14
13
|
--exclude sequel.rb
|
15
14
|
--exclude event.c
|
16
15
|
--exclude backend.+\.c
|
17
|
-
# --load ./docs/link_rewriter.rb
|
18
16
|
-r docs/readme.md
|
19
17
|
./lib
|
20
18
|
./ext/polyphony
|
data/README.md
CHANGED
data/docs/readme.md
CHANGED
data/docs/tutorial.md
CHANGED
@@ -94,7 +94,7 @@ The above program does nothing exceptional, it just sleeps for 1 second and
|
|
94
94
|
prints a bunch of messages. But it is enough to demonstrate how concurrency
|
95
95
|
works in Polyphony. Here's a flow chart of the transfer of control:
|
96
96
|
|
97
|
-
<img src="
|
97
|
+
<img src="https://github.com/digital-fabric/polyphony/raw/master/docs/assets/sleeping-fiber.png">
|
98
98
|
|
99
99
|
Here's the actual sequence of execution (in pseudo-code)
|
100
100
|
|
@@ -189,7 +189,7 @@ innocent call to `#spin`.
|
|
189
189
|
|
190
190
|
Here's a flow chart showing the transfer of control between the different fibers:
|
191
191
|
|
192
|
-
<img src="
|
192
|
+
<img src="https://github.com/digital-fabric/polyphony/raw/master/docs/assets/echo-fibers.png">
|
193
193
|
|
194
194
|
Let's consider the advantage of the Polyphony concurrency model:
|
195
195
|
|
@@ -13,14 +13,14 @@ require 'h1p'
|
|
13
13
|
def handle_client(conn)
|
14
14
|
spin do
|
15
15
|
parser = H1P::Parser.new(conn, :server)
|
16
|
-
|
16
|
+
|
17
17
|
while true # assuming persistent connection
|
18
18
|
headers = parser.parse_headers
|
19
19
|
break unless headers
|
20
20
|
|
21
21
|
raw_buffer = Polyphony.pipe
|
22
22
|
gzip_buffer = Polyphony.pipe
|
23
|
-
|
23
|
+
|
24
24
|
# splice request body to buffer
|
25
25
|
spin do
|
26
26
|
parser.splice_body_to(raw_buffer)
|
data/examples/pipes/tcp_proxy.rb
CHANGED
@@ -280,14 +280,14 @@ inline VALUE backend_snooze(struct Backend_base *backend) {
|
|
280
280
|
VALUE ret;
|
281
281
|
VALUE fiber = rb_fiber_current();
|
282
282
|
VALUE thread = rb_thread_current();
|
283
|
-
|
283
|
+
|
284
284
|
CHECK_FIBER_THREAD_REF(fiber, thread);
|
285
|
-
|
285
|
+
|
286
286
|
Fiber_make_runnable(fiber, Qnil);
|
287
287
|
ret = Thread_switch_fiber(thread);
|
288
288
|
|
289
289
|
COND_TRACE(backend, 4, SYM_unblock, fiber, ret, CALLER());
|
290
|
-
|
290
|
+
|
291
291
|
return ret;
|
292
292
|
}
|
293
293
|
|
@@ -306,7 +306,7 @@ inline double current_time(void) {
|
|
306
306
|
struct timespec ts;
|
307
307
|
double t;
|
308
308
|
uint64_t ns;
|
309
|
-
|
309
|
+
|
310
310
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
311
311
|
ns = ts.tv_sec;
|
312
312
|
ns = ns * 1e9 + ts.tv_nsec;
|
@@ -101,7 +101,7 @@ static VALUE Backend_initialize(VALUE self) {
|
|
101
101
|
while (1) {
|
102
102
|
int ret = io_uring_queue_init(backend->prepared_limit, &backend->ring, flags);
|
103
103
|
if (!ret) break;
|
104
|
-
|
104
|
+
|
105
105
|
// if ENOMEM is returned, use a smaller limit
|
106
106
|
if (ret == -ENOMEM && backend->prepared_limit > 64)
|
107
107
|
backend->prepared_limit = backend->prepared_limit / 2;
|
@@ -263,10 +263,10 @@ inline VALUE Backend_poll(VALUE self, VALUE blocking) {
|
|
263
263
|
if (!is_blocking && backend->pending_sqes) io_uring_backend_immediate_submit(backend);
|
264
264
|
|
265
265
|
COND_TRACE(&backend->base, 2, SYM_enter_poll, rb_fiber_current());
|
266
|
-
|
266
|
+
|
267
267
|
if (is_blocking) io_uring_backend_poll(backend);
|
268
268
|
io_uring_backend_handle_ready_cqes(backend);
|
269
|
-
|
269
|
+
|
270
270
|
COND_TRACE(&backend->base, 2, SYM_leave_poll, rb_fiber_current());
|
271
271
|
|
272
272
|
return self;
|
@@ -414,7 +414,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE buffer, VALUE length, VALUE to_eo
|
|
414
414
|
struct io_uring_sqe *sqe = io_uring_backend_get_sqe(backend);
|
415
415
|
int result;
|
416
416
|
int completed;
|
417
|
-
|
417
|
+
|
418
418
|
io_uring_prep_read(sqe, fd, buffer_spec.ptr, buffer_spec.len, -1);
|
419
419
|
|
420
420
|
result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
|
@@ -449,7 +449,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE buffer, VALUE length, VALUE to_eo
|
|
449
449
|
}
|
450
450
|
|
451
451
|
if (!total) return Qnil;
|
452
|
-
|
452
|
+
|
453
453
|
if (!buffer_spec.raw) backend_finalize_string_buffer(buffer, &buffer_spec, total, fptr);
|
454
454
|
return buffer_spec.raw ? INT2FIX(total) : buffer;
|
455
455
|
}
|
@@ -1412,7 +1412,7 @@ int io_uring_backend_submit_timeout_and_await(Backend_t *backend, double duratio
|
|
1412
1412
|
struct __kernel_timespec ts = double_to_timespec(duration);
|
1413
1413
|
struct io_uring_sqe *sqe = io_uring_backend_get_sqe(backend);
|
1414
1414
|
op_context_t *ctx = context_store_acquire(&backend->store, OP_TIMEOUT);
|
1415
|
-
|
1415
|
+
|
1416
1416
|
io_uring_prep_timeout(sqe, &ts, 0, 0);
|
1417
1417
|
io_uring_backend_defer_submit_and_await(backend, sqe, ctx, resume_value);
|
1418
1418
|
return context_store_release(&backend->store, ctx);
|
@@ -1723,7 +1723,7 @@ VALUE Backend_chain(int argc,VALUE *argv, VALUE self) {
|
|
1723
1723
|
completed = context_store_release(&backend->store, ctx);
|
1724
1724
|
if (!completed) {
|
1725
1725
|
struct io_uring_sqe *sqe;
|
1726
|
-
|
1726
|
+
|
1727
1727
|
Backend_chain_ctx_attach_buffers(ctx, argc, argv);
|
1728
1728
|
|
1729
1729
|
// op was not completed (an exception was raised), so we need to cancel it
|
@@ -1793,7 +1793,7 @@ static inline void splice_chunks_get_sqe(
|
|
1793
1793
|
|
1794
1794
|
static inline void splice_chunks_cancel(Backend_t *backend, op_context_t *ctx) {
|
1795
1795
|
struct io_uring_sqe *sqe;
|
1796
|
-
|
1796
|
+
|
1797
1797
|
ctx->result = -ECANCELED;
|
1798
1798
|
sqe = io_uring_backend_get_sqe(backend);
|
1799
1799
|
io_uring_prep_cancel(sqe, ctx, 0);
|
@@ -169,14 +169,14 @@ inline VALUE Backend_poll(VALUE self, VALUE blocking) {
|
|
169
169
|
backend->base.poll_count++;
|
170
170
|
|
171
171
|
COND_TRACE(&backend->base, 2, SYM_enter_poll, rb_fiber_current());
|
172
|
-
|
172
|
+
|
173
173
|
ev_run:
|
174
174
|
backend->base.currently_polling = 1;
|
175
175
|
errno = 0;
|
176
176
|
ev_run(backend->ev_loop, blocking == Qtrue ? EVRUN_ONCE : EVRUN_NOWAIT);
|
177
177
|
backend->base.currently_polling = 0;
|
178
178
|
if (errno == EINTR && runqueue_empty_p(&backend->base.runqueue)) goto ev_run;
|
179
|
-
|
179
|
+
|
180
180
|
COND_TRACE(&backend->base, 2, SYM_leave_poll, rb_fiber_current());
|
181
181
|
|
182
182
|
return self;
|
@@ -335,7 +335,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE buffer, VALUE length, VALUE to_eo
|
|
335
335
|
}
|
336
336
|
|
337
337
|
if (!total) return Qnil;
|
338
|
-
|
338
|
+
|
339
339
|
if (!buffer_spec.raw) backend_finalize_string_buffer(buffer, &buffer_spec, total, fptr);
|
340
340
|
|
341
341
|
RB_GC_GUARD(watcher.fiber);
|
@@ -359,7 +359,7 @@ VALUE Backend_recvmsg(VALUE self, VALUE io, VALUE buffer, VALUE maxlen, VALUE po
|
|
359
359
|
struct backend_buffer_spec buffer_spec = backend_get_buffer_spec(buffer, 0);
|
360
360
|
long total = 0;
|
361
361
|
VALUE switchpoint_result = Qnil;
|
362
|
-
|
362
|
+
|
363
363
|
GetBackend(self, backend);
|
364
364
|
backend_prepare_read_buffer(buffer, maxlen, &buffer_spec, FIX2INT(pos));
|
365
365
|
fd = fd_from_io(io, &fptr, 0, 1);
|
@@ -403,7 +403,7 @@ VALUE Backend_recvmsg(VALUE self, VALUE io, VALUE buffer, VALUE maxlen, VALUE po
|
|
403
403
|
}
|
404
404
|
|
405
405
|
if (!total) return Qnil;
|
406
|
-
|
406
|
+
|
407
407
|
if (!buffer_spec.raw) backend_finalize_string_buffer(buffer, &buffer_spec, total, fptr);
|
408
408
|
VALUE addr = name_to_addrinfo(msg.msg_name, msg.msg_namelen);
|
409
409
|
VALUE rflags = INT2NUM(msg.msg_flags);
|
data/ext/polyphony/fiber.c
CHANGED
@@ -60,13 +60,14 @@ inline void Fiber_make_runnable_with_priority(VALUE fiber, VALUE value) {
|
|
60
60
|
Thread_schedule_fiber_with_priority(thread, fiber, value);
|
61
61
|
}
|
62
62
|
|
63
|
-
/*
|
64
|
-
*
|
65
|
-
*
|
66
|
-
*
|
67
|
-
*
|
68
|
-
*
|
69
|
-
* @
|
63
|
+
/* Adds the fiber to the runqueue with the given resume value. If no resume
|
64
|
+
* value is given, the fiber will be resumed with `nil`.
|
65
|
+
*
|
66
|
+
* @overload schedule(value)
|
67
|
+
* @param value [any] resume value
|
68
|
+
* @return [Fiber] scheduled fiber
|
69
|
+
* @overload schedule
|
70
|
+
* @return [Fiber] scheduled fiber
|
70
71
|
*/
|
71
72
|
|
72
73
|
static VALUE Fiber_schedule(int argc, VALUE *argv, VALUE self) {
|
@@ -75,14 +76,14 @@ static VALUE Fiber_schedule(int argc, VALUE *argv, VALUE self) {
|
|
75
76
|
return self;
|
76
77
|
}
|
77
78
|
|
78
|
-
/*
|
79
|
-
*
|
80
|
-
*
|
81
|
-
*
|
82
|
-
*
|
83
|
-
*
|
84
|
-
*
|
85
|
-
*
|
79
|
+
/* Adds the fiber to the head of the runqueue with the given resume value. If no
|
80
|
+
* resume value is given, the fiber will be resumed with `nil`.
|
81
|
+
*
|
82
|
+
* @overload schedule_with_priority(value)
|
83
|
+
* @param value [any] resume value
|
84
|
+
* @return [Fiber] scheduled fiber
|
85
|
+
* @overload schedule_with_priority
|
86
|
+
* @return [Fiber] scheduled fiber
|
86
87
|
*/
|
87
88
|
|
88
89
|
static VALUE Fiber_schedule_with_priority(int argc, VALUE *argv, VALUE self) {
|
@@ -91,12 +92,14 @@ static VALUE Fiber_schedule_with_priority(int argc, VALUE *argv, VALUE self) {
|
|
91
92
|
return self;
|
92
93
|
}
|
93
94
|
|
94
|
-
/*
|
95
|
-
*
|
96
|
-
*
|
97
|
-
*
|
98
|
-
* `:waiting
|
99
|
-
*
|
95
|
+
/* Returns the current state for the fiber, one of the following:
|
96
|
+
*
|
97
|
+
* - `:running` - the fiber is currently running.
|
98
|
+
* - `:runnable` - the fiber is on the runqueue, scheduled to be resumed ("ran").
|
99
|
+
* - `:waiting` - the fiber is waiting on some blocking operation to complete,
|
100
|
+
* allowing other fibers to run.
|
101
|
+
* - `:dead` - the fiber has finished running.
|
102
|
+
*
|
100
103
|
* @return [Symbol]
|
101
104
|
*/
|
102
105
|
|
@@ -109,14 +112,11 @@ static VALUE Fiber_state(VALUE self) {
|
|
109
112
|
return SYM_waiting;
|
110
113
|
}
|
111
114
|
|
112
|
-
/*
|
113
|
-
* fiber.send(msg)
|
114
|
-
*
|
115
|
-
* Sends a message to the given fiber. The message will be added to the fiber's
|
115
|
+
/* Sends a message to the given fiber. The message will be added to the fiber's
|
116
116
|
* mailbox.
|
117
|
-
*
|
117
|
+
*
|
118
118
|
* @param msg [any]
|
119
|
-
* @return [
|
119
|
+
* @return [Fiber] self
|
120
120
|
*/
|
121
121
|
|
122
122
|
VALUE Fiber_send(VALUE self, VALUE msg) {
|
@@ -129,12 +129,9 @@ VALUE Fiber_send(VALUE self, VALUE msg) {
|
|
129
129
|
return self;
|
130
130
|
}
|
131
131
|
|
132
|
-
/*
|
133
|
-
* fiber.receive -> msg
|
134
|
-
*
|
135
|
-
* Receive's a message from the fiber's mailbox. If no message is available,
|
132
|
+
/* Receive's a message from the fiber's mailbox. If no message is available,
|
136
133
|
* waits for a message to be sent to it.
|
137
|
-
*
|
134
|
+
*
|
138
135
|
* @return [any] received message
|
139
136
|
*/
|
140
137
|
|
@@ -147,11 +144,8 @@ VALUE Fiber_receive(VALUE self) {
|
|
147
144
|
return Queue_shift(0, 0, mailbox);
|
148
145
|
}
|
149
146
|
|
150
|
-
/*
|
151
|
-
*
|
152
|
-
*
|
153
|
-
* Returns the fiber's mailbox.
|
154
|
-
*
|
147
|
+
/* Returns the fiber's mailbox.
|
148
|
+
*
|
155
149
|
* @return [Queue]
|
156
150
|
*/
|
157
151
|
|
@@ -164,11 +158,8 @@ VALUE Fiber_mailbox(VALUE self) {
|
|
164
158
|
return mailbox;
|
165
159
|
}
|
166
160
|
|
167
|
-
/*
|
168
|
-
*
|
169
|
-
*
|
170
|
-
* Receives all messages currently in the fiber's mailbox.
|
171
|
-
*
|
161
|
+
/* Receives all messages currently in the fiber's mailbox.
|
162
|
+
*
|
172
163
|
* @return [Array]
|
173
164
|
*/
|
174
165
|
|
@@ -322,7 +322,7 @@ void read_gzip_header_str(struct buffer_spec *buffer_spec, VALUE *str, unsigned
|
|
322
322
|
}
|
323
323
|
if (null_pos == *total_read)
|
324
324
|
rb_raise(rb_eRuntimeError, "Invalid gzip header");
|
325
|
-
|
325
|
+
|
326
326
|
*str = rb_str_new_cstr((char *)buffer_spec->ptr + *in_pos);
|
327
327
|
*in_pos = null_pos + 1;
|
328
328
|
}
|
@@ -507,14 +507,18 @@ static inline VALUE z_stream_cleanup(struct z_stream_ctx *ctx) {
|
|
507
507
|
#define Z_STREAM_SAFE_IO_LOOP_WITH_CLEANUP(ctx) \
|
508
508
|
rb_ensure(SAFE(z_stream_io_loop), (VALUE)&ctx, SAFE(z_stream_cleanup), (VALUE)&ctx)
|
509
509
|
|
510
|
-
/*
|
511
|
-
* IO.gzip(src, dest) -> bytes_written
|
512
|
-
* IO.gzip(src, dest, opt) -> bytes_written
|
513
|
-
*
|
514
|
-
* Gzips data from the source IO to the destination IO, returning the number
|
510
|
+
/* Gzips data from the source IO to the destination IO, returning the number
|
515
511
|
* bytes written to the destination IO.
|
516
|
-
*
|
517
|
-
* @
|
512
|
+
*
|
513
|
+
* @overload gzip(src, dest)
|
514
|
+
* @param src [IO, Polyphony::Pipe] source IO
|
515
|
+
* @param dest [IO, Polyphony::Pipe] destination IO
|
516
|
+
* @return [Integer]
|
517
|
+
* @overload gzip(src, dest, opt)
|
518
|
+
* @param src [IO, Polyphony::Pipe] source IO
|
519
|
+
* @param dest [IO, Polyphony::Pipe] destination IO
|
520
|
+
* @param opt [Hash] gzip options
|
521
|
+
* @return [Integer]
|
518
522
|
*/
|
519
523
|
|
520
524
|
VALUE IO_gzip(int argc, VALUE *argv, VALUE self) {
|
@@ -542,20 +546,24 @@ VALUE IO_gzip(int argc, VALUE *argv, VALUE self) {
|
|
542
546
|
ret = deflateInit2(&ctx.strm, DEFAULT_LEVEL, Z_DEFLATED, -MAX_WBITS, DEFAULT_MEM_LEVEL, Z_DEFAULT_STRATEGY);
|
543
547
|
if (ret != Z_OK)
|
544
548
|
rb_raise(rb_eRuntimeError, "zlib error: %s\n", ctx.strm.msg);
|
545
|
-
Z_STREAM_SAFE_IO_LOOP_WITH_CLEANUP(ctx);
|
549
|
+
Z_STREAM_SAFE_IO_LOOP_WITH_CLEANUP(ctx);
|
546
550
|
return INT2FIX(ctx.out_total);
|
547
551
|
}
|
548
552
|
|
549
553
|
# define FIX2TIME(v) (rb_funcall(rb_cTime, ID_at, 1, v))
|
550
554
|
|
551
|
-
/*
|
552
|
-
* IO.gunzip(src, dest) -> bytes_written
|
553
|
-
* IO.gunzip(src, dest, opt) -> bytes_written
|
554
|
-
*
|
555
|
-
* Gunzips data from the source IO to the destination IO, returning the number
|
555
|
+
/* Gunzips data from the source IO to the destination IO, returning the number
|
556
556
|
* bytes written to the destination IO.
|
557
|
-
*
|
558
|
-
* @
|
557
|
+
*
|
558
|
+
* @overload gunzip(src, dest)
|
559
|
+
* @param src [IO, Polyphony::Pipe] source IO
|
560
|
+
* @param dest [IO, Polyphony::Pipe] destination IO
|
561
|
+
* @return [Integer]
|
562
|
+
* @overload gunzip(src, dest, opt)
|
563
|
+
* @param src [IO, Polyphony::Pipe] source IO
|
564
|
+
* @param dest [IO, Polyphony::Pipe] destination IO
|
565
|
+
* @param opt [Hash] gzip options
|
566
|
+
* @return [Integer]
|
559
567
|
*/
|
560
568
|
|
561
569
|
VALUE IO_gunzip(int argc, VALUE *argv, VALUE self) {
|
@@ -594,14 +602,18 @@ VALUE IO_gunzip(int argc, VALUE *argv, VALUE self) {
|
|
594
602
|
return INT2FIX(ctx.out_total);
|
595
603
|
}
|
596
604
|
|
597
|
-
/*
|
598
|
-
* IO.deflate(src, dest) -> bytes_written
|
599
|
-
* IO.deflate(src, dest, opt) -> bytes_written
|
600
|
-
*
|
601
|
-
* Defaltes data from the source IO to the destination IO, returning the number
|
605
|
+
/* Deflates data from the source IO to the destination IO, returning the number
|
602
606
|
* bytes written to the destination IO.
|
603
|
-
*
|
604
|
-
* @
|
607
|
+
*
|
608
|
+
* @overload deflate(src, dest)
|
609
|
+
* @param src [IO, Polyphony::Pipe] source IO
|
610
|
+
* @param dest [IO, Polyphony::Pipe] destination IO
|
611
|
+
* @return [Integer]
|
612
|
+
* @overload deflate(src, dest, opt)
|
613
|
+
* @param src [IO, Polyphony::Pipe] source IO
|
614
|
+
* @param dest [IO, Polyphony::Pipe] destination IO
|
615
|
+
* @param opt [Hash] gzip options
|
616
|
+
* @return [Integer]
|
605
617
|
*/
|
606
618
|
|
607
619
|
VALUE IO_deflate(VALUE self, VALUE src, VALUE dest) {
|
@@ -615,18 +627,22 @@ VALUE IO_deflate(VALUE self, VALUE src, VALUE dest) {
|
|
615
627
|
rb_raise(rb_eRuntimeError, "zlib error: %s\n", ctx.strm.msg);
|
616
628
|
|
617
629
|
Z_STREAM_SAFE_IO_LOOP_WITH_CLEANUP(ctx);
|
618
|
-
|
630
|
+
|
619
631
|
return INT2FIX(ctx.out_total);
|
620
632
|
}
|
621
633
|
|
622
|
-
/*
|
623
|
-
* IO.inflate(src, dest) -> bytes_written
|
624
|
-
* IO.inflate(src, dest, opt) -> bytes_written
|
625
|
-
*
|
626
|
-
* Inflates data from the source IO to the destination IO, returning the number
|
634
|
+
/* Inflates data from the source IO to the destination IO, returning the number
|
627
635
|
* bytes written to the destination IO.
|
628
|
-
*
|
629
|
-
* @
|
636
|
+
*
|
637
|
+
* @overload inflate(src, dest)
|
638
|
+
* @param src [IO, Polyphony::Pipe] source IO
|
639
|
+
* @param dest [IO, Polyphony::Pipe] destination IO
|
640
|
+
* @return [Integer]
|
641
|
+
* @overload inflate(src, dest, opt)
|
642
|
+
* @param src [IO, Polyphony::Pipe] source IO
|
643
|
+
* @param dest [IO, Polyphony::Pipe] destination IO
|
644
|
+
* @param opt [Hash] gzip options
|
645
|
+
* @return [Integer]
|
630
646
|
*/
|
631
647
|
|
632
648
|
VALUE IO_inflate(VALUE self, VALUE src, VALUE dest) {
|
@@ -639,17 +655,14 @@ VALUE IO_inflate(VALUE self, VALUE src, VALUE dest) {
|
|
639
655
|
rb_raise(rb_eRuntimeError, "zlib error: %s\n", ctx.strm.msg);
|
640
656
|
|
641
657
|
Z_STREAM_SAFE_IO_LOOP_WITH_CLEANUP(ctx);
|
642
|
-
|
658
|
+
|
643
659
|
return INT2FIX(ctx.out_total);
|
644
660
|
}
|
645
661
|
|
646
|
-
/*
|
647
|
-
* IO.http1_splice_chunked(src, dest, maxlen)
|
648
|
-
*
|
649
|
-
* Splices data from the source IO to the destination IO, writing it in HTTP1
|
662
|
+
/* Splices data from the source IO to the destination IO, writing it in HTTP1
|
650
663
|
* chunked encoding. A pipe is automatically created to buffer data between
|
651
664
|
* source and destination.
|
652
|
-
*
|
665
|
+
*
|
653
666
|
* @param src [IO] source
|
654
667
|
* @param dest [IO] destination
|
655
668
|
* @param maxlen [Integer] maximum bytes to splice
|
data/ext/polyphony/pipe.c
CHANGED
@@ -36,12 +36,7 @@ static VALUE Pipe_allocate(VALUE klass) {
|
|
36
36
|
#define GetPipe(obj, pipe) \
|
37
37
|
TypedData_Get_Struct((obj), Pipe_t, &Pipe_type, (pipe))
|
38
38
|
|
39
|
-
/*
|
40
|
-
* Pipe.new -> pipe
|
41
|
-
*
|
42
|
-
* Creates a new pipe.
|
43
|
-
*
|
44
|
-
* @return [void]
|
39
|
+
/* Creates a new pipe.
|
45
40
|
*/
|
46
41
|
|
47
42
|
static VALUE Pipe_initialize(VALUE self) {
|
@@ -80,11 +75,8 @@ int Pipe_get_fd(VALUE self, int write_mode) {
|
|
80
75
|
return pipe->fds[write_mode ? 1 : 0];
|
81
76
|
}
|
82
77
|
|
83
|
-
/*
|
84
|
-
* pipe.closed? -> bool
|
78
|
+
/* Returns true if the pipe is closed.
|
85
79
|
*
|
86
|
-
* Returns true if the pipe is closed.
|
87
|
-
*
|
88
80
|
* @return [boolean]
|
89
81
|
*/
|
90
82
|
|
@@ -94,11 +86,8 @@ VALUE Pipe_closed_p(VALUE self) {
|
|
94
86
|
return pipe->w_closed ? Qtrue : Qfalse;
|
95
87
|
}
|
96
88
|
|
97
|
-
/*
|
98
|
-
* pipe.close -> pipe
|
89
|
+
/* Closes the pipe.
|
99
90
|
*
|
100
|
-
* Closes the pipe.
|
101
|
-
*
|
102
91
|
* @return [Pipe] self
|
103
92
|
*/
|
104
93
|
|
@@ -113,12 +102,9 @@ VALUE Pipe_close(VALUE self) {
|
|
113
102
|
return self;
|
114
103
|
}
|
115
104
|
|
116
|
-
/*
|
117
|
-
* Pipe.fds -> [r, w]
|
118
|
-
*
|
119
|
-
* Returns an array containing the read and write fds for the pipe,
|
105
|
+
/* Returns an array containing the read and write fds for the pipe,
|
120
106
|
* respectively.
|
121
|
-
*
|
107
|
+
*
|
122
108
|
* @return [Array<Integer>]
|
123
109
|
*/
|
124
110
|
|
@@ -131,7 +117,7 @@ VALUE Pipe_fds(VALUE self) {
|
|
131
117
|
|
132
118
|
void Init_Pipe(void) {
|
133
119
|
cPipe = rb_define_class_under(mPolyphony, "Pipe", rb_cObject);
|
134
|
-
|
120
|
+
|
135
121
|
/*
|
136
122
|
* Document-class: Polyphony::Pipe::ClosedPipeError
|
137
123
|
*
|