Why is PyGILState_Release (...) segfault in this case?

I am working on implementing asynchronous audio playback for PyAudio . The Portaudio backend implements asynchronous playback, creating its own stream and calling the C-callback function whenever it needs / has new audio data. Whenever this C-callback function is called, I call the previously registered Python function where the user must provide audio data.

Since this Python call comes in a thread not created for Python, the documentation says that I need to call PyGILState_Ensure()before and call Python PyGILState_Release(). It looks something like this:

int stream_callback(const void *in, void* out, unsigned long frameCount,
                    const PaStreamCallbackTimeInfo *timeInfo,
                    PaStreamCallbackFlags statusFlags, void *userData)
{
    PyGILState_STATE gstate = PyGILState_Ensure();

    /* create some python variables, as used below… */
    py_result = PyObject_CallFunctionObjArgs(py_callback,
                                             py_frameCount,
                                             py_inTime,
                                             py_curTime,
                                             py_outTime,
                                             py_inputData,
                                             NULL);
    /* evaluate py_result, do some audio stuff… */

    PyGILState_Release(gstate);
    return returnVal;
}

segfaults PyGILState_Release(gstate). . , . gstate 32- 1, 0 PyGILState_Ensure(). , 1. 1, 0.

, PyGILState_Release(…) , , , , - .

:

#0  0x00007fff88c287b7 in pthread_mutex_lock ()
#1  0x00000001001009a6 in PyThread_release_lock ()
#2  0x00000001002efc82 in stream_callback (in=0x1014a4670, out=0x1014a4670, frameCount=4316612208, timeInfo=0x1014a4850, statusFlags=4297757032, userData=0x38) at _portaudiomodule.c:1554
#3  0x00000001004e3710 in AdaptingOutputOnlyProcess ()
#4  0x00000001004e454b in PaUtil_EndBufferProcessing ()
#5  0x00000001004e9665 in AudioIOProc ()
#6  0x00000001013485d0 in dyld_stub_strlen ()
#7  0x0000000101348194 in dyld_stub_strlen ()
#8  0x0000000101346523 in dyld_stub_strlen ()
#9  0x0000000101345870 in dyld_stub_strlen ()
#10 0x000000010134aceb in AUGenericOutputEntry ()
#11 0x00007fff88aa132d in HP_IOProc::Call ()
#12 0x00007fff88aa10ff in IOA_Device::CallIOProcs ()
#13 0x00007fff88aa0f35 in HP_IOThread::PerformIO ()
#14 0x00007fff88a9ef44 in HP_IOThread::WorkLoop ()
#15 0x00007fff88a9e817 in HP_IOThread::ThreadEntry ()
#16 0x00007fff88a9e745 in CAPThread::Entry ()
#17 0x00007fff88c5c536 in _pthread_start ()
#18 0x00007fff88c5c3e9 in thread_start ()

?

+3
2

. , PyEval_InitThreads() , - .

, . Python, GIL, Python , GIL . , GIL PyGILState_Ensure() PyGILState_Release() , .

PyEval_InitThreads(), GIL PyGILState_Ensure() PyGILState_Release() . GIL PyEval_InitThreads() , .

+4

- , , , , , , , PyGILState_Ensure() .

PyEval_InitThreads(), ( ). , PyEval_ReleaseLock(), PyGILState_Ensure(), PyEval_InitThreads() GIL.

, .

+3

Source: https://habr.com/ru/post/1795194/


All Articles