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.
Files changed (55) hide show
  1. data/.gitignore +17 -17
  2. data/.gitmodules +3 -3
  3. data/.rspec +1 -1
  4. data/.travis.yml +16 -16
  5. data/Gemfile +2 -2
  6. data/LICENSE +23 -23
  7. data/README.md +82 -73
  8. data/Rakefile +31 -31
  9. data/lib/libuv.rb +53 -34
  10. data/lib/libuv/async.rb +47 -33
  11. data/lib/libuv/check.rb +55 -48
  12. data/lib/libuv/error.rb +70 -70
  13. data/lib/libuv/ext/ext.rb +264 -256
  14. data/lib/libuv/ext/platform/darwin_x64.rb +12 -12
  15. data/lib/libuv/ext/platform/linux.rb +7 -7
  16. data/lib/libuv/ext/platform/unix.rb +13 -13
  17. data/lib/libuv/ext/platform/windows.rb +26 -26
  18. data/lib/libuv/ext/tasks.rb +27 -27
  19. data/lib/libuv/ext/tasks/mac.rb +23 -23
  20. data/lib/libuv/ext/tasks/unix.rb +23 -23
  21. data/lib/libuv/ext/tasks/win.rb +11 -11
  22. data/lib/libuv/ext/types.rb +234 -229
  23. data/lib/libuv/file.rb +192 -0
  24. data/lib/libuv/filesystem.rb +233 -0
  25. data/lib/libuv/fs_event.rb +31 -31
  26. data/lib/libuv/handle.rb +85 -81
  27. data/lib/libuv/idle.rb +56 -49
  28. data/lib/libuv/loop.rb +338 -310
  29. data/lib/libuv/{assertions.rb → mixins/assertions.rb} +23 -23
  30. data/lib/libuv/mixins/fs_checks.rb +55 -0
  31. data/lib/libuv/{listener.rb → mixins/listener.rb} +34 -34
  32. data/lib/libuv/{net.rb → mixins/net.rb} +37 -37
  33. data/lib/libuv/{resource.rb → mixins/resource.rb} +27 -27
  34. data/lib/libuv/{stream.rb → mixins/stream.rb} +143 -123
  35. data/lib/libuv/pipe.rb +197 -97
  36. data/lib/libuv/prepare.rb +56 -49
  37. data/lib/libuv/q.rb +1 -1
  38. data/lib/libuv/signal.rb +51 -0
  39. data/lib/libuv/tcp.rb +204 -193
  40. data/lib/libuv/timer.rb +88 -75
  41. data/lib/libuv/tty.rb +37 -34
  42. data/lib/libuv/udp.rb +273 -255
  43. data/lib/libuv/version.rb +3 -3
  44. data/lib/libuv/work.rb +63 -61
  45. data/libuv.gemspec +54 -54
  46. data/spec/async_spec.rb +60 -60
  47. data/spec/cpu_spec.rb +10 -0
  48. data/spec/defer_spec.rb +980 -980
  49. data/spec/filesystem_spec.rb +119 -0
  50. data/spec/idle_spec.rb +56 -56
  51. data/spec/pipe_spec.rb +153 -148
  52. data/spec/tcp_spec.rb +203 -188
  53. metadata +73 -49
  54. checksums.yaml +0 -15
  55. data/lib/libuv/simple_async.rb +0 -28
@@ -1,23 +1,23 @@
1
- module Libuv
2
- module Assertions
3
- MSG_NO_PROC = 'no block given'
4
-
5
- def assert_block(proc, msg = MSG_NO_PROC)
6
- raise ArgumentError, msg, caller if proc.nil?
7
- end
8
-
9
- def assert_type(type, actual, msg = nil)
10
- if not actual.kind_of?(type)
11
- msg ||= "value #{actual.inspect} is not a valid #{type}"
12
- raise ArgumentError, msg, caller
13
- end
14
- end
15
-
16
- def assert_boolean(actual, msg = nil)
17
- if not (actual.kind_of?(TrueClass) || actual.kind_of?(FalseClass))
18
- msg ||= "value #{actual.inspect} is not a valid Boolean"
19
- raise ArgumentError, msg, caller
20
- end
21
- end
22
- end
23
- end
1
+ module Libuv
2
+ module Assertions
3
+ MSG_NO_PROC = 'no block given'
4
+
5
+ def assert_block(proc, msg = MSG_NO_PROC)
6
+ raise ArgumentError, msg, caller if proc.nil?
7
+ end
8
+
9
+ def assert_type(type, actual, msg = nil)
10
+ if not actual.kind_of?(type)
11
+ msg ||= "value #{actual.inspect} is not a valid #{type}"
12
+ raise ArgumentError, msg, caller
13
+ end
14
+ end
15
+
16
+ def assert_boolean(actual, msg = nil)
17
+ if not (actual.kind_of?(TrueClass) || actual.kind_of?(FalseClass))
18
+ msg ||= "value #{actual.inspect} is not a valid Boolean"
19
+ raise ArgumentError, msg, caller
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,55 @@
1
+
2
+ module Libuv
3
+ module FsChecks
4
+
5
+
6
+ def stat
7
+ @stat_deferred = @loop.defer
8
+
9
+ request = ::Libuv::Ext.create_request(:uv_fs)
10
+ pre_check @stat_deferred, request, ::Libuv::Ext.fs_fstat(@loop.handle, request, @fileno, callback(:on_stat))
11
+ @stat_deferred.promise
12
+ end
13
+
14
+
15
+ private
16
+
17
+
18
+ def on_stat(req)
19
+ if post_check(req, @stat_deferred)
20
+ uv_stat = req[:stat]
21
+ uv_members = uv_stat.members
22
+ values = UvStat.members.map { |k| uv_members.include?(k) ? uv_stat[k] : nil }
23
+ uv_stat = UvStat.new(*values)
24
+
25
+ cleanup(req)
26
+ @stat_deferred.resolve(uv_stat)
27
+ end
28
+ @stat_deferred = nil
29
+ end
30
+
31
+ def pre_check(deferrable, request, result)
32
+ error = check_result result
33
+ if error
34
+ ::Libuv::Ext.free(request)
35
+ deferrable.reject(error)
36
+ end
37
+ end
38
+
39
+ def cleanup(req)
40
+ ::Libuv::Ext.fs_req_cleanup(req)
41
+ ::Libuv::Ext.free(req)
42
+ end
43
+
44
+ def post_check(req, deferrable)
45
+ error = check_result(req[:result])
46
+ if error
47
+ cleanup(req)
48
+ deferrable.reject(error)
49
+ false
50
+ else
51
+ true
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,34 +1,34 @@
1
- require 'thread_safe'
2
- require 'set'
3
-
4
- module Libuv
5
- module Listener
6
-
7
-
8
- private
9
-
10
-
11
- CALLBACKS = ThreadSafe::Cache.new
12
-
13
-
14
- def callbacks
15
- @callbacks ||= Set.new
16
- end
17
-
18
- def callback(name)
19
- const_name = "#{name}_#{object_id}".to_sym
20
- unless CALLBACKS[const_name]
21
- callbacks << const_name
22
- CALLBACKS[const_name] = method(name)
23
- end
24
- CALLBACKS[const_name]
25
- end
26
-
27
- def clear_callbacks
28
- callbacks.each do |name|
29
- CALLBACKS.delete(name)
30
- end
31
- callbacks.clear
32
- end
33
- end
34
- end
1
+ require 'thread_safe'
2
+ require 'set'
3
+
4
+ module Libuv
5
+ module Listener
6
+
7
+
8
+ private
9
+
10
+
11
+ CALLBACKS = ThreadSafe::Cache.new
12
+
13
+
14
+ def callbacks
15
+ @callbacks ||= Set.new
16
+ end
17
+
18
+ def callback(name)
19
+ const_name = "#{name}_#{object_id}".to_sym
20
+ unless CALLBACKS[const_name]
21
+ callbacks << const_name
22
+ CALLBACKS[const_name] = method(name)
23
+ end
24
+ CALLBACKS[const_name]
25
+ end
26
+
27
+ def clear_callbacks
28
+ callbacks.each do |name|
29
+ CALLBACKS.delete(name)
30
+ end
31
+ callbacks.clear
32
+ end
33
+ end
34
+ end
@@ -1,38 +1,38 @@
1
- require 'socket'
2
-
3
- module Libuv
4
- module Net
5
-
6
-
7
- IP_ARGUMENT_ERROR = "ip must be a String".freeze # Arguments specifying an IP address
8
- PORT_ARGUMENT_ERROR = "port must be an Integer".freeze # Arguments specifying an IP port
9
-
10
-
11
- private
12
-
13
-
14
- def get_sockaddr_and_len
15
- sockaddr = FFI::MemoryPointer.new(UV::Sockaddr)
16
- len = FFI::MemoryPointer.new(:int)
17
- len.put_int(0, UV::Sockaddr.size)
18
- [sockaddr, len]
19
- end
20
-
21
- def get_ip_and_port(sockaddr, len=nil)
22
- if sockaddr[:sa_family] == Socket::Constants::AF_INET6
23
- len ||= Socket::Constants::INET6_ADDRSTRLEN
24
- sockaddr_in6 = UV::SockaddrIn6.new(sockaddr.pointer)
25
- ip_ptr = FFI::MemoryPointer.new(:char, len)
26
- ::Libuv::Ext.ip6_name(sockaddr_in6, ip_ptr, len)
27
- port = ::Libuv::Ext.ntohs(sockaddr_in6[:sin6_port])
28
- else
29
- len ||= Socket::Constants::INET_ADDRSTRLEN
30
- sockaddr_in = UV::SockaddrIn.new(sockaddr.pointer)
31
- ip_ptr = FFI::MemoryPointer.new(:char, len)
32
- ::Libuv::Ext.ip4_name(sockaddr_in, ip_ptr, len)
33
- port = ::Libuv::Ext.ntohs(sockaddr_in[:sin_port])
34
- end
35
- [ip_ptr.read_string, port]
36
- end
37
- end
1
+ require 'socket'
2
+
3
+ module Libuv
4
+ module Net
5
+
6
+
7
+ IP_ARGUMENT_ERROR = "ip must be a String".freeze # Arguments specifying an IP address
8
+ PORT_ARGUMENT_ERROR = "port must be an Integer".freeze # Arguments specifying an IP port
9
+
10
+
11
+ private
12
+
13
+
14
+ def get_sockaddr_and_len
15
+ sockaddr = FFI::MemoryPointer.new(UV::Sockaddr)
16
+ len = FFI::MemoryPointer.new(:int)
17
+ len.put_int(0, UV::Sockaddr.size)
18
+ [sockaddr, len]
19
+ end
20
+
21
+ def get_ip_and_port(sockaddr, len=nil)
22
+ if sockaddr[:sa_family] == Socket::Constants::AF_INET6
23
+ len ||= Socket::Constants::INET6_ADDRSTRLEN
24
+ sockaddr_in6 = UV::SockaddrIn6.new(sockaddr.pointer)
25
+ ip_ptr = FFI::MemoryPointer.new(:char, len)
26
+ ::Libuv::Ext.ip6_name(sockaddr_in6, ip_ptr, len)
27
+ port = ::Libuv::Ext.ntohs(sockaddr_in6[:sin6_port])
28
+ else
29
+ len ||= Socket::Constants::INET_ADDRSTRLEN
30
+ sockaddr_in = UV::SockaddrIn.new(sockaddr.pointer)
31
+ ip_ptr = FFI::MemoryPointer.new(:char, len)
32
+ ::Libuv::Ext.ip4_name(sockaddr_in, ip_ptr, len)
33
+ port = ::Libuv::Ext.ntohs(sockaddr_in[:sin_port])
34
+ end
35
+ [ip_ptr.read_string, port]
36
+ end
37
+ end
38
38
  end
@@ -1,28 +1,28 @@
1
- module Libuv
2
- module Resource
3
-
4
-
5
- def resolve(deferred, rc)
6
- if rc.nil? || rc >= 0
7
- deferred.resolve(nil)
8
- else
9
- deferred.reject(@loop.lookup_error(rc))
10
- end
11
- end
12
-
13
- def check_result!(rc)
14
- e = @loop.lookup_error(rc) unless rc.nil? || rc >= 0
15
- raise e if e
16
- end
17
-
18
- def check_result(rc)
19
- @loop.lookup_error(rc) unless rc.nil? || rc >= 0
20
- end
21
-
22
- def to_ptr
23
- @pointer
24
- end
25
-
26
-
27
- end
1
+ module Libuv
2
+ module Resource
3
+
4
+
5
+ def resolve(deferred, rc)
6
+ if rc.nil? || rc >= 0
7
+ deferred.resolve(nil)
8
+ else
9
+ deferred.reject(@loop.lookup_error(rc))
10
+ end
11
+ end
12
+
13
+ def check_result!(rc)
14
+ e = @loop.lookup_error(rc) unless rc.nil? || rc >= 0
15
+ raise e if e
16
+ end
17
+
18
+ def check_result(rc)
19
+ @loop.lookup_error(rc) unless rc.nil? || rc >= 0
20
+ end
21
+
22
+ def to_ptr
23
+ @pointer
24
+ end
25
+
26
+
27
+ end
28
28
  end
@@ -1,124 +1,144 @@
1
- module Libuv
2
- module Stream
3
-
4
-
5
- BACKLOG_ERROR = "backlog must be an Integer".freeze
6
- WRITE_ERROR = "data must be a String".freeze
7
-
8
-
9
- def listen(backlog)
10
- return if @closed
11
- assert_type(Integer, backlog, BACKLOG_ERROR)
12
- error = check_result ::Libuv::Ext.listen(handle, Integer(backlog), callback(:on_listen))
13
- reject(error) if error
14
- end
15
-
16
- # Starts reading from the handle
17
- def start_read
18
- error = check_result ::Libuv::Ext.read_start(handle, callback(:on_allocate), callback(:on_read))
19
- reject(error) if error
20
- end
21
-
22
- # Stops reading from the handle
23
- def stop_read
24
- error = check_result ::Libuv::Ext.read_stop(handle)
25
- reject(error) if error
26
- end
27
-
28
- # Shutsdown the writes on the handle waiting until the last write is complete before triggering the callback
29
- def shutdown
30
- error = check_result ::Libuv::Ext.shutdown(::Libuv::Ext.create_request(:uv_shutdown), handle, callback(:on_shutdown))
31
- reject(error) if error
32
- end
33
-
34
- def write(data)
35
- deferred = @loop.defer
36
- begin
37
- assert_type(String, data, WRITE_ERROR)
38
-
39
- size = data.respond_to?(:bytesize) ? data.bytesize : data.size
40
- buffer = ::Libuv::Ext.buf_init(FFI::MemoryPointer.from_string(data), size)
41
-
42
- # local as this variable will be avaliable until the handle is closed
43
- @write_callbacks = @write_callbacks || []
44
-
45
- #
46
- # create the curried callback
47
- #
48
- callback = FFI::Function.new(:void, [:pointer, :int]) do |req, status|
49
- ::Libuv::Ext.free(req)
50
- # remove the callback from the array
51
- # assumes writes are done in order
52
- promise = @write_callbacks.shift[0]
53
- resolve promise, status
54
- end
55
-
56
-
57
- @write_callbacks << [deferred, callback]
58
- req = ::Libuv::Ext.create_request(:uv_write)
59
- error = check_result ::Libuv::Ext.write(req, handle, buffer, 1, callback)
60
-
61
- if error
62
- @write_callbacks.pop
63
- ::Libuv::Ext.free(req)
64
- deferred.reject(error)
65
-
66
- reject(error) # close the handle
67
- end
68
- rescue Exception => e
69
- deferred.reject(e) # this write exception may not be fatal
70
- end
71
- deferred.promise
72
- end
73
-
74
- def readable?
75
- ::Libuv::Ext.is_readable(handle) > 0
76
- end
77
-
78
- def writable?
79
- ::Libuv::Ext.is_writable(handle) > 0
80
- end
81
-
82
-
83
- private
84
-
85
-
86
- def on_listen(server, status)
87
- e = check_result(status)
88
-
89
- if e
90
- reject(e) # is this cause for closing the handle?
91
- else
92
- begin
93
- @on_listen.call(self)
94
- rescue Exception => e
95
- @loop.log :error, :stream_listen_cb, e
96
- end
97
- end
98
- end
99
-
100
- def on_allocate(client, suggested_size)
101
- ::Libuv::Ext.buf_init(::Libuv::Ext.malloc(suggested_size), suggested_size)
102
- end
103
-
104
- def on_read(handle, nread, buf)
105
- e = check_result(nread)
106
- base = buf[:base]
107
-
108
- if e
109
- ::Libuv::Ext.free(base)
110
- reject(e)
111
- else
112
- data = base.read_string(nread)
113
- ::Libuv::Ext.free(base)
114
- defer.notify(data) # stream the data
115
- end
116
- end
117
-
118
- def on_shutdown(req, status)
119
- ::Libuv::Ext.free(req)
120
- @close_error = check_result(status)
121
- close
122
- end
123
- end
1
+ module Libuv
2
+ module Stream
3
+
4
+
5
+ BACKLOG_ERROR = "backlog must be an Integer".freeze
6
+ WRITE_ERROR = "data must be a String".freeze
7
+ STREAM_CLOSED_ERROR = "unable to write to a closed stream".freeze
8
+ CLOSED_HANDLE_ERROR = "handle closed before accept called".freeze
9
+
10
+
11
+ def listen(backlog)
12
+ return if @closed
13
+ assert_type(Integer, backlog, BACKLOG_ERROR)
14
+ error = check_result ::Libuv::Ext.listen(handle, Integer(backlog), callback(:on_listen))
15
+ reject(error) if error
16
+ end
17
+
18
+ # Starts reading from the handle
19
+ def start_read
20
+ return if @closed
21
+ error = check_result ::Libuv::Ext.read_start(handle, callback(:on_allocate), callback(:on_read))
22
+ reject(error) if error
23
+ end
24
+
25
+ # Stops reading from the handle
26
+ def stop_read
27
+ return if @closed
28
+ error = check_result ::Libuv::Ext.read_stop(handle)
29
+ reject(error) if error
30
+ end
31
+
32
+ # Shutsdown the writes on the handle waiting until the last write is complete before triggering the callback
33
+ def shutdown
34
+ return if @closed
35
+ error = check_result ::Libuv::Ext.shutdown(::Libuv::Ext.create_request(:uv_shutdown), handle, callback(:on_shutdown))
36
+ reject(error) if error
37
+ end
38
+
39
+ def write(data)
40
+ # NOTE:: Similar to udp.rb -> write
41
+ deferred = @loop.defer
42
+ if !@closed
43
+ begin
44
+ assert_type(String, data, WRITE_ERROR)
45
+
46
+ size = data.respond_to?(:bytesize) ? data.bytesize : data.size
47
+ buffer = ::Libuv::Ext.buf_init(FFI::MemoryPointer.from_string(data), size)
48
+
49
+ # local as this variable will be avaliable until the handle is closed
50
+ @write_callbacks ||= []
51
+
52
+ #
53
+ # create the curried callback
54
+ #
55
+ callback = FFI::Function.new(:void, [:pointer, :int]) do |req, status|
56
+ ::Libuv::Ext.free(req)
57
+ # remove the callback from the array
58
+ # assumes writes are done in order
59
+ promise = @write_callbacks.shift[0]
60
+ resolve promise, status
61
+ end
62
+
63
+
64
+ @write_callbacks << [deferred, callback]
65
+ req = ::Libuv::Ext.create_request(:uv_write)
66
+ error = check_result ::Libuv::Ext.write(req, handle, buffer, 1, callback)
67
+
68
+ if error
69
+ @write_callbacks.pop
70
+ ::Libuv::Ext.free(req)
71
+ deferred.reject(error)
72
+
73
+ reject(error) # close the handle
74
+ end
75
+ rescue Exception => e
76
+ deferred.reject(e) # this write exception may not be fatal
77
+ end
78
+ else
79
+ deferred.reject(RuntimeError.new(STREAM_CLOSED_ERROR))
80
+ end
81
+ deferred.promise
82
+ end
83
+
84
+ def readable?
85
+ return false if @closed
86
+ ::Libuv::Ext.is_readable(handle) > 0
87
+ end
88
+
89
+ def writable?
90
+ return false if @closed
91
+ ::Libuv::Ext.is_writable(handle) > 0
92
+ end
93
+
94
+ def progress(callback = nil, &blk)
95
+ @progress = callback || blk
96
+ end
97
+
98
+
99
+ private
100
+
101
+
102
+ def on_listen(server, status)
103
+ e = check_result(status)
104
+
105
+ if e
106
+ reject(e) # is this cause for closing the handle?
107
+ else
108
+ begin
109
+ @on_listen.call(self)
110
+ rescue Exception => e
111
+ @loop.log :error, :stream_listen_cb, e
112
+ end
113
+ end
114
+ end
115
+
116
+ def on_allocate(client, suggested_size)
117
+ ::Libuv::Ext.buf_init(::Libuv::Ext.malloc(suggested_size), suggested_size)
118
+ end
119
+
120
+ def on_read(handle, nread, buf)
121
+ e = check_result(nread)
122
+ base = buf[:base]
123
+
124
+ if e
125
+ ::Libuv::Ext.free(base)
126
+ reject(e)
127
+ else
128
+ data = base.read_string(nread)
129
+ ::Libuv::Ext.free(base)
130
+ begin
131
+ @progress.call data, self
132
+ rescue Exception => e
133
+ @loop.log :error, :stream_progress_cb, e
134
+ end
135
+ end
136
+ end
137
+
138
+ def on_shutdown(req, status)
139
+ ::Libuv::Ext.free(req)
140
+ @close_error = check_result(status)
141
+ close
142
+ end
143
+ end
124
144
  end