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.144 by root, Fri Jan 19 15:55:27 2007 UTC vs.
Revision 1.156 by root, Sat Jan 27 23:59:29 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];
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
1625 1649
1626void cleanup (const char *cause, bool make_core = false) 1650void cleanup (const char *cause, bool make_core = false)
1627 1651
1628void emergency_save () 1652void emergency_save ()
1629 1653
1630void _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
1631 1661
1632#if _POSIX_MEMLOCK 1662#if _POSIX_MEMLOCK
1633 1663
1634int mlockall (int flags = MCL_CURRENT | MCL_FUTURE) 1664int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1635 1665
1690 CODE: 1720 CODE:
1691 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); 1721 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1692 OUTPUT: 1722 OUTPUT:
1693 RETVAL 1723 RETVAL
1694 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
1695INCLUDE: $PERL genacc attachable ../include/cfperl.h | 1735INCLUDE: $PERL genacc attachable ../include/cfperl.h |
1696 1736
1697MODULE = cf PACKAGE = cf::global 1737MODULE = cf PACKAGE = cf::global
1698 1738
1699int invoke (SV *klass, int event, ...) 1739int invoke (SV *klass, int event, ...)
1715 for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i))); 1755 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); 1756 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END);
1717 OUTPUT: RETVAL 1757 OUTPUT: RETVAL
1718 1758
1719SV *registry (object *op) 1759SV *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 1760
1727int objects_size () 1761int objects_size ()
1728 CODE: 1762 CODE:
1729 RETVAL = objects.size (); 1763 RETVAL = objects.size ();
1730 OUTPUT: RETVAL 1764 OUTPUT: RETVAL
2107 EXTEND (SP, THIS->players); 2141 EXTEND (SP, THIS->players);
2108 for_all_players (pl) 2142 for_all_players (pl)
2109 if (pl->ob && pl->ob->map == THIS) 2143 if (pl->ob && pl->ob->map == THIS)
2110 PUSHs (sv_2mortal (to_sv (pl->ob))); 2144 PUSHs (sv_2mortal (to_sv (pl->ob)));
2111 } 2145 }
2146
2147void
2148maptile::set_regiondata (SV *data, SV *plt)
2149 CODE:
2150{
2151 if (!SvROK (plt) || SvTYPE (SvRV (plt)) != SVt_PVAV)
2152 croak ("maptile::set_regiondata needs arrayref as plt arg");
2153
2154 AV *av = (AV *)SvRV (plt);
2155
2156 region **regionmap = (region **)malloc ((av_len (av) + 1) * sizeof (region *));
2157
2158 for (int i = av_len (av); i; --i)
2159 regionmap [i] = region::find (SvPVutf8_nolen (*av_fetch (av, i, 1)));
2160
2161 THIS->regions = salloc<uint8_t> (THIS->size (), (uint8_t *)SvPVbyte_nolen (data));
2162 THIS->regionmap = regionmap;
2163}
2112 2164
2113void play_sound_map (maptile *map, int x, int y, int sound_num) 2165void play_sound_map (maptile *map, int x, int y, int sound_num)
2114 2166
2115int out_of_map (maptile *map, int x, int y) 2167int out_of_map (maptile *map, int x, int y)
2116 2168
2221 char *origin_map,\ 2273 char *origin_map,\
2222 char *final_map,\ 2274 char *final_map,\
2223 char *exitstyle,\ 2275 char *exitstyle,\
2224 char *this_map,\ 2276 char *this_map,\
2225 char *exit_on_final_map,\ 2277 char *exit_on_final_map,\
2226 int Xsize,\ 2278 int xsize,\
2227 int Ysize,\ 2279 int ysize,\
2228 int expand2x,\ 2280 int expand2x,\
2229 int layoutoptions1,\ 2281 int layoutoptions1,\
2230 int layoutoptions2,\ 2282 int layoutoptions2,\
2231 int layoutoptions3,\ 2283 int layoutoptions3,\
2232 int symmetry,\ 2284 int symmetry,\
2237 int dungeon_depth,\ 2289 int dungeon_depth,\
2238 int decoroptions,\ 2290 int decoroptions,\
2239 int orientation,\ 2291 int orientation,\
2240 int origin_y,\ 2292 int origin_y,\
2241 int origin_x,\ 2293 int origin_x,\
2242 int random_seed,\ 2294 U32 random_seed,\
2243 val64 total_map_hp,\ 2295 val64 total_map_hp,\
2244 int map_layout_style,\ 2296 int map_layout_style,\
2245 int treasureoptions,\ 2297 int treasureoptions,\
2246 int symmetry_used,\ 2298 int symmetry_used,\
2247 region *region,\ 2299 region *region,\
2263 assign (rmp.exit_on_final_map, exit_on_final_map); 2315 assign (rmp.exit_on_final_map, exit_on_final_map);
2264 2316
2265 rmp.origin_map = origin_map; 2317 rmp.origin_map = origin_map;
2266 rmp.final_map = final_map; 2318 rmp.final_map = final_map;
2267 rmp.this_map = this_map; 2319 rmp.this_map = this_map;
2268 rmp.Xsize = Xsize; 2320 rmp.xsize = xsize;
2269 rmp.Ysize = Ysize; 2321 rmp.ysize = ysize;
2270 rmp.expand2x = expand2x; 2322 rmp.expand2x = expand2x;
2271 rmp.layoutoptions1 = layoutoptions1; 2323 rmp.layoutoptions1 = layoutoptions1;
2272 rmp.layoutoptions2 = layoutoptions2; 2324 rmp.layoutoptions2 = layoutoptions2;
2273 rmp.layoutoptions3 = layoutoptions3; 2325 rmp.layoutoptions3 = layoutoptions3;
2274 rmp.symmetry = symmetry; 2326 rmp.symmetry = symmetry;
2329 OUTPUT: RETVAL 2381 OUTPUT: RETVAL
2330 2382
2331region *find (char *name) 2383region *find (char *name)
2332 PROTOTYPE: $ 2384 PROTOTYPE: $
2333 CODE: 2385 CODE:
2334 RETVAL = get_region_by_name (name); 2386 RETVAL = region::find (name);
2335 OUTPUT: RETVAL 2387 OUTPUT: RETVAL
2336 2388
2337INCLUDE: $PERL genacc region ../include/map.h | 2389INCLUDE: $PERL genacc region ../include/map.h |
2338 2390
2339MODULE = cf PACKAGE = cf::living 2391MODULE = cf PACKAGE = cf::living

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines