Chris@87: #ifndef Py_CEVAL_H Chris@87: #define Py_CEVAL_H Chris@87: #ifdef __cplusplus Chris@87: extern "C" { Chris@87: #endif Chris@87: Chris@87: Chris@87: /* Interface to random parts in ceval.c */ Chris@87: Chris@87: PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( Chris@87: PyObject *, PyObject *, PyObject *); Chris@87: Chris@87: /* Inline this */ Chris@87: #define PyEval_CallObject(func,arg) \ Chris@87: PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL) Chris@87: Chris@87: PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *obj, Chris@87: const char *format, ...); Chris@87: PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, Chris@87: const char *methodname, Chris@87: const char *format, ...); Chris@87: Chris@87: PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); Chris@87: PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); Chris@87: Chris@87: struct _frame; /* Avoid including frameobject.h */ Chris@87: Chris@87: PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); Chris@87: PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); Chris@87: PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); Chris@87: PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void); Chris@87: PyAPI_FUNC(int) PyEval_GetRestricted(void); Chris@87: Chris@87: /* Look at the current frame's (if any) code's co_flags, and turn on Chris@87: the corresponding compiler flags in cf->cf_flags. Return 1 if any Chris@87: flag was set, else return 0. */ Chris@87: PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); Chris@87: Chris@87: PyAPI_FUNC(int) Py_FlushLine(void); Chris@87: Chris@87: PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); Chris@87: PyAPI_FUNC(int) Py_MakePendingCalls(void); Chris@87: Chris@87: /* Protection against deeply nested recursive calls */ Chris@87: PyAPI_FUNC(void) Py_SetRecursionLimit(int); Chris@87: PyAPI_FUNC(int) Py_GetRecursionLimit(void); Chris@87: Chris@87: #define Py_EnterRecursiveCall(where) \ Chris@87: (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ Chris@87: _Py_CheckRecursiveCall(where)) Chris@87: #define Py_LeaveRecursiveCall() \ Chris@87: (--PyThreadState_GET()->recursion_depth) Chris@87: PyAPI_FUNC(int) _Py_CheckRecursiveCall(char *where); Chris@87: PyAPI_DATA(int) _Py_CheckRecursionLimit; Chris@87: #ifdef USE_STACKCHECK Chris@87: # define _Py_MakeRecCheck(x) (++(x) > --_Py_CheckRecursionLimit) Chris@87: #else Chris@87: # define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) Chris@87: #endif Chris@87: Chris@87: PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); Chris@87: PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); Chris@87: Chris@87: PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *); Chris@87: PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *); Chris@87: PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc); Chris@87: Chris@87: /* this used to be handled on a per-thread basis - now just two globals */ Chris@87: PyAPI_DATA(volatile int) _Py_Ticker; Chris@87: PyAPI_DATA(int) _Py_CheckInterval; Chris@87: Chris@87: /* Interface for threads. Chris@87: Chris@87: A module that plans to do a blocking system call (or something else Chris@87: that lasts a long time and doesn't touch Python data) can allow other Chris@87: threads to run as follows: Chris@87: Chris@87: ...preparations here... Chris@87: Py_BEGIN_ALLOW_THREADS Chris@87: ...blocking system call here... Chris@87: Py_END_ALLOW_THREADS Chris@87: ...interpret result here... Chris@87: Chris@87: The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a Chris@87: {}-surrounded block. Chris@87: To leave the block in the middle (e.g., with return), you must insert Chris@87: a line containing Py_BLOCK_THREADS before the return, e.g. Chris@87: Chris@87: if (...premature_exit...) { Chris@87: Py_BLOCK_THREADS Chris@87: PyErr_SetFromErrno(PyExc_IOError); Chris@87: return NULL; Chris@87: } Chris@87: Chris@87: An alternative is: Chris@87: Chris@87: Py_BLOCK_THREADS Chris@87: if (...premature_exit...) { Chris@87: PyErr_SetFromErrno(PyExc_IOError); Chris@87: return NULL; Chris@87: } Chris@87: Py_UNBLOCK_THREADS Chris@87: Chris@87: For convenience, that the value of 'errno' is restored across Chris@87: Py_END_ALLOW_THREADS and Py_BLOCK_THREADS. Chris@87: Chris@87: WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND Chris@87: Py_END_ALLOW_THREADS!!! Chris@87: Chris@87: The function PyEval_InitThreads() should be called only from Chris@87: initthread() in "threadmodule.c". Chris@87: Chris@87: Note that not yet all candidates have been converted to use this Chris@87: mechanism! Chris@87: */ Chris@87: Chris@87: PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); Chris@87: PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); Chris@87: Chris@87: #ifdef WITH_THREAD Chris@87: Chris@87: PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); Chris@87: PyAPI_FUNC(void) PyEval_InitThreads(void); Chris@87: PyAPI_FUNC(void) PyEval_AcquireLock(void); Chris@87: PyAPI_FUNC(void) PyEval_ReleaseLock(void); Chris@87: PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); Chris@87: PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); Chris@87: PyAPI_FUNC(void) PyEval_ReInitThreads(void); Chris@87: Chris@87: #define Py_BEGIN_ALLOW_THREADS { \ Chris@87: PyThreadState *_save; \ Chris@87: _save = PyEval_SaveThread(); Chris@87: #define Py_BLOCK_THREADS PyEval_RestoreThread(_save); Chris@87: #define Py_UNBLOCK_THREADS _save = PyEval_SaveThread(); Chris@87: #define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ Chris@87: } Chris@87: Chris@87: #else /* !WITH_THREAD */ Chris@87: Chris@87: #define Py_BEGIN_ALLOW_THREADS { Chris@87: #define Py_BLOCK_THREADS Chris@87: #define Py_UNBLOCK_THREADS Chris@87: #define Py_END_ALLOW_THREADS } Chris@87: Chris@87: #endif /* !WITH_THREAD */ Chris@87: Chris@87: PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); Chris@87: Chris@87: Chris@87: #ifdef __cplusplus Chris@87: } Chris@87: #endif Chris@87: #endif /* !Py_CEVAL_H */