mt-libuv 4.1.0

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 (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.gitmodules +6 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +24 -0
  6. data/Gemfile +9 -0
  7. data/LICENSE +24 -0
  8. data/README.md +195 -0
  9. data/Rakefile +31 -0
  10. data/ext/README.md +6 -0
  11. data/ext/Rakefile +28 -0
  12. data/lib/mt-libuv/async.rb +51 -0
  13. data/lib/mt-libuv/check.rb +59 -0
  14. data/lib/mt-libuv/coroutines.rb +79 -0
  15. data/lib/mt-libuv/dns.rb +98 -0
  16. data/lib/mt-libuv/error.rb +88 -0
  17. data/lib/mt-libuv/ext/ext.rb +322 -0
  18. data/lib/mt-libuv/ext/platform/darwin_x64.rb +61 -0
  19. data/lib/mt-libuv/ext/platform/unix.rb +69 -0
  20. data/lib/mt-libuv/ext/platform/windows.rb +83 -0
  21. data/lib/mt-libuv/ext/tasks/mac.rb +24 -0
  22. data/lib/mt-libuv/ext/tasks/unix.rb +42 -0
  23. data/lib/mt-libuv/ext/tasks/win.rb +29 -0
  24. data/lib/mt-libuv/ext/tasks.rb +27 -0
  25. data/lib/mt-libuv/ext/types.rb +253 -0
  26. data/lib/mt-libuv/fiber_pool.rb +83 -0
  27. data/lib/mt-libuv/file.rb +309 -0
  28. data/lib/mt-libuv/filesystem.rb +263 -0
  29. data/lib/mt-libuv/fs_event.rb +37 -0
  30. data/lib/mt-libuv/handle.rb +108 -0
  31. data/lib/mt-libuv/idle.rb +59 -0
  32. data/lib/mt-libuv/mixins/accessors.rb +41 -0
  33. data/lib/mt-libuv/mixins/assertions.rb +25 -0
  34. data/lib/mt-libuv/mixins/fs_checks.rb +96 -0
  35. data/lib/mt-libuv/mixins/listener.rb +69 -0
  36. data/lib/mt-libuv/mixins/net.rb +42 -0
  37. data/lib/mt-libuv/mixins/resource.rb +30 -0
  38. data/lib/mt-libuv/mixins/stream.rb +276 -0
  39. data/lib/mt-libuv/pipe.rb +217 -0
  40. data/lib/mt-libuv/prepare.rb +59 -0
  41. data/lib/mt-libuv/q.rb +475 -0
  42. data/lib/mt-libuv/reactor.rb +567 -0
  43. data/lib/mt-libuv/signal.rb +62 -0
  44. data/lib/mt-libuv/spawn.rb +113 -0
  45. data/lib/mt-libuv/tcp.rb +465 -0
  46. data/lib/mt-libuv/timer.rb +107 -0
  47. data/lib/mt-libuv/tty.rb +42 -0
  48. data/lib/mt-libuv/udp.rb +302 -0
  49. data/lib/mt-libuv/version.rb +5 -0
  50. data/lib/mt-libuv/work.rb +86 -0
  51. data/lib/mt-libuv.rb +80 -0
  52. data/mt-libuv.gemspec +62 -0
  53. data/spec/async_spec.rb +67 -0
  54. data/spec/coroutines_spec.rb +121 -0
  55. data/spec/cpu_spec.rb +10 -0
  56. data/spec/defer_spec.rb +906 -0
  57. data/spec/dns_spec.rb +110 -0
  58. data/spec/dsl_spec.rb +43 -0
  59. data/spec/filesystem_spec.rb +270 -0
  60. data/spec/idle_spec.rb +44 -0
  61. data/spec/pipe_spec.rb +151 -0
  62. data/spec/spawn_spec.rb +119 -0
  63. data/spec/tcp_spec.rb +272 -0
  64. data/spec/test.sh +4 -0
  65. data/spec/test_fail.sh +3 -0
  66. data/spec/test_read.sh +3 -0
  67. data/spec/timer_spec.rb +14 -0
  68. data/spec/udp_spec.rb +73 -0
  69. data/spec/zen_spec.rb +34 -0
  70. 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