Compare commits

..

5 Commits

Author SHA1 Message Date
jhorv
8198b99935 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
2023-03-30 22:07:07 +02:00
ACGNnsj
460f96967d Slight Code Refactoring (#4373)
* Simplify return statements by using ternary expressions

* Remove a redundant type conversion

* Reduce nesting by inverting "if" statements

* Try to improve code readability by using LINQ and inverting "if" statements

* Try to improve code readability by using LINQ, using ternary expressions, and inverting "if" statements

* Add line breaks to long LINQ

* Add line breaks to long LINQ
2023-03-28 14:59:43 +02:00
Mary
7ca779a26d audout: Fix a possible crash with SDL2 when the SDL2 audio backend is dummy (#4605)
This change makes audio device error not fatal.
In case of error, the SDL2 audio backend will behave like the dummy
backend.
2023-03-27 20:56:36 +02:00
Mary
b5032b3c91 vulkan: Fix access level of extensions fields and make them readonly (#4608) 2023-03-27 08:40:27 +02:00
Mary
f0a3dff136 vulkan: Remove CreateCommandBufferPool from VulkanInitialization (#4606)
It was only called in one place, that can be simplified.
2023-03-27 02:16:31 +00:00
11 changed files with 124 additions and 299 deletions

View File

@@ -18,6 +18,7 @@ namespace Ryujinx.Audio.Backends.SDL2
private ulong _playedSampleCount; private ulong _playedSampleCount;
private ManualResetEvent _updateRequiredEvent; private ManualResetEvent _updateRequiredEvent;
private uint _outputStream; private uint _outputStream;
private bool _hasSetupError;
private SDL_AudioCallback _callbackDelegate; private SDL_AudioCallback _callbackDelegate;
private int _bytesPerFrame; private int _bytesPerFrame;
private uint _sampleCount; private uint _sampleCount;
@@ -42,7 +43,7 @@ namespace Ryujinx.Audio.Backends.SDL2
private void EnsureAudioStreamSetup(AudioBuffer buffer) private void EnsureAudioStreamSetup(AudioBuffer buffer)
{ {
uint bufferSampleCount = (uint)GetSampleCount(buffer); uint bufferSampleCount = (uint)GetSampleCount(buffer);
bool needAudioSetup = _outputStream == 0 || bool needAudioSetup = (_outputStream == 0 && !_hasSetupError) ||
(bufferSampleCount >= Constants.TargetSampleCount && bufferSampleCount < _sampleCount); (bufferSampleCount >= Constants.TargetSampleCount && bufferSampleCount < _sampleCount);
if (needAudioSetup) if (needAudioSetup)
@@ -51,12 +52,9 @@ namespace Ryujinx.Audio.Backends.SDL2
uint newOutputStream = SDL2HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate); uint newOutputStream = SDL2HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate);
if (newOutputStream == 0) _hasSetupError = newOutputStream == 0;
{
// No stream in place, this is unexpected. if (!_hasSetupError)
throw new InvalidOperationException($"OpenStream failed with error: \"{SDL_GetError()}\"");
}
else
{ {
if (_outputStream != 0) if (_outputStream != 0)
{ {
@@ -151,12 +149,21 @@ namespace Ryujinx.Audio.Backends.SDL2
{ {
EnsureAudioStreamSetup(buffer); EnsureAudioStreamSetup(buffer);
if (_outputStream != 0)
{
SDL2AudioBuffer driverBuffer = new SDL2AudioBuffer(buffer.DataPointer, GetSampleCount(buffer)); SDL2AudioBuffer driverBuffer = new SDL2AudioBuffer(buffer.DataPointer, GetSampleCount(buffer));
_ringBuffer.Write(buffer.Data, 0, buffer.Data.Length); _ringBuffer.Write(buffer.Data, 0, buffer.Data.Length);
_queuedBuffers.Enqueue(driverBuffer); _queuedBuffers.Enqueue(driverBuffer);
} }
else
{
Interlocked.Add(ref _playedSampleCount, GetSampleCount(buffer));
_updateRequiredEvent.Set();
}
}
public override void SetVolume(float volume) public override void SetVolume(float volume)
{ {

View File

@@ -1,18 +1,21 @@
using Microsoft.Win32.SafeHandles;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Common.SystemInterop namespace Ryujinx.Common.SystemInterop
{ {
public partial class StdErrAdapter : IDisposable public partial class StdErrAdapter : IDisposable
{ {
private bool _disposable = false; private bool _disposable = false;
private UnixStream _pipeReader; private Stream _pipeReader;
private UnixStream _pipeWriter; private Stream _pipeWriter;
private Thread _worker; private CancellationTokenSource _cancellationTokenSource;
private Task _worker;
public StdErrAdapter() public StdErrAdapter()
{ {
@@ -31,21 +34,21 @@ namespace Ryujinx.Common.SystemInterop
(int readFd, int writeFd) = MakePipe(); (int readFd, int writeFd) = MakePipe();
dup2(writeFd, stdErrFileno); dup2(writeFd, stdErrFileno);
_pipeReader = new UnixStream(readFd); _pipeReader = CreateFileDescriptorStream(readFd);
_pipeWriter = new UnixStream(writeFd); _pipeWriter = CreateFileDescriptorStream(writeFd);
_worker = new Thread(EventWorker); _cancellationTokenSource = new CancellationTokenSource();
_worker = Task.Run(async () => await EventWorkerAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token);
_disposable = true; _disposable = true;
_worker.Start();
} }
[SupportedOSPlatform("linux")] [SupportedOSPlatform("linux")]
[SupportedOSPlatform("macos")] [SupportedOSPlatform("macos")]
private void EventWorker() private async Task EventWorkerAsync(CancellationToken cancellationToken)
{ {
TextReader reader = new StreamReader(_pipeReader); using TextReader reader = new StreamReader(_pipeReader, leaveOpen: true);
string line; string line;
while ((line = reader.ReadLine()) != null) while (cancellationToken.IsCancellationRequested == false && (line = await reader.ReadLineAsync(cancellationToken)) != null)
{ {
Logger.Error?.PrintRawMsg(line); Logger.Error?.PrintRawMsg(line);
} }
@@ -55,13 +58,15 @@ namespace Ryujinx.Common.SystemInterop
{ {
if (_disposable) if (_disposable)
{ {
_disposable = false;
if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{ {
_cancellationTokenSource.Cancel();
_worker.Wait(0);
_pipeReader?.Close(); _pipeReader?.Close();
_pipeWriter?.Close(); _pipeWriter?.Close();
} }
_disposable = false;
} }
} }
@@ -74,11 +79,11 @@ namespace Ryujinx.Common.SystemInterop
private static partial int dup2(int fd, int fd2); private static partial int dup2(int fd, int fd2);
[LibraryImport("libc", SetLastError = true)] [LibraryImport("libc", SetLastError = true)]
private static unsafe partial int pipe(int* pipefd); private static partial int pipe(Span<int> pipefd);
private static unsafe (int, int) MakePipe() private static (int, int) MakePipe()
{ {
int *pipefd = stackalloc int[2]; Span<int> pipefd = stackalloc int[2];
if (pipe(pipefd) == 0) if (pipe(pipefd) == 0)
{ {
@@ -89,5 +94,16 @@ namespace Ryujinx.Common.SystemInterop
throw new(); throw new();
} }
} }
[SupportedOSPlatform("linux")]
[SupportedOSPlatform("macos")]
private static Stream CreateFileDescriptorStream(int fd)
{
return new FileStream(
new SafeFileHandle((IntPtr)fd, ownsHandle: true),
FileAccess.ReadWrite
);
}
} }
} }

View File

@@ -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;
}
}
}

View File

@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
private const string AppName = "Ryujinx.Graphics.Vulkan"; private const string AppName = "Ryujinx.Graphics.Vulkan";
private const int QueuesCount = 2; private const int QueuesCount = 2;
public static string[] DesirableExtensions { get; } = new string[] private static readonly string[] _desirableExtensions = new string[]
{ {
ExtConditionalRendering.ExtensionName, ExtConditionalRendering.ExtensionName,
ExtExtendedDynamicState.ExtensionName, ExtExtendedDynamicState.ExtensionName,
@@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Vulkan
"VK_KHR_portability_subset", // By spec, we should enable this if present. "VK_KHR_portability_subset", // By spec, we should enable this if present.
}; };
public static string[] RequiredExtensions { get; } = new string[] private static readonly string[] _requiredExtensions = new string[]
{ {
KhrSwapchain.ExtensionName KhrSwapchain.ExtensionName
}; };
@@ -337,14 +337,14 @@ namespace Ryujinx.Graphics.Vulkan
{ {
string extensionName = Marshal.PtrToStringAnsi((IntPtr)pExtensionProperties[i].ExtensionName); string extensionName = Marshal.PtrToStringAnsi((IntPtr)pExtensionProperties[i].ExtensionName);
if (RequiredExtensions.Contains(extensionName)) if (_requiredExtensions.Contains(extensionName))
{ {
extensionMatches++; extensionMatches++;
} }
} }
} }
return extensionMatches == RequiredExtensions.Length && FindSuitableQueueFamily(api, physicalDevice, surface, out _) != InvalidIndex; return extensionMatches == _requiredExtensions.Length && FindSuitableQueueFamily(api, physicalDevice, surface, out _) != InvalidIndex;
} }
internal static uint FindSuitableQueueFamily(Vk api, PhysicalDevice physicalDevice, SurfaceKHR surface, out uint queueCount) internal static uint FindSuitableQueueFamily(Vk api, PhysicalDevice physicalDevice, SurfaceKHR surface, out uint queueCount)
@@ -626,7 +626,7 @@ namespace Ryujinx.Graphics.Vulkan
pExtendedFeatures = &featuresCustomBorderColor; pExtendedFeatures = &featuresCustomBorderColor;
} }
var enabledExtensions = RequiredExtensions.Union(DesirableExtensions.Intersect(supportedExtensions)).ToArray(); var enabledExtensions = _requiredExtensions.Union(_desirableExtensions.Intersect(supportedExtensions)).ToArray();
IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length]; IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];
@@ -672,11 +672,6 @@ namespace Ryujinx.Graphics.Vulkan
return extensionProperties.Select(x => Marshal.PtrToStringAnsi((IntPtr)x.ExtensionName)).ToArray(); return extensionProperties.Select(x => Marshal.PtrToStringAnsi((IntPtr)x.ExtensionName)).ToArray();
} }
internal static CommandBufferPool CreateCommandBufferPool(Vk api, Device device, Queue queue, object queueLock, uint queueFamilyIndex)
{
return new CommandBufferPool(api, device, queue, queueLock, queueFamilyIndex);
}
internal unsafe static void CreateDebugMessenger( internal unsafe static void CreateDebugMessenger(
Vk api, Vk api,
GraphicsDebugLevel logLevel, GraphicsDebugLevel logLevel,

View File

@@ -320,7 +320,7 @@ namespace Ryujinx.Graphics.Vulkan
MemoryAllocator = new MemoryAllocator(Api, _physicalDevice, _device, properties.Limits.MaxMemoryAllocationCount); MemoryAllocator = new MemoryAllocator(Api, _physicalDevice, _device, properties.Limits.MaxMemoryAllocationCount);
CommandBufferPool = VulkanInitialization.CreateCommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex); CommandBufferPool = new CommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex);
DescriptorSetManager = new DescriptorSetManager(_device); DescriptorSetManager = new DescriptorSetManager(_device);

View File

@@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
namespace Ryujinx.Horizon.Generators.Kernel namespace Ryujinx.Horizon.Generators.Kernel
{ {
@@ -151,24 +152,15 @@ namespace Ryujinx.Horizon.Generators.Kernel
GenerateMethod32(generator, context.Compilation, method); GenerateMethod32(generator, context.Compilation, method);
GenerateMethod64(generator, context.Compilation, method); GenerateMethod64(generator, context.Compilation, method);
foreach (var attributeList in method.AttributeLists) foreach (AttributeSyntax attribute in method.AttributeLists.SelectMany(attributeList =>
attributeList.Attributes.Where(attribute =>
GetCanonicalTypeName(context.Compilation, attribute) == TypeSvcAttribute)))
{ {
foreach (var attribute in attributeList.Attributes) syscalls.AddRange(from attributeArg in attribute.ArgumentList.Arguments
{ where attributeArg.Expression.Kind() == SyntaxKind.NumericLiteralExpression
if (GetCanonicalTypeName(context.Compilation, attribute) != TypeSvcAttribute) select (LiteralExpressionSyntax)attributeArg.Expression
{ into numericLiteral
continue; select new SyscallIdAndName((int)numericLiteral.Token.Value, method.Identifier.Text));
}
foreach (var attributeArg in attribute.ArgumentList.Arguments)
{
if (attributeArg.Expression.Kind() == SyntaxKind.NumericLiteralExpression)
{
LiteralExpressionSyntax numericLiteral = (LiteralExpressionSyntax)attributeArg.Expression;
syscalls.Add(new SyscallIdAndName((int)numericLiteral.Token.Value, method.Identifier.Text));
}
}
}
} }
} }
@@ -510,28 +502,14 @@ namespace Ryujinx.Horizon.Generators.Kernel
private static string GenerateCastFromUInt64(string value, string canonicalTargetTypeName, string targetTypeName) private static string GenerateCastFromUInt64(string value, string canonicalTargetTypeName, string targetTypeName)
{ {
if (canonicalTargetTypeName == TypeSystemBoolean) return canonicalTargetTypeName == TypeSystemBoolean ? $"({value} & 1) != 0" : $"({targetTypeName}){value}";
{
return $"({value} & 1) != 0";
}
return $"({targetTypeName}){value}";
} }
private static bool IsPointerSized(Compilation compilation, ParameterSyntax parameterSyntax) private static bool IsPointerSized(Compilation compilation, ParameterSyntax parameterSyntax)
{ {
foreach (var attributeList in parameterSyntax.AttributeLists) return parameterSyntax.AttributeLists.Any(attributeList =>
{ attributeList.Attributes.Any(attribute =>
foreach (var attribute in attributeList.Attributes) GetCanonicalTypeName(compilation, attribute) == TypePointerSizedAttribute));
{
if (GetCanonicalTypeName(compilation, attribute) == TypePointerSizedAttribute)
{
return true;
}
}
}
return false;
} }
public void Initialize(GeneratorInitializationContext context) public void Initialize(GeneratorInitializationContext context)

View File

@@ -16,12 +16,17 @@ namespace Ryujinx.Horizon.Generators.Kernel
public void OnVisitSyntaxNode(SyntaxNode syntaxNode) public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{ {
if (syntaxNode is ClassDeclarationSyntax classDeclaration && classDeclaration.AttributeLists.Count != 0) if (!(syntaxNode is ClassDeclarationSyntax classDeclaration) || classDeclaration.AttributeLists.Count == 0)
{ {
foreach (var attributeList in classDeclaration.AttributeLists) return;
{ }
if (attributeList.Attributes.Any(x => x.Name.GetText().ToString() == "SvcImpl"))
if (!classDeclaration.AttributeLists.Any(attributeList =>
attributeList.Attributes.Any(x => x.Name.GetText().ToString() == "SvcImpl")))
{ {
return;
}
foreach (var memberDeclaration in classDeclaration.Members) foreach (var memberDeclaration in classDeclaration.Members)
{ {
if (memberDeclaration is MethodDeclarationSyntax methodDeclaration) if (memberDeclaration is MethodDeclarationSyntax methodDeclaration)
@@ -29,25 +34,19 @@ namespace Ryujinx.Horizon.Generators.Kernel
VisitMethod(methodDeclaration); VisitMethod(methodDeclaration);
} }
} }
break;
}
}
}
} }
private void VisitMethod(MethodDeclarationSyntax methodDeclaration) private void VisitMethod(MethodDeclarationSyntax methodDeclaration)
{ {
if (methodDeclaration.AttributeLists.Count != 0) if (methodDeclaration.AttributeLists.Count == 0)
{ {
foreach (var attributeList in methodDeclaration.AttributeLists) return;
{ }
if (attributeList.Attributes.Any(x => x.Name.GetText().ToString() == "Svc"))
if (methodDeclaration.AttributeLists.Any(attributeList =>
attributeList.Attributes.Any(x => x.Name.GetText().ToString() == "Svc")))
{ {
SvcImplementations.Add(methodDeclaration); SvcImplementations.Add(methodDeclaration);
break;
}
}
} }
} }
} }

View File

@@ -40,12 +40,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
var runtimeMetadata = context.Processor.GetRuntimeMetadata(); var runtimeMetadata = context.Processor.GetRuntimeMetadata();
Result result = context.Processor.PrepareForProcess(ref context, runtimeMetadata); Result result = context.Processor.PrepareForProcess(ref context, runtimeMetadata);
if (result.IsFailure) return result.IsFailure ? result : _invoke(ref context, _processor, runtimeMetadata, inRawData, ref outHeader);
{
return result;
}
return _invoke(ref context, _processor, runtimeMetadata, inRawData, ref outHeader);
} }
public static void GetCmifOutHeaderPointer(ref Span<CmifOutHeader> outHeader, ref Span<byte> outRawData) public static void GetCmifOutHeaderPointer(ref Span<CmifOutHeader> outHeader, ref Span<byte> outRawData)

View File

@@ -53,7 +53,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
public static void SerializeArg<T>(Span<byte> outRawData, int offset, T value) where T : unmanaged public static void SerializeArg<T>(Span<byte> outRawData, int offset, T value) where T : unmanaged
{ {
MemoryMarshal.Cast<byte, T>(outRawData.Slice(offset, Unsafe.SizeOf<T>()))[0] = (T)value; MemoryMarshal.Cast<byte, T>(outRawData.Slice(offset, Unsafe.SizeOf<T>()))[0] = value;
} }
public static void SerializeCopyHandle(HipcMessageData response, int index, int value) public static void SerializeCopyHandle(HipcMessageData response, int index, int value)

View File

@@ -41,10 +41,8 @@ namespace Ryujinx.Horizon.Sdk.Sf
{ {
_args = args; _args = args;
for (int i = 0; i < args.Length; i++) foreach (CommandArg argInfo in args)
{ {
var argInfo = args[i];
switch (argInfo.Type) switch (argInfo.Type)
{ {
case CommandArgType.Buffer: case CommandArgType.Buffer:
@@ -239,15 +237,14 @@ namespace Ryujinx.Horizon.Sdk.Sf
{ {
return mode == HipcBufferMode.NonSecure; return mode == HipcBufferMode.NonSecure;
} }
else if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonDevice))
if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonDevice))
{ {
return mode == HipcBufferMode.NonDevice; return mode == HipcBufferMode.NonDevice;
} }
else
{
return mode == HipcBufferMode.Normal; return mode == HipcBufferMode.Normal;
} }
}
public void SetOutBuffers(HipcMessageData response, bool[] isBufferMapAlias) public void SetOutBuffers(HipcMessageData response, bool[] isBufferMapAlias)
{ {
@@ -261,8 +258,11 @@ namespace Ryujinx.Horizon.Sdk.Sf
} }
var flags = _args[i].BufferFlags; var flags = _args[i].BufferFlags;
if (flags.HasFlag(HipcBufferFlags.Out)) if (!flags.HasFlag(HipcBufferFlags.Out))
{ {
continue;
}
var buffer = _bufferRanges[i]; var buffer = _bufferRanges[i];
if (flags.HasFlag(HipcBufferFlags.Pointer)) if (flags.HasFlag(HipcBufferFlags.Pointer))
@@ -284,7 +284,6 @@ namespace Ryujinx.Horizon.Sdk.Sf
recvPointerIndex++; recvPointerIndex++;
} }
} }
}
public override void SetImplementationProcessor(ServerMessageProcessor impl) public override void SetImplementationProcessor(ServerMessageProcessor impl)
{ {
@@ -339,16 +338,18 @@ namespace Ryujinx.Horizon.Sdk.Sf
int inObjectIndex = 0; int inObjectIndex = 0;
for (int i = 0; i < _args.Length; i++) foreach (CommandArg t in _args)
{ {
if (_args[i].Type == CommandArgType.InObject) if (t.Type != CommandArgType.InObject)
{ {
continue;
}
int index = inObjectIndex++; int index = inObjectIndex++;
var inObject = inObjects[index]; var inObject = inObjects[index];
objects[index] = inObject?.ServiceObject; objects[index] = inObject?.ServiceObject;
} }
}
return Result.Success; return Result.Success;
} }

View File

@@ -37,12 +37,7 @@ namespace Ryujinx.Horizon.Sm.Impl
result = GetServiceImpl(out handle, ref _services[serviceIndex]); result = GetServiceImpl(out handle, ref _services[serviceIndex]);
if (result == KernelResult.SessionCountExceeded) return result == KernelResult.SessionCountExceeded ? SmResult.OutOfSessions : result;
{
return SmResult.OutOfSessions;
}
return result;
} }
private Result GetServiceImpl(out int handle, ref ServiceInfo serviceInfo) private Result GetServiceImpl(out int handle, ref ServiceInfo serviceInfo)
@@ -61,13 +56,7 @@ namespace Ryujinx.Horizon.Sm.Impl
} }
// TODO: Validation with GetProcessInfo etc. // TODO: Validation with GetProcessInfo etc.
return HasServiceInfo(name) ? SmResult.AlreadyRegistered : RegisterServiceImpl(out handle, processId, name, maxSessions, isLight);
if (HasServiceInfo(name))
{
return SmResult.AlreadyRegistered;
}
return RegisterServiceImpl(out handle, processId, name, maxSessions, isLight);
} }
public Result RegisterServiceForSelf(out int handle, ServiceName name, int maxSessions) public Result RegisterServiceForSelf(out int handle, ServiceName name, int maxSessions)