polyphony 0.90 → 0.91
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/examples/pipes/echo_server.rb +17 -0
- data/examples/pipes/gunzip.rb +6 -0
- data/examples/pipes/gzip.rb +6 -0
- data/examples/pipes/gzip_http_server.rb +49 -0
- data/examples/pipes/tcp_proxy.rb +28 -0
- data/examples/pipes/tee.rb +15 -0
- data/ext/polyphony/backend_common.c +9 -7
- data/ext/polyphony/backend_io_uring.c +129 -20
- data/ext/polyphony/backend_libev.c +23 -23
- data/ext/polyphony/io_extensions.c +0 -1
- data/ext/polyphony/polyphony.c +11 -1
- data/ext/polyphony/polyphony.h +7 -0
- data/ext/polyphony/queue.c +3 -3
- data/ext/polyphony/socket_extensions.c +2 -2
- data/lib/polyphony/extensions/io.rb +4 -0
- data/lib/polyphony/version.rb +1 -1
- data/test/stress.rb +1 -1
- data/test/test_io.rb +25 -0
- data/test/test_signal.rb +6 -2
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1b4a68e893c4cdca8e308cf3297fbf2549f70c0a7038f7c492f5c7c0a6ca6b4
|
4
|
+
data.tar.gz: 65a1cd1b10fa1a29c37c24972c0a47c324f744ff0ddba6e67464000da2a2707e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 316969779f3e2ce5a055c886ee89448b1908e57dcfb06775f5aa01491e895b450cfdaa3ec3d1f72f3a59017326dd7c3478b21e85cb7914a8bf2c17544bd47de7
|
7
|
+
data.tar.gz: 0a5badc5927cac1b111a13dd65eac242e2c2a7436dbf9a42e2376c4b321d042e27012e7d6b3906bf1d434d62a85bbfa8651700f2d4585475cbf89bc52de64569
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'polyphony'
|
5
|
+
|
6
|
+
def handle_client(conn)
|
7
|
+
spin do
|
8
|
+
buffer = Polyphony.pipe
|
9
|
+
spin { IO.splice_to_eof(conn, buffer) }
|
10
|
+
IO.splice_to_eof(buffer, conn)
|
11
|
+
end
|
12
|
+
rescue SystemCallError
|
13
|
+
# ignore
|
14
|
+
end
|
15
|
+
|
16
|
+
puts "Serving echo on port 1234..."
|
17
|
+
TCPServer.new('127.0.0.1', 1234).accept_loop { |c| handle_client(c) }
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/inline'
|
4
|
+
|
5
|
+
gemfile do
|
6
|
+
gem 'h1p'
|
7
|
+
gem 'polyphony', path: '.'
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'polyphony'
|
11
|
+
require 'h1p'
|
12
|
+
|
13
|
+
def handle_client(conn)
|
14
|
+
spin do
|
15
|
+
parser = H1P::Parser.new(conn, :server)
|
16
|
+
|
17
|
+
while true # assuming persistent connection
|
18
|
+
headers = parser.parse_headers
|
19
|
+
break unless headers
|
20
|
+
|
21
|
+
raw_buffer = Polyphony.pipe
|
22
|
+
gzip_buffer = Polyphony.pipe
|
23
|
+
|
24
|
+
# splice request body to buffer
|
25
|
+
spin do
|
26
|
+
parser.splice_body_to(raw_buffer)
|
27
|
+
raw_buffer.close
|
28
|
+
end
|
29
|
+
|
30
|
+
# zip data from buffer into gzip buffer
|
31
|
+
spin do
|
32
|
+
IO.gzip(raw_buffer, gzip_buffer)
|
33
|
+
gzip_buffer.close
|
34
|
+
end
|
35
|
+
|
36
|
+
# send headers and splice response from gzip buffer
|
37
|
+
conn << "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
|
38
|
+
IO.http1_splice_chunked(gzip_buffer, conn, 65535)
|
39
|
+
end
|
40
|
+
rescue H1P::Error
|
41
|
+
puts 'Got invalid request, closing connection...'
|
42
|
+
ensure
|
43
|
+
conn.close
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
puts "Serving echo on port 1234..."
|
48
|
+
TCPServer.new('127.0.0.1', 1234).accept_loop { |c| handle_client(c) }
|
49
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'polyphony'
|
5
|
+
|
6
|
+
DESTINATION = ['127.0.0.1', 1234]
|
7
|
+
|
8
|
+
def handle_client(conn)
|
9
|
+
spin do
|
10
|
+
dest = TCPSocket.new(*DESTINATION)
|
11
|
+
w_buffer = Polyphony.pipe
|
12
|
+
r_buffer = Polyphony.pipe
|
13
|
+
|
14
|
+
spin { IO.splice_to_eof(conn, w_buffer) }
|
15
|
+
spin { IO.splice_to_eof(w_buffer, dest) }
|
16
|
+
|
17
|
+
spin { IO.splice_to_eof(dest, r_buffer) }
|
18
|
+
spin { IO.splice_to_eof(r_buffer, conn) }
|
19
|
+
|
20
|
+
Fiber.current.await_all_children
|
21
|
+
end
|
22
|
+
rescue SystemCallError
|
23
|
+
dest.close rescue nil
|
24
|
+
# ignore
|
25
|
+
end
|
26
|
+
|
27
|
+
puts "Serving TCP proxy on port 4321..."
|
28
|
+
TCPServer.new('127.0.0.1', 4321).accept_loop { |c| handle_client(c) }
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'polyphony'
|
5
|
+
|
6
|
+
chunk_size = 1 << 16
|
7
|
+
file_path = ARGV[0]
|
8
|
+
|
9
|
+
File.open(file_path, 'w+') do |f|
|
10
|
+
loop do
|
11
|
+
len = IO.tee(STDIN, STDOUT, chunk_size)
|
12
|
+
break if len == 0
|
13
|
+
IO.splice(STDIN, f, len)
|
14
|
+
end
|
15
|
+
end
|
@@ -140,7 +140,9 @@ inline void backend_base_unpark_fiber(struct Backend_base *base, VALUE fiber) {
|
|
140
140
|
inline void backend_trace(struct Backend_base *base, int argc, VALUE *argv) {
|
141
141
|
if (base->trace_proc == Qnil || base->in_trace_proc) return;
|
142
142
|
|
143
|
+
base->in_trace_proc = 1;
|
143
144
|
rb_funcallv(base->trace_proc, ID_call, argc, argv);
|
145
|
+
base->in_trace_proc = 0;
|
144
146
|
}
|
145
147
|
|
146
148
|
#ifdef POLYPHONY_USE_PIDFD_OPEN
|
@@ -416,13 +418,13 @@ VALUE Backend_stats(VALUE self) {
|
|
416
418
|
struct backend_stats backend_stats = backend_get_stats(self);
|
417
419
|
|
418
420
|
VALUE stats = rb_hash_new();
|
419
|
-
rb_hash_aset(stats, SYM_runqueue_size,
|
420
|
-
rb_hash_aset(stats, SYM_runqueue_length,
|
421
|
-
rb_hash_aset(stats, SYM_runqueue_max_length,
|
422
|
-
rb_hash_aset(stats, SYM_op_count,
|
423
|
-
rb_hash_aset(stats, SYM_switch_count,
|
424
|
-
rb_hash_aset(stats, SYM_poll_count,
|
425
|
-
rb_hash_aset(stats, SYM_pending_ops,
|
421
|
+
rb_hash_aset(stats, SYM_runqueue_size, INT2FIX(backend_stats.runqueue_size));
|
422
|
+
rb_hash_aset(stats, SYM_runqueue_length, INT2FIX(backend_stats.runqueue_length));
|
423
|
+
rb_hash_aset(stats, SYM_runqueue_max_length, INT2FIX(backend_stats.runqueue_max_length));
|
424
|
+
rb_hash_aset(stats, SYM_op_count, INT2FIX(backend_stats.op_count));
|
425
|
+
rb_hash_aset(stats, SYM_switch_count, INT2FIX(backend_stats.switch_count));
|
426
|
+
rb_hash_aset(stats, SYM_poll_count, INT2FIX(backend_stats.poll_count));
|
427
|
+
rb_hash_aset(stats, SYM_pending_ops, INT2FIX(backend_stats.pending_ops));
|
426
428
|
RB_GC_GUARD(stats);
|
427
429
|
return stats;
|
428
430
|
}
|
@@ -364,7 +364,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
|
|
364
364
|
int fd;
|
365
365
|
rb_io_t *fptr;
|
366
366
|
struct io_buffer buffer = get_io_buffer(str);
|
367
|
-
long buf_pos =
|
367
|
+
long buf_pos = FIX2INT(pos);
|
368
368
|
int shrinkable_string = 0;
|
369
369
|
int expandable_buffer = 0;
|
370
370
|
long total = 0;
|
@@ -456,7 +456,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
|
|
456
456
|
rb_io_t *fptr;
|
457
457
|
VALUE str;
|
458
458
|
long total;
|
459
|
-
long len =
|
459
|
+
long len = FIX2INT(maxlen);
|
460
460
|
int shrinkable;
|
461
461
|
char *buf;
|
462
462
|
|
@@ -584,7 +584,7 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
|
|
584
584
|
}
|
585
585
|
}
|
586
586
|
|
587
|
-
return
|
587
|
+
return INT2FIX(buffer.len);
|
588
588
|
}
|
589
589
|
|
590
590
|
VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
|
@@ -652,7 +652,7 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
|
|
652
652
|
}
|
653
653
|
|
654
654
|
free(iov);
|
655
|
-
return
|
655
|
+
return INT2FIX(total_written);
|
656
656
|
}
|
657
657
|
|
658
658
|
VALUE Backend_write_m(int argc, VALUE *argv, VALUE self) {
|
@@ -669,7 +669,7 @@ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length, VALUE pos) {
|
|
669
669
|
int fd;
|
670
670
|
rb_io_t *fptr;
|
671
671
|
struct io_buffer buffer = get_io_buffer(str);
|
672
|
-
long buf_pos =
|
672
|
+
long buf_pos = FIX2INT(pos);
|
673
673
|
int shrinkable_string = 0;
|
674
674
|
int expandable_buffer = 0;
|
675
675
|
long total = 0;
|
@@ -742,7 +742,7 @@ VALUE Backend_recv_loop(VALUE self, VALUE io, VALUE maxlen) {
|
|
742
742
|
rb_io_t *fptr;
|
743
743
|
VALUE str;
|
744
744
|
long total;
|
745
|
-
long len =
|
745
|
+
long len = FIX2INT(maxlen);
|
746
746
|
int shrinkable;
|
747
747
|
char *buf;
|
748
748
|
|
@@ -838,7 +838,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
|
|
838
838
|
|
839
839
|
struct io_buffer buffer = get_io_buffer(str);
|
840
840
|
long left = buffer.len;
|
841
|
-
int flags_int =
|
841
|
+
int flags_int = FIX2INT(flags);
|
842
842
|
|
843
843
|
GetBackend(self, backend);
|
844
844
|
fd = fd_from_io(io, &fptr, 1, 0);
|
@@ -869,7 +869,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
|
|
869
869
|
}
|
870
870
|
}
|
871
871
|
|
872
|
-
return
|
872
|
+
return INT2FIX(buffer.len);
|
873
873
|
}
|
874
874
|
|
875
875
|
VALUE io_uring_backend_accept(Backend_t *backend, VALUE server_socket, VALUE socket_class, int loop) {
|
@@ -954,7 +954,7 @@ VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest, VALUE m
|
|
954
954
|
int result;
|
955
955
|
int completed;
|
956
956
|
|
957
|
-
io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1,
|
957
|
+
io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1, FIX2INT(maxlen), 0);
|
958
958
|
|
959
959
|
result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
|
960
960
|
completed = context_store_release(&backend->store, ctx);
|
@@ -965,7 +965,7 @@ VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest, VALUE m
|
|
965
965
|
rb_syserr_fail(-result, strerror(-result));
|
966
966
|
|
967
967
|
total += result;
|
968
|
-
if (result == 0 || !loop) return
|
968
|
+
if (result == 0 || !loop) return INT2FIX(total);
|
969
969
|
}
|
970
970
|
|
971
971
|
RB_GC_GUARD(resume_value);
|
@@ -984,6 +984,112 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize)
|
|
984
984
|
return io_uring_backend_splice(backend, src, dest, chunksize, 1);
|
985
985
|
}
|
986
986
|
|
987
|
+
struct double_splice_ctx {
|
988
|
+
Backend_t *backend;
|
989
|
+
VALUE src;
|
990
|
+
VALUE dest;
|
991
|
+
int pipefd[2];
|
992
|
+
};
|
993
|
+
|
994
|
+
#define DOUBLE_SPLICE_MAXLEN (1 << 16)
|
995
|
+
|
996
|
+
static inline op_context_t *prepare_double_splice_ctx(Backend_t *backend, int src_fd, int dest_fd) {
|
997
|
+
op_context_t *ctx = context_store_acquire(&backend->store, OP_SPLICE);
|
998
|
+
struct io_uring_sqe *sqe = io_uring_backend_get_sqe(backend);
|
999
|
+
io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1, DOUBLE_SPLICE_MAXLEN, 0);
|
1000
|
+
io_uring_sqe_set_data(sqe, ctx);
|
1001
|
+
io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
|
1002
|
+
backend->base.op_count += 1;
|
1003
|
+
backend->pending_sqes += 1;
|
1004
|
+
|
1005
|
+
return ctx;
|
1006
|
+
}
|
1007
|
+
|
1008
|
+
static inline void io_uring_backend_cancel(Backend_t *backend, op_context_t *ctx) {
|
1009
|
+
struct io_uring_sqe *sqe = io_uring_backend_get_sqe(backend);
|
1010
|
+
ctx->result = -ECANCELED;
|
1011
|
+
io_uring_prep_cancel(sqe, (__u64)ctx, 0);
|
1012
|
+
}
|
1013
|
+
|
1014
|
+
VALUE double_splice_to_eof_safe(struct double_splice_ctx *ctx) {
|
1015
|
+
int src_fd;
|
1016
|
+
int dest_fd;
|
1017
|
+
rb_io_t *src_fptr;
|
1018
|
+
rb_io_t *dest_fptr;
|
1019
|
+
int total = 0;
|
1020
|
+
VALUE resume_value = Qnil;
|
1021
|
+
|
1022
|
+
src_fd = fd_from_io(ctx->src, &src_fptr, 0, 0);
|
1023
|
+
dest_fd = fd_from_io(ctx->dest, &dest_fptr, 1, 0);
|
1024
|
+
|
1025
|
+
op_context_t *ctx_src = prepare_double_splice_ctx(ctx->backend, src_fd, ctx->pipefd[1]);
|
1026
|
+
op_context_t *ctx_dest = prepare_double_splice_ctx(ctx->backend, ctx->pipefd[0], dest_fd);
|
1027
|
+
|
1028
|
+
if (ctx->backend->pending_sqes >= ctx->backend->prepared_limit)
|
1029
|
+
io_uring_backend_immediate_submit(ctx->backend);
|
1030
|
+
|
1031
|
+
while (1) {
|
1032
|
+
resume_value = backend_await((struct Backend_base *)ctx->backend);
|
1033
|
+
|
1034
|
+
if ((ctx_src && ctx_src->ref_count == 2 && ctx_dest && ctx_dest->ref_count == 2) || TEST_EXCEPTION(resume_value)) {
|
1035
|
+
if (ctx_src) {
|
1036
|
+
context_store_release(&ctx->backend->store, ctx_src);
|
1037
|
+
io_uring_backend_cancel(ctx->backend, ctx_src);
|
1038
|
+
}
|
1039
|
+
if (ctx_dest) {
|
1040
|
+
context_store_release(&ctx->backend->store, ctx_dest);
|
1041
|
+
io_uring_backend_cancel(ctx->backend, ctx_dest);
|
1042
|
+
}
|
1043
|
+
io_uring_backend_immediate_submit(ctx->backend);
|
1044
|
+
RAISE_IF_EXCEPTION(resume_value);
|
1045
|
+
return resume_value;
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
if (ctx_src && ctx_src->ref_count == 1) {
|
1049
|
+
context_store_release(&ctx->backend->store, ctx_src);
|
1050
|
+
if (ctx_src->result == 0) {
|
1051
|
+
// close write end of pipe
|
1052
|
+
close(ctx->pipefd[1]);
|
1053
|
+
ctx_src = NULL;
|
1054
|
+
}
|
1055
|
+
else {
|
1056
|
+
ctx_src = prepare_double_splice_ctx(ctx->backend, src_fd, ctx->pipefd[1]);
|
1057
|
+
}
|
1058
|
+
}
|
1059
|
+
if (ctx_dest && ctx_dest->ref_count == 1) {
|
1060
|
+
context_store_release(&ctx->backend->store, ctx_dest);
|
1061
|
+
if (ctx_dest->result == 0)
|
1062
|
+
break;
|
1063
|
+
else {
|
1064
|
+
total += ctx_dest->result;
|
1065
|
+
ctx_dest = prepare_double_splice_ctx(ctx->backend, ctx->pipefd[0], dest_fd);
|
1066
|
+
}
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
if (ctx->backend->pending_sqes >= ctx->backend->prepared_limit)
|
1070
|
+
io_uring_backend_immediate_submit(ctx->backend);
|
1071
|
+
}
|
1072
|
+
RB_GC_GUARD(resume_value);
|
1073
|
+
return INT2FIX(total);
|
1074
|
+
}
|
1075
|
+
|
1076
|
+
VALUE double_splice_to_eof_cleanup(struct double_splice_ctx *ctx) {
|
1077
|
+
if (ctx->pipefd[0]) close(ctx->pipefd[0]);
|
1078
|
+
if (ctx->pipefd[1]) close(ctx->pipefd[1]);
|
1079
|
+
return Qnil;
|
1080
|
+
}
|
1081
|
+
|
1082
|
+
VALUE Backend_double_splice_to_eof(VALUE self, VALUE src, VALUE dest) {
|
1083
|
+
struct double_splice_ctx ctx = { NULL, src, dest, 0, 0 };
|
1084
|
+
GetBackend(self, ctx.backend);
|
1085
|
+
if (pipe(ctx.pipefd) == -1) rb_syserr_fail(errno, strerror(errno));
|
1086
|
+
|
1087
|
+
return rb_ensure(
|
1088
|
+
SAFE(double_splice_to_eof_safe), (VALUE)&ctx,
|
1089
|
+
SAFE(double_splice_to_eof_cleanup), (VALUE)&ctx
|
1090
|
+
);
|
1091
|
+
}
|
1092
|
+
|
987
1093
|
VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
988
1094
|
Backend_t *backend;
|
989
1095
|
GetBackend(self, backend);
|
@@ -1003,7 +1109,7 @@ VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1003
1109
|
int result;
|
1004
1110
|
int completed;
|
1005
1111
|
|
1006
|
-
io_uring_prep_tee(sqe, src_fd, dest_fd,
|
1112
|
+
io_uring_prep_tee(sqe, src_fd, dest_fd, FIX2INT(maxlen), 0);
|
1007
1113
|
|
1008
1114
|
result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
|
1009
1115
|
completed = context_store_release(&backend->store, ctx);
|
@@ -1013,7 +1119,7 @@ VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1013
1119
|
if (result < 0)
|
1014
1120
|
rb_syserr_fail(-result, strerror(-result));
|
1015
1121
|
|
1016
|
-
return
|
1122
|
+
return INT2FIX(result);
|
1017
1123
|
}
|
1018
1124
|
|
1019
1125
|
RB_GC_GUARD(resume_value);
|
@@ -1222,7 +1328,7 @@ VALUE Backend_timeout(int argc, VALUE *argv, VALUE self) {
|
|
1222
1328
|
}
|
1223
1329
|
|
1224
1330
|
VALUE Backend_waitpid(VALUE self, VALUE pid) {
|
1225
|
-
int pid_int =
|
1331
|
+
int pid_int = FIX2INT(pid);
|
1226
1332
|
int fd = pidfd_open(pid_int, 0);
|
1227
1333
|
int status;
|
1228
1334
|
pid_t ret;
|
@@ -1246,7 +1352,7 @@ VALUE Backend_waitpid(VALUE self, VALUE pid) {
|
|
1246
1352
|
else
|
1247
1353
|
rb_syserr_fail(e, strerror(e));
|
1248
1354
|
}
|
1249
|
-
return rb_ary_new_from_args(2,
|
1355
|
+
return rb_ary_new_from_args(2, INT2FIX(ret), INT2FIX(WEXITSTATUS(status)));
|
1250
1356
|
}
|
1251
1357
|
|
1252
1358
|
/*
|
@@ -1324,7 +1430,7 @@ struct io_uring_sqe *Backend_chain_prepare_send(Backend_t *backend, VALUE io, VA
|
|
1324
1430
|
fd = fd_from_io(io, &fptr, 1, 0);
|
1325
1431
|
|
1326
1432
|
sqe = io_uring_backend_get_sqe(backend);
|
1327
|
-
io_uring_prep_send(sqe, fd, StringValuePtr(str), RSTRING_LEN(str),
|
1433
|
+
io_uring_prep_send(sqe, fd, StringValuePtr(str), RSTRING_LEN(str), FIX2INT(flags));
|
1328
1434
|
return sqe;
|
1329
1435
|
}
|
1330
1436
|
|
@@ -1338,7 +1444,7 @@ struct io_uring_sqe *Backend_chain_prepare_splice(Backend_t *backend, VALUE src,
|
|
1338
1444
|
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
1339
1445
|
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
1340
1446
|
sqe = io_uring_backend_get_sqe(backend);
|
1341
|
-
io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1,
|
1447
|
+
io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1, FIX2INT(maxlen), 0);
|
1342
1448
|
return sqe;
|
1343
1449
|
}
|
1344
1450
|
|
@@ -1434,7 +1540,7 @@ VALUE Backend_chain(int argc,VALUE *argv, VALUE self) {
|
|
1434
1540
|
}
|
1435
1541
|
|
1436
1542
|
RB_GC_GUARD(resume_value);
|
1437
|
-
return
|
1543
|
+
return INT2FIX(result);
|
1438
1544
|
}
|
1439
1545
|
|
1440
1546
|
VALUE Backend_idle_gc_period_set(VALUE self, VALUE period) {
|
@@ -1540,7 +1646,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1540
1646
|
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
1541
1647
|
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
1542
1648
|
|
1543
|
-
maxlen =
|
1649
|
+
maxlen = FIX2INT(chunk_size);
|
1544
1650
|
|
1545
1651
|
if (pipe(pipefd) == -1) {
|
1546
1652
|
err = errno;
|
@@ -1566,7 +1672,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1566
1672
|
if (chunk_len == 0) break;
|
1567
1673
|
|
1568
1674
|
total += chunk_len;
|
1569
|
-
chunk_len_value =
|
1675
|
+
chunk_len_value = INT2FIX(chunk_len);
|
1570
1676
|
|
1571
1677
|
|
1572
1678
|
if (chunk_prefix != Qnil) {
|
@@ -1605,7 +1711,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1605
1711
|
RB_GC_GUARD(switchpoint_result);
|
1606
1712
|
if (pipefd[0] != -1) close(pipefd[0]);
|
1607
1713
|
if (pipefd[1] != -1) close(pipefd[1]);
|
1608
|
-
return
|
1714
|
+
return INT2FIX(total);
|
1609
1715
|
syscallerror:
|
1610
1716
|
if (pipefd[0] != -1) close(pipefd[0]);
|
1611
1717
|
if (pipefd[1] != -1) close(pipefd[1]);
|
@@ -1693,9 +1799,12 @@ void Init_Backend() {
|
|
1693
1799
|
rb_define_method(cBackend, "send", Backend_send, 3);
|
1694
1800
|
rb_define_method(cBackend, "sendv", Backend_sendv, 3);
|
1695
1801
|
rb_define_method(cBackend, "sleep", Backend_sleep, 1);
|
1802
|
+
|
1696
1803
|
rb_define_method(cBackend, "splice", Backend_splice, 3);
|
1697
1804
|
rb_define_method(cBackend, "splice_to_eof", Backend_splice_to_eof, 3);
|
1805
|
+
rb_define_method(cBackend, "double_splice_to_eof", Backend_double_splice_to_eof, 2);
|
1698
1806
|
rb_define_method(cBackend, "tee", Backend_tee, 3);
|
1807
|
+
|
1699
1808
|
rb_define_method(cBackend, "timeout", Backend_timeout, -1);
|
1700
1809
|
rb_define_method(cBackend, "timer_loop", Backend_timer_loop, 1);
|
1701
1810
|
rb_define_method(cBackend, "wait_event", Backend_wait_event, 1);
|
@@ -291,7 +291,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
|
|
291
291
|
rb_io_t *fptr;
|
292
292
|
|
293
293
|
struct io_buffer buffer = get_io_buffer(str);
|
294
|
-
long buf_pos =
|
294
|
+
long buf_pos = FIX2INT(pos);
|
295
295
|
int shrinkable_string = 0;
|
296
296
|
int expandable_buffer = 0;
|
297
297
|
long total = 0;
|
@@ -389,7 +389,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
|
|
389
389
|
rb_io_t *fptr;
|
390
390
|
VALUE str;
|
391
391
|
long total;
|
392
|
-
long len =
|
392
|
+
long len = FIX2INT(maxlen);
|
393
393
|
int shrinkable;
|
394
394
|
char *buf;
|
395
395
|
VALUE switchpoint_result = Qnil;
|
@@ -519,7 +519,7 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
|
|
519
519
|
RB_GC_GUARD(watcher.fiber);
|
520
520
|
RB_GC_GUARD(switchpoint_result);
|
521
521
|
|
522
|
-
return
|
522
|
+
return INT2FIX(buffer.len);
|
523
523
|
error:
|
524
524
|
return RAISE_EXCEPTION(switchpoint_result);
|
525
525
|
}
|
@@ -590,7 +590,7 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
|
|
590
590
|
RB_GC_GUARD(switchpoint_result);
|
591
591
|
|
592
592
|
free(iov);
|
593
|
-
return
|
593
|
+
return INT2FIX(total_written);
|
594
594
|
error:
|
595
595
|
free(iov);
|
596
596
|
return RAISE_EXCEPTION(switchpoint_result);
|
@@ -763,7 +763,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
|
|
763
763
|
|
764
764
|
struct io_buffer buffer = get_io_buffer(str);
|
765
765
|
long left = buffer.len;
|
766
|
-
int flags_int =
|
766
|
+
int flags_int = FIX2INT(flags);
|
767
767
|
|
768
768
|
GetBackend(self, backend);
|
769
769
|
fd = fd_from_io(io, &fptr, 1, 0);
|
@@ -795,7 +795,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
|
|
795
795
|
RB_GC_GUARD(watcher.fiber);
|
796
796
|
RB_GC_GUARD(switchpoint_result);
|
797
797
|
|
798
|
-
return
|
798
|
+
return INT2FIX(buffer.len);
|
799
799
|
error:
|
800
800
|
return RAISE_EXCEPTION(switchpoint_result);
|
801
801
|
}
|
@@ -868,7 +868,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
868
868
|
|
869
869
|
while (1) {
|
870
870
|
backend->base.op_count++;
|
871
|
-
len = splice(src_fd, 0, dest_fd, 0,
|
871
|
+
len = splice(src_fd, 0, dest_fd, 0, FIX2INT(maxlen), 0);
|
872
872
|
if (len < 0) {
|
873
873
|
int e = errno;
|
874
874
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
@@ -889,7 +889,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
889
889
|
RB_GC_GUARD(watcher.ctx.fiber);
|
890
890
|
RB_GC_GUARD(switchpoint_result);
|
891
891
|
|
892
|
-
return
|
892
|
+
return INT2FIX(len);
|
893
893
|
error:
|
894
894
|
return RAISE_EXCEPTION(switchpoint_result);
|
895
895
|
}
|
@@ -912,7 +912,7 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
912
912
|
|
913
913
|
while (1) {
|
914
914
|
backend->base.op_count++;
|
915
|
-
len = splice(src_fd, 0, dest_fd, 0,
|
915
|
+
len = splice(src_fd, 0, dest_fd, 0, FIX2INT(maxlen), 0);
|
916
916
|
if (len < 0) {
|
917
917
|
int e = errno;
|
918
918
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
@@ -936,7 +936,7 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
936
936
|
RB_GC_GUARD(watcher.ctx.fiber);
|
937
937
|
RB_GC_GUARD(switchpoint_result);
|
938
938
|
|
939
|
-
return
|
939
|
+
return INT2FIX(total);
|
940
940
|
error:
|
941
941
|
return RAISE_EXCEPTION(switchpoint_result);
|
942
942
|
}
|
@@ -958,7 +958,7 @@ VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
958
958
|
|
959
959
|
while (1) {
|
960
960
|
backend->base.op_count++;
|
961
|
-
len = tee(src_fd, dest_fd,
|
961
|
+
len = tee(src_fd, dest_fd, FIX2INT(maxlen), 0);
|
962
962
|
if (len < 0) {
|
963
963
|
int e = errno;
|
964
964
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
@@ -979,7 +979,7 @@ VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
979
979
|
RB_GC_GUARD(watcher.ctx.fiber);
|
980
980
|
RB_GC_GUARD(switchpoint_result);
|
981
981
|
|
982
|
-
return
|
982
|
+
return INT2FIX(len);
|
983
983
|
error:
|
984
984
|
return RAISE_EXCEPTION(switchpoint_result);
|
985
985
|
}
|
@@ -994,7 +994,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
994
994
|
int dest_fd;
|
995
995
|
rb_io_t *src_fptr;
|
996
996
|
rb_io_t *dest_fptr;
|
997
|
-
int len =
|
997
|
+
int len = FIX2INT(maxlen);
|
998
998
|
VALUE str = rb_str_new(0, len);
|
999
999
|
char *buf = RSTRING_PTR(str);
|
1000
1000
|
int left = 0;
|
@@ -1047,7 +1047,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1047
1047
|
RB_GC_GUARD(switchpoint_result);
|
1048
1048
|
RB_GC_GUARD(str);
|
1049
1049
|
|
1050
|
-
return
|
1050
|
+
return INT2FIX(total);
|
1051
1051
|
error:
|
1052
1052
|
return RAISE_EXCEPTION(switchpoint_result);
|
1053
1053
|
}
|
@@ -1060,7 +1060,7 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1060
1060
|
int dest_fd;
|
1061
1061
|
rb_io_t *src_fptr;
|
1062
1062
|
rb_io_t *dest_fptr;
|
1063
|
-
int len =
|
1063
|
+
int len = FIX2INT(maxlen);
|
1064
1064
|
VALUE str = rb_str_new(0, len);
|
1065
1065
|
char *buf = RSTRING_PTR(str);
|
1066
1066
|
int left = 0;
|
@@ -1118,7 +1118,7 @@ done:
|
|
1118
1118
|
RB_GC_GUARD(switchpoint_result);
|
1119
1119
|
RB_GC_GUARD(str);
|
1120
1120
|
|
1121
|
-
return
|
1121
|
+
return INT2FIX(total);
|
1122
1122
|
error:
|
1123
1123
|
return RAISE_EXCEPTION(switchpoint_result);
|
1124
1124
|
}
|
@@ -1263,7 +1263,7 @@ VALUE Backend_timeout(int argc,VALUE *argv, VALUE self) {
|
|
1263
1263
|
|
1264
1264
|
#ifdef POLYPHONY_USE_PIDFD_OPEN
|
1265
1265
|
VALUE Backend_waitpid(VALUE self, VALUE pid) {
|
1266
|
-
int pid_int =
|
1266
|
+
int pid_int = FIX2INT(pid);
|
1267
1267
|
int fd = pidfd_open(pid_int, 0);
|
1268
1268
|
if (fd >= 0) {
|
1269
1269
|
Backend_t *backend;
|
@@ -1286,7 +1286,7 @@ VALUE Backend_waitpid(VALUE self, VALUE pid) {
|
|
1286
1286
|
int e = errno;
|
1287
1287
|
rb_syserr_fail(e, strerror(e));
|
1288
1288
|
}
|
1289
|
-
return rb_ary_new_from_args(2,
|
1289
|
+
return rb_ary_new_from_args(2, INT2FIX(ret), INT2FIX(WEXITSTATUS(status)));
|
1290
1290
|
}
|
1291
1291
|
#else
|
1292
1292
|
struct libev_child {
|
@@ -1299,7 +1299,7 @@ void Backend_child_callback(EV_P_ ev_child *w, int revents) {
|
|
1299
1299
|
int exit_status = WEXITSTATUS(w->rstatus);
|
1300
1300
|
VALUE status;
|
1301
1301
|
|
1302
|
-
status = rb_ary_new_from_args(2,
|
1302
|
+
status = rb_ary_new_from_args(2, INT2FIX(w->rpid), INT2FIX(exit_status));
|
1303
1303
|
Fiber_make_runnable(watcher->fiber, status);
|
1304
1304
|
}
|
1305
1305
|
|
@@ -1310,7 +1310,7 @@ VALUE Backend_waitpid(VALUE self, VALUE pid) {
|
|
1310
1310
|
GetBackend(self, backend);
|
1311
1311
|
|
1312
1312
|
watcher.fiber = rb_fiber_current();
|
1313
|
-
ev_child_init(&watcher.child, Backend_child_callback,
|
1313
|
+
ev_child_init(&watcher.child, Backend_child_callback, FIX2INT(pid), 0);
|
1314
1314
|
ev_child_start(backend->ev_loop, &watcher.child);
|
1315
1315
|
backend->base.op_count++;
|
1316
1316
|
|
@@ -1491,7 +1491,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1491
1491
|
|
1492
1492
|
struct libev_rw_io watcher;
|
1493
1493
|
watcher.ctx.fiber = Qnil;
|
1494
|
-
int maxlen =
|
1494
|
+
int maxlen = FIX2INT(chunk_size);
|
1495
1495
|
VALUE str = Qnil;
|
1496
1496
|
VALUE chunk_len_value = Qnil;
|
1497
1497
|
|
@@ -1515,7 +1515,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1515
1515
|
if (chunk_len == 0) break;
|
1516
1516
|
|
1517
1517
|
total += chunk_len;
|
1518
|
-
chunk_len_value =
|
1518
|
+
chunk_len_value = INT2FIX(chunk_len);
|
1519
1519
|
|
1520
1520
|
if (chunk_prefix != Qnil) {
|
1521
1521
|
VALUE str = (TYPE(chunk_prefix) == T_STRING) ? chunk_prefix : rb_funcall(chunk_prefix, ID_call, 1, chunk_len_value);
|
@@ -1553,7 +1553,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1553
1553
|
RB_GC_GUARD(result);
|
1554
1554
|
if (pipefd[0] != -1) close(pipefd[0]);
|
1555
1555
|
if (pipefd[1] != -1) close(pipefd[1]);
|
1556
|
-
return
|
1556
|
+
return INT2FIX(total);
|
1557
1557
|
syscallerror:
|
1558
1558
|
if (pipefd[0] != -1) close(pipefd[0]);
|
1559
1559
|
if (pipefd[1] != -1) close(pipefd[1]);
|
@@ -502,7 +502,6 @@ static inline VALUE z_stream_cleanup(struct z_stream_ctx *ctx) {
|
|
502
502
|
return Qnil;
|
503
503
|
}
|
504
504
|
|
505
|
-
#define SAFE(f) (VALUE (*)(VALUE))(f)
|
506
505
|
#define Z_STREAM_SAFE_IO_LOOP_WITH_CLEANUP(ctx) \
|
507
506
|
rb_ensure(SAFE(z_stream_io_loop), (VALUE)&ctx, SAFE(z_stream_cleanup), (VALUE)&ctx)
|
508
507
|
|
data/ext/polyphony/polyphony.c
CHANGED
@@ -94,6 +94,12 @@ VALUE Polyphony_backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE c
|
|
94
94
|
return Backend_splice_to_eof(BACKEND(), src, dest, chunksize);
|
95
95
|
}
|
96
96
|
|
97
|
+
#ifdef POLYPHONY_BACKEND_LIBURING
|
98
|
+
VALUE Polyphony_backend_double_splice_to_eof(VALUE self, VALUE src, VALUE dest) {
|
99
|
+
return Backend_double_splice_to_eof(BACKEND(), src, dest);
|
100
|
+
}
|
101
|
+
#endif
|
102
|
+
|
97
103
|
#ifdef POLYPHONY_LINUX
|
98
104
|
VALUE Polyphony_backend_tee(VALUE self, VALUE src, VALUE dest, VALUE chunksize) {
|
99
105
|
return Backend_tee(BACKEND(), src, dest, chunksize);
|
@@ -126,7 +132,7 @@ VALUE Polyphony_backend_write(int argc, VALUE *argv, VALUE self) {
|
|
126
132
|
|
127
133
|
VALUE Polyphony_with_raw_buffer(VALUE self, VALUE size) {
|
128
134
|
struct raw_buffer buffer;
|
129
|
-
buffer.len =
|
135
|
+
buffer.len = FIX2INT(size);
|
130
136
|
buffer.ptr = malloc(buffer.len);
|
131
137
|
if (!buffer.ptr)
|
132
138
|
rb_raise(rb_eRuntimeError, "Failed to allocate buffer");
|
@@ -187,6 +193,10 @@ void Init_Polyphony() {
|
|
187
193
|
rb_define_singleton_method(mPolyphony, "backend_splice", Polyphony_backend_splice, 3);
|
188
194
|
rb_define_singleton_method(mPolyphony, "backend_splice_to_eof", Polyphony_backend_splice_to_eof, 3);
|
189
195
|
|
196
|
+
#ifdef POLYPHONY_BACKEND_LIBURING
|
197
|
+
rb_define_singleton_method(mPolyphony, "backend_double_splice_to_eof", Polyphony_backend_double_splice_to_eof, 2);
|
198
|
+
#endif
|
199
|
+
|
190
200
|
#ifdef POLYPHONY_LINUX
|
191
201
|
rb_define_singleton_method(mPolyphony, "backend_tee", Polyphony_backend_tee, 3);
|
192
202
|
#endif
|
data/ext/polyphony/polyphony.h
CHANGED
@@ -35,6 +35,9 @@
|
|
35
35
|
|
36
36
|
#define BACKEND() (rb_ivar_get(rb_thread_current(), ID_ivar_backend))
|
37
37
|
|
38
|
+
// SAFE is used to cast functions used in rb_ensure
|
39
|
+
#define SAFE(f) (VALUE (*)(VALUE))(f)
|
40
|
+
|
38
41
|
extern VALUE mPolyphony;
|
39
42
|
extern VALUE cPipe;
|
40
43
|
extern VALUE cQueue;
|
@@ -114,6 +117,10 @@ VALUE Backend_sleep(VALUE self, VALUE duration);
|
|
114
117
|
VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen);
|
115
118
|
VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize);
|
116
119
|
|
120
|
+
#ifdef POLYPHONY_BACKEND_LIBURING
|
121
|
+
VALUE Backend_double_splice_to_eof(VALUE self, VALUE src, VALUE dest);
|
122
|
+
#endif
|
123
|
+
|
117
124
|
#ifdef POLYPHONY_LINUX
|
118
125
|
VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen);
|
119
126
|
#endif
|
data/ext/polyphony/queue.c
CHANGED
@@ -210,7 +210,7 @@ VALUE Queue_capped_p(VALUE self) {
|
|
210
210
|
Queue_t *queue;
|
211
211
|
GetQueue(self, queue);
|
212
212
|
|
213
|
-
return queue->capacity ?
|
213
|
+
return queue->capacity ? INT2FIX(queue->capacity) : Qnil;
|
214
214
|
}
|
215
215
|
|
216
216
|
VALUE Queue_clear(VALUE self) {
|
@@ -280,14 +280,14 @@ VALUE Queue_num_waiting(VALUE self) {
|
|
280
280
|
Queue_t *queue;
|
281
281
|
GetQueue(self, queue);
|
282
282
|
|
283
|
-
return
|
283
|
+
return INT2FIX(queue->shift_queue.count);
|
284
284
|
}
|
285
285
|
|
286
286
|
VALUE Queue_size_m(VALUE self) {
|
287
287
|
Queue_t *queue;
|
288
288
|
GetQueue(self, queue);
|
289
289
|
|
290
|
-
return
|
290
|
+
return INT2FIX(queue->values.count);
|
291
291
|
}
|
292
292
|
|
293
293
|
VALUE Queue_closed_p(VALUE self) {
|
@@ -6,13 +6,13 @@ VALUE Socket_send(VALUE self, VALUE msg, VALUE flags) {
|
|
6
6
|
|
7
7
|
VALUE Socket_write(int argc, VALUE *argv, VALUE self) {
|
8
8
|
VALUE ary = rb_ary_new_from_values(argc, argv);
|
9
|
-
VALUE result = Backend_sendv(BACKEND(), self, ary,
|
9
|
+
VALUE result = Backend_sendv(BACKEND(), self, ary, INT2FIX(0));
|
10
10
|
RB_GC_GUARD(ary);
|
11
11
|
return result;
|
12
12
|
}
|
13
13
|
|
14
14
|
VALUE Socket_double_chevron(VALUE self, VALUE msg) {
|
15
|
-
Backend_send(BACKEND(), self, msg,
|
15
|
+
Backend_send(BACKEND(), self, msg, INT2FIX(0));
|
16
16
|
return self;
|
17
17
|
}
|
18
18
|
|
data/lib/polyphony/version.rb
CHANGED
data/test/stress.rb
CHANGED
data/test/test_io.rb
CHANGED
@@ -368,6 +368,31 @@ class IOTest < MiniTest::Test
|
|
368
368
|
end
|
369
369
|
end
|
370
370
|
|
371
|
+
def test_double_splice_to_eof
|
372
|
+
if Thread.current.backend.kind == :io_uring
|
373
|
+
skip "IO.double_splice_to_eof available only with io_uring"
|
374
|
+
end
|
375
|
+
|
376
|
+
src = Polyphony.pipe
|
377
|
+
dest = Polyphony.pipe
|
378
|
+
ret = nil
|
379
|
+
data = 'foobar' * 10
|
380
|
+
|
381
|
+
f1 = spin {
|
382
|
+
ret = IO.double_splice_to_eof(src, dest)
|
383
|
+
dest.close
|
384
|
+
}
|
385
|
+
|
386
|
+
src << data
|
387
|
+
src.close
|
388
|
+
|
389
|
+
f1.await
|
390
|
+
|
391
|
+
spliced = dest.read
|
392
|
+
assert_equal data, spliced
|
393
|
+
assert_equal data.bytesize, ret
|
394
|
+
end
|
395
|
+
|
371
396
|
def test_tee_from
|
372
397
|
skip "tested only on Linux" unless RUBY_PLATFORM =~ /linux/
|
373
398
|
|
data/test/test_signal.rb
CHANGED
@@ -32,11 +32,15 @@ class SignalTrapTest < Minitest::Test
|
|
32
32
|
trap ('SIGINT') { raise Interrupt }
|
33
33
|
end
|
34
34
|
|
35
|
+
# remove [:spin, :oob], [:schedule, :oob], since they are generated inside
|
36
|
+
# the signal handler, which occur while the trace proc is running.
|
37
|
+
events = events.reject do |e|
|
38
|
+
e == [:spin, :oob] || e == [:schedule, :oob]
|
39
|
+
end
|
40
|
+
|
35
41
|
expected = [
|
36
42
|
[:block, :main],
|
37
43
|
[:enter_poll, :main],
|
38
|
-
[:spin, :oob],
|
39
|
-
[:schedule, :oob],
|
40
44
|
[:leave_poll, :main],
|
41
45
|
[:unblock, :oob],
|
42
46
|
[:terminate, :oob],
|
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.
|
4
|
+
version: '0.91'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -305,6 +305,12 @@ files:
|
|
305
305
|
- examples/performance/thread-vs-fiber/threaded_server.rb
|
306
306
|
- examples/performance/thread_pool_perf.rb
|
307
307
|
- examples/performance/thread_switch.rb
|
308
|
+
- examples/pipes/echo_server.rb
|
309
|
+
- examples/pipes/gunzip.rb
|
310
|
+
- examples/pipes/gzip.rb
|
311
|
+
- examples/pipes/gzip_http_server.rb
|
312
|
+
- examples/pipes/tcp_proxy.rb
|
313
|
+
- examples/pipes/tee.rb
|
308
314
|
- ext/libev/Changes
|
309
315
|
- ext/libev/LICENSE
|
310
316
|
- ext/libev/README
|