@@ -236,7 +236,7 @@ should_audit(PyInterpreterState *interp)
236236 return 0 ;
237237 }
238238 return (interp -> runtime -> audit_hooks .head
239- || interp -> audit_hooks
239+ || FT_ATOMIC_LOAD_PTR_ACQUIRE ( interp -> audit_hooks )
240240 || PyDTrace_AUDIT_ENABLED ());
241241}
242242
@@ -306,13 +306,14 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
306306 }
307307
308308 /* Call interpreter hooks */
309- if (is -> audit_hooks ) {
309+ PyObject * audit_hooks = FT_ATOMIC_LOAD_PTR_ACQUIRE (is -> audit_hooks );
310+ if (audit_hooks ) {
310311 eventName = PyUnicode_FromString (event );
311312 if (!eventName ) {
312313 goto exit ;
313314 }
314315
315- hooks = PyObject_GetIter (is -> audit_hooks );
316+ hooks = PyObject_GetIter (audit_hooks );
316317 if (!hooks ) {
317318 goto exit ;
318319 }
@@ -536,20 +537,29 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook)
536537 }
537538
538539 PyInterpreterState * interp = tstate -> interp ;
540+ PyMutex mutex = interp -> audit_hooks_mutex ;
541+ PyMutex_Lock (& mutex );
542+
539543 if (interp -> audit_hooks == NULL ) {
540- interp -> audit_hooks = PyList_New (0 );
541- if (interp -> audit_hooks == NULL ) {
542- return NULL ;
544+ PyObject * new_list = PyList_New (0 );
545+ if (new_list == NULL ) {
546+ goto error ;
543547 }
544548 /* Avoid having our list of hooks show up in the GC module */
545- PyObject_GC_UnTrack (interp -> audit_hooks );
549+ PyObject_GC_UnTrack (new_list );
550+ FT_ATOMIC_STORE_PTR_RELEASE (interp -> audit_hooks , new_list );
546551 }
547552
548553 if (PyList_Append (interp -> audit_hooks , hook ) < 0 ) {
549- return NULL ;
554+ goto error ;
550555 }
551556
557+ PyMutex_Unlock (& mutex );
552558 Py_RETURN_NONE ;
559+
560+ error :
561+ PyMutex_Unlock (& mutex );
562+ return NULL ;
553563}
554564
555565/*[clinic input]
0 commit comments