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.121 by root, Tue Jan 2 11:11:52 2007 UTC vs.
Revision 1.128 by root, Wed Jan 3 00:28:47 2007 UTC

8use Storable; 8use Storable;
9use Opcode; 9use Opcode;
10use Safe; 10use Safe;
11use Safe::Hole; 11use Safe::Hole;
12 12
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; 18use Coro::AIO;
245 # wake up all waiters, to be on the safe side 245 # wake up all waiters, to be on the safe side
246 $_->ready for @{ delete $LOCK{$key} }; 246 $_->ready for @{ delete $LOCK{$key} };
247 } 247 }
248} 248}
249 249
250=item cf::async { BLOCK }
251
252Like C<Coro::async>, but runs the given BLOCK in an eval and only logs the
253error instead of exiting the server in case of a problem.
254
255=cut
256
257sub async(&) {
258 my ($cb) = @_;
259
260 Coro::async {
261 eval { $cb->() };
262 warn $@ if $@;
263 }
264}
265
250=item cf::sync_job { BLOCK } 266=item cf::sync_job { BLOCK }
251 267
252The design of crossfire+ requires that the main coro ($Coro::main) is 268The design of crossfire+ requires that the main coro ($Coro::main) is
253always able to handle events or runnable, as crossfire+ is only partly 269always able to handle events or runnable, as crossfire+ is only partly
254reentrant. Thus "blocking" it by e.g. waiting for I/O is not acceptable. 270reentrant. Thus "blocking" it by e.g. waiting for I/O is not acceptable.
301=cut 317=cut
302 318
303sub coro(&) { 319sub coro(&) {
304 my $cb = shift; 320 my $cb = shift;
305 321
306 my $coro; $coro = async { 322 my $coro = &cf::async ($cb);
307 eval {
308 $cb->();
309 };
310 warn $@ if $@;
311 };
312 323
313 $coro->on_destroy (sub { 324 $coro->on_destroy (sub {
314 delete $EXT_CORO{$coro+0}; 325 delete $EXT_CORO{$coro+0};
315 }); 326 });
316 $EXT_CORO{$coro+0} = $coro; 327 $EXT_CORO{$coro+0} = $coro;
1153# and all this just because we cannot iterate over 1164# and all this just because we cannot iterate over
1154# all maps in C++... 1165# all maps in C++...
1155sub change_all_map_light { 1166sub change_all_map_light {
1156 my ($change) = @_; 1167 my ($change) = @_;
1157 1168
1158 $_->change_map_light ($change) for values %cf::MAP; 1169 $_->change_map_light ($change)
1170 for grep $_->outdoor, values %cf::MAP;
1159} 1171}
1160 1172
1161sub try_load_header($) { 1173sub try_load_header($) {
1162 my ($path) = @_; 1174 my ($path) = @_;
1163 1175
1174 $map->{load_path} = $path; 1186 $map->{load_path} = $path;
1175 1187
1176 $map 1188 $map
1177} 1189}
1178 1190
1191sub find_map;
1179sub find_map { 1192sub find_map {
1180 my ($path, $origin) = @_; 1193 my ($path, $origin) = @_;
1181 1194
1182 #warn "find_map<$path,$origin>\n";#d# 1195 #warn "find_map<$path,$origin>\n";#d#
1183 1196
1218 $map->{last_save} = $cf::RUNTIME; 1231 $map->{last_save} = $cf::RUNTIME;
1219 $map->last_access ($cf::RUNTIME); 1232 $map->last_access ($cf::RUNTIME);
1220 1233
1221 if ($map->should_reset) { 1234 if ($map->should_reset) {
1222 $map->reset; 1235 $map->reset;
1236 undef $guard;
1223 $map = find_map $path; 1237 $map = find_map $path
1238 or return;
1224 } 1239 }
1225 1240
1226 $cf::MAP{$key} = $map 1241 $cf::MAP{$key} = $map
1227 } 1242 }
1228} 1243}
1534 1549
1535 # try to abort aborted map switching on player login :) 1550 # try to abort aborted map switching on player login :)
1536 # should happen only on crashes 1551 # should happen only on crashes
1537 if ($pl->ob->{_link_pos}) { 1552 if ($pl->ob->{_link_pos}) {
1538 $pl->ob->enter_link; 1553 $pl->ob->enter_link;
1539 Coro::async { 1554 cf::async {
1540 # we need this sleep as the login has a concurrent enter_exit running 1555 # we need this sleep as the login has a concurrent enter_exit running
1541 # and this sleep increases chances of the player not ending up in scorn 1556 # and this sleep increases chances of the player not ending up in scorn
1542 Coro::Timer::sleep 1; 1557 Coro::Timer::sleep 1;
1543 $pl->ob->leave_link; 1558 $pl->ob->leave_link;
1544 }; 1559 };
1553sub cf::object::player::goto_map { 1568sub cf::object::player::goto_map {
1554 my ($self, $path, $x, $y) = @_; 1569 my ($self, $path, $x, $y) = @_;
1555 1570
1556 $self->enter_link; 1571 $self->enter_link;
1557 1572
1558 (Coro::async { 1573 (cf::async {
1559 $path = new cf::path $path; 1574 $path = new cf::path $path;
1560 1575
1561 my $map = cf::map::find_map $path->as_string; 1576 my $map = cf::map::find_map $path->as_string;
1562 $map = $map->customise_for ($self) if $map; 1577 $map = $map->customise_for ($self) if $map;
1563 1578
1625 1640
1626 return unless $self->type == cf::PLAYER; 1641 return unless $self->type == cf::PLAYER;
1627 1642
1628 $self->enter_link; 1643 $self->enter_link;
1629 1644
1630 (Coro::async { 1645 (cf::async {
1631 unless (eval { 1646 unless (eval {
1632
1633 prepare_random_map $exit 1647 prepare_random_map $exit
1634 if $exit->slaying eq "/!"; 1648 if $exit->slaying eq "/!";
1635 1649
1636 my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path; 1650 my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path;
1637 $self->goto_map ($path, $exit->stats->hp, $exit->stats->sp); 1651 $self->goto_map ($path, $exit->stats->hp, $exit->stats->sp);
1699 on_reply => sub { 1713 on_reply => sub {
1700 my ($ns, $msg) = @_; 1714 my ($ns, $msg) = @_;
1701 1715
1702 # this weird shuffling is so that direct followup queries 1716 # this weird shuffling is so that direct followup queries
1703 # get handled first 1717 # get handled first
1704 my $queue = delete $ns->{query_queue}; 1718 my $queue = delete $ns->{query_queue}
1719 or return; # be conservative, not sure how that cna happen, but we saw a crash here
1705 1720
1706 (shift @$queue)->[1]->($msg); 1721 (shift @$queue)->[1]->($msg);
1707 1722
1708 push @{ $ns->{query_queue} }, @$queue; 1723 push @{ $ns->{query_queue} }, @$queue;
1709 1724
1726=cut 1741=cut
1727 1742
1728sub cf::client::coro { 1743sub cf::client::coro {
1729 my ($self, $cb) = @_; 1744 my ($self, $cb) = @_;
1730 1745
1731 my $coro; $coro = async { 1746 my $coro = &cf::async ($cb);
1732 eval {
1733 $cb->();
1734 };
1735 warn $@ if $@;
1736 };
1737 1747
1738 $coro->on_destroy (sub { 1748 $coro->on_destroy (sub {
1739 delete $self->{_coro}{$coro+0}; 1749 delete $self->{_coro}{$coro+0};
1740 }); 1750 });
1741 1751
2188 or warn "ERROR: unable to write runtime file: $!"; 2198 or warn "ERROR: unable to write runtime file: $!";
2189 })->(); 2199 })->();
2190 }, 2200 },
2191); 2201);
2192 2202
2203END { cf::emergency_save }
2204
21931 22051
2194 2206

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines