1
0
mirror of https://github.com/square/okhttp.git synced 2025-08-07 12:42:57 +03:00

Start fewer threads in TaskRunner (#8391)

We've got a race where we'll start a thread when we need
one, even if we've already started a thread. This changes
TaskRunner's behavior to never add a thread if we're
still waiting for a recently-added one to start running.

This is intended to reduce the number of threads contenting
for the TaskRunner lock as reported in this issue:

https://github.com/square/okhttp/issues/8388
This commit is contained in:
Jesse Wilson
2024-04-28 20:33:04 -04:00
committed by GitHub
parent aede7c57f3
commit d0b6a464d8
3 changed files with 129 additions and 10 deletions

View File

@@ -63,29 +63,32 @@ class TaskFaker : Closeable {
/**
* True if this task faker has ever had multiple tasks scheduled to run concurrently. Guarded by
* [taskRunner].
* [TaskRunner.lock].
*/
var isParallel = false
/** Number of calls to [TaskRunner.Backend.execute]. Guarded by [TaskRunner.lock]. */
var executeCallCount = 0
/** Guarded by [taskRunner]. */
var nanoTime = 0L
private set
/** Backlog of tasks to run. Only one task runs at a time. Guarded by [taskRunner]. */
/** Backlog of tasks to run. Only one task runs at a time. Guarded by [TaskRunner.lock]. */
private val serialTaskQueue = ArrayDeque<SerialTask>()
/** The task that's currently executing. Guarded by [taskRunner]. */
/** The task that's currently executing. Guarded by [TaskRunner.lock]. */
private var currentTask: SerialTask = TestThreadSerialTask
/** The coordinator task if it's waiting, and how it will resume. Guarded by [taskRunner]. */
/** The coordinator task if it's waiting, and how it will resume. Guarded by [TaskRunner.lock]. */
private var waitingCoordinatorTask: SerialTask? = null
private var waitingCoordinatorInterrupted = false
private var waitingCoordinatorNotified = false
/** How many times a new task has been started. Guarded by [taskRunner]. */
/** How many times a new task has been started. Guarded by [TaskRunner.lock]. */
private var contextSwitchCount = 0
/** Guarded by [taskRunner]. */
/** Guarded by [TaskRunner.lock]. */
private var activeThreads = 0
/** A task runner that posts tasks to this fake. Tasks won't be executed until requested. */
@@ -100,6 +103,7 @@ class TaskFaker : Closeable {
val queuedTask = RunnableSerialTask(runnable)
serialTaskQueue += queuedTask
executeCallCount++
isParallel = serialTaskQueue.size > 1
}