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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88fa8b206f015cc52f9fb975060cd60ad960b4156a9b827aeb553a31ae34cf39
4
- data.tar.gz: 00adc02e6a7c43bb44ec0c1b701bd3d8b6b1681df54cb3a4163a0b981a087da6
3
+ metadata.gz: f667d77a73e96a72c9cbaa28e3d45b7511aa5d3ecafe79d23923c89918d634a6
4
+ data.tar.gz: 99ae5d37d366f37c0d81da184a5ff15abe681a56af5cf4383841e9acb4a091e2
5
5
  SHA512:
6
- metadata.gz: '0156339ebc1d6924032c142bd106036a9852c5564d01d25e4e198e7b5e11fc006bcfbdcfabe0ec3b26cb925acaa8c102f3690b7f05d5098d4cdf4b318967ee5b'
7
- data.tar.gz: 7cdc6b398b61e1c202653116d6faad460f84a248d0867dde5905f27e6aee288278f91a3d16f0c4444316a4396105ade08a9562b7a8a064d6f627580ddc8e80cc
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 frozen, shareable snapshot of the whole hash
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
 
@@ -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; the caller freezes it if it escapes. */
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 rb_ractor_make_shareable(keys);
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 rb_ractor_make_shareable(lockhash_snapshot(arg->self));
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, frozen and shareable, of the whole hash as
293
- * it was at one moment.
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)
@@ -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
- Ractor.make_shareable(proxy_class.new(owner, payload))
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
- boot << [:ok, port]
212
-
213
- proxy = klass.proxy_class.new(Ractor.current, port).freeze
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  class Ractor
4
4
  module Sharing
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ractor-sharing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Sasada