Repository: dotnet/runtime
File: src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs (C#)

Code before:
            catch (Exception ex)
            {
                Debug.Write("Exception Caught. - " + ex);
                Dispose();
                throw;
            }
        }

        public override bool IsInvalid => _sslContext?.IsInvalid ?? true;

        protected override void Dispose(bool disposing)
        {
            if (disposing && !_disposed)
            {
                _disposed = true;

                lock (_lock)
                {
                    _inputBuffer.Dispose();
                    _outputBuffer.Dispose();
                    _sslContext.Dispose();
                }

                if (_gcHandle.IsAllocated)
                {
                    _gcHandle.Free();
                }
            }

            base.Dispose(disposing);
        }

        [UnmanagedCallersOnly]
        private static unsafe void WriteToConnection(IntPtr connection, byte* data, int dataLength)
        {
            GCHandle h = GCHandle.FromIntPtr(connection);
            SafeDeleteSslContext? context = h.IsAllocated ? h.Target as SafeDeleteSslContext : null;
            if (context is null || context._disposed)
            {
                Debug.Write("WriteToConnection: context is null");
                return;
            }

            try
            {
                lock (context._lock)
                {
                    var inputBuffer = new ReadOnlySpan<byte>(data, dataLength);

                    context._outputBuffer.EnsureAvailableSpace(dataLength);
                    inputBuffer.CopyTo(context._outputBuffer.AvailableSpan);

Review comment (suggestion):
Technically this could be called twice on the same handle which according to the docs will throw.
Maybe we should instead lock on the _disposed check and only perform the clean if we successfully write true to it on the given thread. Or alternatively interlocked exchange, but it's probably not worth the trouble.

Code after:
                Debug.Write("Exception Caught. - " + ex);
                Dispose();
                throw;
            }
        }

        public override bool IsInvalid => _sslContext?.IsInvalid ?? true;

        protected override void Dispose(bool disposing)
        {
            lock (_lock)
            {
                if (!_disposed)
                {
                    _disposed = true;

                    // First dispose the SSL context to trigger native cleanup
                    _sslContext.Dispose();

                    if (disposing)
                    {
                        // Then dispose the buffers
                        _inputBuffer.Dispose();
                        _outputBuffer.Dispose();
                    }
                }
            }

            base.Dispose(disposing);
        }

        [UnmanagedCallersOnly]
        private static unsafe void WriteToConnection(IntPtr connection, byte* data, int dataLength)
        {
            WeakGCHandle<SafeDeleteSslContext> h = WeakGCHandle<SafeDeleteSslContext>.FromIntPtr(connection);
            if (!h.TryGetTarget(out SafeDeleteSslContext? context))
            {
                Debug.Write("WriteToConnection: failed to get target context");
                return;
            }

            lock (context._lock)
            {
                if (context._disposed)
                {
                    Debug.Write("WriteToConnection: context is disposed");
                    return;
                }

                var inputBuffer = new ReadOnlySpan<byte>(data, dataLength);