Bug 887889 - Fix temporary leak in Sqlite.jsm transactions r?mak draft
authorDoug Thayer <dothayer@mozilla.com>
Mon, 12 Mar 2018 14:47:51 -0700
changeset 766454 9b9480c0a006c6afccb783d3543009a65f3427e6
parent 766453 59527b372c70538d45215ec83f7da1988977bfc5
push id102329
push userbmo:dothayer@mozilla.com
push dateMon, 12 Mar 2018 21:53:24 +0000
reviewersmak
bugs887889
milestone60.0a1
Bug 887889 - Fix temporary leak in Sqlite.jsm transactions r?mak I was getting shutdown leaks when I started wrapping statements in transactions. After a bit of debugging I found that we were holding onto things due to the setTimeout race. Just clearing it resolved the issue for me. MozReview-Commit-ID: 8kyf7E6VYJr
toolkit/modules/Sqlite.jsm
--- a/toolkit/modules/Sqlite.jsm
+++ b/toolkit/modules/Sqlite.jsm
@@ -622,26 +622,29 @@ ConnectionData.prototype = Object.freeze
               this._log.warn("Error committing transaction", ex);
               throw ex;
             }
           }
 
           return result;
         } finally {
           this._hasInProgressTransaction = false;
+          // Ensure we don't hold onto anything for too long by keeping the timeout alive
+          clearTimeout(timeoutHandle);
         }
       })();
 
       // If a transaction yields on a never resolved promise, or is mistakenly
       // nested, it could hang the transactions queue forever.  Thus we timeout
       // the execution after a meaningful amount of time, to ensure in any case
       // we'll proceed after a while.
+      let timeoutHandle;
       let timeoutPromise = new Promise((resolve, reject) => {
-        setTimeout(() => reject(new Error("Transaction timeout, most likely caused by unresolved pending work.")),
-                   TRANSACTIONS_QUEUE_TIMEOUT_MS);
+        timeoutHandle = setTimeout(() => reject(new Error("Transaction timeout, most likely caused by unresolved pending work.")),
+                                   TRANSACTIONS_QUEUE_TIMEOUT_MS);
       });
       return Promise.race([transactionPromise, timeoutPromise]);
     });
     // Atomically update the queue before anyone else has a chance to enqueue
     // further transactions.
     this._transactionQueue = promise.catch(ex => { console.error(ex); });
 
     // Make sure that we do not shutdown the connection during a transaction.