Class: Event::Backend::KQueue
- Inherits:
-
Object
- Object
- Event::Backend::KQueue
- Defined in:
- ext/event/backend/kqueue.c
Instance Method Summary collapse
- #close ⇒ Object
- #initialize(loop) ⇒ Object constructor
- #io_wait(fiber, io, events) ⇒ Object
- #select(duration) ⇒ Object
Constructor Details
#initialize(loop) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'ext/event/backend/kqueue.c', line 87 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
#close ⇒ Object
106 107 108 109 110 111 112 113 |
# File 'ext/event/backend/kqueue.c', line 106 VALUE Event_Backend_KQueue_close(VALUE self) { struct Event_Backend_KQueue *data = NULL; TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data); close_internal(data); return Qnil; } |
#io_wait(fiber, io, events) ⇒ Object
208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'ext/event/backend/kqueue.c', line 208 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); int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0)); struct io_wait_arguments io_wait_arguments = { .events = io_add_filters(data->descriptor, descriptor, NUM2INT(events), fiber), .data = data, .descriptor = descriptor, }; return rb_rescue(io_wait_transfer, (VALUE)&io_wait_arguments, io_wait_rescue, (VALUE)&io_wait_arguments); } |
#select(duration) ⇒ Object
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'ext/event/backend/kqueue.c', line 291 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 select_arguments arguments = { .data = data, .count = KQUEUE_MAX_EVENTS, .storage = { .tv_sec = 0, .tv_nsec = 0 } }; // We break this implementation into two parts. // (1) count = kevent(..., timeout = 0) // (2) without gvl: kevent(..., timeout = 0) if count == 0 and timeout != 0 // This allows us to avoid releasing and reacquiring the GVL. // Non-comprehensive testing shows this gives a 1.5x speedup. arguments.timeout = &arguments.storage; // First do the syscall with no timeout to get any immediately available events: select_internal_with_gvl(&arguments); // If there were no pending events, if we have a timeout, wait for more events: if (arguments.count == 0) { arguments.timeout = make_timeout(duration, &arguments.storage); if (!timeout_nonblocking(arguments.timeout)) { arguments.count = KQUEUE_MAX_EVENTS; select_internal_without_gvl(&arguments); } } for (int i = 0; i < arguments.count; i += 1) { VALUE fiber = (VALUE)arguments.events[i].udata; VALUE result = INT2NUM(arguments.events[i].filter); rb_funcall(fiber, id_transfer, 1, result); } return INT2NUM(arguments.count); } |