From 157d6604ad0854d2b2d068cf062a71583db169c3 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 3 Jun 2024 16:11:28 +0200 Subject: [PATCH] hcontrol,mixer: improve callback GIL state handling Link: https://github.com/alsa-project/alsa-python/issues/11 Closes: https://github.com/alsa-project/alsa-python/pull/12 Signed-off-by: Jaroslav Kysela --- pyalsa/alsahcontrol.c | 8 +++----- pyalsa/alsamixer.c | 8 +++----- pyalsa/common.h | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/pyalsa/alsahcontrol.c b/pyalsa/alsahcontrol.c index 1ad0c29..2d7d627 100644 --- a/pyalsa/alsahcontrol.c +++ b/pyalsa/alsahcontrol.c @@ -1520,10 +1520,10 @@ MOD_INIT(alsahcontrol) static int element_callback(snd_hctl_elem_t *elem, unsigned int mask) { - PyThreadState *tstate, *origstate; struct pyalsahcontrolelement *pyhelem; PyObject *o, *t, *r; int res = 0, inside = 1; + CALLBACK_VARIABLES; if (elem == NULL) return -EINVAL; @@ -1531,8 +1531,7 @@ static int element_callback(snd_hctl_elem_t *elem, unsigned int mask) if (pyhelem == NULL || pyhelem->callback == NULL) return -EINVAL; - tstate = PyThreadState_New(main_interpreter); - origstate = PyThreadState_Swap(tstate); + CALLBACK_INIT; o = PyObject_GetAttr(pyhelem->callback, InternFromString("callback")); if (!o) { @@ -1570,8 +1569,7 @@ static int element_callback(snd_hctl_elem_t *elem, unsigned int mask) Py_DECREF(o); } - PyThreadState_Swap(origstate); - PyThreadState_Delete(tstate); + CALLBACK_DONE; return res; } diff --git a/pyalsa/alsamixer.c b/pyalsa/alsamixer.c index 91fe198..000b784 100644 --- a/pyalsa/alsamixer.c +++ b/pyalsa/alsamixer.c @@ -1325,10 +1325,10 @@ MOD_INIT(alsamixer) static int element_callback(snd_mixer_elem_t *elem, unsigned int mask) { - PyThreadState *tstate, *origstate; struct pyalsamixerelement *pyelem; PyObject *o, *t, *r; int res = 0, inside = 1; + CALLBACK_VARIABLES; if (elem == NULL) return -EINVAL; @@ -1336,8 +1336,7 @@ static int element_callback(snd_mixer_elem_t *elem, unsigned int mask) if (pyelem == NULL || pyelem->callback == NULL) return -EINVAL; - tstate = PyThreadState_New(main_interpreter); - origstate = PyThreadState_Swap(tstate); + CALLBACK_INIT; o = PyObject_GetAttr(pyelem->callback, InternFromString("callback")); if (!o) { @@ -1377,8 +1376,7 @@ static int element_callback(snd_mixer_elem_t *elem, unsigned int mask) Py_DECREF(o); } - PyThreadState_Swap(origstate); - PyThreadState_Delete(tstate); + CALLBACK_DONE; return res; } diff --git a/pyalsa/common.h b/pyalsa/common.h index ee50ba8..641520f 100644 --- a/pyalsa/common.h +++ b/pyalsa/common.h @@ -65,6 +65,31 @@ ob = Py_InitModule3(name, methods, doc); #endif +/* + * + */ +#if PY_MAJOR_VERSION >= 3 + #define CALLBACK_VARIABLES \ + PyGILState_STATE __gstate + #define CALLBACK_INIT \ + __gstate = PyGILState_Ensure() + #define CALLBACK_DONE \ + PyGILState_Release(__gstate) +#else + #define CALLBACK_VARIABLES \ + PyThreadState *__tstate, *__origstate + #define CALLBACK_INIT \ + do { \ + __tstate = PyThreadState_New(main_interpreter); \ + __origstate = PyThreadState_Swap(__tstate); \ + } while (0) + #define CALLBACK_DONE \ + do { \ + PyThreadState_Swap(origstate); \ + PyThreadState_Delete(tstate); \ + } while (0) +#endif + /* * */ -- 2.47.1