libuv 2.0.12 → 3.0.0

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 +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +67 -34
  4. data/lib/libuv.rb +30 -5
  5. data/lib/libuv/async.rb +16 -10
  6. data/lib/libuv/check.rb +19 -12
  7. data/lib/libuv/coroutines.rb +39 -12
  8. data/lib/libuv/dns.rb +25 -18
  9. data/lib/libuv/error.rb +2 -0
  10. data/lib/libuv/ext/ext.rb +28 -36
  11. data/lib/libuv/ext/platform/darwin_x64.rb +2 -0
  12. data/lib/libuv/ext/platform/unix.rb +2 -0
  13. data/lib/libuv/ext/platform/windows.rb +2 -0
  14. data/lib/libuv/ext/tasks.rb +2 -0
  15. data/lib/libuv/ext/tasks/mac.rb +2 -0
  16. data/lib/libuv/ext/tasks/unix.rb +2 -0
  17. data/lib/libuv/ext/tasks/win.rb +2 -0
  18. data/lib/libuv/ext/types.rb +2 -1
  19. data/lib/libuv/file.rb +67 -50
  20. data/lib/libuv/filesystem.rb +63 -61
  21. data/lib/libuv/fs_event.rb +7 -4
  22. data/lib/libuv/handle.rb +30 -14
  23. data/lib/libuv/idle.rb +17 -10
  24. data/lib/libuv/mixins/accessors.rb +41 -0
  25. data/lib/libuv/mixins/assertions.rb +3 -1
  26. data/lib/libuv/mixins/fs_checks.rb +29 -6
  27. data/lib/libuv/mixins/listener.rb +4 -2
  28. data/lib/libuv/mixins/net.rb +4 -2
  29. data/lib/libuv/mixins/resource.rb +5 -3
  30. data/lib/libuv/mixins/stream.rb +128 -35
  31. data/lib/libuv/pipe.rb +54 -27
  32. data/lib/libuv/prepare.rb +19 -12
  33. data/lib/libuv/q.rb +109 -101
  34. data/lib/libuv/{loop.rb → reactor.rb} +163 -85
  35. data/lib/libuv/signal.rb +13 -5
  36. data/lib/libuv/tcp.rb +109 -63
  37. data/lib/libuv/timer.rb +44 -24
  38. data/lib/libuv/tty.rb +8 -3
  39. data/lib/libuv/udp.rb +49 -22
  40. data/lib/libuv/version.rb +3 -1
  41. data/lib/libuv/work.rb +14 -10
  42. data/libuv.gemspec +11 -9
  43. data/spec/async_spec.rb +13 -13
  44. data/spec/coroutines_spec.rb +20 -50
  45. data/spec/defer_spec.rb +182 -311
  46. data/spec/dns_spec.rb +51 -41
  47. data/spec/dsl_spec.rb +43 -0
  48. data/spec/filesystem_spec.rb +65 -87
  49. data/spec/idle_spec.rb +19 -33
  50. data/spec/pipe_spec.rb +25 -32
  51. data/spec/tcp_spec.rb +116 -53
  52. data/spec/timer_spec.rb +3 -3
  53. data/spec/udp_spec.rb +16 -17
  54. data/spec/zen_spec.rb +2 -3
  55. metadata +37 -30
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Libuv
2
4
  class Filesystem
3
5
  include Assertions, Resource, Listener, FsChecks
@@ -21,125 +23,125 @@ module Libuv
21
23
  define_callback function: :on_chown, **fs_params
22
24
 
23
25
 
24
- def initialize(thread)
25
- @loop = thread
26
+ def initialize(reactor)
27
+ @reactor = reactor
26
28
  end
27
29
 
28
- def unlink(path)
30
+ def unlink(path, wait: true)
29
31
  assert_type(String, path, "path must be a String")
30
- @unlink_deferred = @loop.defer
32
+ @unlink_deferred = @reactor.defer
31
33
 
32
34
  request = ::Libuv::Ext.allocate_request_fs
33
- pre_check @unlink_deferred, request, ::Libuv::Ext.fs_unlink(@loop, request, path, callback(:on_unlink, request.address))
34
- @unlink_deferred.promise
35
+ pre_check @unlink_deferred, request, ::Libuv::Ext.fs_unlink(@reactor, request, path, callback(:on_unlink, request.address))
36
+ respond wait, @unlink_deferred.promise
35
37
  end
36
38
 
37
- def mkdir(path, mode = 0777)
39
+ def mkdir(path, mode = 0777, wait: true)
38
40
  assert_type(String, path, "path must be a String")
39
41
  assert_type(Integer, mode, "mode must be an Integer")
40
- @mkdir_deferred = @loop.defer
42
+ @mkdir_deferred = @reactor.defer
41
43
 
42
44
  request = ::Libuv::Ext.allocate_request_fs
43
- pre_check @mkdir_deferred, request, ::Libuv::Ext.fs_mkdir(@loop, request, path, mode, callback(:on_mkdir, request.address))
44
- @mkdir_deferred.promise
45
+ pre_check @mkdir_deferred, request, ::Libuv::Ext.fs_mkdir(@reactor, request, path, mode, callback(:on_mkdir, request.address))
46
+ respond wait, @mkdir_deferred.promise
45
47
  end
46
48
 
47
- def rmdir(path)
49
+ def rmdir(path, wait: true)
48
50
  assert_type(String, path, "path must be a String")
49
- @rmdir_deferred = @loop.defer
51
+ @rmdir_deferred = @reactor.defer
50
52
 
51
53
  request = ::Libuv::Ext.allocate_request_fs
52
- pre_check @rmdir_deferred, request, ::Libuv::Ext.fs_rmdir(@loop, request, path, callback(:on_rmdir, request.address))
53
- @rmdir_deferred.promise
54
+ pre_check @rmdir_deferred, request, ::Libuv::Ext.fs_rmdir(@reactor, request, path, callback(:on_rmdir, request.address))
55
+ respond wait, @rmdir_deferred.promise
54
56
  end
55
57
 
56
- def readdir(path)
58
+ def readdir(path, wait: true)
57
59
  assert_type(String, path, "path must be a String")
58
- @readdir_deferred = @loop.defer
60
+ @readdir_deferred = @reactor.defer
59
61
 
60
62
  request = ::Libuv::Ext.allocate_request_fs
61
- pre_check @readdir_deferred, request, ::Libuv::Ext.fs_readdir(@loop, request, path, 0, callback(:on_readdir, request.address))
62
- @readdir_deferred.promise
63
+ pre_check @readdir_deferred, request, ::Libuv::Ext.fs_readdir(@reactor, request, path, 0, callback(:on_readdir, request.address))
64
+ respond wait, @readdir_deferred.promise
63
65
  end
64
66
 
65
- def rename(old_path, new_path)
67
+ def rename(old_path, new_path, wait: true)
66
68
  assert_type(String, old_path, "old_path must be a String")
67
69
  assert_type(String, new_path, "new_path must be a String")
68
- @rename_deferred = @loop.defer
70
+ @rename_deferred = @reactor.defer
69
71
 
70
72
  request = ::Libuv::Ext.allocate_request_fs
71
- pre_check @rename_deferred, request, ::Libuv::Ext.fs_rename(@loop, request, old_path, new_path, callback(:on_rename, request.address))
72
- @rename_deferred.promise
73
+ pre_check @rename_deferred, request, ::Libuv::Ext.fs_rename(@reactor, request, old_path, new_path, callback(:on_rename, request.address))
74
+ respond wait, @rename_deferred.promise
73
75
  end
74
76
 
75
- def chmod(path, mode)
77
+ def chmod(path, mode, wait: true)
76
78
  assert_type(String, path, "path must be a String")
77
79
  assert_type(Integer, mode, "mode must be an Integer")
78
- @chmod_deferred = @loop.defer
80
+ @chmod_deferred = @reactor.defer
79
81
 
80
82
  request = ::Libuv::Ext.allocate_request_fs
81
- pre_check @chmod_deferred, request, ::Libuv::Ext.fs_chmod(@loop, request, path, mode, callback(:on_chmod, request.address))
82
- @chmod_deferred.promise
83
+ pre_check @chmod_deferred, request, ::Libuv::Ext.fs_chmod(@reactor, request, path, mode, callback(:on_chmod, request.address))
84
+ respond wait, @chmod_deferred.promise
83
85
  end
84
86
 
85
- def utime(path, atime, mtime)
87
+ def utime(path, atime, mtime, wait: true)
86
88
  assert_type(String, path, "path must be a String")
87
89
  assert_type(Integer, atime, "atime must be an Integer")
88
90
  assert_type(Integer, mtime, "mtime must be an Integer")
89
- @utime_deferred = @loop.defer
91
+ @utime_deferred = @reactor.defer
90
92
 
91
93
  request = ::Libuv::Ext.allocate_request_fs
92
- pre_check @utime_deferred, request, ::Libuv::Ext.fs_utime(@loop, request, path, atime, mtime, callback(:on_utime, request.address))
93
- @utime_deferred.promise
94
+ pre_check @utime_deferred, request, ::Libuv::Ext.fs_utime(@reactor, request, path, atime, mtime, callback(:on_utime, request.address))
95
+ respond wait, @utime_deferred.promise
94
96
  end
95
97
 
96
- def lstat(path)
98
+ def lstat(path, wait: true)
97
99
  assert_type(String, path, "path must be a String")
98
- @stat_deferred = @loop.defer
100
+ @stat_deferred = @reactor.defer
99
101
 
100
102
  request = ::Libuv::Ext.allocate_request_fs
101
- pre_check @stat_deferred, request, ::Libuv::Ext.fs_lstat(@loop, request, path, callback(:on_stat, request.address))
102
- @stat_deferred.promise
103
+ pre_check @stat_deferred, request, ::Libuv::Ext.fs_lstat(@reactor, request, path, callback(:on_stat, request.address))
104
+ respond wait, @stat_deferred.promise
103
105
  end
104
106
 
105
- def link(old_path, new_path)
107
+ def link(old_path, new_path, wait: true)
106
108
  assert_type(String, old_path, "old_path must be a String")
107
109
  assert_type(String, new_path, "new_path must be a String")
108
- @link_deferred = @loop.defer
110
+ @link_deferred = @reactor.defer
109
111
 
110
112
  request = ::Libuv::Ext.allocate_request_fs
111
- pre_check @link_deferred, request, ::Libuv::Ext.fs_link(@loop, request, old_path, new_path, callback(:on_link, request.address))
112
- @link_deferred.promise
113
+ pre_check @link_deferred, request, ::Libuv::Ext.fs_link(@reactor, request, old_path, new_path, callback(:on_link, request.address))
114
+ respond wait, @link_deferred.promise
113
115
  end
114
116
 
115
- def symlink(old_path, new_path)
117
+ def symlink(old_path, new_path, wait: true)
116
118
  assert_type(String, old_path, "old_path must be a String")
117
119
  assert_type(String, new_path, "new_path must be a String")
118
- @symlink_deferred = @loop.defer
120
+ @symlink_deferred = @reactor.defer
119
121
 
120
122
  request = ::Libuv::Ext.allocate_request_fs
121
- pre_check @symlink_deferred, request, ::Libuv::Ext.fs_symlink(@loop, request, old_path, new_path, 0, callback(:on_symlink, request.address))
122
- @symlink_deferred.promise
123
+ pre_check @symlink_deferred, request, ::Libuv::Ext.fs_symlink(@reactor, request, old_path, new_path, 0, callback(:on_symlink, request.address))
124
+ respond wait, @symlink_deferred.promise
123
125
  end
124
126
 
125
- def readlink(path)
127
+ def readlink(path, wait: true)
126
128
  assert_type(String, path, "path must be a String")
127
- @readlink_deferred = @loop.defer
129
+ @readlink_deferred = @reactor.defer
128
130
 
129
131
  request = ::Libuv::Ext.allocate_request_fs
130
- pre_check @readlink_deferred, request, ::Libuv::Ext.fs_readlink(@loop, request, path, callback(:on_readlink, request.address))
131
- @readlink_deferred.promise
132
+ pre_check @readlink_deferred, request, ::Libuv::Ext.fs_readlink(@reactor, request, path, callback(:on_readlink, request.address))
133
+ respond wait, @readlink_deferred.promise
132
134
  end
133
135
 
134
- def chown(path, uid, gid)
136
+ def chown(path, uid, gid, wait: true)
135
137
  assert_type(String, path, "path must be a String")
136
138
  assert_type(Integer, uid, "uid must be an Integer")
137
139
  assert_type(Integer, gid, "gid must be an Integer")
138
- @chown_deferred = @loop.defer
140
+ @chown_deferred = @reactor.defer
139
141
 
140
142
  request = ::Libuv::Ext.allocate_request_fs
141
- pre_check @chown_deferred, request, ::Libuv::Ext.fs_chown(@loop, request, path, uid, gid, callback(:on_chown, request.address))
142
- @chown_deferred.promise
143
+ pre_check @chown_deferred, request, ::Libuv::Ext.fs_chown(@reactor, request, path, uid, gid, callback(:on_chown, request.address))
144
+ respond wait, @chown_deferred.promise
143
145
  end
144
146
 
145
147
 
@@ -150,7 +152,7 @@ module Libuv
150
152
  if post_check(req, @unlink_deferred)
151
153
  path = req[:path]
152
154
  cleanup(req)
153
- @unlink_deferred.resolve(path)
155
+ ::Fiber.new { @unlink_deferred.resolve(path) }.resume
154
156
  end
155
157
  @unlink_deferred = nil
156
158
  end
@@ -159,7 +161,7 @@ module Libuv
159
161
  if post_check(req, @mkdir_deferred)
160
162
  path = req[:path]
161
163
  cleanup(req)
162
- @mkdir_deferred.resolve(path)
164
+ ::Fiber.new { @mkdir_deferred.resolve(path) }.resume
163
165
  end
164
166
  @mkdir_deferred = nil
165
167
  end
@@ -168,7 +170,7 @@ module Libuv
168
170
  if post_check(req, @rmdir_deferred)
169
171
  path = req[:path]
170
172
  cleanup(req)
171
- @rmdir_deferred.resolve(path)
173
+ ::Fiber.new { @rmdir_deferred.resolve(path) }.resume
172
174
  end
173
175
  @rmdir_deferred = nil
174
176
  end
@@ -189,7 +191,7 @@ module Libuv
189
191
  end
190
192
 
191
193
  cleanup(req)
192
- @readdir_deferred.resolve(files)
194
+ ::Fiber.new { @readdir_deferred.resolve(files) }.resume
193
195
  end
194
196
  @readdir_deferred = nil
195
197
  end
@@ -198,7 +200,7 @@ module Libuv
198
200
  if post_check(req, @rename_deferred)
199
201
  path = req[:path]
200
202
  cleanup(req)
201
- @rename_deferred.resolve(path)
203
+ ::Fiber.new { @rename_deferred.resolve(path) }.resume
202
204
  end
203
205
  @rename_deferred = nil
204
206
  end
@@ -207,7 +209,7 @@ module Libuv
207
209
  if post_check(req, @chmod_deferred)
208
210
  path = req[:path]
209
211
  cleanup(req)
210
- @chmod_deferred.resolve(path)
212
+ ::Fiber.new { @chmod_deferred.resolve(path) }.resume
211
213
  end
212
214
  @chmod_deferred = nil
213
215
  end
@@ -216,7 +218,7 @@ module Libuv
216
218
  if post_check(req, @utime_deferred)
217
219
  path = req[:path]
218
220
  cleanup(req)
219
- @utime_deferred.resolve(path)
221
+ ::Fiber.new { @utime_deferred.resolve(path) }.resume
220
222
  end
221
223
  @utime_deferred = nil
222
224
  end
@@ -225,7 +227,7 @@ module Libuv
225
227
  if post_check(req, @link_deferred)
226
228
  path = req[:path]
227
229
  cleanup(req)
228
- @link_deferred.resolve(path)
230
+ ::Fiber.new { @link_deferred.resolve(path) }.resume
229
231
  end
230
232
  @link_deferred = nil
231
233
  end
@@ -234,7 +236,7 @@ module Libuv
234
236
  if post_check(req, @symlink_deferred)
235
237
  path = req[:path]
236
238
  cleanup(req)
237
- @symlink_deferred.resolve(path)
239
+ ::Fiber.new { @symlink_deferred.resolve(path) }.resume
238
240
  end
239
241
  @symlink_deferred = nil
240
242
  end
@@ -244,7 +246,7 @@ module Libuv
244
246
  string_ptr = req[:ptr]
245
247
  path = string_ptr.null? ? nil : string_ptr.read_string_to_null
246
248
  cleanup(req)
247
- @readlink_deferred.resolve(path)
249
+ ::Fiber.new { @readlink_deferred.resolve(path) }.resume
248
250
  end
249
251
  @readlink_deferred = nil
250
252
  end
@@ -253,7 +255,7 @@ module Libuv
253
255
  if post_check(req, @chown_deferred)
254
256
  path = req[:path]
255
257
  cleanup(req)
256
- @chown_deferred.resolve(path)
258
+ ::Fiber.new { @chown_deferred.resolve(path) }.resume
257
259
  end
258
260
  @chown_deferred = nil
259
261
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Libuv
2
4
  class FSEvent < Handle
3
5
 
@@ -8,11 +10,11 @@ module Libuv
8
10
  EVENTS = {1 => :rename, 2 => :change}.freeze
9
11
 
10
12
 
11
- def initialize(thread, path)
12
- @loop = thread
13
+ def initialize(reactor, path)
14
+ @reactor = reactor
13
15
 
14
16
  fs_event_ptr = ::Libuv::Ext.allocate_handle_fs_event
15
- error = check_result ::Libuv::Ext.fs_event_init(thread.handle, fs_event_ptr, path, callback(:on_fs_event, fs_event_ptr.address), 0)
17
+ error = check_result ::Libuv::Ext.fs_event_init(reactor.handle, fs_event_ptr, path, callback(:on_fs_event, fs_event_ptr.address), 0)
16
18
 
17
19
  super(fs_event_ptr, error)
18
20
  end
@@ -27,7 +29,8 @@ module Libuv
27
29
  if e
28
30
  reject(e)
29
31
  else
30
- defer.notify(filename, EVENTS[events]) # notify of a change
32
+ # notify of a change
33
+ ::Fiber.new { defer.notify(filename, EVENTS[events]) }.resume
31
34
  end
32
35
  end
33
36
  end
data/lib/libuv/handle.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Libuv
2
4
  class Handle < Q::DeferredPromise
3
5
  include Assertions, Resource, Listener
@@ -5,7 +7,7 @@ module Libuv
5
7
 
6
8
  attr_accessor :storage # A place for general storage
7
9
  attr_reader :closed
8
- attr_reader :loop
10
+ attr_reader :reactor
9
11
 
10
12
 
11
13
  define_callback function: :on_close
@@ -16,7 +18,7 @@ module Libuv
16
18
  @instance_id = @pointer.address
17
19
 
18
20
  # Initialise the promise
19
- super(loop, loop.defer)
21
+ super(reactor, reactor.defer)
20
22
 
21
23
  # clean up on init error (always raise here)
22
24
  if error
@@ -27,28 +29,35 @@ module Libuv
27
29
  end
28
30
  end
29
31
 
30
- # Public: Increment internal ref counter for the handle on the loop. Useful for
31
- # extending the loop with custom watchers that need to make loop not stop
32
+ # Public: Increment internal ref counter for the handle on the reactor. Useful for
33
+ # extending the reactor with custom watchers that need to make reactor not stop
32
34
  #
33
35
  # Returns self
34
36
  def ref
35
- return if @closed
37
+ return self if @closed
36
38
  ::Libuv::Ext.ref(handle)
39
+ self
37
40
  end
38
41
 
39
- # Public: Decrement internal ref counter for the handle on the loop, useful to stop
40
- # loop even when there are outstanding open handles
42
+ # Public: Decrement internal ref counter for the handle on the reactor, useful to stop
43
+ # reactor even when there are outstanding open handles
41
44
  #
42
45
  # Returns self
43
46
  def unref
44
- return if @closed
47
+ return self if @closed
45
48
  ::Libuv::Ext.unref(handle)
49
+ self
46
50
  end
47
51
 
48
52
  def close
49
- return if @closed
53
+ return self if @closed
50
54
  @closed = true
51
55
  ::Libuv::Ext.close(handle, callback(:on_close))
56
+ self
57
+ end
58
+
59
+ def closed?
60
+ !!@closed
52
61
  end
53
62
 
54
63
  def active?
@@ -82,11 +91,18 @@ module Libuv
82
91
  #clear_callbacks
83
92
  cleanup_callbacks
84
93
 
85
- if @close_error
86
- defer.reject(@close_error)
87
- else
88
- defer.resolve(nil)
89
- end
94
+ ::Fiber.new {
95
+ if @close_error
96
+ defer.reject(@close_error)
97
+ else
98
+ defer.resolve(nil)
99
+ end
100
+
101
+ if @coroutine
102
+ @coroutine.resolve(self)
103
+ @coroutine = nil
104
+ end
105
+ }.resume
90
106
  end
91
107
  end
92
108
  end
data/lib/libuv/idle.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Libuv
2
4
  class Idle < Handle
3
5
 
@@ -5,14 +7,14 @@ module Libuv
5
7
  define_callback function: :on_idle
6
8
 
7
9
 
8
- # @param thread [::Libuv::Loop] loop this idle handler will be associated
9
- # @param callback [Proc] callback to be called when the loop is idle
10
- def initialize(thread, callback = nil, &blk)
11
- @loop = thread
10
+ # @param reactor [::Libuv::Reactor] reactor this idle handler will be associated
11
+ # @param callback [Proc] callback to be called when the reactor is idle
12
+ def initialize(reactor, callback = nil, &blk)
13
+ @reactor = reactor
12
14
  @callback = callback || blk
13
15
 
14
16
  idle_ptr = ::Libuv::Ext.allocate_handle_idle
15
- error = check_result(::Libuv::Ext.idle_init(thread.handle, idle_ptr))
17
+ error = check_result(::Libuv::Ext.idle_init(reactor.handle, idle_ptr))
16
18
 
17
19
  super(idle_ptr, error)
18
20
  end
@@ -22,6 +24,7 @@ module Libuv
22
24
  return if @closed
23
25
  error = check_result ::Libuv::Ext.idle_start(handle, callback(:on_idle))
24
26
  reject(error) if error
27
+ self
25
28
  end
26
29
 
27
30
  # Disables the idle handler.
@@ -29,6 +32,7 @@ module Libuv
29
32
  return if @closed
30
33
  error = check_result ::Libuv::Ext.idle_stop(handle)
31
34
  reject(error) if error
35
+ self
32
36
  end
33
37
 
34
38
  # Used to update the callback that will be triggered on idle
@@ -36,6 +40,7 @@ module Libuv
36
40
  # @param callback [Proc] the callback to be called on idle trigger
37
41
  def progress(callback = nil, &blk)
38
42
  @callback = callback || blk
43
+ self
39
44
  end
40
45
 
41
46
 
@@ -43,11 +48,13 @@ module Libuv
43
48
 
44
49
 
45
50
  def on_idle(handle)
46
- begin
47
- @callback.call
48
- rescue Exception => e
49
- @loop.log :error, :idle_cb, e
50
- end
51
+ ::Fiber.new {
52
+ begin
53
+ @callback.call
54
+ rescue Exception => e
55
+ @reactor.log e, 'performing idle callback'
56
+ end
57
+ }.resume
51
58
  end
52
59
  end
53
60
  end