io-event 1.6.5 → 1.6.7
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/ext/extconf.rb +22 -12
- data/ext/io/event/selector/array.h +4 -0
- data/ext/io/event/selector/epoll.c +3 -3
- data/ext/io/event/selector/kqueue.c +3 -3
- data/ext/io/event/selector/selector.c +20 -1
- data/ext/io/event/selector/selector.h +9 -4
- data/ext/io/event/selector/uring.c +3 -3
- data/lib/io/event/debug/selector.rb +3 -3
- data/lib/io/event/interrupt.rb +2 -2
- data/lib/io/event/selector/nonblock.rb +2 -2
- data/lib/io/event/selector/select.rb +6 -2
- data/lib/io/event/selector.rb +5 -5
- data/lib/io/event/support.rb +11 -2
- data/lib/io/event/timers.rb +1 -1
- data/lib/io/event/version.rb +1 -1
- data/lib/io/event.rb +5 -5
- data/license.md +1 -0
- data/readme.md +3 -3
- data.tar.gz.sig +0 -0
- metadata +7 -4
- metadata.gz.sig +0 -0
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 53bb3bfd2bffe7db8d43a4dd2d136a2ec9b62df30b78f90894b816a33a855765
         | 
| 4 | 
            +
              data.tar.gz: 151b806b36724b5f210e28a59949ca4c4550a79a15e29174b6c7bdf9e5e4ba7d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: ef219c25c4acc91a0fb56bfb3a36275b131d71e594682c0f6d383e0d66657ecd286b711bf90323e661d83be0961fa0baaf4368c0e3c2309b0e3376f9c006fefc
         | 
| 7 | 
            +
              data.tar.gz: 56112593370c044238ee9198ef1ee608e0be69507a37dd380c9a54d03948074b1ec89e692308f4b6e58096730398be1fd2a3efee4c9e055977e543058716aaec
         | 
    
        checksums.yaml.gz.sig
    CHANGED
    
    | Binary file | 
    
        data/ext/extconf.rb
    CHANGED
    
    | @@ -2,21 +2,23 @@ | |
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 3 |  | 
| 4 4 | 
             
            # Released under the MIT License.
         | 
| 5 | 
            -
            # Copyright, 2021- | 
| 5 | 
            +
            # Copyright, 2021-2024, by Samuel Williams.
         | 
| 6 6 | 
             
            # Copyright, 2023, by Math Ieu.
         | 
| 7 7 |  | 
| 8 8 | 
             
            return if RUBY_DESCRIPTION =~ /jruby/
         | 
| 9 9 |  | 
| 10 | 
            -
            require  | 
| 10 | 
            +
            require "mkmf"
         | 
| 11 11 |  | 
| 12 12 | 
             
            gem_name = File.basename(__dir__)
         | 
| 13 | 
            -
            extension_name =  | 
| 13 | 
            +
            extension_name = "IO_Event"
         | 
| 14 14 |  | 
| 15 15 | 
             
            # dir_config(extension_name)
         | 
| 16 16 |  | 
| 17 17 | 
             
            $CFLAGS << " -Wall -Wno-unknown-pragmas -std=c99"
         | 
| 18 18 |  | 
| 19 | 
            -
            if ENV.key?( | 
| 19 | 
            +
            if ENV.key?("RUBY_DEBUG")
         | 
| 20 | 
            +
            	$stderr.puts "Enabling debug mode..."
         | 
| 21 | 
            +
            	
         | 
| 20 22 | 
             
            	$CFLAGS << " -DRUBY_DEBUG -O0"
         | 
| 21 23 | 
             
            end
         | 
| 22 24 |  | 
| @@ -24,24 +26,24 @@ $srcs = ["io/event/event.c", "io/event/selector/selector.c"] | |
| 24 26 | 
             
            $VPATH << "$(srcdir)/io/event"
         | 
| 25 27 | 
             
            $VPATH << "$(srcdir)/io/event/selector"
         | 
| 26 28 |  | 
| 27 | 
            -
            have_func( | 
| 28 | 
            -
            have_func( | 
| 29 | 
            +
            have_func("rb_ext_ractor_safe")
         | 
| 30 | 
            +
            have_func("&rb_fiber_transfer")
         | 
| 29 31 |  | 
| 30 | 
            -
            if have_library( | 
| 32 | 
            +
            if have_library("uring") and have_header("liburing.h")
         | 
| 31 33 | 
             
            	$srcs << "io/event/selector/uring.c"
         | 
| 32 34 | 
             
            end
         | 
| 33 35 |  | 
| 34 | 
            -
            if have_header( | 
| 36 | 
            +
            if have_header("sys/epoll.h")
         | 
| 35 37 | 
             
            	$srcs << "io/event/selector/epoll.c"
         | 
| 36 38 | 
             
            end
         | 
| 37 39 |  | 
| 38 | 
            -
            if have_header( | 
| 40 | 
            +
            if have_header("sys/event.h")
         | 
| 39 41 | 
             
            	$srcs << "io/event/selector/kqueue.c"
         | 
| 40 42 | 
             
            end
         | 
| 41 43 |  | 
| 42 | 
            -
            have_header( | 
| 44 | 
            +
            have_header("sys/wait.h")
         | 
| 43 45 |  | 
| 44 | 
            -
            have_header( | 
| 46 | 
            +
            have_header("sys/eventfd.h")
         | 
| 45 47 | 
             
            $srcs << "io/event/interrupt.c"
         | 
| 46 48 |  | 
| 47 49 | 
             
            have_func("rb_io_descriptor")
         | 
| @@ -50,7 +52,15 @@ have_func("rb_fiber_current") | |
| 50 52 | 
             
            have_func("&rb_fiber_raise")
         | 
| 51 53 | 
             
            have_func("epoll_pwait2")
         | 
| 52 54 |  | 
| 53 | 
            -
            have_header( | 
| 55 | 
            +
            have_header("ruby/io/buffer.h")
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            if ENV.key?("RUBY_SANITIZE")
         | 
| 58 | 
            +
            	$stderr.puts "Enabling sanitizers..."
         | 
| 59 | 
            +
            	
         | 
| 60 | 
            +
            	# Add address and undefined behaviour sanitizers:
         | 
| 61 | 
            +
            	$CFLAGS << " -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer"
         | 
| 62 | 
            +
            	$LDFLAGS << " -fsanitize=address -fsanitize=undefined"
         | 
| 63 | 
            +
            end
         | 
| 54 64 |  | 
| 55 65 | 
             
            create_header
         | 
| 56 66 |  | 
| @@ -29,6 +29,8 @@ inline static void IO_Event_Array_allocate(struct IO_Event_Array *array, size_t | |
| 29 29 | 
             
            {
         | 
| 30 30 | 
             
            	if (count) {
         | 
| 31 31 | 
             
            		array->base = (void**)calloc(count, sizeof(void*));
         | 
| 32 | 
            +
            		assert(array->base);
         | 
| 33 | 
            +
            		
         | 
| 32 34 | 
             
            		array->count = count;
         | 
| 33 35 | 
             
            	} else {
         | 
| 34 36 | 
             
            		array->base = NULL;
         | 
| @@ -51,6 +53,7 @@ inline static void IO_Event_Array_free(struct IO_Event_Array *array) | |
| 51 53 | 
             
            		void *element = array->base[i];
         | 
| 52 54 | 
             
            		if (element) {
         | 
| 53 55 | 
             
            			array->element_free(element);
         | 
| 56 | 
            +
            			
         | 
| 54 57 | 
             
            			free(element);
         | 
| 55 58 | 
             
            		}
         | 
| 56 59 | 
             
            	}
         | 
| @@ -107,6 +110,7 @@ inline static void* IO_Event_Array_lookup(struct IO_Event_Array *array, size_t i | |
| 107 110 | 
             
            	// Allocate the element if it doesn't exist:
         | 
| 108 111 | 
             
            	if (*element == NULL) {
         | 
| 109 112 | 
             
            		*element = malloc(array->element_size);
         | 
| 113 | 
            +
            		assert(*element);
         | 
| 110 114 |  | 
| 111 115 | 
             
            		if (array->element_initialize) {
         | 
| 112 116 | 
             
            			array->element_initialize(*element);
         | 
| @@ -184,7 +184,7 @@ static const rb_data_type_t IO_Event_Selector_EPoll_Type = { | |
| 184 184 | 
             
            		.dsize = IO_Event_Selector_EPoll_Type_size,
         | 
| 185 185 | 
             
            	},
         | 
| 186 186 | 
             
            	.data = NULL,
         | 
| 187 | 
            -
            	.flags = RUBY_TYPED_FREE_IMMEDIATELY,
         | 
| 187 | 
            +
            	.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
         | 
| 188 188 | 
             
            };
         | 
| 189 189 |  | 
| 190 190 | 
             
            inline static
         | 
| @@ -333,7 +333,7 @@ VALUE IO_Event_Selector_EPoll_allocate(VALUE self) { | |
| 333 333 | 
             
            	struct IO_Event_Selector_EPoll *selector = NULL;
         | 
| 334 334 | 
             
            	VALUE instance = TypedData_Make_Struct(self, struct IO_Event_Selector_EPoll, &IO_Event_Selector_EPoll_Type, selector);
         | 
| 335 335 |  | 
| 336 | 
            -
            	IO_Event_Selector_initialize(&selector->backend, Qnil);
         | 
| 336 | 
            +
            	IO_Event_Selector_initialize(&selector->backend, self, Qnil);
         | 
| 337 337 | 
             
            	selector->descriptor = -1;
         | 
| 338 338 | 
             
            	selector->blocked = 0;
         | 
| 339 339 |  | 
| @@ -363,7 +363,7 @@ VALUE IO_Event_Selector_EPoll_initialize(VALUE self, VALUE loop) { | |
| 363 363 | 
             
            	struct IO_Event_Selector_EPoll *selector = NULL;
         | 
| 364 364 | 
             
            	TypedData_Get_Struct(self, struct IO_Event_Selector_EPoll, &IO_Event_Selector_EPoll_Type, selector);
         | 
| 365 365 |  | 
| 366 | 
            -
            	IO_Event_Selector_initialize(&selector->backend, loop);
         | 
| 366 | 
            +
            	IO_Event_Selector_initialize(&selector->backend, self, loop);
         | 
| 367 367 | 
             
            	int result = epoll_create1(EPOLL_CLOEXEC);
         | 
| 368 368 |  | 
| 369 369 | 
             
            	if (result == -1) {
         | 
| @@ -183,7 +183,7 @@ static const rb_data_type_t IO_Event_Selector_KQueue_Type = { | |
| 183 183 | 
             
            		.dsize = IO_Event_Selector_KQueue_Type_size,
         | 
| 184 184 | 
             
            	},
         | 
| 185 185 | 
             
            	.data = NULL,
         | 
| 186 | 
            -
            	.flags = RUBY_TYPED_FREE_IMMEDIATELY,
         | 
| 186 | 
            +
            	.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
         | 
| 187 187 | 
             
            };
         | 
| 188 188 |  | 
| 189 189 | 
             
            inline static
         | 
| @@ -307,7 +307,7 @@ VALUE IO_Event_Selector_KQueue_allocate(VALUE self) { | |
| 307 307 | 
             
            	struct IO_Event_Selector_KQueue *selector = NULL;
         | 
| 308 308 | 
             
            	VALUE instance = TypedData_Make_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, selector);
         | 
| 309 309 |  | 
| 310 | 
            -
            	IO_Event_Selector_initialize(&selector->backend, Qnil);
         | 
| 310 | 
            +
            	IO_Event_Selector_initialize(&selector->backend, self, Qnil);
         | 
| 311 311 | 
             
            	selector->descriptor = -1;
         | 
| 312 312 | 
             
            	selector->blocked = 0;
         | 
| 313 313 |  | 
| @@ -340,7 +340,7 @@ VALUE IO_Event_Selector_KQueue_initialize(VALUE self, VALUE loop) { | |
| 340 340 | 
             
            	struct IO_Event_Selector_KQueue *selector = NULL;
         | 
| 341 341 | 
             
            	TypedData_Get_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, selector);
         | 
| 342 342 |  | 
| 343 | 
            -
            	IO_Event_Selector_initialize(&selector->backend, loop);
         | 
| 343 | 
            +
            	IO_Event_Selector_initialize(&selector->backend, self, loop);
         | 
| 344 344 | 
             
            	int result = kqueue();
         | 
| 345 345 |  | 
| 346 346 | 
             
            	if (result == -1) {
         | 
| @@ -172,24 +172,35 @@ static void queue_pop(struct IO_Event_Selector *backend, struct IO_Event_Selecto | |
| 172 172 | 
             
            	if (waiting->head) {
         | 
| 173 173 | 
             
            		waiting->head->tail = waiting->tail;
         | 
| 174 174 | 
             
            	} else {
         | 
| 175 | 
            +
            		// We must have been at the head of the queue:
         | 
| 175 176 | 
             
            		backend->waiting = waiting->tail;
         | 
| 176 177 | 
             
            	}
         | 
| 177 178 |  | 
| 178 179 | 
             
            	if (waiting->tail) {
         | 
| 179 180 | 
             
            		waiting->tail->head = waiting->head;
         | 
| 180 181 | 
             
            	} else {
         | 
| 182 | 
            +
            		// We must have been at the tail of the queue:
         | 
| 181 183 | 
             
            		backend->ready = waiting->head;
         | 
| 182 184 | 
             
            	}
         | 
| 185 | 
            +
            	
         | 
| 186 | 
            +
            	waiting->head = NULL;
         | 
| 187 | 
            +
            	waiting->tail = NULL;
         | 
| 183 188 | 
             
            }
         | 
| 184 189 |  | 
| 185 190 | 
             
            static void queue_push(struct IO_Event_Selector *backend, struct IO_Event_Selector_Queue *waiting) {
         | 
| 191 | 
            +
            	assert(waiting->head == NULL);
         | 
| 192 | 
            +
            	assert(waiting->tail == NULL);
         | 
| 193 | 
            +
            	
         | 
| 186 194 | 
             
            	if (backend->waiting) {
         | 
| 195 | 
            +
            		// If there was an item in the queue already, we shift it along:
         | 
| 187 196 | 
             
            		backend->waiting->head = waiting;
         | 
| 188 197 | 
             
            		waiting->tail = backend->waiting;
         | 
| 189 198 | 
             
            	} else {
         | 
| 199 | 
            +
            		// If the queue was empty, we update the tail too:
         | 
| 190 200 | 
             
            		backend->ready = waiting;
         | 
| 191 201 | 
             
            	}
         | 
| 192 202 |  | 
| 203 | 
            +
            	// We always push to the front/head:
         | 
| 193 204 | 
             
            	backend->waiting = waiting;
         | 
| 194 205 | 
             
            }
         | 
| 195 206 |  | 
| @@ -270,11 +281,14 @@ VALUE IO_Event_Selector_raise(struct IO_Event_Selector *backend, int argc, VALUE | |
| 270 281 | 
             
            void IO_Event_Selector_queue_push(struct IO_Event_Selector *backend, VALUE fiber)
         | 
| 271 282 | 
             
            {
         | 
| 272 283 | 
             
            	struct IO_Event_Selector_Queue *waiting = malloc(sizeof(struct IO_Event_Selector_Queue));
         | 
| 284 | 
            +
            	assert(waiting);
         | 
| 273 285 |  | 
| 274 286 | 
             
            	waiting->head = NULL;
         | 
| 275 287 | 
             
            	waiting->tail = NULL;
         | 
| 276 288 | 
             
            	waiting->flags = IO_EVENT_SELECTOR_QUEUE_INTERNAL;
         | 
| 289 | 
            +
            	
         | 
| 277 290 | 
             
            	waiting->fiber = fiber;
         | 
| 291 | 
            +
            	RB_OBJ_WRITTEN(backend->self, Qundef, fiber);
         | 
| 278 292 |  | 
| 279 293 | 
             
            	queue_push(backend, waiting);
         | 
| 280 294 | 
             
            }
         | 
| @@ -283,9 +297,10 @@ static inline | |
| 283 297 | 
             
            void IO_Event_Selector_queue_pop(struct IO_Event_Selector *backend, struct IO_Event_Selector_Queue *ready)
         | 
| 284 298 | 
             
            {
         | 
| 285 299 | 
             
            	if (DEBUG) fprintf(stderr, "IO_Event_Selector_queue_pop -> %p\n", (void*)ready->fiber);
         | 
| 300 | 
            +
            	
         | 
| 286 301 | 
             
            	if (ready->flags & IO_EVENT_SELECTOR_QUEUE_FIBER) {
         | 
| 287 302 | 
             
            		IO_Event_Selector_fiber_transfer(ready->fiber, 0, NULL);
         | 
| 288 | 
            -
            	} else {
         | 
| 303 | 
            +
            	} else if (ready->flags & IO_EVENT_SELECTOR_QUEUE_INTERNAL) {
         | 
| 289 304 | 
             
            		VALUE fiber = ready->fiber;
         | 
| 290 305 | 
             
            		queue_pop(backend, ready);
         | 
| 291 306 | 
             
            		free(ready);
         | 
| @@ -293,6 +308,8 @@ void IO_Event_Selector_queue_pop(struct IO_Event_Selector *backend, struct IO_Ev | |
| 293 308 | 
             
            		if (RTEST(rb_funcall(fiber, id_alive_p, 0))) {
         | 
| 294 309 | 
             
            			rb_funcall(fiber, id_transfer, 0);
         | 
| 295 310 | 
             
            		}
         | 
| 311 | 
            +
            	} else {
         | 
| 312 | 
            +
            		rb_raise(rb_eRuntimeError, "Unknown queue type!");
         | 
| 296 313 | 
             
            	}
         | 
| 297 314 | 
             
            }
         | 
| 298 315 |  | 
| @@ -300,6 +317,8 @@ int IO_Event_Selector_queue_flush(struct IO_Event_Selector *backend) | |
| 300 317 | 
             
            {
         | 
| 301 318 | 
             
            	int count = 0;
         | 
| 302 319 |  | 
| 320 | 
            +
            	// During iteration of the queue, the same item may be re-queued. If we don't handle this correctly, we may end up in an infinite loop. So, to avoid this situation, we keep note of the current head of the queue and break the loop if we reach the same item again.
         | 
| 321 | 
            +
            	
         | 
| 303 322 | 
             
            	// Get the current tail and head of the queue:
         | 
| 304 323 | 
             
            	struct IO_Event_Selector_Queue *waiting = backend->waiting;
         | 
| 305 324 | 
             
            	if (DEBUG) fprintf(stderr, "IO_Event_Selector_queue_flush waiting = %p\n", waiting);
         | 
| @@ -95,27 +95,31 @@ struct IO_Event_Selector_Queue { | |
| 95 95 | 
             
            };
         | 
| 96 96 |  | 
| 97 97 | 
             
            struct IO_Event_Selector {
         | 
| 98 | 
            +
            	VALUE self;
         | 
| 98 99 | 
             
            	VALUE loop;
         | 
| 99 100 |  | 
| 100 101 | 
             
            	struct IO_Event_Selector_Queue *free;
         | 
| 101 102 |  | 
| 102 | 
            -
            	// Append to waiting.
         | 
| 103 | 
            +
            	// Append to waiting (front/head of queue).
         | 
| 103 104 | 
             
            	struct IO_Event_Selector_Queue *waiting;
         | 
| 104 | 
            -
            	// Process from ready.
         | 
| 105 | 
            +
            	// Process from ready (back/tail of queue).
         | 
| 105 106 | 
             
            	struct IO_Event_Selector_Queue *ready;
         | 
| 106 107 | 
             
            };
         | 
| 107 108 |  | 
| 108 109 | 
             
            static inline
         | 
| 109 | 
            -
            void IO_Event_Selector_initialize(struct IO_Event_Selector *backend, VALUE loop) {
         | 
| 110 | 
            -
            	backend-> | 
| 110 | 
            +
            void IO_Event_Selector_initialize(struct IO_Event_Selector *backend, VALUE self, VALUE loop) {
         | 
| 111 | 
            +
            	RB_OBJ_WRITE(self, &backend->self, self);
         | 
| 112 | 
            +
            	RB_OBJ_WRITE(self, &backend->loop, loop);
         | 
| 111 113 | 
             
            	backend->waiting = NULL;
         | 
| 112 114 | 
             
            	backend->ready = NULL;
         | 
| 113 115 | 
             
            }
         | 
| 114 116 |  | 
| 115 117 | 
             
            static inline
         | 
| 116 118 | 
             
            void IO_Event_Selector_mark(struct IO_Event_Selector *backend) {
         | 
| 119 | 
            +
            	rb_gc_mark_movable(backend->self);
         | 
| 117 120 | 
             
            	rb_gc_mark_movable(backend->loop);
         | 
| 118 121 |  | 
| 122 | 
            +
            	// Walk backwards through the ready queue:
         | 
| 119 123 | 
             
            	struct IO_Event_Selector_Queue *ready = backend->ready;
         | 
| 120 124 | 
             
            	while (ready) {
         | 
| 121 125 | 
             
            		rb_gc_mark_movable(ready->fiber);
         | 
| @@ -125,6 +129,7 @@ void IO_Event_Selector_mark(struct IO_Event_Selector *backend) { | |
| 125 129 |  | 
| 126 130 | 
             
            static inline
         | 
| 127 131 | 
             
            void IO_Event_Selector_compact(struct IO_Event_Selector *backend) {
         | 
| 132 | 
            +
            	backend->self = rb_gc_location(backend->self);
         | 
| 128 133 | 
             
            	backend->loop = rb_gc_location(backend->loop);
         | 
| 129 134 |  | 
| 130 135 | 
             
            	struct IO_Event_Selector_Queue *ready = backend->ready;
         | 
| @@ -152,7 +152,7 @@ static const rb_data_type_t IO_Event_Selector_URing_Type = { | |
| 152 152 | 
             
            		.dsize = IO_Event_Selector_URing_Type_size,
         | 
| 153 153 | 
             
            	},
         | 
| 154 154 | 
             
            	.data = NULL,
         | 
| 155 | 
            -
            	.flags = RUBY_TYPED_FREE_IMMEDIATELY,
         | 
| 155 | 
            +
            	.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
         | 
| 156 156 | 
             
            };
         | 
| 157 157 |  | 
| 158 158 | 
             
            inline static
         | 
| @@ -228,7 +228,7 @@ VALUE IO_Event_Selector_URing_allocate(VALUE self) { | |
| 228 228 | 
             
            	struct IO_Event_Selector_URing *selector = NULL;
         | 
| 229 229 | 
             
            	VALUE instance = TypedData_Make_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, selector);
         | 
| 230 230 |  | 
| 231 | 
            -
            	IO_Event_Selector_initialize(&selector->backend, Qnil);
         | 
| 231 | 
            +
            	IO_Event_Selector_initialize(&selector->backend, self, Qnil);
         | 
| 232 232 | 
             
            	selector->ring.ring_fd = -1;
         | 
| 233 233 |  | 
| 234 234 | 
             
            	selector->pending = 0;
         | 
| @@ -249,7 +249,7 @@ VALUE IO_Event_Selector_URing_initialize(VALUE self, VALUE loop) { | |
| 249 249 | 
             
            	struct IO_Event_Selector_URing *selector = NULL;
         | 
| 250 250 | 
             
            	TypedData_Get_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, selector);
         | 
| 251 251 |  | 
| 252 | 
            -
            	IO_Event_Selector_initialize(&selector->backend, loop);
         | 
| 252 | 
            +
            	IO_Event_Selector_initialize(&selector->backend, self, loop);
         | 
| 253 253 | 
             
            	int result = io_uring_queue_init(URING_ENTRIES, &selector->ring, 0);
         | 
| 254 254 |  | 
| 255 255 | 
             
            	if (result < 0) {
         | 
| @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            # Released under the MIT License.
         | 
| 4 4 | 
             
            # Copyright, 2021-2024, by Samuel Williams.
         | 
| 5 5 |  | 
| 6 | 
            -
            require_relative  | 
| 6 | 
            +
            require_relative "../support"
         | 
| 7 7 |  | 
| 8 8 | 
             
            module IO::Event
         | 
| 9 9 | 
             
            	module Debug
         | 
| @@ -12,8 +12,8 @@ module IO::Event | |
| 12 12 | 
             
            			def self.wrap(selector, env = ENV)
         | 
| 13 13 | 
             
            				log = nil
         | 
| 14 14 |  | 
| 15 | 
            -
            				if log_path = env[ | 
| 16 | 
            -
            					log = File.open(log_path,  | 
| 15 | 
            +
            				if log_path = env["IO_EVENT_DEBUG_SELECTOR_LOG"]
         | 
| 16 | 
            +
            					log = File.open(log_path, "w")
         | 
| 17 17 | 
             
            				end
         | 
| 18 18 |  | 
| 19 19 | 
             
            				return self.new(selector, log: log)
         | 
    
        data/lib/io/event/interrupt.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Released under the MIT License.
         | 
| 4 | 
            -
            # Copyright, 2021- | 
| 4 | 
            +
            # Copyright, 2021-2024, by Samuel Williams.
         | 
| 5 5 |  | 
| 6 6 | 
             
            module IO::Event
         | 
| 7 7 | 
             
            	# A thread safe synchronisation primative.
         | 
| @@ -27,7 +27,7 @@ module IO::Event | |
| 27 27 |  | 
| 28 28 | 
             
            		# Send a sigle byte interrupt.
         | 
| 29 29 | 
             
            		def signal
         | 
| 30 | 
            -
            			@output.write( | 
| 30 | 
            +
            			@output.write(".")
         | 
| 31 31 | 
             
            			@output.flush
         | 
| 32 32 | 
             
            		rescue IOError
         | 
| 33 33 | 
             
            			# Ignore.
         | 
| @@ -4,8 +4,8 @@ | |
| 4 4 | 
             
            # Copyright, 2021-2024, by Samuel Williams.
         | 
| 5 5 | 
             
            # Copyright, 2023, by Math Ieu.
         | 
| 6 6 |  | 
| 7 | 
            -
            require_relative  | 
| 8 | 
            -
            require_relative  | 
| 7 | 
            +
            require_relative "../interrupt"
         | 
| 8 | 
            +
            require_relative "../support"
         | 
| 9 9 |  | 
| 10 10 | 
             
            module IO::Event
         | 
| 11 11 | 
             
            	module Selector
         | 
| @@ -168,6 +168,8 @@ module IO::Event | |
| 168 168 | 
             
            			if Support.fiber_scheduler_v3?
         | 
| 169 169 | 
             
            				# Ruby 3.3+, full IO::Buffer support.
         | 
| 170 170 |  | 
| 171 | 
            +
            				# Read from the given IO to the buffer.
         | 
| 172 | 
            +
            				#
         | 
| 171 173 | 
             
            				# @parameter length [Integer] The minimum number of bytes to read.
         | 
| 172 174 | 
             
            				# @parameter offset [Integer] The offset into the buffer to read to.
         | 
| 173 175 | 
             
            				def io_read(fiber, io, buffer, length, offset = 0)
         | 
| @@ -196,6 +198,8 @@ module IO::Event | |
| 196 198 | 
             
            					return total
         | 
| 197 199 | 
             
            				end
         | 
| 198 200 |  | 
| 201 | 
            +
            				# Write to the given IO from the buffer.
         | 
| 202 | 
            +
            				#
         | 
| 199 203 | 
             
            				# @parameter length [Integer] The minimum number of bytes to write.
         | 
| 200 204 | 
             
            				# @parameter offset [Integer] The offset into the buffer to write from.
         | 
| 201 205 | 
             
            				def io_write(fiber, io, buffer, length, offset = 0)
         | 
    
        data/lib/io/event/selector.rb
    CHANGED
    
    | @@ -3,14 +3,14 @@ | |
| 3 3 | 
             
            # Released under the MIT License.
         | 
| 4 4 | 
             
            # Copyright, 2021-2024, by Samuel Williams.
         | 
| 5 5 |  | 
| 6 | 
            -
            require_relative  | 
| 7 | 
            -
            require_relative  | 
| 8 | 
            -
            require_relative  | 
| 6 | 
            +
            require_relative "selector/select"
         | 
| 7 | 
            +
            require_relative "debug/selector"
         | 
| 8 | 
            +
            require_relative "support"
         | 
| 9 9 |  | 
| 10 10 | 
             
            module IO::Event
         | 
| 11 11 | 
             
            	module Selector
         | 
| 12 12 | 
             
            		def self.default(env = ENV)
         | 
| 13 | 
            -
            			if name = env[ | 
| 13 | 
            +
            			if name = env["IO_EVENT_SELECTOR"]&.to_sym
         | 
| 14 14 | 
             
            				return const_get(name)
         | 
| 15 15 | 
             
            			end
         | 
| 16 16 |  | 
| @@ -28,7 +28,7 @@ module IO::Event | |
| 28 28 | 
             
            		def self.new(loop, env = ENV)
         | 
| 29 29 | 
             
            			selector = default(env).new(loop)
         | 
| 30 30 |  | 
| 31 | 
            -
            			if debug = env[ | 
| 31 | 
            +
            			if debug = env["IO_EVENT_DEBUG_SELECTOR"]
         | 
| 32 32 | 
             
            				selector = Debug::Selector.wrap(selector, env)
         | 
| 33 33 | 
             
            			end
         | 
| 34 34 |  | 
    
        data/lib/io/event/support.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Released under the MIT License.
         | 
| 4 | 
            -
            # Copyright, 2022- | 
| 4 | 
            +
            # Copyright, 2022-2024, by Samuel Williams.
         | 
| 5 5 |  | 
| 6 6 | 
             
            class IO
         | 
| 7 7 | 
             
            	module Event
         | 
| @@ -10,14 +10,23 @@ class IO | |
| 10 10 | 
             
            				IO.const_defined?(:Buffer)
         | 
| 11 11 | 
             
            			end
         | 
| 12 12 |  | 
| 13 | 
            +
            			# To be removed on 31 Mar 2025.
         | 
| 13 14 | 
             
            			def self.fiber_scheduler_v1?
         | 
| 14 | 
            -
            				IO.const_defined?(:Buffer) | 
| 15 | 
            +
            				IO.const_defined?(:Buffer)
         | 
| 15 16 | 
             
            			end
         | 
| 16 17 |  | 
| 18 | 
            +
            			# To be removed on 31 Mar 2026.
         | 
| 17 19 | 
             
            			def self.fiber_scheduler_v2?
         | 
| 20 | 
            +
            				# Some interface changes were back-ported incorrectly:
         | 
| 21 | 
            +
            				# https://github.com/ruby/ruby/pull/10778
         | 
| 22 | 
            +
            				# Specifically "Improvements to IO::Buffer read/write/pread/pwrite."
         | 
| 23 | 
            +
            				# Missing correct size calculation.
         | 
| 24 | 
            +
            				return false if RUBY_VERSION >= "3.2.5"
         | 
| 25 | 
            +
            				
         | 
| 18 26 | 
             
            				IO.const_defined?(:Buffer) and Fiber.respond_to?(:blocking) and IO::Buffer.instance_method(:read).arity == -1
         | 
| 19 27 | 
             
            			end
         | 
| 20 28 |  | 
| 29 | 
            +
            			# To become the default 31 Mar 2026.
         | 
| 21 30 | 
             
            			def self.fiber_scheduler_v3?
         | 
| 22 31 | 
             
            				if fiber_scheduler_v2?
         | 
| 23 32 | 
             
            					return true if RUBY_VERSION >= "3.3"
         | 
    
        data/lib/io/event/timers.rb
    CHANGED
    
    
    
        data/lib/io/event/version.rb
    CHANGED
    
    
    
        data/lib/io/event.rb
    CHANGED
    
    | @@ -3,13 +3,13 @@ | |
| 3 3 | 
             
            # Released under the MIT License.
         | 
| 4 4 | 
             
            # Copyright, 2021-2024, by Samuel Williams.
         | 
| 5 5 |  | 
| 6 | 
            -
            require_relative  | 
| 7 | 
            -
            require_relative  | 
| 8 | 
            -
            require_relative  | 
| 6 | 
            +
            require_relative "event/version"
         | 
| 7 | 
            +
            require_relative "event/selector"
         | 
| 8 | 
            +
            require_relative "event/timers"
         | 
| 9 9 |  | 
| 10 10 | 
             
            begin
         | 
| 11 | 
            -
            	require  | 
| 11 | 
            +
            	require "IO_Event"
         | 
| 12 12 | 
             
            rescue LoadError => error
         | 
| 13 13 | 
             
            	warn "Could not load native event selector: #{error}"
         | 
| 14 | 
            -
            	require_relative  | 
| 14 | 
            +
            	require_relative "event/selector/nonblock"
         | 
| 15 15 | 
             
            end
         | 
    
        data/license.md
    CHANGED
    
    | @@ -8,6 +8,7 @@ Copyright, 2022, by Alex Matchneer. | |
| 8 8 | 
             
            Copyright, 2022, by Bruno Sutic.  
         | 
| 9 9 | 
             
            Copyright, 2023, by Math Ieu.  
         | 
| 10 10 | 
             
            Copyright, 2024, by Pavel Rosický.  
         | 
| 11 | 
            +
            Copyright, 2024, by Anthony Ross.  
         | 
| 11 12 |  | 
| 12 13 | 
             
            Permission is hereby granted, free of charge, to any person obtaining a copy
         | 
| 13 14 | 
             
            of this software and associated documentation files (the "Software"), to deal
         | 
    
        data/readme.md
    CHANGED
    
    | @@ -24,8 +24,8 @@ We welcome contributions to this project. | |
| 24 24 |  | 
| 25 25 | 
             
            ### Developer Certificate of Origin
         | 
| 26 26 |  | 
| 27 | 
            -
             | 
| 27 | 
            +
            In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
         | 
| 28 28 |  | 
| 29 | 
            -
            ###  | 
| 29 | 
            +
            ### Community Guidelines
         | 
| 30 30 |  | 
| 31 | 
            -
            This project is  | 
| 31 | 
            +
            This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
         | 
    
        data.tar.gz.sig
    CHANGED
    
    | Binary file | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: io-event
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.6. | 
| 4 | 
            +
              version: 1.6.7
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Samuel Williams
         | 
| @@ -10,6 +10,7 @@ authors: | |
| 10 10 | 
             
            - Benoit Daloze
         | 
| 11 11 | 
             
            - Bruno Sutic
         | 
| 12 12 | 
             
            - Alex Matchneer
         | 
| 13 | 
            +
            - Anthony Ross
         | 
| 13 14 | 
             
            - Delton Ding
         | 
| 14 15 | 
             
            - Pavel Rosický
         | 
| 15 16 | 
             
            autorequire:
         | 
| @@ -44,7 +45,7 @@ cert_chain: | |
| 44 45 | 
             
              Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
         | 
| 45 46 | 
             
              voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
         | 
| 46 47 | 
             
              -----END CERTIFICATE-----
         | 
| 47 | 
            -
            date: 2024- | 
| 48 | 
            +
            date: 2024-10-03 00:00:00.000000000 Z
         | 
| 48 49 | 
             
            dependencies: []
         | 
| 49 50 | 
             
            description:
         | 
| 50 51 | 
             
            email:
         | 
| @@ -85,7 +86,9 @@ files: | |
| 85 86 | 
             
            homepage: https://github.com/socketry/io-event
         | 
| 86 87 | 
             
            licenses:
         | 
| 87 88 | 
             
            - MIT
         | 
| 88 | 
            -
            metadata: | 
| 89 | 
            +
            metadata:
         | 
| 90 | 
            +
              documentation_uri: https://socketry.github.io/io-event/
         | 
| 91 | 
            +
              source_code_uri: https://github.com/socketry/io-event.git
         | 
| 89 92 | 
             
            post_install_message:
         | 
| 90 93 | 
             
            rdoc_options: []
         | 
| 91 94 | 
             
            require_paths:
         | 
| @@ -101,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 101 104 | 
             
                - !ruby/object:Gem::Version
         | 
| 102 105 | 
             
                  version: '0'
         | 
| 103 106 | 
             
            requirements: []
         | 
| 104 | 
            -
            rubygems_version: 3. | 
| 107 | 
            +
            rubygems_version: 3.4.19
         | 
| 105 108 | 
             
            signing_key:
         | 
| 106 109 | 
             
            specification_version: 4
         | 
| 107 110 | 
             
            summary: An event loop.
         | 
    
        metadata.gz.sig
    CHANGED
    
    | Binary file |