浏览代码

Merge pull request #4613 from jakesmith/hpcc-8053b

HPCC-8053 - Timeouts can cause superfile update inconsistencies

Reviewed-By: Gavin Halliday <gavin.halliday@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 12 年之前
父节点
当前提交
97c5bdddec
共有 1 个文件被更改,包括 22 次插入5 次删除
  1. 22 5
      dali/base/dadfs.cpp

+ 22 - 5
dali/base/dadfs.cpp

@@ -2240,6 +2240,7 @@ protected:
     unsigned transactionnest;
     Linked<IUserDescriptor> udesc;
     unsigned defaultTimeout;
+    bool dirty;
 public:
 
     IPropertyTree *queryRoot() { return root; }
@@ -2250,6 +2251,7 @@ public:
         proplockcount = 0;
         transactionnest = 0;
         defaultTimeout = INFINITE;
+        dirty = false;
     }
 
     ~CDistributedFileBase<INTERFACE>()
@@ -2351,22 +2353,35 @@ public:
         bool reload = false;
         if (timeoutms==INFINITE)
             timeoutms = defaultTimeout;
-        reload = false;
-        if (proplockcount++==0) {
-            if (conn) {
+        if (proplockcount++==0)
+        {
+            if (conn)
+            {
                 conn->rollback(); // changes chouldn't be done outside lock properties
 #ifdef TRACE_LOCKS
                 PROGLOG("lockProperties: pre safeChangeModeWrite(%x)",(unsigned)(memsize_t)conn.get());
 #endif
-                try {
+                try
+                {
                     safeChangeModeWrite(conn,queryLogicalName(),reload,timeoutms);
                 }
                 catch(IException *)
                 {
                     proplockcount--;
                     dfCheckRoot("lockProperties",root,conn);
+                    if (reload)
+                        dirty = true; // safeChangeModeWrite unlocked, and reload will be need if retried
                     throw;
                 }
+                if (dirty) // a previous attempt unlocked and did not reload
+                {
+                    dirty = false;
+                    if (!reload) // if reload=true, safeChangeModeWrite has just reloaded, so no need to again here
+                    {
+                        conn->reload();
+                        reload = true;
+                    }
+                }
 #ifdef TRACE_LOCKS
                 PROGLOG("lockProperties: done safeChangeModeWrite(%x)",(unsigned)(memsize_t)conn.get());
                 LogRemoteConn(conn);
@@ -4243,7 +4258,9 @@ class CDistributedSuperFile: public CDistributedFileBase<IDistributedSuperFile>
         }
         bool refresh() // returns true if any changes
         {
-            return (refresh(parent.get()) || refresh(file.get()));
+            bool pChanged = refresh(parent);
+            bool fChanged = refresh(file);
+            return pChanged || fChanged;
         }
     public:
         cSwapFileAction(IDistributedFileTransaction *_transaction,const char *_parentlname,const char *_filelname)