uvrb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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