public void TestWeakReferenceLifetime() { var target = new DisposableObject(); var reference = new ReferenceCountedDisposable <DisposableObject>(target); var weakReference = new ReferenceCountedDisposable <DisposableObject> .WeakReference(reference); var reference2 = reference.TryAddReference(); Assert.NotNull(reference2); reference.Dispose(); // TryAddReference fails after dispose for a counted reference Assert.Null(reference.TryAddReference()); Assert.NotNull(reference2.Target); Assert.False(target.IsDisposed); // However, a WeakReference created from the disposed reference can still add a reference var reference3 = weakReference.TryAddReference(); Assert.NotNull(reference3); reference2.Dispose(); Assert.False(target.IsDisposed); reference3.Dispose(); Assert.True(target.IsDisposed); }
public bool TryGetTelemetryId(out Guid telemetryId) { telemetryId = default; using var state = _state.TryAddReference(); if (state is null) { return(false); } var workspace = state.Target.Workspace; if (workspace == null) { return(false); } var documentId = workspace.GetDocumentIdInCurrentContext(state.Target.SubjectBuffer.AsTextContainer()); if (documentId == null) { return(false); } var project = workspace.CurrentSolution.GetProject(documentId.ProjectId); if (project == null) { return(false); } switch (project.Language) { case LanguageNames.CSharp: telemetryId = s_CSharpSourceGuid; return(true); case LanguageNames.VisualBasic: telemetryId = s_visualBasicSourceGuid; return(true); case "Xaml": telemetryId = s_xamlSourceGuid; return(true); default: return(false); } }
public override async Task <Connection> TryCreateConnectionAsync(string serviceName, object callbackTarget, CancellationToken cancellationToken) { // get stream from service hub to communicate service specific information // this is what consumer actually use to communicate information var serviceStream = await RequestServiceAsync(_hubClient, serviceName, _hostGroup, _timeout, cancellationToken).ConfigureAwait(false); return(new JsonRpcConnection(callbackTarget, serviceStream, _remotableDataRpc.TryAddReference())); }
public void TestTryAddReferenceFailsAfterDispose2() { var target = new DisposableObject(); var reference = new ReferenceCountedDisposable <DisposableObject>(target); // TryAddReference succeeds before dispose var reference2 = reference.TryAddReference(); Assert.NotNull(reference2); reference.Dispose(); // TryAddReference fails after dispose, even if another instance is alive Assert.Null(reference.TryAddReference()); Assert.NotNull(reference2.Target); Assert.False(target.IsDisposed); }
/// <summary> /// Caller is responsible for disposing the returned stream. /// multiple call of this will not increase VM. /// </summary> public Stream CreateReadableStream() { // Note: TryAddReference behaves according to its documentation even if the target object has been // disposed. If it returns non-null, then the object will not be disposed before the returned // reference is disposed (see comments on _memoryMappedFile and TryAddReference). var streamAccessor = _weakReadAccessor.TryAddReference(); if (streamAccessor == null) { var rawAccessor = RunWithCompactingGCFallback(
public void TestTryAddReferenceFailsAfterDispose() { var target = new DisposableObject(); var reference = new ReferenceCountedDisposable <DisposableObject>(target); reference.Dispose(); Assert.Null(reference.TryAddReference()); }
public void TestWeakReferenceCannotBeCreatedFromDisposedReference_NoPriorWeakReference() { var target = new DisposableObject(); var reference = new ReferenceCountedDisposable <DisposableObject>(target); var secondReference = reference.TryAddReference(); Assert.NotNull(secondReference); reference.Dispose(); var weakReference = new ReferenceCountedDisposable <DisposableObject> .WeakReference(reference); Assert.Null(weakReference.TryAddReference()); }
public void TestOutOfOrderDispose() { var target = new DisposableObject(); var reference = new ReferenceCountedDisposable <DisposableObject>(target); var reference2 = reference.TryAddReference(); var reference3 = reference2.TryAddReference(); reference2.Dispose(); Assert.False(target.IsDisposed); reference3.Dispose(); Assert.False(target.IsDisposed); reference.Dispose(); Assert.True(target.IsDisposed); Assert.Equal(1, target.DisposeCount); }
private async Task <Connection> TryCreateNewConnectionAsync(string serviceName, object callbackTarget, CancellationToken cancellationToken) { var dataRpc = _remotableDataRpc.TryAddReference(); if (dataRpc == null) { // dataRpc is disposed. this can happen if someone killed remote host process while there is // no other one holding the data connection. // in those error case, don't crash but return null. this method is TryCreate since caller expects it to return null // on such error situation. return(null); } // get stream from service hub to communicate service specific information // this is what consumer actually use to communicate information var serviceStream = await Connections.RequestServiceAsync(_hubClient, serviceName, _hostGroup, _timeout, cancellationToken).ConfigureAwait(false); return(new JsonRpcConnection(_hubClient.Logger, callbackTarget, serviceStream, dataRpc)); }
public void TestWeakReferenceCannotBeCreatedFromDisposedReference_WithPriorWeakReference() { var target = new DisposableObject(); var reference = new ReferenceCountedDisposable <DisposableObject>(target); // Create an initial weak reference at a point where the reference is alive. This ensures the internal // shared WeakReference<T> is initialized. var weakReference = new ReferenceCountedDisposable <DisposableObject> .WeakReference(reference); Assert.NotNull(weakReference.TryAddReference()); var secondReference = reference.TryAddReference(); Assert.NotNull(secondReference); reference.Dispose(); var secondWeakReference = new ReferenceCountedDisposable <DisposableObject> .WeakReference(reference); Assert.Null(secondWeakReference.TryAddReference()); }
/// <summary> /// Allocate shared storage of a specified size. /// </summary> /// <remarks> /// <para>"Small" requests are fulfilled from oversized memory mapped files which support several individual /// storage units. Larger requests are allocated in their own memory mapped files.</para> /// </remarks> /// <param name="size">The size of the shared storage block to allocate.</param> /// <returns>A <see cref="MemoryMappedInfo"/> describing the allocated block.</returns> private MemoryMappedInfo CreateTemporaryStorage(long size) { if (size >= SingleFileThreshold) { // Larger blocks are allocated separately var mapName = CreateUniqueName(size); var storage = MemoryMappedFile.CreateNew(mapName, size); return(new MemoryMappedInfo(new ReferenceCountedDisposable <MemoryMappedFile>(storage), mapName, offset: 0, size: size)); } lock (_gate) { // Obtain a reference to the memory mapped file, creating one if necessary. If a reference counted // handle to a memory mapped file is obtained in this section, it must either be disposed before // returning or returned to the caller who will own it through the MemoryMappedInfo. var reference = _weakFileReference.TryAddReference(); if (reference == null || _offset + size > _fileSize) { var mapName = CreateUniqueName(MultiFileBlockSize); var file = MemoryMappedFile.CreateNew(mapName, MultiFileBlockSize); reference = new ReferenceCountedDisposable <MemoryMappedFile>(file); _weakFileReference = new ReferenceCountedDisposable <MemoryMappedFile> .WeakReference(reference); _name = mapName; _fileSize = MultiFileBlockSize; _offset = size; return(new MemoryMappedInfo(reference, _name, offset: 0, size: size)); } else { // Reserve additional space in the existing storage location Contract.ThrowIfNull(_name); _offset += size; return(new MemoryMappedInfo(reference, _name, _offset - size, size)); } } }
private async Task <Connection?> TryCreateNewConnectionAsync(string serviceName, object?callbackTarget, CancellationToken cancellationToken) { var dataRpc = _remotableDataRpc.TryAddReference(); if (dataRpc == null) { // TODO: If we used multiplex stream we wouldn't get to this state and we could always assume to have a connection // unless the service process stops working, in which case we should report an error and ask user to restart VS // (https://github.com/dotnet/roslyn/issues/40146) // // dataRpc is disposed. this can happen if someone killed remote host process while there is // no other one holding the data connection. // in those error case, don't crash but return null. this method is TryCreate since caller expects it to return null // on such error situation. return(null); } // get stream from service hub to communicate service specific information // this is what consumer actually use to communicate information var serviceStream = await Connections.RequestServiceAsync(dataRpc.Target.Workspace, _hubClient, serviceName, _hostGroup, _timeout, cancellationToken).ConfigureAwait(false); return(new JsonRpcConnection(_hubClient.Logger, callbackTarget, serviceStream, dataRpc)); }
public static IChecksummedPersistentStorage AddReferenceCountToAndCreateWrapper(ReferenceCountedDisposable <IChecksummedPersistentStorage> storage) { return(new PersistentStorageReferenceCountedDisposableWrapper(storage.TryAddReference())); }
public ReferenceCountedDisposable <ISaveDataExtraDataAccessor> Lock() { return(_accessor.TryAddReference()); }
public static IChecksummedPersistentStorage AddReferenceCountToAndCreateWrapper(ReferenceCountedDisposable <IChecksummedPersistentStorage> storage) { // This should only be called from a caller that has a non-null storage that it // already has a reference on. So .TryAddReference cannot fail. return(new PersistentStorageReferenceCountedDisposableWrapper(storage.TryAddReference() ?? throw ExceptionUtilities.Unreachable)); }