KClientSession.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using Ryujinx.HLE.HOS.Kernel.Common;
  2. using Ryujinx.HLE.HOS.Kernel.Process;
  3. using Ryujinx.HLE.HOS.Kernel.Threading;
  4. using Ryujinx.HLE.HOS.Services;
  5. using System;
  6. namespace Ryujinx.HLE.HOS.Kernel.Ipc
  7. {
  8. class KClientSession : KSynchronizationObject
  9. {
  10. public KProcess CreatorProcess { get; }
  11. private KSession _parent;
  12. public ChannelState State { get; set; }
  13. public KClientPort ParentPort { get; }
  14. // TODO: Remove that, we need it for now to allow HLE
  15. // services implementation to work with the new IPC system.
  16. public IpcService Service { get; set; }
  17. public KClientSession(KernelContext context, KSession parent, KClientPort parentPort) : base(context)
  18. {
  19. _parent = parent;
  20. ParentPort = parentPort;
  21. parentPort?.IncrementReferenceCount();
  22. State = ChannelState.Open;
  23. CreatorProcess = context.Scheduler.GetCurrentProcess();
  24. CreatorProcess.IncrementReferenceCount();
  25. }
  26. public KernelResult SendSyncRequest(ulong customCmdBuffAddr = 0, ulong customCmdBuffSize = 0)
  27. {
  28. KThread currentThread = KernelContext.Scheduler.GetCurrentThread();
  29. KSessionRequest request = new KSessionRequest(currentThread, customCmdBuffAddr, customCmdBuffSize);
  30. KernelContext.CriticalSection.Enter();
  31. currentThread.SignaledObj = null;
  32. currentThread.ObjSyncResult = KernelResult.Success;
  33. KernelResult result = _parent.ServerSession.EnqueueRequest(request);
  34. KernelContext.CriticalSection.Leave();
  35. if (result == KernelResult.Success)
  36. {
  37. result = currentThread.ObjSyncResult;
  38. }
  39. return result;
  40. }
  41. public KernelResult SendAsyncRequest(KWritableEvent asyncEvent, ulong customCmdBuffAddr = 0, ulong customCmdBuffSize = 0)
  42. {
  43. KThread currentThread = KernelContext.Scheduler.GetCurrentThread();
  44. KSessionRequest request = new KSessionRequest(currentThread, customCmdBuffAddr, customCmdBuffSize, asyncEvent);
  45. KernelContext.CriticalSection.Enter();
  46. KernelResult result = _parent.ServerSession.EnqueueRequest(request);
  47. KernelContext.CriticalSection.Leave();
  48. return result;
  49. }
  50. public void DisconnectFromPort()
  51. {
  52. if (ParentPort != null)
  53. {
  54. ParentPort.Disconnect();
  55. ParentPort.DecrementReferenceCount();
  56. }
  57. }
  58. protected override void Destroy()
  59. {
  60. _parent.DisconnectClient();
  61. _parent.DecrementReferenceCount();
  62. if (Service is IDisposable disposableObj)
  63. {
  64. disposableObj.Dispose();
  65. }
  66. }
  67. }
  68. }