diff options
| author | Kasumi Hanazuki <kasumi@rollingapple.net> | 2026-02-20 10:56:50 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-20 14:56:50 +1300 |
| commit | b5ccab2093c9bb19ae8564a935e6fd72ec7354cc (patch) | |
| tree | 1f07f8f458dfa5c3d7aad89411da9e8c08413b3c /io_buffer.c | |
| parent | 126b657bd103a1abf4b572ade557ffdc7ae99982 (diff) | |
IO::Buffer#locked: Release lock even when the block raises (#16180)
IO::Buffer#locked: Release lock even when the block raises/breaks
Previously, `IO::Buffer#locked` leaks the lock when the block raises
an exception, or breaks.
Fixes: [Bug #21882]
Diffstat (limited to 'io_buffer.c')
| -rw-r--r-- | io_buffer.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/io_buffer.c b/io_buffer.c index 4bb4685e74..cb35141f47 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -1424,6 +1424,17 @@ rb_io_buffer_try_unlock(VALUE self) return 0; } +static VALUE +rb_io_buffer_locked_ensure(VALUE self) +{ + struct rb_io_buffer *buffer = NULL; + TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer); + + buffer->flags &= ~RB_IO_BUFFER_LOCKED; + + return Qnil; +} + /* * call-seq: locked { ... } * @@ -1466,11 +1477,7 @@ rb_io_buffer_locked(VALUE self) buffer->flags |= RB_IO_BUFFER_LOCKED; - VALUE result = rb_yield(self); - - buffer->flags &= ~RB_IO_BUFFER_LOCKED; - - return result; + return rb_ensure(rb_yield, self, rb_io_buffer_locked_ensure, self); } /* |
