--- deliantra/server/lib/cf.pm 2007/09/04 08:42:58 1.357 +++ deliantra/server/lib/cf.pm 2007/09/07 18:10:52 1.358 @@ -287,10 +287,16 @@ =cut our %LOCK; +our %LOCKER;#d# sub lock_wait($) { my ($key) = @_; + if ($LOCKER{$key} == $Coro::current) {#d# + Carp::cluck "lock_wait($key) for already-acquired lock";#d# + return;#d# + }#d# + # wait for lock, if any while ($LOCK{$key}) { push @{ $LOCK{$key} }, $Coro::current; @@ -305,8 +311,10 @@ lock_wait $key; $LOCK{$key} = []; + $LOCKER{$key} = $Coro::current;#d# Coro::guard { + delete $LOCKER{$key};#d# # wake up all waiters, to be on the safe side $_->ready for @{ delete $LOCK{$key} }; } @@ -1843,10 +1851,13 @@ $path = normalise $path, $origin && $origin->path; + cf::lock_wait "map_data:$path";#d#remove cf::lock_wait "map_find:$path"; $cf::MAP{$path} || do { - my $guard = cf::lock_acquire "map_find:$path"; + my $guard1 = cf::lock_acquire "map_find:$path"; + my $guard2 = cf::lock_acquire "map_data:$path"; # just for the fun of it + my $map = new_from_path cf::map $path or return; @@ -1858,8 +1869,9 @@ if ($map->should_reset) {#d#TODO# disabled, crashy (locking issue?) # doing this can freeze the server in a sync job, obviously #$cf::WAIT_FOR_TICK->wait; + undef $guard1; + undef $guard2; $map->reset; - undef $guard; return find $path; } @@ -2063,6 +2075,7 @@ return if $self->in_memory != cf::MAP_IN_MEMORY; return if $self->{deny_save}; + $self->deactivate; $self->clear; $self->in_memory (cf::MAP_SWAPPED); } @@ -2106,6 +2119,7 @@ delete $cf::MAP{$self->path}; + $self->deactivate; $self->clear; $_->clear_links_to ($self) for values %cf::MAP;