Add sequence numbers to game state

This oopses on output dependency violations, e.g. two threads doing a
read-modify-write without synchronization, or the one thread nesting
several read-modify-writes.  Such bugs are difficult to spot, and tend
to be abusable.  I figure we have quite a few of them.

New struct emptypedstr member seqno.  Make sure all members of unit
empobj_storage share it.  Initialize it in files: main() and
file_sct_init().  Set it in ef_blank() and new ef_set_uid() by calling
new get_seqno().  Use ef_set_uid() when copying objects: swaps(),
doland(), doship(), doplane(), dounit(), delete_old_news().  Step it
in ef_write() by calling new new_seqno().

Factor do_read() out of fillcache() to make it available for
get_seqno().
This commit is contained in:
Markus Armbruster 2008-05-17 22:44:00 +02:00
parent 087c0aae36
commit 536ef0b0a2
20 changed files with 134 additions and 19 deletions

View file

@ -588,7 +588,7 @@ doland(char op, int arg, char *p, struct sctstr *sect)
return RET_SYN;
sect->sct_x = newx;
sect->sct_y = newy;
sect->sct_uid = XYOFFSET(newx, newy);
ef_set_uid(EF_SECTOR, &sect, XYOFFSET(newx, newy));
break;
case 'D':
if (!sarg_xy(p, &newx, &newy))
@ -771,7 +771,7 @@ doship(char op, int arg, char *p, struct shpstr *ship)
ship->shp_rflags = arg;
break;
case 'U':
ship->shp_uid = arg;
ef_set_uid(EF_SHIP, ship, arg);
break;
case 'O':
if (ship->shp_own)
@ -875,7 +875,7 @@ dounit(char op, int arg, char *p, struct lndstr *land)
land->lnd_land = arg;
break;
case 'U':
land->lnd_uid = arg;
ef_set_uid(EF_LAND, land, arg);
break;
case 'O':
if (land->lnd_own)
@ -998,7 +998,7 @@ doplane(char op, int arg, char *p, struct plnstr *plane)
plane->pln_nuketype = arg;
break;
case 'U':
plane->pln_uid = arg;
ef_set_uid(EF_PLANE, plane, arg);
break;
case 'l':
if (!sarg_xy(p, &newx, &newy))

View file

@ -63,14 +63,14 @@ swaps(void)
/* change the location of secta to that of sectb */
secta.sct_x = sectb.sct_x;
secta.sct_y = sectb.sct_y;
secta.sct_uid = sectb.sct_uid;
ef_set_uid(EF_SECTOR, &secta, sectb.sct_uid);
secta.sct_dist_x = sectb.sct_x;
secta.sct_dist_y = sectb.sct_y;
secta.sct_coastal = sectb.sct_coastal;
/* change the location of sectb to where secta was */
sectb.sct_x = tmp.sct_x;
sectb.sct_y = tmp.sct_y;
sectb.sct_uid = tmp.sct_uid;
ef_set_uid(EF_SECTOR, &sectb, tmp.sct_uid);
sectb.sct_dist_x = tmp.sct_x;
sectb.sct_dist_y = tmp.sct_y;
sectb.sct_coastal = tmp.sct_coastal;