@@ -550,20 +550,20 @@ typedef struct _socket_state {
550
550
551
551
/* Default timeout for new sockets */
552
552
PyTime_t defaulttimeout ;
553
+ } socket_state ;
553
554
554
555
#if defined(HAVE_ACCEPT ) || defined(HAVE_ACCEPT4 )
555
556
#if defined(HAVE_ACCEPT4 ) && defined(SOCK_CLOEXEC )
556
- /* accept4() is available on Linux 2.6.28+ and glibc 2.10 */
557
- int accept4_works ;
557
+ /* accept4() is available on Linux 2.6.28+ and glibc 2.10 */
558
+ static int accept4_works = -1 ;
558
559
#endif
559
560
#endif
560
561
561
562
#ifdef SOCK_CLOEXEC
562
- /* socket() and socketpair() fail with EINVAL on Linux kernel older
563
- * than 2.6.27 if SOCK_CLOEXEC flag is set in the socket type. */
564
- int sock_cloexec_works ;
563
+ /* socket() and socketpair() fail with EINVAL on Linux kernel older
564
+ * than 2.6.27 if SOCK_CLOEXEC flag is set in the socket type. */
565
+ static int sock_cloexec_works = -1 ;
565
566
#endif
566
- } socket_state ;
567
567
568
568
static inline void
569
569
set_sock_fd (PySocketSockObject * s , SOCKET_T fd )
@@ -2904,16 +2904,15 @@ sock_accept_impl(PySocketSockObject *s, void *data)
2904
2904
#endif
2905
2905
2906
2906
#if defined(HAVE_ACCEPT4 ) && defined(SOCK_CLOEXEC )
2907
- socket_state * state = s -> state ;
2908
- if (state -> accept4_works != 0 ) {
2907
+ if (_Py_atomic_load_int_relaxed (& accept4_works ) != 0 ) {
2909
2908
ctx -> result = accept4 (get_sock_fd (s ), addr , paddrlen ,
2910
2909
SOCK_CLOEXEC );
2911
- if (ctx -> result == INVALID_SOCKET && state -> accept4_works == -1 ) {
2910
+ if (ctx -> result == INVALID_SOCKET && _Py_atomic_load_int_relaxed ( & accept4_works ) == -1 ) {
2912
2911
/* On Linux older than 2.6.28, accept4() fails with ENOSYS */
2913
- state -> accept4_works = ( errno != ENOSYS );
2912
+ _Py_atomic_store_int_relaxed ( & accept4_works , errno != ENOSYS );
2914
2913
}
2915
2914
}
2916
- if (state -> accept4_works == 0 )
2915
+ if (_Py_atomic_load_int_relaxed ( & accept4_works ) == 0 )
2917
2916
ctx -> result = accept (get_sock_fd (s ), addr , paddrlen );
2918
2917
#else
2919
2918
ctx -> result = accept (get_sock_fd (s ), addr , paddrlen );
@@ -2966,8 +2965,7 @@ sock_accept(PySocketSockObject *s, PyObject *Py_UNUSED(ignored))
2966
2965
#else
2967
2966
2968
2967
#if defined(HAVE_ACCEPT4 ) && defined(SOCK_CLOEXEC )
2969
- socket_state * state = s -> state ;
2970
- if (!state -> accept4_works )
2968
+ if (!_Py_atomic_load_int_relaxed (& accept4_works ))
2971
2969
#endif
2972
2970
{
2973
2971
if (_Py_set_inheritable (newfd , 0 , NULL ) < 0 ) {
@@ -5428,7 +5426,7 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,
5428
5426
5429
5427
#ifndef MS_WINDOWS
5430
5428
#ifdef SOCK_CLOEXEC
5431
- int * atomic_flag_works = & state -> sock_cloexec_works ;
5429
+ int * atomic_flag_works = & sock_cloexec_works ;
5432
5430
#else
5433
5431
int * atomic_flag_works = NULL ;
5434
5432
#endif
@@ -5583,15 +5581,16 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,
5583
5581
/* UNIX */
5584
5582
Py_BEGIN_ALLOW_THREADS
5585
5583
#ifdef SOCK_CLOEXEC
5586
- if (state -> sock_cloexec_works != 0 ) {
5584
+ if (_Py_atomic_load_int_relaxed ( & sock_cloexec_works ) != 0 ) {
5587
5585
fd = socket (family , type | SOCK_CLOEXEC , proto );
5588
- if (state -> sock_cloexec_works == -1 ) {
5586
+ if (_Py_atomic_load_int_relaxed ( & sock_cloexec_works ) == -1 ) {
5589
5587
if (fd >= 0 ) {
5590
- state -> sock_cloexec_works = 1 ;
5588
+ _Py_atomic_store_int_relaxed ( & sock_cloexec_works , 1 ) ;
5591
5589
}
5590
+
5592
5591
else if (errno == EINVAL ) {
5593
5592
/* Linux older than 2.6.27 does not support SOCK_CLOEXEC */
5594
- state -> sock_cloexec_works = 0 ;
5593
+ _Py_atomic_store_int_relaxed ( & sock_cloexec_works , 0 ) ;
5595
5594
fd = socket (family , type , proto );
5596
5595
}
5597
5596
}
@@ -6332,7 +6331,7 @@ socket_socketpair(PyObject *self, PyObject *args)
6332
6331
PyObject * res = NULL ;
6333
6332
socket_state * state = get_module_state (self );
6334
6333
#ifdef SOCK_CLOEXEC
6335
- int * atomic_flag_works = & state -> sock_cloexec_works ;
6334
+ int * atomic_flag_works = & sock_cloexec_works ;
6336
6335
#else
6337
6336
int * atomic_flag_works = NULL ;
6338
6337
#endif
@@ -6350,15 +6349,15 @@ socket_socketpair(PyObject *self, PyObject *args)
6350
6349
/* Create a pair of socket fds */
6351
6350
Py_BEGIN_ALLOW_THREADS
6352
6351
#ifdef SOCK_CLOEXEC
6353
- if (state -> sock_cloexec_works != 0 ) {
6352
+ if (_Py_atomic_load_int_relaxed ( & sock_cloexec_works ) != 0 ) {
6354
6353
ret = socketpair (family , type | SOCK_CLOEXEC , proto , sv );
6355
- if (state -> sock_cloexec_works == -1 ) {
6354
+ if (_Py_atomic_load_int_relaxed ( & sock_cloexec_works ) == -1 ) {
6356
6355
if (ret >= 0 ) {
6357
- state -> sock_cloexec_works = 1 ;
6356
+ _Py_atomic_store_int_relaxed ( & sock_cloexec_works , 1 ) ;
6358
6357
}
6359
6358
else if (errno == EINVAL ) {
6360
6359
/* Linux older than 2.6.27 does not support SOCK_CLOEXEC */
6361
- state -> sock_cloexec_works = 0 ;
6360
+ _Py_atomic_store_int_relaxed ( & sock_cloexec_works , 0 ) ;
6362
6361
ret = socketpair (family , type , proto , sv );
6363
6362
}
6364
6363
}
@@ -7466,17 +7465,8 @@ socket_exec(PyObject *m)
7466
7465
}
7467
7466
7468
7467
socket_state * state = get_module_state (m );
7469
- state -> defaulttimeout = _PYTIME_FROMSECONDS (-1 );
7470
-
7471
- #if defined(HAVE_ACCEPT ) || defined(HAVE_ACCEPT4 )
7472
- #if defined(HAVE_ACCEPT4 ) && defined(SOCK_CLOEXEC )
7473
- state -> accept4_works = -1 ;
7474
- #endif
7475
- #endif
7476
7468
7477
- #ifdef SOCK_CLOEXEC
7478
- state -> sock_cloexec_works = -1 ;
7479
- #endif
7469
+ _Py_atomic_store_int64_relaxed (& state -> defaulttimeout , _PYTIME_FROMSECONDS (-1 ));
7480
7470
7481
7471
#define ADD_EXC (MOD , NAME , VAR , BASE ) do { \
7482
7472
VAR = PyErr_NewException("socket." NAME, BASE, NULL); \
0 commit comments