about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2021-09-27 16:12:45 +0000
committerJune McEnroe <june@causal.agency>2021-09-27 16:12:45 +0000
commitc1fcf0416ed960b669b2a4194684e2dbb1749fd3 (patch)
tree1e2e7cf65d5022d6816189e92a16449cf10d95b4
parentCopy CSVs to web directory from snapshot.sh (diff)
downloadtorus-c1fcf0416ed960b669b2a4194684e2dbb1749fd3.tar.gz
torus-c1fcf0416ed960b669b2a4194684e2dbb1749fd3.zip
Call msync(2) after modifying tiles
Without it, changes aren't visible to a process read(2)'ing the
file until all mappings of the file are unmapped, on OpenBSD. There
is apparently no guarantee that they are visible on other systems
either. TIL.
-rw-r--r--server.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/server.c b/server.c
index ee19ec8..435eefa 100644
--- a/server.c
+++ b/server.c
@@ -67,7 +67,7 @@ static struct Tile *tileGet(uint32_t tileX, uint32_t tileY) {
 	return tile;
 }
 
-static const struct Tile *tileAccess(uint32_t tileX, uint32_t tileY) {
+static struct Tile *tileAccess(uint32_t tileX, uint32_t tileY) {
 	struct Tile *tile = tileGet(tileX, tileY);
 	tile->accessTime = time(NULL);
 	tile->accessCount++;
@@ -81,6 +81,12 @@ static struct Tile *tileModify(uint32_t tileX, uint32_t tileY) {
 	return tile;
 }
 
+static struct Tile *tileSync(struct Tile *tile) {
+	int error = msync(tile, sizeof(*tile), MS_ASYNC);
+	if (error) err(EX_IOERR, "msync");
+	return tile;
+}
+
 enum { ClientsCap = 256 };
 static struct Client {
 	int fd;
@@ -107,7 +113,9 @@ clientSend(const struct Client *client, const struct ServerMessage *msg) {
 	ssize_t len = send(client->fd, msg, sizeof(*msg), 0);
 	if (len < 0) return -1;
 	if (msg->type == ServerTile) {
-		const struct Tile *tile = tileAccess(client->tileX, client->tileY);
+		const struct Tile *tile = tileSync(
+			tileAccess(client->tileX, client->tileY)
+		);
 		len = send(client->fd, tile, sizeof(*tile), 0);
 		if (len < 0) return -1;
 	}
@@ -251,6 +259,7 @@ static int clientPut(const struct Client *client, uint8_t color, uint8_t cell) {
 	struct Tile *tile = tileModify(client->tileX, client->tileY);
 	tile->colors[client->cellY][client->cellX] = color;
 	tile->cells[client->cellY][client->cellX] = cell;
+	tileSync(tile);
 	struct ServerMessage msg = {
 		.type = ServerPut,
 		.put = {