kgio 1.3.1 → 2.0.0pre1
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/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +1 -1
- data/HACKING +1 -1
- data/ISSUES +9 -11
- data/README +6 -7
- data/ext/kgio/connect.c +7 -7
- data/ext/kgio/kgio.h +2 -2
- data/ext/kgio/read_write.c +21 -17
- data/ext/kgio/wait.c +54 -90
- data/kgio.gemspec +1 -1
- data/lib/kgio.rb +3 -3
- data/test/lib_read_write.rb +15 -25
- data/test/test_connect_fd_leak.rb +0 -4
- data/test/test_default_wait.rb +21 -0
- data/test/test_pipe_popen.rb +1 -1
- data/test/test_tcp_connect.rb +1 -4
- data/test/test_unix_connect.rb +1 -3
- metadata +16 -12
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
@@ -139,7 +139,7 @@ release: verify package $(release_notes) $(release_changes)
|
|
139
139
|
# make tgz release on RubyForge
|
140
140
|
rubyforge add_release -f -n $(release_notes) -a $(release_changes) \
|
141
141
|
$(rfproject) $(rfpackage) $(VERSION) $(pkgtgz)
|
142
|
-
# push gem to
|
142
|
+
# push gem to RubyGems.org
|
143
143
|
gem push $(pkggem)
|
144
144
|
# in case of gem downloads from RubyForge releases page
|
145
145
|
-rubyforge add_file \
|
data/HACKING
CHANGED
@@ -31,7 +31,7 @@ characters wide) and NOT the indentation style of Matz Ruby.
|
|
31
31
|
|
32
32
|
Contributions are welcome in the form of patches, pull requests, code
|
33
33
|
review, testing, documentation, user support or any other feedback. The
|
34
|
-
{
|
34
|
+
{kgio mailing list}[mailto:kgio@librelist.com] is the
|
35
35
|
central coordination point for all user and developer feedback and bug
|
36
36
|
reports.
|
37
37
|
|
data/ISSUES
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
= Issues
|
2
2
|
|
3
|
-
The
|
3
|
+
The kgio {mailing list}[mailto:kgio@librelist.com] is the best
|
4
4
|
place to report bugs, submit patches and/or obtain support after you
|
5
5
|
have searched the mailing list archives and
|
6
6
|
{documentation}[http://unicorn.bogomips.org/kgio].
|
7
7
|
|
8
|
-
* No subscription is needed to post to the mailing list,
|
9
|
-
let us know that we need to Cc: replies to you if you're unsubscribed.
|
10
8
|
* Do not {top post}[http://catb.org/jargon/html/T/top-post.html] in replies
|
11
9
|
* Quote only the relevant portions of the message you're replying to
|
12
|
-
* Do not send HTML mail
|
10
|
+
* Do not send any HTML mail at all
|
13
11
|
|
14
12
|
If your issue is of a sensitive nature or you're just shy in public,
|
15
|
-
then feel free to email us privately at mailto:
|
13
|
+
then feel free to email us privately at mailto:kgio@bogomips.org
|
16
14
|
instead and your issue will be handled discreetly.
|
17
15
|
|
18
16
|
If you don't get a response within a few days, we may have forgotten
|
@@ -26,11 +24,11 @@ guidelines for patch submission.
|
|
26
24
|
|
27
25
|
== Mailing List Info
|
28
26
|
|
29
|
-
* subscribe:
|
30
|
-
* post: mailto:
|
31
|
-
* private: mailto:
|
27
|
+
* subscribe: send a message to the mailing list
|
28
|
+
* post: mailto:kgio@librelist.com
|
29
|
+
* private: mailto:kgio@bogomips.org
|
32
30
|
|
33
|
-
== Mailing List Archives
|
31
|
+
== Mailing List Archives (coming soon)
|
34
32
|
|
35
|
-
*
|
36
|
-
*
|
33
|
+
* http://unicorn.bogomips.org/kgio/archives/
|
34
|
+
* nntp://news.gmane.org/gmane.comp.lang.ruby.kgio.general
|
data/README
CHANGED
@@ -8,16 +8,16 @@ applications.
|
|
8
8
|
== Features
|
9
9
|
|
10
10
|
* Can avoid expensive exceptions on common EAGAIN/EINPROGRESS errors,
|
11
|
-
returning
|
11
|
+
returning :wait_readable or :wait_writable instead.
|
12
12
|
These exceptions got more expensive to hit under Ruby 1.9.2
|
13
13
|
(but should be fixed in Ruby 1.9.3 to 1.9.1 performance levels)
|
14
14
|
|
15
15
|
* Returns the unwritten portion of the string on partial writes,
|
16
16
|
making it ideal for buffering unwritten data.
|
17
17
|
|
18
|
-
* May
|
19
|
-
methods to allow socket/pipe objects to make custom
|
20
|
-
(such as adding the file descriptor to a poll set and yielding
|
18
|
+
* May call any method defined to be "kgio_wait_writable" or
|
19
|
+
"kgio_wait_readable" methods to allow socket/pipe objects to make custom
|
20
|
+
callbacks (such as adding the file descriptor to a poll set and yielding
|
21
21
|
the current Fiber).
|
22
22
|
|
23
23
|
* Uses
|
@@ -38,7 +38,7 @@ and run setup.rb after unpacking it:
|
|
38
38
|
|
39
39
|
http://rubyforge.org/frs/?group_id=8977
|
40
40
|
|
41
|
-
You may also install it via RubyGems
|
41
|
+
You may also install it via RubyGems.org:
|
42
42
|
|
43
43
|
gem install kgio
|
44
44
|
|
@@ -61,8 +61,7 @@ from git.
|
|
61
61
|
|
62
62
|
All feedback (bug reports, user/development dicussion, patches, pull
|
63
63
|
requests) go to the mailing list/newsgroup. See the ISSUES document for
|
64
|
-
information on the
|
65
|
-
{Unicorn mailing list}[mailto:mongrel-unicorn@rubyforge.org].
|
64
|
+
information on the {kgio mailing list}[mailto:kgio@librelist.com]
|
66
65
|
|
67
66
|
For the latest on kgio releases, you may check our NEWS page (and
|
68
67
|
subscribe to our Atom feed).
|
data/ext/kgio/connect.c
CHANGED
@@ -46,7 +46,7 @@ my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
|
|
46
46
|
|
47
47
|
if (io_wait) {
|
48
48
|
errno = EAGAIN;
|
49
|
-
|
49
|
+
(void)kgio_call_wait_writable(io);
|
50
50
|
}
|
51
51
|
return io;
|
52
52
|
}
|
@@ -81,7 +81,7 @@ static VALUE tcp_connect(VALUE klass, VALUE ip, VALUE port, int io_wait)
|
|
81
81
|
* Creates a new Kgio::TCPSocket object and initiates a
|
82
82
|
* non-blocking connection.
|
83
83
|
*
|
84
|
-
* This may block and call any method
|
84
|
+
* This may block and call any method defined to kgio_wait_writable.
|
85
85
|
*
|
86
86
|
* Unlike the TCPSocket.new in Ruby, this does NOT perform DNS
|
87
87
|
* lookups (which is subject to a different set of timeouts and
|
@@ -100,7 +100,7 @@ static VALUE kgio_tcp_connect(VALUE klass, VALUE ip, VALUE port)
|
|
100
100
|
* Creates a new Kgio::TCPSocket object and initiates a
|
101
101
|
* non-blocking connection. The caller should select/poll
|
102
102
|
* on the socket for writability before attempting to write
|
103
|
-
* or optimistically attempt a write and handle
|
103
|
+
* or optimistically attempt a write and handle :wait_writable
|
104
104
|
* or Errno::EAGAIN.
|
105
105
|
*
|
106
106
|
* Unlike the TCPSocket.new in Ruby, this does NOT perform DNS
|
@@ -138,7 +138,7 @@ static VALUE unix_connect(VALUE klass, VALUE path, int io_wait)
|
|
138
138
|
* Creates a new Kgio::UNIXSocket object and initiates a
|
139
139
|
* non-blocking connection.
|
140
140
|
*
|
141
|
-
* This may block and call any method
|
141
|
+
* This may block and call any method defined to kgio_wait_writable.
|
142
142
|
*/
|
143
143
|
static VALUE kgio_unix_connect(VALUE klass, VALUE path)
|
144
144
|
{
|
@@ -153,7 +153,7 @@ static VALUE kgio_unix_connect(VALUE klass, VALUE path)
|
|
153
153
|
* Creates a new Kgio::UNIXSocket object and initiates a
|
154
154
|
* non-blocking connection. The caller should select/poll
|
155
155
|
* on the socket for writability before attempting to write
|
156
|
-
* or optimistically attempt a write and handle
|
156
|
+
* or optimistically attempt a write and handle :wait_writable
|
157
157
|
* or Errno::EAGAIN.
|
158
158
|
*/
|
159
159
|
static VALUE kgio_unix_start(VALUE klass, VALUE path)
|
@@ -197,7 +197,7 @@ static VALUE stream_connect(VALUE klass, VALUE addr, int io_wait)
|
|
197
197
|
* Creates a generic Kgio::Socket object and initiates a
|
198
198
|
* non-blocking connection.
|
199
199
|
*
|
200
|
-
* This may block and call any method assigned to
|
200
|
+
* This may block and call any method assigned to kgio_wait_writable.
|
201
201
|
*/
|
202
202
|
static VALUE kgio_connect(VALUE klass, VALUE addr)
|
203
203
|
{
|
@@ -215,7 +215,7 @@ static VALUE kgio_connect(VALUE klass, VALUE addr)
|
|
215
215
|
* Creates a generic Kgio::Socket object and initiates a
|
216
216
|
* non-blocking connection. The caller should select/poll
|
217
217
|
* on the socket for writability before attempting to write
|
218
|
-
* or optimistically attempt a write and handle
|
218
|
+
* or optimistically attempt a write and handle :wait_writable
|
219
219
|
* or Errno::EAGAIN.
|
220
220
|
*/
|
221
221
|
static VALUE kgio_start(VALUE klass, VALUE addr)
|
data/ext/kgio/kgio.h
CHANGED
@@ -34,7 +34,7 @@ void init_kgio_read_write(void);
|
|
34
34
|
void init_kgio_accept(void);
|
35
35
|
void init_kgio_connect(void);
|
36
36
|
|
37
|
-
|
38
|
-
|
37
|
+
VALUE kgio_call_wait_writable(VALUE io);
|
38
|
+
VALUE kgio_call_wait_readable(VALUE io);
|
39
39
|
|
40
40
|
#endif /* KGIO_H */
|
data/ext/kgio/read_write.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#include "kgio.h"
|
2
|
-
static VALUE
|
2
|
+
static VALUE sym_wait_readable, sym_wait_writable;
|
3
3
|
static VALUE eErrno_EPIPE, eErrno_ECONNRESET;
|
4
4
|
|
5
5
|
/*
|
@@ -26,7 +26,7 @@ static void raise_empty_bt(VALUE err, const char *msg)
|
|
26
26
|
|
27
27
|
static void my_eof_error(void)
|
28
28
|
{
|
29
|
-
raise_empty_bt(rb_eEOFError, "");
|
29
|
+
raise_empty_bt(rb_eEOFError, "end of file reached");
|
30
30
|
}
|
31
31
|
|
32
32
|
static void wr_sys_fail(const char *msg)
|
@@ -67,14 +67,14 @@ static int read_check(struct io_args *a, long n, const char *msg, int io_wait)
|
|
67
67
|
rb_str_set_len(a->buf, 0);
|
68
68
|
if (errno == EAGAIN) {
|
69
69
|
if (io_wait) {
|
70
|
-
|
70
|
+
(void)kgio_call_wait_readable(a->io);
|
71
71
|
|
72
72
|
/* buf may be modified in other thread/fiber */
|
73
73
|
rb_str_resize(a->buf, a->len);
|
74
74
|
a->ptr = RSTRING_PTR(a->buf);
|
75
75
|
return -1;
|
76
76
|
} else {
|
77
|
-
a->buf =
|
77
|
+
a->buf = sym_wait_readable;
|
78
78
|
return 0;
|
79
79
|
}
|
80
80
|
}
|
@@ -112,8 +112,8 @@ retry:
|
|
112
112
|
* Reads at most maxlen bytes from the stream socket. Returns with a
|
113
113
|
* newly allocated buffer, or may reuse an existing buffer if supplied.
|
114
114
|
*
|
115
|
-
* Calls
|
116
|
-
*
|
115
|
+
* Calls whatever is is defined to be the kgio_wait_readable method
|
116
|
+
* for the class.
|
117
117
|
*
|
118
118
|
* Returns nil on EOF.
|
119
119
|
*
|
@@ -127,7 +127,9 @@ static VALUE kgio_read(int argc, VALUE *argv, VALUE io)
|
|
127
127
|
|
128
128
|
/*
|
129
129
|
* Same as Kgio::PipeMethods#kgio_read, except EOFError is raised
|
130
|
-
* on EOF without a backtrace
|
130
|
+
* on EOF without a backtrace. This method is intended as a
|
131
|
+
* drop-in replacement for places where IO#readpartial is used, and
|
132
|
+
* may be aliased as such.
|
131
133
|
*/
|
132
134
|
static VALUE kgio_read_bang(int argc, VALUE *argv, VALUE io)
|
133
135
|
{
|
@@ -148,7 +150,7 @@ static VALUE kgio_read_bang(int argc, VALUE *argv, VALUE io)
|
|
148
150
|
*
|
149
151
|
* Returns nil on EOF.
|
150
152
|
*
|
151
|
-
* Returns
|
153
|
+
* Returns :wait_readable if EAGAIN is encountered.
|
152
154
|
*/
|
153
155
|
static VALUE kgio_tryread(int argc, VALUE *argv, VALUE io)
|
154
156
|
{
|
@@ -230,7 +232,7 @@ done:
|
|
230
232
|
long written = RSTRING_LEN(a->buf) - a->len;
|
231
233
|
|
232
234
|
if (io_wait) {
|
233
|
-
|
235
|
+
(void)kgio_call_wait_writable(a->io);
|
234
236
|
|
235
237
|
/* buf may be modified in other thread/fiber */
|
236
238
|
a->len = RSTRING_LEN(a->buf) - written;
|
@@ -241,7 +243,7 @@ done:
|
|
241
243
|
} else if (written > 0) {
|
242
244
|
a->buf = rb_str_new(a->ptr, a->len);
|
243
245
|
} else {
|
244
|
-
a->buf =
|
246
|
+
a->buf = sym_wait_writable;
|
245
247
|
}
|
246
248
|
return 0;
|
247
249
|
}
|
@@ -276,9 +278,8 @@ retry:
|
|
276
278
|
*
|
277
279
|
* Returns nil when the write completes.
|
278
280
|
*
|
279
|
-
* Calls
|
280
|
-
*
|
281
|
-
* fatal error occurs.
|
281
|
+
* Calls whatever is is defined to be the kgio_wait_writable method
|
282
|
+
* for the class.
|
282
283
|
*/
|
283
284
|
static VALUE kgio_write(VALUE io, VALUE str)
|
284
285
|
{
|
@@ -288,14 +289,14 @@ static VALUE kgio_write(VALUE io, VALUE str)
|
|
288
289
|
/*
|
289
290
|
* call-seq:
|
290
291
|
*
|
291
|
-
* io.kgio_trywrite(str) -> nil or
|
292
|
+
* io.kgio_trywrite(str) -> nil or :wait_writable
|
292
293
|
*
|
293
294
|
* Returns nil if the write was completed in full.
|
294
295
|
*
|
295
296
|
* Returns a String containing the unwritten portion if EAGAIN
|
296
297
|
* was encountered, but some portion was successfully written.
|
297
298
|
*
|
298
|
-
* Returns
|
299
|
+
* Returns :wait_writable if EAGAIN is encountered and nothing
|
299
300
|
* was written.
|
300
301
|
*/
|
301
302
|
static VALUE kgio_trywrite(VALUE io, VALUE str)
|
@@ -350,9 +351,10 @@ void init_kgio_read_write(void)
|
|
350
351
|
{
|
351
352
|
VALUE mPipeMethods, mSocketMethods;
|
352
353
|
VALUE mKgio = rb_define_module("Kgio");
|
354
|
+
VALUE mWaiters = rb_const_get(mKgio, rb_intern("DefaultWaiters"));
|
353
355
|
|
354
|
-
|
355
|
-
|
356
|
+
sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
|
357
|
+
sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
|
356
358
|
|
357
359
|
/*
|
358
360
|
* Document-module: Kgio::PipeMethods
|
@@ -391,4 +393,6 @@ void init_kgio_read_write(void)
|
|
391
393
|
|
392
394
|
eErrno_EPIPE = rb_const_get(rb_mErrno, rb_intern("EPIPE"));
|
393
395
|
eErrno_ECONNRESET = rb_const_get(rb_mErrno, rb_intern("ECONNRESET"));
|
396
|
+
rb_include_module(mPipeMethods, mWaiters);
|
397
|
+
rb_include_module(mSocketMethods, mWaiters);
|
394
398
|
}
|
data/ext/kgio/wait.c
CHANGED
@@ -1,117 +1,81 @@
|
|
1
1
|
#include "kgio.h"
|
2
2
|
|
3
|
-
static ID
|
3
|
+
static ID id_wait_rd, id_wait_wr;
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
rb_sys_fail("wait readable");
|
12
|
-
}
|
13
|
-
}
|
5
|
+
/*
|
6
|
+
* avoiding rb_thread_select() or similar since rb_io_wait_*able can be
|
7
|
+
* made to use poll() later on. It's highly unlikely Ruby will move to
|
8
|
+
* use an edge-triggered event notification, so assigning EAGAIN is
|
9
|
+
* probably safe...
|
10
|
+
*/
|
14
11
|
|
15
|
-
void kgio_wait_writable(VALUE io, int fd)
|
16
|
-
{
|
17
|
-
if (io_wait_wr) {
|
18
|
-
(void)rb_funcall(io, io_wait_wr, 0, 0);
|
19
|
-
} else {
|
20
|
-
if (!rb_io_wait_writable(fd))
|
21
|
-
rb_sys_fail("wait writable");
|
22
|
-
}
|
23
|
-
}
|
24
12
|
|
25
13
|
/*
|
26
|
-
*
|
14
|
+
* Blocks the running Thread indefinitely until +self+ IO object is writable.
|
15
|
+
* This method is automatically called by default whenever kgio_read needs
|
16
|
+
* to block on input.
|
27
17
|
*
|
28
|
-
*
|
29
|
-
*
|
30
|
-
*
|
31
|
-
* Sets a method for kgio_read to call when a read would block.
|
32
|
-
* This is useful for non-blocking frameworks that use Fibers,
|
33
|
-
* as the method referred to this may cause the current Fiber
|
34
|
-
* to yield execution.
|
35
|
-
*
|
36
|
-
* A special value of nil will cause Ruby to wait using the
|
37
|
-
* rb_io_wait_readable() function.
|
18
|
+
* Users of alternative threading/fiber libraries are
|
19
|
+
* encouraged to override this method in their subclasses or modules to
|
20
|
+
* work with their threading/blocking methods.
|
38
21
|
*/
|
39
|
-
static VALUE
|
22
|
+
static VALUE kgio_wait_readable(VALUE self)
|
40
23
|
{
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
io_wait_rd = 0;
|
47
|
-
return sym;
|
48
|
-
}
|
49
|
-
rb_raise(rb_eTypeError, "must be a symbol or nil");
|
50
|
-
return sym;
|
24
|
+
errno = EAGAIN;
|
25
|
+
if (!rb_io_wait_readable(my_fileno(self)))
|
26
|
+
rb_sys_fail("kgio_wait_readable");
|
27
|
+
|
28
|
+
return self;
|
51
29
|
}
|
52
30
|
|
53
31
|
/*
|
54
|
-
*
|
55
|
-
*
|
56
|
-
*
|
57
|
-
*
|
58
|
-
*
|
59
|
-
*
|
60
|
-
* This is useful for non-blocking frameworks that use Fibers,
|
61
|
-
* as the method referred to this may cause the current Fiber
|
62
|
-
* to yield execution.
|
63
|
-
*
|
64
|
-
* A special value of nil will cause Ruby to wait using the
|
65
|
-
* rb_io_wait_writable() function.
|
32
|
+
* blocks the running Thread indefinitely until +self+ IO object is writable
|
33
|
+
* This method is automatically called whenever kgio_write needs to
|
34
|
+
* block on output.
|
35
|
+
* Users of alternative threading/fiber libraries are
|
36
|
+
* encouraged to override this method in their subclasses or modules to
|
37
|
+
* work with their threading/blocking methods.
|
66
38
|
*/
|
67
|
-
static VALUE
|
39
|
+
static VALUE kgio_wait_writable(VALUE self)
|
68
40
|
{
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
io_wait_wr = 0;
|
75
|
-
return sym;
|
76
|
-
}
|
77
|
-
rb_raise(rb_eTypeError, "must be a symbol or nil");
|
78
|
-
return sym;
|
41
|
+
errno = EAGAIN;
|
42
|
+
if (!rb_io_wait_writable(my_fileno(self)))
|
43
|
+
rb_sys_fail("kgio_wait_writable");
|
44
|
+
|
45
|
+
return self;
|
79
46
|
}
|
80
47
|
|
81
|
-
|
82
|
-
* call-seq:
|
83
|
-
*
|
84
|
-
* Kgio.wait_writable -> Symbol or nil
|
85
|
-
*
|
86
|
-
* Returns the symbolic method name of the method assigned to
|
87
|
-
* call when EAGAIN is occurs on a Kgio::PipeMethods#kgio_write
|
88
|
-
* or Kgio::SocketMethods#kgio_write call
|
89
|
-
*/
|
90
|
-
static VALUE wait_wr(VALUE mod)
|
48
|
+
VALUE kgio_call_wait_writable(VALUE io)
|
91
49
|
{
|
92
|
-
return
|
50
|
+
return rb_funcall(io, id_wait_wr, 0, 0);
|
93
51
|
}
|
94
52
|
|
95
|
-
|
96
|
-
* call-seq:
|
97
|
-
*
|
98
|
-
* Kgio.wait_readable -> Symbol or nil
|
99
|
-
*
|
100
|
-
* Returns the symbolic method name of the method assigned to
|
101
|
-
* call when EAGAIN is occurs on a Kgio::PipeMethods#kgio_read
|
102
|
-
* or Kgio::SocketMethods#kgio_read call.
|
103
|
-
*/
|
104
|
-
static VALUE wait_rd(VALUE mod)
|
53
|
+
VALUE kgio_call_wait_readable(VALUE io)
|
105
54
|
{
|
106
|
-
return
|
55
|
+
return rb_funcall(io, id_wait_rd, 0, 0);
|
107
56
|
}
|
108
57
|
|
109
58
|
void init_kgio_wait(void)
|
110
59
|
{
|
111
60
|
VALUE mKgio = rb_define_module("Kgio");
|
112
61
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
62
|
+
/*
|
63
|
+
* Document-module: Kgio::DefaultWaiters
|
64
|
+
*
|
65
|
+
* This module contains default kgio_wait_readable and
|
66
|
+
* kgio_wait_writable methods that block indefinitely (in a
|
67
|
+
* thread-safe manner) until an IO object is read or writable.
|
68
|
+
* This module is included in the Kgio::PipeMethods and
|
69
|
+
* Kgio::SocketMethods modules used by all bundled IO-derived
|
70
|
+
* objects.
|
71
|
+
*/
|
72
|
+
VALUE mWaiters = rb_define_module_under(mKgio, "DefaultWaiters");
|
73
|
+
|
74
|
+
id_wait_rd = rb_intern("kgio_wait_readable");
|
75
|
+
id_wait_wr = rb_intern("kgio_wait_writable");
|
76
|
+
|
77
|
+
rb_define_method(mWaiters, "kgio_wait_readable",
|
78
|
+
kgio_wait_readable, 0);
|
79
|
+
rb_define_method(mWaiters, "kgio_wait_writable",
|
80
|
+
kgio_wait_writable, 0);
|
117
81
|
}
|
data/kgio.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.authors = ["kgio hackers"]
|
12
12
|
s.date = Time.now.utc.strftime('%Y-%m-%d')
|
13
13
|
s.description = description
|
14
|
-
s.email = %q{
|
14
|
+
s.email = %q{kgio@bogomips.org}
|
15
15
|
|
16
16
|
s.extra_rdoc_files = File.readlines('.document').map! do |x|
|
17
17
|
x.chomp!
|
data/lib/kgio.rb
CHANGED
@@ -8,11 +8,11 @@ module Kgio
|
|
8
8
|
LOCALHOST = '127.0.0.1'
|
9
9
|
|
10
10
|
# Kgio::PipeMethods#kgio_tryread and Kgio::SocketMethods#kgio_tryread will
|
11
|
-
# return
|
11
|
+
# return :wait_readable when waiting for a read is required.
|
12
12
|
WaitReadable = :wait_readable
|
13
13
|
|
14
|
-
# PipeMethods#kgio_trywrite and SocketMethods#kgio_trywrite will
|
15
|
-
#
|
14
|
+
# PipeMethods#kgio_trywrite and SocketMethods#kgio_trywrite will return
|
15
|
+
# :wait_writable when waiting for a read is required.
|
16
16
|
WaitWritable = :wait_writable
|
17
17
|
end
|
18
18
|
|
data/test/lib_read_write.rb
CHANGED
@@ -13,9 +13,6 @@ module LibReadWriteTest
|
|
13
13
|
@rd.close unless @rd.closed?
|
14
14
|
@wr.close unless @wr.closed?
|
15
15
|
end
|
16
|
-
assert_nothing_raised do
|
17
|
-
Kgio.wait_readable = Kgio.wait_writable = nil
|
18
|
-
end
|
19
16
|
end
|
20
17
|
|
21
18
|
def test_read_zero
|
@@ -97,9 +94,9 @@ module LibReadWriteTest
|
|
97
94
|
case rv
|
98
95
|
when String
|
99
96
|
wr = rv
|
100
|
-
when
|
97
|
+
when :wait_readable
|
101
98
|
assert false, "should never get here line=#{__LINE__}"
|
102
|
-
when
|
99
|
+
when :wait_writable
|
103
100
|
IO.select(nil, [ @wr ])
|
104
101
|
else
|
105
102
|
wr = false
|
@@ -122,7 +119,7 @@ module LibReadWriteTest
|
|
122
119
|
end
|
123
120
|
|
124
121
|
def test_tryread_empty
|
125
|
-
assert_equal
|
122
|
+
assert_equal :wait_readable, @rd.kgio_tryread(1)
|
126
123
|
end
|
127
124
|
|
128
125
|
def test_read_too_much
|
@@ -159,10 +156,10 @@ module LibReadWriteTest
|
|
159
156
|
|
160
157
|
def test_trywrite_return_wait_writable
|
161
158
|
tmp = []
|
162
|
-
tmp << @wr.kgio_trywrite("HI") until tmp[-1] ==
|
163
|
-
assert
|
164
|
-
assert(!(
|
165
|
-
assert_equal
|
159
|
+
tmp << @wr.kgio_trywrite("HI") until tmp[-1] == :wait_writable
|
160
|
+
assert :wait_writable === tmp[-1]
|
161
|
+
assert(!(:wait_readable === tmp[-1]))
|
162
|
+
assert_equal :wait_writable, tmp.pop
|
166
163
|
assert tmp.size > 0
|
167
164
|
penultimate = tmp.pop
|
168
165
|
assert(penultimate == "I" || penultimate == nil)
|
@@ -173,7 +170,7 @@ module LibReadWriteTest
|
|
173
170
|
def test_tryread_extra_buf_eagain_clears_buffer
|
174
171
|
tmp = "hello world"
|
175
172
|
rv = @rd.kgio_tryread(2, tmp)
|
176
|
-
assert_equal
|
173
|
+
assert_equal :wait_readable, rv
|
177
174
|
assert_equal "", tmp
|
178
175
|
end
|
179
176
|
|
@@ -205,11 +202,10 @@ module LibReadWriteTest
|
|
205
202
|
|
206
203
|
def test_monster_write_wait_writable
|
207
204
|
@wr.instance_variable_set :@nr, 0
|
208
|
-
def @wr.
|
205
|
+
def @wr.kgio_wait_writable
|
209
206
|
@nr += 1
|
210
207
|
IO.select(nil, [self])
|
211
208
|
end
|
212
|
-
Kgio.wait_writable = :wait_writable
|
213
209
|
buf = "." * 1024 * 1024 * 10
|
214
210
|
thr = Thread.new { @wr.kgio_write(buf) }
|
215
211
|
readed = @rd.read(buf.size)
|
@@ -220,7 +216,6 @@ module LibReadWriteTest
|
|
220
216
|
end
|
221
217
|
|
222
218
|
def test_wait_readable_ruby_default
|
223
|
-
assert_nothing_raised { Kgio.wait_readable = nil }
|
224
219
|
elapsed = 0
|
225
220
|
foo = nil
|
226
221
|
t0 = Time.now
|
@@ -243,7 +238,6 @@ module LibReadWriteTest
|
|
243
238
|
rescue Errno::EAGAIN
|
244
239
|
break
|
245
240
|
end while true
|
246
|
-
assert_nothing_raised { Kgio.wait_writable = nil }
|
247
241
|
elapsed = 0
|
248
242
|
foo = nil
|
249
243
|
t0 = Time.now
|
@@ -261,10 +255,9 @@ module LibReadWriteTest
|
|
261
255
|
end
|
262
256
|
|
263
257
|
def test_wait_readable_method
|
264
|
-
def @rd.
|
258
|
+
def @rd.kgio_wait_readable
|
265
259
|
defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
|
266
260
|
end
|
267
|
-
assert_nothing_raised { Kgio.wait_readable = :moo }
|
268
261
|
foo = nil
|
269
262
|
begin
|
270
263
|
foo = @rd.kgio_read(5)
|
@@ -277,29 +270,26 @@ module LibReadWriteTest
|
|
277
270
|
end
|
278
271
|
|
279
272
|
def test_tryread_wait_readable_method
|
280
|
-
def @rd.
|
273
|
+
def @rd.kgio_wait_readable
|
281
274
|
raise "Hello"
|
282
275
|
end
|
283
|
-
|
284
|
-
assert_equal Kgio::WaitReadable, @rd.kgio_tryread(5)
|
276
|
+
assert_equal :wait_readable, @rd.kgio_tryread(5)
|
285
277
|
end
|
286
278
|
|
287
279
|
def test_trywrite_wait_readable_method
|
288
|
-
def @wr.
|
280
|
+
def @wr.kgio_wait_writable
|
289
281
|
raise "Hello"
|
290
282
|
end
|
291
|
-
assert_nothing_raised { Kgio.wait_writable = :moo }
|
292
283
|
tmp = []
|
293
284
|
buf = "." * 1024
|
294
285
|
10000.times { tmp << @wr.kgio_trywrite(buf) }
|
295
|
-
assert_equal
|
286
|
+
assert_equal :wait_writable, tmp.pop
|
296
287
|
end
|
297
288
|
|
298
289
|
def test_wait_writable_method
|
299
|
-
def @wr.
|
290
|
+
def @wr.kgio_wait_writable
|
300
291
|
defined?(@z) ? raise(RuntimeError, "Hello") : @z = "HI"
|
301
292
|
end
|
302
|
-
assert_nothing_raised { Kgio.wait_writable = :moo }
|
303
293
|
n = []
|
304
294
|
begin
|
305
295
|
loop { n << @wr.kgio_write("HIHIHIHIHIHI") }
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'io/nonblock'
|
3
|
+
$-w = true
|
4
|
+
require 'kgio'
|
5
|
+
|
6
|
+
class TestDefaultWait < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_socket_pair
|
9
|
+
a, b = Kgio::UNIXSocket.pair
|
10
|
+
assert_equal a, a.kgio_wait_writable
|
11
|
+
a.syswrite('.')
|
12
|
+
assert_equal b, b.kgio_wait_readable
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_pipe
|
16
|
+
a, b = Kgio::Pipe.new
|
17
|
+
assert_equal b, b.kgio_wait_writable
|
18
|
+
b.syswrite('.')
|
19
|
+
assert_equal a, a.kgio_wait_readable
|
20
|
+
end
|
21
|
+
end
|
data/test/test_pipe_popen.rb
CHANGED
@@ -6,7 +6,7 @@ require 'kgio'
|
|
6
6
|
class TestPipePopen < Test::Unit::TestCase
|
7
7
|
def test_popen
|
8
8
|
io = Kgio::Pipe.popen("sleep 1 && echo HI")
|
9
|
-
assert_equal
|
9
|
+
assert_equal :wait_readable, io.kgio_tryread(2)
|
10
10
|
sleep 1.5
|
11
11
|
assert_equal "HI\n", io.kgio_read(3)
|
12
12
|
assert_nil io.kgio_read(5)
|
data/test/test_tcp_connect.rb
CHANGED
@@ -5,7 +5,7 @@ require 'kgio'
|
|
5
5
|
|
6
6
|
class SubSocket < Kgio::Socket
|
7
7
|
attr_accessor :foo
|
8
|
-
def
|
8
|
+
def kgio_wait_writable
|
9
9
|
@foo = "waited"
|
10
10
|
end
|
11
11
|
end
|
@@ -23,7 +23,6 @@ class TestKgioTcpConnect < Test::Unit::TestCase
|
|
23
23
|
@srv.close unless @srv.closed?
|
24
24
|
Kgio.accept_cloexec = true
|
25
25
|
Kgio.accept_nonblock = false
|
26
|
-
Kgio.wait_readable = Kgio.wait_writable = nil
|
27
26
|
end
|
28
27
|
|
29
28
|
def test_new
|
@@ -56,7 +55,6 @@ class TestKgioTcpConnect < Test::Unit::TestCase
|
|
56
55
|
end
|
57
56
|
|
58
57
|
def test_socket_start
|
59
|
-
Kgio::wait_writable = :wait_writable
|
60
58
|
sock = SubSocket.start(@addr)
|
61
59
|
assert_nil sock.foo
|
62
60
|
ready = IO.select(nil, [ sock ])
|
@@ -65,7 +63,6 @@ class TestKgioTcpConnect < Test::Unit::TestCase
|
|
65
63
|
end
|
66
64
|
|
67
65
|
def test_wait_writable_set
|
68
|
-
Kgio::wait_writable = :wait_writable
|
69
66
|
sock = SubSocket.new(@addr)
|
70
67
|
assert_equal "waited", sock.foo
|
71
68
|
assert_equal nil, sock.kgio_write("HELLO")
|
data/test/test_unix_connect.rb
CHANGED
@@ -6,7 +6,7 @@ require 'tempfile'
|
|
6
6
|
|
7
7
|
class SubSocket < Kgio::Socket
|
8
8
|
attr_accessor :foo
|
9
|
-
def
|
9
|
+
def kgio_wait_writable
|
10
10
|
@foo = "waited"
|
11
11
|
end
|
12
12
|
end
|
@@ -57,7 +57,6 @@ class TestKgioUnixConnect < Test::Unit::TestCase
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def test_socket_start
|
60
|
-
Kgio::wait_writable = :wait_writable
|
61
60
|
sock = SubSocket.start(@addr)
|
62
61
|
assert_nil sock.foo
|
63
62
|
ready = IO.select(nil, [ sock ])
|
@@ -66,7 +65,6 @@ class TestKgioUnixConnect < Test::Unit::TestCase
|
|
66
65
|
end
|
67
66
|
|
68
67
|
def test_wait_writable_set
|
69
|
-
Kgio::wait_writable = :wait_writable
|
70
68
|
sock = SubSocket.new(@addr)
|
71
69
|
assert_kind_of Kgio::Socket, sock
|
72
70
|
assert_instance_of SubSocket, sock
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kgio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: -766259887
|
5
|
+
prerelease: true
|
6
6
|
segments:
|
7
|
-
-
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version:
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
- 0pre1
|
10
|
+
version: 2.0.0pre1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- kgio hackers
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-11-18 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -24,7 +24,7 @@ description: |-
|
|
24
24
|
exceptions on EAGAIN and EINPROGRESS. It is intended for use with the
|
25
25
|
Unicorn and Rainbows! Rack servers, but may be used by other
|
26
26
|
applications.
|
27
|
-
email:
|
27
|
+
email: kgio@bogomips.org
|
28
28
|
executables: []
|
29
29
|
|
30
30
|
extensions:
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- test/lib_server_accept.rb
|
79
79
|
- test/test_accept_class.rb
|
80
80
|
- test/test_connect_fd_leak.rb
|
81
|
+
- test/test_default_wait.rb
|
81
82
|
- test/test_pipe_popen.rb
|
82
83
|
- test/test_pipe_read_write.rb
|
83
84
|
- test/test_socketpair_read_write.rb
|
@@ -112,12 +113,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
113
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
114
|
none: false
|
114
115
|
requirements:
|
115
|
-
- - "
|
116
|
+
- - ">"
|
116
117
|
- !ruby/object:Gem::Version
|
117
|
-
hash:
|
118
|
+
hash: 25
|
118
119
|
segments:
|
119
|
-
-
|
120
|
-
|
120
|
+
- 1
|
121
|
+
- 3
|
122
|
+
- 1
|
123
|
+
version: 1.3.1
|
121
124
|
requirements: []
|
122
125
|
|
123
126
|
rubyforge_project: rainbows
|
@@ -126,6 +129,7 @@ signing_key:
|
|
126
129
|
specification_version: 3
|
127
130
|
summary: kinder, gentler I/O for Ruby
|
128
131
|
test_files:
|
132
|
+
- test/test_default_wait.rb
|
129
133
|
- test/test_unix_connect.rb
|
130
134
|
- test/test_pipe_read_write.rb
|
131
135
|
- test/test_unix_server.rb
|