Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

netplay/tcp: generalize checkSockets() function to be usable with various polling APIs #4196

Conversation

ManManson
Copy link
Member

@ManManson ManManson commented Feb 8, 2025

The patchset introduces the following abstractions to make it easier to switch between various polling APIs in the TCP_DIRECT netcode:

  1. IDescriptorSet interface to abstract away the details of a particular polling API (select() and poll() are supported).

  2. PollEventType enumeration to be used in concrete subclasses of IDescriptorSet to describe the type of events we are interested in, when polling a given descriptor set (generally speaking, both select and poll can listen for multiple types of events simultaneously, but in our particular case we listen for only one of them at a time).

  3. SelectDescriptorSet<PollEventType> and PollDescriptorSet<PollEventType> descriptor set types which actually implement the support for select and poll APIs.

  4. checkSocketsReadable() function now makes direct use of SelectDescriptorSet(Windows, note on support below) and PollDescriptorSet(Linux/macOS/*BSD).

NOTE: We don't use poll()(WSAPoll(), to be accurate) on Windows for the time being, since it's affected by a bug in Windows versions prior to Windows 10 version 2004 (and there wasn't any prior analysis on how many potential players will be affected):

WSAPoll() function can time out on socket connection errors instead of returning an error early.

For more information on the bug, see: https://stackoverflow.com/questions/21653003/is-this-wsapoll-bug-for-non-blocking-sockets-fixed
and also https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll#remarks

Signed-off-by: Pavel Solodovnikov pavel.al.solodovnikov@gmail.com

The new naming scheme clearly conveys the purpose of the function.

Signed-off-by: Pavel Solodovnikov <pavel.al.solodovnikov@gmail.com>
@ManManson ManManson force-pushed the netsocket_lowlevel_polling_generalization branch 3 times, most recently from 89d39e3 to 2d40815 Compare February 8, 2025 21:55
@ManManson ManManson force-pushed the netsocket_lowlevel_polling_generalization branch from 2d40815 to c13b40c Compare February 9, 2025 09:18
@ManManson ManManson added this to the 4.6.0-beta1 milestone Feb 9, 2025
@ManManson ManManson requested a review from past-due February 9, 2025 09:19
@ManManson ManManson force-pushed the netsocket_lowlevel_polling_generalization branch from c13b40c to 06d6a8e Compare February 9, 2025 12:45
// `MAX_TMP_SOCKETS` for `tmp_socket_set` (also in netplay.cpp)
static constexpr size_t MAX_FDS_COUNT = MAX_CONNECTED_PLAYERS + MAX_TMP_SOCKETS;

std::array<pollfd, MAX_FDS_COUNT> fds_;
Copy link
Member

@past-due past-due Feb 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the caveat that, while this is okay as a step 1 for now (because this is only used by checkSocketsReadable), future refactoring to use PollDescriptorSet in socketThreadFunction will require this to not have a hard-coded max limit (and presumably use a std::vector). (As-is, socketThreadFunction could already exceed this limit by at least 1 due to writes to rs_socket.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, will address it in the next PR.

@ManManson ManManson force-pushed the netsocket_lowlevel_polling_generalization branch 3 times, most recently from 567033d to 29ade85 Compare February 9, 2025 22:00
…arious polling APIs

The patch introduces the following abstractions to make it easier to
switch between various polling APIs in the TCP_DIRECT netcode:

1. `IDescriptorSet` interface to abstract away the details of a
   particular polling API (`select()` and `poll()` are supported).
2. `PollEventType` enumeration to be used in concrete subclasses
   of `IDescriptorSet` to describe the type of events we are interested
   in, when polling a given descriptor set (generally speaking,
   both `select` and `poll` can listen for multiple types of events
   simultaneously, but in our particular case we listen for only
   one of them at a time).
3. `SelectDescriptorSet<PollEventType>` and
   `PollDescriptorSet<PollEventType>` descriptor set types which
   actually implement the support for `select` and `poll` APIs.
4. `checkSocketsReadable()` function now makes direct use of
   `SelectDescriptorSet`(Windows, note on support below) and
   `PollDescriptorSet`(Linux/macOS/*BSD).

NOTE: We don't use `poll()`(`WSAPoll()`, to be accurate) on Windows
for the time being, since it's affected by a bug in Windows versions
prior to Windows 10 version 2004 (and there wasn't any prior analysis
on how many potential players will be affected):

`WSAPoll()` function can time out on socket connection errors instead
of returning an error early.

For more information on the bug, see: https://stackoverflow.com/questions/21653003/is-this-wsapoll-bug-for-non-blocking-sockets-fixed
and also https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll#remarks

Signed-off-by: Pavel Solodovnikov <pavel.al.solodovnikov@gmail.com>
@ManManson ManManson force-pushed the netsocket_lowlevel_polling_generalization branch from 29ade85 to 0bf7d26 Compare February 9, 2025 22:36
@past-due past-due merged commit b05594e into Warzone2100:master Feb 10, 2025
37 checks passed
@ManManson ManManson deleted the netsocket_lowlevel_polling_generalization branch February 11, 2025 21:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants