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.104 by root, Sat Dec 30 16:56:16 2006 UTC vs.
Revision 1.105 by root, Sun Dec 31 17:17:23 2006 UTC

13use Coro 3.3; 13use Coro 3.3;
14use Coro::Event; 14use Coro::Event;
15use Coro::Timer; 15use Coro::Timer;
16use Coro::Signal; 16use Coro::Signal;
17use Coro::Semaphore; 17use Coro::Semaphore;
18use Coro::AIO;
18 19
20use Fcntl;
19use IO::AIO 2.3; 21use IO::AIO 2.31 ();
20use YAML::Syck (); 22use YAML::Syck ();
21use Time::HiRes; 23use Time::HiRes;
22 24
23use Event; $Event::Eval = 1; # no idea why this is required, but it is 25use Event; $Event::Eval = 1; # no idea why this is required, but it is
24 26
172sub to_json($) { 174sub to_json($) {
173 $JSON::Syck::ImplicitUnicode = 0; # work around JSON::Syck bugs 175 $JSON::Syck::ImplicitUnicode = 0; # work around JSON::Syck bugs
174 JSON::Syck::Dump $_[0] 176 JSON::Syck::Dump $_[0]
175} 177}
176 178
179# main coro must never ever "block" except in Event
180# sync_job ensures this by running the job in a coroutine
181# and waiting in Event while the server is otherwise frozen
182sub sync_job(&) {
183 my ($job) = @_;
184
185 my $busy = 1;
186 my @res;
187
188 local $FREEZE = 1;
189
190 my $coro = Coro::async {
191 @res = eval { $job->() };
192 warn $@ if $@;
193 undef $busy;
194 };
195
196 if ($Coro::current == $Coro::main) {
197 $coro->prio (Coro::PRIO_MAX);
198 while ($busy) {
199 Coro::cede_notself;
200 Event::one_event unless Coro::nready;
201 }
202 } else {
203 $coro->join;
204 }
205
206 wantarray ? @res : $res[0]
207}
208
177=item $coro = cf::coro { BLOCK } 209=item $coro = cf::coro { BLOCK }
178 210
179Creates and returns a new coro. This coro is automcatially being canceled 211Creates and returns a new coro. This coro is automcatially being canceled
180when the extension calling this is being unloaded. 212when the extension calling this is being unloaded.
181 213
563); 595);
564 596
565sub object_freezer_save { 597sub object_freezer_save {
566 my ($filename, $rdata, $objs) = @_; 598 my ($filename, $rdata, $objs) = @_;
567 599
600 sync_job {
568 if (length $$rdata) { 601 if (length $$rdata) {
569 warn sprintf "saving %s (%d,%d)\n", 602 warn sprintf "saving %s (%d,%d)\n",
570 $filename, length $$rdata, scalar @$objs; 603 $filename, length $$rdata, scalar @$objs;
571 604
572 if (open my $fh, ">:raw", "$filename~") { 605 if (my $fh = aio_open "$filename~", O_WRONLY | O_CREAT, 0600) {
573 chmod SAVE_MODE, $fh;
574 syswrite $fh, $$rdata;
575 close $fh;
576
577 if (@$objs && open my $fh, ">:raw", "$filename.pst~") {
578 chmod SAVE_MODE, $fh; 606 chmod SAVE_MODE, $fh;
579 syswrite $fh, Storable::nfreeze { version => 1, objs => $objs }; 607 aio_write $fh, 0, (length $$rdata), $$rdata, 0;
608 aio_fsync $fh;
580 close $fh; 609 close $fh;
610
611 if (@$objs) {
612 if (my $fh = aio_open "$filename.pst~", O_WRONLY | O_CREAT, 0600) {
613 chmod SAVE_MODE, $fh;
614 my $data = Storable::nfreeze { version => 1, objs => $objs };
615 aio_write $fh, 0, (length $data), $data, 0;
616 aio_fsync $fh;
617 close $fh;
581 rename "$filename.pst~", "$filename.pst"; 618 aio_rename "$filename.pst~", "$filename.pst";
619 }
620 } else {
621 aio_unlink "$filename.pst";
622 }
623
624 aio_rename "$filename~", $filename;
582 } else { 625 } else {
583 unlink "$filename.pst"; 626 warn "FATAL: $filename~: $!\n";
584 } 627 }
585
586 rename "$filename~", $filename;
587 } else { 628 } else {
588 warn "FATAL: $filename~: $!\n";
589 }
590 } else {
591 unlink $filename; 629 aio_unlink $filename;
592 unlink "$filename.pst"; 630 aio_unlink "$filename.pst";
631 }
593 } 632 }
594} 633}
595 634
596sub object_freezer_as_string { 635sub object_freezer_as_string {
597 my ($rdata, $objs) = @_; 636 my ($rdata, $objs) = @_;
602} 641}
603 642
604sub object_thawer_load { 643sub object_thawer_load {
605 my ($filename) = @_; 644 my ($filename) = @_;
606 645
607 local $/; 646 my ($data, $av);
608 647
609 my $av; 648 (aio_load $filename, $data) >= 0
649 or return;
610 650
611 #TODO: use sysread etc. 651 unless (aio_stat "$filename.pst") {
612 if (open my $data, "<:raw:perlio", $filename) { 652 (aio_load "$filename.pst", $av) >= 0
613 $data = <$data>; 653 or return;
614 if (open my $pst, "<:raw:perlio", "$filename.pst") {
615 $av = eval { (Storable::thaw <$pst>)->{objs} }; 654 $av = eval { (Storable::thaw <$av>)->{objs} };
616 } 655 }
656
617 return ($data, $av); 657 return ($data, $av);
618 }
619
620 ()
621} 658}
622 659
623############################################################################# 660#############################################################################
624# command handling &c 661# command handling &c
625 662

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines