uringmachine 0.29.2 → 0.31.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.
data/ext/um/um.h CHANGED
@@ -48,6 +48,9 @@ enum um_op_kind {
48
48
  OP_CLOSE,
49
49
  OP_CLOSE_ASYNC,
50
50
  OP_STATX,
51
+ OP_SPLICE,
52
+ OP_TEE,
53
+ OP_FSYNC,
51
54
 
52
55
  OP_ACCEPT,
53
56
  OP_RECV,
@@ -77,12 +80,12 @@ enum um_op_kind {
77
80
  OP_TIMEOUT_MULTISHOT,
78
81
  };
79
82
 
80
- enum um_stream_mode {
81
- STREAM_BP_READ,
82
- STREAM_BP_RECV,
83
- STREAM_SSL,
84
- STREAM_STRING,
85
- STREAM_IO_BUFFER
83
+ enum um_connection_mode {
84
+ CONNECTION_FD,
85
+ CONNECTION_SOCKET,
86
+ CONNECTION_SSL,
87
+ CONNECTION_STRING,
88
+ CONNECTION_IO_BUFFER
86
89
  };
87
90
 
88
91
  #define OP_F_CQE_SEEN (1U << 0) // CQE has been seen
@@ -161,7 +164,7 @@ struct um_op {
161
164
  struct iovec *iovecs; // used for vectorized write/send
162
165
  siginfo_t siginfo; // used for waitid
163
166
  int int_value; // used for getsockopt
164
- size_t bp_commit_level; // buffer pool commit threshold
167
+ size_t bp_commit_level; // buffer pool commit level
165
168
  };
166
169
  };
167
170
 
@@ -269,11 +272,11 @@ struct um_async_op {
269
272
  struct um_op *op;
270
273
  };
271
274
 
272
- struct um_stream {
275
+ struct um_connection {
273
276
  VALUE self;
274
277
  struct um *machine;
275
278
 
276
- enum um_stream_mode mode;
279
+ enum um_connection_mode mode;
277
280
  union {
278
281
  int fd;
279
282
  VALUE target;
@@ -301,7 +304,7 @@ extern VALUE eUMError;
301
304
  extern VALUE cMutex;
302
305
  extern VALUE cQueue;
303
306
  extern VALUE cAsyncOp;
304
- extern VALUE eStreamRESPError;
307
+ extern VALUE eConnectionRESPError;
305
308
 
306
309
  struct um *um_get_machine(VALUE self);
307
310
  void um_setup(VALUE self, struct um *machine, uint size, uint sqpoll_timeout_msec, int sidecar_mode);
@@ -325,7 +328,6 @@ void um_op_list_compact(struct um *machine, struct um_op *head);
325
328
  void um_op_multishot_results_push(struct um *machine, struct um_op *op, __s32 res, __u32 flags);
326
329
  void um_op_multishot_results_clear(struct um *machine, struct um_op *op);
327
330
 
328
- struct um_segment *um_segment_alloc(struct um *machine);
329
331
  void um_segment_free(struct um *machine, struct um_segment *segment);
330
332
 
331
333
  void um_runqueue_push(struct um *machine, struct um_op *op);
@@ -350,7 +352,7 @@ int um_get_buffer_bytes_for_writing(VALUE buffer, const void **base, size_t *siz
350
352
  void * um_prepare_read_buffer(VALUE buffer, ssize_t len, ssize_t ofs);
351
353
  void um_update_read_buffer(VALUE buffer, ssize_t buffer_offset, __s32 result);
352
354
  int um_setup_buffer_ring(struct um *machine, unsigned size, unsigned count);
353
- VALUE um_get_string_from_buffer_ring(struct um *machine, int bgid, __s32 result, __u32 flags);
355
+ VALUE um_read_from_buffer_ring(struct um *machine, int bgid, __s32 result, __u32 flags);
354
356
  void um_add_strings_to_buffer_ring(struct um *machine, int bgid, VALUE strings);
355
357
  struct iovec *um_alloc_iovecs_for_writing(int argc, VALUE *argv, size_t *total_len);
356
358
  void um_advance_iovecs_for_writing(struct iovec **ptr, int *len, size_t adv);
@@ -376,7 +378,7 @@ VALUE um_read(struct um *machine, int fd, VALUE buffer, size_t maxlen, ssize_t b
376
378
  size_t um_read_raw(struct um *machine, int fd, char *buffer, size_t maxlen);
377
379
  VALUE um_read_each(struct um *machine, int fd, int bgid);
378
380
  VALUE um_write(struct um *machine, int fd, VALUE buffer, size_t len, __u64 file_offset);
379
- size_t um_write_raw(struct um *machine, int fd, const char *buffer, size_t maxlen);
381
+ size_t um_write_raw(struct um *machine, int fd, const char *buffer, size_t len);
380
382
  VALUE um_writev(struct um *machine, int fd, int argc, VALUE *argv);
381
383
  VALUE um_write_async(struct um *machine, int fd, VALUE buffer, size_t len, __u64 file_offset);
382
384
  VALUE um_close(struct um *machine, int fd);
@@ -391,6 +393,9 @@ VALUE um_waitid_status(struct um *machine, int idtype, int id, int options);
391
393
  #endif
392
394
 
393
395
  VALUE um_statx(struct um *machine, int dirfd, VALUE path, int flags, unsigned int mask);
396
+ VALUE um_splice(struct um *machine, int in_fd, int out_fd, uint nbytes);
397
+ VALUE um_tee(struct um *machine, int in_fd, int out_fd, uint nbytes);
398
+ VALUE um_fsync(struct um *machine, int fd);
394
399
 
395
400
  VALUE um_accept(struct um *machine, int fd);
396
401
  VALUE um_accept_each(struct um *machine, int fd);
@@ -398,6 +403,7 @@ VALUE um_accept_into_queue(struct um *machine, int fd, VALUE queue);
398
403
  VALUE um_socket(struct um *machine, int domain, int type, int protocol, uint flags);
399
404
  VALUE um_connect(struct um *machine, int fd, const struct sockaddr *addr, socklen_t addrlen);
400
405
  VALUE um_send(struct um *machine, int fd, VALUE buffer, size_t len, int flags);
406
+ size_t um_send_raw(struct um *machine, int fd, const char *buffer, size_t len, int flags);
401
407
  VALUE um_sendv(struct um *machine, int fd, int argc, VALUE *argv);
402
408
  VALUE um_send_bundle(struct um *machine, int fd, int bgid, VALUE strings);
403
409
  VALUE um_recv(struct um *machine, int fd, VALUE buffer, size_t maxlen, int flags);
@@ -432,12 +438,16 @@ VALUE um_queue_pop(struct um *machine, struct um_queue *queue);
432
438
  VALUE um_queue_unshift(struct um *machine, struct um_queue *queue, VALUE value);
433
439
  VALUE um_queue_shift(struct um *machine, struct um_queue *queue);
434
440
 
435
- void stream_teardown(struct um_stream *stream);
436
- void stream_clear(struct um_stream *stream);
437
- VALUE stream_get_line(struct um_stream *stream, VALUE buf, size_t maxlen);
438
- VALUE stream_get_string(struct um_stream *stream, VALUE out_buffer, ssize_t len, size_t inc, int safe_inc);
439
- void stream_skip(struct um_stream *stream, size_t inc, int safe_inc);
440
- VALUE resp_decode(struct um_stream *stream, VALUE out_buffer);
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);
441
451
  void resp_encode(struct um_write_buffer *buf, VALUE obj);
442
452
  void resp_encode_cmd(struct um_write_buffer *buf, int argc, VALUE *argv);
443
453
 
@@ -454,9 +464,11 @@ void um_sidecar_signal_wait(struct um *machine);
454
464
  void um_sidecar_signal_wake(struct um *machine);
455
465
 
456
466
  void um_ssl_set_bio(struct um *machine, VALUE ssl_obj);
457
- int um_ssl_read(struct um *machine, VALUE ssl, VALUE buf, int maxlen);
458
- int um_ssl_read_raw(struct um *machine, VALUE ssl_obj, char *ptr, int maxlen);
459
- int um_ssl_write(struct um *machine, VALUE ssl, VALUE buf, int len);
467
+ int um_ssl_read(struct um *machine, VALUE ssl, VALUE buf, size_t maxlen);
468
+ int um_ssl_read_raw(struct um *machine, VALUE ssl_obj, char *ptr, size_t maxlen);
469
+ int um_ssl_write(struct um *machine, VALUE ssl, VALUE buf, size_t len);
470
+ int um_ssl_write_raw(struct um *machine, VALUE ssl, const char *buffer, size_t len);
471
+ int um_ssl_writev(struct um *machine, VALUE ssl, int argc, VALUE *argv);
460
472
 
461
473
  void bp_setup(struct um *machine);
462
474
  void bp_teardown(struct um *machine);
@@ -18,7 +18,7 @@ inline struct um_buffer *buffer_alloc(struct um *machine) {
18
18
  return buffer;
19
19
  }
20
20
 
21
- inline struct um_buffer *bp_buffer_checkout(struct um *machine) {
21
+ struct um_buffer *bp_buffer_checkout(struct um *machine) {
22
22
  struct um_buffer *buffer = machine->bp_buffer_freelist;
23
23
  if (buffer) {
24
24
  struct um_buffer *next = buffer->next;
@@ -50,13 +50,13 @@ inline void buffer_free(struct um *machine, struct um_buffer *buffer) {
50
50
  }
51
51
  }
52
52
 
53
- inline void bp_buffer_checkin(struct um *machine, struct um_buffer *buffer) {
53
+ void bp_buffer_checkin(struct um *machine, struct um_buffer *buffer) {
54
54
  assert(buffer->ref_count > 0);
55
55
  buffer->ref_count--;
56
56
  if (!buffer->ref_count) buffer_free(machine, buffer);
57
57
  }
58
58
 
59
- inline void bp_discard_buffer_freelist(struct um *machine) {
59
+ void bp_discard_buffer_freelist(struct um *machine) {
60
60
  while (machine->bp_buffer_freelist) {
61
61
  struct um_buffer *buffer = machine->bp_buffer_freelist;
62
62
  struct um_buffer *next = buffer->next;
@@ -69,7 +69,7 @@ inline void bp_discard_buffer_freelist(struct um *machine) {
69
69
  }
70
70
  }
71
71
 
72
- inline void bp_setup(struct um *machine) {
72
+ void bp_setup(struct um *machine) {
73
73
  int ret;
74
74
  machine->bp_br = io_uring_setup_buf_ring(&machine->ring, BP_BR_ENTRIES, BP_BGID, IOU_PBUF_RING_INC, &ret);
75
75
  if (unlikely(!machine->bp_br)) rb_syserr_fail(ret, strerror(ret));
@@ -85,7 +85,7 @@ inline void bp_setup(struct um *machine) {
85
85
  machine->bp_total_commited = 0;
86
86
  }
87
87
 
88
- inline void bp_teardown(struct um *machine) {
88
+ void bp_teardown(struct um *machine) {
89
89
  bp_discard_buffer_freelist(machine);
90
90
  for (int i = 0; i < BP_BR_ENTRIES; i++) {
91
91
  struct um_buffer *buffer = machine->bp_commited_buffers[i];
@@ -162,7 +162,7 @@ inline int should_commit_more_p(struct um *machine) {
162
162
  (machine->bp_total_commited < machine->bp_commit_level);
163
163
  }
164
164
 
165
- inline void bp_ensure_commit_level(struct um *machine) {
165
+ void bp_ensure_commit_level(struct um *machine) {
166
166
  if (machine->bp_total_commited > (machine->bp_commit_level / 2))
167
167
  return;
168
168
 
@@ -179,7 +179,7 @@ inline void bp_ensure_commit_level(struct um *machine) {
179
179
  // size.
180
180
  }
181
181
 
182
- inline void bp_handle_enobufs(struct um *machine) {
182
+ void bp_handle_enobufs(struct um *machine) {
183
183
  if (unlikely(machine->bp_commit_level >= BP_MAX_COMMIT_LEVEL))
184
184
  rb_raise(eUMError, "Buffer starvation");
185
185
 
@@ -189,7 +189,7 @@ inline void bp_handle_enobufs(struct um *machine) {
189
189
  bp_discard_buffer_freelist(machine);
190
190
  }
191
191
 
192
- inline struct um_segment *um_segment_alloc(struct um *machine) {
192
+ inline struct um_segment *segment_alloc(struct um *machine) {
193
193
  if (machine->segment_freelist) {
194
194
  struct um_segment *segment = machine->segment_freelist;
195
195
  machine->segment_freelist = segment->next;
@@ -208,14 +208,14 @@ inline struct um_segment *um_segment_alloc(struct um *machine) {
208
208
  return batch;
209
209
  }
210
210
 
211
- inline void um_segment_free(struct um *machine, struct um_segment *segment) {
211
+ void um_segment_free(struct um *machine, struct um_segment *segment) {
212
212
  segment->next = machine->segment_freelist;
213
213
  machine->segment_freelist = segment;
214
214
  machine->metrics.segments_free++;
215
215
  }
216
216
 
217
- inline struct um_segment *bp_buffer_consume(struct um *machine, struct um_buffer *buffer, size_t len) {
218
- struct um_segment *segment = um_segment_alloc(machine);
217
+ struct um_segment *bp_buffer_consume(struct um *machine, struct um_buffer *buffer, size_t len) {
218
+ struct um_segment *segment = segment_alloc(machine);
219
219
  segment->ptr = buffer->buf + buffer->pos;
220
220
  segment->len = len;
221
221
  segment->buffer = buffer;
data/ext/um/um_class.c CHANGED
@@ -534,6 +534,60 @@ VALUE UM_statx(VALUE self, VALUE dirfd, VALUE path, VALUE flags, VALUE mask) {
534
534
  return um_statx(machine, NUM2INT(dirfd), path, NUM2INT(flags), NUM2UINT(mask));
535
535
  }
536
536
 
537
+ /* call-seq:
538
+ * machine.splice(in_fd, out_fd, nbytes) -> len
539
+ *
540
+ * Splices bytes from in_fd to out_fd. At least one of the given fds must be a
541
+ * pipe.
542
+ *
543
+ * - https://www.man7.org/linux/man-pages/man2/splice.2.html
544
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_splice.3.html
545
+ *
546
+ * @param in_fd [Integer] fd to splice from
547
+ * @param out_fd [Integer] fd to splice to
548
+ * @param nbytes [Integer] number of bytes to splice
549
+ * @return [Integer] number of bytes spliced
550
+ */
551
+ VALUE UM_splice(VALUE self, VALUE in_fd, VALUE out_fd, VALUE nbytes) {
552
+ struct um *machine = um_get_machine(self);
553
+ return um_splice(machine, NUM2INT(in_fd), NUM2INT(out_fd), NUM2UINT(nbytes));
554
+ }
555
+
556
+ /* call-seq:
557
+ * machine.tee(in_fd, out_fd, nbytes) -> len
558
+ *
559
+ * Duplicates bytes from in_fd to out_fd. At least one of the given fds must be
560
+ * a pipe.
561
+ *
562
+ * - https://www.man7.org/linux/man-pages/man2/tee.2.html
563
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_tee.3.html
564
+ *
565
+ * @param in_fd [Integer] fd to copy from
566
+ * @param out_fd [Integer] fd to copy to
567
+ * @param nbytes [Integer] number of bytes to duplicate
568
+ * @return [Integer] number of bytes duplicated
569
+ */
570
+ VALUE UM_tee(VALUE self, VALUE in_fd, VALUE out_fd, VALUE nbytes) {
571
+ struct um *machine = um_get_machine(self);
572
+ return um_tee(machine, NUM2INT(in_fd), NUM2INT(out_fd), NUM2UINT(nbytes));
573
+ }
574
+
575
+ /* call-seq:
576
+ * machine.fsync(fd) -> 0
577
+ *
578
+ * Flushes all modified file data to the storage device.
579
+ *
580
+ * - https://www.man7.org/linux/man-pages/man2/fsync.2.html
581
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_fsync.3.html
582
+ *
583
+ * @param fd [Integer] fd
584
+ * @return [Integer] 0 if successful
585
+ */
586
+ VALUE UM_fsync(VALUE self, VALUE fd) {
587
+ struct um *machine = um_get_machine(self);
588
+ return um_fsync(machine, NUM2INT(fd));
589
+ }
590
+
537
591
  /* call-seq:
538
592
  * machine.close(fd) -> 0
539
593
  *
@@ -1480,6 +1534,9 @@ void Init_UM(void) {
1480
1534
  rb_define_method(cUM, "writev", UM_writev, -1);
1481
1535
  rb_define_method(cUM, "write_async", UM_write_async, -1);
1482
1536
  rb_define_method(cUM, "statx", UM_statx, 4);
1537
+ rb_define_method(cUM, "splice", UM_splice, 3);
1538
+ rb_define_method(cUM, "tee", UM_tee, 3);
1539
+ rb_define_method(cUM, "fsync", UM_fsync, 1);
1483
1540
 
1484
1541
  rb_define_method(cUM, "poll", UM_poll, 2);
1485
1542
  rb_define_method(cUM, "select", UM_select, 3);