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.396 by root, Wed Nov 14 08:09:46 2007 UTC vs.
Revision 1.401 by root, Mon Dec 17 06:45:53 2007 UTC

10use Opcode; 10use Opcode;
11use Safe; 11use Safe;
12use Safe::Hole; 12use Safe::Hole;
13use Storable (); 13use Storable ();
14 14
15use Coro 4.1 (); 15use Coro 4.32 ();
16use Coro::State; 16use Coro::State;
17use Coro::Handle; 17use Coro::Handle;
18use Coro::EV; 18use Coro::EV;
19use Coro::Timer; 19use Coro::Timer;
20use Coro::Signal; 20use Coro::Signal;
21use Coro::Semaphore; 21use Coro::Semaphore;
22use Coro::AIO; 22use Coro::AIO;
23use Coro::BDB;
23use Coro::Storable; 24use Coro::Storable;
24use Coro::Util (); 25use Coro::Util ();
25 26
26use JSON::XS (); 27use JSON::XS 2.01 ();
27use BDB (); 28use BDB ();
28use Data::Dumper; 29use Data::Dumper;
29use Digest::MD5; 30use Digest::MD5;
30use Fcntl; 31use Fcntl;
31use YAML::Syck (); 32use YAML::Syck ();
74our $TICK = MAX_TIME * 1e-6; # this is a CONSTANT(!) 75our $TICK = MAX_TIME * 1e-6; # this is a CONSTANT(!)
75our $TICK_WATCHER; 76our $TICK_WATCHER;
76our $AIO_POLL_WATCHER; 77our $AIO_POLL_WATCHER;
77our $NEXT_RUNTIME_WRITE; # when should the runtime file be written 78our $NEXT_RUNTIME_WRITE; # when should the runtime file be written
78our $NEXT_TICK; 79our $NEXT_TICK;
79our $NOW;
80our $USE_FSYNC = 1; # use fsync to write maps - default off 80our $USE_FSYNC = 1; # use fsync to write maps - default off
81 81
82our $BDB_POLL_WATCHER; 82our $BDB_POLL_WATCHER;
83our $BDB_DEADLOCK_WATCHER; 83our $BDB_DEADLOCK_WATCHER;
84our $BDB_CHECKPOINT_WATCHER; 84our $BDB_CHECKPOINT_WATCHER;
87 87
88our %CFG; 88our %CFG;
89 89
90our $UPTIME; $UPTIME ||= time; 90our $UPTIME; $UPTIME ||= time;
91our $RUNTIME; 91our $RUNTIME;
92our $NOW;
92 93
93our (%PLAYER, %PLAYER_LOADING); # all users 94our (%PLAYER, %PLAYER_LOADING); # all users
94our (%MAP, %MAP_LOADING ); # all maps 95our (%MAP, %MAP_LOADING ); # all maps
95our $LINK_MAP; # the special {link} map, which is always available 96our $LINK_MAP; # the special {link} map, which is always available
96 97
246 $d =~ s/([\x00-\x07\x09\x0b\x0c\x0e-\x1f])/sprintf "\\x%02x", ord($1)/ge; 247 $d =~ s/([\x00-\x07\x09\x0b\x0c\x0e-\x1f])/sprintf "\\x%02x", ord($1)/ge;
247 $d 248 $d
248 } || "[unable to dump $_[0]: '$@']"; 249 } || "[unable to dump $_[0]: '$@']";
249} 250}
250 251
251=item $ref = cf::from_json $json 252=item $ref = cf::decode_json $json
252 253
253Converts a JSON string into the corresponding perl data structure. 254Converts a JSON string into the corresponding perl data structure.
254 255
255=item $json = cf::to_json $ref 256=item $json = cf::encode_json $ref
256 257
257Converts a perl data structure into its JSON representation. 258Converts a perl data structure into its JSON representation.
258 259
259=cut 260=cut
260 261
261our $json_coder = JSON::XS->new->utf8->max_size (1e6); # accept ~1mb max 262our $json_coder = JSON::XS->new->utf8->max_size (1e6); # accept ~1mb max
262 263
263sub to_json ($) { $json_coder->encode ($_[0]) } 264sub encode_json($) { $json_coder->encode ($_[0]) }
264sub from_json ($) { $json_coder->decode ($_[0]) } 265sub decode_json($) { $json_coder->decode ($_[0]) }
265 266
266=item cf::lock_wait $string 267=item cf::lock_wait $string
267 268
268Wait until the given lock is available. See cf::lock_acquire. 269Wait until the given lock is available. See cf::lock_acquire.
269 270
1055cf::attachable->attach ( 1056cf::attachable->attach (
1056 prio => -1000000, 1057 prio => -1000000,
1057 on_instantiate => sub { 1058 on_instantiate => sub {
1058 my ($obj, $data) = @_; 1059 my ($obj, $data) = @_;
1059 1060
1060 $data = from_json $data; 1061 $data = decode_json $data;
1061 1062
1062 for (@$data) { 1063 for (@$data) {
1063 my ($name, $args) = @$_; 1064 my ($name, $args) = @$_;
1064 1065
1065 $obj->attach ($name, %{$args || {} }); 1066 $obj->attach ($name, %{$args || {} });
2638 $rmp->{origin_y} = $exit->y; 2639 $rmp->{origin_y} = $exit->y;
2639 } 2640 }
2640 2641
2641 $rmp->{random_seed} ||= $exit->random_seed; 2642 $rmp->{random_seed} ||= $exit->random_seed;
2642 2643
2643 my $data = cf::to_json $rmp; 2644 my $data = cf::encode_json $rmp;
2644 my $md5 = Digest::MD5::md5_hex $data; 2645 my $md5 = Digest::MD5::md5_hex $data;
2645 my $meta = "$RANDOMDIR/$md5.meta"; 2646 my $meta = "$RANDOMDIR/$md5.meta";
2646 2647
2647 if (my $fh = aio_open "$meta~", O_WRONLY | O_CREAT, 0666) { 2648 if (my $fh = aio_open "$meta~", O_WRONLY | O_CREAT, 0666) {
2648 aio_write $fh, 0, (length $data), $data, 0; 2649 aio_write $fh, 0, (length $data), $data, 0;
3328 reload_config; 3329 reload_config;
3329 db_init; 3330 db_init;
3330 load_extensions; 3331 load_extensions;
3331 3332
3332 $TICK_WATCHER->start; 3333 $TICK_WATCHER->start;
3334 $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority
3333 EV::loop; 3335 EV::loop;
3334} 3336}
3335 3337
3336############################################################################# 3338#############################################################################
3337# initialisation and cleanup 3339# initialisation and cleanup
3628 _post_tick; 3630 _post_tick;
3629}; 3631};
3630$TICK_WATCHER->priority (EV::MAXPRI); 3632$TICK_WATCHER->priority (EV::MAXPRI);
3631 3633
3632{ 3634{
3635 # configure BDB
3636
3633 BDB::min_parallel 8; 3637 BDB::min_parallel 8;
3634 BDB::max_poll_time $TICK * 0.1; 3638 BDB::max_poll_reqs $TICK * 0.1;
3635 $BDB_POLL_WATCHER = EV::io BDB::poll_fileno, EV::READ, \&BDB::poll_cb;
3636
3637 BDB::set_sync_prepare {
3638 my $status;
3639 my $current = $Coro::current;
3640 (
3641 sub {
3642 $status = $!;
3643 $current->ready; undef $current;
3644 },
3645 sub {
3646 Coro::schedule while defined $current;
3647 $! = $status;
3648 },
3649 )
3650 };
3651 3639
3652 unless ($DB_ENV) { 3640 unless ($DB_ENV) {
3653 $DB_ENV = BDB::db_env_create; 3641 $DB_ENV = BDB::db_env_create;
3654 $DB_ENV->set_flags (BDB::AUTO_COMMIT | BDB::REGION_INIT | BDB::TXN_NOSYNC 3642 $DB_ENV->set_flags (BDB::AUTO_COMMIT | BDB::REGION_INIT | BDB::TXN_NOSYNC
3655 | BDB::LOG_AUTOREMOVE, 1); 3643 | BDB::LOG_AUTOREMOVE, 1);
3682 BDB::db_env_memp_trickle $DB_ENV, 20, 0, sub { }; 3670 BDB::db_env_memp_trickle $DB_ENV, 20, 0, sub { };
3683 }; 3671 };
3684} 3672}
3685 3673
3686{ 3674{
3675 # configure IO::AIO
3676
3687 IO::AIO::min_parallel 8; 3677 IO::AIO::min_parallel 8;
3688
3689 undef $Coro::AIO::WATCHER;
3690 IO::AIO::max_poll_time $TICK * 0.1; 3678 IO::AIO::max_poll_time $TICK * 0.1;
3691 $AIO_POLL_WATCHER = EV::io IO::AIO::poll_fileno, EV::READ, \&IO::AIO::poll_cb;
3692} 3679}
3693 3680
3694my $_log_backtrace; 3681my $_log_backtrace;
3695 3682
3696sub _log_backtrace { 3683sub _log_backtrace {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines