@@ -550,20 +550,20 @@ typedef struct _socket_state {
550550
551551    /* Default timeout for new sockets */ 
552552    PyTime_t  defaulttimeout ;
553+ } socket_state ;
553554
554555#if  defined(HAVE_ACCEPT ) ||  defined(HAVE_ACCEPT4 )
555556#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 ;
558559#endif 
559560#endif 
560561
561562#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 ;
565566#endif 
566- } socket_state ;
567567
568568static  inline  void 
569569set_sock_fd (PySocketSockObject  * s , SOCKET_T  fd )
@@ -2904,16 +2904,15 @@ sock_accept_impl(PySocketSockObject *s, void *data)
29042904#endif 
29052905
29062906#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 ) {
29092908        ctx -> result  =  accept4 (get_sock_fd (s ), addr , paddrlen ,
29102909                              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 ) {
29122911            /* 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 );
29142913        }
29152914    }
2916-     if  (state -> accept4_works  ==  0 )
2915+     if  (_Py_atomic_load_int_relaxed ( & accept4_works )  ==  0 )
29172916        ctx -> result  =  accept (get_sock_fd (s ), addr , paddrlen );
29182917#else 
29192918    ctx -> result  =  accept (get_sock_fd (s ), addr , paddrlen );
@@ -2966,8 +2965,7 @@ sock_accept(PySocketSockObject *s, PyObject *Py_UNUSED(ignored))
29662965#else 
29672966
29682967#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 ))
29712969#endif 
29722970    {
29732971        if  (_Py_set_inheritable (newfd , 0 , NULL ) <  0 ) {
@@ -3388,7 +3386,6 @@ sockets the address is a tuple (ifname, proto [,pkttype [,hatype [,addr]]])");
33883386   will surely fail. */ 
33893387
33903388/*[clinic input] 
3391- @critical_section 
33923389_socket.socket.close 
33933390    self as s: self(type="PySocketSockObject *") 
33943391
@@ -3399,7 +3396,7 @@ Close the socket.  It cannot be used after this call.
33993396
34003397static  PyObject  * 
34013398_socket_socket_close_impl (PySocketSockObject  * s )
3402- /*[clinic end generated code: output=038b2418e07f6f6c input=9839a261e05bcb97 ]*/ 
3399+ /*[clinic end generated code: output=038b2418e07f6f6c input=dc487e470e55a83c ]*/ 
34033400{
34043401    SOCKET_T  fd ;
34053402    int  res ;
@@ -5428,7 +5425,7 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,
54285425
54295426#ifndef  MS_WINDOWS 
54305427#ifdef  SOCK_CLOEXEC 
5431-     int  * atomic_flag_works  =  & state -> sock_cloexec_works ;
5428+     int  * atomic_flag_works  =  & sock_cloexec_works ;
54325429#else 
54335430    int  * atomic_flag_works  =  NULL ;
54345431#endif 
@@ -5583,15 +5580,16 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto,
55835580        /* UNIX */ 
55845581        Py_BEGIN_ALLOW_THREADS 
55855582#ifdef  SOCK_CLOEXEC 
5586-         if  (state -> sock_cloexec_works  !=  0 ) {
5583+         if  (_Py_atomic_load_int_relaxed ( & sock_cloexec_works )  !=  0 ) {
55875584            fd  =  socket (family , type  | SOCK_CLOEXEC , proto );
5588-             if  (state -> sock_cloexec_works  ==  -1 ) {
5585+             if  (_Py_atomic_load_int_relaxed ( & sock_cloexec_works )  ==  -1 ) {
55895586                if  (fd  >= 0 ) {
5590-                     state -> sock_cloexec_works   =   1 ;
5587+                     _Py_atomic_store_int_relaxed ( & sock_cloexec_works ,  1 ) ;
55915588                }
5589+ 
55925590                else  if  (errno  ==  EINVAL ) {
55935591                    /* Linux older than 2.6.27 does not support SOCK_CLOEXEC */ 
5594-                     state -> sock_cloexec_works   =   0 ;
5592+                     _Py_atomic_store_int_relaxed ( & sock_cloexec_works ,  0 ) ;
55955593                    fd  =  socket (family , type , proto );
55965594                }
55975595            }
@@ -6332,7 +6330,7 @@ socket_socketpair(PyObject *self, PyObject *args)
63326330    PyObject  * res  =  NULL ;
63336331    socket_state  * state  =  get_module_state (self );
63346332#ifdef  SOCK_CLOEXEC 
6335-     int  * atomic_flag_works  =  & state -> sock_cloexec_works ;
6333+     int  * atomic_flag_works  =  & sock_cloexec_works ;
63366334#else 
63376335    int  * atomic_flag_works  =  NULL ;
63386336#endif 
@@ -6350,15 +6348,15 @@ socket_socketpair(PyObject *self, PyObject *args)
63506348    /* Create a pair of socket fds */ 
63516349    Py_BEGIN_ALLOW_THREADS 
63526350#ifdef  SOCK_CLOEXEC 
6353-     if  (state -> sock_cloexec_works  !=  0 ) {
6351+     if  (_Py_atomic_load_int_relaxed ( & sock_cloexec_works )  !=  0 ) {
63546352        ret  =  socketpair (family , type  | SOCK_CLOEXEC , proto , sv );
6355-         if  (state -> sock_cloexec_works  ==  -1 ) {
6353+         if  (_Py_atomic_load_int_relaxed ( & sock_cloexec_works )  ==  -1 ) {
63566354            if  (ret  >= 0 ) {
6357-                 state -> sock_cloexec_works   =   1 ;
6355+                 _Py_atomic_store_int_relaxed ( & sock_cloexec_works ,  1 ) ;
63586356            }
63596357            else  if  (errno  ==  EINVAL ) {
63606358                /* Linux older than 2.6.27 does not support SOCK_CLOEXEC */ 
6361-                 state -> sock_cloexec_works   =   0 ;
6359+                 _Py_atomic_store_int_relaxed ( & sock_cloexec_works ,  0 ) ;
63626360                ret  =  socketpair (family , type , proto , sv );
63636361            }
63646362        }
@@ -7466,17 +7464,8 @@ socket_exec(PyObject *m)
74667464    }
74677465
74687466    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 
74767467
7477- #ifdef  SOCK_CLOEXEC 
7478-     state -> sock_cloexec_works  =  -1 ;
7479- #endif 
7468+     _Py_atomic_store_int64_relaxed (& state -> defaulttimeout , _PYTIME_FROMSECONDS (-1 ));
74807469
74817470#define  ADD_EXC (MOD , NAME , VAR , BASE ) do {                  \
74827471    VAR = PyErr_NewException("socket." NAME, BASE, NULL);   \
0 commit comments