kgio 2.8.1 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.manifest +4 -1
- data/ChangeLog +152 -0
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +0 -1
- data/LATEST +18 -20
- data/NEWS +22 -0
- data/Rakefile +0 -37
- data/ext/kgio/accept.c +7 -4
- data/ext/kgio/ancient_ruby.h +0 -3
- data/ext/kgio/blocking_io_region.h +6 -3
- data/ext/kgio/connect.c +11 -9
- data/ext/kgio/extconf.rb +2 -0
- data/ext/kgio/kgio.h +34 -10
- data/ext/kgio/kgio_ext.c +55 -1
- data/ext/kgio/poll.c +2 -2
- data/ext/kgio/read.c +328 -0
- data/ext/kgio/set_file_path.h +1 -0
- data/ext/kgio/tryopen.c +20 -13
- data/ext/kgio/write.c +267 -0
- data/ext/kgio/writev.c +317 -0
- data/test/test_poll.rb +0 -25
- data/test/test_syssend.rb +43 -0
- metadata +31 -42
- data/ext/kgio/read_write.c +0 -852
data/.manifest
CHANGED
@@ -28,11 +28,13 @@ ext/kgio/missing_accept4.h
|
|
28
28
|
ext/kgio/my_fileno.h
|
29
29
|
ext/kgio/nonblock.h
|
30
30
|
ext/kgio/poll.c
|
31
|
-
ext/kgio/
|
31
|
+
ext/kgio/read.c
|
32
32
|
ext/kgio/set_file_path.h
|
33
33
|
ext/kgio/sock_for_fd.h
|
34
34
|
ext/kgio/tryopen.c
|
35
35
|
ext/kgio/wait.c
|
36
|
+
ext/kgio/write.c
|
37
|
+
ext/kgio/writev.c
|
36
38
|
kgio.gemspec
|
37
39
|
lib/kgio.rb
|
38
40
|
pkg.mk
|
@@ -54,6 +56,7 @@ test/test_poll.rb
|
|
54
56
|
test/test_singleton_read_write.rb
|
55
57
|
test/test_socket.rb
|
56
58
|
test/test_socketpair_read_write.rb
|
59
|
+
test/test_syssend.rb
|
57
60
|
test/test_tcp6_client_read_server_write.rb
|
58
61
|
test/test_tcp_client_read_server_write.rb
|
59
62
|
test/test_tcp_connect.rb
|
data/ChangeLog
CHANGED
@@ -1,5 +1,157 @@
|
|
1
1
|
ChangeLog from http://bogomips.org/kgio.git
|
2
2
|
|
3
|
+
commit cbba2690a75830d68c1db779a1c15ecad3725528
|
4
|
+
Author: Eric Wong <e@80x24.org>
|
5
|
+
Date: Tue Feb 4 03:06:42 2014 +0000
|
6
|
+
|
7
|
+
kgio 2.9.0 - cleanups, bug fixes, minor improvements
|
8
|
+
|
9
|
+
This adds a new kgio_syssend method for Ruby 1.9+ which behaves
|
10
|
+
like BasicSocket#send, but will not raise exceptions on EAGAIN.
|
11
|
+
|
12
|
+
Eric Wong (12):
|
13
|
+
test_poll: remove race prone test_poll_EINTR_changed test
|
14
|
+
tryopen: remove RARRAY_PTR usage in init
|
15
|
+
read_write: remove the rest of RARRAY_PTR usage
|
16
|
+
my_writev: stylistic fixes
|
17
|
+
Rakefile: kill raa_update task
|
18
|
+
avoid downsizing casts
|
19
|
+
connect: constify RSTRING-related things
|
20
|
+
set RSTRING_MODIFIED where appropriate for Rubinius
|
21
|
+
split read_write.c into {read,write,writev}.c
|
22
|
+
add kgio_syssend method to wrap send(2)
|
23
|
+
write: correct check for various blocking regions
|
24
|
+
tryopen: additional debug information for bad Errno values
|
25
|
+
|
26
|
+
Hleb Valoshka (1):
|
27
|
+
Don't use deprecated api
|
28
|
+
|
29
|
+
commit f991debdcc3cbba721029285e4a77f32d8222aa1
|
30
|
+
Author: Eric Wong <e@80x24.org>
|
31
|
+
Date: Tue Feb 4 03:01:46 2014 +0000
|
32
|
+
|
33
|
+
tryopen: additional debug information for bad Errno values
|
34
|
+
|
35
|
+
In case users run into the same problem in the future.
|
36
|
+
ref: http://mid.gmane.org/20131227074129.GA6381@dcvr.yhbt.net
|
37
|
+
|
38
|
+
commit cf4c09c3f280850cd5a018d603e9df08ce54ade2
|
39
|
+
Author: Eric Wong <e@80x24.org>
|
40
|
+
Date: Tue Feb 4 02:42:51 2014 +0000
|
41
|
+
|
42
|
+
write: correct check for various blocking regions
|
43
|
+
|
44
|
+
This will allow us to support past/future Rubies without
|
45
|
+
rb_thread_io_blocking_region but still have other ways
|
46
|
+
of releasing GVL.
|
47
|
+
|
48
|
+
commit 070b5aeb9313ef09303dffa7bc72c771f6f86f31
|
49
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
50
|
+
Date: Tue Feb 4 00:51:59 2014 +0000
|
51
|
+
|
52
|
+
add kgio_syssend method to wrap send(2)
|
53
|
+
|
54
|
+
This behaves like kgio_trywrite on GNU/Linux, but allows extra flags
|
55
|
+
to be specified. The main purpose of this is to support use of the
|
56
|
+
MSG_MORE flag on GNU/Linux.
|
57
|
+
|
58
|
+
commit a876a30e4bfae6e3aa4af2e34f68bf66be5715b4
|
59
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
60
|
+
Date: Thu Nov 21 21:18:45 2013 +0000
|
61
|
+
|
62
|
+
split read_write.c into {read,write,writev}.c
|
63
|
+
|
64
|
+
This helps make our code more manageable, as well as isolating
|
65
|
+
RSTRING_MODIFIED usage to files which actually need it.
|
66
|
+
writev.c can eventually be fixed to avoid modifying RSTRING
|
67
|
+
pointers, but write.c can already benefit from const RSTRING_PTR
|
68
|
+
values right away.
|
69
|
+
|
70
|
+
commit 8788e248f9978da6708dd1e85d40531bb30d0bb2
|
71
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
72
|
+
Date: Thu Nov 21 19:05:23 2013 +0000
|
73
|
+
|
74
|
+
set RSTRING_MODIFIED where appropriate for Rubinius
|
75
|
+
|
76
|
+
Not yet tested, but it makes sense to do this.
|
77
|
+
|
78
|
+
commit 7a49e4df0a8f23594a83f21f2fd54955dcb6a0fc
|
79
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
80
|
+
Date: Thu Nov 21 18:57:09 2013 +0000
|
81
|
+
|
82
|
+
connect: constify RSTRING-related things
|
83
|
+
|
84
|
+
This should enforce correctness with our non-use of RSTRING_MODIFIED
|
85
|
+
in this file, hopefully allowing Rubinius to optimize better.
|
86
|
+
|
87
|
+
commit 809b9716a2593c0bfcaa115e7e560615c6357b55
|
88
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
89
|
+
Date: Mon Jan 20 21:16:14 2014 +0000
|
90
|
+
|
91
|
+
avoid downsizing casts
|
92
|
+
|
93
|
+
It's always safe to cast a 32-bit value to a 64-bit value, but
|
94
|
+
compilers can warn going the other way (because VALUE is a pointer).
|
95
|
+
|
96
|
+
Tested with `ruby -v`
|
97
|
+
ruby 2.2.0dev (2014-01-19 trunk 44646) [x86_64-linux]
|
98
|
+
which enables -Wpointer-to-int-cast
|
99
|
+
|
100
|
+
commit 008483785d1a5bb801219af8afbb77be18b9bef1
|
101
|
+
Author: Hleb Valoshka <375gnu@gmail.com>
|
102
|
+
Date: Mon Jan 20 22:36:19 2014 +0300
|
103
|
+
|
104
|
+
Don't use deprecated api
|
105
|
+
|
106
|
+
Signed-off-by: Eric Wong <normalperson@yhbt.net>
|
107
|
+
|
108
|
+
commit a8cb03f58be2c2742f0030a28a9e8454c3d56634
|
109
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
110
|
+
Date: Mon Sep 30 18:22:43 2013 +0000
|
111
|
+
|
112
|
+
Rakefile: kill raa_update task
|
113
|
+
|
114
|
+
RAA is dead
|
115
|
+
|
116
|
+
commit fc91f1d424af2a94d0fbed4b1f4d0171c8add79f
|
117
|
+
Author: Eric Wong <e@yhbt.net>
|
118
|
+
Date: Wed Sep 25 19:37:22 2013 +0000
|
119
|
+
|
120
|
+
my_writev: stylistic fixes
|
121
|
+
|
122
|
+
Rename 'str' to 'ary', as that's the whole point of supporting
|
123
|
+
writev... Also, long lines need to be wrapped at 80 columns
|
124
|
+
|
125
|
+
commit 13725d97e0c493cc38a4c833c1053216fb5c799b
|
126
|
+
Author: Eric Wong <e@yhbt.net>
|
127
|
+
Date: Wed Sep 25 19:26:26 2013 +0000
|
128
|
+
|
129
|
+
read_write: remove the rest of RARRAY_PTR usage
|
130
|
+
|
131
|
+
I have not benchmarked this, but this should not make a difference
|
132
|
+
as far as performance goes. This should also allow better
|
133
|
+
performance of better GCs in Ruby 2.1.0 and Rubinius.
|
134
|
+
|
135
|
+
commit e0d3b3cbe90b47facf0e67036429502ad8f99c49
|
136
|
+
Author: Eric Wong <e@yhbt.net>
|
137
|
+
Date: Wed Sep 25 19:20:11 2013 +0000
|
138
|
+
|
139
|
+
tryopen: remove RARRAY_PTR usage in init
|
140
|
+
|
141
|
+
This is trivially non-performance-critical, and can only
|
142
|
+
help with advanced GCs in Ruby 2.1.0 and Rubinius
|
143
|
+
|
144
|
+
commit 98bbc4bd1fda4aa7fddcb57db659bb3e507238e7
|
145
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
146
|
+
Date: Wed Sep 25 17:42:17 2013 +0000
|
147
|
+
|
148
|
+
test_poll: remove race prone test_poll_EINTR_changed test
|
149
|
+
|
150
|
+
We haven't figured out a way to reliably test this w/o races, so lets
|
151
|
+
just remove it for now and trust it works by reading the C code.
|
152
|
+
|
153
|
+
ref: <CAAB-KcnpvcG6=OZNsBmvv440OHfCWs6-eDD7L6oD=ziCRXPHLA@mail.gmail.com>
|
154
|
+
|
3
155
|
commit 9bde3ab9a7e6e1776ba43bd0e7a3e9202f1026f6
|
4
156
|
Author: Eric Wong <normalperson@yhbt.net>
|
5
157
|
Date: Wed Sep 11 00:01:21 2013 +0000
|
data/GIT-VERSION-FILE
CHANGED
@@ -1 +1 @@
|
|
1
|
-
GIT_VERSION = 2.
|
1
|
+
GIT_VERSION = 2.9.0
|
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
data/LATEST
CHANGED
@@ -1,24 +1,22 @@
|
|
1
|
-
=== kgio 2.
|
1
|
+
=== kgio 2.9.0 - cleanups, bug fixes, minor improvements / 2014-02-04 03:09 UTC
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
test case fixes for race conditions.
|
3
|
+
This adds a new kgio_syssend method for Ruby 1.9+ which behaves
|
4
|
+
like BasicSocket#send, but will not raise exceptions on EAGAIN.
|
6
5
|
|
7
|
-
|
8
|
-
|
6
|
+
Eric Wong (12):
|
7
|
+
test_poll: remove race prone test_poll_EINTR_changed test
|
8
|
+
tryopen: remove RARRAY_PTR usage in init
|
9
|
+
read_write: remove the rest of RARRAY_PTR usage
|
10
|
+
my_writev: stylistic fixes
|
11
|
+
Rakefile: kill raa_update task
|
12
|
+
avoid downsizing casts
|
13
|
+
connect: constify RSTRING-related things
|
14
|
+
set RSTRING_MODIFIED where appropriate for Rubinius
|
15
|
+
split read_write.c into {read,write,writev}.c
|
16
|
+
add kgio_syssend method to wrap send(2)
|
17
|
+
write: correct check for various blocking regions
|
18
|
+
tryopen: additional debug information for bad Errno values
|
9
19
|
|
10
|
-
|
11
|
-
|
12
|
-
accept: more informative exception on unknown family
|
13
|
-
test_tryopen: skip EACCES test when euid == 0
|
14
|
-
test/lib_read_write: account for larger-than-normal pipes
|
15
|
-
test_poll: avoid potentially thread-unsafe test
|
16
|
-
test_poll: preserve original trap(:USR1) handler
|
17
|
-
test_poll: be less dependent on signal handler ordering
|
18
|
-
|
19
|
-
Hleb Valoshka (4):
|
20
|
-
Change prefix of temporary sockets to prevent races
|
21
|
-
Don't dump 20M in case of failure
|
22
|
-
Create own directory for every unix socket in unit tests
|
23
|
-
Close tempfile and unlink it immediately.
|
20
|
+
Hleb Valoshka (1):
|
21
|
+
Don't use deprecated api
|
24
22
|
|
data/NEWS
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
=== kgio 2.9.0 - cleanups, bug fixes, minor improvements / 2014-02-04 03:09 UTC
|
2
|
+
|
3
|
+
This adds a new kgio_syssend method for Ruby 1.9+ which behaves
|
4
|
+
like BasicSocket#send, but will not raise exceptions on EAGAIN.
|
5
|
+
|
6
|
+
Eric Wong (12):
|
7
|
+
test_poll: remove race prone test_poll_EINTR_changed test
|
8
|
+
tryopen: remove RARRAY_PTR usage in init
|
9
|
+
read_write: remove the rest of RARRAY_PTR usage
|
10
|
+
my_writev: stylistic fixes
|
11
|
+
Rakefile: kill raa_update task
|
12
|
+
avoid downsizing casts
|
13
|
+
connect: constify RSTRING-related things
|
14
|
+
set RSTRING_MODIFIED where appropriate for Rubinius
|
15
|
+
split read_write.c into {read,write,writev}.c
|
16
|
+
add kgio_syssend method to wrap send(2)
|
17
|
+
write: correct check for various blocking regions
|
18
|
+
tryopen: additional debug information for bad Errno values
|
19
|
+
|
20
|
+
Hleb Valoshka (1):
|
21
|
+
Don't use deprecated api
|
22
|
+
|
1
23
|
=== kgio 2.8.1 - minor improvements and test fixes / 2013-09-11 00:22 UTC
|
2
24
|
|
3
25
|
Improved error reporting for kgio_accept/kgio_tryaccept.
|
data/Rakefile
CHANGED
@@ -30,40 +30,3 @@ task :publish_news do
|
|
30
30
|
rf.login
|
31
31
|
rf.post_news('rainbows', subject, body)
|
32
32
|
end
|
33
|
-
|
34
|
-
desc "post to RAA"
|
35
|
-
task :raa_update do
|
36
|
-
require 'net/http'
|
37
|
-
require 'net/netrc'
|
38
|
-
rc = Net::Netrc.locate('kgio-raa') or abort "~/.netrc not found"
|
39
|
-
password = rc.password
|
40
|
-
|
41
|
-
s = Gem::Specification.load('kgio.gemspec')
|
42
|
-
desc = [ s.description.strip ]
|
43
|
-
desc << ""
|
44
|
-
desc << "* #{s.email}"
|
45
|
-
desc << "* #{git_url}"
|
46
|
-
desc << "* #{cgit_url}"
|
47
|
-
desc = desc.join("\n")
|
48
|
-
uri = URI.parse('http://raa.ruby-lang.org/regist.rhtml')
|
49
|
-
form = {
|
50
|
-
:name => s.name,
|
51
|
-
:short_description => s.summary,
|
52
|
-
:version => s.version.to_s,
|
53
|
-
:status => 'experimental',
|
54
|
-
:owner => s.authors.first,
|
55
|
-
:email => s.email,
|
56
|
-
:category_major => 'Library',
|
57
|
-
:category_minor => 'System',
|
58
|
-
:url => s.homepage,
|
59
|
-
:download => 'http://rubyforge.org/frs/?group_id=8977',
|
60
|
-
:license => "LGPL",
|
61
|
-
:description_style => 'Plain',
|
62
|
-
:description => desc,
|
63
|
-
:pass => password,
|
64
|
-
:submit => 'Update',
|
65
|
-
}
|
66
|
-
res = Net::HTTP.post_form(uri, form)
|
67
|
-
p res
|
68
|
-
puts res.body
|
69
|
-
end
|
data/ext/kgio/accept.c
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
/* ref: rubinius b2811f260de16d1e972462e27852470364608de5 */
|
2
|
+
#define RSTRING_MODIFIED 1
|
3
|
+
|
1
4
|
#include "kgio.h"
|
2
5
|
#include "missing_accept4.h"
|
3
6
|
#include "sock_for_fd.h"
|
@@ -10,7 +13,7 @@ static VALUE cKgio_Socket;
|
|
10
13
|
static VALUE mSocketMethods;
|
11
14
|
static VALUE iv_kgio_addr;
|
12
15
|
|
13
|
-
#if defined(__linux__) && defined(
|
16
|
+
#if defined(__linux__) && defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL)
|
14
17
|
static int accept4_flags = SOCK_CLOEXEC;
|
15
18
|
#else /* ! linux */
|
16
19
|
static int accept4_flags = SOCK_CLOEXEC | SOCK_NONBLOCK;
|
@@ -76,7 +79,7 @@ static VALUE xaccept(void *ptr)
|
|
76
79
|
return (VALUE)rv;
|
77
80
|
}
|
78
81
|
|
79
|
-
#ifdef
|
82
|
+
#ifdef KGIO_HAVE_THREAD_CALL_WITHOUT_GVL
|
80
83
|
# include <time.h>
|
81
84
|
# include "blocking_io_region.h"
|
82
85
|
static int thread_accept(struct accept_args *a, int force_nonblock)
|
@@ -86,7 +89,7 @@ static int thread_accept(struct accept_args *a, int force_nonblock)
|
|
86
89
|
return (int)rb_thread_io_blocking_region(xaccept, a, a->fd);
|
87
90
|
}
|
88
91
|
|
89
|
-
#else /* !
|
92
|
+
#else /* ! KGIO_HAVE_THREAD_CALL_WITHOUT_GVL */
|
90
93
|
# include <rubysig.h>
|
91
94
|
static int thread_accept(struct accept_args *a, int force_nonblock)
|
92
95
|
{
|
@@ -103,7 +106,7 @@ static int thread_accept(struct accept_args *a, int force_nonblock)
|
|
103
106
|
TRAP_END;
|
104
107
|
return rv;
|
105
108
|
}
|
106
|
-
#endif /* !
|
109
|
+
#endif /* ! KGIO_HAVE_THREAD_CALL_WITHOUT_GVL */
|
107
110
|
|
108
111
|
static void
|
109
112
|
prepare_accept(struct accept_args *a, VALUE self, int argc, const VALUE *argv)
|
data/ext/kgio/ancient_ruby.h
CHANGED
@@ -17,9 +17,6 @@ static void my_str_set_len(VALUE str, long len)
|
|
17
17
|
# define RSTRING_LEN(s) (RSTRING(s)->len)
|
18
18
|
#endif /* !defined(RSTRING_LEN) */
|
19
19
|
|
20
|
-
#ifndef RARRAY_PTR
|
21
|
-
# define RARRAY_PTR(s) (RARRAY(s)->ptr)
|
22
|
-
#endif /* !defined(RARRAY_PTR) */
|
23
20
|
#ifndef RARRAY_LEN
|
24
21
|
# define RARRAY_LEN(s) (RARRAY(s)->len)
|
25
22
|
#endif /* !defined(RARRAY_LEN) */
|
@@ -1,8 +1,11 @@
|
|
1
|
-
#ifdef
|
2
|
-
#
|
1
|
+
#ifdef KGIO_HAVE_THREAD_CALL_WITHOUT_GVL
|
2
|
+
# if defined(HAVE_RB_THREAD_IO_BLOCKING_REGION)
|
3
3
|
/* temporary API for Ruby 1.9.3 */
|
4
4
|
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *, void *, int);
|
5
|
-
#
|
5
|
+
# elif defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
6
|
+
# define rb_thread_io_blocking_region(fn,data,fd) \
|
7
|
+
rb_thread_call_without_gvl((fn),(data),RUBY_UBF_IO,0)
|
8
|
+
# elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
6
9
|
# define rb_thread_io_blocking_region(fn,data,fd) \
|
7
10
|
rb_thread_blocking_region((fn),(data),RUBY_UBF_IO,0)
|
8
11
|
# endif
|
data/ext/kgio/connect.c
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
/* We do not modify RSTRING in this file, so RSTRING_MODIFIED is not needed */
|
1
2
|
#include "kgio.h"
|
2
3
|
#include "my_fileno.h"
|
3
4
|
#include "sock_for_fd.h"
|
@@ -67,7 +68,8 @@ retry:
|
|
67
68
|
}
|
68
69
|
|
69
70
|
static VALUE
|
70
|
-
my_connect(VALUE klass, int io_wait, int domain,
|
71
|
+
my_connect(VALUE klass, int io_wait, int domain,
|
72
|
+
const void *addr, socklen_t addrlen)
|
71
73
|
{
|
72
74
|
int fd = my_socket(domain);
|
73
75
|
|
@@ -133,25 +135,25 @@ static VALUE tcp_connect(VALUE klass, VALUE ip, VALUE port, int io_wait)
|
|
133
135
|
&addr, hints.ai_addrlen);
|
134
136
|
}
|
135
137
|
|
136
|
-
static struct sockaddr *sockaddr_from(socklen_t *addrlen, VALUE addr)
|
138
|
+
static const struct sockaddr *sockaddr_from(socklen_t *addrlen, VALUE addr)
|
137
139
|
{
|
138
140
|
if (TYPE(addr) == T_STRING) {
|
139
141
|
*addrlen = (socklen_t)RSTRING_LEN(addr);
|
140
|
-
return (struct sockaddr *)(RSTRING_PTR(addr));
|
142
|
+
return (const struct sockaddr *)(RSTRING_PTR(addr));
|
141
143
|
}
|
142
144
|
rb_raise(rb_eTypeError, "invalid address");
|
143
145
|
return NULL;
|
144
146
|
}
|
145
147
|
|
146
|
-
#if defined(MSG_FASTOPEN) && defined(
|
148
|
+
#if defined(MSG_FASTOPEN) && defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL)
|
147
149
|
#ifndef HAVE_RB_STR_SUBSEQ
|
148
150
|
#define rb_str_subseq rb_str_substr
|
149
151
|
#endif
|
150
152
|
struct tfo_args {
|
151
153
|
int fd;
|
152
|
-
void *buf;
|
154
|
+
const void *buf;
|
153
155
|
size_t buflen;
|
154
|
-
struct sockaddr *addr;
|
156
|
+
const struct sockaddr *addr;
|
155
157
|
socklen_t addrlen;
|
156
158
|
};
|
157
159
|
|
@@ -296,9 +298,9 @@ static VALUE stream_connect(VALUE klass, VALUE addr, int io_wait)
|
|
296
298
|
{
|
297
299
|
int domain;
|
298
300
|
socklen_t addrlen;
|
299
|
-
struct sockaddr *sockaddr = sockaddr_from(&addrlen, addr);
|
301
|
+
const struct sockaddr *sockaddr = sockaddr_from(&addrlen, addr);
|
300
302
|
|
301
|
-
switch (((struct sockaddr_storage *)(sockaddr))->ss_family) {
|
303
|
+
switch (((const struct sockaddr_storage *)(sockaddr))->ss_family) {
|
302
304
|
case AF_UNIX: domain = PF_UNIX; break;
|
303
305
|
case AF_INET: domain = PF_INET; break;
|
304
306
|
case AF_INET6: domain = PF_INET6; break;
|
@@ -381,7 +383,7 @@ void init_kgio_connect(void)
|
|
381
383
|
rb_define_singleton_method(cKgio_Socket, "new", kgio_new, -1);
|
382
384
|
rb_define_singleton_method(cKgio_Socket, "connect", kgio_connect, 1);
|
383
385
|
rb_define_singleton_method(cKgio_Socket, "start", kgio_start, 1);
|
384
|
-
#if defined(MSG_FASTOPEN) && defined(
|
386
|
+
#if defined(MSG_FASTOPEN) && defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL)
|
385
387
|
rb_define_method(cKgio_Socket, "kgio_fastopen", fastopen, 2);
|
386
388
|
#endif
|
387
389
|
/*
|
data/ext/kgio/extconf.rb
CHANGED
@@ -46,6 +46,8 @@ have_func('rb_io_ascii8bit_binmode')
|
|
46
46
|
have_func('rb_update_max_fd')
|
47
47
|
have_func('rb_fd_fix_cloexec')
|
48
48
|
have_func('rb_cloexec_open')
|
49
|
+
have_header('ruby/thread.h')
|
50
|
+
have_func('rb_thread_call_without_gvl', %w{ruby/thread.h})
|
49
51
|
have_func('rb_thread_blocking_region')
|
50
52
|
have_func('rb_thread_io_blocking_region')
|
51
53
|
have_func('rb_str_set_len')
|
data/ext/kgio/kgio.h
CHANGED
@@ -7,6 +7,9 @@
|
|
7
7
|
#else
|
8
8
|
# include <rubyio.h>
|
9
9
|
#endif
|
10
|
+
#ifdef HAVE_RUBY_THREAD_H
|
11
|
+
# include <ruby/thread.h>
|
12
|
+
#endif
|
10
13
|
#include <errno.h>
|
11
14
|
#include <sys/types.h>
|
12
15
|
#include <sys/socket.h>
|
@@ -20,16 +23,10 @@
|
|
20
23
|
|
21
24
|
#include "ancient_ruby.h"
|
22
25
|
|
23
|
-
struct io_args {
|
24
|
-
VALUE io;
|
25
|
-
VALUE buf;
|
26
|
-
char *ptr;
|
27
|
-
long len;
|
28
|
-
int fd;
|
29
|
-
};
|
30
|
-
|
31
26
|
void init_kgio_wait(void);
|
32
|
-
void
|
27
|
+
void init_kgio_read(void);
|
28
|
+
void init_kgio_write(void);
|
29
|
+
void init_kgio_writev(void);
|
33
30
|
void init_kgio_accept(void);
|
34
31
|
void init_kgio_connect(void);
|
35
32
|
void init_kgio_autopush(void);
|
@@ -42,7 +39,16 @@ void kgio_autopush_send(VALUE);
|
|
42
39
|
|
43
40
|
VALUE kgio_call_wait_writable(VALUE io);
|
44
41
|
VALUE kgio_call_wait_readable(VALUE io);
|
45
|
-
#if defined(
|
42
|
+
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
43
|
+
# define KGIO_HAVE_THREAD_CALL_WITHOUT_GVL 1
|
44
|
+
typedef void *(*kgio_blocking_fn_t)(void*);
|
45
|
+
# define rb_thread_blocking_region(fn,data1,ubf,data2) \
|
46
|
+
rb_thread_call_without_gvl((kgio_blocking_fn_t)(fn),(data1),(ubf),(data2))
|
47
|
+
#elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
48
|
+
# define KGIO_HAVE_THREAD_CALL_WITHOUT_GVL 1
|
49
|
+
#endif /* HAVE_RB_THREAD_CALL_WITHOUT_GVL || HAVE_RB_THREAD_BLOCKING_REGION */
|
50
|
+
|
51
|
+
#if defined(KGIO_HAVE_THREAD_CALL_WITHOUT_GVL) && defined(HAVE_POLL)
|
46
52
|
# define USE_KGIO_POLL
|
47
53
|
#endif /* USE_KGIO_POLL */
|
48
54
|
|
@@ -71,5 +77,23 @@ VALUE kgio_call_wait_readable(VALUE io);
|
|
71
77
|
#endif
|
72
78
|
|
73
79
|
extern unsigned kgio_tfo;
|
80
|
+
NORETURN(void kgio_raise_empty_bt(VALUE, const char *));
|
81
|
+
NORETURN(void kgio_wr_sys_fail(const char *));
|
82
|
+
NORETURN(void kgio_rd_sys_fail(const char *));
|
74
83
|
|
84
|
+
/*
|
85
|
+
* we know MSG_DONTWAIT works properly on all stream sockets under Linux
|
86
|
+
* we can define this macro for other platforms as people care and
|
87
|
+
* notice.
|
88
|
+
*/
|
89
|
+
# if defined(__linux__)
|
90
|
+
# define USE_MSG_DONTWAIT
|
91
|
+
# endif
|
92
|
+
|
93
|
+
#ifdef USE_MSG_DONTWAIT
|
94
|
+
/* we don't need these variants, we call kgio_autopush_send/recv directly */
|
95
|
+
static inline void kgio_autopush_write(VALUE io) { }
|
96
|
+
#else
|
97
|
+
static inline void kgio_autopush_write(VALUE io) { kgio_autopush_send(io); }
|
98
|
+
#endif
|
75
99
|
#endif /* KGIO_H */
|
data/ext/kgio/kgio_ext.c
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
#include <stdio.h>
|
4
4
|
/* true if TCP Fast Open is usable */
|
5
5
|
unsigned kgio_tfo;
|
6
|
+
static VALUE eErrno_EPIPE, eErrno_ECONNRESET;
|
7
|
+
static ID id_set_backtrace;
|
6
8
|
|
7
9
|
static void tfo_maybe(void)
|
8
10
|
{
|
@@ -34,11 +36,63 @@ static void tfo_maybe(void)
|
|
34
36
|
#endif
|
35
37
|
}
|
36
38
|
|
39
|
+
void kgio_raise_empty_bt(VALUE err, const char *msg)
|
40
|
+
{
|
41
|
+
VALUE exc = rb_exc_new2(err, msg);
|
42
|
+
VALUE bt = rb_ary_new();
|
43
|
+
|
44
|
+
rb_funcall(exc, id_set_backtrace, 1, bt);
|
45
|
+
rb_exc_raise(exc);
|
46
|
+
}
|
47
|
+
|
48
|
+
void kgio_wr_sys_fail(const char *msg)
|
49
|
+
{
|
50
|
+
switch (errno) {
|
51
|
+
case EPIPE:
|
52
|
+
errno = 0;
|
53
|
+
kgio_raise_empty_bt(eErrno_EPIPE, msg);
|
54
|
+
case ECONNRESET:
|
55
|
+
errno = 0;
|
56
|
+
kgio_raise_empty_bt(eErrno_ECONNRESET, msg);
|
57
|
+
}
|
58
|
+
rb_sys_fail(msg);
|
59
|
+
}
|
60
|
+
|
61
|
+
void kgio_rd_sys_fail(const char *msg)
|
62
|
+
{
|
63
|
+
if (errno == ECONNRESET) {
|
64
|
+
errno = 0;
|
65
|
+
kgio_raise_empty_bt(eErrno_ECONNRESET, msg);
|
66
|
+
}
|
67
|
+
rb_sys_fail(msg);
|
68
|
+
}
|
69
|
+
|
37
70
|
void Init_kgio_ext(void)
|
38
71
|
{
|
72
|
+
VALUE mKgio = rb_define_module("Kgio");
|
73
|
+
VALUE mPipeMethods = rb_define_module_under(mKgio, "PipeMethods");
|
74
|
+
VALUE mSocketMethods = rb_define_module_under(mKgio, "SocketMethods");
|
75
|
+
VALUE mWaiters = rb_define_module_under(mKgio, "DefaultWaiters");
|
76
|
+
|
77
|
+
id_set_backtrace = rb_intern("set_backtrace");
|
78
|
+
eErrno_EPIPE = rb_const_get(rb_mErrno, rb_intern("EPIPE"));
|
79
|
+
eErrno_ECONNRESET = rb_const_get(rb_mErrno, rb_intern("ECONNRESET"));
|
80
|
+
|
81
|
+
/*
|
82
|
+
* Returns the client IP address of the socket as a string
|
83
|
+
* (e.g. "127.0.0.1" or "::1").
|
84
|
+
* This is always the value of the Kgio::LOCALHOST constant
|
85
|
+
* for UNIX domain sockets.
|
86
|
+
*/
|
87
|
+
rb_define_attr(mSocketMethods, "kgio_addr", 1, 1);
|
88
|
+
rb_include_module(mPipeMethods, mWaiters);
|
89
|
+
rb_include_module(mSocketMethods, mWaiters);
|
90
|
+
|
39
91
|
tfo_maybe();
|
40
92
|
init_kgio_wait();
|
41
|
-
|
93
|
+
init_kgio_read();
|
94
|
+
init_kgio_write();
|
95
|
+
init_kgio_writev();
|
42
96
|
init_kgio_connect();
|
43
97
|
init_kgio_accept();
|
44
98
|
init_kgio_autopush();
|
data/ext/kgio/poll.c
CHANGED
@@ -139,13 +139,13 @@ static VALUE poll_result(int nr, struct poll_args *a)
|
|
139
139
|
static VALUE do_poll(VALUE args)
|
140
140
|
{
|
141
141
|
struct poll_args *a = (struct poll_args *)args;
|
142
|
-
|
142
|
+
long nr;
|
143
143
|
|
144
144
|
Check_Type(a->ios, T_HASH);
|
145
145
|
|
146
146
|
retry:
|
147
147
|
hash2pollfds(a);
|
148
|
-
nr = (
|
148
|
+
nr = (long)rb_thread_blocking_region(nogvl_poll, a, RUBY_UBF_IO, NULL);
|
149
149
|
if (nr < 0) {
|
150
150
|
if (interrupted()) {
|
151
151
|
if (retryable(a)) {
|