| Index: src/com/github/rjeschke/neetutils/dispose/Disposer.java |
| diff --git a/src/com/github/rjeschke/neetutils/dispose/Disposer.java b/src/com/github/rjeschke/neetutils/dispose/Disposer.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4200be1cf4e0be6b75184a1e313258131fab6d50 |
| --- /dev/null |
| +++ b/src/com/github/rjeschke/neetutils/dispose/Disposer.java |
| @@ -0,0 +1,99 @@ |
| +/* |
| + * Copyright (C) 2012 René Jeschke <rene_jeschke@yahoo.de> |
| + * |
| + * Licensed under the Apache License, Version 2.0 (the "License"); |
| + * you may not use this file except in compliance with the License. |
| + * You may obtain a copy of the License at |
| + * |
| + * http://www.apache.org/licenses/LICENSE-2.0 |
| + * |
| + * Unless required by applicable law or agreed to in writing, software |
| + * distributed under the License is distributed on an "AS IS" BASIS, |
| + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| + * See the License for the specific language governing permissions and |
| + * limitations under the License. |
| + */ |
| +package com.github.rjeschke.neetutils.dispose; |
| + |
| +import java.lang.ref.ReferenceQueue; |
| +import java.lang.ref.WeakReference; |
| + |
| +import com.github.rjeschke.neetutils.dispose.ReferenceList.Node; |
| + |
| +/** |
| + * |
| + * @author René Jeschke (rene_jeschke@yahoo.de) |
| + * |
| + */ |
| +public class Disposer extends WeakReference<Disposable> |
| +{ |
| + private final Disposable disposable; |
| + private final Node<Disposer> disposer; |
| + private volatile boolean disposed = false; |
| + final static ReferenceQueue<Disposable> refQueue; |
| + final static ReferenceList<Disposer> disposers; |
| + |
| + static |
| + { |
| + refQueue = new ReferenceQueue<Disposable>(); |
| + disposers = new ReferenceList<Disposer>(); |
| + |
| + final Thread thread = new Thread(new Cleaner()); |
| + thread.setName("neetutils-Disposer"); |
| + thread.setDaemon(true); |
| + thread.start(); |
| + } |
| + |
| + public Disposer(final Disposable referent, final Disposable disposable) |
| + { |
| + super(referent, refQueue); |
| + this.disposable = disposable; |
| + synchronized (disposers) |
| + { |
| + this.disposer = disposers.add(this); |
| + } |
| + } |
| + |
| + public void dispose() |
| + { |
| + if (!this.disposed) |
| + { |
| + synchronized (disposers) |
| + { |
| + disposers.remove(this.disposer); |
| + } |
| + this.disposed = true; |
| + this.disposable.dispose(); |
| + } |
| + } |
| + |
| + public boolean isDisposed() |
| + { |
| + return this.disposed; |
| + } |
| + |
| + private static final class Cleaner implements Runnable |
| + { |
| + public Cleaner() |
| + { |
| + // empty |
| + } |
| + |
| + @Override |
| + public void run() |
| + { |
| + final ReferenceQueue<Disposable> refQueue = Disposer.refQueue; |
| + for (;;) |
| + { |
| + try |
| + { |
| + ((Disposer)refQueue.remove()).dispose(); |
| + } |
| + catch (final Throwable t) |
| + { |
| + // |
| + } |
| + } |
| + } |
| + } |
| +} |