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
Fixed #30171 -- Made DatabaseWrapper thread sharing logic reentrant. #10972
Conversation
I'm very confused as to why this change would result in a segfault. I'll keep digging, but have been unable to reproduce locally so far on Fedora 29. If anyone has any ideas, I'm interested to hear them. |
Do you see any test failures on your machine? I can't reproduce the seg fault either but I have a number of test failures on my Ubuntu 18.04 machine (SQLite 3.22). |
I used an environment with an older sqlite3 version and I have been able to reproduce locally and even got a segfault once, so I have something to work with. |
I have fixed the test failures by adding the line |
Hmm isn't it a bit odd that setting it back to Also, shouldn't Also, the commit message mentions |
The newly added test, I like the suggestion of checking the count before decrementing and will make that update. Thanks!
Can you clarify what you mean. Are you suggesting something like this? @property
def allow_thread_sharing(self):
with self._thread_sharing_lock:
return self._thread_sharing_count > 0
def inc_thread_sharing(self):
with self._thread_sharing_lock:
self._thread_sharing_count += 1
def dec_thread_sharing(self):
with self._thread_sharing_lock:
if self._thread_sharing_count <= 0:
raise RuntimeError(
'The DatabaseWrapper thread sharing count was decremented below zero.'
)
self._thread_sharing_count -= 1 Or do you have something else in mind? I'm open to this but can you briefly explain what potential scenario this will solve for my benefit? |
Makes sense, thanks for the clarifications!
yeah, that's what I had in mind.
I might be missing something but I was under the impression a threading lock was required to make sure alterations of the counter were thread safe since the connection was meant to be shared between threads. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen the warning when running the Django test suite. In particular, it seems that servers
tests reliably give that warning after 8c77539. I'd be okay with backporting to 2.2 if it doesn't seem too risky.
docs/releases/3.0.txt
Outdated
@@ -223,6 +223,9 @@ backends. | |||
``can_return_ids_from_bulk_insert`` are renamed to | |||
``can_return_columns_from_insert`` and ``can_return_rows_from_bulk_insert``. | |||
|
|||
* The third argument of the ``DatabaseWrapper`` constructor, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use present tense:
* The third argument of ``DatabaseWrapper.__init__()``,
``allow_thread_sharing``, is removed.
It should be pretty safe to backport IMO. |
Is |
You are right, |
Made DatabaseWrapper thread sharing logic reentrant. Used a reference counting like scheme to allow nested uses. The error appeared after 8c77539.
Thanks. I've amended Tim's edits to change RLock to Lock. |
Changed to use a reference counting like scheme to allow nested uses. To increment the reference count, use the method
DatabaseWrapper.inc_thread_sharing()
. To decrement it, use the methodDatabaseWrapper.dec_thread_sharing()
.DatabaseWrapper.allow_thread_sharing
isTrue
if the reference count is greater than zero.This change obviates the need for passing the value of `allow_thread_sharing to the constructor, so it has been removed.
Fixed the following warning during LiveServerTestCase:
https://code.djangoproject.com/ticket/30171