summaryrefslogtreecommitdiff
path: root/io_buffer.c
diff options
context:
space:
mode:
authorKasumi Hanazuki <kasumi@rollingapple.net>2026-02-20 10:56:50 +0900
committerGitHub <noreply@github.com>2026-02-20 14:56:50 +1300
commitb5ccab2093c9bb19ae8564a935e6fd72ec7354cc (patch)
tree1f07f8f458dfa5c3d7aad89411da9e8c08413b3c /io_buffer.c
parent126b657bd103a1abf4b572ade557ffdc7ae99982 (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.c17
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);
}
/*