Compare commits

...

2 Commits

Author SHA1 Message Date
TSRBerry
c05c688ee8 Avoid copying more handles than we have space for (#4564)
* Avoid copying more handles than we have space for

* Use locks instead

* Reduce nesting by combining the lock statements

* Add locks for other uses of _sessionHandles and _portHandles

* Use one object to lock instead of locking twice

* Release the lock as soon as possible
2023-03-19 11:30:04 +01:00
riperiperi
b2623dc27d OpenGL: Fix inverted conditional for counter flush from #4471 (#4560)
Fixes OpenGL.
2023-03-18 20:39:05 -03:00
2 changed files with 29 additions and 10 deletions

View File

@@ -74,7 +74,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
{ {
result = Marshal.ReadInt64(_bufferMap); result = Marshal.ReadInt64(_bufferMap);
return WaitingForValue(result); return !WaitingForValue(result);
} }
public long AwaitResult(AutoResetEvent wakeSignal = null) public long AwaitResult(AutoResetEvent wakeSignal = null)

View File

@@ -32,6 +32,8 @@ namespace Ryujinx.HLE.HOS.Services
0x01007FFF 0x01007FFF
}; };
private readonly object _handleLock = new();
private readonly KernelContext _context; private readonly KernelContext _context;
private KProcess _selfProcess; private KProcess _selfProcess;
@@ -76,8 +78,11 @@ namespace Ryujinx.HLE.HOS.Services
} }
private void AddPort(int serverPortHandle, Func<IpcService> objectFactory) private void AddPort(int serverPortHandle, Func<IpcService> objectFactory)
{
lock (_handleLock)
{ {
_portHandles.Add(serverPortHandle); _portHandles.Add(serverPortHandle);
}
_ports.Add(serverPortHandle, objectFactory); _ports.Add(serverPortHandle, objectFactory);
} }
@@ -91,8 +96,11 @@ namespace Ryujinx.HLE.HOS.Services
} }
public void AddSessionObj(int serverSessionHandle, IpcService obj) public void AddSessionObj(int serverSessionHandle, IpcService obj)
{
lock (_handleLock)
{ {
_sessionHandles.Add(serverSessionHandle); _sessionHandles.Add(serverSessionHandle);
}
_sessions.Add(serverSessionHandle, obj); _sessions.Add(serverSessionHandle, obj);
} }
@@ -126,12 +134,20 @@ namespace Ryujinx.HLE.HOS.Services
while (true) while (true)
{ {
int handleCount = _portHandles.Count + _sessionHandles.Count; int handleCount;
int portHandleCount;
int[] handles;
int[] handles = ArrayPool<int>.Shared.Rent(handleCount); lock (_handleLock)
{
portHandleCount = _portHandles.Count;
handleCount = portHandleCount + _sessionHandles.Count;
handles = ArrayPool<int>.Shared.Rent(handleCount);
_portHandles.CopyTo(handles, 0); _portHandles.CopyTo(handles, 0);
_sessionHandles.CopyTo(handles, _portHandles.Count); _sessionHandles.CopyTo(handles, portHandleCount);
}
// We still need a timeout here to allow the service to pick up and listen new sessions... // We still need a timeout here to allow the service to pick up and listen new sessions...
var rc = _context.Syscall.ReplyAndReceive(out int signaledIndex, handles.AsSpan(0, handleCount), replyTargetHandle, 1000000L); var rc = _context.Syscall.ReplyAndReceive(out int signaledIndex, handles.AsSpan(0, handleCount), replyTargetHandle, 1000000L);
@@ -145,7 +161,7 @@ namespace Ryujinx.HLE.HOS.Services
replyTargetHandle = 0; replyTargetHandle = 0;
if (rc == Result.Success && signaledIndex >= _portHandles.Count) if (rc == Result.Success && signaledIndex >= portHandleCount)
{ {
// We got a IPC request, process it, pass to the appropriate service if needed. // We got a IPC request, process it, pass to the appropriate service if needed.
int signaledHandle = handles[signaledIndex]; int signaledHandle = handles[signaledIndex];
@@ -278,7 +294,10 @@ namespace Ryujinx.HLE.HOS.Services
else if (request.Type == IpcMessageType.HipcCloseSession || request.Type == IpcMessageType.TipcCloseSession) else if (request.Type == IpcMessageType.HipcCloseSession || request.Type == IpcMessageType.TipcCloseSession)
{ {
_context.Syscall.CloseHandle(serverSessionHandle); _context.Syscall.CloseHandle(serverSessionHandle);
lock (_handleLock)
{
_sessionHandles.Remove(serverSessionHandle); _sessionHandles.Remove(serverSessionHandle);
}
IpcService service = _sessions[serverSessionHandle]; IpcService service = _sessions[serverSessionHandle];
(service as IDisposable)?.Dispose(); (service as IDisposable)?.Dispose();
_sessions.Remove(serverSessionHandle); _sessions.Remove(serverSessionHandle);