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/handle.rb
CHANGED
@@ -1,82 +1,86 @@
|
|
1
|
-
module Libuv
|
2
|
-
class Handle < Q::DeferredPromise
|
3
|
-
include Assertions, Resource, Listener
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
end
|
48
|
-
|
49
|
-
def
|
50
|
-
::Libuv::Ext.
|
51
|
-
end
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
1
|
+
module Libuv
|
2
|
+
class Handle < Q::DeferredPromise
|
3
|
+
include Assertions, Resource, Listener
|
4
|
+
|
5
|
+
|
6
|
+
attr_accessor :storage # A place for general storage
|
7
|
+
attr_reader :closed
|
8
|
+
|
9
|
+
|
10
|
+
def initialize(pointer, error)
|
11
|
+
@pointer = pointer
|
12
|
+
|
13
|
+
# Initialise the promise
|
14
|
+
super(loop, loop.defer)
|
15
|
+
|
16
|
+
# clean up on init error (always raise here)
|
17
|
+
if error
|
18
|
+
::Libuv::Ext.free(pointer)
|
19
|
+
defer.reject(error)
|
20
|
+
@closed = true
|
21
|
+
raise error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Public: Increment internal ref counter for the handle on the loop. Useful for
|
26
|
+
# extending the loop with custom watchers that need to make loop not stop
|
27
|
+
#
|
28
|
+
# Returns self
|
29
|
+
def ref
|
30
|
+
return if @closed
|
31
|
+
::Libuv::Ext.ref(handle)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Public: Decrement internal ref counter for the handle on the loop, useful to stop
|
35
|
+
# loop even when there are outstanding open handles
|
36
|
+
#
|
37
|
+
# Returns self
|
38
|
+
def unref
|
39
|
+
return if @closed
|
40
|
+
::Libuv::Ext.unref(handle)
|
41
|
+
end
|
42
|
+
|
43
|
+
def close
|
44
|
+
return if @closed
|
45
|
+
@closed = true
|
46
|
+
Libuv::Ext.close(handle, callback(:on_close))
|
47
|
+
end
|
48
|
+
|
49
|
+
def active?
|
50
|
+
::Libuv::Ext.is_active(handle) > 0
|
51
|
+
end
|
52
|
+
|
53
|
+
def closing?
|
54
|
+
::Libuv::Ext.is_closing(handle) > 0
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
|
61
|
+
def loop; @loop; end
|
62
|
+
def handle; @pointer; end
|
63
|
+
def defer; @defer; end
|
64
|
+
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
|
69
|
+
# Clean up and throw an error
|
70
|
+
def reject(reason)
|
71
|
+
@close_error = reason
|
72
|
+
close
|
73
|
+
end
|
74
|
+
|
75
|
+
def on_close(pointer)
|
76
|
+
::Libuv::Ext.free(pointer)
|
77
|
+
clear_callbacks
|
78
|
+
|
79
|
+
if @close_error
|
80
|
+
defer.reject(@close_error)
|
81
|
+
else
|
82
|
+
defer.resolve(nil)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
82
86
|
end
|
data/lib/libuv/idle.rb
CHANGED
@@ -1,49 +1,56 @@
|
|
1
|
-
module Libuv
|
2
|
-
class Idle < Handle
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
1
|
+
module Libuv
|
2
|
+
class Idle < Handle
|
3
|
+
|
4
|
+
|
5
|
+
# @param loop [::Libuv::Loop] loop this idle handler will be associated
|
6
|
+
# @param callback [Proc] callback to be called when the loop is idle
|
7
|
+
def initialize(loop, callback = nil, &blk)
|
8
|
+
@loop = loop
|
9
|
+
@callback = callback || blk
|
10
|
+
|
11
|
+
idle_ptr = ::Libuv::Ext.create_handle(:uv_idle)
|
12
|
+
error = check_result(::Libuv::Ext.idle_init(loop.handle, idle_ptr))
|
13
|
+
|
14
|
+
super(idle_ptr, error)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Enables the idle handler.
|
18
|
+
def start
|
19
|
+
return if @closed
|
20
|
+
error = check_result ::Libuv::Ext.idle_start(handle, callback(:on_idle))
|
21
|
+
reject(error) if error
|
22
|
+
end
|
23
|
+
|
24
|
+
# Disables the idle handler.
|
25
|
+
def stop
|
26
|
+
return if @closed
|
27
|
+
error = check_result ::Libuv::Ext.idle_stop(handle)
|
28
|
+
reject(error) if error
|
29
|
+
end
|
30
|
+
|
31
|
+
# Used to update the callback that will be triggered on idle
|
32
|
+
#
|
33
|
+
# @param callback [Proc] the callback to be called on idle trigger
|
34
|
+
def progress(callback = nil, &blk)
|
35
|
+
@callback = callback || blk
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
|
42
|
+
def on_idle(handle, status)
|
43
|
+
e = check_result(status)
|
44
|
+
|
45
|
+
if e
|
46
|
+
reject(e)
|
47
|
+
else
|
48
|
+
begin
|
49
|
+
@callback.call
|
50
|
+
rescue Exception => e
|
51
|
+
@loop.log :error, :idle_cb, e
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/libuv/loop.rb
CHANGED
@@ -1,310 +1,338 @@
|
|
1
|
-
require 'thread'
|
2
|
-
|
3
|
-
module Libuv
|
4
|
-
class Loop
|
5
|
-
include Resource, Assertions
|
6
|
-
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
# Get default loop
|
10
|
-
#
|
11
|
-
# @return [::Libuv::Loop]
|
12
|
-
def default
|
13
|
-
create(::Libuv::Ext.default_loop)
|
14
|
-
end
|
15
|
-
|
16
|
-
# Create new loop
|
17
|
-
#
|
18
|
-
# @return [::Libuv::Loop]
|
19
|
-
def new
|
20
|
-
create(::Libuv::Ext.loop_new)
|
21
|
-
end
|
22
|
-
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# @return [::Libuv::Loop]
|
26
|
-
def create(pointer)
|
27
|
-
allocate.tap { |i| i.send(:initialize, FFI::AutoPointer.new(pointer, ::Libuv::Ext.method(:loop_delete))) }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
extend ClassMethods
|
31
|
-
|
32
|
-
|
33
|
-
# Initialize a loop using an FFI::Pointer
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
@
|
64
|
-
@
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
def
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
@loop
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
# @return [::Libuv::Q::
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
#
|
124
|
-
# promises
|
125
|
-
#
|
126
|
-
#
|
127
|
-
# @
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
#
|
136
|
-
#
|
137
|
-
# @return
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
#
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
#
|
152
|
-
#
|
153
|
-
|
154
|
-
|
155
|
-
::Libuv::Ext.
|
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
|
-
# @return [::Libuv::
|
182
|
-
def
|
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
|
-
handle
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
#
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
#
|
262
|
-
#
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
#
|
305
|
-
#
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Libuv
|
4
|
+
class Loop
|
5
|
+
include Resource, Assertions
|
6
|
+
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
# Get default loop
|
10
|
+
#
|
11
|
+
# @return [::Libuv::Loop]
|
12
|
+
def default
|
13
|
+
create(::Libuv::Ext.default_loop)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create new Libuv loop
|
17
|
+
#
|
18
|
+
# @return [::Libuv::Loop]
|
19
|
+
def new
|
20
|
+
create(::Libuv::Ext.loop_new)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Build a Ruby Libuv loop from an existing loop pointer
|
24
|
+
#
|
25
|
+
# @return [::Libuv::Loop]
|
26
|
+
def create(pointer)
|
27
|
+
allocate.tap { |i| i.send(:initialize, FFI::AutoPointer.new(pointer, ::Libuv::Ext.method(:loop_delete))) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
extend ClassMethods
|
31
|
+
|
32
|
+
|
33
|
+
# Initialize a loop using an FFI::Pointer to a libuv loop
|
34
|
+
def initialize(pointer) # :notnew:
|
35
|
+
@pointer = pointer
|
36
|
+
@loop = self
|
37
|
+
|
38
|
+
# Create an async call for scheduling work from other threads
|
39
|
+
@run_queue = Queue.new
|
40
|
+
@queue_proc = proc do
|
41
|
+
# ensure we only execute what was required for this tick
|
42
|
+
length = @run_queue.length
|
43
|
+
length.times do
|
44
|
+
begin
|
45
|
+
run = @run_queue.pop true # pop non-block
|
46
|
+
run.call
|
47
|
+
rescue Exception => e
|
48
|
+
@loop.log :error, :next_tick_cb, e
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
@process_queue = Async.new(@loop, @queue_proc)
|
53
|
+
|
54
|
+
# Create a next tick timer
|
55
|
+
@next_tick = @loop.timer do
|
56
|
+
@next_tick_scheduled = false
|
57
|
+
@queue_proc.call
|
58
|
+
end
|
59
|
+
|
60
|
+
# Create an async call for ending the loop
|
61
|
+
@stop_loop = Async.new @loop do
|
62
|
+
@process_queue.close
|
63
|
+
@stop_loop.close
|
64
|
+
@next_tick.close
|
65
|
+
|
66
|
+
::Libuv::Ext.stop(@pointer)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def handle; @pointer; end
|
71
|
+
|
72
|
+
# Run the actual event loop. This method will block until the loop is stopped.
|
73
|
+
#
|
74
|
+
# @param run_type [:UV_RUN_DEFAULT, :UV_RUN_ONCE, :UV_RUN_NOWAIT]
|
75
|
+
# @yieldparam promise [::Libuv::Q::Promise] Yields a promise that can be used for logging unhandled
|
76
|
+
# exceptions on the loop.
|
77
|
+
def run(run_type = :UV_RUN_DEFAULT)
|
78
|
+
@loop_notify = @loop.defer
|
79
|
+
|
80
|
+
begin
|
81
|
+
@reactor_thread = Thread.current
|
82
|
+
yield @loop_notify.promise if block_given?
|
83
|
+
::Libuv::Ext.run(@pointer, run_type) # This is blocking
|
84
|
+
ensure
|
85
|
+
@reactor_thread = nil
|
86
|
+
@run_queue.clear
|
87
|
+
end
|
88
|
+
|
89
|
+
@loop
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# Creates a deferred result object for where the result of an operation may only be returned
|
94
|
+
# at some point in the future or is being processed on a different thread (thread safe)
|
95
|
+
#
|
96
|
+
# @return [::Libuv::Q::Deferred]
|
97
|
+
def defer
|
98
|
+
Q.defer(@loop)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Combines multiple promises into a single promise that is resolved when all of the input
|
102
|
+
# promises are resolved. (thread safe)
|
103
|
+
#
|
104
|
+
# @param *promises [::Libuv::Q::Promise] a number of promises that will be combined into a single promise
|
105
|
+
# @return [::Libuv::Q::Promise] Returns a single promise that will be resolved with an array of values,
|
106
|
+
# each value corresponding to the promise at the same index in the `promises` array. If any of
|
107
|
+
# the promises is resolved with a rejection, this resulting promise will be resolved with the
|
108
|
+
# same rejection.
|
109
|
+
def all(*promises)
|
110
|
+
Q.all(@loop, *promises)
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Combines multiple promises into a single promise that is resolved when any of the input
|
115
|
+
# promises are resolved.
|
116
|
+
#
|
117
|
+
# @param *promises [::Libuv::Q::Promise] a number of promises that will be combined into a single promise
|
118
|
+
# @return [::Libuv::Q::Promise] Returns a single promise
|
119
|
+
def any(*promises)
|
120
|
+
Q.any(@loop, *promises)
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Combines multiple promises into a single promise that is resolved when all of the input
|
125
|
+
# promises are resolved or rejected.
|
126
|
+
#
|
127
|
+
# @param *promises [::Libuv::Q::Promise] a number of promises that will be combined into a single promise
|
128
|
+
# @return [::Libuv::Q::Promise] Returns a single promise that will be resolved with an array of values,
|
129
|
+
# each [result, wasResolved] value pair corresponding to a at the same index in the `promises` array.
|
130
|
+
def finally(*promises)
|
131
|
+
Q.finally(@loop, *promises)
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
# forces loop time update, useful for getting more granular times
|
136
|
+
#
|
137
|
+
# @return nil
|
138
|
+
def update_time
|
139
|
+
::Libuv::Ext.update_time(@pointer)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Get current time in microseconds
|
143
|
+
#
|
144
|
+
# @return [Fixnum]
|
145
|
+
def now
|
146
|
+
::Libuv::Ext.now(@pointer)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Lookup an error code and return is as an error object
|
150
|
+
#
|
151
|
+
# @param err [Integer] The error code to look up.
|
152
|
+
# @return [::Libuv::Error]
|
153
|
+
def lookup_error(err)
|
154
|
+
name = ::Libuv::Ext.err_name(err)
|
155
|
+
msg = ::Libuv::Ext.strerror(err)
|
156
|
+
|
157
|
+
::Libuv::Error.const_get(name.to_sym).new(msg)
|
158
|
+
rescue Exception => e
|
159
|
+
@loop.log :warn, :error_lookup_failed, e
|
160
|
+
::Libuv::Error::UNKNOWN.new("error lookup failed for code #{err} #{name} #{msg}")
|
161
|
+
end
|
162
|
+
|
163
|
+
# Get a new TCP instance
|
164
|
+
#
|
165
|
+
# @return [::Libuv::TCP]
|
166
|
+
def tcp
|
167
|
+
TCP.new(@loop)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Get a new UDP instance
|
171
|
+
#
|
172
|
+
# @return [::Libuv::UDP]
|
173
|
+
def udp
|
174
|
+
UDP.new(@loop)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Get a new TTY instance
|
178
|
+
#
|
179
|
+
# @param fileno [Integer] Integer file descriptor of a tty device
|
180
|
+
# @param readable [true, false] Boolean indicating if TTY is readable
|
181
|
+
# @return [::Libuv::TTY]
|
182
|
+
def tty(fileno, readable = false)
|
183
|
+
assert_type(Integer, fileno, "io#fileno must return an integer file descriptor, #{fileno.inspect} given")
|
184
|
+
|
185
|
+
TTY.new(@loop, fileno, readable)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Get a new Pipe instance
|
189
|
+
#
|
190
|
+
# @param ipc [true, false] indicate if a handle will be used for ipc, useful for sharing tcp socket between processes
|
191
|
+
# @return [::Libuv::Pipe]
|
192
|
+
def pipe(ipc = false)
|
193
|
+
Pipe.new(@loop, ipc)
|
194
|
+
end
|
195
|
+
|
196
|
+
# Get a new timer instance
|
197
|
+
#
|
198
|
+
# @param callback [Proc] the callback to be called on timer trigger
|
199
|
+
# @return [::Libuv::Timer]
|
200
|
+
def timer(callback = nil, &blk)
|
201
|
+
Timer.new(@loop, callback || blk)
|
202
|
+
end
|
203
|
+
|
204
|
+
# Get a new Prepare handle
|
205
|
+
#
|
206
|
+
# @return [::Libuv::Prepare]
|
207
|
+
def prepare
|
208
|
+
Prepare.new(@loop)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Get a new Check handle
|
212
|
+
#
|
213
|
+
# @return [::Libuv::Check]
|
214
|
+
def check
|
215
|
+
Check.new(@loop)
|
216
|
+
end
|
217
|
+
|
218
|
+
# Get a new Idle handle
|
219
|
+
#
|
220
|
+
# @param callback [Proc] the callback to be called on idle trigger
|
221
|
+
# @return [::Libuv::Idle]
|
222
|
+
def idle(callback = nil, &block)
|
223
|
+
Idle.new(@loop, callback || block)
|
224
|
+
end
|
225
|
+
|
226
|
+
# Get a new Async handle
|
227
|
+
#
|
228
|
+
# @return [::Libuv::Async]
|
229
|
+
def async(callback = nil, &block)
|
230
|
+
callback ||= block
|
231
|
+
handle = Async.new(@loop)
|
232
|
+
handle.progress callback if callback
|
233
|
+
handle
|
234
|
+
end
|
235
|
+
|
236
|
+
# Get a new signal handler
|
237
|
+
#
|
238
|
+
# @return [::Libuv::Signal]
|
239
|
+
def signal(signum = nil, callback = nil, &block)
|
240
|
+
callback ||= block
|
241
|
+
handle = Signal.new(@loop)
|
242
|
+
handle.progress callback if callback
|
243
|
+
handle.start(signum) if signum
|
244
|
+
handle
|
245
|
+
end
|
246
|
+
|
247
|
+
# Queue some work for processing in the libuv thread pool
|
248
|
+
#
|
249
|
+
# @param callback [Proc] the callback to be called in the thread pool
|
250
|
+
# @return [::Libuv::Work]
|
251
|
+
# @raise [ArgumentError] if block is not given
|
252
|
+
def work(callback = nil, &block)
|
253
|
+
callback ||= block
|
254
|
+
assert_block(callback)
|
255
|
+
Work.new(@loop, callback) # Work is a promise object
|
256
|
+
end
|
257
|
+
|
258
|
+
# Get a new FSEvent instance
|
259
|
+
#
|
260
|
+
# @param path [String] the path to the file or folder for watching
|
261
|
+
# @return [::Libuv::FSEvent]
|
262
|
+
# @raise [ArgumentError] if path is not a string
|
263
|
+
def fs_event(path)
|
264
|
+
assert_type(String, path)
|
265
|
+
FSEvent.new(@loop, path)
|
266
|
+
end
|
267
|
+
|
268
|
+
# Opens a file and returns an object that can be used to manipulate it
|
269
|
+
#
|
270
|
+
# @param path [String] the path to the file or folder for watching
|
271
|
+
# @param flags [Integer] see ruby File::Constants
|
272
|
+
# @param mode [Integer]
|
273
|
+
# @return [::Libuv::File]
|
274
|
+
def file(path, flags = 0, mode = 0)
|
275
|
+
assert_type(String, path, "path must be a String")
|
276
|
+
assert_type(Integer, flags, "flags must be an Integer")
|
277
|
+
assert_type(Integer, mode, "mode must be an Integer")
|
278
|
+
File.new(@loop, path, flags, mode)
|
279
|
+
end
|
280
|
+
|
281
|
+
# Returns an object for manipulating the filesystem
|
282
|
+
#
|
283
|
+
# @return [::Libuv::Filesystem]
|
284
|
+
def filesystem
|
285
|
+
Filesystem.new(@loop)
|
286
|
+
end
|
287
|
+
|
288
|
+
# Schedule some work to be processed on the event loop as soon as possible (thread safe)
|
289
|
+
#
|
290
|
+
# @param callback [Proc] the callback to be called on the reactor thread
|
291
|
+
# @raise [ArgumentError] if block is not given
|
292
|
+
def schedule(callback = nil, &block)
|
293
|
+
callback ||= block
|
294
|
+
assert_block(callback)
|
295
|
+
|
296
|
+
if @reactor_thread == Thread.current
|
297
|
+
block.call
|
298
|
+
else
|
299
|
+
@run_queue << callback
|
300
|
+
@process_queue.call
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# Queue some work to be processed in the next iteration of the event loop (thread safe)
|
305
|
+
#
|
306
|
+
# @param callback [Proc] the callback to be called on the reactor thread
|
307
|
+
# @raise [ArgumentError] if block is not given
|
308
|
+
def next_tick(callback = nil, &block)
|
309
|
+
callback ||= block
|
310
|
+
assert_block(callback)
|
311
|
+
|
312
|
+
@run_queue << callback
|
313
|
+
if @reactor_thread == Thread.current
|
314
|
+
# Create a next tick timer
|
315
|
+
if not @next_tick_scheduled
|
316
|
+
@next_tick.start(0)
|
317
|
+
@next_tick_scheduled = true
|
318
|
+
end
|
319
|
+
else
|
320
|
+
@process_queue.call
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
# Notifies the loop there was an event that should be logged
|
325
|
+
#
|
326
|
+
# @param level [Symbol] the error level (info, warn, error etc)
|
327
|
+
# @param id [Object] some kind of identifying information
|
328
|
+
# @param *args [*args] any additional information
|
329
|
+
def log(level, id, *args)
|
330
|
+
@loop_notify.notify(level, id, *args)
|
331
|
+
end
|
332
|
+
|
333
|
+
# Closes handles opened by the loop class and completes the current loop iteration (thread safe)
|
334
|
+
def stop
|
335
|
+
@stop_loop.call
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|