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:
parent
cea39829af
commit
c1eb1bd5d2
1 changed files with 59 additions and 61 deletions
|
@ -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,14 +195,12 @@ 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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue