00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 package org.objectweb.cjdbc.controller.scheduler.schema;
00026
00027 import java.util.ArrayList;
00028
00029 import org.objectweb.cjdbc.common.sql.AbstractRequest;
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 public class TransactionExclusiveLock
00041 {
00042 private boolean isLocked = false;
00043
00044
00045 private long locker;
00046
00047
00048 private ArrayList waitingList = new ArrayList();
00049
00050
00051
00052
00053
00054 private class WaitingListElement
00055 {
00056
00057 Thread thread;
00058
00059
00060 long transactionId;
00061
00062
00063
00064
00065
00066
00067
00068 WaitingListElement(Thread thread, long transactionId)
00069 {
00070 this.thread = thread;
00071 this.transactionId = transactionId;
00072 }
00073
00074
00075
00076
00077
00078
00079 public long getTransactionId()
00080 {
00081 return transactionId;
00082 }
00083
00084
00085
00086
00087
00088
00089 public Thread getThread()
00090 {
00091 return thread;
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
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
00184
00185
00186
00187
00188
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
00207
00208
00209
00210
00211
00212 public boolean isLocked()
00213 {
00214 return isLocked;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223 public long getLocker()
00224 {
00225 return locker;
00226 }
00227
00228
00229
00230
00231
00232
00233 public ArrayList getWaitingList()
00234 {
00235 return waitingList;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
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 }