Esempio n. 1
0
// BlockThreads() reclaims the GIL (and restores per-thread state), after is has
// been released by UnblockThreads().
//
// If this function is called without UnblockThreads() having been called, then
// nothing happens and the function returns immediately.
func (lock *Lock) BlockThreads() {
	if lock.gilState == nil {
		panic("BlockThreads() called on Unlocked Lock")
	}

	if lock.thState != nil {
		C.PyEval_RestoreThread(lock.thState)
		lock.thState = nil
	}
}
Esempio n. 2
0
// Unlock unlocks the lock.  When it returns no calls into Python made be made.
//
// If the lock is not locked when this function is called, then nothing happens,
// and the function returns immediately.  Also, it is not necessay to call
// BlockThreads() before calling Unlock(), even if UnblockThreads() has been
// called.
func (lock *Lock) Unlock() {
	if lock.gilState == nil {
		return
	}

	if lock.thState != nil {
		C.PyEval_RestoreThread(lock.thState)
		lock.thState = nil
	}

	lock.gilState.Release()
	runtime.UnlockOSThread()
	lock.gilState = nil
}
Esempio n. 3
0
// Unlock unlocks the lock.  When it returns no calls into Python may be made.
//
// If the lock is not locked when this function is called, then nothing happens,
// and the function returns immediately.  Also, it is not necessay to call
// BlockThreads() before calling Unlock(), even if UnblockThreads() has been
// called.
func (lock *Lock) Unlock() {
	if lock.gilState == nil {
		return
	}

	if lock.thState != nil {
		C.PyEval_RestoreThread(lock.thState)
		lock.thState = nil
	}

	releaseOsThread := lock.dec()

	lock.gilState.Release()
	if releaseOsThread {
		runtime.UnlockOSThread()
	}
	lock.gilState = nil
}
Esempio n. 4
0
//export gil
func gil(self, args *C.PyObject) *C.PyObject {
	var res *C.PyObject

	tState := C.PyEval_SaveThread()

	var mu sync.Mutex
	mu.Lock()

	go func() {
		C.PyEval_RestoreThread(tState)
		res = C.PyLong_FromLong(1)
		mu.Unlock()
	}()

	mu.Lock()

	return res
}
Esempio n. 5
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)
}
Esempio n. 6
0
// void PyEval_RestoreThread(PyThreadState *tstate)
// Acquire the global interpreter lock (if it has been created and thread
// support is enabled) and set the thread state to tstate, which must not be
// NULL. If the lock has been created, the current thread must not have
// acquired it, otherwise deadlock ensues. (This function is available even
// when thread support is disabled at compile time.)
func PyEval_RestoreThread(state *PyThreadState) {
	C.PyEval_RestoreThread(state.ptr)
}