/ext/pycall/gc.c
https://github.com/mrkn/pycall.rb · C · 74 lines · 59 code · 15 blank · 0 comment · 2 complexity · 286e5f503625c9b48720799cddd57193 MD5 · raw file
- #include "pycall_internal.h"
- static ID id_gcguard_table;
- static PyObject *weakref_callback_pyobj;
- static PyObject *gcguard_weakref_destroyed(PyObject *self, PyObject *weakref);
- PyMethodDef gcguard_weakref_callback_def = {
- "_gcguard_weakref_destroyed", (PyCFunction) gcguard_weakref_destroyed, Py_METH_O
- };
- static PyObject *
- gcguard_weakref_destroyed(PyObject *self, PyObject *weakref)
- {
- pycall_gcguard_delete(weakref);
- Py_API(Py_DecRef)(weakref);
- Py_API(Py_IncRef)(Py_API(_Py_NoneStruct));
- return Py_API(_Py_NoneStruct);
- }
- void
- pycall_gcguard_aset(PyObject *pyobj, VALUE rbobj)
- {
- VALUE table = rb_ivar_get(mPyCall, id_gcguard_table);
- rb_hash_aset(table, PTR2NUM(pyobj), rbobj);
- }
- void
- pycall_gcguard_delete(PyObject *pyobj)
- {
- VALUE table = rb_ivar_get(mPyCall, id_gcguard_table);
- rb_hash_delete(table, PTR2NUM(pyobj));
- }
- void
- pycall_gcguard_register_pyrubyobj(PyObject *pyobj)
- {
- VALUE rbobj;
- if (!PyRuby_Check(pyobj)) {
- rb_raise(rb_eTypeError, "wrong type of python object %s (expect PyCall.ruby_object)", Py_TYPE(pyobj)->tp_name);
- }
- rbobj = PyRuby_get_ruby_object(pyobj);
- pycall_gcguard_aset(pyobj, rbobj);
- }
- void
- pycall_gcguard_unregister_pyrubyobj(PyObject *pyobj)
- {
- if (!PyRuby_Check(pyobj)) {
- rb_raise(rb_eTypeError, "wrong type of python object %s (expect PyCall.ruby_object)", Py_TYPE(pyobj)->tp_name);
- }
- pycall_gcguard_delete(pyobj);
- }
- void
- pycall_gcguard_register(PyObject *pyobj, VALUE obj)
- {
- PyObject *wref;
- wref = Py_API(PyWeakref_NewRef)(pyobj, weakref_callback_pyobj);
- pycall_gcguard_aset(wref, obj);
- }
- void
- pycall_init_gcguard(void)
- {
- id_gcguard_table = rb_intern("gcguard_table");
- rb_ivar_set(mPyCall, id_gcguard_table, rb_hash_new());
- weakref_callback_pyobj = Py_API(PyCFunction_NewEx)(&gcguard_weakref_callback_def, NULL, NULL);
- }