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.579 by root, Wed Jan 4 03:22:28 2012 UTC vs.
Revision 1.582 by root, Fri Feb 3 03:01:45 2012 UTC

129our $DB_ENV; 129our $DB_ENV;
130 130
131our @EXTRA_MODULES = qw(pod match mapscript incloader); 131our @EXTRA_MODULES = qw(pod match mapscript incloader);
132 132
133our %CFG; 133our %CFG;
134our %EXT_CFG; # cfgkeyname => [var-ref, defaultvalue]
134 135
135our $UPTIME; $UPTIME ||= time; 136our $UPTIME; $UPTIME ||= time;
136our $RUNTIME = 0; 137our $RUNTIME = 0;
137our $SERVER_TICK = 0; 138our $SERVER_TICK = 0;
138our $NOW; 139our $NOW;
372 $d =~ s/([\x00-\x07\x09\x0b\x0c\x0e-\x1f])/sprintf "\\x%02x", ord($1)/ge; 373 $d =~ s/([\x00-\x07\x09\x0b\x0c\x0e-\x1f])/sprintf "\\x%02x", ord($1)/ge;
373 $d 374 $d
374 } || "[unable to dump $_[0]: '$@']"; 375 } || "[unable to dump $_[0]: '$@']";
375} 376}
376 377
377=item $scalar = load_file $path 378=item $scalar = cf::load_file $path
378 379
379Loads the given file from path and returns its contents. Croaks on error 380Loads the given file from path and returns its contents. Croaks on error
380and can block. 381and can block.
381 382
382=cut 383=cut
384sub load_file($) { 385sub load_file($) {
385 0 <= aio_load $_[0], my $data 386 0 <= aio_load $_[0], my $data
386 or Carp::croak "$_[0]: $!"; 387 or Carp::croak "$_[0]: $!";
387 388
388 $data 389 $data
390}
391
392=item $success = cf::replace_file $path, $data, $sync
393
394Atomically replaces the file at the given $path with new $data, and
395optionally $sync the data to disk before replacing the file.
396
397=cut
398
399sub replace_file($$;$) {
400 my ($path, $data, $sync) = @_;
401
402 my $lock = cf::lock_acquire ("replace_file:$path");
403
404 my $fh = aio_open "$path~", Fcntl::O_WRONLY | Fcntl::O_CREAT | Fcntl::O_TRUNC, 0644
405 or return;
406
407 $data = $data->() if ref $data;
408
409 length $data == aio_write $fh, 0, (length $data), $data, 0
410 or return;
411
412 !$sync
413 or !aio_fsync $fh
414 or return;
415
416 aio_close $fh
417 and return;
418
419 aio_rename "$path~", $path
420 and return;
421
422 if ($sync) {
423 $path =~ s%/[^/]*$%%;
424 aio_pathsync $path;
425 }
426
427 1
389} 428}
390 429
391=item $ref = cf::decode_json $json 430=item $ref = cf::decode_json $json
392 431
393Converts a JSON string into the corresponding perl data structure. 432Converts a JSON string into the corresponding perl data structure.
1493 }; 1532 };
1494 1533
1495 $grp 1534 $grp
1496} 1535}
1497 1536
1537sub _ext_cfg_reg($$$$) {
1538 my ($rvar, $varname, $cfgname, $default) = @_;
1539
1540 $cfgname = lc $varname
1541 unless length $cfgname;
1542
1543 $EXT_CFG{$cfgname} = [$rvar, $default];
1544
1545 $$rvar = exists $CFG{$cfgname} ? $CFG{$cfgname} : $default;
1546}
1547
1498sub load_extensions { 1548sub load_extensions {
1499 info "loading extensions..."; 1549 info "loading extensions...";
1550
1551 %EXT_CFG = ();
1500 1552
1501 cf::sync_job { 1553 cf::sync_job {
1502 my %todo; 1554 my %todo;
1503 1555
1504 for my $path (<$LIBDIR/*.ext>) { 1556 for my $path (<$LIBDIR/*.ext>) {
1547 unless exists $done{$_}; 1599 unless exists $done{$_};
1548 } 1600 }
1549 1601
1550 trace "... pass $pass, loading '$k' into '$v->{pkg}'\n"; 1602 trace "... pass $pass, loading '$k' into '$v->{pkg}'\n";
1551 1603
1604 my $source = $v->{source};
1605
1606 # support "CONF varname :confname = default" pseudo-statements
1607 $source =~ s{
1608 ^ CONF \s+ ([^\s:=]+) \s* (?:: \s* ([^\s:=]+) \s* )? = ([^\n#]+)
1609 }{
1610 "our \$$1; BEGIN { cf::_ext_cfg_reg \\\$$1, q\x00$1\x00, q\x00$2\x00, $3 }";
1611 }gmxe;
1612
1552 my $active = eval $v->{source}; 1613 my $active = eval $source;
1553 1614
1554 if (length $@) { 1615 if (length $@) {
1555 error "$v->{path}: $@\n"; 1616 error "$v->{path}: $@\n";
1556 1617
1557 cf::cleanup "mandatory extension '$k' failed to load, exiting." 1618 cf::cleanup "mandatory extension '$k' failed to load, exiting."
3520 # TODO: different hash - must free and use new index, or cache ixface data queue 3581 # TODO: different hash - must free and use new index, or cache ixface data queue
3521 my $idx = (cf::face::find $name) || cf::face::alloc $name; 3582 my $idx = (cf::face::find $name) || cf::face::alloc $name;
3522 3583
3523 cf::face::set_data $idx, 0, $info->{data}, $info->{hash}; 3584 cf::face::set_data $idx, 0, $info->{data}, $info->{hash};
3524 cf::face::set_type $idx, $type; 3585 cf::face::set_type $idx, $type;
3525 cf::face::set_meta $idx, $type & 1 ? undef : $info->{meta}; # any keys left are stashed into meta unless prepended 3586 cf::face::set_meta $idx, $type & 1 ? undef : $info->{meta}; # preserve meta unless prepended already
3526 } else { 3587 } else {
3527# $RESOURCE{$name} = $info; # unused 3588# $RESOURCE{$name} = $info; # unused
3528 } 3589 }
3529 3590
3530 cf::cede_to_tick; 3591 cf::cede_to_tick;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines