diff --git a/include/misc.h b/include/misc.h index 8fc5d513..e805cf68 100644 --- a/include/misc.h +++ b/include/misc.h @@ -111,6 +111,8 @@ extern int debug; extern int oops(char *, char *, int); +void exit_nomem(void) ATTRIBUTE((noreturn)); + /* return codes from command routines */ #define RET_OK 0 /* command completed sucessfully */ #define RET_FAIL 1 /* command completed unsucessfully [?] */ diff --git a/include/server.h b/include/server.h index 2f4485e2..69b30cf3 100644 --- a/include/server.h +++ b/include/server.h @@ -51,7 +51,7 @@ void market_update(void *); void mobility_check(void *); void player_kill_idle(void *); void update_main(void *); -void update_sched(void *); +void update_init(void); void shutdown_sequence(void *); void update_force(void *); diff --git a/src/lib/common/log.c b/src/lib/common/log.c index 048cf107..8ca2f2b3 100644 --- a/src/lib/common/log.c +++ b/src/lib/common/log.c @@ -106,7 +106,20 @@ logerror(char *format, ...) int oops(char *msg, char *file, int line) { - logerror("Oops: %s in %s:%d", msg ? msg : "bug", file, line); - if (debug) abort(); - return 1; + logerror("Oops: %s in %s:%d", msg ? msg : "bug", file, line); + if (debug) abort(); + return 1; +} + +/* + * Report out-of-memory condition and terminate the program. + * Use this with restraint! Clean error recovery is preferable, but + * not always feasible (e.g. halfway through the update) or worthwhile + * (during server startup). + */ +void +exit_nomem(void) +{ + logerror("Memory exhausted"); + exit(1); } diff --git a/src/server/main.c b/src/server/main.c index 86ddb425..43162e7c 100644 --- a/src/server/main.c +++ b/src/server/main.c @@ -325,8 +325,6 @@ start_server(int flags) "AcceptPlayers", "Accept network connections", 0); empth_create(PP_KILLIDLE, player_kill_idle, (50 * 1024), flags, "KillIdle", "Kills idle player connections", 0); - empth_create(PP_SCHED, update_sched, (50 * 1024), flags, "UpdateSched", - "Schedules updates to occur", 0); empth_create(PP_TIMESTAMP, delete_lostitems, (50 * 1024), flags, "DeleteItems", "Deletes old lost items", 0); if (opt_MOB_ACCESS) { @@ -339,6 +337,8 @@ start_server(int flags) empth_create(PP_TIMESTAMP, market_update, (50 * 1024), flags, "MarketUpdate", "Updates the market", 0); } + + update_init(); } /* diff --git a/src/server/update.c b/src/server/update.c index b6de55c1..f6f46426 100644 --- a/src/server/update.c +++ b/src/server/update.c @@ -51,20 +51,34 @@ empth_sem_t *update_sem; empth_rwlock_t *update_lock; time_t update_time; +static void update_sched(void *); static void update_wait(void *unused); static int run_hook(char *cmd, char *name); -/*ARGSUSED*/ void +update_init(void) +{ + update_sem = empth_sem_create("Update", 0); + update_lock = empth_rwlock_create("Update"); + if (!update_sem || !update_lock) + exit_nomem(); + + if (!empth_create(PP_SCHED, update_wait, 50 * 1024, 0, + "Update", "Updates the world", NULL)) + exit_nomem(); + + if (!empth_create(PP_SCHED, update_sched, 50 * 1024, 0, + "UpdateSched", "Schedules updates to occur", NULL)) + exit_nomem(); +} + +/*ARGSUSED*/ +static void update_sched(void *unused) { int wind; time_t now, delta; - update_sem = empth_sem_create("Update", 0); - update_lock = empth_rwlock_create("Update"); - empth_create(PP_SCHED, update_wait, (50 * 1024), 0, "UpdateWait", - "Waits until players idle", 0); if (s_p_etu <= 0) { logerror("bad value for s_p_etu (%d)", s_p_etu); s_p_etu = 2 * 60;