greenlet.h 3.7 KB

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