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/tty.rb
CHANGED
@@ -1,34 +1,37 @@
|
|
1
|
-
module Libuv
|
2
|
-
class TTY < Handle
|
3
|
-
include Stream
|
4
|
-
|
5
|
-
|
6
|
-
def initialize(loop, fileno, readable)
|
7
|
-
@loop = loop
|
8
|
-
|
9
|
-
tty_ptr = ::Libuv::Ext.create_handle(:uv_tty)
|
10
|
-
error = check_result(::Libuv::Ext.tty_init(loop.handle, tty_ptr, fileno, readable ? 1 : 0))
|
11
|
-
|
12
|
-
super(tty_ptr, error)
|
13
|
-
end
|
14
|
-
|
15
|
-
def enable_raw_mode
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
1
|
+
module Libuv
|
2
|
+
class TTY < Handle
|
3
|
+
include Stream
|
4
|
+
|
5
|
+
|
6
|
+
def initialize(loop, fileno, readable)
|
7
|
+
@loop = loop
|
8
|
+
|
9
|
+
tty_ptr = ::Libuv::Ext.create_handle(:uv_tty)
|
10
|
+
error = check_result(::Libuv::Ext.tty_init(loop.handle, tty_ptr, fileno, readable ? 1 : 0))
|
11
|
+
|
12
|
+
super(tty_ptr, error)
|
13
|
+
end
|
14
|
+
|
15
|
+
def enable_raw_mode
|
16
|
+
return if @closed
|
17
|
+
check_result ::Libuv::Ext.tty_set_mode(handle, 1)
|
18
|
+
end
|
19
|
+
|
20
|
+
def disable_raw_mode
|
21
|
+
return if @closed
|
22
|
+
check_result ::Libuv::Ext.tty_set_mode(handle, 0)
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset_mode
|
26
|
+
::Libuv::Ext.tty_reset_mode
|
27
|
+
end
|
28
|
+
|
29
|
+
def winsize
|
30
|
+
return [] if @closed
|
31
|
+
width = FFI::MemoryPointer.new(:int)
|
32
|
+
height = FFI::MemoryPointer.new(:int)
|
33
|
+
::Libuv::Ext.tty_get_winsize(handle, width, height)
|
34
|
+
[width.get_int(0), height.get_int(0)]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/libuv/udp.rb
CHANGED
@@ -1,256 +1,274 @@
|
|
1
|
-
module Libuv
|
2
|
-
class UDP < Handle
|
3
|
-
include Net
|
4
|
-
|
5
|
-
|
6
|
-
SEND_DATA_ERROR = "data must be a String".freeze
|
7
|
-
TTL_ARGUMENT_ERROR = "ttl must be an Integer".freeze
|
8
|
-
MULTICAST_ARGUMENT_ERROR = "multicast_address must be a String".freeze
|
9
|
-
INTERFACE_ARGUMENT_ERROR = "interface_address must be a String".freeze
|
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
|
-
error = check_result ::Libuv::Ext.
|
57
|
-
reject(error) if error
|
58
|
-
end
|
59
|
-
|
60
|
-
def
|
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
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
error
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
if
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
1
|
+
module Libuv
|
2
|
+
class UDP < Handle
|
3
|
+
include Net
|
4
|
+
|
5
|
+
|
6
|
+
SEND_DATA_ERROR = "data must be a String".freeze
|
7
|
+
TTL_ARGUMENT_ERROR = "ttl must be an Integer".freeze
|
8
|
+
MULTICAST_ARGUMENT_ERROR = "multicast_address must be a String".freeze
|
9
|
+
INTERFACE_ARGUMENT_ERROR = "interface_address must be a String".freeze
|
10
|
+
HANDLE_CLOSED_ERROR = "unable to send as handle closed".freeze
|
11
|
+
|
12
|
+
|
13
|
+
def initialize(loop)
|
14
|
+
@loop = loop
|
15
|
+
|
16
|
+
udp_ptr = ::Libuv::Ext.create_handle(:uv_udp)
|
17
|
+
error = check_result(::Libuv::Ext.udp_init(loop.handle, udp_ptr))
|
18
|
+
|
19
|
+
super(udp_ptr, error)
|
20
|
+
end
|
21
|
+
|
22
|
+
def bind(ip, port, ipv6_only = false)
|
23
|
+
return if @closed
|
24
|
+
assert_type(String, ip, IP_ARGUMENT_ERROR)
|
25
|
+
assert_type(Integer, port, PORT_ARGUMENT_ERROR)
|
26
|
+
|
27
|
+
begin
|
28
|
+
@udp_socket = create_socket(IPAddr.new(ip), port)
|
29
|
+
@udp_socket.bind(ipv6_only)
|
30
|
+
rescue Exception => e
|
31
|
+
reject(e)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def sockname
|
36
|
+
return [] if @closed
|
37
|
+
sockaddr, len = get_sockaddr_and_len
|
38
|
+
check_result! ::Libuv::Ext.udp_getsockname(handle, sockaddr, len)
|
39
|
+
get_ip_and_port(UV::Sockaddr.new(sockaddr), len.get_int(0))
|
40
|
+
end
|
41
|
+
|
42
|
+
def join(multicast_address, interface_address)
|
43
|
+
return if @closed
|
44
|
+
assert_type(String, multicast_address, MULTICAST_ARGUMENT_ERROR)
|
45
|
+
assert_type(String, interface_address, INTERFACE_ARGUMENT_ERROR)
|
46
|
+
|
47
|
+
error = check_result ::Libuv::Ext.udp_set_membership(handle, multicast_address, interface_address, :uv_join_group)
|
48
|
+
reject(error) if error
|
49
|
+
end
|
50
|
+
|
51
|
+
def leave(multicast_address, interface_address)
|
52
|
+
return if @closed
|
53
|
+
assert_type(String, multicast_address, MULTICAST_ARGUMENT_ERROR)
|
54
|
+
assert_type(String, interface_address, INTERFACE_ARGUMENT_ERROR)
|
55
|
+
|
56
|
+
error = check_result ::Libuv::Ext.udp_set_membership(handle, multicast_address, interface_address, :uv_leave_group)
|
57
|
+
reject(error) if error
|
58
|
+
end
|
59
|
+
|
60
|
+
def start_recv
|
61
|
+
return if @closed
|
62
|
+
error = check_result ::Libuv::Ext.udp_recv_start(handle, callback(:on_allocate), callback(:on_recv))
|
63
|
+
reject(error) if error
|
64
|
+
end
|
65
|
+
|
66
|
+
def stop_recv
|
67
|
+
return if @closed
|
68
|
+
error = check_result ::Libuv::Ext.udp_recv_stop(handle)
|
69
|
+
reject(error) if error
|
70
|
+
end
|
71
|
+
|
72
|
+
def send(ip, port, data)
|
73
|
+
# NOTE:: Similar to stream.rb -> write
|
74
|
+
deferred = @loop.defer
|
75
|
+
if !@closed
|
76
|
+
begin
|
77
|
+
assert_type(String, ip, IP_ARGUMENT_ERROR)
|
78
|
+
assert_type(Integer, port, PORT_ARGUMENT_ERROR)
|
79
|
+
assert_type(String, data, SEND_DATA_ERROR)
|
80
|
+
|
81
|
+
@udp_socket = create_socket(IPAddr.new(ip), port)
|
82
|
+
|
83
|
+
# local as this variable will be avaliable until the handle is closed
|
84
|
+
@sent_callbacks = @sent_callbacks || []
|
85
|
+
|
86
|
+
#
|
87
|
+
# create the curried callback
|
88
|
+
#
|
89
|
+
callback = FFI::Function.new(:void, [:pointer, :int]) do |req, status|
|
90
|
+
::Libuv::Ext.free(req)
|
91
|
+
# remove the callback from the array
|
92
|
+
# assumes sends are done in order
|
93
|
+
promise = @sent_callbacks.shift[0]
|
94
|
+
resolve promise, status
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Save the callback and return the promise
|
99
|
+
#
|
100
|
+
begin
|
101
|
+
@sent_callbacks << [deferred, callback]
|
102
|
+
@udp_socket.send(data, callback)
|
103
|
+
rescue Exception => e
|
104
|
+
@sent_callbacks.pop
|
105
|
+
deferred.reject(e)
|
106
|
+
|
107
|
+
reject(e) # close the handle
|
108
|
+
end
|
109
|
+
rescue Exception => e
|
110
|
+
deferred.reject(e)
|
111
|
+
end
|
112
|
+
else
|
113
|
+
deferred.reject(RuntimeError.new(HANDLE_CLOSED_ERROR))
|
114
|
+
end
|
115
|
+
deferred.promise
|
116
|
+
end
|
117
|
+
|
118
|
+
def enable_multicast_loop
|
119
|
+
return if @closed
|
120
|
+
error = check_result ::Libuv::Ext.udp_set_multicast_loop(handle, 1)
|
121
|
+
reject(error) if error
|
122
|
+
end
|
123
|
+
|
124
|
+
def disable_multicast_loop
|
125
|
+
return if @closed
|
126
|
+
error = check_result ::Libuv::Ext.udp_set_multicast_loop(handle, 0)
|
127
|
+
reject(error) if error
|
128
|
+
end
|
129
|
+
|
130
|
+
def multicast_ttl=(ttl)
|
131
|
+
return if @closed
|
132
|
+
assert_type(Integer, ttl, TTL_ARGUMENT_ERROR)
|
133
|
+
error = check_result ::Libuv::Ext.udp_set_multicast_ttl(handle, ttl)
|
134
|
+
reject(error) if error
|
135
|
+
end
|
136
|
+
|
137
|
+
def enable_broadcast
|
138
|
+
return if @closed
|
139
|
+
error = check_result ::Libuv::Ext.udp_set_broadcast(handle, 1)
|
140
|
+
reject(error) if error
|
141
|
+
end
|
142
|
+
|
143
|
+
def disable_broadcast
|
144
|
+
return if @closed
|
145
|
+
error = check_result ::Libuv::Ext.udp_set_broadcast(handle, 0)
|
146
|
+
reject(error) if error
|
147
|
+
end
|
148
|
+
|
149
|
+
def ttl=(ttl)
|
150
|
+
return if @closed
|
151
|
+
assert_type(Integer, ttl, TTL_ARGUMENT_ERROR)
|
152
|
+
error = check_result ::Libuv::Ext.udp_set_ttl(handle, Integer(ttl))
|
153
|
+
reject(error) if error
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
|
160
|
+
def on_allocate(client, suggested_size)
|
161
|
+
::Libuv::Ext.buf_init(::Libuv::Ext.malloc(suggested_size), suggested_size)
|
162
|
+
end
|
163
|
+
|
164
|
+
def on_recv(handle, nread, buf, sockaddr, flags)
|
165
|
+
e = check_result(nread)
|
166
|
+
base = buf[:base]
|
167
|
+
|
168
|
+
if e
|
169
|
+
::Libuv::Ext.free(base)
|
170
|
+
reject(e)
|
171
|
+
else
|
172
|
+
data = base.read_string(nread)
|
173
|
+
::Libuv::Ext.free(base)
|
174
|
+
unless sockaddr.null?
|
175
|
+
ip, port = get_ip_and_port(UV::Sockaddr.new(sockaddr))
|
176
|
+
end
|
177
|
+
defer.notify(data, ip, port) # stream the data
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def create_socket(ip, port)
|
182
|
+
if ip.ipv4?
|
183
|
+
Socket4.new(@loop, handle, ip, port)
|
184
|
+
else
|
185
|
+
Socket6.new(@loop, handle, ip, port)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
module SocketMethods
|
191
|
+
include Resource
|
192
|
+
|
193
|
+
def initialize(loop, udp, ip, port)
|
194
|
+
@loop, @udp, @sockaddr = loop, udp, ip_addr(ip.to_s, port)
|
195
|
+
end
|
196
|
+
|
197
|
+
def bind(ipv6_only = false)
|
198
|
+
check_result! udp_bind(ipv6_only)
|
199
|
+
end
|
200
|
+
|
201
|
+
def send(data, callback)
|
202
|
+
check_result! udp_send(data, callback)
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
private
|
207
|
+
|
208
|
+
|
209
|
+
def send_req
|
210
|
+
::Libuv::Ext.create_request(:uv_udp_send)
|
211
|
+
end
|
212
|
+
|
213
|
+
def buf_init(data)
|
214
|
+
::Libuv::Ext.buf_init(FFI::MemoryPointer.from_string(data), data.respond_to?(:bytesize) ? data.bytesize : data.size)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
class Socket4
|
220
|
+
include SocketMethods
|
221
|
+
|
222
|
+
|
223
|
+
private
|
224
|
+
|
225
|
+
|
226
|
+
def ip_addr(ip, port)
|
227
|
+
::Libuv::Ext.ip4_addr(ip, port)
|
228
|
+
end
|
229
|
+
|
230
|
+
def udp_bind(ipv6_only)
|
231
|
+
::Libuv::Ext.udp_bind(@udp, @sockaddr, 0)
|
232
|
+
end
|
233
|
+
|
234
|
+
def udp_send(data, callback)
|
235
|
+
::Libuv::Ext.udp_send(
|
236
|
+
send_req,
|
237
|
+
@udp,
|
238
|
+
buf_init(data),
|
239
|
+
1,
|
240
|
+
@sockaddr,
|
241
|
+
callback
|
242
|
+
)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
class Socket6 < Socket
|
248
|
+
include SocketMethods
|
249
|
+
|
250
|
+
|
251
|
+
private
|
252
|
+
|
253
|
+
|
254
|
+
def ip_addr(ip, port)
|
255
|
+
::Libuv::Ext.ip6_addr(ip, port)
|
256
|
+
end
|
257
|
+
|
258
|
+
def udp_bind(ipv6_only)
|
259
|
+
::Libuv::Ext.udp_bind6(@udp, @sockaddr, ipv6_only ? 1 : 0)
|
260
|
+
end
|
261
|
+
|
262
|
+
def udp_send(data, callback)
|
263
|
+
::Libuv::Ext.udp_send6(
|
264
|
+
send_req,
|
265
|
+
@udp,
|
266
|
+
buf_init(data),
|
267
|
+
1,
|
268
|
+
@sockaddr,
|
269
|
+
callback
|
270
|
+
)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
256
274
|
end
|