mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* io.c (io_getpartial): use rb_str_locktmp_ensure().
[ruby-core:56121] [Bug #8669] * io.c (rb_io_sysread): ditto. * test/ruby/test_io.rb: add tests for above. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42214 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5c2f4fbcbd
commit
e4b0852ae4
3 changed files with 63 additions and 5 deletions
|
@ -1,3 +1,12 @@
|
|||
Sun Jul 28 20:28:41 2013 Masaki Matsushita <glass.saga@gmail.com>
|
||||
|
||||
* io.c (io_getpartial): use rb_str_locktmp_ensure().
|
||||
[ruby-core:56121] [Bug #8669]
|
||||
|
||||
* io.c (rb_io_sysread): ditto.
|
||||
|
||||
* test/ruby/test_io.rb: add tests for above.
|
||||
|
||||
Sun Jul 28 20:10:49 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* ext/extmk.rb (extmake): should make static libraries for extensions
|
||||
|
|
31
io.c
31
io.c
|
@ -2397,12 +2397,27 @@ rb_io_set_nonblock(rb_io_t *fptr)
|
|||
void
|
||||
rb_readwrite_sys_fail(int writable, const char *mesg);
|
||||
|
||||
struct read_internal_arg {
|
||||
int fd;
|
||||
char *str_ptr;
|
||||
long len;
|
||||
};
|
||||
|
||||
static VALUE
|
||||
read_internal_call(VALUE arg)
|
||||
{
|
||||
struct read_internal_arg *p = (struct read_internal_arg *)arg;
|
||||
p->len = rb_read_internal(p->fd, p->str_ptr, p->len);
|
||||
return Qundef;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
|
||||
{
|
||||
rb_io_t *fptr;
|
||||
VALUE length, str;
|
||||
long n, len;
|
||||
struct read_internal_arg arg;
|
||||
|
||||
rb_scan_args(argc, argv, "11", &length, &str);
|
||||
|
||||
|
@ -2428,9 +2443,11 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
|
|||
rb_io_set_nonblock(fptr);
|
||||
}
|
||||
io_setstrbuf(&str, len);
|
||||
rb_str_locktmp(str);
|
||||
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);
|
||||
rb_str_unlocktmp(str);
|
||||
arg.fd = fptr->fd;
|
||||
arg.str_ptr = RSTRING_PTR(str);
|
||||
arg.len = len;
|
||||
rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg);
|
||||
n = arg.len;
|
||||
if (n < 0) {
|
||||
if (!nonblock && rb_io_wait_readable(fptr->fd))
|
||||
goto again;
|
||||
|
@ -4542,6 +4559,7 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
|
|||
VALUE len, str;
|
||||
rb_io_t *fptr;
|
||||
long n, ilen;
|
||||
struct read_internal_arg arg;
|
||||
|
||||
rb_scan_args(argc, argv, "11", &len, &str);
|
||||
ilen = NUM2LONG(len);
|
||||
|
@ -4571,8 +4589,11 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
|
|||
|
||||
io_setstrbuf(&str, ilen);
|
||||
rb_str_locktmp(str);
|
||||
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), ilen);
|
||||
rb_str_unlocktmp(str);
|
||||
arg.fd = fptr->fd;
|
||||
arg.str_ptr = RSTRING_PTR(str);
|
||||
arg.len = ilen;
|
||||
rb_ensure(read_internal_call, (VALUE)&arg, rb_str_unlocktmp, str);
|
||||
n = arg.len;
|
||||
|
||||
if (n == -1) {
|
||||
rb_sys_fail_path(fptr->pathv);
|
||||
|
|
|
@ -2815,4 +2815,32 @@ End
|
|||
ensure
|
||||
t.kill
|
||||
end
|
||||
|
||||
def test_readpartial_unlocktmp_ensure
|
||||
bug8669 = '[ruby-core:56121] [Bug #8669]'
|
||||
|
||||
str = ""
|
||||
r, = IO.pipe
|
||||
t = Thread.new { r.readpartial(4096, str) }
|
||||
sleep 0.1 until t.stop?
|
||||
t.raise
|
||||
sleep 0.1 while t.alive?
|
||||
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
|
||||
ensure
|
||||
t.kill
|
||||
end
|
||||
|
||||
def test_sysread_unlocktmp_ensure
|
||||
bug8669 = '[ruby-core:56121] [Bug #8669]'
|
||||
|
||||
str = ""
|
||||
r, = IO.pipe
|
||||
t = Thread.new { r.sysread(4096, str) }
|
||||
sleep 0.1 until t.stop?
|
||||
t.raise
|
||||
sleep 0.1 while t.alive?
|
||||
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
|
||||
ensure
|
||||
t.kill
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue