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.142 by elmex, Sun Jan 14 11:00:47 2007 UTC vs.
Revision 1.160 by elmex, Wed Jan 31 14:11:02 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);
114}
115
116void
117attachable::sever_self ()
118{
119 if (HV *self = this->self)
120 {
121 // keep a refcount because sv_unmagic might call attachable_free,
122 // which might clear self, causing sv_unmagic to crash on a now
123 // invalid object.
124 SvREFCNT_inc (self);
125 hv_clear (self);
126 sv_unmagic ((SV *)self, PERL_MAGIC_ext);
127 SvREFCNT_dec (self);
128
129 // self *must* be null now because thats sv_unmagic's job.
130 assert (!this->self);
131 }
113} 132}
114 133
115void 134void
116attachable::optimise () 135attachable::optimise ()
117{ 136{
118 if (self 137 if (self
119 && SvREFCNT (self) == 1 138 && SvREFCNT (self) == 1
120 && !HvTOTALKEYS (self)) 139 && !HvTOTALKEYS (self))
140 sever_self ();
141}
142
143// check wether the object really is dead
144void
145attachable::do_check ()
146{
147 if (refcnt_cnt () > 0)
148 return;
149
150 destroy ();
151}
152
153void
154attachable::do_destroy ()
155{
156 invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
157
158 if (cb)
121 { 159 {
122 refcnt_inc ();
123 SvREFCNT_dec ((SV *)self); 160 SvREFCNT_dec (cb);
161 cb = 0;
124 } 162 }
125}
126
127// check wether the object really is dead
128void
129attachable::do_check ()
130{
131 if (refcnt > 0 || refcnt_cnt () > 0)
132 return;
133
134 destroy ();
135 163
136 if (self) 164 if (self)
137 { 165 sever_self ();
138 hv_clear (self);
139 sv_unmagic ((SV *)self, PERL_MAGIC_ext);
140 SvREFCNT_dec (self);
141 self = 0;
142 }
143}
144
145void
146attachable::do_destroy ()
147{
148 invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
149
150 if (self)
151 hv_clear (self);
152 166
153 mortals.push_back (this); 167 mortals.push_back (this);
154} 168}
155 169
156void 170void
164} 178}
165 179
166void 180void
167attachable::check_mortals () 181attachable::check_mortals ()
168{ 182{
169 for (int i = 0; i < mortals.size (); ) 183 static int i = 0;
184
185 for (;;)
170 { 186 {
187 if (i >= mortals.size ())
188 {
189 i = 0;
190
191 if (mortals.size () > 1000)
192 fprintf (stderr, "mortal queue size (%d) exceeds 1000.\n", (int)mortals.size ());
193
194 break;
195 }
196
171 attachable *obj = mortals [i]; 197 attachable *obj = mortals [i];
172 198
173 obj->refcnt_chk (); // unborrow from perl, if necessary 199 obj->refcnt_chk (); // unborrow from perl, if necessary
174 200
201 //if (obj->refcnt > 0 || obj->self)
175 if (obj->refcnt || obj->self) 202 if (obj->refcnt || obj->self)
176 { 203 {
177#if 0 204//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 205 ++i; // further delay freeing
206
207 if (!(i & 0x3ff))
208 break;
183 }//D 209 }
184 else 210 else
185 { 211 {
186 //Dfprintf (stderr, "deleteing %d:%p:%s\n", i, obj,typeid (*obj).name ());//D
187 mortals.erase (i); 212 mortals.erase (i);
188 delete obj; 213 delete obj;
189 } 214 }
190 } 215 }
191} 216}
216 241
217static int 242static int
218attachable_free (pTHX_ SV *sv, MAGIC *mg) 243attachable_free (pTHX_ SV *sv, MAGIC *mg)
219{ 244{
220 attachable *at = (attachable *)mg->mg_ptr; 245 attachable *at = (attachable *)mg->mg_ptr;
246
247 //TODO: check if transaction behaviour is really required here
248 if (SV *self = (SV *)at->self)
249 {
221 at->self = 0; 250 at->self = 0;
251 SvREFCNT_dec (self);
252 }
253
222 // next line makes sense, but most objects still have refcnt 0 by default 254 // next line makes sense, but most objects still have refcnt 0 by default
223 //at->refcnt_chk (); 255 //at->refcnt_chk ();
224 return 0; 256 return 0;
225} 257}
226 258
234 266
235 if (!obj->self) 267 if (!obj->self)
236 { 268 {
237 obj->self = newHV (); 269 obj->self = newHV ();
238 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); 270 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 271
244 // now bless the object _once_ 272 // now bless the object _once_
245 return sv_bless (newRV_inc ((SV *)obj->self), stash); 273 return sv_bless (newRV_inc ((SV *)obj->self), stash);
246 } 274 }
247 else 275 else
313inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); } 341inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); }
314 342
315inline SV *to_sv (object & v) { return to_sv (&v); } 343inline SV *to_sv (object & v) { return to_sv (&v); }
316inline SV *to_sv (living & v) { return to_sv (&v); } 344inline SV *to_sv (living & v) { return to_sv (&v); }
317 345
318inline SV *to_sv (New_Face * v) { return to_sv (v->name); } 346inline SV *to_sv (facetile * v) { return to_sv (v->name); }
319inline SV *to_sv (treasurelist * v) { return to_sv (v->name); } 347inline SV *to_sv (treasurelist * v) { return to_sv (v->name); }
320 348
321inline SV *to_sv (UUID v) 349inline SV *to_sv (UUID v)
322{ 350{
323 char buf[128]; 351 char buf[128];
324 snprintf (buf, 128, "<1,%" PRIx64 ">", v.seq); 352 snprintf (buf, 128, "<1.%" PRIx64 ">", v.seq);
325 return newSVpv (buf, 0); 353 return newSVpv (buf, 0);
326} 354}
327 355
328inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; } 356inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; }
329inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; } 357inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; }
348inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); } 376inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); }
349inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); } 377inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); }
350inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); } 378inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); }
351inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); } 379inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); }
352 380
353inline void sv_to (SV *sv, New_Face * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; } 381inline void sv_to (SV *sv, facetile * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; }
354inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); } 382inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); }
355 383
356template<class T> 384template<class T>
357inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; } 385inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; }
358 386
895void 923void
896iw::alloc () 924iw::alloc ()
897{ 925{
898 pe = GEventAPI->new_idle (0, 0); 926 pe = GEventAPI->new_idle (0, 0);
899 927
928 WaREENTRANT_off (pe);
900 pe->base.callback = (void *)iw_dispatch; 929 pe->base.callback = (void *)iw_dispatch;
901 pe->base.ext_data = (void *)this; 930 pe->base.ext_data = (void *)this;
902} 931}
903 932
904static void iow_dispatch (pe_event *ev) 933static void iow_dispatch (pe_event *ev)
910void 939void
911iow::alloc () 940iow::alloc ()
912{ 941{
913 pe = GEventAPI->new_io (0, 0); 942 pe = GEventAPI->new_io (0, 0);
914 943
944 WaREENTRANT_off (pe);
915 pe->base.callback = (void *)iow_dispatch; 945 pe->base.callback = (void *)iow_dispatch;
916 pe->base.ext_data = (void *)this; 946 pe->base.ext_data = (void *)this;
917 947
918 pe->fd = -1; 948 pe->fd = -1;
919 pe->poll = 0; 949 pe->poll = 0;
1248 const_iv (FLAG_IS_WATER) 1278 const_iv (FLAG_IS_WATER)
1249 const_iv (FLAG_CONTENT_ON_GEN) 1279 const_iv (FLAG_CONTENT_ON_GEN)
1250 const_iv (FLAG_IS_A_TEMPLATE) 1280 const_iv (FLAG_IS_A_TEMPLATE)
1251 const_iv (FLAG_IS_BUILDABLE) 1281 const_iv (FLAG_IS_BUILDABLE)
1252 const_iv (FLAG_DESTROY_ON_DEATH) 1282 const_iv (FLAG_DESTROY_ON_DEATH)
1253 const_iv (FLAG_NO_SAVE) 1283 const_iv (FLAG_NO_MAP_SAVE)
1254 1284
1255 const_iv (NDI_BLACK) 1285 const_iv (NDI_BLACK)
1256 const_iv (NDI_WHITE) 1286 const_iv (NDI_WHITE)
1257 const_iv (NDI_NAVY) 1287 const_iv (NDI_NAVY)
1258 const_iv (NDI_RED) 1288 const_iv (NDI_RED)
1443 const_iv (ATNR_BLIND) 1473 const_iv (ATNR_BLIND)
1444 const_iv (ATNR_INTERNAL) 1474 const_iv (ATNR_INTERNAL)
1445 const_iv (ATNR_LIFE_STEALING) 1475 const_iv (ATNR_LIFE_STEALING)
1446 const_iv (ATNR_DISEASE) 1476 const_iv (ATNR_DISEASE)
1447 1477
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) 1478 const_iv (MAP_IN_MEMORY)
1455 const_iv (MAP_SWAPPED) 1479 const_iv (MAP_SWAPPED)
1456 const_iv (MAP_LOADING) 1480 const_iv (MAP_LOADING)
1457 const_iv (MAP_SAVING) 1481 const_iv (MAP_SAVING)
1458 1482
1551} 1575}
1552 1576
1553NV floor (NV x) 1577NV floor (NV x)
1554 1578
1555NV ceil (NV x) 1579NV ceil (NV x)
1580
1581NV rndm (...)
1582 CODE:
1583 switch (items)
1584 {
1585 case 0: RETVAL = rndm (); break;
1586 case 1: RETVAL = rndm (SvUV (ST (0))); break;
1587 case 2: RETVAL = rndm (SvIV (ST (0)), SvIV (ST (1))); break;
1588 default: croak ("cf::rndm requires none, one or two parameters."); break;
1589 }
1590 OUTPUT:
1591 RETVAL
1556 1592
1557void server_tick () 1593void server_tick ()
1558 CODE: 1594 CODE:
1559 runtime = SvNVx (sv_runtime); 1595 runtime = SvNVx (sv_runtime);
1560 server_tick (); 1596 server_tick ();
1607 } 1643 }
1608 OUTPUT: RETVAL 1644 OUTPUT: RETVAL
1609 1645
1610void abort () 1646void abort ()
1611 1647
1648void fork_abort (char *cause = "cf::fork_abort")
1649
1612void cleanup (const char *cause, bool make_core = false) 1650void cleanup (const char *cause, bool make_core = false)
1613 1651
1614void emergency_save () 1652void emergency_save ()
1615 1653
1616void _exit (int status = 0) 1654void _exit (int status = EXIT_SUCCESS)
1655
1656UV sv_2watcher (SV *w)
1657 CODE:
1658 RETVAL = (UV)GEventAPI->sv_2watcher (w);
1659 OUTPUT:
1660 RETVAL
1617 1661
1618#if _POSIX_MEMLOCK 1662#if _POSIX_MEMLOCK
1619 1663
1620int mlockall (int flags = MCL_CURRENT | MCL_FUTURE) 1664int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1621 1665
1676 CODE: 1720 CODE:
1677 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); 1721 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1678 OUTPUT: 1722 OUTPUT:
1679 RETVAL 1723 RETVAL
1680 1724
1725int mortals_size ()
1726 CODE:
1727 RETVAL = attachable::mortals.size ();
1728 OUTPUT: RETVAL
1729
1730#object *mortals (U32 index)
1731# CODE:
1732# RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0;
1733# OUTPUT: RETVAL
1734
1681INCLUDE: $PERL genacc attachable ../include/cfperl.h | 1735INCLUDE: $PERL genacc attachable ../include/cfperl.h |
1682 1736
1683MODULE = cf PACKAGE = cf::global 1737MODULE = cf PACKAGE = cf::global
1684 1738
1685int invoke (SV *klass, int event, ...) 1739int invoke (SV *klass, int event, ...)
1702 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END); 1756 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END);
1703 OUTPUT: RETVAL 1757 OUTPUT: RETVAL
1704 1758
1705SV *registry (object *op) 1759SV *registry (object *op)
1706 1760
1707void mortals ()
1708 PPCODE:
1709 EXTEND (SP, object::mortals.size ());
1710 for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i)
1711 PUSHs (to_sv (*i));
1712
1713int objects_size () 1761int objects_size ()
1714 CODE: 1762 CODE:
1715 RETVAL = objects.size (); 1763 RETVAL = objects.size ();
1716 OUTPUT: RETVAL 1764 OUTPUT: RETVAL
1717 1765
1756 1804
1757void 1805void
1758set_animation (object *op, int idx) 1806set_animation (object *op, int idx)
1759 CODE: 1807 CODE:
1760 SET_ANIMATION (op, idx); 1808 SET_ANIMATION (op, idx);
1809
1810int
1811num_animations (object *op)
1812 CODE:
1813 RETVAL = NUM_ANIMATIONS (op);
1814 OUTPUT: RETVAL
1761 1815
1762object *find_best_object_match (object *op, const char *match) 1816object *find_best_object_match (object *op, const char *match)
1763 1817
1764object *find_marked_object (object *op) 1818object *find_marked_object (object *op)
1765 1819
2093 EXTEND (SP, THIS->players); 2147 EXTEND (SP, THIS->players);
2094 for_all_players (pl) 2148 for_all_players (pl)
2095 if (pl->ob && pl->ob->map == THIS) 2149 if (pl->ob && pl->ob->map == THIS)
2096 PUSHs (sv_2mortal (to_sv (pl->ob))); 2150 PUSHs (sv_2mortal (to_sv (pl->ob)));
2097 } 2151 }
2152
2153void
2154maptile::set_regiondata (SV *data, SV *plt)
2155 CODE:
2156{
2157 if (!SvROK (plt) || SvTYPE (SvRV (plt)) != SVt_PVAV)
2158 croak ("maptile::set_regiondata needs arrayref as plt arg");
2159
2160 AV *av = (AV *)SvRV (plt);
2161
2162 region **regionmap = (region **)malloc ((av_len (av) + 1) * sizeof (region *));
2163
2164 for (int i = av_len (av) + 1; i--; )
2165 regionmap [i] = region::find (SvPVutf8_nolen (*av_fetch (av, i, 1)));
2166
2167 THIS->regions = salloc<uint8_t> (THIS->size (), (uint8_t *)SvPVbyte_nolen (data));
2168 THIS->regionmap = regionmap;
2169}
2098 2170
2099void play_sound_map (maptile *map, int x, int y, int sound_num) 2171void play_sound_map (maptile *map, int x, int y, int sound_num)
2100 2172
2101int out_of_map (maptile *map, int x, int y) 2173int out_of_map (maptile *map, int x, int y)
2102 2174
2184 2256
2185void fix_walls (maptile *map, int x, int y) 2257void fix_walls (maptile *map, int x, int y)
2186 2258
2187void fix_walls_around (maptile *map, int x, int y) 2259void fix_walls_around (maptile *map, int x, int y)
2188 2260
2189const char *
2190region_name (maptile *m)
2191 CODE:
2192 RETVAL = get_name_of_region_for_map (m);
2193 OUTPUT: RETVAL
2194
2195# worst xs function of my life 2261# worst xs function of my life
2196bool 2262bool
2197_create_random_map (\ 2263_create_random_map (\
2198 maptile *self,\ 2264 maptile *self,\
2199 char *wallstyle,\ 2265 char *wallstyle,\
2207 char *origin_map,\ 2273 char *origin_map,\
2208 char *final_map,\ 2274 char *final_map,\
2209 char *exitstyle,\ 2275 char *exitstyle,\
2210 char *this_map,\ 2276 char *this_map,\
2211 char *exit_on_final_map,\ 2277 char *exit_on_final_map,\
2212 int Xsize,\ 2278 int xsize,\
2213 int Ysize,\ 2279 int ysize,\
2214 int expand2x,\ 2280 int expand2x,\
2215 int layoutoptions1,\ 2281 int layoutoptions1,\
2216 int layoutoptions2,\ 2282 int layoutoptions2,\
2217 int layoutoptions3,\ 2283 int layoutoptions3,\
2218 int symmetry,\ 2284 int symmetry,\
2223 int dungeon_depth,\ 2289 int dungeon_depth,\
2224 int decoroptions,\ 2290 int decoroptions,\
2225 int orientation,\ 2291 int orientation,\
2226 int origin_y,\ 2292 int origin_y,\
2227 int origin_x,\ 2293 int origin_x,\
2228 int random_seed,\ 2294 U32 random_seed,\
2229 val64 total_map_hp,\ 2295 val64 total_map_hp,\
2230 int map_layout_style,\ 2296 int map_layout_style,\
2231 int treasureoptions,\ 2297 int treasureoptions,\
2232 int symmetry_used,\ 2298 int symmetry_used,\
2233 region *region,\ 2299 region *region,\
2249 assign (rmp.exit_on_final_map, exit_on_final_map); 2315 assign (rmp.exit_on_final_map, exit_on_final_map);
2250 2316
2251 rmp.origin_map = origin_map; 2317 rmp.origin_map = origin_map;
2252 rmp.final_map = final_map; 2318 rmp.final_map = final_map;
2253 rmp.this_map = this_map; 2319 rmp.this_map = this_map;
2254 rmp.Xsize = Xsize; 2320 rmp.xsize = xsize;
2255 rmp.Ysize = Ysize; 2321 rmp.ysize = ysize;
2256 rmp.expand2x = expand2x; 2322 rmp.expand2x = expand2x;
2257 rmp.layoutoptions1 = layoutoptions1; 2323 rmp.layoutoptions1 = layoutoptions1;
2258 rmp.layoutoptions2 = layoutoptions2; 2324 rmp.layoutoptions2 = layoutoptions2;
2259 rmp.layoutoptions3 = layoutoptions3; 2325 rmp.layoutoptions3 = layoutoptions3;
2260 rmp.symmetry = symmetry; 2326 rmp.symmetry = symmetry;
2315 OUTPUT: RETVAL 2381 OUTPUT: RETVAL
2316 2382
2317region *find (char *name) 2383region *find (char *name)
2318 PROTOTYPE: $ 2384 PROTOTYPE: $
2319 CODE: 2385 CODE:
2320 RETVAL = get_region_by_name (name); 2386 RETVAL = region::find (name);
2321 OUTPUT: RETVAL 2387 OUTPUT: RETVAL
2322 2388
2323INCLUDE: $PERL genacc region ../include/map.h | 2389INCLUDE: $PERL genacc region ../include/map.h |
2324 2390
2325MODULE = cf PACKAGE = cf::living 2391MODULE = cf PACKAGE = cf::living

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines