ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
(Generate patch)

Comparing deliantra/server/lib/cf.pm (file contents):
Revision 1.416 by root, Fri Apr 11 13:59:06 2008 UTC vs.
Revision 1.422 by root, Tue Apr 15 20:46:55 2008 UTC

427 } 427 }
428 } 428 }
429}; 429};
430 430
431sub get_slot($;$$) { 431sub get_slot($;$$) {
432 return if tick_inhibit;
433
432 my ($time, $pri, $name) = @_; 434 my ($time, $pri, $name) = @_;
433 435
434 $time = $TICK * .6 if $time > $TICK * .6; 436 $time = $TICK * .6 if $time > $TICK * .6;
435 my $sig = new Coro::Signal; 437 my $sig = new Coro::Signal;
436 438
1473 1475
1474 return if $pl->{deny_save}; 1476 return if $pl->{deny_save};
1475 1477
1476 aio_mkdir playerdir $pl, 0770; 1478 aio_mkdir playerdir $pl, 0770;
1477 $pl->{last_save} = $cf::RUNTIME; 1479 $pl->{last_save} = $cf::RUNTIME;
1480
1481 cf::get_slot 0.01;
1478 1482
1479 $pl->save_pl ($path); 1483 $pl->save_pl ($path);
1480 cf::cede_to_tick; 1484 cf::cede_to_tick;
1481} 1485}
1482 1486
1775our $MAX_RESET = 3600; 1779our $MAX_RESET = 3600;
1776our $DEFAULT_RESET = 3000; 1780our $DEFAULT_RESET = 3000;
1777 1781
1778sub generate_random_map { 1782sub generate_random_map {
1779 my ($self, $rmp) = @_; 1783 my ($self, $rmp) = @_;
1784
1785 my $lock = cf::lock_acquire "generate_random_map"; # the random map generator is NOT reentrant ATM
1786
1780 # mit "rum" bekleckern, nicht 1787 # mit "rum" bekleckern, nicht
1781 $self->_create_random_map ( 1788 $self->_create_random_map (
1782 $rmp->{wallstyle}, $rmp->{wall_name}, $rmp->{floorstyle}, $rmp->{monsterstyle}, 1789 $rmp->{wallstyle}, $rmp->{wall_name}, $rmp->{floorstyle}, $rmp->{monsterstyle},
1783 $rmp->{treasurestyle}, $rmp->{layoutstyle}, $rmp->{doorstyle}, $rmp->{decorstyle}, 1790 $rmp->{treasurestyle}, $rmp->{layoutstyle}, $rmp->{doorstyle}, $rmp->{decorstyle},
1784 $rmp->{origin_map}, $rmp->{final_map}, $rmp->{exitstyle}, $rmp->{this_map}, 1791 $rmp->{origin_map}, $rmp->{final_map}, $rmp->{exitstyle}, $rmp->{this_map},
1906 1913
1907# the temporary/swap location 1914# the temporary/swap location
1908sub save_path { 1915sub save_path {
1909 my ($self) = @_; 1916 my ($self) = @_;
1910 1917
1911 (my $path = $_[0]{path}) =~ s/\//$PATH_SEP/g; 1918 (my $path = $_[0]{path}) =~ s/\//$PATH_SEP/go;
1912 "$TMPDIR/$path.map" 1919 "$TMPDIR/$path.map"
1913} 1920}
1914 1921
1915# the unique path, undef == no special unique path 1922# the unique path, undef == no special unique path
1916sub uniq_path { 1923sub uniq_path {
1917 my ($self) = @_; 1924 my ($self) = @_;
1918 1925
1919 (my $path = $_[0]{path}) =~ s/\//$PATH_SEP/g; 1926 (my $path = $_[0]{path}) =~ s/\//$PATH_SEP/go;
1920 "$UNIQUEDIR/$path" 1927 "$UNIQUEDIR/$path"
1921} 1928}
1922 1929
1923# and all this just because we cannot iterate over 1930# and all this just because we cannot iterate over
1924# all maps in C++... 1931# all maps in C++...
2110 } 2117 }
2111 2118
2112 $self->{last_save} = $cf::RUNTIME; 2119 $self->{last_save} = $cf::RUNTIME;
2113 $self->last_access ($cf::RUNTIME); 2120 $self->last_access ($cf::RUNTIME);
2114 2121
2115 $self->in_memory (cf::MAP_IN_MEMORY); 2122 $self->in_memory (cf::MAP_ACTIVE);
2116 } 2123 }
2117 2124
2118 $self->post_load; 2125 $self->post_load;
2119} 2126}
2120 2127
2178 my ($path, $origin, $load) = @_; 2185 my ($path, $origin, $load) = @_;
2179 2186
2180 $path = normalise $path, $origin && $origin->{path}; 2187 $path = normalise $path, $origin && $origin->{path};
2181 2188
2182 if (my $map = $cf::MAP{$path}) { 2189 if (my $map = $cf::MAP{$path}) {
2183 return $map if !$load || $map->in_memory == cf::MAP_IN_MEMORY; 2190 return $map if !$load || $map->in_memory == cf::MAP_ACTIVE;
2184 } 2191 }
2185 2192
2186 $MAP_PREFETCH{$path} |= $load; 2193 $MAP_PREFETCH{$path} |= $load;
2187 2194
2188 $MAP_PREFETCHER ||= cf::async { 2195 $MAP_PREFETCHER ||= cf::async {
2225 cf::async { 2232 cf::async {
2226 $Coro::current->{desc} = "map player save"; 2233 $Coro::current->{desc} = "map player save";
2227 $_->contr->save for $self->players; 2234 $_->contr->save for $self->players;
2228 }; 2235 };
2229 2236
2237 cf::get_slot 0.02;
2238
2230 if ($uniq) { 2239 if ($uniq) {
2231 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS); 2240 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS);
2232 $self->_save_objects ($uniq, cf::IO_UNIQUES); 2241 $self->_save_objects ($uniq, cf::IO_UNIQUES);
2233 } else { 2242 } else {
2234 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS | cf::IO_UNIQUES); 2243 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS | cf::IO_UNIQUES);
2242 $self->save; 2251 $self->save;
2243 2252
2244 my $lock = cf::lock_acquire "map_data:$self->{path}"; 2253 my $lock = cf::lock_acquire "map_data:$self->{path}";
2245 2254
2246 return if $self->players; 2255 return if $self->players;
2247 return if $self->in_memory != cf::MAP_IN_MEMORY; 2256 return if $self->in_memory != cf::MAP_ACTIVE;
2248 return if $self->{deny_save}; 2257 return if $self->{deny_save};
2249 2258
2250 $self->in_memory (cf::MAP_SWAPPED); 2259 $self->in_memory (cf::MAP_SWAPPED);
2251 2260
2252 $self->deactivate; 2261 $self->deactivate;
2370 2379
2371sub unique_maps() { 2380sub unique_maps() {
2372 [ 2381 [
2373 map { 2382 map {
2374 utf8::decode $_; 2383 utf8::decode $_;
2375 /\.map$/ 2384 s/\.map$//; # TODO future compatibility hack
2385 /\.pst$/ || !/^$PATH_SEP/o # TODO unique maps apparebntly lack the .map suffix :/
2386 ? ()
2376 ? normalise $_ 2387 : normalise $_
2377 : ()
2378 } @{ aio_readdir $UNIQUEDIR or [] } 2388 } @{ aio_readdir $UNIQUEDIR or [] }
2379 ] 2389 ]
2380} 2390}
2381 2391
2382=back 2392=back
2389 2399
2390=over 4 2400=over 4
2391 2401
2392=item $ob->inv_recursive 2402=item $ob->inv_recursive
2393 2403
2394Returns the inventory of the object _and_ their inventories, recursively. 2404Returns the inventory of the object I<and> their inventories, recursively,
2405but I<not> the object itself.
2395 2406
2396=cut 2407=cut
2397 2408
2398sub inv_recursive_; 2409sub inv_recursive_;
2399sub inv_recursive_ { 2410sub inv_recursive_ {
2404 inv_recursive_ inv $_[0] 2415 inv_recursive_ inv $_[0]
2405} 2416}
2406 2417
2407=item $ref = $ob->ref 2418=item $ref = $ob->ref
2408 2419
2409creates and returns a persistent reference to an objetc that can be stored as a string. 2420Creates and returns a persistent reference to an object that can be stored as a string.
2410 2421
2411=item $ob = cf::object::deref ($refstring) 2422=item $ob = cf::object::deref ($refstring)
2412 2423
2413returns the objetc referenced by refstring. may return undef when it cnanot find the object, 2424returns the objetc referenced by refstring. may return undef when it cnanot find the object,
2414even if the object actually exists. May block. 2425even if the object actually exists. May block.
2688 $rmp->{origin_y} = $exit->y; 2699 $rmp->{origin_y} = $exit->y;
2689 } 2700 }
2690 2701
2691 $rmp->{random_seed} ||= $exit->random_seed; 2702 $rmp->{random_seed} ||= $exit->random_seed;
2692 2703
2693 my $data = cf::encode_json $rmp; 2704 my $data = JSON::XS->new->utf8->pretty->canonical->encode ($rmp);
2694 my $md5 = Digest::MD5::md5_hex $data; 2705 my $md5 = Digest::MD5::md5_hex $data;
2695 my $meta = "$RANDOMDIR/$md5.meta"; 2706 my $meta = "$RANDOMDIR/$md5.meta";
2696 2707
2697 if (my $fh = aio_open "$meta~", O_WRONLY | O_CREAT, 0666) { 2708 if (my $fh = aio_open "$meta~", O_WRONLY | O_CREAT, 0666) {
2698 aio_write $fh, 0, (length $data), $data, 0; 2709 aio_write $fh, 0, (length $data), $data, 0;
3404 cf::cleanup "SIG$signal"; 3415 cf::cleanup "SIG$signal";
3405 }; 3416 };
3406 } 3417 }
3407} 3418}
3408 3419
3409sub write_runtime { 3420sub write_runtime_sync {
3410 my $runtime = "$LOCALDIR/runtime"; 3421 my $runtime = "$LOCALDIR/runtime";
3411 3422
3412 # first touch the runtime file to show we are still running: 3423 # first touch the runtime file to show we are still running:
3413 # the fsync below can take a very very long time. 3424 # the fsync below can take a very very long time.
3414 3425
3542 warn "reloading..."; 3553 warn "reloading...";
3543 3554
3544 warn "entering sync_job"; 3555 warn "entering sync_job";
3545 3556
3546 cf::sync_job { 3557 cf::sync_job {
3547 cf::write_runtime; # external watchdog should not bark 3558 cf::write_runtime_sync; # external watchdog should not bark
3548 cf::emergency_save; 3559 cf::emergency_save;
3549 cf::write_runtime; # external watchdog should not bark 3560 cf::write_runtime_sync; # external watchdog should not bark
3550 3561
3551 warn "syncing database to disk"; 3562 warn "syncing database to disk";
3552 BDB::db_env_txn_checkpoint $DB_ENV; 3563 BDB::db_env_txn_checkpoint $DB_ENV;
3553 3564
3554 # if anything goes wrong in here, we should simply crash as we already saved 3565 # if anything goes wrong in here, we should simply crash as we already saved
3709 3720
3710 if ($NOW >= $NEXT_RUNTIME_WRITE) { 3721 if ($NOW >= $NEXT_RUNTIME_WRITE) {
3711 $NEXT_RUNTIME_WRITE = List::Util::max $NEXT_RUNTIME_WRITE + 10, $NOW + 5.; 3722 $NEXT_RUNTIME_WRITE = List::Util::max $NEXT_RUNTIME_WRITE + 10, $NOW + 5.;
3712 Coro::async_pool { 3723 Coro::async_pool {
3713 $Coro::current->{desc} = "runtime saver"; 3724 $Coro::current->{desc} = "runtime saver";
3714 write_runtime 3725 write_runtime_sync
3715 or warn "ERROR: unable to write runtime file: $!"; 3726 or warn "ERROR: unable to write runtime file: $!";
3716 }; 3727 };
3717 } 3728 }
3718 3729
3719 if (my $sig = shift @WAIT_FOR_TICK_BEGIN) { 3730 if (my $sig = shift @WAIT_FOR_TICK_BEGIN) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines