libuv 0.11.22 → 0.12.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +19 -17
  3. data/.gitmodules +3 -3
  4. data/.rspec +1 -1
  5. data/.travis.yml +16 -16
  6. data/Gemfile +4 -4
  7. data/LICENSE +23 -23
  8. data/README.md +89 -89
  9. data/Rakefile +31 -31
  10. data/lib/libuv.rb +54 -54
  11. data/lib/libuv/async.rb +47 -47
  12. data/lib/libuv/check.rb +55 -55
  13. data/lib/libuv/dns.rb +85 -85
  14. data/lib/libuv/error.rb +78 -74
  15. data/lib/libuv/ext/ext.rb +260 -258
  16. data/lib/libuv/ext/platform/darwin_x64.rb +23 -23
  17. data/lib/libuv/ext/platform/linux.rb +7 -7
  18. data/lib/libuv/ext/platform/unix.rb +29 -29
  19. data/lib/libuv/ext/platform/windows.rb +40 -40
  20. data/lib/libuv/ext/tasks.rb +31 -31
  21. data/lib/libuv/ext/tasks/mac.rb +23 -23
  22. data/lib/libuv/ext/tasks/unix.rb +23 -23
  23. data/lib/libuv/ext/tasks/win.rb +14 -14
  24. data/lib/libuv/ext/types.rb +238 -238
  25. data/lib/libuv/file.rb +281 -269
  26. data/lib/libuv/filesystem.rb +232 -232
  27. data/lib/libuv/fs_event.rb +31 -31
  28. data/lib/libuv/handle.rb +85 -85
  29. data/lib/libuv/idle.rb +56 -56
  30. data/lib/libuv/loop.rb +412 -412
  31. data/lib/libuv/mixins/assertions.rb +23 -23
  32. data/lib/libuv/mixins/fs_checks.rb +60 -58
  33. data/lib/libuv/mixins/listener.rb +34 -34
  34. data/lib/libuv/mixins/net.rb +40 -40
  35. data/lib/libuv/mixins/resource.rb +27 -27
  36. data/lib/libuv/mixins/stream.rb +153 -154
  37. data/lib/libuv/pipe.rb +184 -203
  38. data/lib/libuv/prepare.rb +56 -56
  39. data/lib/libuv/signal.rb +51 -51
  40. data/lib/libuv/tcp.rb +334 -334
  41. data/lib/libuv/timer.rb +85 -85
  42. data/lib/libuv/tty.rb +37 -37
  43. data/lib/libuv/udp.rb +240 -240
  44. data/lib/libuv/version.rb +3 -3
  45. data/lib/libuv/work.rb +75 -75
  46. data/libuv.gemspec +56 -56
  47. data/spec/async_spec.rb +61 -60
  48. data/spec/cpu_spec.rb +10 -10
  49. data/spec/defer_spec.rb +980 -980
  50. data/spec/dns_spec.rb +96 -90
  51. data/spec/filesystem_spec.rb +270 -261
  52. data/spec/idle_spec.rb +56 -56
  53. data/spec/pipe_spec.rb +160 -160
  54. data/spec/tcp_spec.rb +271 -267
  55. metadata +64 -51
data/lib/libuv/pipe.rb CHANGED
@@ -1,203 +1,184 @@
1
- module Libuv
2
- class Pipe < Handle
3
- include Stream
4
-
5
-
6
- WRITE2_ERROR = "data must be a String".freeze
7
-
8
-
9
- def initialize(loop, ipc, acceptor = nil)
10
- @loop, @ipc = loop, ipc
11
-
12
- pipe_ptr = ::Libuv::Ext.create_handle(:uv_pipe)
13
- error = check_result(::Libuv::Ext.pipe_init(loop.handle, pipe_ptr, ipc ? 1 : 0))
14
- error = check_result(::Libuv::Ext.accept(acceptor, pipe_ptr)) if acceptor && error.nil?
15
-
16
- super(pipe_ptr, error)
17
- end
18
-
19
- def bind(name, callback = nil, &blk)
20
- return if @closed
21
- @on_listen = callback || blk
22
- assert_type(String, name, "name must be a String")
23
- name = windows_path name if FFI::Platform.windows?
24
-
25
- error = check_result ::Libuv::Ext.pipe_bind(handle, name)
26
- reject(error) if error
27
- end
28
-
29
- def accept(callback = nil, &blk)
30
- pipe = nil
31
- begin
32
- raise RuntimeError, CLOSED_HANDLE_ERROR if @closed
33
- pipe = Pipe.new(loop, @ipc, handle)
34
- rescue Exception => e
35
- @loop.log :info, :pipe_accept_failed, e
36
- end
37
- if pipe
38
- begin
39
- (callback || blk).call(pipe)
40
- rescue Exception => e
41
- @loop.log :error, :pipe_accept_cb, e
42
- end
43
- end
44
- nil
45
- end
46
-
47
- def open(fileno, callback = nil, &blk)
48
- @callback = callback || blk
49
- assert_type(Integer, fileno, "io#fileno must return an integer file descriptor")
50
- begin
51
- raise RuntimeError, CLOSED_HANDLE_ERROR if @closed
52
- check_result! ::Libuv::Ext.pipe_open(handle, fileno)
53
-
54
- # Emulate on_connect behavior
55
- begin
56
- @callback.call(self)
57
- rescue Exception => e
58
- @loop.log :error, :pipe_connect_cb, e
59
- end
60
- rescue Exception => e
61
- reject(e)
62
- end
63
- end
64
-
65
- def connect(name, callback = nil, &blk)
66
- return if @closed
67
- @callback = callback || blk
68
- assert_type(String, name, "name must be a String")
69
- begin
70
- name = windows_path name if FFI::Platform.windows?
71
- ::Libuv::Ext.pipe_connect(::Libuv::Ext.create_request(:uv_connect), handle, name, callback(:on_connect))
72
- rescue Exception => e
73
- reject(e)
74
- end
75
- end
76
-
77
- def write2(fd, data = ".")
78
- deferred = @loop.defer
79
- if @ipc && !@closed
80
- begin
81
- assert_type(String, data, WRITE_ERROR)
82
- assert_type(Handle, fd, WRITE2_ERROR)
83
-
84
- size = data.respond_to?(:bytesize) ? data.bytesize : data.size
85
- buffer = ::Libuv::Ext.buf_init(FFI::MemoryPointer.from_string(data), size)
86
-
87
- # local as this variable will be avaliable until the handle is closed
88
- @write_callbacks = @write_callbacks || []
89
-
90
- #
91
- # create the curried callback
92
- #
93
- callback = FFI::Function.new(:void, [:pointer, :int]) do |req, status|
94
- ::Libuv::Ext.free(req)
95
- # remove the callback from the array
96
- # assumes writes are done in order
97
- promise = @write_callbacks.shift[0]
98
- resolve promise, status
99
- end
100
-
101
-
102
- @write_callbacks << [deferred, callback]
103
- req = ::Libuv::Ext.create_request(:uv_write)
104
- error = check_result ::Libuv::Ext.write2(req, handle, buffer, 1, fd.handle, callback)
105
-
106
- if error
107
- @write_callbacks.pop
108
- ::Libuv::Ext.free(req)
109
- deferred.reject(error)
110
-
111
- reject(error) # close the handle
112
- end
113
- rescue Exception => e
114
- deferred.reject(e) # this write exception may not be fatal
115
- end
116
- else
117
- deferred.reject(TypeError.new('pipe not initialized for interprocess communication'))
118
- end
119
- deferred.promise
120
- end
121
-
122
- def start_read2
123
- return if @closed
124
- error = check_result ::Libuv::Ext.read2_start(handle, callback(:on_allocate), callback(:on_read2))
125
- reject(error) if error
126
- end
127
-
128
- # Windows only
129
- def pending_instances=(count)
130
- return 0 if @closed
131
- assert_type(Integer, count, "count must be an Integer")
132
- ::Libuv::Ext.pipe_pending_instances(handle, count)
133
- end
134
-
135
-
136
- private
137
-
138
-
139
- def on_connect(req, status)
140
- ::Libuv::Ext.free(req)
141
- e = check_result(status)
142
-
143
- if e
144
- reject(e)
145
- else
146
- begin
147
- @callback.call(self)
148
- rescue Exception => e
149
- @loop.log :error, :pipe_connect_cb, e
150
- end
151
- end
152
- end
153
-
154
- def on_read2(handle, nread, buf, pending)
155
- if pending != :uv_unknown_handle
156
- # similar to regular read in stream
157
- e = check_result(nread)
158
- base = buf[:base]
159
-
160
- if e
161
- ::Libuv::Ext.free(base)
162
- reject(e)
163
- else
164
- data = base.read_string(nread)
165
- ::Libuv::Ext.free(base)
166
-
167
- # Hide the accept logic
168
- remote = nil
169
- begin
170
- case pending
171
- when :uv_tcp
172
- remote = TCP.new(loop, handle)
173
- when :uv_pipe
174
- remote = Pipe.new(loop, @ipc, handle)
175
- else
176
- raise NotImplementedError, "IPC for handle #{pending} not supported"
177
- end
178
- rescue Exception => e
179
- remote = nil
180
- @loop.log :info, :pipe_read2_failed, e
181
- reject(e) # if accept fails we should close the socket to avoid a stale pipe
182
- end
183
- if remote
184
- # stream the data and new socket
185
- begin
186
- @progress.call data, remote
187
- rescue Exception => e
188
- @loop.log :error, :stream_progress_cb, e
189
- end
190
- end
191
- end
192
- end
193
- end
194
-
195
- def windows_path(name)
196
- # test for \\\\.\\pipe
197
- if not name =~ /(\/|\\){2}\.(\/|\\)pipe/i
198
- name = ::File.join("\\\\.\\pipe", name)
199
- end
200
- name.gsub("/", "\\")
201
- end
202
- end
203
- end
1
+ module Libuv
2
+ class Pipe < Handle
3
+ include Stream
4
+
5
+
6
+ WRITE2_ERROR = "data must be a String".freeze
7
+
8
+
9
+ def initialize(loop, ipc, acceptor = nil)
10
+ @loop, @ipc = loop, ipc
11
+
12
+ pipe_ptr = ::Libuv::Ext.create_handle(:uv_pipe)
13
+ error = check_result(::Libuv::Ext.pipe_init(loop.handle, pipe_ptr, ipc ? 1 : 0))
14
+ error = check_result(::Libuv::Ext.accept(acceptor, pipe_ptr)) if acceptor && error.nil?
15
+
16
+ super(pipe_ptr, error)
17
+ end
18
+
19
+ def bind(name, callback = nil, &blk)
20
+ return if @closed
21
+ @on_listen = callback || blk
22
+ assert_type(String, name, "name must be a String")
23
+ name = windows_path name if FFI::Platform.windows?
24
+
25
+ error = check_result ::Libuv::Ext.pipe_bind(handle, name)
26
+ reject(error) if error
27
+ end
28
+
29
+ def accept(callback = nil, &blk)
30
+ pipe = nil
31
+ begin
32
+ raise RuntimeError, CLOSED_HANDLE_ERROR if @closed
33
+ pipe = Pipe.new(loop, @ipc, handle)
34
+ rescue Exception => e
35
+ @loop.log :info, :pipe_accept_failed, e
36
+ end
37
+ if pipe
38
+ begin
39
+ (callback || blk).call(pipe)
40
+ rescue Exception => e
41
+ @loop.log :error, :pipe_accept_cb, e
42
+ end
43
+ end
44
+ nil
45
+ end
46
+
47
+ def open(fileno, callback = nil, &blk)
48
+ @callback = callback || blk
49
+ assert_type(Integer, fileno, "io#fileno must return an integer file descriptor")
50
+ begin
51
+ raise RuntimeError, CLOSED_HANDLE_ERROR if @closed
52
+ check_result! ::Libuv::Ext.pipe_open(handle, fileno)
53
+
54
+ # Emulate on_connect behavior
55
+ begin
56
+ @callback.call(self)
57
+ rescue Exception => e
58
+ @loop.log :error, :pipe_connect_cb, e
59
+ end
60
+ rescue Exception => e
61
+ reject(e)
62
+ end
63
+ end
64
+
65
+ def connect(name, callback = nil, &blk)
66
+ return if @closed
67
+ @callback = callback || blk
68
+ assert_type(String, name, "name must be a String")
69
+ begin
70
+ name = windows_path name if FFI::Platform.windows?
71
+ ::Libuv::Ext.pipe_connect(::Libuv::Ext.create_request(:uv_connect), handle, name, callback(:on_connect))
72
+ rescue Exception => e
73
+ reject(e)
74
+ end
75
+ end
76
+
77
+ def write2(fd, data = ".")
78
+ deferred = @loop.defer
79
+ if @ipc && !@closed
80
+ begin
81
+ assert_type(String, data, WRITE_ERROR)
82
+ assert_type(Handle, fd, WRITE2_ERROR)
83
+
84
+ size = data.respond_to?(:bytesize) ? data.bytesize : data.size
85
+ buffer = ::Libuv::Ext.buf_init(FFI::MemoryPointer.from_string(data), size)
86
+
87
+ # local as this variable will be avaliable until the handle is closed
88
+ @write_callbacks = @write_callbacks || []
89
+
90
+ #
91
+ # create the curried callback
92
+ #
93
+ callback = FFI::Function.new(:void, [:pointer, :int]) do |req, status|
94
+ ::Libuv::Ext.free(req)
95
+ # remove the callback from the array
96
+ # assumes writes are done in order
97
+ promise = @write_callbacks.shift[0]
98
+ resolve promise, status
99
+ end
100
+
101
+
102
+ @write_callbacks << [deferred, callback]
103
+ req = ::Libuv::Ext.create_request(:uv_write)
104
+ error = check_result ::Libuv::Ext.write2(req, handle, buffer, 1, fd.handle, callback)
105
+
106
+ if error
107
+ @write_callbacks.pop
108
+ ::Libuv::Ext.free(req)
109
+ deferred.reject(error)
110
+
111
+ reject(error) # close the handle
112
+ end
113
+ rescue Exception => e
114
+ deferred.reject(e) # this write exception may not be fatal
115
+ end
116
+ else
117
+ deferred.reject(TypeError.new('pipe not initialized for interprocess communication'))
118
+ end
119
+ deferred.promise
120
+ end
121
+
122
+ # Windows only
123
+ def pending_instances=(count)
124
+ return 0 if @closed
125
+ assert_type(Integer, count, "count must be an Integer")
126
+ ::Libuv::Ext.pipe_pending_instances(handle, count)
127
+ end
128
+
129
+ def check_pending(expecting = nil)
130
+ return nil if ::Libuv::Ext.pipe_pending_count(handle) <= 0
131
+
132
+ pending = ::Libuv::Ext.pipe_pending_type(handle)
133
+ raise TypeError, "IPC expecting #{expecting} and received #{pending}" if expecting && expecting != pending
134
+
135
+ # Hide the accept logic
136
+ remote = nil
137
+ case pending
138
+ when :uv_tcp
139
+ remote = TCP.new(loop, handle)
140
+ when :uv_pipe
141
+ remote = Pipe.new(loop, @ipc, handle)
142
+ else
143
+ raise NotImplementedError, "IPC for handle #{pending} not supported"
144
+ end
145
+ remote
146
+ end
147
+
148
+ def getsockname
149
+ size = 256
150
+ len = FFI::MemoryPointer.new(:size_t)
151
+ len.put_int(0, size)
152
+ buffer = FFI::MemoryPointer.new(size)
153
+ check_result! ::Libuv::Ext.pipe_getsockname(handle, buffer, len)
154
+ buffer.read_string
155
+ end
156
+
157
+
158
+ private
159
+
160
+
161
+ def on_connect(req, status)
162
+ ::Libuv::Ext.free(req)
163
+ e = check_result(status)
164
+
165
+ if e
166
+ reject(e)
167
+ else
168
+ begin
169
+ @callback.call(self)
170
+ rescue Exception => e
171
+ @loop.log :error, :pipe_connect_cb, e
172
+ end
173
+ end
174
+ end
175
+
176
+ def windows_path(name)
177
+ # test for \\\\.\\pipe
178
+ if not name =~ /(\/|\\){2}\.(\/|\\)pipe/i
179
+ name = ::File.join("\\\\.\\pipe", name)
180
+ end
181
+ name.gsub("/", "\\")
182
+ end
183
+ end
184
+ end
data/lib/libuv/prepare.rb CHANGED
@@ -1,56 +1,56 @@
1
- module Libuv
2
- class Prepare < Handle
3
-
4
-
5
- # @param loop [::Libuv::Loop] loop this prepare handle will be associated
6
- # @param callback [Proc] callback to be called on loop preparation
7
- def initialize(loop, callback = nil, &blk)
8
- @loop = loop
9
- @callback = callback || blk
10
-
11
- prepare_ptr = ::Libuv::Ext.create_handle(:uv_prepare)
12
- error = check_result(::Libuv::Ext.prepare_init(loop.handle, prepare_ptr))
13
-
14
- super(prepare_ptr, error)
15
- end
16
-
17
- # Enables the prepare handler.
18
- def start
19
- return if @closed
20
- error = check_result ::Libuv::Ext.prepare_start(handle, callback(:on_prepare))
21
- reject(error) if error
22
- end
23
-
24
- # Disables the prepare handler.
25
- def stop
26
- return if @closed
27
- error = check_result ::Libuv::Ext.prepare_stop(handle)
28
- reject(error) if error
29
- end
30
-
31
- # Used to update the callback that will be triggered on loop prepare
32
- #
33
- # @param callback [Proc] the callback to be called on loop prepare
34
- def progress(callback = nil, &blk)
35
- @callback = callback || blk
36
- end
37
-
38
-
39
- private
40
-
41
-
42
- def on_prepare(handle, status)
43
- e = check_result(status)
44
-
45
- if e
46
- reject(e)
47
- else
48
- begin
49
- @callback.call
50
- rescue Exception => e
51
- @loop.log :error, :prepare_cb, e
52
- end
53
- end
54
- end
55
- end
56
- end
1
+ module Libuv
2
+ class Prepare < Handle
3
+
4
+
5
+ # @param loop [::Libuv::Loop] loop this prepare handle will be associated
6
+ # @param callback [Proc] callback to be called on loop preparation
7
+ def initialize(loop, callback = nil, &blk)
8
+ @loop = loop
9
+ @callback = callback || blk
10
+
11
+ prepare_ptr = ::Libuv::Ext.create_handle(:uv_prepare)
12
+ error = check_result(::Libuv::Ext.prepare_init(loop.handle, prepare_ptr))
13
+
14
+ super(prepare_ptr, error)
15
+ end
16
+
17
+ # Enables the prepare handler.
18
+ def start
19
+ return if @closed
20
+ error = check_result ::Libuv::Ext.prepare_start(handle, callback(:on_prepare))
21
+ reject(error) if error
22
+ end
23
+
24
+ # Disables the prepare handler.
25
+ def stop
26
+ return if @closed
27
+ error = check_result ::Libuv::Ext.prepare_stop(handle)
28
+ reject(error) if error
29
+ end
30
+
31
+ # Used to update the callback that will be triggered on loop prepare
32
+ #
33
+ # @param callback [Proc] the callback to be called on loop prepare
34
+ def progress(callback = nil, &blk)
35
+ @callback = callback || blk
36
+ end
37
+
38
+
39
+ private
40
+
41
+
42
+ def on_prepare(handle, status)
43
+ e = check_result(status)
44
+
45
+ if e
46
+ reject(e)
47
+ else
48
+ begin
49
+ @callback.call
50
+ rescue Exception => e
51
+ @loop.log :error, :prepare_cb, e
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end