kgio 2.8.1 → 2.9.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.
- 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)) {
|