Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2005:
[Freeciv-Dev] (PR#13986) Attribute upload isn't atomic
Home

[Freeciv-Dev] (PR#13986) Attribute upload isn't atomic

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13986) Attribute upload isn't atomic
From: "Mateusz Stefek" <mstefek@xxxxxxxxx>
Date: Fri, 16 Sep 2005 02:20:22 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13986 >

This leads to problems when someone saves a game or the client
disconnects while uploading attributes.

This patch fixes those problems.
--
mateusz
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.238
diff -u -r1.238 game.c
--- common/game.c       7 Sep 2005 19:18:12 -0000       1.238
+++ common/game.c       16 Sep 2005 08:59:21 -0000
@@ -438,8 +438,16 @@
   if (pplayer->attribute_block.data) {
     free(pplayer->attribute_block.data);
     pplayer->attribute_block.data = NULL;
+    pplayer->attribute_block.length = 0;
   }
 
+  if (pplayer->attribute_block_buffer.data) {
+    free(pplayer->attribute_block_buffer.data);
+    pplayer->attribute_block_buffer.data = NULL;
+    pplayer->attribute_block_buffer.length = 0;
+  }
+
+
 #if 0
   assert(conn_list_size(pplayer->connections) == 0);
   /* FIXME: Connections that are unlinked here are left dangling.  It's up to
Index: common/packets.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v
retrieving revision 1.276
diff -u -r1.276 packets.c
--- common/packets.c    16 Sep 2005 08:29:14 -0000      1.276
+++ common/packets.c    16 Sep 2005 08:59:24 -0000
@@ -579,27 +579,39 @@
       || chunk->offset < 0
       || chunk->offset + chunk->chunk_length > chunk->total_length
       || (chunk->offset != 0
-          && chunk->total_length != pplayer->attribute_block.length)) {
+          && chunk->total_length != pplayer->attribute_block_buffer.length)) {
     /* wrong attribute data */
-    if (pplayer->attribute_block.data) {
-      free(pplayer->attribute_block.data);
-      pplayer->attribute_block.data = NULL;
+    if (pplayer->attribute_block_buffer.data) {
+      free(pplayer->attribute_block_buffer.data);
+      pplayer->attribute_block_buffer.data = NULL;
     }
-    pplayer->attribute_block.length = 0;
+    pplayer->attribute_block_buffer.length = 0;
     freelog(LOG_ERROR, "Received wrong attribute chunk");
     return;
   }
   /* first one in a row */
   if (chunk->offset == 0) {
-    if (pplayer->attribute_block.data) {
-      free(pplayer->attribute_block.data);
-      pplayer->attribute_block.data = NULL;
+    if (pplayer->attribute_block_buffer.data) {
+      free(pplayer->attribute_block_buffer.data);
+      pplayer->attribute_block_buffer.data = NULL;
     }
-    pplayer->attribute_block.data = fc_malloc(chunk->total_length);
-    pplayer->attribute_block.length = chunk->total_length;
+    pplayer->attribute_block_buffer.data = fc_malloc(chunk->total_length);
+    pplayer->attribute_block_buffer.length = chunk->total_length;
   }
-  memcpy((char *) (pplayer->attribute_block.data) + chunk->offset,
+  memcpy((char *) (pplayer->attribute_block_buffer.data) + chunk->offset,
         chunk->data, chunk->chunk_length);
+  
+  if (chunk->offset + chunk->chunk_length == chunk->total_length) {
+    /* Received full attribute block */
+    if (pplayer->attribute_block.data != NULL) {
+      free(pplayer->attribute_block.data);
+    }
+    pplayer->attribute_block.data = pplayer->attribute_block_buffer.data;
+    pplayer->attribute_block.length = pplayer->attribute_block_buffer.length;
+    
+    pplayer->attribute_block_buffer.data = NULL;
+    pplayer->attribute_block_buffer.length = 0;
+  }
 }
 
 /**************************************************************************
Index: common/player.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.c,v
retrieving revision 1.192
diff -u -r1.192 player.c
--- common/player.c     4 Sep 2005 04:31:17 -0000       1.192
+++ common/player.c     16 Sep 2005 08:59:29 -0000
@@ -161,6 +161,8 @@
 
   plr->attribute_block.data = NULL;
   plr->attribute_block.length = 0;
+  plr->attribute_block_buffer.data = NULL;
+  plr->attribute_block_buffer.length = 0;
   BV_CLR_ALL(plr->debug);
 }
 
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.164
diff -u -r1.164 player.h
--- common/player.h     4 Sep 2005 04:31:18 -0000       1.164
+++ common/player.h     16 Sep 2005 08:59:29 -0000
@@ -196,6 +196,10 @@
     int length;
     void *data;
   } attribute_block;
+  struct {
+    int length;
+    void *data;
+  } attribute_block_buffer;
   bv_debug debug;
 };
 
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.187.2.4
diff -u -r1.187.2.4 game.c
--- common/game.c       21 Jul 2005 19:32:04 -0000      1.187.2.4
+++ common/game.c       16 Sep 2005 09:08:06 -0000
@@ -439,6 +439,13 @@
   if (pplayer->attribute_block.data) {
     free(pplayer->attribute_block.data);
     pplayer->attribute_block.data = NULL;
+    pplayer->attribute_block.length = 0;
+  }
+
+  if (pplayer->attribute_block_buffer.data) {
+    free(pplayer->attribute_block_buffer.data);
+    pplayer->attribute_block_buffer.data = NULL;
+    pplayer->attribute_block_buffer.length = 0;
   }
 
   if (pplayer->island_improv) {
Index: common/packets.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v
retrieving revision 1.271.2.2
diff -u -r1.271.2.2 packets.c
--- common/packets.c    16 Sep 2005 08:31:25 -0000      1.271.2.2
+++ common/packets.c    16 Sep 2005 09:08:06 -0000
@@ -581,27 +581,39 @@
       || chunk->offset < 0
       || chunk->offset + chunk->chunk_length > chunk->total_length
       || (chunk->offset != 0
-          && chunk->total_length != pplayer->attribute_block.length)) {
+          && chunk->total_length != pplayer->attribute_block_buffer.length)) {
     /* wrong attribute data */
-    if (pplayer->attribute_block.data) {
-      free(pplayer->attribute_block.data);
-      pplayer->attribute_block.data = NULL;
+    if (pplayer->attribute_block_buffer.data) {
+      free(pplayer->attribute_block_buffer.data);
+      pplayer->attribute_block_buffer.data = NULL;
     }
-    pplayer->attribute_block.length = 0;
+    pplayer->attribute_block_buffer.length = 0;
     freelog(LOG_ERROR, "Received wrong attribute chunk");
     return;
   }
   /* first one in a row */
   if (chunk->offset == 0) {
-    if (pplayer->attribute_block.data) {
-      free(pplayer->attribute_block.data);
-      pplayer->attribute_block.data = NULL;
+    if (pplayer->attribute_block_buffer.data) {
+      free(pplayer->attribute_block_buffer.data);
+      pplayer->attribute_block_buffer.data = NULL;
     }
-    pplayer->attribute_block.data = fc_malloc(chunk->total_length);
-    pplayer->attribute_block.length = chunk->total_length;
+    pplayer->attribute_block_buffer.data = fc_malloc(chunk->total_length);
+    pplayer->attribute_block_buffer.length = chunk->total_length;
   }
-  memcpy((char *) (pplayer->attribute_block.data) + chunk->offset,
+  memcpy((char *) (pplayer->attribute_block_buffer.data) + chunk->offset,
         chunk->data, chunk->chunk_length);
+  
+  if (chunk->offset + chunk->chunk_length == chunk->total_length) {
+    /* Received full attribute block */
+    if (pplayer->attribute_block.data != NULL) {
+      free(pplayer->attribute_block.data);
+    }
+    pplayer->attribute_block.data = pplayer->attribute_block_buffer.data;
+    pplayer->attribute_block.length = pplayer->attribute_block_buffer.length;
+    
+    pplayer->attribute_block_buffer.data = NULL;
+    pplayer->attribute_block_buffer.length = 0;
+  }
 }
 
 /**************************************************************************
Index: common/player.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.c,v
retrieving revision 1.157.2.6
diff -u -r1.157.2.6 player.c
--- common/player.c     22 Aug 2005 20:58:53 -0000      1.157.2.6
+++ common/player.c     16 Sep 2005 09:08:06 -0000
@@ -150,6 +150,9 @@
 
   plr->attribute_block.data = NULL;
   plr->attribute_block.length = 0;
+  plr->attribute_block_buffer.data = NULL;
+  plr->attribute_block_buffer.length = 0;
+
   plr->debug = FALSE;
 }
 
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.130.2.4
diff -u -r1.130.2.4 player.h
--- common/player.h     19 Apr 2005 22:05:57 -0000      1.130.2.4
+++ common/player.h     16 Sep 2005 09:08:07 -0000
@@ -225,6 +225,11 @@
     int length;
     void *data;
   } attribute_block;
+  struct {
+    int length;
+    void *data;
+  } attribute_block_buffer;
+  
   bool debug;
 };
 

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#13986) Attribute upload isn't atomic, Mateusz Stefek <=