1 /* vim:set noet ts=8 sw=8 : */
3 /* Greenlet object interface */
5 #ifndef Py_GREENLETOBJECT_H
6 #define Py_GREENLETOBJECT_H
14 #define GREENLET_VERSION "0.4.17"
16 #if PY_VERSION_HEX >= 0x030700A3
17 # define GREENLET_USE_EXC_INFO
20 #ifndef GREENLET_USE_CONTEXT_VARS
22 #define GREENLET_USE_CONTEXT_VARS 1
24 #define GREENLET_USE_CONTEXT_VARS 0
28 typedef struct _greenlet {
34 struct _greenlet* stack_prev;
35 struct _greenlet* parent;
37 struct _frame* top_frame;
39 PyObject* weakreflist;
40 #ifdef GREENLET_USE_EXC_INFO
41 _PyErr_StackItem* exc_info;
42 _PyErr_StackItem exc_state;
46 PyObject* exc_traceback;
49 #if GREENLET_USE_CONTEXT_VARS
54 #define PyGreenlet_Check(op) PyObject_TypeCheck(op, &PyGreenlet_Type)
55 #define PyGreenlet_MAIN(op) (((PyGreenlet*)(op))->stack_stop == (char*) -1)
56 #define PyGreenlet_STARTED(op) (((PyGreenlet*)(op))->stack_stop != NULL)
57 #define PyGreenlet_ACTIVE(op) (((PyGreenlet*)(op))->stack_start != NULL)
58 #define PyGreenlet_GET_PARENT(op) (((PyGreenlet*)(op))->parent)
60 #if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 7) || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 1) || PY_MAJOR_VERSION > 3
61 #define GREENLET_USE_PYCAPSULE
66 /* Total number of symbols that are exported */
67 #define PyGreenlet_API_pointers 8
69 #define PyGreenlet_Type_NUM 0
70 #define PyExc_GreenletError_NUM 1
71 #define PyExc_GreenletExit_NUM 2
73 #define PyGreenlet_New_NUM 3
74 #define PyGreenlet_GetCurrent_NUM 4
75 #define PyGreenlet_Throw_NUM 5
76 #define PyGreenlet_Switch_NUM 6
77 #define PyGreenlet_SetParent_NUM 7
79 #ifndef GREENLET_MODULE
80 /* This section is used by modules that uses the greenlet C API */
81 static void **_PyGreenlet_API = NULL;
83 #define PyGreenlet_Type (*(PyTypeObject *) _PyGreenlet_API[PyGreenlet_Type_NUM])
85 #define PyExc_GreenletError \
86 ((PyObject *) _PyGreenlet_API[PyExc_GreenletError_NUM])
88 #define PyExc_GreenletExit \
89 ((PyObject *) _PyGreenlet_API[PyExc_GreenletExit_NUM])
92 * PyGreenlet_New(PyObject *args)
94 * greenlet.greenlet(run, parent=None)
96 #define PyGreenlet_New \
97 (* (PyGreenlet * (*)(PyObject *run, PyGreenlet *parent)) \
98 _PyGreenlet_API[PyGreenlet_New_NUM])
101 * PyGreenlet_GetCurrent(void)
103 * greenlet.getcurrent()
105 #define PyGreenlet_GetCurrent \
106 (* (PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM])
110 * PyGreenlet *greenlet,
117 #define PyGreenlet_Throw \
119 (PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)) \
120 _PyGreenlet_API[PyGreenlet_Throw_NUM])
123 * PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args)
125 * g.switch(*args, **kwargs)
127 #define PyGreenlet_Switch \
128 (* (PyObject * (*)(PyGreenlet *greenlet, PyObject *args, PyObject *kwargs)) \
129 _PyGreenlet_API[PyGreenlet_Switch_NUM])
132 * PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent)
134 * g.parent = new_parent
136 #define PyGreenlet_SetParent \
137 (* (int (*)(PyGreenlet *greenlet, PyGreenlet *nparent)) \
138 _PyGreenlet_API[PyGreenlet_SetParent_NUM])
140 /* Macro that imports greenlet and initializes C API */
141 #ifdef GREENLET_USE_PYCAPSULE
142 #define PyGreenlet_Import() \
144 _PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \
147 #define PyGreenlet_Import() \
149 PyObject *module = PyImport_ImportModule("greenlet"); \
150 if (module != NULL) { \
151 PyObject *c_api_object = PyObject_GetAttrString( \
153 if (c_api_object != NULL && PyCObject_Check(c_api_object)) { \
155 (void **) PyCObject_AsVoidPtr(c_api_object); \
156 Py_DECREF(c_api_object); \
163 #endif /* GREENLET_MODULE */
168 #endif /* !Py_GREENLETOBJECT_H */