Skip to content

Commit

Permalink
Correctly add write barriers for heap-allocated ready list.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Oct 3, 2024
1 parent 93ea5ba commit bef8e91
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 10 deletions.
6 changes: 3 additions & 3 deletions ext/io/event/selector/epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ static const rb_data_type_t IO_Event_Selector_EPoll_Type = {
.dsize = IO_Event_Selector_EPoll_Type_size,
},
.data = NULL,
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

inline static
Expand Down Expand Up @@ -333,7 +333,7 @@ VALUE IO_Event_Selector_EPoll_allocate(VALUE self) {
struct IO_Event_Selector_EPoll *selector = NULL;
VALUE instance = TypedData_Make_Struct(self, struct IO_Event_Selector_EPoll, &IO_Event_Selector_EPoll_Type, selector);

IO_Event_Selector_initialize(&selector->backend, Qnil);
IO_Event_Selector_initialize(&selector->backend, self, Qnil);
selector->descriptor = -1;
selector->blocked = 0;

Expand Down Expand Up @@ -363,7 +363,7 @@ VALUE IO_Event_Selector_EPoll_initialize(VALUE self, VALUE loop) {
struct IO_Event_Selector_EPoll *selector = NULL;
TypedData_Get_Struct(self, struct IO_Event_Selector_EPoll, &IO_Event_Selector_EPoll_Type, selector);

IO_Event_Selector_initialize(&selector->backend, loop);
IO_Event_Selector_initialize(&selector->backend, self, loop);
int result = epoll_create1(EPOLL_CLOEXEC);

if (result == -1) {
Expand Down
6 changes: 3 additions & 3 deletions ext/io/event/selector/kqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ static const rb_data_type_t IO_Event_Selector_KQueue_Type = {
.dsize = IO_Event_Selector_KQueue_Type_size,
},
.data = NULL,
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

inline static
Expand Down Expand Up @@ -307,7 +307,7 @@ VALUE IO_Event_Selector_KQueue_allocate(VALUE self) {
struct IO_Event_Selector_KQueue *selector = NULL;
VALUE instance = TypedData_Make_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, selector);

IO_Event_Selector_initialize(&selector->backend, Qnil);
IO_Event_Selector_initialize(&selector->backend, self, Qnil);
selector->descriptor = -1;
selector->blocked = 0;

Expand Down Expand Up @@ -340,7 +340,7 @@ VALUE IO_Event_Selector_KQueue_initialize(VALUE self, VALUE loop) {
struct IO_Event_Selector_KQueue *selector = NULL;
TypedData_Get_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, selector);

IO_Event_Selector_initialize(&selector->backend, loop);
IO_Event_Selector_initialize(&selector->backend, self, loop);
int result = kqueue();

if (result == -1) {
Expand Down
2 changes: 2 additions & 0 deletions ext/io/event/selector/selector.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,9 @@ void IO_Event_Selector_queue_push(struct IO_Event_Selector *backend, VALUE fiber
waiting->head = NULL;
waiting->tail = NULL;
waiting->flags = IO_EVENT_SELECTOR_QUEUE_INTERNAL;

waiting->fiber = fiber;
RB_OBJ_WRITTEN(backend->self, Qundef, fiber);

queue_push(backend, waiting);
}
Expand Down
18 changes: 17 additions & 1 deletion ext/io/event/selector/selector.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct IO_Event_Selector_Queue {
};

struct IO_Event_Selector {
VALUE self;
VALUE loop;

struct IO_Event_Selector_Queue *free;
Expand All @@ -106,16 +107,24 @@ struct IO_Event_Selector {
};

static inline
void IO_Event_Selector_initialize(struct IO_Event_Selector *backend, VALUE loop) {
void IO_Event_Selector_initialize(struct IO_Event_Selector *backend, VALUE self, VALUE loop) {
backend->self = self;
backend->loop = loop;
backend->waiting = NULL;
backend->ready = NULL;
}

static inline
void IO_Event_Selector_mark(struct IO_Event_Selector *backend) {
rb_gc_mark_movable(backend->self);
rb_gc_mark_movable(backend->loop);

struct IO_Event_Selector_Queue *waiting = backend->waiting;
while (waiting) {
rb_gc_mark_movable(waiting->fiber);
waiting = waiting->head;
}

struct IO_Event_Selector_Queue *ready = backend->ready;
while (ready) {
rb_gc_mark_movable(ready->fiber);
Expand All @@ -125,8 +134,15 @@ void IO_Event_Selector_mark(struct IO_Event_Selector *backend) {

static inline
void IO_Event_Selector_compact(struct IO_Event_Selector *backend) {
backend->self = rb_gc_location(backend->self);
backend->loop = rb_gc_location(backend->loop);

struct IO_Event_Selector_Queue *waiting = backend->waiting;
while (waiting) {
waiting->fiber = rb_gc_location(waiting->fiber);
waiting = waiting->head;
}

struct IO_Event_Selector_Queue *ready = backend->ready;
while (ready) {
ready->fiber = rb_gc_location(ready->fiber);
Expand Down
6 changes: 3 additions & 3 deletions ext/io/event/selector/uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ static const rb_data_type_t IO_Event_Selector_URing_Type = {
.dsize = IO_Event_Selector_URing_Type_size,
},
.data = NULL,
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};

inline static
Expand Down Expand Up @@ -228,7 +228,7 @@ VALUE IO_Event_Selector_URing_allocate(VALUE self) {
struct IO_Event_Selector_URing *selector = NULL;
VALUE instance = TypedData_Make_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, selector);

IO_Event_Selector_initialize(&selector->backend, Qnil);
IO_Event_Selector_initialize(&selector->backend, self, Qnil);
selector->ring.ring_fd = -1;

selector->pending = 0;
Expand All @@ -249,7 +249,7 @@ VALUE IO_Event_Selector_URing_initialize(VALUE self, VALUE loop) {
struct IO_Event_Selector_URing *selector = NULL;
TypedData_Get_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, selector);

IO_Event_Selector_initialize(&selector->backend, loop);
IO_Event_Selector_initialize(&selector->backend, self, loop);
int result = io_uring_queue_init(URING_ENTRIES, &selector->ring, 0);

if (result < 0) {
Expand Down

0 comments on commit bef8e91

Please sign in to comment.