]> git.pond.sub.org Git - empserver/commitdiff
Rewrite how updates are triggered (closes #1504036):
authorMarkus Armbruster <armbru@pond.sub.org>
Thu, 8 Feb 2007 11:54:31 +0000 (11:54 +0000)
committerMarkus Armbruster <armbru@pond.sub.org>
Thu, 8 Feb 2007 11:54:31 +0000 (11:54 +0000)
(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().

src/server/update.c

index 7c0effc071388bd4e1ac2365860072827b810e88..fc08c941f7ab304c1f3d2084029f2609010d2e3b 100644 (file)
 #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,22 +110,25 @@ 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);
-       time(&now);
-       now += adj_update;
-       if (!gamehours(now)) {
-           logerror("No update permitted (hours restriction)");
-           continue;
-       }
-       if (!updatetime(&now)) {
-           logerror("No update wanted");
-           continue;
-       }
-       if (updates_disabled()) {
-           logerror("Updates disabled...skipping update");
-           continue;
+       if (!update_forced) {
+           time(&now);
+           now += adj_update;
+           if (!gamehours(now)) {
+               logerror("No update permitted (hours restriction)");
+               continue;
+           }
+           if (!updatetime(&now)) {
+               logerror("No update wanted");
+               continue;
+           }
+           if (updates_disabled()) {
+               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,46 +169,38 @@ 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)
-               continue;
-           if (p->command) {
-               pr_flash(p, "Update aborting command\n");
-               p->aborted = 1;
-               empth_wakeup(p->proc);
-           }
+    update_pending = 1;
+    for (p = player_next(0); p != 0; p = player_next(p)) {
+       if (p->state != PS_PLAYING)
+           continue;
+       if (p->command) {
+           pr_flash(p, "Update aborting command\n");
+           p->aborted = 1;
+           empth_wakeup(p->proc);
        }
-       empth_rwlock_wrlock(update_lock);
-       if (*pre_update_hook) {
-           if (run_hook(pre_update_hook, "pre-update")) {
-               update_pending = 0;
-               empth_rwlock_unlock(update_lock);
-               continue;
-           }
+    }
+    empth_rwlock_wrlock(update_lock);
+    if (*pre_update_hook) {
+       if (run_hook(pre_update_hook, "pre-update")) {
+           update_pending = 0;
+           empth_rwlock_unlock(update_lock);
+           return;
        }
-       update_main();
-       update_pending = 0;
-       empth_rwlock_unlock(update_lock);
     }
-    /*NOTREACHED*/
+    update_main();
+    update_pending = 0;
+    empth_rwlock_unlock(update_lock);
 }
 
 static int