uringmachine 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/TODO.md +6 -16
- data/ext/um/um.c +80 -0
- data/ext/um/um.h +6 -1
- data/ext/um/um_class.c +219 -81
- data/ext/um/um_op.c +3 -1
- data/ext/um/um_stream.c +11 -0
- data/ext/um/um_stream_class.c +9 -0
- data/grant-2025/tasks.md +3 -16
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +5 -0
- data/test/test_async_op.rb +1 -1
- data/test/test_stream.rb +17 -0
- data/test/test_um.rb +315 -33
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c42e434298bf496752efc6fe6a4cc81d04857f28f1151cfc3165ac3c288ec6a2
|
|
4
|
+
data.tar.gz: ec176b165f129aa7d1b6d0bdbc5f4b7e55d5e553569061d89956d0b1aee68503
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1760b892d6ae21c7007fd0a109a78d631da4ae9a79667ad85bc4740ac0e339802ca9cb0bc34114570bf7e6113e4dab704a1c9f40513a196e840b759a494a35b9
|
|
7
|
+
data.tar.gz: 7dfe1426f96ecd1e99af4224c34d3b3173858b5d6c156b949314a0e80c34b836ae738e930ed26662319bc6700401cd0b369028e172ed1b70982cee64fb13f7a1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# 0.28.0 2026-02-19
|
|
2
|
+
|
|
3
|
+
- Add `#terminate`
|
|
4
|
+
- Make `#sendv` available also for older kernels (using `#writev`)
|
|
5
|
+
- Implement `Stream#skip`
|
|
6
|
+
- Inherit exceptions from `StandardError` instead of `RuntimeError`
|
|
7
|
+
|
|
8
|
+
# 0.27.0 2026-02-15
|
|
9
|
+
|
|
10
|
+
- Add `.pr_set_child_subreaper` method
|
|
11
|
+
- Add `#send_fd`, `#recv_fd` methods
|
|
12
|
+
|
|
1
13
|
# 0.26.0 2026-02-13
|
|
2
14
|
|
|
3
15
|
- Reimplement um_op lifecycle tracking
|
data/TODO.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
## immediate
|
|
2
2
|
|
|
3
|
-
-
|
|
3
|
+
- Add tests for support for Set in `machine#await_fibers`
|
|
4
|
+
- Add tests for support for Set, Array in `machine#join`
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
- (?) Fix all futex value (Queue, Mutex) to be properly aligned
|
|
6
7
|
|
|
8
|
+
## Buffer rings - automatic management
|
|
7
9
|
- Take the buffer_pool branch, rewrite it
|
|
8
10
|
- Allow multiple stream modes:
|
|
9
11
|
- :buffer_pool - uses buffer rings
|
|
@@ -64,19 +66,6 @@ stream = UM::Stream.new(conn) # io mode
|
|
|
64
66
|
- select on multiple queues (ala Go)
|
|
65
67
|
- select on mixture of queues and fds
|
|
66
68
|
|
|
67
|
-
(see also simplified op management below)
|
|
68
|
-
|
|
69
|
-
## simplified op management
|
|
70
|
-
|
|
71
|
-
Op lifecycle management can be much much simpler
|
|
72
|
-
|
|
73
|
-
- make all ops heap-allocated
|
|
74
|
-
- clear up state transitions:
|
|
75
|
-
|
|
76
|
-
- kernel-side state: unsubmitted, submitted, completed, done (for multishot ops)
|
|
77
|
-
- app-side state: unsubmitted, submitted, ...
|
|
78
|
-
|
|
79
|
-
|
|
80
69
|
## ops
|
|
81
70
|
|
|
82
71
|
- splice / - tee
|
|
@@ -104,7 +93,8 @@ We're still missing:
|
|
|
104
93
|
- ability to supply buffer to `get_line` and `get_string`
|
|
105
94
|
- allow read to eof, maybe with `read_to_eof`
|
|
106
95
|
|
|
107
|
-
For the sake of performance, simplicity and explicitness, we change the API as
|
|
96
|
+
For the sake of performance, simplicity and explicitness, we change the API as
|
|
97
|
+
follows:
|
|
108
98
|
|
|
109
99
|
```ruby
|
|
110
100
|
stream.get_line(buf, limit)
|
data/ext/um/um.c
CHANGED
|
@@ -977,6 +977,86 @@ VALUE um_shutdown_async(struct um *machine, int fd, int how) {
|
|
|
977
977
|
return INT2NUM(fd);
|
|
978
978
|
}
|
|
979
979
|
|
|
980
|
+
struct send_recv_fd_ctx {
|
|
981
|
+
struct msghdr msgh;
|
|
982
|
+
char iobuf[1];
|
|
983
|
+
struct iovec iov;
|
|
984
|
+
union { // Ancillary data buffer, wrapped in a union for alignment
|
|
985
|
+
char buf[CMSG_SPACE(sizeof(int))];
|
|
986
|
+
struct cmsghdr align;
|
|
987
|
+
} u;
|
|
988
|
+
};
|
|
989
|
+
|
|
990
|
+
inline void send_recv_fd_setup_ctx(struct send_recv_fd_ctx *ctx, int fd) {
|
|
991
|
+
ctx->iov.iov_base = ctx->iobuf;
|
|
992
|
+
ctx->iov.iov_len = sizeof(ctx->iobuf);
|
|
993
|
+
|
|
994
|
+
memset(&ctx->msgh, 0, sizeof(ctx->msgh));
|
|
995
|
+
ctx->msgh.msg_iov = &ctx->iov;
|
|
996
|
+
ctx->msgh.msg_iovlen = 1;
|
|
997
|
+
ctx->msgh.msg_control = ctx->u.buf;
|
|
998
|
+
ctx->msgh.msg_controllen = sizeof(ctx->u.buf);
|
|
999
|
+
|
|
1000
|
+
if (fd > 0) {
|
|
1001
|
+
struct cmsghdr *cmsgp = CMSG_FIRSTHDR(&ctx->msgh);
|
|
1002
|
+
cmsgp->cmsg_level = SOL_SOCKET;
|
|
1003
|
+
cmsgp->cmsg_type = SCM_RIGHTS;
|
|
1004
|
+
cmsgp->cmsg_len = CMSG_LEN(sizeof(fd));
|
|
1005
|
+
memcpy(CMSG_DATA(cmsgp), &fd, sizeof(fd));
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
VALUE um_send_fd(struct um *machine, int sock_fd, int fd) {
|
|
1010
|
+
struct send_recv_fd_ctx ctx;
|
|
1011
|
+
send_recv_fd_setup_ctx(&ctx, fd);
|
|
1012
|
+
|
|
1013
|
+
VALUE ret = Qnil;
|
|
1014
|
+
struct um_op *op = um_op_acquire(machine);
|
|
1015
|
+
um_prep_op(machine, op, OP_SENDMSG, 2, 0);
|
|
1016
|
+
struct io_uring_sqe *sqe = um_get_sqe(machine, op);
|
|
1017
|
+
io_uring_prep_sendmsg(sqe, sock_fd, &ctx.msgh, 0);
|
|
1018
|
+
|
|
1019
|
+
ret = um_yield(machine);
|
|
1020
|
+
|
|
1021
|
+
if (likely(um_verify_op_completion(machine, op, true))) ret = INT2NUM(fd);
|
|
1022
|
+
um_op_release(machine, op);
|
|
1023
|
+
|
|
1024
|
+
RAISE_IF_EXCEPTION(ret);
|
|
1025
|
+
RB_GC_GUARD(ret);
|
|
1026
|
+
return ret;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
inline int recv_fd_get_fd(struct send_recv_fd_ctx *ctx) {
|
|
1030
|
+
int fd;
|
|
1031
|
+
struct cmsghdr *cmsgp = CMSG_FIRSTHDR(&ctx->msgh);
|
|
1032
|
+
|
|
1033
|
+
if (cmsgp == NULL || cmsgp->cmsg_len != CMSG_LEN(sizeof(int)) ||
|
|
1034
|
+
cmsgp->cmsg_level != SOL_SOCKET || cmsgp->cmsg_type != SCM_RIGHTS
|
|
1035
|
+
) um_raise_on_error_result(-EINVAL);
|
|
1036
|
+
|
|
1037
|
+
memcpy(&fd, CMSG_DATA(cmsgp), sizeof(int));
|
|
1038
|
+
return fd;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
VALUE um_recv_fd(struct um *machine, int sock_fd) {
|
|
1042
|
+
struct send_recv_fd_ctx ctx;
|
|
1043
|
+
send_recv_fd_setup_ctx(&ctx, -1);
|
|
1044
|
+
|
|
1045
|
+
struct um_op *op = um_op_acquire(machine);
|
|
1046
|
+
um_prep_op(machine, op, OP_RECVMSG, 2, 0);
|
|
1047
|
+
struct io_uring_sqe *sqe = um_get_sqe(machine, op);
|
|
1048
|
+
io_uring_prep_recvmsg(sqe, sock_fd, &ctx.msgh, 0);
|
|
1049
|
+
|
|
1050
|
+
VALUE ret = um_yield(machine);
|
|
1051
|
+
|
|
1052
|
+
if (likely(um_verify_op_completion(machine, op, true))) ret = INT2NUM(recv_fd_get_fd(&ctx));
|
|
1053
|
+
um_op_release(machine, op);
|
|
1054
|
+
|
|
1055
|
+
RAISE_IF_EXCEPTION(ret);
|
|
1056
|
+
RB_GC_GUARD(ret);
|
|
1057
|
+
return ret;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
980
1060
|
VALUE um_open(struct um *machine, VALUE pathname, int flags, int mode) {
|
|
981
1061
|
struct um_op *op = um_op_acquire(machine);
|
|
982
1062
|
um_prep_op(machine, op, OP_OPEN, 2, 0);
|
data/ext/um/um.h
CHANGED
|
@@ -51,9 +51,11 @@ enum um_op_kind {
|
|
|
51
51
|
|
|
52
52
|
OP_ACCEPT,
|
|
53
53
|
OP_RECV,
|
|
54
|
+
OP_RECVMSG,
|
|
54
55
|
OP_SEND,
|
|
55
|
-
OP_SENDV,
|
|
56
56
|
OP_SEND_BUNDLE,
|
|
57
|
+
OP_SENDMSG,
|
|
58
|
+
OP_SENDV,
|
|
57
59
|
OP_SOCKET,
|
|
58
60
|
OP_CONNECT,
|
|
59
61
|
OP_BIND,
|
|
@@ -349,6 +351,8 @@ VALUE um_getsockopt(struct um *machine, int fd, int level, int opt);
|
|
|
349
351
|
VALUE um_setsockopt(struct um *machine, int fd, int level, int opt, int value);
|
|
350
352
|
VALUE um_shutdown(struct um *machine, int fd, int how);
|
|
351
353
|
VALUE um_shutdown_async(struct um *machine, int fd, int how);
|
|
354
|
+
VALUE um_send_fd(struct um *machine, int sock_fd, int fd);
|
|
355
|
+
VALUE um_recv_fd(struct um *machine, int sock_fd);
|
|
352
356
|
|
|
353
357
|
void um_async_op_set(VALUE self, struct um *machine, struct um_op *op);
|
|
354
358
|
VALUE um_async_op_await(struct um_async_op *async_op);
|
|
@@ -373,6 +377,7 @@ VALUE um_queue_shift(struct um *machine, struct um_queue *queue);
|
|
|
373
377
|
|
|
374
378
|
VALUE stream_get_line(struct um_stream *stream, VALUE buf, ssize_t maxlen);
|
|
375
379
|
VALUE stream_get_string(struct um_stream *stream, VALUE buf, ssize_t len);
|
|
380
|
+
VALUE stream_skip(struct um_stream *stream, size_t len);
|
|
376
381
|
VALUE resp_decode(struct um_stream *stream, VALUE out_buffer);
|
|
377
382
|
void resp_encode(struct um_write_buffer *buf, VALUE obj);
|
|
378
383
|
void resp_encode_cmd(struct um_write_buffer *buf, int argc, VALUE *argv);
|