KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > resource > AssocWithThreadResourcePool


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.resource;
24
25 import java.util.*;
26
27 import javax.resource.ResourceException JavaDoc;
28 import javax.resource.spi.ManagedConnection JavaDoc;
29 import javax.transaction.*;
30 import java.util.logging.*;
31 import com.sun.logging.*;
32
33 import javax.naming.Context JavaDoc;
34 import javax.naming.NamingException JavaDoc;
35 import com.sun.enterprise.Switch;
36 import com.sun.enterprise.connectors.*;
37 import com.sun.enterprise.distributedtx.*;
38 import com.sun.enterprise.util.i18n.StringManager;
39
40
41
42 /**
43  * this resource pool does not allow sharing
44  * A resource is only given out if it is not used by
45  * any enterprise bean and it does not have any pending transaction
46  *
47  * @author Aditya Gore
48  */

49 public class AssocWithThreadResourcePool extends AbstractResourcePool {
50     
51     private static ThreadLocal JavaDoc<ResourceHandle> localResource =
52         new ThreadLocal JavaDoc<ResourceHandle>();
53
54     public AssocWithThreadResourcePool( String JavaDoc poolName )
55         throws PoolingException
56     {
57         super( poolName );
58     }
59     
60     protected ResourceHandle prefetch( ResourceSpec spec,
61         ResourceAllocator alloc, Transaction tran)
62     {
63         ResourceHandle ar = localResource.get();
64         if (ar != null) {
65             //synch on ar and do a quick-n-dirty check to see if the local
66
//resource is usable at all
67
synchronized( ar.lock ) {
68                 if ( (ar.getThreadId() != Thread.currentThread().getId()) ||
69                         ar.hasConnectionErrorOccurred() ||
70                         ar.isDirty() || !ar.isAssociated() ) {
71                     //we were associated with someone else or resource error
72
//occurred or resource was disassociated and used by some one else. So evict
73
//NOTE: We do not setAssociated to false here since someone
74
//else has associated this resource to themself. Also, if
75
//the eviction is because of a resourceError, the resource is
76
//not going to be used anyway.
77

78                     localResource.remove();
79                     return null;
80                 }
81                 
82                 if (ar.getResourceState().isFree() &&
83                         ar.getResourceState().isUnenlisted()) {
84                     if (matchConnections) {
85                         if (! alloc.matchConnection( ar ) ) {
86                             //again, since the credentials of the caller don't match
87
//evict from ThreadLocal
88
//also, mark the resource as unassociated and make this resource
89
//potentially usable
90
localResource.remove();
91                             ar.setAssociated( false );
92                             if ( monitoringEnabled ) {
93                                 poolCounters.incrementNumConnNotSuccessfullyMatched();
94                             }
95                             return null;
96                         }
97                         if (monitoringEnabled) {
98                             poolCounters.incrementNumConnSuccessfullyMatched();
99                         }
100                     }
101             
102                     
103                     ar.getResourceState().setBusy( true );
104
105                     return ar;
106                 }
107             }
108         }
109
110         return null;
111     }
112
113     private void setInThreadLocal( ResourceHandle h ) {
114         if ( h != null ) {
115             h.setThreadId( Thread.currentThread().getId() );
116             h.setAssociated( true );
117             localResource.set( h );
118         }
119
120     }
121
122     protected boolean isResourceUnused(ResourceHandle h){
123         return h.getResourceState().isFree() && !h.isAssociated() ;
124     }
125
126
127     // this is the RI getResource() with some modifications
128
/**
129      * return resource in free list. If none is found, returns null
130      *
131      */

132     synchronized protected ResourceHandle getUnenlistedResource(ResourceSpec spec,
133     ResourceAllocator alloc,
134     Transaction tran) throws PoolingException {
135     
136         ResourceHandle result = null;
137         result = super.getUnenlistedResource( spec, alloc, tran );
138
139         //If we came here, that's because free doesn't have anything
140
//to offer us. This could be because:
141
//1. All free resources are associated
142
//2. There are no free resources
143
//3. We cannot create anymore free resources
144
//Handle case 1 here
145

146         //DISASSOCIATE
147
if ( result == null ) {
148             Iterator tempIter = resources.iterator();
149             while( tempIter.hasNext() ) {
150                 ResourceHandle h = (ResourceHandle) tempIter.next();
151                 synchronized( h.lock ) {
152                     //though we are checking resources from within the free list,
153
//we could have a situation where the resource was free upto
154
//this point, put just before we entered the synchronized block,
155
//the resource "h" got used by the thread that was associating it
156
//so we need to check for isFree also
157

158                     if (h.getResourceState().isUnenlisted() &&
159                             h.getResourceState().isFree()) {
160                         if (matchConnections) {
161                             if (! alloc.matchConnection(h) ) {
162                                 if (monitoringEnabled) {
163                                     poolCounters.incrementNumConnNotSuccessfullyMatched();
164                                 }
165                                 continue;
166                             }
167                             if ( monitoringEnabled ) {
168                                 poolCounters.incrementNumConnSuccessfullyMatched();
169                             }
170                         }
171
172                         if ( h.hasConnectionErrorOccurred() ) {
173                             continue;
174                         }
175                         result = h;
176                         result.getResourceState().setBusy( true );
177                         result.setAssociated( false );
178                         break;
179                     }
180                 }
181             }
182         }
183        
184         if ( localResource.get() == null ) {
185             setInThreadLocal( result );
186         }
187         return result;
188         
189     }
190
191     protected synchronized void freeUnenlistedResource(ResourceHandle h) {
192         if ( ! h.isAssociated() ) {
193             free.add( h );
194         }
195         notifyWaitingThreads();
196     }
197
198     protected void destroyResource(ResourceHandle resourceHandle) {
199         try {
200             super.destroyResource( resourceHandle );
201         } finally {
202             //Note: here we are using the connectionErrorOccurred flag to indicate
203
//that this resource is no longer usable. This flag would be checked while
204
//getting from ThreadLocal
205
//The main intention of marking this is to handle the case where
206
//failAllConnections happens
207
//Note that setDirty only happens here - i.e during destroying of a
208
//resource
209

210             synchronized( resourceHandle.lock ) {
211                 resourceHandle.setDirty();
212             }
213         }
214     }
215
216 }
217
Popular Tags