greenlet.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* vim:set noet ts=8 sw=8 : */
  2. /* Greenlet object interface */
  3. #ifndef Py_GREENLETOBJECT_H
  4. #define Py_GREENLETOBJECT_H
  5. #include <Python.h>
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. #define GREENLET_VERSION "0.4.15"
  10. #if PY_VERSION_HEX >= 0x030700A3
  11. # define GREENLET_USE_EXC_INFO
  12. #endif
  13. typedef struct _greenlet {
  14. PyObject_HEAD
  15. char* stack_start;
  16. char* stack_stop;
  17. char* stack_copy;
  18. intptr_t stack_saved;
  19. struct _greenlet* stack_prev;
  20. struct _greenlet* parent;
  21. PyObject* run_info;
  22. struct _frame* top_frame;
  23. int recursion_depth;
  24. PyObject* weakreflist;
  25. #ifdef GREENLET_USE_EXC_INFO
  26. _PyErr_StackItem* exc_info;
  27. _PyErr_StackItem exc_state;
  28. #else
  29. PyObject* exc_type;
  30. PyObject* exc_value;
  31. PyObject* exc_traceback;
  32. #endif
  33. PyObject* dict;
  34. } PyGreenlet;
  35. #define PyGreenlet_Check(op) PyObject_TypeCheck(op, &PyGreenlet_Type)
  36. #define PyGreenlet_MAIN(op) (((PyGreenlet*)(op))->stack_stop == (char*) -1)
  37. #define PyGreenlet_STARTED(op) (((PyGreenlet*)(op))->stack_stop != NULL)
  38. #define PyGreenlet_ACTIVE(op) (((PyGreenlet*)(op))->stack_start != NULL)
  39. #define PyGreenlet_GET_PARENT(op) (((PyGreenlet*)(op))->parent)
  40. #if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 7) || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 1) || PY_MAJOR_VERSION > 3
  41. #define GREENLET_USE_PYCAPSULE
  42. #endif
  43. /* C API functions */
  44. /* Total number of symbols that are exported */
  45. #define PyGreenlet_API_pointers 8
  46. #define PyGreenlet_Type_NUM 0
  47. #define PyExc_GreenletError_NUM 1
  48. #define PyExc_GreenletExit_NUM 2
  49. #define PyGreenlet_New_NUM 3
  50. #define PyGreenlet_GetCurrent_NUM 4
  51. #define PyGreenlet_Throw_NUM 5
  52. #define PyGreenlet_Switch_NUM 6
  53. #define PyGreenlet_SetParent_NUM 7
  54. #ifndef GREENLET_MODULE
  55. /* This section is used by modules that uses the greenlet C API */
  56. static void **_PyGreenlet_API = NULL;
  57. #define PyGreenlet_Type (*(PyTypeObject *) _PyGreenlet_API[PyGreenlet_Type_NUM])
  58. #define PyExc_GreenletError \
  59. ((PyObject *) _PyGreenlet_API[PyExc_GreenletError_NUM])
  60. #define PyExc_GreenletExit \
  61. ((PyObject *) _PyGreenlet_API[PyExc_GreenletExit_NUM])
  62. /*
  63. * PyGreenlet_New(PyObject *args)
  64. *
  65. * greenlet.greenlet(run, parent=None)
  66. */
  67. #define PyGreenlet_New \
  68. (* (PyGreenlet * (*)(PyObject *run, PyGreenlet *parent)) \
  69. _PyGreenlet_API[PyGreenlet_New_NUM])
  70. /*
  71. * PyGreenlet_GetCurrent(void)
  72. *
  73. * greenlet.getcurrent()
  74. */
  75. #define PyGreenlet_GetCurrent \
  76. (* (PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM])
  77. /*
  78. * PyGreenlet_Throw(
  79. * PyGreenlet *greenlet,
  80. * PyObject *typ,
  81. * PyObject *val,
  82. * PyObject *tb)
  83. *
  84. * g.throw(...)
  85. */
  86. #define PyGreenlet_Throw \
  87. (* (PyObject * (*) \
  88. (PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)) \
  89. _PyGreenlet_API[PyGreenlet_Throw_NUM])
  90. /*
  91. * PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args)
  92. *
  93. * g.switch(*args, **kwargs)
  94. */
  95. #define PyGreenlet_Switch \
  96. (* (PyObject * (*)(PyGreenlet *greenlet, PyObject *args, PyObject *kwargs)) \
  97. _PyGreenlet_API[PyGreenlet_Switch_NUM])
  98. /*
  99. * PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent)
  100. *
  101. * g.parent = new_parent
  102. */
  103. #define PyGreenlet_SetParent \
  104. (* (int (*)(PyGreenlet *greenlet, PyGreenlet *nparent)) \
  105. _PyGreenlet_API[PyGreenlet_SetParent_NUM])
  106. /* Macro that imports greenlet and initializes C API */
  107. #ifdef GREENLET_USE_PYCAPSULE
  108. #define PyGreenlet_Import() \
  109. { \
  110. _PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \
  111. }
  112. #else
  113. #define PyGreenlet_Import() \
  114. { \
  115. PyObject *module = PyImport_ImportModule("greenlet"); \
  116. if (module != NULL) { \
  117. PyObject *c_api_object = PyObject_GetAttrString( \
  118. module, "_C_API"); \
  119. if (c_api_object != NULL && PyCObject_Check(c_api_object)) { \
  120. _PyGreenlet_API = \
  121. (void **) PyCObject_AsVoidPtr(c_api_object); \
  122. Py_DECREF(c_api_object); \
  123. } \
  124. Py_DECREF(module); \
  125. } \
  126. }
  127. #endif
  128. #endif /* GREENLET_MODULE */
  129. #ifdef __cplusplus
  130. }
  131. #endif
  132. #endif /* !Py_GREENLETOBJECT_H */