nio4r 2.4.0-java → 2.5.4-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71d4fee6ac5ffa50d4eb9ee66347d85f35a9d3a172c8ab42992b982178b4798a
4
- data.tar.gz: 783fb9c6221945577e3e6589f849ff34661e01920a20eef6e5bc635d98864952
3
+ metadata.gz: 0dd2943f91c8881b70cfeb24520d024f2e0d84347f28a7a7ef8df18fc2ecaeef
4
+ data.tar.gz: 3f22f3fecf31e13b826635ff30474c9142d256d8c7193b597cc8099a15b444d4
5
5
  SHA512:
6
- metadata.gz: 050eaac512ad36b6bd32bbfb4caea4ae5edcb2690403edf13533dd7066339dc883a754daa12be822a0f6f6d6fe5340d57ef67a4e2c2d8eb8f23c13a504130605
7
- data.tar.gz: 6ae842bc8b41d38ee3b030b45e22a943b4fe4dd33173e79db5454a4ffa9ed038a95164b5400c3c17bb6b8395af8f0bfb2937ff1b330e9c3976d688ec0b7cc466
6
+ metadata.gz: '0745847595697587834d9af1be90e3b30c620fffba51612329a3b2a26901d7375621734ca7b8380c9c06865a35677dc0a8fee23bb6a7e0606264e79771abf30c'
7
+ data.tar.gz: a2829dc0ae245a9b6dd45c9aec5017ce1f0307b7ad46a4723b391fe7c07de1a3037046c39645affd877612b8b197caaa75fe80cf09a9f629542759a99a79e21f
@@ -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
@@ -1,23 +1,40 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.3
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
+
5
14
  Layout/SpaceInsideBlockBraces:
6
15
  Enabled: false
7
16
 
8
17
  Style/IfUnlessModifier:
9
18
  Enabled: false
10
19
 
20
+ Style/UnpackFirst:
21
+ Enabled: false
22
+
11
23
  #
12
24
  # Lint
13
25
  #
14
26
 
15
- Lint/HandleExceptions:
27
+ Lint/SuppressedException:
16
28
  Enabled: false
17
29
 
18
30
  Lint/Loop:
19
31
  Enabled: false
20
32
 
33
+ Lint/RaiseException:
34
+ Enabled: false
35
+
36
+ Lint/StructNewOverride:
37
+ Enabled: false
21
38
  #
22
39
  # Metrics
23
40
  #
@@ -32,9 +49,6 @@ Metrics/BlockLength:
32
49
  Metrics/ClassLength:
33
50
  Max: 128
34
51
 
35
- Metrics/LineLength:
36
- Max: 128
37
-
38
52
  Metrics/MethodLength:
39
53
  CountComments: false
40
54
  Max: 50
@@ -46,16 +60,12 @@ Metrics/PerceivedComplexity:
46
60
  Max: 15
47
61
 
48
62
  #
49
- # Performance
63
+ # Style
50
64
  #
51
65
 
52
- Performance/RegexpMatch:
66
+ Style/ExponentialNotation:
53
67
  Enabled: false
54
68
 
55
- #
56
- # Style
57
- #
58
-
59
69
  Style/FormatStringToken:
60
70
  Enabled: false
61
71
 
@@ -65,6 +75,15 @@ Style/FrozenStringLiteralComment:
65
75
  Style/GlobalVars:
66
76
  Enabled: false
67
77
 
78
+ Style/HashEachMethods:
79
+ Enabled: false
80
+
81
+ Style/HashTransformKeys:
82
+ Enabled: false
83
+
84
+ Style/HashTransformValues:
85
+ Enabled: false
86
+
68
87
  Style/NumericPredicate:
69
88
  Enabled: false
70
89
 
data/CHANGES.md CHANGED
@@ -1,3 +1,46 @@
1
+ ## 2.5.4 (2020-09-16)
2
+
3
+ * [#251](https://github.com/socketry/nio4r/issues/251)
4
+ Intermittent SEGV during GC.
5
+ ([@boazsegev])
6
+
7
+ ## 2.5.3 (2020-09-07)
8
+
9
+ * [#241](https://github.com/socketry/nio4r/issues/241)
10
+ Possible bug with Ruby >= 2.7.0 and `GC.compact`.
11
+ ([@boazsegev])
12
+
13
+ ## 2.5.2 (2019-09-24)
14
+
15
+ * [#220](https://github.com/socketry/nio4r/issues/220)
16
+ Update to libev-4.27 & fix assorted warnings.
17
+ ([@ioquatix])
18
+
19
+ * [#225](https://github.com/socketry/nio4r/issues/225)
20
+ Avoid need for linux headers.
21
+ ([@ioquatix])
22
+
23
+ ## 2.4.0 (2019-07-07)
24
+
25
+ * [#211](https://github.com/socketry/nio4r/pull/211)
26
+ Enable KQUEUE on macOS 10.14+.
27
+ ([@ioquatix])
28
+
29
+ * Bump minimum supported Ruby to 2.3.
30
+ ([@ioquatix])
31
+
32
+ * Assorted fixes for TruffleRuby & JRuby.
33
+ ([@eregon], [@olleolleolle])
34
+ Possible bug with Ruby >= 2.7.0 and `GC.compact`
35
+ * Update libev to v4.25.
36
+ ([@ioquatix])
37
+
38
+ * Bind to ephemeral (port 0) for more reliable specs.
39
+ ([@ioquatix])
40
+
41
+ * Improve handling of SSL sockets and related specs.
42
+ ([@MSP-Greg])
43
+
1
44
  ## 2.3.1 (2018-05-03)
2
45
 
3
46
  * [#188](https://github.com/socketry/nio4r/pull/188)
@@ -219,3 +262,6 @@
219
262
  [@HoneyryderChuck]: https://github.com/HoneyryderChuck
220
263
  [@tompng]: https://github.com/tompng
221
264
  [@ioquatix]: https://github.com/ioquatix
265
+ [@eregon]: https://github.com/eregon
266
+ [@olleolleolle]: https://github.com/olleolleolle
267
+ [@boazsegev]: https://github.com/boazsegev
data/Gemfile CHANGED
@@ -15,5 +15,5 @@ group :development, :test do
15
15
  gem "coveralls", require: false
16
16
  gem "rake-compiler", require: false
17
17
  gem "rspec", "~> 3.7", require: false
18
- gem "rubocop", "0.52.1", require: false
18
+ gem "rubocop", "0.82.0", require: false
19
19
  end
data/README.md CHANGED
@@ -1,17 +1,10 @@
1
1
  # ![nio4r](https://raw.github.com/socketry/nio4r/master/logo.png)
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/nio4r.svg)](http://rubygems.org/gems/nio4r)
4
- [![Travis CI Status](https://secure.travis-ci.org/socketry/nio4r.svg?branch=master)](http://travis-ci.org/socketry/nio4r)
5
- [![Appveyor Status](https://ci.appveyor.com/api/projects/status/1ru8x81v91vaewax/branch/master?svg=true)](https://ci.appveyor.com/project/tarcieri/nio4r/branch/master)
4
+ [![Build Status](https://github.com/socketry/nio4r/workflows/nio4r/badge.svg?branch=master&event=push)](https://github.com/socketry/nio4r/actions?query=workflow:nio4r)
6
5
  [![Code Climate](https://codeclimate.com/github/socketry/nio4r.svg)](https://codeclimate.com/github/socketry/nio4r)
7
6
  [![Coverage Status](https://coveralls.io/repos/socketry/nio4r/badge.svg?branch=master)](https://coveralls.io/r/socketry/nio4r)
8
7
  [![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/gems/nio4r/2.2.0)
9
- [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/socketry/nio4r/blob/master/LICENSE.txt)
10
-
11
- _NOTE: This is the 2.x **stable** branch of nio4r. For the 1.x **legacy** branch,
12
- please see:_
13
-
14
- https://github.com/socketry/nio4r/tree/1-x-stable
15
8
 
16
9
  **New I/O for Ruby (nio4r)**: cross-platform asynchronous I/O primitives for
17
10
  scalable network clients and servers. Modeled after the Java NIO API, but
@@ -25,12 +18,14 @@ writing.
25
18
  ## Projects using nio4r
26
19
 
27
20
  * [ActionCable]: Rails 5 WebSocket protocol, uses nio4r for a WebSocket server
28
- * [Celluloid::IO]: Actor-based concurrency framework, uses nio4r for async I/O
29
- * [Socketry Async]: Asynchronous I/O framework for Ruby
21
+ * [Celluloid]: Actor-based concurrency framework, uses nio4r for async I/O
22
+ * [Async]: Asynchronous I/O framework for Ruby
23
+ * [Puma]: Ruby/Rack web server built for concurrency
30
24
 
31
25
  [ActionCable]: https://rubygems.org/gems/actioncable
32
- [Celluloid::IO]: https://github.com/celluloid/celluloid-io
33
- [Socketry Async]: https://github.com/socketry/async
26
+ [Celluloid]: https://github.com/celluloid/celluloid-io
27
+ [Async]: https://github.com/socketry/async
28
+ [Puma]: https://github.com/puma/puma
34
29
 
35
30
  ## Goals
36
31
 
@@ -41,11 +36,12 @@ writing.
41
36
 
42
37
  ## Supported platforms
43
38
 
44
- * Ruby 2.3
45
39
  * Ruby 2.4
46
40
  * Ruby 2.5
47
41
  * Ruby 2.6
48
- * JRuby 9000
42
+ * Ruby 2.7
43
+ * [JRuby](https://github.com/jruby/jruby)
44
+ * [TruffleRuby](https://github.com/oracle/truffleruby)
49
45
 
50
46
  ## Supported backends
51
47
 
@@ -53,17 +49,6 @@ writing.
53
49
  * **Java NIO**: JRuby extension which wraps the Java NIO subsystem
54
50
  * **Pure Ruby**: `Kernel.select`-based backend that should work on any Ruby interpreter
55
51
 
56
- ## Discussion
57
-
58
- For discussion and general help with nio4r, email
59
- [socketry+subscribe@googlegroups.com][subscribe]
60
- or join on the web via the [Google Group].
61
-
62
- We're also on IRC at ##socketry on irc.freenode.net.
63
-
64
- [subscribe]: mailto:socketry+subscribe@googlegroups.com
65
- [google group]: https://groups.google.com/group/socketry
66
-
67
52
  ## Documentation
68
53
 
69
54
  [Please see the nio4r wiki](https://github.com/socketry/nio4r/wiki)
@@ -94,13 +79,54 @@ to maintain a large codebase.
94
79
  [EventMachine]: https://github.com/eventmachine/eventmachine
95
80
  [Cool.io]: https://coolio.github.io/
96
81
 
82
+ ## Releases
83
+
84
+ ### CRuby
85
+
86
+ ```
87
+ rake clean
88
+ rake release
89
+ ```
90
+
91
+ ### JRuby
92
+
93
+ You might need to delete `Gemfile.lock` before trying to `bundle install`.
94
+
95
+ ```
96
+ rake clean
97
+ rake compile
98
+ rake release
99
+ ```
100
+
97
101
  ## License
98
102
 
99
- Copyright (c) 2011-2018 Tony Arcieri. Distributed under the MIT License.
100
- See [LICENSE.txt] for further details.
103
+ Released under the MIT license.
104
+
105
+ Copyright, 2019, by Tony Arcieri.
106
+ Copyright, 2019, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
107
+
108
+ Permission is hereby granted, free of charge, to any person obtaining a copy
109
+ of this software and associated documentation files (the "Software"), to deal
110
+ in the Software without restriction, including without limitation the rights
111
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
112
+ copies of the Software, and to permit persons to whom the Software is
113
+ furnished to do so, subject to the following conditions:
114
+
115
+ The above copyright notice and this permission notice shall be included in
116
+ all copies or substantial portions of the Software.
117
+
118
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
119
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
120
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
121
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
122
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
123
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
124
+ THE SOFTWARE.
125
+
126
+ ### libev
127
+
128
+ Released under the BSD license. See [ext/libev/LICENSE] for details.
101
129
 
102
- Includes libev 4.24. Copyright (c) 2007-2016 Marc Alexander Lehmann.
103
- Distributed under the BSD license. See [ext/libev/LICENSE] for details.
130
+ Copyright, 2007-2019, by Marc Alexander Lehmann.
104
131
 
105
- [LICENSE.txt]: https://github.com/socketry/nio4r/blob/master/LICENSE.txt
106
132
  [ext/libev/LICENSE]: https://github.com/socketry/nio4r/blob/master/ext/libev/LICENSE
@@ -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,8 +1,27 @@
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
+
3
22
  4.25 Fri Dec 21 07:49:20 CET 2018
4
23
  - INCOMPATIBLE CHANGE: EV_THROW was renamed to EV_NOEXCEPT
5
- (EV_THROW sitll provided) and now uses noexcept on C++11 or newer.
24
+ (EV_THROW still provided) and now uses noexcept on C++11 or newer.
6
25
  - move the darwin select workaround highe rin ev.c, as newer versions of
7
26
  darwin managed to break their broken select even more.
8
27
  - ANDROID => __ANDROID__ (reported by enh@google.com).
@@ -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-2018 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-
@@ -126,6 +126,15 @@
126
126
  # define EV_USE_EPOLL 0
127
127
  # endif
128
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
+
129
138
  # if HAVE_KQUEUE && HAVE_SYS_EVENT_H
130
139
  # ifndef EV_USE_KQUEUE
131
140
  # define EV_USE_KQUEUE EV_FEATURE_BACKENDS
@@ -430,6 +439,14 @@
430
439
  # endif
431
440
  #endif
432
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
+
433
450
  #if EV_USE_INOTIFY
434
451
  # include <sys/statfs.h>
435
452
  # include <sys/inotify.h>
@@ -545,7 +562,7 @@ struct signalfd_siginfo
545
562
  #define ECB_H
546
563
 
547
564
  /* 16 bits major, 16 bits minor */
548
- #define ECB_VERSION 0x00010005
565
+ #define ECB_VERSION 0x00010006
549
566
 
550
567
  #ifdef _WIN32
551
568
  typedef signed char int8_t;
@@ -669,6 +686,7 @@ struct signalfd_siginfo
669
686
 
670
687
  #ifndef ECB_MEMORY_FENCE
671
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")
672
690
  #if __i386 || __i386__
673
691
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
674
692
  #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
@@ -728,12 +746,14 @@ struct signalfd_siginfo
728
746
  #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
729
747
  #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE)
730
748
  #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE)
749
+ #define ECB_MEMORY_FENCE_RELAXED __atomic_thread_fence (__ATOMIC_RELAXED)
731
750
 
732
751
  #elif ECB_CLANG_EXTENSION(c_atomic)
733
752
  /* see comment below (stdatomic.h) about the C11 memory model. */
734
753
  #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
735
754
  #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE)
736
755
  #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE)
756
+ #define ECB_MEMORY_FENCE_RELAXED __c11_atomic_thread_fence (__ATOMIC_RELAXED)
737
757
 
738
758
  #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
739
759
  #define ECB_MEMORY_FENCE __sync_synchronize ()
@@ -753,9 +773,10 @@ struct signalfd_siginfo
753
773
  #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
754
774
  #elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
755
775
  #include <mbarrier.h>
756
- #define ECB_MEMORY_FENCE __machine_rw_barrier ()
757
- #define ECB_MEMORY_FENCE_ACQUIRE __machine_r_barrier ()
758
- #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 ()
759
780
  #elif __xlC__
760
781
  #define ECB_MEMORY_FENCE __sync ()
761
782
  #endif
@@ -766,15 +787,9 @@ struct signalfd_siginfo
766
787
  /* we assume that these memory fences work on all variables/all memory accesses, */
767
788
  /* not just C11 atomics and atomic accesses */
768
789
  #include <stdatomic.h>
769
- /* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */
770
- /* any fence other than seq_cst, which isn't very efficient for us. */
771
- /* Why that is, we don't know - either the C11 memory model is quite useless */
772
- /* for most usages, or gcc and clang have a bug */
773
- /* I *currently* lean towards the latter, and inefficiently implement */
774
- /* all three of ecb's fences as a seq_cst fence */
775
- /* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */
776
- /* for all __atomic_thread_fence's except seq_cst */
777
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)
778
793
  #endif
779
794
  #endif
780
795
 
@@ -804,6 +819,10 @@ struct signalfd_siginfo
804
819
  #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
805
820
  #endif
806
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
+
807
826
  /*****************************************************************************/
808
827
 
809
828
  #if ECB_CPP
@@ -1554,8 +1573,7 @@ ecb_binary32_to_binary16 (uint32_t x)
1554
1573
  # define ABSPRI(w) (((W)w)->priority - EV_MINPRI)
1555
1574
  #endif
1556
1575
 
1557
- #define EMPTY /* required for microsofts broken pseudo-c compiler */
1558
- #define EMPTY2(a,b) /* used to suppress some warnings */
1576
+ #define EMPTY /* required for microsofts broken pseudo-c compiler */
1559
1577
 
1560
1578
  typedef ev_watcher *W;
1561
1579
  typedef ev_watcher_list *WL;
@@ -1590,6 +1608,10 @@ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work?
1590
1608
 
1591
1609
  /*****************************************************************************/
1592
1610
 
1611
+ #if EV_USE_LINUXAIO
1612
+ # include <linux/aio_abi.h> /* probably only needed for aio_context_t */
1613
+ #endif
1614
+
1593
1615
  /* define a suitable floor function (only used by periodics atm) */
1594
1616
 
1595
1617
  #if EV_USE_FLOOR
@@ -1724,7 +1746,7 @@ ev_syserr (const char *msg)
1724
1746
  }
1725
1747
 
1726
1748
  static void *
1727
- ev_realloc_emul (void *ptr, long size) EV_NOEXCEPT
1749
+ ev_realloc_emul (void *ptr, size_t size) EV_NOEXCEPT
1728
1750
  {
1729
1751
  /* some systems, notably openbsd and darwin, fail to properly
1730
1752
  * implement realloc (x, 0) (as required by both ansi c-89 and
@@ -1740,17 +1762,17 @@ ev_realloc_emul (void *ptr, long size) EV_NOEXCEPT
1740
1762
  return 0;
1741
1763
  }
1742
1764
 
1743
- static void *(*alloc)(void *ptr, long size) EV_NOEXCEPT = ev_realloc_emul;
1765
+ static void *(*alloc)(void *ptr, size_t size) EV_NOEXCEPT = ev_realloc_emul;
1744
1766
 
1745
1767
  ecb_cold
1746
1768
  void
1747
- ev_set_allocator (void *(*cb)(void *ptr, long size) EV_NOEXCEPT) EV_NOEXCEPT
1769
+ ev_set_allocator (void *(*cb)(void *ptr, size_t size) EV_NOEXCEPT) EV_NOEXCEPT
1748
1770
  {
1749
1771
  alloc = cb;
1750
1772
  }
1751
1773
 
1752
1774
  inline_speed void *
1753
- ev_realloc (void *ptr, long size)
1775
+ ev_realloc (void *ptr, size_t size)
1754
1776
  {
1755
1777
  ptr = alloc (ptr, size);
1756
1778
 
@@ -1781,7 +1803,7 @@ typedef struct
1781
1803
  WL head;
1782
1804
  unsigned char events; /* the events watched for */
1783
1805
  unsigned char reify; /* flag set when this ANFD needs reification (EV_ANFD_REIFY, EV__IOFDSET) */
1784
- 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 */
1785
1807
  unsigned char unused;
1786
1808
  #if EV_USE_EPOLL
1787
1809
  unsigned int egen; /* generation counter to counter epoll bugs */
@@ -1972,8 +1994,10 @@ array_realloc (int elem, void *base, int *cur, int cnt)
1972
1994
  return ev_realloc (base, elem * *cur);
1973
1995
  }
1974
1996
 
1975
- #define array_init_zero(base,count) \
1976
- 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))
1977
2001
 
1978
2002
  #define array_needsize(type,base,cur,cnt,init) \
1979
2003
  if (expect_false ((cnt) > (cur))) \
@@ -1981,7 +2005,7 @@ array_realloc (int elem, void *base, int *cur, int cnt)
1981
2005
  ecb_unused int ocur_ = (cur); \
1982
2006
  (base) = (type *)array_realloc \
1983
2007
  (sizeof (type), (base), &(cur), (cnt)); \
1984
- init ((base) + (ocur_), (cur) - ocur_); \
2008
+ init ((base), ocur_, ((cur) - ocur_)); \
1985
2009
  }
1986
2010
 
1987
2011
  #if 0
@@ -2018,7 +2042,7 @@ ev_feed_event (EV_P_ void *w, int revents) EV_NOEXCEPT
2018
2042
  else
2019
2043
  {
2020
2044
  w_->pending = ++pendingcnt [pri];
2021
- array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, EMPTY2);
2045
+ array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, array_needsize_noinit);
2022
2046
  pendings [pri][w_->pending - 1].w = w_;
2023
2047
  pendings [pri][w_->pending - 1].events = revents;
2024
2048
  }
@@ -2029,7 +2053,7 @@ ev_feed_event (EV_P_ void *w, int revents) EV_NOEXCEPT
2029
2053
  inline_speed void
2030
2054
  feed_reverse (EV_P_ W w)
2031
2055
  {
2032
- array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, EMPTY2);
2056
+ array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, array_needsize_noinit);
2033
2057
  rfeeds [rfeedcnt++] = w;
2034
2058
  }
2035
2059
 
@@ -2126,7 +2150,7 @@ fd_reify (EV_P)
2126
2150
  unsigned char o_events = anfd->events;
2127
2151
  unsigned char o_reify = anfd->reify;
2128
2152
 
2129
- anfd->reify = 0;
2153
+ anfd->reify = 0;
2130
2154
 
2131
2155
  /*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */
2132
2156
  {
@@ -2157,7 +2181,7 @@ fd_change (EV_P_ int fd, int flags)
2157
2181
  if (expect_true (!reify))
2158
2182
  {
2159
2183
  ++fdchangecnt;
2160
- array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2);
2184
+ array_needsize (int, fdchanges, fdchangemax, fdchangecnt, array_needsize_noinit);
2161
2185
  fdchanges [fdchangecnt - 1] = fd;
2162
2186
  }
2163
2187
  }
@@ -2717,6 +2741,9 @@ childcb (EV_P_ ev_signal *sw, int revents)
2717
2741
  #if EV_USE_EPOLL
2718
2742
  # include "ev_epoll.c"
2719
2743
  #endif
2744
+ #if EV_USE_LINUXAIO
2745
+ # include "ev_linuxaio.c"
2746
+ #endif
2720
2747
  #if EV_USE_POLL
2721
2748
  # include "ev_poll.c"
2722
2749
  #endif
@@ -2754,11 +2781,16 @@ ev_supported_backends (void) EV_NOEXCEPT
2754
2781
  {
2755
2782
  unsigned int flags = 0;
2756
2783
 
2757
- if (EV_USE_PORT ) flags |= EVBACKEND_PORT;
2758
- if (EV_USE_KQUEUE) flags |= EVBACKEND_KQUEUE;
2759
- if (EV_USE_EPOLL ) flags |= EVBACKEND_EPOLL;
2760
- if (EV_USE_POLL ) flags |= EVBACKEND_POLL;
2761
- 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;
2762
2794
 
2763
2795
  return flags;
2764
2796
  }
@@ -2784,6 +2816,11 @@ ev_recommended_backends (void) EV_NOEXCEPT
2784
2816
  flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */
2785
2817
  #endif
2786
2818
 
2819
+ /* TODO: linuxaio is very experimental */
2820
+ #if !EV_RECOMMEND_LINUXAIO
2821
+ flags &= ~EVBACKEND_LINUXAIO;
2822
+ #endif
2823
+
2787
2824
  return flags;
2788
2825
  }
2789
2826
 
@@ -2928,22 +2965,25 @@ loop_init (EV_P_ unsigned int flags) EV_NOEXCEPT
2928
2965
  flags |= ev_recommended_backends ();
2929
2966
 
2930
2967
  #if EV_USE_IOCP
2931
- if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
2968
+ if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
2932
2969
  #endif
2933
2970
  #if EV_USE_PORT
2934
- if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
2971
+ if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
2935
2972
  #endif
2936
2973
  #if EV_USE_KQUEUE
2937
- 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);
2938
2978
  #endif
2939
2979
  #if EV_USE_EPOLL
2940
- if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags);
2980
+ if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags);
2941
2981
  #endif
2942
2982
  #if EV_USE_POLL
2943
- if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags);
2983
+ if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags);
2944
2984
  #endif
2945
2985
  #if EV_USE_SELECT
2946
- if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
2986
+ if (!backend && (flags & EVBACKEND_SELECT )) backend = select_init (EV_A_ flags);
2947
2987
  #endif
2948
2988
 
2949
2989
  ev_prepare_init (&pending_w, pendingcb);
@@ -3008,22 +3048,25 @@ ev_loop_destroy (EV_P)
3008
3048
  close (backend_fd);
3009
3049
 
3010
3050
  #if EV_USE_IOCP
3011
- if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
3051
+ if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
3012
3052
  #endif
3013
3053
  #if EV_USE_PORT
3014
- if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
3054
+ if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
3015
3055
  #endif
3016
3056
  #if EV_USE_KQUEUE
3017
- 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);
3018
3061
  #endif
3019
3062
  #if EV_USE_EPOLL
3020
- if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A);
3063
+ if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A);
3021
3064
  #endif
3022
3065
  #if EV_USE_POLL
3023
- if (backend == EVBACKEND_POLL ) poll_destroy (EV_A);
3066
+ if (backend == EVBACKEND_POLL ) poll_destroy (EV_A);
3024
3067
  #endif
3025
3068
  #if EV_USE_SELECT
3026
- if (backend == EVBACKEND_SELECT) select_destroy (EV_A);
3069
+ if (backend == EVBACKEND_SELECT ) select_destroy (EV_A);
3027
3070
  #endif
3028
3071
 
3029
3072
  for (i = NUMPRI; i--; )
@@ -3075,13 +3118,16 @@ inline_size void
3075
3118
  loop_fork (EV_P)
3076
3119
  {
3077
3120
  #if EV_USE_PORT
3078
- if (backend == EVBACKEND_PORT ) port_fork (EV_A);
3121
+ if (backend == EVBACKEND_PORT ) port_fork (EV_A);
3079
3122
  #endif
3080
3123
  #if EV_USE_KQUEUE
3081
- 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);
3082
3128
  #endif
3083
3129
  #if EV_USE_EPOLL
3084
- if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A);
3130
+ if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A);
3085
3131
  #endif
3086
3132
  #if EV_USE_INOTIFY
3087
3133
  infy_fork (EV_A);
@@ -3586,11 +3632,13 @@ struct ev_poll_args {
3586
3632
  };
3587
3633
 
3588
3634
  static
3589
- VALUE ev_backend_poll(void *ptr)
3635
+ void * ev_backend_poll(void *ptr)
3590
3636
  {
3591
3637
  struct ev_poll_args *args = (struct ev_poll_args *)ptr;
3592
3638
  struct ev_loop *loop = args->loop;
3593
3639
  backend_poll (EV_A_ args->waittime);
3640
+
3641
+ return NULL;
3594
3642
  }
3595
3643
  /* ######################################## */
3596
3644
 
@@ -3598,7 +3646,7 @@ int
3598
3646
  ev_run (EV_P_ int flags)
3599
3647
  {
3600
3648
  /* ########## NIO4R PATCHERY HO! ########## */
3601
- struct ev_poll_args poll_args;
3649
+ struct ev_poll_args poll_args;
3602
3650
  /* ######################################## */
3603
3651
 
3604
3652
  #if EV_FEATURE_API
@@ -3951,10 +3999,13 @@ ev_io_start (EV_P_ ev_io *w) EV_NOEXCEPT
3951
3999
  assert (("libev: ev_io_start called with negative fd", fd >= 0));
3952
4000
  assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE))));
3953
4001
 
4002
+ #if EV_VERIFY >= 2
4003
+ assert (("libev: ev_io_start called on watcher with invalid fd", fd_valid (fd)));
4004
+ #endif
3954
4005
  EV_FREQUENT_CHECK;
3955
4006
 
3956
4007
  ev_start (EV_A_ (W)w, 1);
3957
- array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero);
4008
+ array_needsize (ANFD, anfds, anfdmax, fd + 1, array_needsize_zerofill);
3958
4009
  wlist_add (&anfds[fd].head, (WL)w);
3959
4010
 
3960
4011
  /* common bug, apparently */
@@ -3976,6 +4027,9 @@ ev_io_stop (EV_P_ ev_io *w) EV_NOEXCEPT
3976
4027
 
3977
4028
  assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
3978
4029
 
4030
+ #if EV_VERIFY >= 2
4031
+ assert (("libev: ev_io_stop called on watcher with invalid fd", fd_valid (w->fd)));
4032
+ #endif
3979
4033
  EV_FREQUENT_CHECK;
3980
4034
 
3981
4035
  wlist_del (&anfds[w->fd].head, (WL)w);
@@ -4001,7 +4055,7 @@ ev_timer_start (EV_P_ ev_timer *w) EV_NOEXCEPT
4001
4055
 
4002
4056
  ++timercnt;
4003
4057
  ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1);
4004
- array_needsize (ANHE, timers, timermax, ev_active (w) + 1, EMPTY2);
4058
+ array_needsize (ANHE, timers, timermax, ev_active (w) + 1, array_needsize_noinit);
4005
4059
  ANHE_w (timers [ev_active (w)]) = (WT)w;
4006
4060
  ANHE_at_cache (timers [ev_active (w)]);
4007
4061
  upheap (timers, ev_active (w));
@@ -4098,7 +4152,7 @@ ev_periodic_start (EV_P_ ev_periodic *w) EV_NOEXCEPT
4098
4152
 
4099
4153
  ++periodiccnt;
4100
4154
  ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1);
4101
- array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2);
4155
+ array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, array_needsize_noinit);
4102
4156
  ANHE_w (periodics [ev_active (w)]) = (WT)w;
4103
4157
  ANHE_at_cache (periodics [ev_active (w)]);
4104
4158
  upheap (periodics, ev_active (w));
@@ -4693,7 +4747,7 @@ ev_idle_start (EV_P_ ev_idle *w) EV_NOEXCEPT
4693
4747
  ++idleall;
4694
4748
  ev_start (EV_A_ (W)w, active);
4695
4749
 
4696
- 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);
4697
4751
  idles [ABSPRI (w)][active - 1] = w;
4698
4752
  }
4699
4753
 
@@ -4733,7 +4787,7 @@ ev_prepare_start (EV_P_ ev_prepare *w) EV_NOEXCEPT
4733
4787
  EV_FREQUENT_CHECK;
4734
4788
 
4735
4789
  ev_start (EV_A_ (W)w, ++preparecnt);
4736
- array_needsize (ev_prepare *, prepares, preparemax, preparecnt, EMPTY2);
4790
+ array_needsize (ev_prepare *, prepares, preparemax, preparecnt, array_needsize_noinit);
4737
4791
  prepares [preparecnt - 1] = w;
4738
4792
 
4739
4793
  EV_FREQUENT_CHECK;
@@ -4771,7 +4825,7 @@ ev_check_start (EV_P_ ev_check *w) EV_NOEXCEPT
4771
4825
  EV_FREQUENT_CHECK;
4772
4826
 
4773
4827
  ev_start (EV_A_ (W)w, ++checkcnt);
4774
- array_needsize (ev_check *, checks, checkmax, checkcnt, EMPTY2);
4828
+ array_needsize (ev_check *, checks, checkmax, checkcnt, array_needsize_noinit);
4775
4829
  checks [checkcnt - 1] = w;
4776
4830
 
4777
4831
  EV_FREQUENT_CHECK;
@@ -4919,7 +4973,7 @@ ev_fork_start (EV_P_ ev_fork *w) EV_NOEXCEPT
4919
4973
  EV_FREQUENT_CHECK;
4920
4974
 
4921
4975
  ev_start (EV_A_ (W)w, ++forkcnt);
4922
- array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2);
4976
+ array_needsize (ev_fork *, forks, forkmax, forkcnt, array_needsize_noinit);
4923
4977
  forks [forkcnt - 1] = w;
4924
4978
 
4925
4979
  EV_FREQUENT_CHECK;
@@ -4957,7 +5011,7 @@ ev_cleanup_start (EV_P_ ev_cleanup *w) EV_NOEXCEPT
4957
5011
  EV_FREQUENT_CHECK;
4958
5012
 
4959
5013
  ev_start (EV_A_ (W)w, ++cleanupcnt);
4960
- array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, EMPTY2);
5014
+ array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, array_needsize_noinit);
4961
5015
  cleanups [cleanupcnt - 1] = w;
4962
5016
 
4963
5017
  /* cleanup watchers should never keep a refcount on the loop */
@@ -5002,7 +5056,7 @@ ev_async_start (EV_P_ ev_async *w) EV_NOEXCEPT
5002
5056
  EV_FREQUENT_CHECK;
5003
5057
 
5004
5058
  ev_start (EV_A_ (W)w, ++asynccnt);
5005
- array_needsize (ev_async *, asyncs, asyncmax, asynccnt, EMPTY2);
5059
+ array_needsize (ev_async *, asyncs, asyncmax, asynccnt, array_needsize_noinit);
5006
5060
  asyncs [asynccnt - 1] = w;
5007
5061
 
5008
5062
  EV_FREQUENT_CHECK;
@@ -5081,12 +5135,6 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo
5081
5135
  {
5082
5136
  struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once));
5083
5137
 
5084
- if (expect_false (!once))
5085
- {
5086
- cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMER, arg);
5087
- return;
5088
- }
5089
-
5090
5138
  once->cb = cb;
5091
5139
  once->arg = arg;
5092
5140