Skip to content

Commit 28f22d7

Browse files
committed
dispose more StableRef
1 parent 4987757 commit 28f22d7

File tree

9 files changed

+51
-32
lines changed

9 files changed

+51
-32
lines changed

aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/auth/signing/AwsSignerNative.kt

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import kotlinx.coroutines.channels.Channel
1919
import kotlinx.coroutines.runBlocking
2020
import libcrt.*
2121
import platform.posix.UINT64_MAX
22+
import aws.sdk.kotlin.crt.util.use
2223

2324
/**
2425
* Static class for a variety of AWS signing APIs.
@@ -36,7 +37,6 @@ public actual object AwsSigner {
3637
request.toNativeRequest().usePinned { nativeRequest ->
3738
// Pair of HTTP request and callback channel containing the signature
3839
val userData = nativeRequest to Channel<ByteArray>(1)
39-
val userDataStableRef = StableRef.create(userData)
4040

4141
val signable = checkNotNull(
4242
aws_signable_new_http_request(
@@ -47,20 +47,20 @@ public actual object AwsSigner {
4747

4848
val nativeSigningConfig: CPointer<aws_signing_config_base> = config.toNativeSigningConfig().reinterpret()
4949

50-
awsAssertOpSuccess(
51-
aws_sign_request_aws(
52-
allocator = Allocator.Default.allocator,
53-
signable = signable,
54-
base_config = nativeSigningConfig,
55-
on_complete = staticCFunction(::signCallback),
56-
userdata = userDataStableRef.asCPointer(),
57-
),
58-
) { "sign() aws_sign_request_aws" }
50+
StableRef.create(userData).use { userDataStableRef ->
51+
awsAssertOpSuccess(
52+
aws_sign_request_aws(
53+
allocator = Allocator.Default.allocator,
54+
signable = signable,
55+
base_config = nativeSigningConfig,
56+
on_complete = staticCFunction(::signCallback),
57+
userdata = userDataStableRef.asCPointer(),
58+
),
59+
) { "sign() aws_sign_request_aws" }
5960

60-
val callbackChannel = userDataStableRef.get().second
61-
val signature = callbackChannel.receive() // wait for async signing to complete....
62-
return AwsSigningResult(nativeRequest.get().toHttpRequest(), signature).also {
63-
userDataStableRef.dispose()
61+
val callbackChannel = userDataStableRef.get().second
62+
val signature = callbackChannel.receive() // wait for async signing to complete....
63+
return AwsSigningResult(nativeRequest.get().toHttpRequest(), signature)
6464
}
6565
}
6666
}
@@ -126,7 +126,7 @@ public actual object AwsSigner {
126126

127127
private fun signChunkSignable(signable: CPointer<aws_signable>, config: AwsSigningConfig): AwsSigningResult = memScoped {
128128
val callbackChannel = Channel<ByteArray>(1)
129-
val callbackChannelStableRef = StableRef.create(callbackChannel)
129+
val callbackChannelStableRef = StableRef.create(callbackChannel) // Done
130130

131131
val nativeConfig: CPointer<aws_signing_config_base> = config.toNativeSigningConfig().reinterpret()
132132

@@ -196,7 +196,7 @@ private fun AwsSigningConfig.toNativeSigningConfig(): CPointer<aws_signing_confi
196196
aws_date_time_init_epoch_millis(date.ptr, this@toNativeSigningConfig.date.toULong())
197197

198198
this@toNativeSigningConfig.shouldSignHeader?.let {
199-
val shouldSignHeaderStableRef = StableRef.create(it)
199+
val shouldSignHeaderStableRef = StableRef.create(it) // FIXME Dispose this StableRef somehow...
200200
should_sign_header = staticCFunction(::nativeShouldSignHeaderFn)
201201
should_sign_header_ud = shouldSignHeaderStableRef.asCPointer()
202202
}

aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/http/HttpClientConnectionManagerNative.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,9 @@ public actual class HttpClientConnectionManager actual constructor(
132132
public actual suspend fun acquireConnection(): HttpClientConnection =
133133
suspendCoroutine { cont ->
134134
val cb = staticCFunction(::onConnectionAcquired)
135-
val userdata = StableRef.create(HttpConnectionAcquisitionRequest(cont, this))
136-
aws_http_connection_manager_acquire_connection(manager, cb, userdata.asCPointer())
135+
StableRef.create(HttpConnectionAcquisitionRequest(cont, this)).use { userdata ->
136+
aws_http_connection_manager_acquire_connection(manager, cb, userdata.asCPointer())
137+
}
137138
}
138139

139140
/**
@@ -153,6 +154,7 @@ public actual class HttpClientConnectionManager actual constructor(
153154

154155
actual override fun close() {
155156
aws_http_connection_manager_release(manager)
157+
shutdownCompleteStableRef.dispose()
156158
}
157159
}
158160

aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/http/HttpClientConnectionNative.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal class HttpClientConnectionNative(
2929
override fun makeRequest(httpReq: HttpRequest, handler: HttpStreamResponseHandler): HttpStream {
3030
val nativeReq = httpReq.toNativeRequest()
3131
val cbData = HttpStreamContext(handler, nativeReq)
32-
val stableRef = StableRef.create(cbData)
32+
val stableRef = StableRef.create(cbData) // FIXME Close this StableRef somehow...
3333
val reqOptions = cValue<aws_http_make_request_options> {
3434
self_size = sizeOf<aws_http_make_request_options>().convert()
3535
request = nativeReq

aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/http/HttpStreamNative.kt

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import aws.sdk.kotlin.crt.CrtRuntimeException
99
import aws.sdk.kotlin.crt.NativeHandle
1010
import aws.sdk.kotlin.crt.awsAssertOpSuccess
1111
import aws.sdk.kotlin.crt.util.asAwsByteCursor
12+
import aws.sdk.kotlin.crt.util.use
1213
import kotlinx.cinterop.*
1314
import libcrt.*
1415
import kotlin.coroutines.Continuation
@@ -63,18 +64,19 @@ internal class HttpStreamNative(
6364
throw CrtRuntimeException("aws_input_stream_new_from_cursor()")
6465
}
6566

66-
val req = StableRef.create(WriteChunkRequest(cont, byteBuf, stream))
67-
val chunkOpts = cValue<aws_http1_chunk_options> {
68-
chunk_data_size = chunkData.size.convert()
69-
chunk_data = stream
70-
on_complete = staticCFunction(::onWriteChunkComplete)
71-
user_data = req.asCPointer()
72-
}
73-
awsAssertOpSuccess(
74-
aws_http1_stream_write_chunk(ptr, chunkOpts),
75-
) {
76-
cleanupWriteChunkCbData(req)
77-
"aws_http1_stream_write_chunk()"
67+
StableRef.create(WriteChunkRequest(cont, byteBuf, stream)).use { req ->
68+
val chunkOpts = cValue<aws_http1_chunk_options> {
69+
chunk_data_size = chunkData.size.convert()
70+
chunk_data = stream
71+
on_complete = staticCFunction(::onWriteChunkComplete)
72+
user_data = req.asCPointer()
73+
}
74+
awsAssertOpSuccess(
75+
aws_http1_stream_write_chunk(ptr, chunkOpts),
76+
) {
77+
cleanupWriteChunkCbData(req)
78+
"aws_http1_stream_write_chunk()"
79+
}
7880
}
7981
}
8082

aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/http/RequestBodyStream.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ internal fun inputStream(khandler: HttpRequestBodyStream): CPointer<aws_input_st
112112
val stream: aws_input_stream = Allocator.Default.alloc()
113113
stream.vtable = requestStreamVtable
114114
val impl = RequestBodyStream(khandler)
115-
val stableRef = StableRef.create(impl)
115+
val stableRef = StableRef.create(impl) // FIXME Dispose this StableRef somehow...
116116
stream.impl = stableRef.asCPointer()
117117
return stream.ptr
118118
}

aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/io/ClientBootstrapNative.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public actual class ClientBootstrap private constructor(
5454

5555
actual override fun close() {
5656
aws_client_bootstrap_release(ptr)
57+
channelStableRef.dispose()
5758

5859
if (manageHr) hr.close()
5960
if (manageElg) elg.close()

aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/io/EventLoopGroupNative.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public actual class EventLoopGroup actual constructor(maxThreads: Int) :
6060

6161
actual override fun close() {
6262
aws_event_loop_group_release(ptr)
63+
channelStableRef.dispose()
6364
}
6465
}
6566

aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/io/HostResolverNative.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public actual class HostResolver private constructor(
5757

5858
actual override fun close() {
5959
aws_host_resolver_release(ptr)
60+
channelStableRef.dispose()
6061

6162
if (manageElg) elg.close()
6263
}

aws-crt-kotlin/native/src/aws/sdk/kotlin/crt/util/Interop.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package aws.sdk.kotlin.crt.util
66

77
import kotlinx.coroutines.channels.Channel
8+
import kotlinx.cinterop.StableRef
89

910
/**
1011
* Channel used to signal async shutdown from C callback to a suspend fn
@@ -15,3 +16,14 @@ internal typealias ShutdownChannel = Channel<Unit>
1516
* Create a new shutdown notification channel
1617
*/
1718
internal fun shutdownChannel(): ShutdownChannel = Channel(Channel.RENDEZVOUS)
19+
20+
/**
21+
* Execute [block] using [StableRef], then dispose it.
22+
*/
23+
internal inline fun <T : Any, R> StableRef<T>.use(block: (StableRef<T>) -> R): R {
24+
try {
25+
return block(this)
26+
} finally {
27+
dispose()
28+
}
29+
}

0 commit comments

Comments
 (0)