libuv 0.10.0 → 0.10.2

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