Rewrite how updates are triggered (closes #1504036):

(update_init, update_sched, update_run, update_wait): Don't create a
separate UpdateSched thread, run update_sched() in the Update thread.
Run the update by calling update_run() instead of by signalling its
thread.  update_run() replaces update_wait(); it just runs the update
and returns instead of waiting for the signal to update in a loop.
Move initialization of the Update thread's *player to its new thread
entry point.
(update_sem, update_init): Remove update_sem.
(update_thread): New.
(update_init): Initialize it.
(update_forced): New.
(update_trigger, update_force): Wake up update_thread with
update_force set.
(update_sched): Reset it before sleep, test it after sleep so that
schedule checking is only done for scheduled updates, not forced
updates.

(update_sched, update_init): Move sanity test of s_p_etu to
update_init().
This commit is contained in:
Markus Armbruster 2007-02-08 11:54:31 +00:00
parent cea39829af
commit c1eb1bd5d2

View file

@ -48,14 +48,15 @@
#include "prototypes.h" #include "prototypes.h"
#include "server.h" #include "server.h"
empth_sem_t *update_sem; static empth_t *update_thread;
empth_rwlock_t *update_lock; empth_rwlock_t *update_lock;
int update_pending; int update_pending;
time_t update_time; time_t update_time;
static int update_forced;
static void update_sched(void *); static void update_sched(void *);
static void update_force(void *); static void update_force(void *);
static void update_wait(void *unused); static void update_run(void);
static int run_hook(char *cmd, char *name); static int run_hook(char *cmd, char *name);
void void
@ -64,9 +65,14 @@ update_init(void)
struct player *dp; struct player *dp;
int stacksize; int stacksize;
update_sem = empth_sem_create("Update", 0); if (s_p_etu <= 0) {
logerror("bad value for s_p_etu (%d)", s_p_etu);
s_p_etu = 2 * 60;
logerror("setting s_p_etu to %d", s_p_etu);
}
update_lock = empth_rwlock_create("Update"); update_lock = empth_rwlock_create("Update");
if (!update_sem || !update_lock) if (!update_lock)
exit_nomem(); exit_nomem();
dp = player_new(-1); dp = player_new(-1);
@ -76,12 +82,9 @@ update_init(void)
stacksize = 100000 + stacksize = 100000 +
/* finish_sects */ WORLD_X * WORLD_Y * (2 * sizeof(double) + /* finish_sects */ WORLD_X * WORLD_Y * (2 * sizeof(double) +
sizeof(char *)); sizeof(char *));
if (!empth_create(PP_UPDATE, update_wait, stacksize, 0, update_thread = empth_create(PP_UPDATE, update_sched, stacksize, 0,
"Update", dp)) "Update", dp);
exit_nomem(); if (!update_thread)
if (!empth_create(PP_SCHED, update_sched, 50 * 1024, 0,
"UpdateSched", NULL))
exit_nomem(); exit_nomem();
} }
@ -92,12 +95,11 @@ update_sched(void *unused)
int wind; int wind;
time_t now, delta; time_t now, delta;
if (s_p_etu <= 0) { player->proc = empth_self();
logerror("bad value for s_p_etu (%d)", s_p_etu); player->cnum = 0;
s_p_etu = 2 * 60; player->god = 1;
logerror("setting s_p_etu to %d", s_p_etu);
} for (;;) {
while (1) {
time(&now); time(&now);
next_update_time(&now, &update_time, &delta); next_update_time(&now, &update_time, &delta);
if (update_window > 0) { if (update_window > 0) {
@ -108,7 +110,9 @@ update_sched(void *unused)
logerror("Next update at %s", ctime(&update_time)); logerror("Next update at %s", ctime(&update_time));
logerror("Next update in %ld seconds", (long)delta); logerror("Next update in %ld seconds", (long)delta);
/* sleep until update is scheduled to go off */ /* sleep until update is scheduled to go off */
update_forced = 0;
empth_sleep(update_time); empth_sleep(update_time);
if (!update_forced) {
time(&now); time(&now);
now += adj_update; now += adj_update;
if (!gamehours(now)) { if (!gamehours(now)) {
@ -123,7 +127,8 @@ update_sched(void *unused)
logerror("Updates disabled...skipping update"); logerror("Updates disabled...skipping update");
continue; continue;
} }
empth_sem_signal(update_sem); }
update_run();
} }
/*NOTREACHED*/ /*NOTREACHED*/
} }
@ -141,7 +146,8 @@ update_trigger(time_t secs_from_now)
return -1; return -1;
if (secs_from_now == 0) { if (secs_from_now == 0) {
empth_sem_signal(update_sem); update_forced = 1;
empth_wakeup(update_thread);
return 0; return 0;
} }
@ -163,23 +169,17 @@ update_force(void *seconds)
time(&now); time(&now);
empth_sleep(now + *(time_t *)seconds); empth_sleep(now + *(time_t *)seconds);
empth_sem_signal(update_sem); update_forced = 1;
empth_wakeup(update_thread);
free(seconds); free(seconds);
empth_exit(); empth_exit();
} }
/*ARGSUSED*/
static void static void
update_wait(void *unused) update_run(void)
{ {
struct player *p; struct player *p;
player->proc = empth_self();
player->cnum = 0;
player->god = 1;
while (1) {
empth_sem_wait(update_sem);
update_pending = 1; update_pending = 1;
for (p = player_next(0); p != 0; p = player_next(p)) { for (p = player_next(0); p != 0; p = player_next(p)) {
if (p->state != PS_PLAYING) if (p->state != PS_PLAYING)
@ -195,15 +195,13 @@ update_wait(void *unused)
if (run_hook(pre_update_hook, "pre-update")) { if (run_hook(pre_update_hook, "pre-update")) {
update_pending = 0; update_pending = 0;
empth_rwlock_unlock(update_lock); empth_rwlock_unlock(update_lock);
continue; return;
} }
} }
update_main(); update_main();
update_pending = 0; update_pending = 0;
empth_rwlock_unlock(update_lock); empth_rwlock_unlock(update_lock);
} }
/*NOTREACHED*/
}
static int static int
run_hook(char *cmd, char *name) run_hook(char *cmd, char *name)