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.135 by root, Thu Jan 4 20:29:46 2007 UTC vs.
Revision 1.138 by root, Fri Jan 5 17:07:17 2007 UTC

221 # wake up all waiters, to be on the safe side 221 # wake up all waiters, to be on the safe side
222 $_->ready for @{ delete $LOCK{$key} }; 222 $_->ready for @{ delete $LOCK{$key} };
223 } 223 }
224} 224}
225 225
226=item cf::async { BLOCK }
227
228Like C<Coro::async>, but runs the given BLOCK in an eval and only logs the
229error instead of exiting the server in case of a problem.
230
231=cut
232
233sub async(&) {
234 my ($cb) = @_;
235
236 Coro::async {
237 eval { $cb->() };
238 warn $@ if $@;
239 }
240}
241
242sub freeze_mainloop { 226sub freeze_mainloop {
243 return unless $TICK_WATCHER->is_active; 227 return unless $TICK_WATCHER->is_active;
244 228
245 my $guard = Coro::guard { $TICK_WATCHER->start }; 229 my $guard = Coro::guard { $TICK_WATCHER->start };
246 $TICK_WATCHER->stop; 230 $TICK_WATCHER->stop;
272 my $freeze_guard = freeze_mainloop; 256 my $freeze_guard = freeze_mainloop;
273 257
274 my $busy = 1; 258 my $busy = 1;
275 my @res; 259 my @res;
276 260
277 (Coro::async { 261 (Coro::async_pool {
278 @res = eval { $job->() }; 262 @res = eval { $job->() };
279 warn $@ if $@; 263 warn $@ if $@;
280 undef $busy; 264 undef $busy;
281 })->prio (Coro::PRIO_MAX); 265 })->prio (Coro::PRIO_MAX);
282 266
293 } 277 }
294} 278}
295 279
296=item $coro = cf::coro { BLOCK } 280=item $coro = cf::coro { BLOCK }
297 281
298Creates and returns a new coro. This coro is automcatially being canceled 282Creates (and readies) and returns a new coro. This coro is automcatially
299when the extension calling this is being unloaded. 283being canceled when the extension calling this is being unloaded.
300 284
301=cut 285=cut
302 286
303sub coro(&) { 287sub coro(&) {
304 my $cb = shift; 288 my $cb = shift;
305 289
306 my $coro = &cf::async ($cb); 290 my $coro = &Coro::async_pool ($cb);
307 291
308 $coro->on_destroy (sub { 292 $coro->on_destroy (sub {
309 delete $EXT_CORO{$coro+0}; 293 delete $EXT_CORO{$coro+0};
310 }); 294 });
311 $EXT_CORO{$coro+0} = $coro; 295 $EXT_CORO{$coro+0} = $coro;
1296} 1280}
1297 1281
1298sub save { 1282sub save {
1299 my ($self) = @_; 1283 my ($self) = @_;
1300 1284
1285 my $lock = cf::lock_acquire "map_data:" . $self->path;
1286
1301 $self->{last_save} = $cf::RUNTIME; 1287 $self->{last_save} = $cf::RUNTIME;
1302 1288
1303 return unless $self->dirty; 1289 return unless $self->dirty;
1304 1290
1305 my $save = $self->{path}->save_path; utf8::encode $save; 1291 my $save = $self->{path}->save_path; utf8::encode $save;
1323 my ($self) = @_; 1309 my ($self) = @_;
1324 1310
1325 # save first because save cedes 1311 # save first because save cedes
1326 $self->save; 1312 $self->save;
1327 1313
1314 my $lock = cf::lock_acquire "map_data:" . $self->path;
1315
1328 return if $self->players; 1316 return if $self->players;
1329 return if $self->in_memory != cf::MAP_IN_MEMORY; 1317 return if $self->in_memory != cf::MAP_IN_MEMORY;
1330 return if $self->{deny_save}; 1318 return if $self->{deny_save};
1331 1319
1332 $self->clear; 1320 $self->clear;
1373 $self->save; 1361 $self->save;
1374} 1362}
1375 1363
1376sub reset { 1364sub reset {
1377 my ($self) = @_; 1365 my ($self) = @_;
1366
1367 my $lock = cf::lock_acquire "map_data:" . $self->path;
1378 1368
1379 return if $self->players; 1369 return if $self->players;
1380 return if $self->{path}{user_rel};#d# 1370 return if $self->{path}{user_rel};#d#
1381 1371
1382 warn "resetting map ", $self->path;#d# 1372 warn "resetting map ", $self->path;#d#
1549 1539
1550 # try to abort aborted map switching on player login :) 1540 # try to abort aborted map switching on player login :)
1551 # should happen only on crashes 1541 # should happen only on crashes
1552 if ($pl->ob->{_link_pos}) { 1542 if ($pl->ob->{_link_pos}) {
1553 $pl->ob->enter_link; 1543 $pl->ob->enter_link;
1554 cf::async { 1544 Coro::async_pool {
1555 # we need this sleep as the login has a concurrent enter_exit running 1545 # we need this sleep as the login has a concurrent enter_exit running
1556 # and this sleep increases chances of the player not ending up in scorn 1546 # and this sleep increases chances of the player not ending up in scorn
1557 Coro::Timer::sleep 1; 1547 Coro::Timer::sleep 1;
1558 $pl->ob->leave_link; 1548 $pl->ob->leave_link;
1559 }; 1549 };
1560 } 1550 }
1561 }, 1551 },
1562); 1552);
1563 1553
1564=item $player_object->goto_map ($path, $x, $y) 1554=item $player_object->goto ($path, $x, $y)
1565 1555
1566=cut 1556=cut
1567 1557
1568sub cf::object::player::goto_map { 1558sub cf::object::player::goto {
1569 my ($self, $path, $x, $y) = @_; 1559 my ($self, $path, $x, $y) = @_;
1570 1560
1571 $self->enter_link; 1561 $self->enter_link;
1572 1562
1573 (cf::async { 1563 (Coro::async_pool {
1574 $path = new cf::path $path; 1564 $path = new cf::path $path;
1575 1565
1576 my $map = cf::map::find $path->as_string; 1566 my $map = cf::map::find $path->as_string;
1577 $map = $map->customise_for ($self) if $map; 1567 $map = $map->customise_for ($self) if $map;
1578 1568
1640 1630
1641 return unless $self->type == cf::PLAYER; 1631 return unless $self->type == cf::PLAYER;
1642 1632
1643 $self->enter_link; 1633 $self->enter_link;
1644 1634
1645 (cf::async { 1635 (Coro::async_pool {
1646 $self->deactivate_recursive; # just to be sure 1636 $self->deactivate_recursive; # just to be sure
1647 unless (eval { 1637 unless (eval {
1648 prepare_random_map $exit 1638 prepare_random_map $exit
1649 if $exit->slaying eq "/!"; 1639 if $exit->slaying eq "/!";
1650 1640
1651 my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path; 1641 my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path;
1652 $self->goto_map ($path, $exit->stats->hp, $exit->stats->sp); 1642 $self->goto ($path, $exit->stats->hp, $exit->stats->sp);
1653 1643
1654 1; 1644 1;
1655 }) { 1645 }) {
1656 $self->message ("Something went wrong deep within the crossfire server. " 1646 $self->message ("Something went wrong deep within the crossfire server. "
1657 . "I'll try to bring you back to the map you were before. " 1647 . "I'll try to bring you back to the map you were before. "
1742=cut 1732=cut
1743 1733
1744sub cf::client::coro { 1734sub cf::client::coro {
1745 my ($self, $cb) = @_; 1735 my ($self, $cb) = @_;
1746 1736
1747 my $coro = &cf::async ($cb); 1737 my $coro = &Coro::async_pool ($cb);
1748 1738
1749 $coro->on_destroy (sub { 1739 $coro->on_destroy (sub {
1750 delete $self->{_coro}{$coro+0}; 1740 delete $self->{_coro}{$coro+0};
1751 }); 1741 });
1752 1742

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines