libuv 0.11.3 → 0.11.4

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. checksums.yaml +14 -6
  2. data/.gitignore +17 -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 +82 -82
  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 +73 -70
  15. data/lib/libuv/ext/ext.rb +258 -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 +29 -29
  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 +11 -11
  24. data/lib/libuv/ext/types.rb +238 -238
  25. data/lib/libuv/file.rb +191 -191
  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 +387 -385
  31. data/lib/libuv/mixins/assertions.rb +23 -23
  32. data/lib/libuv/mixins/fs_checks.rb +55 -55
  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 +154 -154
  37. data/lib/libuv/pipe.rb +197 -197
  38. data/lib/libuv/prepare.rb +56 -56
  39. data/lib/libuv/signal.rb +51 -51
  40. data/lib/libuv/tcp.rb +317 -315
  41. data/lib/libuv/timer.rb +91 -91
  42. data/lib/libuv/tty.rb +37 -37
  43. data/lib/libuv/udp.rb +224 -224
  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 +60 -60
  48. data/spec/cpu_spec.rb +10 -10
  49. data/spec/defer_spec.rb +980 -980
  50. data/spec/dns_spec.rb +90 -90
  51. data/spec/filesystem_spec.rb +124 -124
  52. data/spec/idle_spec.rb +56 -56
  53. data/spec/pipe_spec.rb +160 -160
  54. data/spec/tcp_spec.rb +267 -267
  55. metadata +24 -30
@@ -1,91 +1,91 @@
1
- module Libuv
2
- class Timer < Handle
3
- include Assertions
4
-
5
-
6
- TIMEOUT_ERROR = "timeout must be an Integer".freeze
7
- REPEAT_ERROR = "repeat must be an Integer".freeze
8
-
9
-
10
- # @param loop [::Libuv::Loop] loop this timer will be associated
11
- # @param callback [Proc] callback to be called when the timer is triggered
12
- def initialize(loop, callback = nil)
13
- @loop, @callback = loop, callback
14
-
15
- timer_ptr = ::Libuv::Ext.create_handle(:uv_timer)
16
- error = check_result(::Libuv::Ext.timer_init(loop.handle, timer_ptr))
17
- @stopped = true
18
-
19
- super(timer_ptr, error)
20
- end
21
-
22
- # Enables the timer. A repeat of 0 means no repeat
23
- #
24
- # @param timeout [Fixnum] time in milliseconds before the timer callback is triggered the first time
25
- # @param repeat [Fixnum] time in milliseconds between repeated callbacks after the first
26
- def start(timeout, repeat = 0)
27
- return if @closed
28
- @stopped = false
29
-
30
- assert_type(Integer, timeout, TIMEOUT_ERROR)
31
- assert_type(Integer, repeat, REPEAT_ERROR)
32
-
33
- error = check_result ::Libuv::Ext.timer_start(handle, callback(:on_timer), timeout, repeat)
34
- reject(error) if error
35
- end
36
-
37
- # Disables the timer.
38
- def stop
39
- return if @stopped || @closed
40
- @stopped = true
41
- error = check_result ::Libuv::Ext.timer_stop(handle)
42
- reject(error) if error
43
- end
44
-
45
- # Resets the current repeat
46
- def again
47
- return if @closed
48
- error = check_result ::Libuv::Ext.timer_again(handle)
49
- reject(error) if error
50
- end
51
-
52
- # Updates the repeat timeout
53
- def repeat=(repeat)
54
- return if @closed
55
- assert_type(Integer, repeat, REPEAT_ERROR)
56
- check_result ::Libuv::Ext.timer_set_repeat(handle, repeat)
57
- reject(error) if error
58
- end
59
-
60
- # Returns the current repeat timeout
61
- def repeat
62
- return if @closed
63
- ::Libuv::Ext.timer_get_repeat(handle)
64
- end
65
-
66
- # Used to update the callback to be triggered by the timer
67
- #
68
- # @param callback [Proc] the callback to be called by the timer
69
- def progress(callback = nil, &blk)
70
- @callback = callback || blk
71
- end
72
-
73
-
74
- private
75
-
76
-
77
- def on_timer(handle, status)
78
- e = check_result(status)
79
-
80
- if e
81
- reject(e)
82
- else
83
- begin
84
- @callback.call
85
- rescue Exception => e
86
- @loop.log :error, :timer_cb, e
87
- end
88
- end
89
- end
90
- end
91
- end
1
+ module Libuv
2
+ class Timer < Handle
3
+ include Assertions
4
+
5
+
6
+ TIMEOUT_ERROR = "timeout must be an Integer".freeze
7
+ REPEAT_ERROR = "repeat must be an Integer".freeze
8
+
9
+
10
+ # @param loop [::Libuv::Loop] loop this timer will be associated
11
+ # @param callback [Proc] callback to be called when the timer is triggered
12
+ def initialize(loop, callback = nil)
13
+ @loop, @callback = loop, callback
14
+
15
+ timer_ptr = ::Libuv::Ext.create_handle(:uv_timer)
16
+ error = check_result(::Libuv::Ext.timer_init(loop.handle, timer_ptr))
17
+ @stopped = true
18
+
19
+ super(timer_ptr, error)
20
+ end
21
+
22
+ # Enables the timer. A repeat of 0 means no repeat
23
+ #
24
+ # @param timeout [Fixnum] time in milliseconds before the timer callback is triggered the first time
25
+ # @param repeat [Fixnum] time in milliseconds between repeated callbacks after the first
26
+ def start(timeout, repeat = 0)
27
+ return if @closed
28
+ @stopped = false
29
+
30
+ assert_type(Integer, timeout, TIMEOUT_ERROR)
31
+ assert_type(Integer, repeat, REPEAT_ERROR)
32
+
33
+ error = check_result ::Libuv::Ext.timer_start(handle, callback(:on_timer), timeout, repeat)
34
+ reject(error) if error
35
+ end
36
+
37
+ # Disables the timer.
38
+ def stop
39
+ return if @stopped || @closed
40
+ @stopped = true
41
+ error = check_result ::Libuv::Ext.timer_stop(handle)
42
+ reject(error) if error
43
+ end
44
+
45
+ # Resets the current repeat
46
+ def again
47
+ return if @closed
48
+ error = check_result ::Libuv::Ext.timer_again(handle)
49
+ reject(error) if error
50
+ end
51
+
52
+ # Updates the repeat timeout
53
+ def repeat=(repeat)
54
+ return if @closed
55
+ assert_type(Integer, repeat, REPEAT_ERROR)
56
+ check_result ::Libuv::Ext.timer_set_repeat(handle, repeat)
57
+ reject(error) if error
58
+ end
59
+
60
+ # Returns the current repeat timeout
61
+ def repeat
62
+ return if @closed
63
+ ::Libuv::Ext.timer_get_repeat(handle)
64
+ end
65
+
66
+ # Used to update the callback to be triggered by the timer
67
+ #
68
+ # @param callback [Proc] the callback to be called by the timer
69
+ def progress(callback = nil, &blk)
70
+ @callback = callback || blk
71
+ end
72
+
73
+
74
+ private
75
+
76
+
77
+ def on_timer(handle, status)
78
+ e = check_result(status)
79
+
80
+ if e
81
+ reject(e)
82
+ else
83
+ begin
84
+ @callback.call
85
+ rescue Exception => e
86
+ @loop.log :error, :timer_cb, e
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -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
@@ -1,225 +1,225 @@
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_allocate(client, suggested_size, buffer)
199
- buffer[:len] = suggested_size
200
- buffer[:base] = ::Libuv::Ext.malloc(suggested_size)
201
- end
202
-
203
- def on_recv(handle, nread, buf, sockaddr, flags)
204
- e = check_result(nread)
205
- base = buf[:base]
206
-
207
- if e
208
- ::Libuv::Ext.free(base)
209
- reject(e)
210
- else
211
- data = base.read_string(nread)
212
- ::Libuv::Ext.free(base)
213
- unless sockaddr.null?
214
- ip, port = get_ip_and_port(UV::Sockaddr.new(sockaddr))
215
- end
216
-
217
- begin
218
- @progress.call data, ip, port, self
219
- rescue Exception => e
220
- @loop.log :error, :udp_progress_cb, e
221
- end
222
- end
223
- end
224
- 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_allocate(client, suggested_size, buffer)
199
+ buffer[:len] = suggested_size
200
+ buffer[:base] = ::Libuv::Ext.malloc(suggested_size)
201
+ end
202
+
203
+ def on_recv(handle, nread, buf, sockaddr, flags)
204
+ e = check_result(nread)
205
+ base = buf[:base]
206
+
207
+ if e
208
+ ::Libuv::Ext.free(base)
209
+ reject(e)
210
+ else
211
+ data = base.read_string(nread)
212
+ ::Libuv::Ext.free(base)
213
+ unless sockaddr.null?
214
+ ip, port = get_ip_and_port(UV::Sockaddr.new(sockaddr))
215
+ end
216
+
217
+ begin
218
+ @progress.call data, ip, port, self
219
+ rescue Exception => e
220
+ @loop.log :error, :udp_progress_cb, e
221
+ end
222
+ end
223
+ end
224
+ end
225
225
  end