--- deliantra/Deliantra-Client/DC/DB.pm 2007/07/24 04:54:47 1.12 +++ deliantra/Deliantra-Client/DC/DB.pm 2007/08/13 06:47:07 1.18 @@ -18,9 +18,9 @@ use utf8; use Carp (); -use AnyEvent (); use Storable (); use Config; +use Event (); use CFPlus; @@ -53,6 +53,10 @@ CFPlus::DB::Server::req (unlink => @_); } +sub read_file($$) { + CFPlus::DB::Server::req (read_file => @_); +} + sub write_file($$$) { CFPlus::DB::Server::req (write_file => @_); } @@ -61,6 +65,10 @@ CFPlus::DB::Server::req (prefetch_file => @_); } +sub logprint($$$) { + CFPlus::DB::Server::req (logprint => @_); +} + our $tilemap; sub get_tile_id_sync($) { @@ -127,8 +135,6 @@ } } -our $SYNC_INTERVAL = 60; - our %CB; our $FH; our $ID = "aaa0"; @@ -137,12 +143,17 @@ our $write_buf; our $read_buf; +our $SYNC = Event->idle (min => 120, max => 180, parked => 1, cb => sub { + CFPlus::DB::Server::req (sync => sub { }); + $_[0]->w->stop; +}); + sub fh_write { my $len = syswrite $FH, $write_buf; substr $write_buf, 0, $len, ""; - undef $fh_w_watcher + $fh_w_watcher->stop unless length $write_buf; } @@ -188,12 +199,8 @@ $write_buf .= pack "N/a*", Storable::freeze [$id, $type, @args]; $CB{$id} = $cb; - $fh_w_watcher = AnyEvent->io (fh => $FH, poll => 'w', cb => \&fh_write); -} - -sub sync_tick { - req "sync", sub { }; - $sync_timer = AnyEvent->timer (after => $SYNC_INTERVAL, cb => \&sync_tick); + $fh_w_watcher->start; + $SYNC->start; } sub do_sync { @@ -273,30 +280,63 @@ unlink $_[0]; } +sub do_read_file { + my ($path) = @_; + + utf8::downgrade $path; + open my $fh, "<:raw", $path + or return; + sysread $fh, my $buf, -s $fh; + + $buf +} + sub do_write_file { - my ($file, $data) = @_; + my ($path, $data) = @_; - utf8::downgrade $file; + utf8::downgrade $path; utf8::downgrade $data; - open my $fh, ">:raw", $file + open my $fh, ">:raw", $path or return; - print $fh $data; + syswrite $fh, $data; close $fh; 1 } sub do_prefetch_file { - my ($file, $size) = @_; + my ($path, $size) = @_; - utf8::downgrade $file; - open my $fh, "<:raw", $file + utf8::downgrade $path; + open my $fh, "<:raw", $path or return; sysread $fh, my $buf, $size; 1 } +our %LOG_FH; + +sub do_logprint { + my ($path, $line) = @_; + + $LOG_FH{$path} ||= do { + open my $fh, ">>:utf8", $path + or warn "Couldn't open logfile $path: $!"; + + $fh->autoflush (1); + + $fh + }; + + my ($sec, $min, $hour, $mday, $mon, $year) = localtime time; + + my $ts = sprintf "%04d-%02d-%02d %02d:%02d:%02d", + $year + 1900, $mon + 1, $mday, $hour, $min, $sec; + + print { $LOG_FH{$path} } "$ts $line\n" +} + sub run { ($FH, my $fh) = CFPlus::socketpipe; @@ -306,7 +346,9 @@ my $pid = fork; if (defined $pid && !$pid) { + local $SIG{QUIT}; local $SIG{__DIE__}; + local $SIG{__WARN__}; eval { close $FH; @@ -350,9 +392,9 @@ $CB{die} = sub { die shift }; - $fh_r_watcher = AnyEvent->io (fh => $FH, poll => 'r', cb => \&fh_read); - - sync_tick; + $fh_r_watcher = Event->io (fd => $FH, poll => 'r', nice => 1, cb => \&fh_read); + $fh_w_watcher = Event->io (fd => $FH, poll => 'w', nice => -1, parked => 1, cb => \&fh_write); + $SYNC->start; } sub stop {