diff --git a/libs/Common.Utilities/src/DisposableBase.cs b/libs/Common.Utilities/src/DisposableBase.cs deleted file mode 100644 index 33da63e..0000000 --- a/libs/Common.Utilities/src/DisposableBase.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -using System; -using System.Threading; - -namespace Microsoft.MixedReality.Sharing.Utilities -{ - /// - /// This is a base class for common IDisposable implementation. - /// - /// Follows https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose - public class DisposableBase : IDisposable - { - private string objectName; - private ThreadLocal insideDisposeFunction = new ThreadLocal(() => false); - - /// - /// Is the current object disposed. - /// - public bool IsDisposed { get; private set; } - - /// - /// The name of the current object. - /// - protected virtual string ObjectName => objectName ?? (objectName = GetType().Name); - - ~DisposableBase() - { - Dispose(false); - } - - /// - /// Dispose the current object. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool isDisposing) - { - if (IsDisposed) - { - return; - } - - IsDisposed = true; - - // If the finalizer is running, don't access the insideDisposeFunction, as it will - // also be finalizing. - if (isDisposing) - { - insideDisposeFunction = null; - } - else - { - insideDisposeFunction.Value = true; - } - - try - { - if (isDisposing) - { - OnManagedDispose(); - } - - OnUnmanagedDispose(); - } - finally - { - if (insideDisposeFunction != null) - { - insideDisposeFunction.Value = false; - } - } - } - - /// - /// Override this method to dispose of managed objects. - /// - protected virtual void OnManagedDispose() { } - - /// - /// Override this method to dispose of unmanaged objects. - /// - protected virtual void OnUnmanagedDispose() { } - - /// - /// A helper method to throw if the current object is disposed. - /// - protected void ThrowIfDisposed() - { - if (insideDisposeFunction == null || (!insideDisposeFunction.Value && IsDisposed)) - { - throw new ObjectDisposedException(ObjectName); - } - } - } -} diff --git a/libs/Matchmaking/src/Peer/PeerDiscoveryAgent.cs b/libs/Matchmaking/src/Peer/PeerDiscoveryAgent.cs index 91ec21c..d204ba2 100644 --- a/libs/Matchmaking/src/Peer/PeerDiscoveryAgent.cs +++ b/libs/Matchmaking/src/Peer/PeerDiscoveryAgent.cs @@ -876,13 +876,14 @@ namespace Microsoft.MixedReality.Sharing.Matchmaking /// /// Simple discovery agent for local networks. /// - public class PeerDiscoveryAgent : DisposableBase, IDiscoveryAgent + public class PeerDiscoveryAgent : IDiscoveryAgent { /// The transport for this agent. private readonly IPeerDiscoveryTransport transport_; private Server server_; private Client client_; private Options options_; + private int disposed_ = 0; // Counts how many things (local resources or discovery tasks) are using the transport. private int transportRefCount_ = 0; @@ -950,19 +951,22 @@ namespace Microsoft.MixedReality.Sharing.Matchmaking } } - protected override void OnUnmanagedDispose() + public void Dispose() { - server_?.Stop(); - client_?.Stop(); - - // Give some time for the ByeBye message to be sent before shutting down the sockets. - // todo is there a smarter way to do this? - Task.Delay(1).Wait(); - - // Stop the network and prevent later disposals from trying to stop it again. - if (Interlocked.Exchange(ref transportRefCount_, 0) > 0) + if( Interlocked.CompareExchange(ref disposed_, 1, 0) == 0 ) { - transport_.Stop(); + server_?.Stop(); + client_?.Stop(); + + // Give some time for the ByeBye message to be sent before shutting down the sockets. + // todo is there a smarter way to do this? + Task.Delay(1).Wait(); + + // Stop the network and prevent later disposals from trying to stop it again. + if (Interlocked.Exchange(ref transportRefCount_, 0) > 0) + { + transport_.Stop(); + } } } } diff --git a/libs/SpatialAlignment/src/SpatialCoordinateServiceBase.cs b/libs/SpatialAlignment/src/SpatialCoordinateServiceBase.cs index 8e7942c..fc4ebbb 100644 --- a/libs/SpatialAlignment/src/SpatialCoordinateServiceBase.cs +++ b/libs/SpatialAlignment/src/SpatialCoordinateServiceBase.cs @@ -16,7 +16,7 @@ namespace Microsoft.MixedReality.SpatialAlignment /// Helper base class for implementations. /// /// They key for the . - public abstract class SpatialCoordinateServiceBase : DisposableBase, ISpatialCoordinateService + public abstract class SpatialCoordinateServiceBase : ISpatialCoordinateService { /// public event Action CoordinatedDiscovered; @@ -29,9 +29,19 @@ namespace Microsoft.MixedReality.SpatialAlignment private volatile bool isDiscovering = false; private volatile int discoveryOrCreateRequests = 0; + private int isDisposed = 0; + protected readonly ConcurrentDictionary knownCoordinates = new ConcurrentDictionary(); + protected void ThrowIfDisposed() + { + if (isDisposed != 0) + { + throw new ObjectDisposedException("SpatialCoordinateServiceBase"); + } + } + /// public bool IsTracking { @@ -55,15 +65,16 @@ namespace Microsoft.MixedReality.SpatialAlignment } } - protected override void OnManagedDispose() + public void Dispose() { - base.OnManagedDispose(); + if (Interlocked.CompareExchange(ref isDisposed, 1, 0) == 0) + { + // Notify of dispose to any existing operations + disposedCTS.Cancel(); + disposedCTS.Dispose(); - // Notify of dispose to any existing operations - disposedCTS.Cancel(); - disposedCTS.Dispose(); - - knownCoordinates.Clear(); + knownCoordinates.Clear(); + } } bool ISpatialCoordinateService.TryGetKnownCoordinate(string id, out ISpatialCoordinate spatialCoordinate)