--- deliantra/server/lib/cf.pm 2007/01/02 23:12:47 1.126 +++ deliantra/server/lib/cf.pm 2007/01/04 00:53:54 1.131 @@ -10,7 +10,7 @@ use Safe; use Safe::Hole; -use Coro 3.3; +use Coro 3.3 (); use Coro::Event; use Coro::Timer; use Coro::Signal; @@ -73,8 +73,7 @@ # a special map that is always available our $LINK_MAP; - -our $EMERGENCY_POSITION = $cf::CFG{emergency_position} || ["/world/world_105_115", 5, 37]; +our $EMERGENCY_POSITION; ############################################################################# @@ -247,6 +246,22 @@ } } +=item cf::async { BLOCK } + +Like C, but runs the given BLOCK in an eval and only logs the +error instead of exiting the server in case of a problem. + +=cut + +sub async(&) { + my ($cb) = @_; + + Coro::async { + eval { $cb->() }; + warn $@ if $@; + } +} + =item cf::sync_job { BLOCK } The design of crossfire+ requires that the main coro ($Coro::main) is @@ -303,12 +318,7 @@ sub coro(&) { my $cb = shift; - my $coro; $coro = async { - eval { - $cb->(); - }; - warn $@ if $@; - }; + my $coro = &cf::async ($cb); $coro->on_destroy (sub { delete $EXT_CORO{$coro+0}; @@ -1313,11 +1323,13 @@ sub swap_out { my ($self) = @_; + # save first because save cedes + $self->save; + return if $self->players; return if $self->in_memory != cf::MAP_IN_MEMORY; return if $self->{deny_save}; - $self->save; $self->clear; $self->in_memory (cf::MAP_SWAPPED); } @@ -1540,7 +1552,7 @@ # should happen only on crashes if ($pl->ob->{_link_pos}) { $pl->ob->enter_link; - Coro::async { + cf::async { # we need this sleep as the login has a concurrent enter_exit running # and this sleep increases chances of the player not ending up in scorn Coro::Timer::sleep 1; @@ -1559,7 +1571,7 @@ $self->enter_link; - (Coro::async { + (cf::async { $path = new cf::path $path; my $map = cf::map::find_map $path->as_string; @@ -1631,9 +1643,8 @@ $self->enter_link; - (Coro::async { + (cf::async { unless (eval { - prepare_random_map $exit if $exit->slaying eq "/!"; @@ -1705,7 +1716,8 @@ # this weird shuffling is so that direct followup queries # get handled first - my $queue = delete $ns->{query_queue}; + my $queue = delete $ns->{query_queue} + or return; # be conservative, not sure how that can happen, but we saw a crash here (shift @$queue)->[1]->($msg); @@ -1732,12 +1744,7 @@ sub cf::client::coro { my ($self, $cb) = @_; - my $coro; $coro = async { - eval { - $cb->(); - }; - warn $@ if $@; - }; + my $coro = &cf::async ($cb); $coro->on_destroy (sub { delete $self->{_coro}{$coro+0}; @@ -1982,6 +1989,16 @@ local $/; *CFG = YAML::Syck::Load <$fh>; + + $EMERGENCY_POSITION = $CFG{emergency_position} || ["/world/world_105_115", 5, 37]; + + if (exists $CFG{mlockall}) { + eval { + $CFG{mlockall} ? &mlockall : &munlockall + and die "WARNING: m(un)lockall failed: $!\n"; + }; + warn $@ if $@; + } } sub main {