diff options
| author | Mary-nyan <mary@mary.zone> | 2022-11-27 21:18:05 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-27 20:18:05 +0000 |
| commit | 1865ea87e538047efaf36c7a707c30390d620496 (patch) | |
| tree | 4acebf5eca8b4dd5af8572f6d3a3abaa96f2becb /Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs | |
| parent | 18b61aff59783e0e9dd01c2d45c44406a47b82a9 (diff) | |
bsd: Fix eventfd broken logic (#3647)
* bsd: Fix eventfd broken logic
This commit fix eventfd logic being broken.
The following changes were made:
- EventFd IPC definition had argument inverted
- EventFd events weren't fired correctly
- Poll logic was wrong and unfinished for eventfd
- Reintroduce workaround from #3385 but in a safer way, and spawn 4
threads.
* ipc: Rework a bit for multithreads
* Clean up debug logs
* Make server thread yield when managed lock isn't availaible
* Fix replyTargetHandle not being added in the proper locking scope
* Simplify some scopes
* Address gdkchan's comments
* Revert IPC workaround for now
* Reintroduce the EventFileDescriptor workaround
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs index 239e2434..f84e9b93 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs @@ -26,8 +26,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd _value = value; _flags = flags; - WriteEvent = new ManualResetEvent(true); - ReadEvent = new ManualResetEvent(true); + WriteEvent = new ManualResetEvent(false); + ReadEvent = new ManualResetEvent(false); + UpdateEventStates(); } public int Refcount { get; set; } @@ -38,6 +39,25 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd ReadEvent.Dispose(); } + private void ResetEventStates() + { + WriteEvent.Reset(); + ReadEvent.Reset(); + } + + private void UpdateEventStates() + { + if (_value > 0) + { + ReadEvent.Set(); + } + + if (_value != uint.MaxValue - 1) + { + WriteEvent.Set(); + } + } + public LinuxError Read(out int readSize, Span<byte> buffer) { if (buffer.Length < sizeof(ulong)) @@ -47,10 +67,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return LinuxError.EINVAL; } - ReadEvent.Reset(); - lock (_lock) { + ResetEventStates(); + ref ulong count = ref MemoryMarshal.Cast<byte, ulong>(buffer)[0]; if (_value == 0) @@ -66,6 +86,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { readSize = 0; + UpdateEventStates(); return LinuxError.EAGAIN; } } @@ -85,8 +106,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd _value = 0; } - ReadEvent.Set(); - + UpdateEventStates(); return LinuxError.SUCCESS; } } @@ -100,10 +120,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return LinuxError.EINVAL; } - WriteEvent.Reset(); - lock (_lock) { + ResetEventStates(); + if (_value > _value + count) { if (Blocking) @@ -114,6 +134,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { writeSize = 0; + UpdateEventStates(); return LinuxError.EAGAIN; } } @@ -123,8 +144,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd _value += count; Monitor.Pulse(_lock); - WriteEvent.Set(); - + UpdateEventStates(); return LinuxError.SUCCESS; } } |
