ractor-sharing 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/docs/lockhash.md +5 -2
- data/ext/ractor/lock/lockhash.c +8 -5
- data/lib/ractor/active_object.rb +9 -4
- data/lib/ractor/sharing/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f667d77a73e96a72c9cbaa28e3d45b7511aa5d3ecafe79d23923c89918d634a6
|
|
4
|
+
data.tar.gz: 99ae5d37d366f37c0d81da184a5ff15abe681a56af5cf4383841e9acb4a091e2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ace4ea48c92eef46604b3743138609ff081325857138c1c581538aefb28a1636e993f0ce6a80c80796ad66beff047df648a829578767219476c970d233f58b3c
|
|
7
|
+
data.tar.gz: db8a6797917215ee087193ed345a75d7e619896a978e6a552ab7e2f85c19f017ccc33278b7e21acc452471b210247765629ef5420cfe34a9f7becc7686085a43
|
data/docs/lockhash.md
CHANGED
|
@@ -38,7 +38,7 @@ h = Ractor::LockHash.new(initial = nil)
|
|
|
38
38
|
h[key] # read
|
|
39
39
|
h.fetch(key, default) # read, with the usual default / block / KeyError
|
|
40
40
|
h.key?(key)
|
|
41
|
-
h.keys / h.to_h # a
|
|
41
|
+
h.keys / h.to_h # a copy of the whole hash as it was at one moment
|
|
42
42
|
h.inspect
|
|
43
43
|
|
|
44
44
|
h.synchronize {|h| ... } # the only place writes are allowed; yields the LockHash
|
|
@@ -55,7 +55,10 @@ that block **after** the lookup has released the lock, so a default that reads
|
|
|
55
55
|
this hash again is fine.
|
|
56
56
|
|
|
57
57
|
Keys and values must be **shareable**; `ArgumentError` otherwise. The LockHash
|
|
58
|
-
itself is frozen and shareable, so it can be passed to any Ractor.
|
|
58
|
+
itself is frozen and shareable, so it can be passed to any Ractor. `keys` and
|
|
59
|
+
`to_h` return plain mutable copies, yours to reshape; everything inside them is
|
|
60
|
+
shareable already, so `Ractor.make_shareable(h.to_h)` is all it takes to hand
|
|
61
|
+
one to another Ractor.
|
|
59
62
|
|
|
60
63
|
### Writes only inside `synchronize`
|
|
61
64
|
|
data/ext/ractor/lock/lockhash.c
CHANGED
|
@@ -210,7 +210,7 @@ lockhash_collect_pair(st_data_t key, st_data_t value, st_data_t hash)
|
|
|
210
210
|
return ST_CONTINUE;
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
/* A Hash of the entries as they are now
|
|
213
|
+
/* A Hash of the entries as they are now, owned by the calling Ractor. */
|
|
214
214
|
static VALUE
|
|
215
215
|
lockhash_snapshot(VALUE self)
|
|
216
216
|
{
|
|
@@ -225,14 +225,14 @@ lockhash_keys_body(VALUE ptr)
|
|
|
225
225
|
struct rs_guard_arg *arg = (struct rs_guard_arg *)ptr;
|
|
226
226
|
VALUE keys = rb_ary_new_capa(lockhash_ptr(arg->self)->tbl->num_entries);
|
|
227
227
|
st_foreach(lockhash_ptr(arg->self)->tbl, lockhash_collect_key, (st_data_t)keys);
|
|
228
|
-
return
|
|
228
|
+
return keys;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
static VALUE
|
|
232
232
|
lockhash_to_h_body(VALUE ptr)
|
|
233
233
|
{
|
|
234
234
|
struct rs_guard_arg *arg = (struct rs_guard_arg *)ptr;
|
|
235
|
-
return
|
|
235
|
+
return lockhash_snapshot(arg->self);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
static VALUE
|
|
@@ -289,8 +289,11 @@ lockhash_key_p(VALUE self, VALUE key)
|
|
|
289
289
|
* lockhash.keys -> array
|
|
290
290
|
* lockhash.to_h -> hash
|
|
291
291
|
*
|
|
292
|
-
* A snapshot taken under the lock
|
|
293
|
-
*
|
|
292
|
+
* A snapshot taken under the lock of the whole hash as it was at one moment:
|
|
293
|
+
* a plain mutable copy, the caller's own. Not frozen -- freezing protected
|
|
294
|
+
* nothing (the LockHash never sees the copy again) and only stopped the
|
|
295
|
+
* caller reshaping it. Everything inside is shareable, so make_shareable is
|
|
296
|
+
* one cheap call away when it has to cross to another Ractor.
|
|
294
297
|
*/
|
|
295
298
|
static VALUE
|
|
296
299
|
lockhash_keys(VALUE self)
|
data/lib/ractor/active_object.rb
CHANGED
|
@@ -122,7 +122,10 @@ class Ractor
|
|
|
122
122
|
raise Error, "owner Ractor #{owner.inspect} terminated during initialization" if src.equal?(owner)
|
|
123
123
|
raise __ao_restore_exception__(payload, backtrace) if status == :raise
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
# The proxy the owner built: there is exactly one per active object, so
|
|
126
|
+
# a method that returns self hands back this same object, and .equal?
|
|
127
|
+
# means what it says.
|
|
128
|
+
payload
|
|
126
129
|
end
|
|
127
130
|
|
|
128
131
|
# Class of the proxies returned by .new (a subclass of ActiveObject::Proxy).
|
|
@@ -208,9 +211,11 @@ class Ractor
|
|
|
208
211
|
__ao_reply__(boot, :raise, e)
|
|
209
212
|
return
|
|
210
213
|
end
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
+
# The one proxy for this object, made shareable so it crosses every
|
|
215
|
+
# port by reference: .new returns it, and so does a method returning
|
|
216
|
+
# self. A bare .freeze here used to leave .new building a second one.
|
|
217
|
+
proxy = Ractor.make_shareable(klass.proxy_class.new(Ractor.current, port))
|
|
218
|
+
boot << [:ok, proxy]
|
|
214
219
|
pending = pending_name = nil
|
|
215
220
|
begin
|
|
216
221
|
loop do
|