From 53c16e06983f9b03464f41b8c0ed3206382c5538 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Sun, 9 Jan 2005 04:59:30 +0000 Subject: support for Python threads, at last small fixes merged in 20041229-newdetach branch. renamed locking functions svn path=/trunk/; revision=2483 --- externals/grill/py/source/main.h | 157 +++++++++++++++++++++++---------------- 1 file changed, 92 insertions(+), 65 deletions(-) (limited to 'externals/grill/py/source/main.h') diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h index 6dde3f54..e953b319 100644 --- a/externals/grill/py/source/main.h +++ b/externals/grill/py/source/main.h @@ -2,7 +2,7 @@ py/pyext - python script object for PD and MaxMSP -Copyright (c)2002-2004 Thomas Grill (gr@grrrr.org) +Copyright (c)2002-2005 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. @@ -24,8 +24,8 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include #endif -#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 408) -#error You need at least flext version 0.4.8 +#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500) +#error You need at least flext version 0.5.0 #endif #define PY__VERSION "0.2.0pre" @@ -38,16 +38,28 @@ WARRANTIES, see the file, "license.txt," in this distribution. #define PY_STOP_TICK 10 // ms +class Fifo +{ +protected: + struct FifoEl { + PyObject *fun; + PyObject *args; + FifoEl *nxt; + }; +public: + Fifo(): head(NULL),tail(NULL) {} + ~Fifo(); -#define I int -#define C char -#define V void -#define BL bool -#define F float -#define D double + bool Push(PyObject *f,PyObject *a); + bool Pop(PyObject *&f,PyObject *&a); + +protected: + FifoEl *head,*tail; +}; -#include "main.h" +PyThreadState *FindThreadState(); +void FreeThreadState(); class py: public flext_base @@ -57,43 +69,43 @@ class py: public: py(); ~py(); - static V lib_setup(); + static void lib_setup(); - static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,I inlet = -1,BL withself = false); + static PyObject *MakePyArgs(const t_symbol *s,int argc,const t_atom *argv,int inlet = -1,bool withself = false); static AtomList *GetPyArgs(PyObject *pValue,PyObject **self = NULL); protected: - V m__dir(PyObject *obj); - V m__doc(PyObject *obj); + void m__dir(PyObject *obj); + void m__doc(PyObject *obj); - V m_dir() { m__dir(module); } - V mg_dir(AtomList &lst) { m__dir(module); } - V m_doc() { m__doc(dict); } + void m_dir() { m__dir(module); } + void mg_dir(AtomList &lst) { m__dir(module); } + void m_doc() { m__doc(dict); } PyObject *module,*dict; // inherited user class module and associated dictionary - static const C *py_doc; + static const char *py_doc; - V GetDir(PyObject *obj,AtomList &lst); + void GetDir(PyObject *obj,AtomList &lst); - V GetModulePath(const C *mod,C *dir,I len); - V AddToPath(const C *dir); - V SetArgs(I argc,const t_atom *argv); - V ImportModule(const C *name); - V UnimportModule(); - V ReloadModule(); + void GetModulePath(const char *mod,char *dir,int len); + void AddToPath(const char *dir); + void SetArgs(int argc,const t_atom *argv); + void ImportModule(const char *name); + void UnimportModule(); + void ReloadModule(); - V Register(const C *reg); - V Unregister(const C *reg); - V Reregister(const C *reg); - virtual V Reload() = 0; + void Register(const char *reg); + void Unregister(const char *reg); + void Reregister(const char *reg); + virtual void Reload() = 0; - V Respond(BL b) { if(respond) { t_atom a[1]; SetBool(a[0],b); ToOutAnything(GetOutAttr(),MakeSymbol("response"),1,a); } } + void Respond(bool b); - static BL IsAnything(const t_symbol *s) { return s && s != sym_bang && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; } + static bool IsAnything(const t_symbol *s) { return s && s != sym_bang && s != sym_float && s != sym_int && s != sym_symbol && s != sym_list && s != sym_pointer; } - enum retval { nothing,atom,sequ /*,tuple,list*/ }; + enum retval { nothing,atom,sequ }; // --- module stuff ----- @@ -108,8 +120,7 @@ protected: static PyObject *py_samplerate(PyObject *,PyObject *args); static PyObject *py_blocksize(PyObject *,PyObject *args); - static PyObject *py_inchannels(PyObject *,PyObject *args); - static PyObject *py_outchannels(PyObject *,PyObject *args); + #if FLEXT_SYS == FLEXT_SYS_PD static PyObject *py_getvalue(PyObject *,PyObject *args); static PyObject *py_setvalue(PyObject *,PyObject *args); @@ -117,24 +128,59 @@ protected: // ----thread stuff ------------ - virtual V m_stop(int argc,const t_atom *argv); + virtual void m_stop(int argc,const t_atom *argv); - BL detach,shouldexit,respond; - I thrcount; - I stoptick; + bool shouldexit,respond; + int thrcount; + int stoptick; Timer stoptmr; + int detach; - V tick(V *); + void tick(void *); + + bool gencall(PyObject *fun,PyObject *args); + virtual bool callpy(PyObject *fun,PyObject *args) = 0; + +private: +// PyInterpreterState *interpreter; + + bool qucall(PyObject *fun,PyObject *args); + void threadworker(); + Fifo qufifo; + ThrCond qucond; + + void work_wrapper(void *data); + +#ifdef FLEXT_THREADS + FLEXT_THREAD_X(work_wrapper) +#else + FLEXT_CALLBACK_X(work_wrapper) +#endif public: #ifdef FLEXT_THREADS ThrMutex mutex; - inline V Lock() { mutex.Unlock(); } - inline V Unlock() { mutex.Unlock(); } + inline void Lock() { mutex.Unlock(); } + inline void Unlock() { mutex.Unlock(); } + + inline PyThreadState *PyLock() + { + PyEval_AcquireLock(); + return PyThreadState_Swap(FindThreadState()); + } + + inline void PyUnlock(PyThreadState *st) + { + PyThreadState_Swap(st); + PyEval_ReleaseLock(); + } #else - inline V Lock() {} - inline V Unlock() {} + inline void Lock() {} + inline void Unlock() {} + + inline PyThreadState *PyLock() { return NULL; } + inline void PyUnlock(PyThreadState *st) {} #endif static PyObject* StdOut_Write(PyObject* Self, PyObject* Args); @@ -142,34 +188,15 @@ public: protected: // callbacks - FLEXT_ATTRVAR_B(detach) + FLEXT_ATTRVAR_I(detach) FLEXT_ATTRVAR_B(respond) FLEXT_CALLBACK_V(m_stop) FLEXT_CALLBACK(m_dir) FLEXT_CALLGET_V(mg_dir) FLEXT_CALLBACK(m_doc) FLEXT_CALLBACK_T(tick) -}; - -#ifdef FLEXT_THREADS - -PyThreadState *FindThreadState(); -void FreeThreadState(); - -#define PY_LOCK \ - { \ - PyEval_AcquireLock(); \ - PyThreadState *__st = FindThreadState(); \ - PyThreadState *__oldst = PyThreadState_Swap(__st); - -#define PY_UNLOCK \ - PyThreadState_Swap(__oldst); \ - PyEval_ReleaseLock(); \ - } -#else -#define PY_LOCK -#define PY_UNLOCK -#endif + FLEXT_THREAD(threadworker) +}; #endif -- cgit v1.2.1