-
Notifications
You must be signed in to change notification settings - Fork 143
/
ResourceHandle.java
372 lines (298 loc) · 9.85 KB
/
ResourceHandle.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
/*
* Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.enterprise.resource;
import com.sun.appserv.connectors.internal.api.PoolingException;
import com.sun.enterprise.connectors.ConnectorRuntime;
import com.sun.enterprise.resource.allocator.LocalTxConnectorAllocator;
import com.sun.enterprise.resource.allocator.ResourceAllocator;
import com.sun.enterprise.transaction.spi.TransactionalResource;
import com.sun.logging.LogDomains;
import jakarta.resource.spi.ConnectionEventListener;
import jakarta.resource.spi.DissociatableManagedConnection;
import jakarta.resource.spi.LazyEnlistableManagedConnection;
import jakarta.transaction.Transaction;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
import javax.security.auth.Subject;
import javax.transaction.xa.XAResource;
import static java.util.logging.Level.FINEST;
/**
* ResourceHandle encapsulates a resource connection.
*
* <p>Equality on the handle is based on the id field.
*
* @author Tony Ng
*/
public class ResourceHandle implements com.sun.appserv.connectors.internal.api.ResourceHandle, TransactionalResource {
private static final Logger logger = LogDomains.getLogger(ResourceHandle.class, LogDomains.RSR_LOGGER);
// unique ID for resource handles
static private long idSequence;
private final long id;
private final ClientSecurityInfo info;
private final Object resource; // represents MC
private ResourceSpec spec;
private XAResource xaRes;
private Object userConnection; // represents connection-handle to user
private final ResourceAllocator resourceAllocator;
private Object instance; // the component instance holding this resource
private int shareCount; // sharing within a component (XA only)
private final boolean supportsXAResource;
private Subject subject;
private ResourceState state;
private ConnectionEventListener listener;
private boolean enlistmentSuspended;
private boolean supportsLazyEnlistment_;
private boolean supportsLazyAssoc_;
public final Object lock = new Object();
private long lastValidated; // holds the latest time at which the connection was validated.
private int usageCount; // holds the no. of times the handle(connection) is used so far.
private int partition;
private int index;
private boolean isDestroyByLeakTimeOut;
private boolean connectionErrorOccurred;
static private long getNextId() {
synchronized (ResourceHandle.class) {
idSequence++;
return idSequence;
}
}
private boolean markedReclaim;
public ResourceHandle(Object resource, ResourceSpec spec, ResourceAllocator alloc, ClientSecurityInfo info) {
this.id = getNextId();
this.spec = spec;
this.info = info;
this.resource = resource;
this.resourceAllocator = alloc;
if (alloc instanceof LocalTxConnectorAllocator) {
supportsXAResource = false;
} else {
supportsXAResource = true;
}
if (resource instanceof LazyEnlistableManagedConnection) {
supportsLazyEnlistment_ = true;
}
if (resource instanceof DissociatableManagedConnection) {
supportsLazyAssoc_ = true;
}
}
/**
* Does this resource need enlistment to transaction manager?
*/
@Override
public boolean isTransactional() {
return resourceAllocator.isTransactional();
}
/**
* To check whether lazy enlistment is suspended or not.
*
* <p>If {@code true}, TM will not do enlist/lazy enlist.
*
* @return boolean
*/
@Override
public boolean isEnlistmentSuspended() {
return enlistmentSuspended;
}
@Override
public void setEnlistmentSuspended(boolean enlistmentSuspended) {
this.enlistmentSuspended = enlistmentSuspended;
}
public void markForReclaim(boolean reclaim) {
this.markedReclaim = reclaim;
}
/**
* To check if the resourceHandle is marked for leak reclaim or not.
*
* @return boolean
*/
public boolean isMarkedForReclaim() {
return markedReclaim;
}
@Override
public boolean supportsXA() {
return supportsXAResource;
}
public ResourceAllocator getResourceAllocator() {
return resourceAllocator;
}
public Object getResource() {
return resource;
}
public ClientSecurityInfo getClientSecurityInfo() {
return info;
}
public void setResourceSpec(ResourceSpec spec) {
this.spec = spec;
}
public ResourceSpec getResourceSpec() {
return spec;
}
@Override
public XAResource getXAResource() {
return xaRes;
}
public Object getUserConnection() {
return userConnection;
}
@Override
public void setComponentInstance(Object instance) {
this.instance = instance;
}
@Override
public void closeUserConnection() throws PoolingException {
getResourceAllocator().closeUserConnection(this);
}
@Override
public Object getComponentInstance() {
return instance;
}
public long getId() {
return id;
}
public void fillInResourceObjects(Object userConnection, XAResource xaRes) {
if (userConnection != null) {
this.userConnection = userConnection;
}
if (xaRes != null) {
if (logger.isLoggable(FINEST)) {
// When Log level is Finest, XAResourceWrapper is used to log
// all XA interactions - Don't wrap XAResourceWrapper if it is
// already wrapped
if ((xaRes instanceof XAResourceWrapper) || (xaRes instanceof ConnectorXAResource)) {
this.xaRes = xaRes;
} else {
this.xaRes = new XAResourceWrapper(xaRes);
}
} else {
this.xaRes = xaRes;
}
}
}
// For XA-capable connections, multiple connections within a
// component are collapsed into one. shareCount keeps track of
// the number of additional shared connections
public void incrementCount() {
shareCount++;
}
public void decrementCount() {
if (shareCount == 0) {
throw new IllegalStateException("shareCount cannot be negative");
}
shareCount--;
}
public int getShareCount() {
return shareCount;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
public Subject getSubject() {
return subject;
}
@Override
public boolean equals(Object other) {
if (other == null) {
return false;
}
if (other instanceof ResourceHandle) {
return this.id == (((ResourceHandle) other).id);
}
return false;
}
@Override
public int hashCode() {
return Long.valueOf(id).hashCode();
}
@Override
public String toString() {
return String.valueOf(id);
}
public void setConnectionErrorOccurred() {
connectionErrorOccurred = true;
}
public boolean hasConnectionErrorOccurred() {
return connectionErrorOccurred;
}
public void setResourceState(ResourceState state) {
this.state = state;
}
public ResourceState getResourceState() {
return state;
}
public void setListener(ConnectionEventListener l) {
this.listener = l;
}
public ConnectionEventListener getListener() {
return listener;
}
@Override
public boolean isShareable() {
return resourceAllocator.shareableWithinComponent();
}
@Override
public void destroyResource() {
throw new UnsupportedOperationException("Transaction is not supported yet");
}
@Override
public boolean isEnlisted() {
return state != null && state.isEnlisted();
}
public long getLastValidated() {
return lastValidated;
}
public void setLastValidated(long lastValidated) {
this.lastValidated = lastValidated;
}
public int getUsageCount() {
return usageCount;
}
public void incrementUsageCount() {
usageCount++;
}
public int getPartition() {
return partition;
}
public void setPartition(int partition) {
this.partition = partition;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
@Override
public String getName() {
return spec.getResourceId();
}
public boolean supportsLazyEnlistment() {
return supportsLazyEnlistment_;
}
public boolean supportsLazyAssociation() {
return supportsLazyAssoc_;
}
@Override
public void enlistedInTransaction(Transaction transaction) throws IllegalStateException {
ConnectorRuntime.getRuntime().getPoolManager().resourceEnlisted(transaction, this);
}
public boolean getDestroyByLeakTimeOut() {
return isDestroyByLeakTimeOut;
}
public void setDestroyByLeakTimeOut(boolean isDestroyByLeakTimeOut) {
this.isDestroyByLeakTimeOut = isDestroyByLeakTimeOut;
}
}