summaryrefslogtreecommitdiffstats
path: root/.templateconf
diff options
context:
space:
mode:
authorJoshua Watt <jpewhacker@gmail.com>2018-12-03 21:42:30 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-12-07 12:38:58 +0000
commit7afa726becd9a13deb95299dc8ab83a5df8501db (patch)
tree3112427608fa4cd586a5fd65be1d2adba3ab9460 /.templateconf
parent6f2ef620d90ab39870bb6c02183249e0e1045aeb (diff)
downloadpoky-7afa726becd9a13deb95299dc8ab83a5df8501db.tar.gz
bitbake: persist_data: Fix leaking cursors causing deadlock
The original implementation of persistent data executed all SQL statements via sqlite3.Connection.execute(). Behind the scenes, this function created a sqlite3 Cursor object, executed the statement, then returned the cursor. However, the implementation did not account for this and failed to close the cursor object when it was done. The cursor would eventually be closed when the garbage collector got around to destroying it. However, sqlite has a limit on the number of cursors that can exist at any given time, and once this limit is reached it will block a query to wait for a cursor to be destroyed. Under heavy database queries, this can result in Python deadlocking with itself, since the SQL query will block waiting for a free cursor, but Python can no longer run garbage collection (as it is blocked) to free one. This restructures the SQLTable class to use two decorators to aid in performing actions correctly. The first decorator (@retry) wraps a member function in the retry logic that automatically restarts the function in the event that the database is locked. The second decorator (@transaction) wraps the function so that it occurs in a database transaction, which will automatically COMMIT the changes on success and ROLLBACK on failure. This function additionally creates an explicit cursor, passes it to the wrapped function, and cleans it up when the function is finished. Note that it is still possible to leak cursors when iterating. This is much less frequent, but can still be mitigated by wrapping the iteration in a `with` statement: with db.iteritems() as it: for (k, v) in it: ... As a side effect, since most statements are wrapped in a transaction, setting the isolation_level when the connection is created is no longer necessary. [YOCTO #13030] (Bitbake rev: e8b9d3f534ef404780be23b601d5a4bb9cec928a) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to '.templateconf')
0 files changed, 0 insertions, 0 deletions