summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2024-12-13 16:18:17 +0900
committerKoichi Sasada <ko1@atdot.net>2024-12-13 17:05:58 +0900
commite09c23433e2a7f4e2410b46c8dc79496f0453307 (patch)
tree63143355d5a1414d98443a4960b5c8fa2f8b4d42
parent1d3091b4db5656f8feb3dfe5113573d80352b72d (diff)
followup 0bdb38ba6be208064a514c12a9b80328645689f8
(forgot to amend...)
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/12331
-rw-r--r--NEWS.md4
-rw-r--r--ractor.c2
-rw-r--r--ractor.rb14
3 files changed, 20 insertions, 0 deletions
diff --git a/NEWS.md b/NEWS.md
index 99f21e0bcc..d7bf5e66c0 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -83,6 +83,9 @@ Note: We're only listing outstanding class updates.
* Ractor.[] and Ractor.[]= are added to access the ractor local storage
of the current Ractor. [[Feature #20715]]
+ * `Ractor.store_if_absent(key){ init }` is added to initialize ractor local
+ variables in thread-safty. [[Feature #20875]]
+
* Range
* Range#size now raises TypeError if the range is not iterable. [[Misc #18984]]
@@ -401,6 +404,7 @@ details of the default gems or bundled gems.
[Bug #20795]: https://bugs.ruby-lang.org/issues/20795
[Feature #20811]: https://bugs.ruby-lang.org/issues/20811
[Feature #20860]: https://bugs.ruby-lang.org/issues/20860
+[Feature #20875]: https://bugs.ruby-lang.org/issues/20875
[Feature #20876]: https://bugs.ruby-lang.org/issues/20876
[Feature #20884]: https://bugs.ruby-lang.org/issues/20884
[Feature #20902]: https://bugs.ruby-lang.org/issues/20902
diff --git a/ractor.c b/ractor.c
index 9db904dc03..6f50064964 100644
--- a/ractor.c
+++ b/ractor.c
@@ -3677,6 +3677,8 @@ ractor_local_storage_mark(rb_ractor_t *r)
if (r->idkey_local_storage) {
rb_id_table_foreach_values(r->idkey_local_storage, idkey_local_storage_mark_i, NULL);
}
+
+ rb_gc_mark(r->local_storage_store_lock);
}
static int
diff --git a/ractor.rb b/ractor.rb
index da0ca1d4c2..3119682dd1 100644
--- a/ractor.rb
+++ b/ractor.rb
@@ -856,6 +856,20 @@ class Ractor
Primitive.ractor_local_value_set(sym, val)
end
+ # call-seq:
+ # Ractor.store_if_absent(key){ init_block }
+ #
+ # If the correponding value is not set, yield a value with
+ # init_block and store the value in thread-safe manner.
+ # This method returns corresponding stored value.
+ #
+ # (1..10).map{
+ # Thread.new(it){|i|
+ # Ractor.store_if_absent(:s){ f(); i }
+ # #=> return stored value of key :s
+ # }
+ # }.map(&:value).uniq.size #=> 1 and f() is called only once
+ #
def self.store_if_absent(sym)
Primitive.ractor_local_value_store_if_absent(sym)
end