rb_ractor_belonging() returns 0 only if it has sharable flag.
rb_ractor_confirm_belonging() checks rb_ractor_shareable_p()
if the belonging ractor id is different from current ractor id.
http://rubyci.s3.amazonaws.com/ubuntu/ruby-master/log/20201021T123003Z.log.html.gz
```
/home/chkbuild/chkbuild/tmp/build/20201021T123003Z/ruby/test/json/json_parser_test.rb:227: warning: ambiguous first argument; put parentheses or a space even after `-' operator
/home/chkbuild/chkbuild/tmp/build/20201021T123003Z/ruby/test/json/json_parser_test.rb:228: warning: ambiguous first argument; put parentheses or a space even after `-' operator
```
rb_objspace_reachable_objects_from(obj) is used to traverse all
reachable objects from obj. This function modify objspace but it
is not ractor-safe (thread-safe). This patch fix the problem.
Strategy:
(1) call GC mark process during_gc
(2) call Ractor-local custom mark func when !during_gc
Introduce new method Ractor.make_shareable(obj) which tries to make
obj shareable object. Protocol is here.
(1) If obj is shareable, it is shareable.
(2) If obj is not a shareable object and if obj can be shareable
object if it is frozen, then freeze obj. If obj has reachable
objects (rs), do rs.each{|o| Ractor.make_shareable(o)}
recursively (recursion is not Ruby-level, but C-level).
(3) Otherwise, raise Ractor::Error. Now T_DATA is not a shareable
object even if the object is frozen.
If the method finished without error, given obj is marked as
a sharable object.
To allow makng a shareable frozen T_DATA object, then set
`RUBY_TYPED_FROZEN_SHAREABLE` as type->flags. On default,
this flag is not set. It means user defined T_DATA objects are
not allowed to become shareable objects when it is frozen.
You can make any object shareable by setting FL_SHAREABLE flag,
so if you know that the T_DATA object is shareable (== thread-safe),
set this flag, at creation time for example. `Ractor` object is one
example, which is not a frozen, but a shareable object.
* Support ArithmeticSequence in Array#slice
* Extract rb_range_component_beg_len
* Use rb_range_values to check Range object
* Fix ary_make_partial_step
* Fix for negative step cases
* range.c: Describe the role of err argument in rb_range_component_beg_len
* Raise a RangeError when an arithmetic sequence refers the outside of an array
[Feature #16812]
On Solaris, it seems to access ENV in ``, so skip it now.
```
stderr output is not empty
Exception `NameError' at bootstraptest.tmp.rb:7 - can not access non-sharable objects in constant Object::ENV by non-main Ractor.
#<Thread:0x0044cdf0 run> terminated with exception (report_on_exception is true):
bootstraptest.tmp.rb:7:in ``': can not access non-sharable objects in constant Object::ENV by non-main Ractor. (NameError)
Exception `Ractor::RemoteError' at <internal:ractor>:130 - thrown by remote Ractor.
<internal:ractor>:130:in `take': thrown by remote Ractor. (Ractor::RemoteError)
from bootstraptest.tmp.rb:55:in `<main>'
bootstraptest.tmp.rb:7:in ``': can not access non-sharable objects in constant Object::ENV by non-main Ractor. (NameError)
from bootstraptest.tmp.rb:7:in `ractor_local_globals'
from bootstraptest.tmp.rb:54:in `block in <main>'
```
Unshareable objects should not be touched from multiple ractors
so ObjectSpace.each_object should be restricted. On multi-ractor
mode, ObjectSpace.each_object only iterates shareable objects.
[Feature #17270]
This is a weird use case of Ripper.lex which I'm not sure is supposed to
be maintained, so I'm adding this test so that we can easily notice such
changes.
If we change the behavior, this will break the behavior of hamlit.gem v1
and code like https://github.com/haml/haml/pull/1043.
This reverts commit de17e2dea1.
This patch can introduce race condition because of conflicting
read/write access for enc_table::default_list. Maybe we need to
freeze default_list at the end of Init_encdb() in enc/encdb.c.
To access TLS, it is faster to use language TLS specifier instead
of using pthread_get/setspecific functions.
Original proposal is: Use native thread locals. #3665
To reduce the number of locking for encoding manipulation,
enc_table::list is splited to ::default_list and ::additional_list.
::default_list is pre-allocated and no need locking to access to
the ::default_list. If additional encoding space is needed, use
::additional_list and this list need to use locking.
However, most of case, ::default_list is enough.
According to the log of ac803ab55d, I
found that a thread terminates silently due to "recycled object" of
id2ref:
```
"/home/chkbuild/chkbuild/tmp/build/20201017T033002Z/ruby/lib/drb/drb.rb:366:in `_id2ref'"
"/home/chkbuild/chkbuild/tmp/build/20201017T033002Z/ruby/lib/drb/drb.rb:366:in `to_obj'"
"/home/chkbuild/chkbuild/tmp/build/20201017T033002Z/ruby/lib/drb/drb.rb:1528:in `to_obj'"
"/home/chkbuild/chkbuild/tmp/build/20201017T033002Z/ruby/lib/drb/drb.rb:1847:in `to_obj'"
"/home/chkbuild/chkbuild/tmp/build/20201017T033002Z/ruby/lib/drb/drb.rb:1136:in `method_missing'"
"/home/chkbuild/chkbuild/tmp/build/20201017T033002Z/ruby/test/rinda/test_rinda.rb:652:in `block in do_reply'"
```
https://rubyci.org/logs/rubyci.s3.amazonaws.com/rhel8/ruby-master/log/20201017T033002Z.log.html.gz
I believe that this unintentional thread termination has caused
intermittent timeout failure of `TestRingServer#test_do_reply`.
The root cause of the "recycled object" issue is a bug of
`TestRingServer#test_do_reply`. It creates a callback Proc object but
does not hold the reference to the object:
```
callback = DRb::DRbObject.new callback
```
The original "callback" object is GC'ed unintentionally.
I could consistently reproduce this issue on my machine by adding
`GC.stress = true` at the first of `_test_do_reply` method body.
This change uses another local variable name, "callback_orig", to keep
the original Proc object.
iv_index_tbl manages instance variable indexes (ID -> index).
This data structure should be synchronized with other ractors
so introduce some VM locks.
This patch also introduced atomic ivar cache used by
set/getinlinecache instructions. To make updating ivar cache (IVC),
we changed iv_index_tbl data structure to manage (ID -> entry)
and an entry points serial and index. IVC points to this entry so
that cache update becomes atomically.
Buggy native extensions could have mark functions that cause stack
overflow. When a stack overflow happens during GC, Ruby used to recover
by raising an exception, which runs the interpreter. It's not safe to
run the interpreter during GC since the GC is in an inconsistent state.
This could cause object allocation during GC, for example.
Instead of running the interpreter and potentially causing a crash down
the line, fail fast and abort.