Skip to content

Commit 28308e7

Browse files
authored
KTOR-5332 Fixes iOS unit test deadlock occurring with DarwinClientEngine (#3291)
1 parent cfa15db commit 28308e7

6 files changed

Lines changed: 28 additions & 22 deletions

File tree

ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/DarwinLegacyClientEngine.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import platform.Foundation.*
1616
internal class DarwinLegacyClientEngine(
1717
override val config: DarwinLegacyClientEngineConfig
1818
) : HttpClientEngineBase("ktor-darwin-legacy") {
19-
private val requestQueue = NSOperationQueue()
19+
private val requestQueue: NSOperationQueue? = NSOperationQueue.currentQueue()
2020

2121
override val dispatcher = Dispatchers.Unconfined
2222

ktor-client/ktor-client-darwin-legacy/darwin/src/io/ktor/client/engine/darwin/internal/DarwinLegacySession.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import kotlin.coroutines.*
1313
@OptIn(UnsafeNumber::class)
1414
internal class DarwinLegacySession(
1515
private val config: DarwinLegacyClientEngineConfig,
16-
private val requestQueue: NSOperationQueue
16+
private val requestQueue: NSOperationQueue?
1717
) : Closeable {
1818
private val closed = atomic(false)
1919

@@ -47,7 +47,7 @@ internal class DarwinLegacySession(
4747
@OptIn(UnsafeNumber::class)
4848
internal fun createSession(
4949
config: DarwinLegacyClientEngineConfig,
50-
requestQueue: NSOperationQueue
50+
requestQueue: NSOperationQueue?
5151
): Pair<NSURLSession, KtorLegacyNSURLSessionDelegate> {
5252
val configuration = NSURLSessionConfiguration.defaultSessionConfiguration().apply {
5353
setupProxy(config)

ktor-client/ktor-client-darwin-legacy/darwin/test/DarwinLegacyEngineTest.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import io.ktor.http.*
88
import kotlinx.coroutines.*
99
import platform.Foundation.*
1010
import platform.Foundation.NSHTTPCookieStorage.Companion.sharedHTTPCookieStorage
11+
import kotlin.coroutines.CoroutineContext
1112
import kotlin.test.*
1213

1314
/*
@@ -16,8 +17,10 @@ import kotlin.test.*
1617

1718
class DarwinLegacyEngineTest {
1819

20+
val testCoroutineContext: CoroutineContext = Dispatchers.Default
21+
1922
@Test
20-
fun testRequestInRunBlocking() = runBlocking {
23+
fun testRequestInRunBlocking() = runBlocking(testCoroutineContext) {
2124
val client = HttpClient(DarwinLegacy)
2225

2326
try {
@@ -31,7 +34,7 @@ class DarwinLegacyEngineTest {
3134
}
3235

3336
@Test
34-
fun testQueryWithCyrillic() = runBlocking {
37+
fun testQueryWithCyrillic() = runBlocking(testCoroutineContext) {
3538
val client = HttpClient(DarwinLegacy)
3639

3740
try {
@@ -45,7 +48,7 @@ class DarwinLegacyEngineTest {
4548
}
4649

4750
@Test
48-
fun testQueryWithMultipleParams() = runBlocking {
51+
fun testQueryWithMultipleParams() = runBlocking(testCoroutineContext) {
4952
val client = HttpClient(DarwinLegacy)
5053

5154
try {
@@ -72,7 +75,7 @@ class DarwinLegacyEngineTest {
7275
}
7376

7477
@Test
75-
fun testCookieIsNotPersistedByDefault() = runBlocking {
78+
fun testCookieIsNotPersistedByDefault() = runBlocking(testCoroutineContext) {
7679
val client = HttpClient(DarwinLegacy)
7780
try {
7881
client.get("$TEST_SERVER/cookies")
@@ -86,7 +89,7 @@ class DarwinLegacyEngineTest {
8689
}
8790

8891
@Test
89-
fun testCookiePersistedWithSessionStore() = runBlocking {
92+
fun testCookiePersistedWithSessionStore() = runBlocking(testCoroutineContext) {
9093
val client = HttpClient(DarwinLegacy) {
9194
engine {
9295
configureSession {
@@ -107,7 +110,7 @@ class DarwinLegacyEngineTest {
107110
}
108111

109112
@Test
110-
fun testOverrideDefaultSession(): Unit = runBlocking {
113+
fun testOverrideDefaultSession(): Unit = runBlocking(testCoroutineContext) {
111114
val client = HttpClient(DarwinLegacy) {
112115
val delegate = KtorLegacyNSURLSessionDelegate()
113116
val session = NSURLSession.sessionWithConfiguration(
@@ -129,7 +132,7 @@ class DarwinLegacyEngineTest {
129132
}
130133

131134
@Test
132-
fun testConfigureRequest(): Unit = runBlocking {
135+
fun testConfigureRequest(): Unit = runBlocking(testCoroutineContext) {
133136
val client = HttpClient(DarwinLegacy) {
134137
engine {
135138
configureRequest {

ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/DarwinClientEngine.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import kotlin.coroutines.*
1818

1919
@OptIn(InternalAPI::class)
2020
internal class DarwinClientEngine(override val config: DarwinClientEngineConfig) : HttpClientEngineBase("ktor-darwin") {
21-
private val requestQueue = NSOperationQueue()
21+
private val requestQueue: NSOperationQueue? = NSOperationQueue.currentQueue()
2222

2323
override val dispatcher = Dispatchers.Unconfined
2424

ktor-client/ktor-client-darwin/darwin/src/io/ktor/client/engine/darwin/internal/DarwinSession.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import kotlin.coroutines.*
1313
@OptIn(UnsafeNumber::class)
1414
internal class DarwinSession(
1515
private val config: DarwinClientEngineConfig,
16-
requestQueue: NSOperationQueue
16+
requestQueue: NSOperationQueue?
1717
) : Closeable {
1818
private val closed = atomic(false)
1919

@@ -54,7 +54,7 @@ internal class DarwinSession(
5454
@OptIn(UnsafeNumber::class)
5555
internal fun createSession(
5656
config: DarwinClientEngineConfig,
57-
requestQueue: NSOperationQueue
57+
requestQueue: NSOperationQueue?
5858
): Pair<NSURLSession, KtorNSURLSessionDelegate> {
5959
val configuration = NSURLSessionConfiguration.defaultSessionConfiguration().apply {
6060
setupProxy(config)

ktor-client/ktor-client-darwin/darwin/test/DarwinEngineTest.kt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import kotlinx.cinterop.*
1111
import kotlinx.coroutines.*
1212
import platform.Foundation.*
1313
import platform.Foundation.NSHTTPCookieStorage.Companion.sharedHTTPCookieStorage
14+
import kotlin.coroutines.CoroutineContext
1415
import kotlin.test.*
1516

1617
/*
@@ -19,8 +20,10 @@ import kotlin.test.*
1920

2021
class DarwinEngineTest {
2122

23+
val testCoroutineContext: CoroutineContext = Dispatchers.Default
24+
2225
@Test
23-
fun testRequestInRunBlocking() = runBlocking {
26+
fun testRequestInRunBlocking() = runBlocking(testCoroutineContext) {
2427
val client = HttpClient(Darwin)
2528

2629
try {
@@ -34,7 +37,7 @@ class DarwinEngineTest {
3437
}
3538

3639
@Test
37-
fun testQueryWithCyrillic() = runBlocking {
40+
fun testQueryWithCyrillic() = runBlocking(testCoroutineContext) {
3841
val client = HttpClient(Darwin)
3942

4043
try {
@@ -48,7 +51,7 @@ class DarwinEngineTest {
4851
}
4952

5053
@Test
51-
fun testQueryWithMultipleParams() = runBlocking {
54+
fun testQueryWithMultipleParams() = runBlocking(testCoroutineContext) {
5255
val client = HttpClient(Darwin)
5356

5457
try {
@@ -75,7 +78,7 @@ class DarwinEngineTest {
7578
}
7679

7780
@Test
78-
fun testCookieIsNotPersistedByDefault() = runBlocking {
81+
fun testCookieIsNotPersistedByDefault() = runBlocking(testCoroutineContext) {
7982
val client = HttpClient(Darwin)
8083
try {
8184
client.get("$TEST_SERVER/cookies")
@@ -89,7 +92,7 @@ class DarwinEngineTest {
8992
}
9093

9194
@Test
92-
fun testCookiePersistedWithSessionStore() = runBlocking {
95+
fun testCookiePersistedWithSessionStore() = runBlocking(testCoroutineContext) {
9396
val client = HttpClient(Darwin) {
9497
engine {
9598
configureSession {
@@ -110,7 +113,7 @@ class DarwinEngineTest {
110113
}
111114

112115
@Test
113-
fun testOverrideDefaultSession(): Unit = runBlocking {
116+
fun testOverrideDefaultSession(): Unit = runBlocking(testCoroutineContext) {
114117
val client = HttpClient(Darwin) {
115118
val delegate = KtorNSURLSessionDelegate()
116119
val session = NSURLSession.sessionWithConfiguration(
@@ -132,7 +135,7 @@ class DarwinEngineTest {
132135
}
133136

134137
@Test
135-
fun testOverrideDefaultSessionWithWebSockets(): Unit = runBlocking {
138+
fun testOverrideDefaultSessionWithWebSockets(): Unit = runBlocking(testCoroutineContext) {
136139
val client = HttpClient(Darwin) {
137140
val delegate = KtorNSURLSessionDelegate()
138141
val session = NSURLSession.sessionWithConfiguration(
@@ -158,7 +161,7 @@ class DarwinEngineTest {
158161
}
159162

160163
@Test
161-
fun testConfigureRequest(): Unit = runBlocking {
164+
fun testConfigureRequest(): Unit = runBlocking(testCoroutineContext) {
162165
val client = HttpClient(Darwin) {
163166
engine {
164167
configureRequest {
@@ -174,7 +177,7 @@ class DarwinEngineTest {
174177

175178
@OptIn(UnsafeNumber::class)
176179
@Test
177-
fun testConfigureWebsocketRequest(): Unit = runBlocking {
180+
fun testConfigureWebsocketRequest(): Unit = runBlocking(testCoroutineContext) {
178181
var customChallengeCalled = false
179182
val client = HttpClient(Darwin) {
180183
engine {

0 commit comments

Comments
 (0)