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.137 by root, Fri Jan 5 10:23:05 2007 UTC vs.
Revision 1.139 by root, Fri Jan 5 19:12:03 2007 UTC

26use Event; $Event::Eval = 1; # no idea why this is required, but it is 26use Event; $Event::Eval = 1; # no idea why this is required, but it is
27 27
28# work around bug in YAML::Syck - bad news for perl6, will it be as broken wrt. unicode? 28# work around bug in YAML::Syck - bad news for perl6, will it be as broken wrt. unicode?
29$YAML::Syck::ImplicitUnicode = 1; 29$YAML::Syck::ImplicitUnicode = 1;
30 30
31$Coro::main->prio (2); # run main coroutine ("the server") with very high priority 31$Coro::main->prio (Coro::PRIO_MAX); # run main coroutine ("the server") with very high priority
32 32
33sub WF_AUTOCANCEL () { 1 } # automatically cancel this watcher on reload 33sub WF_AUTOCANCEL () { 1 } # automatically cancel this watcher on reload
34 34
35our %COMMAND = (); 35our %COMMAND = ();
36our %COMMAND_TIME = (); 36our %COMMAND_TIME = ();
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
283 while ($busy) { 267 while ($busy) {
284 Coro::cede_notself; 268 unless (Coro::cede) {
285 Event::one_event unless Coro::nready; 269 Coro::nready ? Event::one_event 0 : Event::one_event;
270 Coro::cede_notself unless Coro::cede;
271 }
286 } 272 }
287 273
288 wantarray ? @res : $res[0] 274 wantarray ? @res : $res[0]
289 } else { 275 } else {
290 # we are in another coroutine, how wonderful, everything just works 276 # we are in another coroutine, how wonderful, everything just works
293 } 279 }
294} 280}
295 281
296=item $coro = cf::coro { BLOCK } 282=item $coro = cf::coro { BLOCK }
297 283
298Creates and returns a new coro. This coro is automcatially being canceled 284Creates (and readies) and returns a new coro. This coro is automcatially
299when the extension calling this is being unloaded. 285being canceled when the extension calling this is being unloaded.
300 286
301=cut 287=cut
302 288
303sub coro(&) { 289sub coro(&) {
304 my $cb = shift; 290 my $cb = shift;
305 291
306 my $coro = &cf::async ($cb); 292 my $coro = &Coro::async_pool ($cb);
307 293
308 $coro->on_destroy (sub { 294 $coro->on_destroy (sub {
309 delete $EXT_CORO{$coro+0}; 295 delete $EXT_CORO{$coro+0};
310 }); 296 });
311 $EXT_CORO{$coro+0} = $coro; 297 $EXT_CORO{$coro+0} = $coro;
1284} 1270}
1285 1271
1286sub find_sync { 1272sub find_sync {
1287 my ($path, $origin) = @_; 1273 my ($path, $origin) = @_;
1288 1274
1289 cf::sync_job { cf::map::find $path, $origin } 1275 cf::sync_job {
1276 my $map = cf::map::find $path, $origin;
1277 $map
1278 }
1290} 1279}
1291 1280
1292sub do_load_sync { 1281sub do_load_sync {
1293 my ($map) = @_; 1282 my ($map) = @_;
1294 1283
1554 my ($pl) = @_; 1543 my ($pl) = @_;
1555 1544
1556 # try to abort aborted map switching on player login :) 1545 # try to abort aborted map switching on player login :)
1557 # should happen only on crashes 1546 # should happen only on crashes
1558 if ($pl->ob->{_link_pos}) { 1547 if ($pl->ob->{_link_pos}) {
1548
1559 $pl->ob->enter_link; 1549 $pl->ob->enter_link;
1560 cf::async { 1550 (Coro::async_pool {
1561 # we need this sleep as the login has a concurrent enter_exit running 1551 # we need this sleep as the login has a concurrent enter_exit running
1562 # and this sleep increases chances of the player not ending up in scorn 1552 # and this sleep increases chances of the player not ending up in scorn
1563 Coro::Timer::sleep 1; 1553 Coro::Timer::sleep 1;
1564 $pl->ob->leave_link; 1554 $pl->ob->leave_link;
1565 }; 1555 })->prio (2);
1566 } 1556 }
1567 }, 1557 },
1568); 1558);
1569 1559
1570=item $player_object->goto ($path, $x, $y) 1560=item $player_object->goto ($path, $x, $y)
1574sub cf::object::player::goto { 1564sub cf::object::player::goto {
1575 my ($self, $path, $x, $y) = @_; 1565 my ($self, $path, $x, $y) = @_;
1576 1566
1577 $self->enter_link; 1567 $self->enter_link;
1578 1568
1579 (cf::async { 1569 (Coro::async_pool {
1580 $path = new cf::path $path; 1570 $path = new cf::path $path;
1581 1571
1582 my $map = cf::map::find $path->as_string; 1572 my $map = cf::map::find $path->as_string;
1583 $map = $map->customise_for ($self) if $map; 1573 $map = $map->customise_for ($self) if $map;
1584 1574
1646 1636
1647 return unless $self->type == cf::PLAYER; 1637 return unless $self->type == cf::PLAYER;
1648 1638
1649 $self->enter_link; 1639 $self->enter_link;
1650 1640
1651 (cf::async { 1641 (Coro::async_pool {
1652 $self->deactivate_recursive; # just to be sure 1642 $self->deactivate_recursive; # just to be sure
1653 unless (eval { 1643 unless (eval {
1654 prepare_random_map $exit 1644 prepare_random_map $exit
1655 if $exit->slaying eq "/!"; 1645 if $exit->slaying eq "/!";
1656 1646
1748=cut 1738=cut
1749 1739
1750sub cf::client::coro { 1740sub cf::client::coro {
1751 my ($self, $cb) = @_; 1741 my ($self, $cb) = @_;
1752 1742
1753 my $coro = &cf::async ($cb); 1743 my $coro = &Coro::async_pool ($cb);
1754 1744
1755 $coro->on_destroy (sub { 1745 $coro->on_destroy (sub {
1756 delete $self->{_coro}{$coro+0}; 1746 delete $self->{_coro}{$coro+0};
1757 }); 1747 });
1758 1748
1996 local $/; 1986 local $/;
1997 *CFG = YAML::Syck::Load <$fh>; 1987 *CFG = YAML::Syck::Load <$fh>;
1998 1988
1999 $EMERGENCY_POSITION = $CFG{emergency_position} || ["/world/world_105_115", 5, 37]; 1989 $EMERGENCY_POSITION = $CFG{emergency_position} || ["/world/world_105_115", 5, 37];
2000 1990
1991 $cf::map::MAX_RESET = $CFG{map_max_reset} if exists $CFG{map_max_reset};
1992 $cf::map::DEFAULT_RESET = $CFG{map_default_reset} if exists $CFG{map_default_reset};
1993
2001 if (exists $CFG{mlockall}) { 1994 if (exists $CFG{mlockall}) {
2002 eval { 1995 eval {
2003 $CFG{mlockall} ? &mlockall : &munlockall 1996 $CFG{mlockall} ? &mlockall : &munlockall
2004 and die "WARNING: m(un)lockall failed: $!\n"; 1997 and die "WARNING: m(un)lockall failed: $!\n";
2005 }; 1998 };
2009 2002
2010sub main { 2003sub main {
2011 # we must not ever block the main coroutine 2004 # we must not ever block the main coroutine
2012 local $Coro::idle = sub { 2005 local $Coro::idle = sub {
2013 Carp::cluck "FATAL: Coro::idle was called, major BUG, use cf::sync_job!\n";#d# 2006 Carp::cluck "FATAL: Coro::idle was called, major BUG, use cf::sync_job!\n";#d#
2014 (Coro::unblock_sub { 2007 Coro::async_pool { Event::one_event };
2015 Event::one_event;
2016 })->();
2017 }; 2008 };
2018 2009
2019 cfg_load; 2010 cfg_load;
2020 db_load; 2011 db_load;
2021 load_extensions; 2012 load_extensions;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines