greenlet_internal.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
  2. #ifndef GREENLET_INTERNAL_H
  3. #define GREENLET_INTERNAL_H
  4. #ifdef __clang__
  5. # pragma clang diagnostic push
  6. # pragma clang diagnostic ignored "-Wunused-function"
  7. #endif
  8. /**
  9. * Implementation helpers.
  10. *
  11. * C++ templates and inline functions should go here.
  12. */
  13. #define PY_SSIZE_T_CLEAN
  14. #include "greenlet_compiler_compat.hpp"
  15. #include "greenlet_cpython_compat.hpp"
  16. #include "greenlet_exceptions.hpp"
  17. #include "TGreenlet.hpp"
  18. #include "greenlet_allocator.hpp"
  19. #include <vector>
  20. #include <string>
  21. #define GREENLET_MODULE
  22. struct _greenlet;
  23. typedef struct _greenlet PyGreenlet;
  24. namespace greenlet {
  25. class ThreadState;
  26. // We can't use the PythonAllocator for this, because we push to it
  27. // from the thread state destructor, which doesn't have the GIL,
  28. // and Python's allocators can only be called with the GIL.
  29. typedef std::vector<ThreadState*> cleanup_queue_t;
  30. };
  31. #define implementation_ptr_t greenlet::Greenlet*
  32. #include "greenlet.h"
  33. void
  34. greenlet::refs::MainGreenletExactChecker(void *p)
  35. {
  36. if (!p) {
  37. return;
  38. }
  39. // We control the class of the main greenlet exactly.
  40. if (Py_TYPE(p) != &PyGreenlet_Type) {
  41. std::string err("MainGreenlet: Expected exactly a greenlet, not a ");
  42. err += Py_TYPE(p)->tp_name;
  43. throw greenlet::TypeError(err);
  44. }
  45. // Greenlets from dead threads no longer respond to main() with a
  46. // true value; so in that case we need to perform an additional
  47. // check.
  48. Greenlet* g = static_cast<PyGreenlet*>(p)->pimpl;
  49. if (g->main()) {
  50. return;
  51. }
  52. if (!dynamic_cast<MainGreenlet*>(g)) {
  53. std::string err("MainGreenlet: Expected exactly a main greenlet, not a ");
  54. err += Py_TYPE(p)->tp_name;
  55. throw greenlet::TypeError(err);
  56. }
  57. }
  58. template <typename T, greenlet::refs::TypeChecker TC>
  59. inline greenlet::Greenlet* greenlet::refs::_OwnedGreenlet<T, TC>::operator->() const noexcept
  60. {
  61. return reinterpret_cast<PyGreenlet*>(this->p)->pimpl;
  62. }
  63. template <typename T, greenlet::refs::TypeChecker TC>
  64. inline greenlet::Greenlet* greenlet::refs::_BorrowedGreenlet<T, TC>::operator->() const noexcept
  65. {
  66. return reinterpret_cast<PyGreenlet*>(this->p)->pimpl;
  67. }
  68. #include <memory>
  69. #include <stdexcept>
  70. extern PyTypeObject PyGreenlet_Type;
  71. /**
  72. * Forward declarations needed in multiple files.
  73. */
  74. static PyObject* green_switch(PyGreenlet* self, PyObject* args, PyObject* kwargs);
  75. #ifdef __clang__
  76. # pragma clang diagnostic pop
  77. #endif
  78. #endif
  79. // Local Variables:
  80. // flycheck-clang-include-path: ("../../include" "/opt/local/Library/Frameworks/Python.framework/Versions/3.10/include/python3.10")
  81. // End: