Fixed an issue with destruction callbacks in the QApplication destructor - in this case the interpreter may be nulled already and callbacks must not happen into Ruby/Python.

This commit is contained in:
Matthias Köfferlein 2018-09-06 23:37:26 +02:00 committed by Matthias Koefferlein
parent 8c4099b77d
commit cb15132029
7 changed files with 61 additions and 6 deletions

View File

@ -41,6 +41,7 @@ struct GSI_PUBLIC Callee
virtual ~Callee () { } virtual ~Callee () { }
virtual void call (int id, SerialArgs &args, SerialArgs &ret) const = 0; virtual void call (int id, SerialArgs &args, SerialArgs &ret) const = 0;
virtual bool can_call () const { return true; }
}; };
/** /**
@ -72,7 +73,7 @@ struct Callback
bool can_issue () const bool can_issue () const
{ {
return callee.get () != 0; return callee && callee->can_call ();
} }
// 0 arguments // 0 arguments

View File

@ -111,6 +111,50 @@ bool CallbackFunction::operator== (const CallbackFunction &other) const
return callable_ref () == other.callable_ref (); return callable_ref () == other.callable_ref ();
} }
/**
* @brief An adaptor class for the callback mechanism
*/
class Callee
: public gsi::Callee
{
public:
/**
* @brief Constructor for a Callee object pointing the to given Python object
*/
Callee (PYAObjectBase *obj);
/**
* @brief Destructor
*/
~Callee ();
/**
* @brief Adds a callback (given by the CallbackFunction)
* This method returns a callback ID which can be used to register the callback
* at an GSI object.
*/
int add_callback (const CallbackFunction &vf);
/**
* @brief Clears all callbacks registered
*/
void clear_callbacks ();
/**
* @brief Implementation of the Callee interface
*/
virtual void call (int id, gsi::SerialArgs &args, gsi::SerialArgs &ret) const;
/**
* @brief Implementation of the Callee interface
*/
virtual bool can_call () const;
private:
PYAObjectBase *mp_obj;
std::vector<CallbackFunction> m_cbfuncs;
};
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Implementation of Callee // Implementation of Callee
@ -138,6 +182,12 @@ Callee::clear_callbacks ()
m_cbfuncs.clear (); m_cbfuncs.clear ();
} }
bool
Callee::can_call () const
{
return pya::PythonInterpreter::instance () != 0;
}
void void
Callee::call (int id, gsi::SerialArgs &args, gsi::SerialArgs &ret) const Callee::call (int id, gsi::SerialArgs &args, gsi::SerialArgs &ret) const
{ {

View File

@ -1732,8 +1732,7 @@ RubyInterpreter::~RubyInterpreter ()
rb_release_top_self (); rb_release_top_self ();
// This prevents reinitialization sp_rba_interpreter = 0;
sp_rba_interpreter = reinterpret_cast<RubyInterpreter *> (1);
} }
RubyInterpreter *RubyInterpreter::instance () RubyInterpreter *RubyInterpreter::instance ()

View File

@ -132,7 +132,7 @@ public:
: m_hash (hash) : m_hash (hash)
{ {
rb_gc_register_address (&m_hash); rb_gc_register_address (&m_hash);
m_keys = rb_ary_new2 (RHASH_SIZE (m_hash)); m_keys = rb_ary_new2 (long (RHASH_SIZE (m_hash)));
rb_gc_register_address (&m_keys); rb_gc_register_address (&m_keys);
rb_hash_foreach (m_hash, (int (*)(...)) &push_key_to_ary_i, m_keys); rb_hash_foreach (m_hash, (int (*)(...)) &push_key_to_ary_i, m_keys);
} }

View File

@ -301,6 +301,11 @@ Proxy::signal_handler (const gsi::MethodBase *meth)
return sh; return sh;
} }
bool Proxy::can_call () const
{
return rba::RubyInterpreter::instance () != 0;
}
void void
Proxy::call (int id, gsi::SerialArgs &args, gsi::SerialArgs &ret) const Proxy::call (int id, gsi::SerialArgs &args, gsi::SerialArgs &ret) const
{ {

View File

@ -147,6 +147,7 @@ public:
VALUE signal_handler (const gsi::MethodBase *meth); VALUE signal_handler (const gsi::MethodBase *meth);
virtual void call (int id, gsi::SerialArgs &args, gsi::SerialArgs &ret) const; virtual void call (int id, gsi::SerialArgs &args, gsi::SerialArgs &ret) const;
virtual bool can_call () const;
private: private:
const gsi::ClassBase *m_cls_decl; const gsi::ClassBase *m_cls_decl;

View File

@ -40,8 +40,7 @@ RubyInterpreter::RubyInterpreter ()
RubyInterpreter::~RubyInterpreter () RubyInterpreter::~RubyInterpreter ()
{ {
// This prevents reinitialization sp_rba_interpreter = 0;
sp_rba_interpreter = reinterpret_cast<RubyInterpreter *> (1);
} }
RubyInterpreter *RubyInterpreter::instance () RubyInterpreter *RubyInterpreter::instance ()