EventFileDescriptorPollManager.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using Ryujinx.Common.Logging;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
  5. {
  6. class EventFileDescriptorPollManager : IPollManager
  7. {
  8. private static EventFileDescriptorPollManager _instance;
  9. public static EventFileDescriptorPollManager Instance
  10. {
  11. get
  12. {
  13. if (_instance == null)
  14. {
  15. _instance = new EventFileDescriptorPollManager();
  16. }
  17. return _instance;
  18. }
  19. }
  20. public bool IsCompatible(PollEvent evnt)
  21. {
  22. return evnt.FileDescriptor is EventFileDescriptor;
  23. }
  24. public LinuxError Poll(List<PollEvent> events, int timeoutMilliseconds, out int updatedCount)
  25. {
  26. updatedCount = 0;
  27. List<ManualResetEvent> waiters = new List<ManualResetEvent>();
  28. for (int i = 0; i < events.Count; i++)
  29. {
  30. PollEvent evnt = events[i];
  31. EventFileDescriptor socket = (EventFileDescriptor)evnt.FileDescriptor;
  32. bool isValidEvent = false;
  33. if (evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Input) ||
  34. evnt.Data.InputEvents.HasFlag(PollEventTypeMask.UrgentInput))
  35. {
  36. waiters.Add(socket.ReadEvent);
  37. isValidEvent = true;
  38. }
  39. if (evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Output))
  40. {
  41. waiters.Add(socket.WriteEvent);
  42. isValidEvent = true;
  43. }
  44. if (!isValidEvent)
  45. {
  46. Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported Poll input event type: {evnt.Data.InputEvents}");
  47. return LinuxError.EINVAL;
  48. }
  49. }
  50. int index = WaitHandle.WaitAny(waiters.ToArray(), timeoutMilliseconds);
  51. if (index != WaitHandle.WaitTimeout)
  52. {
  53. for (int i = 0; i < events.Count; i++)
  54. {
  55. PollEvent evnt = events[i];
  56. EventFileDescriptor socket = (EventFileDescriptor)evnt.FileDescriptor;
  57. if ((evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Input) ||
  58. evnt.Data.InputEvents.HasFlag(PollEventTypeMask.UrgentInput))
  59. && socket.ReadEvent.WaitOne(0))
  60. {
  61. waiters.Add(socket.ReadEvent);
  62. }
  63. if ((evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Output))
  64. && socket.WriteEvent.WaitOne(0))
  65. {
  66. waiters.Add(socket.WriteEvent);
  67. }
  68. }
  69. }
  70. else
  71. {
  72. return LinuxError.ETIMEDOUT;
  73. }
  74. return LinuxError.SUCCESS;
  75. }
  76. }
  77. }