--- deliantra/server/lib/cf.pm 2007/02/12 01:25:55 1.209 +++ deliantra/server/lib/cf.pm 2007/02/13 19:25:44 1.212 @@ -1611,9 +1611,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; @@ -2199,32 +2208,34 @@ our $DB; -unless ($DB) { - $DB = BDB::db_create $DB_ENV; +sub db_init { + unless ($DB) { + $DB = BDB::db_create $DB_ENV; - cf::sync_job { - eval { - $DB->set_flags (BDB::CHKSUM); + cf::sync_job { + eval { + $DB->set_flags (BDB::CHKSUM); - BDB::db_open $DB, undef, "db", undef, BDB::BTREE, - BDB::CREATE | BDB::AUTO_COMMIT, 0666; - cf::cleanup "db_open(db): $!" if $!; + BDB::db_open $DB, undef, "db", undef, BDB::BTREE, + BDB::CREATE | BDB::AUTO_COMMIT, 0666; + cf::cleanup "db_open(db): $!" if $!; + }; + cf::cleanup "db_open(db): $@" if $@; }; - cf::cleanup "db_open(db): $@" if $@; - }; - my $path = cf::localdir . "/database.pst"; - if (stat $path) { - cf::sync_job { - my $pst = Storable::retrieve $path; + my $path = cf::localdir . "/database.pst"; + if (stat $path) { + cf::sync_job { + my $pst = Storable::retrieve $path; - cf::db_put (board => data => $pst->{board}); - cf::db_put (guildrules => data => $pst->{guildrules}); - cf::db_put (rent => balance => $pst->{rent}{balance}); - BDB::db_env_txn_checkpoint $DB_ENV; + cf::db_put (board => data => $pst->{board}); + cf::db_put (guildrules => data => $pst->{guildrules}); + cf::db_put (rent => balance => $pst->{rent}{balance}); + BDB::db_env_txn_checkpoint $DB_ENV; - unlink $path; - }; + unlink $path; + }; + } } } @@ -2287,6 +2298,7 @@ }; cfg_load; + db_init; load_extensions; $TICK_WATCHER->start; @@ -2344,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) { @@ -2353,12 +2372,16 @@ warn "reloading..."; - warn "cancelling server ticker"; - $TICK_WATCHER->cancel; + warn "entering sync_job"; + + sync_job { + write_runtime; + cf::emergency_save; + write_runtime; - 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"; @@ -2366,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; @@ -2451,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"; }; @@ -2514,9 +2532,6 @@ $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# @@ -2596,12 +2611,17 @@ $WRITE_RUNTIME_WATCHER = Event->timer ( reentrant => 0, data => WF_AUTOCANCEL, + parked => 1, 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: $!"; + cb => sub { + $TICK_WATCHER->is_active or cf::cleanup "mainloop frozen but runtime active", 1; + + Coro::async_pool { + write_runtime + or warn "ERROR: unable to write runtime file: $!"; + }; }, );