Misc fixes and improvements on new IPC methods
This commit is contained in:
parent
357c0c7977
commit
89e703302b
12 changed files with 239 additions and 156 deletions
|
@ -115,6 +115,16 @@ namespace Ryujinx.HLE
|
|||
|
||||
public void Set(ulong address, byte value, ulong size)
|
||||
{
|
||||
if (address + size < address)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(size));
|
||||
}
|
||||
|
||||
if (address + size > RamSize)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(address));
|
||||
}
|
||||
|
||||
ulong size8 = size & ~7UL;
|
||||
|
||||
ulong valueRep = (ulong)value * 0x0101010101010101;
|
||||
|
@ -132,6 +142,21 @@ namespace Ryujinx.HLE
|
|||
|
||||
public void Copy(ulong dst, ulong src, ulong size)
|
||||
{
|
||||
if (dst + size < dst || src + size < src)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(size));
|
||||
}
|
||||
|
||||
if (dst + size > RamSize)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(dst));
|
||||
}
|
||||
|
||||
if (src + size > RamSize)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(src));
|
||||
}
|
||||
|
||||
ulong size8 = size & ~7UL;
|
||||
|
||||
for (ulong offs = 0; offs < size8; offs += 8)
|
||||
|
|
10
Ryujinx.HLE/HOS/Kernel/Ipc/ChannelState.cs
Normal file
10
Ryujinx.HLE/HOS/Kernel/Ipc/ChannelState.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
||||
{
|
||||
enum ChannelState
|
||||
{
|
||||
NotInitialized,
|
||||
Open,
|
||||
ClientDisconnected,
|
||||
ServerDisconnected
|
||||
}
|
||||
}
|
|
@ -18,15 +18,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
//SM implementation to work with the new IPC system.
|
||||
public IpcService Service { get; set; }
|
||||
|
||||
public KClientPort(Horizon system) : base(system)
|
||||
{
|
||||
_countIncLock = new object();
|
||||
}
|
||||
|
||||
public void Initialize(KPort parent, int maxSessions)
|
||||
public KClientPort(Horizon system, KPort parent, int maxSessions) : base(system)
|
||||
{
|
||||
_maxSessions = maxSessions;
|
||||
_parent = parent;
|
||||
|
||||
_countIncLock = new object();
|
||||
}
|
||||
|
||||
public KernelResult Connect(out KClientSession clientSession)
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
private KSession _parent;
|
||||
|
||||
public int ResourceStatus { get; private set; }
|
||||
public ChannelState State { get; set; }
|
||||
|
||||
//TODO: Remove that, we need it for now to allow HLE
|
||||
//services implementation to work with the new IPC system.
|
||||
|
@ -21,7 +21,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
{
|
||||
_parent = parent;
|
||||
|
||||
ResourceStatus = 1;
|
||||
State = ChannelState.Open;
|
||||
}
|
||||
|
||||
public KernelResult SendSyncRequest(ulong customCmdBuffAddr = 0, ulong customCmdBuffSize = 0)
|
||||
|
@ -51,6 +51,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
protected override void Destroy()
|
||||
{
|
||||
_parent.DisconnectClient();
|
||||
_parent.DecrementReferenceCount();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,25 +8,20 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
public KClientPort ClientPort { get; }
|
||||
|
||||
private long _nameAddress;
|
||||
private int _resourceStatus;
|
||||
|
||||
private ChannelState _state;
|
||||
|
||||
public bool IsLight { get; private set; }
|
||||
|
||||
public KPort(Horizon system) : base(system)
|
||||
public KPort(Horizon system, int maxSessions, bool isLight, long nameAddress) : base(system)
|
||||
{
|
||||
ServerPort = new KServerPort(system);
|
||||
ClientPort = new KClientPort(system);
|
||||
}
|
||||
|
||||
public void Initialize(int maxSessions, bool isLight, long nameAddress)
|
||||
{
|
||||
ServerPort.Initialize(this);
|
||||
ClientPort.Initialize(this, maxSessions);
|
||||
ServerPort = new KServerPort(system, this);
|
||||
ClientPort = new KClientPort(system, this, maxSessions);
|
||||
|
||||
IsLight = isLight;
|
||||
_nameAddress = nameAddress;
|
||||
|
||||
_resourceStatus = 1;
|
||||
_state = ChannelState.Open;
|
||||
}
|
||||
|
||||
public KernelResult EnqueueIncomingSession(KServerSession session)
|
||||
|
@ -35,7 +30,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
System.CriticalSection.Enter();
|
||||
|
||||
if (_resourceStatus == 1)
|
||||
if (_state == ChannelState.Open)
|
||||
{
|
||||
ServerPort.EnqueueIncomingSession(session);
|
||||
|
||||
|
|
|
@ -12,15 +12,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
public bool IsLight => _parent.IsLight;
|
||||
|
||||
public KServerPort(Horizon system) : base(system)
|
||||
{
|
||||
_incomingConnections = new LinkedList<KServerSession>();
|
||||
_lightIncomingConnections = new LinkedList<KServerSession>();
|
||||
}
|
||||
|
||||
public void Initialize(KPort parent)
|
||||
public KServerPort(Horizon system, KPort parent) : base(system)
|
||||
{
|
||||
_parent = parent;
|
||||
|
||||
_incomingConnections = new LinkedList<KServerSession>();
|
||||
_lightIncomingConnections = new LinkedList<KServerSession>();
|
||||
}
|
||||
|
||||
public void EnqueueIncomingSession(KServerSession session)
|
||||
|
|
|
@ -173,20 +173,20 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
public KernelResult EnqueueRequest(KSessionRequest request)
|
||||
{
|
||||
if (_parent.ClientSession.ResourceStatus != 1)
|
||||
if (_parent.ClientSession.State != ChannelState.Open)
|
||||
{
|
||||
return KernelResult.PortRemoteClosed;
|
||||
}
|
||||
|
||||
if (request.AsyncEvent == null)
|
||||
{
|
||||
if (request.SenderThread.ShallBeTerminated ||
|
||||
request.SenderThread.SchedFlags == ThreadSchedState.TerminationPending)
|
||||
if (request.ClientThread.ShallBeTerminated ||
|
||||
request.ClientThread.SchedFlags == ThreadSchedState.TerminationPending)
|
||||
{
|
||||
return KernelResult.ThreadTerminating;
|
||||
}
|
||||
|
||||
request.SenderThread.Reschedule(ThreadSchedState.Paused);
|
||||
request.ClientThread.Reschedule(ThreadSchedState.Paused);
|
||||
}
|
||||
|
||||
_requests.AddLast(request);
|
||||
|
@ -206,38 +206,36 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
System.CriticalSection.Enter();
|
||||
|
||||
if (_parent.ClientSession.ResourceStatus != 1)
|
||||
if (_parent.ClientSession.State != ChannelState.Open)
|
||||
{
|
||||
System.CriticalSection.Leave();
|
||||
|
||||
return KernelResult.PortRemoteClosed;
|
||||
}
|
||||
|
||||
if (_activeRequest != null || _requests.Count == 0)
|
||||
if (_activeRequest != null || !PickRequest(out KSessionRequest request))
|
||||
{
|
||||
System.CriticalSection.Leave();
|
||||
|
||||
return KernelResult.NotFound;
|
||||
}
|
||||
|
||||
KSessionRequest request = _requests.First.Value;
|
||||
|
||||
_requests.RemoveFirst();
|
||||
|
||||
if (request.SenderThread == null)
|
||||
if (request.ClientThread == null)
|
||||
{
|
||||
System.CriticalSection.Leave();
|
||||
|
||||
return KernelResult.PortRemoteClosed;
|
||||
}
|
||||
|
||||
KThread clientThread = request.SenderThread;
|
||||
KThread clientThread = request.ClientThread;
|
||||
KProcess clientProcess = clientThread.Owner;
|
||||
|
||||
System.CriticalSection.Leave();
|
||||
|
||||
_activeRequest = request;
|
||||
|
||||
request.ServerProcess = serverProcess;
|
||||
|
||||
Message clientMsg = new Message(
|
||||
clientThread,
|
||||
request.CustomCmdBuffAddr,
|
||||
|
@ -259,7 +257,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
void CleanUpForError()
|
||||
{
|
||||
request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager);
|
||||
if (request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager) == KernelResult.Success)
|
||||
{
|
||||
request.BufferDescriptorTable.RestoreClientBuffers(clientProcess.MemoryManager);
|
||||
}
|
||||
|
||||
CloseAllHandles(serverMsg, header, serverProcess);
|
||||
|
||||
|
@ -274,29 +275,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
System.CriticalSection.Leave();
|
||||
|
||||
if (request.AsyncEvent != null)
|
||||
{
|
||||
System.Device.Memory.WriteInt64((long)clientMsg.DramAddress + 0, 0);
|
||||
System.Device.Memory.WriteInt32((long)clientMsg.DramAddress + 8, (int)clientResult);
|
||||
|
||||
clientProcess.MemoryManager.UnborrowIpcBuffer(clientMsg.Address, clientMsg.Size);
|
||||
|
||||
request.AsyncEvent.Signal();
|
||||
}
|
||||
else
|
||||
{
|
||||
System.CriticalSection.Enter();
|
||||
|
||||
if ((clientThread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused)
|
||||
{
|
||||
clientThread.SignaledObj = null;
|
||||
clientThread.ObjSyncResult = clientResult;
|
||||
|
||||
clientThread.Reschedule(ThreadSchedState.Running);
|
||||
}
|
||||
|
||||
System.CriticalSection.Leave();
|
||||
}
|
||||
WakeClient(request, clientResult);
|
||||
}
|
||||
|
||||
if (header.ReceiveListType < 2 && header.ReceiveListOffset > clientMsg.Size)
|
||||
|
@ -386,7 +365,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
if (clientResult == KernelResult.Success && handle != 0)
|
||||
{
|
||||
clientResult = GetCopyObjectHandle(clientThread, handle, out newHandle);
|
||||
clientResult = GetCopyObjectHandle(clientThread, serverProcess, handle, out newHandle);
|
||||
}
|
||||
|
||||
serverProcess.CpuMemory.WriteInt32((long)serverMsg.Address + offset * 4, newHandle);
|
||||
|
@ -404,7 +383,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
{
|
||||
if (clientResult == KernelResult.Success)
|
||||
{
|
||||
clientResult = GetMoveObjectHandle(serverProcess, handle, out newHandle);
|
||||
clientResult = GetMoveObjectHandle(clientProcess, serverProcess, handle, out newHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -640,7 +619,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
System.CriticalSection.Leave();
|
||||
|
||||
KThread clientThread = request.SenderThread;
|
||||
KThread clientThread = request.ClientThread;
|
||||
KProcess clientProcess = clientThread.Owner;
|
||||
|
||||
Message clientMsg = new Message(
|
||||
|
@ -662,46 +641,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
KernelResult clientResult = KernelResult.Success;
|
||||
KernelResult serverResult = KernelResult.Success;
|
||||
|
||||
void SendResultToClient()
|
||||
{
|
||||
if (request.AsyncEvent != null)
|
||||
{
|
||||
if (clientResult != KernelResult.Success)
|
||||
{
|
||||
System.Device.Memory.WriteInt64((long)clientMsg.DramAddress + 0, 0);
|
||||
System.Device.Memory.WriteInt32((long)clientMsg.DramAddress + 8, (int)clientResult);
|
||||
}
|
||||
|
||||
clientProcess.MemoryManager.UnborrowIpcBuffer(clientMsg.Address, clientMsg.Size);
|
||||
|
||||
request.AsyncEvent.Signal();
|
||||
}
|
||||
else
|
||||
{
|
||||
System.CriticalSection.Enter();
|
||||
|
||||
if ((clientThread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused)
|
||||
{
|
||||
clientThread.SignaledObj = null;
|
||||
clientThread.ObjSyncResult = clientResult;
|
||||
|
||||
clientThread.Reschedule(ThreadSchedState.Running);
|
||||
}
|
||||
|
||||
System.CriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
void CleanUpForError()
|
||||
{
|
||||
CloseAllHandles(clientMsg, header, serverProcess);
|
||||
CloseAllHandles(clientMsg, header, clientProcess);
|
||||
|
||||
if (request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager) == KernelResult.Success)
|
||||
{
|
||||
request.BufferDescriptorTable.RestoreClientBuffers(serverProcess.MemoryManager);
|
||||
}
|
||||
|
||||
SendResultToClient();
|
||||
CancelRequest(request, clientResult);
|
||||
}
|
||||
|
||||
if (header.ReceiveListType < 2 && header.ReceiveListOffset > clientMsg.Size)
|
||||
|
@ -737,18 +681,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
return KernelResult.CmdBufferTooSmall;
|
||||
}
|
||||
|
||||
//Close move handles.
|
||||
uint pidSizeInWords = header.HasPid ? 2u : 0u;
|
||||
|
||||
ulong moveHandlesAddr = serverMsg.Address + (3u + pidSizeInWords + header.CopyHandlesCount) * 4;
|
||||
|
||||
for (int index = 0; index < header.MoveHandlesCount; index++)
|
||||
{
|
||||
int handle = serverProcess.CpuMemory.ReadInt32((long)moveHandlesAddr + index * 4);
|
||||
|
||||
serverProcess.HandleTable.CloseHandle(handle);
|
||||
}
|
||||
|
||||
//Read receive list.
|
||||
ulong[] receiveList = null;
|
||||
|
||||
|
@ -806,10 +738,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
if (handle != 0)
|
||||
{
|
||||
GetCopyObjectHandle(clientThread, handle, out newHandle);
|
||||
GetCopyObjectHandle(serverThread, clientProcess, handle, out newHandle);
|
||||
}
|
||||
|
||||
serverProcess.CpuMemory.WriteInt32((long)serverMsg.Address + offset * 4, newHandle);
|
||||
System.Device.Memory.WriteInt32((long)clientMsg.DramAddress + offset * 4, newHandle);
|
||||
|
||||
offset++;
|
||||
}
|
||||
|
@ -824,7 +756,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
{
|
||||
if (clientResult == KernelResult.Success)
|
||||
{
|
||||
clientResult = GetMoveObjectHandle(serverProcess, handle, out newHandle);
|
||||
clientResult = GetMoveObjectHandle(serverProcess, clientProcess, handle, out newHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -832,7 +764,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
}
|
||||
}
|
||||
|
||||
serverProcess.CpuMemory.WriteInt32((long)serverMsg.Address + offset * 4, newHandle);
|
||||
System.Device.Memory.WriteInt32((long)clientMsg.DramAddress + offset * 4, newHandle);
|
||||
|
||||
offset++;
|
||||
}
|
||||
|
@ -941,36 +873,39 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
return serverResult;
|
||||
}
|
||||
|
||||
//Wake client thread.
|
||||
SendResultToClient();
|
||||
WakeClient(request, clientResult);
|
||||
|
||||
return serverResult;
|
||||
}
|
||||
|
||||
private KernelResult GetCopyObjectHandle(KThread thread, int srcHandle, out int dstHandle)
|
||||
private KernelResult GetCopyObjectHandle(
|
||||
KThread srcThread,
|
||||
KProcess dstProcess,
|
||||
int srcHandle,
|
||||
out int dstHandle)
|
||||
{
|
||||
dstHandle = 0;
|
||||
|
||||
KProcess process = thread.Owner;
|
||||
KProcess srcProcess = srcThread.Owner;
|
||||
|
||||
KAutoObject obj;
|
||||
|
||||
if (srcHandle == KHandleTable.SelfProcessHandle)
|
||||
{
|
||||
obj = process;
|
||||
obj = srcProcess;
|
||||
}
|
||||
else if (srcHandle == KHandleTable.SelfThreadHandle)
|
||||
{
|
||||
obj = thread;
|
||||
obj = srcThread;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = process.HandleTable.GetObject<KAutoObject>(srcHandle);
|
||||
obj = srcProcess.HandleTable.GetObject<KAutoObject>(srcHandle);
|
||||
}
|
||||
|
||||
if (obj != null)
|
||||
{
|
||||
return process.HandleTable.GenerateHandle(obj, out dstHandle);
|
||||
return dstProcess.HandleTable.GenerateHandle(obj, out dstHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -978,7 +913,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
}
|
||||
}
|
||||
|
||||
private KernelResult GetMoveObjectHandle(KProcess srcProcess, int srcHandle, out int dstHandle)
|
||||
private KernelResult GetMoveObjectHandle(
|
||||
KProcess srcProcess,
|
||||
KProcess dstProcess,
|
||||
int srcHandle,
|
||||
out int dstHandle)
|
||||
{
|
||||
dstHandle = 0;
|
||||
|
||||
|
@ -986,7 +925,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
if (obj != null)
|
||||
{
|
||||
KernelResult result = srcProcess.HandleTable.GenerateHandle(obj, out dstHandle);
|
||||
KernelResult result = dstProcess.HandleTable.GenerateHandle(obj, out dstHandle);
|
||||
|
||||
srcProcess.HandleTable.CloseHandle(srcHandle);
|
||||
|
||||
|
@ -1102,7 +1041,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
public override bool IsSignaled()
|
||||
{
|
||||
if (_parent.ClientSession.ResourceStatus != 1)
|
||||
if (_parent.ClientSession.State != ChannelState.Open)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1112,7 +1051,110 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
protected override void Destroy()
|
||||
{
|
||||
_parent.DisconnectServer();
|
||||
|
||||
CancelAllRequests(KernelResult.PortRemoteClosed);
|
||||
|
||||
_parent.DecrementReferenceCount();
|
||||
}
|
||||
|
||||
private void CancelAllRequests(KernelResult result)
|
||||
{
|
||||
System.CriticalSection.Enter();
|
||||
|
||||
if (_activeRequest != null)
|
||||
{
|
||||
KSessionRequest request = _activeRequest;
|
||||
|
||||
_activeRequest = null;
|
||||
|
||||
CancelRequest(request, result);
|
||||
|
||||
System.CriticalSection.Leave();
|
||||
}
|
||||
else
|
||||
{
|
||||
System.CriticalSection.Leave();
|
||||
}
|
||||
|
||||
while (PickRequest(out KSessionRequest request))
|
||||
{
|
||||
CancelRequest(request, result);
|
||||
}
|
||||
}
|
||||
|
||||
private bool PickRequest(out KSessionRequest request)
|
||||
{
|
||||
request = null;
|
||||
|
||||
System.CriticalSection.Enter();
|
||||
|
||||
bool hasRequest = _requests.First != null;
|
||||
|
||||
if (hasRequest)
|
||||
{
|
||||
request = _requests.First.Value;
|
||||
|
||||
_requests.RemoveFirst();
|
||||
}
|
||||
|
||||
System.CriticalSection.Leave();
|
||||
|
||||
return hasRequest;
|
||||
}
|
||||
|
||||
private void CancelRequest(KSessionRequest request, KernelResult result)
|
||||
{
|
||||
KProcess clientProcess = request.ClientThread.Owner;
|
||||
KProcess serverProcess = request.ServerProcess;
|
||||
|
||||
KernelResult unmapResult = KernelResult.Success;
|
||||
|
||||
if (serverProcess != null)
|
||||
{
|
||||
unmapResult = request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager);
|
||||
}
|
||||
|
||||
if (unmapResult == KernelResult.Success)
|
||||
{
|
||||
request.BufferDescriptorTable.RestoreClientBuffers(clientProcess.MemoryManager);
|
||||
}
|
||||
|
||||
WakeClient(request, result);
|
||||
}
|
||||
|
||||
private void WakeClient(KSessionRequest request, KernelResult result)
|
||||
{
|
||||
KThread clientThread = request.ClientThread;
|
||||
KProcess clientProcess = clientThread.Owner;
|
||||
|
||||
if (request.AsyncEvent != null)
|
||||
{
|
||||
ulong address = clientProcess.MemoryManager.GetDramAddressFromVa(request.CustomCmdBuffAddr);
|
||||
|
||||
System.Device.Memory.WriteInt64((long)address + 0, 0);
|
||||
System.Device.Memory.WriteInt32((long)address + 8, (int)result);
|
||||
|
||||
clientProcess.MemoryManager.UnborrowIpcBuffer(
|
||||
request.CustomCmdBuffAddr,
|
||||
request.CustomCmdBuffSize);
|
||||
|
||||
request.AsyncEvent.Signal();
|
||||
}
|
||||
else
|
||||
{
|
||||
System.CriticalSection.Enter();
|
||||
|
||||
if ((clientThread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused)
|
||||
{
|
||||
clientThread.SignaledObj = null;
|
||||
clientThread.ObjSyncResult = result;
|
||||
|
||||
clientThread.Reschedule(ThreadSchedState.Running);
|
||||
}
|
||||
|
||||
System.CriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,24 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
ClientSession = new KClientSession(system, this);
|
||||
}
|
||||
|
||||
public void DisconnectClient()
|
||||
{
|
||||
if (ClientSession.State == ChannelState.Open)
|
||||
{
|
||||
ClientSession.State = ChannelState.ClientDisconnected;
|
||||
|
||||
//TODO: Wake up client, etc.
|
||||
}
|
||||
}
|
||||
|
||||
public void DisconnectServer()
|
||||
{
|
||||
if (ClientSession.State == ChannelState.Open)
|
||||
{
|
||||
ClientSession.State = ChannelState.ServerDisconnected;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Ryujinx.HLE.HOS.Kernel.Process;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
||||
|
@ -6,7 +7,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
{
|
||||
public KBufferDescriptorTable BufferDescriptorTable { get; }
|
||||
|
||||
public KThread SenderThread { get; }
|
||||
public KThread ClientThread { get; }
|
||||
|
||||
public KProcess ServerProcess { get; set; }
|
||||
|
||||
public KWritableEvent AsyncEvent { get; }
|
||||
|
||||
|
@ -14,11 +17,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
public ulong CustomCmdBuffSize { get; }
|
||||
|
||||
public KSessionRequest(
|
||||
KThread senderThread,
|
||||
KThread clientThread,
|
||||
ulong customCmdBuffAddr,
|
||||
ulong customCmdBuffSize)
|
||||
{
|
||||
SenderThread = senderThread;
|
||||
ClientThread = clientThread;
|
||||
CustomCmdBuffAddr = customCmdBuffAddr;
|
||||
CustomCmdBuffSize = customCmdBuffSize;
|
||||
|
||||
|
|
|
@ -1778,7 +1778,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||
|
||||
if (visitedSize != 0)
|
||||
{
|
||||
InsertBlock(address, size, SetIpcMappingPermissions, permissionMask);
|
||||
InsertBlock(address, visitedSize / PageSize, SetIpcMappingPermissions, permissionMask);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1850,14 +1850,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||
|
||||
firstPageFillAddress += unusedSizeBefore + copySize;
|
||||
|
||||
unusedSizeAfter = addressRounded - endAddr;
|
||||
unusedSizeAfter = addressRounded > endAddr ? addressRounded - endAddr : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
unusedSizeAfter = PageSize;
|
||||
}
|
||||
|
||||
_system.Device.Memory.Set(firstPageFillAddress, 0, unusedSizeAfter);
|
||||
if (unusedSizeAfter != 0)
|
||||
{
|
||||
_system.Device.Memory.Set(firstPageFillAddress, 0, unusedSizeAfter);
|
||||
}
|
||||
|
||||
KPageList pages = new KPageList();
|
||||
|
||||
|
@ -1989,15 +1992,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||
|
||||
if (pageList.Nodes.Count != 0)
|
||||
{
|
||||
if (MapPages(va, pageList, permission) != KernelResult.Success)
|
||||
KernelResult result = MapPages(va, pageList, permission);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Unexpected failure while trying to map pages.");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertBlock(va, neededPagesCount, state, permission);
|
||||
}
|
||||
|
||||
InsertBlock(va, neededPagesCount, state, permission);
|
||||
|
||||
mappedVa = va;
|
||||
}
|
||||
|
|
|
@ -666,6 +666,8 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
{
|
||||
currentProcess.HandleTable.SetReservedHandleObj(handle, session);
|
||||
|
||||
session.DecrementReferenceCount();
|
||||
|
||||
sessionHandle = handle;
|
||||
|
||||
result = KernelResult.Success;
|
||||
|
@ -933,9 +935,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return KernelResult.MaximumExceeded;
|
||||
}
|
||||
|
||||
KPort port = new KPort(_system);
|
||||
|
||||
port.Initialize(maxSessions, isLight, (long)namePtr);
|
||||
KPort port = new KPort(_system, maxSessions, isLight, (long)namePtr);
|
||||
|
||||
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
|
||||
|
||||
|
@ -980,7 +980,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return KClientPort.RemoveName(_system, name);
|
||||
}
|
||||
|
||||
KPort port = new KPort(_system);
|
||||
KPort port = new KPort(_system, maxSessions, false, 0);
|
||||
|
||||
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
|
||||
|
||||
|
@ -991,8 +991,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
return result;
|
||||
}
|
||||
|
||||
port.Initialize(maxSessions, false, 0);
|
||||
|
||||
result = port.ClientPort.SetName(name);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
|
|
|
@ -32,9 +32,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm
|
|||
|
||||
public static void InitializePort(Horizon system)
|
||||
{
|
||||
KPort port = new KPort(system);
|
||||
|
||||
port.Initialize(256, false, 0);
|
||||
KPort port = new KPort(system, 256, false, 0);
|
||||
|
||||
port.ClientPort.SetName("sm:");
|
||||
|
||||
|
@ -110,11 +108,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm
|
|||
return ErrorCode.MakeError(ErrorModule.Sm, SmErr.InvalidName);
|
||||
}
|
||||
|
||||
System.Console.WriteLine("register service " + name + " " + maxSessions);
|
||||
|
||||
KPort port = new KPort(context.Device.System);
|
||||
|
||||
port.Initialize(maxSessions, isLight, 0);
|
||||
KPort port = new KPort(context.Device.System, maxSessions, isLight, 0);
|
||||
|
||||
if (!_registeredServices.TryAdd(name, port))
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue