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")
}
Example #2
0
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)
}
Example #3
0
// 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())
}
Example #4
0
func GilState_Ensure() *GilState {
	ret := C.PyGILState_Ensure()
	return &GilState{ret, true}
}