@@ -235,7 +235,7 @@ should_audit(PyInterpreterState *interp)
235235 return 0 ;
236236 }
237237 return (interp -> runtime -> audit_hooks .head
238- || interp -> audit_hooks
238+ || FT_ATOMIC_LOAD_PTR_ACQUIRE ( interp -> audit_hooks )
239239 || PyDTrace_AUDIT_ENABLED ());
240240}
241241
@@ -305,13 +305,14 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
305305 }
306306
307307 /* Call interpreter hooks */
308- if (is -> audit_hooks ) {
308+ PyObject * audit_hooks = FT_ATOMIC_LOAD_PTR_ACQUIRE (is -> audit_hooks );
309+ if (audit_hooks ) {
309310 eventName = PyUnicode_FromString (event );
310311 if (!eventName ) {
311312 goto exit ;
312313 }
313314
314- hooks = PyObject_GetIter (is -> audit_hooks );
315+ hooks = PyObject_GetIter (audit_hooks );
315316 if (!hooks ) {
316317 goto exit ;
317318 }
@@ -535,20 +536,29 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook)
535536 }
536537
537538 PyInterpreterState * interp = tstate -> interp ;
539+ PyMutex mutex = interp -> audit_hooks_mutex ;
540+ PyMutex_Lock (& mutex );
541+
538542 if (interp -> audit_hooks == NULL ) {
539- interp -> audit_hooks = PyList_New (0 );
540- if (interp -> audit_hooks == NULL ) {
541- return NULL ;
543+ PyObject * new_list = PyList_New (0 );
544+ if (new_list == NULL ) {
545+ goto error ;
542546 }
543547 /* Avoid having our list of hooks show up in the GC module */
544- PyObject_GC_UnTrack (interp -> audit_hooks );
548+ PyObject_GC_UnTrack (new_list );
549+ FT_ATOMIC_STORE_PTR_RELEASE (interp -> audit_hooks , new_list );
545550 }
546551
547552 if (PyList_Append (interp -> audit_hooks , hook ) < 0 ) {
548- return NULL ;
553+ goto error ;
549554 }
550555
556+ PyMutex_Unlock (& mutex );
551557 Py_RETURN_NONE ;
558+
559+ error :
560+ PyMutex_Unlock (& mutex );
561+ return NULL ;
552562}
553563
554564/*[clinic input]
0 commit comments