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