… | |
… | |
18 | use utf8; |
18 | use utf8; |
19 | |
19 | |
20 | use Carp (); |
20 | use Carp (); |
21 | use Storable (); |
21 | use Storable (); |
22 | use Config; |
22 | use Config; |
23 | use Event (); |
|
|
24 | |
23 | |
25 | use CFPlus; |
24 | use CFPlus; |
26 | |
25 | |
27 | our $DB_HOME = "$Crossfire::VARDIR/cfplus-$BerkeleyDB::db_version-$Config{archname}"; |
26 | our $DB_HOME = "$Crossfire::VARDIR/cfplus-$BerkeleyDB::db_version-$Config{archname}"; |
28 | |
27 | |
… | |
… | |
149 | our ($fh_r_watcher, $fh_w_watcher); |
148 | our ($fh_r_watcher, $fh_w_watcher); |
150 | our $sync_timer; |
149 | our $sync_timer; |
151 | our $write_buf; |
150 | our $write_buf; |
152 | our $read_buf; |
151 | our $read_buf; |
153 | |
152 | |
154 | our $SYNC = Event->idle (min => 120, max => 180, parked => 1, cb => sub { |
153 | our $SYNC = EV::timer_ns 0, 60, sub { |
|
|
154 | $_[0]->stop; |
155 | CFPlus::DB::Server::req (sync => sub { }); |
155 | CFPlus::DB::Server::req (sync => sub { }); |
156 | $_[0]->w->stop; |
|
|
157 | }); |
156 | }; |
158 | |
157 | |
159 | sub fh_write { |
158 | sub fh_write { |
160 | my $len = syswrite $FH, $write_buf; |
159 | my $len = syswrite $FH, $write_buf; |
161 | |
160 | |
162 | substr $write_buf, 0, $len, ""; |
161 | substr $write_buf, 0, $len, ""; |
… | |
… | |
206 | my $id = ++$ID; |
205 | my $id = ++$ID; |
207 | $write_buf .= pack "N/a*", Storable::freeze [$id, $type, @args]; |
206 | $write_buf .= pack "N/a*", Storable::freeze [$id, $type, @args]; |
208 | $CB{$id} = $cb; |
207 | $CB{$id} = $cb; |
209 | |
208 | |
210 | $fh_w_watcher->start; |
209 | $fh_w_watcher->start; |
211 | $SYNC->start; |
210 | $SYNC->again unless $SYNC->is_active; |
212 | } |
211 | } |
213 | |
212 | |
214 | sub do_sync { |
213 | sub do_sync { |
215 | $DB_ENV->txn_checkpoint (0, 0, 0); |
214 | $DB_ENV->txn_checkpoint (0, 0, 0); |
216 | () |
215 | () |
… | |
… | |
378 | my ($id, $type, @args) = @$req; |
377 | my ($id, $type, @args) = @$req; |
379 | my $cb = CFPlus::DB::Server->can ("do_$type") |
378 | my $cb = CFPlus::DB::Server->can ("do_$type") |
380 | or die "$type: unknown database request type\n"; |
379 | or die "$type: unknown database request type\n"; |
381 | my $res = pack "N/a*", Storable::freeze [$id, $cb->(@args)]; |
380 | my $res = pack "N/a*", Storable::freeze [$id, $cb->(@args)]; |
382 | (syswrite $fh, $res) == length $res |
381 | (syswrite $fh, $res) == length $res |
383 | or die; |
382 | or die "DB::write: $!"; |
384 | } |
383 | } |
385 | }; |
384 | }; |
386 | |
385 | |
387 | my $error = $@; |
386 | my $error = $@; |
388 | |
387 | |
… | |
… | |
391 | undef $DB_ENV; |
390 | undef $DB_ENV; |
392 | |
391 | |
393 | Storable::store_fd [die => $error], $fh; |
392 | Storable::store_fd [die => $error], $fh; |
394 | }; |
393 | }; |
395 | |
394 | |
|
|
395 | $DB_ENV->txn_checkpoint (0, 0, 0); |
396 | CFPlus::_exit 0; |
396 | CFPlus::_exit 0; |
397 | } |
397 | } |
398 | |
398 | |
399 | close $fh; |
399 | close $fh; |
400 | CFPlus::fh_nonblocking $FH, 1; |
400 | CFPlus::fh_nonblocking $FH, 1; |
401 | |
401 | |
402 | $CB{die} = sub { die shift }; |
402 | $CB{die} = sub { die shift }; |
403 | |
403 | |
404 | $fh_r_watcher = Event->io (fd => $FH, poll => 'r', nice => 1, cb => \&fh_read); |
404 | $fh_r_watcher = EV::io $FH, EV::READ , \&fh_read; |
405 | $fh_w_watcher = Event->io (fd => $FH, poll => 'w', nice => -1, parked => 1, cb => \&fh_write); |
405 | $fh_w_watcher = EV::io $FH, EV::WRITE, \&fh_write; |
406 | $SYNC->start; |
406 | $SYNC->again unless $SYNC->is_active; |
407 | } |
407 | } |
408 | |
408 | |
409 | sub stop { |
409 | sub stop { |
410 | close $FH; |
410 | close $FH; |
411 | } |
411 | } |