Skip to content

Add locks around accesses/modifications to global encodings table #13600

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

luke-gruber
Copy link
Contributor

This fixes segfaults and errors of the type "Encoding not found" when using encoding-related methods and internal encoding c functions across ractors.

@zzak
Copy link
Member

zzak commented Jun 16, 2025

Could you add a test and/or reproduction case?

Was there a ticket associated with this PR?

@jhawthorn
Copy link
Member

Could you add a test and/or reproduction case?

It tends to be difficult to make reliable reproductions to concurrency issues, and at the moment all Ractor tests need an assert_separately, which is less than desirable. It's better to make things safe based on correct design and in this case it's pretty obvious that we'll need to hold a lock to read or write to a global st_table (and the ASSERT_GLOBAL_ENC_TABLE_LOCKED added ensure this won't regress)

Was there a ticket associated with this PR?

As Ractors are experimental and there are many issues we aren't necessarily filing tickets as the fixes will not be backported.

@zzak
Copy link
Member

zzak commented Jun 16, 2025

Cool just checking, I saw this and thought neat but there was no bug associated or other context, so wasn't sure if it was ready for review or not. 🙏

@luke-gruber luke-gruber force-pushed the ractor_encoding_add_locks branch from 7792937 to 79c7b72 Compare June 17, 2025 17:32
@luke-gruber
Copy link
Contributor Author

@zzak Sorry yeah, I added a test that is fairly reproducible.

@luke-gruber luke-gruber force-pushed the ractor_encoding_add_locks branch 2 times, most recently from 42453db to 463dbb2 Compare June 17, 2025 18:06
This fixes segfaults and errors of the type "Encoding not found" when
using encoding-related methods and internal encoding c functions across
ractors.

Accessing Encoding#default_external and Encoding#default_internal are
done lock-free (atomics), and accessing one of the 3 main encodings is done
without the VM lock.

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

```ruby
rs = []
100.times do
  rs << Ractor.new do
    "abc".force_encoding(Encoding.list.shuffle.first)
  end
end
while rs.any?
  r, obj = Ractor.select(*rs)
  rs.delete(r)
end
```
@luke-gruber luke-gruber force-pushed the ractor_encoding_add_locks branch from 463dbb2 to 7311646 Compare June 17, 2025 18:17

This comment has been minimized.

@luke-gruber luke-gruber force-pushed the ractor_encoding_add_locks branch from 4c02b96 to cffea2b Compare June 17, 2025 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants