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