libuv 0.11.4 → 0.11.5

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 +6 -14
  2. data/.gitignore +17 -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 +82 -82
  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 +73 -73
  15. data/lib/libuv/ext/ext.rb +258 -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 +29 -29
  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 +11 -11
  24. data/lib/libuv/ext/types.rb +238 -238
  25. data/lib/libuv/file.rb +191 -191
  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 +387 -387
  31. data/lib/libuv/mixins/assertions.rb +23 -23
  32. data/lib/libuv/mixins/fs_checks.rb +55 -55
  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 +154 -154
  37. data/lib/libuv/pipe.rb +197 -197
  38. data/lib/libuv/prepare.rb +56 -56
  39. data/lib/libuv/signal.rb +51 -51
  40. data/lib/libuv/tcp.rb +317 -317
  41. data/lib/libuv/timer.rb +91 -91
  42. data/lib/libuv/tty.rb +37 -37
  43. data/lib/libuv/udp.rb +224 -224
  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 +60 -60
  48. data/spec/cpu_spec.rb +10 -10
  49. data/spec/defer_spec.rb +980 -980
  50. data/spec/dns_spec.rb +90 -90
  51. data/spec/filesystem_spec.rb +124 -124
  52. data/spec/idle_spec.rb +56 -56
  53. data/spec/pipe_spec.rb +160 -160
  54. data/spec/tcp_spec.rb +267 -267
  55. metadata +29 -21
@@ -1,197 +1,197 @@
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
- begin
142
- @callback.call(self)
143
- rescue Exception => e
144
- @loop.log :error, :pipe_connect_cb, e
145
- end
146
- end
147
-
148
- def on_read2(handle, nread, buf, pending)
149
- if pending != :uv_unknown_handle
150
- # similar to regular read in stream
151
- e = check_result(nread)
152
- base = buf[:base]
153
-
154
- if e
155
- ::Libuv::Ext.free(base)
156
- reject(e)
157
- else
158
- data = base.read_string(nread)
159
- ::Libuv::Ext.free(base)
160
-
161
- # Hide the accept logic
162
- remote = nil
163
- begin
164
- case pending
165
- when :uv_tcp
166
- remote = TCP.new(loop, handle)
167
- when :uv_pipe
168
- remote = Pipe.new(loop, @ipc, handle)
169
- else
170
- raise NotImplementedError, "IPC for handle #{pending} not supported"
171
- end
172
- rescue Exception => e
173
- remote = nil
174
- @loop.log :info, :pipe_read2_failed, e
175
- reject(e) # if accept fails we should close the socket to avoid a stale pipe
176
- end
177
- if remote
178
- # stream the data and new socket
179
- begin
180
- @progress.call data, remote
181
- rescue Exception => e
182
- @loop.log :error, :stream_progress_cb, e
183
- end
184
- end
185
- end
186
- end
187
- end
188
-
189
- def windows_path(name)
190
- # test for \\\\.\\pipe
191
- if not name =~ /(\/|\\){2}\.(\/|\\)pipe/i
192
- name = ::File.join("\\\\.\\pipe", name)
193
- end
194
- name.gsub("/", "\\")
195
- end
196
- end
197
- 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
+ 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
+ begin
142
+ @callback.call(self)
143
+ rescue Exception => e
144
+ @loop.log :error, :pipe_connect_cb, e
145
+ end
146
+ end
147
+
148
+ def on_read2(handle, nread, buf, pending)
149
+ if pending != :uv_unknown_handle
150
+ # similar to regular read in stream
151
+ e = check_result(nread)
152
+ base = buf[:base]
153
+
154
+ if e
155
+ ::Libuv::Ext.free(base)
156
+ reject(e)
157
+ else
158
+ data = base.read_string(nread)
159
+ ::Libuv::Ext.free(base)
160
+
161
+ # Hide the accept logic
162
+ remote = nil
163
+ begin
164
+ case pending
165
+ when :uv_tcp
166
+ remote = TCP.new(loop, handle)
167
+ when :uv_pipe
168
+ remote = Pipe.new(loop, @ipc, handle)
169
+ else
170
+ raise NotImplementedError, "IPC for handle #{pending} not supported"
171
+ end
172
+ rescue Exception => e
173
+ remote = nil
174
+ @loop.log :info, :pipe_read2_failed, e
175
+ reject(e) # if accept fails we should close the socket to avoid a stale pipe
176
+ end
177
+ if remote
178
+ # stream the data and new socket
179
+ begin
180
+ @progress.call data, remote
181
+ rescue Exception => e
182
+ @loop.log :error, :stream_progress_cb, e
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ def windows_path(name)
190
+ # test for \\\\.\\pipe
191
+ if not name =~ /(\/|\\){2}\.(\/|\\)pipe/i
192
+ name = ::File.join("\\\\.\\pipe", name)
193
+ end
194
+ name.gsub("/", "\\")
195
+ end
196
+ end
197
+ end
@@ -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