Skip to content

rb_trilogy_connect: add GC guard for all string configs - #313

Merged
byroot merged 2 commits into
trilogy-libraries:mainfrom
byroot:compact-fix
Aug 5, 2026
Merged

rb_trilogy_connect: add GC guard for all string configs#313
byroot merged 2 commits into
trilogy-libraries:mainfrom
byroot:compact-fix

Conversation

@byroot

@byroot byroot commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Fix: #312

Since we're initializing connopt with pointers inside the user provided strings, we must ensure that they are pinned until we return from rb_trilogy_connect, otherwise if compaction happens concurrently, or another thread clears the opts hash, they could be guarbage collected or moved.

To achieve that, every string option has an associated local variables that is guarded to ensure it isn't optimized out by the compiler.

byroot added 2 commits August 5, 2026 07:15
Fix: trilogy-libraries#312

Since we're initializing `connopt` with pointers inside the user provided
strings, we must ensure that they are pinned until we return from
`rb_trilogy_connect`, otherwise if compaction happens concurrently,
or another thread clears the `opts` hash, they could be guarbage
collected or moved.

To achieve that, every string option has an associated local variables
that is guarded to ensure it isn't optimized out by the compiler.
Methods that take a string and release the GVL should handle
concurrent modification of the string and concurrent compaction.

For compaction the solution is to ensure they are pinned by
virtue of being present on the stack, which is normally the
case but compilers may optimize that out, so we should explictly
use `RB_GC_GUARD`.

As for concurrent modification, the intended API for that is `rb_str_locktmp`
but it's quite incovenient to use when the method may raise, so
a more ergonomic API is to acquire our own frozen copy with
`rb_str_new_frozen`. That means an extra allocation but it's an
acceptable tradeoff.

@jeremy jeremy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also noting that handle_trilogy_error is NORETURN and the guards sit after it… in principle the compiler could treat those VALUEs as dead on a branch that never reaches the guard. Kept live on the clang I checked, but leans on compiler behavior rather than a guarantee.

Comment thread contrib/ruby/ext/trilogy-ruby/cext.c
Comment thread contrib/ruby/ext/trilogy-ruby/cext.c
@byroot
byroot merged commit 63392f0 into trilogy-libraries:main Aug 5, 2026
39 checks passed
@byroot
byroot deleted the compact-fix branch August 5, 2026 06:39
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.

Connection error message formatted from a dangling char* after try_connect (GC compaction)

2 participants