--- deliantra/server/lib/cf.pm 2010/04/29 08:26:38 1.536 +++ deliantra/server/lib/cf.pm 2010/05/09 22:51:13 1.547 @@ -22,9 +22,7 @@ package cf; -use 5.10.0; -use utf8; -use strict qw(vars subs); +use common::sense; use Symbol; use List::Util; @@ -80,6 +78,8 @@ sub WF_AUTOCANCEL () { 1 } # automatically cancel this watcher on reload +our @ORIG_INC; + our %COMMAND = (); our %COMMAND_TIME = (); @@ -126,7 +126,7 @@ our $BDB_TRICKLE_WATCHER; our $DB_ENV; -our @EXTRA_MODULES = qw(pod match mapscript); +our @EXTRA_MODULES = qw(pod match mapscript incloader); our %CFG; @@ -235,9 +235,14 @@ =item cf::wait_for_tick, cf::wait_for_tick_begin These are functions that inhibit the current coroutine one tick. cf::wait_for_tick_begin only -returns directly I the tick processing (and consequently, can only wake one process +returns directly I the tick processing (and consequently, can only wake one thread per tick), while cf::wait_for_tick wakes up all waiters after tick processing. +=cut + +sub wait_for_tick(); +sub wait_for_tick_begin(); + =item @cf::INVOKE_RESULTS This array contains the results of the last C call. When @@ -589,6 +594,10 @@ =cut +sub post_fork { + reset_signals; +} + sub fork_call(&@) { my ($cb, @args) = @_; @@ -597,7 +606,7 @@ # TODO: investigate and fix (likely this will be rather laborious) my @res = Coro::Util::fork_eval { - reset_signals; + cf::post_fork; &$cb }, @args; @@ -1425,7 +1434,7 @@ if $source =~ /\A#!.*?perl.*?#\s*(.*)$/m; $ext{source} = - "package $pkg; use 5.10.0; use strict 'vars', 'subs'; use utf8;\n" + "package $pkg; use common::sense;\n" . "#line 1 \"$path\"\n{\n" . $source . "\n};\n1"; @@ -1645,7 +1654,10 @@ $pl->invoke (cf::EVENT_PLAYER_LOGOUT, 1) if $pl->active; $pl->deactivate; + my $killer = cf::arch::get "killer_quit"; $pl->killer ($killer); $killer->destroy; + ext::highscore::check ($pl->ob); + $pl->invoke (cf::EVENT_PLAYER_QUIT); $pl->ns->destroy if $pl->ns; @@ -1850,7 +1862,6 @@ my (undef, $regex, $prio) = @_; my $pkg = caller; - no strict; push @{"$pkg\::ISA"}, __PACKAGE__; $EXT_MAP{$pkg} = [$prio, qr<$regex>]; @@ -1872,7 +1883,7 @@ sub normalise { my ($path, $base) = @_; - $path = "$path"; # make sure its a string + $path = "$path"; # make sure it's a string $path =~ s/\.map$//; @@ -1921,7 +1932,7 @@ } } - Carp::cluck "unable to resolve path '$path' (base '$base')."; + Carp::cluck "unable to resolve path '$path' (base '$base')"; () } @@ -2054,6 +2065,8 @@ sub find { my ($path, $origin) = @_; + cf::cede_to_tick; + $path = normalise $path, $origin && $origin->path; my $guard1 = cf::lock_acquire "map_data:$path";#d#remove @@ -3275,7 +3288,6 @@ ["cf::player" => qw(peaceful send_msg)], ["cf::map" => qw(trigger)], ) { - no strict 'refs'; my ($pkg, @funs) = @$_; *{"safe::$pkg\::$_"} = $safe_hole->wrap (\&{"$pkg\::$_"}) for @funs; @@ -3372,8 +3384,7 @@ trace "loading facedata from $path\n"; - my $facedata; - 0 < aio_load $path, $facedata + 0 < aio_load $path, my $facedata or die "$path: $!"; $facedata = Coro::Storable::thaw $facedata; @@ -3527,6 +3538,8 @@ sub reload_resources { trace "reloading resource files...\n"; + reload_exp_table; + reload_materials; reload_facedata; reload_sound; reload_archetypes; @@ -3539,11 +3552,13 @@ sub reload_config { trace "reloading config file...\n"; - open my $fh, "<:utf8", "$CONFDIR/config" - or return; + 0 < aio_load "$CONFDIR/config", my $config + or die "$CONFDIR/config: $!"; - local $/; - *CFG = YAML::XS::Load scalar <$fh>; + utf8::decode $config; + + cf::get_slot 0.1, 10, "reload_config"; # yaml might be slow... + *CFG = YAML::XS::Load $config; $EMERGENCY_POSITION = $CFG{emergency_position} || ["/world/world_104_115", 49, 38]; @@ -3557,8 +3572,6 @@ }; warn $@ if $@; } - - trace "finished reloading resource files\n"; } sub pidfile() { @@ -3593,7 +3606,7 @@ cf::init_globals; # initialise logging LOG llevInfo, "Welcome to Deliantra, v" . VERSION; - LOG llevInfo, "Copyright (C) 2005-2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team."; + LOG llevInfo, "Copyright (C) 2005-2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team."; LOG llevInfo, "Copyright (C) 1994 Mark Wedel."; LOG llevInfo, "Copyright (C) 1992 Frank Tore Johansen."; @@ -3611,13 +3624,13 @@ evthread_start IO::AIO::poll_fileno; cf::sync_job { - cf::init_experience; + cf::incloader::init (); + cf::init_anim; cf::init_attackmess; cf::init_dynamic; cf::load_settings; - cf::load_materials; reload_resources; reload_config; @@ -3645,7 +3658,12 @@ cf::object::thawer::errors_are_fatal 0; info "parse errors in files are no longer fatal from this point on.\n"; - main_loop; + my $free_main; $free_main = EV::idle sub { + undef $free_main; + undef &main; # free gobs of memory :) + }; + + goto &main_loop; } ############################################################################# @@ -3822,8 +3840,6 @@ IO::AIO::flush; - IO::AIO::flush; - error Carp::longmess "post_cleanup backtrace" if $make_core; @@ -3858,7 +3874,7 @@ sub do_reload_perl() { # can/must only be called in main - if (in_main) { + unless (in_main) { error "can only reload from main coroutine"; return; } @@ -3868,12 +3884,13 @@ my $t1 = AE::time; while ($RELOAD) { + cf::get_slot 0.1, -1, "reload_perl"; info "reloading..."; trace "entering sync_job"; cf::sync_job { - cf::emergency_save; + #cf::emergency_save; trace "cancelling all extension coros"; $_->cancel for values %EXT_CORO; @@ -3998,14 +4015,14 @@ } }; -unshift @INC, $LIBDIR; +############################################################################# my $bug_warning = 0; our @WAIT_FOR_TICK; our @WAIT_FOR_TICK_BEGIN; -sub wait_for_tick { +sub wait_for_tick() { return Coro::cede if tick_inhibit || $Coro::current == $Coro::main; my $signal = new Coro::Signal; @@ -4013,7 +4030,7 @@ $signal->wait; } -sub wait_for_tick_begin { +sub wait_for_tick_begin() { return Coro::cede if tick_inhibit || $Coro::current == $Coro::main; my $signal = new Coro::Signal;