Skip to content

Commit 157d660

Browse files
committed
hcontrol,mixer: improve callback GIL state handling
Link: #11 Closes: #12 Signed-off-by: Jaroslav Kysela <[email protected]>
1 parent 3da7653 commit 157d660

File tree

3 files changed

+31
-10
lines changed

3 files changed

+31
-10
lines changed

pyalsa/alsahcontrol.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,19 +1520,18 @@ MOD_INIT(alsahcontrol)
15201520

15211521
static int element_callback(snd_hctl_elem_t *elem, unsigned int mask)
15221522
{
1523-
PyThreadState *tstate, *origstate;
15241523
struct pyalsahcontrolelement *pyhelem;
15251524
PyObject *o, *t, *r;
15261525
int res = 0, inside = 1;
1526+
CALLBACK_VARIABLES;
15271527

15281528
if (elem == NULL)
15291529
return -EINVAL;
15301530
pyhelem = snd_hctl_elem_get_callback_private(elem);
15311531
if (pyhelem == NULL || pyhelem->callback == NULL)
15321532
return -EINVAL;
15331533

1534-
tstate = PyThreadState_New(main_interpreter);
1535-
origstate = PyThreadState_Swap(tstate);
1534+
CALLBACK_INIT;
15361535

15371536
o = PyObject_GetAttr(pyhelem->callback, InternFromString("callback"));
15381537
if (!o) {
@@ -1570,8 +1569,7 @@ static int element_callback(snd_hctl_elem_t *elem, unsigned int mask)
15701569
Py_DECREF(o);
15711570
}
15721571

1573-
PyThreadState_Swap(origstate);
1574-
PyThreadState_Delete(tstate);
1572+
CALLBACK_DONE;
15751573

15761574
return res;
15771575
}

pyalsa/alsamixer.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,19 +1325,18 @@ MOD_INIT(alsamixer)
13251325

13261326
static int element_callback(snd_mixer_elem_t *elem, unsigned int mask)
13271327
{
1328-
PyThreadState *tstate, *origstate;
13291328
struct pyalsamixerelement *pyelem;
13301329
PyObject *o, *t, *r;
13311330
int res = 0, inside = 1;
1331+
CALLBACK_VARIABLES;
13321332

13331333
if (elem == NULL)
13341334
return -EINVAL;
13351335
pyelem = snd_mixer_elem_get_callback_private(elem);
13361336
if (pyelem == NULL || pyelem->callback == NULL)
13371337
return -EINVAL;
13381338

1339-
tstate = PyThreadState_New(main_interpreter);
1340-
origstate = PyThreadState_Swap(tstate);
1339+
CALLBACK_INIT;
13411340

13421341
o = PyObject_GetAttr(pyelem->callback, InternFromString("callback"));
13431342
if (!o) {
@@ -1377,8 +1376,7 @@ static int element_callback(snd_mixer_elem_t *elem, unsigned int mask)
13771376
Py_DECREF(o);
13781377
}
13791378

1380-
PyThreadState_Swap(origstate);
1381-
PyThreadState_Delete(tstate);
1379+
CALLBACK_DONE;
13821380

13831381
return res;
13841382
}

pyalsa/common.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,31 @@
6565
ob = Py_InitModule3(name, methods, doc);
6666
#endif
6767

68+
/*
69+
*
70+
*/
71+
#if PY_MAJOR_VERSION >= 3
72+
#define CALLBACK_VARIABLES \
73+
PyGILState_STATE __gstate
74+
#define CALLBACK_INIT \
75+
__gstate = PyGILState_Ensure()
76+
#define CALLBACK_DONE \
77+
PyGILState_Release(__gstate)
78+
#else
79+
#define CALLBACK_VARIABLES \
80+
PyThreadState *__tstate, *__origstate
81+
#define CALLBACK_INIT \
82+
do { \
83+
__tstate = PyThreadState_New(main_interpreter); \
84+
__origstate = PyThreadState_Swap(__tstate); \
85+
} while (0)
86+
#define CALLBACK_DONE \
87+
do { \
88+
PyThreadState_Swap(origstate); \
89+
PyThreadState_Delete(tstate); \
90+
} while (0)
91+
#endif
92+
6893
/*
6994
*
7095
*/

0 commit comments

Comments
 (0)