nio4r 1.2.1 → 2.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/workflow.yml +43 -0
- data/.gitignore +1 -0
- data/.rspec +0 -1
- data/.rubocop.yml +70 -31
- data/CHANGES.md +190 -42
- data/Gemfile +8 -4
- data/Guardfile +10 -0
- data/README.md +102 -147
- data/Rakefile +3 -4
- data/examples/echo_server.rb +3 -2
- data/ext/libev/Changes +44 -13
- data/ext/libev/README +2 -1
- data/ext/libev/ev.c +314 -225
- data/ext/libev/ev.h +90 -88
- data/ext/libev/ev_epoll.c +30 -16
- data/ext/libev/ev_kqueue.c +19 -9
- data/ext/libev/ev_linuxaio.c +642 -0
- data/ext/libev/ev_poll.c +19 -11
- data/ext/libev/ev_port.c +13 -6
- data/ext/libev/ev_select.c +4 -2
- data/ext/libev/ev_vars.h +14 -3
- data/ext/libev/ev_wrap.h +16 -0
- data/ext/nio4r/bytebuffer.c +429 -0
- data/ext/nio4r/extconf.rb +17 -30
- data/ext/nio4r/monitor.c +113 -49
- data/ext/nio4r/nio4r.h +11 -13
- data/ext/nio4r/org/nio4r/ByteBuffer.java +293 -0
- data/ext/nio4r/org/nio4r/Monitor.java +175 -0
- data/ext/nio4r/org/nio4r/Nio4r.java +22 -391
- data/ext/nio4r/org/nio4r/Selector.java +299 -0
- data/ext/nio4r/selector.c +155 -68
- data/lib/nio.rb +4 -4
- data/lib/nio/bytebuffer.rb +229 -0
- data/lib/nio/monitor.rb +73 -11
- data/lib/nio/selector.rb +64 -21
- data/lib/nio/version.rb +1 -1
- data/nio4r.gemspec +34 -20
- data/{tasks → rakelib}/extension.rake +4 -0
- data/{tasks → rakelib}/rspec.rake +2 -0
- data/{tasks → rakelib}/rubocop.rake +2 -0
- data/spec/nio/acceptables_spec.rb +5 -5
- data/spec/nio/bytebuffer_spec.rb +354 -0
- data/spec/nio/monitor_spec.rb +128 -79
- data/spec/nio/selectables/pipe_spec.rb +12 -3
- data/spec/nio/selectables/ssl_socket_spec.rb +61 -29
- data/spec/nio/selectables/tcp_socket_spec.rb +47 -34
- data/spec/nio/selectables/udp_socket_spec.rb +24 -7
- data/spec/nio/selector_spec.rb +65 -16
- data/spec/spec_helper.rb +12 -3
- data/spec/support/selectable_examples.rb +45 -18
- metadata +33 -23
- data/.rubocop_todo.yml +0 -35
- data/.travis.yml +0 -27
- data/LICENSE.txt +0 -20
- data/ext/libev/README.embed +0 -3
- data/ext/libev/test_libev_win32.c +0 -123
data/Gemfile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gemspec
|
@@ -5,11 +7,13 @@ gemspec
|
|
5
7
|
gem "jruby-openssl" if defined? JRUBY_VERSION
|
6
8
|
|
7
9
|
group :development do
|
8
|
-
gem "
|
10
|
+
gem "guard-rspec", require: false
|
11
|
+
gem "pry", require: false
|
9
12
|
end
|
10
13
|
|
11
|
-
group :test do
|
12
|
-
gem "rspec", "~> 3.0"
|
13
|
-
gem "rubocop", "0.36.0"
|
14
|
+
group :development, :test do
|
14
15
|
gem "coveralls", require: false
|
16
|
+
gem "rake-compiler", require: false
|
17
|
+
gem "rspec", "~> 3.7", require: false
|
18
|
+
gem "rubocop", "0.82.0", require: false
|
15
19
|
end
|
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -1,196 +1,151 @@
|
|
1
|
-
![nio4r](https://raw.github.com/
|
2
|
-
|
1
|
+
# ![nio4r](https://raw.github.com/socketry/nio4r/master/logo.png)
|
2
|
+
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/nio4r.svg)](http://rubygems.org/gems/nio4r)
|
4
|
-
[![
|
5
|
-
[![
|
6
|
-
[![
|
7
|
-
[![
|
4
|
+
[![Travis CI Status](https://secure.travis-ci.org/socketry/nio4r.svg?branch=master)](http://travis-ci.org/socketry/nio4r)
|
5
|
+
[![Appveyor Status](https://ci.appveyor.com/api/projects/status/1ru8x81v91vaewax/branch/master?svg=true)](https://ci.appveyor.com/project/tarcieri/nio4r/branch/master)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/socketry/nio4r.svg)](https://codeclimate.com/github/socketry/nio4r)
|
7
|
+
[![Coverage Status](https://coveralls.io/repos/socketry/nio4r/badge.svg?branch=master)](https://coveralls.io/r/socketry/nio4r)
|
8
|
+
[![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/gems/nio4r/2.2.0)
|
9
|
+
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/socketry/nio4r/blob/master/LICENSE.txt)
|
10
|
+
|
11
|
+
_NOTE: This is the 2.x **stable** branch of nio4r. For the 1.x **legacy** branch,
|
12
|
+
please see:_
|
8
13
|
|
9
|
-
nio4r
|
14
|
+
https://github.com/socketry/nio4r/tree/1-x-stable
|
10
15
|
|
11
|
-
|
16
|
+
**New I/O for Ruby (nio4r)**: cross-platform asynchronous I/O primitives for
|
17
|
+
scalable network clients and servers. Modeled after the Java NIO API, but
|
18
|
+
simplified for ease-of-use.
|
19
|
+
|
20
|
+
**nio4r** provides an abstract, cross-platform stateful I/O selector API for Ruby.
|
12
21
|
I/O selectors are the heart of "reactor"-based event loops, and monitor
|
13
22
|
multiple I/O objects for various types of readiness, e.g. ready for reading or
|
14
23
|
writing.
|
15
24
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
25
|
+
## Projects using nio4r
|
26
|
+
|
27
|
+
* [ActionCable]: Rails 5 WebSocket protocol, uses nio4r for a WebSocket server
|
28
|
+
* [Celluloid::IO]: Actor-based concurrency framework, uses nio4r for async I/O
|
29
|
+
* [Socketry Async]: Asynchronous I/O framework for Ruby
|
30
|
+
* [Puma]: Ruby/Rack web server built for concurrency
|
21
31
|
|
22
|
-
|
32
|
+
[ActionCable]: https://rubygems.org/gems/actioncable
|
33
|
+
[Celluloid::IO]: https://github.com/celluloid/celluloid-io
|
34
|
+
[Socketry Async]: https://github.com/socketry/async
|
35
|
+
[Puma]: https://github.com/puma/puma
|
23
36
|
|
24
|
-
|
37
|
+
## Goals
|
25
38
|
|
26
39
|
* Expose high-level interfaces for stateful IO selectors
|
27
40
|
* Keep the API small to maximize both portability and performance across many
|
28
41
|
different OSes and Ruby VMs
|
29
42
|
* Provide inherently thread-safe facilities for working with IO objects
|
30
43
|
|
31
|
-
|
32
|
-
monitor multiple IO objects from a single Celluloid actor.
|
44
|
+
## Supported platforms
|
33
45
|
|
34
|
-
|
35
|
-
|
46
|
+
* Ruby 2.3
|
47
|
+
* Ruby 2.4
|
48
|
+
* Ruby 2.5
|
49
|
+
* Ruby 2.6
|
50
|
+
* Ruby 2.7
|
51
|
+
* [JRuby](https://github.com/jruby/jruby)
|
52
|
+
* [TruffleRuby](https://github.com/oracle/truffleruby)
|
36
53
|
|
37
|
-
|
54
|
+
## Supported backends
|
38
55
|
|
39
|
-
* MRI
|
40
|
-
* JRuby
|
41
|
-
*
|
42
|
-
* A pure Ruby implementation based on Kernel.select is also provided
|
56
|
+
* **libev**: MRI C extension targeting multiple native IO selector APIs (e.g epoll, kqueue)
|
57
|
+
* **Java NIO**: JRuby extension which wraps the Java NIO subsystem
|
58
|
+
* **Pure Ruby**: `Kernel.select`-based backend that should work on any Ruby interpreter
|
43
59
|
|
44
|
-
|
60
|
+
## Discussion
|
45
61
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
* A pure Ruby implementation is also provided for Ruby implementations which
|
50
|
-
don't implement the MRI C extension API
|
62
|
+
For discussion and general help with nio4r, email
|
63
|
+
[socketry+subscribe@googlegroups.com][subscribe]
|
64
|
+
or join on the web via the [Google Group].
|
51
65
|
|
52
|
-
|
53
|
-
-----
|
66
|
+
We're also on IRC at ##socketry on irc.freenode.net.
|
54
67
|
|
55
|
-
|
68
|
+
[subscribe]: mailto:socketry+subscribe@googlegroups.com
|
69
|
+
[google group]: https://groups.google.com/group/socketry
|
56
70
|
|
57
|
-
|
58
|
-
might otherwise use Kernel.select, but want to monitor the same set of IO
|
59
|
-
objects across multiple select calls rather than having to reregister them
|
60
|
-
every single time:
|
71
|
+
## Documentation
|
61
72
|
|
62
|
-
|
63
|
-
|
73
|
+
[Please see the nio4r wiki](https://github.com/socketry/nio4r/wiki)
|
74
|
+
for more detailed documentation and usage notes:
|
64
75
|
|
65
|
-
|
66
|
-
|
76
|
+
* [Getting Started]: Introduction to nio4r's components
|
77
|
+
* [Selectors]: monitor multiple `IO` objects for readiness events
|
78
|
+
* [Monitors]: control interests and inspect readiness for specific `IO` objects
|
79
|
+
* [Byte Buffers]: fixed-size native buffers for high-performance I/O
|
67
80
|
|
68
|
-
|
69
|
-
|
70
|
-
|
81
|
+
[Getting Started]: https://github.com/socketry/nio4r/wiki/Getting-Started
|
82
|
+
[Selectors]: https://github.com/socketry/nio4r/wiki/Selectors
|
83
|
+
[Monitors]: https://github.com/socketry/nio4r/wiki/Monitors
|
84
|
+
[Byte Buffers]: https://github.com/socketry/nio4r/wiki/Byte-Buffers
|
71
85
|
|
72
|
-
|
73
|
-
>> reader, writer = IO.pipe
|
74
|
-
=> [#<IO:0xf30>, #<IO:0xf34>]
|
75
|
-
>> monitor = selector.register(reader, :r)
|
76
|
-
=> #<NIO::Monitor:0xfbc>
|
77
|
-
```
|
86
|
+
See also:
|
78
87
|
|
79
|
-
|
80
|
-
object which you can use for managing how a particular IO object is being
|
81
|
-
monitored. Monitors will store an arbitrary value of your choice, which
|
82
|
-
provides an easy way to implement callbacks:
|
88
|
+
* [YARD API documentation](http://www.rubydoc.info/gems/nio4r/frames)
|
83
89
|
|
84
|
-
|
85
|
-
>> monitor = selector.register(reader, :r)
|
86
|
-
=> #<NIO::Monitor:0xfbc>
|
87
|
-
>> monitor.value = proc { puts "Got some data: #{monitor.io.read_nonblock(4096)}" }
|
88
|
-
=> #<Proc:0x1000@(irb):4>
|
89
|
-
```
|
90
|
+
## Non-goals
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
=> #<IO:0x103c>
|
97
|
-
>> ready = selector.select
|
98
|
-
=> [#<NIO::Monitor:0xfbc>]
|
99
|
-
>> ready.each { |m| m.value.call }
|
100
|
-
Got some data: Hi there!
|
101
|
-
=> [#<NIO::Monitor:0xfbc>]
|
102
|
-
```
|
103
|
-
|
104
|
-
By default, NIO::Selector#select will block indefinitely until one of the IO
|
105
|
-
objects being monitored becomes ready. However, you can also pass a timeout to
|
106
|
-
wait in seconds to NIO::Selector#select just like you can with Kernel.select:
|
92
|
+
**nio4r** is not a full-featured event framework like [EventMachine] or [Cool.io].
|
93
|
+
Instead, nio4r is the sort of thing you might write a library like that on
|
94
|
+
top of. nio4r provides a minimal API such that individual Ruby implementers
|
95
|
+
may choose to produce optimized versions for their platform, without having
|
96
|
+
to maintain a large codebase.
|
107
97
|
|
108
|
-
|
109
|
-
|
110
|
-
```
|
98
|
+
[EventMachine]: https://github.com/eventmachine/eventmachine
|
99
|
+
[Cool.io]: https://coolio.github.io/
|
111
100
|
|
112
|
-
|
101
|
+
## Releases
|
113
102
|
|
114
|
-
|
115
|
-
passing a block to select. The block will be called for each ready monitor
|
116
|
-
object, with that object passed as an argument. The number of ready monitors
|
117
|
-
is returned as a Fixnum:
|
103
|
+
### CRuby
|
118
104
|
|
119
|
-
```ruby
|
120
|
-
>> selector.select { |m| m.value.call }
|
121
|
-
Got some data: Hi there!
|
122
|
-
=> 1
|
123
105
|
```
|
124
|
-
|
125
|
-
|
126
|
-
the selector:
|
127
|
-
|
128
|
-
```ruby
|
129
|
-
selector.deregister(reader)
|
106
|
+
rake clean
|
107
|
+
rake release
|
130
108
|
```
|
131
109
|
|
132
|
-
###
|
133
|
-
|
134
|
-
Monitors provide methods which let you introspect on why a particular IO
|
135
|
-
object was selected. These methods are not thread safe unless you are holding
|
136
|
-
the selector lock (i.e. if you're in a block passed to #select). Only use them
|
137
|
-
if you aren't concerned with thread safety, or you're within a #select
|
138
|
-
block:
|
139
|
-
|
140
|
-
- ***#interests***: what this monitor is interested in (:r, :w, or :rw)
|
141
|
-
- ***#interests=***: change the current interests for a monitor (to :r, :w, or :rw)
|
142
|
-
- ***#readiness***: what I/O operations the monitored object is ready for
|
143
|
-
- ***#readable?***: was the IO readable last time it was selected?
|
144
|
-
- ***#writable?***: was the IO writable last time it was selected?
|
145
|
-
|
146
|
-
Monitors also support a ***#value*** and ***#value=*** method for storing a
|
147
|
-
handle to an arbitrary object of your choice (e.g. a proc)
|
148
|
-
|
149
|
-
### Flow Control
|
110
|
+
### JRuby
|
150
111
|
|
151
|
-
|
152
|
-
please read the [Flow Control Guide on the
|
153
|
-
Wiki](https://github.com/celluloid/nio4r/wiki/Basic-Flow-Control)
|
112
|
+
You might need to delete `Gemfile.lock` before trying to `bundle install`.
|
154
113
|
|
155
|
-
|
156
|
-
|
114
|
+
```
|
115
|
+
rake clean
|
116
|
+
rake compile
|
117
|
+
rake release
|
118
|
+
```
|
157
119
|
|
158
|
-
|
159
|
-
concurrent threads. Only one thread can select on a NIO::Selector at a given
|
160
|
-
time, and while a thread is selecting other threads are blocked from
|
161
|
-
registering or deregistering IO objects. Once a pending select has completed,
|
162
|
-
requests to register/unregister IO objects will be processed.
|
120
|
+
## License
|
163
121
|
|
164
|
-
|
165
|
-
middle of an NIO::Selector#select operation. This lets other threads that need
|
166
|
-
to communicate immediately with the selector unblock it so it can process
|
167
|
-
other events that it's not presently selecting on.
|
122
|
+
Released under the MIT license.
|
168
123
|
|
169
|
-
|
170
|
-
|
124
|
+
Copyright, 2019, by Tony Arcieri.
|
125
|
+
Copyright, 2019, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
|
171
126
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
to
|
127
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
128
|
+
of this software and associated documentation files (the "Software"), to deal
|
129
|
+
in the Software without restriction, including without limitation the rights
|
130
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
131
|
+
copies of the Software, and to permit persons to whom the Software is
|
132
|
+
furnished to do so, subject to the following conditions:
|
177
133
|
|
178
|
-
|
134
|
+
The above copyright notice and this permission notice shall be included in
|
135
|
+
all copies or substantial portions of the Software.
|
179
136
|
|
180
|
-
|
181
|
-
|
182
|
-
|
137
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
138
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
139
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
140
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
141
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
142
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
143
|
+
THE SOFTWARE.
|
183
144
|
|
184
|
-
|
185
|
-
advanced Ruby IO APIs. At some point in the future nio4r might provide a
|
186
|
-
cross-platform implementation that uses KGIO on CRubies, and Java NIO on JRuby,
|
187
|
-
however this is not the case today.
|
145
|
+
### libev
|
188
146
|
|
189
|
-
|
190
|
-
-------
|
147
|
+
Released under the BSD license. See [ext/libev/LICENSE] for details.
|
191
148
|
|
192
|
-
Copyright
|
193
|
-
See LICENSE.txt for further details.
|
149
|
+
Copyright, 2007-2019, by Marc Alexander Lehmann.
|
194
150
|
|
195
|
-
|
196
|
-
Distributed under the BSD license. See ext/libev/LICENSE for details.
|
151
|
+
[ext/libev/LICENSE]: https://github.com/socketry/nio4r/blob/master/ext/libev/LICENSE
|
data/Rakefile
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "bundler/gem_tasks"
|
3
4
|
require "rake/clean"
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
task default: %w(compile spec rubocop)
|
6
|
+
task default: %w[compile spec rubocop]
|
8
7
|
|
9
8
|
CLEAN.include "**/*.o", "**/*.so", "**/*.bundle", "**/*.jar", "pkg", "tmp"
|
data/examples/echo_server.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
$LOAD_PATH.push File.expand_path("
|
4
|
+
$LOAD_PATH.push File.expand_path("../lib", __dir__)
|
4
5
|
require "nio"
|
5
6
|
require "socket"
|
6
7
|
|
@@ -18,7 +19,7 @@ class EchoServer
|
|
18
19
|
|
19
20
|
def run
|
20
21
|
loop do
|
21
|
-
@selector.select { |monitor| monitor.value.call
|
22
|
+
@selector.select { |monitor| monitor.value.call }
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
data/ext/libev/Changes
CHANGED
@@ -1,18 +1,49 @@
|
|
1
1
|
Revision history for libev, a high-performance and full-featured event loop.
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
4.27 Thu Jun 27 22:43:44 CEST 2019
|
4
|
+
- linux aio backend almost complete rewritten to work around its
|
5
|
+
limitations.
|
6
|
+
- epoll backend now mandatory for linux aio backend.
|
7
|
+
- fail assertions more aggressively on invalid fd's detected
|
8
|
+
in the event loop, do not just silently fd_kill in case of
|
9
|
+
user error.
|
10
|
+
- ev_io_start/ev_io_stop now verify the watcher fd using
|
11
|
+
a syscall when EV_VERIFY is 2 or higher.
|
12
|
+
|
13
|
+
4.26 (EV only)
|
14
|
+
- update to libecb 0x00010006.
|
15
|
+
- new experimental linux aio backend (linux 4.18+).
|
16
|
+
- removed redundant 0-ptr check in ev_once.
|
17
|
+
- updated/extended ev_set_allocator documentation.
|
18
|
+
- replaced EMPTY2 macro by array_needsize_noinit.
|
19
|
+
- minor code cleanups.
|
20
|
+
- epoll backend now uses epoll_create1 also after fork.
|
21
|
+
|
22
|
+
4.25 Fri Dec 21 07:49:20 CET 2018
|
23
|
+
- INCOMPATIBLE CHANGE: EV_THROW was renamed to EV_NOEXCEPT
|
24
|
+
(EV_THROW still provided) and now uses noexcept on C++11 or newer.
|
25
|
+
- move the darwin select workaround highe rin ev.c, as newer versions of
|
26
|
+
darwin managed to break their broken select even more.
|
27
|
+
- ANDROID => __ANDROID__ (reported by enh@google.com).
|
28
|
+
- disable epoll_create1 on android because it has broken header files
|
29
|
+
and google is unwilling to fix them (reported by enh@google.com).
|
30
|
+
- avoid a minor compilation warning on win32.
|
31
|
+
- c++: remove deprecated dynamic throw() specifications.
|
32
|
+
- c++: improve the (unsupported) bad_loop exception class.
|
33
|
+
- backport perl ev_periodic example to C, untested.
|
34
|
+
- update libecb, biggets change is to include a memory fence
|
35
|
+
in ECB_MEMORY_FENCE_RELEASE on x86/amd64.
|
36
|
+
- minor autoconf/automake modernisation.
|
37
|
+
|
38
|
+
4.24 Wed Dec 28 05:19:55 CET 2016
|
39
|
+
- bump version to 4.24, as the release tarball inexplicably
|
40
|
+
didn't have the right version in ev.h, even though the cvs-tagged
|
41
|
+
version did have the right one (reported by Ales Teska).
|
42
|
+
|
43
|
+
4.23 Wed Nov 16 18:23:41 CET 2016
|
44
|
+
- move some declarations at the beginning to help certain retarded
|
45
|
+
microsoft compilers, even though their documentation claims
|
46
|
+
otherwise (reported by Ruslan Osmanov).
|
16
47
|
|
17
48
|
4.22 Sun Dec 20 22:11:50 CET 2015
|
18
49
|
- when epoll detects unremovable fds in the fd set, rebuild
|
data/ext/libev/README
CHANGED
@@ -18,7 +18,8 @@ ABOUT
|
|
18
18
|
- extensive and detailed, readable documentation (not doxygen garbage).
|
19
19
|
- fully supports fork, can detect fork in various ways and automatically
|
20
20
|
re-arms kernel mechanisms that do not support fork.
|
21
|
-
- highly optimised select, poll, epoll,
|
21
|
+
- highly optimised select, poll, linux epoll, linux aio, bsd kqueue
|
22
|
+
and solaris event ports backends.
|
22
23
|
- filesystem object (path) watching (with optional linux inotify support).
|
23
24
|
- wallclock-based times (using absolute time, cron-like).
|
24
25
|
- relative timers/timeouts (handle time jumps).
|
data/ext/libev/ev.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* libev event processing core, watcher management
|
3
3
|
*
|
4
|
-
* Copyright (c) 2007
|
4
|
+
* Copyright (c) 2007-2019 Marc Alexander Lehmann <libev@schmorp.de>
|
5
5
|
* All rights reserved.
|
6
6
|
*
|
7
7
|
* Redistribution and use in source and binary forms, with or without modifica-
|
@@ -39,6 +39,11 @@
|
|
39
39
|
|
40
40
|
/* ########## NIO4R PATCHERY HO! ########## */
|
41
41
|
#include "ruby.h"
|
42
|
+
#include "ruby/thread.h"
|
43
|
+
|
44
|
+
#ifdef __APPLE__
|
45
|
+
#include <AvailabilityMacros.h>
|
46
|
+
#endif
|
42
47
|
/* ######################################## */
|
43
48
|
|
44
49
|
/* this big block deduces configuration from config.h */
|
@@ -121,6 +126,15 @@
|
|
121
126
|
# define EV_USE_EPOLL 0
|
122
127
|
# endif
|
123
128
|
|
129
|
+
# if HAVE_LINUX_AIO_ABI_H
|
130
|
+
# ifndef EV_USE_LINUXAIO
|
131
|
+
# define EV_USE_LINUXAIO EV_FEATURE_BACKENDS
|
132
|
+
# endif
|
133
|
+
# else
|
134
|
+
# undef EV_USE_LINUXAIO
|
135
|
+
# define EV_USE_LINUXAIO 0
|
136
|
+
# endif
|
137
|
+
|
124
138
|
# if HAVE_KQUEUE && HAVE_SYS_EVENT_H
|
125
139
|
# ifndef EV_USE_KQUEUE
|
126
140
|
# define EV_USE_KQUEUE EV_FEATURE_BACKENDS
|
@@ -168,6 +182,16 @@
|
|
168
182
|
|
169
183
|
#endif
|
170
184
|
|
185
|
+
/* OS X, in its infinite idiocy, actually HARDCODES
|
186
|
+
* a limit of 1024 into their select. Where people have brains,
|
187
|
+
* OS X engineers apparently have a vacuum. Or maybe they were
|
188
|
+
* ordered to have a vacuum, or they do anything for money.
|
189
|
+
* This might help. Or not.
|
190
|
+
* Note that this must be defined early, as other include files
|
191
|
+
* will rely on this define as well.
|
192
|
+
*/
|
193
|
+
#define _DARWIN_UNLIMITED_SELECT 1
|
194
|
+
|
171
195
|
#include <stdlib.h>
|
172
196
|
#include <string.h>
|
173
197
|
#include <fcntl.h>
|
@@ -215,14 +239,6 @@
|
|
215
239
|
# undef EV_AVOID_STDIO
|
216
240
|
#endif
|
217
241
|
|
218
|
-
/* OS X, in its infinite idiocy, actually HARDCODES
|
219
|
-
* a limit of 1024 into their select. Where people have brains,
|
220
|
-
* OS X engineers apparently have a vacuum. Or maybe they were
|
221
|
-
* ordered to have a vacuum, or they do anything for money.
|
222
|
-
* This might help. Or not.
|
223
|
-
*/
|
224
|
-
#define _DARWIN_UNLIMITED_SELECT 1
|
225
|
-
|
226
242
|
/* this block tries to deduce configuration from header-defined symbols and defaults */
|
227
243
|
|
228
244
|
/* try to deduce the maximum number of signals on this platform */
|
@@ -369,7 +385,7 @@
|
|
369
385
|
# define EV_HEAP_CACHE_AT EV_FEATURE_DATA
|
370
386
|
#endif
|
371
387
|
|
372
|
-
#ifdef
|
388
|
+
#ifdef __ANDROID__
|
373
389
|
/* supposedly, android doesn't typedef fd_mask */
|
374
390
|
# undef EV_USE_SELECT
|
375
391
|
# define EV_USE_SELECT 0
|
@@ -423,6 +439,14 @@
|
|
423
439
|
# endif
|
424
440
|
#endif
|
425
441
|
|
442
|
+
#if EV_USE_LINUXAIO
|
443
|
+
# include <sys/syscall.h>
|
444
|
+
# if !SYS_io_getevents || !EV_USE_EPOLL /* ev_linxaio uses ev_poll.c:ev_epoll_create */
|
445
|
+
# undef EV_USE_LINUXAIO
|
446
|
+
# define EV_USE_LINUXAIO 0
|
447
|
+
# endif
|
448
|
+
#endif
|
449
|
+
|
426
450
|
#if EV_USE_INOTIFY
|
427
451
|
# include <sys/statfs.h>
|
428
452
|
# include <sys/inotify.h>
|
@@ -538,7 +562,7 @@ struct signalfd_siginfo
|
|
538
562
|
#define ECB_H
|
539
563
|
|
540
564
|
/* 16 bits major, 16 bits minor */
|
541
|
-
#define ECB_VERSION
|
565
|
+
#define ECB_VERSION 0x00010006
|
542
566
|
|
543
567
|
#ifdef _WIN32
|
544
568
|
typedef signed char int8_t;
|
@@ -613,6 +637,8 @@ struct signalfd_siginfo
|
|
613
637
|
|
614
638
|
#define ECB_CPP (__cplusplus+0)
|
615
639
|
#define ECB_CPP11 (__cplusplus >= 201103L)
|
640
|
+
#define ECB_CPP14 (__cplusplus >= 201402L)
|
641
|
+
#define ECB_CPP17 (__cplusplus >= 201703L)
|
616
642
|
|
617
643
|
#if ECB_CPP
|
618
644
|
#define ECB_C 0
|
@@ -624,6 +650,7 @@ struct signalfd_siginfo
|
|
624
650
|
|
625
651
|
#define ECB_C99 (ECB_STDC_VERSION >= 199901L)
|
626
652
|
#define ECB_C11 (ECB_STDC_VERSION >= 201112L)
|
653
|
+
#define ECB_C17 (ECB_STDC_VERSION >= 201710L)
|
627
654
|
|
628
655
|
#if ECB_CPP
|
629
656
|
#define ECB_EXTERN_C extern "C"
|
@@ -659,14 +686,15 @@ struct signalfd_siginfo
|
|
659
686
|
|
660
687
|
#ifndef ECB_MEMORY_FENCE
|
661
688
|
#if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
|
689
|
+
#define ECB_MEMORY_FENCE_RELAXED __asm__ __volatile__ ("" : : : "memory")
|
662
690
|
#if __i386 || __i386__
|
663
691
|
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
|
664
692
|
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
|
665
|
-
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
|
693
|
+
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("" : : : "memory")
|
666
694
|
#elif ECB_GCC_AMD64
|
667
695
|
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
|
668
696
|
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
|
669
|
-
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
|
697
|
+
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("" : : : "memory")
|
670
698
|
#elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__
|
671
699
|
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
|
672
700
|
#elif defined __ARM_ARCH_2__ \
|
@@ -718,12 +746,14 @@ struct signalfd_siginfo
|
|
718
746
|
#define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
|
719
747
|
#define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE)
|
720
748
|
#define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE)
|
749
|
+
#define ECB_MEMORY_FENCE_RELAXED __atomic_thread_fence (__ATOMIC_RELAXED)
|
721
750
|
|
722
751
|
#elif ECB_CLANG_EXTENSION(c_atomic)
|
723
752
|
/* see comment below (stdatomic.h) about the C11 memory model. */
|
724
753
|
#define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
|
725
754
|
#define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE)
|
726
755
|
#define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE)
|
756
|
+
#define ECB_MEMORY_FENCE_RELAXED __c11_atomic_thread_fence (__ATOMIC_RELAXED)
|
727
757
|
|
728
758
|
#elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
|
729
759
|
#define ECB_MEMORY_FENCE __sync_synchronize ()
|
@@ -743,9 +773,10 @@ struct signalfd_siginfo
|
|
743
773
|
#define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
|
744
774
|
#elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
|
745
775
|
#include <mbarrier.h>
|
746
|
-
#define ECB_MEMORY_FENCE __machine_rw_barrier
|
747
|
-
#define ECB_MEMORY_FENCE_ACQUIRE
|
748
|
-
#define ECB_MEMORY_FENCE_RELEASE
|
776
|
+
#define ECB_MEMORY_FENCE __machine_rw_barrier ()
|
777
|
+
#define ECB_MEMORY_FENCE_ACQUIRE __machine_acq_barrier ()
|
778
|
+
#define ECB_MEMORY_FENCE_RELEASE __machine_rel_barrier ()
|
779
|
+
#define ECB_MEMORY_FENCE_RELAXED __compiler_barrier ()
|
749
780
|
#elif __xlC__
|
750
781
|
#define ECB_MEMORY_FENCE __sync ()
|
751
782
|
#endif
|
@@ -756,15 +787,9 @@ struct signalfd_siginfo
|
|
756
787
|
/* we assume that these memory fences work on all variables/all memory accesses, */
|
757
788
|
/* not just C11 atomics and atomic accesses */
|
758
789
|
#include <stdatomic.h>
|
759
|
-
/* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */
|
760
|
-
/* any fence other than seq_cst, which isn't very efficient for us. */
|
761
|
-
/* Why that is, we don't know - either the C11 memory model is quite useless */
|
762
|
-
/* for most usages, or gcc and clang have a bug */
|
763
|
-
/* I *currently* lean towards the latter, and inefficiently implement */
|
764
|
-
/* all three of ecb's fences as a seq_cst fence */
|
765
|
-
/* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */
|
766
|
-
/* for all __atomic_thread_fence's except seq_cst */
|
767
790
|
#define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst)
|
791
|
+
#define ECB_MEMORY_FENCE_ACQUIRE atomic_thread_fence (memory_order_acquire)
|
792
|
+
#define ECB_MEMORY_FENCE_RELEASE atomic_thread_fence (memory_order_release)
|
768
793
|
#endif
|
769
794
|
#endif
|
770
795
|
|
@@ -794,6 +819,10 @@ struct signalfd_siginfo
|
|
794
819
|
#define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
|
795
820
|
#endif
|
796
821
|
|
822
|
+
#if !defined ECB_MEMORY_FENCE_RELAXED && defined ECB_MEMORY_FENCE
|
823
|
+
#define ECB_MEMORY_FENCE_RELAXED ECB_MEMORY_FENCE /* very heavy-handed */
|
824
|
+
#endif
|
825
|
+
|
797
826
|
/*****************************************************************************/
|
798
827
|
|
799
828
|
#if ECB_CPP
|
@@ -1533,7 +1562,7 @@ ecb_binary32_to_binary16 (uint32_t x)
|
|
1533
1562
|
#if EV_FEATURE_CODE
|
1534
1563
|
# define inline_speed ecb_inline
|
1535
1564
|
#else
|
1536
|
-
# define inline_speed static
|
1565
|
+
# define inline_speed noinline static
|
1537
1566
|
#endif
|
1538
1567
|
|
1539
1568
|
#define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
|
@@ -1544,8 +1573,7 @@ ecb_binary32_to_binary16 (uint32_t x)
|
|
1544
1573
|
# define ABSPRI(w) (((W)w)->priority - EV_MINPRI)
|
1545
1574
|
#endif
|
1546
1575
|
|
1547
|
-
#define EMPTY
|
1548
|
-
#define EMPTY2(a,b) /* used to suppress some warnings */
|
1576
|
+
#define EMPTY /* required for microsofts broken pseudo-c compiler */
|
1549
1577
|
|
1550
1578
|
typedef ev_watcher *W;
|
1551
1579
|
typedef ev_watcher_list *WL;
|
@@ -1580,6 +1608,10 @@ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work?
|
|
1580
1608
|
|
1581
1609
|
/*****************************************************************************/
|
1582
1610
|
|
1611
|
+
#if EV_USE_LINUXAIO
|
1612
|
+
# include <linux/aio_abi.h> /* probably only needed for aio_context_t */
|
1613
|
+
#endif
|
1614
|
+
|
1583
1615
|
/* define a suitable floor function (only used by periodics atm) */
|
1584
1616
|
|
1585
1617
|
#if EV_USE_FLOOR
|
@@ -1590,7 +1622,8 @@ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work?
|
|
1590
1622
|
#include <float.h>
|
1591
1623
|
|
1592
1624
|
/* a floor() replacement function, should be independent of ev_tstamp type */
|
1593
|
-
|
1625
|
+
noinline
|
1626
|
+
static ev_tstamp
|
1594
1627
|
ev_floor (ev_tstamp v)
|
1595
1628
|
{
|
1596
1629
|
/* the choice of shift factor is not terribly important */
|
@@ -1632,7 +1665,8 @@ ev_floor (ev_tstamp v)
|
|
1632
1665
|
# include <sys/utsname.h>
|
1633
1666
|
#endif
|
1634
1667
|
|
1635
|
-
|
1668
|
+
noinline ecb_cold
|
1669
|
+
static unsigned int
|
1636
1670
|
ev_linux_version (void)
|
1637
1671
|
{
|
1638
1672
|
#ifdef __linux
|
@@ -1671,22 +1705,25 @@ ev_linux_version (void)
|
|
1671
1705
|
/*****************************************************************************/
|
1672
1706
|
|
1673
1707
|
#if EV_AVOID_STDIO
|
1674
|
-
|
1708
|
+
noinline ecb_cold
|
1709
|
+
static void
|
1675
1710
|
ev_printerr (const char *msg)
|
1676
1711
|
{
|
1677
1712
|
write (STDERR_FILENO, msg, strlen (msg));
|
1678
1713
|
}
|
1679
1714
|
#endif
|
1680
1715
|
|
1681
|
-
static void (*syserr_cb)(const char *msg)
|
1716
|
+
static void (*syserr_cb)(const char *msg) EV_NOEXCEPT;
|
1682
1717
|
|
1683
|
-
|
1684
|
-
|
1718
|
+
ecb_cold
|
1719
|
+
void
|
1720
|
+
ev_set_syserr_cb (void (*cb)(const char *msg) EV_NOEXCEPT) EV_NOEXCEPT
|
1685
1721
|
{
|
1686
1722
|
syserr_cb = cb;
|
1687
1723
|
}
|
1688
1724
|
|
1689
|
-
|
1725
|
+
noinline ecb_cold
|
1726
|
+
static void
|
1690
1727
|
ev_syserr (const char *msg)
|
1691
1728
|
{
|
1692
1729
|
if (!msg)
|
@@ -1709,7 +1746,7 @@ ev_syserr (const char *msg)
|
|
1709
1746
|
}
|
1710
1747
|
|
1711
1748
|
static void *
|
1712
|
-
ev_realloc_emul (void *ptr,
|
1749
|
+
ev_realloc_emul (void *ptr, size_t size) EV_NOEXCEPT
|
1713
1750
|
{
|
1714
1751
|
/* some systems, notably openbsd and darwin, fail to properly
|
1715
1752
|
* implement realloc (x, 0) (as required by both ansi c-89 and
|
@@ -1725,16 +1762,17 @@ ev_realloc_emul (void *ptr, long size) EV_THROW
|
|
1725
1762
|
return 0;
|
1726
1763
|
}
|
1727
1764
|
|
1728
|
-
static void *(*alloc)(void *ptr,
|
1765
|
+
static void *(*alloc)(void *ptr, size_t size) EV_NOEXCEPT = ev_realloc_emul;
|
1729
1766
|
|
1730
|
-
|
1731
|
-
|
1767
|
+
ecb_cold
|
1768
|
+
void
|
1769
|
+
ev_set_allocator (void *(*cb)(void *ptr, size_t size) EV_NOEXCEPT) EV_NOEXCEPT
|
1732
1770
|
{
|
1733
1771
|
alloc = cb;
|
1734
1772
|
}
|
1735
1773
|
|
1736
1774
|
inline_speed void *
|
1737
|
-
ev_realloc (void *ptr,
|
1775
|
+
ev_realloc (void *ptr, size_t size)
|
1738
1776
|
{
|
1739
1777
|
ptr = alloc (ptr, size);
|
1740
1778
|
|
@@ -1765,7 +1803,7 @@ typedef struct
|
|
1765
1803
|
WL head;
|
1766
1804
|
unsigned char events; /* the events watched for */
|
1767
1805
|
unsigned char reify; /* flag set when this ANFD needs reification (EV_ANFD_REIFY, EV__IOFDSET) */
|
1768
|
-
unsigned char emask; /*
|
1806
|
+
unsigned char emask; /* some backends store the actual kernel mask in here */
|
1769
1807
|
unsigned char unused;
|
1770
1808
|
#if EV_USE_EPOLL
|
1771
1809
|
unsigned int egen; /* generation counter to counter epoll bugs */
|
@@ -1855,7 +1893,7 @@ typedef struct
|
|
1855
1893
|
|
1856
1894
|
#ifndef EV_HAVE_EV_TIME
|
1857
1895
|
ev_tstamp
|
1858
|
-
ev_time (void)
|
1896
|
+
ev_time (void) EV_NOEXCEPT
|
1859
1897
|
{
|
1860
1898
|
#if EV_USE_REALTIME
|
1861
1899
|
if (expect_true (have_realtime))
|
@@ -1889,14 +1927,14 @@ get_clock (void)
|
|
1889
1927
|
|
1890
1928
|
#if EV_MULTIPLICITY
|
1891
1929
|
ev_tstamp
|
1892
|
-
ev_now (EV_P)
|
1930
|
+
ev_now (EV_P) EV_NOEXCEPT
|
1893
1931
|
{
|
1894
1932
|
return ev_rt_now;
|
1895
1933
|
}
|
1896
1934
|
#endif
|
1897
1935
|
|
1898
1936
|
void
|
1899
|
-
ev_sleep (ev_tstamp delay)
|
1937
|
+
ev_sleep (ev_tstamp delay) EV_NOEXCEPT
|
1900
1938
|
{
|
1901
1939
|
if (delay > 0.)
|
1902
1940
|
{
|
@@ -1906,6 +1944,8 @@ ev_sleep (ev_tstamp delay) EV_THROW
|
|
1906
1944
|
EV_TS_SET (ts, delay);
|
1907
1945
|
nanosleep (&ts, 0);
|
1908
1946
|
#elif defined _WIN32
|
1947
|
+
/* maybe this should round up, as ms is very low resolution */
|
1948
|
+
/* compared to select (µs) or nanosleep (ns) */
|
1909
1949
|
Sleep ((unsigned long)(delay * 1e3));
|
1910
1950
|
#else
|
1911
1951
|
struct timeval tv;
|
@@ -1946,23 +1986,26 @@ array_nextsize (int elem, int cur, int cnt)
|
|
1946
1986
|
return ncur;
|
1947
1987
|
}
|
1948
1988
|
|
1949
|
-
|
1989
|
+
noinline ecb_cold
|
1990
|
+
static void *
|
1950
1991
|
array_realloc (int elem, void *base, int *cur, int cnt)
|
1951
1992
|
{
|
1952
1993
|
*cur = array_nextsize (elem, *cur, cnt);
|
1953
1994
|
return ev_realloc (base, elem * *cur);
|
1954
1995
|
}
|
1955
1996
|
|
1956
|
-
#define
|
1957
|
-
|
1997
|
+
#define array_needsize_noinit(base,offset,count)
|
1998
|
+
|
1999
|
+
#define array_needsize_zerofill(base,offset,count) \
|
2000
|
+
memset ((void *)(base + offset), 0, sizeof (*(base)) * (count))
|
1958
2001
|
|
1959
2002
|
#define array_needsize(type,base,cur,cnt,init) \
|
1960
2003
|
if (expect_false ((cnt) > (cur))) \
|
1961
2004
|
{ \
|
1962
|
-
int
|
2005
|
+
ecb_unused int ocur_ = (cur); \
|
1963
2006
|
(base) = (type *)array_realloc \
|
1964
2007
|
(sizeof (type), (base), &(cur), (cnt)); \
|
1965
|
-
init ((base)
|
2008
|
+
init ((base), ocur_, ((cur) - ocur_)); \
|
1966
2009
|
}
|
1967
2010
|
|
1968
2011
|
#if 0
|
@@ -1981,13 +2024,15 @@ array_realloc (int elem, void *base, int *cur, int cnt)
|
|
1981
2024
|
/*****************************************************************************/
|
1982
2025
|
|
1983
2026
|
/* dummy callback for pending events */
|
1984
|
-
|
2027
|
+
noinline
|
2028
|
+
static void
|
1985
2029
|
pendingcb (EV_P_ ev_prepare *w, int revents)
|
1986
2030
|
{
|
1987
2031
|
}
|
1988
2032
|
|
1989
|
-
|
1990
|
-
|
2033
|
+
noinline
|
2034
|
+
void
|
2035
|
+
ev_feed_event (EV_P_ void *w, int revents) EV_NOEXCEPT
|
1991
2036
|
{
|
1992
2037
|
W w_ = (W)w;
|
1993
2038
|
int pri = ABSPRI (w_);
|
@@ -1997,7 +2042,7 @@ ev_feed_event (EV_P_ void *w, int revents) EV_THROW
|
|
1997
2042
|
else
|
1998
2043
|
{
|
1999
2044
|
w_->pending = ++pendingcnt [pri];
|
2000
|
-
array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending,
|
2045
|
+
array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, array_needsize_noinit);
|
2001
2046
|
pendings [pri][w_->pending - 1].w = w_;
|
2002
2047
|
pendings [pri][w_->pending - 1].events = revents;
|
2003
2048
|
}
|
@@ -2008,7 +2053,7 @@ ev_feed_event (EV_P_ void *w, int revents) EV_THROW
|
|
2008
2053
|
inline_speed void
|
2009
2054
|
feed_reverse (EV_P_ W w)
|
2010
2055
|
{
|
2011
|
-
array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1,
|
2056
|
+
array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, array_needsize_noinit);
|
2012
2057
|
rfeeds [rfeedcnt++] = w;
|
2013
2058
|
}
|
2014
2059
|
|
@@ -2058,7 +2103,7 @@ fd_event (EV_P_ int fd, int revents)
|
|
2058
2103
|
}
|
2059
2104
|
|
2060
2105
|
void
|
2061
|
-
ev_feed_fd_event (EV_P_ int fd, int revents)
|
2106
|
+
ev_feed_fd_event (EV_P_ int fd, int revents) EV_NOEXCEPT
|
2062
2107
|
{
|
2063
2108
|
if (fd >= 0 && fd < anfdmax)
|
2064
2109
|
fd_event_nocheck (EV_A_ fd, revents);
|
@@ -2105,7 +2150,7 @@ fd_reify (EV_P)
|
|
2105
2150
|
unsigned char o_events = anfd->events;
|
2106
2151
|
unsigned char o_reify = anfd->reify;
|
2107
2152
|
|
2108
|
-
anfd->reify
|
2153
|
+
anfd->reify = 0;
|
2109
2154
|
|
2110
2155
|
/*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */
|
2111
2156
|
{
|
@@ -2126,7 +2171,8 @@ fd_reify (EV_P)
|
|
2126
2171
|
}
|
2127
2172
|
|
2128
2173
|
/* something about the given fd changed */
|
2129
|
-
inline_size
|
2174
|
+
inline_size
|
2175
|
+
void
|
2130
2176
|
fd_change (EV_P_ int fd, int flags)
|
2131
2177
|
{
|
2132
2178
|
unsigned char reify = anfds [fd].reify;
|
@@ -2135,13 +2181,13 @@ fd_change (EV_P_ int fd, int flags)
|
|
2135
2181
|
if (expect_true (!reify))
|
2136
2182
|
{
|
2137
2183
|
++fdchangecnt;
|
2138
|
-
array_needsize (int, fdchanges, fdchangemax, fdchangecnt,
|
2184
|
+
array_needsize (int, fdchanges, fdchangemax, fdchangecnt, array_needsize_noinit);
|
2139
2185
|
fdchanges [fdchangecnt - 1] = fd;
|
2140
2186
|
}
|
2141
2187
|
}
|
2142
2188
|
|
2143
2189
|
/* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */
|
2144
|
-
inline_speed void
|
2190
|
+
inline_speed ecb_cold void
|
2145
2191
|
fd_kill (EV_P_ int fd)
|
2146
2192
|
{
|
2147
2193
|
ev_io *w;
|
@@ -2154,7 +2200,7 @@ fd_kill (EV_P_ int fd)
|
|
2154
2200
|
}
|
2155
2201
|
|
2156
2202
|
/* check whether the given fd is actually valid, for error recovery */
|
2157
|
-
inline_size int
|
2203
|
+
inline_size ecb_cold int
|
2158
2204
|
fd_valid (int fd)
|
2159
2205
|
{
|
2160
2206
|
#ifdef _WIN32
|
@@ -2165,7 +2211,8 @@ fd_valid (int fd)
|
|
2165
2211
|
}
|
2166
2212
|
|
2167
2213
|
/* called on EBADF to verify fds */
|
2168
|
-
|
2214
|
+
noinline ecb_cold
|
2215
|
+
static void
|
2169
2216
|
fd_ebadf (EV_P)
|
2170
2217
|
{
|
2171
2218
|
int fd;
|
@@ -2177,7 +2224,8 @@ fd_ebadf (EV_P)
|
|
2177
2224
|
}
|
2178
2225
|
|
2179
2226
|
/* called on ENOMEM in select/poll to kill some fds and retry */
|
2180
|
-
|
2227
|
+
noinline ecb_cold
|
2228
|
+
static void
|
2181
2229
|
fd_enomem (EV_P)
|
2182
2230
|
{
|
2183
2231
|
int fd;
|
@@ -2191,7 +2239,8 @@ fd_enomem (EV_P)
|
|
2191
2239
|
}
|
2192
2240
|
|
2193
2241
|
/* usually called after fork if backend needs to re-arm all fds from scratch */
|
2194
|
-
|
2242
|
+
noinline
|
2243
|
+
static void
|
2195
2244
|
fd_rearm_all (EV_P)
|
2196
2245
|
{
|
2197
2246
|
int fd;
|
@@ -2382,7 +2431,8 @@ static ANSIG signals [EV_NSIG - 1];
|
|
2382
2431
|
|
2383
2432
|
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
|
2384
2433
|
|
2385
|
-
|
2434
|
+
noinline ecb_cold
|
2435
|
+
static void
|
2386
2436
|
evpipe_init (EV_P)
|
2387
2437
|
{
|
2388
2438
|
if (!ev_is_active (&pipe_w))
|
@@ -2463,7 +2513,7 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
|
|
2463
2513
|
#ifdef _WIN32
|
2464
2514
|
WSABUF buf;
|
2465
2515
|
DWORD sent;
|
2466
|
-
buf.buf = &buf;
|
2516
|
+
buf.buf = (char *)&buf;
|
2467
2517
|
buf.len = 1;
|
2468
2518
|
WSASend (EV_FD_TO_WIN32_HANDLE (evpipe [1]), &buf, 1, &sent, 0, 0, 0);
|
2469
2519
|
#else
|
@@ -2545,7 +2595,7 @@ pipecb (EV_P_ ev_io *iow, int revents)
|
|
2545
2595
|
/*****************************************************************************/
|
2546
2596
|
|
2547
2597
|
void
|
2548
|
-
ev_feed_signal (int signum)
|
2598
|
+
ev_feed_signal (int signum) EV_NOEXCEPT
|
2549
2599
|
{
|
2550
2600
|
#if EV_MULTIPLICITY
|
2551
2601
|
EV_P;
|
@@ -2570,8 +2620,9 @@ ev_sighandler (int signum)
|
|
2570
2620
|
ev_feed_signal (signum);
|
2571
2621
|
}
|
2572
2622
|
|
2573
|
-
|
2574
|
-
|
2623
|
+
noinline
|
2624
|
+
void
|
2625
|
+
ev_feed_signal_event (EV_P_ int signum) EV_NOEXCEPT
|
2575
2626
|
{
|
2576
2627
|
WL w;
|
2577
2628
|
|
@@ -2690,6 +2741,9 @@ childcb (EV_P_ ev_signal *sw, int revents)
|
|
2690
2741
|
#if EV_USE_EPOLL
|
2691
2742
|
# include "ev_epoll.c"
|
2692
2743
|
#endif
|
2744
|
+
#if EV_USE_LINUXAIO
|
2745
|
+
# include "ev_linuxaio.c"
|
2746
|
+
#endif
|
2693
2747
|
#if EV_USE_POLL
|
2694
2748
|
# include "ev_poll.c"
|
2695
2749
|
#endif
|
@@ -2697,20 +2751,20 @@ childcb (EV_P_ ev_signal *sw, int revents)
|
|
2697
2751
|
# include "ev_select.c"
|
2698
2752
|
#endif
|
2699
2753
|
|
2700
|
-
int
|
2701
|
-
ev_version_major (void)
|
2754
|
+
ecb_cold int
|
2755
|
+
ev_version_major (void) EV_NOEXCEPT
|
2702
2756
|
{
|
2703
2757
|
return EV_VERSION_MAJOR;
|
2704
2758
|
}
|
2705
2759
|
|
2706
|
-
int
|
2707
|
-
ev_version_minor (void)
|
2760
|
+
ecb_cold int
|
2761
|
+
ev_version_minor (void) EV_NOEXCEPT
|
2708
2762
|
{
|
2709
2763
|
return EV_VERSION_MINOR;
|
2710
2764
|
}
|
2711
2765
|
|
2712
2766
|
/* return true if we are running with elevated privileges and should ignore env variables */
|
2713
|
-
|
2767
|
+
inline_size ecb_cold int
|
2714
2768
|
enable_secure (void)
|
2715
2769
|
{
|
2716
2770
|
#ifdef _WIN32
|
@@ -2721,44 +2775,58 @@ enable_secure (void)
|
|
2721
2775
|
#endif
|
2722
2776
|
}
|
2723
2777
|
|
2724
|
-
|
2725
|
-
|
2778
|
+
ecb_cold
|
2779
|
+
unsigned int
|
2780
|
+
ev_supported_backends (void) EV_NOEXCEPT
|
2726
2781
|
{
|
2727
2782
|
unsigned int flags = 0;
|
2728
2783
|
|
2729
|
-
if (EV_USE_PORT
|
2730
|
-
if (EV_USE_KQUEUE) flags |= EVBACKEND_KQUEUE;
|
2731
|
-
if (EV_USE_EPOLL
|
2732
|
-
|
2733
|
-
|
2784
|
+
if (EV_USE_PORT ) flags |= EVBACKEND_PORT;
|
2785
|
+
if (EV_USE_KQUEUE ) flags |= EVBACKEND_KQUEUE;
|
2786
|
+
if (EV_USE_EPOLL ) flags |= EVBACKEND_EPOLL;
|
2787
|
+
|
2788
|
+
#ifdef EV_USE_LINUXAIO
|
2789
|
+
if (EV_USE_LINUXAIO) flags |= EVBACKEND_LINUXAIO;
|
2790
|
+
#endif
|
2791
|
+
|
2792
|
+
if (EV_USE_POLL ) flags |= EVBACKEND_POLL;
|
2793
|
+
if (EV_USE_SELECT ) flags |= EVBACKEND_SELECT;
|
2734
2794
|
|
2735
2795
|
return flags;
|
2736
2796
|
}
|
2737
2797
|
|
2738
|
-
|
2739
|
-
|
2798
|
+
ecb_cold
|
2799
|
+
unsigned int
|
2800
|
+
ev_recommended_backends (void) EV_NOEXCEPT
|
2740
2801
|
{
|
2741
2802
|
unsigned int flags = ev_supported_backends ();
|
2742
2803
|
|
2743
|
-
#
|
2804
|
+
#if defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_14)
|
2805
|
+
/* apple has a poor track record but post 10.12.2 it seems to work sufficiently well */
|
2806
|
+
#elif defined(__NetBSD__)
|
2744
2807
|
/* kqueue is borked on everything but netbsd apparently */
|
2745
2808
|
/* it usually doesn't work correctly on anything but sockets and pipes */
|
2746
|
-
|
2747
|
-
#endif
|
2748
|
-
#ifdef __APPLE__
|
2809
|
+
#else
|
2749
2810
|
/* only select works correctly on that "unix-certified" platform */
|
2750
2811
|
flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */
|
2751
2812
|
flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */
|
2752
2813
|
#endif
|
2814
|
+
|
2753
2815
|
#ifdef __FreeBSD__
|
2754
2816
|
flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */
|
2755
2817
|
#endif
|
2756
2818
|
|
2819
|
+
/* TODO: linuxaio is very experimental */
|
2820
|
+
#if !EV_RECOMMEND_LINUXAIO
|
2821
|
+
flags &= ~EVBACKEND_LINUXAIO;
|
2822
|
+
#endif
|
2823
|
+
|
2757
2824
|
return flags;
|
2758
2825
|
}
|
2759
2826
|
|
2760
|
-
|
2761
|
-
|
2827
|
+
ecb_cold
|
2828
|
+
unsigned int
|
2829
|
+
ev_embeddable_backends (void) EV_NOEXCEPT
|
2762
2830
|
{
|
2763
2831
|
int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT;
|
2764
2832
|
|
@@ -2770,56 +2838,56 @@ ev_embeddable_backends (void) EV_THROW
|
|
2770
2838
|
}
|
2771
2839
|
|
2772
2840
|
unsigned int
|
2773
|
-
ev_backend (EV_P)
|
2841
|
+
ev_backend (EV_P) EV_NOEXCEPT
|
2774
2842
|
{
|
2775
2843
|
return backend;
|
2776
2844
|
}
|
2777
2845
|
|
2778
2846
|
#if EV_FEATURE_API
|
2779
2847
|
unsigned int
|
2780
|
-
ev_iteration (EV_P)
|
2848
|
+
ev_iteration (EV_P) EV_NOEXCEPT
|
2781
2849
|
{
|
2782
2850
|
return loop_count;
|
2783
2851
|
}
|
2784
2852
|
|
2785
2853
|
unsigned int
|
2786
|
-
ev_depth (EV_P)
|
2854
|
+
ev_depth (EV_P) EV_NOEXCEPT
|
2787
2855
|
{
|
2788
2856
|
return loop_depth;
|
2789
2857
|
}
|
2790
2858
|
|
2791
2859
|
void
|
2792
|
-
ev_set_io_collect_interval (EV_P_ ev_tstamp interval)
|
2860
|
+
ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT
|
2793
2861
|
{
|
2794
2862
|
io_blocktime = interval;
|
2795
2863
|
}
|
2796
2864
|
|
2797
2865
|
void
|
2798
|
-
ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval)
|
2866
|
+
ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT
|
2799
2867
|
{
|
2800
2868
|
timeout_blocktime = interval;
|
2801
2869
|
}
|
2802
2870
|
|
2803
2871
|
void
|
2804
|
-
ev_set_userdata (EV_P_ void *data)
|
2872
|
+
ev_set_userdata (EV_P_ void *data) EV_NOEXCEPT
|
2805
2873
|
{
|
2806
2874
|
userdata = data;
|
2807
2875
|
}
|
2808
2876
|
|
2809
2877
|
void *
|
2810
|
-
ev_userdata (EV_P)
|
2878
|
+
ev_userdata (EV_P) EV_NOEXCEPT
|
2811
2879
|
{
|
2812
2880
|
return userdata;
|
2813
2881
|
}
|
2814
2882
|
|
2815
2883
|
void
|
2816
|
-
ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb)
|
2884
|
+
ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_NOEXCEPT
|
2817
2885
|
{
|
2818
2886
|
invoke_cb = invoke_pending_cb;
|
2819
2887
|
}
|
2820
2888
|
|
2821
2889
|
void
|
2822
|
-
ev_set_loop_release_cb (EV_P_ void (*release)(EV_P)
|
2890
|
+
ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_NOEXCEPT, void (*acquire)(EV_P) EV_NOEXCEPT) EV_NOEXCEPT
|
2823
2891
|
{
|
2824
2892
|
release_cb = release;
|
2825
2893
|
acquire_cb = acquire;
|
@@ -2827,8 +2895,9 @@ ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV
|
|
2827
2895
|
#endif
|
2828
2896
|
|
2829
2897
|
/* initialise a loop structure, must be zero-initialised */
|
2830
|
-
|
2831
|
-
|
2898
|
+
noinline ecb_cold
|
2899
|
+
static void
|
2900
|
+
loop_init (EV_P_ unsigned int flags) EV_NOEXCEPT
|
2832
2901
|
{
|
2833
2902
|
if (!backend)
|
2834
2903
|
{
|
@@ -2896,22 +2965,25 @@ loop_init (EV_P_ unsigned int flags) EV_THROW
|
|
2896
2965
|
flags |= ev_recommended_backends ();
|
2897
2966
|
|
2898
2967
|
#if EV_USE_IOCP
|
2899
|
-
if (!backend && (flags & EVBACKEND_IOCP
|
2968
|
+
if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
|
2900
2969
|
#endif
|
2901
2970
|
#if EV_USE_PORT
|
2902
|
-
if (!backend && (flags & EVBACKEND_PORT
|
2971
|
+
if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
|
2903
2972
|
#endif
|
2904
2973
|
#if EV_USE_KQUEUE
|
2905
|
-
if (!backend && (flags & EVBACKEND_KQUEUE)) backend = kqueue_init
|
2974
|
+
if (!backend && (flags & EVBACKEND_KQUEUE )) backend = kqueue_init (EV_A_ flags);
|
2975
|
+
#endif
|
2976
|
+
#if EV_USE_LINUXAIO
|
2977
|
+
if (!backend && (flags & EVBACKEND_LINUXAIO)) backend = linuxaio_init (EV_A_ flags);
|
2906
2978
|
#endif
|
2907
2979
|
#if EV_USE_EPOLL
|
2908
|
-
if (!backend && (flags & EVBACKEND_EPOLL
|
2980
|
+
if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags);
|
2909
2981
|
#endif
|
2910
2982
|
#if EV_USE_POLL
|
2911
|
-
if (!backend && (flags & EVBACKEND_POLL
|
2983
|
+
if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags);
|
2912
2984
|
#endif
|
2913
2985
|
#if EV_USE_SELECT
|
2914
|
-
if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init
|
2986
|
+
if (!backend && (flags & EVBACKEND_SELECT )) backend = select_init (EV_A_ flags);
|
2915
2987
|
#endif
|
2916
2988
|
|
2917
2989
|
ev_prepare_init (&pending_w, pendingcb);
|
@@ -2924,7 +2996,8 @@ loop_init (EV_P_ unsigned int flags) EV_THROW
|
|
2924
2996
|
}
|
2925
2997
|
|
2926
2998
|
/* free up a loop structure */
|
2927
|
-
|
2999
|
+
ecb_cold
|
3000
|
+
void
|
2928
3001
|
ev_loop_destroy (EV_P)
|
2929
3002
|
{
|
2930
3003
|
int i;
|
@@ -2975,22 +3048,25 @@ ev_loop_destroy (EV_P)
|
|
2975
3048
|
close (backend_fd);
|
2976
3049
|
|
2977
3050
|
#if EV_USE_IOCP
|
2978
|
-
if (backend == EVBACKEND_IOCP
|
3051
|
+
if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
|
2979
3052
|
#endif
|
2980
3053
|
#if EV_USE_PORT
|
2981
|
-
if (backend == EVBACKEND_PORT
|
3054
|
+
if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
|
2982
3055
|
#endif
|
2983
3056
|
#if EV_USE_KQUEUE
|
2984
|
-
if (backend == EVBACKEND_KQUEUE) kqueue_destroy
|
3057
|
+
if (backend == EVBACKEND_KQUEUE ) kqueue_destroy (EV_A);
|
3058
|
+
#endif
|
3059
|
+
#if EV_USE_LINUXAIO
|
3060
|
+
if (backend == EVBACKEND_LINUXAIO) linuxaio_destroy (EV_A);
|
2985
3061
|
#endif
|
2986
3062
|
#if EV_USE_EPOLL
|
2987
|
-
if (backend == EVBACKEND_EPOLL
|
3063
|
+
if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A);
|
2988
3064
|
#endif
|
2989
3065
|
#if EV_USE_POLL
|
2990
|
-
if (backend == EVBACKEND_POLL
|
3066
|
+
if (backend == EVBACKEND_POLL ) poll_destroy (EV_A);
|
2991
3067
|
#endif
|
2992
3068
|
#if EV_USE_SELECT
|
2993
|
-
if (backend == EVBACKEND_SELECT) select_destroy
|
3069
|
+
if (backend == EVBACKEND_SELECT ) select_destroy (EV_A);
|
2994
3070
|
#endif
|
2995
3071
|
|
2996
3072
|
for (i = NUMPRI; i--; )
|
@@ -3042,13 +3118,16 @@ inline_size void
|
|
3042
3118
|
loop_fork (EV_P)
|
3043
3119
|
{
|
3044
3120
|
#if EV_USE_PORT
|
3045
|
-
if (backend == EVBACKEND_PORT
|
3121
|
+
if (backend == EVBACKEND_PORT ) port_fork (EV_A);
|
3046
3122
|
#endif
|
3047
3123
|
#if EV_USE_KQUEUE
|
3048
|
-
if (backend == EVBACKEND_KQUEUE) kqueue_fork
|
3124
|
+
if (backend == EVBACKEND_KQUEUE ) kqueue_fork (EV_A);
|
3125
|
+
#endif
|
3126
|
+
#if EV_USE_LINUXAIO
|
3127
|
+
if (backend == EVBACKEND_LINUXAIO) linuxaio_fork (EV_A);
|
3049
3128
|
#endif
|
3050
3129
|
#if EV_USE_EPOLL
|
3051
|
-
if (backend == EVBACKEND_EPOLL
|
3130
|
+
if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A);
|
3052
3131
|
#endif
|
3053
3132
|
#if EV_USE_INOTIFY
|
3054
3133
|
infy_fork (EV_A);
|
@@ -3076,8 +3155,9 @@ loop_fork (EV_P)
|
|
3076
3155
|
|
3077
3156
|
#if EV_MULTIPLICITY
|
3078
3157
|
|
3079
|
-
|
3080
|
-
|
3158
|
+
ecb_cold
|
3159
|
+
struct ev_loop *
|
3160
|
+
ev_loop_new (unsigned int flags) EV_NOEXCEPT
|
3081
3161
|
{
|
3082
3162
|
EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
|
3083
3163
|
|
@@ -3094,7 +3174,8 @@ ev_loop_new (unsigned int flags) EV_THROW
|
|
3094
3174
|
#endif /* multiplicity */
|
3095
3175
|
|
3096
3176
|
#if EV_VERIFY
|
3097
|
-
|
3177
|
+
noinline ecb_cold
|
3178
|
+
static void
|
3098
3179
|
verify_watcher (EV_P_ W w)
|
3099
3180
|
{
|
3100
3181
|
assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
|
@@ -3103,7 +3184,8 @@ verify_watcher (EV_P_ W w)
|
|
3103
3184
|
assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
|
3104
3185
|
}
|
3105
3186
|
|
3106
|
-
|
3187
|
+
noinline ecb_cold
|
3188
|
+
static void
|
3107
3189
|
verify_heap (EV_P_ ANHE *heap, int N)
|
3108
3190
|
{
|
3109
3191
|
int i;
|
@@ -3118,7 +3200,8 @@ verify_heap (EV_P_ ANHE *heap, int N)
|
|
3118
3200
|
}
|
3119
3201
|
}
|
3120
3202
|
|
3121
|
-
|
3203
|
+
noinline ecb_cold
|
3204
|
+
static void
|
3122
3205
|
array_verify (EV_P_ W *ws, int cnt)
|
3123
3206
|
{
|
3124
3207
|
while (cnt--)
|
@@ -3131,7 +3214,7 @@ array_verify (EV_P_ W *ws, int cnt)
|
|
3131
3214
|
|
3132
3215
|
#if EV_FEATURE_API
|
3133
3216
|
void ecb_cold
|
3134
|
-
ev_verify (EV_P)
|
3217
|
+
ev_verify (EV_P) EV_NOEXCEPT
|
3135
3218
|
{
|
3136
3219
|
#if EV_VERIFY
|
3137
3220
|
int i;
|
@@ -3217,11 +3300,12 @@ ev_verify (EV_P) EV_THROW
|
|
3217
3300
|
#endif
|
3218
3301
|
|
3219
3302
|
#if EV_MULTIPLICITY
|
3220
|
-
|
3303
|
+
ecb_cold
|
3304
|
+
struct ev_loop *
|
3221
3305
|
#else
|
3222
3306
|
int
|
3223
3307
|
#endif
|
3224
|
-
ev_default_loop (unsigned int flags)
|
3308
|
+
ev_default_loop (unsigned int flags) EV_NOEXCEPT
|
3225
3309
|
{
|
3226
3310
|
if (!ev_default_loop_ptr)
|
3227
3311
|
{
|
@@ -3250,7 +3334,7 @@ ev_default_loop (unsigned int flags) EV_THROW
|
|
3250
3334
|
}
|
3251
3335
|
|
3252
3336
|
void
|
3253
|
-
ev_loop_fork (EV_P)
|
3337
|
+
ev_loop_fork (EV_P) EV_NOEXCEPT
|
3254
3338
|
{
|
3255
3339
|
postfork = 1;
|
3256
3340
|
}
|
@@ -3264,7 +3348,7 @@ ev_invoke (EV_P_ void *w, int revents)
|
|
3264
3348
|
}
|
3265
3349
|
|
3266
3350
|
unsigned int
|
3267
|
-
ev_pending_count (EV_P)
|
3351
|
+
ev_pending_count (EV_P) EV_NOEXCEPT
|
3268
3352
|
{
|
3269
3353
|
int pri;
|
3270
3354
|
unsigned int count = 0;
|
@@ -3275,15 +3359,17 @@ ev_pending_count (EV_P) EV_THROW
|
|
3275
3359
|
return count;
|
3276
3360
|
}
|
3277
3361
|
|
3278
|
-
|
3362
|
+
noinline
|
3363
|
+
void
|
3279
3364
|
ev_invoke_pending (EV_P)
|
3280
3365
|
{
|
3281
3366
|
pendingpri = NUMPRI;
|
3282
3367
|
|
3283
|
-
|
3368
|
+
do
|
3284
3369
|
{
|
3285
3370
|
--pendingpri;
|
3286
3371
|
|
3372
|
+
/* pendingpri possibly gets modified in the inner loop */
|
3287
3373
|
while (pendingcnt [pendingpri])
|
3288
3374
|
{
|
3289
3375
|
ANPENDING *p = pendings [pendingpri] + --pendingcnt [pendingpri];
|
@@ -3293,6 +3379,7 @@ ev_invoke_pending (EV_P)
|
|
3293
3379
|
EV_FREQUENT_CHECK;
|
3294
3380
|
}
|
3295
3381
|
}
|
3382
|
+
while (pendingpri);
|
3296
3383
|
}
|
3297
3384
|
|
3298
3385
|
#if EV_IDLE_ENABLE
|
@@ -3360,7 +3447,8 @@ timers_reify (EV_P)
|
|
3360
3447
|
|
3361
3448
|
#if EV_PERIODIC_ENABLE
|
3362
3449
|
|
3363
|
-
|
3450
|
+
noinline
|
3451
|
+
static void
|
3364
3452
|
periodic_recalc (EV_P_ ev_periodic *w)
|
3365
3453
|
{
|
3366
3454
|
ev_tstamp interval = w->interval > MIN_INTERVAL ? w->interval : MIN_INTERVAL;
|
@@ -3428,7 +3516,8 @@ periodics_reify (EV_P)
|
|
3428
3516
|
|
3429
3517
|
/* simply recalculate all periodics */
|
3430
3518
|
/* TODO: maybe ensure that at least one event happens when jumping forward? */
|
3431
|
-
|
3519
|
+
noinline ecb_cold
|
3520
|
+
static void
|
3432
3521
|
periodics_reschedule (EV_P)
|
3433
3522
|
{
|
3434
3523
|
int i;
|
@@ -3451,7 +3540,8 @@ periodics_reschedule (EV_P)
|
|
3451
3540
|
#endif
|
3452
3541
|
|
3453
3542
|
/* adjust all timers by a given offset */
|
3454
|
-
|
3543
|
+
noinline ecb_cold
|
3544
|
+
static void
|
3455
3545
|
timers_reschedule (EV_P_ ev_tstamp adjust)
|
3456
3546
|
{
|
3457
3547
|
int i;
|
@@ -3536,29 +3626,27 @@ time_update (EV_P_ ev_tstamp max_block)
|
|
3536
3626
|
}
|
3537
3627
|
|
3538
3628
|
/* ########## NIO4R PATCHERY HO! ########## */
|
3539
|
-
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
3540
3629
|
struct ev_poll_args {
|
3541
3630
|
struct ev_loop *loop;
|
3542
3631
|
ev_tstamp waittime;
|
3543
3632
|
};
|
3544
3633
|
|
3545
3634
|
static
|
3546
|
-
|
3635
|
+
void * ev_backend_poll(void *ptr)
|
3547
3636
|
{
|
3548
3637
|
struct ev_poll_args *args = (struct ev_poll_args *)ptr;
|
3549
3638
|
struct ev_loop *loop = args->loop;
|
3550
3639
|
backend_poll (EV_A_ args->waittime);
|
3640
|
+
|
3641
|
+
return NULL;
|
3551
3642
|
}
|
3552
|
-
#endif
|
3553
3643
|
/* ######################################## */
|
3554
3644
|
|
3555
3645
|
int
|
3556
3646
|
ev_run (EV_P_ int flags)
|
3557
3647
|
{
|
3558
3648
|
/* ########## NIO4R PATCHERY HO! ########## */
|
3559
|
-
|
3560
|
-
struct ev_poll_args poll_args;
|
3561
|
-
#endif
|
3649
|
+
struct ev_poll_args poll_args;
|
3562
3650
|
/* ######################################## */
|
3563
3651
|
|
3564
3652
|
#if EV_FEATURE_API
|
@@ -3719,25 +3807,9 @@ rb_thread_unsafe_dangerous_crazy_blocking_region_end(...);
|
|
3719
3807
|
#######################################################################
|
3720
3808
|
*/
|
3721
3809
|
|
3722
|
-
/*
|
3723
|
-
simulate to rb_thread_call_without_gvl using rb_theread_blocking_region.
|
3724
|
-
https://github.com/brianmario/mysql2/blob/master/ext/mysql2/client.h#L8
|
3725
|
-
*/
|
3726
|
-
|
3727
|
-
#ifndef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
3728
|
-
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
|
3729
|
-
#define rb_thread_call_without_gvl(func, data1, ubf, data2) \
|
3730
|
-
rb_thread_blocking_region((rb_blocking_function_t *)func, data1, ubf, data2)
|
3731
|
-
#endif
|
3732
|
-
#endif
|
3733
|
-
|
3734
|
-
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
3735
3810
|
poll_args.loop = loop;
|
3736
3811
|
poll_args.waittime = waittime;
|
3737
3812
|
rb_thread_call_without_gvl(ev_backend_poll, (void *)&poll_args, RUBY_UBF_IO, 0);
|
3738
|
-
#else
|
3739
|
-
backend_poll (EV_A_ waittime);
|
3740
|
-
#endif
|
3741
3813
|
/*
|
3742
3814
|
############################# END PATCHERY ############################
|
3743
3815
|
*/
|
@@ -3794,37 +3866,37 @@ rb_thread_unsafe_dangerous_crazy_blocking_region_end(...);
|
|
3794
3866
|
}
|
3795
3867
|
|
3796
3868
|
void
|
3797
|
-
ev_break (EV_P_ int how)
|
3869
|
+
ev_break (EV_P_ int how) EV_NOEXCEPT
|
3798
3870
|
{
|
3799
3871
|
loop_done = how;
|
3800
3872
|
}
|
3801
3873
|
|
3802
3874
|
void
|
3803
|
-
ev_ref (EV_P)
|
3875
|
+
ev_ref (EV_P) EV_NOEXCEPT
|
3804
3876
|
{
|
3805
3877
|
++activecnt;
|
3806
3878
|
}
|
3807
3879
|
|
3808
3880
|
void
|
3809
|
-
ev_unref (EV_P)
|
3881
|
+
ev_unref (EV_P) EV_NOEXCEPT
|
3810
3882
|
{
|
3811
3883
|
--activecnt;
|
3812
3884
|
}
|
3813
3885
|
|
3814
3886
|
void
|
3815
|
-
ev_now_update (EV_P)
|
3887
|
+
ev_now_update (EV_P) EV_NOEXCEPT
|
3816
3888
|
{
|
3817
3889
|
time_update (EV_A_ 1e100);
|
3818
3890
|
}
|
3819
3891
|
|
3820
3892
|
void
|
3821
|
-
ev_suspend (EV_P)
|
3893
|
+
ev_suspend (EV_P) EV_NOEXCEPT
|
3822
3894
|
{
|
3823
3895
|
ev_now_update (EV_A);
|
3824
3896
|
}
|
3825
3897
|
|
3826
3898
|
void
|
3827
|
-
ev_resume (EV_P)
|
3899
|
+
ev_resume (EV_P) EV_NOEXCEPT
|
3828
3900
|
{
|
3829
3901
|
ev_tstamp mn_prev = mn_now;
|
3830
3902
|
|
@@ -3873,7 +3945,7 @@ clear_pending (EV_P_ W w)
|
|
3873
3945
|
}
|
3874
3946
|
|
3875
3947
|
int
|
3876
|
-
ev_clear_pending (EV_P_ void *w)
|
3948
|
+
ev_clear_pending (EV_P_ void *w) EV_NOEXCEPT
|
3877
3949
|
{
|
3878
3950
|
W w_ = (W)w;
|
3879
3951
|
int pending = w_->pending;
|
@@ -3915,8 +3987,9 @@ ev_stop (EV_P_ W w)
|
|
3915
3987
|
|
3916
3988
|
/*****************************************************************************/
|
3917
3989
|
|
3918
|
-
|
3919
|
-
|
3990
|
+
noinline
|
3991
|
+
void
|
3992
|
+
ev_io_start (EV_P_ ev_io *w) EV_NOEXCEPT
|
3920
3993
|
{
|
3921
3994
|
int fd = w->fd;
|
3922
3995
|
|
@@ -3926,10 +3999,13 @@ ev_io_start (EV_P_ ev_io *w) EV_THROW
|
|
3926
3999
|
assert (("libev: ev_io_start called with negative fd", fd >= 0));
|
3927
4000
|
assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE))));
|
3928
4001
|
|
4002
|
+
#if EV_VERIFY >= 2
|
4003
|
+
assert (("libev: ev_io_start called on watcher with invalid fd", fd_valid (fd)));
|
4004
|
+
#endif
|
3929
4005
|
EV_FREQUENT_CHECK;
|
3930
4006
|
|
3931
4007
|
ev_start (EV_A_ (W)w, 1);
|
3932
|
-
array_needsize (ANFD, anfds, anfdmax, fd + 1,
|
4008
|
+
array_needsize (ANFD, anfds, anfdmax, fd + 1, array_needsize_zerofill);
|
3933
4009
|
wlist_add (&anfds[fd].head, (WL)w);
|
3934
4010
|
|
3935
4011
|
/* common bug, apparently */
|
@@ -3941,8 +4017,9 @@ ev_io_start (EV_P_ ev_io *w) EV_THROW
|
|
3941
4017
|
EV_FREQUENT_CHECK;
|
3942
4018
|
}
|
3943
4019
|
|
3944
|
-
|
3945
|
-
|
4020
|
+
noinline
|
4021
|
+
void
|
4022
|
+
ev_io_stop (EV_P_ ev_io *w) EV_NOEXCEPT
|
3946
4023
|
{
|
3947
4024
|
clear_pending (EV_A_ (W)w);
|
3948
4025
|
if (expect_false (!ev_is_active (w)))
|
@@ -3950,6 +4027,9 @@ ev_io_stop (EV_P_ ev_io *w) EV_THROW
|
|
3950
4027
|
|
3951
4028
|
assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
|
3952
4029
|
|
4030
|
+
#if EV_VERIFY >= 2
|
4031
|
+
assert (("libev: ev_io_stop called on watcher with invalid fd", fd_valid (w->fd)));
|
4032
|
+
#endif
|
3953
4033
|
EV_FREQUENT_CHECK;
|
3954
4034
|
|
3955
4035
|
wlist_del (&anfds[w->fd].head, (WL)w);
|
@@ -3960,8 +4040,9 @@ ev_io_stop (EV_P_ ev_io *w) EV_THROW
|
|
3960
4040
|
EV_FREQUENT_CHECK;
|
3961
4041
|
}
|
3962
4042
|
|
3963
|
-
|
3964
|
-
|
4043
|
+
noinline
|
4044
|
+
void
|
4045
|
+
ev_timer_start (EV_P_ ev_timer *w) EV_NOEXCEPT
|
3965
4046
|
{
|
3966
4047
|
if (expect_false (ev_is_active (w)))
|
3967
4048
|
return;
|
@@ -3974,7 +4055,7 @@ ev_timer_start (EV_P_ ev_timer *w) EV_THROW
|
|
3974
4055
|
|
3975
4056
|
++timercnt;
|
3976
4057
|
ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1);
|
3977
|
-
array_needsize (ANHE, timers, timermax, ev_active (w) + 1,
|
4058
|
+
array_needsize (ANHE, timers, timermax, ev_active (w) + 1, array_needsize_noinit);
|
3978
4059
|
ANHE_w (timers [ev_active (w)]) = (WT)w;
|
3979
4060
|
ANHE_at_cache (timers [ev_active (w)]);
|
3980
4061
|
upheap (timers, ev_active (w));
|
@@ -3984,8 +4065,9 @@ ev_timer_start (EV_P_ ev_timer *w) EV_THROW
|
|
3984
4065
|
/*assert (("libev: internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/
|
3985
4066
|
}
|
3986
4067
|
|
3987
|
-
|
3988
|
-
|
4068
|
+
noinline
|
4069
|
+
void
|
4070
|
+
ev_timer_stop (EV_P_ ev_timer *w) EV_NOEXCEPT
|
3989
4071
|
{
|
3990
4072
|
clear_pending (EV_A_ (W)w);
|
3991
4073
|
if (expect_false (!ev_is_active (w)))
|
@@ -4014,8 +4096,9 @@ ev_timer_stop (EV_P_ ev_timer *w) EV_THROW
|
|
4014
4096
|
EV_FREQUENT_CHECK;
|
4015
4097
|
}
|
4016
4098
|
|
4017
|
-
|
4018
|
-
|
4099
|
+
noinline
|
4100
|
+
void
|
4101
|
+
ev_timer_again (EV_P_ ev_timer *w) EV_NOEXCEPT
|
4019
4102
|
{
|
4020
4103
|
EV_FREQUENT_CHECK;
|
4021
4104
|
|
@@ -4042,14 +4125,15 @@ ev_timer_again (EV_P_ ev_timer *w) EV_THROW
|
|
4042
4125
|
}
|
4043
4126
|
|
4044
4127
|
ev_tstamp
|
4045
|
-
ev_timer_remaining (EV_P_ ev_timer *w)
|
4128
|
+
ev_timer_remaining (EV_P_ ev_timer *w) EV_NOEXCEPT
|
4046
4129
|
{
|
4047
4130
|
return ev_at (w) - (ev_is_active (w) ? mn_now : 0.);
|
4048
4131
|
}
|
4049
4132
|
|
4050
4133
|
#if EV_PERIODIC_ENABLE
|
4051
|
-
|
4052
|
-
|
4134
|
+
noinline
|
4135
|
+
void
|
4136
|
+
ev_periodic_start (EV_P_ ev_periodic *w) EV_NOEXCEPT
|
4053
4137
|
{
|
4054
4138
|
if (expect_false (ev_is_active (w)))
|
4055
4139
|
return;
|
@@ -4068,7 +4152,7 @@ ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
|
|
4068
4152
|
|
4069
4153
|
++periodiccnt;
|
4070
4154
|
ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1);
|
4071
|
-
array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1,
|
4155
|
+
array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, array_needsize_noinit);
|
4072
4156
|
ANHE_w (periodics [ev_active (w)]) = (WT)w;
|
4073
4157
|
ANHE_at_cache (periodics [ev_active (w)]);
|
4074
4158
|
upheap (periodics, ev_active (w));
|
@@ -4078,8 +4162,9 @@ ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
|
|
4078
4162
|
/*assert (("libev: internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/
|
4079
4163
|
}
|
4080
4164
|
|
4081
|
-
|
4082
|
-
|
4165
|
+
noinline
|
4166
|
+
void
|
4167
|
+
ev_periodic_stop (EV_P_ ev_periodic *w) EV_NOEXCEPT
|
4083
4168
|
{
|
4084
4169
|
clear_pending (EV_A_ (W)w);
|
4085
4170
|
if (expect_false (!ev_is_active (w)))
|
@@ -4106,8 +4191,9 @@ ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW
|
|
4106
4191
|
EV_FREQUENT_CHECK;
|
4107
4192
|
}
|
4108
4193
|
|
4109
|
-
|
4110
|
-
|
4194
|
+
noinline
|
4195
|
+
void
|
4196
|
+
ev_periodic_again (EV_P_ ev_periodic *w) EV_NOEXCEPT
|
4111
4197
|
{
|
4112
4198
|
/* TODO: use adjustheap and recalculation */
|
4113
4199
|
ev_periodic_stop (EV_A_ w);
|
@@ -4121,8 +4207,9 @@ ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW
|
|
4121
4207
|
|
4122
4208
|
#if EV_SIGNAL_ENABLE
|
4123
4209
|
|
4124
|
-
|
4125
|
-
|
4210
|
+
noinline
|
4211
|
+
void
|
4212
|
+
ev_signal_start (EV_P_ ev_signal *w) EV_NOEXCEPT
|
4126
4213
|
{
|
4127
4214
|
if (expect_false (ev_is_active (w)))
|
4128
4215
|
return;
|
@@ -4203,8 +4290,9 @@ ev_signal_start (EV_P_ ev_signal *w) EV_THROW
|
|
4203
4290
|
EV_FREQUENT_CHECK;
|
4204
4291
|
}
|
4205
4292
|
|
4206
|
-
|
4207
|
-
|
4293
|
+
noinline
|
4294
|
+
void
|
4295
|
+
ev_signal_stop (EV_P_ ev_signal *w) EV_NOEXCEPT
|
4208
4296
|
{
|
4209
4297
|
clear_pending (EV_A_ (W)w);
|
4210
4298
|
if (expect_false (!ev_is_active (w)))
|
@@ -4245,7 +4333,7 @@ ev_signal_stop (EV_P_ ev_signal *w) EV_THROW
|
|
4245
4333
|
#if EV_CHILD_ENABLE
|
4246
4334
|
|
4247
4335
|
void
|
4248
|
-
ev_child_start (EV_P_ ev_child *w)
|
4336
|
+
ev_child_start (EV_P_ ev_child *w) EV_NOEXCEPT
|
4249
4337
|
{
|
4250
4338
|
#if EV_MULTIPLICITY
|
4251
4339
|
assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
|
@@ -4262,7 +4350,7 @@ ev_child_start (EV_P_ ev_child *w) EV_THROW
|
|
4262
4350
|
}
|
4263
4351
|
|
4264
4352
|
void
|
4265
|
-
ev_child_stop (EV_P_ ev_child *w)
|
4353
|
+
ev_child_stop (EV_P_ ev_child *w) EV_NOEXCEPT
|
4266
4354
|
{
|
4267
4355
|
clear_pending (EV_A_ (W)w);
|
4268
4356
|
if (expect_false (!ev_is_active (w)))
|
@@ -4289,14 +4377,15 @@ ev_child_stop (EV_P_ ev_child *w) EV_THROW
|
|
4289
4377
|
#define NFS_STAT_INTERVAL 30.1074891 /* for filesystems potentially failing inotify */
|
4290
4378
|
#define MIN_STAT_INTERVAL 0.1074891
|
4291
4379
|
|
4292
|
-
static void
|
4380
|
+
noinline static void stat_timer_cb (EV_P_ ev_timer *w_, int revents);
|
4293
4381
|
|
4294
4382
|
#if EV_USE_INOTIFY
|
4295
4383
|
|
4296
4384
|
/* the * 2 is to allow for alignment padding, which for some reason is >> 8 */
|
4297
4385
|
# define EV_INOTIFY_BUFSIZE (sizeof (struct inotify_event) * 2 + NAME_MAX)
|
4298
4386
|
|
4299
|
-
|
4387
|
+
noinline
|
4388
|
+
static void
|
4300
4389
|
infy_add (EV_P_ ev_stat *w)
|
4301
4390
|
{
|
4302
4391
|
w->wd = inotify_add_watch (fs_fd, w->path,
|
@@ -4370,7 +4459,8 @@ infy_add (EV_P_ ev_stat *w)
|
|
4370
4459
|
if (ev_is_active (&w->timer)) ev_unref (EV_A);
|
4371
4460
|
}
|
4372
4461
|
|
4373
|
-
|
4462
|
+
noinline
|
4463
|
+
static void
|
4374
4464
|
infy_del (EV_P_ ev_stat *w)
|
4375
4465
|
{
|
4376
4466
|
int slot;
|
@@ -4387,7 +4477,8 @@ infy_del (EV_P_ ev_stat *w)
|
|
4387
4477
|
inotify_rm_watch (fs_fd, wd);
|
4388
4478
|
}
|
4389
4479
|
|
4390
|
-
|
4480
|
+
noinline
|
4481
|
+
static void
|
4391
4482
|
infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev)
|
4392
4483
|
{
|
4393
4484
|
if (slot < 0)
|
@@ -4433,7 +4524,8 @@ infy_cb (EV_P_ ev_io *w, int revents)
|
|
4433
4524
|
}
|
4434
4525
|
}
|
4435
4526
|
|
4436
|
-
inline_size
|
4527
|
+
inline_size ecb_cold
|
4528
|
+
void
|
4437
4529
|
ev_check_2625 (EV_P)
|
4438
4530
|
{
|
4439
4531
|
/* kernels < 2.6.25 are borked
|
@@ -4533,7 +4625,7 @@ infy_fork (EV_P)
|
|
4533
4625
|
#endif
|
4534
4626
|
|
4535
4627
|
void
|
4536
|
-
ev_stat_stat (EV_P_ ev_stat *w)
|
4628
|
+
ev_stat_stat (EV_P_ ev_stat *w) EV_NOEXCEPT
|
4537
4629
|
{
|
4538
4630
|
if (lstat (w->path, &w->attr) < 0)
|
4539
4631
|
w->attr.st_nlink = 0;
|
@@ -4541,7 +4633,8 @@ ev_stat_stat (EV_P_ ev_stat *w) EV_THROW
|
|
4541
4633
|
w->attr.st_nlink = 1;
|
4542
4634
|
}
|
4543
4635
|
|
4544
|
-
|
4636
|
+
noinline
|
4637
|
+
static void
|
4545
4638
|
stat_timer_cb (EV_P_ ev_timer *w_, int revents)
|
4546
4639
|
{
|
4547
4640
|
ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer));
|
@@ -4582,7 +4675,7 @@ stat_timer_cb (EV_P_ ev_timer *w_, int revents)
|
|
4582
4675
|
}
|
4583
4676
|
|
4584
4677
|
void
|
4585
|
-
ev_stat_start (EV_P_ ev_stat *w)
|
4678
|
+
ev_stat_start (EV_P_ ev_stat *w) EV_NOEXCEPT
|
4586
4679
|
{
|
4587
4680
|
if (expect_false (ev_is_active (w)))
|
4588
4681
|
return;
|
@@ -4613,7 +4706,7 @@ ev_stat_start (EV_P_ ev_stat *w) EV_THROW
|
|
4613
4706
|
}
|
4614
4707
|
|
4615
4708
|
void
|
4616
|
-
ev_stat_stop (EV_P_ ev_stat *w)
|
4709
|
+
ev_stat_stop (EV_P_ ev_stat *w) EV_NOEXCEPT
|
4617
4710
|
{
|
4618
4711
|
clear_pending (EV_A_ (W)w);
|
4619
4712
|
if (expect_false (!ev_is_active (w)))
|
@@ -4639,7 +4732,7 @@ ev_stat_stop (EV_P_ ev_stat *w) EV_THROW
|
|
4639
4732
|
|
4640
4733
|
#if EV_IDLE_ENABLE
|
4641
4734
|
void
|
4642
|
-
ev_idle_start (EV_P_ ev_idle *w)
|
4735
|
+
ev_idle_start (EV_P_ ev_idle *w) EV_NOEXCEPT
|
4643
4736
|
{
|
4644
4737
|
if (expect_false (ev_is_active (w)))
|
4645
4738
|
return;
|
@@ -4654,7 +4747,7 @@ ev_idle_start (EV_P_ ev_idle *w) EV_THROW
|
|
4654
4747
|
++idleall;
|
4655
4748
|
ev_start (EV_A_ (W)w, active);
|
4656
4749
|
|
4657
|
-
array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active,
|
4750
|
+
array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, array_needsize_noinit);
|
4658
4751
|
idles [ABSPRI (w)][active - 1] = w;
|
4659
4752
|
}
|
4660
4753
|
|
@@ -4662,7 +4755,7 @@ ev_idle_start (EV_P_ ev_idle *w) EV_THROW
|
|
4662
4755
|
}
|
4663
4756
|
|
4664
4757
|
void
|
4665
|
-
ev_idle_stop (EV_P_ ev_idle *w)
|
4758
|
+
ev_idle_stop (EV_P_ ev_idle *w) EV_NOEXCEPT
|
4666
4759
|
{
|
4667
4760
|
clear_pending (EV_A_ (W)w);
|
4668
4761
|
if (expect_false (!ev_is_active (w)))
|
@@ -4686,7 +4779,7 @@ ev_idle_stop (EV_P_ ev_idle *w) EV_THROW
|
|
4686
4779
|
|
4687
4780
|
#if EV_PREPARE_ENABLE
|
4688
4781
|
void
|
4689
|
-
ev_prepare_start (EV_P_ ev_prepare *w)
|
4782
|
+
ev_prepare_start (EV_P_ ev_prepare *w) EV_NOEXCEPT
|
4690
4783
|
{
|
4691
4784
|
if (expect_false (ev_is_active (w)))
|
4692
4785
|
return;
|
@@ -4694,14 +4787,14 @@ ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW
|
|
4694
4787
|
EV_FREQUENT_CHECK;
|
4695
4788
|
|
4696
4789
|
ev_start (EV_A_ (W)w, ++preparecnt);
|
4697
|
-
array_needsize (ev_prepare *, prepares, preparemax, preparecnt,
|
4790
|
+
array_needsize (ev_prepare *, prepares, preparemax, preparecnt, array_needsize_noinit);
|
4698
4791
|
prepares [preparecnt - 1] = w;
|
4699
4792
|
|
4700
4793
|
EV_FREQUENT_CHECK;
|
4701
4794
|
}
|
4702
4795
|
|
4703
4796
|
void
|
4704
|
-
ev_prepare_stop (EV_P_ ev_prepare *w)
|
4797
|
+
ev_prepare_stop (EV_P_ ev_prepare *w) EV_NOEXCEPT
|
4705
4798
|
{
|
4706
4799
|
clear_pending (EV_A_ (W)w);
|
4707
4800
|
if (expect_false (!ev_is_active (w)))
|
@@ -4724,7 +4817,7 @@ ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW
|
|
4724
4817
|
|
4725
4818
|
#if EV_CHECK_ENABLE
|
4726
4819
|
void
|
4727
|
-
ev_check_start (EV_P_ ev_check *w)
|
4820
|
+
ev_check_start (EV_P_ ev_check *w) EV_NOEXCEPT
|
4728
4821
|
{
|
4729
4822
|
if (expect_false (ev_is_active (w)))
|
4730
4823
|
return;
|
@@ -4732,14 +4825,14 @@ ev_check_start (EV_P_ ev_check *w) EV_THROW
|
|
4732
4825
|
EV_FREQUENT_CHECK;
|
4733
4826
|
|
4734
4827
|
ev_start (EV_A_ (W)w, ++checkcnt);
|
4735
|
-
array_needsize (ev_check *, checks, checkmax, checkcnt,
|
4828
|
+
array_needsize (ev_check *, checks, checkmax, checkcnt, array_needsize_noinit);
|
4736
4829
|
checks [checkcnt - 1] = w;
|
4737
4830
|
|
4738
4831
|
EV_FREQUENT_CHECK;
|
4739
4832
|
}
|
4740
4833
|
|
4741
4834
|
void
|
4742
|
-
ev_check_stop (EV_P_ ev_check *w)
|
4835
|
+
ev_check_stop (EV_P_ ev_check *w) EV_NOEXCEPT
|
4743
4836
|
{
|
4744
4837
|
clear_pending (EV_A_ (W)w);
|
4745
4838
|
if (expect_false (!ev_is_active (w)))
|
@@ -4761,8 +4854,9 @@ ev_check_stop (EV_P_ ev_check *w) EV_THROW
|
|
4761
4854
|
#endif
|
4762
4855
|
|
4763
4856
|
#if EV_EMBED_ENABLE
|
4764
|
-
|
4765
|
-
|
4857
|
+
noinline
|
4858
|
+
void
|
4859
|
+
ev_embed_sweep (EV_P_ ev_embed *w) EV_NOEXCEPT
|
4766
4860
|
{
|
4767
4861
|
ev_run (w->other, EVRUN_NOWAIT);
|
4768
4862
|
}
|
@@ -4820,7 +4914,7 @@ embed_idle_cb (EV_P_ ev_idle *idle, int revents)
|
|
4820
4914
|
#endif
|
4821
4915
|
|
4822
4916
|
void
|
4823
|
-
ev_embed_start (EV_P_ ev_embed *w)
|
4917
|
+
ev_embed_start (EV_P_ ev_embed *w) EV_NOEXCEPT
|
4824
4918
|
{
|
4825
4919
|
if (expect_false (ev_is_active (w)))
|
4826
4920
|
return;
|
@@ -4851,7 +4945,7 @@ ev_embed_start (EV_P_ ev_embed *w) EV_THROW
|
|
4851
4945
|
}
|
4852
4946
|
|
4853
4947
|
void
|
4854
|
-
ev_embed_stop (EV_P_ ev_embed *w)
|
4948
|
+
ev_embed_stop (EV_P_ ev_embed *w) EV_NOEXCEPT
|
4855
4949
|
{
|
4856
4950
|
clear_pending (EV_A_ (W)w);
|
4857
4951
|
if (expect_false (!ev_is_active (w)))
|
@@ -4871,7 +4965,7 @@ ev_embed_stop (EV_P_ ev_embed *w) EV_THROW
|
|
4871
4965
|
|
4872
4966
|
#if EV_FORK_ENABLE
|
4873
4967
|
void
|
4874
|
-
ev_fork_start (EV_P_ ev_fork *w)
|
4968
|
+
ev_fork_start (EV_P_ ev_fork *w) EV_NOEXCEPT
|
4875
4969
|
{
|
4876
4970
|
if (expect_false (ev_is_active (w)))
|
4877
4971
|
return;
|
@@ -4879,14 +4973,14 @@ ev_fork_start (EV_P_ ev_fork *w) EV_THROW
|
|
4879
4973
|
EV_FREQUENT_CHECK;
|
4880
4974
|
|
4881
4975
|
ev_start (EV_A_ (W)w, ++forkcnt);
|
4882
|
-
array_needsize (ev_fork *, forks, forkmax, forkcnt,
|
4976
|
+
array_needsize (ev_fork *, forks, forkmax, forkcnt, array_needsize_noinit);
|
4883
4977
|
forks [forkcnt - 1] = w;
|
4884
4978
|
|
4885
4979
|
EV_FREQUENT_CHECK;
|
4886
4980
|
}
|
4887
4981
|
|
4888
4982
|
void
|
4889
|
-
ev_fork_stop (EV_P_ ev_fork *w)
|
4983
|
+
ev_fork_stop (EV_P_ ev_fork *w) EV_NOEXCEPT
|
4890
4984
|
{
|
4891
4985
|
clear_pending (EV_A_ (W)w);
|
4892
4986
|
if (expect_false (!ev_is_active (w)))
|
@@ -4909,7 +5003,7 @@ ev_fork_stop (EV_P_ ev_fork *w) EV_THROW
|
|
4909
5003
|
|
4910
5004
|
#if EV_CLEANUP_ENABLE
|
4911
5005
|
void
|
4912
|
-
ev_cleanup_start (EV_P_ ev_cleanup *w)
|
5006
|
+
ev_cleanup_start (EV_P_ ev_cleanup *w) EV_NOEXCEPT
|
4913
5007
|
{
|
4914
5008
|
if (expect_false (ev_is_active (w)))
|
4915
5009
|
return;
|
@@ -4917,7 +5011,7 @@ ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW
|
|
4917
5011
|
EV_FREQUENT_CHECK;
|
4918
5012
|
|
4919
5013
|
ev_start (EV_A_ (W)w, ++cleanupcnt);
|
4920
|
-
array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt,
|
5014
|
+
array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, array_needsize_noinit);
|
4921
5015
|
cleanups [cleanupcnt - 1] = w;
|
4922
5016
|
|
4923
5017
|
/* cleanup watchers should never keep a refcount on the loop */
|
@@ -4926,7 +5020,7 @@ ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW
|
|
4926
5020
|
}
|
4927
5021
|
|
4928
5022
|
void
|
4929
|
-
ev_cleanup_stop (EV_P_ ev_cleanup *w)
|
5023
|
+
ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_NOEXCEPT
|
4930
5024
|
{
|
4931
5025
|
clear_pending (EV_A_ (W)w);
|
4932
5026
|
if (expect_false (!ev_is_active (w)))
|
@@ -4950,7 +5044,7 @@ ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW
|
|
4950
5044
|
|
4951
5045
|
#if EV_ASYNC_ENABLE
|
4952
5046
|
void
|
4953
|
-
ev_async_start (EV_P_ ev_async *w)
|
5047
|
+
ev_async_start (EV_P_ ev_async *w) EV_NOEXCEPT
|
4954
5048
|
{
|
4955
5049
|
if (expect_false (ev_is_active (w)))
|
4956
5050
|
return;
|
@@ -4962,14 +5056,14 @@ ev_async_start (EV_P_ ev_async *w) EV_THROW
|
|
4962
5056
|
EV_FREQUENT_CHECK;
|
4963
5057
|
|
4964
5058
|
ev_start (EV_A_ (W)w, ++asynccnt);
|
4965
|
-
array_needsize (ev_async *, asyncs, asyncmax, asynccnt,
|
5059
|
+
array_needsize (ev_async *, asyncs, asyncmax, asynccnt, array_needsize_noinit);
|
4966
5060
|
asyncs [asynccnt - 1] = w;
|
4967
5061
|
|
4968
5062
|
EV_FREQUENT_CHECK;
|
4969
5063
|
}
|
4970
5064
|
|
4971
5065
|
void
|
4972
|
-
ev_async_stop (EV_P_ ev_async *w)
|
5066
|
+
ev_async_stop (EV_P_ ev_async *w) EV_NOEXCEPT
|
4973
5067
|
{
|
4974
5068
|
clear_pending (EV_A_ (W)w);
|
4975
5069
|
if (expect_false (!ev_is_active (w)))
|
@@ -4990,7 +5084,7 @@ ev_async_stop (EV_P_ ev_async *w) EV_THROW
|
|
4990
5084
|
}
|
4991
5085
|
|
4992
5086
|
void
|
4993
|
-
ev_async_send (EV_P_ ev_async *w)
|
5087
|
+
ev_async_send (EV_P_ ev_async *w) EV_NOEXCEPT
|
4994
5088
|
{
|
4995
5089
|
w->sent = 1;
|
4996
5090
|
evpipe_write (EV_A_ &async_pending);
|
@@ -5037,16 +5131,10 @@ once_cb_to (EV_P_ ev_timer *w, int revents)
|
|
5037
5131
|
}
|
5038
5132
|
|
5039
5133
|
void
|
5040
|
-
ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg)
|
5134
|
+
ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_NOEXCEPT
|
5041
5135
|
{
|
5042
5136
|
struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once));
|
5043
5137
|
|
5044
|
-
if (expect_false (!once))
|
5045
|
-
{
|
5046
|
-
cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMER, arg);
|
5047
|
-
return;
|
5048
|
-
}
|
5049
|
-
|
5050
5138
|
once->cb = cb;
|
5051
5139
|
once->arg = arg;
|
5052
5140
|
|
@@ -5068,8 +5156,9 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo
|
|
5068
5156
|
/*****************************************************************************/
|
5069
5157
|
|
5070
5158
|
#if EV_WALK_ENABLE
|
5071
|
-
|
5072
|
-
|
5159
|
+
ecb_cold
|
5160
|
+
void
|
5161
|
+
ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_NOEXCEPT
|
5073
5162
|
{
|
5074
5163
|
int i, j;
|
5075
5164
|
ev_watcher_list *wl, *wn;
|