--- deliantra/server/lib/cf.pm 2010/04/11 04:52:07 1.512 +++ deliantra/server/lib/cf.pm 2010/04/17 02:22:14 1.522 @@ -110,6 +110,9 @@ our %RESOURCE; +our $OUTPUT_RATE_MIN = 4000; +our $OUTPUT_RATE_MAX = 100000; + our $TICK = MAX_TIME * 1e-6; # this is a CONSTANT(!) our $NEXT_RUNTIME_WRITE; # when should the runtime file be written our $NEXT_TICK; @@ -164,6 +167,10 @@ sub cf::map::normalise; +sub in_main() { + $Coro::current == $Coro::main +} + ############################################################################# %REFLECT = (); @@ -260,7 +267,7 @@ warn Carp::longmess $_[0]; - if ($Coro::current == $Coro::main) {#d# + if (in_main) {#d# warn "DIEHOOK called in main context, Coro bug?\n";#d# return;#d# }#d# @@ -398,7 +405,7 @@ =item cf::periodic $interval, $cb Like EV::periodic, but randomly selects a starting point so that the actions -get spread over timer. +get spread over time. =cut @@ -588,6 +595,17 @@ wantarray ? @res : $res[-1] } +sub objinfo { + ( + "counter value" => cf::object::object_count, + "objects created" => cf::object::create_count, + "objects destroyed" => cf::object::destroy_count, + "freelist size" => cf::object::free_count, + "allocated objects" => cf::object::objects_size, + "active objects" => cf::object::actives_size, + ) +} + =item $coin = coin_from_name $name =cut @@ -1424,6 +1442,9 @@ cf::cleanup "mandatory extension '$k' failed to load, exiting." if exists $v->{meta}{mandatory}; + + warn "$v->{base}: optional extension cannot be loaded, skipping.\n"; + delete $todo{$k}; } else { $done{$k} = delete $todo{$k}; push @EXTS, $v->{pkg}; @@ -2200,11 +2221,10 @@ () } -sub save { +# common code, used by both ->save and ->swapout +sub _save { my ($self) = @_; - my $lock = cf::lock_acquire "map_data:$self->{path}"; - $self->{last_save} = $cf::RUNTIME; return unless $self->dirty; @@ -2233,22 +2253,32 @@ } } -sub swap_out { +sub save { my ($self) = @_; - # save first because save cedes - $self->save; + my $lock = cf::lock_acquire "map_data:$self->{path}"; + + $self->_save; +} + +sub swap_out { + my ($self) = @_; my $lock = cf::lock_acquire "map_data:$self->{path}"; - return if $self->players; return if $self->in_memory != cf::MAP_ACTIVE; return if $self->{deny_save}; + return if $self->players; - $self->in_memory (cf::MAP_SWAPPED); - + # first deactivate the map and "unlink" it from the core $self->deactivate; $_->clear_links_to ($self) for values %cf::MAP; + $self->in_memory (cf::MAP_SWAPPED); + + # then atomically save + $self->_save; + + # then free the map $self->clear; } @@ -2587,7 +2617,7 @@ $self->{_link_pos} ||= [$self->map->{path}, $self->x, $self->y] if $self->map && $self->map->{path} ne "{link}"; - $self->enter_map ($LINK_MAP || link_map, 10, 10); + $self->enter_map ($LINK_MAP || link_map, 3, 3); } sub cf::object::player::leave_link { @@ -3531,11 +3561,6 @@ LOG llevInfo, "Copyright (C) 1994 Mark Wedel."; LOG llevInfo, "Copyright (C) 1992 Frank Tore Johansen."; - cf::init_experience; - cf::init_anim; - cf::init_attackmess; - cf::init_dynamic; - $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority # we must not ever block the main coroutine @@ -3550,6 +3575,11 @@ evthread_start IO::AIO::poll_fileno; cf::sync_job { + cf::init_experience; + cf::init_anim; + cf::init_attackmess; + cf::init_dynamic; + cf::load_settings; cf::load_materials; @@ -3576,6 +3606,9 @@ (pop @POST_INIT)->(0) while @POST_INIT; }; + cf::object::thawer::errors_are_fatal 0; + warn "parse errors in files are no longer fatal from this point on.\n"; + main_loop; } @@ -3761,12 +3794,11 @@ _gv_clear *{"$pkg$name"}; # use PApp::Util; PApp::Util::sv_dump *{"$pkg$name"}; } - warn "cleared package $pkg\n";#d# } sub do_reload_perl() { # can/must only be called in main - if ($Coro::current != $Coro::main) { + if (in_main) { warn "can only reload from main coroutine"; return; }