Merge pull request #125 from ddunbar/directory-permissions

[Basic] Introduce a FS method for creating directories.
diff --git a/lib/BuildSystem/BuildSystem.cpp b/lib/BuildSystem/BuildSystem.cpp
index 410b866..62be1e3 100644
--- a/lib/BuildSystem/BuildSystem.cpp
+++ b/lib/BuildSystem/BuildSystem.cpp
@@ -1338,7 +1338,14 @@
   /// Whether to inherit the base environment.
   bool inheritEnv = true;
 
+  /// The cached signature, once computed -- 0 is used as a sentinel value.
+  std::atomic<uint64_t> cachedSignature{ 0 };
+  
   virtual uint64_t getSignature() override {
+    uint64_t signature = cachedSignature;
+    if (signature != 0)
+      return signature;
+      
     // FIXME: Use a more appropriate hashing infrastructure.
     using llvm::hash_combine;
     llvm::hash_code code = ExternalCommand::getSignature();
@@ -1354,7 +1361,12 @@
     }
     code = hash_combine(code, int(depsStyle));
     code = hash_combine(code, int(inheritEnv));
-    return size_t(code);
+    signature = size_t(code);
+    if (signature == 0) {
+      signature = 1;
+    }
+    cachedSignature = signature;
+    return signature;
   }
 
   bool processDiscoveredDependencies(BuildSystemCommandInterface& bsci,
diff --git a/lib/BuildSystem/BuildSystemFrontend.cpp b/lib/BuildSystem/BuildSystemFrontend.cpp
index 41ebf1c..fa2afb8 100644
--- a/lib/BuildSystem/BuildSystemFrontend.cpp
+++ b/lib/BuildSystem/BuildSystemFrontend.cpp
@@ -340,10 +340,16 @@
 
 void BuildSystemFrontendDelegate::cancel() {
   // FIXME: We should audit that a build is happening.
+  if (isCancelled_) {
+    return;
+  }
   isCancelled_ = true;
 
   auto delegateImpl = static_cast<BuildSystemFrontendDelegateImpl*>(impl);
-  delegateImpl->system->cancel();
+  auto system = delegateImpl->system;
+  if (system) {
+    system->cancel();
+  }
 }
 
 void BuildSystemFrontendDelegate::resetForBuild() {