KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > util > Exit


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.util;
30
31 import java.util.ArrayList JavaDoc;
32
33 /**
34  * The exit class is used to automatically clean state. For example,
35  * Resin JavaScript will close open files when the script exits.
36  *
37  * Here's a sample use:
38  * <pre>
39  * boolean isExit = addExit();
40  * try {
41  * ...
42  * } finally {
43  * if (isExit)
44  * exit();
45  * }
46  * </pre>
47  *
48  * <p>Objects register for the exit callback by calling
49  * <code>addExit(listener, object)</code>.
50  *
51  * <p>Exits are intrinsically tied to a thread.
52  */

53 public class Exit {
54   static private ThreadLocal JavaDoc<Queue> _waiting = new ThreadLocal JavaDoc<Queue>();
55
56   private Exit() {}
57
58   /**
59    * Registers the object and listener. The listener will be called when
60    * the thread exits the scope.
61    *
62    * <p>If there is no protection scope, i.e. addExit() hasn't been called,
63    * then this function does nothing.
64    *
65    * @param listener the exit handler
66    * @param object the object which needs cleanup
67    */

68   static public void addExit(ExitListener listener, Object JavaDoc object)
69   {
70     Queue queue = _waiting.get();
71
72     if (queue != null)
73       queue.add(listener, object);
74   }
75
76   /**
77    * Starts a protection scope. Only the outermost scope is important, so
78    * protecting routines must check the return value to see if they are the
79    * outermost scope.
80    *
81    * @return true if this is the outermost scope.
82    */

83   static public boolean addExit()
84   {
85     Queue queue = _waiting.get();
86
87     if (queue == null) {
88       queue = Queue.allocate();
89       _waiting.set(queue);
90       return true;
91     } else
92       return false;
93   }
94
95   /**
96    * Calls all registered listeners.
97    */

98   static public void exit()
99   {
100     Queue queue = null;
101
102     queue = _waiting.get();
103     _waiting.set(null);
104
105     if (queue == null)
106       return;
107     
108     int size = queue._listeners.size();
109     for (int i = 0; i < size; i++) {
110       ExitListener listener = queue._listeners.get(i);
111       Object JavaDoc object = queue._objects.get(i);
112
113       if (listener != null) {
114     try {
115       listener.handleExit(object);
116     } catch (Exception JavaDoc e) {
117     }
118       }
119     }
120
121     queue.free();
122   }
123
124   private static class Queue {
125     static Queue _freeList;
126
127     Queue _next;
128     ArrayList JavaDoc<ExitListener> _listeners = new ArrayList JavaDoc<ExitListener>();
129     ArrayList JavaDoc<Object JavaDoc> _objects = new ArrayList JavaDoc<Object JavaDoc>();
130
131     private Queue()
132     {
133     }
134
135     void add(ExitListener listener, Object JavaDoc object)
136     {
137       _listeners.add(listener);
138       _objects.add(object);
139     }
140
141     static Queue allocate()
142     {
143       if (_freeList == null)
144     return new Queue();
145
146       Queue queue = _freeList;
147       _freeList = _freeList._next;
148
149       return queue;
150     }
151
152     void free()
153     {
154       _listeners.clear();
155       _objects.clear();
156       _next = _freeList;
157       _freeList = this;
158     }
159   }
160 }
161
Popular Tags