1 28 29 package com.caucho.jca; 30 31 import com.caucho.log.Log; 32 import com.caucho.util.Alarm; 33 import com.caucho.util.L10N; 34 import com.caucho.util.ThreadPool; 35 36 import javax.resource.spi.work.ExecutionContext ; 37 import javax.resource.spi.work.Work ; 38 import javax.resource.spi.work.WorkEvent ; 39 import javax.resource.spi.work.WorkException ; 40 import javax.resource.spi.work.WorkListener ; 41 import javax.resource.spi.work.WorkManager ; 42 import java.util.ArrayList ; 43 import java.util.logging.Logger ; 44 45 48 public class WorkManagerImpl implements WorkManager { 49 private static final L10N L = new L10N(WorkManagerImpl.class); 50 private static final Logger log = Log.open(WorkManagerImpl.class); 51 52 private ArrayList <Work > _activeTasks = new ArrayList <Work >(); 53 54 private volatile boolean _isClosed; 55 56 59 WorkManagerImpl() 60 { 61 } 62 63 67 public void doWork(Work work) 68 throws WorkException 69 { 70 doWork(work, INDEFINITE, null, null); 71 } 72 73 77 public void doWork(Work work, 78 long startTimeout, 79 ExecutionContext context, 80 WorkListener listener) 81 throws WorkException 82 { 83 boolean isStart = false; 84 85 try { 86 WorkException exn = null; 87 88 synchronized (this) { 89 if (_isClosed) 90 exn = new WorkException (L.l("Work task can't be started from closed context.")); 91 else if (_activeTasks.contains(work)) 92 exn = new WorkException (L.l("Reentrant Work tasks are not allowed.")); 93 else { 94 isStart = true; 95 96 _activeTasks.add(work); 97 } 98 } 99 100 if (listener == null) { 101 } 102 else if (isStart) 103 listener.workAccepted(new WorkEvent (this, WorkEvent.WORK_ACCEPTED, 104 work, null, 0)); 105 else { 106 listener.workRejected(new WorkEvent (this, WorkEvent.WORK_REJECTED, 107 work, exn, 0)); 108 } 109 110 if (exn != null) 111 throw exn; 112 113 if (listener != null) 114 listener.workStarted(new WorkEvent (this, WorkEvent.WORK_STARTED, 115 work, null, 0)); 116 117 work.run(); 118 119 if (listener != null) 120 listener.workCompleted(new WorkEvent (this, WorkEvent.WORK_COMPLETED, 121 work, null, 0)); 122 } finally { 123 synchronized (this) { 124 _activeTasks.remove(work); 125 } 126 } 127 } 128 129 133 public long startWork(Work work) 134 throws WorkException 135 { 136 return startWork(work, INDEFINITE, null, null); 137 } 138 139 143 public long startWork(Work work, 144 long startTimeout, 145 ExecutionContext context, 146 WorkListener listener) 147 throws WorkException 148 { 149 long start = Alarm.getCurrentTime(); 150 151 startWork(work, startTimeout, context, listener, true); 152 153 return Alarm.getCurrentTime() - start; 154 } 155 156 159 public void scheduleWork(Work work) 160 throws WorkException 161 { 162 scheduleWork(work, INDEFINITE, null, null); 164 } 165 166 169 public void scheduleWork(Work work, 170 long startTimeout, 171 ExecutionContext context, 172 WorkListener listener) 173 throws WorkException 174 { 175 startWork(work, startTimeout, context, listener, false); 176 } 177 178 182 private long startWork(Work work, 183 long startTimeout, 184 ExecutionContext context, 185 WorkListener listener, 186 boolean waitForStart) 187 throws WorkException 188 { 189 boolean isStart = false; 190 191 WorkException exn = null; 192 193 try { 194 synchronized (this) { 195 if (_isClosed) 196 exn = new WorkException (L.l("Work task can't be started from closed context.")); 197 else if (_activeTasks.contains(work)) 198 exn = new WorkException (L.l("Reentrant Work tasks are not allowed.")); 199 else 200 _activeTasks.add(work); 201 } 202 203 if (exn != null) { 204 if (listener != null) 205 listener.workRejected(new WorkEvent (this, WorkEvent.WORK_REJECTED, 206 work, exn, 0)); 207 throw exn; 208 } 209 else if (listener != null) 210 listener.workAccepted(new WorkEvent (this, WorkEvent.WORK_ACCEPTED, 211 work, null, 0)); 212 213 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 214 WorkThread workThread = new WorkThread(this, work, loader, listener); 215 216 if (listener != null) 217 listener.workStarted(new WorkEvent (this, WorkEvent.WORK_STARTED, 218 work, null, 0)); 219 220 if (waitForStart) 221 isStart = ThreadPool.getThreadPool().start(workThread, startTimeout); 222 else 223 isStart = ThreadPool.getThreadPool().schedule(workThread, startTimeout); 224 } finally { 225 synchronized (this) { 226 if (! isStart) 227 _activeTasks.remove(work); 228 } 229 } 230 231 return 0; 232 } 233 234 void completeWork(Work work) 235 { 236 synchronized (this) { 237 _activeTasks.remove(work); 238 } 239 } 240 241 244 public void destroy() 245 { 246 synchronized (this) { 247 if (_isClosed) 248 return; 249 250 _isClosed = true; 251 } 252 253 ArrayList <Work > activeTasks = new ArrayList <Work >(); 254 255 synchronized (this) { 256 activeTasks.addAll(_activeTasks); 257 } 258 259 for (int i = 0; i < activeTasks.size(); i++) 260 activeTasks.get(i).release(); 261 } 262 } 263 | Popular Tags |