libuv 0.11.22 → 0.12.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.
- checksums.yaml +4 -4
- data/.gitignore +19 -17
- data/.gitmodules +3 -3
- data/.rspec +1 -1
- data/.travis.yml +16 -16
- data/Gemfile +4 -4
- data/LICENSE +23 -23
- data/README.md +89 -89
- data/Rakefile +31 -31
- data/lib/libuv.rb +54 -54
- data/lib/libuv/async.rb +47 -47
- data/lib/libuv/check.rb +55 -55
- data/lib/libuv/dns.rb +85 -85
- data/lib/libuv/error.rb +78 -74
- data/lib/libuv/ext/ext.rb +260 -258
- data/lib/libuv/ext/platform/darwin_x64.rb +23 -23
- data/lib/libuv/ext/platform/linux.rb +7 -7
- data/lib/libuv/ext/platform/unix.rb +29 -29
- data/lib/libuv/ext/platform/windows.rb +40 -40
- data/lib/libuv/ext/tasks.rb +31 -31
- 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 +14 -14
- data/lib/libuv/ext/types.rb +238 -238
- data/lib/libuv/file.rb +281 -269
- data/lib/libuv/filesystem.rb +232 -232
- data/lib/libuv/fs_event.rb +31 -31
- data/lib/libuv/handle.rb +85 -85
- data/lib/libuv/idle.rb +56 -56
- data/lib/libuv/loop.rb +412 -412
- data/lib/libuv/mixins/assertions.rb +23 -23
- data/lib/libuv/mixins/fs_checks.rb +60 -58
- data/lib/libuv/mixins/listener.rb +34 -34
- data/lib/libuv/mixins/net.rb +40 -40
- data/lib/libuv/mixins/resource.rb +27 -27
- data/lib/libuv/mixins/stream.rb +153 -154
- data/lib/libuv/pipe.rb +184 -203
- data/lib/libuv/prepare.rb +56 -56
- data/lib/libuv/signal.rb +51 -51
- data/lib/libuv/tcp.rb +334 -334
- data/lib/libuv/timer.rb +85 -85
- data/lib/libuv/tty.rb +37 -37
- data/lib/libuv/udp.rb +240 -240
- data/lib/libuv/version.rb +3 -3
- data/lib/libuv/work.rb +75 -75
- data/libuv.gemspec +56 -56
- data/spec/async_spec.rb +61 -60
- data/spec/cpu_spec.rb +10 -10
- data/spec/defer_spec.rb +980 -980
- data/spec/dns_spec.rb +96 -90
- data/spec/filesystem_spec.rb +270 -261
- data/spec/idle_spec.rb +56 -56
- data/spec/pipe_spec.rb +160 -160
- data/spec/tcp_spec.rb +271 -267
- metadata +64 -51
@@ -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 unless proc.respond_to? :call
|
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 unless proc.respond_to? :call
|
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,58 +1,60 @@
|
|
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
|
-
|
23
|
-
stats = {}
|
24
|
-
uv_members.each do |key|
|
25
|
-
stats[key] = uv_stat[key]
|
26
|
-
end
|
27
|
-
|
28
|
-
cleanup(req)
|
29
|
-
@stat_deferred.resolve(stats)
|
30
|
-
end
|
31
|
-
@stat_deferred = nil
|
32
|
-
end
|
33
|
-
|
34
|
-
def pre_check(deferrable, request, result)
|
35
|
-
error = check_result result
|
36
|
-
if error
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
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
|
+
|
23
|
+
stats = {}
|
24
|
+
uv_members.each do |key|
|
25
|
+
stats[key] = uv_stat[key]
|
26
|
+
end
|
27
|
+
|
28
|
+
cleanup(req)
|
29
|
+
@stat_deferred.resolve(stats)
|
30
|
+
end
|
31
|
+
@stat_deferred = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def pre_check(deferrable, request, result)
|
35
|
+
error = check_result result
|
36
|
+
if error
|
37
|
+
@request_refs.delete request.address
|
38
|
+
::Libuv::Ext.free(request)
|
39
|
+
deferrable.reject(error)
|
40
|
+
end
|
41
|
+
deferrable.promise
|
42
|
+
end
|
43
|
+
|
44
|
+
def cleanup(req)
|
45
|
+
::Libuv::Ext.fs_req_cleanup(req)
|
46
|
+
::Libuv::Ext.free(req)
|
47
|
+
end
|
48
|
+
|
49
|
+
def post_check(req, deferrable)
|
50
|
+
error = check_result(req[:result])
|
51
|
+
if error
|
52
|
+
cleanup(req)
|
53
|
+
deferrable.reject(error)
|
54
|
+
false
|
55
|
+
else
|
56
|
+
true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
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
|
data/lib/libuv/mixins/net.rb
CHANGED
@@ -1,40 +1,40 @@
|
|
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
|
-
INET_ADDRSTRLEN = 16
|
10
|
-
INET6_ADDRSTRLEN = 46
|
11
|
-
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
|
16
|
-
def get_sockaddr_and_len
|
17
|
-
sockaddr = FFI::MemoryPointer.new(::Libuv::Ext::Sockaddr)
|
18
|
-
len = FFI::MemoryPointer.new(:int)
|
19
|
-
len.put_int(0, ::Libuv::Ext::Sockaddr.size)
|
20
|
-
[sockaddr, len]
|
21
|
-
end
|
22
|
-
|
23
|
-
def get_ip_and_port(sockaddr, len = nil)
|
24
|
-
if sockaddr[:sa_family] == Socket::Constants::AF_INET6
|
25
|
-
len ||= INET6_ADDRSTRLEN
|
26
|
-
sockaddr_in6 = ::Libuv::Ext::SockaddrIn6.new(sockaddr.pointer)
|
27
|
-
ip_ptr = FFI::MemoryPointer.new(:char, len)
|
28
|
-
::Libuv::Ext.ip6_name(sockaddr_in6, ip_ptr, len)
|
29
|
-
port = ::Libuv::Ext.ntohs(sockaddr_in6[:sin6_port])
|
30
|
-
else
|
31
|
-
len ||= INET_ADDRSTRLEN
|
32
|
-
sockaddr_in = ::Libuv::Ext::SockaddrIn.new(sockaddr.pointer)
|
33
|
-
ip_ptr = FFI::MemoryPointer.new(:char, len)
|
34
|
-
::Libuv::Ext.ip4_name(sockaddr_in, ip_ptr, len)
|
35
|
-
port = ::Libuv::Ext.ntohs(sockaddr_in[:sin_port])
|
36
|
-
end
|
37
|
-
[ip_ptr.read_string, port]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
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
|
+
INET_ADDRSTRLEN = 16
|
10
|
+
INET6_ADDRSTRLEN = 46
|
11
|
+
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
|
16
|
+
def get_sockaddr_and_len
|
17
|
+
sockaddr = FFI::MemoryPointer.new(::Libuv::Ext::Sockaddr)
|
18
|
+
len = FFI::MemoryPointer.new(:int)
|
19
|
+
len.put_int(0, ::Libuv::Ext::Sockaddr.size)
|
20
|
+
[sockaddr, len]
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_ip_and_port(sockaddr, len = nil)
|
24
|
+
if sockaddr[:sa_family] == Socket::Constants::AF_INET6
|
25
|
+
len ||= INET6_ADDRSTRLEN
|
26
|
+
sockaddr_in6 = ::Libuv::Ext::SockaddrIn6.new(sockaddr.pointer)
|
27
|
+
ip_ptr = FFI::MemoryPointer.new(:char, len)
|
28
|
+
::Libuv::Ext.ip6_name(sockaddr_in6, ip_ptr, len)
|
29
|
+
port = ::Libuv::Ext.ntohs(sockaddr_in6[:sin6_port])
|
30
|
+
else
|
31
|
+
len ||= INET_ADDRSTRLEN
|
32
|
+
sockaddr_in = ::Libuv::Ext::SockaddrIn.new(sockaddr.pointer)
|
33
|
+
ip_ptr = FFI::MemoryPointer.new(:char, len)
|
34
|
+
::Libuv::Ext.ip4_name(sockaddr_in, ip_ptr, len)
|
35
|
+
port = ::Libuv::Ext.ntohs(sockaddr_in[:sin_port])
|
36
|
+
end
|
37
|
+
[ip_ptr.read_string, port]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,28 +1,28 @@
|
|
1
|
-
module Libuv
|
2
|
-
module Resource
|
3
|
-
|
4
|
-
|
5
|
-
def resolve(deferred, rc)
|
6
|
-
if rc && rc < 0
|
7
|
-
deferred.reject(@loop.lookup_error(rc))
|
8
|
-
else
|
9
|
-
deferred.resolve(nil)
|
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 && rc < 0
|
7
|
+
deferred.reject(@loop.lookup_error(rc))
|
8
|
+
else
|
9
|
+
deferred.resolve(nil)
|
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
|
data/lib/libuv/mixins/stream.rb
CHANGED
@@ -1,155 +1,154 @@
|
|
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 -> send
|
41
|
-
deferred = @loop.defer
|
42
|
-
if !@closed
|
43
|
-
begin
|
44
|
-
assert_type(String, data, WRITE_ERROR)
|
45
|
-
|
46
|
-
size
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
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 -> send
|
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
|
+
buffer1 = ::Libuv::Ext.malloc size
|
48
|
+
buffer1.write_string data
|
49
|
+
buffer = ::Libuv::Ext.buf_init(buffer1, size)
|
50
|
+
|
51
|
+
# local as this variable will be available until the handle is closed
|
52
|
+
@write_callbacks ||= {}
|
53
|
+
req = ::Libuv::Ext.create_request(:uv_write)
|
54
|
+
@write_callbacks[req.address] = [deferred, buffer1]
|
55
|
+
error = check_result ::Libuv::Ext.write(req, handle, buffer, 1, callback(:write_complete))
|
56
|
+
|
57
|
+
if error
|
58
|
+
@write_callbacks.delete req.address
|
59
|
+
::Libuv::Ext.free(req)
|
60
|
+
::Libuv::Ext.free(buffer1)
|
61
|
+
deferred.reject(error)
|
62
|
+
|
63
|
+
reject(error) # close the handle
|
64
|
+
end
|
65
|
+
rescue => e
|
66
|
+
deferred.reject(e) # this write exception may not be fatal
|
67
|
+
end
|
68
|
+
else
|
69
|
+
deferred.reject(RuntimeError.new(STREAM_CLOSED_ERROR))
|
70
|
+
end
|
71
|
+
deferred.promise
|
72
|
+
end
|
73
|
+
|
74
|
+
def readable?
|
75
|
+
return false if @closed
|
76
|
+
::Libuv::Ext.is_readable(handle) > 0
|
77
|
+
end
|
78
|
+
|
79
|
+
def writable?
|
80
|
+
return false if @closed
|
81
|
+
::Libuv::Ext.is_writable(handle) > 0
|
82
|
+
end
|
83
|
+
|
84
|
+
def progress(callback = nil, &blk)
|
85
|
+
@progress = callback || blk
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
|
92
|
+
def on_listen(server, status)
|
93
|
+
e = check_result(status)
|
94
|
+
|
95
|
+
if e
|
96
|
+
reject(e) # is this cause for closing the handle?
|
97
|
+
else
|
98
|
+
begin
|
99
|
+
@on_listen.call(self)
|
100
|
+
rescue Exception => e
|
101
|
+
@loop.log :error, :stream_listen_cb, e
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def on_allocate(client, suggested_size, buffer)
|
107
|
+
buffer[:len] = suggested_size
|
108
|
+
buffer[:base] = ::Libuv::Ext.malloc(suggested_size)
|
109
|
+
end
|
110
|
+
|
111
|
+
def write_complete(req, status)
|
112
|
+
deferred, buffer1 = @write_callbacks.delete req.address
|
113
|
+
|
114
|
+
::Libuv::Ext.free(req)
|
115
|
+
::Libuv::Ext.free(buffer1)
|
116
|
+
|
117
|
+
resolve deferred, status
|
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
|
+
# I assume this is desirable behaviour
|
127
|
+
if e.is_a? ::Libuv::Error::EOF
|
128
|
+
close # Close gracefully
|
129
|
+
else
|
130
|
+
reject(e)
|
131
|
+
end
|
132
|
+
else
|
133
|
+
data = base.read_string(nread)
|
134
|
+
::Libuv::Ext.free(base)
|
135
|
+
|
136
|
+
if @tls.nil?
|
137
|
+
begin
|
138
|
+
@progress.call data, self
|
139
|
+
rescue Exception => e
|
140
|
+
@loop.log :error, :stream_progress_cb, e
|
141
|
+
end
|
142
|
+
else
|
143
|
+
@tls.decrypt(data)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def on_shutdown(req, status)
|
149
|
+
::Libuv::Ext.free(req)
|
150
|
+
@close_error = check_result(status)
|
151
|
+
close
|
152
|
+
end
|
153
|
+
end
|
155
154
|
end
|