<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/test/ruby/test_encoding.rb, branch v4.0.4</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Fixes to encoding/transcoding for ractors.</title>
<updated>2025-08-22T17:49:44+00:00</updated>
<author>
<name>Luke Gruber</name>
<email>luke.gruber@shopify.com</email>
</author>
<published>2025-08-14T23:21:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=9db54a1a98956ea37a04d6e3f83fcd6745ed96a6'/>
<id>9db54a1a98956ea37a04d6e3f83fcd6745ed96a6</id>
<content type='text'>
Not all ractor-related encoding issues were fixed by 1afc07e815051e2f73493f055f2130cb642ba12a.
I found more by running my test-all branch with 3 ractors for each test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Not all ractor-related encoding issues were fixed by 1afc07e815051e2f73493f055f2130cb642ba12a.
I found more by running my test-all branch with 3 ractors for each test.
</pre>
</div>
</content>
</entry>
<entry>
<title>Autoload encodings on the main ractor</title>
<updated>2025-07-07T10:44:21+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-07-04T07:39:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=482f4cad8237647c4a0a5a5945cca5264333c8c2'/>
<id>482f4cad8237647c4a0a5a5945cca5264333c8c2</id>
<content type='text'>
None of the datastructures involved in the require process are
safe to call on a secondary ractor, however when autoloading
encodings, we do so from the current ractor.

So all sorts of corruption can happen when using an autoloaded
encoding for the first time from a secondary ractor.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
None of the datastructures involved in the require process are
safe to call on a secondary ractor, however when autoloading
encodings, we do so from the current ractor.

So all sorts of corruption can happen when using an autoloaded
encoding for the first time from a secondary ractor.
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Add locks around accesses/modifications to global encodings table"</title>
<updated>2025-07-04T04:39:10+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2025-07-04T03:52:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=24ac9f11dedcf1b1003000dcb25774b0a3bc38a7'/>
<id>24ac9f11dedcf1b1003000dcb25774b0a3bc38a7</id>
<content type='text'>
This reverts commit cf4d37fbc079116453e69cf08ea8007d0e1c73e6.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit cf4d37fbc079116453e69cf08ea8007d0e1c73e6.
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Make get/set default internal/external encoding lock-free"</title>
<updated>2025-07-04T04:39:10+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2025-07-04T03:52:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=50704fe8e6e5b75b5d0d4544247cdabf7c8411ea'/>
<id>50704fe8e6e5b75b5d0d4544247cdabf7c8411ea</id>
<content type='text'>
This reverts commit dda5a04f2b4835582dba09ba33797258a61efafe.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit dda5a04f2b4835582dba09ba33797258a61efafe.
</pre>
</div>
</content>
</entry>
<entry>
<title>Make get/set default internal/external encoding lock-free</title>
<updated>2025-07-03T20:33:10+00:00</updated>
<author>
<name>Luke Gruber</name>
<email>luke.gruber@shopify.com</email>
</author>
<published>2025-06-30T15:20:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=dda5a04f2b4835582dba09ba33797258a61efafe'/>
<id>dda5a04f2b4835582dba09ba33797258a61efafe</id>
<content type='text'>
Also, make sure autoloading of encodings is safe across ractors.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Also, make sure autoloading of encodings is safe across ractors.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add locks around accesses/modifications to global encodings table</title>
<updated>2025-07-03T20:33:10+00:00</updated>
<author>
<name>Luke Gruber</name>
<email>luke.gruber@shopify.com</email>
</author>
<published>2025-06-25T16:44:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=cf4d37fbc079116453e69cf08ea8007d0e1c73e6'/>
<id>cf4d37fbc079116453e69cf08ea8007d0e1c73e6</id>
<content type='text'>
This fixes segfaults and errors of the type "Encoding not found" when
using encoding-related methods and internal encoding c functions across
ractors.

Example of a possible segfault in release mode or assertion error in debug mode:

```ruby
rs = []
100.times do
  rs &lt;&lt; Ractor.new do
    "abc".force_encoding(Encoding.list.shuffle.first)
  end
end
while rs.any?
  r, obj = Ractor.select(*rs)
  rs.delete(r)
end
```
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This fixes segfaults and errors of the type "Encoding not found" when
using encoding-related methods and internal encoding c functions across
ractors.

Example of a possible segfault in release mode or assertion error in debug mode:

```ruby
rs = []
100.times do
  rs &lt;&lt; Ractor.new do
    "abc".force_encoding(Encoding.list.shuffle.first)
  end
end
while rs.any?
  r, obj = Ractor.select(*rs)
  rs.delete(r)
end
```
</pre>
</div>
</content>
</entry>
<entry>
<title>Refactor generic fields to use `T_IMEMO/fields` objects.</title>
<updated>2025-06-17T13:28:05+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-06-16T09:19:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=cd9f447be247478d2eb3da985295735cce20cb23'/>
<id>cd9f447be247478d2eb3da985295735cce20cb23</id>
<content type='text'>
Followup: https://github.com/ruby/ruby/pull/13589

This simplify a lot of things, as we no longer need to manually
manage the memory, we can use the Read-Copy-Update pattern and
avoid numerous race conditions.

Co-Authored-By: Étienne Barrié &lt;etienne.barrie@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Followup: https://github.com/ruby/ruby/pull/13589

This simplify a lot of things, as we no longer need to manually
manage the memory, we can use the Read-Copy-Update pattern and
avoid numerous race conditions.

Co-Authored-By: Étienne Barrié &lt;etienne.barrie@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>`Ractor::Port`</title>
<updated>2025-05-30T19:01:33+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2025-05-26T18:58:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ef2bb61018cd9ccb5b61a3d91911e04a773da4a7'/>
<id>ef2bb61018cd9ccb5b61a3d91911e04a773da4a7</id>
<content type='text'>
* Added `Ractor::Port`
  * `Ractor::Port#receive` (support multi-threads)
  * `Rcator::Port#close`
  * `Ractor::Port#closed?`
* Added some methods
  * `Ractor#join`
  * `Ractor#value`
  * `Ractor#monitor`
  * `Ractor#unmonitor`
* Removed some methods
  * `Ractor#take`
  * `Ractor.yield`
* Change the spec
  * `Racotr.select`

You can wait for multiple sequences of messages with `Ractor::Port`.

```ruby
ports = 3.times.map{ Ractor::Port.new }
ports.map.with_index do |port, ri|
  Ractor.new port,ri do |port, ri|
    3.times{|i| port &lt;&lt; "r#{ri}-#{i}"}
  end
end

p ports.each{|port| pp 3.times.map{port.receive}}

```

In this example, we use 3 ports, and 3 Ractors send messages to them respectively.
We can receive a series of messages from each port.

You can use `Ractor#value` to get the last value of a Ractor's block:

```ruby
result = Ractor.new do
  heavy_task()
end.value
```

You can wait for the termination of a Ractor with `Ractor#join` like this:

```ruby
Ractor.new do
  some_task()
end.join
```

`#value` and `#join` are similar to `Thread#value` and `Thread#join`.

To implement `#join`, `Ractor#monitor` (and `Ractor#unmonitor`) is introduced.

This commit changes `Ractor.select()` method.
It now only accepts ports or Ractors, and returns when a port receives a message or a Ractor terminates.

We removes `Ractor.yield` and `Ractor#take` because:
* `Ractor::Port` supports most of similar use cases in a simpler manner.
* Removing them significantly simplifies the code.

We also change the internal thread scheduler code (thread_pthread.c):
* During barrier synchronization, we keep the `ractor_sched` lock to avoid deadlocks.
  This lock is released by `rb_ractor_sched_barrier_end()`
  which is called at the end of operations that require the barrier.
* fix potential deadlock issues by checking interrupts just before setting UBF.

https://bugs.ruby-lang.org/issues/21262
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Added `Ractor::Port`
  * `Ractor::Port#receive` (support multi-threads)
  * `Rcator::Port#close`
  * `Ractor::Port#closed?`
* Added some methods
  * `Ractor#join`
  * `Ractor#value`
  * `Ractor#monitor`
  * `Ractor#unmonitor`
* Removed some methods
  * `Ractor#take`
  * `Ractor.yield`
* Change the spec
  * `Racotr.select`

You can wait for multiple sequences of messages with `Ractor::Port`.

```ruby
ports = 3.times.map{ Ractor::Port.new }
ports.map.with_index do |port, ri|
  Ractor.new port,ri do |port, ri|
    3.times{|i| port &lt;&lt; "r#{ri}-#{i}"}
  end
end

p ports.each{|port| pp 3.times.map{port.receive}}

```

In this example, we use 3 ports, and 3 Ractors send messages to them respectively.
We can receive a series of messages from each port.

You can use `Ractor#value` to get the last value of a Ractor's block:

```ruby
result = Ractor.new do
  heavy_task()
end.value
```

You can wait for the termination of a Ractor with `Ractor#join` like this:

```ruby
Ractor.new do
  some_task()
end.join
```

`#value` and `#join` are similar to `Thread#value` and `Thread#join`.

To implement `#join`, `Ractor#monitor` (and `Ractor#unmonitor`) is introduced.

This commit changes `Ractor.select()` method.
It now only accepts ports or Ractors, and returns when a port receives a message or a Ractor terminates.

We removes `Ractor.yield` and `Ractor#take` because:
* `Ractor::Port` supports most of similar use cases in a simpler manner.
* Removing them significantly simplifies the code.

We also change the internal thread scheduler code (thread_pthread.c):
* During barrier synchronization, we keep the `ractor_sched` lock to avoid deadlocks.
  This lock is released by `rb_ractor_sched_barrier_end()`
  which is called at the end of operations that require the barrier.
* fix potential deadlock issues by checking interrupts just before setting UBF.

https://bugs.ruby-lang.org/issues/21262
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix calls to require_internal in multi-ractor mode</title>
<updated>2024-12-24T02:40:00+00:00</updated>
<author>
<name>lukeg</name>
<email>luke.gru@gmail.com</email>
</author>
<published>2023-04-04T20:24:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=0d81177c2013b0a596eb4caebe0bcca557144139'/>
<id>0d81177c2013b0a596eb4caebe0bcca557144139</id>
<content type='text'>
After a ractor is started (multi-ractor mode), any calls to
require_internal will hang the process due to deadlock. For example,
loading a new encoding will deadlock after a ractor starts.

Fixes [Bug #19562]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
After a ractor is started (multi-ractor mode), any calls to
require_internal will hang the process due to deadlock. For example,
loading a new encoding will deadlock after a ractor starts.

Fixes [Bug #19562]
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove --disable-gems for assert_separately</title>
<updated>2023-08-03T00:11:08+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2023-08-02T21:02:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4b6c584023f41827c891f33a16cb5db221b7cd19'/>
<id>4b6c584023f41827c891f33a16cb5db221b7cd19</id>
<content type='text'>
assert_separately adds --disable=gems so we don't need to add
--disable-gems when calling assert_separately.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
assert_separately adds --disable=gems so we don't need to add
--disable-gems when calling assert_separately.
</pre>
</div>
</content>
</entry>
</feed>
