Skip to content

Commit

Permalink
Implement UM#add
Browse files Browse the repository at this point in the history
  • Loading branch information
noteflakes committed Nov 13, 2024
1 parent b3cef2b commit a6c88da
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 15 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
- Add `#open`
- Fix `#spin`
- Fix handling of signal interruption.
- Reimplement and simplify um_op
- Add `UM::Queue`, `#push`, `#pop`, `#shift`, `#unshift`
- Add `UM::Mutex`, `#synchronize`
- Add `#recv_each`
- Add `#getsockopt`, `#setsockopt`
- Simplify and improve op management
Expand Down
14 changes: 14 additions & 0 deletions ext/um/um.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,20 @@ VALUE um_setsockopt(struct um *machine, int fd, int level, int opt, int value) {
return raise_if_exception(ret);
}

VALUE um_open(struct um *machine, VALUE pathname, int flags, int mode) {
struct um_op op;
um_prep_op(machine, &op, OP_BIND);
struct io_uring_sqe *sqe = um_get_sqe(machine, &op);
io_uring_prep_open(sqe, StringValueCStr(pathname), flags, mode);

VALUE ret = um_fiber_switch(machine);
if (um_check_completion(machine, &op))
ret = INT2NUM(op.result.res);

RB_GC_GUARD(ret);
return raise_if_exception(ret);
}

/*******************************************************************************
multishot ops
*******************************************************************************/
Expand Down
1 change: 1 addition & 0 deletions ext/um/um.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ VALUE um_read(struct um *machine, int fd, VALUE buffer, int maxlen, int buffer_o
VALUE um_read_each(struct um *machine, int fd, int bgid);
VALUE um_write(struct um *machine, int fd, VALUE str, int len);
VALUE um_close(struct um *machine, int fd);
VALUE um_open(struct um *machine, VALUE pathname, int flags, int mode);

VALUE um_accept(struct um *machine, int fd);
VALUE um_accept_each(struct um *machine, int fd);
Expand Down
53 changes: 38 additions & 15 deletions ext/um/um_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,28 @@ VALUE UM_queue_shift(VALUE self, VALUE queue) {

#endif

struct um_open_ctx {
VALUE self;
VALUE fd;
};

VALUE UM_open_ensure(VALUE arg) {
struct um_open_ctx *ctx = (struct um_open_ctx *)arg;
UM_close(ctx->self, ctx->fd);
return ctx->self;
}

VALUE UM_open(VALUE self, VALUE pathname, VALUE flags) {
struct um *machine = get_machine(self);
VALUE ret = um_open(machine, pathname, NUM2INT(flags), S_IRWXU);
if (rb_block_given_p()) {
struct um_open_ctx ctx = { self, ret };
return rb_ensure(rb_yield, ret, UM_open_ensure, (VALUE)&ctx);
}
else
return ret;
}

VALUE UM_kernel_version(VALUE self) {
return INT2NUM(UM_KERNEL_VERSION);
}
Expand All @@ -269,41 +291,42 @@ void Init_UM(void) {
rb_define_alloc_func(cUM, UM_allocate);

rb_define_method(cUM, "initialize", UM_initialize, 0);
rb_define_method(cUM, "setup_buffer_ring", UM_setup_buffer_ring, 2);
rb_define_method(cUM, "pending_count", UM_pending_count, 0);
rb_define_method(cUM, "setup_buffer_ring", UM_setup_buffer_ring, 2);
rb_define_singleton_method(cUM, "kernel_version", UM_kernel_version, 0);


rb_define_method(cUM, "snooze", UM_snooze, 0);
rb_define_method(cUM, "yield", UM_yield, 0);
rb_define_method(cUM, "schedule", UM_schedule, 2);
rb_define_method(cUM, "snooze", UM_snooze, 0);
rb_define_method(cUM, "timeout", UM_timeout, 2);
rb_define_method(cUM, "yield", UM_yield, 0);

rb_define_method(cUM, "sleep", UM_sleep, 1);
rb_define_method(cUM, "close", UM_close, 1);
rb_define_method(cUM, "open", UM_open, 2);
rb_define_method(cUM, "read", UM_read, -1);
rb_define_method(cUM, "read_each", UM_read_each, 2);
rb_define_method(cUM, "sleep", UM_sleep, 1);
rb_define_method(cUM, "write", UM_write, -1);
rb_define_method(cUM, "close", UM_close, 1);

rb_define_method(cUM, "accept", UM_accept, 1);
rb_define_method(cUM, "accept_each", UM_accept_each, 1);
rb_define_method(cUM, "socket", UM_socket, 4);
rb_define_method(cUM, "bind", UM_bind, 3);
rb_define_method(cUM, "connect", UM_connect, 3);
rb_define_method(cUM, "send", UM_send, 4);
rb_define_method(cUM, "getsockopt", UM_getsockopt, 3);
rb_define_method(cUM, "listen", UM_listen, 2);
rb_define_method(cUM, "recv", UM_recv, 4);
rb_define_method(cUM, "recv_each", UM_recv_each, 3);
rb_define_method(cUM, "bind", UM_bind, 3);
rb_define_method(cUM, "listen", UM_listen, 2);
rb_define_method(cUM, "getsockopt", UM_getsockopt, 3);
rb_define_method(cUM, "send", UM_send, 4);
rb_define_method(cUM, "setsockopt", UM_setsockopt, 4);
rb_define_method(cUM, "socket", UM_socket, 4);

#ifdef HAVE_IO_URING_PREP_FUTEX
rb_define_method(cUM, "synchronize", UM_mutex_synchronize, 1);
rb_define_method(cUM, "push", UM_queue_push, 2);
rb_define_method(cUM, "pop", UM_queue_pop, 1);
rb_define_method(cUM, "unshift", UM_queue_unshift, 2);
rb_define_method(cUM, "push", UM_queue_push, 2);
rb_define_method(cUM, "shift", UM_queue_shift, 1);
rb_define_method(cUM, "synchronize", UM_mutex_synchronize, 1);
rb_define_method(cUM, "unshift", UM_queue_unshift, 2);
#endif

rb_define_singleton_method(cUM, "kernel_version", UM_kernel_version, 0);

um_define_net_constants(cUM);
}
20 changes: 20 additions & 0 deletions ext/um/um_const.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include "ruby.h"

#include <fcntl.h>

#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
Expand All @@ -12,6 +15,23 @@
#define DEF_CONST_INT(mod, v) rb_define_const(mod, #v, INT2NUM(v))

void um_define_net_constants(VALUE mod) {
DEF_CONST_INT(mod, O_APPEND);
DEF_CONST_INT(mod, O_CLOEXEC);
DEF_CONST_INT(mod, O_CREAT);
DEF_CONST_INT(mod, O_DIRECT);
DEF_CONST_INT(mod, O_DIRECTORY);
DEF_CONST_INT(mod, O_DSYNC);
DEF_CONST_INT(mod, O_EXCL);
DEF_CONST_INT(mod, O_NOCTTY);
DEF_CONST_INT(mod, O_NOFOLLOW);
DEF_CONST_INT(mod, O_PATH);
DEF_CONST_INT(mod, O_RDONLY);
DEF_CONST_INT(mod, O_RDWR);
DEF_CONST_INT(mod, O_SYNC);
DEF_CONST_INT(mod, O_TMPFILE);
DEF_CONST_INT(mod, O_TRUNC);
DEF_CONST_INT(mod, O_WRONLY);

DEF_CONST_INT(mod, SOCK_STREAM);
DEF_CONST_INT(mod, SOCK_DGRAM);
DEF_CONST_INT(mod, SOCK_RAW);
Expand Down
30 changes: 30 additions & 0 deletions test/test_um.rb
Original file line number Diff line number Diff line change
Expand Up @@ -963,3 +963,33 @@ def test_shift_shift_1
end
end

class OpenTest < UMBaseTest
PATH = '/tmp/um_open_test'

def setup
super
FileUtils.rm(PATH, force: true)
end

def test_open
fd = machine.open(PATH, UM::O_CREAT | UM::O_WRONLY)
assert_kind_of Integer, fd
assert File.file?(PATH)

machine.write(fd, 'foo')
machine.close(fd)

assert_equal 'foo', IO.read(PATH)
end

def test_open_with_block
res = machine.open(PATH, UM::O_CREAT | UM::O_WRONLY) do |fd|
machine.write(fd, 'bar')
fd
end

assert_kind_of Integer, res
assert_raises(Errno::EBADF) { machine.close(res) }
assert_equal 'bar', IO.read(PATH)
end
end

0 comments on commit a6c88da

Please sign in to comment.