aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs')
-rw-r--r--src/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs b/src/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs
new file mode 100644
index 00000000..21a3919c
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs
@@ -0,0 +1,87 @@
+using Ryujinx.HLE.HOS.Kernel.Common;
+using System.Collections.Generic;
+
+namespace Ryujinx.HLE.HOS.Kernel.Ipc
+{
+ class KServerPort : KSynchronizationObject
+ {
+ private readonly LinkedList<KServerSession> _incomingConnections;
+ private readonly LinkedList<KLightServerSession> _lightIncomingConnections;
+
+ private readonly KPort _parent;
+
+ public bool IsLight => _parent.IsLight;
+
+ public KServerPort(KernelContext context, KPort parent) : base(context)
+ {
+ _parent = parent;
+
+ _incomingConnections = new LinkedList<KServerSession>();
+ _lightIncomingConnections = new LinkedList<KLightServerSession>();
+ }
+
+ public void EnqueueIncomingSession(KServerSession session)
+ {
+ AcceptIncomingConnection(_incomingConnections, session);
+ }
+
+ public void EnqueueIncomingLightSession(KLightServerSession session)
+ {
+ AcceptIncomingConnection(_lightIncomingConnections, session);
+ }
+
+ private void AcceptIncomingConnection<T>(LinkedList<T> list, T session)
+ {
+ KernelContext.CriticalSection.Enter();
+
+ list.AddLast(session);
+
+ if (list.Count == 1)
+ {
+ Signal();
+ }
+
+ KernelContext.CriticalSection.Leave();
+ }
+
+ public KServerSession AcceptIncomingConnection()
+ {
+ return AcceptIncomingConnection(_incomingConnections);
+ }
+
+ public KLightServerSession AcceptIncomingLightConnection()
+ {
+ return AcceptIncomingConnection(_lightIncomingConnections);
+ }
+
+ private T AcceptIncomingConnection<T>(LinkedList<T> list)
+ {
+ T session = default;
+
+ KernelContext.CriticalSection.Enter();
+
+ if (list.Count != 0)
+ {
+ session = list.First.Value;
+
+ list.RemoveFirst();
+ }
+
+ KernelContext.CriticalSection.Leave();
+
+ return session;
+ }
+
+ public override bool IsSignaled()
+ {
+ if (_parent.IsLight)
+ {
+ return _lightIncomingConnections.Count != 0;
+ }
+ else
+ {
+ return _incomingConnections.Count != 0;
+ }
+ }
+ }
+} \ No newline at end of file