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

Code before:
            Debug.Assert(h.IsAllocated);

            SafeDeleteSslContext? context = (SafeDeleteSslContext?)h.Target;
            Debug.Assert(context != null);

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

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

                    context._outputBuffer.EnsureAvailableSpace(dataLength);
                    inputBuffer.CopyTo(context._outputBuffer.AvailableSpan);
                    context._outputBuffer.Commit(dataLength);
                }
            }
            catch (Exception ex)
            {
                Debug.Write("Exception Caught. - " + ex);
                throw;
            }
        }

        [UnmanagedCallersOnly]
        private static unsafe PAL_SSLStreamStatus ReadFromConnection(IntPtr connection, byte* data, int* dataLength)
        {
            GCHandle h = GCHandle.FromIntPtr(connection);
            Debug.Assert(h.IsAllocated);

            SafeDeleteSslContext? context = (SafeDeleteSslContext?)h.Target;
            Debug.Assert(context != null);

            try
            {
                lock (context._lock)
                {
                    if (context._disposed)
                    {
                        Debug.Write("ReadFromConnection: context is disposed");
                        *dataLength = 0;
                        return PAL_SSLStreamStatus.Error;
                    }

                    int toRead = *dataLength;
                    if (toRead == 0)

Review comment (bug):
Exceptions thrown from `UnmanagedCallersOnly` methods turn into unhandled exceptions (on non-Windows). This means that the app is going to crash if any exceptions are thrown by this method. Is it what we want? Should the exceptions be propagated to the user instead?

If you want to keep the behavior and crash the app if any exception is thrown here, it is better to do that without the try/catch. It is better for diagnostics. try/catch/rethrow can overwrite some of the details that may be useful for diagnosing the exceptions, and the unhandled exception handler should print the same details as the Debug.Write to the console.

Code after:
            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);

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

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

            lock (context._lock)
            {
                if (context._disposed)
                {
                    Debug.Write("ReadFromConnection: context is disposed");
                    *dataLength = 0;
                    return PAL_SSLStreamStatus.Error;
                }

                int toRead = *dataLength;
                if (toRead == 0)
                    return PAL_SSLStreamStatus.OK;

                if (context._inputBuffer.ActiveLength == 0)
                {
                    *dataLength = 0;
                    return PAL_SSLStreamStatus.NeedData;
                }