Skip to content

Commit b85643f

Browse files
committed
Wrap render in SWIG threads macro, to disable Python GIL
Amended after running black formatting
1 parent 95a43d6 commit b85643f

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

library/rpi_ws281x.i

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// SWIG interface file to define rpi_ws281x library python wrapper.
22
// Author: Tony DiCola ([email protected]), Jeremy Garff ([email protected])
33

4+
%nothread;
5+
46
// Define module name rpi_ws281x. This will actually be imported under
57
// the name _rpi_ws281x following the SWIG & Python conventions.
68
%module rpi_ws281x
@@ -92,3 +94,12 @@ static int convert_iarray(PyObject *input, uint8_t *ptr, int size) {
9294
return &ws->channel[channelnum];
9395
}
9496
%}
97+
98+
%thread;
99+
%inline %{
100+
ws2811_return_t ws2811_render_nogil(ws2811_t *ws2811)
101+
{
102+
return ws2811_render(ws2811);
103+
}
104+
%}
105+
%nothread;

library/rpi_ws281x.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,7 @@ def ws2811_led_set(channel, lednum, color):
221221

222222
def ws2811_channel_get(ws, channelnum):
223223
return _rpi_ws281x.ws2811_channel_get(ws, channelnum)
224+
225+
226+
def ws2811_render_nogil(ws2811):
227+
return _rpi_ws281x.ws2811_render_nogil(ws2811)

library/rpi_ws281x/rpi_ws281x.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@ def show(self):
149149
str_resp = ws.ws2811_get_return_t_str(resp)
150150
raise RuntimeError('ws2811_render failed with code {0} ({1})'.format(resp, str_resp))
151151

152+
def show_nogil(self):
153+
"""Update the display with the data from the LED buffer."""
154+
resp = ws.ws2811_render_nogil(self._leds)
155+
if resp != 0:
156+
str_resp = ws.ws2811_get_return_t_str(resp)
157+
raise RuntimeError('ws2811_render failed with code {0} ({1})'.format(resp, str_resp))
158+
152159
def setPixelColor(self, n, color):
153160
"""Set LED at position n to the provided 24-bit color value (in RGB order).
154161
"""

library/rpi_ws281x_wrap.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define SWIGPYTHON
1414
#endif
1515

16+
#define SWIG_PYTHON_THREADS
1617
#define SWIG_PYTHON_DIRECTOR_NO_VTABLE
1718

1819
/* -----------------------------------------------------------------------------
@@ -3132,6 +3133,12 @@ SWIG_FromCharPtr(const char *cptr)
31323133
return &ws->channel[channelnum];
31333134
}
31343135

3136+
3137+
ws2811_return_t ws2811_render_nogil(ws2811_t *ws2811)
3138+
{
3139+
return ws2811_render(ws2811);
3140+
}
3141+
31353142
#ifdef __cplusplus
31363143
extern "C" {
31373144
#endif
@@ -4370,6 +4377,33 @@ SWIGINTERN PyObject *_wrap_ws2811_channel_get(PyObject *SWIGUNUSEDPARM(self), Py
43704377
}
43714378

43724379

4380+
SWIGINTERN PyObject *_wrap_ws2811_render_nogil(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
4381+
PyObject *resultobj = 0;
4382+
ws2811_t *arg1 = (ws2811_t *) 0 ;
4383+
void *argp1 = 0 ;
4384+
int res1 = 0 ;
4385+
PyObject *swig_obj[1] ;
4386+
ws2811_return_t result;
4387+
4388+
if (!args) SWIG_fail;
4389+
swig_obj[0] = args;
4390+
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ws2811_t, 0 | 0 );
4391+
if (!SWIG_IsOK(res1)) {
4392+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ws2811_render_nogil" "', argument " "1"" of type '" "ws2811_t *""'");
4393+
}
4394+
arg1 = (ws2811_t *)(argp1);
4395+
{
4396+
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
4397+
result = (ws2811_return_t)ws2811_render_nogil(arg1);
4398+
SWIG_PYTHON_THREAD_END_ALLOW;
4399+
}
4400+
resultobj = SWIG_From_int((int)(result));
4401+
return resultobj;
4402+
fail:
4403+
return NULL;
4404+
}
4405+
4406+
43734407
static PyMethodDef SwigMethods[] = {
43744408
{ "SWIG_PyInstanceMethod_New", SWIG_PyInstanceMethod_New, METH_O, NULL},
43754409
{ "ws2811_channel_t_gpionum_set", _wrap_ws2811_channel_t_gpionum_set, METH_VARARGS, NULL},
@@ -4423,6 +4457,7 @@ static PyMethodDef SwigMethods[] = {
44234457
{ "ws2811_led_get", _wrap_ws2811_led_get, METH_VARARGS, NULL},
44244458
{ "ws2811_led_set", _wrap_ws2811_led_set, METH_VARARGS, NULL},
44254459
{ "ws2811_channel_get", _wrap_ws2811_channel_get, METH_VARARGS, NULL},
4460+
{ "ws2811_render_nogil", _wrap_ws2811_render_nogil, METH_O, NULL},
44264461
{ NULL, NULL, 0, NULL }
44274462
};
44284463

@@ -5263,6 +5298,9 @@ SWIG_init(void) {
52635298
SWIG_Python_SetConstant(d, "WS2811_ERROR_SPI_SETUP",SWIG_From_int((int)(WS2811_ERROR_SPI_SETUP)));
52645299
SWIG_Python_SetConstant(d, "WS2811_ERROR_SPI_TRANSFER",SWIG_From_int((int)(WS2811_ERROR_SPI_TRANSFER)));
52655300
SWIG_Python_SetConstant(d, "WS2811_RETURN_STATE_COUNT",SWIG_From_int((int)(WS2811_RETURN_STATE_COUNT)));
5301+
5302+
/* Initialize threading */
5303+
SWIG_PYTHON_INITIALIZE_THREADS;
52665304
#if PY_VERSION_HEX >= 0x03000000
52675305
return m;
52685306
#else

0 commit comments

Comments
 (0)