浏览代码

HPCC-8063 Avoid follow on error from disk full

A CRowStreamWriter with autoflush on, could cause problem if
a disk full exception whilst writing led to the classes
destruction where another attempt (and failure) was made to
write by autoflush

Signed-off-by: Jake Smith <jake.smith@lexisnexis.com>
Jake Smith 12 年之前
父节点
当前提交
affdd21971
共有 1 个文件被更改,包括 42 次插入21 次删除
  1. 42 21
      common/thorhelper/thorcommon.cpp

+ 42 - 21
common/thorhelper/thorcommon.cpp

@@ -1343,29 +1343,50 @@ class CRowStreamWriter : public CSimpleInterface, private IRowSerializerTarget,
 
     void flushBuffer(bool final) 
     {
-        if (bufpos) {
-            stream->write(bufpos,buf);
-            if (tallycrc)
-                crc.tally(bufpos,buf);
-            bufpos = 0;
+        try
+        {
+            if (bufpos) {
+                stream->write(bufpos,buf);
+                if (tallycrc)
+                    crc.tally(bufpos,buf);
+                bufpos = 0;
+            }
+            size32_t extpos = extbuf.length();
+            if (!extpos)
+                return;
+            if (!final)
+                extpos = (extpos/ROW_WRITER_BUFFERSIZE)*ROW_WRITER_BUFFERSIZE;
+            if (extpos) {
+                stream->write(extpos,extbuf.toByteArray());
+                if (tallycrc)
+                    crc.tally(extpos,extbuf.toByteArray());
+            }
+            if (extpos<extbuf.length()) {
+                bufpos = extbuf.length()-extpos;
+                memcpy(buf,extbuf.toByteArray()+extpos,bufpos);
+            }
+            extbuf.clear();
         }
-        size32_t extpos = extbuf.length();
-        if (!extpos)
-            return;
-        if (!final) 
-            extpos = (extpos/ROW_WRITER_BUFFERSIZE)*ROW_WRITER_BUFFERSIZE;
-        if (extpos) {
-            stream->write(extpos,extbuf.toByteArray());
-            if (tallycrc)
-                crc.tally(extpos,extbuf.toByteArray());
+        catch (IException *e)
+        {
+            autoflush = false; // avoid follow-on errors
+            EXCLOG(e, "flushBuffer");
+            throw;
         }
-        if (extpos<extbuf.length()) {
-            bufpos = extbuf.length()-extpos;
-            memcpy(buf,extbuf.toByteArray()+extpos,bufpos);
+    }
+    void streamFlush()
+    {
+        try
+        {
+            stream->flush();
+        }
+        catch (IException *e)
+        {
+            autoflush = false; // avoid follow-on errors
+            EXCLOG(e, "streamFlush");
+            throw;
         }
-        extbuf.clear();
     }
-
 public:
     IMPLEMENT_IINTERFACE_USING(CSimpleInterface);
 
@@ -1425,13 +1446,13 @@ public:
     void flush()
     {
         flushBuffer(true);
-        stream->flush();
+        streamFlush();
     }
 
     void flush(CRC32 *crcout)
     {
         flushBuffer(true);
-        stream->flush();
+        streamFlush();
         if (crcout)
             *crcout = crc;
     }