Class: Utilrb::WeakRef

Inherits:
Object show all
Defined in:
ext/utilrb/weakref.cc

Defined Under Namespace

Classes: RefError

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.do_object_finalize(obj_id) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'ext/utilrb/weakref.cc', line 58

static VALUE do_object_finalize(VALUE mod, VALUE obj_id)
{
    RefFromObjID::iterator ref_set = from_obj_id.find(obj_id);
    if (ref_set != from_obj_id.end())
    {
        ObjSet::iterator it = ref_set->second.begin();
        ObjSet::iterator const end = ref_set->second.end();
        for (; it != end; ++it)
        {
            // Do NOT use Data_Wrap_Struct here, it would break on recent Ruby
            // interpreters. The reason is that the object type is reset during
            // GC -- and the call to free functions is deferred.
            //
            // So, at this point, we're sure we have a RDATA in *it (otherwise
            // weakref_free would have been called), but we can't use
            // Data_Wrap_Struct because that would crash.
            WeakRef& ref = *reinterpret_cast<WeakRef*>(RDATA(*it)->data);;
            ref.obj = Qundef;
            from_ref_id.erase(rb_obj_id(*it));
        }
        from_obj_id.erase(obj_id);
    }
    return Qnil;
}

.refcount(obj) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
# File 'ext/utilrb/weakref.cc', line 120

static VALUE refcount(VALUE mod, VALUE obj)
{
    if (0 == (obj & FIXNUM_FLAG))
        obj = rb_obj_id(obj);

    RefFromObjID::const_iterator it = from_obj_id.find(obj);
    if (it == from_obj_id.end())
        return Qnil;
    else
        return INT2FIX(it->second.size());
}

Instance Method Details

#do_initialize(obj) ⇒ Object

object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'ext/utilrb/weakref.cc', line 88

static VALUE weakref_do_initialize(VALUE self, VALUE obj)
{
    if (!FL_ABLE(obj))
    {
        VALUE str = rb_any_to_s(obj);
        rb_raise(rb_eArgError, "%s cannot be finalized", StringValuePtr(str));
    }

    WeakRef& ref = get_weakref(self);
    ref.obj = obj;

    RefFromObjID::iterator it = from_obj_id.find(rb_obj_id(obj));
    if (it == from_obj_id.end())
        it = from_obj_id.insert( make_pair(rb_obj_id(obj), ObjSet()) ).first;

    it->second.insert(self);
    from_ref_id.insert( std::make_pair(rb_obj_id(self), obj) );

    return Qnil;
}

#getObject



109
110
111
112
113
114
115
116
117
118
# File 'ext/utilrb/weakref.cc', line 109

static VALUE weakref_get(VALUE self)
{
    WeakRef const& ref = get_weakref(self);

    if (ref.obj == Qnil)
        rb_raise(cRefError, "initialized weakref");
    if (ref.obj == Qundef)
        rb_raise(cRefError, "finalized object");
    return ref.obj;
}