libuv 0.11.22 → 0.12.0

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