summaryrefslogtreecommitdiff
path: root/cont.c
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2023-02-25 19:27:11 +1300
committerGitHub <noreply@github.com>2023-02-25 19:27:11 +1300
commitf94e83faa04d99a6deac49b8c0a14c585aeea59a (patch)
tree05b734e3d92ecc1dd4a4df44184006adf481de1e /cont.c
parent57bc3f2f462df8e945ddfa5f9a8de45c1b0f0a86 (diff)
downloadruby-f94e83faa04d99a6deac49b8c0a14c585aeea59a.tar.gz
Assigning `nil` to fiber storage deletes the association. (#7378)
Also avoid allocations when looking up `Fiber#storage` if not needed.
Diffstat (limited to 'cont.c')
-rw-r--r--cont.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/cont.c b/cont.c
index 3962572b4e..a932bebf41 100644
--- a/cont.c
+++ b/cont.c
@@ -2059,10 +2059,10 @@ fiber_storage_set(struct rb_fiber_struct *fiber, VALUE storage)
}
static inline VALUE
-fiber_storage_get(rb_fiber_t *fiber)
+fiber_storage_get(rb_fiber_t *fiber, int allocate)
{
VALUE storage = fiber->cont.saved_ec.storage;
- if (storage == Qnil) {
+ if (storage == Qnil && allocate) {
storage = rb_hash_new();
fiber_storage_set(fiber, storage);
}
@@ -2089,7 +2089,14 @@ static VALUE
rb_fiber_storage_get(VALUE self)
{
storage_access_must_be_from_same_fiber(self);
- return rb_obj_dup(fiber_storage_get(fiber_ptr(self)));
+
+ VALUE storage = fiber_storage_get(fiber_ptr(self), FALSE);
+
+ if (storage == Qnil) {
+ return Qnil;
+ } else {
+ return rb_obj_dup(storage);
+ }
}
static int
@@ -2170,8 +2177,7 @@ rb_fiber_storage_aref(VALUE class, VALUE key)
ID id = rb_check_id(&key);
if (!id) return Qnil;
- VALUE storage = fiber_storage_get(fiber_current());
-
+ VALUE storage = fiber_storage_get(fiber_current(), FALSE);
if (storage == Qnil) return Qnil;
return rb_hash_aref(storage, key);
@@ -2193,9 +2199,14 @@ rb_fiber_storage_aset(VALUE class, VALUE key, VALUE value)
ID id = rb_check_id(&key);
if (!id) return Qnil;
- VALUE storage = fiber_storage_get(fiber_current());
+ VALUE storage = fiber_storage_get(fiber_current(), value != Qnil);
+ if (storage == Qnil) return Qnil;
- return rb_hash_aset(storage, key, value);
+ if (value == Qnil) {
+ return rb_hash_delete(storage, key);
+ } else {
+ return rb_hash_aset(storage, key, value);
+ }
}
static VALUE