nio4r 2.3.1-java → 2.5.3-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/workflow.yml +43 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +37 -11
  5. data/CHANGES.md +40 -0
  6. data/Gemfile +5 -6
  7. data/README.md +53 -7
  8. data/Rakefile +0 -2
  9. data/examples/echo_server.rb +2 -2
  10. data/ext/libev/Changes +35 -0
  11. data/ext/libev/README +2 -1
  12. data/ext/libev/ev.c +213 -151
  13. data/ext/libev/ev.h +95 -88
  14. data/ext/libev/ev_epoll.c +26 -15
  15. data/ext/libev/ev_kqueue.c +11 -5
  16. data/ext/libev/ev_linuxaio.c +642 -0
  17. data/ext/libev/ev_poll.c +13 -8
  18. data/ext/libev/ev_port.c +5 -2
  19. data/ext/libev/ev_vars.h +14 -3
  20. data/ext/libev/ev_wrap.h +16 -0
  21. data/ext/nio4r/extconf.rb +2 -0
  22. data/ext/nio4r/monitor.c +1 -0
  23. data/ext/nio4r/nio4r.h +1 -1
  24. data/ext/nio4r/org/nio4r/Selector.java +5 -1
  25. data/ext/nio4r/selector.c +5 -5
  26. data/lib/nio.rb +3 -3
  27. data/lib/nio/bytebuffer.rb +4 -0
  28. data/lib/nio/monitor.rb +10 -8
  29. data/lib/nio/selector.rb +3 -1
  30. data/lib/nio/version.rb +1 -1
  31. data/nio4r.gemspec +10 -2
  32. data/{tasks → rakelib}/extension.rake +2 -0
  33. data/{tasks → rakelib}/rspec.rake +0 -0
  34. data/{tasks → rakelib}/rubocop.rake +0 -0
  35. data/spec/nio/acceptables_spec.rb +3 -5
  36. data/spec/nio/bytebuffer_spec.rb +2 -4
  37. data/spec/nio/monitor_spec.rb +2 -2
  38. data/spec/nio/selectables/ssl_socket_spec.rb +50 -20
  39. data/spec/nio/selectables/tcp_socket_spec.rb +23 -17
  40. data/spec/nio/selectables/udp_socket_spec.rb +13 -8
  41. data/spec/nio/selector_spec.rb +34 -16
  42. data/spec/spec_helper.rb +4 -16
  43. data/spec/support/selectable_examples.rb +37 -17
  44. metadata +28 -17
  45. data/.travis.yml +0 -36
  46. data/LICENSE.txt +0 -20
  47. data/appveyor.yml +0 -27
  48. data/ext/libev/README.embed +0 -3
  49. data/ext/libev/test_libev_win32.c +0 -123
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c88a32f43cf5641855c0e4a43a41b7d39feb95375adc7fd000fd5dde6af7f196
4
- data.tar.gz: 002e8e31de2d8684c5a04aa224de9a21ab9f3faeda6aa32e89d3642da2160e89
3
+ metadata.gz: e0a7d6c47bf4c20b6b863e848f4323a43d72fce5715627c5d30b95860f64139f
4
+ data.tar.gz: e00c20672ac8d7f58793434bcefa9cd3a390f86766aa2982d845df1d2ceb8907
5
5
  SHA512:
6
- metadata.gz: 6479c8cb7074dd20b4b0db25b694dc23c3d5350f6354ee43423035d1f1f8cca69c1f4c3b0ae48e120793c3c3bfac9f92e59d199084653308de183b68741c92a7
7
- data.tar.gz: 3b80ae22d65d9699d096475ecd53cfa92f23514c45a7cf0c91391abfc2afbaa3869be67e8b92f2c7138d56b3547b4f688948b39d82dca3381b56fce0b986684d
6
+ metadata.gz: 4d754981494d9864ceb267b63a038874626c3999d7bc3848a41d3661b5403dbae09fd2af63d8fb6c661df6181a8c59c7fe831fadaa999b01dc778ab5db413d38
7
+ data.tar.gz: 1925e25e2a5c8ee1e384271a724c370646e541d5540b23cb298205cd3312d01705b3e807f79978e7ddf67580890d1fe0754e6bd5b54398349e8f9c9515ccf6d8
@@ -0,0 +1,43 @@
1
+ name: nio4r
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ name: >-
8
+ ${{matrix.os}}, ${{matrix.ruby}}
9
+ env:
10
+ CI: true
11
+ TESTOPTS: -v
12
+
13
+ runs-on: ${{matrix.os}}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ os: [ubuntu-16.04, ubuntu-18.04, macos-latest, windows-latest]
18
+ ruby: [2.4, 2.5, 2.6, 2.7, jruby, truffleruby-head]
19
+ exclude:
20
+ - { os: windows-latest, ruby: jruby }
21
+ - { os: windows-latest, ruby: truffleruby-head }
22
+
23
+ steps:
24
+ - name: repo checkout
25
+ uses: actions/checkout@v2
26
+
27
+ - name: load ruby
28
+ uses: ruby/setup-ruby@v1
29
+ with:
30
+ ruby-version: ${{matrix.ruby}}
31
+
32
+ - name: RubyGems, Bundler Update
33
+ run: gem update --system --no-document --conservative
34
+
35
+ - name: bundle install
36
+ run: bundle install --path .bundle/gems --without development
37
+
38
+ - name: compile
39
+ run: bundle exec rake compile
40
+
41
+ - name: test
42
+ run: bundle exec rake spec
43
+ timeout-minutes: 10
data/.gitignore CHANGED
@@ -18,3 +18,4 @@ tmp
18
18
  lib/nio4r_ext.*
19
19
  ext/**/*.o
20
20
  ext/**/nio4r_ext.*
21
+ .rspec_status
@@ -1,17 +1,40 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.2
2
+ TargetRubyVersion: 2.4
3
3
  DisplayCopNames: true
4
4
 
5
+ Layout/HashAlignment:
6
+ Enabled: false
7
+
8
+ Layout/LineLength:
9
+ Max: 128
10
+
11
+ Layout/SpaceAroundMethodCallOperator:
12
+ Enabled: false
13
+
14
+ Layout/SpaceInsideBlockBraces:
15
+ Enabled: false
16
+
17
+ Style/IfUnlessModifier:
18
+ Enabled: false
19
+
20
+ Style/UnpackFirst:
21
+ Enabled: false
22
+
5
23
  #
6
24
  # Lint
7
25
  #
8
26
 
9
- Lint/HandleExceptions:
27
+ Lint/SuppressedException:
10
28
  Enabled: false
11
29
 
12
30
  Lint/Loop:
13
31
  Enabled: false
14
32
 
33
+ Lint/RaiseException:
34
+ Enabled: false
35
+
36
+ Lint/StructNewOverride:
37
+ Enabled: false
15
38
  #
16
39
  # Metrics
17
40
  #
@@ -21,13 +44,11 @@ Metrics/AbcSize:
21
44
 
22
45
  Metrics/BlockLength:
23
46
  Max: 128
47
+ Enabled: false
24
48
 
25
49
  Metrics/ClassLength:
26
50
  Max: 128
27
51
 
28
- Metrics/LineLength:
29
- Max: 128
30
-
31
52
  Metrics/MethodLength:
32
53
  CountComments: false
33
54
  Max: 50
@@ -39,16 +60,12 @@ Metrics/PerceivedComplexity:
39
60
  Max: 15
40
61
 
41
62
  #
42
- # Performance
63
+ # Style
43
64
  #
44
65
 
45
- Performance/RegexpMatch:
66
+ Style/ExponentialNotation:
46
67
  Enabled: false
47
68
 
48
- #
49
- # Style
50
- #
51
-
52
69
  Style/FormatStringToken:
53
70
  Enabled: false
54
71
 
@@ -58,6 +75,15 @@ Style/FrozenStringLiteralComment:
58
75
  Style/GlobalVars:
59
76
  Enabled: false
60
77
 
78
+ Style/HashEachMethods:
79
+ Enabled: false
80
+
81
+ Style/HashTransformKeys:
82
+ Enabled: false
83
+
84
+ Style/HashTransformValues:
85
+ Enabled: false
86
+
61
87
  Style/NumericPredicate:
62
88
  Enabled: false
63
89
 
data/CHANGES.md CHANGED
@@ -1,3 +1,40 @@
1
+ ## 2.5.3 (2020-09-07)
2
+
3
+ * [#241](https://github.com/socketry/nio4r/issues/241)
4
+ Possible bug with Ruby >= 2.7.0 and `GC.compact`.
5
+ ([@boazsegev])
6
+
7
+ ## 2.5.2 (2019-09-24)
8
+
9
+ * [#220](https://github.com/socketry/nio4r/issues/220)
10
+ Update to libev-4.27 & fix assorted warnings.
11
+ ([@ioquatix])
12
+
13
+ * [#225](https://github.com/socketry/nio4r/issues/225)
14
+ Avoid need for linux headers.
15
+ ([@ioquatix])
16
+
17
+ ## 2.4.0 (2019-07-07)
18
+
19
+ * [#211](https://github.com/socketry/nio4r/pull/211)
20
+ Enable KQUEUE on macOS 10.14+.
21
+ ([@ioquatix])
22
+
23
+ * Bump minimum supported Ruby to 2.3.
24
+ ([@ioquatix])
25
+
26
+ * Assorted fixes for TruffleRuby & JRuby.
27
+ ([@eregon], [@olleolleolle])
28
+ Possible bug with Ruby >= 2.7.0 and `GC.compact`
29
+ * Update libev to v4.25.
30
+ ([@ioquatix])
31
+
32
+ * Bind to ephemeral (port 0) for more reliable specs.
33
+ ([@ioquatix])
34
+
35
+ * Improve handling of SSL sockets and related specs.
36
+ ([@MSP-Greg])
37
+
1
38
  ## 2.3.1 (2018-05-03)
2
39
 
3
40
  * [#188](https://github.com/socketry/nio4r/pull/188)
@@ -219,3 +256,6 @@
219
256
  [@HoneyryderChuck]: https://github.com/HoneyryderChuck
220
257
  [@tompng]: https://github.com/tompng
221
258
  [@ioquatix]: https://github.com/ioquatix
259
+ [@eregon]: https://github.com/eregon
260
+ [@olleolleolle]: https://github.com/olleolleolle
261
+ [@boazsegev]: https://github.com/boazsegev
data/Gemfile CHANGED
@@ -8,13 +8,12 @@ gem "jruby-openssl" if defined? JRUBY_VERSION
8
8
 
9
9
  group :development do
10
10
  gem "guard-rspec", require: false
11
- gem "pry", require: false
11
+ gem "pry", require: false
12
12
  end
13
13
 
14
14
  group :development, :test do
15
- gem "coveralls", require: false
16
- gem "rake-compiler", require: false
17
- gem "rspec", "~> 3.7", require: false
18
- gem "rspec-retry", require: false
19
- gem "rubocop", "0.52.1", require: false
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
20
19
  end
data/README.md CHANGED
@@ -27,10 +27,12 @@ writing.
27
27
  * [ActionCable]: Rails 5 WebSocket protocol, uses nio4r for a WebSocket server
28
28
  * [Celluloid::IO]: Actor-based concurrency framework, uses nio4r for async I/O
29
29
  * [Socketry Async]: Asynchronous I/O framework for Ruby
30
+ * [Puma]: Ruby/Rack web server built for concurrency
30
31
 
31
32
  [ActionCable]: https://rubygems.org/gems/actioncable
32
33
  [Celluloid::IO]: https://github.com/celluloid/celluloid-io
33
34
  [Socketry Async]: https://github.com/socketry/async
35
+ [Puma]: https://github.com/puma/puma
34
36
 
35
37
  ## Goals
36
38
 
@@ -41,10 +43,13 @@ writing.
41
43
 
42
44
  ## Supported platforms
43
45
 
44
- * Ruby 2.2.2+
45
46
  * Ruby 2.3
46
47
  * Ruby 2.4
47
- * JRuby 9000
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)
48
53
 
49
54
  ## Supported backends
50
55
 
@@ -93,13 +98,54 @@ to maintain a large codebase.
93
98
  [EventMachine]: https://github.com/eventmachine/eventmachine
94
99
  [Cool.io]: https://coolio.github.io/
95
100
 
101
+ ## Releases
102
+
103
+ ### CRuby
104
+
105
+ ```
106
+ rake clean
107
+ rake release
108
+ ```
109
+
110
+ ### JRuby
111
+
112
+ You might need to delete `Gemfile.lock` before trying to `bundle install`.
113
+
114
+ ```
115
+ rake clean
116
+ rake compile
117
+ rake release
118
+ ```
119
+
96
120
  ## License
97
121
 
98
- Copyright (c) 2011-2018 Tony Arcieri. Distributed under the MIT License.
99
- See [LICENSE.txt] for further details.
122
+ Released under the MIT license.
123
+
124
+ Copyright, 2019, by Tony Arcieri.
125
+ Copyright, 2019, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
126
+
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:
133
+
134
+ The above copyright notice and this permission notice shall be included in
135
+ all copies or substantial portions of the Software.
136
+
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.
144
+
145
+ ### libev
146
+
147
+ Released under the BSD license. See [ext/libev/LICENSE] for details.
100
148
 
101
- Includes libev 4.24. Copyright (c) 2007-2016 Marc Alexander Lehmann.
102
- Distributed under the BSD license. See [ext/libev/LICENSE] for details.
149
+ Copyright, 2007-2019, by Marc Alexander Lehmann.
103
150
 
104
- [LICENSE.txt]: https://github.com/socketry/nio4r/blob/master/LICENSE.txt
105
151
  [ext/libev/LICENSE]: https://github.com/socketry/nio4r/blob/master/ext/libev/LICENSE
data/Rakefile CHANGED
@@ -3,8 +3,6 @@
3
3
  require "bundler/gem_tasks"
4
4
  require "rake/clean"
5
5
 
6
- Dir[File.expand_path("../tasks/**/*.rake", __FILE__)].each { |task| load task }
7
-
8
6
  task default: %w[compile spec rubocop]
9
7
 
10
8
  CLEAN.include "**/*.o", "**/*.so", "**/*.bundle", "**/*.jar", "pkg", "tmp"
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
4
+ $LOAD_PATH.push File.expand_path("../lib", __dir__)
5
5
  require "nio"
6
6
  require "socket"
7
7
 
@@ -19,7 +19,7 @@ class EchoServer
19
19
 
20
20
  def run
21
21
  loop do
22
- @selector.select { |monitor| monitor.value.call(monitor) }
22
+ @selector.select { |monitor| monitor.value.call }
23
23
  end
24
24
  end
25
25
 
@@ -1,5 +1,40 @@
1
1
  Revision history for libev, a high-performance and full-featured event loop.
2
2
 
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
+
3
38
  4.24 Wed Dec 28 05:19:55 CET 2016
4
39
  - bump version to 4.24, as the release tarball inexplicably
5
40
  didn't have the right version in ev.h, even though the cvs-tagged
@@ -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, kqueue and event ports backends.
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).
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libev event processing core, watcher management
3
3
  *
4
- * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
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-
@@ -40,6 +40,10 @@
40
40
  /* ########## NIO4R PATCHERY HO! ########## */
41
41
  #include "ruby.h"
42
42
  #include "ruby/thread.h"
43
+
44
+ #ifdef __APPLE__
45
+ #include <AvailabilityMacros.h>
46
+ #endif
43
47
  /* ######################################## */
44
48
 
45
49
  /* this big block deduces configuration from config.h */
@@ -122,6 +126,15 @@
122
126
  # define EV_USE_EPOLL 0
123
127
  # endif
124
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
+
125
138
  # if HAVE_KQUEUE && HAVE_SYS_EVENT_H
126
139
  # ifndef EV_USE_KQUEUE
127
140
  # define EV_USE_KQUEUE EV_FEATURE_BACKENDS
@@ -169,6 +182,16 @@
169
182
 
170
183
  #endif
171
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
+
172
195
  #include <stdlib.h>
173
196
  #include <string.h>
174
197
  #include <fcntl.h>
@@ -216,14 +239,6 @@
216
239
  # undef EV_AVOID_STDIO
217
240
  #endif
218
241
 
219
- /* OS X, in its infinite idiocy, actually HARDCODES
220
- * a limit of 1024 into their select. Where people have brains,
221
- * OS X engineers apparently have a vacuum. Or maybe they were
222
- * ordered to have a vacuum, or they do anything for money.
223
- * This might help. Or not.
224
- */
225
- #define _DARWIN_UNLIMITED_SELECT 1
226
-
227
242
  /* this block tries to deduce configuration from header-defined symbols and defaults */
228
243
 
229
244
  /* try to deduce the maximum number of signals on this platform */
@@ -370,7 +385,7 @@
370
385
  # define EV_HEAP_CACHE_AT EV_FEATURE_DATA
371
386
  #endif
372
387
 
373
- #ifdef ANDROID
388
+ #ifdef __ANDROID__
374
389
  /* supposedly, android doesn't typedef fd_mask */
375
390
  # undef EV_USE_SELECT
376
391
  # define EV_USE_SELECT 0
@@ -424,6 +439,14 @@
424
439
  # endif
425
440
  #endif
426
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
+
427
450
  #if EV_USE_INOTIFY
428
451
  # include <sys/statfs.h>
429
452
  # include <sys/inotify.h>
@@ -539,7 +562,7 @@ struct signalfd_siginfo
539
562
  #define ECB_H
540
563
 
541
564
  /* 16 bits major, 16 bits minor */
542
- #define ECB_VERSION 0x00010005
565
+ #define ECB_VERSION 0x00010006
543
566
 
544
567
  #ifdef _WIN32
545
568
  typedef signed char int8_t;
@@ -614,6 +637,8 @@ struct signalfd_siginfo
614
637
 
615
638
  #define ECB_CPP (__cplusplus+0)
616
639
  #define ECB_CPP11 (__cplusplus >= 201103L)
640
+ #define ECB_CPP14 (__cplusplus >= 201402L)
641
+ #define ECB_CPP17 (__cplusplus >= 201703L)
617
642
 
618
643
  #if ECB_CPP
619
644
  #define ECB_C 0
@@ -625,6 +650,7 @@ struct signalfd_siginfo
625
650
 
626
651
  #define ECB_C99 (ECB_STDC_VERSION >= 199901L)
627
652
  #define ECB_C11 (ECB_STDC_VERSION >= 201112L)
653
+ #define ECB_C17 (ECB_STDC_VERSION >= 201710L)
628
654
 
629
655
  #if ECB_CPP
630
656
  #define ECB_EXTERN_C extern "C"
@@ -660,14 +686,15 @@ struct signalfd_siginfo
660
686
 
661
687
  #ifndef ECB_MEMORY_FENCE
662
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")
663
690
  #if __i386 || __i386__
664
691
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
665
692
  #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
666
- #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
693
+ #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("" : : : "memory")
667
694
  #elif ECB_GCC_AMD64
668
695
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
669
696
  #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
670
- #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
697
+ #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("" : : : "memory")
671
698
  #elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__
672
699
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
673
700
  #elif defined __ARM_ARCH_2__ \
@@ -719,12 +746,14 @@ struct signalfd_siginfo
719
746
  #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
720
747
  #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE)
721
748
  #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE)
749
+ #define ECB_MEMORY_FENCE_RELAXED __atomic_thread_fence (__ATOMIC_RELAXED)
722
750
 
723
751
  #elif ECB_CLANG_EXTENSION(c_atomic)
724
752
  /* see comment below (stdatomic.h) about the C11 memory model. */
725
753
  #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
726
754
  #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE)
727
755
  #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE)
756
+ #define ECB_MEMORY_FENCE_RELAXED __c11_atomic_thread_fence (__ATOMIC_RELAXED)
728
757
 
729
758
  #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
730
759
  #define ECB_MEMORY_FENCE __sync_synchronize ()
@@ -744,9 +773,10 @@ struct signalfd_siginfo
744
773
  #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
745
774
  #elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
746
775
  #include <mbarrier.h>
747
- #define ECB_MEMORY_FENCE __machine_rw_barrier ()
748
- #define ECB_MEMORY_FENCE_ACQUIRE __machine_r_barrier ()
749
- #define ECB_MEMORY_FENCE_RELEASE __machine_w_barrier ()
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 ()
750
780
  #elif __xlC__
751
781
  #define ECB_MEMORY_FENCE __sync ()
752
782
  #endif
@@ -757,15 +787,9 @@ struct signalfd_siginfo
757
787
  /* we assume that these memory fences work on all variables/all memory accesses, */
758
788
  /* not just C11 atomics and atomic accesses */
759
789
  #include <stdatomic.h>
760
- /* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */
761
- /* any fence other than seq_cst, which isn't very efficient for us. */
762
- /* Why that is, we don't know - either the C11 memory model is quite useless */
763
- /* for most usages, or gcc and clang have a bug */
764
- /* I *currently* lean towards the latter, and inefficiently implement */
765
- /* all three of ecb's fences as a seq_cst fence */
766
- /* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */
767
- /* for all __atomic_thread_fence's except seq_cst */
768
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)
769
793
  #endif
770
794
  #endif
771
795
 
@@ -795,6 +819,10 @@ struct signalfd_siginfo
795
819
  #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
796
820
  #endif
797
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
+
798
826
  /*****************************************************************************/
799
827
 
800
828
  #if ECB_CPP
@@ -1545,8 +1573,7 @@ ecb_binary32_to_binary16 (uint32_t x)
1545
1573
  # define ABSPRI(w) (((W)w)->priority - EV_MINPRI)
1546
1574
  #endif
1547
1575
 
1548
- #define EMPTY /* required for microsofts broken pseudo-c compiler */
1549
- #define EMPTY2(a,b) /* used to suppress some warnings */
1576
+ #define EMPTY /* required for microsofts broken pseudo-c compiler */
1550
1577
 
1551
1578
  typedef ev_watcher *W;
1552
1579
  typedef ev_watcher_list *WL;
@@ -1581,6 +1608,10 @@ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work?
1581
1608
 
1582
1609
  /*****************************************************************************/
1583
1610
 
1611
+ #if EV_USE_LINUXAIO
1612
+ # include <linux/aio_abi.h> /* probably only needed for aio_context_t */
1613
+ #endif
1614
+
1584
1615
  /* define a suitable floor function (only used by periodics atm) */
1585
1616
 
1586
1617
  #if EV_USE_FLOOR
@@ -1682,11 +1713,11 @@ ev_printerr (const char *msg)
1682
1713
  }
1683
1714
  #endif
1684
1715
 
1685
- static void (*syserr_cb)(const char *msg) EV_THROW;
1716
+ static void (*syserr_cb)(const char *msg) EV_NOEXCEPT;
1686
1717
 
1687
1718
  ecb_cold
1688
1719
  void
1689
- ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW
1720
+ ev_set_syserr_cb (void (*cb)(const char *msg) EV_NOEXCEPT) EV_NOEXCEPT
1690
1721
  {
1691
1722
  syserr_cb = cb;
1692
1723
  }
@@ -1715,7 +1746,7 @@ ev_syserr (const char *msg)
1715
1746
  }
1716
1747
 
1717
1748
  static void *
1718
- ev_realloc_emul (void *ptr, long size) EV_THROW
1749
+ ev_realloc_emul (void *ptr, size_t size) EV_NOEXCEPT
1719
1750
  {
1720
1751
  /* some systems, notably openbsd and darwin, fail to properly
1721
1752
  * implement realloc (x, 0) (as required by both ansi c-89 and
@@ -1731,17 +1762,17 @@ ev_realloc_emul (void *ptr, long size) EV_THROW
1731
1762
  return 0;
1732
1763
  }
1733
1764
 
1734
- static void *(*alloc)(void *ptr, long size) EV_THROW = ev_realloc_emul;
1765
+ static void *(*alloc)(void *ptr, size_t size) EV_NOEXCEPT = ev_realloc_emul;
1735
1766
 
1736
1767
  ecb_cold
1737
1768
  void
1738
- ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW
1769
+ ev_set_allocator (void *(*cb)(void *ptr, size_t size) EV_NOEXCEPT) EV_NOEXCEPT
1739
1770
  {
1740
1771
  alloc = cb;
1741
1772
  }
1742
1773
 
1743
1774
  inline_speed void *
1744
- ev_realloc (void *ptr, long size)
1775
+ ev_realloc (void *ptr, size_t size)
1745
1776
  {
1746
1777
  ptr = alloc (ptr, size);
1747
1778
 
@@ -1772,7 +1803,7 @@ typedef struct
1772
1803
  WL head;
1773
1804
  unsigned char events; /* the events watched for */
1774
1805
  unsigned char reify; /* flag set when this ANFD needs reification (EV_ANFD_REIFY, EV__IOFDSET) */
1775
- unsigned char emask; /* the epoll backend stores the actual kernel mask in here */
1806
+ unsigned char emask; /* some backends store the actual kernel mask in here */
1776
1807
  unsigned char unused;
1777
1808
  #if EV_USE_EPOLL
1778
1809
  unsigned int egen; /* generation counter to counter epoll bugs */
@@ -1862,7 +1893,7 @@ typedef struct
1862
1893
 
1863
1894
  #ifndef EV_HAVE_EV_TIME
1864
1895
  ev_tstamp
1865
- ev_time (void) EV_THROW
1896
+ ev_time (void) EV_NOEXCEPT
1866
1897
  {
1867
1898
  #if EV_USE_REALTIME
1868
1899
  if (expect_true (have_realtime))
@@ -1896,14 +1927,14 @@ get_clock (void)
1896
1927
 
1897
1928
  #if EV_MULTIPLICITY
1898
1929
  ev_tstamp
1899
- ev_now (EV_P) EV_THROW
1930
+ ev_now (EV_P) EV_NOEXCEPT
1900
1931
  {
1901
1932
  return ev_rt_now;
1902
1933
  }
1903
1934
  #endif
1904
1935
 
1905
1936
  void
1906
- ev_sleep (ev_tstamp delay) EV_THROW
1937
+ ev_sleep (ev_tstamp delay) EV_NOEXCEPT
1907
1938
  {
1908
1939
  if (delay > 0.)
1909
1940
  {
@@ -1913,6 +1944,8 @@ ev_sleep (ev_tstamp delay) EV_THROW
1913
1944
  EV_TS_SET (ts, delay);
1914
1945
  nanosleep (&ts, 0);
1915
1946
  #elif defined _WIN32
1947
+ /* maybe this should round up, as ms is very low resolution */
1948
+ /* compared to select (µs) or nanosleep (ns) */
1916
1949
  Sleep ((unsigned long)(delay * 1e3));
1917
1950
  #else
1918
1951
  struct timeval tv;
@@ -1961,8 +1994,10 @@ array_realloc (int elem, void *base, int *cur, int cnt)
1961
1994
  return ev_realloc (base, elem * *cur);
1962
1995
  }
1963
1996
 
1964
- #define array_init_zero(base,count) \
1965
- memset ((void *)(base), 0, sizeof (*(base)) * (count))
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))
1966
2001
 
1967
2002
  #define array_needsize(type,base,cur,cnt,init) \
1968
2003
  if (expect_false ((cnt) > (cur))) \
@@ -1970,7 +2005,7 @@ array_realloc (int elem, void *base, int *cur, int cnt)
1970
2005
  ecb_unused int ocur_ = (cur); \
1971
2006
  (base) = (type *)array_realloc \
1972
2007
  (sizeof (type), (base), &(cur), (cnt)); \
1973
- init ((base) + (ocur_), (cur) - ocur_); \
2008
+ init ((base), ocur_, ((cur) - ocur_)); \
1974
2009
  }
1975
2010
 
1976
2011
  #if 0
@@ -1997,7 +2032,7 @@ pendingcb (EV_P_ ev_prepare *w, int revents)
1997
2032
 
1998
2033
  noinline
1999
2034
  void
2000
- ev_feed_event (EV_P_ void *w, int revents) EV_THROW
2035
+ ev_feed_event (EV_P_ void *w, int revents) EV_NOEXCEPT
2001
2036
  {
2002
2037
  W w_ = (W)w;
2003
2038
  int pri = ABSPRI (w_);
@@ -2007,7 +2042,7 @@ ev_feed_event (EV_P_ void *w, int revents) EV_THROW
2007
2042
  else
2008
2043
  {
2009
2044
  w_->pending = ++pendingcnt [pri];
2010
- array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, EMPTY2);
2045
+ array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, array_needsize_noinit);
2011
2046
  pendings [pri][w_->pending - 1].w = w_;
2012
2047
  pendings [pri][w_->pending - 1].events = revents;
2013
2048
  }
@@ -2018,7 +2053,7 @@ ev_feed_event (EV_P_ void *w, int revents) EV_THROW
2018
2053
  inline_speed void
2019
2054
  feed_reverse (EV_P_ W w)
2020
2055
  {
2021
- array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, EMPTY2);
2056
+ array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, array_needsize_noinit);
2022
2057
  rfeeds [rfeedcnt++] = w;
2023
2058
  }
2024
2059
 
@@ -2068,7 +2103,7 @@ fd_event (EV_P_ int fd, int revents)
2068
2103
  }
2069
2104
 
2070
2105
  void
2071
- ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW
2106
+ ev_feed_fd_event (EV_P_ int fd, int revents) EV_NOEXCEPT
2072
2107
  {
2073
2108
  if (fd >= 0 && fd < anfdmax)
2074
2109
  fd_event_nocheck (EV_A_ fd, revents);
@@ -2115,7 +2150,7 @@ fd_reify (EV_P)
2115
2150
  unsigned char o_events = anfd->events;
2116
2151
  unsigned char o_reify = anfd->reify;
2117
2152
 
2118
- anfd->reify = 0;
2153
+ anfd->reify = 0;
2119
2154
 
2120
2155
  /*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */
2121
2156
  {
@@ -2146,7 +2181,7 @@ fd_change (EV_P_ int fd, int flags)
2146
2181
  if (expect_true (!reify))
2147
2182
  {
2148
2183
  ++fdchangecnt;
2149
- array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2);
2184
+ array_needsize (int, fdchanges, fdchangemax, fdchangecnt, array_needsize_noinit);
2150
2185
  fdchanges [fdchangecnt - 1] = fd;
2151
2186
  }
2152
2187
  }
@@ -2478,7 +2513,7 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
2478
2513
  #ifdef _WIN32
2479
2514
  WSABUF buf;
2480
2515
  DWORD sent;
2481
- buf.buf = &buf;
2516
+ buf.buf = (char *)&buf;
2482
2517
  buf.len = 1;
2483
2518
  WSASend (EV_FD_TO_WIN32_HANDLE (evpipe [1]), &buf, 1, &sent, 0, 0, 0);
2484
2519
  #else
@@ -2560,7 +2595,7 @@ pipecb (EV_P_ ev_io *iow, int revents)
2560
2595
  /*****************************************************************************/
2561
2596
 
2562
2597
  void
2563
- ev_feed_signal (int signum) EV_THROW
2598
+ ev_feed_signal (int signum) EV_NOEXCEPT
2564
2599
  {
2565
2600
  #if EV_MULTIPLICITY
2566
2601
  EV_P;
@@ -2587,7 +2622,7 @@ ev_sighandler (int signum)
2587
2622
 
2588
2623
  noinline
2589
2624
  void
2590
- ev_feed_signal_event (EV_P_ int signum) EV_THROW
2625
+ ev_feed_signal_event (EV_P_ int signum) EV_NOEXCEPT
2591
2626
  {
2592
2627
  WL w;
2593
2628
 
@@ -2706,6 +2741,9 @@ childcb (EV_P_ ev_signal *sw, int revents)
2706
2741
  #if EV_USE_EPOLL
2707
2742
  # include "ev_epoll.c"
2708
2743
  #endif
2744
+ #if EV_USE_LINUXAIO
2745
+ # include "ev_linuxaio.c"
2746
+ #endif
2709
2747
  #if EV_USE_POLL
2710
2748
  # include "ev_poll.c"
2711
2749
  #endif
@@ -2714,13 +2752,13 @@ childcb (EV_P_ ev_signal *sw, int revents)
2714
2752
  #endif
2715
2753
 
2716
2754
  ecb_cold int
2717
- ev_version_major (void) EV_THROW
2755
+ ev_version_major (void) EV_NOEXCEPT
2718
2756
  {
2719
2757
  return EV_VERSION_MAJOR;
2720
2758
  }
2721
2759
 
2722
2760
  ecb_cold int
2723
- ev_version_minor (void) EV_THROW
2761
+ ev_version_minor (void) EV_NOEXCEPT
2724
2762
  {
2725
2763
  return EV_VERSION_MINOR;
2726
2764
  }
@@ -2739,45 +2777,56 @@ enable_secure (void)
2739
2777
 
2740
2778
  ecb_cold
2741
2779
  unsigned int
2742
- ev_supported_backends (void) EV_THROW
2780
+ ev_supported_backends (void) EV_NOEXCEPT
2743
2781
  {
2744
2782
  unsigned int flags = 0;
2745
2783
 
2746
- if (EV_USE_PORT ) flags |= EVBACKEND_PORT;
2747
- if (EV_USE_KQUEUE) flags |= EVBACKEND_KQUEUE;
2748
- if (EV_USE_EPOLL ) flags |= EVBACKEND_EPOLL;
2749
- if (EV_USE_POLL ) flags |= EVBACKEND_POLL;
2750
- if (EV_USE_SELECT) flags |= EVBACKEND_SELECT;
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;
2751
2794
 
2752
2795
  return flags;
2753
2796
  }
2754
2797
 
2755
2798
  ecb_cold
2756
2799
  unsigned int
2757
- ev_recommended_backends (void) EV_THROW
2800
+ ev_recommended_backends (void) EV_NOEXCEPT
2758
2801
  {
2759
2802
  unsigned int flags = ev_supported_backends ();
2760
2803
 
2761
- #ifndef __NetBSD__
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__)
2762
2807
  /* kqueue is borked on everything but netbsd apparently */
2763
2808
  /* it usually doesn't work correctly on anything but sockets and pipes */
2764
- flags &= ~EVBACKEND_KQUEUE;
2765
- #endif
2766
- #ifdef __APPLE__
2809
+ #else
2767
2810
  /* only select works correctly on that "unix-certified" platform */
2768
2811
  flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */
2769
2812
  flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */
2770
2813
  #endif
2814
+
2771
2815
  #ifdef __FreeBSD__
2772
2816
  flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */
2773
2817
  #endif
2774
2818
 
2819
+ /* TODO: linuxaio is very experimental */
2820
+ #if !EV_RECOMMEND_LINUXAIO
2821
+ flags &= ~EVBACKEND_LINUXAIO;
2822
+ #endif
2823
+
2775
2824
  return flags;
2776
2825
  }
2777
2826
 
2778
2827
  ecb_cold
2779
2828
  unsigned int
2780
- ev_embeddable_backends (void) EV_THROW
2829
+ ev_embeddable_backends (void) EV_NOEXCEPT
2781
2830
  {
2782
2831
  int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT;
2783
2832
 
@@ -2789,56 +2838,56 @@ ev_embeddable_backends (void) EV_THROW
2789
2838
  }
2790
2839
 
2791
2840
  unsigned int
2792
- ev_backend (EV_P) EV_THROW
2841
+ ev_backend (EV_P) EV_NOEXCEPT
2793
2842
  {
2794
2843
  return backend;
2795
2844
  }
2796
2845
 
2797
2846
  #if EV_FEATURE_API
2798
2847
  unsigned int
2799
- ev_iteration (EV_P) EV_THROW
2848
+ ev_iteration (EV_P) EV_NOEXCEPT
2800
2849
  {
2801
2850
  return loop_count;
2802
2851
  }
2803
2852
 
2804
2853
  unsigned int
2805
- ev_depth (EV_P) EV_THROW
2854
+ ev_depth (EV_P) EV_NOEXCEPT
2806
2855
  {
2807
2856
  return loop_depth;
2808
2857
  }
2809
2858
 
2810
2859
  void
2811
- ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
2860
+ ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT
2812
2861
  {
2813
2862
  io_blocktime = interval;
2814
2863
  }
2815
2864
 
2816
2865
  void
2817
- ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
2866
+ ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT
2818
2867
  {
2819
2868
  timeout_blocktime = interval;
2820
2869
  }
2821
2870
 
2822
2871
  void
2823
- ev_set_userdata (EV_P_ void *data) EV_THROW
2872
+ ev_set_userdata (EV_P_ void *data) EV_NOEXCEPT
2824
2873
  {
2825
2874
  userdata = data;
2826
2875
  }
2827
2876
 
2828
2877
  void *
2829
- ev_userdata (EV_P) EV_THROW
2878
+ ev_userdata (EV_P) EV_NOEXCEPT
2830
2879
  {
2831
2880
  return userdata;
2832
2881
  }
2833
2882
 
2834
2883
  void
2835
- ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW
2884
+ ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_NOEXCEPT
2836
2885
  {
2837
2886
  invoke_cb = invoke_pending_cb;
2838
2887
  }
2839
2888
 
2840
2889
  void
2841
- ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW
2890
+ ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_NOEXCEPT, void (*acquire)(EV_P) EV_NOEXCEPT) EV_NOEXCEPT
2842
2891
  {
2843
2892
  release_cb = release;
2844
2893
  acquire_cb = acquire;
@@ -2848,7 +2897,7 @@ ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV
2848
2897
  /* initialise a loop structure, must be zero-initialised */
2849
2898
  noinline ecb_cold
2850
2899
  static void
2851
- loop_init (EV_P_ unsigned int flags) EV_THROW
2900
+ loop_init (EV_P_ unsigned int flags) EV_NOEXCEPT
2852
2901
  {
2853
2902
  if (!backend)
2854
2903
  {
@@ -2916,22 +2965,25 @@ loop_init (EV_P_ unsigned int flags) EV_THROW
2916
2965
  flags |= ev_recommended_backends ();
2917
2966
 
2918
2967
  #if EV_USE_IOCP
2919
- if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
2968
+ if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
2920
2969
  #endif
2921
2970
  #if EV_USE_PORT
2922
- if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
2971
+ if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
2923
2972
  #endif
2924
2973
  #if EV_USE_KQUEUE
2925
- if (!backend && (flags & EVBACKEND_KQUEUE)) backend = kqueue_init (EV_A_ flags);
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);
2926
2978
  #endif
2927
2979
  #if EV_USE_EPOLL
2928
- if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags);
2980
+ if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags);
2929
2981
  #endif
2930
2982
  #if EV_USE_POLL
2931
- if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags);
2983
+ if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags);
2932
2984
  #endif
2933
2985
  #if EV_USE_SELECT
2934
- if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
2986
+ if (!backend && (flags & EVBACKEND_SELECT )) backend = select_init (EV_A_ flags);
2935
2987
  #endif
2936
2988
 
2937
2989
  ev_prepare_init (&pending_w, pendingcb);
@@ -2996,22 +3048,25 @@ ev_loop_destroy (EV_P)
2996
3048
  close (backend_fd);
2997
3049
 
2998
3050
  #if EV_USE_IOCP
2999
- if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
3051
+ if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
3000
3052
  #endif
3001
3053
  #if EV_USE_PORT
3002
- if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
3054
+ if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
3003
3055
  #endif
3004
3056
  #if EV_USE_KQUEUE
3005
- if (backend == EVBACKEND_KQUEUE) kqueue_destroy (EV_A);
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);
3006
3061
  #endif
3007
3062
  #if EV_USE_EPOLL
3008
- if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A);
3063
+ if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A);
3009
3064
  #endif
3010
3065
  #if EV_USE_POLL
3011
- if (backend == EVBACKEND_POLL ) poll_destroy (EV_A);
3066
+ if (backend == EVBACKEND_POLL ) poll_destroy (EV_A);
3012
3067
  #endif
3013
3068
  #if EV_USE_SELECT
3014
- if (backend == EVBACKEND_SELECT) select_destroy (EV_A);
3069
+ if (backend == EVBACKEND_SELECT ) select_destroy (EV_A);
3015
3070
  #endif
3016
3071
 
3017
3072
  for (i = NUMPRI; i--; )
@@ -3063,13 +3118,16 @@ inline_size void
3063
3118
  loop_fork (EV_P)
3064
3119
  {
3065
3120
  #if EV_USE_PORT
3066
- if (backend == EVBACKEND_PORT ) port_fork (EV_A);
3121
+ if (backend == EVBACKEND_PORT ) port_fork (EV_A);
3067
3122
  #endif
3068
3123
  #if EV_USE_KQUEUE
3069
- if (backend == EVBACKEND_KQUEUE) kqueue_fork (EV_A);
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);
3070
3128
  #endif
3071
3129
  #if EV_USE_EPOLL
3072
- if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A);
3130
+ if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A);
3073
3131
  #endif
3074
3132
  #if EV_USE_INOTIFY
3075
3133
  infy_fork (EV_A);
@@ -3099,7 +3157,7 @@ loop_fork (EV_P)
3099
3157
 
3100
3158
  ecb_cold
3101
3159
  struct ev_loop *
3102
- ev_loop_new (unsigned int flags) EV_THROW
3160
+ ev_loop_new (unsigned int flags) EV_NOEXCEPT
3103
3161
  {
3104
3162
  EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
3105
3163
 
@@ -3156,7 +3214,7 @@ array_verify (EV_P_ W *ws, int cnt)
3156
3214
 
3157
3215
  #if EV_FEATURE_API
3158
3216
  void ecb_cold
3159
- ev_verify (EV_P) EV_THROW
3217
+ ev_verify (EV_P) EV_NOEXCEPT
3160
3218
  {
3161
3219
  #if EV_VERIFY
3162
3220
  int i;
@@ -3247,7 +3305,7 @@ struct ev_loop *
3247
3305
  #else
3248
3306
  int
3249
3307
  #endif
3250
- ev_default_loop (unsigned int flags) EV_THROW
3308
+ ev_default_loop (unsigned int flags) EV_NOEXCEPT
3251
3309
  {
3252
3310
  if (!ev_default_loop_ptr)
3253
3311
  {
@@ -3276,7 +3334,7 @@ ev_default_loop (unsigned int flags) EV_THROW
3276
3334
  }
3277
3335
 
3278
3336
  void
3279
- ev_loop_fork (EV_P) EV_THROW
3337
+ ev_loop_fork (EV_P) EV_NOEXCEPT
3280
3338
  {
3281
3339
  postfork = 1;
3282
3340
  }
@@ -3290,7 +3348,7 @@ ev_invoke (EV_P_ void *w, int revents)
3290
3348
  }
3291
3349
 
3292
3350
  unsigned int
3293
- ev_pending_count (EV_P) EV_THROW
3351
+ ev_pending_count (EV_P) EV_NOEXCEPT
3294
3352
  {
3295
3353
  int pri;
3296
3354
  unsigned int count = 0;
@@ -3307,10 +3365,11 @@ ev_invoke_pending (EV_P)
3307
3365
  {
3308
3366
  pendingpri = NUMPRI;
3309
3367
 
3310
- while (pendingpri) /* pendingpri possibly gets modified in the inner loop */
3368
+ do
3311
3369
  {
3312
3370
  --pendingpri;
3313
3371
 
3372
+ /* pendingpri possibly gets modified in the inner loop */
3314
3373
  while (pendingcnt [pendingpri])
3315
3374
  {
3316
3375
  ANPENDING *p = pendings [pendingpri] + --pendingcnt [pendingpri];
@@ -3320,6 +3379,7 @@ ev_invoke_pending (EV_P)
3320
3379
  EV_FREQUENT_CHECK;
3321
3380
  }
3322
3381
  }
3382
+ while (pendingpri);
3323
3383
  }
3324
3384
 
3325
3385
  #if EV_IDLE_ENABLE
@@ -3572,11 +3632,13 @@ struct ev_poll_args {
3572
3632
  };
3573
3633
 
3574
3634
  static
3575
- VALUE ev_backend_poll(void *ptr)
3635
+ void * ev_backend_poll(void *ptr)
3576
3636
  {
3577
3637
  struct ev_poll_args *args = (struct ev_poll_args *)ptr;
3578
3638
  struct ev_loop *loop = args->loop;
3579
3639
  backend_poll (EV_A_ args->waittime);
3640
+
3641
+ return NULL;
3580
3642
  }
3581
3643
  /* ######################################## */
3582
3644
 
@@ -3584,7 +3646,7 @@ int
3584
3646
  ev_run (EV_P_ int flags)
3585
3647
  {
3586
3648
  /* ########## NIO4R PATCHERY HO! ########## */
3587
- struct ev_poll_args poll_args;
3649
+ struct ev_poll_args poll_args;
3588
3650
  /* ######################################## */
3589
3651
 
3590
3652
  #if EV_FEATURE_API
@@ -3804,37 +3866,37 @@ rb_thread_unsafe_dangerous_crazy_blocking_region_end(...);
3804
3866
  }
3805
3867
 
3806
3868
  void
3807
- ev_break (EV_P_ int how) EV_THROW
3869
+ ev_break (EV_P_ int how) EV_NOEXCEPT
3808
3870
  {
3809
3871
  loop_done = how;
3810
3872
  }
3811
3873
 
3812
3874
  void
3813
- ev_ref (EV_P) EV_THROW
3875
+ ev_ref (EV_P) EV_NOEXCEPT
3814
3876
  {
3815
3877
  ++activecnt;
3816
3878
  }
3817
3879
 
3818
3880
  void
3819
- ev_unref (EV_P) EV_THROW
3881
+ ev_unref (EV_P) EV_NOEXCEPT
3820
3882
  {
3821
3883
  --activecnt;
3822
3884
  }
3823
3885
 
3824
3886
  void
3825
- ev_now_update (EV_P) EV_THROW
3887
+ ev_now_update (EV_P) EV_NOEXCEPT
3826
3888
  {
3827
3889
  time_update (EV_A_ 1e100);
3828
3890
  }
3829
3891
 
3830
3892
  void
3831
- ev_suspend (EV_P) EV_THROW
3893
+ ev_suspend (EV_P) EV_NOEXCEPT
3832
3894
  {
3833
3895
  ev_now_update (EV_A);
3834
3896
  }
3835
3897
 
3836
3898
  void
3837
- ev_resume (EV_P) EV_THROW
3899
+ ev_resume (EV_P) EV_NOEXCEPT
3838
3900
  {
3839
3901
  ev_tstamp mn_prev = mn_now;
3840
3902
 
@@ -3883,7 +3945,7 @@ clear_pending (EV_P_ W w)
3883
3945
  }
3884
3946
 
3885
3947
  int
3886
- ev_clear_pending (EV_P_ void *w) EV_THROW
3948
+ ev_clear_pending (EV_P_ void *w) EV_NOEXCEPT
3887
3949
  {
3888
3950
  W w_ = (W)w;
3889
3951
  int pending = w_->pending;
@@ -3927,7 +3989,7 @@ ev_stop (EV_P_ W w)
3927
3989
 
3928
3990
  noinline
3929
3991
  void
3930
- ev_io_start (EV_P_ ev_io *w) EV_THROW
3992
+ ev_io_start (EV_P_ ev_io *w) EV_NOEXCEPT
3931
3993
  {
3932
3994
  int fd = w->fd;
3933
3995
 
@@ -3937,10 +3999,13 @@ ev_io_start (EV_P_ ev_io *w) EV_THROW
3937
3999
  assert (("libev: ev_io_start called with negative fd", fd >= 0));
3938
4000
  assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE))));
3939
4001
 
4002
+ #if EV_VERIFY >= 2
4003
+ assert (("libev: ev_io_start called on watcher with invalid fd", fd_valid (fd)));
4004
+ #endif
3940
4005
  EV_FREQUENT_CHECK;
3941
4006
 
3942
4007
  ev_start (EV_A_ (W)w, 1);
3943
- array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero);
4008
+ array_needsize (ANFD, anfds, anfdmax, fd + 1, array_needsize_zerofill);
3944
4009
  wlist_add (&anfds[fd].head, (WL)w);
3945
4010
 
3946
4011
  /* common bug, apparently */
@@ -3954,7 +4019,7 @@ ev_io_start (EV_P_ ev_io *w) EV_THROW
3954
4019
 
3955
4020
  noinline
3956
4021
  void
3957
- ev_io_stop (EV_P_ ev_io *w) EV_THROW
4022
+ ev_io_stop (EV_P_ ev_io *w) EV_NOEXCEPT
3958
4023
  {
3959
4024
  clear_pending (EV_A_ (W)w);
3960
4025
  if (expect_false (!ev_is_active (w)))
@@ -3962,6 +4027,9 @@ ev_io_stop (EV_P_ ev_io *w) EV_THROW
3962
4027
 
3963
4028
  assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
3964
4029
 
4030
+ #if EV_VERIFY >= 2
4031
+ assert (("libev: ev_io_stop called on watcher with invalid fd", fd_valid (w->fd)));
4032
+ #endif
3965
4033
  EV_FREQUENT_CHECK;
3966
4034
 
3967
4035
  wlist_del (&anfds[w->fd].head, (WL)w);
@@ -3974,7 +4042,7 @@ ev_io_stop (EV_P_ ev_io *w) EV_THROW
3974
4042
 
3975
4043
  noinline
3976
4044
  void
3977
- ev_timer_start (EV_P_ ev_timer *w) EV_THROW
4045
+ ev_timer_start (EV_P_ ev_timer *w) EV_NOEXCEPT
3978
4046
  {
3979
4047
  if (expect_false (ev_is_active (w)))
3980
4048
  return;
@@ -3987,7 +4055,7 @@ ev_timer_start (EV_P_ ev_timer *w) EV_THROW
3987
4055
 
3988
4056
  ++timercnt;
3989
4057
  ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1);
3990
- array_needsize (ANHE, timers, timermax, ev_active (w) + 1, EMPTY2);
4058
+ array_needsize (ANHE, timers, timermax, ev_active (w) + 1, array_needsize_noinit);
3991
4059
  ANHE_w (timers [ev_active (w)]) = (WT)w;
3992
4060
  ANHE_at_cache (timers [ev_active (w)]);
3993
4061
  upheap (timers, ev_active (w));
@@ -3999,7 +4067,7 @@ ev_timer_start (EV_P_ ev_timer *w) EV_THROW
3999
4067
 
4000
4068
  noinline
4001
4069
  void
4002
- ev_timer_stop (EV_P_ ev_timer *w) EV_THROW
4070
+ ev_timer_stop (EV_P_ ev_timer *w) EV_NOEXCEPT
4003
4071
  {
4004
4072
  clear_pending (EV_A_ (W)w);
4005
4073
  if (expect_false (!ev_is_active (w)))
@@ -4030,7 +4098,7 @@ ev_timer_stop (EV_P_ ev_timer *w) EV_THROW
4030
4098
 
4031
4099
  noinline
4032
4100
  void
4033
- ev_timer_again (EV_P_ ev_timer *w) EV_THROW
4101
+ ev_timer_again (EV_P_ ev_timer *w) EV_NOEXCEPT
4034
4102
  {
4035
4103
  EV_FREQUENT_CHECK;
4036
4104
 
@@ -4057,7 +4125,7 @@ ev_timer_again (EV_P_ ev_timer *w) EV_THROW
4057
4125
  }
4058
4126
 
4059
4127
  ev_tstamp
4060
- ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW
4128
+ ev_timer_remaining (EV_P_ ev_timer *w) EV_NOEXCEPT
4061
4129
  {
4062
4130
  return ev_at (w) - (ev_is_active (w) ? mn_now : 0.);
4063
4131
  }
@@ -4065,7 +4133,7 @@ ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW
4065
4133
  #if EV_PERIODIC_ENABLE
4066
4134
  noinline
4067
4135
  void
4068
- ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
4136
+ ev_periodic_start (EV_P_ ev_periodic *w) EV_NOEXCEPT
4069
4137
  {
4070
4138
  if (expect_false (ev_is_active (w)))
4071
4139
  return;
@@ -4084,7 +4152,7 @@ ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
4084
4152
 
4085
4153
  ++periodiccnt;
4086
4154
  ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1);
4087
- array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2);
4155
+ array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, array_needsize_noinit);
4088
4156
  ANHE_w (periodics [ev_active (w)]) = (WT)w;
4089
4157
  ANHE_at_cache (periodics [ev_active (w)]);
4090
4158
  upheap (periodics, ev_active (w));
@@ -4096,7 +4164,7 @@ ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
4096
4164
 
4097
4165
  noinline
4098
4166
  void
4099
- ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW
4167
+ ev_periodic_stop (EV_P_ ev_periodic *w) EV_NOEXCEPT
4100
4168
  {
4101
4169
  clear_pending (EV_A_ (W)w);
4102
4170
  if (expect_false (!ev_is_active (w)))
@@ -4125,7 +4193,7 @@ ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW
4125
4193
 
4126
4194
  noinline
4127
4195
  void
4128
- ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW
4196
+ ev_periodic_again (EV_P_ ev_periodic *w) EV_NOEXCEPT
4129
4197
  {
4130
4198
  /* TODO: use adjustheap and recalculation */
4131
4199
  ev_periodic_stop (EV_A_ w);
@@ -4141,7 +4209,7 @@ ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW
4141
4209
 
4142
4210
  noinline
4143
4211
  void
4144
- ev_signal_start (EV_P_ ev_signal *w) EV_THROW
4212
+ ev_signal_start (EV_P_ ev_signal *w) EV_NOEXCEPT
4145
4213
  {
4146
4214
  if (expect_false (ev_is_active (w)))
4147
4215
  return;
@@ -4224,7 +4292,7 @@ ev_signal_start (EV_P_ ev_signal *w) EV_THROW
4224
4292
 
4225
4293
  noinline
4226
4294
  void
4227
- ev_signal_stop (EV_P_ ev_signal *w) EV_THROW
4295
+ ev_signal_stop (EV_P_ ev_signal *w) EV_NOEXCEPT
4228
4296
  {
4229
4297
  clear_pending (EV_A_ (W)w);
4230
4298
  if (expect_false (!ev_is_active (w)))
@@ -4265,7 +4333,7 @@ ev_signal_stop (EV_P_ ev_signal *w) EV_THROW
4265
4333
  #if EV_CHILD_ENABLE
4266
4334
 
4267
4335
  void
4268
- ev_child_start (EV_P_ ev_child *w) EV_THROW
4336
+ ev_child_start (EV_P_ ev_child *w) EV_NOEXCEPT
4269
4337
  {
4270
4338
  #if EV_MULTIPLICITY
4271
4339
  assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
@@ -4282,7 +4350,7 @@ ev_child_start (EV_P_ ev_child *w) EV_THROW
4282
4350
  }
4283
4351
 
4284
4352
  void
4285
- ev_child_stop (EV_P_ ev_child *w) EV_THROW
4353
+ ev_child_stop (EV_P_ ev_child *w) EV_NOEXCEPT
4286
4354
  {
4287
4355
  clear_pending (EV_A_ (W)w);
4288
4356
  if (expect_false (!ev_is_active (w)))
@@ -4557,7 +4625,7 @@ infy_fork (EV_P)
4557
4625
  #endif
4558
4626
 
4559
4627
  void
4560
- ev_stat_stat (EV_P_ ev_stat *w) EV_THROW
4628
+ ev_stat_stat (EV_P_ ev_stat *w) EV_NOEXCEPT
4561
4629
  {
4562
4630
  if (lstat (w->path, &w->attr) < 0)
4563
4631
  w->attr.st_nlink = 0;
@@ -4607,7 +4675,7 @@ stat_timer_cb (EV_P_ ev_timer *w_, int revents)
4607
4675
  }
4608
4676
 
4609
4677
  void
4610
- ev_stat_start (EV_P_ ev_stat *w) EV_THROW
4678
+ ev_stat_start (EV_P_ ev_stat *w) EV_NOEXCEPT
4611
4679
  {
4612
4680
  if (expect_false (ev_is_active (w)))
4613
4681
  return;
@@ -4638,7 +4706,7 @@ ev_stat_start (EV_P_ ev_stat *w) EV_THROW
4638
4706
  }
4639
4707
 
4640
4708
  void
4641
- ev_stat_stop (EV_P_ ev_stat *w) EV_THROW
4709
+ ev_stat_stop (EV_P_ ev_stat *w) EV_NOEXCEPT
4642
4710
  {
4643
4711
  clear_pending (EV_A_ (W)w);
4644
4712
  if (expect_false (!ev_is_active (w)))
@@ -4664,7 +4732,7 @@ ev_stat_stop (EV_P_ ev_stat *w) EV_THROW
4664
4732
 
4665
4733
  #if EV_IDLE_ENABLE
4666
4734
  void
4667
- ev_idle_start (EV_P_ ev_idle *w) EV_THROW
4735
+ ev_idle_start (EV_P_ ev_idle *w) EV_NOEXCEPT
4668
4736
  {
4669
4737
  if (expect_false (ev_is_active (w)))
4670
4738
  return;
@@ -4679,7 +4747,7 @@ ev_idle_start (EV_P_ ev_idle *w) EV_THROW
4679
4747
  ++idleall;
4680
4748
  ev_start (EV_A_ (W)w, active);
4681
4749
 
4682
- array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, EMPTY2);
4750
+ array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, array_needsize_noinit);
4683
4751
  idles [ABSPRI (w)][active - 1] = w;
4684
4752
  }
4685
4753
 
@@ -4687,7 +4755,7 @@ ev_idle_start (EV_P_ ev_idle *w) EV_THROW
4687
4755
  }
4688
4756
 
4689
4757
  void
4690
- ev_idle_stop (EV_P_ ev_idle *w) EV_THROW
4758
+ ev_idle_stop (EV_P_ ev_idle *w) EV_NOEXCEPT
4691
4759
  {
4692
4760
  clear_pending (EV_A_ (W)w);
4693
4761
  if (expect_false (!ev_is_active (w)))
@@ -4711,7 +4779,7 @@ ev_idle_stop (EV_P_ ev_idle *w) EV_THROW
4711
4779
 
4712
4780
  #if EV_PREPARE_ENABLE
4713
4781
  void
4714
- ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW
4782
+ ev_prepare_start (EV_P_ ev_prepare *w) EV_NOEXCEPT
4715
4783
  {
4716
4784
  if (expect_false (ev_is_active (w)))
4717
4785
  return;
@@ -4719,14 +4787,14 @@ ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW
4719
4787
  EV_FREQUENT_CHECK;
4720
4788
 
4721
4789
  ev_start (EV_A_ (W)w, ++preparecnt);
4722
- array_needsize (ev_prepare *, prepares, preparemax, preparecnt, EMPTY2);
4790
+ array_needsize (ev_prepare *, prepares, preparemax, preparecnt, array_needsize_noinit);
4723
4791
  prepares [preparecnt - 1] = w;
4724
4792
 
4725
4793
  EV_FREQUENT_CHECK;
4726
4794
  }
4727
4795
 
4728
4796
  void
4729
- ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW
4797
+ ev_prepare_stop (EV_P_ ev_prepare *w) EV_NOEXCEPT
4730
4798
  {
4731
4799
  clear_pending (EV_A_ (W)w);
4732
4800
  if (expect_false (!ev_is_active (w)))
@@ -4749,7 +4817,7 @@ ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW
4749
4817
 
4750
4818
  #if EV_CHECK_ENABLE
4751
4819
  void
4752
- ev_check_start (EV_P_ ev_check *w) EV_THROW
4820
+ ev_check_start (EV_P_ ev_check *w) EV_NOEXCEPT
4753
4821
  {
4754
4822
  if (expect_false (ev_is_active (w)))
4755
4823
  return;
@@ -4757,14 +4825,14 @@ ev_check_start (EV_P_ ev_check *w) EV_THROW
4757
4825
  EV_FREQUENT_CHECK;
4758
4826
 
4759
4827
  ev_start (EV_A_ (W)w, ++checkcnt);
4760
- array_needsize (ev_check *, checks, checkmax, checkcnt, EMPTY2);
4828
+ array_needsize (ev_check *, checks, checkmax, checkcnt, array_needsize_noinit);
4761
4829
  checks [checkcnt - 1] = w;
4762
4830
 
4763
4831
  EV_FREQUENT_CHECK;
4764
4832
  }
4765
4833
 
4766
4834
  void
4767
- ev_check_stop (EV_P_ ev_check *w) EV_THROW
4835
+ ev_check_stop (EV_P_ ev_check *w) EV_NOEXCEPT
4768
4836
  {
4769
4837
  clear_pending (EV_A_ (W)w);
4770
4838
  if (expect_false (!ev_is_active (w)))
@@ -4788,7 +4856,7 @@ ev_check_stop (EV_P_ ev_check *w) EV_THROW
4788
4856
  #if EV_EMBED_ENABLE
4789
4857
  noinline
4790
4858
  void
4791
- ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW
4859
+ ev_embed_sweep (EV_P_ ev_embed *w) EV_NOEXCEPT
4792
4860
  {
4793
4861
  ev_run (w->other, EVRUN_NOWAIT);
4794
4862
  }
@@ -4846,7 +4914,7 @@ embed_idle_cb (EV_P_ ev_idle *idle, int revents)
4846
4914
  #endif
4847
4915
 
4848
4916
  void
4849
- ev_embed_start (EV_P_ ev_embed *w) EV_THROW
4917
+ ev_embed_start (EV_P_ ev_embed *w) EV_NOEXCEPT
4850
4918
  {
4851
4919
  if (expect_false (ev_is_active (w)))
4852
4920
  return;
@@ -4877,7 +4945,7 @@ ev_embed_start (EV_P_ ev_embed *w) EV_THROW
4877
4945
  }
4878
4946
 
4879
4947
  void
4880
- ev_embed_stop (EV_P_ ev_embed *w) EV_THROW
4948
+ ev_embed_stop (EV_P_ ev_embed *w) EV_NOEXCEPT
4881
4949
  {
4882
4950
  clear_pending (EV_A_ (W)w);
4883
4951
  if (expect_false (!ev_is_active (w)))
@@ -4897,7 +4965,7 @@ ev_embed_stop (EV_P_ ev_embed *w) EV_THROW
4897
4965
 
4898
4966
  #if EV_FORK_ENABLE
4899
4967
  void
4900
- ev_fork_start (EV_P_ ev_fork *w) EV_THROW
4968
+ ev_fork_start (EV_P_ ev_fork *w) EV_NOEXCEPT
4901
4969
  {
4902
4970
  if (expect_false (ev_is_active (w)))
4903
4971
  return;
@@ -4905,14 +4973,14 @@ ev_fork_start (EV_P_ ev_fork *w) EV_THROW
4905
4973
  EV_FREQUENT_CHECK;
4906
4974
 
4907
4975
  ev_start (EV_A_ (W)w, ++forkcnt);
4908
- array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2);
4976
+ array_needsize (ev_fork *, forks, forkmax, forkcnt, array_needsize_noinit);
4909
4977
  forks [forkcnt - 1] = w;
4910
4978
 
4911
4979
  EV_FREQUENT_CHECK;
4912
4980
  }
4913
4981
 
4914
4982
  void
4915
- ev_fork_stop (EV_P_ ev_fork *w) EV_THROW
4983
+ ev_fork_stop (EV_P_ ev_fork *w) EV_NOEXCEPT
4916
4984
  {
4917
4985
  clear_pending (EV_A_ (W)w);
4918
4986
  if (expect_false (!ev_is_active (w)))
@@ -4935,7 +5003,7 @@ ev_fork_stop (EV_P_ ev_fork *w) EV_THROW
4935
5003
 
4936
5004
  #if EV_CLEANUP_ENABLE
4937
5005
  void
4938
- ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW
5006
+ ev_cleanup_start (EV_P_ ev_cleanup *w) EV_NOEXCEPT
4939
5007
  {
4940
5008
  if (expect_false (ev_is_active (w)))
4941
5009
  return;
@@ -4943,7 +5011,7 @@ ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW
4943
5011
  EV_FREQUENT_CHECK;
4944
5012
 
4945
5013
  ev_start (EV_A_ (W)w, ++cleanupcnt);
4946
- array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, EMPTY2);
5014
+ array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, array_needsize_noinit);
4947
5015
  cleanups [cleanupcnt - 1] = w;
4948
5016
 
4949
5017
  /* cleanup watchers should never keep a refcount on the loop */
@@ -4952,7 +5020,7 @@ ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW
4952
5020
  }
4953
5021
 
4954
5022
  void
4955
- ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW
5023
+ ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_NOEXCEPT
4956
5024
  {
4957
5025
  clear_pending (EV_A_ (W)w);
4958
5026
  if (expect_false (!ev_is_active (w)))
@@ -4976,7 +5044,7 @@ ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW
4976
5044
 
4977
5045
  #if EV_ASYNC_ENABLE
4978
5046
  void
4979
- ev_async_start (EV_P_ ev_async *w) EV_THROW
5047
+ ev_async_start (EV_P_ ev_async *w) EV_NOEXCEPT
4980
5048
  {
4981
5049
  if (expect_false (ev_is_active (w)))
4982
5050
  return;
@@ -4988,14 +5056,14 @@ ev_async_start (EV_P_ ev_async *w) EV_THROW
4988
5056
  EV_FREQUENT_CHECK;
4989
5057
 
4990
5058
  ev_start (EV_A_ (W)w, ++asynccnt);
4991
- array_needsize (ev_async *, asyncs, asyncmax, asynccnt, EMPTY2);
5059
+ array_needsize (ev_async *, asyncs, asyncmax, asynccnt, array_needsize_noinit);
4992
5060
  asyncs [asynccnt - 1] = w;
4993
5061
 
4994
5062
  EV_FREQUENT_CHECK;
4995
5063
  }
4996
5064
 
4997
5065
  void
4998
- ev_async_stop (EV_P_ ev_async *w) EV_THROW
5066
+ ev_async_stop (EV_P_ ev_async *w) EV_NOEXCEPT
4999
5067
  {
5000
5068
  clear_pending (EV_A_ (W)w);
5001
5069
  if (expect_false (!ev_is_active (w)))
@@ -5016,7 +5084,7 @@ ev_async_stop (EV_P_ ev_async *w) EV_THROW
5016
5084
  }
5017
5085
 
5018
5086
  void
5019
- ev_async_send (EV_P_ ev_async *w) EV_THROW
5087
+ ev_async_send (EV_P_ ev_async *w) EV_NOEXCEPT
5020
5088
  {
5021
5089
  w->sent = 1;
5022
5090
  evpipe_write (EV_A_ &async_pending);
@@ -5063,16 +5131,10 @@ once_cb_to (EV_P_ ev_timer *w, int revents)
5063
5131
  }
5064
5132
 
5065
5133
  void
5066
- ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW
5134
+ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_NOEXCEPT
5067
5135
  {
5068
5136
  struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once));
5069
5137
 
5070
- if (expect_false (!once))
5071
- {
5072
- cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMER, arg);
5073
- return;
5074
- }
5075
-
5076
5138
  once->cb = cb;
5077
5139
  once->arg = arg;
5078
5140
 
@@ -5096,7 +5158,7 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo
5096
5158
  #if EV_WALK_ENABLE
5097
5159
  ecb_cold
5098
5160
  void
5099
- ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW
5161
+ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_NOEXCEPT
5100
5162
  {
5101
5163
  int i, j;
5102
5164
  ev_watcher_list *wl, *wn;