io-event 1.6.5 → 1.7.5
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 +25 -12
- data/ext/io/event/event.c +2 -8
- data/ext/io/event/interrupt.c +7 -0
- data/ext/io/event/selector/array.h +52 -18
- data/ext/io/event/selector/epoll.c +26 -11
- data/ext/io/event/selector/kqueue.c +20 -10
- data/ext/io/event/selector/list.h +19 -1
- data/ext/io/event/selector/selector.c +24 -2
- data/ext/io/event/selector/selector.h +11 -8
- data/ext/io/event/selector/uring.c +114 -14
- data/lib/io/event/debug/selector.rb +44 -4
- data/lib/io/event/interrupt.rb +2 -2
- data/lib/io/event/priority_heap.rb +13 -14
- data/lib/io/event/selector/nonblock.rb +6 -2
- data/lib/io/event/selector/select.rb +25 -5
- data/lib/io/event/selector.rb +15 -5
- data/lib/io/event/support.rb +23 -2
- data/lib/io/event/timers.rb +42 -4
- data/lib/io/event/version.rb +3 -1
- data/lib/io/event.rb +5 -5
- data/license.md +3 -0
- data/readme.md +14 -4
- data/releases.md +5 -0
- data.tar.gz.sig +0 -0
- metadata +8 -4
- metadata.gz.sig +0 -0
data/lib/io/event/selector.rb
CHANGED
|
@@ -3,14 +3,19 @@
|
|
|
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
|
+
# @namespace
|
|
11
12
|
module Selector
|
|
13
|
+
# The default selector implementation, which is chosen based on the environment and available implementations.
|
|
14
|
+
#
|
|
15
|
+
# @parameter env [Hash] The environment to read configuration from.
|
|
16
|
+
# @returns [Class] The default selector implementation.
|
|
12
17
|
def self.default(env = ENV)
|
|
13
|
-
if name = env[
|
|
18
|
+
if name = env["IO_EVENT_SELECTOR"]&.to_sym
|
|
14
19
|
return const_get(name)
|
|
15
20
|
end
|
|
16
21
|
|
|
@@ -25,10 +30,15 @@ module IO::Event
|
|
|
25
30
|
end
|
|
26
31
|
end
|
|
27
32
|
|
|
33
|
+
# Create a new selector instance, according to the best available implementation.
|
|
34
|
+
#
|
|
35
|
+
# @parameter loop [Fiber] The event loop fiber.
|
|
36
|
+
# @parameter env [Hash] The environment to read configuration from.
|
|
37
|
+
# @returns [Selector] The new selector instance.
|
|
28
38
|
def self.new(loop, env = ENV)
|
|
29
39
|
selector = default(env).new(loop)
|
|
30
40
|
|
|
31
|
-
if debug = env[
|
|
41
|
+
if debug = env["IO_EVENT_DEBUG_SELECTOR"]
|
|
32
42
|
selector = Debug::Selector.wrap(selector, env)
|
|
33
43
|
end
|
|
34
44
|
|
data/lib/io/event/support.rb
CHANGED
|
@@ -1,23 +1,44 @@
|
|
|
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
|
|
8
|
+
# Helper methods for detecting support for various features.
|
|
8
9
|
module Support
|
|
10
|
+
# Some features are only availble if the IO::Buffer class is available.
|
|
11
|
+
#
|
|
12
|
+
# @returns [Boolean] Whether the IO::Buffer class is available.
|
|
9
13
|
def self.buffer?
|
|
10
14
|
IO.const_defined?(:Buffer)
|
|
11
15
|
end
|
|
12
16
|
|
|
17
|
+
# The basic fiber scheduler was introduced along side the IO::Buffer class.
|
|
18
|
+
#
|
|
19
|
+
# @returns [Boolean] Whether the IO::Buffer class is available.
|
|
20
|
+
#
|
|
21
|
+
# To be removed on 31 Mar 2025.
|
|
13
22
|
def self.fiber_scheduler_v1?
|
|
14
|
-
IO.const_defined?(:Buffer)
|
|
23
|
+
IO.const_defined?(:Buffer)
|
|
15
24
|
end
|
|
16
25
|
|
|
26
|
+
# More advanced read/write methods and blocking controls were introduced in Ruby 3.2.
|
|
27
|
+
#
|
|
28
|
+
# To be removed on 31 Mar 2026.
|
|
17
29
|
def self.fiber_scheduler_v2?
|
|
30
|
+
# Some interface changes were back-ported incorrectly:
|
|
31
|
+
# https://github.com/ruby/ruby/pull/10778
|
|
32
|
+
# Specifically "Improvements to IO::Buffer read/write/pread/pwrite."
|
|
33
|
+
# Missing correct size calculation.
|
|
34
|
+
return false if RUBY_VERSION >= "3.2.5"
|
|
35
|
+
|
|
18
36
|
IO.const_defined?(:Buffer) and Fiber.respond_to?(:blocking) and IO::Buffer.instance_method(:read).arity == -1
|
|
19
37
|
end
|
|
20
38
|
|
|
39
|
+
# Updated inferfaces for read/write and IO::Buffer were introduced in Ruby 3.3, including pread/pwrite.
|
|
40
|
+
#
|
|
41
|
+
# To become the default 31 Mar 2026.
|
|
21
42
|
def self.fiber_scheduler_v3?
|
|
22
43
|
if fiber_scheduler_v2?
|
|
23
44
|
return true if RUBY_VERSION >= "3.3"
|
data/lib/io/event/timers.rb
CHANGED
|
@@ -3,46 +3,68 @@
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
4
|
# Copyright, 2024, by Samuel Williams.
|
|
5
5
|
|
|
6
|
-
require_relative
|
|
6
|
+
require_relative "priority_heap"
|
|
7
7
|
|
|
8
8
|
class IO
|
|
9
9
|
module Event
|
|
10
|
+
# An efficient sorted set of timers.
|
|
10
11
|
class Timers
|
|
12
|
+
# A handle to a scheduled timer.
|
|
11
13
|
class Handle
|
|
14
|
+
# Initialize the handle with the given time and block.
|
|
15
|
+
#
|
|
16
|
+
# @parameter time [Float] The time at which the block should be called.
|
|
17
|
+
# @parameter block [Proc] The block to call.
|
|
12
18
|
def initialize(time, block)
|
|
13
19
|
@time = time
|
|
14
20
|
@block = block
|
|
15
21
|
end
|
|
16
22
|
|
|
23
|
+
# @attribute [Float] The time at which the block should be called.
|
|
24
|
+
attr :time
|
|
25
|
+
|
|
26
|
+
# @attribute [Proc | Nil] The block to call when the timer fires.
|
|
27
|
+
attr :block
|
|
28
|
+
|
|
29
|
+
# Compare the handle with another handle.
|
|
30
|
+
#
|
|
31
|
+
# @parameter other [Handle] The other handle to compare with.
|
|
32
|
+
# @returns [Boolean] Whether the handle is less than the other handle.
|
|
17
33
|
def < other
|
|
18
34
|
@time < other.time
|
|
19
35
|
end
|
|
20
36
|
|
|
37
|
+
# Compare the handle with another handle.
|
|
38
|
+
#
|
|
39
|
+
# @parameter other [Handle] The other handle to compare with.
|
|
40
|
+
# @returns [Boolean] Whether the handle is greater than the other handle.
|
|
21
41
|
def > other
|
|
22
42
|
@time > other.time
|
|
23
43
|
end
|
|
24
44
|
|
|
25
|
-
|
|
26
|
-
attr :block
|
|
27
|
-
|
|
45
|
+
# Invoke the block.
|
|
28
46
|
def call(...)
|
|
29
47
|
@block.call(...)
|
|
30
48
|
end
|
|
31
49
|
|
|
50
|
+
# Cancel the timer.
|
|
32
51
|
def cancel!
|
|
33
52
|
@block = nil
|
|
34
53
|
end
|
|
35
54
|
|
|
55
|
+
# @returns [Boolean] Whether the timer has been cancelled.
|
|
36
56
|
def cancelled?
|
|
37
57
|
@block.nil?
|
|
38
58
|
end
|
|
39
59
|
end
|
|
40
60
|
|
|
61
|
+
# Initialize the timers.
|
|
41
62
|
def initialize
|
|
42
63
|
@heap = PriorityHeap.new
|
|
43
64
|
@scheduled = []
|
|
44
65
|
end
|
|
45
66
|
|
|
67
|
+
# @returns [Integer] The number of timers in the heap.
|
|
46
68
|
def size
|
|
47
69
|
flush!
|
|
48
70
|
|
|
@@ -50,7 +72,9 @@ class IO
|
|
|
50
72
|
end
|
|
51
73
|
|
|
52
74
|
# Schedule a block to be called at a specific time in the future.
|
|
75
|
+
#
|
|
53
76
|
# @parameter time [Float] The time at which the block should be called, relative to {#now}.
|
|
77
|
+
# @parameter block [Proc] The block to call.
|
|
54
78
|
def schedule(time, block)
|
|
55
79
|
handle = Handle.new(time, block)
|
|
56
80
|
|
|
@@ -60,11 +84,18 @@ class IO
|
|
|
60
84
|
end
|
|
61
85
|
|
|
62
86
|
# Schedule a block to be called after a specific time offset, relative to the current time as returned by {#now}.
|
|
87
|
+
#
|
|
63
88
|
# @parameter offset [#to_f] The time offset from the current time at which the block should be called.
|
|
89
|
+
# @yields {|now| ...} When the timer fires.
|
|
64
90
|
def after(offset, &block)
|
|
65
91
|
schedule(self.now + offset.to_f, block)
|
|
66
92
|
end
|
|
67
93
|
|
|
94
|
+
|
|
95
|
+
# Compute the time interval until the next timer fires.
|
|
96
|
+
#
|
|
97
|
+
# @parameter now [Float] The current time.
|
|
98
|
+
# @returns [Float | Nil] The time interval until the next timer fires, if any.
|
|
68
99
|
def wait_interval(now = self.now)
|
|
69
100
|
flush!
|
|
70
101
|
|
|
@@ -77,10 +108,14 @@ class IO
|
|
|
77
108
|
end
|
|
78
109
|
end
|
|
79
110
|
|
|
111
|
+
# @returns [Float] The current time.
|
|
80
112
|
def now
|
|
81
113
|
::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
|
82
114
|
end
|
|
83
115
|
|
|
116
|
+
# Fire all timers that are ready to fire.
|
|
117
|
+
#
|
|
118
|
+
# @parameter now [Float] The current time.
|
|
84
119
|
def fire(now = self.now)
|
|
85
120
|
# Flush scheduled timers into the heap:
|
|
86
121
|
flush!
|
|
@@ -101,6 +136,9 @@ class IO
|
|
|
101
136
|
end
|
|
102
137
|
end
|
|
103
138
|
|
|
139
|
+
# Flush all scheduled timers into the heap.
|
|
140
|
+
#
|
|
141
|
+
# This is a small optimization which assumes that most timers (timeouts) will be cancelled.
|
|
104
142
|
protected def flush!
|
|
105
143
|
while handle = @scheduled.pop
|
|
106
144
|
@heap.push(handle) unless handle.cancelled?
|
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,9 @@ 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.
|
|
12
|
+
Copyright, 2024, by Shizuo Fujita.
|
|
13
|
+
Copyright, 2024, by Jean Boussier.
|
|
11
14
|
|
|
12
15
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
16
|
of this software and associated documentation files (the "Software"), to deal
|
data/readme.md
CHANGED
|
@@ -10,7 +10,17 @@ The initial proof-of-concept [Async](https://github.com/socketry/async) was buil
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
Please see the [project documentation](https://socketry.github.io/io-event/).
|
|
13
|
+
Please see the [project documentation](https://socketry.github.io/io-event/) for more details.
|
|
14
|
+
|
|
15
|
+
- [Getting Started](https://socketry.github.io/io-event/guides/getting-started/index) - This guide explains how to use `io-event` for non-blocking IO.
|
|
16
|
+
|
|
17
|
+
## Releases
|
|
18
|
+
|
|
19
|
+
Please see the [project releases](https://socketry.github.io/io-event/releases/index) for all releases.
|
|
20
|
+
|
|
21
|
+
### v1.7.5
|
|
22
|
+
|
|
23
|
+
- Fix `process_wait` race condition on EPoll that could cause a hang.
|
|
14
24
|
|
|
15
25
|
## Contributing
|
|
16
26
|
|
|
@@ -24,8 +34,8 @@ We welcome contributions to this project.
|
|
|
24
34
|
|
|
25
35
|
### Developer Certificate of Origin
|
|
26
36
|
|
|
27
|
-
|
|
37
|
+
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
38
|
|
|
29
|
-
###
|
|
39
|
+
### Community Guidelines
|
|
30
40
|
|
|
31
|
-
This project is
|
|
41
|
+
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/releases.md
ADDED
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.
|
|
4
|
+
version: 1.7.5
|
|
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-12-15 00:00:00.000000000 Z
|
|
48
49
|
dependencies: []
|
|
49
50
|
description:
|
|
50
51
|
email:
|
|
@@ -82,10 +83,13 @@ files:
|
|
|
82
83
|
- lib/io/event/version.rb
|
|
83
84
|
- license.md
|
|
84
85
|
- readme.md
|
|
86
|
+
- releases.md
|
|
85
87
|
homepage: https://github.com/socketry/io-event
|
|
86
88
|
licenses:
|
|
87
89
|
- MIT
|
|
88
|
-
metadata:
|
|
90
|
+
metadata:
|
|
91
|
+
documentation_uri: https://socketry.github.io/io-event/
|
|
92
|
+
source_code_uri: https://github.com/socketry/io-event.git
|
|
89
93
|
post_install_message:
|
|
90
94
|
rdoc_options: []
|
|
91
95
|
require_paths:
|
|
@@ -101,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
101
105
|
- !ruby/object:Gem::Version
|
|
102
106
|
version: '0'
|
|
103
107
|
requirements: []
|
|
104
|
-
rubygems_version: 3.5.
|
|
108
|
+
rubygems_version: 3.5.22
|
|
105
109
|
signing_key:
|
|
106
110
|
specification_version: 4
|
|
107
111
|
summary: An event loop.
|
metadata.gz.sig
CHANGED
|
Binary file
|