Qucs-S S-parameter Viewer & RF Synthesis Tools
Loading...
Searching...
No Matches
TMainGreenlet.cpp
1/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
12#ifndef T_MAIN_GREENLET_CPP
13#define T_MAIN_GREENLET_CPP
14
15#include "TGreenlet.hpp"
16
17#ifdef Py_GIL_DISABLED
18#include <atomic>
19#endif
20
21// Incremented when we create a main greenlet, in a new thread, decremented
22// when it is destroyed.
23#ifdef Py_GIL_DISABLED
24static std::atomic<Py_ssize_t> G_TOTAL_MAIN_GREENLETS(0);
25#else
26// Protected by the GIL.
27static Py_ssize_t G_TOTAL_MAIN_GREENLETS;
28#endif
29
30namespace greenlet {
31greenlet::PythonAllocator<MainGreenlet> MainGreenlet::allocator;
32
33void* MainGreenlet::operator new(size_t UNUSED(count))
34{
35 return allocator.allocate(1);
36}
37
38
39void MainGreenlet::operator delete(void* ptr)
40{
41 return allocator.deallocate(static_cast<MainGreenlet*>(ptr),
42 1);
43}
44
45
46MainGreenlet::MainGreenlet(PyGreenlet* p, ThreadState* state)
47 : Greenlet(p, StackState::make_main()),
48 _self(p),
49 _thread_state(state)
50{
51 G_TOTAL_MAIN_GREENLETS++;
52}
53
54MainGreenlet::~MainGreenlet()
55{
56 G_TOTAL_MAIN_GREENLETS--;
57 this->tp_clear();
58}
59
60ThreadState*
61MainGreenlet::thread_state() const noexcept
62{
63 return this->_thread_state;
64}
65
66void
67MainGreenlet::thread_state(ThreadState* t) noexcept
68{
69 assert(!t);
70 this->_thread_state = t;
71}
72
73
74const BorrowedMainGreenlet
75MainGreenlet::main_greenlet() const
76{
77 return this->_self;
78}
79
80BorrowedMainGreenlet
81MainGreenlet::find_main_greenlet_in_lineage() const
82{
83 return BorrowedMainGreenlet(this->_self);
84}
85
86bool
87MainGreenlet::was_running_in_dead_thread() const noexcept
88{
89 return !this->_thread_state;
90}
91
92OwnedObject
93MainGreenlet::g_switch()
94{
95 try {
96 this->check_switch_allowed();
97 }
98 catch (const PyErrOccurred&) {
99 this->release_args();
100 throw;
101 }
102
103 switchstack_result_t err = this->g_switchstack();
104 if (err.status < 0) {
105 // XXX: This code path is untested, but it is shared
106 // with the UserGreenlet path that is tested.
107 return this->on_switchstack_or_initialstub_failure(
108 this,
109 err,
110 true, // target was me
111 false // was initial stub
112 );
113 }
114
115 return err.the_new_current_greenlet->g_switch_finish(err);
116}
117
118int
119MainGreenlet::tp_traverse(visitproc visit, void* arg)
120{
121 if (this->_thread_state) {
122 // we've already traversed main, (self), don't do it again.
123 int result = this->_thread_state->tp_traverse(visit, arg, false);
124 if (result) {
125 return result;
126 }
127 }
128 return Greenlet::tp_traverse(visit, arg);
129}
130
131const OwnedObject&
132MainGreenlet::run() const
133{
134 throw AttributeError("Main greenlets do not have a run attribute.");
135}
136
137void
138MainGreenlet::run(const BorrowedObject UNUSED(nrun))
139{
140 throw AttributeError("Main greenlets do not have a run attribute.");
141}
142
143void
144MainGreenlet::parent(const BorrowedObject raw_new_parent)
145{
146 if (!raw_new_parent) {
147 throw AttributeError("can't delete attribute");
148 }
149 throw AttributeError("cannot set the parent of a main greenlet");
150}
151
152const OwnedGreenlet
153MainGreenlet::parent() const
154{
155 return OwnedGreenlet(); // null becomes None
156}
157
158}; // namespace greenlet
159
160#endif
Definition __init__.py:1
int make_main(Sequence[str] argv)
Definition build.py:291
Definition greenlet.h:22
Definition greenlet_allocator.hpp:17