summaryrefslogtreecommitdiffstats
path: root/Python/sysmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/sysmodule.c')
-rw-r--r--Python/sysmodule.c56
1 files changed, 39 insertions, 17 deletions
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 4427e73..7027410 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -168,7 +168,7 @@ should_audit(PyInterpreterState *interp)
if (!interp) {
return 0;
}
- return (interp->runtime->audit_hook_head
+ return (interp->runtime->audit_hooks.head
|| interp->audit_hooks
|| PyDTrace_AUDIT_ENABLED());
}
@@ -224,8 +224,11 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
goto exit;
}
- /* Call global hooks */
- _Py_AuditHookEntry *e = is->runtime->audit_hook_head;
+ /* Call global hooks
+ *
+ * We don't worry about any races on hooks getting added,
+ * since that would not leave is in an inconsistent state. */
+ _Py_AuditHookEntry *e = is->runtime->audit_hooks.head;
for (; e; e = e->next) {
if (e->hookCFunction(event, eventArgs, e->userData) < 0) {
goto exit;
@@ -353,8 +356,12 @@ _PySys_ClearAuditHooks(PyThreadState *ts)
_PySys_Audit(ts, "cpython._PySys_ClearAuditHooks", NULL);
_PyErr_Clear(ts);
- _Py_AuditHookEntry *e = runtime->audit_hook_head, *n;
- runtime->audit_hook_head = NULL;
+ /* We don't worry about the very unlikely race right here,
+ * since it's entirely benign. Nothing else removes entries
+ * from the list and adding an entry right now would not cause
+ * any trouble. */
+ _Py_AuditHookEntry *e = runtime->audit_hooks.head, *n;
+ runtime->audit_hooks.head = NULL;
while (e) {
n = e->next;
PyMem_RawFree(e);
@@ -362,6 +369,22 @@ _PySys_ClearAuditHooks(PyThreadState *ts)
}
}
+static void
+add_audit_hook_entry_unlocked(_PyRuntimeState *runtime,
+ _Py_AuditHookEntry *entry)
+{
+ if (runtime->audit_hooks.head == NULL) {
+ runtime->audit_hooks.head = entry;
+ }
+ else {
+ _Py_AuditHookEntry *last = runtime->audit_hooks.head;
+ while (last->next) {
+ last = last->next;
+ }
+ last->next = entry;
+ }
+}
+
int
PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
{
@@ -389,29 +412,28 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
}
}
- _Py_AuditHookEntry *e = runtime->audit_hook_head;
- if (!e) {
- e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
- runtime->audit_hook_head = e;
- } else {
- while (e->next) {
- e = e->next;
- }
- e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc(
+ _Py_AuditHookEntry *e = (_Py_AuditHookEntry*)PyMem_RawMalloc(
sizeof(_Py_AuditHookEntry));
- }
-
if (!e) {
if (tstate != NULL) {
_PyErr_NoMemory(tstate);
}
return -1;
}
-
e->next = NULL;
e->hookCFunction = (Py_AuditHookFunction)hook;
e->userData = userData;
+ if (runtime->audit_hooks.mutex == NULL) {
+ /* The runtime must not be initailized yet. */
+ add_audit_hook_entry_unlocked(runtime, e);
+ }
+ else {
+ PyThread_acquire_lock(runtime->audit_hooks.mutex, WAIT_LOCK);
+ add_audit_hook_entry_unlocked(runtime, e);
+ PyThread_release_lock(runtime->audit_hooks.mutex);
+ }
+
return 0;
}