Skip to content

Commit ec11e4c

Browse files
committed
fix: handle the case where GC runs during fork safety checks
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.
1 parent 47f904e commit ec11e4c

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

lib/sqlite3/fork_safety.rb

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,21 @@ def discard # :nodoc:
3535
@databases.each do |db|
3636
next unless db.weakref_alive?
3737

38-
unless db.closed? || db.readonly?
39-
unless warned
40-
# If you are here, you may want to read
41-
# https://github.com/sparklemotion/sqlite3-ruby/pull/558
42-
warn("Writable sqlite database connection(s) were inherited from a forked process. " \
43-
"This is unsafe and the connections are being closed to prevent possible data " \
44-
"corruption. Please close writable sqlite database connections before forking.",
45-
uplevel: 0)
46-
warned = true
38+
begin
39+
unless db.closed? || db.readonly?
40+
unless warned
41+
# If you are here, you may want to read
42+
# https://github.com/sparklemotion/sqlite3-ruby/pull/558
43+
warn("Writable sqlite database connection(s) were inherited from a forked process. " \
44+
"This is unsafe and the connections are being closed to prevent possible data " \
45+
"corruption. Please close writable sqlite database connections before forking.",
46+
uplevel: 0)
47+
warned = true
48+
end
49+
db.close
4750
end
48-
db.close
51+
rescue WeakRef::RefError
52+
# GC may run while this method is executing, and that's OK
4953
end
5054
end
5155
@databases.clear

0 commit comments

Comments
 (0)