ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
(Generate patch)

Comparing deliantra/server/lib/cf.pm (file contents):
Revision 1.356 by root, Tue Sep 4 05:43:21 2007 UTC vs.
Revision 1.361 by root, Sun Sep 9 12:52:48 2007 UTC

285Return true if the lock is currently active, i.e. somebody has locked it. 285Return true if the lock is currently active, i.e. somebody has locked it.
286 286
287=cut 287=cut
288 288
289our %LOCK; 289our %LOCK;
290our %LOCKER;#d#
290 291
291sub lock_wait($) { 292sub lock_wait($) {
292 my ($key) = @_; 293 my ($key) = @_;
294
295 if ($LOCKER{$key} == $Coro::current) {#d#
296 Carp::cluck "lock_wait($key) for already-acquired lock";#d#
297 return;#d#
298 }#d#
293 299
294 # wait for lock, if any 300 # wait for lock, if any
295 while ($LOCK{$key}) { 301 while ($LOCK{$key}) {
296 push @{ $LOCK{$key} }, $Coro::current; 302 push @{ $LOCK{$key} }, $Coro::current;
297 Coro::schedule; 303 Coro::schedule;
303 309
304 # wait, to be sure we are not locked 310 # wait, to be sure we are not locked
305 lock_wait $key; 311 lock_wait $key;
306 312
307 $LOCK{$key} = []; 313 $LOCK{$key} = [];
314 $LOCKER{$key} = $Coro::current;#d#
308 315
309 Coro::guard { 316 Coro::guard {
317 delete $LOCKER{$key};#d#
310 # wake up all waiters, to be on the safe side 318 # wake up all waiters, to be on the safe side
311 $_->ready for @{ delete $LOCK{$key} }; 319 $_->ready for @{ delete $LOCK{$key} };
312 } 320 }
313} 321}
314 322
1268use Coro::AIO; 1276use Coro::AIO;
1269 1277
1270=head3 cf::player 1278=head3 cf::player
1271 1279
1272=over 4 1280=over 4
1281
1282=item cf::player::num_playing
1283
1284Returns the official number of playing players, as per the Crossfire metaserver rules.
1285
1286=cut
1287
1288sub num_playing {
1289 scalar grep
1290 $_->ob->map
1291 && !$_->hidden
1292 && !$_->ob->flag (cf::FLAG_WIZ),
1293 cf::player::list
1294}
1273 1295
1274=item cf::player::find $login 1296=item cf::player::find $login
1275 1297
1276Returns the given player object, loading it if necessary (might block). 1298Returns the given player object, loading it if necessary (might block).
1277 1299
1841sub find { 1863sub find {
1842 my ($path, $origin) = @_; 1864 my ($path, $origin) = @_;
1843 1865
1844 $path = normalise $path, $origin && $origin->path; 1866 $path = normalise $path, $origin && $origin->path;
1845 1867
1868 cf::lock_wait "map_data:$path";#d#remove
1846 cf::lock_wait "map_find:$path"; 1869 cf::lock_wait "map_find:$path";
1847 1870
1848 $cf::MAP{$path} || do { 1871 $cf::MAP{$path} || do {
1849 my $guard = cf::lock_acquire "map_find:$path"; 1872 my $guard1 = cf::lock_acquire "map_find:$path";
1873 my $guard2 = cf::lock_acquire "map_data:$path"; # just for the fun of it
1874
1850 my $map = new_from_path cf::map $path 1875 my $map = new_from_path cf::map $path
1851 or return; 1876 or return;
1852 1877
1853 $map->{last_save} = $cf::RUNTIME; 1878 $map->{last_save} = $cf::RUNTIME;
1854 1879
1856 or return; 1881 or return;
1857 1882
1858 if ($map->should_reset) {#d#TODO# disabled, crashy (locking issue?) 1883 if ($map->should_reset) {#d#TODO# disabled, crashy (locking issue?)
1859 # doing this can freeze the server in a sync job, obviously 1884 # doing this can freeze the server in a sync job, obviously
1860 #$cf::WAIT_FOR_TICK->wait; 1885 #$cf::WAIT_FOR_TICK->wait;
1886 undef $guard1;
1887 undef $guard2;
1861 $map->reset; 1888 $map->reset;
1862 undef $guard;
1863 return find $path; 1889 return find $path;
1864 } 1890 }
1865 1891
1866 $cf::MAP{$path} = $map 1892 $cf::MAP{$path} = $map
1867 } 1893 }
1876 local $self->{deny_reset} = 1; # loading can take a long time 1902 local $self->{deny_reset} = 1; # loading can take a long time
1877 1903
1878 my $path = $self->{path}; 1904 my $path = $self->{path};
1879 1905
1880 { 1906 {
1881 my $guard1 = cf::lock_acquire "map_data:$path"; 1907 my $guard = cf::lock_acquire "map_data:$path";
1882 my $guard2 = cf::lock_acquire "map_load:$path";
1883 1908
1909 return unless $self->valid;
1884 return if $self->in_memory != cf::MAP_SWAPPED; 1910 return unless $self->in_memory == cf::MAP_SWAPPED;
1885 1911
1886 $self->in_memory (cf::MAP_LOADING); 1912 $self->in_memory (cf::MAP_LOADING);
1887 1913
1888 $self->alloc; 1914 $self->alloc;
1889 1915
2061 2087
2062 return if $self->players; 2088 return if $self->players;
2063 return if $self->in_memory != cf::MAP_IN_MEMORY; 2089 return if $self->in_memory != cf::MAP_IN_MEMORY;
2064 return if $self->{deny_save}; 2090 return if $self->{deny_save};
2065 2091
2092 $self->in_memory (cf::MAP_SWAPPED);
2093
2094 $self->deactivate;
2095 $_->clear_links_to ($self) for values %cf::MAP;
2066 $self->clear; 2096 $self->clear;
2067 $self->in_memory (cf::MAP_SWAPPED);
2068} 2097}
2069 2098
2070sub reset_at { 2099sub reset_at {
2071 my ($self) = @_; 2100 my ($self) = @_;
2072 2101
2104 if $uniq; 2133 if $uniq;
2105 } 2134 }
2106 2135
2107 delete $cf::MAP{$self->path}; 2136 delete $cf::MAP{$self->path};
2108 2137
2138 $self->deactivate;
2139 $_->clear_links_to ($self) for values %cf::MAP;
2109 $self->clear; 2140 $self->clear;
2110
2111 $_->clear_links_to ($self) for values %cf::MAP;
2112 2141
2113 $self->unlink_save; 2142 $self->unlink_save;
2114 $self->destroy; 2143 $self->destroy;
2115} 2144}
2116 2145

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines