quick fix 2
This commit is contained in:
259
Lib/site-packages/ffpyplayer/threading.pyx
Normal file
259
Lib/site-packages/ffpyplayer/threading.pyx
Normal file
@ -0,0 +1,259 @@
|
||||
|
||||
__all__ = ('MTGenerator', )
|
||||
|
||||
include "includes/ff_consts.pxi"
|
||||
include "includes/inline_funcs.pxi"
|
||||
|
||||
from cpython.ref cimport PyObject
|
||||
|
||||
cdef extern from "Python.h":
|
||||
void Py_INCREF(PyObject *)
|
||||
void Py_XINCREF(PyObject *)
|
||||
void Py_DECREF(PyObject *)
|
||||
|
||||
ctypedef int (*int_cls_method)(void *) nogil
|
||||
|
||||
import traceback
|
||||
|
||||
cdef int sdl_initialized = 0
|
||||
def initialize_sdl():
|
||||
'''Initializes sdl. Must be called before anything can be used.
|
||||
It is automatically called by the modules that use SDL.
|
||||
'''
|
||||
global sdl_initialized
|
||||
if sdl_initialized:
|
||||
return
|
||||
if SDL_Init(0):
|
||||
raise ValueError('Could not initialize SDL - %s' % SDL_GetError())
|
||||
sdl_initialized = 1
|
||||
initialize_sdl()
|
||||
|
||||
|
||||
cdef class MTMutex(object):
|
||||
|
||||
def __cinit__(MTMutex self, MT_lib lib):
|
||||
self.lib = lib
|
||||
self.mutex = NULL
|
||||
if lib == SDL_MT:
|
||||
self.mutex = SDL_CreateMutex()
|
||||
if self.mutex == NULL:
|
||||
raise Exception('Cannot create mutex.')
|
||||
elif lib == Py_MT:
|
||||
import threading
|
||||
mutex = threading.Lock()
|
||||
self.mutex = <PyObject *>mutex
|
||||
Py_INCREF(<PyObject *>self.mutex)
|
||||
|
||||
def __dealloc__(MTMutex self):
|
||||
if self.lib == SDL_MT:
|
||||
if self.mutex != NULL:
|
||||
SDL_DestroyMutex(<SDL_mutex *>self.mutex)
|
||||
elif self.lib == Py_MT:
|
||||
Py_DECREF(<PyObject *>self.mutex)
|
||||
|
||||
cdef int lock(MTMutex self) nogil except 2:
|
||||
if self.lib == SDL_MT:
|
||||
return SDL_mutexP(<SDL_mutex *>self.mutex)
|
||||
elif self.lib == Py_MT:
|
||||
return self._lock_py()
|
||||
|
||||
cdef int _lock_py(MTMutex self) nogil except 2:
|
||||
with gil:
|
||||
return not (<object>self.mutex).acquire()
|
||||
|
||||
cdef int unlock(MTMutex self) nogil except 2:
|
||||
if self.lib == SDL_MT:
|
||||
return SDL_mutexV(<SDL_mutex *>self.mutex)
|
||||
elif self.lib == Py_MT:
|
||||
return self._unlock_py()
|
||||
|
||||
cdef int _unlock_py(MTMutex self) nogil except 2:
|
||||
with gil:
|
||||
(<object>self.mutex).release()
|
||||
return 0
|
||||
|
||||
cdef class MTCond(object):
|
||||
|
||||
def __cinit__(MTCond self, MT_lib lib):
|
||||
self.lib = lib
|
||||
self.mutex = MTMutex.__new__(MTMutex, lib)
|
||||
self.cond = NULL
|
||||
if self.lib == SDL_MT:
|
||||
self.cond = SDL_CreateCond()
|
||||
if self.cond == NULL:
|
||||
raise Exception('Cannot create condition.')
|
||||
elif self.lib == Py_MT:
|
||||
import threading
|
||||
cond = threading.Condition(<object>self.mutex.mutex)
|
||||
self.cond = <PyObject *>cond
|
||||
Py_INCREF(<PyObject *>self.cond)
|
||||
|
||||
def __dealloc__(MTCond self):
|
||||
if self.lib == SDL_MT:
|
||||
if self.cond != NULL:
|
||||
SDL_DestroyCond(<SDL_cond *>self.cond)
|
||||
elif self.lib == Py_MT:
|
||||
Py_DECREF(<PyObject *>self.cond)
|
||||
|
||||
cdef int lock(MTCond self) nogil except 2:
|
||||
self.mutex.lock()
|
||||
|
||||
cdef int unlock(MTCond self) nogil except 2:
|
||||
self.mutex.unlock()
|
||||
|
||||
cdef int cond_signal(MTCond self) nogil except 2:
|
||||
if self.lib == SDL_MT:
|
||||
return SDL_CondSignal(<SDL_cond *>self.cond)
|
||||
elif self.lib == Py_MT:
|
||||
return self._cond_signal_py()
|
||||
|
||||
cdef int _cond_signal_py(MTCond self) nogil except 2:
|
||||
with gil:
|
||||
(<object>self.cond).notify()
|
||||
return 0
|
||||
|
||||
cdef int cond_wait(MTCond self) nogil except 2:
|
||||
if self.lib == SDL_MT:
|
||||
return SDL_CondWait(<SDL_cond *>self.cond, <SDL_mutex *>self.mutex.mutex)
|
||||
elif self.lib == Py_MT:
|
||||
return self._cond_wait_py()
|
||||
|
||||
cdef int _cond_wait_py(MTCond self) nogil except 2:
|
||||
with gil:
|
||||
(<object>self.cond).wait()
|
||||
return 0
|
||||
|
||||
cdef int cond_wait_timeout(MTCond self, uint32_t val) nogil except 2:
|
||||
if self.lib == SDL_MT:
|
||||
return SDL_CondWaitTimeout(<SDL_cond *>self.cond, <SDL_mutex *>self.mutex.mutex, val)
|
||||
elif self.lib == Py_MT:
|
||||
return self._cond_wait_timeout_py(val)
|
||||
|
||||
cdef int _cond_wait_timeout_py(MTCond self, uint32_t val) nogil except 2:
|
||||
with gil:
|
||||
(<object>self.cond).wait(val / 1000.)
|
||||
return 0
|
||||
|
||||
def enterance_func(target_func, target_arg):
|
||||
return (<int_void_func><uintptr_t>target_func)(<void *><uintptr_t>target_arg)
|
||||
|
||||
cdef class MTThread(object):
|
||||
|
||||
def __cinit__(MTThread self, MT_lib lib):
|
||||
self.lib = lib
|
||||
self.thread = NULL
|
||||
|
||||
def __dealloc__(MTThread self):
|
||||
if self.lib == Py_MT and self.thread != NULL:
|
||||
Py_DECREF(<PyObject *>self.thread)
|
||||
|
||||
cdef int create_thread(MTThread self, int_void_func func, const char *thread_name, void *arg) nogil except 2:
|
||||
if self.lib == SDL_MT:
|
||||
with gil:
|
||||
self.thread = SDL_CreateThread(func, thread_name, arg)
|
||||
if self.thread == NULL:
|
||||
raise Exception('Cannot create thread.')
|
||||
elif self.lib == Py_MT:
|
||||
with gil:
|
||||
import threading
|
||||
thread = threading.Thread(group=None, target=enterance_func,
|
||||
name=None, args=(<uintptr_t>func, <uintptr_t>arg), kwargs={})
|
||||
self.thread = <PyObject *>thread
|
||||
Py_INCREF(<PyObject *>self.thread)
|
||||
thread.start()
|
||||
return 0
|
||||
|
||||
cdef int wait_thread(MTThread self, int *status) nogil except 2:
|
||||
if self.lib == SDL_MT:
|
||||
if self.thread != NULL:
|
||||
SDL_WaitThread(<SDL_Thread *>self.thread, status)
|
||||
elif self.lib == Py_MT:
|
||||
with gil:
|
||||
(<object>self.thread).join()
|
||||
if status != NULL:
|
||||
status[0] = 0
|
||||
return 0
|
||||
|
||||
|
||||
cdef int_cls_method mutex_lock = <int_cls_method>MTMutex.lock
|
||||
cdef int_cls_method mutex_release = <int_cls_method>MTMutex.unlock
|
||||
|
||||
cdef int _SDL_lockmgr_py(void ** mtx, int op) with gil:
|
||||
cdef bytes msg
|
||||
cdef int res = 1
|
||||
cdef MTMutex mutex
|
||||
|
||||
try:
|
||||
if op == FF_LOCK_CREATE:
|
||||
mutex = MTMutex.__new__(MTMutex, SDL_MT)
|
||||
Py_INCREF(<PyObject *>mutex)
|
||||
mtx[0] = <PyObject *>mutex
|
||||
res = 0
|
||||
elif op == FF_LOCK_DESTROY:
|
||||
if mtx[0] != NULL:
|
||||
Py_DECREF(<PyObject *>mtx[0])
|
||||
res = 0
|
||||
except:
|
||||
msg = traceback.format_exc().encode('utf8')
|
||||
av_log(NULL, AV_LOG_ERROR, '%s', msg)
|
||||
return res
|
||||
|
||||
cdef int SDL_lockmgr(void ** mtx, int op) nogil:
|
||||
if op == FF_LOCK_OBTAIN:
|
||||
return not not mutex_lock(mtx[0])
|
||||
elif op == FF_LOCK_RELEASE:
|
||||
return not not mutex_release(mtx[0])
|
||||
else:
|
||||
return _SDL_lockmgr_py(mtx, op)
|
||||
|
||||
cdef int Py_lockmgr(void ** mtx, int op) with gil:
|
||||
cdef int res = 1
|
||||
cdef bytes msg
|
||||
cdef MTMutex mutex
|
||||
|
||||
try:
|
||||
if op == FF_LOCK_CREATE:
|
||||
mutex = MTMutex.__new__(MTMutex, Py_MT)
|
||||
Py_INCREF(<PyObject *>mutex)
|
||||
mtx[0] = <PyObject *>mutex
|
||||
res = 0
|
||||
elif op == FF_LOCK_OBTAIN:
|
||||
mutex = <MTMutex>mtx[0]
|
||||
res = not not mutex.lock() # force it to 0, or 1
|
||||
elif op == FF_LOCK_RELEASE:
|
||||
mutex = <MTMutex>mtx[0]
|
||||
res = not not mutex.unlock()
|
||||
elif op == FF_LOCK_DESTROY:
|
||||
if mtx[0] != NULL:
|
||||
Py_DECREF(<PyObject *>mtx[0])
|
||||
res = 0
|
||||
except:
|
||||
msg = traceback.format_exc().encode('utf8')
|
||||
av_log(NULL, AV_LOG_ERROR, '%s', msg)
|
||||
res = 1
|
||||
return res
|
||||
|
||||
|
||||
cdef lockmgr_func get_lib_lockmgr(MT_lib lib) nogil:
|
||||
if lib == SDL_MT:
|
||||
return SDL_lockmgr
|
||||
elif lib == Py_MT:
|
||||
return Py_lockmgr
|
||||
|
||||
|
||||
cdef class MTGenerator(object):
|
||||
|
||||
def __cinit__(MTGenerator self, MT_lib mt_src, **kwargs):
|
||||
self.mt_src = mt_src
|
||||
|
||||
cdef int delay(MTGenerator self, int delay) nogil except 2:
|
||||
if self.mt_src == SDL_MT:
|
||||
SDL_Delay(delay)
|
||||
elif self.mt_src == Py_MT:
|
||||
with gil:
|
||||
import time
|
||||
time.sleep(delay / 1000.)
|
||||
return 0
|
||||
|
||||
cdef lockmgr_func get_lockmgr(MTGenerator self) nogil:
|
||||
return get_lib_lockmgr(self.mt_src)
|
||||
Reference in New Issue
Block a user