… | |
… | |
41 | use Coro::EV; |
41 | use Coro::EV; |
42 | use Coro::AnyEvent; |
42 | use Coro::AnyEvent; |
43 | use Coro::Timer; |
43 | use Coro::Timer; |
44 | use Coro::Signal; |
44 | use Coro::Signal; |
45 | use Coro::Semaphore; |
45 | use Coro::Semaphore; |
|
|
46 | use Coro::SemaphoreSet; |
46 | use Coro::AnyEvent; |
47 | use Coro::AnyEvent; |
47 | use Coro::AIO; |
48 | use Coro::AIO; |
48 | use Coro::BDB 1.6; |
49 | use Coro::BDB 1.6; |
49 | use Coro::Storable; |
50 | use Coro::Storable; |
50 | use Coro::Util (); |
51 | use Coro::Util (); |
… | |
… | |
347 | |
348 | |
348 | Return true if the lock is currently active, i.e. somebody has locked it. |
349 | Return true if the lock is currently active, i.e. somebody has locked it. |
349 | |
350 | |
350 | =cut |
351 | =cut |
351 | |
352 | |
352 | our %LOCK; |
353 | our $LOCKS = new Coro::SemaphoreSet; |
353 | our %LOCKER;#d# |
|
|
354 | |
354 | |
355 | sub lock_wait($) { |
355 | sub lock_wait($) { |
356 | my ($key) = @_; |
356 | $LOCKS->wait ($_[0]); |
357 | |
|
|
358 | if ($LOCKER{$key} == $Coro::current) {#d# |
|
|
359 | Carp::cluck "lock_wait($key) for already-acquired lock";#d# |
|
|
360 | return;#d# |
|
|
361 | }#d# |
|
|
362 | |
|
|
363 | # wait for lock, if any |
|
|
364 | while ($LOCK{$key}) { |
|
|
365 | #local $Coro::current->{desc} = "$Coro::current->{desc} <waiting for lock $key>"; |
|
|
366 | push @{ $LOCK{$key} }, $Coro::current; |
|
|
367 | Coro::schedule; |
|
|
368 | } |
|
|
369 | } |
357 | } |
370 | |
358 | |
371 | sub lock_acquire($) { |
359 | sub lock_acquire($) { |
372 | my ($key) = @_; |
360 | $LOCKS->guard ($_[0]) |
373 | |
|
|
374 | # wait, to be sure we are not locked |
|
|
375 | lock_wait $key; |
|
|
376 | |
|
|
377 | $LOCK{$key} = []; |
|
|
378 | $LOCKER{$key} = $Coro::current;#d# |
|
|
379 | |
|
|
380 | Guard::guard { |
|
|
381 | delete $LOCKER{$key};#d# |
|
|
382 | # wake up all waiters, to be on the safe side |
|
|
383 | $_->ready for @{ delete $LOCK{$key} }; |
|
|
384 | } |
|
|
385 | } |
361 | } |
386 | |
362 | |
387 | sub lock_active($) { |
363 | sub lock_active($) { |
388 | my ($key) = @_; |
364 | $LOCKS->count ($_[0]) < 1 |
389 | |
|
|
390 | ! ! $LOCK{$key} |
|
|
391 | } |
365 | } |
392 | |
366 | |
393 | sub freeze_mainloop { |
367 | sub freeze_mainloop { |
394 | tick_inhibit_inc; |
368 | tick_inhibit_inc; |
395 | |
369 | |
… | |
… | |
1988 | sub find { |
1962 | sub find { |
1989 | my ($path, $origin) = @_; |
1963 | my ($path, $origin) = @_; |
1990 | |
1964 | |
1991 | $path = normalise $path, $origin && $origin->path; |
1965 | $path = normalise $path, $origin && $origin->path; |
1992 | |
1966 | |
1993 | cf::lock_wait "map_data:$path";#d#remove |
1967 | my $guard1 = cf::lock_acquire "map_data:$path";#d#remove |
1994 | cf::lock_wait "map_find:$path"; |
1968 | my $guard2 = cf::lock_acquire "map_find:$path"; |
1995 | |
1969 | |
1996 | $cf::MAP{$path} || do { |
1970 | $cf::MAP{$path} || do { |
1997 | my $guard1 = cf::lock_acquire "map_data:$path"; # just for the fun of it |
|
|
1998 | my $guard2 = cf::lock_acquire "map_find:$path"; |
|
|
1999 | |
|
|
2000 | my $map = new_from_path cf::map $path |
1971 | my $map = new_from_path cf::map $path |
2001 | or return; |
1972 | or return; |
2002 | |
1973 | |
2003 | $map->{last_save} = $cf::RUNTIME; |
1974 | $map->{last_save} = $cf::RUNTIME; |
2004 | |
1975 | |