Class: Event::Backend::KQueue
- Inherits:
-
Object
- Object
- Event::Backend::KQueue
- Defined in:
- ext/event/backend/kqueue.c
Instance Method Summary collapse
- #initialize(loop) ⇒ Object constructor
- #io_wait(fiber, io, events) ⇒ Object
- #select(duration) ⇒ Object
Constructor Details
#initialize(loop) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'ext/event/backend/kqueue.c', line 81
VALUE Event_Backend_KQueue_initialize(VALUE self, VALUE loop) {
struct Event_Backend_KQueue *data = NULL;
TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
data->loop = loop;
int result = kqueue();
if (result == -1) {
rb_sys_fail("kqueue");
} else {
ioctl(result, FIOCLEX);
data->descriptor = result;
rb_update_max_fd(data->descriptor);
}
return self;
}
|
Instance Method Details
#io_wait(fiber, io, events) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'ext/event/backend/kqueue.c', line 122
VALUE Event_Backend_KQueue_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE events) {
struct Event_Backend_KQueue *data = NULL;
TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
struct kevent event = {0};
int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
event.ident = descriptor;
event.filter = kqueue_filters_from_events(events);
event.flags = EV_ADD | EV_ENABLE | EV_ONESHOT;
event.udata = (void*)fiber;
// A better approach is to batch all changes:
int result = kevent(data->descriptor, &event, 1, NULL, 0, NULL);
if (result == -1) {
rb_sys_fail("kevent");
}
VALUE result = rb_funcall(data->loop, id_transfer, 0);
return INT2NUM(events_from_kqueue_filter(NUM2INT(result)));
}
|
#select(duration) ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'ext/event/backend/kqueue.c', line 172
VALUE Event_Backend_KQueue_select(VALUE self, VALUE duration) {
struct Event_Backend_KQueue *data = NULL;
TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
struct kevent events[KQUEUE_MAX_EVENTS];
struct timespec storage;
int count = kevent(data->descriptor, NULL, 0, events, KQUEUE_MAX_EVENTS, make_timeout(duration, &storage));
if (count == -1) {
rb_sys_fail("kevent");
}
for (int i = 0; i < count; i += 1) {
VALUE fiber = (VALUE)events[i].udata;
VALUE result = INT2NUM(events[i].filter);
rb_funcall(fiber, id_transfer, 1, result);
}
return INT2NUM(count);
}
|