--- deliantra/server/lib/cf.pm 2007/01/01 12:28:47 1.111 +++ deliantra/server/lib/cf.pm 2007/01/01 13:31:47 1.112 @@ -199,28 +199,34 @@ sub sync_job(&) { my ($job) = @_; - my $busy = 1; - my @res; - - my $coro = Coro::async { - @res = eval { $job->() }; - warn $@ if $@; - undef $busy; - }; - if ($Coro::current == $Coro::main) { + # this is the main coro, too bad, we have to block + # till the operation succeeds, freezing the server :/ + # TODO: use suspend/resume instead + # (but this is cancel-safe) local $FREEZE = 1; - $coro->prio (Coro::PRIO_MAX); + + my $busy = 1; + my @res; + + (Coro::async { + @res = eval { $job->() }; + warn $@ if $@; + undef $busy; + })->prio (Coro::PRIO_MAX); + while ($busy) { Coro::cede_notself; Event::one_event unless Coro::nready; } + + wantarray ? @res : $res[0] } else { - $coro->join; + # we are in another coroutine, how wonderful, everything just works + + $job->() } - - wantarray ? @res : $res[0] } =item $coro = cf::coro { BLOCK } @@ -254,7 +260,7 @@ my $fh = aio_open "$runtime~", O_WRONLY | O_CREAT, 0644 or return; - my $value = $cf::RUNTIME; + my $value = $cf::RUNTIME + 1 + 10; # 10 is the runtime save interval, for a monotonic clock (aio_write $fh, 0, (length $value), $value, 0) <= 0 and return; @@ -1048,8 +1054,6 @@ our $MAX_RESET = 7200; our $DEFAULT_RESET = 3600; -$MAX_RESET = 10;#d# -$DEFAULT_RESET = 10;#d# sub generate_random_map { my ($path, $rmp) = @_; @@ -1092,7 +1096,6 @@ or return; $map->{load_path} = $path; - use Data::Dumper; warn Dumper $map;#d# $map } @@ -1102,7 +1105,7 @@ #warn "find_map<$path,$origin>\n";#d# - $path = ref $path ? $path : new cf::path $path, $origin && $origin->path; + $path = new cf::path $path, $origin && $origin->path; my $key = $path->as_string; $cf::MAP{$key} || do { @@ -1134,7 +1137,10 @@ $map->{path} = $path; $map->last_access ($cf::RUNTIME); - $map->reset if $map->should_reset; + if ($map->should_reset) { + $map->reset; + $map = find_map $path; + } $cf::MAP{$key} = $map } @@ -1153,7 +1159,8 @@ $self->load_objects ($self->{load_path}, 1) or return; - $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1) if delete $self->{load_original}; + $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1) + if delete $self->{load_original}; if (my $uniq = $path->uniq_path) { utf8::encode $uniq; @@ -1209,8 +1216,6 @@ return if $self->{deny_save}; - warn "saving map ", $self->path; - if ($uniq) { $self->save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS); $self->save_objects ($uniq, cf::IO_UNIQUES); @@ -1231,19 +1236,24 @@ $self->in_memory (cf::MAP_SWAPPED); } -sub should_reset { - my ($map) = @_; +sub reset_at { + my ($self) = @_; # TODO: safety, remove and allow resettable per-player maps - return if $map->{path}{user_rel};#d# - return if $map->{deny_reset}; - #return unless $map->reset_timeout; + return 1e100 if $self->{path}{user_rel}; + return 1e100 if $self->{deny_reset}; - my $time = $map->fixed_resettime ? $map->{instantiate_time} : $map->last_access; - my $to = $map->reset_timeout || $DEFAULT_RESET; + my $time = $self->fixed_resettime ? $self->{instantiate_time} : $self->last_access; + my $to = $self->reset_timeout || $DEFAULT_RESET; $to = $MAX_RESET if $to > $MAX_RESET; - $time + $to < $cf::RUNTIME + $time + $to +} + +sub should_reset { + my ($self) = @_; + + $self->reset_at <= $cf::RUNTIME } sub unlink_save {