blob: 680a54e81dd5dc9df6d2862a9eb004fda5995f0d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Hisashi MIYASHITA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.util.win32.comclutch;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
/**
* ResourceManager treats the life cycle of the native resources. All resources
* are wrapped by Java object, so the resources can be managed by the garbage
* collection system.
*/
public class ResourceManager {
private final ResourceManager parent;
private ArrayList<ResourceManager> childRMs;
private static final int HASHSIZE = (1 << 13) - 1; // Mersenne 5.
private WeakReference<IResource> resourceHashArray[] = new WeakReference[HASHSIZE];
/**
* @param ptr
* the reference pointer to be searched
* @return the instance of IResource having ptr. It returns null if resource
* is not found.
*/
public IResource findInResource(long ptr) {
int idx = (int) ptr % HASHSIZE;
WeakReference<IResource> wr = resourceHashArray[idx];
if (wr == null)
return null;
IResource r = wr.get();
if (r == null)
return null;
if (r.getPtr() == ptr)
return r;
return null;
}
/**
* All resources will be released.
*
* @param except
* the resource to be excluded from the clearance
*/
public void releaseAll(IResource except) {
int len = resourceHashArray.length;
for (int i = 0; i < len; i++) {
WeakReference<IResource> wr = resourceHashArray[i];
if (wr == null)
continue;
resourceHashArray[i] = null;
IResource r = wr.get();
if (r != null) {
r.release();
}
}
addResource(except);
if (childRMs != null) {
Iterator<ResourceManager> itm = childRMs.iterator();
while (itm.hasNext()) {
itm.next().releaseAll(except);
}
}
}
/**
* @param resource
* the resource to be removed from the manager
*/
public void removeResource(IResource resource) {
long ptr = resource.getPtr();
int idx = (int) ptr % HASHSIZE;
WeakReference<IResource> wr = resourceHashArray[idx];
if (wr == null)
return;
IResource r = wr.get();
if (r == null) {
resourceHashArray[idx] = null;
return;
}
if (r.getPtr() != ptr)
return;
resourceHashArray[idx] = null;
wr.clear();
return;
}
/**
* @param target
* the resource to be added to the manager
*/
public void addResource(IResource target) {
long ptr = target.getPtr();
int idx = (int) ptr % HASHSIZE;
WeakReference<IResource> wr = new WeakReference<IResource>(target);
resourceHashArray[idx] = wr;
return;
}
/**
* @param parent
* the parent resource manager
* @return the new instance of ResourceManager has the parent
*/
public static ResourceManager newResourceManager(ResourceManager parent) {
ResourceManager rm = new ResourceManager(parent);
if (parent != null) {
if (parent.childRMs == null) {
parent.childRMs = new ArrayList<ResourceManager>(1);
}
parent.childRMs.add(rm);
}
return rm;
}
private ResourceManager(ResourceManager parent) {
this.parent = parent;
}
}