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.
- data/.gitignore +17 -17
- data/.gitmodules +3 -3
- data/.rspec +1 -1
- data/.travis.yml +16 -16
- data/Gemfile +2 -2
- data/LICENSE +23 -23
- data/README.md +82 -73
- data/Rakefile +31 -31
- data/lib/libuv.rb +53 -34
- data/lib/libuv/async.rb +47 -33
- data/lib/libuv/check.rb +55 -48
- data/lib/libuv/error.rb +70 -70
- data/lib/libuv/ext/ext.rb +264 -256
- data/lib/libuv/ext/platform/darwin_x64.rb +12 -12
- data/lib/libuv/ext/platform/linux.rb +7 -7
- data/lib/libuv/ext/platform/unix.rb +13 -13
- data/lib/libuv/ext/platform/windows.rb +26 -26
- data/lib/libuv/ext/tasks.rb +27 -27
- data/lib/libuv/ext/tasks/mac.rb +23 -23
- data/lib/libuv/ext/tasks/unix.rb +23 -23
- data/lib/libuv/ext/tasks/win.rb +11 -11
- data/lib/libuv/ext/types.rb +234 -229
- data/lib/libuv/file.rb +192 -0
- data/lib/libuv/filesystem.rb +233 -0
- data/lib/libuv/fs_event.rb +31 -31
- data/lib/libuv/handle.rb +85 -81
- data/lib/libuv/idle.rb +56 -49
- data/lib/libuv/loop.rb +338 -310
- data/lib/libuv/{assertions.rb → mixins/assertions.rb} +23 -23
- data/lib/libuv/mixins/fs_checks.rb +55 -0
- data/lib/libuv/{listener.rb → mixins/listener.rb} +34 -34
- data/lib/libuv/{net.rb → mixins/net.rb} +37 -37
- data/lib/libuv/{resource.rb → mixins/resource.rb} +27 -27
- data/lib/libuv/{stream.rb → mixins/stream.rb} +143 -123
- data/lib/libuv/pipe.rb +197 -97
- data/lib/libuv/prepare.rb +56 -49
- data/lib/libuv/q.rb +1 -1
- data/lib/libuv/signal.rb +51 -0
- data/lib/libuv/tcp.rb +204 -193
- data/lib/libuv/timer.rb +88 -75
- data/lib/libuv/tty.rb +37 -34
- data/lib/libuv/udp.rb +273 -255
- data/lib/libuv/version.rb +3 -3
- data/lib/libuv/work.rb +63 -61
- data/libuv.gemspec +54 -54
- data/spec/async_spec.rb +60 -60
- data/spec/cpu_spec.rb +10 -0
- data/spec/defer_spec.rb +980 -980
- data/spec/filesystem_spec.rb +119 -0
- data/spec/idle_spec.rb +56 -56
- data/spec/pipe_spec.rb +153 -148
- data/spec/tcp_spec.rb +203 -188
- metadata +73 -49
- checksums.yaml +0 -15
- 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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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 = []
|
data/lib/libuv/signal.rb
ADDED
@@ -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
|