41
41
* Is [ 1116101 ] jacob-msg 0284 relevant???
42
42
*/
43
43
public abstract class ROT {
44
- /**
45
- * Manual garbage collection was the only option pre 1.9
46
- */
47
- protected static final boolean USE_AUTOMATIC_GARBAGE_COLLECTION =
48
- "true" .equalsIgnoreCase (System .getProperty ("com.jacob.autogc" ) );
44
+ /**
45
+ * Manual garbage collection was the only option pre 1.9
46
+ */
47
+ protected static final boolean USE_AUTOMATIC_GARBAGE_COLLECTION =
48
+ "true" .equalsIgnoreCase ( System .getProperty ( "com.jacob.autogc" ) );
49
49
50
- /**
51
- * A hash table where each element is another
52
- * HashMap that represents a thread.
53
- * Each thread HashMap contains the com objects created
54
- * in that thread
55
- */
56
- private static HashMap rot = new HashMap ();
50
+ /**
51
+ * A hash table where each element is another
52
+ * HashMap that represents a thread.
53
+ * Each thread HashMap contains the com objects created
54
+ * in that thread
55
+ */
56
+ private static HashMap rot = new HashMap ();
57
57
58
- /**
59
- * adds a new thread storage area to rot
60
- * @return Map corresponding to the thread that this call was made in
61
- */
62
- protected static Map addThread () {
63
- String t_name = Thread .currentThread ().getName ();
64
- if (rot .containsKey (t_name )){
65
- // nothing to do
66
- } else {
67
- Map tab = null ;
68
- if (JacobObject .isDebugEnabled ()){
69
- JacobObject .debug ("ROT: Automatic GC flag == " + USE_AUTOMATIC_GARBAGE_COLLECTION
70
- );}
71
- if (!USE_AUTOMATIC_GARBAGE_COLLECTION ){
72
- tab = new HashMap ();
73
- } else {
74
- tab = new WeakHashMap ();
75
- }
76
- rot .put (t_name ,tab );
77
- }
78
- return getThreadObjects (false );
79
- }
58
+ /**
59
+ * adds a new thread storage area to rot
60
+ * @return Map corresponding to the thread that this call was made in
61
+ */
62
+ protected synchronized static Map addThread () {
63
+ // should use the id here instead of the name because the name can be changed
64
+ String t_name = Thread .currentThread ().getName ();
65
+ if ( rot .containsKey ( t_name ) ) {
66
+ // nothing to do
67
+ } else {
68
+ Map tab = null ;
69
+ if ( JacobObject .isDebugEnabled () ) {
70
+ JacobObject .debug ( "ROT: Automatic GC flag == " + USE_AUTOMATIC_GARBAGE_COLLECTION );
71
+ }
72
+ if ( !USE_AUTOMATIC_GARBAGE_COLLECTION ) {
73
+ tab = new HashMap ();
74
+ } else {
75
+ tab = new WeakHashMap ();
76
+ }
77
+ rot .put ( t_name , tab );
78
+ }
79
+ return getThreadObjects ( false );
80
+ }
80
81
81
-
82
- /**
83
- * returns the pool for this thread if it exists. can create a new
84
- * one if you wish by passing in TRUE
85
- * @param createIfDoesNotExist
86
- * @return Map the collection that holds the objects created in the current thread
87
- */
88
- protected static Map getThreadObjects (boolean createIfDoesNotExist ) {
89
- String t_name = Thread .currentThread ().getName ();
90
- if (!rot .containsKey (t_name ) && createIfDoesNotExist ){
91
- addThread ();
92
- }
93
- return (Map )rot .get (t_name );
94
- }
95
-
96
- /**
97
- * Iterates across all of the entries in the Hashmap in the rot
98
- * that corresponds to this thread.
99
- * This calls safeRelease() on each entry and then
100
- * clears the map when done and removes it from the rot.
101
- * All traces of this thread's objects will disapear.
102
- * This is called by COMThread in the tear down and provides a
103
- * synchronous way of releasing memory
104
- */
105
- protected static void clearObjects () {
106
- Map tab = getThreadObjects (false );
107
- if (JacobObject .isDebugEnabled ()){
108
- JacobObject .debug ("ROT: " +rot .keySet ().size ()+" thread tables exist" );
109
- }
110
- if (tab != null ){
111
- if (JacobObject .isDebugEnabled ()){
112
- JacobObject .debug ("ROT: " +tab .keySet ().size ()+ " objects to clear in this thread " );
113
- }
114
- // walk the values
115
- Iterator it ;
116
- if (USE_AUTOMATIC_GARBAGE_COLLECTION ){
117
- it = tab .keySet ().iterator ();
118
- } else {
119
- it = tab .values ().iterator ();
120
- }
121
- while (it .hasNext ()) {
122
- JacobObject o = (JacobObject ) it .next ();
123
- if (o != null
124
- // can't use this cause creates a Variant if calling SafeAray
125
- // and we get an exceptin modifying the collection while iterating
126
- // && o.toString() != null
127
- ){
128
- if (JacobObject .isDebugEnabled ()){
129
- if (o instanceof SafeArray ){
130
- // SafeArray create more objects when calling toString()
131
- // which causes a concurrent modification exception in HashMap
132
- JacobObject .debug ("ROT: removing " +o .getClass ().getName ());
133
- } else {
134
- // Variant toString() is probably always bad in here
135
- JacobObject .debug ("ROT: removing " +o .hashCode ()+"->" +o .getClass ().getName ());
136
- }
137
- }
138
- o .safeRelease ();
139
- }
140
- // used to be an iterator.remove() but why bother when we're nuking them all anyway?
141
- }
142
- // empty the collection
143
- tab .clear ();
144
- // remove the collection from rot
145
- rot .remove (Thread .currentThread ().getName ());
146
- if (JacobObject .isDebugEnabled ()){
147
- JacobObject .debug ("ROT: thread table cleared and removed" );
148
- }
149
- } else {
150
- if (JacobObject .isDebugEnabled ()){ JacobObject .debug ("ROT: nothing to clear!" );}
151
- }
152
- }
82
+ /**
83
+ * returns the pool for this thread if it exists. can create a new
84
+ * one if you wish by passing in TRUE
85
+ * @param createIfDoesNotExist
86
+ * @return Map the collection that holds the objects created in the current thread
87
+ */
88
+ protected synchronized static Map getThreadObjects ( boolean createIfDoesNotExist ) {
89
+ String t_name = Thread .currentThread ().getName ();
90
+ if ( !rot .containsKey ( t_name ) && createIfDoesNotExist ) {
91
+ addThread ();
92
+ }
93
+ return (Map ) rot .get ( t_name );
94
+ }
153
95
154
- /**
155
- * generates the key used to insert object into the thread's list of objects.
156
- * @param targetMap the map we need the key for. Used to make sure we create a compatabile key
157
- * @param o JacobObject we need key for
158
- * @return some key compatabile with hashmaps
159
- */
160
- protected static Object getMapKey (Map targetMap , JacobObject o ){
161
- if (targetMap instanceof WeakHashMap ){
162
- return o ;
163
- } else {
164
- return new Integer (o .hashCode ());
165
- }
166
- }
167
-
168
- /**
169
- * generates the object used to insert object into the thread's list of objects.
170
- * @param targetMap the map we need the key for. Used to make sure we create a compatabile key
171
- * @param o JacobObject we need key for
172
- * @return some compatabile with hashmaps (null for weak has map)
173
- */
174
- protected static Object getMapValue (Map targetMap , JacobObject o ){
175
- if (targetMap instanceof WeakHashMap ){
176
- return null ;
177
- } else {
178
- return o ;
179
- }
180
- }
181
-
182
- /**
183
- * @deprecated the java model leave the responsibility of clearing up objects
184
- * to the Garbage Collector. Our programming model should not require that the
185
- * user specifically remove object from the thread.
186
- *
187
- * This will remove an object from the ROT
188
- * @param o
189
- */
190
- protected static void removeObject (JacobObject o ) {
191
- String t_name = Thread .currentThread ().getName ();
192
- Map tab = (Map ) rot .get (t_name );
193
- if (tab != null ) {
194
- tab .remove (getMapKey (tab ,o ));
195
- }
196
- o .safeRelease ();
197
- }
198
-
199
- /**
200
- * adds an object to the HashMap for the current thread
201
- * @param o
202
- */
203
- protected static void addObject (JacobObject o ) {
204
- Map tab = getThreadObjects (false );
205
- if (tab == null ) {
206
- // this thread has not been initialized as a COM thread
207
- // so make it part of MTA for backwards compatibility
208
- ComThread .InitMTA (false );
209
- tab = getThreadObjects (true );
210
- }
211
- if (JacobObject .isDebugEnabled ()){
212
- JacobObject .debug (
213
- "ROT: adding " +o +"->" +o .getClass ().getName () +
214
- " table size prior to addition:" +tab .size ());}
215
- if (tab != null ) {
216
- tab .put (getMapKey (tab ,o ),getMapValue (tab ,o ));
217
- }
218
- }
96
+ /**
97
+ * Iterates across all of the entries in the Hashmap in the rot
98
+ * that corresponds to this thread.
99
+ * This calls safeRelease() on each entry and then
100
+ * clears the map when done and removes it from the rot.
101
+ * All traces of this thread's objects will disapear.
102
+ * This is called by COMThread in the tear down and provides a
103
+ * synchronous way of releasing memory
104
+ */
105
+ protected synchronized static void clearObjects () {
106
+ Map tab = getThreadObjects ( false );
107
+ if ( JacobObject .isDebugEnabled () ) {
108
+ JacobObject .debug ( "ROT: " + rot .keySet ().size () + " thread tables exist" );
109
+ }
110
+ if ( tab != null ) {
111
+ if ( JacobObject .isDebugEnabled () ) {
112
+ JacobObject .debug ( "ROT: " + tab .keySet ().size () + " objects to clear in this thread " );
113
+ }
114
+ // walk the values
115
+ Iterator it ;
116
+ if ( USE_AUTOMATIC_GARBAGE_COLLECTION ) {
117
+ it = tab .keySet ().iterator ();
118
+ } else {
119
+ it = tab .values ().iterator ();
120
+ }
121
+ while ( it .hasNext () ) {
122
+ JacobObject o = (JacobObject ) it .next ();
123
+ if ( o != null
124
+ // can't use this cause creates a Variant if calling SafeAray
125
+ // and we get an exceptin modifying the collection while iterating
126
+ // && o.toString() != null
127
+ ) {
128
+ if ( JacobObject .isDebugEnabled () ) {
129
+ if ( o instanceof SafeArray ) {
130
+ // SafeArray create more objects when calling toString()
131
+ // which causes a concurrent modification exception in HashMap
132
+ JacobObject .debug ( "ROT: removing " + o .getClass ().getName () );
133
+ } else {
134
+ // Variant toString() is probably always bad in here
135
+ JacobObject .debug ( "ROT: removing " + o .hashCode () + "->" + o .getClass ().getName () );
136
+ }
137
+ }
138
+ o .safeRelease ();
139
+ }
140
+ // used to be an iterator.remove() but why bother when we're nuking them all anyway?
141
+ }
142
+ // empty the collection
143
+ tab .clear ();
144
+ // remove the collection from rot
145
+ rot .remove ( Thread .currentThread ().getName () );
146
+ if ( JacobObject .isDebugEnabled () ) {
147
+ JacobObject .debug ( "ROT: thread table cleared and removed" );
148
+ }
149
+ } else {
150
+ if ( JacobObject .isDebugEnabled () ) {
151
+ JacobObject .debug ( "ROT: nothing to clear!" );
152
+ }
153
+ }
154
+ }
219
155
220
- /**
221
- * ROT can't be a subclass of JacobObject because of the way ROT pools are managed
222
- * so we force a DLL load here by referncing JacobObject
223
- */
224
- static {
225
- LibraryLoader .loadJacobLibrary ();
226
- }
227
-
228
- }
156
+ /**
157
+ * generates the key used to insert object into the thread's list of objects.
158
+ * @param targetMap the map we need the key for. Used to make sure we create a compatabile key
159
+ * @param o JacobObject we need key for
160
+ * @return some key compatabile with hashmaps
161
+ */
162
+ protected static Object getMapKey ( Map targetMap , JacobObject o ) {
163
+ if ( targetMap instanceof WeakHashMap ) {
164
+ return o ;
165
+ } else {
166
+ return new Integer ( o .hashCode () );
167
+ }
168
+ }
169
+
170
+ /**
171
+ * generates the object used to insert object into the thread's list of objects.
172
+ * @param targetMap the map we need the key for. Used to make sure we create a compatabile key
173
+ * @param o JacobObject we need key for
174
+ * @return some compatabile with hashmaps (null for weak has map)
175
+ */
176
+ protected static Object getMapValue ( Map targetMap , JacobObject o ) {
177
+ if ( targetMap instanceof WeakHashMap ) {
178
+ return null ;
179
+ } else {
180
+ return o ;
181
+ }
182
+ }
183
+
184
+ /**
185
+ * @deprecated the java model leave the responsibility of clearing up objects
186
+ * to the Garbage Collector. Our programming model should not require that the
187
+ * user specifically remove object from the thread.
188
+ *
189
+ * This will remove an object from the ROT
190
+ * @param o
191
+ */
192
+ protected synchronized static void removeObject ( JacobObject o ) {
193
+ String t_name = Thread .currentThread ().getName ();
194
+ Map tab = (Map ) rot .get ( t_name );
195
+ if ( tab != null ) {
196
+ tab .remove ( getMapKey ( tab , o ) );
197
+ }
198
+ o .safeRelease ();
199
+ }
200
+
201
+ /**
202
+ * adds an object to the HashMap for the current thread
203
+ * @param o
204
+ */
205
+ protected synchronized static void addObject ( JacobObject o ) {
206
+ Map tab = getThreadObjects ( false );
207
+ if ( tab == null ) {
208
+ // this thread has not been initialized as a COM thread
209
+ // so make it part of MTA for backwards compatibility
210
+ ComThread .InitMTA ( false );
211
+ tab = getThreadObjects ( true );
212
+ }
213
+ if ( JacobObject .isDebugEnabled () ) {
214
+ JacobObject .debug (
215
+ "ROT: adding " + o + "->" + o .getClass ().getName () +
216
+ " table size prior to addition:" + tab .size () );
217
+ }
218
+ if ( tab != null ) {
219
+ tab .put ( getMapKey ( tab , o ), getMapValue ( tab , o ) );
220
+ }
221
+ }
222
+
223
+ /**
224
+ * ROT can't be a subclass of JacobObject because of the way ROT pools are managed
225
+ * so we force a DLL load here by referncing JacobObject
226
+ */
227
+ static {
228
+ LibraryLoader .loadJacobLibrary ();
229
+ }
230
+
231
+ }
232
+
0 commit comments