summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kweku Adams <kwekua@google.com> 2020-07-13 15:52:00 -0700
committer Kweku Adams <kwekua@google.com> 2020-07-13 15:52:00 -0700
commitc3a32b861d6c0f57ad6505db337a33e76d71263f (patch)
treeac17b03e55200877331692633eb338933a111498
parent79d4a4c181d5c4c8cfca51e83903b96ca1f30829 (diff)
Avoid overlapping jobstore disk writes.
Given that a followup write could be scheduled while one is already going on, if the first one took too long, then the send write could start and overlap with the first write. This change prevents that and makes sure there's only one write happening at a time. Bug: N/A Test: atest CtsJobSchedulerTestCases Test: atest FrameworksServicesTests:JobStoreTest Change-Id: Ie77510508795e5395a24a40266178283d0c525cb
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobStore.java12
1 files changed, 9 insertions, 3 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
index f2a55805d70a..7bd51b77a119 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
@@ -335,7 +335,7 @@ public final class JobStore {
Slog.v(TAG, "Scheduling persist of jobs to disk.");
}
mIoHandler.postDelayed(mWriteRunnable, JOB_PERSIST_DELAY);
- mWriteScheduled = mWriteInProgress = true;
+ mWriteScheduled = true;
}
}
}
@@ -353,7 +353,7 @@ public final class JobStore {
throw new IllegalStateException("An asynchronous write is already scheduled.");
}
- mWriteScheduled = mWriteInProgress = true;
+ mWriteScheduled = true;
mWriteRunnable.run();
}
}
@@ -369,7 +369,7 @@ public final class JobStore {
final long start = SystemClock.uptimeMillis();
final long end = start + maxWaitMillis;
synchronized (mWriteScheduleLock) {
- while (mWriteInProgress) {
+ while (mWriteScheduled || mWriteInProgress) {
final long now = SystemClock.uptimeMillis();
if (now >= end) {
// still not done and we've hit the end; failure
@@ -404,6 +404,12 @@ public final class JobStore {
// a bit of lock contention.
synchronized (mWriteScheduleLock) {
mWriteScheduled = false;
+ if (mWriteInProgress) {
+ // Another runnable is currently writing. Postpone this new write task.
+ maybeWriteStatusToDiskAsync();
+ return;
+ }
+ mWriteInProgress = true;
}
synchronized (mLock) {
// Clone the jobs so we can release the lock before writing.