two io wrapper functions CmiFwrite and CmiFclose that handles EINTR and short writes.
authorGengbin Zheng <gzheng@illinois.edu>
Thu, 14 Oct 2010 15:58:08 +0000 (10:58 -0500)
committerGengbin Zheng <gzheng@illinois.edu>
Thu, 14 Oct 2010 15:58:08 +0000 (10:58 -0500)
pup uses CmiFwrite now.

src/conv-core/converse.h
src/util/pup_util.C

index 9a7ee94d1db2624974a6c61efabaff27777f569c..9829c54513341695bedbfcc5a84d03fd38933d55 100644 (file)
@@ -51,6 +51,7 @@
 #include <stdint.h>
 #endif
 
+#include <stdio.h>
 #include <stdlib.h>
 
 /* Paste the tokens x and y together, without any space between them.
@@ -1854,6 +1855,11 @@ extern int CmiGridQueueLookupMsg (char *msg);
 #endif
 #endif
 
+/******** I/O wrappers ***********/
+
+size_t CmiFwrite(const void *ptr, size_t size, size_t nmemb, FILE *f);
+int CmiFclose(FILE *fp);
+
 #include "debug-conv.h"
 
 typedef struct {
index 00862b4b96fef389f5377305aa2e8d7bf5b4049b..53f1a85a593296b5d8876ad513121e8e57f5fa88 100644 (file)
@@ -16,6 +16,8 @@ virtual functions are defined here.
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <errno.h>
+
 #include "charm.h"
 #include "pup.h"
 #include "ckhashtable.h"
@@ -135,9 +137,44 @@ void PUP::fromMem::bytes(void *p,int n,size_t itemSize,dataType t)
        buf+=n;
 }
 
+// dealing with short write
+size_t CmiFwrite(const void *ptr, size_t size, size_t nmemb, FILE *f)
+{
+        size_t nwritten = 0;
+        const char *buf = (const char *)ptr;
+        while (nwritten < nmemb) {
+          size_t ncur = fwrite(buf+nwritten*size,size,nmemb-nwritten,f);
+          if (ncur <= 0) {
+            if  (errno == EINTR)
+              printf("Warning: CmiFwrite retrying ...\n");
+            else
+              break;
+          }
+          else
+            nwritten += ncur;
+        }
+        return nwritten;
+}
+
+// more robust fclose that handling interrupt
+int CmiFclose(FILE *fp)
+{
+        int status = 0;
+        while (1) {
+          status = fclose(fp);
+          if (status != 0 && errno==EINTR) {
+            printf("Warning: CmiFclose retrying ...\n");
+            continue;
+          }
+          else
+            break;
+        }
+        return status;
+}
+
 /*Disk PUP::er's*/
 void PUP::toDisk::bytes(void *p,int n,size_t itemSize,dataType /*t*/)
-{/* CkPrintf("writing %d bytes\n",itemSize*n); */ fwrite(p,itemSize,n,F);}
+{/* CkPrintf("writing %d bytes\n",itemSize*n); */ CmiFwrite(p,itemSize,n,F);}
 void PUP::fromDisk::bytes(void *p,int n,size_t itemSize,dataType /*t*/)
 {/* CkPrintf("reading %d bytes\n",itemSize*n); */ fread(p,itemSize,n,F);}