ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
(Generate patch)

Comparing deliantra/server/server/cfperl.xs (file contents):
Revision 1.146 by root, Fri Jan 19 22:24:10 2007 UTC vs.
Revision 1.154 by root, Fri Jan 26 21:44:11 2007 UTC

102unordered_vector<attachable *> attachable::mortals; 102unordered_vector<attachable *> attachable::mortals;
103 103
104attachable::~attachable () 104attachable::~attachable ()
105{ 105{
106 assert (!self); 106 assert (!self);
107 assert (!cb);
107} 108}
108 109
109int 110int
110attachable::refcnt_cnt () const 111attachable::refcnt_cnt () const
111{ 112{
112 return refcnt + (self ? SvREFCNT (self) : 0); 113 return refcnt + (self ? SvREFCNT (self) - 1 : 0);
113} 114}
114 115
115void 116void
116attachable::optimise () 117attachable::optimise ()
117{ 118{
118 if (self 119 if (self
119 && SvREFCNT (self) == 1 120 && SvREFCNT (self) == 1
120 && !HvTOTALKEYS (self)) 121 && !HvTOTALKEYS (self))
121 { 122 {
122 refcnt_inc (); 123 SV *self = (SV *)this->self;
124
125 SvREFCNT_inc (self);
126 sv_unmagic (self, PERL_MAGIC_ext);
123 SvREFCNT_dec ((SV *)self); 127 SvREFCNT_dec (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
128void 133void
129attachable::do_check () 134attachable::do_check ()
130{ 135{
131 if (refcnt > 0 || refcnt_cnt () > 0) 136 if (refcnt_cnt () > 0)
132 return; 137 return;
133 138
134 destroy (); 139 destroy ();
140}
141
142void
143attachable::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
145void
146attachable::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
156void 168void
164} 176}
165 177
166void 178void
167attachable::check_mortals () 179attachable::check_mortals ()
168{ 180{
169 for (int i = 0; i < mortals.size (); ) 181 static int i = 0;
182
183 for (;;)
170 { 184 {
185 if (i >= mortals.size ())
186 {
187 i = 0;
188
189 if (mortals.size () > 1000)
190 fprintf (stderr, "mortal queue size (%d) exceeds 1000.\n", (int)mortals.size ());
191
192 break;
193 }
194
171 attachable *obj = mortals [i]; 195 attachable *obj = mortals [i];
172 196
173 obj->refcnt_chk (); // unborrow from perl, if necessary 197 obj->refcnt_chk (); // unborrow from perl, if necessary
174 198
199 //if (obj->refcnt > 0 || obj->self)
175 if (obj->refcnt || obj->self) 200 if (obj->refcnt || obj->self)
176 { 201 {
177#if 0 202//printf ("%p rc %d\n", obj, obj->refcnt_cnt ());//D
178 if (mortals.size() > 5)fprintf (stderr, "%d delaying %d:%p:%s %d (self %p:%d)\n", time(0),i, obj, typeid (*obj).name (),
179 obj->refcnt, obj->self, obj->self ? SvREFCNT(obj->self): - 1);//D
180#endif
181
182 ++i; // further delay freeing 203 ++i; // further delay freeing
204
205 if (!(i & 0x3ff))
206 break;
183 }//D 207 }
184 else 208 else
185 { 209 {
186 //Dfprintf (stderr, "deleteing %d:%p:%s\n", i, obj,typeid (*obj).name ());//D
187 mortals.erase (i); 210 mortals.erase (i);
188 delete obj; 211 delete obj;
189 } 212 }
190 } 213 }
191} 214}
216 239
217static int 240static int
218attachable_free (pTHX_ SV *sv, MAGIC *mg) 241attachable_free (pTHX_ SV *sv, MAGIC *mg)
219{ 242{
220 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 {
221 at->self = 0; 248 at->self = 0;
249 SvREFCNT_dec (self);
250 }
251
222 // 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
223 //at->refcnt_chk (); 253 //at->refcnt_chk ();
224 return 0; 254 return 0;
225} 255}
226 256
234 264
235 if (!obj->self) 265 if (!obj->self)
236 { 266 {
237 obj->self = newHV (); 267 obj->self = newHV ();
238 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); 268 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0);
239
240 // borrow the refcnt from the object
241 // it is important thta no refcnt_chk is being executed here
242 obj->refcnt_dec ();
243 269
244 // now bless the object _once_ 270 // now bless the object _once_
245 return sv_bless (newRV_inc ((SV *)obj->self), stash); 271 return sv_bless (newRV_inc ((SV *)obj->self), stash);
246 } 272 }
247 else 273 else
895void 921void
896iw::alloc () 922iw::alloc ()
897{ 923{
898 pe = GEventAPI->new_idle (0, 0); 924 pe = GEventAPI->new_idle (0, 0);
899 925
926 WaREENTRANT_off (pe);
900 pe->base.callback = (void *)iw_dispatch; 927 pe->base.callback = (void *)iw_dispatch;
901 pe->base.ext_data = (void *)this; 928 pe->base.ext_data = (void *)this;
902} 929}
903 930
904static void iow_dispatch (pe_event *ev) 931static void iow_dispatch (pe_event *ev)
910void 937void
911iow::alloc () 938iow::alloc ()
912{ 939{
913 pe = GEventAPI->new_io (0, 0); 940 pe = GEventAPI->new_io (0, 0);
914 941
942 WaREENTRANT_off (pe);
915 pe->base.callback = (void *)iow_dispatch; 943 pe->base.callback = (void *)iow_dispatch;
916 pe->base.ext_data = (void *)this; 944 pe->base.ext_data = (void *)this;
917 945
918 pe->fd = -1; 946 pe->fd = -1;
919 pe->poll = 0; 947 pe->poll = 0;
1248 const_iv (FLAG_IS_WATER) 1276 const_iv (FLAG_IS_WATER)
1249 const_iv (FLAG_CONTENT_ON_GEN) 1277 const_iv (FLAG_CONTENT_ON_GEN)
1250 const_iv (FLAG_IS_A_TEMPLATE) 1278 const_iv (FLAG_IS_A_TEMPLATE)
1251 const_iv (FLAG_IS_BUILDABLE) 1279 const_iv (FLAG_IS_BUILDABLE)
1252 const_iv (FLAG_DESTROY_ON_DEATH) 1280 const_iv (FLAG_DESTROY_ON_DEATH)
1253 const_iv (FLAG_NO_SAVE) 1281 const_iv (FLAG_NO_MAP_SAVE)
1254 1282
1255 const_iv (NDI_BLACK) 1283 const_iv (NDI_BLACK)
1256 const_iv (NDI_WHITE) 1284 const_iv (NDI_WHITE)
1257 const_iv (NDI_NAVY) 1285 const_iv (NDI_NAVY)
1258 const_iv (NDI_RED) 1286 const_iv (NDI_RED)
1443 const_iv (ATNR_BLIND) 1471 const_iv (ATNR_BLIND)
1444 const_iv (ATNR_INTERNAL) 1472 const_iv (ATNR_INTERNAL)
1445 const_iv (ATNR_LIFE_STEALING) 1473 const_iv (ATNR_LIFE_STEALING)
1446 const_iv (ATNR_DISEASE) 1474 const_iv (ATNR_DISEASE)
1447 1475
1448 const_iv (MAP_FLUSH)
1449 const_iv (MAP_PLAYER_UNIQUE)
1450 const_iv (MAP_BLOCK)
1451 const_iv (MAP_STYLE)
1452 const_iv (MAP_OVERLAY)
1453
1454 const_iv (MAP_IN_MEMORY) 1476 const_iv (MAP_IN_MEMORY)
1455 const_iv (MAP_SWAPPED) 1477 const_iv (MAP_SWAPPED)
1456 const_iv (MAP_LOADING) 1478 const_iv (MAP_LOADING)
1457 const_iv (MAP_SAVING) 1479 const_iv (MAP_SAVING)
1458 1480
1625 1647
1626void cleanup (const char *cause, bool make_core = false) 1648void cleanup (const char *cause, bool make_core = false)
1627 1649
1628void emergency_save () 1650void emergency_save ()
1629 1651
1652UV sv_2watcher (SV *w)
1653 CODE:
1654 RETVAL = (UV)GEventAPI->sv_2watcher (w);
1655 OUTPUT:
1656 RETVAL
1657
1630void _exit (int status = 0) 1658void _exit (int status = 0)
1631 1659
1632#if _POSIX_MEMLOCK 1660#if _POSIX_MEMLOCK
1633 1661
1634int mlockall (int flags = MCL_CURRENT | MCL_FUTURE) 1662int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1690 CODE: 1718 CODE:
1691 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); 1719 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1692 OUTPUT: 1720 OUTPUT:
1693 RETVAL 1721 RETVAL
1694 1722
1723int 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
1695INCLUDE: $PERL genacc attachable ../include/cfperl.h | 1733INCLUDE: $PERL genacc attachable ../include/cfperl.h |
1696 1734
1697MODULE = cf PACKAGE = cf::global 1735MODULE = cf PACKAGE = cf::global
1698 1736
1699int invoke (SV *klass, int event, ...) 1737int invoke (SV *klass, int event, ...)
1715 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)));
1716 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END); 1754 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END);
1717 OUTPUT: RETVAL 1755 OUTPUT: RETVAL
1718 1756
1719SV *registry (object *op) 1757SV *registry (object *op)
1720
1721void mortals ()
1722 PPCODE:
1723 EXTEND (SP, object::mortals.size ());
1724 for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i)
1725 PUSHs (to_sv (*i));
1726 1758
1727int objects_size () 1759int objects_size ()
1728 CODE: 1760 CODE:
1729 RETVAL = objects.size (); 1761 RETVAL = objects.size ();
1730 OUTPUT: RETVAL 1762 OUTPUT: RETVAL

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines