mt-libuv 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
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