Skip to content

Commit 526c690

Browse files
authored
replace Once-guarded UnsafeCell with AtomicPtr (#6026)
1 parent 901b032 commit 526c690

1 file changed

Lines changed: 12 additions & 19 deletions

File tree

pyo3-ffi/src/datetime.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use crate::{PyLong_AsLong, PyLong_Check, PyObject_GetAttrString, Py_DecRef};
1111
use crate::{PyObject, PyObject_TypeCheck, PyTypeObject, Py_IS_TYPE, Py_None};
1212
use std::ffi::c_char;
1313
use std::ffi::c_int;
14+
use std::ffi::CStr;
1415
use 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))]
1818
use {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]
606606
pub 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
611611
pub 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

Comments
 (0)