CObjects.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #ifndef COBJECTS_CPP
  2. #define COBJECTS_CPP
  3. /*****************************************************************************
  4. * C interface
  5. *
  6. * These are exported using the CObject API
  7. */
  8. #ifdef __clang__
  9. # pragma clang diagnostic push
  10. # pragma clang diagnostic ignored "-Wunused-function"
  11. #endif
  12. #include "greenlet_exceptions.hpp"
  13. #include "greenlet_internal.hpp"
  14. #include "greenlet_refs.hpp"
  15. #include "TThreadStateDestroy.cpp"
  16. #include "PyGreenlet.hpp"
  17. using greenlet::PyErrOccurred;
  18. using greenlet::Require;
  19. extern "C" {
  20. static PyGreenlet*
  21. PyGreenlet_GetCurrent(void)
  22. {
  23. return GET_THREAD_STATE().state().get_current().relinquish_ownership();
  24. }
  25. static int
  26. PyGreenlet_SetParent(PyGreenlet* g, PyGreenlet* nparent)
  27. {
  28. return green_setparent((PyGreenlet*)g, (PyObject*)nparent, NULL);
  29. }
  30. static PyGreenlet*
  31. PyGreenlet_New(PyObject* run, PyGreenlet* parent)
  32. {
  33. using greenlet::refs::NewDictReference;
  34. // In the past, we didn't use green_new and green_init, but that
  35. // was a maintenance issue because we duplicated code. This way is
  36. // much safer, but slightly slower. If that's a problem, we could
  37. // refactor green_init to separate argument parsing from initialization.
  38. OwnedGreenlet g = OwnedGreenlet::consuming(green_new(&PyGreenlet_Type, nullptr, nullptr));
  39. if (!g) {
  40. return NULL;
  41. }
  42. try {
  43. NewDictReference kwargs;
  44. if (run) {
  45. kwargs.SetItem(mod_globs->str_run, run);
  46. }
  47. if (parent) {
  48. kwargs.SetItem("parent", (PyObject*)parent);
  49. }
  50. Require(green_init(g.borrow(), mod_globs->empty_tuple, kwargs.borrow()));
  51. }
  52. catch (const PyErrOccurred&) {
  53. return nullptr;
  54. }
  55. return g.relinquish_ownership();
  56. }
  57. static PyObject*
  58. PyGreenlet_Switch(PyGreenlet* self, PyObject* args, PyObject* kwargs)
  59. {
  60. if (!PyGreenlet_Check(self)) {
  61. PyErr_BadArgument();
  62. return NULL;
  63. }
  64. if (args == NULL) {
  65. args = mod_globs->empty_tuple;
  66. }
  67. if (kwargs == NULL || !PyDict_Check(kwargs)) {
  68. kwargs = NULL;
  69. }
  70. return green_switch(self, args, kwargs);
  71. }
  72. static PyObject*
  73. PyGreenlet_Throw(PyGreenlet* self, PyObject* typ, PyObject* val, PyObject* tb)
  74. {
  75. if (!PyGreenlet_Check(self)) {
  76. PyErr_BadArgument();
  77. return nullptr;
  78. }
  79. try {
  80. PyErrPieces err_pieces(typ, val, tb);
  81. return internal_green_throw(self, err_pieces).relinquish_ownership();
  82. }
  83. catch (const PyErrOccurred&) {
  84. return nullptr;
  85. }
  86. }
  87. static int
  88. Extern_PyGreenlet_MAIN(PyGreenlet* self)
  89. {
  90. if (!PyGreenlet_Check(self)) {
  91. PyErr_BadArgument();
  92. return -1;
  93. }
  94. return self->pimpl->main();
  95. }
  96. static int
  97. Extern_PyGreenlet_ACTIVE(PyGreenlet* self)
  98. {
  99. if (!PyGreenlet_Check(self)) {
  100. PyErr_BadArgument();
  101. return -1;
  102. }
  103. return self->pimpl->active();
  104. }
  105. static int
  106. Extern_PyGreenlet_STARTED(PyGreenlet* self)
  107. {
  108. if (!PyGreenlet_Check(self)) {
  109. PyErr_BadArgument();
  110. return -1;
  111. }
  112. return self->pimpl->started();
  113. }
  114. static PyGreenlet*
  115. Extern_PyGreenlet_GET_PARENT(PyGreenlet* self)
  116. {
  117. if (!PyGreenlet_Check(self)) {
  118. PyErr_BadArgument();
  119. return NULL;
  120. }
  121. // This can return NULL even if there is no exception
  122. return self->pimpl->parent().acquire();
  123. }
  124. } // extern C.
  125. /** End C API ****************************************************************/
  126. #ifdef __clang__
  127. # pragma clang diagnostic pop
  128. #endif
  129. #endif