uvrb 0.1.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 (79) hide show
  1. data/.gitignore +17 -0
  2. data/.gitmodules +3 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +13 -0
  5. data/Formula/libuv.rb +20 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +24 -0
  8. data/README.rdoc +70 -0
  9. data/Rakefile +29 -0
  10. data/examples/example +0 -0
  11. data/examples/example.c +37 -0
  12. data/examples/example.rb +29 -0
  13. data/examples/example_oop.rb +26 -0
  14. data/examples/python.py +1 -0
  15. data/examples/ruby.rb +1 -0
  16. data/examples/tcp_client_oop.rb +31 -0
  17. data/examples/tcp_example +0 -0
  18. data/examples/tcp_example.c +68 -0
  19. data/examples/tcp_example.rb +41 -0
  20. data/examples/tcp_example_oop.rb +43 -0
  21. data/examples/tcp_example_plain.rb +19 -0
  22. data/examples/tty_example.rb +20 -0
  23. data/features/async.feature +38 -0
  24. data/features/idle.feature +44 -0
  25. data/features/pipe.feature +150 -0
  26. data/features/prepare_and_check.feature +49 -0
  27. data/features/step_definitions/additional_cli_steps.rb +20 -0
  28. data/features/support/env.rb +6 -0
  29. data/lib/uv.rb +248 -0
  30. data/lib/uv/assertions.rb +24 -0
  31. data/lib/uv/async.rb +24 -0
  32. data/lib/uv/check.rb +27 -0
  33. data/lib/uv/error.rb +58 -0
  34. data/lib/uv/file.rb +221 -0
  35. data/lib/uv/file/stat.rb +35 -0
  36. data/lib/uv/filesystem.rb +335 -0
  37. data/lib/uv/fs_event.rb +21 -0
  38. data/lib/uv/handle.rb +65 -0
  39. data/lib/uv/idle.rb +27 -0
  40. data/lib/uv/listener.rb +26 -0
  41. data/lib/uv/loop.rb +326 -0
  42. data/lib/uv/net.rb +31 -0
  43. data/lib/uv/pipe.rb +47 -0
  44. data/lib/uv/prepare.rb +27 -0
  45. data/lib/uv/resource.rb +20 -0
  46. data/lib/uv/stream.rb +105 -0
  47. data/lib/uv/tasks.rb +27 -0
  48. data/lib/uv/tasks/mac.rb +23 -0
  49. data/lib/uv/tasks/unix.rb +23 -0
  50. data/lib/uv/tasks/win.rb +2 -0
  51. data/lib/uv/tcp.rb +162 -0
  52. data/lib/uv/timer.rb +48 -0
  53. data/lib/uv/tty.rb +30 -0
  54. data/lib/uv/types.rb +249 -0
  55. data/lib/uv/types/darwin_x64.rb +10 -0
  56. data/lib/uv/types/linux.rb +6 -0
  57. data/lib/uv/types/unix.rb +12 -0
  58. data/lib/uv/types/windows.rb +13 -0
  59. data/lib/uv/udp.rb +215 -0
  60. data/lib/uv/version.rb +3 -0
  61. data/lib/uvrb.rb +1 -0
  62. data/spec/shared_examples/handle.rb +54 -0
  63. data/spec/shared_examples/stream.rb +109 -0
  64. data/spec/spec_helper.rb +26 -0
  65. data/spec/uv/async_spec.rb +18 -0
  66. data/spec/uv/check_spec.rb +30 -0
  67. data/spec/uv/file_spec.rb +177 -0
  68. data/spec/uv/filesystem_spec.rb +246 -0
  69. data/spec/uv/fs_event_spec.rb +10 -0
  70. data/spec/uv/idle_spec.rb +30 -0
  71. data/spec/uv/loop_spec.rb +241 -0
  72. data/spec/uv/pipe_spec.rb +54 -0
  73. data/spec/uv/prepare_spec.rb +30 -0
  74. data/spec/uv/tcp_spec.rb +134 -0
  75. data/spec/uv/timer_spec.rb +61 -0
  76. data/spec/uv/tty_spec.rb +53 -0
  77. data/spec/uv/udp_spec.rb +190 -0
  78. data/uvrb.gemspec +28 -0
  79. metadata +247 -0
@@ -0,0 +1,21 @@
1
+ module UV
2
+ class FSEvent
3
+ include Handle
4
+
5
+ EVENTS = {1 => :rename, 2 => :change}.freeze
6
+
7
+ def initialize(loop, fs_event_ptr, &block)
8
+ @fs_event_block = block
9
+
10
+ super(loop, fs_event_ptr)
11
+ end
12
+
13
+ private
14
+
15
+ def on_fs_event(handle, filename, events, status)
16
+ @fs_event_block.call(check_result(status), filename, EVENTS[events])
17
+ end
18
+
19
+ public :callback
20
+ end
21
+ end
data/lib/uv/handle.rb ADDED
@@ -0,0 +1,65 @@
1
+ module UV
2
+ module Handle
3
+ include Assertions, Resource, Listener
4
+
5
+ def initialize(loop, pointer)
6
+ @loop, @pointer = loop, pointer
7
+ end
8
+
9
+ # Public: Increment internal ref counter for the handle on the loop. Useful for
10
+ # extending the loop with custom watchers that need to make loop not stop
11
+ #
12
+ # Returns self
13
+ def ref
14
+ UV.ref(@pointer)
15
+
16
+ self
17
+ end
18
+
19
+ # Public: Decrement internal ref counter for the handle on the loop, useful to stop
20
+ # loop even when there are outstanding open handles
21
+ #
22
+ # Returns self
23
+ def unref
24
+ UV.unref(@pointer)
25
+
26
+ self
27
+ end
28
+
29
+ def close(&block)
30
+ assert_block(block)
31
+ assert_arity(0, block)
32
+
33
+ @close_block = block
34
+
35
+ UV.close(@pointer, callback(:on_close))
36
+
37
+ self
38
+ end
39
+
40
+ def active?
41
+ UV.is_active(@pointer) > 0
42
+ end
43
+
44
+ def closing?
45
+ UV.is_closing(@pointer) > 0
46
+ end
47
+
48
+ protected
49
+
50
+ def loop; @loop; end
51
+ def handle; @pointer; end
52
+
53
+ private
54
+
55
+ def handle_name
56
+ self.class.name.split('::').last.downcase.to_sym
57
+ end
58
+
59
+ def on_close(pointer)
60
+ UV.free(pointer)
61
+ clear_callbacks
62
+ @close_block.call
63
+ end
64
+ end
65
+ end
data/lib/uv/idle.rb ADDED
@@ -0,0 +1,27 @@
1
+ module UV
2
+ class Idle
3
+ include Handle
4
+
5
+ def start(&block)
6
+ assert_block(block)
7
+ assert_arity(1, block)
8
+
9
+ @idle_block = block
10
+
11
+ check_result! UV.idle_start(handle, callback(:on_idle))
12
+
13
+ self
14
+ end
15
+
16
+ def stop
17
+ check_result! UV.idle_stop(handle)
18
+
19
+ self
20
+ end
21
+
22
+ private
23
+ def on_idle(handle, status)
24
+ @idle_block.call(check_result(status))
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ require 'set'
2
+
3
+ module UV
4
+ module Listener
5
+ private
6
+ def callbacks
7
+ @callbacks ||= Set.new
8
+ end
9
+
10
+ def callback(name)
11
+ const_name = "#{name.upcase}_#{object_id}"
12
+ unless self.class.const_defined?(const_name)
13
+ callbacks << const_name
14
+ self.class.const_set(const_name, method(name))
15
+ end
16
+ self.class.const_get(const_name)
17
+ end
18
+
19
+ def clear_callbacks
20
+ callbacks.each do |name|
21
+ self.class.send(:remove_const, name)
22
+ end
23
+ callbacks.clear
24
+ end
25
+ end
26
+ end
data/lib/uv/loop.rb ADDED
@@ -0,0 +1,326 @@
1
+ require 'thread'
2
+
3
+ module UV
4
+ class Loop
5
+ module ClassMethods
6
+ # Public: Get default loop
7
+ #
8
+ # Returns UV::Loop
9
+ def default
10
+ create(UV.default_loop)
11
+ end
12
+
13
+ # Public: Create new loop
14
+ #
15
+ # Returns UV::Loop
16
+ def new
17
+ create(UV.loop_new)
18
+ end
19
+
20
+ # Internal: Create custom loop from pointer
21
+ #
22
+ # Returns UV::Loop
23
+ def create(pointer)
24
+ allocate.tap { |i| i.send(:initialize, FFI::AutoPointer.new(pointer, UV.method(:loop_delete))) }
25
+ end
26
+ end
27
+
28
+ extend ClassMethods
29
+
30
+ include Resource, Assertions
31
+
32
+ # Internal: Initialize a loop using an FFI::Pointer
33
+ #
34
+ # Returns nothing
35
+ def initialize(pointer) # :notnew:
36
+ @pointer = pointer
37
+ end
38
+
39
+ # Public: Run the actual event loop. This method will block for the duration of event loop
40
+ #
41
+ # Returns nothing.
42
+ #
43
+ # Raises UV::Error::UNKNOWN
44
+ # Raises UV::Error::EOF
45
+ # Raises UV::Error::EADDRINFO
46
+ # Raises UV::Error::EACCES
47
+ # Raises UV::Error::EAGAIN
48
+ # Raises UV::Error::EADDRINUSE
49
+ # Raises UV::Error::EADDRNOTAVAIL
50
+ # Raises UV::Error::EAFNOSUPPORT
51
+ # Raises UV::Error::EALREADY
52
+ # Raises UV::Error::EBADF
53
+ # Raises UV::Error::EBUSY
54
+ # Raises UV::Error::ECONNABORTED
55
+ # Raises UV::Error::ECONNREFUSED
56
+ # Raises UV::Error::ECONNRESET
57
+ # Raises UV::Error::EDESTADDRREQ
58
+ # Raises UV::Error::EFAULT
59
+ # Raises UV::Error::EHOSTUNREACH
60
+ # Raises UV::Error::EINTR
61
+ # Raises UV::Error::EINVAL
62
+ # Raises UV::Error::EISCONN
63
+ # Raises UV::Error::EMFILE
64
+ # Raises UV::Error::EMSGSIZE
65
+ # Raises UV::Error::ENETDOWN
66
+ # Raises UV::Error::ENETUNREACH
67
+ # Raises UV::Error::ENFILE
68
+ # Raises UV::Error::ENOBUFS
69
+ # Raises UV::Error::ENOMEM
70
+ # Raises UV::Error::ENOTDIR
71
+ # Raises UV::Error::EISDIR
72
+ # Raises UV::Error::ENONET
73
+ # Raises UV::Error::ENOTCONN
74
+ # Raises UV::Error::ENOTSOCK
75
+ # Raises UV::Error::ENOTSUP
76
+ # Raises UV::Error::ENOENT
77
+ # Raises UV::Error::ENOSYS
78
+ # Raises UV::Error::EPIPE
79
+ # Raises UV::Error::EPROTO
80
+ # Raises UV::Error::EPROTONOSUPPORT
81
+ # Raises UV::Error::EPROTOTYPE
82
+ # Raises UV::Error::ETIMEDOUT
83
+ # Raises UV::Error::ECHARSE
84
+ # Raises UV::Error::EAIFAMNOSUPPORT
85
+ # Raises UV::Error::EAISERVICE
86
+ # Raises UV::Error::EAISOCKTYPE
87
+ # Raises UV::Error::ESHUTDOWN
88
+ # Raises UV::Error::EEXIST
89
+ # Raises UV::Error::ESRCH
90
+ # Raises UV::Error::ENAMETOOLONG
91
+ # Raises UV::Error::EPERM
92
+ # Raises UV::Error::ELOOP
93
+ # Raises UV::Error::EXDEV
94
+ # Raises UV::Error::ENOTEMPTY
95
+ # Raises UV::Error::ENOSPC
96
+ def run
97
+ check_result! UV.run(@pointer)
98
+ end
99
+
100
+ # Public: Runs outstanding events once, yields control back
101
+ #
102
+ # Returns nothing.
103
+ #
104
+ # Raises UV::Error::UNKNOWN
105
+ # Raises UV::Error::EOF
106
+ # Raises UV::Error::EADDRINFO
107
+ # Raises UV::Error::EACCES
108
+ # Raises UV::Error::EAGAIN
109
+ # Raises UV::Error::EADDRINUSE
110
+ # Raises UV::Error::EADDRNOTAVAIL
111
+ # Raises UV::Error::EAFNOSUPPORT
112
+ # Raises UV::Error::EALREADY
113
+ # Raises UV::Error::EBADF
114
+ # Raises UV::Error::EBUSY
115
+ # Raises UV::Error::ECONNABORTED
116
+ # Raises UV::Error::ECONNREFUSED
117
+ # Raises UV::Error::ECONNRESET
118
+ # Raises UV::Error::EDESTADDRREQ
119
+ # Raises UV::Error::EFAULT
120
+ # Raises UV::Error::EHOSTUNREACH
121
+ # Raises UV::Error::EINTR
122
+ # Raises UV::Error::EINVAL
123
+ # Raises UV::Error::EISCONN
124
+ # Raises UV::Error::EMFILE
125
+ # Raises UV::Error::EMSGSIZE
126
+ # Raises UV::Error::ENETDOWN
127
+ # Raises UV::Error::ENETUNREACH
128
+ # Raises UV::Error::ENFILE
129
+ # Raises UV::Error::ENOBUFS
130
+ # Raises UV::Error::ENOMEM
131
+ # Raises UV::Error::ENOTDIR
132
+ # Raises UV::Error::EISDIR
133
+ # Raises UV::Error::ENONET
134
+ # Raises UV::Error::ENOTCONN
135
+ # Raises UV::Error::ENOTSOCK
136
+ # Raises UV::Error::ENOTSUP
137
+ # Raises UV::Error::ENOENT
138
+ # Raises UV::Error::ENOSYS
139
+ # Raises UV::Error::EPIPE
140
+ # Raises UV::Error::EPROTO
141
+ # Raises UV::Error::EPROTONOSUPPORT
142
+ # Raises UV::Error::EPROTOTYPE
143
+ # Raises UV::Error::ETIMEDOUT
144
+ # Raises UV::Error::ECHARSE
145
+ # Raises UV::Error::EAIFAMNOSUPPORT
146
+ # Raises UV::Error::EAISERVICE
147
+ # Raises UV::Error::EAISOCKTYPE
148
+ # Raises UV::Error::ESHUTDOWN
149
+ # Raises UV::Error::EEXIST
150
+ # Raises UV::Error::ESRCH
151
+ # Raises UV::Error::ENAMETOOLONG
152
+ # Raises UV::Error::EPERM
153
+ # Raises UV::Error::ELOOP
154
+ # Raises UV::Error::EXDEV
155
+ # Raises UV::Error::ENOTEMPTY
156
+ # Raises UV::Error::ENOSPC
157
+ def run_once
158
+ check_result! UV.run_once(@pointer)
159
+ end
160
+
161
+ # Public: forces loop time update, useful for getting more granular times
162
+ #
163
+ # Returns nothing
164
+ def update_time
165
+ UV.update_time(@pointer)
166
+ end
167
+
168
+ # Public: Get current time in microseconds
169
+ #
170
+ # Returns timestamp with microseconds as an Integer
171
+ def now
172
+ UV.now(@pointer)
173
+ end
174
+
175
+ # Internal: Get last error from the loop
176
+ #
177
+ # Returns one of UV::Error or nil
178
+ def last_error
179
+ err = UV.last_error(@pointer)
180
+ name = UV.err_name(err)
181
+ msg = UV.strerror(err)
182
+
183
+ return nil if name == "OK"
184
+
185
+ Error.const_get(name.to_sym).new(msg)
186
+ end
187
+
188
+ # Public: Get a new timer instance
189
+ #
190
+ # Returns UV::Timer
191
+ def timer
192
+ timer_ptr = UV.create_handle(:uv_timer)
193
+
194
+ check_result! UV.timer_init(@pointer, timer_ptr)
195
+ Timer.new(self, timer_ptr)
196
+ end
197
+
198
+ # Public: Get a new TCP instance
199
+ #
200
+ # Returns UV::TCP instance
201
+ def tcp
202
+ tcp_ptr = UV.create_handle(:uv_tcp)
203
+
204
+ check_result! UV.tcp_init(@pointer, tcp_ptr)
205
+ TCP.new(self, tcp_ptr)
206
+ end
207
+
208
+ # Public: Get a new UDP instance
209
+ #
210
+ # Returns UV::UDP instance
211
+ def udp
212
+ udp_ptr = UV.create_handle(:uv_udp)
213
+
214
+ check_result! UV.udp_init(@pointer, udp_ptr)
215
+ UV::UDP.new(self, udp_ptr)
216
+ end
217
+
218
+ # Public: Get a new TTY instance
219
+ #
220
+ # fileno - Integer file descriptor of a tty device.
221
+ # readable - Boolean wether TTY is readable or not
222
+ #
223
+ # Returns UV::TTY
224
+ #
225
+ # Raises ArgumentError if fileno argument is not an Integer
226
+ # Raises Argument error if readable is not a Boolean
227
+ def tty(fileno, readable = false)
228
+ assert_type(Integer, fileno, "io#fileno must return an integer file descriptor, #{fileno.inspect} given")
229
+ assert_boolean(readable)
230
+
231
+ tty_ptr = UV.create_handle(:uv_tty)
232
+
233
+ check_result! UV.tty_init(@pointer, tty_ptr, fileno, readable ? 1 : 0)
234
+ TTY.new(self, tty_ptr)
235
+ end
236
+
237
+ # Public: Get a new Pipe instance
238
+ #
239
+ # ipc - Boolean wether handle will be used for ipc, useful for sharing tcp socket
240
+ # between processes
241
+ #
242
+ # Returns UV::Pipe
243
+ def pipe(ipc = false)
244
+ assert_boolean(ipc)
245
+
246
+ pipe_ptr = UV.create_handle(:uv_pipe)
247
+
248
+ check_result! UV.pipe_init(@pointer, pipe_ptr, ipc ? 1 : 0)
249
+ Pipe.new(self, pipe_ptr)
250
+ end
251
+
252
+ # Public: Get a new Prepare handle
253
+ #
254
+ # Returns UV::Prepare
255
+ def prepare
256
+ prepare_ptr = UV.create_handle(:uv_prepare)
257
+
258
+ check_result! UV.prepare_init(@pointer, prepare_ptr)
259
+ Prepare.new(self, prepare_ptr)
260
+ end
261
+
262
+ # Public: Get a new Check handle
263
+ #
264
+ # Returns UV::Check
265
+ def check
266
+ check_ptr = UV.create_handle(:uv_check)
267
+
268
+ check_result! UV.check_init(@pointer, check_ptr)
269
+ Check.new(self, check_ptr)
270
+ end
271
+
272
+ # Public: Get a new Idle handle
273
+ #
274
+ # Returns UV::Handle
275
+ def idle
276
+ idle_ptr = UV.create_handle(:uv_idle)
277
+
278
+ check_result! UV.idle_init(@pointer, idle_ptr)
279
+ Idle.new(self, idle_ptr)
280
+ end
281
+
282
+ # Public: Get a new Async handle
283
+ #
284
+ # Returns UV::Async
285
+ #
286
+ # Raises ArgumentError if block is not given and is not expecting one argument exactly
287
+ def async(&block)
288
+ assert_block(block)
289
+ assert_arity(1, block)
290
+
291
+ async_ptr = UV.create_handle(:uv_async)
292
+ async = Async.new(self, async_ptr, &block)
293
+
294
+ check_result! UV.async_init(@pointer, async_ptr, async.callback(:on_async))
295
+ async
296
+ end
297
+
298
+ # Public: Get a new Filesystem instance
299
+ #
300
+ # Returns UV::Filesystem
301
+ def fs
302
+ Filesystem.new(self)
303
+ end
304
+
305
+ # Public: Get a new FSEvent instance
306
+ #
307
+ # Returns UV::FSEvent
308
+ def fs_event(path, &block)
309
+ assert_block(block)
310
+ assert_arity(3, block)
311
+
312
+ fs_event_ptr = UV.create_handle(:uv_fs_event)
313
+ fs_event = FSEvent.new(self, fs_event_ptr, &block)
314
+
315
+ check_result! UV.fs_event_init(@pointer, fs_event_ptr, path, fs_event.callback(:on_fs_event), 0)
316
+ fs_event
317
+ end
318
+
319
+ # Internal: Get a hold of internal loop pointer instance
320
+ #
321
+ # Returns FFI::Pointer
322
+ def to_ptr
323
+ @pointer
324
+ end
325
+ end
326
+ end