]> git.alsa-project.org Git - alsa-python.git/commitdiff
hcontrol,mixer: improve callback GIL state handling
authorJaroslav Kysela <perex@perex.cz>
Mon, 3 Jun 2024 14:11:28 +0000 (16:11 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 4 Jun 2024 14:31:39 +0000 (16:31 +0200)
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 <perex@perex.cz>
pyalsa/alsahcontrol.c
pyalsa/alsamixer.c
pyalsa/common.h

index 1ad0c290b43ce468827d68e47411deac16b59da6..2d7d627885178b736b94a954bf48d67a50c2c825 100644 (file)
@@ -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;
 }
index 91fe198c7b3797359b12308fb089fc21346fd463..000b784231c95b0779c07068030c37f88528fd33 100644 (file)
@@ -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;
 }
index ee50ba8a4982b3846b1210bf71ab5e0179d1c897..641520f98147c82b68f7c9ad7b790d577cf4c4af 100644 (file)
           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
+
 /*
  *
  */