kgio 2.4.2 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document CHANGED
@@ -14,3 +14,4 @@ ext/kgio/kgio_ext.c
14
14
  ext/kgio/poll.c
15
15
  ext/kgio/read_write.c
16
16
  ext/kgio/wait.c
17
+ ext/kgio/tryopen.c
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v2.4.2.GIT
4
+ DEF_VER=v2.5.0.GIT
5
5
 
6
6
  LF='
7
7
  '
data/HACKING CHANGED
@@ -29,7 +29,7 @@ characters wide) and NOT the indentation style of Matz Ruby.
29
29
 
30
30
  Contributions are welcome in the form of patches, pull requests, code
31
31
  review, testing, documentation, user support or any other feedback. The
32
- {kgio mailing list}[mailto:kgio@librelist.com] is the
32
+ {kgio mailing list}[mailto:kgio@librelist.org] is the
33
33
  central coordination point for all user and developer feedback and bug
34
34
  reports.
35
35
 
data/ISSUES CHANGED
@@ -1,6 +1,6 @@
1
1
  = Issues
2
2
 
3
- The kgio {mailing list}[mailto:kgio@librelist.com] is the best
3
+ The kgio {mailing list}[mailto:kgio@librelist.org] 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://bogomips.org/kgio].
@@ -25,7 +25,7 @@ guidelines for patch submission.
25
25
  == Mailing List Info
26
26
 
27
27
  * subscribe: send a message to the mailing list
28
- * post: mailto:kgio@librelist.com
28
+ * post: mailto:kgio@librelist.org
29
29
  * private: mailto:kgio@bogomips.org
30
30
 
31
31
  == Mailing List Archives (coming soon)
data/README CHANGED
@@ -3,7 +3,7 @@
3
3
  kgio provides non-blocking I/O methods for Ruby without raising
4
4
  exceptions on EAGAIN and EINPROGRESS. It is intended for use with the
5
5
  Unicorn and Rainbows! Rack servers, but may be used by other
6
- applications.
6
+ applications (that run on Unix-like platforms).
7
7
 
8
8
  == Features
9
9
 
@@ -30,11 +30,8 @@ applications.
30
30
 
31
31
  == Install
32
32
 
33
- The library consists of a C extension so you'll need a C compiler
34
- and Ruby development libraries/headers.
35
-
36
- You may download the tarball from the Rainbows! project page on Rubyforge
37
- and run setup.rb after unpacking it:
33
+ The library consists of a C extension so you'll need a Unix-like system
34
+ with a C compiler and Ruby development libraries/headers.
38
35
 
39
36
  http://rubyforge.org/frs/?group_id=8977
40
37
 
@@ -61,7 +58,7 @@ from git.
61
58
 
62
59
  All feedback (bug reports, user/development dicussion, patches, pull
63
60
  requests) go to the mailing list/newsgroup. See the ISSUES document for
64
- information on the {kgio mailing list}[mailto:kgio@librelist.com]
61
+ information on the {kgio mailing list}[mailto:kgio@librelist.org]
65
62
 
66
63
  For the latest on kgio releases, you may check our NEWS page (and
67
64
  subscribe to our Atom feed).
@@ -1,6 +1,8 @@
1
1
  #include "kgio.h"
2
2
  #include "missing_accept4.h"
3
3
  #include "sock_for_fd.h"
4
+ #include "my_fileno.h"
5
+ #include "nonblock.h"
4
6
 
5
7
  static VALUE localhost;
6
8
  static VALUE cClientSocket;
@@ -2,11 +2,12 @@
2
2
  #define MISSING_ANCIENT_RUBY_H
3
3
 
4
4
  #ifndef HAVE_RB_STR_SET_LEN
5
- static void rb_str_set_len(VALUE str, long len)
5
+ static void my_str_set_len(VALUE str, long len)
6
6
  {
7
7
  RSTRING(str)->len = len;
8
8
  RSTRING(str)->ptr[len] = '\0';
9
9
  }
10
+ #define rb_str_set_len(str,len) my_str_set_len((str),(len))
10
11
  #endif /* ! HAVE_RB_STR_SET_LEN */
11
12
 
12
13
  #ifndef RSTRING_PTR
@@ -13,6 +13,7 @@
13
13
  */
14
14
 
15
15
  #include "kgio.h"
16
+ #include "my_fileno.h"
16
17
  #include <netinet/tcp.h>
17
18
 
18
19
  /*
@@ -142,10 +143,6 @@ static VALUE autopush_get(VALUE io)
142
143
  */
143
144
  static VALUE autopush_set(VALUE io, VALUE vbool)
144
145
  {
145
- int fd = my_fileno(io);
146
- int val;
147
- socklen_t len = sizeof(val);
148
-
149
146
  if (RTEST(vbool))
150
147
  state_set(io, AUTOPUSH_STATE_WRITER);
151
148
  else
@@ -61,7 +61,6 @@ static VALUE tcp_connect(VALUE klass, VALUE ip, VALUE port, int io_wait)
61
61
  struct sockaddr_storage addr;
62
62
  int rc;
63
63
  struct addrinfo *res;
64
- VALUE sock;
65
64
  const char *ipname = StringValuePtr(ip);
66
65
  char ipport[6];
67
66
  unsigned uport = FIX2UINT(port);
@@ -21,16 +21,20 @@ have_func("getnameinfo", %w(sys/types.h sys/socket.h netdb.h)) or
21
21
  have_type("struct sockaddr_storage", %w(sys/types.h sys/socket.h)) or
22
22
  abort "struct sockaddr_storage required"
23
23
  have_func('accept4', %w(sys/socket.h))
24
+ have_header("sys/select.h")
25
+
24
26
  if have_header('ruby/io.h')
25
27
  rubyio = %w(ruby.h ruby/io.h)
26
28
  have_struct_member("rb_io_t", "fd", rubyio)
27
29
  have_struct_member("rb_io_t", "mode", rubyio)
30
+ have_struct_member("rb_io_t", "pathv", rubyio)
28
31
  else
29
32
  rubyio = %w(ruby.h rubyio.h)
30
33
  rb_io_t = have_type("OpenFile", rubyio) ? "OpenFile" : "rb_io_t"
31
34
  have_struct_member(rb_io_t, "f", rubyio)
32
35
  have_struct_member(rb_io_t, "f2", rubyio)
33
36
  have_struct_member(rb_io_t, "mode", rubyio)
37
+ have_struct_member(rb_io_t, "path", rubyio)
34
38
  have_func('rb_fdopen')
35
39
  end
36
40
  have_type("struct RFile", rubyio) and check_sizeof("struct RFile", rubyio)
@@ -40,5 +44,7 @@ have_func('rb_io_ascii8bit_binmode')
40
44
  have_func('rb_thread_blocking_region')
41
45
  have_func('rb_thread_io_blocking_region')
42
46
  have_func('rb_str_set_len')
47
+ have_func('rb_time_interval')
48
+ have_func('rb_wait_for_single_fd')
43
49
 
44
50
  create_makefile('kgio_ext')
@@ -19,8 +19,6 @@
19
19
  #include <netdb.h>
20
20
 
21
21
  #include "ancient_ruby.h"
22
- #include "nonblock.h"
23
- #include "my_fileno.h"
24
22
 
25
23
  struct io_args {
26
24
  VALUE io;
@@ -36,6 +34,7 @@ void init_kgio_accept(void);
36
34
  void init_kgio_connect(void);
37
35
  void init_kgio_autopush(void);
38
36
  void init_kgio_poll(void);
37
+ void init_kgio_tryopen(void);
39
38
 
40
39
  void kgio_autopush_accept(VALUE, VALUE);
41
40
  void kgio_autopush_recv(VALUE);
@@ -8,4 +8,5 @@ void Init_kgio_ext(void)
8
8
  init_kgio_accept();
9
9
  init_kgio_autopush();
10
10
  init_kgio_poll();
11
+ init_kgio_tryopen();
11
12
  }
@@ -1,5 +1,6 @@
1
1
  #include "kgio.h"
2
2
  #if defined(USE_KGIO_POLL)
3
+ #include "my_fileno.h"
3
4
  #include <time.h>
4
5
  #include "broken_system_compat.h"
5
6
  #include <poll.h>
@@ -1,4 +1,6 @@
1
1
  #include "kgio.h"
2
+ #include "my_fileno.h"
3
+ #include "nonblock.h"
2
4
  static VALUE sym_wait_readable, sym_wait_writable;
3
5
  static VALUE eErrno_EPIPE, eErrno_ECONNRESET;
4
6
  static ID id_set_backtrace;
@@ -518,9 +520,10 @@ void init_kgio_read_write(void)
518
520
  rb_define_method(mSocketMethods, "kgio_peek", kgio_peek, -1);
519
521
 
520
522
  /*
521
- * Returns the client IPv4 address of the socket in dotted quad
522
- * form as a string. This is always the value of the
523
- * Kgio::LOCALHOST constant for UNIX domain sockets.
523
+ * Returns the client IP address of the socket as a string
524
+ * (e.g. "127.0.0.1" or "::1").
525
+ * This is always the value of the Kgio::LOCALHOST constant
526
+ * for UNIX domain sockets.
524
527
  */
525
528
  rb_define_attr(mSocketMethods, "kgio_addr", 1, 1);
526
529
  id_set_backtrace = rb_intern("set_backtrace");
@@ -0,0 +1,26 @@
1
+ #if defined(HAVE_RB_IO_T) && \
2
+ defined(HAVE_TYPE_STRUCT_RFILE) && \
3
+ defined(HAVE_ST_PATHV)
4
+ /* MRI 1.9 */
5
+ static void set_file_path(VALUE io, VALUE path)
6
+ {
7
+ rb_io_t *fptr = RFILE(io)->fptr;
8
+ fptr->pathv = rb_str_new4(path);
9
+ }
10
+ #elif defined(HAVE_TYPE_OPENFILE) && \
11
+ defined(HAVE_TYPE_STRUCT_RFILE) && \
12
+ defined(HAVE_ST_PATH)
13
+ /* MRI 1.8 */
14
+ #include "util.h"
15
+ static void set_file_path(VALUE io, VALUE path)
16
+ {
17
+ OpenFile *fptr = RFILE(io)->fptr;
18
+ fptr->path = ruby_strdup(RSTRING_PTR(path));
19
+ }
20
+ #else
21
+ /* Rubinius */
22
+ static void set_file_path(VALUE io, VALUE path)
23
+ {
24
+ rb_iv_set(io, "@path", rb_str_new4(path));
25
+ }
26
+ #endif
@@ -0,0 +1,181 @@
1
+ #include <ruby.h>
2
+ #ifdef HAVE_RUBY_IO_H
3
+ # include <ruby/io.h>
4
+ #else
5
+ # include <rubyio.h>
6
+ #endif
7
+
8
+ #ifdef HAVE_RUBY_ST_H
9
+ # include <ruby/st.h>
10
+ #else
11
+ # include <st.h>
12
+ #endif
13
+
14
+ #include <sys/types.h>
15
+ #include <sys/stat.h>
16
+ #include <fcntl.h>
17
+ #include "set_file_path.h"
18
+
19
+ static ID id_for_fd, id_to_path, id_path;
20
+ static st_table *errno2sym;
21
+
22
+ struct open_args {
23
+ const char *pathname;
24
+ int flags;
25
+ mode_t mode;
26
+ };
27
+
28
+ static VALUE nogvl_open(void *ptr)
29
+ {
30
+ struct open_args *o = ptr;
31
+
32
+ return (VALUE)open(o->pathname, o->flags, o->mode);
33
+ }
34
+
35
+ #ifndef HAVE_RB_THREAD_BLOCKING_REGION
36
+ # define RUBY_UBF_IO ((void *)(-1))
37
+ # include "rubysig.h"
38
+ typedef void rb_unblock_function_t(void *);
39
+ typedef VALUE rb_blocking_function_t(void *);
40
+ static VALUE rb_thread_blocking_region(
41
+ rb_blocking_function_t *fn, void *data1,
42
+ rb_unblock_function_t *ubf, void *data2)
43
+ {
44
+ VALUE rv;
45
+
46
+ TRAP_BEG; /* for FIFO */
47
+ rv = fn(data1);
48
+ TRAP_END;
49
+
50
+ return rv;
51
+ }
52
+ #endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
53
+
54
+ /*
55
+ * call-seq:
56
+ *
57
+ * Kgio::File.tryopen(filename, [, mode [, perm]]) -> Kgio::File or Symbol
58
+ *
59
+ * Returns a Kgio::File object on a successful open. +filename+ is a
60
+ * path to any file on the filesystem. If specified, +mode+ is a bitmask
61
+ * of flags (see IO.sysopen) and +perm+ should be an octal number.
62
+ *
63
+ * This does not raise errors for most failures, but installs returns a
64
+ * Ruby symbol for the constant in the Errno::* namespace.
65
+ *
66
+ * Common error symbols are:
67
+ *
68
+ * - :ENOENT
69
+ * - :EACCES
70
+ *
71
+ * See your open(2) manpage for more information on open(2) errors.
72
+ */
73
+ static VALUE s_tryopen(int argc, VALUE *argv, VALUE klass)
74
+ {
75
+ int fd;
76
+ VALUE pathname, flags, mode;
77
+ struct open_args o;
78
+ int retried = 0;
79
+ VALUE rv;
80
+
81
+ rb_scan_args(argc, argv, "12", &pathname, &flags, &mode);
82
+ if (rb_respond_to(pathname, id_to_path))
83
+ pathname = rb_funcall(pathname, id_to_path, 0);
84
+ o.pathname = StringValueCStr(pathname);
85
+
86
+ switch (TYPE(flags)) {
87
+ case T_NIL: o.flags = O_RDONLY; break;
88
+ case T_FIXNUM: o.flags = FIX2INT(flags); break;
89
+ case T_BIGNUM: o.flags = NUM2INT(flags); break;
90
+ default: rb_raise(rb_eArgError, "flags must be an Integer");
91
+ }
92
+ switch (TYPE(mode)) {
93
+ case T_NIL: o.mode = 0666; break;
94
+ case T_FIXNUM: o.mode = FIX2INT(mode); break;
95
+ case T_BIGNUM: o.mode = NUM2INT(mode); break;
96
+ default: rb_raise(rb_eArgError, "mode must be an Integer");
97
+ }
98
+
99
+ retry:
100
+ fd = (int)rb_thread_blocking_region(nogvl_open, &o, RUBY_UBF_IO, 0);
101
+ if (fd == -1) {
102
+ if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {
103
+ rb_gc();
104
+ if (retried)
105
+ rb_sys_fail(o.pathname);
106
+ retried = 1;
107
+ goto retry;
108
+ }
109
+ if (fd == -1) {
110
+ int saved_errno = errno;
111
+
112
+ if (!st_lookup(errno2sym, (st_data_t)errno, &rv)) {
113
+ errno = saved_errno;
114
+ rb_sys_fail(o.pathname);
115
+ }
116
+ return rv;
117
+ }
118
+ }
119
+ rv = rb_funcall(klass, id_for_fd, 1, INT2FIX(fd));
120
+ set_file_path(rv, pathname);
121
+ return rv;
122
+ }
123
+
124
+ void init_kgio_tryopen(void)
125
+ {
126
+ VALUE mKgio = rb_define_module("Kgio");
127
+ VALUE mPipeMethods = rb_const_get(mKgio, rb_intern("PipeMethods"));
128
+ VALUE cFile;
129
+ VALUE tmp;
130
+ VALUE *ptr;
131
+ long len;
132
+
133
+ id_path = rb_intern("path");
134
+ id_for_fd = rb_intern("for_fd");
135
+ id_to_path = rb_intern("to_path");
136
+
137
+ /*
138
+ * Document-class: Kgio::File
139
+ *
140
+ * This subclass of the core File class adds the "tryopen" singleton
141
+ * method for opening files. A single "tryopen" and check for the
142
+ * return value may be used to avoid unnecessary stat(2) syscalls
143
+ * or File.open exceptions when checking for the existence of a file
144
+ * and opening it.
145
+ */
146
+ cFile = rb_define_class_under(mKgio, "File", rb_cFile);
147
+ rb_define_singleton_method(cFile, "tryopen", s_tryopen, -1);
148
+ rb_include_module(cFile, mPipeMethods);
149
+
150
+ if (!rb_funcall(cFile, rb_intern("method_defined?"), 1,
151
+ ID2SYM(id_to_path)))
152
+ rb_define_alias(cFile, "to_path", "path");
153
+
154
+ errno2sym = st_init_numtable();
155
+ tmp = rb_funcall(rb_mErrno, rb_intern("constants"), 0);
156
+ ptr = RARRAY_PTR(tmp);
157
+ len = RARRAY_LEN(tmp);
158
+ for (; --len >= 0; ptr++) {
159
+ VALUE error;
160
+ ID const_id;
161
+
162
+ switch (TYPE(*ptr)) {
163
+ case T_SYMBOL: const_id = SYM2ID(*ptr); break;
164
+ case T_STRING: const_id = rb_intern(RSTRING_PTR(*ptr)); break;
165
+ default: rb_bug("constant not a symbol or string");
166
+ }
167
+
168
+ error = rb_const_get(rb_mErrno, const_id);
169
+ if ((TYPE(error) != T_CLASS) ||
170
+ !rb_const_defined(error, rb_intern("Errno")))
171
+ continue;
172
+
173
+ error = rb_const_get(error, rb_intern("Errno"));
174
+ switch (TYPE(error)) {
175
+ case T_FIXNUM:
176
+ case T_BIGNUM:
177
+ st_insert(errno2sym, (st_data_t)NUM2INT(error),
178
+ ID2SYM(const_id));
179
+ }
180
+ }
181
+ }
@@ -1,53 +1,93 @@
1
1
  #include "kgio.h"
2
-
2
+ #include "my_fileno.h"
3
3
  static ID id_wait_rd, id_wait_wr;
4
4
 
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
- */
5
+ #if defined(HAVE_RB_TIME_INTERVAL) && defined(HAVE_RB_WAIT_FOR_SINGLE_FD)
6
+ static int kgio_timedwait(VALUE self, VALUE timeout, int write_p)
7
+ {
8
+ struct timeval tv = rb_time_interval(timeout);
9
+ int events = write_p ? RB_WAITFD_OUT : RB_WAITFD_IN;
10
+
11
+ return rb_wait_for_single_fd(my_fileno(self), events, &tv);
12
+ }
13
+ #else /* ! (HAVE_RB_TIME_INTERVAL && HAVE_RB_WAIT_FOR_SINGLE_FD) */
14
+ static int kgio_timedwait(VALUE self, VALUE timeout, int write_p)
15
+ {
16
+ VALUE argv[4];
17
+ VALUE set = rb_ary_new3(1, self);
11
18
 
19
+ argv[0] = write_p ? Qnil : set;
20
+ argv[1] = write_p ? set : Qnil;
21
+ argv[2] = Qnil;
22
+ argv[3] = timeout;
23
+
24
+ set = rb_funcall2(rb_cIO, rb_intern("select"), 4, argv);
25
+ return NIL_P(set) ? 0 : 1;
26
+ }
27
+ #endif /* ! (HAVE_RB_TIME_INTERVAL && HAVE_RB_WAIT_FOR_SINGLE_FD) */
28
+
29
+ static int kgio_wait(int argc, VALUE *argv, VALUE self, int write_p)
30
+ {
31
+ int fd;
32
+ VALUE timeout;
33
+
34
+ if (rb_scan_args(argc, argv, "01", &timeout) == 1 && !NIL_P(timeout))
35
+ return kgio_timedwait(self, timeout, write_p);
36
+
37
+ fd = my_fileno(self);
38
+ errno = EAGAIN;
39
+ write_p ? rb_io_wait_writable(fd) : rb_io_wait_readable(fd);
40
+ return 1;
41
+ }
12
42
 
13
43
  /*
14
- * Blocks the running Thread indefinitely until +self+ IO object is readable.
15
- * This method is automatically called by default whenever kgio_read needs
16
- * to block on input.
44
+ * call-seq:
45
+ *
46
+ * io.kgio_wait_readable -> IO
47
+ * io.kgio_wait_readable(timeout) -> IO or nil
48
+ *
49
+ * Blocks the running Thread indefinitely until the IO object is readable
50
+ * or if +timeout+ expires. If +timeout+ is specified and expires, +nil+
51
+ * is returned.
52
+ *
53
+ * This method is automatically called (without timeout argument) by default
54
+ * whenever kgio_read needs to block on input.
17
55
  *
18
56
  * Users of alternative threading/fiber libraries are
19
57
  * encouraged to override this method in their subclasses or modules to
20
58
  * work with their threading/blocking methods.
21
59
  */
22
- static VALUE kgio_wait_readable(VALUE self)
60
+ static VALUE kgio_wait_readable(int argc, VALUE *argv, VALUE self)
23
61
  {
24
- int fd = my_fileno(self);
25
-
26
- errno = EAGAIN;
27
- if (!rb_io_wait_readable(fd))
28
- rb_sys_fail("kgio_wait_readable");
62
+ int r = kgio_wait(argc, argv, self, 0);
29
63
 
30
- return self;
64
+ if (r < 0) rb_sys_fail("kgio_wait_readable");
65
+ return r == 0 ? Qnil : self;
31
66
  }
32
67
 
33
68
  /*
34
- * Blocks the running Thread indefinitely until +self+ IO object is writable.
35
- * This method is automatically called whenever kgio_write needs to
36
- * block on output.
69
+ * call-seq:
70
+ *
71
+ * io.kgio_wait_writeable -> IO
72
+ * io.kgio_wait_writable(timeout) -> IO or nil
73
+ *
74
+ * Blocks the running Thread indefinitely until the IO object is writable
75
+ * or if +timeout+ expires. If +timeout+ is specified and expires, +nil+
76
+ * is returned.
77
+ *
78
+ * This method is automatically called (without timeout argument) by default
79
+ * whenever kgio_write needs to block on output.
37
80
  *
38
81
  * Users of alternative threading/fiber libraries are
39
82
  * encouraged to override this method in their subclasses or modules to
40
83
  * work with their threading/blocking methods.
41
84
  */
42
- static VALUE kgio_wait_writable(VALUE self)
85
+ static VALUE kgio_wait_writable(int argc, VALUE *argv, VALUE self)
43
86
  {
44
- int fd = my_fileno(self);
45
-
46
- errno = EAGAIN;
47
- if (!rb_io_wait_writable(fd))
48
- rb_sys_fail("kgio_wait_writable");
87
+ int r = kgio_wait(argc, argv, self, 1);
49
88
 
50
- return self;
89
+ if (r < 0) rb_sys_fail("kgio_wait_writable");
90
+ return r == 0 ? Qnil : self;
51
91
  }
52
92
 
53
93
  VALUE kgio_call_wait_writable(VALUE io)
@@ -80,7 +120,7 @@ void init_kgio_wait(void)
80
120
  id_wait_wr = rb_intern("kgio_wait_writable");
81
121
 
82
122
  rb_define_method(mWaiters, "kgio_wait_readable",
83
- kgio_wait_readable, 0);
123
+ kgio_wait_readable, -1);
84
124
  rb_define_method(mWaiters, "kgio_wait_writable",
85
- kgio_wait_writable, 0);
125
+ kgio_wait_writable, -1);
86
126
  }
data/pkg.mk CHANGED
@@ -69,7 +69,7 @@ doc:: .document .wrongdoc.yml $(pkg_extra)
69
69
  $(RM) -r doc
70
70
  $(WRONGDOC) all
71
71
  install -m644 COPYING doc/COPYING
72
- install -m644 $(shell grep '^[A-Z]' .document) doc/
72
+ install -m644 $(shell LC_ALL=C grep '^[A-Z]' .document) doc/
73
73
 
74
74
  ifneq ($(VERSION),)
75
75
  pkggem := pkg/$(rfpackage)-$(VERSION).gem
@@ -167,5 +167,9 @@ doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
167
167
  doc_gz:
168
168
  for i in $(docs); do \
169
169
  gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
170
+ check-warnings:
171
+ @(for i in $$(git ls-files '*.rb'| grep -v '^setup\.rb$$'); \
172
+ do $(RUBY) -d -W2 -c $$i; done) | grep -v '^Syntax OK$$' || :
170
173
 
171
174
  .PHONY: all .FORCE-GIT-VERSION-FILE doc test $(test_units) manifest
175
+ .PHONY: check-warnings
@@ -18,4 +18,28 @@ class TestDefaultWait < Test::Unit::TestCase
18
18
  b.syswrite('.')
19
19
  assert_equal a, a.kgio_wait_readable
20
20
  end
21
+
22
+ def test_wait_readable_timed
23
+ a, b = Kgio::Pipe.new
24
+ t0 = Time.now
25
+ assert_nil a.kgio_wait_readable(1.1)
26
+ diff = Time.now - t0
27
+ assert_in_delta diff, 1.1, 0.05
28
+
29
+ b.kgio_write '.'
30
+ assert_equal a, a.kgio_wait_readable(1.1)
31
+ end
32
+
33
+ def test_wait_writable_timed
34
+ a, b = Kgio::Pipe.new
35
+ buf = "*" * 65536
36
+ true until Symbol === b.kgio_trywrite(buf)
37
+ t0 = Time.now
38
+ assert_nil b.kgio_wait_writable(1.1)
39
+ diff = Time.now - t0
40
+ assert_in_delta diff, 1.1, 0.05
41
+
42
+ a.kgio_read(16384)
43
+ assert_equal b, b.kgio_wait_writable(1.1)
44
+ end
21
45
  end
@@ -0,0 +1,81 @@
1
+ require 'tempfile'
2
+ require 'test/unit'
3
+ $-w = true
4
+ require 'kgio'
5
+
6
+ class TestTryopen < Test::Unit::TestCase
7
+
8
+ def test_tryopen_success
9
+ tmp = Kgio::File.tryopen(__FILE__)
10
+ assert_kind_of File, tmp
11
+ assert_equal File.read(__FILE__), tmp.read
12
+ assert_equal __FILE__, tmp.path
13
+ assert_equal __FILE__, tmp.to_path
14
+ assert_nothing_raised { tmp.close }
15
+ end
16
+
17
+ def test_tryopen_ENOENT
18
+ tmp = Tempfile.new "tryopen"
19
+ path = tmp.path
20
+ tmp.close!
21
+ tmp = Kgio::File.tryopen(path)
22
+ assert_equal :ENOENT, tmp
23
+ end
24
+
25
+ def test_tryopen_EPERM
26
+ tmp = Tempfile.new "tryopen"
27
+ File.chmod 0000, tmp.path
28
+ tmp = Kgio::File.tryopen(tmp.path)
29
+ assert_equal :EACCES, tmp
30
+ end
31
+
32
+ def test_tryopen_readwrite
33
+ tmp = Tempfile.new "tryopen"
34
+ file = Kgio::File.tryopen(tmp.path, IO::RDWR)
35
+ file.syswrite "FOO"
36
+ assert_equal "FOO", tmp.sysread(3)
37
+ end
38
+
39
+ def test_tryopen_try_readwrite
40
+ tmp = Tempfile.new "tryopen"
41
+ file = Kgio::File.tryopen(tmp.path, IO::RDWR)
42
+ assert_nil file.kgio_trywrite("FOO")
43
+ file.rewind
44
+ assert_equal "FOO", file.kgio_tryread(3)
45
+ end
46
+
47
+ def test_tryopen_mode
48
+ tmp = Tempfile.new "tryopen"
49
+ path = tmp.path
50
+ tmp.close!
51
+ file = Kgio::File.tryopen(path, IO::RDWR|IO::CREAT, 0000)
52
+ assert_equal 0100000, File.stat(path).mode
53
+ ensure
54
+ File.unlink path
55
+ end
56
+
57
+ require "benchmark"
58
+ def test_benchmark
59
+ nr = 1000000
60
+ tmp = Tempfile.new('tryopen')
61
+ file = tmp.path
62
+ Benchmark.bmbm do |x|
63
+ x.report("tryopen (OK)") do
64
+ nr.times { Kgio::File.tryopen(file).close }
65
+ end
66
+ x.report("open (OK)") do
67
+ nr.times { File.readable?(file) && File.open(file).close }
68
+ end
69
+ end
70
+ tmp.close!
71
+ assert_equal :ENOENT, Kgio::File.tryopen(file)
72
+ Benchmark.bmbm do |x|
73
+ x.report("tryopen (ENOENT)") do
74
+ nr.times { Kgio::File.tryopen(file) }
75
+ end
76
+ x.report("open (ENOENT)") do
77
+ nr.times { File.readable?(file) && File.open(file) }
78
+ end
79
+ end
80
+ end if ENV["BENCHMARK"]
81
+ end
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
- - 4
9
- - 2
10
- version: 2.4.2
8
+ - 5
9
+ - 0
10
+ version: 2.5.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-06-14 00:00:00 Z
18
+ date: 2011-06-20 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: wrongdoc
@@ -51,7 +51,7 @@ description: |-
51
51
  kgio provides non-blocking I/O methods for Ruby without raising
52
52
  exceptions on EAGAIN and EINPROGRESS. It is intended for use with the
53
53
  Unicorn and Rainbows! Rack servers, but may be used by other
54
- applications.
54
+ applications (that run on Unix-like platforms).
55
55
  email: kgio@librelist.org
56
56
  executables: []
57
57
 
@@ -74,6 +74,7 @@ extra_rdoc_files:
74
74
  - ext/kgio/poll.c
75
75
  - ext/kgio/read_write.c
76
76
  - ext/kgio/wait.c
77
+ - ext/kgio/tryopen.c
77
78
  files:
78
79
  - .document
79
80
  - .gitignore
@@ -106,7 +107,9 @@ files:
106
107
  - ext/kgio/nonblock.h
107
108
  - ext/kgio/poll.c
108
109
  - ext/kgio/read_write.c
110
+ - ext/kgio/set_file_path.h
109
111
  - ext/kgio/sock_for_fd.h
112
+ - ext/kgio/tryopen.c
110
113
  - ext/kgio/wait.c
111
114
  - kgio.gemspec
112
115
  - lib/kgio.rb
@@ -132,6 +135,7 @@ files:
132
135
  - test/test_tcp_connect.rb
133
136
  - test/test_tcp_server.rb
134
137
  - test/test_tcp_server_read_client_write.rb
138
+ - test/test_tryopen.rb
135
139
  - test/test_unix_client_read_server_write.rb
136
140
  - test/test_unix_connect.rb
137
141
  - test/test_unix_server.rb
@@ -189,6 +193,7 @@ test_files:
189
193
  - test/test_connect_fd_leak.rb
190
194
  - test/test_singleton_read_write.rb
191
195
  - test/test_kgio_addr.rb
196
+ - test/test_tryopen.rb
192
197
  - test/test_tcp6_client_read_server_write.rb
193
198
  - test/test_tcp_server_read_client_write.rb
194
199
  - test/test_unix_client_read_server_write.rb