nio4r 2.3.1-java → 2.5.3-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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;