/// <summary> /// This method will shutdown the node being hosted by the child process and notify the parent process if requested, /// </summary> /// <param name="shutdownLevel">What kind of shutdown is causing the child node to shutdown</param> /// <param name="exitProcess">should the child process exit as part of the shutdown process</param> /// <param name="noParentNotification">Indicates if the parent process should be notified the child node is being shutdown</param> internal void ShutdownNode(Node.NodeShutdownLevel shutdownLevel, bool exitProcess, bool noParentNotification) { if (node != null) { try { node.ShutdownNode(shutdownLevel); if (!noParentNotification) { // Write the last event out directly LocalCallDescriptorForShutdownComplete callDescriptor = new LocalCallDescriptorForShutdownComplete(shutdownLevel, node.TotalTaskTime); // Post the message indicating that the shutdown is complete engineCallback.PostMessageToParent(callDescriptor, true); } } catch (Exception e) { if (shutdownLevel != Node.NodeShutdownLevel.ErrorShutdown) { ReportNonFatalCommunicationError(e); } } } // If the shutdownLevel is not a build complete message, then this means there was a politeshutdown or an error shutdown, null the node out // as either it is no longer needed due to the node goign idle or there was a error and it is now in a bad state. if (shutdownLevel != Node.NodeShutdownLevel.BuildCompleteSuccess && shutdownLevel != Node.NodeShutdownLevel.BuildCompleteFailure) { node = null; notInUseEvent.Set(); } if (exitProcess) { // Even if we completed a build, if we are goign to exit the process we need to null out the node and set the notInUseEvent, this is // accomplished by calling this method again with the ErrorShutdown handle if (shutdownLevel == Node.NodeShutdownLevel.BuildCompleteSuccess || shutdownLevel == Node.NodeShutdownLevel.BuildCompleteFailure) { ShutdownNode(Node.NodeShutdownLevel.ErrorShutdown, false, true); } // Signal all the communication threads to exit shutdownEvent.Set(); } }
/// <summary> /// This method first reads the objectId as an int from the stream, /// this int should be found in the "ObjectType" enumeration. This /// objectId informs the method what kind of object should be /// deserialized and returned from the method. The objectId is an /// output parameter. This parameter is also returned so it can be /// used in the read and write methods to determine if /// a frame or end marker was found. /// </summary> private object DeserializeFromStream(out int objectId) { object objectRead = null; objectId = readStream.ReadByte(); switch ((ObjectType)objectId) { case ObjectType.NetSerialization: objectRead = binaryFormatter.Deserialize(readStream); break; case ObjectType.FrameMarker: objectRead = binaryReader.ReadInt32(); break; case ObjectType.PostBuildResult: objectRead = new LocalCallDescriptorForPostBuildResult(); ((LocalCallDescriptorForPostBuildResult)objectRead).CreateFromStream(binaryReader); break; case ObjectType.PostBuildRequests: objectRead = new LocalCallDescriptorForPostBuildRequests(); ((LocalCallDescriptorForPostBuildRequests)objectRead).CreateFromStream(binaryReader); break; case ObjectType.PostLoggingMessagesToHost: objectRead = new LocalCallDescriptorForPostLoggingMessagesToHost(); ((LocalCallDescriptorForPostLoggingMessagesToHost)objectRead).CreateFromStream(binaryReader, loggingTypeCache); break; case ObjectType.InitializeNode: objectRead = new LocalCallDescriptorForInitializeNode(); ((LocalCallDescriptorForInitializeNode)objectRead).CreateFromStream(binaryReader); break; case ObjectType.InitializationComplete: objectRead = new LocalCallDescriptorForInitializationComplete(); ((LocalCallDescriptorForInitializationComplete)objectRead).CreateFromStream(binaryReader); break; case ObjectType.UpdateNodeSettings: objectRead = new LocalCallDescriptorForUpdateNodeSettings(); ((LocalCallDescriptorForUpdateNodeSettings)objectRead).CreateFromStream(binaryReader); break; case ObjectType.RequestStatus: objectRead = new LocalCallDescriptorForRequestStatus(); ((LocalCallDescriptorForRequestStatus)objectRead).CreateFromStream(binaryReader); break; case ObjectType.PostCacheEntriesToHost: objectRead = new LocalCallDescriptorForPostingCacheEntriesToHost(); ((LocalCallDescriptorForPostingCacheEntriesToHost)objectRead).CreateFromStream(binaryReader); break; case ObjectType.GetCacheEntriesFromHost: objectRead = new LocalCallDescriptorForGettingCacheEntriesFromHost(); ((LocalCallDescriptorForGettingCacheEntriesFromHost)objectRead).CreateFromStream(binaryReader); break; case ObjectType.ShutdownComplete: objectRead = new LocalCallDescriptorForShutdownComplete(); ((LocalCallDescriptorForShutdownComplete)objectRead).CreateFromStream(binaryReader); break; case ObjectType.ShutdownNode: objectRead = new LocalCallDescriptorForShutdownNode(); ((LocalCallDescriptorForShutdownNode)objectRead).CreateFromStream(binaryReader); break; case ObjectType.PostIntrospectorCommand: objectRead = new LocalCallDescriptorForPostIntrospectorCommand(null, null); ((LocalCallDescriptorForPostIntrospectorCommand)objectRead).CreateFromStream(binaryReader); break; case ObjectType.GenericSingleObjectReply: objectRead = new LocalReplyCallDescriptor(); ((LocalReplyCallDescriptor)objectRead).CreateFromStream(binaryReader); break; case ObjectType.PostStatus: objectRead = new LocalCallDescriptorForPostStatus(); ((LocalCallDescriptorForPostStatus)objectRead).CreateFromStream(binaryReader); break; case ObjectType.EndMarker: return(null); default: ErrorUtilities.VerifyThrow(false, "Should not be here, ObjectId:" + objectId + "Next:" + readStream.ReadByte()); break; } return(objectRead); }