Merge pull request #304 from BenchR267/feature/39798231-add-pid-to-extended-result

Added process identifier to command_extended_result
diff --git a/include/llbuild/Basic/CrossPlatformCompatibility.h b/include/llbuild/Basic/CrossPlatformCompatibility.h
new file mode 100644
index 0000000..567f836
--- /dev/null
+++ b/include/llbuild/Basic/CrossPlatformCompatibility.h
@@ -0,0 +1,33 @@
+//===- PlatformUtility.h ----------------------------------------*- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines cross platform definitions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CrossPlatformCompatibility_h
+#define CrossPlatformCompatibility_h
+
+#ifdef _MSC_VER
+typedef int llbuild_pid_t;
+#else
+
+#if defined(__linux__) || defined(__GNU__)
+#include <termios.h>
+#else
+#include <sys/types.h>
+#endif
+
+typedef pid_t llbuild_pid_t;
+#endif
+
+#endif /* CrossPlatformCompatibility_h */
diff --git a/include/llbuild/BuildSystem/CommandResult.h b/include/llbuild/BuildSystem/CommandResult.h
index ec46b8d..665ae80 100644
--- a/include/llbuild/BuildSystem/CommandResult.h
+++ b/include/llbuild/BuildSystem/CommandResult.h
@@ -13,6 +13,7 @@
 #ifndef LLBUILD_BUILDSYSTEM_COMMAND_RESULT_H
 #define LLBUILD_BUILDSYSTEM_COMMAND_RESULT_H
 
+#include "llbuild/Basic/CrossPlatformCompatibility.h"
 #include <inttypes.h>
 
 namespace llbuild {
@@ -31,23 +32,23 @@
   CommandResult result; /// The final status of the command
   int exitStatus;       /// The exit code
 
-  uint64_t utime;       /// User time (in us)
-  uint64_t stime;       /// Sys time (in us)
-  uint64_t maxrss;      /// Max RSS (in bytes)
+  uint64_t utime;     /// User time (in us)
+  uint64_t stime;     /// Sys time (in us)
+  uint64_t maxrss;    /// Max RSS (in bytes)
+  llbuild_pid_t pid;  /// Process identifier (can be -1 for failure reasons)
 
-
-  CommandExtendedResult(CommandResult result, int exitStatus, uint64_t utime = 0,
+  CommandExtendedResult(CommandResult result, int exitStatus, llbuild_pid_t pid, uint64_t utime = 0,
                 uint64_t stime = 0, uint64_t maxrss = 0)
-    : result(result), exitStatus(exitStatus)
-    , utime(utime), stime(stime), maxrss(maxrss)
+    : result(result), exitStatus(exitStatus), utime(utime)
+    , stime(stime), maxrss(maxrss), pid(pid)
   {}
 
   static CommandExtendedResult makeFailed(int exitStatus = -1) {
-    return CommandExtendedResult(CommandResult::Failed, exitStatus);
+    return CommandExtendedResult(CommandResult::Failed, exitStatus, -1);
   }
 
   static CommandExtendedResult makeCancelled(int exitStatus = -1) {
-    return CommandExtendedResult(CommandResult::Cancelled, exitStatus);
+    return CommandExtendedResult(CommandResult::Cancelled, exitStatus, -1);
   }
 
 };
diff --git a/lib/BuildSystem/LaneBasedExecutionQueue.cpp b/lib/BuildSystem/LaneBasedExecutionQueue.cpp
index 8cc82ee..13e641a 100644
--- a/lib/BuildSystem/LaneBasedExecutionQueue.cpp
+++ b/lib/BuildSystem/LaneBasedExecutionQueue.cpp
@@ -14,6 +14,7 @@
 
 #include "POSIXEnvironment.h"
 
+#include "llbuild/Basic/CrossPlatformCompatibility.h"
 #include "llbuild/Basic/LLVM.h"
 #include "llbuild/Basic/PlatformUtility.h"
 #include "llbuild/Basic/Tracing.h"
@@ -133,7 +134,7 @@
   bool shutdown { false };
   
   /// The set of spawned processes to terminate if we get cancelled.
-  std::unordered_map<pid_t, ProcessInfo> spawnedProcesses;
+  std::unordered_map<llbuild_pid_t, ProcessInfo> spawnedProcesses;
   std::mutex spawnedProcessesMutex;
 
   /// Management of cancellation and SIGKILL escalation
@@ -460,7 +461,7 @@
     }
       
     // Spawn the command.
-    pid_t pid = -1;
+    llbuild_pid_t pid = -1;
     bool wasCancelled;
     {
       // We need to hold the spawn processes lock when we spawn, to ensure that
@@ -568,7 +569,7 @@
     // Notify of the process completion.
     bool cancelled = WIFSIGNALED(status) && (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGKILL);
     CommandResult commandResult = cancelled ? CommandResult::Cancelled : (status == 0) ? CommandResult::Succeeded : CommandResult::Failed;
-    CommandExtendedResult extendedResult(commandResult, status, utime, stime,
+    CommandExtendedResult extendedResult(commandResult, status, pid, utime, stime,
                                          usage.ru_maxrss);
     getDelegate().commandProcessFinished(context.job.getForCommand(), handle,
                                          extendedResult);
diff --git a/lib/Commands/NinjaBuildCommand.cpp b/lib/Commands/NinjaBuildCommand.cpp
index 5e73cd0..8557bb9 100644
--- a/lib/Commands/NinjaBuildCommand.cpp
+++ b/lib/Commands/NinjaBuildCommand.cpp
@@ -13,15 +13,19 @@
 #include "NinjaBuildCommand.h"
 
 #include "llbuild/Basic/Compiler.h"
+#include "llbuild/Basic/CrossPlatformCompatibility.h"
 #include "llbuild/Basic/FileInfo.h"
 #include "llbuild/Basic/Hashing.h"
 #include "llbuild/Basic/PlatformUtility.h"
 #include "llbuild/Basic/SerialQueue.h"
 #include "llbuild/Basic/Version.h"
+
 #include "llbuild/Commands/Commands.h"
+
 #include "llbuild/Core/BuildDB.h"
 #include "llbuild/Core/BuildEngine.h"
 #include "llbuild/Core/MakefileDepsParser.h"
+
 #include "llbuild/Ninja/ManifestLoader.h"
 
 #include "llvm/ADT/SmallString.h"
@@ -484,7 +488,7 @@
   struct sigaction previousSigintHandler;
 
   /// The set of spawned processes to cancel when interrupted.
-  std::unordered_set<pid_t> spawnedProcesses;
+  std::unordered_set<llbuild_pid_t> spawnedProcesses;
   std::mutex spawnedProcessesMutex;
 
   /// Low-level flag for when a SIGINT has been received.
@@ -505,7 +509,7 @@
   void sendSignalToProcesses(int signal) {
     std::unique_lock<std::mutex> lock(spawnedProcessesMutex);
 
-    for (pid_t pid: spawnedProcesses) {
+    for (llbuild_pid_t pid: spawnedProcesses) {
       // We are killing the whole process group here, this depends on us
       // spawning each process in its own group earlier.
       ::kill(-pid, signal);
@@ -1254,7 +1258,7 @@
       args[3] = nullptr;
 
       // Spawn the command.
-      pid_t pid;
+      llbuild_pid_t pid;
       {
         // We need to hold the spawn processes lock when we spawn, to ensure that
         // we don't create a process in between when we are cancelled.
diff --git a/llbuild.xcodeproj/project.pbxproj b/llbuild.xcodeproj/project.pbxproj
index 0446a8e..0b1888f 100644
--- a/llbuild.xcodeproj/project.pbxproj
+++ b/llbuild.xcodeproj/project.pbxproj
@@ -868,6 +868,7 @@
 		9DB0478B1DF9D3E2006CDF52 /* LaneBasedExecutionQueueTest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LaneBasedExecutionQueueTest.cpp; sourceTree = "<group>"; };
 		9DB047A81DF9D43D006CDF52 /* BuildSystemTests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = BuildSystemTests; sourceTree = BUILT_PRODUCTS_DIR; };
 		9DDD8BDF1DDCAB9A00FB62D2 /* SQLiteBuildDBTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLiteBuildDBTest.cpp; sourceTree = "<group>"; };
+		B563CEA620A6252500276198 /* CrossPlatformCompatibility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CrossPlatformCompatibility.h; sourceTree = "<group>"; };
 		BC8DEEFF2030088600E9EF0C /* libllbuildSwift.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libllbuildSwift.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		BC8DEF0520300AAF00E9EF0C /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; tabWidth = 2; };
 		BC8DEF0620300AAF00E9EF0C /* BuildSystemBindings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BuildSystemBindings.swift; sourceTree = "<group>"; };
@@ -1829,6 +1830,7 @@
 			children = (
 				E120B9EF1E4E65FC00B28469 /* BinaryCoding.h */,
 				E182BE111ABA2B8D001840AD /* Compiler.h */,
+				B563CEA620A6252500276198 /* CrossPlatformCompatibility.h */,
 				E11470901B75160400ED84CF /* FileInfo.h */,
 				E138129C1C536CFC000092C0 /* FileSystem.h */,
 				E147DEFD1BA81D0E0032D08E /* Hashing.h */,
diff --git a/products/libllbuild/BuildSystem-C-API.cpp b/products/libllbuild/BuildSystem-C-API.cpp
index f60a059..50dea92 100644
--- a/products/libllbuild/BuildSystem-C-API.cpp
+++ b/products/libllbuild/BuildSystem-C-API.cpp
@@ -378,6 +378,7 @@
       llb_buildsystem_command_extended_result_t result;
       result.result = get_command_result(commandResult.result);
       result.exit_status = commandResult.exitStatus;
+      result.pid = commandResult.pid;
       result.utime = commandResult.utime;
       result.stime = commandResult.stime;
       result.maxrss = commandResult.maxrss;
diff --git a/products/libllbuild/include/llbuild/buildsystem.h b/products/libllbuild/include/llbuild/buildsystem.h
index c9ef101..8c0dd25 100644
--- a/products/libllbuild/include/llbuild/buildsystem.h
+++ b/products/libllbuild/include/llbuild/buildsystem.h
@@ -24,6 +24,19 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#ifdef _MSC_VER
+typedef int llbuild_pid_t;
+#else
+
+#if defined(__linux__) || defined(__GNU__)
+#include <termios.h>
+#else
+#include <sys/types.h>
+#endif
+
+typedef pid_t llbuild_pid_t;
+#endif
+
 /// @name File System Behaviors
 /// @{
 
@@ -102,6 +115,7 @@
   uint64_t utime;                           /// User time (in us)
   uint64_t stime;                           /// Sys time (in us)
   uint64_t maxrss;                          /// Max RSS (in bytes)
+  llbuild_pid_t pid;                        /// The process identifier (-1 if process creation failed)
 } llb_buildsystem_command_extended_result_t;
 
 /// Status change event kinds.
diff --git a/products/llbuildSwift/BuildSystemBindings.swift b/products/llbuildSwift/BuildSystemBindings.swift
index a0b0bb1..52522f8 100644
--- a/products/llbuildSwift/BuildSystemBindings.swift
+++ b/products/llbuildSwift/BuildSystemBindings.swift
@@ -240,7 +240,7 @@
     public let stime: UInt64         /// Sys time (in us)
     public let maxRSS: UInt64        /// Max RSS (in bytes)
 
-    init(utime: UInt64, stime: UInt64, maxRSS: UInt64) {
+    public init(utime: UInt64, stime: UInt64, maxRSS: UInt64) {
         self.utime = utime
         self.stime = stime
         self.maxRSS = maxRSS
@@ -251,11 +251,17 @@
 public struct CommandExtendedResult {
     public let result: CommandResult    /// The result of a command execution
     public let exitStatus: Int32        /// The exit code
+    public let pid: llbuild_pid_t?      /// The process identifier (nil if failed to create a process)
     public let metrics: CommandMetrics? /// Metrics about the executed command
 
     init(_ result: UnsafePointer<llb_buildsystem_command_extended_result_t>) {
         self.result = CommandResult(result.pointee.result)
         self.exitStatus = result.pointee.exit_status
+        if result.pointee.pid >= 0 {
+            self.pid = result.pointee.pid
+        } else {
+            self.pid = nil
+        }
         switch self.result {
         case .succeeded, .failed:
             self.metrics = CommandMetrics(utime: result.pointee.utime, stime: result.pointee.stime, maxRSS: result.pointee.maxrss)
@@ -264,11 +270,13 @@
         }
     }
 
-    public init(result: CommandResult, exitStatus: Int32) {
+    public init(result: CommandResult, exitStatus: Int32, pid: llbuild_pid_t?, metrics: CommandMetrics? = nil) {
         self.result = result
         self.exitStatus = exitStatus
-        self.metrics = nil
+        self.pid = pid
+        self.metrics = metrics
     }
+
 }
 
 /// Status change event kinds.