… | |
… | |
15 | use Coro::Timer; |
15 | use Coro::Timer; |
16 | use Coro::Signal; |
16 | use Coro::Signal; |
17 | use Coro::Semaphore; |
17 | use Coro::Semaphore; |
18 | use Coro::AIO; |
18 | use Coro::AIO; |
19 | |
19 | |
|
|
20 | use BDB (); |
20 | use Data::Dumper; |
21 | use Data::Dumper; |
21 | use Digest::MD5; |
22 | use Digest::MD5; |
22 | use Fcntl; |
23 | use Fcntl; |
23 | use IO::AIO 2.32 (); |
24 | use IO::AIO 2.32 (); |
24 | use YAML::Syck (); |
25 | use YAML::Syck (); |
… | |
… | |
50 | our $WRITE_RUNTIME_WATCHER; |
51 | our $WRITE_RUNTIME_WATCHER; |
51 | our $NEXT_TICK; |
52 | our $NEXT_TICK; |
52 | our $NOW; |
53 | our $NOW; |
53 | our $USE_FSYNC = 1; # use fsync to write maps - default off |
54 | our $USE_FSYNC = 1; # use fsync to write maps - default off |
54 | |
55 | |
|
|
56 | our $BDB_POLL_WATCHER; |
|
|
57 | our $DB_ENV; |
|
|
58 | |
55 | our %CFG; |
59 | our %CFG; |
56 | |
60 | |
57 | our $UPTIME; $UPTIME ||= time; |
61 | our $UPTIME; $UPTIME ||= time; |
58 | our $RUNTIME; |
62 | our $RUNTIME; |
59 | |
63 | |
60 | our %PLAYER; # all users |
64 | our %PLAYER; # all users |
61 | our %MAP; # all maps |
65 | our %MAP; # all maps |
62 | our $LINK_MAP; # the special {link} map, which is always available |
66 | our $LINK_MAP; # the special {link} map, which is always available |
63 | our $RANDOM_MAPS = cf::localdir . "/random"; |
67 | our $RANDOM_MAPS = cf::localdir . "/random"; |
|
|
68 | our $BDB_ENV_DIR = cf::localdir . "/db"; |
64 | |
69 | |
65 | our $WAIT_FOR_TICK; $WAIT_FOR_TICK ||= new Coro::Signal; |
70 | our $WAIT_FOR_TICK; $WAIT_FOR_TICK ||= new Coro::Signal; |
66 | our $WAIT_FOR_TICK_ONE; $WAIT_FOR_TICK_ONE ||= new Coro::Signal; |
71 | our $WAIT_FOR_TICK_ONE; $WAIT_FOR_TICK_ONE ||= new Coro::Signal; |
67 | |
72 | |
68 | # used to convert map paths into valid unix filenames by replacing / by ∕ |
73 | # used to convert map paths into valid unix filenames by replacing / by ∕ |
… | |
… | |
81 | mkdir cf::localdir; |
86 | mkdir cf::localdir; |
82 | mkdir cf::localdir . "/" . cf::playerdir; |
87 | mkdir cf::localdir . "/" . cf::playerdir; |
83 | mkdir cf::localdir . "/" . cf::tmpdir; |
88 | mkdir cf::localdir . "/" . cf::tmpdir; |
84 | mkdir cf::localdir . "/" . cf::uniquedir; |
89 | mkdir cf::localdir . "/" . cf::uniquedir; |
85 | mkdir $RANDOM_MAPS; |
90 | mkdir $RANDOM_MAPS; |
|
|
91 | mkdir $BDB_ENV_DIR; |
86 | |
92 | |
87 | our $EMERGENCY_POSITION; |
93 | our $EMERGENCY_POSITION; |
88 | |
94 | |
89 | sub cf::map::normalise; |
95 | sub cf::map::normalise; |
90 | |
96 | |
… | |
… | |
2552 | $TICK_WATCHER->at ($NEXT_TICK); |
2558 | $TICK_WATCHER->at ($NEXT_TICK); |
2553 | $TICK_WATCHER->start; |
2559 | $TICK_WATCHER->start; |
2554 | }, |
2560 | }, |
2555 | ); |
2561 | ); |
2556 | |
2562 | |
|
|
2563 | { |
|
|
2564 | BDB::max_poll_time $TICK * 0.1; |
|
|
2565 | $BDB_POLL_WATCHER = Event->io ( |
|
|
2566 | reentrant => 0, |
|
|
2567 | fd => BDB::poll_fileno, |
|
|
2568 | poll => 'r', |
|
|
2569 | prio => 0, |
|
|
2570 | data => WF_AUTOCANCEL, |
|
|
2571 | cb => \&BDB::poll_cb, |
|
|
2572 | ); |
|
|
2573 | BDB::min_parallel 8; |
|
|
2574 | |
|
|
2575 | BDB::set_sync_prepare { |
|
|
2576 | my $status; |
|
|
2577 | my $current = $Coro::current; |
|
|
2578 | ( |
|
|
2579 | sub { |
|
|
2580 | $status = $!; |
|
|
2581 | $current->ready; undef $current; |
|
|
2582 | }, |
|
|
2583 | sub { |
|
|
2584 | Coro::schedule while defined $current; |
|
|
2585 | $! = $status; |
|
|
2586 | }, |
|
|
2587 | ) |
|
|
2588 | }; |
|
|
2589 | |
|
|
2590 | unless ($DB_ENV) { |
|
|
2591 | $DB_ENV = BDB::db_env_create; |
|
|
2592 | |
|
|
2593 | cf::sync_job { |
|
|
2594 | BDB::db_env_open |
|
|
2595 | $DB_ENV, |
|
|
2596 | $BDB_ENV_DIR, |
|
|
2597 | BDB::INIT_LOCK | BDB::INIT_LOG | BDB::INIT_MPOOL | BDB::INIT_TXN |
|
|
2598 | | BDB::RECOVER | BDB::REGISTER | BDB::USE_ENVIRON | BDB::CREATE, |
|
|
2599 | 0666; |
|
|
2600 | |
|
|
2601 | cf::cleanup "$!" if $!; |
|
|
2602 | |
|
|
2603 | $DB_ENV->set_flags (BDB::AUTO_COMMIT | BDB::REGION_INIT | BDB::TXN_NOSYNC, 1); |
|
|
2604 | }; |
|
|
2605 | } |
|
|
2606 | } |
|
|
2607 | |
|
|
2608 | { |
|
|
2609 | IO::AIO::min_parallel 8; |
|
|
2610 | |
|
|
2611 | undef $Coro::AIO::WATCHER; |
2557 | IO::AIO::max_poll_time $TICK * 0.1; |
2612 | IO::AIO::max_poll_time $TICK * 0.1; |
2558 | |
|
|
2559 | undef $Coro::AIO::WATCHER; |
|
|
2560 | $AIO_POLL_WATCHER = Event->io ( |
2613 | $AIO_POLL_WATCHER = Event->io ( |
2561 | reentrant => 0, |
2614 | reentrant => 0, |
2562 | fd => IO::AIO::poll_fileno, |
2615 | fd => IO::AIO::poll_fileno, |
2563 | poll => 'r', |
2616 | poll => 'r', |
2564 | prio => 6, |
2617 | prio => 6, |
2565 | data => WF_AUTOCANCEL, |
2618 | data => WF_AUTOCANCEL, |
2566 | cb => \&IO::AIO::poll_cb, |
2619 | cb => \&IO::AIO::poll_cb, |
2567 | ); |
2620 | ); |
|
|
2621 | } |
2568 | |
2622 | |
2569 | $WRITE_RUNTIME_WATCHER = Event->timer ( |
2623 | $WRITE_RUNTIME_WATCHER = Event->timer ( |
2570 | reentrant => 0, |
2624 | reentrant => 0, |
2571 | data => WF_AUTOCANCEL, |
2625 | data => WF_AUTOCANCEL, |
2572 | after => 1, |
2626 | after => 1, |