示例#1
0
        public void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
                                              byte[] optionalPayload, WriteFlags writeFlags)
        {
            using (completionQueue.NewScope())
            {
                var ctx = completionQueue.CompletionRegistry.RegisterBatchCompletion(CompletionHandler_ISendStatusFromServerCompletionCallback, callback);
                var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero;

                const int MaxStackAllocBytes = 256;
                int       maxBytes           = MarshalUtils.GetMaxByteCountUTF8(status.Detail);
                if (maxBytes > MaxStackAllocBytes)
                {
                    // pay the extra to get the *actual* size; this could mean that
                    // it ends up fitting on the stack after all, but even if not
                    // it will mean that we ask for a *much* smaller buffer
                    maxBytes = MarshalUtils.GetByteCountUTF8(status.Detail);
                }

                unsafe
                {
                    if (maxBytes <= MaxStackAllocBytes)
                    {   // for small status, we can encode on the stack without touching arrays
                        // note: if init-locals is disabled, it would be more efficient
                        // to just stackalloc[MaxStackAllocBytes]; but by default, since we
                        // expect this to be small and it needs to wipe, just use maxBytes
                        byte *ptr         = stackalloc byte[maxBytes];
                        int   statusBytes = MarshalUtils.GetBytesUTF8(status.Detail, ptr, maxBytes);
                        Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, new IntPtr(ptr), new UIntPtr((ulong)statusBytes), metadataArray, sendEmptyInitialMetadata ? 1 : 0,
                                                                      optionalPayload, optionalPayloadLength, writeFlags).CheckOk();
                    }
                    else
                    {   // for larger status (rare), rent a buffer from the pool and
                        // use that for encoding
                        var statusBuffer = ArrayPool <byte> .Shared.Rent(maxBytes);

                        try
                        {
                            fixed(byte *ptr = statusBuffer)
                            {
                                int statusBytes = MarshalUtils.GetBytesUTF8(status.Detail, ptr, maxBytes);

                                Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, new IntPtr(ptr), new UIntPtr((ulong)statusBytes), metadataArray, sendEmptyInitialMetadata ? 1 : 0,
                                                                              optionalPayload, optionalPayloadLength, writeFlags).CheckOk();
                            }
                        }
                        finally
                        {
                            ArrayPool <byte> .Shared.Return(statusBuffer);
                        }
                    }
                }
            }
        }
示例#2
0
        // Gets data of recv_status_on_client completion.
        public ClientSideStatus GetReceivedStatusOnClient()
        {
            UIntPtr detailsLength;
            IntPtr  detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength);
            string  details    = MarshalUtils.PtrToStringUTF8(detailsPtr, (int)detailsLength.ToUInt32());
            var     status     = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details);

            IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
            var    metadata         = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);

            return(new ClientSideStatus(status, metadata));
        }
示例#3
0
 public void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
                                       byte[] optionalPayload, WriteFlags writeFlags)
 {
     using (completionQueue.NewScope())
     {
         var ctx = completionQueue.CompletionRegistry.RegisterBatchCompletion(CompletionHandler_ISendStatusFromServerCompletionCallback, callback);
         var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero;
         var statusDetailBytes     = MarshalUtils.GetBytesUTF8(status.Detail);
         Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, statusDetailBytes, new UIntPtr((ulong)statusDetailBytes.Length), metadataArray, sendEmptyInitialMetadata ? 1 : 0,
                                                       optionalPayload, optionalPayloadLength, writeFlags).CheckOk();
     }
 }