소스 검색

Merge branch 'candidate-5.6.0' into candidate-6.0.0

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 9 년 전
부모
커밋
35b5d4f7e8

+ 1 - 0
cmake_modules/commonSetup.cmake

@@ -346,6 +346,7 @@ IF ("${COMMONSETUP_DONE}" STREQUAL "")
           SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wparentheses")
         endif ()
       endif ()
+      SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE}")
       SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
       if (GENERATE_COVERAGE_INFO)
         message ("Build system with coverage.")

+ 1 - 0
dali/base/CMakeLists.txt

@@ -62,6 +62,7 @@ include_directories (
          ./../../system/mp 
          ./../../system/include 
          ./../../system/jlib 
+         ./../../rtl/include 
     )
 
 ADD_DEFINITIONS( -DLOGMSGCOMPONENT=3 -D_USRDLL -DDALI_EXPORTS )

+ 210 - 211
dali/base/dadfs.cpp

@@ -38,6 +38,7 @@
 #include "mputil.hpp"
 #include "rmtfile.hpp"
 #include "dadfs.hpp"
+#include "eclhelper.hpp"
 
 #ifdef _DEBUG
 //#define EXTRA_LOGGING
@@ -964,6 +965,7 @@ interface IDistributedFileTransactionExt : extends IDistributedFileTransaction
     virtual void retryActions()=0;
     virtual void runActions()=0;
     virtual void commitAndClearup()=0;
+    virtual ICodeContext *queryCodeContext()=0;
 };
 
 class CDistributedFileDirectory: public CInterface, implements IDistributedFileDirectory
@@ -1324,7 +1326,7 @@ public:
             // This will do the right thing for either super-files and logical-files.
             try
             {
-                file->detach(0); // 0 == timeout immediately if cannot get exclusive lock
+                file->detach(0, NULL); // 0 == timeout immediately if cannot get exclusive lock
                 return;
             }
             catch (ISDSException *e)
@@ -1458,6 +1460,7 @@ class CDistributedFileTransaction: public CInterface, implements IDistributedFil
     // any exception to the rule used by addSubFile / removeSubFile
     unsigned depth;
     unsigned prepared;
+    ICodeContext *codeCtx;
 
     /* 'owner' is set if, transaction object is implicitly created, because none provided
      * The owner cannot be release or unlocked. The transaction can still retry if other files are locked,
@@ -1465,8 +1468,6 @@ class CDistributedFileTransaction: public CInterface, implements IDistributedFil
      */
     IDistributedSuperFile *owner;
 
-
-    void validateAddSubFile(IDistributedSuperFile *super, IDistributedFile *sub, const char *subName);
     CTransactionFile *queryCreate(const char *name, IDistributedFile *file, bool recreate=false)
     {
         Owned<CTransactionFile> trackedFile;
@@ -1486,11 +1487,42 @@ class CDistributedFileTransaction: public CInterface, implements IDistributedFil
     {
         return trackedFiles.find(file);
     }
-
+    void commitActions()
+    {
+        while (actions.ordinality())  // if we get here everything should work!
+        {
+            Owned<CDFAction> action = &actions.popGet();
+            action->commit();
+        }
+    }
+    IDistributedFile *findFile(const char *name)
+    {
+        StringBuffer tmp;
+        name = normalizeLFN(name, tmp);
+        CTransactionFile *trackedFile = trackedFilesByName.find(tmp.str());
+        if (!trackedFile)
+            return NULL;
+        return trackedFile->queryFile();
+    }
+    void deleteFiles()      // no rollback at this point
+    {
+        Owned<IMultiException> me = MakeMultiException("Transaction");
+        ForEachItemIn(i,delayeddelete) {
+            try {
+                delayeddelete.item(i).doDelete();
+            } catch (IException *e) {
+                me->append(*e);
+            }
+        }
+        delayeddelete.kill();
+        if (me->ordinality())
+            throw me.getClear();
+    }
 public:
     IMPLEMENT_IINTERFACE;
-    CDistributedFileTransaction(IUserDescriptor *user, IDistributedSuperFile *_owner=NULL)
-        : isactive(false), depth(0), prepared(0), owner(_owner)
+
+    CDistributedFileTransaction(IUserDescriptor *user, IDistributedSuperFile *_owner=NULL, ICodeContext *_codeCtx=NULL)
+        : isactive(false), depth(0), prepared(0), owner(_owner), codeCtx(_codeCtx)
     {
         setUserDescriptor(udesc,user);
     }
@@ -1502,79 +1534,8 @@ public:
             rollback();
         assert(depth == 0);
     }
-    void ensureFile(IDistributedFile *file)
-    {
-        if (!trackedFiles.find(file))
-            addFile(file);
-    }
-    void addFile(IDistributedFile *file)
-    {
-        CTransactionFile *trackedFile = queryCreate(file->queryLogicalName(), file, false);
-        // Also add subfiles to cache
-        IDistributedSuperFile *sfile = file->querySuperFile();
-        if (sfile)
-        {
-            Owned<IDistributedFileIterator> iter = sfile->getSubFileIterator();
-            ForEach(*iter)
-            {
-                IDistributedFile *f = &iter->query();
-                trackedFile->noteAddSubFile(f);
-                addFile(f);
-            }
-        }
-    }
-    void noteAddSubFile(IDistributedSuperFile *super, const char *superName, IDistributedFile *sub)
-    {
-        CTransactionFile *trackedSuper = queryCreate(superName, super);
-        trackedSuper->noteAddSubFile(sub);
-    }
-    void noteRemoveSubFile(IDistributedSuperFile *super, IDistributedFile *sub)
-    {
-        CTransactionFile *trackedSuper = lookupTrackedFile(super);
-        if (trackedSuper)
-            trackedSuper->noteRemoveSubFile(sub);
-    }
-    virtual void clearSubFiles(IDistributedSuperFile *super)
-    {
-        CTransactionFile *trackedSuper = lookupTrackedFile(super);
-        if (trackedSuper)
-            trackedSuper->clearSubs();
-    }
-    virtual void noteSuperSwap(IDistributedSuperFile *super1, IDistributedSuperFile *super2)
-    {
-        CTransactionFile *trackedSuper1 = lookupTrackedFile(super1);
-        CTransactionFile *trackedSuper2 = lookupTrackedFile(super2);
-        assertex(trackedSuper1 && trackedSuper2);
-        ICopyArrayOf<IDistributedFile> super1Subs, super2Subs;
-        Owned<IDistributedFileIterator> iter = trackedSuper1->getSubFiles();
-        ForEach(*iter)
-            super1Subs.append(iter->query());
-        trackedSuper1->clearSubs();
-        iter.setown(trackedSuper2->getSubFiles());
-        ForEach(*iter)
-            super2Subs.append(iter->query());
-        trackedSuper2->clearSubs();
-        ForEachItemIn(s, super2Subs)
-            trackedSuper1->noteAddSubFile(&super2Subs.item(s));
-        ForEachItemIn(s2, super1Subs)
-            trackedSuper2->noteAddSubFile(&super1Subs.item(s2));
-    }
-    void noteRename(IDistributedFile *file, const char *newName)
-    {
-        CTransactionFile *trackedFile = lookupTrackedFile(file);
-        if (trackedFile)
-        {
-            trackedFiles.removeExact(trackedFile);
-            trackedFilesByName.removeExact(trackedFile);
-            trackedFile = queryCreate(newName, file);
-        }
-    }
-    void addAction(CDFAction *action)
-    {
-        actions.append(*action); // takes ownership
-        action->setTransaction(this);
-    }
-    void start()
+// IDistributedFileTransaction impl.
+    virtual void start()
     {
         if (isactive)
             throw MakeStringException(-1,"Transaction already started");
@@ -1584,39 +1545,7 @@ public:
         prepared = 0;
         assertex(actions.ordinality()==0);
     }
-    bool prepareActions()
-    {
-        prepared = 0;
-        unsigned toPrepare = actions.ordinality();
-        ForEachItemIn(i0,actions)
-        {
-            if (actions.item(i0).prepare())
-                ++prepared;
-            else
-                break;
-        }
-        return prepared == toPrepare;
-    }
-    void retryActions()
-    {
-        clearFiles(); // clear all previously tracked pending file changes, e.g. renames, super file additions/removals
-        while (prepared) // unlock for retry
-            actions.item(--prepared).retry();
-    }
-    void runActions()
-    {
-        ForEachItemIn(i,actions)
-            actions.item(i).run();
-    }
-    void commitActions()
-    {
-        while (actions.ordinality())  // if we get here everything should work!
-        {
-            Owned<CDFAction> action = &actions.popGet();
-            action->commit();
-        }
-    }
-    void commit()
+    virtual void commit()
     {
         if (!isactive)
             return;
@@ -1644,17 +1573,7 @@ public:
         rollback();
         throw rete;
     }
-    void commitAndClearup()
-    {
-        // =============== COMMIT and CLEANUP
-        commitActions();
-        clearFiles();
-        isactive = false;
-        actions.kill();
-        deleteFiles();
-    }
-
-    void rollback()
+    virtual void rollback()
     {
         // =============== ROLLBACK AND CLEANUP
         while (actions.ordinality())
@@ -1681,46 +1600,11 @@ public:
         // this we only want to do if active
         delayeddelete.kill();
     }
-
-    void autoCommit()
-    {
-        // Recursive calls to transaction will not commit until
-        // all calls have finished (gone back to zero depth)
-        if (!depth && !isactive) {
-            try {
-                isactive = true;
-                commit();
-            }
-            catch (IException *) {
-                rollback();
-                throw;
-            }
-        }
-    }
-
-    // Call this when you're recurring
-    void descend()
-    {
-        depth++;
-    }
-
-    // Call this at the end of the block that started recursion
-    void ascend()
-    {
-        assertex(depth);
-        depth--;
-    }
-
-    IDistributedFile *findFile(const char *name)
+    virtual bool active()
     {
-        StringBuffer tmp;
-        name = normalizeLFN(name, tmp);
-        CTransactionFile *trackedFile = trackedFilesByName.find(tmp.str());
-        if (!trackedFile)
-            return NULL;
-        return trackedFile->queryFile();
+        return isactive;
     }
-    IDistributedFile *lookupFile(const char *name,unsigned timeout)
+    virtual IDistributedFile *lookupFile(const char *name,unsigned timeout)
     {
         IDistributedFile *ret = findFile(name);
         if (ret)
@@ -1733,8 +1617,7 @@ public:
             return ret;
         }
     }
-
-    IDistributedSuperFile *lookupSuperFile(const char *name, unsigned timeout)
+    virtual IDistributedSuperFile *lookupSuperFile(const char *name, unsigned timeout)
     {
         IDistributedFile *f = findFile(name);
         if (f)
@@ -1747,29 +1630,62 @@ public:
             return ret;
         }
     }
-
-    virtual bool isSubFile(IDistributedSuperFile *super, const char *subFile, bool sub)
+// IDistributedFileTransactionExt impl.
+    virtual IUserDescriptor *queryUser()
     {
-        CTransactionFile *trackedSuper = lookupTrackedFile(super);
-        if (!trackedSuper)
-            return false;
-        return trackedSuper->find(subFile, sub);
+        return udesc;
     }
-
-public:
-    bool active()
+    virtual void descend() // Call this when you're recurring
     {
-        return isactive;
+        depth++;
     }
-
-    void clearFiles()
+    virtual void ascend() // Call this at the end of the block that started recursion
     {
-        trackedFiles.kill();
-        trackedFilesByName.kill();
-        if (owner)
-            addFile(owner); // ensure remains tracked
+        assertex(depth);
+        depth--;
+    }
+    virtual void autoCommit()
+    {
+        // Recursive calls to transaction will not commit until
+        // all calls have finished (gone back to zero depth)
+        if (!depth && !isactive) {
+            try {
+                isactive = true;
+                commit();
+            }
+            catch (IException *) {
+                rollback();
+                throw;
+            }
+        }
     }
-    void clearFile(IDistributedFile *file)
+    virtual void addAction(CDFAction *action)
+    {
+        actions.append(*action); // takes ownership
+        action->setTransaction(this);
+    }
+    virtual void addFile(IDistributedFile *file)
+    {
+        CTransactionFile *trackedFile = queryCreate(file->queryLogicalName(), file, false);
+        // Also add subfiles to cache
+        IDistributedSuperFile *sfile = file->querySuperFile();
+        if (sfile)
+        {
+            Owned<IDistributedFileIterator> iter = sfile->getSubFileIterator();
+            ForEach(*iter)
+            {
+                IDistributedFile *f = &iter->query();
+                trackedFile->noteAddSubFile(f);
+                addFile(f);
+            }
+        }
+    }
+    virtual void ensureFile(IDistributedFile *file)
+    {
+        if (!trackedFiles.find(file))
+            addFile(file);
+    }
+    virtual void clearFile(IDistributedFile *file)
     {
         CTransactionFile *trackedFile = lookupTrackedFile(file);
         IDistributedSuperFile *sfile = file->querySuperFile();
@@ -1785,31 +1701,108 @@ public:
             trackedFilesByName.removeExact(trackedFile);
         }
     }
-
-    IUserDescriptor *queryUser()
+    virtual void clearFiles()
     {
-        return udesc;
+        trackedFiles.kill();
+        trackedFilesByName.kill();
+        if (owner)
+            addFile(owner); // ensure remains tracked
     }
-
-    bool addDelayedDelete(CDfsLogicalFileName &lfn,unsigned timeoutms)
+    virtual void noteAddSubFile(IDistributedSuperFile *super, const char *superName, IDistributedFile *sub)
+    {
+        CTransactionFile *trackedSuper = queryCreate(superName, super);
+        trackedSuper->noteAddSubFile(sub);
+    }
+    virtual void noteRemoveSubFile(IDistributedSuperFile *super, IDistributedFile *sub)
+    {
+        CTransactionFile *trackedSuper = lookupTrackedFile(super);
+        if (trackedSuper)
+            trackedSuper->noteRemoveSubFile(sub);
+    }
+    virtual void noteSuperSwap(IDistributedSuperFile *super1, IDistributedSuperFile *super2)
+    {
+        CTransactionFile *trackedSuper1 = lookupTrackedFile(super1);
+        CTransactionFile *trackedSuper2 = lookupTrackedFile(super2);
+        assertex(trackedSuper1 && trackedSuper2);
+        ICopyArrayOf<IDistributedFile> super1Subs, super2Subs;
+        Owned<IDistributedFileIterator> iter = trackedSuper1->getSubFiles();
+        ForEach(*iter)
+            super1Subs.append(iter->query());
+        trackedSuper1->clearSubs();
+        iter.setown(trackedSuper2->getSubFiles());
+        ForEach(*iter)
+            super2Subs.append(iter->query());
+        trackedSuper2->clearSubs();
+        ForEachItemIn(s, super2Subs)
+            trackedSuper1->noteAddSubFile(&super2Subs.item(s));
+        ForEachItemIn(s2, super1Subs)
+            trackedSuper2->noteAddSubFile(&super1Subs.item(s2));
+    }
+    virtual void clearSubFiles(IDistributedSuperFile *super)
+    {
+        CTransactionFile *trackedSuper = lookupTrackedFile(super);
+        if (trackedSuper)
+            trackedSuper->clearSubs();
+    }
+    virtual void noteRename(IDistributedFile *file, const char *newName)
+    {
+        CTransactionFile *trackedFile = lookupTrackedFile(file);
+        if (trackedFile)
+        {
+            trackedFiles.removeExact(trackedFile);
+            trackedFilesByName.removeExact(trackedFile);
+            trackedFile = queryCreate(newName, file);
+        }
+    }
+    virtual void validateAddSubFile(IDistributedSuperFile *super, IDistributedFile *sub, const char *subName);
+    virtual bool isSubFile(IDistributedSuperFile *super, const char *subFile, bool sub)
+    {
+        CTransactionFile *trackedSuper = lookupTrackedFile(super);
+        if (!trackedSuper)
+            return false;
+        return trackedSuper->find(subFile, sub);
+    }
+    virtual bool addDelayedDelete(CDfsLogicalFileName &lfn,unsigned timeoutms)
     {
         delayeddelete.append(*new CDelayedDelete(lfn,udesc,timeoutms));
         return true;
     }
-    
-    void deleteFiles()      // no rollback at this point
+    virtual bool prepareActions()
     {
-        Owned<IMultiException> me = MakeMultiException("Transaction");
-        ForEachItemIn(i,delayeddelete) {
-            try {
-                delayeddelete.item(i).doDelete();
-            } catch (IException *e) {
-                me->append(*e);
-            }
+        prepared = 0;
+        unsigned toPrepare = actions.ordinality();
+        ForEachItemIn(i0,actions)
+        {
+            if (actions.item(i0).prepare())
+                ++prepared;
+            else
+                break;
         }
-        delayeddelete.kill();
-        if (me->ordinality())
-            throw me.getClear();
+        return prepared == toPrepare;
+    }
+    virtual void retryActions()
+    {
+        clearFiles(); // clear all previously tracked pending file changes, e.g. renames, super file additions/removals
+        while (prepared) // unlock for retry
+            actions.item(--prepared).retry();
+    }
+    virtual void runActions()
+    {
+        ForEachItemIn(i,actions)
+            actions.item(i).run();
+    }
+    virtual void commitAndClearup()
+    {
+        // =============== COMMIT and CLEANUP
+        commitActions();
+        clearFiles();
+        isactive = false;
+        actions.kill();
+        deleteFiles();
+    }
+    virtual ICodeContext *queryCodeContext()
+    {
+        return codeCtx;
     }
 };
 
@@ -3197,7 +3190,7 @@ protected:
                 parts.item(i1++).clearDirty();
         }
     }
-    void detach(unsigned timeoutMs=INFINITE, bool removePhysicals=true)
+    void detach(unsigned timeoutMs, bool removePhysicals, ICodeContext *ctx)
     {
         // Removes either a cluster in case of multi cluster file or the whole File entry from DFS
 
@@ -3943,13 +3936,13 @@ public:
 public:
     void detachLogical(unsigned timeoutms=INFINITE)
     {
-        detach(timeoutms, false);
+        detach(timeoutms, false, NULL);
     }
 
 public:
-    virtual void detach(unsigned timeoutMs=INFINITE)
+    virtual void detach(unsigned timeoutMs=INFINITE, ICodeContext *ctx=NULL)
     {
-        detach(timeoutMs, true);
+        detach(timeoutMs, true, ctx);
     }
 
     bool existsPhysicalPartFiles(unsigned short port)
@@ -4931,7 +4924,7 @@ protected:
     int interleaved; // 0 not interleaved, 1 interleaved old, 2 interleaved new
     IArrayOf<IDistributedFile> subfiles;
 
-    void clearSuperOwners(unsigned timeoutMs)
+    void clearSuperOwners(unsigned timeoutMs, ICodeContext *ctx)
     {
         /* JCSMORE - Why on earth is this doing this way?
          * We are in a super file, we already have [read] locks to sub files (in 'subfiles' array)
@@ -4940,7 +4933,6 @@ protected:
         Owned<IPropertyTreeIterator> iter = root->getElements("SubFile");
         StringBuffer oquery;
         oquery.append("SuperOwner[@name=\"").append(logicalName.get()).append("\"]");
-        Owned<IMultiException> exceptions = MakeMultiException("CDelayedDelete::doRemoveEntry::SuperOwners");
         ForEach(*iter)
         {
             const char *name = iter->query().queryProp("@name");
@@ -4957,13 +4949,20 @@ protected:
                     if (subfroot)
                     {
                         if (!subfroot->removeProp(oquery.str()))
-                            exceptions->append(*MakeStringException(-1, "CDelayedDelete::removeEntry: SubFile %s of %s not found for removal",name?name:"(NULL)", logicalName.get()));
+                        {
+                            VStringBuffer s("SubFile %s is not owned by SuperFile %s", name, logicalName.get());
+                            if (ctx)
+                                ctx->addWuException(s.str(), 0, SeverityWarning, "DFS[clearSuperOwner]");
+                            else
+                            {
+                                Owned<IException> e = makeStringException(-1, s.str());
+                                EXCLOG(e, "DFS[clearSuperOwner]");
+                            }
+                        }
                     }
                 }
             }
         }
-        if (exceptions->ordinality())
-            throw exceptions.getClear();
     }
 
     static StringBuffer &getSubPath(StringBuffer &path,unsigned idx)
@@ -5529,7 +5528,7 @@ public:
         loadSubFiles(NULL, 0, true);
     }
 
-    void detach(unsigned timeoutMs=INFINITE)
+    void detach(unsigned timeoutMs=INFINITE, ICodeContext *ctx=NULL)
     {   
         assertex(conn.get()); // must be attached
         CriticalBlock block(sect);
@@ -5551,7 +5550,7 @@ public:
          * 5) updateFS (housekeeping of empty scopes, relationships) - ok
          */
         CFileChangeWriteLock writeLock(conn, timeoutMs);
-        clearSuperOwners(timeoutMs);
+        clearSuperOwners(timeoutMs, ctx);
         writeLock.clear();
         root.setown(closeConnection(true));
         updateFS(logicalName, parent->queryDefaultTimeout());
@@ -7753,7 +7752,7 @@ public:
     {
         if (nestedTransaction)
             nestedTransaction->runActions();
-        super->detach();
+        super->detach(INFINITE, transaction->queryCodeContext());
     }
     virtual void commit()
     {
@@ -10692,9 +10691,9 @@ IDaliServer *createDaliDFSServer(IPropertyTree *config)
     return daliDFSServer;
 }
 
-IDistributedFileTransaction *createDistributedFileTransaction(IUserDescriptor *user)
+IDistributedFileTransaction *createDistributedFileTransaction(IUserDescriptor *user, ICodeContext *ctx)
 {
-    return new CDistributedFileTransaction(user);
+    return new CDistributedFileTransaction(user, NULL, ctx);
 }
 
 static void encodeCompareResult(DistributedFileCompareResult &ret,bool differs,CDateTime &newestdt1,CDateTime &newestdt2)

+ 3 - 3
dali/base/dadfs.hpp

@@ -300,12 +300,12 @@ interface IDistributedSuperFileIterator: extends IIteratorOf<IDistributedSuperFi
     virtual const char *queryName() = 0;
 };
 
+interface ICodeContext;
 /**
  * A distributed file, composed of one or more DistributedFileParts.
  */
 interface IDistributedFile: extends IInterface
 {
-
     virtual unsigned numParts() = 0;
     virtual IDistributedFilePart &queryPart(unsigned idx) = 0;
     virtual IDistributedFilePart* getPart(unsigned idx) = 0;
@@ -324,7 +324,7 @@ interface IDistributedFile: extends IInterface
     virtual const char *queryPartMask() = 0;                                    // default part name mask
 
     virtual void attach(const char *logicalname,IUserDescriptor *user) = 0;     // attach to name in DFS
-    virtual void detach(unsigned timeoutms=INFINITE) = 0;                       // no longer attached to name in DFS
+    virtual void detach(unsigned timeoutms=INFINITE, ICodeContext *ctx=NULL) = 0; // no longer attached to name in DFS
 
     virtual IPropertyTree &queryAttributes() = 0;                               // DFile attributes
 
@@ -779,7 +779,7 @@ extern da_decl StringBuffer &getClusterGroupName(IPropertyTree &cluster, StringB
 extern da_decl StringBuffer &getClusterSpareGroupName(IPropertyTree &cluster, StringBuffer &groupName);
 extern da_decl IGroup *getClusterNodeGroup(const char *clusterName, const char *type, unsigned timems=INFINITE);
 
-extern da_decl IDistributedFileTransaction *createDistributedFileTransaction(IUserDescriptor *user);
+extern da_decl IDistributedFileTransaction *createDistributedFileTransaction(IUserDescriptor *user, ICodeContext *ctx=NULL);
 
 extern da_decl const char *normalizeLFN(const char *s, StringBuffer &normalized);
 

+ 1 - 2
dali/base/dautils.cpp

@@ -1135,8 +1135,7 @@ bool CDfsLogicalFileName::setFromMask(const char *fname,const char *rootdir)
                             if (memicmp(fname,"_of_",4)==0) {
                                 if (!fname[4])
                                     return false;
-                                set(logicalName.str());
-                                return true;
+                                return setValidate(logicalName.str());
                             }
                         }
                     }

+ 1 - 1
docs/ECLLanguageReference/ECLR_mods/BltInFunc-DISTRIBUTE.xml

@@ -156,7 +156,7 @@
     the existing distribution of the specified <emphasis>index</emphasis>,
     where the linkage between the two is determined by the
     <emphasis>joincondition</emphasis>. Records for which the
-    <emphasis>joncondition</emphasis> is true will end up on the same
+    <emphasis>joincondition</emphasis> is true will end up on the same
     node.</para>
   </sect2>
 

+ 0 - 4
docs/Installing_and_RunningTheHPCCPlatform/Installing_and_RunningTheHPCCPlatform.xml

@@ -209,10 +209,6 @@
     </sect1>
   </chapter>
 
-  <xi:include href="Installing_and_RunningTheHPCCPlatform/Inst-Mods/Hardware.xml"
-              xpointer="Hardware-and-Software-Chapter"
-              xmlns:xi="http://www.w3.org/2001/XInclude" />
-
   <chapter id="HPCC-installation-and-startup">
     <title>HPCC Installation and Startup</title>
 

+ 1 - 1
ecl/eclagent/eclagent.cpp

@@ -3013,7 +3013,7 @@ void EclAgent::reportProgress(const char *progress, unsigned flags)
 IDistributedFileTransaction *EclAgent::querySuperFileTransaction()
 {
     if (!superfiletransaction.get())
-        superfiletransaction.setown(createDistributedFileTransaction(queryUserDescriptor()));
+        superfiletransaction.setown(createDistributedFileTransaction(queryUserDescriptor(), this));
     return superfiletransaction.get();
 }
 

+ 7 - 1
ecl/hql/hqlgram2.cpp

@@ -2881,8 +2881,14 @@ void HqlGram::releaseScopes()
 
     leftRightScopes.kill();
     
-    while (selfScopes.length()>0)
+    while (selfScopes.length() > 0)
+    {
+        //Ensure that we do not remove any scopes that are still active - otherwise they will be released too early
+        OwnedHqlExpr self = getSelfScope();
+        if (activeRecords.contains(*self))
+            break;
         popSelfScope();
+    }
     modScope.clear();
     outerScopeAccessDepth = 0;
 

+ 1 - 1
roxie/ccd/ccdcontext.cpp

@@ -3702,7 +3702,7 @@ public:
     {
         CriticalBlock b(contextCrit);
         if (!superfileTransaction.get())
-            superfileTransaction.setown(createDistributedFileTransaction(queryUserDescriptor()));
+            superfileTransaction.setown(createDistributedFileTransaction(queryUserDescriptor(), queryCodeContext()));
         return superfileTransaction.get();
     }
     virtual void flush(unsigned seqNo) { throwUnexpected(); }

+ 1 - 1
thorlcr/graph/thgraphmaster.cpp

@@ -1221,7 +1221,7 @@ public:
     virtual IDistributedFileTransaction *querySuperFileTransaction()
     {
         if (!superfiletransaction.get())
-            superfiletransaction.setown(createDistributedFileTransaction(userDesc));
+            superfiletransaction.setown(createDistributedFileTransaction(userDesc, this));
         return superfiletransaction.get();
     }
     virtual char *getJobName()

+ 1 - 1
thorlcr/graph/thgraphslave.cpp

@@ -1038,7 +1038,7 @@ public:
     {
         // NB: shouldn't really have fileservice being called on slaves
         if (!superfiletransaction.get())
-            superfiletransaction.setown(createDistributedFileTransaction(userDesc));
+            superfiletransaction.setown(createDistributedFileTransaction(userDesc, this));
         return superfiletransaction.get();
     }
     virtual void getResultStringF(unsigned tlen, char * tgt, const char * name, unsigned sequence) { throwUnexpected(); }