00001
00025
package org.objectweb.cjdbc.controller.scheduler.schema;
00026
00027
import java.util.ArrayList;
00028
00029
import org.objectweb.cjdbc.common.sql.AbstractRequest;
00030
00040 public class TransactionExclusiveLock
00041 {
00042 private boolean isLocked =
false;
00043
00045 private long locker;
00046
00048 private ArrayList
waitingList =
new ArrayList();
00049
00054 private class WaitingListElement
00055 {
00057 Thread
thread;
00058
00060 long transactionId;
00061
00068 WaitingListElement(Thread thread,
long transactionId)
00069 {
00070
this.thread = thread;
00071
this.transactionId = transactionId;
00072 }
00073
00079 public long getTransactionId()
00080 {
00081
return transactionId;
00082 }
00083
00089 public Thread
getThread()
00090 {
00091
return thread;
00092 }
00093 }
00094
00107 public boolean acquire(
AbstractRequest request)
00108 {
00109
long tid = request.
getTransactionId();
00110
00111
synchronized (Thread.currentThread())
00112 {
00113
WaitingListElement wle = null;
00114
synchronized (
this)
00115 {
00116
if (!
isLocked)
00117 {
00118
locker = tid;
00119
isLocked =
true;
00120
return true;
00121 }
00122
else
00123 {
00124
if ((!request.
isAutoCommit()) && (
locker == tid))
00125
return true;
00126
else
00127 {
00128 wle =
new WaitingListElement(Thread.currentThread(), tid);
00129
waitingList.add(wle);
00130 }
00131 }
00132 }
00133
00134
try
00135 {
00136
int timeout = request.
getTimeout();
00137
if (timeout == 0)
00138 {
00139 Thread.currentThread().wait();
00140
00141
return true;
00142 }
00143
else
00144 {
00145
long start = System.currentTimeMillis();
00146
00147
long lTimeout = timeout * 1000;
00148 Thread.currentThread().wait(lTimeout);
00149
long end = System.currentTimeMillis();
00150
int remaining = (
int) (lTimeout - (end - start));
00151
if (remaining > 0)
00152 {
00153 request.
setTimeout(remaining);
00154
00155
return true;
00156 }
00157
else
00158 {
00159
synchronized (
this)
00160 {
00161
int idx =
waitingList.indexOf(wle);
00162
if (idx == -1)
00163
00164
00165
release();
00166
else
00167
waitingList.remove(idx);
00168 }
00169
return false;
00170 }
00171 }
00172 }
00173
catch (InterruptedException ie)
00174 {
00175
synchronized (
this)
00176 {
00177
waitingList.remove(Thread.currentThread());
00178 }
00179
return false;
00180 }
00181 }
00182 }
00183
00189 public synchronized void release()
00190 {
00191
while (!
waitingList.isEmpty())
00192 {
00193
00194
WaitingListElement e = (
WaitingListElement)
waitingList.remove(0);
00195 Thread thread = e.
getThread();
00196
locker = e.
getTransactionId();
00197
synchronized (thread)
00198 {
00199 thread.notify();
00200
00201
return;
00202 }
00203 }
00204
isLocked =
false;
00205 }
00206
00212 public boolean isLocked()
00213 {
00214
return isLocked;
00215 }
00216
00223 public long getLocker()
00224 {
00225
return locker;
00226 }
00227
00233 public ArrayList
getWaitingList()
00234 {
00235
return waitingList;
00236 }
00237
00245 public synchronized boolean isWaiting(
long transactionId)
00246 {
00247
WaitingListElement e;
00248
int size =
waitingList.size();
00249
for (
int i = 0; i < size; i++)
00250 {
00251 e = (
WaitingListElement)
waitingList.get(i);
00252
if (e.
getTransactionId() == transactionId)
00253
return true;
00254 }
00255
return false;
00256 }
00257 }