--- deliantra/server/lib/cf.pm 2007/02/12 00:27:20 1.208 +++ deliantra/server/lib/cf.pm 2007/02/15 03:19:02 1.215 @@ -51,7 +51,7 @@ our $TICK = MAX_TIME * 1e-6; our $TICK_WATCHER; our $AIO_POLL_WATCHER; -our $WRITE_RUNTIME_WATCHER; +our $NEXT_RUNTIME_WRITE; # when should the runtime file be written our $NEXT_TICK; our $NOW; our $USE_FSYNC = 1; # use fsync to write maps - default off @@ -275,9 +275,7 @@ my $guard = Coro::guard { $TICK_WATCHER->start; - $WRITE_RUNTIME_WATCHER->start; }; - $WRITE_RUNTIME_WATCHER->stop; $TICK_WATCHER->stop; $guard } @@ -1611,9 +1609,18 @@ warn "resetting map ", $self->path;#d# + $self->in_memory (cf::MAP_SWAPPED); + + # need to save uniques path + unless ($self->{deny_save}) { + my $uniq = $self->uniq_path; utf8::encode $uniq; + + $self->_save_objects ($uniq, cf::IO_UNIQUES) + if $uniq; + } + delete $cf::MAP{$self->path}; - $self->in_memory (cf::MAP_SWAPPED); $self->clear; $_->clear_links_to ($self) for values %cf::MAP; @@ -1813,6 +1820,8 @@ return unless $self->contr->active; $self->activate_recursive; + + local $self->{_prev_pos} = $link_pos; # ugly hack for rent.ext $self->enter_map ($map, $x, $y); } @@ -1835,12 +1844,12 @@ if ($pl->ob->{_link_pos}) { $pl->ob->enter_link; (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 $pl->ob->reply (undef, "There was an internal problem at your last logout, " . "the server will try to bring you to your intended destination in a second.", cf::NDI_RED); + # 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; $pl->ob->leave_link; })->prio (2); @@ -2199,7 +2208,7 @@ our $DB; -sub db_load() { +sub db_init { unless ($DB) { $DB = BDB::db_create $DB_ENV; @@ -2289,7 +2298,7 @@ }; cfg_load; - db_load; + db_init; load_extensions; $TICK_WATCHER->start; @@ -2347,6 +2356,13 @@ warn "leave emergency perl save\n"; } +sub post_cleanup { + my ($make_core) = @_; + + warn Carp::longmess "post_cleanup backtrace" + if $make_core; +} + sub reload() { # can/must only be called in main if ($Coro::current != $Coro::main) { @@ -2356,12 +2372,16 @@ warn "reloading..."; - warn "cancelling server ticker"; - $TICK_WATCHER->cancel; + warn "entering sync_job"; + + cf::sync_job { + cf::write_runtime; # external watchdog should not bark + cf::emergency_save; + cf::write_runtime; # external watchdog should not bark - cf::emergency_save; + warn "syncing database to disk"; + BDB::db_env_txn_checkpoint $DB_ENV; - eval { # if anything goes wrong in here, we should simply crash as we already saved warn "cancelling all WF_AUTOCANCEL watchers"; @@ -2369,9 +2389,6 @@ $_->cancel if $_->data & WF_AUTOCANCEL; } - warn "syncing database to disk"; - BDB::db_env_txn_checkpoint $DB_ENV, 0, 0, 0, sub { }; - warn "flushing outstanding aio requests"; for (;;) { BDB::flush; @@ -2442,7 +2459,6 @@ warn "loading config and database again"; cf::cfg_load; - cf::db_load; warn "loading extensions"; cf::load_extensions; @@ -2455,16 +2471,14 @@ warn "loading reloadable resources"; load_resources; - warn "restarting server ticker"; + warn "leaving sync_job"; - $TICK_WATCHER->start; - }; - - if ($@) { + 1 + } or do { warn $@; warn "error while reloading, exiting."; exit 1; - } + }; warn "reloaded"; }; @@ -2515,12 +2529,18 @@ $RUNTIME += $TICK; $NEXT_TICK += $TICK; + if ($NOW >= $NEXT_RUNTIME_WRITE) { + $NEXT_RUNTIME_WRITE = $NOW + 10; + Coro::async_pool { + write_runtime + or warn "ERROR: unable to write runtime file: $!"; + }; + } + + $WAIT_FOR_TICK->broadcast; $WAIT_FOR_TICK_ONE->send if $WAIT_FOR_TICK_ONE->awaited; - Event::sweep; - Coro::cede_notself; - # my $AFTER = Event::time; # warn $AFTER - $NOW;#d# @@ -2589,26 +2609,14 @@ IO::AIO::max_poll_time $TICK * 0.1; $AIO_POLL_WATCHER = Event->io ( reentrant => 0, + data => WF_AUTOCANCEL, fd => IO::AIO::poll_fileno, poll => 'r', prio => 6, - data => WF_AUTOCANCEL, cb => \&IO::AIO::poll_cb, ); } -$WRITE_RUNTIME_WATCHER = Event->timer ( - reentrant => 0, - data => WF_AUTOCANCEL, - after => 1, - interval => 10, - prio => 6, # keep it lowest so it acts like a watchdog - cb => Coro::unblock_sub { - write_runtime - or warn "ERROR: unable to write runtime file: $!"; - }, -); - END { cf::emergency_save } 1