diff options
| -rw-r--r-- | api/current.xml | 13 | ||||
| -rw-r--r-- | core/java/android/database/sqlite/SQLiteDatabase.java | 31 |
2 files changed, 40 insertions, 4 deletions
diff --git a/api/current.xml b/api/current.xml index e75f2b28f13b..96e1d2d93382 100644 --- a/api/current.xml +++ b/api/current.xml @@ -47785,6 +47785,19 @@ visibility="public" > </method> +<method name="yieldIfContendedSafely" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="sleepAfterYieldDelay" type="long"> +</parameter> +</method> <field name="CREATE_IF_NECESSARY" type="int" transient="false" diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 6143b6c847fc..5d7af69d256a 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -519,7 +519,8 @@ public class SQLiteDatabase extends SQLiteClosable { */ @Deprecated public boolean yieldIfContended() { - return yieldIfContendedHelper(false /* do not check yielding */); + return yieldIfContendedHelper(false /* do not check yielding */, + -1 /* sleepAfterYieldDelay */); } /** @@ -527,14 +528,29 @@ public class SQLiteDatabase extends SQLiteClosable { * successful so far. Do not call setTransactionSuccessful before calling this. When this * returns a new transaction will have been created but not marked as successful. This assumes * that there are no nested transactions (beginTransaction has only been called once) and will - * through an exception if that is not the case. + * throw an exception if that is not the case. * @return true if the transaction was yielded */ public boolean yieldIfContendedSafely() { - return yieldIfContendedHelper(true /* check yielding */); + return yieldIfContendedHelper(true /* check yielding */, -1 /* sleepAfterYieldDelay*/); } - private boolean yieldIfContendedHelper(boolean checkFullyYielded) { + /** + * Temporarily end the transaction to let other threads run. The transaction is assumed to be + * successful so far. Do not call setTransactionSuccessful before calling this. When this + * returns a new transaction will have been created but not marked as successful. This assumes + * that there are no nested transactions (beginTransaction has only been called once) and will + * throw an exception if that is not the case. + * @param sleepAfterYieldDelay if > 0, sleep this long before starting a new transaction if + * the lock was actually yielded. This will allow other background threads to make some + * more progress than they would if we started the transaction immediately. + * @return true if the transaction was yielded + */ + public boolean yieldIfContendedSafely(long sleepAfterYieldDelay) { + return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay); + } + + private boolean yieldIfContendedHelper(boolean checkFullyYielded, long sleepAfterYieldDelay) { if (mLock.getQueueLength() == 0) { // Reset the lock acquire time since we know that the thread was willing to yield // the lock at this time. @@ -550,6 +566,13 @@ public class SQLiteDatabase extends SQLiteClosable { "Db locked more than once. yielfIfContended cannot yield"); } } + if (sleepAfterYieldDelay > 0) { + try { + Thread.sleep(sleepAfterYieldDelay); + } catch (InterruptedException e) { + Thread.interrupted(); + } + } beginTransaction(); return true; } |