/* * Process Hacker - * disposable object base functionality * * Copyright (C) 2009 wj32 * * This file is part of Process Hacker. * * Process Hacker is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Process Hacker is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Process Hacker. If not, see . */ using System; namespace ProcessHacker.Common { /// /// Provides methods for managing a disposable object or resource. /// public abstract class DisposableObject : IDisposable, IReferenceCountedObject { private bool _owned = true; private int _refCount = 1; private bool _disposed = false; /// /// Initializes a disposable object. /// public DisposableObject() : this(true) { } /// /// Initializes a disposable object. /// /// Whether the resource is owned. public DisposableObject(bool owned) { _owned = owned; // Don't need to finalize the object if it doesn't need to be disposed. if (!_owned) GC.SuppressFinalize(this); } /// /// Frees the resources associated with the object. /// ~DisposableObject() { this.Dispose(false); } /// /// Decrements the reference count of the object. /// public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } /// /// Decrements the reference count of the object. /// /// Whether to dispose managed resources. public void Dispose(bool disposing) { _refCount--; if (_refCount < 0) _refCount = 0; if (!_disposed && _refCount == 0 && _owned) { this.DisposeObject(disposing); _disposed = true; } } /// /// Disposes the resources of the object. This method must not be /// called directly; instead, override this method in a derived class. /// /// Whether or not to dispose managed objects. protected virtual void DisposeObject(bool disposing) { } /// /// Gets whether the object is freed. /// public bool Disposed { get { return _disposed; } } /// /// Gets whether the object can be freed. /// public bool Owned { get { return _owned; } } /// /// Gets the current reference count of the object. /// public int ReferenceCount { get { return _refCount; } } /// /// Decrements the reference count of the object. /// /// The old reference count. public int Dereference() { return this.Dereference(true); } /// /// Decrements the reference count of the object. /// /// Whether to dispose managed resources. /// The old reference count. public int Dereference(bool managed) { if (!_owned) return 0; if (_refCount == 0) throw new InvalidOperationException("Reference count cannot be negative."); this.Dispose(managed); return _refCount; } /// /// Increments the reference count of the object. /// /// The old reference count. public int Reference() { if (!_owned) return 0; int oldRefCount = _refCount; _refCount++; return oldRefCount; } } }