Пример #1
0
        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);
                }
            }
Пример #3
0
        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()));
        }
Пример #4
0
        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);
        }
Пример #5
0
            /// <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(
Пример #6
0
        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());
        }
Пример #8
0
        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));
                    }
                }
            }
Пример #12
0
            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));
            }
Пример #13
0
 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));
 }