summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/greenlet/TMainGreenlet.cpp
diff options
context:
space:
mode:
authorcyfraeviolae <cyfraeviolae>2024-04-03 03:10:44 -0400
committercyfraeviolae <cyfraeviolae>2024-04-03 03:10:44 -0400
commit6d7ba58f880be618ade07f8ea080fe8c4bf8a896 (patch)
treeb1c931051ffcebd2bd9d61d98d6233ffa289bbce /venv/lib/python3.11/site-packages/greenlet/TMainGreenlet.cpp
parent4f884c9abc32990b4061a1bb6997b4b37e58ea0b (diff)
venv
Diffstat (limited to 'venv/lib/python3.11/site-packages/greenlet/TMainGreenlet.cpp')
-rw-r--r--venv/lib/python3.11/site-packages/greenlet/TMainGreenlet.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/venv/lib/python3.11/site-packages/greenlet/TMainGreenlet.cpp b/venv/lib/python3.11/site-packages/greenlet/TMainGreenlet.cpp
new file mode 100644
index 0000000..c33aadb
--- /dev/null
+++ b/venv/lib/python3.11/site-packages/greenlet/TMainGreenlet.cpp
@@ -0,0 +1,155 @@
+/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
+/**
+ * Implementation of greenlet::MainGreenlet.
+ *
+ * Format with:
+ * clang-format -i --style=file src/greenlet/greenlet.c
+ *
+ *
+ * Fix missing braces with:
+ * clang-tidy src/greenlet/greenlet.c -fix -checks="readability-braces-around-statements"
+*/
+
+#include "greenlet_greenlet.hpp"
+#include "greenlet_thread_state.hpp"
+
+
+// Protected by the GIL. Incremented when we create a main greenlet,
+// in a new thread, decremented when it is destroyed.
+static Py_ssize_t G_TOTAL_MAIN_GREENLETS;
+
+namespace greenlet {
+greenlet::PythonAllocator<MainGreenlet> MainGreenlet::allocator;
+
+void* MainGreenlet::operator new(size_t UNUSED(count))
+{
+ return allocator.allocate(1);
+}
+
+
+void MainGreenlet::operator delete(void* ptr)
+{
+ return allocator.deallocate(static_cast<MainGreenlet*>(ptr),
+ 1);
+}
+
+
+MainGreenlet::MainGreenlet(PyGreenlet* p, ThreadState* state)
+ : Greenlet(p, StackState::make_main()),
+ _self(p),
+ _thread_state(state)
+{
+ G_TOTAL_MAIN_GREENLETS++;
+}
+
+MainGreenlet::~MainGreenlet()
+{
+ G_TOTAL_MAIN_GREENLETS--;
+ this->tp_clear();
+}
+
+ThreadState*
+MainGreenlet::thread_state() const noexcept
+{
+ return this->_thread_state;
+}
+
+void
+MainGreenlet::thread_state(ThreadState* t) noexcept
+{
+ assert(!t);
+ this->_thread_state = t;
+}
+
+BorrowedGreenlet
+MainGreenlet::self() const noexcept
+{
+ return BorrowedGreenlet(this->_self.borrow());
+}
+
+
+const BorrowedMainGreenlet
+MainGreenlet::main_greenlet() const
+{
+ return this->_self;
+}
+
+BorrowedMainGreenlet
+MainGreenlet::find_main_greenlet_in_lineage() const
+{
+ return BorrowedMainGreenlet(this->_self);
+}
+
+bool
+MainGreenlet::was_running_in_dead_thread() const noexcept
+{
+ return !this->_thread_state;
+}
+
+OwnedObject
+MainGreenlet::g_switch()
+{
+ try {
+ this->check_switch_allowed();
+ }
+ catch (const PyErrOccurred&) {
+ this->release_args();
+ throw;
+ }
+
+ switchstack_result_t err = this->g_switchstack();
+ if (err.status < 0) {
+ // XXX: This code path is untested, but it is shared
+ // with the UserGreenlet path that is tested.
+ return this->on_switchstack_or_initialstub_failure(
+ this,
+ err,
+ true, // target was me
+ false // was initial stub
+ );
+ }
+
+ return err.the_new_current_greenlet->g_switch_finish(err);
+}
+
+int
+MainGreenlet::tp_traverse(visitproc visit, void* arg)
+{
+ if (this->_thread_state) {
+ // we've already traversed main, (self), don't do it again.
+ int result = this->_thread_state->tp_traverse(visit, arg, false);
+ if (result) {
+ return result;
+ }
+ }
+ return Greenlet::tp_traverse(visit, arg);
+}
+
+const OwnedObject&
+MainGreenlet::run() const
+{
+ throw AttributeError("Main greenlets do not have a run attribute.");
+}
+
+void
+MainGreenlet::run(const BorrowedObject UNUSED(nrun))
+{
+ throw AttributeError("Main greenlets do not have a run attribute.");
+}
+
+void
+MainGreenlet::parent(const BorrowedObject raw_new_parent)
+{
+ if (!raw_new_parent) {
+ throw AttributeError("can't delete attribute");
+ }
+ throw AttributeError("cannot set the parent of a main greenlet");
+}
+
+const OwnedGreenlet
+MainGreenlet::parent() const
+{
+ return OwnedGreenlet(); // null becomes None
+}
+
+}; // namespace greenlet