1 /* Magical NSA API -- Associate a C ptr with an instance of an object
2 Copyright (C) 1998, 2002 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
40 #include "native_state.h"
42 #define DEFAULT_TABLE_SIZE 97
45 init_state_table_with_size (JNIEnv
*env
, jclass clazz
, jint size
)
47 struct state_table
*table
;
51 hash
= (*env
)->GetFieldID (env
, clazz
, "native_state", "I");
55 clazz_g
= (*env
)->NewGlobalRef (env
, clazz
);
59 table
= (struct state_table
*) malloc (sizeof (struct state_table
));
61 table
->head
= (struct state_node
**) calloc (sizeof (struct state_node
*),
64 table
->clazz
= clazz_g
;
70 init_state_table (JNIEnv
*env
, jclass clazz
)
72 return init_state_table_with_size (env
, clazz
, DEFAULT_TABLE_SIZE
);
76 remove_node (struct state_node
**head
, jint obj_id
)
78 struct state_node
*back_ptr
= NULL
;
79 struct state_node
*node
= *head
;
83 if (node
->key
== obj_id
)
89 back_ptr
->next
= node
->next
;
90 return_value
= node
->c_state
;
102 get_node (struct state_node
**head
, jint obj_id
)
104 struct state_node
*back_ptr
= NULL
;
105 struct state_node
*node
= *head
;
109 if (node
->key
== obj_id
)
111 /* Move the node we found to the front of the list. */
112 if (back_ptr
!= NULL
)
114 back_ptr
->next
= node
->next
;
119 /* Return the match. */
120 return node
->c_state
;
131 add_node (struct state_node
**head
, jint obj_id
, void *state
)
133 struct state_node
*node
= *head
;
134 struct state_node
*back_ptr
= NULL
;
136 struct state_node
*new_node
;
140 while (node
->next
!= NULL
&& obj_id
!= node
->key
)
146 if (node
->key
== obj_id
)
148 /* If we're updating a node, move it to the front of the
150 if (back_ptr
!= NULL
)
152 back_ptr
->next
= node
->next
;
155 node
->c_state
= state
;
160 new_node
= (struct state_node
*) malloc (sizeof (struct state_node
));
161 new_node
->key
= obj_id
;
162 new_node
->c_state
= state
;
163 new_node
->next
= *head
;
168 set_state_oid (JNIEnv
*env
, jobject lock
, struct state_table
*table
,
169 jint obj_id
, void *state
)
173 hash
= obj_id
% table
->size
;
175 (*env
)->MonitorEnter (env
, lock
);
176 add_node (&table
->head
[hash
], obj_id
, state
);
177 (*env
)->MonitorExit (env
, lock
);
181 get_state_oid (JNIEnv
*env
, jobject lock
, struct state_table
*table
,
187 hash
= obj_id
% table
->size
;
189 (*env
)->MonitorEnter (env
, lock
);
190 return_value
= get_node (&table
->head
[hash
], obj_id
);
191 (*env
)->MonitorExit (env
, lock
);
197 remove_state_oid (JNIEnv
*env
, jobject lock
, struct state_table
*table
,
203 hash
= obj_id
% table
->size
;
205 (*env
)->MonitorEnter (env
, lock
);
206 return_value
= remove_node (&table
->head
[hash
], obj_id
);
207 (*env
)->MonitorExit (env
, lock
);
213 set_state (JNIEnv
*env
, jobject obj
, struct state_table
*table
, void *state
)
216 obj_id
= (*env
)->GetIntField (env
, obj
, table
->hash
);
218 if ((*env
)->ExceptionOccurred (env
) != NULL
)
221 set_state_oid (env
, table
->clazz
, table
, obj_id
, state
);
226 get_state (JNIEnv
*env
, jobject obj
, struct state_table
*table
)
229 obj_id
= (*env
)->GetIntField (env
, obj
, table
->hash
);
231 if ((*env
)->ExceptionOccurred (env
) != NULL
)
234 return get_state_oid (env
, table
->clazz
, table
, obj_id
);
238 remove_state_slot (JNIEnv
*env
, jobject obj
, struct state_table
*table
)
241 obj_id
= (*env
)->GetIntField (env
, obj
, table
->hash
);
243 if ((*env
)->ExceptionOccurred (env
) != NULL
)
246 return remove_state_oid (env
, table
->clazz
, table
, obj_id
);