libuv 0.11.22 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +19 -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 +89 -89
  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 +78 -74
  15. data/lib/libuv/ext/ext.rb +260 -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 +31 -31
  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 +14 -14
  24. data/lib/libuv/ext/types.rb +238 -238
  25. data/lib/libuv/file.rb +281 -269
  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 +412 -412
  31. data/lib/libuv/mixins/assertions.rb +23 -23
  32. data/lib/libuv/mixins/fs_checks.rb +60 -58
  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 +153 -154
  37. data/lib/libuv/pipe.rb +184 -203
  38. data/lib/libuv/prepare.rb +56 -56
  39. data/lib/libuv/signal.rb +51 -51
  40. data/lib/libuv/tcp.rb +334 -334
  41. data/lib/libuv/timer.rb +85 -85
  42. data/lib/libuv/tty.rb +37 -37
  43. data/lib/libuv/udp.rb +240 -240
  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 +61 -60
  48. data/spec/cpu_spec.rb +10 -10
  49. data/spec/defer_spec.rb +980 -980
  50. data/spec/dns_spec.rb +96 -90
  51. data/spec/filesystem_spec.rb +270 -261
  52. data/spec/idle_spec.rb +56 -56
  53. data/spec/pipe_spec.rb +160 -160
  54. data/spec/tcp_spec.rb +271 -267
  55. metadata +64 -51
data/lib/libuv/timer.rb CHANGED
@@ -1,85 +1,85 @@
1
- module Libuv
2
- class Timer < Handle
3
-
4
- # @param loop [::Libuv::Loop] loop this timer will be associated
5
- # @param callback [Proc] callback to be called when the timer is triggered
6
- def initialize(loop, callback = nil)
7
- @loop, @callback = loop, callback
8
-
9
- timer_ptr = ::Libuv::Ext.create_handle(:uv_timer)
10
- error = check_result(::Libuv::Ext.timer_init(loop.handle, timer_ptr))
11
- @stopped = true
12
-
13
- super(timer_ptr, error)
14
- end
15
-
16
- # Enables the timer. A repeat of 0 means no repeat
17
- #
18
- # @param timeout [Fixnum] time in milliseconds before the timer callback is triggered the first time
19
- # @param repeat [Fixnum] time in milliseconds between repeated callbacks after the first
20
- def start(timeout, repeat = 0)
21
- return if @closed
22
- @stopped = false
23
-
24
- timeout = timeout.to_i
25
- repeat = repeat.to_i
26
-
27
- error = check_result ::Libuv::Ext.timer_start(handle, callback(:on_timer), timeout, repeat)
28
- reject(error) if error
29
- end
30
-
31
- # Disables the timer.
32
- def stop
33
- return if @stopped || @closed
34
- @stopped = true
35
- error = check_result ::Libuv::Ext.timer_stop(handle)
36
- reject(error) if error
37
- end
38
-
39
- # Resets the current repeat
40
- def again
41
- return if @closed
42
- error = check_result ::Libuv::Ext.timer_again(handle)
43
- reject(error) if error
44
- end
45
-
46
- # Updates the repeat timeout
47
- def repeat=(repeat)
48
- return if @closed
49
- repeat = repeat.to_i
50
- check_result ::Libuv::Ext.timer_set_repeat(handle, repeat)
51
- reject(error) if error
52
- end
53
-
54
- # Returns the current repeat timeout
55
- def repeat
56
- return if @closed
57
- ::Libuv::Ext.timer_get_repeat(handle)
58
- end
59
-
60
- # Used to update the callback to be triggered by the timer
61
- #
62
- # @param callback [Proc] the callback to be called by the timer
63
- def progress(callback = nil, &blk)
64
- @callback = callback || blk
65
- end
66
-
67
-
68
- private
69
-
70
-
71
- def on_timer(handle, status)
72
- e = check_result(status)
73
-
74
- if e
75
- reject(e)
76
- else
77
- begin
78
- @callback.call
79
- rescue Exception => e
80
- @loop.log :error, :timer_cb, e
81
- end
82
- end
83
- end
84
- end
85
- end
1
+ module Libuv
2
+ class Timer < Handle
3
+
4
+ # @param loop [::Libuv::Loop] loop this timer will be associated
5
+ # @param callback [Proc] callback to be called when the timer is triggered
6
+ def initialize(loop, callback = nil)
7
+ @loop, @callback = loop, callback
8
+
9
+ timer_ptr = ::Libuv::Ext.create_handle(:uv_timer)
10
+ error = check_result(::Libuv::Ext.timer_init(loop.handle, timer_ptr))
11
+ @stopped = true
12
+
13
+ super(timer_ptr, error)
14
+ end
15
+
16
+ # Enables the timer. A repeat of 0 means no repeat
17
+ #
18
+ # @param timeout [Fixnum] time in milliseconds before the timer callback is triggered the first time
19
+ # @param repeat [Fixnum] time in milliseconds between repeated callbacks after the first
20
+ def start(timeout, repeat = 0)
21
+ return if @closed
22
+ @stopped = false
23
+
24
+ timeout = timeout.to_i
25
+ repeat = repeat.to_i
26
+
27
+ error = check_result ::Libuv::Ext.timer_start(handle, callback(:on_timer), timeout, repeat)
28
+ reject(error) if error
29
+ end
30
+
31
+ # Disables the timer.
32
+ def stop
33
+ return if @stopped || @closed
34
+ @stopped = true
35
+ error = check_result ::Libuv::Ext.timer_stop(handle)
36
+ reject(error) if error
37
+ end
38
+
39
+ # Resets the current repeat
40
+ def again
41
+ return if @closed
42
+ error = check_result ::Libuv::Ext.timer_again(handle)
43
+ reject(error) if error
44
+ end
45
+
46
+ # Updates the repeat timeout
47
+ def repeat=(repeat)
48
+ return if @closed
49
+ repeat = repeat.to_i
50
+ check_result ::Libuv::Ext.timer_set_repeat(handle, repeat)
51
+ reject(error) if error
52
+ end
53
+
54
+ # Returns the current repeat timeout
55
+ def repeat
56
+ return if @closed
57
+ ::Libuv::Ext.timer_get_repeat(handle)
58
+ end
59
+
60
+ # Used to update the callback to be triggered by the timer
61
+ #
62
+ # @param callback [Proc] the callback to be called by the timer
63
+ def progress(callback = nil, &blk)
64
+ @callback = callback || blk
65
+ end
66
+
67
+
68
+ private
69
+
70
+
71
+ def on_timer(handle, status)
72
+ e = check_result(status)
73
+
74
+ if e
75
+ reject(e)
76
+ else
77
+ begin
78
+ @callback.call
79
+ rescue Exception => e
80
+ @loop.log :error, :timer_cb, e
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
data/lib/libuv/tty.rb CHANGED
@@ -1,37 +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
- 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
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,241 +1,241 @@
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)
23
- return if @closed
24
- assert_type(String, ip, IP_ARGUMENT_ERROR)
25
- assert_type(Integer, port, PORT_ARGUMENT_ERROR)
26
-
27
- sockaddr = create_sockaddr(ip, port)
28
- error = check_result ::Libuv::Ext.udp_bind(handle, sockaddr, 0)
29
- reject(error) if error
30
- end
31
-
32
- def open(fd, binding = true, callback = nil, &blk)
33
- return if @closed
34
- error = check_result UV.udp_open(handle, fd)
35
- reject(error) if error
36
- end
37
-
38
- def sockname
39
- return [] if @closed
40
- sockaddr, len = get_sockaddr_and_len
41
- check_result! ::Libuv::Ext.udp_getsockname(handle, sockaddr, len)
42
- get_ip_and_port(UV::Sockaddr.new(sockaddr), len.get_int(0))
43
- end
44
-
45
- def join(multicast_address, interface_address)
46
- return if @closed
47
- assert_type(String, multicast_address, MULTICAST_ARGUMENT_ERROR)
48
- assert_type(String, interface_address, INTERFACE_ARGUMENT_ERROR)
49
-
50
- error = check_result ::Libuv::Ext.udp_set_membership(handle, multicast_address, interface_address, :uv_join_group)
51
- reject(error) if error
52
- end
53
-
54
- def leave(multicast_address, interface_address)
55
- return if @closed
56
- assert_type(String, multicast_address, MULTICAST_ARGUMENT_ERROR)
57
- assert_type(String, interface_address, INTERFACE_ARGUMENT_ERROR)
58
-
59
- error = check_result ::Libuv::Ext.udp_set_membership(handle, multicast_address, interface_address, :uv_leave_group)
60
- reject(error) if error
61
- end
62
-
63
- # Starts reading from the handle
64
- # Renamed to match Stream
65
- def start_read
66
- return if @closed
67
- error = check_result ::Libuv::Ext.udp_recv_start(handle, callback(:on_allocate), callback(:on_recv))
68
- reject(error) if error
69
- end
70
-
71
- # Stops reading from the handle
72
- # Renamed to match Stream
73
- def stop_read
74
- return if @closed
75
- error = check_result ::Libuv::Ext.udp_recv_stop(handle)
76
- reject(error) if error
77
- end
78
-
79
- def send(ip, port, data)
80
- # NOTE:: Similar to stream.rb -> write
81
- deferred = @loop.defer
82
- if !@closed
83
- begin
84
- assert_type(String, ip, IP_ARGUMENT_ERROR)
85
- assert_type(Integer, port, PORT_ARGUMENT_ERROR)
86
- assert_type(String, data, SEND_DATA_ERROR)
87
-
88
- sockaddr = create_sockaddr(ip, port)
89
-
90
- # local as this variable will be avaliable until the handle is closed
91
- @sent_callbacks ||= []
92
-
93
- #
94
- # create the curried callback
95
- #
96
- callback = FFI::Function.new(:void, [:pointer, :int]) do |req, status|
97
- ::Libuv::Ext.free(req)
98
- # remove the callback from the array
99
- # assumes sends are done in order
100
- promise = @sent_callbacks.shift[0]
101
- resolve promise, status
102
- end
103
-
104
- #
105
- # Save the callback and return the promise
106
- #
107
- @sent_callbacks << [deferred, callback]
108
- error = check_result ::Libuv::Ext.udp_send(
109
- send_req,
110
- handle,
111
- buf_init(data),
112
- 1,
113
- sockaddr,
114
- callback
115
- )
116
- if error
117
- @sent_callbacks.pop
118
- deferred.reject(error)
119
- reject(error) # close the handle
120
- end
121
- rescue StandardError => e
122
- deferred.reject(e)
123
- end
124
- else
125
- deferred.reject(RuntimeError.new(HANDLE_CLOSED_ERROR))
126
- end
127
- deferred.promise
128
- end
129
-
130
- def enable_multicast_loop
131
- return if @closed
132
- error = check_result ::Libuv::Ext.udp_set_multicast_loop(handle, 1)
133
- reject(error) if error
134
- end
135
-
136
- def disable_multicast_loop
137
- return if @closed
138
- error = check_result ::Libuv::Ext.udp_set_multicast_loop(handle, 0)
139
- reject(error) if error
140
- end
141
-
142
- def multicast_ttl=(ttl)
143
- return if @closed
144
- assert_type(Integer, ttl, TTL_ARGUMENT_ERROR)
145
- error = check_result ::Libuv::Ext.udp_set_multicast_ttl(handle, ttl)
146
- reject(error) if error
147
- end
148
-
149
- def enable_broadcast
150
- return if @closed
151
- error = check_result ::Libuv::Ext.udp_set_broadcast(handle, 1)
152
- reject(error) if error
153
- end
154
-
155
- def disable_broadcast
156
- return if @closed
157
- error = check_result ::Libuv::Ext.udp_set_broadcast(handle, 0)
158
- reject(error) if error
159
- end
160
-
161
- def ttl=(ttl)
162
- return if @closed
163
- assert_type(Integer, ttl, TTL_ARGUMENT_ERROR)
164
- error = check_result ::Libuv::Ext.udp_set_ttl(handle, Integer(ttl))
165
- reject(error) if error
166
- end
167
-
168
- def progress(callback = nil, &blk)
169
- @progress = callback || blk
170
- end
171
-
172
-
173
- private
174
-
175
-
176
- def send_req
177
- ::Libuv::Ext.create_request(:uv_udp_send)
178
- end
179
-
180
- def buf_init(data)
181
- ::Libuv::Ext.buf_init(FFI::MemoryPointer.from_string(data), data.respond_to?(:bytesize) ? data.bytesize : data.size)
182
- end
183
-
184
- def create_sockaddr(ip, port)
185
- ips = IPAddr.new(ip)
186
- if ips.ipv4?
187
- addr = Ext::SockaddrIn.new
188
- check_result! ::Libuv::Ext.ip4_addr(ip, port, addr)
189
- addr
190
- else
191
- addr = Ext::SockaddrIn6.new
192
- check_result! ::Libuv::Ext.ip6_addr(ip, port, addr)
193
- addr
194
- end
195
- end
196
-
197
-
198
- def on_close(pointer)
199
- if @receive_buff
200
- ::Libuv::Ext.free(@receive_buff)
201
- @receive_buff = nil
202
- @receive_size = nil
203
- end
204
-
205
- super(pointer)
206
- end
207
-
208
- def on_allocate(client, suggested_size, buffer)
209
- if @receive_buff.nil?
210
- @receive_buff = ::Libuv::Ext.malloc(suggested_size)
211
- @receive_size = suggested_size
212
- end
213
-
214
- buffer[:base] = @receive_buff
215
- buffer[:len] = @receive_size
216
- end
217
-
218
- def on_recv(handle, nread, buf, sockaddr, flags)
219
- e = check_result(nread)
220
-
221
- if e
222
- reject(e) # Will call close
223
- elsif nread > 0
224
- data = @receive_buff.read_string(nread)
225
- unless sockaddr.null?
226
- ip, port = get_ip_and_port(sockaddr)
227
- end
228
-
229
- begin
230
- @progress.call data, ip, port, self
231
- rescue Exception => e
232
- @loop.log :error, :udp_progress_cb, e
233
- end
234
- else
235
- ::Libuv::Ext.free(@receive_buff)
236
- @receive_buff = nil
237
- @receive_size = nil
238
- end
239
- end
240
- 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)
23
+ return if @closed
24
+ assert_type(String, ip, IP_ARGUMENT_ERROR)
25
+ assert_type(Integer, port, PORT_ARGUMENT_ERROR)
26
+
27
+ sockaddr = create_sockaddr(ip, port)
28
+ error = check_result ::Libuv::Ext.udp_bind(handle, sockaddr, 0)
29
+ reject(error) if error
30
+ end
31
+
32
+ def open(fd, binding = true, callback = nil, &blk)
33
+ return if @closed
34
+ error = check_result UV.udp_open(handle, fd)
35
+ reject(error) if error
36
+ end
37
+
38
+ def sockname
39
+ return [] if @closed
40
+ sockaddr, len = get_sockaddr_and_len
41
+ check_result! ::Libuv::Ext.udp_getsockname(handle, sockaddr, len)
42
+ get_ip_and_port(UV::Sockaddr.new(sockaddr), len.get_int(0))
43
+ end
44
+
45
+ def join(multicast_address, interface_address)
46
+ return if @closed
47
+ assert_type(String, multicast_address, MULTICAST_ARGUMENT_ERROR)
48
+ assert_type(String, interface_address, INTERFACE_ARGUMENT_ERROR)
49
+
50
+ error = check_result ::Libuv::Ext.udp_set_membership(handle, multicast_address, interface_address, :uv_join_group)
51
+ reject(error) if error
52
+ end
53
+
54
+ def leave(multicast_address, interface_address)
55
+ return if @closed
56
+ assert_type(String, multicast_address, MULTICAST_ARGUMENT_ERROR)
57
+ assert_type(String, interface_address, INTERFACE_ARGUMENT_ERROR)
58
+
59
+ error = check_result ::Libuv::Ext.udp_set_membership(handle, multicast_address, interface_address, :uv_leave_group)
60
+ reject(error) if error
61
+ end
62
+
63
+ # Starts reading from the handle
64
+ # Renamed to match Stream
65
+ def start_read
66
+ return if @closed
67
+ error = check_result ::Libuv::Ext.udp_recv_start(handle, callback(:on_allocate), callback(:on_recv))
68
+ reject(error) if error
69
+ end
70
+
71
+ # Stops reading from the handle
72
+ # Renamed to match Stream
73
+ def stop_read
74
+ return if @closed
75
+ error = check_result ::Libuv::Ext.udp_recv_stop(handle)
76
+ reject(error) if error
77
+ end
78
+
79
+ def send(ip, port, data)
80
+ # NOTE:: Similar to stream.rb -> write
81
+ deferred = @loop.defer
82
+ if !@closed
83
+ begin
84
+ assert_type(String, ip, IP_ARGUMENT_ERROR)
85
+ assert_type(Integer, port, PORT_ARGUMENT_ERROR)
86
+ assert_type(String, data, SEND_DATA_ERROR)
87
+
88
+ sockaddr = create_sockaddr(ip, port)
89
+
90
+ # local as this variable will be avaliable until the handle is closed
91
+ @sent_callbacks ||= []
92
+
93
+ #
94
+ # create the curried callback
95
+ #
96
+ callback = FFI::Function.new(:void, [:pointer, :int]) do |req, status|
97
+ ::Libuv::Ext.free(req)
98
+ # remove the callback from the array
99
+ # assumes sends are done in order
100
+ promise = @sent_callbacks.shift[0]
101
+ resolve promise, status
102
+ end
103
+
104
+ #
105
+ # Save the callback and return the promise
106
+ #
107
+ @sent_callbacks << [deferred, callback]
108
+ error = check_result ::Libuv::Ext.udp_send(
109
+ send_req,
110
+ handle,
111
+ buf_init(data),
112
+ 1,
113
+ sockaddr,
114
+ callback
115
+ )
116
+ if error
117
+ @sent_callbacks.pop
118
+ deferred.reject(error)
119
+ reject(error) # close the handle
120
+ end
121
+ rescue StandardError => e
122
+ deferred.reject(e)
123
+ end
124
+ else
125
+ deferred.reject(RuntimeError.new(HANDLE_CLOSED_ERROR))
126
+ end
127
+ deferred.promise
128
+ end
129
+
130
+ def enable_multicast_loop
131
+ return if @closed
132
+ error = check_result ::Libuv::Ext.udp_set_multicast_loop(handle, 1)
133
+ reject(error) if error
134
+ end
135
+
136
+ def disable_multicast_loop
137
+ return if @closed
138
+ error = check_result ::Libuv::Ext.udp_set_multicast_loop(handle, 0)
139
+ reject(error) if error
140
+ end
141
+
142
+ def multicast_ttl=(ttl)
143
+ return if @closed
144
+ assert_type(Integer, ttl, TTL_ARGUMENT_ERROR)
145
+ error = check_result ::Libuv::Ext.udp_set_multicast_ttl(handle, ttl)
146
+ reject(error) if error
147
+ end
148
+
149
+ def enable_broadcast
150
+ return if @closed
151
+ error = check_result ::Libuv::Ext.udp_set_broadcast(handle, 1)
152
+ reject(error) if error
153
+ end
154
+
155
+ def disable_broadcast
156
+ return if @closed
157
+ error = check_result ::Libuv::Ext.udp_set_broadcast(handle, 0)
158
+ reject(error) if error
159
+ end
160
+
161
+ def ttl=(ttl)
162
+ return if @closed
163
+ assert_type(Integer, ttl, TTL_ARGUMENT_ERROR)
164
+ error = check_result ::Libuv::Ext.udp_set_ttl(handle, Integer(ttl))
165
+ reject(error) if error
166
+ end
167
+
168
+ def progress(callback = nil, &blk)
169
+ @progress = callback || blk
170
+ end
171
+
172
+
173
+ private
174
+
175
+
176
+ def send_req
177
+ ::Libuv::Ext.create_request(:uv_udp_send)
178
+ end
179
+
180
+ def buf_init(data)
181
+ ::Libuv::Ext.buf_init(FFI::MemoryPointer.from_string(data), data.respond_to?(:bytesize) ? data.bytesize : data.size)
182
+ end
183
+
184
+ def create_sockaddr(ip, port)
185
+ ips = IPAddr.new(ip)
186
+ if ips.ipv4?
187
+ addr = Ext::SockaddrIn.new
188
+ check_result! ::Libuv::Ext.ip4_addr(ip, port, addr)
189
+ addr
190
+ else
191
+ addr = Ext::SockaddrIn6.new
192
+ check_result! ::Libuv::Ext.ip6_addr(ip, port, addr)
193
+ addr
194
+ end
195
+ end
196
+
197
+
198
+ def on_close(pointer)
199
+ if @receive_buff
200
+ ::Libuv::Ext.free(@receive_buff)
201
+ @receive_buff = nil
202
+ @receive_size = nil
203
+ end
204
+
205
+ super(pointer)
206
+ end
207
+
208
+ def on_allocate(client, suggested_size, buffer)
209
+ if @receive_buff.nil?
210
+ @receive_buff = ::Libuv::Ext.malloc(suggested_size)
211
+ @receive_size = suggested_size
212
+ end
213
+
214
+ buffer[:base] = @receive_buff
215
+ buffer[:len] = @receive_size
216
+ end
217
+
218
+ def on_recv(handle, nread, buf, sockaddr, flags)
219
+ e = check_result(nread)
220
+
221
+ if e
222
+ reject(e) # Will call close
223
+ elsif nread > 0
224
+ data = @receive_buff.read_string(nread)
225
+ unless sockaddr.null?
226
+ ip, port = get_ip_and_port(sockaddr)
227
+ end
228
+
229
+ begin
230
+ @progress.call data, ip, port, self
231
+ rescue Exception => e
232
+ @loop.log :error, :udp_progress_cb, e
233
+ end
234
+ else
235
+ ::Libuv::Ext.free(@receive_buff)
236
+ @receive_buff = nil
237
+ @receive_size = nil
238
+ end
239
+ end
240
+ end
241
241
  end