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.187 by root, Sat Jan 20 21:06:52 2007 UTC vs.
Revision 1.192 by root, Wed Jan 24 01:43:01 2007 UTC

1176} 1176}
1177 1177
1178sub normalise { 1178sub normalise {
1179 my ($path, $base) = @_; 1179 my ($path, $base) = @_;
1180 1180
1181 $path = "$path"; # make sure its a string
1182
1181 # map plan: 1183 # map plan:
1182 # 1184 #
1183 # /! non-realised random map exit (special hack!) 1185 # /! non-realised random map exit (special hack!)
1184 # {... are special paths that are not being touched 1186 # {... are special paths that are not being touched
1185 # ?xxx/... are special absolute paths 1187 # ?xxx/... are special absolute paths
1221 $self->init; # pass $1 etc. 1223 $self->init; # pass $1 etc.
1222 return $self; 1224 return $self;
1223 } 1225 }
1224 } 1226 }
1225 1227
1226 Carp::carp "unable to resolve path '$path'."; 1228 Carp::carp "unable to resolve path '$path' (base '$base').";
1227 () 1229 ()
1228} 1230}
1229 1231
1230sub init { 1232sub init {
1231 my ($self) = @_; 1233 my ($self) = @_;
1297 $self->{load_path} = $path; 1299 $self->{load_path} = $path;
1298 1300
1299 1 1301 1
1300} 1302}
1301 1303
1302sub load_orig { 1304sub load_header_orig {
1303 my ($self) = @_; 1305 my ($self) = @_;
1304 1306
1305 $self->load_header_from ($self->load_path) 1307 $self->load_header_from ($self->load_path)
1306} 1308}
1307 1309
1308sub load_temp { 1310sub load_header_temp {
1309 my ($self) = @_; 1311 my ($self) = @_;
1310 1312
1311 $self->load_header_from ($self->save_path) 1313 $self->load_header_from ($self->save_path)
1314}
1315
1316sub prepare_temp {
1317 my ($self) = @_;
1318
1319 $self->last_access ((delete $self->{last_access})
1320 || $cf::RUNTIME); #d#
1321 # safety
1322 $self->{instantiate_time} = $cf::RUNTIME
1323 if $self->{instantiate_time} > $cf::RUNTIME;
1324}
1325
1326sub prepare_orig {
1327 my ($self) = @_;
1328
1329 $self->{load_original} = 1;
1330 $self->{instantiate_time} = $cf::RUNTIME;
1331 $self->last_access ($cf::RUNTIME);
1332 $self->instantiate;
1312} 1333}
1313 1334
1314sub load_header { 1335sub load_header {
1315 my ($self) = @_; 1336 my ($self) = @_;
1316 1337
1317 if ($self->load_temp) { 1338 if ($self->load_header_temp) {
1318 $self->last_access ((delete $self->{last_access}) 1339 $self->prepare_temp;
1319 || $cf::RUNTIME); #d#
1320 # safety
1321 $self->{instantiate_time} = $cf::RUNTIME
1322 if $self->{instantiate_time} > $cf::RUNTIME;
1323 } else { 1340 } else {
1324 $self->load_orig 1341 $self->load_header_orig
1325 or return; 1342 or return;
1326 1343 $self->prepare_orig;
1327 $self->{load_original} = 1;
1328 $self->{instantiate_time} = $cf::RUNTIME;
1329 $self->last_access ($cf::RUNTIME);
1330 $self->instantiate;
1331 } 1344 }
1332 1345
1333 1 1346 1
1334} 1347}
1335 1348
1354 if ($map->should_reset) { 1367 if ($map->should_reset) {
1355 # doing this can freeze the server in a sync job, obviously 1368 # doing this can freeze the server in a sync job, obviously
1356 #$cf::WAIT_FOR_TICK->wait; 1369 #$cf::WAIT_FOR_TICK->wait;
1357 $map->reset; 1370 $map->reset;
1358 undef $guard; 1371 undef $guard;
1359 $map = find $path 1372 return find $path;
1360 or return;
1361 } 1373 }
1362 1374
1363 $cf::MAP{$path} = $map 1375 $cf::MAP{$path} = $map
1364 } 1376 }
1365} 1377}
1378
1379sub pre_load { }
1380sub post_load { }
1366 1381
1367sub load { 1382sub load {
1368 my ($self) = @_; 1383 my ($self) = @_;
1369 1384
1370 my $path = $self->{path}; 1385 my $path = $self->{path};
1373 return if $self->in_memory != cf::MAP_SWAPPED; 1388 return if $self->in_memory != cf::MAP_SWAPPED;
1374 1389
1375 $self->in_memory (cf::MAP_LOADING); 1390 $self->in_memory (cf::MAP_LOADING);
1376 1391
1377 $self->alloc; 1392 $self->alloc;
1393
1394 $self->pre_load;
1395
1378 $self->_load_objects ($self->{load_path}, 1) 1396 $self->_load_objects ($self->{load_path}, 1)
1379 or return; 1397 or return;
1380 1398
1381 $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1) 1399 $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1)
1382 if delete $self->{load_original}; 1400 if delete $self->{load_original};
1404 unless $self->difficulty; 1422 unless $self->difficulty;
1405 Coro::cede; 1423 Coro::cede;
1406 $self->activate; 1424 $self->activate;
1407 } 1425 }
1408 1426
1427 $self->post_load;
1428
1409 $self->in_memory (cf::MAP_IN_MEMORY); 1429 $self->in_memory (cf::MAP_IN_MEMORY);
1410} 1430}
1411 1431
1412sub customise_for { 1432sub customise_for {
1413 my ($self, $ob) = @_; 1433 my ($self, $ob) = @_;
1477 delete $MAP_PREFETCH{$path}; 1497 delete $MAP_PREFETCH{$path};
1478 } 1498 }
1479 } 1499 }
1480 undef $MAP_PREFETCHER; 1500 undef $MAP_PREFETCHER;
1481 }; 1501 };
1502 $MAP_PREFETCHER->prio (6);
1482 1503
1483 () 1504 ()
1484} 1505}
1485 1506
1486sub save { 1507sub save {
2186 sub db_sync() { 2207 sub db_sync() {
2187 db_save if $dirty; 2208 db_save if $dirty;
2188 undef $dirty; 2209 undef $dirty;
2189 } 2210 }
2190 2211
2191 my $idle = Event->idle (min => 10, max => 20, repeat => 0, data => WF_AUTOCANCEL, cb => sub { 2212 my $idle = Event->idle (
2192 db_sync; 2213 reentrant => 0,
2214 min => 10,
2215 max => 20,
2216 repeat => 0,
2217 data => WF_AUTOCANCEL,
2218 cb => \&db_sync,
2193 }); 2219 );
2194 2220
2195 sub db_dirty() { 2221 sub db_dirty() {
2196 $dirty = 1; 2222 $dirty = 1;
2197 $idle->start; 2223 $idle->start;
2198 } 2224 }
2266 2292
2267# install some emergency cleanup handlers 2293# install some emergency cleanup handlers
2268BEGIN { 2294BEGIN {
2269 for my $signal (qw(INT HUP TERM)) { 2295 for my $signal (qw(INT HUP TERM)) {
2270 Event->signal ( 2296 Event->signal (
2297 reentrant => 0,
2271 data => WF_AUTOCANCEL, 2298 data => WF_AUTOCANCEL,
2272 signal => $signal, 2299 signal => $signal,
2300 prio => 0,
2273 cb => sub { 2301 cb => sub {
2274 cf::cleanup "SIG$signal"; 2302 cf::cleanup "SIG$signal";
2275 }, 2303 },
2276 ); 2304 );
2277 } 2305 }
2278} 2306}
2433 $who->message ("reloading server."); 2461 $who->message ("reloading server.");
2434 2462
2435 # doing reload synchronously and two reloads happen back-to-back, 2463 # doing reload synchronously and two reloads happen back-to-back,
2436 # coro crashes during coro_state_free->destroy here. 2464 # coro crashes during coro_state_free->destroy here.
2437 2465
2438 $RELOAD_WATCHER ||= Event->timer (after => 0, data => WF_AUTOCANCEL, cb => sub { 2466 $RELOAD_WATCHER ||= Event->timer (
2467 reentrant => 0,
2468 after => 0,
2469 data => WF_AUTOCANCEL,
2470 cb => sub {
2439 reload; 2471 reload;
2440 undef $RELOAD_WATCHER; 2472 undef $RELOAD_WATCHER;
2473 },
2441 }); 2474 );
2442 } 2475 }
2443}; 2476};
2444 2477
2445unshift @INC, $LIBDIR; 2478unshift @INC, $LIBDIR;
2446 2479
2466 $NEXT_TICK += $TICK; 2499 $NEXT_TICK += $TICK;
2467 2500
2468 $WAIT_FOR_TICK->broadcast; 2501 $WAIT_FOR_TICK->broadcast;
2469 $WAIT_FOR_TICK_ONE->send if $WAIT_FOR_TICK_ONE->awaited; 2502 $WAIT_FOR_TICK_ONE->send if $WAIT_FOR_TICK_ONE->awaited;
2470 2503
2504 Event::sweep;
2505 Coro::cede_notself;
2506
2507# my $AFTER = Event::time;
2508# warn $AFTER - $NOW;#d#
2509
2471 # if we are delayed by four ticks or more, skip them all 2510 # if we are delayed by four ticks or more, skip them all
2472 $NEXT_TICK = Event::time if Event::time >= $NEXT_TICK + $TICK * 4; 2511 $NEXT_TICK = Event::time if Event::time >= $NEXT_TICK + $TICK * 4;
2473 2512
2474 $TICK_WATCHER->at ($NEXT_TICK); 2513 $TICK_WATCHER->at ($NEXT_TICK);
2475 $TICK_WATCHER->start; 2514 $TICK_WATCHER->start;
2476 }, 2515 },
2477); 2516);
2478 2517
2479IO::AIO::max_poll_time $TICK * 0.2; 2518IO::AIO::max_poll_time $TICK * 0.1;
2480 2519
2520undef $Coro::AIO::WATCHER;
2481$AIO_POLL_WATCHER = Event->io ( 2521$AIO_POLL_WATCHER = Event->io (
2522 reentrant => 0,
2482 fd => IO::AIO::poll_fileno, 2523 fd => IO::AIO::poll_fileno,
2483 poll => 'r', 2524 poll => 'r',
2484 prio => 5, 2525 prio => 6,
2485 data => WF_AUTOCANCEL, 2526 data => WF_AUTOCANCEL,
2486 cb => \&IO::AIO::poll_cb, 2527 cb => \&IO::AIO::poll_cb,
2487); 2528);
2488 2529
2489$WRITE_RUNTIME_WATCHER = Event->timer ( 2530$WRITE_RUNTIME_WATCHER = Event->timer (
2531 reentrant => 0,
2490 data => WF_AUTOCANCEL, 2532 data => WF_AUTOCANCEL,
2491 after => 1, 2533 after => 1,
2492 interval => 10, 2534 interval => 10,
2493 prio => 6, # keep it lowest so it acts like a watchdog 2535 prio => 6, # keep it lowest so it acts like a watchdog
2494 cb => Coro::unblock_sub { 2536 cb => Coro::unblock_sub {
2495 write_runtime 2537 write_runtime
2496 or warn "ERROR: unable to write runtime file: $!"; 2538 or warn "ERROR: unable to write runtime file: $!";
2497 }, 2539 },
2498); 2540);
2499 2541

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines