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 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/read_write.c
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.8.1
1
+ GIT_VERSION = 2.9.0
data/GIT-VERSION-GEN CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v2.8.1
4
+ DEF_VER=v2.9.0
5
5
 
6
6
  LF='
7
7
  '
data/GNUmakefile CHANGED
@@ -5,6 +5,5 @@ rfpackage := kgio
5
5
  include pkg.mk
6
6
  ifneq ($(VERSION),)
7
7
  release::
8
- $(RAKE) raa_update VERSION=$(VERSION)
9
8
  $(RAKE) publish_news VERSION=$(VERSION)
10
9
  endif
data/LATEST CHANGED
@@ -1,24 +1,22 @@
1
- === kgio 2.8.1 - minor improvements and test fixes / 2013-09-11 00:22 UTC
1
+ === kgio 2.9.0 - cleanups, bug fixes, minor improvements / 2014-02-04 03:09 UTC
2
2
 
3
- Improved error reporting for kgio_accept/kgio_tryaccept.
4
- Minor size reduction throughout. There are also several
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
- Thanks to Hleb Valoshka and the Debian project for all the
8
- help with this release!
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
- Eric Wong (7):
11
- check syscall returns against < 0 instead of == -1
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(HAVE_RB_THREAD_BLOCKING_REGION)
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 HAVE_RB_THREAD_BLOCKING_REGION
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 /* ! HAVE_RB_THREAD_BLOCKING_REGION */
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 /* ! HAVE_RB_THREAD_BLOCKING_REGION */
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)
@@ -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 HAVE_RB_THREAD_BLOCKING_REGION
2
- # ifdef HAVE_RB_THREAD_IO_BLOCKING_REGION
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
- # else
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, void *addr, socklen_t addrlen)
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(HAVE_RB_THREAD_BLOCKING_REGION)
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(HAVE_RB_THREAD_BLOCKING_REGION)
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 init_kgio_read_write(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(HAVE_RB_THREAD_BLOCKING_REGION) && defined(HAVE_POLL)
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
- init_kgio_read_write();
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
- int nr;
142
+ long nr;
143
143
 
144
144
  Check_Type(a->ios, T_HASH);
145
145
 
146
146
  retry:
147
147
  hash2pollfds(a);
148
- nr = (int)rb_thread_blocking_region(nogvl_poll, a, RUBY_UBF_IO, NULL);
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)) {