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 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)) {