uringmachine 0.31.0 → 0.33.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.
@@ -12,8 +12,8 @@ require 'uringmachine'
12
12
  RE_REQUEST_LINE = /^([a-z]+)\s+([^\s]+)\s+(http\/[0-9\.]{1,3})/i
13
13
  RE_HEADER_LINE = /^([a-z0-9\-]+)\:\s+(.+)/i
14
14
 
15
- def connection_get_request_line(conn, buf)
16
- line = conn.read_line(0)
15
+ def io_get_request_line(io, buf)
16
+ line = io.read_line(0)
17
17
  m = line&.match(RE_REQUEST_LINE)
18
18
  return nil if !m
19
19
 
@@ -26,12 +26,12 @@ end
26
26
 
27
27
  class InvalidHeadersError < StandardError; end
28
28
 
29
- def get_headers(conn, buf)
30
- headers = connection_get_request_line(conn, buf)
29
+ def get_headers(io, buf)
30
+ headers = io_get_request_line(io, buf)
31
31
  return nil if !headers
32
32
 
33
33
  while true
34
- line = conn.read_line(0)
34
+ line = io.read_line(0)
35
35
  break if line.empty?
36
36
 
37
37
  m = line.match(RE_HEADER_LINE)
@@ -52,11 +52,11 @@ end
52
52
 
53
53
  def handle_connection(machine, fd)
54
54
  machine.setsockopt(fd, UM::IPPROTO_TCP, UM::TCP_NODELAY, true)
55
- conn = UM::Connection.new(machine, fd)
55
+ io = UM::IO.new(machine, fd)
56
56
  buf = String.new(capacity: 65536)
57
57
 
58
58
  while true
59
- headers = get_headers(conn, buf)
59
+ headers = get_headers(io, buf)
60
60
  break if !headers
61
61
 
62
62
  send_response(machine, fd)
@@ -77,4 +77,4 @@ machine.bind(fd, '127.0.0.1', PORT)
77
77
  machine.listen(fd, 128)
78
78
 
79
79
  puts "Listening on localhost:#{PORT}"
80
- machine.accept_each(fd) { |conn| machine.spin { handle_connection(machine, conn) } }
80
+ machine.accept_each(fd) { | io| machine.spin { handle_connection(machine, io) } }
data/benchmark/openssl.rb CHANGED
@@ -81,7 +81,7 @@ end
81
81
  @um.ssl_set_bio(@ssl_conn)
82
82
  @ssl_conn.connect
83
83
 
84
- @conn = @um.connection(@ssl_conn, :ssl)
84
+ @io = @um.io(@ssl_conn)
85
85
 
86
86
  @msg = 'abc' * 1000
87
87
  @msg_newline = @msg + "\n"
@@ -91,15 +91,15 @@ def do_io(ssl)
91
91
  ssl.gets
92
92
  end
93
93
 
94
- def do_io_connection(ssl, um, conn)
94
+ def do_io_io(ssl, um, io)
95
95
  um.ssl_write(ssl, @msg_newline, 0)
96
- conn.read_line(0)
96
+ io.read_line(0)
97
97
  end
98
98
 
99
99
  Benchmark.ips do |x|
100
100
  x.report('stock') { do_io(@ssl_stock) }
101
101
  x.report('UM BIO') { do_io(@ssl_um) }
102
- x.report('UM Stream') { do_io_connection(@ssl_conn, @um, @conn) }
102
+ x.report('UM::IO') { do_io_io(@ssl_conn, @um, @io) }
103
103
 
104
104
  x.compare!(order: :baseline)
105
105
  end
data/docs/um_api.md CHANGED
@@ -43,26 +43,21 @@
43
43
  - `pop(queue)` - removes and returns a value off the end of the given queue.
44
44
  - `prep_timeout(interval)` - returns a timeout AsyncOp with the given interval.
45
45
  - `push(queue, value)` - adds the given value to the end of the given queue.
46
- - `read_each(fd, bgid) { |data| ... }` - reads repeatedly from the given fd
47
- using the given buffer group id, yielding each chunk of data to the given
48
- block.
46
+ - `read_each(fd) { |data| ... }` - reads repeatedly from the given fd, yielding
47
+ each chunk of data to the given block.
49
48
  - `read(fd, buffer[, maxlen[, buffer_offset[, file_offset]]])` - reads from the
50
49
  given fd int o the given buffer (String or IO::Buffer).
51
- - `recv_each(fd, bgid, flags)` - receives from the given fd using the given
52
- buffer group id, with the given flags.
50
+ - `recv_each(fd, flags)` - receives repeatedly from the given fd with the given
51
+ flags.
53
52
  - `recv(fd, buffer, maxlen, flags)` - receives from the given fd into the given
54
53
  buffer.
55
54
  - `schedule(fiber, value)` - adds the given fiber to the runqueue with the given
56
55
  resume value.
57
56
  - `select(rfds, wfds, efds)` - selects ready fds from the given readable,
58
57
  writable and exeptable fds.
59
- - `send_bundle(fd, bgid, *strings)` - sends a bundle of buffers to the given fd
60
- using the given buffer group id.
61
58
  - `send(fd, buffer, len, flags)` - sends to the given fd from the given buffer.
62
59
  - `sendv(fd, *buffers)` - sends multiple buffers to the given fd.
63
60
  - `setsockopt(fd, level, opt, value)` - sets a socket option.
64
- - `setup_buffer_ring(size, count)` - sets up a buffer ring and returns the
65
- buffer group id.
66
61
  - `shift(queue)` - removes and returns a value from the head of given queue.
67
62
  - `shutdown_async(fd, how)` - shuts down the given socket fd without blocking.
68
63
  - `shutdown(fd, how)` - shuts down the given socket fd.
@@ -4,7 +4,7 @@
4
4
  def fiber_switch
5
5
  while true
6
6
  next_fiber, value = @runqueue.shift
7
- return next_fiber.transfer value if next_fiber
7
+ return next_fiber.transfer(value) if next_fiber
8
8
 
9
9
  process_events
10
10
  end
@@ -0,0 +1,16 @@
1
+ require 'uringmachine'
2
+
3
+ machine = UM.new
4
+
5
+ reader = machine.spin {
6
+ input = +''
7
+ machine.read(UM::STDIN_FILENO, input, 256)
8
+ machine.write(UM::STDOUT_FILENO, "Got: #{input}")
9
+ }
10
+
11
+ sleeper = machine.spin {
12
+ machine.sleep(5)
13
+ machine.write(UM::STDOUT_FILENO, "5 seconds have elapsed!")
14
+ }
15
+
16
+ machine.join(reader, sleeper)
@@ -7,6 +7,7 @@ int ret;
7
7
  char buf[100];
8
8
 
9
9
  ret = io_uring_queue_init(8, &ring, 0);
10
+
10
11
  sqe = io_uring_get_sqe(&ring);
11
12
  io_uring_prep_read(sqe, STDIN_FILENO, buf, 100, 0);
12
13
  sqe->user_data = 42;
@@ -14,11 +15,19 @@ io_uring_submit(&ring);
14
15
 
15
16
  ...
16
17
 
17
- ret = io_uring_wait_cqe(&ring, &cqe);
18
- if (!ret) {
18
+ sqe = io_uring_get_sqe(&ring);
19
+ io_uring_prep_cancel(sqe, 42, IORING_ASYNC_CANCEL_USERDATA);
20
+ sqe->flags = IOSQE_CQE_SKIP_SUCCESS;
21
+ io_uring_submit(&ring);
22
+
23
+ if (!io_uring_wait_cqe(&ring, &cqe)) {
19
24
  if (cqe->user_data == 42) {
20
- int len = cqe->res;
21
- printf("Got: %d\n", len);
25
+ if (cqe->res == -ECANCELED)
26
+ printf("Cancelled!\n");
27
+ else {
28
+ int len = cqe->res;
29
+ printf("Got %d bytes\n", len);
30
+ }
22
31
  }
23
32
  io_uring_cqe_seen(&ring, cqe);
24
33
  }
data/examples/pg.rb CHANGED
@@ -66,9 +66,9 @@ $machine.listen(server_fd, UM::SOMAXCONN)
66
66
  puts 'Listening on port 1234'
67
67
 
68
68
  def handle_connection(fd)
69
- conn = UM::Connection.new($machine, fd)
69
+ io = UM::IO.new($machine, fd)
70
70
 
71
- while (l = conn.gets)
71
+ while (l = io.gets)
72
72
  $machine.write(fd, "You said: #{l}")
73
73
  end
74
74
  rescue Exception => e
@@ -0,0 +1,20 @@
1
+ f = machine.spin do
2
+ buf = +''
3
+ machine.read(fd, buf, 256)
4
+ machine.write(UM::STDOUT_FILENO, "Got: #{buf}")
5
+ rescue UM::Terminate
6
+ machine.write(UM::STDOUT_FILENO, "Cancelled")
7
+ end
8
+
9
+ machine.sleep(0.1)
10
+ machine.schedule(f, UM::Terminate.new)
11
+
12
+
13
+
14
+
15
+ # read with timeout
16
+ input = +''
17
+ machine.timeout(timeout, TimeoutError) {
18
+ machine.read(fd, input, 256)
19
+ }
20
+
@@ -0,0 +1,10 @@
1
+ machine = UM.new
2
+ scheduler = UM::FiberScheduler.new(machine)
3
+ Fiber.set_scheduler(scheduler)
4
+
5
+ Fiber.schedule {
6
+ # UringMachine-driven I/O!
7
+ puts "What's your favorite color?"
8
+ color = gets
9
+ puts "Wrong answer: #{color}!"
10
+ }
data/examples/um_io.rb ADDED
@@ -0,0 +1,19 @@
1
+ io = machine.io(fd)
2
+
3
+ # parse an incoming HTTP request
4
+ line = io.read_line(4096)
5
+ m = line.match(/^([a-z]+)\s+([^\s]+)\s+(http\/1\.1)/i)
6
+ headers = {
7
+ ':method' => m[1].downcase,
8
+ ':path' => m[2],
9
+ ':protocol' => m[3].downcase
10
+ }
11
+ while true
12
+ line = io.read_line(4096)
13
+ break if line.empty?
14
+
15
+ m = line.match(/^([a-z0-9\-]+)\:\s+(.+)/i)
16
+ headers[m[1].downcase] = m[2]
17
+ end
18
+
19
+ io.write("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")
data/examples/um_mo.c ADDED
@@ -0,0 +1,32 @@
1
+ VALUE um_sleep(struct um *machine, double duration) {
2
+ struct um_op *op = um_op_acquire(machine);
3
+ op->fiber = rb_fiber_current();
4
+ op->ts = um_double_to_timespec(duration);
5
+ struct io_uring_sqe *sqe = um_get_sqe(machine, op);
6
+ io_uring_prep_timeout(sqe, &op->ts, 0, 0);
7
+
8
+ VALUE ret = um_switch(machine);
9
+ if (um_verify_op_completion(machine, op)) ret = DBL2NUM(duration);
10
+ um_op_release(machine, op);
11
+
12
+ RAISE_IF_EXCEPTION(ret);
13
+ return ret;
14
+ }
15
+
16
+ VALUE um_switch(struct um *machine) {
17
+ while (true) {
18
+ struct um_op *op = um_runqueue_shift(machine);
19
+ if (op) return rb_fiber_transfer(op->fiber, 1, &op->value);
20
+
21
+ um_wait_for_and_process_ready_cqes(machine);
22
+ }
23
+ }
24
+
25
+ void um_process_cqe(struct um *machine, struct io_uring_cqe *cqe) {
26
+ struct um_op *op = (struct um_op *)cqe->user_data;
27
+ if (op) {
28
+ op->result.res = cqe->res;
29
+ op->result.flags = cqe->flags;
30
+ um_runqueue_push(machine, op);
31
+ }
32
+ }
@@ -0,0 +1,15 @@
1
+ # singleshot accept
2
+ while (fd = machine.accept(server_fd))
3
+ handle_connection(fd)
4
+ end
5
+
6
+ # multishot accept
7
+ machine.accept_each(server_fd) { handle_connection(it) }
8
+
9
+ # multishot timeout
10
+ machine.periodically(5) { ... }
11
+
12
+ # multishot recv
13
+ machine.recv_each(fd, 0) { |data|
14
+ machine.write(UM::STDOUT_FILENO, "Got: #{data}\n")
15
+ }
@@ -0,0 +1,11 @@
1
+ ssl = OpenSSL::SSL::SSLSocket.new(IO.for_fd(server_fd), server_ctx)
2
+ machine.ssl_set_bio(ssl)
3
+ ssl.accept
4
+
5
+ ssl.write('Hello!')
6
+ # also:
7
+ machine.ssl_write(ssl, 'Hello!')
8
+
9
+ io = machine.io(ssl)
10
+ line = io.read_line(4096)
11
+ ...
data/ext/um/um.c CHANGED
@@ -49,12 +49,6 @@ inline void um_teardown(struct um *machine) {
49
49
  if (machine->sidecar_mode) um_sidecar_teardown(machine);
50
50
  if (machine->sidecar_signal) free(machine->sidecar_signal);
51
51
 
52
- for (unsigned i = 0; i < machine->buffer_ring_count; i++) {
53
- struct buf_ring_descriptor *desc = machine->buffer_rings + i;
54
- io_uring_free_buf_ring(&machine->ring, desc->br, desc->buf_count, i);
55
- free(desc->buf_base);
56
- }
57
- machine->buffer_ring_count = 0;
58
52
  io_uring_queue_exit(&machine->ring);
59
53
  machine->ring_initialized = 0;
60
54
 
@@ -523,7 +517,6 @@ struct op_ctx {
523
517
  struct um *machine;
524
518
  struct um_op *op;
525
519
  int fd;
526
- int bgid;
527
520
 
528
521
  struct um_queue *queue;
529
522
  void *read_buf;
@@ -870,25 +863,6 @@ VALUE um_sendv(struct um *machine, int fd, int argc, VALUE *argv) {
870
863
  return ret;
871
864
  }
872
865
 
873
- VALUE um_send_bundle(struct um *machine, int fd, int bgid, VALUE strings) {
874
- um_add_strings_to_buffer_ring(machine, bgid, strings);
875
- struct um_op *op = um_op_acquire(machine);
876
- um_prep_op(machine, op, OP_SEND_BUNDLE, 2, 0);
877
- struct io_uring_sqe *sqe = um_get_sqe(machine, op);
878
- io_uring_prep_send_bundle(sqe, fd, 0, MSG_NOSIGNAL | MSG_WAITALL);
879
- sqe->flags |= IOSQE_BUFFER_SELECT;
880
- sqe->buf_group = bgid;
881
-
882
- VALUE ret = um_yield(machine);
883
-
884
- if (likely(um_verify_op_completion(machine, op, true))) ret = INT2NUM(op->result.res);
885
- um_op_release(machine, op);
886
-
887
- RAISE_IF_EXCEPTION(ret);
888
- RB_GC_GUARD(ret);
889
- return ret;
890
- }
891
-
892
866
  VALUE um_recv(struct um *machine, int fd, VALUE buffer, size_t maxlen, int flags) {
893
867
  void *ptr = um_prepare_read_buffer(buffer, maxlen, 0);
894
868
  struct um_op *op = um_op_acquire(machine);
@@ -1461,72 +1435,44 @@ VALUE um_accept_into_queue(struct um *machine, int fd, VALUE queue) {
1461
1435
  return rb_ensure(accept_into_queue_start, (VALUE)&ctx, multishot_complete, (VALUE)&ctx);
1462
1436
  }
1463
1437
 
1464
- int um_read_each_singleshot_loop(struct op_ctx *ctx) {
1465
- struct buf_ring_descriptor *desc = ctx->machine->buffer_rings + ctx->bgid;
1466
- ctx->read_maxlen = desc->buf_size;
1467
- ctx->read_buf = malloc(desc->buf_size);
1468
- int total = 0;
1469
-
1470
- while (1) {
1471
- um_prep_op(ctx->machine, ctx->op, OP_READ, 2, 0);
1472
- struct io_uring_sqe *sqe = um_get_sqe(ctx->machine, ctx->op);
1473
- io_uring_prep_read(sqe, ctx->fd, ctx->read_buf, ctx->read_maxlen, -1);
1474
-
1475
- VALUE ret = um_yield(ctx->machine);
1476
-
1477
- if (likely(um_verify_op_completion(ctx->machine, ctx->op, true))) {
1478
- VALUE buf = rb_str_new(ctx->read_buf, ctx->op->result.res);
1479
- total += ctx->op->result.res;
1480
- rb_yield(buf);
1481
- RB_GC_GUARD(buf);
1482
- }
1483
- else {
1484
- RAISE_IF_EXCEPTION(ret);
1485
- return 0;
1486
- }
1487
- RB_GC_GUARD(ret);
1488
- }
1489
- return 0;
1490
- }
1491
-
1492
1438
  // // returns true if more results are expected
1493
- int read_recv_each_multishot_process_result(struct op_ctx *ctx, struct um_op_result *result, int *total) {
1439
+ inline int read_recv_each_multishot_process_result(struct op_ctx *ctx, struct um_op_result *result, int *total) {
1494
1440
  if (result->res == 0)
1495
1441
  return false;
1496
1442
 
1497
1443
  *total += result->res;
1498
- VALUE buf = um_read_from_buffer_ring(ctx->machine, ctx->bgid, result->res, result->flags);
1499
- rb_yield(buf);
1500
- RB_GC_GUARD(buf);
1501
-
1502
- // TTY devices might not support multishot reads:
1503
- // https://github.com/axboe/liburing/issues/1185. We detect this by checking
1504
- // if the F_MORE flag is absent, then switch to single shot mode.
1505
- if (unlikely(!(result->flags & IORING_CQE_F_MORE))) {
1506
- *total += um_read_each_singleshot_loop(ctx);
1507
- return false;
1444
+ if (likely(result->segment)) {
1445
+ VALUE buf = rb_str_new(result->segment->ptr, result->segment->len);
1446
+ um_segment_checkin(ctx->machine, result->segment);
1447
+ result->segment = NULL;
1448
+ rb_yield(buf);
1449
+ RB_GC_GUARD(buf);
1508
1450
  }
1509
1451
 
1510
1452
  return true;
1511
1453
  }
1512
1454
 
1513
- void read_recv_each_prep(struct io_uring_sqe *sqe, struct op_ctx *ctx) {
1455
+ static inline void read_recv_each_prep(struct io_uring_sqe *sqe, struct op_ctx *ctx) {
1456
+ bp_ensure_commit_level(ctx->machine);
1457
+ ctx->op->bp_commit_level = ctx->machine->bp_commit_level;
1458
+
1514
1459
  switch (ctx->op->kind) {
1515
1460
  case OP_READ_MULTISHOT:
1516
- io_uring_prep_read_multishot(sqe, ctx->fd, 0, -1, ctx->bgid);
1461
+ io_uring_prep_read_multishot(sqe, ctx->fd, 0, -1, BP_BGID);
1517
1462
  return;
1518
1463
  case OP_RECV_MULTISHOT:
1519
1464
  io_uring_prep_recv_multishot(sqe, ctx->fd, NULL, 0, 0);
1520
- sqe->buf_group = ctx->bgid;
1465
+ sqe->buf_group = BP_BGID;
1521
1466
  sqe->flags |= IOSQE_BUFFER_SELECT;
1522
1467
  return;
1523
1468
  default:
1524
- return;
1469
+ um_raise_internal_error("Invalid multishot op");
1525
1470
  }
1526
1471
  }
1527
1472
 
1528
1473
  VALUE read_recv_each_start(VALUE arg) {
1529
1474
  struct op_ctx *ctx = (struct op_ctx *)arg;
1475
+
1530
1476
  struct io_uring_sqe *sqe = um_get_sqe(ctx->machine, ctx->op);
1531
1477
  read_recv_each_prep(sqe, ctx);
1532
1478
  int total = 0;
@@ -1558,19 +1504,19 @@ VALUE read_recv_each_start(VALUE arg) {
1558
1504
  return Qnil;
1559
1505
  }
1560
1506
 
1561
- VALUE um_read_each(struct um *machine, int fd, int bgid) {
1507
+ VALUE um_read_each(struct um *machine, int fd) {
1562
1508
  struct um_op *op = um_op_acquire(machine);
1563
- um_prep_op(machine, op, OP_READ_MULTISHOT, 2, OP_F_MULTISHOT);
1509
+ um_prep_op(machine, op, OP_READ_MULTISHOT, 2, OP_F_MULTISHOT | OP_F_BUFFER_POOL);
1564
1510
 
1565
- struct op_ctx ctx = { .machine = machine, .op = op, .fd = fd, .bgid = bgid, .read_buf = NULL };
1511
+ struct op_ctx ctx = { .machine = machine, .op = op, .fd = fd, .read_buf = NULL };
1566
1512
  return rb_ensure(read_recv_each_start, (VALUE)&ctx, multishot_complete, (VALUE)&ctx);
1567
1513
  }
1568
1514
 
1569
- VALUE um_recv_each(struct um *machine, int fd, int bgid, int flags) {
1515
+ VALUE um_recv_each(struct um *machine, int fd, int flags) {
1570
1516
  struct um_op *op = um_op_acquire(machine);
1571
- um_prep_op(machine, op, OP_RECV_MULTISHOT, 2, OP_F_MULTISHOT);
1517
+ um_prep_op(machine, op, OP_RECV_MULTISHOT, 2, OP_F_MULTISHOT | OP_F_BUFFER_POOL);
1572
1518
 
1573
- struct op_ctx ctx = { .machine = machine, .op = op, .fd = fd, .bgid = bgid, .read_buf = NULL, .flags = flags };
1519
+ struct op_ctx ctx = { .machine = machine, .op = op, .fd = fd, .read_buf = NULL, .flags = flags };
1574
1520
  return rb_ensure(read_recv_each_start, (VALUE)&ctx, multishot_complete, (VALUE)&ctx);
1575
1521
  }
1576
1522
 
@@ -1623,7 +1569,6 @@ extern VALUE SYM_ops_free;
1623
1569
  extern VALUE SYM_ops_transient;
1624
1570
  extern VALUE SYM_time_total_cpu;
1625
1571
  extern VALUE SYM_time_total_wait;
1626
- extern VALUE SYM_buffer_groups;
1627
1572
  extern VALUE SYM_buffers_allocated;
1628
1573
  extern VALUE SYM_buffers_free;
1629
1574
  extern VALUE SYM_segments_free;
data/ext/um/um.h CHANGED
@@ -56,7 +56,6 @@ enum um_op_kind {
56
56
  OP_RECV,
57
57
  OP_RECVMSG,
58
58
  OP_SEND,
59
- OP_SEND_BUNDLE,
60
59
  OP_SENDMSG,
61
60
  OP_SENDV,
62
61
  OP_SOCKET,
@@ -80,12 +79,12 @@ enum um_op_kind {
80
79
  OP_TIMEOUT_MULTISHOT,
81
80
  };
82
81
 
83
- enum um_connection_mode {
84
- CONNECTION_FD,
85
- CONNECTION_SOCKET,
86
- CONNECTION_SSL,
87
- CONNECTION_STRING,
88
- CONNECTION_IO_BUFFER
82
+ enum um_io_mode {
83
+ IO_FD,
84
+ IO_SOCKET,
85
+ IO_SSL,
86
+ IO_STRING,
87
+ IO_IO_BUFFER
89
88
  };
90
89
 
91
90
  #define OP_F_CQE_SEEN (1U << 0) // CQE has been seen
@@ -168,15 +167,6 @@ struct um_op {
168
167
  };
169
168
  };
170
169
 
171
- struct buf_ring_descriptor {
172
- struct io_uring_buf_ring *br;
173
- size_t br_size;
174
- unsigned buf_count;
175
- unsigned buf_size;
176
- unsigned buf_mask;
177
- void *buf_base;
178
- };
179
-
180
170
  struct um_metrics {
181
171
  ulong total_ops; // total ops submitted
182
172
  ulong total_switches; // total fiber switches
@@ -199,8 +189,6 @@ struct um_metrics {
199
189
  double time_first_cpu; // last seen time stamp
200
190
  };
201
191
 
202
- #define BUFFER_RING_MAX_COUNT 10
203
-
204
192
  struct um {
205
193
  VALUE self;
206
194
 
@@ -216,13 +204,9 @@ struct um {
216
204
  pthread_t sidecar_thread;
217
205
  uint32_t *sidecar_signal;
218
206
 
219
- uint buffer_ring_count; // number of registered buffer rings
220
-
221
207
  uint size; // size of SQ
222
208
  uint sqpoll_mode; // SQPOLL mode enabled
223
209
 
224
- struct buf_ring_descriptor buffer_rings[BUFFER_RING_MAX_COUNT];
225
-
226
210
  struct um_op *transient_head; // list of pending transient ops
227
211
  VALUE pending_fibers; // set containing pending fibers
228
212
 
@@ -272,11 +256,11 @@ struct um_async_op {
272
256
  struct um_op *op;
273
257
  };
274
258
 
275
- struct um_connection {
259
+ struct um_io {
276
260
  VALUE self;
277
261
  struct um *machine;
278
262
 
279
- enum um_connection_mode mode;
263
+ enum um_io_mode mode;
280
264
  union {
281
265
  int fd;
282
266
  VALUE target;
@@ -304,7 +288,7 @@ extern VALUE eUMError;
304
288
  extern VALUE cMutex;
305
289
  extern VALUE cQueue;
306
290
  extern VALUE cAsyncOp;
307
- extern VALUE eConnectionRESPError;
291
+ extern VALUE eIORESPError;
308
292
 
309
293
  struct um *um_get_machine(VALUE self);
310
294
  void um_setup(VALUE self, struct um *machine, uint size, uint sqpoll_timeout_msec, int sidecar_mode);
@@ -351,9 +335,7 @@ void um_raise_on_error_result(int result);
351
335
  int um_get_buffer_bytes_for_writing(VALUE buffer, const void **base, size_t *size, int raise_on_bad_buffer);
352
336
  void * um_prepare_read_buffer(VALUE buffer, ssize_t len, ssize_t ofs);
353
337
  void um_update_read_buffer(VALUE buffer, ssize_t buffer_offset, __s32 result);
354
- int um_setup_buffer_ring(struct um *machine, unsigned size, unsigned count);
355
- VALUE um_read_from_buffer_ring(struct um *machine, int bgid, __s32 result, __u32 flags);
356
- void um_add_strings_to_buffer_ring(struct um *machine, int bgid, VALUE strings);
338
+
357
339
  struct iovec *um_alloc_iovecs_for_writing(int argc, VALUE *argv, size_t *total_len);
358
340
  void um_advance_iovecs_for_writing(struct iovec **ptr, int *len, size_t adv);
359
341
 
@@ -376,7 +358,7 @@ VALUE um_sleep(struct um *machine, double duration);
376
358
  VALUE um_periodically(struct um *machine, double interval);
377
359
  VALUE um_read(struct um *machine, int fd, VALUE buffer, size_t maxlen, ssize_t buffer_offset, __u64 file_offset);
378
360
  size_t um_read_raw(struct um *machine, int fd, char *buffer, size_t maxlen);
379
- VALUE um_read_each(struct um *machine, int fd, int bgid);
361
+ VALUE um_read_each(struct um *machine, int fd);
380
362
  VALUE um_write(struct um *machine, int fd, VALUE buffer, size_t len, __u64 file_offset);
381
363
  size_t um_write_raw(struct um *machine, int fd, const char *buffer, size_t len);
382
364
  VALUE um_writev(struct um *machine, int fd, int argc, VALUE *argv);
@@ -405,9 +387,8 @@ VALUE um_connect(struct um *machine, int fd, const struct sockaddr *addr, sockle
405
387
  VALUE um_send(struct um *machine, int fd, VALUE buffer, size_t len, int flags);
406
388
  size_t um_send_raw(struct um *machine, int fd, const char *buffer, size_t len, int flags);
407
389
  VALUE um_sendv(struct um *machine, int fd, int argc, VALUE *argv);
408
- VALUE um_send_bundle(struct um *machine, int fd, int bgid, VALUE strings);
409
390
  VALUE um_recv(struct um *machine, int fd, VALUE buffer, size_t maxlen, int flags);
410
- VALUE um_recv_each(struct um *machine, int fd, int bgid, int flags);
391
+ VALUE um_recv_each(struct um *machine, int fd, int flags);
411
392
  VALUE um_bind(struct um *machine, int fd, struct sockaddr *addr, socklen_t addrlen);
412
393
  VALUE um_listen(struct um *machine, int fd, int backlog);
413
394
  VALUE um_getsockopt(struct um *machine, int fd, int level, int opt);
@@ -438,16 +419,16 @@ VALUE um_queue_pop(struct um *machine, struct um_queue *queue);
438
419
  VALUE um_queue_unshift(struct um *machine, struct um_queue *queue, VALUE value);
439
420
  VALUE um_queue_shift(struct um *machine, struct um_queue *queue);
440
421
 
441
- void connection_teardown(struct um_connection *conn);
442
- void connection_clear(struct um_connection *conn);
443
- VALUE connection_read_line(struct um_connection *conn, VALUE out_buffer, size_t maxlen);
444
- VALUE connection_read(struct um_connection *conn, VALUE out_buffer, ssize_t len, size_t inc, int safe_inc);
445
- VALUE connection_read_to_delim(struct um_connection *conn, VALUE out_buffer, VALUE delim, ssize_t maxlen);
446
- void connection_skip(struct um_connection *conn, size_t inc, int safe_inc);
447
- void connection_read_each(struct um_connection *conn);
448
- size_t connection_write_raw(struct um_connection *conn, const char *buffer, size_t len);
449
- VALUE connection_writev(struct um_connection *conn, int argc, VALUE *argv);
450
- VALUE resp_read(struct um_connection *conn, VALUE out_buffer);
422
+ void io_teardown(struct um_io *io);
423
+ void io_clear(struct um_io *io);
424
+ VALUE io_read_line(struct um_io *io, VALUE out_buffer, size_t maxlen);
425
+ VALUE io_read(struct um_io *io, VALUE out_buffer, ssize_t len, size_t inc, int safe_inc);
426
+ VALUE io_read_to_delim(struct um_io *io, VALUE out_buffer, VALUE delim, ssize_t maxlen);
427
+ void io_skip(struct um_io *io, size_t inc, int safe_inc);
428
+ void io_read_each(struct um_io *io);
429
+ size_t io_write_raw(struct um_io *io, const char *buffer, size_t len);
430
+ VALUE io_writev(struct um_io *io, int argc, VALUE *argv);
431
+ VALUE resp_read(struct um_io *io, VALUE out_buffer);
451
432
  void resp_encode(struct um_write_buffer *buf, VALUE obj);
452
433
  void resp_encode_cmd(struct um_write_buffer *buf, int argc, VALUE *argv);
453
434