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>
|
Sun Jul 28 20:10:49 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* ext/extmk.rb (extmake): should make static libraries for extensions
|
* 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
|
void
|
||||||
rb_readwrite_sys_fail(int writable, const char *mesg);
|
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
|
static VALUE
|
||||||
io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
|
io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
|
||||||
{
|
{
|
||||||
rb_io_t *fptr;
|
rb_io_t *fptr;
|
||||||
VALUE length, str;
|
VALUE length, str;
|
||||||
long n, len;
|
long n, len;
|
||||||
|
struct read_internal_arg arg;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &length, &str);
|
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);
|
rb_io_set_nonblock(fptr);
|
||||||
}
|
}
|
||||||
io_setstrbuf(&str, len);
|
io_setstrbuf(&str, len);
|
||||||
rb_str_locktmp(str);
|
arg.fd = fptr->fd;
|
||||||
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);
|
arg.str_ptr = RSTRING_PTR(str);
|
||||||
rb_str_unlocktmp(str);
|
arg.len = len;
|
||||||
|
rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg);
|
||||||
|
n = arg.len;
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (!nonblock && rb_io_wait_readable(fptr->fd))
|
if (!nonblock && rb_io_wait_readable(fptr->fd))
|
||||||
goto again;
|
goto again;
|
||||||
|
@ -4542,6 +4559,7 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
|
||||||
VALUE len, str;
|
VALUE len, str;
|
||||||
rb_io_t *fptr;
|
rb_io_t *fptr;
|
||||||
long n, ilen;
|
long n, ilen;
|
||||||
|
struct read_internal_arg arg;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &len, &str);
|
rb_scan_args(argc, argv, "11", &len, &str);
|
||||||
ilen = NUM2LONG(len);
|
ilen = NUM2LONG(len);
|
||||||
|
@ -4571,8 +4589,11 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
|
||||||
|
|
||||||
io_setstrbuf(&str, ilen);
|
io_setstrbuf(&str, ilen);
|
||||||
rb_str_locktmp(str);
|
rb_str_locktmp(str);
|
||||||
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), ilen);
|
arg.fd = fptr->fd;
|
||||||
rb_str_unlocktmp(str);
|
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) {
|
if (n == -1) {
|
||||||
rb_sys_fail_path(fptr->pathv);
|
rb_sys_fail_path(fptr->pathv);
|
||||||
|
|
|
@ -2815,4 +2815,32 @@ End
|
||||||
ensure
|
ensure
|
||||||
t.kill
|
t.kill
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue