[Python-checkins] cpython: Issue #23618: Enhance EINTR handling in socket.connect()
victor.stinner
python-checkins at python.org
Tue Mar 31 22:24:03 CEST 2015
https://hg.python.org/cpython/rev/7ed567ad8b4c
changeset: 95336:7ed567ad8b4c
user: Victor Stinner <victor.stinner at gmail.com>
date: Tue Mar 31 22:03:59 2015 +0200
summary:
Issue #23618: Enhance EINTR handling in socket.connect()
Call PyErr_CheckSignals() immediatly if connect() or select() fails with EINTR
in internal_connect().
Refactor also the code to limit indentaton and make it more readable.
files:
Modules/socketmodule.c | 78 +++++++++++++++--------------
1 files changed, 40 insertions(+), 38 deletions(-)
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -2461,52 +2461,54 @@
# define TIMEOUT_ERR EWOULDBLOCK
#endif
- int res, err, in_progress, timeout;
-
- timeout = 0;
+ int res, err, wait_connect, timeout;
+ socklen_t res_size;
+
+ *timeoutp = 0;
Py_BEGIN_ALLOW_THREADS
res = connect(s->sock_fd, addr, addrlen);
Py_END_ALLOW_THREADS
- if (res < 0)
- err = GET_ERROR;
- else
- err = res;
- in_progress = (err == IN_PROGRESS_ERR);
-
- if (s->sock_timeout > 0 && in_progress && IS_SELECTABLE(s)) {
- timeout = internal_connect_select(s);
-
- if (timeout == 1) {
- /* timed out */
- err = TIMEOUT_ERR;
- }
- else if (timeout == 0) {
- socklen_t res_size = sizeof res;
- if (!getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR,
- (void *)&res, &res_size)) {
- if (res == EISCONN)
- res = 0;
- err = res;
- }
- else {
- /* getsockopt() failed */
- err = GET_ERROR;
- }
- }
- else {
- /* select() failed */
- err = GET_ERROR;
- }
- }
- *timeoutp = timeout;
-
+ if (!res) {
+ /* connect() succeeded, the socket is connected */
+ return 0;
+ }
+
+ err = GET_ERROR;
if (err == EINTR && PyErr_CheckSignals())
return -1;
- assert(err >= 0);
- return err;
+ wait_connect = (s->sock_timeout > 0 && err == IN_PROGRESS_ERR
+ && IS_SELECTABLE(s));
+ if (!wait_connect)
+ return err;
+
+ timeout = internal_connect_select(s);
+ if (timeout == -1) {
+ /* select() failed */
+ err = GET_ERROR;
+ if (err == EINTR && PyErr_CheckSignals())
+ return -1;
+ return err;
+ }
+
+ if (timeout == 1) {
+ /* select() timed out */
+ *timeoutp = 1;
+ return TIMEOUT_ERR;
+ }
+
+ res_size = sizeof res;
+ if (getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR,
+ (void *)&res, &res_size)) {
+ /* getsockopt() failed */
+ return GET_ERROR;
+ }
+
+ if (res == EISCONN)
+ return 0;
+ return res;
#undef GET_ERROR
#undef IN_PROGRESS_ERR
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list