-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
gh-72894: Dynamically allocate select fd_sets on Windows based on inputs size #13842
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
base: main
Are you sure you want to change the base?
Conversation
By this PR you basically increased the memory consumption for every See the issue's comment added recently |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To test the new seqsize()
code path, I would like to see a test added where select.select()
is called with an iterable which is not a tuple
or list
, for example iter([fd])
instead of [fd]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are also missing error checks where you call seqsize()
.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase And if you don't make the requested changes, you will be put in the comfy chair! |
I have made the requested changes; please review again |
Thanks for making the requested changes! @asvetlov: please review the changes made to this pull request. |
@jdmeyer I removed the seqsize function completely and replaced calls with PySequence_Length. |
hope this pass soon. |
@andzn, please resolve the merge conflict. Thank you! |
@csabella , merge conflicts are now resolved. |
@andzn Could you sign the new CLA by clicking |
@arhadthedev done. |
do { | ||
if (((fd_set FAR *)(set))->fd_count < setsize) | ||
((fd_set FAR *)(set))->fd_array[((fd_set FAR *)(set))->fd_count++]=(fd); | ||
} while(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of the surrounding code do { ... } while (0)
?
size_t i; | ||
for (i = 0; i < setsize + 1 && fd2obj[i].sentinel >= 0; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size_t i; | |
for (i = 0; i < setsize + 1 && fd2obj[i].sentinel >= 0; i++) { | |
for (size_t i = 0; i < setsize + 1 && fd2obj[i].sentinel >= 0; i++) { |
@@ -196,7 +211,7 @@ set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) | |||
return NULL; | |||
|
|||
i = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you declare i here?
struct timeval tv, *tvp; | ||
int imax, omax, emax, max; | ||
int n; | ||
_PyTime_t timeout, deadline = 0; | ||
|
||
setsize = FD_SETSIZE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to initialize the variable where it's declared. Either declare it at this line, or move the declaration here. So the variable is never uninitialized.
return NULL; | ||
} | ||
|
||
if ((size_t)rsize > setsize) setsize = (size_t)rsize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may write: setsize = Py_MAX(setsize, (size_t)rsize);
(same for the 2 lines below). IMO it's more explicit (and how I would write it in Python).
ofdset = (fd_set*) PyMem_NEW(SOCKET, setsize + 1); | ||
efdset = (fd_set*) PyMem_NEW(SOCKET, setsize + 1); | ||
if (ifdset->fd_array == NULL || ofdset->fd_array == NULL || efdset->fd_array == NULL) { | ||
if (ifdset->fd_array) PyMem_DEL(ifdset->fd_array); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PyMem_DEL() is a alias to PyMem_Free(): use it directly.
The NULL test is useless and can be removed. PyMem_Free(NULL) is well defined, it does nothing: https://docs.python.org/dev/c-api/memory.html#c.PyMem_Free
fd_set *ifdset, *ofdset, *efdset; | ||
#if !defined(MS_WINDOWS) | ||
fd_set ifdset_stack, ofdset_stack, efdset_stack; | ||
#if !defined(SELECT_USES_HEAP) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would make the code simpler if the SELECT_USES_HEAP macro would always be defined on Windows, no?
https://bugs.python.org/issue28708