Skip to content

Commit

Permalink
fix: handle the case where GC runs during fork safety checks
Browse files Browse the repository at this point in the history
If GC runs between the check for `db.weakref_alive?` and `db.close`
then an exception will be raised:

    Invalid Reference - probably recycled (WeakRef::RefError)

In this case, let's just swallow the error and keep going, since the
database object isn't in use and was GCed.
  • Loading branch information
flavorjones committed Dec 4, 2024
1 parent 47f904e commit ec11e4c
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions lib/sqlite3/fork_safety.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,21 @@ def discard # :nodoc:
@databases.each do |db|
next unless db.weakref_alive?

unless db.closed? || db.readonly?
unless warned
# If you are here, you may want to read
# https://github.com/sparklemotion/sqlite3-ruby/pull/558
warn("Writable sqlite database connection(s) were inherited from a forked process. " \
"This is unsafe and the connections are being closed to prevent possible data " \
"corruption. Please close writable sqlite database connections before forking.",
uplevel: 0)
warned = true
begin
unless db.closed? || db.readonly?
unless warned
# If you are here, you may want to read
# https://github.com/sparklemotion/sqlite3-ruby/pull/558
warn("Writable sqlite database connection(s) were inherited from a forked process. " \
"This is unsafe and the connections are being closed to prevent possible data " \
"corruption. Please close writable sqlite database connections before forking.",
uplevel: 0)
warned = true
end
db.close
end
db.close
rescue WeakRef::RefError
# GC may run while this method is executing, and that's OK
end
end
@databases.clear
Expand Down

0 comments on commit ec11e4c

Please sign in to comment.