… | |
… | |
102 | unordered_vector<attachable *> attachable::mortals; |
102 | unordered_vector<attachable *> attachable::mortals; |
103 | |
103 | |
104 | attachable::~attachable () |
104 | attachable::~attachable () |
105 | { |
105 | { |
106 | assert (!self); |
106 | assert (!self); |
|
|
107 | assert (!cb); |
107 | } |
108 | } |
108 | |
109 | |
109 | int |
110 | int |
110 | attachable::refcnt_cnt () const |
111 | attachable::refcnt_cnt () const |
111 | { |
112 | { |
… | |
… | |
117 | { |
118 | { |
118 | if (self |
119 | if (self |
119 | && SvREFCNT (self) == 1 |
120 | && SvREFCNT (self) == 1 |
120 | && !HvTOTALKEYS (self)) |
121 | && !HvTOTALKEYS (self)) |
121 | { |
122 | { |
|
|
123 | SV *self = (SV *)this->self; |
|
|
124 | |
|
|
125 | SvREFCNT_inc (self); |
|
|
126 | sv_unmagic (self, PERL_MAGIC_ext); |
122 | SvREFCNT_dec ((SV *)self); |
127 | SvREFCNT_dec (self); |
123 | assert (!self); |
128 | assert (!this->self); |
124 | } |
129 | } |
125 | } |
130 | } |
126 | |
131 | |
127 | // check wether the object really is dead |
132 | // check wether the object really is dead |
128 | void |
133 | void |
… | |
… | |
130 | { |
135 | { |
131 | if (refcnt_cnt () > 0) |
136 | if (refcnt_cnt () > 0) |
132 | return; |
137 | return; |
133 | |
138 | |
134 | destroy (); |
139 | destroy (); |
|
|
140 | } |
|
|
141 | |
|
|
142 | void |
|
|
143 | attachable::do_destroy () |
|
|
144 | { |
|
|
145 | invoke (EVENT_ATTACHABLE_DESTROY, DT_END); |
|
|
146 | |
|
|
147 | if (cb) |
|
|
148 | { |
|
|
149 | SvREFCNT_dec (cb); |
|
|
150 | cb = 0; |
|
|
151 | } |
135 | |
152 | |
136 | if (self) |
153 | if (self) |
137 | { |
154 | { |
138 | hv_clear (self); |
155 | hv_clear (self); |
|
|
156 | |
|
|
157 | SV *self = (SV *)this->self; |
|
|
158 | SvREFCNT_inc (self); |
139 | sv_unmagic ((SV *)self, PERL_MAGIC_ext); |
159 | sv_unmagic (self, PERL_MAGIC_ext); |
140 | SvREFCNT_dec (self); |
160 | SvREFCNT_dec (self); |
141 | self = 0; |
161 | // self is now 0 |
|
|
162 | assert (!this->self);//D//TODO remove soon |
142 | } |
163 | } |
143 | } |
|
|
144 | |
|
|
145 | void |
|
|
146 | attachable::do_destroy () |
|
|
147 | { |
|
|
148 | invoke (EVENT_ATTACHABLE_DESTROY, DT_END); |
|
|
149 | |
|
|
150 | if (self) |
|
|
151 | hv_clear (self); |
|
|
152 | |
164 | |
153 | mortals.push_back (this); |
165 | mortals.push_back (this); |
154 | } |
166 | } |
155 | |
167 | |
156 | void |
168 | void |
… | |
… | |
227 | |
239 | |
228 | static int |
240 | static int |
229 | attachable_free (pTHX_ SV *sv, MAGIC *mg) |
241 | attachable_free (pTHX_ SV *sv, MAGIC *mg) |
230 | { |
242 | { |
231 | attachable *at = (attachable *)mg->mg_ptr; |
243 | attachable *at = (attachable *)mg->mg_ptr; |
|
|
244 | |
|
|
245 | //TODO: check if transaction behaviour is really required here |
|
|
246 | if (SV *self = (SV *)at->self) |
|
|
247 | { |
232 | at->self = 0; |
248 | at->self = 0; |
|
|
249 | SvREFCNT_dec (self); |
|
|
250 | } |
|
|
251 | |
233 | // next line makes sense, but most objects still have refcnt 0 by default |
252 | // next line makes sense, but most objects still have refcnt 0 by default |
234 | //at->refcnt_chk (); |
253 | //at->refcnt_chk (); |
235 | return 0; |
254 | return 0; |
236 | } |
255 | } |
237 | |
256 | |
… | |
… | |
1699 | CODE: |
1718 | CODE: |
1700 | RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); |
1719 | RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); |
1701 | OUTPUT: |
1720 | OUTPUT: |
1702 | RETVAL |
1721 | RETVAL |
1703 | |
1722 | |
|
|
1723 | int mortals_size () |
|
|
1724 | CODE: |
|
|
1725 | RETVAL = attachable::mortals.size (); |
|
|
1726 | OUTPUT: RETVAL |
|
|
1727 | |
|
|
1728 | #object *mortals (U32 index) |
|
|
1729 | # CODE: |
|
|
1730 | # RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0; |
|
|
1731 | # OUTPUT: RETVAL |
|
|
1732 | |
1704 | INCLUDE: $PERL genacc attachable ../include/cfperl.h | |
1733 | INCLUDE: $PERL genacc attachable ../include/cfperl.h | |
1705 | |
1734 | |
1706 | MODULE = cf PACKAGE = cf::global |
1735 | MODULE = cf PACKAGE = cf::global |
1707 | |
1736 | |
1708 | int invoke (SV *klass, int event, ...) |
1737 | int invoke (SV *klass, int event, ...) |
… | |
… | |
1724 | for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i))); |
1753 | for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i))); |
1725 | RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END); |
1754 | RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END); |
1726 | OUTPUT: RETVAL |
1755 | OUTPUT: RETVAL |
1727 | |
1756 | |
1728 | SV *registry (object *op) |
1757 | SV *registry (object *op) |
1729 | |
|
|
1730 | void mortals () |
|
|
1731 | PPCODE: |
|
|
1732 | EXTEND (SP, object::mortals.size ()); |
|
|
1733 | for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i) |
|
|
1734 | PUSHs (to_sv (*i)); |
|
|
1735 | |
1758 | |
1736 | int objects_size () |
1759 | int objects_size () |
1737 | CODE: |
1760 | CODE: |
1738 | RETVAL = objects.size (); |
1761 | RETVAL = objects.size (); |
1739 | OUTPUT: RETVAL |
1762 | OUTPUT: RETVAL |