/// <summary> /// Creates a new mutable from a live pip /// </summary> public static MutablePipState Create(Pip pip) { Contract.Requires(pip != null); Contract.Assert(PipState.Ignored == 0); MutablePipState mutable; switch (pip.PipType) { case PipType.Ipc: var pipAsIpc = (IpcPip)pip; var serviceKind = pipAsIpc.IsServiceFinalization ? ServicePipKind.ServiceFinalization : pipAsIpc.ServicePipDependencies.Any() ? ServicePipKind.ServiceClient : ServicePipKind.None; var serviceInfo = new ServiceInfo(serviceKind, pipAsIpc.ServicePipDependencies); mutable = new ProcessMutablePipState(pip.PipType, pip.SemiStableHash, default(PageableStoreId), serviceInfo, Process.Options.IsLight, default(RewritePolicy), AbsolutePath.Invalid, Process.MinPriority, pip.Provenance.ModuleId); break; case PipType.Process: var pipAsProcess = (Process)pip; mutable = new ProcessMutablePipState( pip.PipType, pip.SemiStableHash, default(PageableStoreId), pipAsProcess.ServiceInfo, pipAsProcess.ProcessOptions, pipAsProcess.RewritePolicy, pipAsProcess.Executable.Path, pipAsProcess.Priority, pipAsProcess.Provenance.ModuleId, pipAsProcess.PreserveOutputsTrustLevel); break; case PipType.CopyFile: var pipAsCopy = (CopyFile)pip; mutable = new CopyMutablePipState(pip.PipType, pip.SemiStableHash, default(PageableStoreId), pipAsCopy.OutputsMustRemainWritable); break; case PipType.SealDirectory: SealDirectoryKind sealDirectoryKind = default; bool scrub = false; var seal = (SealDirectory)pip; if (seal != null) { sealDirectoryKind = seal.Kind; scrub = seal.Scrub; } mutable = new SealDirectoryMutablePipState(pip.PipType, pip.SemiStableHash, default(PageableStoreId), sealDirectoryKind, seal.Patterns, seal.IsComposite, scrub, seal.ContentFilter); break; default: mutable = new MutablePipState(pip.PipType, pip.SemiStableHash, default(PageableStoreId)); break; } mutable.m_weakPip = new WeakReference <Pip>(pip); return(mutable); }
/// <summary> /// Adds <paramref name="pip"/> and <paramref name="mutable"/> for serialization. /// </summary> public void ScheduleSerialization(Pip pip, MutablePipState mutable) { if (!m_nonSerializedDebug) { m_serializationQueue.Post(new QueueItem { Pip = pip, Mutable = mutable }); } else { // Test code! The pips are not serialized. Instead we store them in a list to prevent GC from collecting them. lock (m_nonSerializablePips) { m_nonSerializablePips.Add(pip); } } }
private void ProcessQueueItem(Pip pip, MutablePipState pipState) { ExceptionUtilities.HandleRecoverableIOException( () => { var start = Stopwatch.GetTimestamp(); PageableStoreId value = m_store.Write(writer => ((PipWriter)writer).Write(pip)); #if DEBUG m_store.Read <Pip>(value, reader => ((PipReader)reader).ReadPip()); #endif pipState.StoreId = value; GC.KeepAlive(pip); // Pip must not get GCed until after StoreId has been set. var end = Stopwatch.GetTimestamp(); Interlocked.Add(ref m_writeTicks, end - start); Interlocked.Increment(ref m_writes); }, ex => ExceptionHandling.OnFatalException(ex)); }