Sha256: a9e8aa7c31a1d0836e7c81dbbfddaa809b88dfd5956343364a3aeef7c2b3b1a5

Contents?: true

Size: 1.78 KB

Versions: 16

Compression:

Stored size: 1.78 KB

Contents

#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);
}

Version data entries

16 entries across 16 versions & 1 rubygems

Version Path
pycall-1.4.0 ext/pycall/gc.c
pycall-1.3.1 ext/pycall/gc.c
pycall-1.3.0 ext/pycall/gc.c
pycall-1.3.0.dev ext/pycall/gc.c
pycall-1.2.1 ext/pycall/gc.c
pycall-1.2.0 ext/pycall/gc.c
pycall-1.2.0.beta1 ext/pycall/gc.c
pycall-1.1.0.rc1 ext/pycall/gc.c
pycall-1.0.3 ext/pycall/gc.c
pycall-1.0.2-x86-mingw32 ext/pycall/gc.c
pycall-1.0.2-x64-mingw32 ext/pycall/gc.c
pycall-1.0.2 ext/pycall/gc.c
pycall-1.0.1-x86-mingw32 ext/pycall/gc.c
pycall-1.0.1-x64-mingw32 ext/pycall/gc.c
pycall-1.0.1 ext/pycall/gc.c
pycall-1.0.0 ext/pycall/gc.c