greenlet_internal.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. # pragma clang diagnostic ignored "-Wmissing-field-initializers"
  8. # pragma clang diagnostic ignored "-Wunused-variable"
  9. #endif
  10. /**
  11. * Implementation helpers.
  12. *
  13. * C++ templates and inline functions should go here.
  14. */
  15. #define PY_SSIZE_T_CLEAN
  16. #include "greenlet_compiler_compat.hpp"
  17. #include "greenlet_cpython_compat.hpp"
  18. #include "greenlet_exceptions.hpp"
  19. #include "greenlet_greenlet.hpp"
  20. #include "greenlet_allocator.hpp"
  21. #include <vector>
  22. #include <string>
  23. #define GREENLET_MODULE
  24. struct _greenlet;
  25. typedef struct _greenlet PyGreenlet;
  26. namespace greenlet {
  27. class ThreadState;
  28. };
  29. #define implementation_ptr_t greenlet::Greenlet*
  30. #include "greenlet.h"
  31. G_FP_TMPL_STATIC inline void
  32. greenlet::refs::MainGreenletExactChecker(void *p)
  33. {
  34. if (!p) {
  35. return;
  36. }
  37. // We control the class of the main greenlet exactly.
  38. if (Py_TYPE(p) != &PyGreenlet_Type) {
  39. std::string err("MainGreenlet: Expected exactly a greenlet, not a ");
  40. err += Py_TYPE(p)->tp_name;
  41. throw greenlet::TypeError(err);
  42. }
  43. // Greenlets from dead threads no longer respond to main() with a
  44. // true value; so in that case we need to perform an additional
  45. // check.
  46. Greenlet* g = ((PyGreenlet*)p)->pimpl;
  47. if (g->main()) {
  48. return;
  49. }
  50. if (!dynamic_cast<MainGreenlet*>(g)) {
  51. std::string err("MainGreenlet: Expected exactly a main greenlet, not a ");
  52. err += Py_TYPE(p)->tp_name;
  53. throw greenlet::TypeError(err);
  54. }
  55. }
  56. template <typename T, greenlet::refs::TypeChecker TC>
  57. inline greenlet::Greenlet* greenlet::refs::_OwnedGreenlet<T, TC>::operator->() const G_NOEXCEPT
  58. {
  59. return reinterpret_cast<PyGreenlet*>(this->p)->pimpl;
  60. }
  61. template <typename T, greenlet::refs::TypeChecker TC>
  62. inline greenlet::Greenlet* greenlet::refs::_BorrowedGreenlet<T, TC>::operator->() const G_NOEXCEPT
  63. {
  64. return reinterpret_cast<PyGreenlet*>(this->p)->pimpl;
  65. }
  66. #include <memory>
  67. #include <stdexcept>
  68. extern PyTypeObject PyGreenlet_Type;
  69. /**
  70. * Forward declarations needed in multiple files.
  71. */
  72. static PyGreenlet* green_create_main(greenlet::ThreadState*);
  73. static PyObject* green_switch(PyGreenlet* self, PyObject* args, PyObject* kwargs);
  74. static int green_is_gc(BorrowedGreenlet self);
  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: