Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e6951c6

Browse files
committed
Issue #23618: Refactor internal_select() to prepare socket.connect() for EINTR
1 parent 391fa71 commit e6951c6

1 file changed

Lines changed: 23 additions & 13 deletions

File tree

Modules/socketmodule.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -591,19 +591,13 @@ internal_setblocking(PySocketSockObject *s, int block)
591591
return 1;
592592
}
593593

594-
/* Do a select()/poll() on the socket, if necessary (sock_timeout > 0).
595-
The argument writing indicates the direction.
596-
This does not raise an exception; we'll let our caller do that
597-
after they've reacquired the interpreter lock.
598-
Returns 1 on timeout, -1 on error, 0 otherwise. */
599594
static int
600-
internal_select(PySocketSockObject *s, int writing, _PyTime_t interval)
595+
internal_select_impl(PySocketSockObject *s, int writing, _PyTime_t interval)
601596
{
602597
int n;
603598
#ifdef HAVE_POLL
604599
struct pollfd pollfd;
605-
_PyTime_t timeout;
606-
int timeout_int;
600+
_PyTime_t ms;
607601
#else
608602
fd_set fds;
609603
struct timeval tv;
@@ -633,12 +627,11 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval)
633627
pollfd.events = writing ? POLLOUT : POLLIN;
634628

635629
/* s->sock_timeout is in seconds, timeout in ms */
636-
timeout = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING);
637-
assert(timeout <= INT_MAX);
638-
timeout_int = (int)timeout;
630+
ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING);
631+
assert(ms <= INT_MAX);
639632

640633
Py_BEGIN_ALLOW_THREADS;
641-
n = poll(&pollfd, 1, timeout_int);
634+
n = poll(&pollfd, 1, (int)ms);
642635
Py_END_ALLOW_THREADS;
643636
#else
644637
_PyTime_AsTimeval_noraise(interval, &tv, _PyTime_ROUND_CEILING);
@@ -664,6 +657,23 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval)
664657
return 0;
665658
}
666659

660+
/* Do a select()/poll() on the socket, if necessary (sock_timeout > 0).
661+
The argument writing indicates the direction.
662+
This does not raise an exception; we'll let our caller do that
663+
after they've reacquired the interpreter lock.
664+
Returns 1 on timeout, -1 on error, 0 otherwise. */
665+
static int
666+
internal_select(PySocketSockObject *s, int writing, _PyTime_t interval)
667+
{
668+
return internal_select_impl(s, writing, interval);
669+
}
670+
671+
static int
672+
internal_connect_select(PySocketSockObject *s)
673+
{
674+
return internal_select(s, 1, s->sock_timeout);
675+
}
676+
667677
/*
668678
Two macros for automatic retry of select() in case of false positives
669679
(for example, select() could indicate a socket is ready for reading
@@ -2492,7 +2502,7 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
24922502
if (s->sock_timeout > 0
24932503
&& res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) {
24942504

2495-
timeout = internal_select(s, 1, s->sock_timeout);
2505+
timeout = internal_connect_select(s);
24962506

24972507
if (timeout == 0) {
24982508
/* Bug #1019808: in case of an EINPROGRESS,

0 commit comments

Comments
 (0)