@@ -11,9 +11,9 @@ use crate::{PyLong_AsLong, PyLong_Check, PyObject_GetAttrString, Py_DecRef};
1111use crate :: { PyObject , PyObject_TypeCheck , PyTypeObject , Py_IS_TYPE , Py_None } ;
1212use std:: ffi:: c_char;
1313use std:: ffi:: c_int;
14+ use std:: ffi:: CStr ;
1415use std:: ptr;
15- use std:: sync:: Once ;
16- use std:: { cell:: UnsafeCell , ffi:: CStr } ;
16+ use std:: sync:: atomic:: { AtomicPtr , Ordering } ;
1717#[ cfg( not( PyPy ) ) ]
1818use { crate :: Py_hash_t , std:: ffi:: c_uchar} ;
1919// Type struct wrappers
@@ -604,12 +604,12 @@ pub const PyDateTime_CAPSULE_NAME: &CStr = c"datetime.datetime_CAPI";
604604/// `PyDateTime_IMPORT` is called
605605#[ inline]
606606pub unsafe fn PyDateTimeAPI ( ) -> * mut PyDateTime_CAPI {
607- * PyDateTimeAPI_impl . ptr . get ( )
607+ PyDateTimeAPI_impl . load ( core :: sync :: atomic :: Ordering :: SeqCst )
608608}
609609
610610/// Populates the `PyDateTimeAPI` object
611611pub unsafe fn PyDateTime_IMPORT ( ) {
612- if ! PyDateTimeAPI_impl . once . is_completed ( ) {
612+ if PyDateTimeAPI_impl . load ( Ordering :: SeqCst ) . is_null ( ) {
613613 // PyPy expects the C-API to be initialized via PyDateTime_Import, so trying to use
614614 // `PyCapsule_Import` will behave unexpectedly in pypy.
615615 #[ cfg( PyPy ) ]
@@ -624,11 +624,13 @@ pub unsafe fn PyDateTime_IMPORT() {
624624 }
625625
626626 // Protect against race conditions when the datetime API is concurrently
627- // initialized in multiple threads. UnsafeCell.get() cannot panic so this
628- // won't panic either.
629- PyDateTimeAPI_impl . once . call_once ( || {
630- * PyDateTimeAPI_impl . ptr . get ( ) = py_datetime_c_api;
631- } ) ;
627+ // initialized in multiple threads.
628+ let _ = PyDateTimeAPI_impl . compare_exchange (
629+ ptr:: null_mut ( ) ,
630+ py_datetime_c_api,
631+ Ordering :: SeqCst ,
632+ Ordering :: SeqCst ,
633+ ) ;
632634 }
633635}
634636
@@ -839,13 +841,4 @@ extern_libpython! {
839841
840842// Rust specific implementation details
841843
842- struct PyDateTimeAPISingleton {
843- once : Once ,
844- ptr : UnsafeCell < * mut PyDateTime_CAPI > ,
845- }
846- unsafe impl Sync for PyDateTimeAPISingleton { }
847-
848- static PyDateTimeAPI_impl : PyDateTimeAPISingleton = PyDateTimeAPISingleton {
849- once : Once :: new ( ) ,
850- ptr : UnsafeCell :: new ( ptr:: null_mut ( ) ) ,
851- } ;
844+ static PyDateTimeAPI_impl : AtomicPtr < PyDateTime_CAPI > = AtomicPtr :: new ( ptr:: null_mut ( ) ) ;
0 commit comments