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

Code before:

        private readonly object _lock = new object();

        private ArrayBuffer _inputBuffer = new ArrayBuffer(InitialBufferSize);
        private ArrayBuffer _outputBuffer = new ArrayBuffer(InitialBufferSize);

        public SslStream.JavaProxy SslStreamProxy { get; }

        public SafeSslHandle SslContext => _sslContext;

        private volatile bool _disposed;

        public SafeDeleteSslContext(SslAuthenticationOptions authOptions)
            : base(IntPtr.Zero)
        {
            SslStreamProxy = authOptions.SslStreamProxy
                ?? throw new ArgumentNullException(nameof(authOptions.SslStreamProxy));

            try
            {
                _sslContext = CreateSslContext(SslStreamProxy, authOptions);

                // Create GC handle and store it in dictionary
                GCHandle gcHandle = GCHandle.Alloc(this);
                _nativeHandle = GCHandle.ToIntPtr(gcHandle);
                s_contextMap[_nativeHandle] = gcHandle;

                InitializeSslContext(_sslContext, authOptions);
            }
            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)
            {
                lock (_lock)
                {
                    if (!_disposed)
                    {
                        _disposed = true;
                        _inputBuffer.Dispose();
                        _outputBuffer.Dispose();
                        _sslContext.Dispose();

Review comment (suggestion):
This maps the GCHandle to itself. I do not see what it is trying to solve.

Code after:

        private ArrayBuffer _inputBuffer = new ArrayBuffer(InitialBufferSize);
        private ArrayBuffer _outputBuffer = new ArrayBuffer(InitialBufferSize);

        public SslStream.JavaProxy SslStreamProxy { get; }

        public SafeSslHandle SslContext => _sslContext;

        private volatile bool _disposed;

        public SafeDeleteSslContext(SslAuthenticationOptions authOptions)
            : base(IntPtr.Zero)
        {
            SslStreamProxy = authOptions.SslStreamProxy
                ?? throw new ArgumentNullException(nameof(authOptions.SslStreamProxy));

            try
            {
                _sslContext = CreateSslContext(SslStreamProxy, authOptions);
                InitializeSslContext(_sslContext, authOptions);
            }
            catch (Exception ex)
            {
                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();
                    }
                }
            }