kgio 2.2.0 → 2.3.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/.document CHANGED
@@ -8,7 +8,9 @@ ISSUES
8
8
  HACKING
9
9
  lib
10
10
  ext/kgio/accept.c
11
+ ext/kgio/autopush.c
11
12
  ext/kgio/connect.c
12
13
  ext/kgio/kgio_ext.c
14
+ ext/kgio/poll.c
13
15
  ext/kgio/read_write.c
14
16
  ext/kgio/wait.c
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.2.0.GIT
4
+ DEF_VER=v2.3.0.GIT
5
5
 
6
6
  LF='
7
7
  '
data/README CHANGED
@@ -33,7 +33,7 @@ applications.
33
33
  The library consists of a C extension so you'll need a C compiler
34
34
  and Ruby development libraries/headers.
35
35
 
36
- You may download the tarball from the Mongrel project page on Rubyforge
36
+ You may download the tarball from the Rainbows! project page on Rubyforge
37
37
  and run setup.rb after unpacking it:
38
38
 
39
39
  http://rubyforge.org/frs/?group_id=8977
data/ext/kgio/accept.c CHANGED
@@ -248,7 +248,7 @@ static VALUE addr_bang(VALUE io)
248
248
  * An optional class argument may be specified to override the
249
249
  * Kgio::Socket-class return value:
250
250
  *
251
- * server.kgio_accept(MySocket) -> MySocket
251
+ * server.kgio_tryaccept(MySocket) -> MySocket
252
252
  */
253
253
  static VALUE tcp_tryaccept(int argc, VALUE *argv, VALUE io)
254
254
  {
@@ -453,13 +453,26 @@ void init_kgio_accept(void)
453
453
  rb_define_singleton_method(mKgio, "accept_class=", set_accepted, 1);
454
454
  rb_define_singleton_method(mKgio, "accept_class", get_accepted, 0);
455
455
 
456
+ /*
457
+ * Document-class: Kgio::UNIXServer
458
+ *
459
+ * Kgio::UNIXServer should be used in place of the plain UNIXServer
460
+ * when kgio_accept and kgio_tryaccept methods are needed.
461
+ */
456
462
  cUNIXServer = rb_const_get(rb_cObject, rb_intern("UNIXServer"));
457
463
  cUNIXServer = rb_define_class_under(mKgio, "UNIXServer", cUNIXServer);
458
464
  rb_define_method(cUNIXServer, "kgio_tryaccept", unix_tryaccept, -1);
459
465
  rb_define_method(cUNIXServer, "kgio_accept", unix_accept, -1);
460
466
 
467
+ /*
468
+ * Document-class: Kgio::TCPServer
469
+ *
470
+ * Kgio::TCPServer should be used in place of the plain TCPServer
471
+ * when kgio_accept and kgio_tryaccept methods are needed.
472
+ */
461
473
  cTCPServer = rb_const_get(rb_cObject, rb_intern("TCPServer"));
462
474
  cTCPServer = rb_define_class_under(mKgio, "TCPServer", cTCPServer);
475
+
463
476
  rb_define_method(cTCPServer, "kgio_tryaccept", tcp_tryaccept, -1);
464
477
  rb_define_method(cTCPServer, "kgio_accept", tcp_accept, -1);
465
478
  init_sock_for_fd();
data/ext/kgio/autopush.c CHANGED
@@ -78,11 +78,32 @@ static void state_set(VALUE io, enum autopush_state state)
78
78
  static enum autopush_state detect_acceptor_state(VALUE io);
79
79
  static void push_pending_data(VALUE io);
80
80
 
81
+ /*
82
+ * call-seq:
83
+ * Kgio.autopush? -> true or false
84
+ *
85
+ * Returns whether or not autopush is enabled.
86
+ *
87
+ * Only available on systems with TCP_CORK (Linux) or
88
+ * TCP_NOPUSH (FreeBSD, and maybe other *BSDs).
89
+ */
81
90
  static VALUE s_get_autopush(VALUE self)
82
91
  {
83
92
  return enabled ? Qtrue : Qfalse;
84
93
  }
85
94
 
95
+ /*
96
+ * call-seq:
97
+ * Kgio.autopush = true
98
+ * Kgio.autopush = false
99
+ *
100
+ * Enables or disables autopush for sockets created with kgio_accept
101
+ * and kgio_tryaccept methods. Autopush relies on TCP_CORK/TCP_NOPUSH
102
+ * being enabled on the listen socket.
103
+ *
104
+ * Only available on systems with TCP_CORK (Linux) or
105
+ * TCP_NOPUSH (FreeBSD, and maybe other *BSDs).
106
+ */
86
107
  static VALUE s_set_autopush(VALUE self, VALUE val)
87
108
  {
88
109
  enabled = RTEST(val);
@@ -90,11 +111,35 @@ static VALUE s_set_autopush(VALUE self, VALUE val)
90
111
  return val;
91
112
  }
92
113
 
114
+ /*
115
+ * call-seq:
116
+ *
117
+ * io.kgio_autopush? -> true or false
118
+ *
119
+ * Returns the current autopush state of the Kgio::SocketMethods-enabled
120
+ * socket.
121
+ *
122
+ * Only available on systems with TCP_CORK (Linux) or
123
+ * TCP_NOPUSH (FreeBSD, and maybe other *BSDs).
124
+ */
93
125
  static VALUE autopush_get(VALUE io)
94
126
  {
95
127
  return state_get(io) <= 0 ? Qfalse : Qtrue;
96
128
  }
97
129
 
130
+ /*
131
+ * call-seq:
132
+ *
133
+ * io.kgio_autopush = true
134
+ * io.kgio_autopush = false
135
+ *
136
+ * Enables or disables autopush on any given Kgio::SocketMethods-capable
137
+ * IO object. This does NOT enable or disable TCP_NOPUSH/TCP_CORK right
138
+ * away, that must be done with IO.setsockopt
139
+ *
140
+ * Only available on systems with TCP_CORK (Linux) or
141
+ * TCP_NOPUSH (FreeBSD, and maybe other *BSDs).
142
+ */
98
143
  static VALUE autopush_set(VALUE io, VALUE vbool)
99
144
  {
100
145
  int fd = my_fileno(io);
data/ext/kgio/connect.c CHANGED
@@ -257,12 +257,24 @@ void init_kgio_connect(void)
257
257
  rb_define_singleton_method(cKgio_Socket, "new", kgio_connect, 1);
258
258
  rb_define_singleton_method(cKgio_Socket, "start", kgio_start, 1);
259
259
 
260
+ /*
261
+ * Document-class: Kgio::TCPSocket
262
+ *
263
+ * Kgio::TCPSocket should be used in place of the plain TCPSocket
264
+ * when kgio_* methods are needed.
265
+ */
260
266
  cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
261
267
  cTCPSocket = rb_define_class_under(mKgio, "TCPSocket", cTCPSocket);
262
268
  rb_include_module(cTCPSocket, mSocketMethods);
263
269
  rb_define_singleton_method(cTCPSocket, "new", kgio_tcp_connect, 2);
264
270
  rb_define_singleton_method(cTCPSocket, "start", kgio_tcp_start, 2);
265
271
 
272
+ /*
273
+ * Document-class: Kgio::UNIXSocket
274
+ *
275
+ * Kgio::UNIXSocket should be used in place of the plain UNIXSocket
276
+ * when kgio_* methods are needed.
277
+ */
266
278
  cUNIXSocket = rb_const_get(rb_cObject, rb_intern("UNIXSocket"));
267
279
  cUNIXSocket = rb_define_class_under(mKgio, "UNIXSocket", cUNIXSocket);
268
280
  rb_include_module(cUNIXSocket, mSocketMethods);
data/ext/kgio/extconf.rb CHANGED
@@ -2,6 +2,7 @@ require 'mkmf'
2
2
  $CPPFLAGS << ' -D_GNU_SOURCE'
3
3
  $CPPFLAGS << ' -DPOSIX_C_SOURCE=1'
4
4
 
5
+ have_func("poll", "poll.h")
5
6
  have_func("getaddrinfo", %w(sys/types.h sys/socket.h netdb.h)) or
6
7
  abort "getaddrinfo required"
7
8
  have_func("getnameinfo", %w(sys/socket.h netdb.h)) or
data/ext/kgio/kgio.h CHANGED
@@ -35,6 +35,7 @@ void init_kgio_read_write(void);
35
35
  void init_kgio_accept(void);
36
36
  void init_kgio_connect(void);
37
37
  void init_kgio_autopush(void);
38
+ void init_kgio_poll(void);
38
39
 
39
40
  void kgio_autopush_accept(VALUE, VALUE);
40
41
  void kgio_autopush_recv(VALUE);
@@ -42,5 +43,8 @@ void kgio_autopush_send(VALUE);
42
43
 
43
44
  VALUE kgio_call_wait_writable(VALUE io);
44
45
  VALUE kgio_call_wait_readable(VALUE io);
46
+ #if defined(HAVE_RB_THREAD_BLOCKING_REGION) && defined(HAVE_POLL)
47
+ # define USE_KGIO_POLL
48
+ #endif /* USE_KGIO_POLL */
45
49
 
46
50
  #endif /* KGIO_H */
data/ext/kgio/kgio_ext.c CHANGED
@@ -7,4 +7,5 @@ void Init_kgio_ext(void)
7
7
  init_kgio_connect();
8
8
  init_kgio_accept();
9
9
  init_kgio_autopush();
10
+ init_kgio_poll();
10
11
  }
data/ext/kgio/poll.c ADDED
@@ -0,0 +1,186 @@
1
+ #include "kgio.h"
2
+ #if defined(USE_KGIO_POLL)
3
+ #include <poll.h>
4
+ #ifdef HAVE_RUBY_ST_H
5
+ # include <ruby/st.h>
6
+ #else
7
+ # include <st.h>
8
+ #endif
9
+
10
+ static VALUE sym_wait_readable, sym_wait_writable;
11
+ static ID id_clear;
12
+
13
+ struct poll_args {
14
+ struct pollfd *fds;
15
+ nfds_t nfds;
16
+ int timeout;
17
+ VALUE ios;
18
+ st_table *fd_to_io;
19
+ };
20
+
21
+ static int num2timeout(VALUE timeout)
22
+ {
23
+ switch (TYPE(timeout)) {
24
+ case T_NIL: return -1;
25
+ case T_FIXNUM: return FIX2INT(timeout);
26
+ case T_BIGNUM: return NUM2INT(timeout);
27
+ }
28
+ rb_raise(rb_eTypeError, "timeout must be integer or nil");
29
+ return 0;
30
+ }
31
+
32
+ static VALUE poll_free(VALUE args)
33
+ {
34
+ struct poll_args *a = (struct poll_args *)args;
35
+
36
+ if (a->fds)
37
+ xfree(a->fds);
38
+ if (a->fd_to_io)
39
+ st_free_table(a->fd_to_io);
40
+
41
+ return Qnil;
42
+ }
43
+
44
+ static short value2events(VALUE event)
45
+ {
46
+ if (event == sym_wait_readable) return POLLIN;
47
+ if (event == sym_wait_writable) return POLLOUT;
48
+ if (TYPE(event) == T_FIXNUM) return (short)FIX2INT(event);
49
+ rb_raise(rb_eArgError, "unrecognized event");
50
+ }
51
+
52
+ static int io_to_pollfd_i(VALUE key, VALUE value, VALUE args)
53
+ {
54
+ struct poll_args *a = (struct poll_args *)args;
55
+ struct pollfd *pollfd = &a->fds[a->nfds++];
56
+
57
+ pollfd->fd = my_fileno(key);
58
+ pollfd->events = value2events(value);
59
+ st_insert(a->fd_to_io, (st_data_t)pollfd->fd, (st_data_t)key);
60
+ return ST_CONTINUE;
61
+ }
62
+
63
+ static void hash2pollfds(struct poll_args *a)
64
+ {
65
+ a->fds = xmalloc(sizeof(struct poll_args) * RHASH_SIZE(a->ios));
66
+ a->fd_to_io = st_init_numtable();
67
+ rb_hash_foreach(a->ios, io_to_pollfd_i, (VALUE)a);
68
+ }
69
+
70
+ static VALUE nogvl_poll(void *ptr)
71
+ {
72
+ struct poll_args *a = ptr;
73
+ return (VALUE)poll(a->fds, a->nfds, a->timeout);
74
+ }
75
+
76
+ static VALUE poll_result(int nr, struct poll_args *a)
77
+ {
78
+ struct pollfd *fds = a->fds;
79
+ VALUE io;
80
+ int rc;
81
+
82
+ if ((nfds_t)nr != a->nfds)
83
+ rb_funcall(a->ios, id_clear, 0);
84
+ for (; nr > 0; fds++) {
85
+ if (fds->revents == 0)
86
+ continue;
87
+ --nr;
88
+ rc = st_lookup(a->fd_to_io, (st_data_t)fds->fd, &io);
89
+ assert(rc == 1 && "fd => IO mapping failed");
90
+ rb_hash_aset(a->ios, io, INT2FIX((int)fds->revents));
91
+ }
92
+ return a->ios;
93
+ }
94
+
95
+ static VALUE do_poll(VALUE args)
96
+ {
97
+ struct poll_args *a = (struct poll_args *)args;
98
+ int nr;
99
+
100
+ Check_Type(a->ios, T_HASH);
101
+ hash2pollfds(a);
102
+
103
+ nr = (int)rb_thread_blocking_region(nogvl_poll, a, RUBY_UBF_IO, NULL);
104
+ if (nr < 0) rb_sys_fail("poll");
105
+ if (nr == 0) return Qnil;
106
+
107
+ return poll_result(nr, a);
108
+ }
109
+
110
+ /*
111
+ * call-seq:
112
+ *
113
+ * Kgio.poll({ $stdin => :wait_readable }, 100) -> hash or nil
114
+ * Kgio.poll({ $stdin => Kgio::POLLIN }, 100) -> hash or nil
115
+ *
116
+ * Accepts an input hash with IO objects to wait for as the key and
117
+ * the events to wait for as its value. The events may either be
118
+ * +:wait_readable+ or +:wait_writable+ symbols or a Fixnum mask of
119
+ * Kgio::POLL* constants:
120
+ *
121
+ * Kgio::POLLIN - there is data to read
122
+ * Kgio::POLLPRI - there is urgent data to read
123
+ * Kgio::POLLOUT - writing will not block
124
+ * Kgio::POLLRDHUP - peer has shutdown writes (Linux 2.6.17+ only)
125
+ *
126
+ * Timeout is specified in Integer milliseconds just like the underlying
127
+ * poll(2), not in seconds like IO.select. A nil timeout means to wait
128
+ * forever. It must be an Integer or nil.
129
+ *
130
+ * Kgio.poll modifies and returns its input hash on success with the
131
+ * IO-like object as the key and an Integer mask of events as the hash
132
+ * value. It can return any of the events specified in the input
133
+ * above, along with the following events:
134
+ *
135
+ * Kgio::POLLERR - error condition occurred on the descriptor
136
+ * Kgio::POLLHUP - hang up
137
+ * Kgio::POLLNVAL - invalid request (bad file descriptor)
138
+ *
139
+ * This method is only available under Ruby 1.9 or any other
140
+ * implementations that uses native threads and rb_thread_blocking_region()
141
+ */
142
+ static VALUE s_poll(int argc, VALUE *argv, VALUE self)
143
+ {
144
+ VALUE timeout;
145
+ struct poll_args a;
146
+
147
+ rb_scan_args(argc, argv, "11", &a.ios, &timeout);
148
+ a.timeout = num2timeout(timeout);
149
+ a.nfds = 0;
150
+ a.fds = NULL;
151
+ a.fd_to_io = NULL;
152
+
153
+ return rb_ensure(do_poll, (VALUE)&a, poll_free, (VALUE)&a);
154
+ }
155
+
156
+ void init_kgio_poll(void)
157
+ {
158
+ VALUE mKgio = rb_define_module("Kgio");
159
+ rb_define_singleton_method(mKgio, "poll", s_poll, -1);
160
+
161
+ sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
162
+ sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
163
+ id_clear = rb_intern("clear");
164
+
165
+ #define c(x) rb_define_const(mKgio,#x,INT2NUM((int)x))
166
+
167
+ /* standard types */
168
+
169
+ c(POLLIN);
170
+ c(POLLPRI);
171
+ c(POLLOUT);
172
+
173
+ #ifdef POLLRDHUP
174
+ c(POLLRDHUP);
175
+ #endif
176
+
177
+ /* outputs */
178
+ c(POLLERR);
179
+ c(POLLHUP);
180
+ c(POLLNVAL);
181
+ }
182
+ #else /* ! USE_KGIO_POLL */
183
+ void init_kgio_poll(void)
184
+ {
185
+ }
186
+ #endif /* ! USE_KGIO_POLL */
@@ -10,6 +10,9 @@ static ID id_set_backtrace;
10
10
  */
11
11
  #if defined(__linux__) && ! defined(USE_MSG_DONTWAIT)
12
12
  # define USE_MSG_DONTWAIT
13
+ static const int peek_flags = MSG_DONTWAIT|MSG_PEEK;
14
+ #else
15
+ static const int peek_flags = MSG_PEEK;
13
16
  #endif
14
17
 
15
18
  NORETURN(static void raise_empty_bt(VALUE, const char *));
@@ -223,6 +226,72 @@ static VALUE kgio_tryrecv(int argc, VALUE *argv, VALUE io)
223
226
  # define kgio_tryrecv kgio_tryread
224
227
  #endif /* USE_MSG_DONTWAIT */
225
228
 
229
+ static VALUE my_peek(int io_wait, int argc, VALUE *argv, VALUE io)
230
+ {
231
+ struct io_args a;
232
+ long n;
233
+
234
+ prepare_read(&a, argc, argv, io);
235
+ kgio_autopush_recv(io);
236
+
237
+ if (a.len > 0) {
238
+ if (peek_flags == MSG_PEEK)
239
+ set_nonblocking(a.fd);
240
+ retry:
241
+ n = (long)recv(a.fd, a.ptr, a.len, peek_flags);
242
+ if (read_check(&a, n, "recv(MSG_PEEK)", io_wait) != 0)
243
+ goto retry;
244
+ }
245
+ return a.buf;
246
+ }
247
+
248
+ /*
249
+ * call-seq:
250
+ *
251
+ * socket.kgio_trypeek(maxlen) -> buffer
252
+ * socket.kgio_trypeek(maxlen, buffer) -> buffer
253
+ *
254
+ * Like kgio_tryread, except it uses MSG_PEEK so it does not drain the
255
+ * socket buffer. A subsequent read of any type (including another peek)
256
+ * will return the same data.
257
+ */
258
+ static VALUE kgio_trypeek(int argc, VALUE *argv, VALUE io)
259
+ {
260
+ return my_peek(0, argc, argv, io);
261
+ }
262
+
263
+ /*
264
+ * call-seq:
265
+ *
266
+ * socket.kgio_peek(maxlen) -> buffer
267
+ * socket.kgio_peek(maxlen, buffer) -> buffer
268
+ *
269
+ * Like kgio_read, except it uses MSG_PEEK so it does not drain the
270
+ * socket buffer. A subsequent read of any type (including another peek)
271
+ * will return the same data.
272
+ */
273
+ static VALUE kgio_peek(int argc, VALUE *argv, VALUE io)
274
+ {
275
+ return my_peek(1, argc, argv, io);
276
+ }
277
+
278
+ /*
279
+ * call-seq:
280
+ *
281
+ * Kgio.trypeek(socket, maxlen) -> buffer
282
+ * Kgio.trypeek(socket, maxlen, buffer) -> buffer
283
+ *
284
+ * Like Kgio.tryread, except it uses MSG_PEEK so it does not drain the
285
+ * socket buffer. This can only be used on sockets and not pipe objects.
286
+ * Maybe used in place of SocketMethods#kgio_trypeek for non-Kgio objects
287
+ */
288
+ static VALUE s_trypeek(int argc, VALUE *argv, VALUE mod)
289
+ {
290
+ if (argc <= 1)
291
+ rb_raise(rb_eArgError, "wrong number of arguments");
292
+ return my_peek(0, argc - 1, &argv[1], argv[0]);
293
+ }
294
+
226
295
  static void prepare_write(struct io_args *a, VALUE io, VALUE str)
227
296
  {
228
297
  a->buf = (TYPE(str) == T_STRING) ? str : rb_obj_as_string(str);
@@ -410,6 +479,7 @@ void init_kgio_read_write(void)
410
479
 
411
480
  rb_define_singleton_method(mKgio, "tryread", s_tryread, -1);
412
481
  rb_define_singleton_method(mKgio, "trywrite", s_trywrite, 2);
482
+ rb_define_singleton_method(mKgio, "trypeek", s_trypeek, -1);
413
483
 
414
484
  /*
415
485
  * Document-module: Kgio::PipeMethods
@@ -438,6 +508,8 @@ void init_kgio_read_write(void)
438
508
  rb_define_method(mSocketMethods, "kgio_write", kgio_send, 1);
439
509
  rb_define_method(mSocketMethods, "kgio_tryread", kgio_tryrecv, -1);
440
510
  rb_define_method(mSocketMethods, "kgio_trywrite", kgio_trysend, 1);
511
+ rb_define_method(mSocketMethods, "kgio_trypeek", kgio_trypeek, -1);
512
+ rb_define_method(mSocketMethods, "kgio_peek", kgio_peek, -1);
441
513
 
442
514
  /*
443
515
  * Returns the client IPv4 address of the socket in dotted quad
data/lib/kgio.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # -*- encoding: binary -*-
2
2
  require 'socket'
3
+
4
+ # See the {README}[link:index.html]
3
5
  module Kgio
4
6
 
5
7
  # The IPv4 address of UNIX domain sockets, useful for creating
data/pkg.mk CHANGED
@@ -7,7 +7,7 @@ GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
7
7
  @./GIT-VERSION-GEN
8
8
  -include GIT-VERSION-FILE
9
9
  -include local.mk
10
- DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]')
10
+ DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts RbConfig::CONFIG["DLEXT"]')
11
11
  RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
12
12
  RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
13
13
  lib := lib
@@ -44,24 +44,27 @@ $(ext_dl): $(ext_src) $(ext_pfx_src) $(ext_pfx)/$(ext)/Makefile
44
44
  $(MAKE) -C $(@D)
45
45
  lib := $(lib):$(ext_pfx)/$(ext)
46
46
  build: $(ext_dl)
47
+ else
48
+ build:
47
49
  endif
48
50
 
49
- pkg_extra := GIT-VERSION-FILE NEWS ChangeLog LATEST
51
+ pkg_extra += GIT-VERSION-FILE NEWS ChangeLog LATEST
50
52
  ChangeLog: GIT-VERSION-FILE .wrongdoc.yml
51
53
  $(WRONGDOC) prepare
54
+ NEWS LATEST: ChangeLog
52
55
 
53
56
  manifest:
54
57
  $(RM) .manifest
55
58
  $(MAKE) .manifest
56
59
 
57
- .manifest: ChangeLog
60
+ .manifest: $(pkg_extra)
58
61
  (git ls-files && for i in $@ $(pkg_extra); do echo $$i; done) | \
59
62
  LC_ALL=C sort > $@+
60
63
  cmp $@+ $@ || mv $@+ $@
61
64
  $(RM) $@+
62
65
 
63
- doc:: .document .wrongdoc.yml
64
- find lib -type f -name '*.rbc' -exec rm -f '{}' ';'
66
+ doc:: .document .wrongdoc.yml $(pkg_extra)
67
+ -find lib -type f -name '*.rbc' -exec rm -f '{}' ';'
65
68
  -find ext -type f -name '*.rbc' -exec rm -f '{}' ';'
66
69
  $(RM) -r doc
67
70
  $(WRONGDOC) all
@@ -144,7 +147,7 @@ test_units := $(wildcard test/test_*.rb)
144
147
  test: test-unit
145
148
  test-unit: $(test_units)
146
149
  $(test_units): build
147
- $(RUBY) -I $(lib) $@
150
+ $(RUBY) -I $(lib) $@ $(RUBY_TEST_OPTS)
148
151
 
149
152
  # this requires GNU coreutils variants
150
153
  ifneq ($(RSYNC_DEST),)
data/test/test_peek.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'test/unit'
2
+ $-w = true
3
+ require 'kgio'
4
+
5
+ class TestPeek < Test::Unit::TestCase
6
+ class EIEIO < Errno::EIO
7
+ end
8
+
9
+ def teardown
10
+ @rd.close
11
+ @wr.close
12
+ end
13
+
14
+ def test_peek
15
+ @rd, @wr = Kgio::UNIXSocket.pair
16
+ @wr.kgio_write "HELLO"
17
+ assert_equal "HELLO", @rd.kgio_peek(5)
18
+ assert_equal "HELLO", @rd.kgio_trypeek(5)
19
+ assert_equal "HELLO", @rd.kgio_read(5)
20
+ assert_equal :wait_readable, @rd.kgio_trypeek(5)
21
+ def @rd.kgio_wait_readable
22
+ raise EIEIO
23
+ end
24
+ assert_raises(EIEIO) { @rd.kgio_peek(5) }
25
+ end
26
+
27
+ def test_peek_singleton
28
+ @rd, @wr = UNIXSocket.pair
29
+ @wr.syswrite "HELLO"
30
+ assert_equal "HELLO", Kgio.trypeek(@rd, 666)
31
+ assert_equal "HELLO", Kgio.trypeek(@rd, 666)
32
+ assert_equal "HELLO", Kgio.tryread(@rd, 666)
33
+ assert_equal :wait_readable, Kgio.trypeek(@rd, 5)
34
+ end
35
+ end
data/test/test_poll.rb ADDED
@@ -0,0 +1,68 @@
1
+ require 'test/unit'
2
+ $-w = true
3
+ require 'kgio'
4
+
5
+ class TestPoll < Test::Unit::TestCase
6
+ def teardown
7
+ [ @rd, @wr ].each { |io| io.close unless io.closed? }
8
+ end
9
+
10
+ def setup
11
+ @rd, @wr = IO.pipe
12
+ end
13
+
14
+ def test_constants
15
+ assert_kind_of Integer, Kgio::POLLIN
16
+ assert_kind_of Integer, Kgio::POLLOUT
17
+ assert_kind_of Integer, Kgio::POLLPRI
18
+ assert_kind_of Integer, Kgio::POLLHUP
19
+ assert_kind_of Integer, Kgio::POLLERR
20
+ assert_kind_of Integer, Kgio::POLLNVAL
21
+ end
22
+
23
+ def test_poll_symbol
24
+ set = { @rd => :wait_readable, @wr => :wait_writable }
25
+ res = Kgio.poll(set)
26
+ assert_equal({@wr => Kgio::POLLOUT}, res)
27
+ assert_equal set.object_id, res.object_id
28
+ end
29
+
30
+ def test_poll_integer
31
+ set = { @wr => Kgio::POLLOUT|Kgio::POLLHUP }
32
+ res = Kgio.poll(set)
33
+ assert_equal({@wr => Kgio::POLLOUT}, res)
34
+ assert_equal set.object_id, res.object_id
35
+ end
36
+
37
+ def test_poll_timeout
38
+ t0 = Time.now
39
+ res = Kgio.poll({}, 10)
40
+ diff = Time.now - t0
41
+ assert diff >= 0.010, "diff=#{diff}"
42
+ assert_nil res
43
+ end
44
+
45
+ def test_poll_interrupt
46
+ foo = nil
47
+ oldquit = trap(:QUIT) { foo = :bar }
48
+ thr = Thread.new { sleep 0.100; Process.kill(:QUIT, $$) }
49
+ t0 = Time.now
50
+ assert_raises(Errno::EINTR) { Kgio.poll({}) }
51
+ diff = Time.now - t0
52
+ thr.join
53
+ assert diff >= 0.010, "diff=#{diff}"
54
+ ensure
55
+ trap(:QUIT, "DEFAULT")
56
+ end
57
+
58
+ def test_poll_close
59
+ foo = nil
60
+ thr = Thread.new { sleep 0.100; @wr.close }
61
+ t0 = Time.now
62
+ res = Kgio.poll({@rd => Kgio::POLLIN})
63
+ diff = Time.now - t0
64
+ thr.join
65
+ assert_equal([ @rd ], res.keys)
66
+ assert diff >= 0.010, "diff=#{diff}"
67
+ end
68
+ end if Kgio.respond_to?(:poll)
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: 7
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 2.2.0
10
+ version: 2.3.0
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: 2011-02-04 00:00:00 +00:00
18
+ date: 2011-02-09 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -69,8 +69,10 @@ extra_rdoc_files:
69
69
  - HACKING
70
70
  - lib/kgio.rb
71
71
  - ext/kgio/accept.c
72
+ - ext/kgio/autopush.c
72
73
  - ext/kgio/connect.c
73
74
  - ext/kgio/kgio_ext.c
75
+ - ext/kgio/poll.c
74
76
  - ext/kgio/read_write.c
75
77
  - ext/kgio/wait.c
76
78
  files:
@@ -101,6 +103,7 @@ files:
101
103
  - ext/kgio/missing_accept4.h
102
104
  - ext/kgio/my_fileno.h
103
105
  - ext/kgio/nonblock.h
106
+ - ext/kgio/poll.c
104
107
  - ext/kgio/read_write.c
105
108
  - ext/kgio/sock_for_fd.h
106
109
  - ext/kgio/wait.c
@@ -116,8 +119,10 @@ files:
116
119
  - test/test_default_wait.rb
117
120
  - test/test_kgio_addr.rb
118
121
  - test/test_no_dns_on_tcp_connect.rb
122
+ - test/test_peek.rb
119
123
  - test/test_pipe_popen.rb
120
124
  - test/test_pipe_read_write.rb
125
+ - test/test_poll.rb
121
126
  - test/test_singleton_read_write.rb
122
127
  - test/test_socketpair_read_write.rb
123
128
  - test/test_tcp6_client_read_server_write.rb
@@ -168,6 +173,8 @@ signing_key:
168
173
  specification_version: 3
169
174
  summary: kinder, gentler I/O for Ruby
170
175
  test_files:
176
+ - test/test_poll.rb
177
+ - test/test_peek.rb
171
178
  - test/test_default_wait.rb
172
179
  - test/test_no_dns_on_tcp_connect.rb
173
180
  - test/test_unix_connect.rb