libuv 0.11.3 → 0.11.4

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 +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