func create_thread(ch chan bool, args []string, kw map[string]string) { log.Debug("> create_thread") lock.Lock() defer lock.Unlock() defer func() { ch <- true }() _ch := make(chan bool) defer func() { close(_ch) }() thread := pthread.Create(func() { _gstate := C.PyGILState_Ensure() defer func() { C.PyGILState_Release(_gstate) }() embed_function(args, kw) _ch <- true }) defer func() { thread.Kill() }() <-_ch log.Debug("< create_thread: done") }
func (t *Thread) loop() { runtime.LockOSThread() threadState := threadInit() if threadState == nil { gilState := C.PyGILState_Ensure() oldThreadState := C.PyGILState_GetThisThreadState() threadState = C.PyThreadState_New(oldThreadState.interp) C.PyGILState_Release(gilState) } for f := range t.queue { C.PyEval_RestoreThread(threadState) f() threadState = C.PyEval_SaveThread() } gilState := C.PyGILState_Ensure() C.PyThreadState_Clear(threadState) C.PyThreadState_Delete(threadState) C.PyGILState_Release(gilState) }
// Ensure that the current thread is ready to call the Python C API regardless // of the current state of Python, or of the global interpreter lock. This may // be called as many times as desired by a thread as long as each call is // matched with a call to PyGILState_Release(). In general, other thread-related // APIs may be used between PyGILState_Ensure() and PyGILState_Release() calls // as long as the thread state is restored to its previous state before the // Release(). For example, normal usage of the Py_BEGIN_ALLOW_THREADS and // Py_END_ALLOW_THREADS macros is acceptable. // // The return value is an opaque “handle” to the thread state when // PyGILState_Ensure() was called, and must be passed to PyGILState_Release() // to ensure Python is left in the same state. Even though recursive calls are // allowed, these handles cannot be shared - each unique call to // PyGILState_Ensure() must save the handle for its call to PyGILState_Release(). // // When the function returns, the current thread will hold the GIL and be able // to call arbitrary Python code. Failure is a fatal error. // // New in version 2.3. func PyGILState_Ensure() PyGILState { return PyGILState(C.PyGILState_Ensure()) }
func GilState_Ensure() *GilState { ret := C.PyGILState_Ensure() return &GilState{ret, true} }