Skip to content

Commit

Permalink
Use a fiber rather than a thread to implement clean_fork
Browse files Browse the repository at this point in the history
It has several advantages, first we only need to copy fiber locals,
actual thread local variables are preserved.

Additionally any code using `Thread.current` as a hash key won't be
impacted.

And finally, native gems using APIs such a `pthread_atfork(3)` won't
be impacted either, as the native thread will remain the same in the
child.
  • Loading branch information
byroot committed Jun 12, 2023
1 parent 1f113fa commit 3ca9911
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Use a Fiber rather than a Thread to implement `clean_fork`.

# 0.3.0

- Renamed `after_promotion` in `after_mold_fork`.
Expand Down
20 changes: 8 additions & 12 deletions lib/pitchfork.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,21 +121,17 @@ def self.socketpair
end

def self.clean_fork(&block)
# We fork from a thread to start with a clean stack.
# We fork from a fiber to start with a clean stack.
# If we didn't the base stack would grow after each refork
# putting an effective limit on the number of generations.
parent_thread = Thread.current
Thread.new do
current_thread = Thread.current
# We copy over any thread state it might have
parent_thread.keys.each do |key|
current_thread[key] = parent_thread[key]
end
parent_thread.thread_variables.each do |variable|
current_thread.thread_variable_set(variable, parent_thread.thread_variable_get(variable))
end
current_thread = Thread.current
fiber_locals = current_thread.keys.zip { |k| current_thread[k] }

Fiber.new do
# We copy over any fiber local state it might have
fiber_locals.each { |k, v| current_thread[k] = v }
Process.fork(&block)
end.value
end.transfert
end

def self.fork_sibling(&block)
Expand Down

0 comments on commit 3ca9911

Please sign in to comment.