mt-libuv 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.gitmodules +6 -0
- data/.rspec +1 -0
- data/.travis.yml +24 -0
- data/Gemfile +9 -0
- data/LICENSE +24 -0
- data/README.md +195 -0
- data/Rakefile +31 -0
- data/ext/README.md +6 -0
- data/ext/Rakefile +28 -0
- data/lib/mt-libuv/async.rb +51 -0
- data/lib/mt-libuv/check.rb +59 -0
- data/lib/mt-libuv/coroutines.rb +79 -0
- data/lib/mt-libuv/dns.rb +98 -0
- data/lib/mt-libuv/error.rb +88 -0
- data/lib/mt-libuv/ext/ext.rb +322 -0
- data/lib/mt-libuv/ext/platform/darwin_x64.rb +61 -0
- data/lib/mt-libuv/ext/platform/unix.rb +69 -0
- data/lib/mt-libuv/ext/platform/windows.rb +83 -0
- data/lib/mt-libuv/ext/tasks/mac.rb +24 -0
- data/lib/mt-libuv/ext/tasks/unix.rb +42 -0
- data/lib/mt-libuv/ext/tasks/win.rb +29 -0
- data/lib/mt-libuv/ext/tasks.rb +27 -0
- data/lib/mt-libuv/ext/types.rb +253 -0
- data/lib/mt-libuv/fiber_pool.rb +83 -0
- data/lib/mt-libuv/file.rb +309 -0
- data/lib/mt-libuv/filesystem.rb +263 -0
- data/lib/mt-libuv/fs_event.rb +37 -0
- data/lib/mt-libuv/handle.rb +108 -0
- data/lib/mt-libuv/idle.rb +59 -0
- data/lib/mt-libuv/mixins/accessors.rb +41 -0
- data/lib/mt-libuv/mixins/assertions.rb +25 -0
- data/lib/mt-libuv/mixins/fs_checks.rb +96 -0
- data/lib/mt-libuv/mixins/listener.rb +69 -0
- data/lib/mt-libuv/mixins/net.rb +42 -0
- data/lib/mt-libuv/mixins/resource.rb +30 -0
- data/lib/mt-libuv/mixins/stream.rb +276 -0
- data/lib/mt-libuv/pipe.rb +217 -0
- data/lib/mt-libuv/prepare.rb +59 -0
- data/lib/mt-libuv/q.rb +475 -0
- data/lib/mt-libuv/reactor.rb +567 -0
- data/lib/mt-libuv/signal.rb +62 -0
- data/lib/mt-libuv/spawn.rb +113 -0
- data/lib/mt-libuv/tcp.rb +465 -0
- data/lib/mt-libuv/timer.rb +107 -0
- data/lib/mt-libuv/tty.rb +42 -0
- data/lib/mt-libuv/udp.rb +302 -0
- data/lib/mt-libuv/version.rb +5 -0
- data/lib/mt-libuv/work.rb +86 -0
- data/lib/mt-libuv.rb +80 -0
- data/mt-libuv.gemspec +62 -0
- data/spec/async_spec.rb +67 -0
- data/spec/coroutines_spec.rb +121 -0
- data/spec/cpu_spec.rb +10 -0
- data/spec/defer_spec.rb +906 -0
- data/spec/dns_spec.rb +110 -0
- data/spec/dsl_spec.rb +43 -0
- data/spec/filesystem_spec.rb +270 -0
- data/spec/idle_spec.rb +44 -0
- data/spec/pipe_spec.rb +151 -0
- data/spec/spawn_spec.rb +119 -0
- data/spec/tcp_spec.rb +272 -0
- data/spec/test.sh +4 -0
- data/spec/test_fail.sh +3 -0
- data/spec/test_read.sh +3 -0
- data/spec/timer_spec.rb +14 -0
- data/spec/udp_spec.rb +73 -0
- data/spec/zen_spec.rb +34 -0
- metadata +196 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
file 'ext/libuv/build/gyp' => 'ext/libuv/build' do
|
4
|
+
FileUtils.mkdir('ext/libuv/build') unless File.directory?('ext/libuv/build')
|
5
|
+
result = true
|
6
|
+
if not File.directory?('ext/libuv/build/gyp')
|
7
|
+
result = system "ln", "-rs", "ext/gyp", "ext/libuv/build/gyp"
|
8
|
+
end
|
9
|
+
raise 'unable to download gyp' unless result
|
10
|
+
end
|
11
|
+
|
12
|
+
CLEAN.include('ext/libuv/build/gyp')
|
13
|
+
|
14
|
+
file 'ext/libuv/out' => 'ext/libuv/build/gyp' do
|
15
|
+
target_arch = 'ia32'if FFI::Platform.ia32?
|
16
|
+
target_arch = 'x64' if FFI::Platform.x64?
|
17
|
+
target_arch = 'arm64' if FFI::Platform.arm64?
|
18
|
+
|
19
|
+
abort "Don't know how to build on #{FFI::Platform::ARCH} (yet)" unless target_arch
|
20
|
+
|
21
|
+
Dir.chdir("ext/libuv") do |path|
|
22
|
+
system "./gyp_uv.py -f make -Dtarget_arch=#{target_arch} -Duv_library=shared_library -Dcomponent=shared_library"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
file "ext/libuv/out/Release/lib.target/libuv.#{FFI::Platform::LIBSUFFIX}" => 'ext/libuv/out' do
|
27
|
+
Dir.chdir("ext/libuv") do |path|
|
28
|
+
system 'make -C out BUILDTYPE=Release'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
file "ext/libuv/lib/libuv.#{FFI::Platform::LIBSUFFIX}" => "ext/libuv/out/Release/lib.target/libuv.#{FFI::Platform::LIBSUFFIX}" do
|
33
|
+
FileUtils.mkdir('ext/libuv/lib') unless File.directory?('ext/libuv/lib')
|
34
|
+
begin
|
35
|
+
FileUtils.cp("ext/libuv/out/Release/lib.target/libuv.#{FFI::Platform::LIBSUFFIX}", "ext/libuv/lib/libuv.#{FFI::Platform::LIBSUFFIX}")
|
36
|
+
rescue => e
|
37
|
+
FileUtils.cp("ext/libuv/out/Release/lib.target/libuv.#{FFI::Platform::LIBSUFFIX}.1", "ext/libuv/lib/libuv.#{FFI::Platform::LIBSUFFIX}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
CLEAN.include('ext/libuv/out')
|
42
|
+
CLOBBER.include("ext/libuv/out/Release/lib.target/libuv.#{FFI::Platform::LIBSUFFIX}")
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
file 'ext/libuv/build/gyp' => 'ext/libuv/build' do
|
4
|
+
FileUtils.mkdir('ext/libuv/build') unless File.directory?('ext/libuv/build')
|
5
|
+
result = true
|
6
|
+
if not File.directory?('ext/libuv/build/gyp')
|
7
|
+
result = system "ln", "-rs", "ext/gyp", "ext/libuv/build/gyp"
|
8
|
+
end
|
9
|
+
raise 'unable to download gyp' unless result
|
10
|
+
end
|
11
|
+
|
12
|
+
CLEAN.include('ext/libuv/build/gyp')
|
13
|
+
|
14
|
+
file "ext/libuv/Release/libuv.#{FFI::Platform::LIBSUFFIX}" do
|
15
|
+
target_arch = 'ia32'
|
16
|
+
target_arch = 'x64' if FFI::Platform.x64?
|
17
|
+
|
18
|
+
Dir.chdir("ext/libuv") do |path|
|
19
|
+
system 'git', 'clone', 'https://chromium.googlesource.com/external/gyp', 'build/gyp'
|
20
|
+
system 'vcbuild.bat', 'vs2017', 'shared', 'release', target_arch
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
file "ext/libuv/lib/libuv.#{FFI::Platform::LIBSUFFIX}" => "ext/libuv/Release/libuv.#{FFI::Platform::LIBSUFFIX}" do
|
25
|
+
FileUtils.mkdir('ext/libuv/lib') unless File.directory?('ext/libuv/lib')
|
26
|
+
FileUtils.cp("ext/libuv/Release/libuv.#{FFI::Platform::LIBSUFFIX}", "ext/libuv/lib/libuv.#{FFI::Platform::LIBSUFFIX}")
|
27
|
+
end
|
28
|
+
|
29
|
+
CLOBBER.include("ext/libuv/Release/libuv.#{FFI::Platform::LIBSUFFIX}")
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FFI::Platform
|
4
|
+
def self.ia32?
|
5
|
+
ARCH == "i386"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.x64?
|
9
|
+
ARCH == "x86_64"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.arm64?
|
13
|
+
ARCH == "aarch64"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
file 'ext/libuv/build' do
|
18
|
+
system "git", "submodule", "update", "--init"
|
19
|
+
end
|
20
|
+
|
21
|
+
if FFI::Platform.windows?
|
22
|
+
require File.join File.expand_path("../", __FILE__), 'tasks/win'
|
23
|
+
elsif FFI::Platform.mac?
|
24
|
+
require File.join File.expand_path("../", __FILE__), 'tasks/mac'
|
25
|
+
else # UNIX
|
26
|
+
require File.join File.expand_path("../", __FILE__), 'tasks/unix'
|
27
|
+
end
|
@@ -0,0 +1,253 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'socket' # Addrinfo
|
4
|
+
|
5
|
+
module MTLibuv
|
6
|
+
module Ext
|
7
|
+
# Defined in platform code
|
8
|
+
#require 'mt-libuv/ext/platform/linux.rb' if FFI::Platform.linux?
|
9
|
+
require 'mt-libuv/ext/platform/unix.rb' if FFI::Platform.unix?
|
10
|
+
require 'mt-libuv/ext/platform/darwin_x64.rb' if FFI::Platform.mac? and FFI::Platform::ARCH == 'x86_64'
|
11
|
+
require 'mt-libuv/ext/platform/windows.rb' if FFI::Platform.windows?
|
12
|
+
|
13
|
+
|
14
|
+
enum :uv_handle_type, [
|
15
|
+
:unknown_handle, 0,
|
16
|
+
:async, # start UV_HANDLE_TYPE_MAP
|
17
|
+
:check,
|
18
|
+
:fs_event,
|
19
|
+
:fs_poll,
|
20
|
+
:handle,
|
21
|
+
:idle,
|
22
|
+
:pipe,
|
23
|
+
:poll,
|
24
|
+
:prepare,
|
25
|
+
:process,
|
26
|
+
:stream,
|
27
|
+
:tcp,
|
28
|
+
:timer,
|
29
|
+
:tty,
|
30
|
+
:udp,
|
31
|
+
:signal, # end UV_HANDLE_TYPE_MAP
|
32
|
+
:file,
|
33
|
+
:handle_type_max
|
34
|
+
]
|
35
|
+
enum :uv_req_type, [
|
36
|
+
:unknown_req, 0,
|
37
|
+
:req, # start UV_REQ_TYPE_MAP
|
38
|
+
:connect,
|
39
|
+
:write,
|
40
|
+
:shutdown,
|
41
|
+
:udp_send,
|
42
|
+
:fs,
|
43
|
+
:work,
|
44
|
+
:getaddrinfo,
|
45
|
+
:getnameinfo, # end UV_REQ_TYPE_MAP
|
46
|
+
:req_type_private,
|
47
|
+
:req_type_max
|
48
|
+
]
|
49
|
+
enum :uv_membership, [
|
50
|
+
:uv_leave_group, 0,
|
51
|
+
:uv_join_group
|
52
|
+
]
|
53
|
+
enum :uv_fs_type, [
|
54
|
+
:UV_FS_UNKNOWN, -1,
|
55
|
+
:UV_FS_CUSTOM,
|
56
|
+
:UV_FS_OPEN,
|
57
|
+
:UV_FS_CLOSE,
|
58
|
+
:UV_FS_READ,
|
59
|
+
:UV_FS_WRITE,
|
60
|
+
:UV_FS_SENDFILE,
|
61
|
+
:UV_FS_STAT,
|
62
|
+
:UV_FS_LSTAT,
|
63
|
+
:UV_FS_FSTAT,
|
64
|
+
:UV_FS_FTRUNCATE,
|
65
|
+
:UV_FS_UTIME,
|
66
|
+
:UV_FS_FUTIME,
|
67
|
+
:UV_FS_ACCESS,
|
68
|
+
:UV_FS_CHMOD,
|
69
|
+
:UV_FS_FCHMOD,
|
70
|
+
:UV_FS_FSYNC,
|
71
|
+
:UV_FS_FDATASYNC,
|
72
|
+
:UV_FS_UNLINK,
|
73
|
+
:UV_FS_RMDIR,
|
74
|
+
:UV_FS_MKDIR,
|
75
|
+
:UV_FS_RENAME,
|
76
|
+
:UV_FS_SCANDIR,
|
77
|
+
:UV_FS_LINK,
|
78
|
+
:UV_FS_SYMLINK,
|
79
|
+
:UV_FS_READLINK,
|
80
|
+
:UV_FS_CHOWN,
|
81
|
+
:UV_FS_FCHOWN,
|
82
|
+
:UV_FS_REALPATH
|
83
|
+
]
|
84
|
+
enum :uv_fs_event, [
|
85
|
+
:UV_RENAME, 1,
|
86
|
+
:UV_CHANGE, 2
|
87
|
+
]
|
88
|
+
enum :uv_run_mode, [
|
89
|
+
:UV_RUN_DEFAULT, 0,
|
90
|
+
:UV_RUN_ONCE,
|
91
|
+
:UV_RUN_NOWAIT
|
92
|
+
]
|
93
|
+
enum :uv_dirent_type, [
|
94
|
+
:UV_DIRENT_UNKNOWN, 0,
|
95
|
+
:UV_DIRENT_FILE,
|
96
|
+
:UV_DIRENT_DIR,
|
97
|
+
:UV_DIRENT_LINK,
|
98
|
+
:UV_DIRENT_FIFO,
|
99
|
+
:UV_DIRENT_SOCKET,
|
100
|
+
:UV_DIRENT_CHAR,
|
101
|
+
:UV_DIRENT_BLOCK
|
102
|
+
]
|
103
|
+
|
104
|
+
class UvDirent < FFI::Struct
|
105
|
+
layout :name, :string,
|
106
|
+
:type, :uv_dirent_type
|
107
|
+
end
|
108
|
+
typedef UvDirent.by_ref, :uv_dirent_t
|
109
|
+
|
110
|
+
|
111
|
+
typedef UvBuf.by_ref, :uv_buf_t
|
112
|
+
typedef SockaddrIn.by_ref, :sockaddr_in4
|
113
|
+
typedef SockaddrIn6.by_ref, :sockaddr_in6
|
114
|
+
|
115
|
+
|
116
|
+
class UvTimespec < FFI::Struct
|
117
|
+
layout :tv_sec, :long,
|
118
|
+
:tv_nsec, :long
|
119
|
+
end
|
120
|
+
|
121
|
+
class UvStat < FFI::Struct
|
122
|
+
layout :st_dev, :uint64,
|
123
|
+
:st_mode, :uint64,
|
124
|
+
:st_nlink, :uint64,
|
125
|
+
:st_uid, :uint64,
|
126
|
+
:st_gid, :uint64,
|
127
|
+
:st_rdev, :uint64,
|
128
|
+
:st_ino, :uint64,
|
129
|
+
:st_size, :uint64,
|
130
|
+
:st_blksize, :uint64,
|
131
|
+
:st_blocks, :uint64,
|
132
|
+
:st_flags, :uint64,
|
133
|
+
:st_gen, :uint64,
|
134
|
+
:st_atim, UvTimespec,
|
135
|
+
:st_mtim, UvTimespec,
|
136
|
+
:st_ctim, UvTimespec,
|
137
|
+
:st_birthtim, UvTimespec
|
138
|
+
end
|
139
|
+
|
140
|
+
class UvLoop < FFI::Struct
|
141
|
+
layout :data, :pointer,
|
142
|
+
:active_handles, :uint
|
143
|
+
end
|
144
|
+
|
145
|
+
enum :uv_stdio_flags, [
|
146
|
+
:UV_IGNORE, 0,
|
147
|
+
:UV_CREATE_PIPE, 1,
|
148
|
+
:UV_INHERIT_FD, 2,
|
149
|
+
:UV_INHERIT_STREAM, 4,
|
150
|
+
:UV_READABLE_PIPE, 0x10,
|
151
|
+
:CREATE_READABLE_PIPE, 0x11,
|
152
|
+
:UV_WRITABLE_PIPE, 0x20,
|
153
|
+
:CREATE_WRITABLE_PIPE, 0x21
|
154
|
+
]
|
155
|
+
|
156
|
+
class StdioData < FFI::Union
|
157
|
+
layout :pipe_handle, :pointer,
|
158
|
+
:fd, :int
|
159
|
+
end
|
160
|
+
|
161
|
+
class UvStdioContainer < FFI::Struct
|
162
|
+
layout :flags, :uv_stdio_flags,
|
163
|
+
:data, StdioData.by_value
|
164
|
+
end
|
165
|
+
|
166
|
+
class StdioObjs < FFI::Struct
|
167
|
+
layout :stdin, UvStdioContainer.by_value,
|
168
|
+
:stdout, UvStdioContainer.by_value,
|
169
|
+
:stderr, UvStdioContainer.by_value
|
170
|
+
end
|
171
|
+
|
172
|
+
typedef :pointer, :sockaddr_in
|
173
|
+
typedef :pointer, :uv_handle_t
|
174
|
+
typedef :pointer, :uv_fs_event_t
|
175
|
+
typedef :pointer, :uv_fs_poll_t
|
176
|
+
typedef :pointer, :uv_stream_t
|
177
|
+
typedef :pointer, :uv_tcp_t
|
178
|
+
typedef :pointer, :uv_udp_t
|
179
|
+
typedef :pointer, :uv_tty_t
|
180
|
+
typedef :pointer, :uv_pipe_t
|
181
|
+
typedef :pointer, :uv_prepare_t
|
182
|
+
typedef :pointer, :uv_check_t
|
183
|
+
typedef :pointer, :uv_idle_t
|
184
|
+
typedef :pointer, :uv_async_t
|
185
|
+
typedef :pointer, :uv_timer_t
|
186
|
+
typedef :pointer, :uv_signal_t
|
187
|
+
typedef :pointer, :uv_process_t
|
188
|
+
typedef :pointer, :uv_getaddrinfo_cb
|
189
|
+
typedef :pointer, :uv_work_t
|
190
|
+
typedef :pointer, :uv_loop_t
|
191
|
+
typedef :pointer, :uv_shutdown_t
|
192
|
+
typedef :pointer, :uv_write_t
|
193
|
+
typedef :pointer, :uv_connect_t
|
194
|
+
typedef :pointer, :uv_udp_send_t
|
195
|
+
typedef :int, :uv_file
|
196
|
+
typedef :pointer, :uv_fs_t
|
197
|
+
typedef :pointer, :ares_channel
|
198
|
+
typedef :pointer, :ares_options
|
199
|
+
typedef :pointer, :uv_getaddrinfo_t
|
200
|
+
typedef :pointer, :uv_options_t
|
201
|
+
typedef :pointer, :uv_cpu_info_t
|
202
|
+
typedef :pointer, :uv_interface_address_t
|
203
|
+
typedef :pointer, :uv_lib_t
|
204
|
+
typedef :pointer, :uv_mutex_t
|
205
|
+
typedef :pointer, :uv_rwlock_t
|
206
|
+
typedef :pointer, :uv_once_t
|
207
|
+
typedef :pointer, :uv_thread_t
|
208
|
+
typedef :pointer, :uv_poll_t
|
209
|
+
typedef :pointer, :uv_stat_t
|
210
|
+
typedef :int, :status
|
211
|
+
typedef :int, :events
|
212
|
+
typedef :int, :signal
|
213
|
+
|
214
|
+
callback :uv_alloc_cb, [:uv_handle_t, :size_t, :uv_buf_t], :void
|
215
|
+
callback :uv_read_cb, [:uv_stream_t, :ssize_t, :uv_buf_t], :void
|
216
|
+
callback :uv_read2_cb, [:uv_pipe_t, :ssize_t, :uv_buf_t, :uv_handle_type], :void
|
217
|
+
callback :uv_write_cb, [:uv_write_t, :status], :void
|
218
|
+
callback :uv_connect_cb, [:uv_connect_t, :status], :void
|
219
|
+
callback :uv_shutdown_cb, [:uv_shutdown_t, :status], :void
|
220
|
+
callback :uv_connection_cb, [:uv_stream_t, :status], :void
|
221
|
+
callback :uv_close_cb, [:uv_handle_t], :void
|
222
|
+
callback :uv_poll_cb, [:uv_poll_t, :status, :events], :void
|
223
|
+
callback :uv_timer_cb, [:uv_timer_t], :void
|
224
|
+
callback :uv_signal_cb, [:uv_signal_t, :signal], :void
|
225
|
+
callback :uv_async_cb, [:uv_async_t], :void
|
226
|
+
callback :uv_prepare_cb, [:uv_prepare_t], :void
|
227
|
+
callback :uv_check_cb, [:uv_check_t], :void
|
228
|
+
callback :uv_idle_cb, [:uv_idle_t], :void
|
229
|
+
callback :uv_getaddrinfo_cb, [:uv_getaddrinfo_t, :status, UvAddrinfo.by_ref], :void
|
230
|
+
callback :uv_exit_cb, [:uv_process_t, :int64, :int], :void
|
231
|
+
callback :uv_walk_cb, [:uv_handle_t, :pointer], :void
|
232
|
+
callback :uv_work_cb, [:uv_work_t], :void
|
233
|
+
callback :uv_after_work_cb, [:uv_work_t, :int], :void
|
234
|
+
callback :uv_fs_event_cb, [:uv_fs_event_t, :string, :int, :int], :void
|
235
|
+
callback :uv_fs_poll_cb, [:uv_fs_poll_t, :status, :uv_stat_t, :uv_stat_t], :void
|
236
|
+
callback :uv_udp_send_cb, [:uv_udp_send_t, :int], :void
|
237
|
+
callback :uv_udp_recv_cb, [:uv_udp_t, :ssize_t, :uv_buf_t, Sockaddr.by_ref, :uint], :void
|
238
|
+
callback :uv_cb, [], :void
|
239
|
+
|
240
|
+
class UvProcessOptions < FFI::Struct
|
241
|
+
layout :exit_cb, :uv_exit_cb,
|
242
|
+
:file, :pointer,
|
243
|
+
:args, :pointer, # arg[0] == file
|
244
|
+
:env, :pointer, # environment array of strings
|
245
|
+
:cwd, :pointer, # working dir
|
246
|
+
:flags, :uint,
|
247
|
+
:stdio_count, :int,
|
248
|
+
:stdio, StdioObjs.by_ref,
|
249
|
+
:uid, :uint64,
|
250
|
+
:gid, :uint64
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MTLibuv; end
|
4
|
+
|
5
|
+
# Use of a Fiber Pool increases performance as stack allocations
|
6
|
+
# don't need to continually occur. Especially useful on JRuby and
|
7
|
+
# Rubinius where multiple kernel threads and locks emulate Fibers.
|
8
|
+
class MTLibuv::FiberPool
|
9
|
+
def initialize(thread)
|
10
|
+
@reactor = thread
|
11
|
+
reset
|
12
|
+
end
|
13
|
+
|
14
|
+
def exec
|
15
|
+
if @reactor.reactor_thread?
|
16
|
+
# Execute the block in a Fiber
|
17
|
+
next_fiber do
|
18
|
+
begin
|
19
|
+
yield
|
20
|
+
rescue Exception => e
|
21
|
+
@on_error.call(e) if @on_error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
# move the block onto the reactor thread
|
26
|
+
@reactor.schedule do
|
27
|
+
exec do
|
28
|
+
yield
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_error(&block)
|
35
|
+
@on_error = block
|
36
|
+
end
|
37
|
+
|
38
|
+
def available
|
39
|
+
@pool.size
|
40
|
+
end
|
41
|
+
|
42
|
+
def size
|
43
|
+
@count
|
44
|
+
end
|
45
|
+
|
46
|
+
def reset
|
47
|
+
@pool = []
|
48
|
+
@count = 0
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
|
55
|
+
def next_fiber(&block)
|
56
|
+
fib = if @pool.empty?
|
57
|
+
new_fiber
|
58
|
+
else
|
59
|
+
@pool.pop
|
60
|
+
end
|
61
|
+
|
62
|
+
@job = block
|
63
|
+
fib.resume
|
64
|
+
end
|
65
|
+
|
66
|
+
# Fibers are never cleaned up which shouldn't be much of an issue
|
67
|
+
# This might lead to issues on Rubinius or JRuby however it should
|
68
|
+
# generally improve performance on these platforms
|
69
|
+
def new_fiber
|
70
|
+
@count += 1
|
71
|
+
|
72
|
+
Fiber.new do
|
73
|
+
loop do
|
74
|
+
job = @job
|
75
|
+
@job = nil
|
76
|
+
job.call
|
77
|
+
|
78
|
+
@pool << Fiber.current
|
79
|
+
Fiber.yield
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|