|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef T_GREENLET_GLOBALS |
|
#define T_GREENLET_GLOBALS |
|
|
|
#include "greenlet_refs.hpp" |
|
#include "greenlet_exceptions.hpp" |
|
#include "greenlet_thread_support.hpp" |
|
#include "greenlet_internal.hpp" |
|
|
|
namespace greenlet { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class GreenletGlobals |
|
{ |
|
|
|
public: |
|
const greenlet::refs::ImmortalEventName event_switch; |
|
const greenlet::refs::ImmortalEventName event_throw; |
|
const greenlet::refs::ImmortalException PyExc_GreenletError; |
|
const greenlet::refs::ImmortalException PyExc_GreenletExit; |
|
const greenlet::refs::ImmortalObject empty_tuple; |
|
const greenlet::refs::ImmortalObject empty_dict; |
|
const greenlet::refs::ImmortalString str_run; |
|
Mutex* const thread_states_to_destroy_lock; |
|
greenlet::cleanup_queue_t thread_states_to_destroy; |
|
|
|
GreenletGlobals() : |
|
event_switch("switch"), |
|
event_throw("throw"), |
|
PyExc_GreenletError("greenlet.error"), |
|
PyExc_GreenletExit("greenlet.GreenletExit", PyExc_BaseException), |
|
empty_tuple(Require(PyTuple_New(0))), |
|
empty_dict(Require(PyDict_New())), |
|
str_run("run"), |
|
thread_states_to_destroy_lock(new Mutex()) |
|
{} |
|
|
|
~GreenletGlobals() |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
void queue_to_destroy(ThreadState* ts) const |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
greenlet::cleanup_queue_t& q = const_cast<greenlet::cleanup_queue_t&>(this->thread_states_to_destroy); |
|
q.push_back(ts); |
|
} |
|
|
|
ThreadState* take_next_to_destroy() const |
|
{ |
|
greenlet::cleanup_queue_t& q = const_cast<greenlet::cleanup_queue_t&>(this->thread_states_to_destroy); |
|
ThreadState* result = q.back(); |
|
q.pop_back(); |
|
return result; |
|
} |
|
}; |
|
|
|
}; |
|
|
|
static const greenlet::GreenletGlobals* mod_globs; |
|
|
|
#endif |
|
|