diff options
| author | jhorv <38920027+jhorv@users.noreply.github.com> | 2023-03-30 16:07:07 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-30 22:07:07 +0200 |
| commit | 8198b99935f562ffb2fb9a75175a8df24d235152 (patch) | |
| tree | 914c233f236f6645588142a266b3145cd251958f /Ryujinx.Common/SystemInterop/UnixStream.cs | |
| parent | 460f96967de6f5cb729ed57baaa4dad2178c8cb6 (diff) | |
Fix Linux hang on shutdown (#4617)
* Rework StdErr-to-log redirection to use built-in FileStream, and do reads asynchronously to avoid hanging the process shutdown.
* set _disposable to false ASAP
Diffstat (limited to 'Ryujinx.Common/SystemInterop/UnixStream.cs')
| -rw-r--r-- | Ryujinx.Common/SystemInterop/UnixStream.cs | 155 |
1 files changed, 0 insertions, 155 deletions
diff --git a/Ryujinx.Common/SystemInterop/UnixStream.cs b/Ryujinx.Common/SystemInterop/UnixStream.cs deleted file mode 100644 index 1d644997..00000000 --- a/Ryujinx.Common/SystemInterop/UnixStream.cs +++ /dev/null @@ -1,155 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - -namespace Ryujinx.Common.SystemInterop -{ - [SupportedOSPlatform("linux")] - [SupportedOSPlatform("macos")] - public partial class UnixStream : Stream, IDisposable - { - private const int InvalidFd = -1; - - private int _fd; - - [LibraryImport("libc", SetLastError = true)] - private static partial long read(int fd, IntPtr buf, ulong count); - - [LibraryImport("libc", SetLastError = true)] - private static partial long write(int fd, IntPtr buf, ulong count); - - [LibraryImport("libc", SetLastError = true)] - private static partial int close(int fd); - - public UnixStream(int fd) - { - if (InvalidFd == fd) - { - throw new ArgumentException("Invalid file descriptor"); - } - - _fd = fd; - - CanRead = read(fd, IntPtr.Zero, 0) != -1; - CanWrite = write(fd, IntPtr.Zero, 0) != -1; - } - - ~UnixStream() - { - Close(); - } - - public override bool CanRead { get; } - public override bool CanWrite { get; } - public override bool CanSeek => false; - - public override long Length => throw new NotSupportedException(); - - public override long Position - { - get => throw new NotSupportedException(); - set => throw new NotSupportedException(); - } - - public override void Flush() - { - } - - public override unsafe int Read([In, Out] byte[] buffer, int offset, int count) - { - if (offset < 0 || offset > (buffer.Length - count) || count < 0) - { - throw new ArgumentOutOfRangeException(); - } - - if (buffer.Length == 0) - { - return 0; - } - - long r = 0; - fixed (byte* buf = &buffer[offset]) - { - do - { - r = read(_fd, (IntPtr)buf, (ulong)count); - } while (ShouldRetry(r)); - } - - return (int)r; - } - - public override unsafe void Write(byte[] buffer, int offset, int count) - { - if (offset < 0 || offset > (buffer.Length - count) || count < 0) - { - throw new ArgumentOutOfRangeException(); - } - - if (buffer.Length == 0) - { - return; - } - - fixed (byte* buf = &buffer[offset]) - { - long r = 0; - do { - r = write(_fd, (IntPtr)buf, (ulong)count); - } while (ShouldRetry(r)); - } - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Close() - { - if (_fd == InvalidFd) - { - return; - } - - Flush(); - - int r; - do { - r = close(_fd); - } while (ShouldRetry(r)); - - _fd = InvalidFd; - } - - void IDisposable.Dispose() - { - Close(); - } - - private bool ShouldRetry(long r) - { - if (r == -1) - { - const int eintr = 4; - - int errno = Marshal.GetLastPInvokeError(); - - if (errno == eintr) - { - return true; - } - - throw new SystemException($"Operation failed with error 0x{errno:X}"); - } - - return false; - } - } -} |
