evt 0.1.4 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 666a665e9a03c15a364613ceac651e6e71becfa51b780b81d6cb56652ad6489b
4
- data.tar.gz: 0c21649125a1d4f6c4002b8d8da2e235d98763cde42bc8ae2f0aaac3353a98f5
3
+ metadata.gz: f49f37d3240b1878b00acaeea453e00c9dae2a96c8c7f12889836d653d6b1835
4
+ data.tar.gz: 2af4b0238768dcb2b4112eaff379cad3899633eab69017517f36d5d51ba1fae7
5
5
  SHA512:
6
- metadata.gz: 3b6fe6c7ee071b3da47e4ba66d581d18a1e1e3df3a34e072588cdd1d2b1a0816d1b85ebf6fe89190fefee6c0bc2d8d8df9b30031625febbe02062bb6db366c58
7
- data.tar.gz: d42b01b897e8d673060a5ed5ff5ffee6156cb63b3ad2e7e777044fa674e1ac59e53fc60167231745512cbfe1b31c4fc51b74d2a5331876ea63d8984fbe3311f8
6
+ metadata.gz: 58222d04ff91f47667697fd63d6d235d85c8204e09a82ac18dbd05b27d37eb79d6bcda034117684e2d49cd0cd67d2818df5264a4f73751851f1ebefdbe3a9de2
7
+ data.tar.gz: 17c54e28beb805e30a3883446a807c5114287ba3c37b402a85dcba013f2910e8aca7d29c17efe527dd050a971f224ff0e8f4f2aacd36ef8cbe7970ff8aa06d56
@@ -0,0 +1,21 @@
1
+ name: Build
2
+ on:
3
+ pull_request:
4
+ push:
5
+ branches:
6
+ - master
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-20.04
10
+ steps:
11
+ - uses: actions/checkout@v2
12
+ - uses: ruby/setup-ruby@master
13
+ with:
14
+ ruby-version: '3.0'
15
+ bundler-cache: false
16
+ - name: Install Dependencies
17
+ run: |
18
+ gem install bundler
19
+ bundle install --jobs 4 --retry 3
20
+ - name: Build
21
+ run: rake build
@@ -0,0 +1,40 @@
1
+ name: CI Tests
2
+ on:
3
+ pull_request:
4
+ push:
5
+ branches:
6
+ - master
7
+ schedule:
8
+ - cron: '0 7 * * SUN'
9
+ jobs:
10
+ test:
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ include:
15
+ - { os: ubuntu-20.04, ruby: '3.0', backend: epoll }
16
+ - { os: ubuntu-20.04, ruby: '3.0', backend: ruby, disable-epoll: 1 }
17
+ - { os: macos-11.0, ruby: '3.0', backend: kqueue }
18
+ - { os: macos-11.0, ruby: '3.0', backend: ruby, disable-kqueue: 1 }
19
+ - { os: windows-2019, ruby: mingw, backend: ruby }
20
+ - { os: windows-2019, ruby: mswin, backend: ruby }
21
+ name: test ${{ matrix.os }} ${{ matrix.ruby }} ${{ matrix.backend }}
22
+ runs-on: ${{ matrix.os }}
23
+ timeout-minutes: 5
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - uses: ruby/setup-ruby@master
27
+ with:
28
+ ruby-version: ${{ matrix.ruby }}
29
+ bundler-cache: false
30
+ - name: Install Dependencies
31
+ run: |
32
+ gem install bundler
33
+ bundle install --jobs 4 --retry 3
34
+ - name: Compile
35
+ env:
36
+ DISABLE_EPOLL: ${{ matrix.disable-epoll }}
37
+ DISABLE_KQUEUE: ${{ matrix.disable-kqueue }}
38
+ run: rake compile
39
+ - name: Test
40
+ run: rake test
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
  /*.gem
10
10
  /lib/*.bundle
11
11
  /lib/*.so
12
+ Gemfile.lock
data/Gemfile CHANGED
@@ -3,5 +3,5 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in evt.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake", "~> 12.0"
6
+ gem "rake", "~> 13.0"
7
7
  gem "minitest", "~> 5.0"
data/README.md CHANGED
@@ -1,10 +1,47 @@
1
- # evt
1
+ # Evt
2
2
 
3
- [![Build Status](https://travis-ci.org/dsh0416/evt.svg?branch=master)](https://travis-ci.org/dsh0416/evt)
3
+ The Event Library that designed for Ruby 3.0 Fiber Scheduler.
4
4
 
5
- A Handcrafted Low-Level Event Handler designed as Ruby 3 Scheduler.
5
+ **This gem is still under development, APIs and features are not stable. Advices and PRs are highly welcome.**
6
6
 
7
- Supports `epoll`, `kqueue`, IOCP (WIP), and Ruby `select` fallback.
7
+ [![CI Tests](https://github.com/dsh0416/evt/workflows/CI%20Tests/badge.svg)](https://github.com/dsh0416/evt/actions?query=workflow%3A%22Build%22)
8
+ [![Build](https://github.com/dsh0416/evt/workflows/Build/badge.svg)](https://github.com/dsh0416/evt/actions?query=workflow%3A%22CI+Tests%22)
9
+ [![Gem Version](https://badge.fury.io/rb/evt.svg)](https://rubygems.org/gems/evt)
10
+ [![Downloads](https://ruby-gem-downloads-badge.herokuapp.com/evt?type=total)](https://rubygems.org/gems/evt)
11
+
12
+ ## Features
13
+
14
+ ### IO Backend Support
15
+
16
+ | | Linux | Windows | macOS | FreeBSD |
17
+ | --------------- | ----------- | ------------| ----------- | ----------- |
18
+ | io_uring | ✅ (See 1) | ❌ | ❌ | ❌ |
19
+ | epoll | ✅ (See 2) | ❌ | ❌ | ❌ |
20
+ | kqueue | ❌ | ❌ | ✅ (⚠️ See 5) | ✅ |
21
+ | IOCP | ❌ | ❌ (⚠️See 3) | ❌ | ❌ |
22
+ | Ruby (`IO.select`) | ✅ Fallback | ✅ (⚠️See 4) | ✅ Fallback | ✅ Fallback |
23
+
24
+ 1. when liburing is installed
25
+ 2. when kernel version >= 2.6.8
26
+ 3. WOULD NOT WORK until `FILE_FLAG_OVERLAPPED` is included in I/O initialization process.
27
+ 4. Some I/Os are not able to be nonblock under Windows. See [Scheduler Docs](https://docs.ruby-lang.org/en/master/doc/scheduler_md.html#label-IO).
28
+ 5. `kqueue` performance in Darwin is very poor. **MAY BE DISABLED IN THE FUTURE.**
29
+
30
+ ### Benchmark
31
+
32
+ The benchmark is running under `v0.2.2` version. See [evt-server-benchmark](https://github.com/dsh0416/evt-server-benchmark) for test code, the test is running under a single-thread server.
33
+
34
+ The test command is `wrk -t4 -c8192 -d30s http://localhost:3001`.
35
+
36
+ All of the systems have set their file descriptor limit to maximum.
37
+
38
+ | OS | CPU | Memory | Backend | req/s |
39
+ | ----- | ----------- | ------ | ---------------------- | -------- |
40
+ | Linux | Ryzen 2700x | 64GB | epoll | 54680.08 |
41
+ | Linux | Ryzen 2700x | 64GB | io_uring | 50245.53 |
42
+ | Linux | Ryzen 2700x | 64GB | IO.select (using poll) | 44159.23 |
43
+ | macOS | i7-6820HQ | 16GB | kqueue | 37855.53 |
44
+ | macOS | i7-6820HQ | 16GB | IO.select (using poll) | 28293.36 |
8
45
 
9
46
  ## Install
10
47
 
@@ -18,17 +55,33 @@ gem install evt
18
55
  require 'evt'
19
56
 
20
57
  rd, wr = IO.pipe
21
- Thread.current.scheduler = Evt::Scheduler.new
58
+ scheduler = Evt::Scheduler.new
59
+
60
+ Fiber.set_scheduler scheduler
22
61
 
23
- hit = 0
24
- fiber = Fiber.new do
25
- scheduler.wait_readable(rd)
26
- hit += 1
62
+ Fiber.schedule do
63
+ message = rd.read(20)
64
+ puts message
65
+ rd.close
27
66
  end
28
67
 
29
- wr.write('Hello World')
30
- fiber.resume
31
- Thread.current.scheduler.run
68
+ Fiber.schedule do
69
+ wr.write("Hello World")
70
+ wr.close
71
+ end
32
72
 
33
- puts hit # => 1
73
+ # "Hello World"
34
74
  ```
75
+
76
+ ## Roadmap
77
+
78
+ - [x] Support epoll/kqueue/select
79
+ - [x] Upgrade to the latest Scheduler API
80
+ - [x] Support io_uring
81
+ - [x] Support iov features of io_uring
82
+ - [x] Support IOCP (**NOT ENABLED YET**)
83
+ - [x] Setup tests with Ruby 3
84
+ - [x] Selectable backend compilation by environment variable
85
+ - [ ] Support IOCP with iov features
86
+ - [ ] Setup more tests for production purpose
87
+ - [ ] Documentation for usages
data/Rakefile CHANGED
@@ -11,6 +11,7 @@ Rake::TestTask.new(:test) do |t|
11
11
  t.libs << "test"
12
12
  t.libs << "lib"
13
13
  t.test_files = FileList["test/**/*_test.rb"]
14
+ t.verbose = true
14
15
  end
15
16
 
16
17
  task :default => :test
@@ -6,11 +6,11 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ["Delton Ding"]
7
7
  spec.email = ["dsh0416@gmail.com"]
8
8
 
9
- spec.summary = "A low-level Event Handler designed for Ruby 3 Scheduler"
9
+ spec.summary = "The Event Library that designed for Ruby 3.0 Fiber Scheluer."
10
10
  spec.description = "A low-level Event Handler designed for Ruby 3 Scheduler for better performance"
11
11
  spec.homepage = "https://github.com/dsh0416/evt"
12
12
  spec.license = 'BSD-3-Clause'
13
- spec.required_ruby_version = '>= 2.7.1'
13
+ spec.required_ruby_version = '>= 3.0.0.rc1'
14
14
 
15
15
  spec.metadata["homepage_uri"] = spec.homepage
16
16
  spec.metadata["source_code_uri"] = "https://github.com/dsh0416/evt"
@@ -18,10 +18,11 @@ Gem::Specification.new do |spec|
18
18
  # Specify which files should be added to the gem when it is released.
19
19
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
20
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
21
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|examples|.vscode)/}) }
22
22
  end
23
23
  spec.require_paths = ["lib"]
24
24
  spec.extensions = ['ext/evt/extconf.rb']
25
25
 
26
26
  spec.add_development_dependency 'rake-compiler', '~> 1.0'
27
+ spec.add_development_dependency 'simplecov', '~> 0.20.0'
27
28
  end
@@ -0,0 +1,89 @@
1
+ #ifndef EPOLL_H
2
+ #define EPOLL_H
3
+ #include "evt.h"
4
+
5
+ #if HAVE_SYS_EPOLL_H
6
+ VALUE method_scheduler_epoll_init(VALUE self) {
7
+ rb_iv_set(self, "@epfd", INT2NUM(epoll_create(1))); // Size of epoll is ignored after Linux 2.6.8.
8
+ return Qnil;
9
+ }
10
+
11
+ VALUE method_scheduler_epoll_register(VALUE self, VALUE io, VALUE interest) {
12
+ struct epoll_event event;
13
+ ID id_fileno = rb_intern("fileno");
14
+ int epfd = NUM2INT(rb_iv_get(self, "@epfd"));
15
+ int fd = NUM2INT(rb_funcall(io, id_fileno, 0));
16
+ int ruby_interest = NUM2INT(interest);
17
+ int readable = NUM2INT(rb_const_get(rb_cIO, rb_intern("READABLE")));
18
+ int writable = NUM2INT(rb_const_get(rb_cIO, rb_intern("WRITABLE")));
19
+
20
+ if (ruby_interest & readable) {
21
+ event.events |= EPOLLIN;
22
+ }
23
+
24
+ if (ruby_interest & writable) {
25
+ event.events |= EPOLLOUT;
26
+ }
27
+
28
+ event.data.ptr = (void*) io;
29
+
30
+ epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
31
+ return Qnil;
32
+ }
33
+
34
+ VALUE method_scheduler_epoll_deregister(VALUE self, VALUE io) {
35
+ ID id_fileno = rb_intern("fileno");
36
+ int epfd = NUM2INT(rb_iv_get(self, "@epfd"));
37
+ int fd = NUM2INT(rb_funcall(io, id_fileno, 0));
38
+ epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); // Require Linux 2.6.9 for NULL event.
39
+ return Qnil;
40
+ }
41
+
42
+ VALUE method_scheduler_epoll_wait(VALUE self) {
43
+ int n, epfd, i, event_flag, timeout;
44
+ VALUE next_timeout, obj_io, readables, writables, result;
45
+ ID id_next_timeout = rb_intern("next_timeout");
46
+ ID id_push = rb_intern("push");
47
+
48
+ epfd = NUM2INT(rb_iv_get(self, "@epfd"));
49
+ next_timeout = rb_funcall(self, id_next_timeout, 0);
50
+ readables = rb_ary_new();
51
+ writables = rb_ary_new();
52
+
53
+ if (next_timeout == Qnil) {
54
+ timeout = -1;
55
+ } else {
56
+ timeout = NUM2INT(next_timeout);
57
+ }
58
+
59
+ struct epoll_event events[EPOLL_MAX_EVENTS];
60
+
61
+ n = epoll_wait(epfd, events, EPOLL_MAX_EVENTS, timeout);
62
+ if (n < 0) {
63
+ rb_raise(rb_eIOError, "unable to call epoll_wait");
64
+ }
65
+
66
+ for (i = 0; i < n; i++) {
67
+ event_flag = events[i].events;
68
+ if (event_flag & EPOLLIN) {
69
+ obj_io = (VALUE) events[i].data.ptr;
70
+ rb_funcall(readables, id_push, 1, obj_io);
71
+ }
72
+
73
+ if (event_flag & EPOLLOUT) {
74
+ obj_io = (VALUE) events[i].data.ptr;
75
+ rb_funcall(writables, id_push, 1, obj_io);
76
+ }
77
+ }
78
+
79
+ result = rb_ary_new2(2);
80
+ rb_ary_store(result, 0, readables);
81
+ rb_ary_store(result, 1, writables);
82
+ return result;
83
+ }
84
+
85
+ VALUE method_scheduler_epoll_backend(VALUE klass) {
86
+ return rb_str_new_cstr("epoll");
87
+ }
88
+ #endif
89
+ #endif
@@ -1,218 +1,45 @@
1
+ #ifndef EVT_C
2
+ #define EVT_C
3
+
1
4
  #include "evt.h"
2
5
 
3
6
  void Init_evt_ext()
4
7
  {
8
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
9
+ rb_ext_ractor_safe(true);
10
+ #endif
5
11
  Evt = rb_define_module("Evt");
6
- Scheduler = rb_define_class_under(Evt, "Scheduler", rb_cObject);
7
- rb_define_singleton_method(Scheduler, "backend", method_scheduler_backend, 0);
8
- rb_define_method(Scheduler, "init_selector", method_scheduler_init, 0);
9
- rb_define_method(Scheduler, "register", method_scheduler_register, 2);
10
- rb_define_method(Scheduler, "deregister", method_scheduler_deregister, 1);
11
- rb_define_method(Scheduler, "wait", method_scheduler_wait, 0);
12
- }
13
-
14
-
15
- #if defined(__linux__) // TODO: Do more checks for using epoll
16
- #include <sys/epoll.h>
17
- #define EPOLL_MAX_EVENTS 64
18
-
19
- VALUE method_scheduler_init(VALUE self) {
20
- rb_iv_set(self, "@epfd", INT2NUM(epoll_create(1))); // Size of epoll is ignored after Linux 2.6.8.
21
- return Qnil;
22
- }
23
-
24
- VALUE method_scheduler_register(VALUE self, VALUE io, VALUE interest) {
25
- struct epoll_event event;
26
- ID id_fileno = rb_intern("fileno");
27
- int epfd = NUM2INT(rb_iv_get(self, "@epfd"));
28
- int fd = NUM2INT(rb_funcall(io, id_fileno, 0));
29
- int ruby_interest = NUM2INT(interest);
30
- int readable = NUM2INT(rb_const_get(rb_cIO, rb_intern("WAIT_READABLE")));
31
- int writable = NUM2INT(rb_const_get(rb_cIO, rb_intern("WAIT_WRITABLE")));
32
-
33
- if (ruby_interest & readable) {
34
- event.events |= EPOLLIN;
35
- } else if (ruby_interest & writable) {
36
- event.events |= EPOLLOUT;
37
- }
38
- event.data.ptr = (void*) io;
39
-
40
- epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
41
- return Qnil;
42
- }
43
-
44
- VALUE method_scheduler_deregister(VALUE self, VALUE io) {
45
- ID id_fileno = rb_intern("fileno");
46
- int epfd = NUM2INT(rb_iv_get(self, "@epfd"));
47
- int fd = NUM2INT(rb_funcall(io, id_fileno, 0));
48
- epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); // Require Linux 2.6.9 for NULL event.
49
- return Qnil;
50
- }
51
-
52
- VALUE method_scheduler_wait(VALUE self) {
53
- int n, epfd, i, event_flag, timeout;
54
- VALUE next_timeout, obj_io, readables, writables, result;
55
- ID id_next_timeout = rb_intern("next_timeout");
56
- ID id_push = rb_intern("push");
57
-
58
- epfd = NUM2INT(rb_iv_get(self, "@epfd"));
59
- next_timeout = rb_funcall(self, id_next_timeout, 0);
60
- readables = rb_ary_new();
61
- writables = rb_ary_new();
62
-
63
- if (next_timeout == Qnil) {
64
- timeout = -1;
65
- } else {
66
- timeout = NUM2INT(next_timeout);
67
- }
68
-
69
- struct epoll_event* events = (struct epoll_event*) xmalloc(sizeof(struct epoll_event) * EPOLL_MAX_EVENTS);
70
-
71
- n = epoll_wait(epfd, events, EPOLL_MAX_EVENTS, timeout);
72
- // TODO: Check if n >= 0
73
-
74
- for (i = 0; i < n; i++) {
75
- event_flag = events[i].events;
76
- if (event_flag & EPOLLIN) {
77
- obj_io = (VALUE) events[i].data.ptr;
78
- rb_funcall(readables, id_push, 1, obj_io);
79
- } else if (event_flag & EPOLLOUT) {
80
- obj_io = (VALUE) events[i].data.ptr;
81
- rb_funcall(writables, id_push, 1, obj_io);
82
- }
83
- }
84
-
85
- result = rb_ary_new2(2);
86
- rb_ary_store(result, 0, readables);
87
- rb_ary_store(result, 1, writables);
88
-
89
- xfree(events);
90
- return result;
91
- }
92
-
93
- VALUE method_scheduler_backend() {
94
- return rb_str_new_cstr("epoll");
95
- }
96
- #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
97
- #include <sys/event.h>
98
- #define KQUEUE_MAX_EVENTS 64
99
-
100
- VALUE method_scheduler_init(VALUE self) {
101
- rb_iv_set(self, "@kq", INT2NUM(kqueue()));
102
- return Qnil;
103
- }
104
-
105
- VALUE method_scheduler_register(VALUE self, VALUE io, VALUE interest) {
106
- struct kevent event;
107
- u_short event_flags = 0;
108
- ID id_fileno = rb_intern("fileno");
109
- int kq = NUM2INT(rb_iv_get(self, "@kq"));
110
- int fd = NUM2INT(rb_funcall(io, id_fileno, 0));
111
- int ruby_interest = NUM2INT(interest);
112
- int readable = NUM2INT(rb_const_get(rb_cIO, rb_intern("WAIT_READABLE")));
113
- int writable = NUM2INT(rb_const_get(rb_cIO, rb_intern("WAIT_WRITABLE")));
114
-
115
- if (ruby_interest & readable) {
116
- event_flags |= EVFILT_READ;
117
- } else if (ruby_interest & writable) {
118
- event_flags |= EVFILT_WRITE;
119
- }
120
-
121
- EV_SET(&event, fd, event_flags, EV_ADD|EV_ENABLE, 0, 0, (void*) io);
122
- kevent(kq, &event, 1, NULL, 0, NULL); // TODO: Check the return value
123
- return Qnil;
124
- }
125
-
126
- VALUE method_scheduler_deregister(VALUE self, VALUE io) {
127
- struct kevent event;
128
- ID id_fileno = rb_intern("fileno");
129
- int kq = NUM2INT(rb_iv_get(self, "@kq"));
130
- int fd = NUM2INT(rb_funcall(io, id_fileno, 0));
131
- EV_SET(&event, fd, 0, EV_DELETE, 0, 0, NULL);
132
- kevent(kq, &event, 1, NULL, 0, NULL); // TODO: Check the return value
133
- return Qnil;
134
- }
135
-
136
- VALUE method_scheduler_wait(VALUE self) {
137
- int n, kq, i;
138
- u_short event_flags = 0;
139
-
140
- struct kevent* events; // Event Triggered
141
- struct timespec timeout;
142
- VALUE next_timeout, obj_io, readables, writables, result;
143
- ID id_next_timeout = rb_intern("next_timeout");
144
- ID id_push = rb_intern("push");
145
-
146
- kq = NUM2INT(rb_iv_get(self, "@kq"));
147
- next_timeout = rb_funcall(self, id_next_timeout, 0);
148
- readables = rb_ary_new();
149
- writables = rb_ary_new();
150
-
151
- events = (struct kevent*) xmalloc(sizeof(struct kevent) * KQUEUE_MAX_EVENTS);
152
-
153
- if (next_timeout == Qnil || NUM2INT(next_timeout) == -1) {
154
- n = kevent(kq, NULL, 0, events, KQUEUE_MAX_EVENTS, NULL);
155
- } else {
156
- timeout.tv_sec = next_timeout / 1000;
157
- timeout.tv_nsec = next_timeout % 1000 * 1000 * 1000;
158
- n = kevent(kq, NULL, 0, events, KQUEUE_MAX_EVENTS, &timeout);
159
- }
160
-
161
- // TODO: Check if n >= 0
162
- for (i = 0; i < n; i++) {
163
- event_flags = events[i].filter;
164
- if (event_flags & EVFILT_READ) {
165
- obj_io = (VALUE) events[i].udata;
166
- rb_funcall(readables, id_push, 1, obj_io);
167
- } else if (event_flags & EVFILT_WRITE) {
168
- obj_io = (VALUE) events[i].udata;
169
- rb_funcall(writables, id_push, 1, obj_io);
170
- }
171
- }
172
-
173
- result = rb_ary_new2(2);
174
- rb_ary_store(result, 0, readables);
175
- rb_ary_store(result, 1, writables);
176
-
177
- xfree(events);
178
- return result;
179
- }
180
-
181
- VALUE method_scheduler_backend() {
182
- return rb_str_new_cstr("kqueue");
183
- }
184
- #else
185
- // Fallback to IO.select
186
- VALUE method_scheduler_init(VALUE self) {
187
- return Qnil;
188
- }
189
-
190
- VALUE method_scheduler_register(VALUE self, VALUE io, VALUE interest) {
191
- return Qnil;
192
- }
193
-
194
- VALUE method_scheduler_deregister(VALUE self, VALUE io) {
195
- return Qnil;
196
- }
197
-
198
- VALUE method_scheduler_wait(VALUE self) {
199
- // return IO.select(@readable.keys, @writable.keys, [], next_timeout)
200
- VALUE readable, writable, readable_keys, writable_keys, next_timeout;
201
- ID id_select = rb_intern("select");
202
- ID id_keys = rb_intern("keys");
203
- ID id_next_timeout = rb_intern("next_timeout");
204
-
205
- readable = rb_iv_get(self, "@readable");
206
- writable = rb_iv_get(self, "@writable");
207
-
208
- readable_keys = rb_funcall(readable, id_keys, 0);
209
- writable_keys = rb_funcall(writable, id_keys, 0);
210
- next_timeout = rb_funcall(self, id_next_timeout, 0);
211
-
212
- return rb_funcall(rb_cIO, id_select, 4, readable_keys, writable_keys, rb_ary_new(), next_timeout);
213
- }
214
-
215
- VALUE method_scheduler_backend() {
216
- return rb_str_new_cstr("ruby");
217
- }
218
- #endif
12
+ Bundled = rb_define_class_under(Evt, "Bundled", rb_cObject);
13
+ Payload = rb_define_class_under(Bundled, "Payload", rb_cObject);
14
+ Fiber = rb_define_class("Fiber", rb_cObject);
15
+ #if HAVE_LIBURING_H
16
+ rb_define_singleton_method(Bundled, "uring_backend", method_scheduler_uring_backend, 0);
17
+ rb_define_method(Bundled, "uring_init_selector", method_scheduler_uring_init, 0);
18
+ rb_define_method(Bundled, "uring_register", method_scheduler_uring_register, 2);
19
+ rb_define_method(Bundled, "uring_wait", method_scheduler_uring_wait, 0);
20
+ rb_define_method(Bundled, "uring_io_read", method_scheduler_uring_io_read, 4);
21
+ rb_define_method(Bundled, "uring_io_write", method_scheduler_uring_io_write, 4);
22
+ #endif
23
+ #if HAVE_SYS_EPOLL_H
24
+ rb_define_singleton_method(Bundled, "epoll_backend", method_scheduler_epoll_backend, 0);
25
+ rb_define_method(Bundled, "epoll_init_selector", method_scheduler_epoll_init, 0);
26
+ rb_define_method(Bundled, "epoll_register", method_scheduler_epoll_register, 2);
27
+ rb_define_method(Bundled, "epoll_deregister", method_scheduler_epoll_deregister, 1);
28
+ rb_define_method(Bundled, "epoll_wait", method_scheduler_epoll_wait, 0);
29
+ #endif
30
+ #if HAVE_SYS_EVENT_H
31
+ rb_define_singleton_method(Bundled, "kqueue_backend", method_scheduler_kqueue_backend, 0);
32
+ rb_define_method(Bundled, "kqueue_init_selector", method_scheduler_kqueue_init, 0);
33
+ rb_define_method(Bundled, "kqueue_register", method_scheduler_kqueue_register, 2);
34
+ rb_define_method(Bundled, "kqueue_wait", method_scheduler_kqueue_wait, 0);
35
+ #endif
36
+ rb_define_singleton_method(Bundled, "select_backend", method_scheduler_select_backend, 0);
37
+ rb_define_method(Bundled, "select_wait", method_scheduler_select_wait, 0);
38
+ }
39
+
40
+ #include "uring.h"
41
+ #include "epoll.h"
42
+ #include "kqueue.h"
43
+ // #include "iocp.h"
44
+ #include "select.h"
45
+ #endif