/** * Converts an native job specification to a managed version. * * @param Specification Native job specification (may be empty) * @param bIs64bit Whether the job specification is 64-bit or not * @return Newly created managed job specification, or null if the specification was empty */ AgentJobSpecification ConvertJobSpecification(ref FJobSpecification Specification, bool bIs64bit) { if (Specification.ExecutableName == null) { return null; } else { // Convert the parameters from native to managed String ExecutableName = Specification.ExecutableName; String Parameters = Specification.Parameters; EJobTaskFlags Flags = (EJobTaskFlags)((Specification.Flags & ~EJobTaskFlags.FLAG_64BIT) | (bIs64bit ? EJobTaskFlags.FLAG_64BIT : 0)); List<String> RequiredDependencies = null; if (Specification.RequiredDependencyCount > 0) { RequiredDependencies = new List<String>(); for (UInt32 i = 0; i < Specification.RequiredDependencyCount; i++) { RequiredDependencies.Add(Specification.RequiredDependencies[i]); } } List<String> OptionalDependencies = null; if (Specification.OptionalDependencyCount > 0) { OptionalDependencies = new List<String>(); for (UInt32 i = 0; i < Specification.OptionalDependencyCount; i++) { OptionalDependencies.Add(Specification.OptionalDependencies[i]); } } return new AgentJobSpecification(ConnectionConfiguration.AgentJobGuid, (EJobTaskFlags)Flags, ExecutableName, Parameters, RequiredDependencies, OptionalDependencies); } }
static FJobSpecification MarshalJobSpecification(IntPtr SpecificationPtr) { FJobSpecificationMarshalHelper Helper = (FJobSpecificationMarshalHelper)Marshal.PtrToStructure(SpecificationPtr, typeof(FJobSpecificationMarshalHelper)); FJobSpecification Specification = new FJobSpecification(); Specification.ExecutableName = FStringMarshaler.MarshalNativeToManaged(Helper.ExecutableName); Specification.Parameters = FStringMarshaler.MarshalNativeToManaged(Helper.Parameters); Specification.Flags = Helper.Flags; Specification.RequiredDependencyCount = Helper.RequiredDependencyCount; Specification.RequiredDependencies = new String[Specification.RequiredDependencyCount]; for (UInt32 Index = 0; Index < Specification.RequiredDependencyCount; Index++) { Specification.RequiredDependencies[Index] = FStringMarshaler.MarshalNativeToManaged(Marshal.ReadIntPtr(Helper.RequiredDependencies, (Int32)Index * 8)); } Specification.OptionalDependencyCount = Helper.OptionalDependencyCount; Specification.OptionalDependencies = new String[Specification.OptionalDependencyCount]; for (UInt32 Index = 0; Index < Specification.OptionalDependencyCount; Index++) { Specification.OptionalDependencies[Index] = FStringMarshaler.MarshalNativeToManaged(Marshal.ReadIntPtr(Helper.OptionalDependencies, (Int32)Index * 8)); } Specification.DescriptionCount = Helper.DescriptionCount; Specification.DescriptionKeys = new String[Specification.DescriptionCount]; Specification.DescriptionValues = new String[Specification.DescriptionCount]; for (UInt32 Index = 0; Index < Specification.DescriptionCount; Index++) { Specification.DescriptionKeys[Index] = FStringMarshaler.MarshalNativeToManaged(Marshal.ReadIntPtr(Helper.DescriptionKeys, (Int32)Index * 8)); Specification.DescriptionValues[Index] = FStringMarshaler.MarshalNativeToManaged(Marshal.ReadIntPtr(Helper.DescriptionValues, (Int32)Index * 8)); } return Specification; }
/** * Begins a Job specification, which allows a series of Tasks to be specified * via AddTask. When Tasks are done being specified, call EndJobSpecification. * * The default behavior will be to execute the Job executable with the * specified parameters. If Tasks are added for the Job, they are expected * to be requested by the executable run for the Job. If no Tasks are added * for the Job, it is expected that the Job executable will perform its * operations without additional Task input from Swarm. * * @param Specification32 A structure describing a new 32-bit Job (can be an empty specification) * @param Specification64 A structure describing a new 64-bit Job (can be an empty specification) * * @return Int32 Error code (< 0 is an error) */ public virtual Int32 BeginJobSpecification(FJobSpecification Specification32, FJobSpecification Specification64) { StartTiming("BeginJobSpecification-Managed", true ); Int32 ReturnValue = Constants.INVALID; if (Connection != null) { if (ConnectionConfiguration.AgentJobGuid != null) { // Convert the specifications from native to managed AgentJobSpecification NewSpecification32 = ConvertJobSpecification(ref Specification32, false); AgentJobSpecification NewSpecification64 = ConvertJobSpecification(ref Specification64, true); // Ensure all the files are in the cache with the right cache compatible name if (NewSpecification32 != null) { ReturnValue = CacheAllFiles(NewSpecification32); } if (NewSpecification64 != null && (NewSpecification32 == null || ReturnValue < 0)) { ReturnValue = CacheAllFiles(NewSpecification64); } if (ReturnValue >= 0) { // Pack up the optional descriptions into Hashtables and pass them along UInt32 DescriptionIndex; Hashtable NewDescription32 = null; Hashtable NewDescription64 = null; // 32-bit specification description if (Specification32.DescriptionCount > 0) { try { NewDescription32 = new Hashtable(); NewDescription32["Version"] = ESwarmVersionValue.VER_1_0; for (DescriptionIndex = 0; DescriptionIndex < Specification32.DescriptionCount; DescriptionIndex++) { String NewKey = Specification32.DescriptionKeys[DescriptionIndex]; String NewValue = Specification32.DescriptionValues[DescriptionIndex]; NewDescription32[NewKey] = NewValue; } } catch (Exception Ex) { // Failed to transfer optional description, log and continue Log(EVerbosityLevel.Critical, ELogColour.Red, "[Interface:BeginJobSpecification] Error with Specification32 Description: " + Ex.Message); NewDescription32 = null; } } // 64-bit specification description if (Specification64.DescriptionCount > 0) { try { NewDescription64 = new Hashtable(); NewDescription64["Version"] = ESwarmVersionValue.VER_1_0; for (DescriptionIndex = 0; DescriptionIndex < Specification64.DescriptionCount; DescriptionIndex++) { String NewKey = Specification64.DescriptionKeys[DescriptionIndex]; String NewValue = Specification64.DescriptionValues[DescriptionIndex]; NewDescription64[NewKey] = NewValue; } } catch (Exception Ex) { // Failed to transfer optional description, log and continue Log(EVerbosityLevel.Critical, ELogColour.Red, "[Interface:BeginJobSpecification] Error with Specification64 Description: " + Ex.Message); NewDescription64 = null; } } StartTiming("BeginJobSpecification-Remote", false); try { ReturnValue = Connection.BeginJobSpecification(ConnectionHandle, NewSpecification32, NewDescription32, NewSpecification64, NewDescription64); } catch (Exception Ex) { Log(EVerbosityLevel.Critical, ELogColour.Red, "[Interface:BeginJobSpecification] Error: " + Ex.Message); ReturnValue = Constants.ERROR_CONNECTION_DISCONNECTED; CleanupClosedConnection(); } StopTiming(); } } else { ReturnValue = Constants.ERROR_JOB_NOT_FOUND; } } else { ReturnValue = Constants.ERROR_CONNECTION_NOT_FOUND; } StopTiming(); return ReturnValue; }