… | |
… | |
367 | |
367 | |
368 | $coro |
368 | $coro |
369 | } |
369 | } |
370 | |
370 | |
371 | sub write_runtime { |
371 | sub write_runtime { |
|
|
372 | my $runtime = "$LOCALDIR/runtime"; |
|
|
373 | |
|
|
374 | # first touch the runtime file to show we are still running: |
|
|
375 | # the fsync below can take a very very long time. |
|
|
376 | |
|
|
377 | warn "touching runtime...\n";#d# |
|
|
378 | if (my $fh = aio_open $runtime, O_WRONLY, 0) { |
|
|
379 | utime undef, undef, $fh; |
|
|
380 | } |
|
|
381 | |
372 | my $guard = cf::lock_acquire "write_runtime"; |
382 | my $guard = cf::lock_acquire "write_runtime"; |
373 | |
383 | |
374 | my $runtime = "$LOCALDIR/runtime"; |
384 | warn "starting to write runtime...\n";#d# |
375 | |
|
|
376 | my $fh = aio_open "$runtime~", O_WRONLY | O_CREAT, 0644 |
385 | my $fh = aio_open "$runtime~", O_WRONLY | O_CREAT, 0644 |
377 | or return; |
386 | or return; |
378 | |
387 | |
379 | my $value = $cf::RUNTIME + 90 + 10; |
388 | my $value = $cf::RUNTIME + 90 + 10; |
380 | # 10 is the runtime save interval, for a monotonic clock |
389 | # 10 is the runtime save interval, for a monotonic clock |
… | |
… | |
385 | |
394 | |
386 | # always fsync - this file is important |
395 | # always fsync - this file is important |
387 | aio_fsync $fh |
396 | aio_fsync $fh |
388 | and return; |
397 | and return; |
389 | |
398 | |
|
|
399 | # touch it again to show we are up-to-date |
|
|
400 | utime undef, undef, $fh; |
|
|
401 | |
390 | close $fh |
402 | close $fh |
391 | or return; |
403 | or return; |
392 | |
404 | |
393 | aio_rename "$runtime~", $runtime |
405 | aio_rename "$runtime~", $runtime |
394 | and return; |
406 | and return; |
|
|
407 | |
|
|
408 | warn "... done writing runtime.\n";#d# |
395 | |
409 | |
396 | 1 |
410 | 1 |
397 | } |
411 | } |
398 | |
412 | |
399 | =item cf::datalog type => key => value, ... |
413 | =item cf::datalog type => key => value, ... |
… | |
… | |
1490 | my ($self) = @_; |
1504 | my ($self) = @_; |
1491 | |
1505 | |
1492 | local $self->{deny_reset} = 1; # loading can take a long time |
1506 | local $self->{deny_reset} = 1; # loading can take a long time |
1493 | |
1507 | |
1494 | my $path = $self->{path}; |
1508 | my $path = $self->{path}; |
|
|
1509 | |
|
|
1510 | { |
1495 | my $guard = cf::lock_acquire "map_load:$path"; |
1511 | my $guard = cf::lock_acquire "map_load:$path"; |
1496 | |
1512 | |
1497 | return if $self->in_memory != cf::MAP_SWAPPED; |
1513 | return if $self->in_memory != cf::MAP_SWAPPED; |
1498 | |
1514 | |
1499 | $self->in_memory (cf::MAP_LOADING); |
1515 | $self->in_memory (cf::MAP_LOADING); |
1500 | |
1516 | |
1501 | $self->alloc; |
1517 | $self->alloc; |
1502 | |
1518 | |
1503 | $self->pre_load; |
1519 | $self->pre_load; |
1504 | Coro::cede; |
|
|
1505 | |
|
|
1506 | $self->_load_objects ($self->{load_path}, 1) |
|
|
1507 | or return; |
|
|
1508 | |
|
|
1509 | $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1) |
|
|
1510 | if delete $self->{load_original}; |
|
|
1511 | |
|
|
1512 | if (my $uniq = $self->uniq_path) { |
|
|
1513 | utf8::encode $uniq; |
|
|
1514 | if (aio_open $uniq, O_RDONLY, 0) { |
|
|
1515 | $self->clear_unique_items; |
|
|
1516 | $self->_load_objects ($uniq, 0); |
|
|
1517 | } |
|
|
1518 | } |
|
|
1519 | |
|
|
1520 | Coro::cede; |
|
|
1521 | # now do the right thing for maps |
|
|
1522 | $self->link_multipart_objects; |
|
|
1523 | Coro::cede; |
|
|
1524 | |
|
|
1525 | unless ($self->{deny_activate}) { |
|
|
1526 | $self->decay_objects; |
|
|
1527 | $self->fix_auto_apply; |
|
|
1528 | $self->update_buttons; |
|
|
1529 | Coro::cede; |
1520 | Coro::cede; |
1530 | $self->set_darkness_map; |
1521 | |
|
|
1522 | $self->_load_objects ($self->{load_path}, 1) |
|
|
1523 | or return; |
|
|
1524 | |
|
|
1525 | $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1) |
|
|
1526 | if delete $self->{load_original}; |
|
|
1527 | |
|
|
1528 | if (my $uniq = $self->uniq_path) { |
|
|
1529 | utf8::encode $uniq; |
|
|
1530 | if (aio_open $uniq, O_RDONLY, 0) { |
|
|
1531 | $self->clear_unique_items; |
|
|
1532 | $self->_load_objects ($uniq, 0); |
|
|
1533 | } |
|
|
1534 | } |
|
|
1535 | |
|
|
1536 | Coro::cede; |
|
|
1537 | # now do the right thing for maps |
|
|
1538 | $self->link_multipart_objects; |
1531 | $self->difficulty ($self->estimate_difficulty) |
1539 | $self->difficulty ($self->estimate_difficulty) |
1532 | unless $self->difficulty; |
1540 | unless $self->difficulty; |
1533 | Coro::cede; |
1541 | Coro::cede; |
|
|
1542 | |
|
|
1543 | unless ($self->{deny_activate}) { |
|
|
1544 | $self->decay_objects; |
|
|
1545 | $self->fix_auto_apply; |
|
|
1546 | $self->update_buttons; |
|
|
1547 | Coro::cede; |
|
|
1548 | $self->set_darkness_map; |
|
|
1549 | Coro::cede; |
1534 | $self->activate; |
1550 | $self->activate; |
1535 | Coro::cede; |
1551 | } |
|
|
1552 | |
|
|
1553 | $self->in_memory (cf::MAP_IN_MEMORY); |
1536 | } |
1554 | } |
1537 | |
1555 | |
1538 | $self->post_load; |
1556 | $self->post_load; |
1539 | Coro::cede; |
|
|
1540 | |
|
|
1541 | $self->in_memory (cf::MAP_IN_MEMORY); |
|
|
1542 | } |
1557 | } |
1543 | |
1558 | |
1544 | sub customise_for { |
1559 | sub customise_for { |
1545 | my ($self, $ob) = @_; |
1560 | my ($self, $ob) = @_; |
1546 | |
1561 | |
… | |
… | |
2434 | |
2449 | |
2435 | die $$res unless "ARRAY" eq ref $res; |
2450 | die $$res unless "ARRAY" eq ref $res; |
2436 | |
2451 | |
2437 | return wantarray ? @$res : $res->[-1]; |
2452 | return wantarray ? @$res : $res->[-1]; |
2438 | } else { |
2453 | } else { |
|
|
2454 | reset_signals; |
2439 | local $SIG{__WARN__}; |
2455 | local $SIG{__WARN__}; |
|
|
2456 | local $SIG{__DIE__}; |
2440 | eval { |
2457 | eval { |
2441 | local $SIG{__DIE__}; |
|
|
2442 | close $fh1; |
2458 | close $fh1; |
2443 | |
2459 | |
2444 | my @res = eval { $cb->(@args) }; |
2460 | my @res = eval { $cb->(@args) }; |
2445 | syswrite $fh2, Coro::Storable::freeze +($@ ? \"$@" : \@res); |
2461 | syswrite $fh2, Coro::Storable::freeze +($@ ? \"$@" : \@res); |
2446 | }; |
2462 | }; |
… | |
… | |
2922 | prio => 6, |
2938 | prio => 6, |
2923 | cb => \&IO::AIO::poll_cb, |
2939 | cb => \&IO::AIO::poll_cb, |
2924 | ); |
2940 | ); |
2925 | } |
2941 | } |
2926 | |
2942 | |
|
|
2943 | my $_log_backtrace; |
|
|
2944 | |
|
|
2945 | sub _log_backtrace { |
|
|
2946 | my ($msg, @addr) = @_; |
|
|
2947 | |
|
|
2948 | $msg =~ s/\n//; |
|
|
2949 | |
|
|
2950 | # limit the # of concurrent backtraces |
|
|
2951 | if ($_log_backtrace < 2) { |
|
|
2952 | ++$_log_backtrace; |
|
|
2953 | async { |
|
|
2954 | my @bt = fork_call { |
|
|
2955 | @addr = map { sprintf "%x", $_ } @addr; |
|
|
2956 | my $self = (-f "/proc/$$/exe") ? "/proc/$$/exe" : $^X; |
|
|
2957 | open my $fh, "exec addr2line -C -f -i -e \Q$self\E @addr 2>&1 |" |
|
|
2958 | or die "addr2line: $!"; |
|
|
2959 | |
|
|
2960 | my @funcs; |
|
|
2961 | my @res = <$fh>; |
|
|
2962 | chomp for @res; |
|
|
2963 | while (@res) { |
|
|
2964 | my ($func, $line) = splice @res, 0, 2, (); |
|
|
2965 | push @funcs, "[$func] $line"; |
|
|
2966 | } |
|
|
2967 | |
|
|
2968 | @funcs |
|
|
2969 | }; |
|
|
2970 | |
|
|
2971 | LOG llevInfo, "[ABT] $msg\n"; |
|
|
2972 | LOG llevInfo, "[ABT] $_\n" for @bt; |
|
|
2973 | --$_log_backtrace; |
|
|
2974 | }; |
|
|
2975 | } else { |
|
|
2976 | LOG llevInfo, "[ABT] $msg\n"; |
|
|
2977 | LOG llevInfo, "[ABT] [suppressed]\n"; |
|
|
2978 | } |
|
|
2979 | } |
|
|
2980 | |
2927 | # load additional modules |
2981 | # load additional modules |
2928 | use cf::pod; |
2982 | use cf::pod; |
2929 | |
2983 | |
2930 | END { cf::emergency_save } |
2984 | END { cf::emergency_save } |
2931 | |
2985 | |