KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jca > WorkManagerImpl


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

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 JavaDoc;
37 import javax.resource.spi.work.Work JavaDoc;
38 import javax.resource.spi.work.WorkEvent JavaDoc;
39 import javax.resource.spi.work.WorkException JavaDoc;
40 import javax.resource.spi.work.WorkListener JavaDoc;
41 import javax.resource.spi.work.WorkManager JavaDoc;
42 import java.util.ArrayList JavaDoc;
43 import java.util.logging.Logger JavaDoc;
44
45 /**
46  * Implementation of the work manager.
47  */

48 public class WorkManagerImpl implements WorkManager JavaDoc {
49   private static final L10N L = new L10N(WorkManagerImpl.class);
50   private static final Logger JavaDoc log = Log.open(WorkManagerImpl.class);
51
52   private ArrayList JavaDoc<Work JavaDoc> _activeTasks = new ArrayList JavaDoc<Work JavaDoc>();
53
54   private volatile boolean _isClosed;
55
56   /**
57    * Constructor.
58    */

59   WorkManagerImpl()
60   {
61   }
62
63   /**
64    * Accepts a work instance for processing. The call blocks until
65    * the work instance completes.
66    */

67   public void doWork(Work JavaDoc work)
68     throws WorkException JavaDoc
69   {
70     doWork(work, INDEFINITE, null, null);
71   }
72
73   /**
74    * Accepts a work instance for processing. The call blocks until
75    * the work instance completes.
76    */

77   public void doWork(Work JavaDoc work,
78              long startTimeout,
79              ExecutionContext JavaDoc context,
80              WorkListener JavaDoc listener)
81     throws WorkException JavaDoc
82   {
83     boolean isStart = false;
84     
85     try {
86       WorkException JavaDoc exn = null;
87       
88       synchronized (this) {
89     if (_isClosed)
90       exn = new WorkException JavaDoc(L.l("Work task can't be started from closed context."));
91     else if (_activeTasks.contains(work))
92       exn = new WorkException JavaDoc(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 JavaDoc(this, WorkEvent.WORK_ACCEPTED,
104                         work, null, 0));
105       else {
106     listener.workRejected(new WorkEvent JavaDoc(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 JavaDoc(this, WorkEvent.WORK_STARTED,
115                        work, null, 0));
116       
117       work.run();
118
119       if (listener != null)
120     listener.workCompleted(new WorkEvent JavaDoc(this, WorkEvent.WORK_COMPLETED,
121                          work, null, 0));
122     } finally {
123       synchronized (this) {
124     _activeTasks.remove(work);
125       }
126     }
127   }
128
129   /**
130    * Accepts a work instance for processing. The call blocks until
131    * the work instance starts, but does not wait not until the completion.
132    */

133   public long startWork(Work JavaDoc work)
134     throws WorkException JavaDoc
135   {
136     return startWork(work, INDEFINITE, null, null);
137   }
138
139   /**
140    * Accepts a work instance for processing. The call blocks until
141    * the work instance starts, but does not wait not until the completion.
142    */

143   public long startWork(Work JavaDoc work,
144             long startTimeout,
145             ExecutionContext JavaDoc context,
146             WorkListener JavaDoc listener)
147     throws WorkException JavaDoc
148   {
149     long start = Alarm.getCurrentTime();
150     
151     startWork(work, startTimeout, context, listener, true);
152
153     return Alarm.getCurrentTime() - start;
154   }
155
156   /**
157    * Schedules a work instance.
158    */

159   public void scheduleWork(Work JavaDoc work)
160     throws WorkException JavaDoc
161   {
162     // XXX: since there's no delay in start work, currently,
163
scheduleWork(work, INDEFINITE, null, null);
164   }
165
166   /**
167    * Schedules a work instance.
168    */

169   public void scheduleWork(Work JavaDoc work,
170                long startTimeout,
171                ExecutionContext JavaDoc context,
172                WorkListener JavaDoc listener)
173     throws WorkException JavaDoc
174   {
175     startWork(work, startTimeout, context, listener, false);
176   }
177
178   /**
179    * Accepts a work instance for processing. The call blocks until
180    * the work instance starts, but does not wait not until the completion.
181    */

182   private long startWork(Work JavaDoc work,
183              long startTimeout,
184              ExecutionContext JavaDoc context,
185              WorkListener JavaDoc listener,
186              boolean waitForStart)
187     throws WorkException JavaDoc
188   {
189     boolean isStart = false;
190     
191     WorkException JavaDoc exn = null;
192
193     try {
194       synchronized (this) {
195     if (_isClosed)
196       exn = new WorkException JavaDoc(L.l("Work task can't be started from closed context."));
197     else if (_activeTasks.contains(work))
198       exn = new WorkException JavaDoc(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 JavaDoc(this, WorkEvent.WORK_REJECTED,
206                           work, exn, 0));
207     throw exn;
208       }
209       else if (listener != null)
210     listener.workAccepted(new WorkEvent JavaDoc(this, WorkEvent.WORK_ACCEPTED,
211                         work, null, 0));
212
213       ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
214       WorkThread workThread = new WorkThread(this, work, loader, listener);
215
216       if (listener != null)
217     listener.workStarted(new WorkEvent JavaDoc(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 JavaDoc work)
235   {
236     synchronized (this) {
237       _activeTasks.remove(work);
238     }
239   }
240
241   /**
242    * Closes the work manager.
243    */

244   public void destroy()
245   {
246     synchronized (this) {
247       if (_isClosed)
248     return;
249       
250       _isClosed = true;
251     }
252
253     ArrayList JavaDoc<Work JavaDoc> activeTasks = new ArrayList JavaDoc<Work JavaDoc>();
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