kgio 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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