66
77package kotlinx.rpc.grpc.internal
88
9- import cnames.structs.grpc_call
109import kotlinx.atomicfu.atomic
1110import kotlinx.atomicfu.locks.SynchronizedObject
1211import kotlinx.atomicfu.locks.synchronized
1312import kotlinx.cinterop.*
14- import kotlinx.coroutines.CompletableDeferred
1513import libgrpcpp_c.*
1614import platform.posix.memset
1715import kotlin.experimental.ExperimentalNativeApi
1816import kotlin.native.ref.createCleaner
1917
2018internal sealed interface BatchResult {
21- object Success : BatchResult
22- object ResultError : BatchResult
2319 object CQShutdown : BatchResult
2420 data class CallError (val error : grpc_call_error) : BatchResult
21+ data class Called (val future : CallbackFuture <Boolean >) : BatchResult
2522}
2623
2724/* *
@@ -45,7 +42,7 @@ internal class CompletionQueue {
4542 // internal as it must be accessible from the SHUTDOWN_CB,
4643 // but it shouldn't be used from outside this file.
4744 @Suppress(" PropertyName" )
48- internal val _shutdownDone = CompletableDeferred <Unit >()
45+ internal val _shutdownDone = CallbackFuture <Unit >()
4946
5047 // used for spinning lock. false means not used (available)
5148 private val batchStartGuard = SynchronizedObject ()
@@ -72,40 +69,41 @@ internal class CompletionQueue {
7269 require(kgrpc_iomgr_run_in_background()) { " The gRPC iomgr is not running background threads, required for callback based APIs." }
7370 }
7471
75- // TODO: Remove this method
76- fun runBatch (call : NativeClientCall <* , * >, ops : CPointer <grpc_op>, nOps : ULong ) =
77- runBatch(call.raw, ops, nOps)
78-
79- fun runBatch (call : CPointer <grpc_call>, ops : CPointer <grpc_op>, nOps : ULong ): CompletableDeferred <BatchResult > {
80- val completion = CompletableDeferred <BatchResult >()
72+ fun runBatch (call : NativeClientCall <* , * >, ops : CPointer <grpc_op>, nOps : ULong ): BatchResult {
73+ val completion = CallbackFuture <Boolean >()
8174 val tag = newCbTag(completion, OPS_COMPLETE_CB )
8275
8376 var err = grpc_call_error.GRPC_CALL_ERROR
77+
8478 synchronized(batchStartGuard) {
85- // synchronizes access to grpc_call_start_batch
79+ if (_state .value == State .SHUTTING_DOWN && ops.pointed.op == GRPC_OP_RECV_STATUS_ON_CLIENT ) {
80+ // if the queue is in the process of a SHUTDOWN,
81+ // new call status receive batches will be rejected.
82+ deleteCbTag(tag)
83+ return BatchResult .CQShutdown
84+ }
85+
8686 if (forceShutdown || _state .value == State .CLOSED ) {
8787 // if the queue is either closed or in the process of a FORCE shutdown,
8888 // new batches will instantly fail.
8989 deleteCbTag(tag)
90- completion.complete(BatchResult .CQShutdown )
91- return completion
90+ return BatchResult .CQShutdown
9291 }
9392
94- err = grpc_call_start_batch(call, ops, nOps, tag, null )
93+ err = grpc_call_start_batch(call.raw , ops, nOps, tag, null )
9594 }
9695
9796 if (err != grpc_call_error.GRPC_CALL_OK ) {
9897 // if the call was not successful, the callback will not be invoked.
9998 deleteCbTag(tag)
100- completion.complete(BatchResult .CallError (err))
101- return completion
99+ return BatchResult .CallError (err)
102100 }
103101
104- return completion
102+ return BatchResult . Called ( completion)
105103 }
106104
107105 // must not be canceled as it cleans resources and sets the state to CLOSED
108- fun shutdown (force : Boolean = false): CompletableDeferred <Unit > {
106+ fun shutdown (force : Boolean = false): CallbackFuture <Unit > {
109107 if (force) {
110108 forceShutdown = true
111109 }
@@ -130,10 +128,9 @@ internal class CompletionQueue {
130128@CName(" kq_ops_complete_cb" )
131129private fun opsCompleteCb (functor : CPointer <grpc_completion_queue_functor>? , ok : Int ) {
132130 val tag = functor!! .reinterpret< grpc_cb_tag> ()
133- val cont = tag.pointed.user_data!! .asStableRef<CompletableDeferred < BatchResult >>().get()
131+ val cont = tag.pointed.user_data!! .asStableRef<CallbackFuture < Boolean >>().get()
134132 deleteCbTag(tag)
135- if (ok != 0 ) cont.complete(BatchResult .Success )
136- else cont.complete(BatchResult .ResultError )
133+ cont.complete(ok != 0 )
137134}
138135
139136@CName(" kq_shutdown_cb" )
0 commit comments