diff --git a/include/server.h b/include/server.h index fd2c0cfd..c0bb483d 100644 --- a/include/server.h +++ b/include/server.h @@ -38,6 +38,7 @@ extern int shutdown_pending; extern int update_pending; +extern int update_running; extern empth_rwlock_t *update_lock; extern time_t update_time[]; diff --git a/src/lib/subs/pr.c b/src/lib/subs/pr.c index d9e7a5f0..ea37b5f3 100644 --- a/src/lib/subs/pr.c +++ b/src/lib/subs/pr.c @@ -472,7 +472,7 @@ PR(int cn, char *format, ...) newline = strrchr(buf, '\n') ? 1 : 0; strcat(longline[cn], buf); if (newline) { - if (update_pending || (cn && cn != player->cnum)) + if (update_running || (cn && cn != player->cnum)) typed_wu(0, cn, longline[cn], TEL_BULLETIN); else pr_player(player, C_DATA, longline[cn]); @@ -524,7 +524,7 @@ mpr(int cn, char *format, ...) (void)vsprintf(buf, format, ap); va_end(ap); if (cn) { - if (update_pending || cn != player->cnum) + if (update_running || cn != player->cnum) typed_wu(0, cn, buf, TEL_BULLETIN); else pr_player(player, C_DATA, buf); diff --git a/src/lib/subs/rej.c b/src/lib/subs/rej.c index 27fae9b8..59524902 100644 --- a/src/lib/subs/rej.c +++ b/src/lib/subs/rej.c @@ -94,7 +94,7 @@ setrel(natid us, natid them, int rel) if (theirrel <= MOBILIZATION) { rel = theirrel; cost = 0; - } else if (us == player->cnum && !update_pending) { + } else if (us == player->cnum && !update_running) { if (mynp->nat_money < War_Cost) { mpr(us, "You don't have the money!\n"); return RET_FAIL; @@ -105,7 +105,7 @@ setrel(natid us, natid them, int rel) return RET_FAIL; } if (rel >= oldrel) { - if (us == player->cnum && !update_pending) + if (us == player->cnum && !update_running) mpr(us, "No change required for that!\n"); return RET_FAIL; } @@ -116,7 +116,7 @@ setrel(natid us, natid them, int rel) n_down = N_DECL_WAR; } - if (addendum && us == player->cnum && !update_pending) + if (addendum && us == player->cnum && !update_running) pr("%s\n", addendum); mpr(us, "Diplomatic relations with %s %s to \"%s\".\n", themname, whichway, relates[rel]); diff --git a/src/lib/subs/shpsub.c b/src/lib/subs/shpsub.c index e5b6b367..824b5486 100644 --- a/src/lib/subs/shpsub.c +++ b/src/lib/subs/shpsub.c @@ -139,7 +139,7 @@ shp_nav(struct emp_qelem *list, double *minmobp, double *maxmobp, continue; } if (opt_SAIL) { - if (*ship.shp_path && !update_pending) { + if (*ship.shp_path && !update_running) { shp_mess("has a sail path", mlp); mpr(actor, "Use `sail <#> -' to reset\n"); continue; diff --git a/src/lib/subs/wu.c b/src/lib/subs/wu.c index 91a9432d..23a503da 100644 --- a/src/lib/subs/wu.c +++ b/src/lib/subs/wu.c @@ -74,7 +74,7 @@ telegram_is_new(natid to, struct telstr *tel) is_new |= tel->tel_type != last_tel[to].tel_type; is_new |= tel->tel_from != last_tel[to].tel_from; - is_new |= !update_pending && /* sometimes updates take a long time */ + is_new |= !update_running && /* updates can take a long time */ abs(tel->tel_date - last_tel[to].tel_date) > TEL_SECONDS; last_tel[to].tel_type = tel->tel_type; @@ -104,7 +104,7 @@ wu(natid from, natid to, char *format, ...) (void)vsprintf(buf, format, ap); va_end(ap); np = getnatp(from); - if (update_pending) + if (update_running) return typed_wu(from, to, buf, TEL_UPDATE); else if (np->nat_stat == STAT_GOD) return typed_wu(from, to, buf, TEL_BULLETIN); diff --git a/src/lib/update/mobility.c b/src/lib/update/mobility.c index 59f01bf3..5c7e5c6a 100644 --- a/src/lib/update/mobility.c +++ b/src/lib/update/mobility.c @@ -53,7 +53,7 @@ sct_do_upd_mob(struct sctstr *sp) { int etus; - if (do_upd_checking || update_pending) + if (do_upd_checking || update_running) return; if (sp->sct_own == 0) return; @@ -73,7 +73,7 @@ shp_do_upd_mob(struct shpstr *sp) { int etus; - if (do_upd_checking || update_pending) + if (do_upd_checking || update_running) return; if (sp->shp_own == 0) return; @@ -91,7 +91,7 @@ lnd_do_upd_mob(struct lndstr *lp) { int etus; - if (do_upd_checking || update_pending) + if (do_upd_checking || update_running) return; if (lp->lnd_own == 0) return; @@ -109,7 +109,7 @@ pln_do_upd_mob(struct plnstr *pp) { int etus; - if (do_upd_checking || update_pending) + if (do_upd_checking || update_running) return; if (pp->pln_own == 0) return; diff --git a/src/server/update.c b/src/server/update.c index 863642db..b4e7c07c 100644 --- a/src/server/update.c +++ b/src/server/update.c @@ -50,14 +50,31 @@ #define UPDATES 16 +/* + * Lock to synchronize player threads with the update. + * Update takes it exclusive, commands take it shared. + */ empth_rwlock_t *update_lock; -static empth_t *update_thread; + +/* + * Update is pending, player threads must give up update_lock ASAP. + * This means they must not block while update_pending. + */ int update_pending; +/* + * Update is running. + * Can be used to suppress messages, or direct them to bulletins. + */ +int update_running; + time_t update_time[UPDATES]; + static time_t update_schedule_anchor; static int update_wanted; +static empth_t *update_thread; + static int update_get_schedule(void); static void update_sched(void *); static void update_run(void); @@ -209,8 +226,9 @@ update_run(void) return; } } + update_running = 1; update_main(); - update_pending = 0; + update_pending = update_running = 0; empth_rwlock_unlock(update_lock); }