libuv 0.10.0 → 0.10.2

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. data/.gitignore +17 -17
  2. data/.gitmodules +3 -3
  3. data/.rspec +1 -1
  4. data/.travis.yml +16 -16
  5. data/Gemfile +2 -2
  6. data/LICENSE +23 -23
  7. data/README.md +82 -73
  8. data/Rakefile +31 -31
  9. data/lib/libuv.rb +53 -34
  10. data/lib/libuv/async.rb +47 -33
  11. data/lib/libuv/check.rb +55 -48
  12. data/lib/libuv/error.rb +70 -70
  13. data/lib/libuv/ext/ext.rb +264 -256
  14. data/lib/libuv/ext/platform/darwin_x64.rb +12 -12
  15. data/lib/libuv/ext/platform/linux.rb +7 -7
  16. data/lib/libuv/ext/platform/unix.rb +13 -13
  17. data/lib/libuv/ext/platform/windows.rb +26 -26
  18. data/lib/libuv/ext/tasks.rb +27 -27
  19. data/lib/libuv/ext/tasks/mac.rb +23 -23
  20. data/lib/libuv/ext/tasks/unix.rb +23 -23
  21. data/lib/libuv/ext/tasks/win.rb +11 -11
  22. data/lib/libuv/ext/types.rb +234 -229
  23. data/lib/libuv/file.rb +192 -0
  24. data/lib/libuv/filesystem.rb +233 -0
  25. data/lib/libuv/fs_event.rb +31 -31
  26. data/lib/libuv/handle.rb +85 -81
  27. data/lib/libuv/idle.rb +56 -49
  28. data/lib/libuv/loop.rb +338 -310
  29. data/lib/libuv/{assertions.rb → mixins/assertions.rb} +23 -23
  30. data/lib/libuv/mixins/fs_checks.rb +55 -0
  31. data/lib/libuv/{listener.rb → mixins/listener.rb} +34 -34
  32. data/lib/libuv/{net.rb → mixins/net.rb} +37 -37
  33. data/lib/libuv/{resource.rb → mixins/resource.rb} +27 -27
  34. data/lib/libuv/{stream.rb → mixins/stream.rb} +143 -123
  35. data/lib/libuv/pipe.rb +197 -97
  36. data/lib/libuv/prepare.rb +56 -49
  37. data/lib/libuv/q.rb +1 -1
  38. data/lib/libuv/signal.rb +51 -0
  39. data/lib/libuv/tcp.rb +204 -193
  40. data/lib/libuv/timer.rb +88 -75
  41. data/lib/libuv/tty.rb +37 -34
  42. data/lib/libuv/udp.rb +273 -255
  43. data/lib/libuv/version.rb +3 -3
  44. data/lib/libuv/work.rb +63 -61
  45. data/libuv.gemspec +54 -54
  46. data/spec/async_spec.rb +60 -60
  47. data/spec/cpu_spec.rb +10 -0
  48. data/spec/defer_spec.rb +980 -980
  49. data/spec/filesystem_spec.rb +119 -0
  50. data/spec/idle_spec.rb +56 -56
  51. data/spec/pipe_spec.rb +153 -148
  52. data/spec/tcp_spec.rb +203 -188
  53. metadata +73 -49
  54. checksums.yaml +0 -15
  55. data/lib/libuv/simple_async.rb +0 -28
data/lib/libuv/pipe.rb CHANGED
@@ -1,97 +1,197 @@
1
- module Libuv
2
- class Pipe < Handle
3
- include Stream
4
-
5
-
6
- def initialize(loop, ipc, acceptor = nil)
7
- @loop, @ipc = loop, ipc
8
-
9
- pipe_ptr = ::Libuv::Ext.create_handle(:uv_pipe)
10
- error = check_result(::Libuv::Ext.pipe_init(loop.handle, pipe_ptr, ipc ? 1 : 0))
11
- error = check_result(::Libuv::Ext.accept(acceptor, pipe_ptr)) if acceptor && error.nil?
12
-
13
- super(pipe_ptr, error)
14
- end
15
-
16
- def bind(name, callback = nil, &blk)
17
- @on_listen = callback || blk
18
- assert_type(String, name, "name must be a String")
19
- name = windows_path name if FFI::Platform.windows?
20
-
21
- error = check_result ::Libuv::Ext.pipe_bind(handle, name)
22
- reject(error) if error
23
- end
24
-
25
- def accept(callback = nil, &blk)
26
- pipe = nil
27
- begin
28
- pipe = Pipe.new(loop, @ipc, handle)
29
- rescue Exception => e
30
- @loop.log :info, :pipe_accept_failed, e
31
- end
32
- if pipe
33
- begin
34
- (callback || blk).call(pipe)
35
- rescue Exception => e
36
- @loop.log :error, :pipe_accept_cb, e
37
- end
38
- end
39
- nil
40
- end
41
-
42
- def open(fileno, callback = nil, &blk)
43
- @callback = callback || blk
44
- assert_type(Integer, fileno, "io#fileno must return an integer file descriptor")
45
- begin
46
- check_result! ::Libuv::Ext.pipe_open(handle, fileno)
47
-
48
- # Emulate on_connect behavior
49
- begin
50
- @callback.call(self)
51
- rescue Exception => e
52
- @loop.log :error, :pipe_connect_cb, e
53
- end
54
- rescue Exception => e
55
- reject(e)
56
- end
57
- end
58
-
59
- def connect(name, callback = nil, &blk)
60
- @callback = callback || blk
61
- assert_type(String, name, "name must be a String")
62
- begin
63
- name = windows_path name if FFI::Platform.windows?
64
- ::Libuv::Ext.pipe_connect(::Libuv::Ext.create_request(:uv_connect), handle, name, callback(:on_connect))
65
- rescue Exception => e
66
- reject(e)
67
- end
68
- end
69
-
70
- # Windows only
71
- def pending_instances=(count)
72
- assert_type(Integer, count, "count must be an Integer")
73
- ::Libuv::Ext.pipe_pending_instances(handle, count)
74
- end
75
-
76
-
77
- private
78
-
79
-
80
- def on_connect(req, status)
81
- ::Libuv::Ext.free(req)
82
- begin
83
- @callback.call(self)
84
- rescue Exception => e
85
- @loop.log :error, :pipe_connect_cb, e
86
- end
87
- end
88
-
89
- def windows_path(name)
90
- # test for \\\\.\\pipe
91
- if not name =~ /(\/|\\){2}\.(\/|\\)pipe/i
92
- name = ::File.join("\\\\.\\pipe", name)
93
- end
94
- name.gsub("/", "\\")
95
- end
96
- end
97
- 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
data/lib/libuv/prepare.rb CHANGED
@@ -1,49 +1,56 @@
1
- module Libuv
2
- class Prepare < Handle
3
-
4
-
5
- def initialize(loop, callback = nil, &blk)
6
- @loop = loop
7
- @callback = callback || blk
8
-
9
- prepare_ptr = ::Libuv::Ext.create_handle(:uv_prepare)
10
- error = check_result(::Libuv::Ext.prepare_init(@pointer, prepare_ptr))
11
-
12
- super(prepare_ptr, error)
13
- end
14
-
15
- def start
16
- return if @closed
17
- error = check_result ::Libuv::Ext.prepare_start(handle, callback(:on_prepare))
18
- reject(error) if error
19
- end
20
-
21
- def stop
22
- return if @closed
23
- error = check_result ::Libuv::Ext.prepare_stop(handle)
24
- reject(error) if error
25
- end
26
-
27
- def progress(callback = nil, &blk)
28
- @callback = callback || blk
29
- end
30
-
31
-
32
- private
33
-
34
-
35
- def on_prepare(handle, status)
36
- e = check_result(status)
37
-
38
- if e
39
- reject(e)
40
- else
41
- begin
42
- @callback.call
43
- rescue Exception => e
44
- @loop.log :error, :prepare_cb, e
45
- end
46
- end
47
- end
48
- end
49
- 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(@pointer, 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
data/lib/libuv/q.rb CHANGED
@@ -382,7 +382,7 @@ module Libuv
382
382
  # @param [*Promise] Promises a number of promises that will be combined into a single promise
383
383
  # @return [Promise] Returns a single promise that will be resolved with an array of values,
384
384
  # each [result, wasResolved] value pair corresponding to a at the same index in the `promises` array.
385
- def finally(loop, *promises)
385
+ def self.finally(loop, *promises)
386
386
  deferred = Q.defer(loop)
387
387
  counter = promises.length
388
388
  results = []
@@ -0,0 +1,51 @@
1
+ module Libuv
2
+ class Signal < Handle
3
+
4
+
5
+ SIGNALS = {
6
+ :HUP => 1,
7
+ :SIGHUP => 1,
8
+ :INT => 2,
9
+ :SIGINT => 2,
10
+ :BREAK => 21,
11
+ :SIGBREAK => 21,
12
+ :WINCH => 28,
13
+ :SIGWINCH => 28
14
+ }
15
+
16
+
17
+ # @param loop [::Libuv::Loop] loop this signal handler will be associated
18
+ # @param callback [Proc] callback to be called when the signal is triggered
19
+ def initialize(loop)
20
+ @loop = loop
21
+
22
+ signal_ptr = ::Libuv::Ext.create_handle(:uv_signal)
23
+ error = check_result(::Libuv::Ext.signal_init(loop.handle, signal_ptr))
24
+
25
+ super(signal_ptr, error)
26
+ end
27
+
28
+ # Enables the signal handler.
29
+ def start(signal)
30
+ return if @closed
31
+ signal = SIGNALS[signal] if signal.is_a? Symbol
32
+ error = check_result ::Libuv::Ext.signal_start(handle, callback(:on_sig), signal)
33
+ reject(error) if error
34
+ end
35
+
36
+ # Disables the signal handler.
37
+ def stop
38
+ return if @closed
39
+ error = check_result ::Libuv::Ext.signal_stop(handle)
40
+ reject(error) if error
41
+ end
42
+
43
+
44
+ private
45
+
46
+
47
+ def on_sig(handle, signal)
48
+ defer.notify(signal) # notify of a call
49
+ end
50
+ end
51
+ end