Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
71694d5c
Kaydet (Commit)
71694d5c
authored
Mar 28, 2015
tarafından
Victor Stinner
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #22117: The socket module uses _PyTime_t timestamp for timeouts
üst
95e9cef6
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
105 additions
and
72 deletions
+105
-72
socketmodule.c
Modules/socketmodule.c
+104
-71
socketmodule.h
Modules/socketmodule.h
+1
-1
No files found.
Modules/socketmodule.c
Dosyayı görüntüle @
71694d5c
...
...
@@ -460,7 +460,7 @@ static PyTypeObject sock_type;
#else
/* If there's no timeout left, we don't have to call select, so it's a safe,
* little white lie. */
#define IS_SELECTABLE(s) (_PyIsSelectable_fd((s)->sock_fd) || (s)->sock_timeout <= 0
.0
)
#define IS_SELECTABLE(s) (_PyIsSelectable_fd((s)->sock_fd) || (s)->sock_timeout <= 0)
#endif
static
PyObject
*
...
...
@@ -597,9 +597,17 @@ internal_setblocking(PySocketSockObject *s, int block)
after they've reacquired the interpreter lock.
Returns 1 on timeout, -1 on error, 0 otherwise. */
static
int
internal_select_ex
(
PySocketSockObject
*
s
,
int
writing
,
double
interval
)
internal_select_ex
(
PySocketSockObject
*
s
,
int
writing
,
_PyTime_t
interval
)
{
int
n
;
#ifdef HAVE_POLL
struct
pollfd
pollfd
;
_PyTime_t
timeout
;
int
timeout_int
;
#else
fd_set
fds
;
struct
timeval
tv
;
#endif
#ifdef WITH_THREAD
/* must be called with the GIL held */
...
...
@@ -607,7 +615,7 @@ internal_select_ex(PySocketSockObject *s, int writing, double interval)
#endif
/* Nothing to do unless we're in timeout mode (not non-blocking) */
if
(
s
->
sock_timeout
<=
0
.
0
)
if
(
s
->
sock_timeout
<=
0
)
return
0
;
/* Guard against closed socket */
...
...
@@ -615,33 +623,28 @@ internal_select_ex(PySocketSockObject *s, int writing, double interval)
return
0
;
/* Handling this condition here simplifies the select loops */
if
(
interval
<
0
.
0
)
if
(
interval
<
0
)
return
1
;
/* Prefer poll, if available, since you can poll() any fd
* which can't be done with select(). */
#ifdef HAVE_POLL
{
struct
pollfd
pollfd
;
int
timeout
;
pollfd
.
fd
=
s
->
sock_fd
;
pollfd
.
events
=
writing
?
POLLOUT
:
POLLIN
;
/* s->sock_timeout is in seconds, timeout in ms */
timeout
=
(
int
)(
interval
*
1000
+
0
.
5
);
timeout
=
_PyTime_AsMilliseconds
(
interval
,
_PyTime_ROUND_UP
);
assert
(
timeout
<=
INT_MAX
);
timeout_int
=
(
int
)
timeout
;
Py_BEGIN_ALLOW_THREADS
;
n
=
poll
(
&
pollfd
,
1
,
timeou
t
);
n
=
poll
(
&
pollfd
,
1
,
timeout_in
t
);
Py_END_ALLOW_THREADS
;
}
#else
{
/* Construct the arguments to select */
fd_set
fds
;
struct
timeval
tv
;
tv
.
tv_sec
=
(
int
)
interval
;
tv
.
tv_usec
=
(
int
)((
interval
-
tv
.
tv_sec
)
*
1e6
);
/* conversion was already checked for overflow when
the timeout was set */
(
void
)
_PyTime_AsTimeval
(
interval
,
&
tv
,
_PyTime_ROUND_UP
);
FD_ZERO
(
&
fds
);
FD_SET
(
s
->
sock_fd
,
&
fds
);
...
...
@@ -654,7 +657,6 @@ internal_select_ex(PySocketSockObject *s, int writing, double interval)
n
=
select
(
Py_SAFE_DOWNCAST
(
s
->
sock_fd
+
1
,
SOCKET_T
,
int
),
&
fds
,
NULL
,
NULL
,
&
tv
);
Py_END_ALLOW_THREADS
;
}
#endif
if
(
n
<
0
)
...
...
@@ -694,14 +696,11 @@ internal_select(PySocketSockObject *s, int writing)
#define BEGIN_SELECT_LOOP(s) \
{ \
_PyTime_timeval now, deadline = {0, 0}; \
double interval = s->sock_timeout; \
int has_timeout = s->sock_timeout > 0.0; \
if (has_timeout) { \
_PyTime_monotonic(&now); \
deadline = now; \
_PyTime_AddDouble(&deadline, s->sock_timeout, _PyTime_ROUND_UP); \
} \
_PyTime_t deadline = 0; \
_PyTime_t interval = s->sock_timeout; \
int has_timeout = (s->sock_timeout > 0); \
if (has_timeout) \
deadline = _PyTime_GetMonotonicClock() + interval; \
while (1) { \
errno = 0; \
...
...
@@ -709,14 +708,13 @@ internal_select(PySocketSockObject *s, int writing)
if (!has_timeout || \
(!CHECK_ERRNO(EWOULDBLOCK) && !CHECK_ERRNO(EAGAIN))) \
break; \
_PyTime_monotonic(&now); \
interval = _PyTime_INTERVAL(now, deadline); \
interval = deadline - _PyTime_GetMonotonicClock(); \
} \
} \
/* Initialize a new socket object. */
static
double
defaulttimeout
=
-
1
.
0
;
/* Default timeout for new sockets */
static
_PyTime_t
defaulttimeout
=
-
1
;
/* Default timeout for new sockets */
static
void
init_sockobject
(
PySocketSockObject
*
s
,
...
...
@@ -730,12 +728,12 @@ init_sockobject(PySocketSockObject *s,
s
->
errorhandler
=
&
set_error
;
#ifdef SOCK_NONBLOCK
if
(
type
&
SOCK_NONBLOCK
)
s
->
sock_timeout
=
0
.
0
;
s
->
sock_timeout
=
0
;
else
#endif
{
s
->
sock_timeout
=
defaulttimeout
;
if
(
defaulttimeout
>=
0
.
0
)
if
(
defaulttimeout
>=
0
)
internal_setblocking
(
s
,
0
);
}
...
...
@@ -2168,7 +2166,7 @@ sock_setblocking(PySocketSockObject *s, PyObject *arg)
if
(
block
==
-
1
&&
PyErr_Occurred
())
return
NULL
;
s
->
sock_timeout
=
block
?
-
1
.
0
:
0
.
0
;
s
->
sock_timeout
=
block
?
-
1
:
0
;
internal_setblocking
(
s
,
block
);
Py_INCREF
(
Py_None
);
...
...
@@ -2182,6 +2180,43 @@ Set the socket to blocking (flag is true) or non-blocking (false).\n\
setblocking(True) is equivalent to settimeout(None);
\n
\
setblocking(False) is equivalent to settimeout(0.0)."
);
static
int
socket_parse_timeout
(
_PyTime_t
*
timeout
,
PyObject
*
timeout_obj
)
{
#ifdef MS_WINDOWS
struct
timeval
tv
;
#endif
int
overflow
=
0
;
if
(
timeout_obj
==
Py_None
)
{
*
timeout
=
-
1
;
return
0
;
}
if
(
_PyTime_FromSecondsObject
(
timeout
,
timeout_obj
,
_PyTime_ROUND_UP
)
<
0
)
return
-
1
;
if
(
*
timeout
<
0
)
{
PyErr_SetString
(
PyExc_ValueError
,
"Timeout value out of range"
);
return
-
1
;
}
#ifdef MS_WINDOWS
overflow
=
(
_PyTime_AsTimeval
(
timeout
,
&
tv
,
_PyTime_ROUND_UP
)
<
0
);
#endif
#ifndef HAVE_POLL
timeout
=
_PyTime_AsMilliseconds
(
timeout
,
_PyTime_ROUND_UP
);
overflow
=
(
timeout
>
INT_MAX
);
#endif
if
(
overflow
)
{
PyErr_SetString
(
PyExc_OverflowError
,
"timeout doesn't fit into C timeval"
);
return
-
1
;
}
return
0
;
}
/* s.settimeout(timeout) method. Argument:
None -- no timeout, blocking mode; same as setblocking(True)
0.0 -- non-blocking mode; same as setblocking(False)
...
...
@@ -2191,22 +2226,13 @@ setblocking(False) is equivalent to settimeout(0.0).");
static
PyObject
*
sock_settimeout
(
PySocketSockObject
*
s
,
PyObject
*
arg
)
{
double
timeout
;
_PyTime_t
timeout
;
if
(
arg
==
Py_None
)
timeout
=
-
1
.
0
;
else
{
timeout
=
PyFloat_AsDouble
(
arg
);
if
(
timeout
<
0
.
0
)
{
if
(
!
PyErr_Occurred
())
PyErr_SetString
(
PyExc_ValueError
,
"Timeout value out of range"
);
if
(
socket_parse_timeout
(
&
timeout
,
arg
)
<
0
)
return
NULL
;
}
}
s
->
sock_timeout
=
timeout
;
internal_setblocking
(
s
,
timeout
<
0
.
0
);
internal_setblocking
(
s
,
timeout
<
0
);
Py_INCREF
(
Py_None
);
return
Py_None
;
...
...
@@ -2225,12 +2251,14 @@ Setting a timeout of zero is the same as setblocking(0).");
static
PyObject
*
sock_gettimeout
(
PySocketSockObject
*
s
)
{
if
(
s
->
sock_timeout
<
0
.
0
)
{
if
(
s
->
sock_timeout
<
0
)
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
else
return
PyFloat_FromDouble
(
s
->
sock_timeout
);
else
{
double
seconds
=
_PyTime_AsSecondsDouble
(
s
->
sock_timeout
);
return
PyFloat_FromDouble
(
seconds
);
}
}
PyDoc_STRVAR
(
gettimeout_doc
,
...
...
@@ -2409,27 +2437,28 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
{
int
res
,
timeout
;
timeout
=
0
;
Py_BEGIN_ALLOW_THREADS
res
=
connect
(
s
->
sock_fd
,
addr
,
addrlen
);
Py_END_ALLOW_THREADS
#ifdef MS_WINDOWS
if
(
s
->
sock_timeout
>
0
.
0
if
(
s
->
sock_timeout
>
0
&&
res
<
0
&&
WSAGetLastError
()
==
WSAEWOULDBLOCK
&&
IS_SELECTABLE
(
s
))
{
/* This is a mess. Best solution: trust select */
fd_set
fds
;
fd_set
fds_exc
;
struct
timeval
tv
;
int
conv
;
/* conversion was already checked for overflow when
the timeout was set */
(
void
)
_PyTime_AsTimeval
(
s
->
sock_timeout
,
&
tv
,
_PyTime_ROUND_UP
);
Py_BEGIN_ALLOW_THREADS
tv
.
tv_sec
=
(
int
)
s
->
sock_timeout
;
tv
.
tv_usec
=
(
int
)((
s
->
sock_timeout
-
tv
.
tv_sec
)
*
1e6
);
FD_ZERO
(
&
fds
);
FD_SET
(
s
->
sock_fd
,
&
fds
);
FD_ZERO
(
&
fds_exc
);
...
...
@@ -2469,7 +2498,7 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
#else
if
(
s
->
sock_timeout
>
0
.
0
if
(
s
->
sock_timeout
>
0
&&
res
<
0
&&
errno
==
EINPROGRESS
&&
IS_SELECTABLE
(
s
))
{
timeout
=
internal_select
(
s
,
1
);
...
...
@@ -2498,6 +2527,7 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
#endif
*
timeoutp
=
timeout
;
assert
(
res
>=
0
);
return
res
;
}
...
...
@@ -2520,8 +2550,11 @@ sock_connect(PySocketSockObject *s, PyObject *addro)
PyErr_SetString
(
socket_timeout
,
"timed out"
);
return
NULL
;
}
if
(
res
!=
0
)
if
(
res
<
0
)
return
NULL
;
if
(
res
!=
0
)
{
return
s
->
errorhandler
();
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
...
...
@@ -2548,6 +2581,9 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro)
res
=
internal_connect
(
s
,
SAS2SA
(
&
addrbuf
),
addrlen
,
&
timeout
);
if
(
res
<
0
)
return
NULL
;
/* Signals are not errors (though they may raise exceptions). Adapted
from PyErr_SetFromErrnoWithFilenameObject(). */
if
(
res
==
EINTR
&&
PyErr_CheckSignals
())
...
...
@@ -3967,10 +4003,14 @@ static PyMemberDef sock_memberlist[] = {
{
"family"
,
T_INT
,
offsetof
(
PySocketSockObject
,
sock_family
),
READONLY
,
"the socket family"
},
{
"type"
,
T_INT
,
offsetof
(
PySocketSockObject
,
sock_type
),
READONLY
,
"the socket type"
},
{
"proto"
,
T_INT
,
offsetof
(
PySocketSockObject
,
sock_proto
),
READONLY
,
"the socket protocol"
},
{
"timeout"
,
T_DOUBLE
,
offsetof
(
PySocketSockObject
,
sock_timeout
),
READONLY
,
"the socket timeout"
},
{
0
},
};
static
PyGetSetDef
sock_getsetlist
[]
=
{
{
"timeout"
,
(
getter
)
sock_gettimeout
,
NULL
,
PyDoc_STR
(
"the socket timeout"
)},
{
NULL
}
/* sentinel */
};
/* Deallocate a socket object in response to the last Py_DECREF().
First close the file description. */
...
...
@@ -4034,7 +4074,7 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
new
=
type
->
tp_alloc
(
type
,
0
);
if
(
new
!=
NULL
)
{
((
PySocketSockObject
*
)
new
)
->
sock_fd
=
-
1
;
((
PySocketSockObject
*
)
new
)
->
sock_timeout
=
-
1
.
0
;
((
PySocketSockObject
*
)
new
)
->
sock_timeout
=
-
1
;
((
PySocketSockObject
*
)
new
)
->
errorhandler
=
&
set_error
;
}
return
new
;
...
...
@@ -4217,7 +4257,7 @@ static PyTypeObject sock_type = {
0
,
/* tp_iternext */
sock_methods
,
/* tp_methods */
sock_memberlist
,
/* tp_members */
0
,
/* tp_getset */
sock_getsetlist
,
/* tp_getset */
0
,
/* tp_base */
0
,
/* tp_dict */
0
,
/* tp_descr_get */
...
...
@@ -5540,12 +5580,14 @@ Get host and port for a sockaddr.");
static
PyObject
*
socket_getdefaulttimeout
(
PyObject
*
self
)
{
if
(
defaulttimeout
<
0
.
0
)
{
if
(
defaulttimeout
<
0
)
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
else
return
PyFloat_FromDouble
(
defaulttimeout
);
else
{
double
seconds
=
_PyTime_AsSecondsDouble
(
defaulttimeout
);
return
PyFloat_FromDouble
(
seconds
);
}
}
PyDoc_STRVAR
(
getdefaulttimeout_doc
,
...
...
@@ -5558,19 +5600,10 @@ When the socket module is first imported, the default is None.");
static
PyObject
*
socket_setdefaulttimeout
(
PyObject
*
self
,
PyObject
*
arg
)
{
double
timeout
;
_PyTime_t
timeout
;
if
(
arg
==
Py_None
)
timeout
=
-
1
.
0
;
else
{
timeout
=
PyFloat_AsDouble
(
arg
);
if
(
timeout
<
0
.
0
)
{
if
(
!
PyErr_Occurred
())
PyErr_SetString
(
PyExc_ValueError
,
"Timeout value out of range"
);
if
(
socket_parse_timeout
(
&
timeout
,
arg
)
<
0
)
return
NULL
;
}
}
defaulttimeout
=
timeout
;
...
...
Modules/socketmodule.h
Dosyayı görüntüle @
71694d5c
...
...
@@ -174,7 +174,7 @@ typedef struct {
PyObject
*
(
*
errorhandler
)(
void
);
/* Error handler; checks
errno, returns NULL and
sets a Python exception */
double
sock_timeout
;
/* Operation timeout in seconds;
_PyTime_t
sock_timeout
;
/* Operation timeout in seconds;
0.0 means non-blocking */
}
PySocketSockObject
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment