polyphony 0.91 → 0.92
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/examples/io/splice_echo_server.rb +2 -2
- data/examples/io/tcp_proxy.rb +2 -2
- data/examples/pipes/echo_server.rb +8 -5
- data/examples/pipes/tcp_proxy.rb +23 -11
- data/ext/polyphony/backend_io_uring.c +12 -18
- data/ext/polyphony/backend_libev.c +21 -126
- data/ext/polyphony/polyphony.c +3 -8
- data/ext/polyphony/polyphony.h +1 -2
- data/lib/polyphony/extensions/io.rb +6 -12
- data/lib/polyphony/extensions/pipe.rb +4 -6
- data/lib/polyphony/version.rb +1 -1
- data/test/test_backend.rb +9 -6
- data/test/test_io.rb +8 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73f54eb3c5d34b89d6f24b7e66ba330e6d5345fb94a59f5f6c29efa9d6f6c695
|
4
|
+
data.tar.gz: 03ceb137c92d641d90daea57fc40eeababc86996c0f50df5e4c5246b79e134fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd04383a8ec148ac7c8d79d9d2ba3cd3d53c4eeb459a0bf91d8aa6b5e97523a7a414dac8ca79d81f0182f6be3db741f7eac0d6eb4f9f405f568fea61c0b5ce5e
|
7
|
+
data.tar.gz: bd4fe45c1bc1a014f0c395580f2975e7273f621f43979fa6a59cefd64388ce371631846b29e30589928071532ddebfa5e0c4cbbb9c2fb57bd384648b092d1621
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -7,8 +7,8 @@ require 'polyphony'
|
|
7
7
|
|
8
8
|
def handle_echo_client(conn)
|
9
9
|
buffer = Polyphony.pipe
|
10
|
-
spin { buffer.
|
11
|
-
spin { conn.
|
10
|
+
spin { buffer.splice_from(conn, -1000) }
|
11
|
+
spin { conn.splice_from(buffer, -1000) }
|
12
12
|
end
|
13
13
|
|
14
14
|
puts "Serving echo on port 1234..."
|
data/examples/io/tcp_proxy.rb
CHANGED
@@ -15,7 +15,7 @@ f1 = spin {
|
|
15
15
|
client1 = server1.accept
|
16
16
|
loop do
|
17
17
|
if client2
|
18
|
-
Thread.current.backend.
|
18
|
+
Thread.current.backend.splice(client1, client2, -1000)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
}
|
@@ -24,7 +24,7 @@ f2 = spin {
|
|
24
24
|
client2 = server2.accept
|
25
25
|
loop do
|
26
26
|
if client1
|
27
|
-
Thread.current.backend.
|
27
|
+
Thread.current.backend.splice(client2, client1, -1000)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
}
|
@@ -5,12 +5,15 @@ require 'polyphony'
|
|
5
5
|
|
6
6
|
def handle_client(conn)
|
7
7
|
spin do
|
8
|
-
|
9
|
-
|
10
|
-
IO.
|
8
|
+
IO.double_splice(conn, conn)
|
9
|
+
# buffer = Polyphony.pipe
|
10
|
+
# spin { IO.splice(conn, buffer, -1000) }
|
11
|
+
# IO.splice(buffer, conn, -1000)
|
12
|
+
rescue SystemCallError
|
13
|
+
# ignore
|
14
|
+
ensure
|
15
|
+
conn.close rescue nil
|
11
16
|
end
|
12
|
-
rescue SystemCallError
|
13
|
-
# ignore
|
14
17
|
end
|
15
18
|
|
16
19
|
puts "Serving echo on port 1234..."
|
data/examples/pipes/tcp_proxy.rb
CHANGED
@@ -8,21 +8,33 @@ DESTINATION = ['127.0.0.1', 1234]
|
|
8
8
|
def handle_client(conn)
|
9
9
|
spin do
|
10
10
|
dest = TCPSocket.new(*DESTINATION)
|
11
|
-
w_buffer = Polyphony.pipe
|
12
|
-
r_buffer = Polyphony.pipe
|
11
|
+
# w_buffer = Polyphony.pipe
|
12
|
+
# r_buffer = Polyphony.pipe
|
13
13
|
|
14
|
-
spin { IO.
|
15
|
-
spin { IO.
|
14
|
+
# spin { IO.splice(conn, w_buffer, -1000) }
|
15
|
+
# spin { IO.splice(w_buffer, dest, -1000) }
|
16
16
|
|
17
|
-
spin { IO.
|
18
|
-
spin { IO.
|
17
|
+
# spin { IO.splice(dest, r_buffer, -1000) }
|
18
|
+
# spin { IO.splice(r_buffer, conn, -1000) }
|
19
19
|
|
20
|
-
Fiber.current.await_all_children
|
20
|
+
# Fiber.current.await_all_children
|
21
|
+
|
22
|
+
f = spin do
|
23
|
+
IO.double_splice(conn, dest)
|
24
|
+
raise EOFError
|
25
|
+
end
|
26
|
+
IO.double_splice(dest, conn)
|
27
|
+
f.await
|
28
|
+
rescue EOFError, SystemCallError
|
29
|
+
# ignore
|
30
|
+
ensure
|
31
|
+
conn.close rescue nil
|
32
|
+
dest.close rescue nil
|
21
33
|
end
|
22
|
-
rescue SystemCallError
|
23
|
-
dest.close rescue nil
|
24
|
-
# ignore
|
25
34
|
end
|
26
35
|
|
27
36
|
puts "Serving TCP proxy on port 4321..."
|
28
|
-
TCPServer.new('127.0.0.1', 4321)
|
37
|
+
server = TCPServer.new('127.0.0.1', 4321)
|
38
|
+
while (conn = server.accept)
|
39
|
+
handle_client(conn)
|
40
|
+
end
|
@@ -937,13 +937,15 @@ VALUE Backend_accept_loop(VALUE self, VALUE server_socket, VALUE socket_class) {
|
|
937
937
|
return self;
|
938
938
|
}
|
939
939
|
|
940
|
-
VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest,
|
940
|
+
VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest, int maxlen) {
|
941
941
|
int src_fd;
|
942
942
|
int dest_fd;
|
943
943
|
rb_io_t *src_fptr;
|
944
944
|
rb_io_t *dest_fptr;
|
945
945
|
int total = 0;
|
946
946
|
VALUE resume_value = Qnil;
|
947
|
+
int splice_to_eof = maxlen < 0;
|
948
|
+
if (splice_to_eof) maxlen = -maxlen;
|
947
949
|
|
948
950
|
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
949
951
|
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
@@ -954,7 +956,7 @@ VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest, VALUE m
|
|
954
956
|
int result;
|
955
957
|
int completed;
|
956
958
|
|
957
|
-
io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1,
|
959
|
+
io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1, maxlen, 0);
|
958
960
|
|
959
961
|
result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
|
960
962
|
completed = context_store_release(&backend->store, ctx);
|
@@ -965,7 +967,7 @@ VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest, VALUE m
|
|
965
967
|
rb_syserr_fail(-result, strerror(-result));
|
966
968
|
|
967
969
|
total += result;
|
968
|
-
if (result
|
970
|
+
if (!result || !splice_to_eof) return INT2FIX(total);
|
969
971
|
}
|
970
972
|
|
971
973
|
RB_GC_GUARD(resume_value);
|
@@ -974,14 +976,7 @@ VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest, VALUE m
|
|
974
976
|
VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
975
977
|
Backend_t *backend;
|
976
978
|
GetBackend(self, backend);
|
977
|
-
return io_uring_backend_splice(backend, src, dest, maxlen
|
978
|
-
}
|
979
|
-
|
980
|
-
VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize) {
|
981
|
-
Backend_t *backend;
|
982
|
-
GetBackend(self, backend);
|
983
|
-
|
984
|
-
return io_uring_backend_splice(backend, src, dest, chunksize, 1);
|
979
|
+
return io_uring_backend_splice(backend, src, dest, FIX2INT(maxlen));
|
985
980
|
}
|
986
981
|
|
987
982
|
struct double_splice_ctx {
|
@@ -1011,7 +1006,7 @@ static inline void io_uring_backend_cancel(Backend_t *backend, op_context_t *ctx
|
|
1011
1006
|
io_uring_prep_cancel(sqe, (__u64)ctx, 0);
|
1012
1007
|
}
|
1013
1008
|
|
1014
|
-
VALUE
|
1009
|
+
VALUE double_splice_safe(struct double_splice_ctx *ctx) {
|
1015
1010
|
int src_fd;
|
1016
1011
|
int dest_fd;
|
1017
1012
|
rb_io_t *src_fptr;
|
@@ -1073,20 +1068,20 @@ VALUE double_splice_to_eof_safe(struct double_splice_ctx *ctx) {
|
|
1073
1068
|
return INT2FIX(total);
|
1074
1069
|
}
|
1075
1070
|
|
1076
|
-
VALUE
|
1071
|
+
VALUE double_splice_cleanup(struct double_splice_ctx *ctx) {
|
1077
1072
|
if (ctx->pipefd[0]) close(ctx->pipefd[0]);
|
1078
1073
|
if (ctx->pipefd[1]) close(ctx->pipefd[1]);
|
1079
1074
|
return Qnil;
|
1080
1075
|
}
|
1081
1076
|
|
1082
|
-
VALUE
|
1077
|
+
VALUE Backend_double_splice(VALUE self, VALUE src, VALUE dest) {
|
1083
1078
|
struct double_splice_ctx ctx = { NULL, src, dest, 0, 0 };
|
1084
1079
|
GetBackend(self, ctx.backend);
|
1085
1080
|
if (pipe(ctx.pipefd) == -1) rb_syserr_fail(errno, strerror(errno));
|
1086
1081
|
|
1087
1082
|
return rb_ensure(
|
1088
|
-
SAFE(
|
1089
|
-
SAFE(
|
1083
|
+
SAFE(double_splice_safe), (VALUE)&ctx,
|
1084
|
+
SAFE(double_splice_cleanup), (VALUE)&ctx
|
1090
1085
|
);
|
1091
1086
|
}
|
1092
1087
|
|
@@ -1801,8 +1796,7 @@ void Init_Backend() {
|
|
1801
1796
|
rb_define_method(cBackend, "sleep", Backend_sleep, 1);
|
1802
1797
|
|
1803
1798
|
rb_define_method(cBackend, "splice", Backend_splice, 3);
|
1804
|
-
rb_define_method(cBackend, "
|
1805
|
-
rb_define_method(cBackend, "double_splice_to_eof", Backend_double_splice_to_eof, 2);
|
1799
|
+
rb_define_method(cBackend, "double_splice", Backend_double_splice, 2);
|
1806
1800
|
rb_define_method(cBackend, "tee", Backend_tee, 3);
|
1807
1801
|
|
1808
1802
|
rb_define_method(cBackend, "timeout", Backend_timeout, -1);
|
@@ -860,50 +860,10 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
860
860
|
rb_io_t *src_fptr;
|
861
861
|
rb_io_t *dest_fptr;
|
862
862
|
int len;
|
863
|
-
|
864
|
-
GetBackend(self, backend);
|
865
|
-
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
866
|
-
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
867
|
-
watcher.ctx.fiber = Qnil;
|
868
|
-
|
869
|
-
while (1) {
|
870
|
-
backend->base.op_count++;
|
871
|
-
len = splice(src_fd, 0, dest_fd, 0, FIX2INT(maxlen), 0);
|
872
|
-
if (len < 0) {
|
873
|
-
int e = errno;
|
874
|
-
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
875
|
-
|
876
|
-
switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fd, dest_fd, &watcher);
|
877
|
-
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
878
|
-
}
|
879
|
-
else {
|
880
|
-
break;
|
881
|
-
}
|
882
|
-
}
|
883
|
-
|
884
|
-
if (watcher.ctx.fiber == Qnil) {
|
885
|
-
switchpoint_result = backend_snooze(&backend->base);
|
886
|
-
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
887
|
-
}
|
888
|
-
|
889
|
-
RB_GC_GUARD(watcher.ctx.fiber);
|
890
|
-
RB_GC_GUARD(switchpoint_result);
|
891
|
-
|
892
|
-
return INT2FIX(len);
|
893
|
-
error:
|
894
|
-
return RAISE_EXCEPTION(switchpoint_result);
|
895
|
-
}
|
896
|
-
|
897
|
-
VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
898
|
-
Backend_t *backend;
|
899
|
-
struct libev_rw_io watcher;
|
900
|
-
VALUE switchpoint_result = Qnil;
|
901
|
-
int src_fd;
|
902
|
-
int dest_fd;
|
903
|
-
rb_io_t *src_fptr;
|
904
|
-
rb_io_t *dest_fptr;
|
905
|
-
int len;
|
906
863
|
int total = 0;
|
864
|
+
int maxlen_i = FIX2INT(maxlen);
|
865
|
+
int splice_to_eof = maxlen_i < 0;
|
866
|
+
if (splice_to_eof) maxlen_i = -maxlen_i;
|
907
867
|
|
908
868
|
GetBackend(self, backend);
|
909
869
|
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
@@ -912,7 +872,7 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
912
872
|
|
913
873
|
while (1) {
|
914
874
|
backend->base.op_count++;
|
915
|
-
len = splice(src_fd, 0, dest_fd, 0,
|
875
|
+
len = splice(src_fd, 0, dest_fd, 0, maxlen_i, 0);
|
916
876
|
if (len < 0) {
|
917
877
|
int e = errno;
|
918
878
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
@@ -920,11 +880,9 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
920
880
|
switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fd, dest_fd, &watcher);
|
921
881
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
922
882
|
}
|
923
|
-
else if (len == 0) {
|
924
|
-
break;
|
925
|
-
}
|
926
883
|
else {
|
927
884
|
total += len;
|
885
|
+
if (!len || !splice_to_eof) break;
|
928
886
|
}
|
929
887
|
}
|
930
888
|
|
@@ -983,9 +941,7 @@ VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
983
941
|
error:
|
984
942
|
return RAISE_EXCEPTION(switchpoint_result);
|
985
943
|
}
|
986
|
-
|
987
944
|
#else
|
988
|
-
|
989
945
|
VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
990
946
|
Backend_t *backend;
|
991
947
|
struct libev_io watcher;
|
@@ -994,77 +950,13 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
994
950
|
int dest_fd;
|
995
951
|
rb_io_t *src_fptr;
|
996
952
|
rb_io_t *dest_fptr;
|
997
|
-
int len = FIX2INT(maxlen);
|
998
|
-
VALUE str = rb_str_new(0, len);
|
999
|
-
char *buf = RSTRING_PTR(str);
|
1000
953
|
int left = 0;
|
1001
954
|
int total = 0;
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
watcher.fiber = Qnil;
|
1007
|
-
|
1008
|
-
while (1) {
|
1009
|
-
backend->base.op_count++;
|
1010
|
-
ssize_t n = read(src_fd, buf, len);
|
1011
|
-
if (n < 0) {
|
1012
|
-
int e = errno;
|
1013
|
-
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1014
|
-
|
1015
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend, src_fd, &watcher, EV_READ);
|
1016
|
-
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1017
|
-
}
|
1018
|
-
else {
|
1019
|
-
total = left = n;
|
1020
|
-
break;
|
1021
|
-
}
|
1022
|
-
}
|
1023
|
-
|
1024
|
-
while (left > 0) {
|
1025
|
-
backend->base.op_count++;
|
1026
|
-
ssize_t n = write(dest_fd, buf, left);
|
1027
|
-
if (n < 0) {
|
1028
|
-
int e = errno;
|
1029
|
-
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1030
|
-
|
1031
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fd, &watcher, EV_WRITE);
|
1032
|
-
|
1033
|
-
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1034
|
-
}
|
1035
|
-
else {
|
1036
|
-
buf += n;
|
1037
|
-
left -= n;
|
1038
|
-
}
|
1039
|
-
}
|
1040
|
-
|
1041
|
-
if (watcher.fiber == Qnil) {
|
1042
|
-
switchpoint_result = backend_snooze(&backend->base);
|
1043
|
-
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1044
|
-
}
|
1045
|
-
|
1046
|
-
RB_GC_GUARD(watcher.fiber);
|
1047
|
-
RB_GC_GUARD(switchpoint_result);
|
1048
|
-
RB_GC_GUARD(str);
|
1049
|
-
|
1050
|
-
return INT2FIX(total);
|
1051
|
-
error:
|
1052
|
-
return RAISE_EXCEPTION(switchpoint_result);
|
1053
|
-
}
|
1054
|
-
|
1055
|
-
VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
1056
|
-
Backend_t *backend;
|
1057
|
-
struct libev_io watcher;
|
1058
|
-
VALUE switchpoint_result = Qnil;
|
1059
|
-
int src_fd;
|
1060
|
-
int dest_fd;
|
1061
|
-
rb_io_t *src_fptr;
|
1062
|
-
rb_io_t *dest_fptr;
|
1063
|
-
int len = FIX2INT(maxlen);
|
1064
|
-
VALUE str = rb_str_new(0, len);
|
955
|
+
int maxlen_i = FIX2INT(maxlen);
|
956
|
+
int splice_to_eof = maxlen_i < 0;
|
957
|
+
if (splice_to_eof) maxlen_i = -maxlen_i;
|
958
|
+
VALUE str = rb_str_new(0, maxlen_i);
|
1065
959
|
char *buf = RSTRING_PTR(str);
|
1066
|
-
int left = 0;
|
1067
|
-
int total = 0;
|
1068
960
|
|
1069
961
|
GetBackend(self, backend);
|
1070
962
|
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
@@ -1072,10 +964,10 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1072
964
|
watcher.fiber = Qnil;
|
1073
965
|
|
1074
966
|
while (1) {
|
1075
|
-
|
967
|
+
int done;
|
1076
968
|
while (1) {
|
1077
969
|
backend->base.op_count++;
|
1078
|
-
ssize_t n = read(src_fd,
|
970
|
+
ssize_t n = read(src_fd, buf, maxlen_i);
|
1079
971
|
if (n < 0) {
|
1080
972
|
int e = errno;
|
1081
973
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
@@ -1083,32 +975,32 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1083
975
|
switchpoint_result = libev_wait_fd_with_watcher(backend, src_fd, &watcher, EV_READ);
|
1084
976
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1085
977
|
}
|
1086
|
-
else if (n == 0) goto done;
|
1087
978
|
else {
|
1088
|
-
total += n;
|
1089
|
-
|
979
|
+
total += left = n;
|
980
|
+
done = !n || !splice_to_eof;
|
1090
981
|
break;
|
1091
982
|
}
|
1092
983
|
}
|
1093
984
|
|
1094
985
|
while (left > 0) {
|
1095
986
|
backend->base.op_count++;
|
1096
|
-
ssize_t n = write(dest_fd,
|
987
|
+
ssize_t n = write(dest_fd, buf, left);
|
1097
988
|
if (n < 0) {
|
1098
989
|
int e = errno;
|
1099
990
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1100
991
|
|
1101
992
|
switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fd, &watcher, EV_WRITE);
|
993
|
+
|
1102
994
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1103
995
|
}
|
1104
996
|
else {
|
1105
|
-
|
997
|
+
buf += n;
|
1106
998
|
left -= n;
|
1107
999
|
}
|
1108
1000
|
}
|
1001
|
+
if (done) break;
|
1109
1002
|
}
|
1110
1003
|
|
1111
|
-
done:
|
1112
1004
|
if (watcher.fiber == Qnil) {
|
1113
1005
|
switchpoint_result = backend_snooze(&backend->base);
|
1114
1006
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
@@ -1122,6 +1014,10 @@ done:
|
|
1122
1014
|
error:
|
1123
1015
|
return RAISE_EXCEPTION(switchpoint_result);
|
1124
1016
|
}
|
1017
|
+
|
1018
|
+
VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
1019
|
+
return self;
|
1020
|
+
}
|
1125
1021
|
#endif
|
1126
1022
|
|
1127
1023
|
VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write) {
|
@@ -1644,7 +1540,6 @@ void Init_Backend() {
|
|
1644
1540
|
rb_define_method(cBackend, "sleep", Backend_sleep, 1);
|
1645
1541
|
|
1646
1542
|
rb_define_method(cBackend, "splice", Backend_splice, 3);
|
1647
|
-
rb_define_method(cBackend, "splice_to_eof", Backend_splice_to_eof, 3);
|
1648
1543
|
#ifdef POLYPHONY_LINUX
|
1649
1544
|
rb_define_method(cBackend, "tee", Backend_tee, 3);
|
1650
1545
|
#endif
|
data/ext/polyphony/polyphony.c
CHANGED
@@ -90,13 +90,9 @@ VALUE Polyphony_backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen)
|
|
90
90
|
return Backend_splice(BACKEND(), src, dest, maxlen);
|
91
91
|
}
|
92
92
|
|
93
|
-
VALUE Polyphony_backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize) {
|
94
|
-
return Backend_splice_to_eof(BACKEND(), src, dest, chunksize);
|
95
|
-
}
|
96
|
-
|
97
93
|
#ifdef POLYPHONY_BACKEND_LIBURING
|
98
|
-
VALUE
|
99
|
-
return
|
94
|
+
VALUE Polyphony_backend_double_splice(VALUE self, VALUE src, VALUE dest) {
|
95
|
+
return Backend_double_splice(BACKEND(), src, dest);
|
100
96
|
}
|
101
97
|
#endif
|
102
98
|
|
@@ -191,10 +187,9 @@ void Init_Polyphony() {
|
|
191
187
|
rb_define_singleton_method(mPolyphony, "backend_sendv", Polyphony_backend_sendv, 3);
|
192
188
|
rb_define_singleton_method(mPolyphony, "backend_sleep", Polyphony_backend_sleep, 1);
|
193
189
|
rb_define_singleton_method(mPolyphony, "backend_splice", Polyphony_backend_splice, 3);
|
194
|
-
rb_define_singleton_method(mPolyphony, "backend_splice_to_eof", Polyphony_backend_splice_to_eof, 3);
|
195
190
|
|
196
191
|
#ifdef POLYPHONY_BACKEND_LIBURING
|
197
|
-
rb_define_singleton_method(mPolyphony, "
|
192
|
+
rb_define_singleton_method(mPolyphony, "backend_double_splice", Polyphony_backend_double_splice, 2);
|
198
193
|
#endif
|
199
194
|
|
200
195
|
#ifdef POLYPHONY_LINUX
|
data/ext/polyphony/polyphony.h
CHANGED
@@ -115,10 +115,9 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE msg, VALUE flags);
|
|
115
115
|
VALUE Backend_sendv(VALUE self, VALUE io, VALUE ary, VALUE flags);
|
116
116
|
VALUE Backend_sleep(VALUE self, VALUE duration);
|
117
117
|
VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen);
|
118
|
-
VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize);
|
119
118
|
|
120
119
|
#ifdef POLYPHONY_BACKEND_LIBURING
|
121
|
-
VALUE
|
120
|
+
VALUE Backend_double_splice(VALUE self, VALUE src, VALUE dest);
|
122
121
|
#endif
|
123
122
|
|
124
123
|
#ifdef POLYPHONY_LINUX
|
@@ -78,13 +78,9 @@ class ::IO
|
|
78
78
|
Polyphony.backend_splice(src, dest, maxlen)
|
79
79
|
end
|
80
80
|
|
81
|
-
def splice_to_eof(src, dest, chunk_size = 8192)
|
82
|
-
Polyphony.backend_splice_to_eof(src, dest, chunk_size)
|
83
|
-
end
|
84
|
-
|
85
81
|
if RUBY_PLATFORM =~ /linux/
|
86
|
-
def
|
87
|
-
Polyphony.
|
82
|
+
def double_splice(src, dest)
|
83
|
+
Polyphony.backend_double_splice(src, dest)
|
88
84
|
end
|
89
85
|
|
90
86
|
def tee(src, dest, maxlen)
|
@@ -283,11 +279,9 @@ class ::IO
|
|
283
279
|
Polyphony.backend_splice(src, self, maxlen)
|
284
280
|
end
|
285
281
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
def tee_from(src, maxlen)
|
291
|
-
Polyphony.backend_tee(src, self, maxlen)
|
282
|
+
if RUBY_PLATFORM =~ /linux/
|
283
|
+
def tee_from(src, maxlen)
|
284
|
+
Polyphony.backend_tee(src, self, maxlen)
|
285
|
+
end
|
292
286
|
end
|
293
287
|
end
|
@@ -165,11 +165,9 @@ class Polyphony::Pipe
|
|
165
165
|
Polyphony.backend_splice(src, self, maxlen)
|
166
166
|
end
|
167
167
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
def tee_from(src, maxlen)
|
173
|
-
Polyphony.backend_tee(src, self, maxlen)
|
168
|
+
if RUBY_PLATFORM =~ /linux/
|
169
|
+
def tee_from(src, maxlen)
|
170
|
+
Polyphony.backend_tee(src, self, maxlen)
|
171
|
+
end
|
174
172
|
end
|
175
173
|
end
|
data/lib/polyphony/version.rb
CHANGED
data/test/test_backend.rb
CHANGED
@@ -191,8 +191,10 @@ class BackendTest < MiniTest::Test
|
|
191
191
|
Net = Polyphony::Net
|
192
192
|
|
193
193
|
def test_accept
|
194
|
+
port = rand(1234..4321)
|
195
|
+
|
194
196
|
server = Net.send(
|
195
|
-
:listening_socket_from_options, '127.0.0.1',
|
197
|
+
:listening_socket_from_options, '127.0.0.1', port, reuse_addr: true
|
196
198
|
)
|
197
199
|
|
198
200
|
clients = []
|
@@ -201,12 +203,12 @@ class BackendTest < MiniTest::Test
|
|
201
203
|
clients << c
|
202
204
|
end
|
203
205
|
|
204
|
-
c1 = TCPSocket.new('127.0.0.1',
|
206
|
+
c1 = TCPSocket.new('127.0.0.1', port)
|
205
207
|
sleep 0.01
|
206
208
|
|
207
209
|
assert_equal 1, clients.size
|
208
210
|
|
209
|
-
c2 = TCPSocket.new('127.0.0.1',
|
211
|
+
c2 = TCPSocket.new('127.0.0.1', port)
|
210
212
|
sleep 0.01
|
211
213
|
|
212
214
|
assert_equal 2, clients.size
|
@@ -220,8 +222,9 @@ class BackendTest < MiniTest::Test
|
|
220
222
|
end
|
221
223
|
|
222
224
|
def test_accept_loop
|
225
|
+
port = rand(1234..4321)
|
223
226
|
server = Net.send(
|
224
|
-
:listening_socket_from_options, '127.0.0.1',
|
227
|
+
:listening_socket_from_options, '127.0.0.1', port, reuse_addr: true
|
225
228
|
)
|
226
229
|
|
227
230
|
clients = []
|
@@ -229,12 +232,12 @@ class BackendTest < MiniTest::Test
|
|
229
232
|
@backend.accept_loop(server, TCPSocket) { |c| clients << c }
|
230
233
|
end
|
231
234
|
|
232
|
-
c1 = TCPSocket.new('127.0.0.1',
|
235
|
+
c1 = TCPSocket.new('127.0.0.1', port)
|
233
236
|
sleep 0.01
|
234
237
|
|
235
238
|
assert_equal 1, clients.size
|
236
239
|
|
237
|
-
c2 = TCPSocket.new('127.0.0.1',
|
240
|
+
c2 = TCPSocket.new('127.0.0.1', port)
|
238
241
|
sleep 0.01
|
239
242
|
|
240
243
|
assert_equal 2, clients.size
|
data/test/test_io.rb
CHANGED
@@ -314,13 +314,13 @@ class IOTest < MiniTest::Test
|
|
314
314
|
assert_equal 6, len
|
315
315
|
end
|
316
316
|
|
317
|
-
def
|
317
|
+
def test_splice_from_to_eof
|
318
318
|
i1, o1 = IO.pipe
|
319
319
|
i2, o2 = IO.pipe
|
320
320
|
len = nil
|
321
321
|
|
322
322
|
f = spin {
|
323
|
-
len = o2.
|
323
|
+
len = o2.splice_from(i1, -1000)
|
324
324
|
o2.close
|
325
325
|
}
|
326
326
|
|
@@ -341,13 +341,13 @@ class IOTest < MiniTest::Test
|
|
341
341
|
end
|
342
342
|
end
|
343
343
|
|
344
|
-
def
|
344
|
+
def test_splice_class_method_to_eof
|
345
345
|
i1, o1 = IO.pipe
|
346
346
|
i2, o2 = IO.pipe
|
347
347
|
len = nil
|
348
348
|
|
349
349
|
f = spin {
|
350
|
-
len = IO.
|
350
|
+
len = IO.splice(i1, o2, -1000)
|
351
351
|
o2.close
|
352
352
|
}
|
353
353
|
|
@@ -368,9 +368,9 @@ class IOTest < MiniTest::Test
|
|
368
368
|
end
|
369
369
|
end
|
370
370
|
|
371
|
-
def
|
372
|
-
if Thread.current.backend.kind
|
373
|
-
skip "IO.
|
371
|
+
def test_double_splice
|
372
|
+
if Thread.current.backend.kind != :io_uring
|
373
|
+
skip "IO.double_splice available only on io_uring backend"
|
374
374
|
end
|
375
375
|
|
376
376
|
src = Polyphony.pipe
|
@@ -379,7 +379,7 @@ class IOTest < MiniTest::Test
|
|
379
379
|
data = 'foobar' * 10
|
380
380
|
|
381
381
|
f1 = spin {
|
382
|
-
ret = IO.
|
382
|
+
ret = IO.double_splice(src, dest)
|
383
383
|
dest.close
|
384
384
|
}
|
385
385
|
|
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.92'
|
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-
|
11
|
+
date: 2022-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|