FileDocCategorySizeDatePackage
AssocWithThreadResourcePool.javaAPI DocGlassfish v2 API8754Fri May 04 22:35:14 BST 2007com.sun.enterprise.resource

AssocWithThreadResourcePool

public class AssocWithThreadResourcePool extends AbstractResourcePool
this resource pool does not allow sharing A resource is only given out if it is not used by any enterprise bean and it does not have any pending transaction
author
Aditya Gore

Fields Summary
private static ThreadLocal
localResource
Constructors Summary
public AssocWithThreadResourcePool(String poolName)


         
         
        super( poolName );
    
Methods Summary
protected voiddestroyResource(ResourceHandle resourceHandle)

        try {
            super.destroyResource( resourceHandle );
        } finally { 
            //Note: here we are using the connectionErrorOccurred flag to indicate
            //that this resource is no longer usable. This flag would be checked while
            //getting from ThreadLocal
            //The main intention of marking this is to handle the case where 
            //failAllConnections happens
            //Note that setDirty only happens here - i.e during destroying of a 
            //resource
            
            synchronized( resourceHandle.lock ) {
                resourceHandle.setDirty();
            }
        }
    
protected synchronized voidfreeUnenlistedResource(ResourceHandle h)

        if ( ! h.isAssociated() ) {
            free.add( h );
        }
        //update monitoring data
        if(monitoringEnabled){
            poolCounters.decrementNumConnUsed(false);
        }
        
        if (maxConnectionUsage_ > 0) {
            performMaxConnectionUsageOperation(h);
        }
        notifyWaitingThreads();
    
protected ResourceHandlegetUnenlistedResource(ResourceSpec spec, ResourceAllocator alloc, javax.transaction.Transaction tran)
return resource in free list. If none is found, returns null


        ResourceHandle result;
        result = super.getUnenlistedResource(spec, alloc, tran);

        //If we came here, that's because free doesn't have anything
        //to offer us. This could be because:
        //1. All free resources are associated
        //2. There are no free resources
        //3. We cannot create anymore free resources
        //Handle case 1 here

        //DISASSOCIATE
        if (result == null) {
            synchronized (this) {
                for (ResourceHandle resource : resources) {
                    synchronized (resource.lock) {
                        //though we are checking resources from within the free list,
                        //we could have a situation where the resource was free upto
                        //this point, put just before we entered the synchronized block,
                        //the resource "h" got used by the thread that was associating it
                        //so we need to check for isFree also

                        if (resource.getResourceState().isUnenlisted() &&
                                resource.getResourceState().isFree()) {
                            if (!matchConnection(resource, alloc)) {
                                continue;
                            }

                            if (resource.hasConnectionErrorOccurred()) {
                                continue;
                            }
                            result = resource;
                            setResourceStateToBusy(result);
                            result.setAssociated(false);

                            break;
                        }
                    }
                }
            }
        }

        if (localResource.get() == null) {
            setInThreadLocal(result);
        }

        return result;
    
protected booleanisResourceUnused(ResourceHandle h)

        return h.getResourceState().isFree() && !h.isAssociated() ;
    
protected ResourceHandleprefetch(ResourceSpec spec, ResourceAllocator alloc, javax.transaction.Transaction tran)

        ResourceHandle ar = localResource.get();
        if (ar != null) {
            //synch on ar and do a quick-n-dirty check to see if the local
            //resource is usable at all
            synchronized( ar.lock ) {
                if ( (ar.getThreadId() != Thread.currentThread().getId()) ||
                        ar.hasConnectionErrorOccurred() || 
                        ar.isDirty() || !ar.isAssociated() ) {
                    //we were associated with someone else or resource error 
                    //occurred or resource was disassociated and used by some one else. So evict
                    //NOTE: We do not setAssociated to false here since someone
                    //else has associated this resource to themself. Also, if
                    //the eviction is because of a resourceError, the resource is
                    //not going to be used anyway.
                   
                    localResource.remove();
                    return null;
                }
                
                if (ar.getResourceState().isFree() && 
                        ar.getResourceState().isUnenlisted()) {
                    if (matchConnections) {
                        if (! alloc.matchConnection( ar ) ) {
                            //again, since the credentials of the caller don't match
                            //evict from ThreadLocal
                            //also, mark the resource as unassociated and make this resource
                            //potentially usable
                            localResource.remove();
                            ar.setAssociated( false );
                            if ( monitoringEnabled ) {
                                poolCounters.incrementNumConnNotSuccessfullyMatched();
                            }
                            return null;
                        }
                        if (monitoringEnabled) {
                            poolCounters.incrementNumConnSuccessfullyMatched();
                        }
                    }
            
                    
                    setResourceStateToBusy(ar);
		            if(maxConnectionUsage_ > 0){
                        ar.incrementUsageCount();
                    }
                    return ar;
                }
            }
        }

        return null;
    
private voidsetInThreadLocal(ResourceHandle h)

        if (h != null) {
            synchronized (h.lock) {
                h.setThreadId(Thread.currentThread().getId());
                h.setAssociated(true);
                localResource.set(h);
            }
        }