1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2001 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <assert.h> 30 #include <synch.h> 31 #include <jni.h> 32 33 #include "class_cache.h" 34 35 /* 36 * Only certain classes are deemed worthy of caching. These be them. 37 */ 38 #define DCR_NAME "com/sun/dhcpmgr/data/DhcpClientRecord" 39 #define DTR_NAME "com/sun/dhcpmgr/data/DhcptabRecord" 40 #define NET_NAME "com/sun/dhcpmgr/data/Network" 41 #define MAC_NAME "com/sun/dhcpmgr/data/Macro" 42 #define OPT_NAME "com/sun/dhcpmgr/data/Option" 43 #define DS_NAME "com/sun/dhcpmgr/data/DhcpDatastore" 44 #define CFG_NAME "com/sun/dhcpmgr/data/DhcpdOptions" 45 #define RES_NAME "com/sun/dhcpmgr/data/DhcpResource" 46 #define IP_NAME "com/sun/dhcpmgr/data/IPAddress" 47 #define IPIF_NAME "com/sun/dhcpmgr/data/IPInterface" 48 49 /* 50 * As with classes, only certain methods are cached. 51 */ 52 #define DCR_CONS_NAME "<init>" 53 #define DCR_GETCID_NAME "getClientId" 54 #define DCR_GETFLAG_NAME "getFlagString" 55 #define DCR_GETCIP_NAME "getClientIPAddress" 56 #define DCR_GETSIP_NAME "getServerIPAddress" 57 #define DCR_GETEXP_NAME "getExpirationTime" 58 #define DCR_GETSIG_NAME "getSignature" 59 #define DCR_GETMAC_NAME "getMacro" 60 #define DCR_GETCMT_NAME "getComment" 61 #define DTR_GETKEY_NAME "getKey" 62 #define DTR_GETFLAG_NAME "getFlag" 63 #define DTR_GETSIG_NAME "getSignature" 64 #define DTR_GETVAL_NAME "getValue" 65 #define NET_CONS_NAME "<init>" 66 #define MAC_CONS_NAME "<init>" 67 #define OPT_CONS_NAME "<init>" 68 #define DS_CONS_NAME "<init>" 69 #define DS_GETRSRC_NAME "getResource" 70 #define DS_GETLOC_NAME "getLocation" 71 #define DS_GETRSRCCFG_NAME "getConfig" 72 #define DS_GETVER_NAME "getVersion" 73 #define CFG_CONS_NAME "<init>" 74 #define CFG_SET_NAME "set" 75 #define CFG_GETALL_NAME "getAll" 76 #define RES_GETKEY_NAME "getKey" 77 #define RES_GETVAL_NAME "getValue" 78 #define RES_ISCOM_NAME "isComment" 79 #define IP_CONS_NAME "<init>" 80 #define IPIF_CONS_NAME "<init>" 81 82 /* 83 * Signatures for the methods can be found below. 84 */ 85 #define DCR_CONS_SIG "(Ljava/lang/String;Ljava/lang/String;"\ 86 "Ljava/lang/String;Ljava/lang/String;"\ 87 "Ljava/lang/String;Ljava/lang/String;"\ 88 "Ljava/lang/String;Ljava/lang/String;)V" 89 90 #define DCR_GETCID_SIG "()Ljava/lang/String;" 91 #define DCR_GETFLAG_SIG "()Ljava/lang/String;" 92 #define DCR_GETCIP_SIG "()Ljava/lang/String;" 93 #define DCR_GETSIP_SIG "()Ljava/lang/String;" 94 #define DCR_GETEXP_SIG "()Ljava/lang/String;" 95 #define DCR_GETSIG_SIG "()Ljava/lang/String;" 96 #define DCR_GETMAC_SIG "()Ljava/lang/String;" 97 #define DCR_GETCMT_SIG "()Ljava/lang/String;" 98 #define DTR_GETKEY_SIG "()Ljava/lang/String;" 99 #define DTR_GETFLAG_SIG "()Ljava/lang/String;" 100 #define DTR_GETSIG_SIG "()Ljava/lang/String;" 101 #define DTR_GETVAL_SIG "()Ljava/lang/String;" 102 #define NET_CONS_SIG "(Ljava/lang/String;I)V" 103 #define MAC_CONS_SIG "(Ljava/lang/String;Ljava/lang/String;"\ 104 "Ljava/lang/String;)V" 105 #define OPT_CONS_SIG "(Ljava/lang/String;B[Ljava/lang/String;"\ 106 "SBIILjava/lang/String;Z)V" 107 #define DS_CONS_SIG "(Ljava/lang/String;IZ)V" 108 #define DS_GETRSRC_SIG "()Ljava/lang/String;" 109 #define DS_GETLOC_SIG "()Ljava/lang/String;" 110 #define DS_GETRSRCCFG_SIG "()Ljava/lang/String;" 111 #define DS_GETVER_SIG "()I" 112 #define CFG_CONS_SIG "()V" 113 #define CFG_SET_SIG "(Ljava/lang/String;Ljava/lang/String;Z)V" 114 #define CFG_GETALL_SIG "()[Ljava/lang/Object;" 115 #define RES_GETKEY_SIG "()Ljava/lang/String;" 116 #define RES_GETVAL_SIG "()Ljava/lang/String;" 117 #define RES_ISCOM_SIG "()Z" 118 #define IP_CONS_SIG "(Ljava/lang/String;)V" 119 #define IPIF_CONS_SIG "(Ljava/lang/String;Ljava/lang/String;"\ 120 "Ljava/lang/String;)V" 121 /* 122 * Class map. 123 */ 124 typedef struct { 125 jclass cl_class; 126 char *cl_name; 127 } cl_map_t; 128 129 /* 130 * Note that the order of the entries in this table must match 131 * exactly with the CC_CLASSMAP_ID enumeration in class_cache.h. 132 */ 133 static cl_map_t classMap[] = { 134 { NULL, DCR_NAME }, /* DCR_CLASS */ 135 { NULL, DTR_NAME }, /* DTR_CLASS */ 136 { NULL, NET_NAME }, /* NET_CLASS */ 137 { NULL, MAC_NAME }, /* MAC_CLASS */ 138 { NULL, OPT_NAME }, /* OPT_CLASS */ 139 { NULL, DS_NAME }, /* DS_CLASS */ 140 { NULL, CFG_NAME }, /* CFG_CLASS */ 141 { NULL, RES_NAME }, /* RES_CLASS */ 142 { NULL, IP_NAME }, /* IP_CLASS */ 143 { NULL, IPIF_NAME } /* IPIF_CLASS */ 144 }; 145 146 /* 147 * Method ID map. 148 */ 149 typedef struct { 150 jmethodID mi_methodID; 151 char *mi_name; 152 char *mi_signature; 153 } mi_map_t; 154 155 /* 156 * Note that the order of the entries in this table must match 157 * exactly with the CC_METHODMAP_ID enumeration in class_cache.h. 158 */ 159 static mi_map_t methodIDMap[] = { 160 { NULL, DCR_CONS_NAME, DCR_CONS_SIG }, /* DCR_CONS */ 161 { NULL, DCR_GETCID_NAME, DCR_GETCID_SIG }, /* DCR_GETCID */ 162 { NULL, DCR_GETFLAG_NAME, DCR_GETFLAG_SIG }, /* DCR_GETFLAG */ 163 { NULL, DCR_GETCIP_NAME, DCR_GETCIP_SIG }, /* DCR_GETCIP */ 164 { NULL, DCR_GETSIP_NAME, DCR_GETSIP_SIG }, /* DCR_GETSIP */ 165 { NULL, DCR_GETEXP_NAME, DCR_GETEXP_SIG }, /* DCR_GETEXP */ 166 { NULL, DCR_GETSIG_NAME, DCR_GETSIG_SIG }, /* DCR_GETSIG */ 167 { NULL, DCR_GETMAC_NAME, DCR_GETMAC_SIG }, /* DCR_GETMAC */ 168 { NULL, DCR_GETCMT_NAME, DCR_GETCMT_SIG }, /* DCR_GETCMT */ 169 { NULL, DTR_GETKEY_NAME, DTR_GETKEY_SIG }, /* DTR_GETKEY */ 170 { NULL, DTR_GETFLAG_NAME, DTR_GETFLAG_SIG }, /* DTR_GETFLAG */ 171 { NULL, DTR_GETSIG_NAME, DTR_GETSIG_SIG }, /* DTR_GETSIG */ 172 { NULL, DTR_GETVAL_NAME, DTR_GETVAL_SIG }, /* DTR_GETVAL */ 173 { NULL, NET_CONS_NAME, NET_CONS_SIG }, /* NET_CONS */ 174 { NULL, MAC_CONS_NAME, MAC_CONS_SIG }, /* MAC_CONS */ 175 { NULL, OPT_CONS_NAME, OPT_CONS_SIG }, /* OPT_CONS */ 176 { NULL, DS_CONS_NAME, DS_CONS_SIG }, /* DS_CONS */ 177 { NULL, DS_GETRSRC_NAME, DS_GETRSRC_SIG }, /* DS_GETRSRC */ 178 { NULL, DS_GETLOC_NAME, DS_GETLOC_SIG }, /* DS_GETLOC */ 179 { NULL, DS_GETRSRCCFG_NAME, DS_GETRSRCCFG_SIG }, /* DS_GETRSRCCFG */ 180 { NULL, DS_GETVER_NAME, DS_GETVER_SIG }, /* DS_GETVER */ 181 { NULL, CFG_CONS_NAME, CFG_CONS_SIG }, /* CFG_CONS */ 182 { NULL, CFG_SET_NAME, CFG_SET_SIG }, /* CFG_SET */ 183 { NULL, CFG_GETALL_NAME, CFG_GETALL_SIG }, /* CFG_GETALL */ 184 { NULL, RES_GETKEY_NAME, RES_GETKEY_SIG }, /* RES_GETKEY */ 185 { NULL, RES_GETVAL_NAME, RES_GETVAL_SIG }, /* RES_GETVAL */ 186 { NULL, RES_ISCOM_NAME, RES_ISCOM_SIG }, /* RES_ISCOM */ 187 { NULL, IP_CONS_NAME, IP_CONS_SIG }, /* IP_CONS */ 188 { NULL, IPIF_CONS_NAME, IPIF_CONS_SIG } /* IPIF_CONS */ 189 }; 190 191 /* 192 * The locks to protect the class and method maps. 193 */ 194 static mutex_t cmap_lock; 195 static mutex_t mmap_lock; 196 197 void 198 init_class_cache(void) { 199 (void) mutex_init(&cmap_lock, USYNC_THREAD, NULL); 200 (void) mutex_init(&mmap_lock, USYNC_THREAD, NULL); 201 } 202 203 /* 204 * Get a dhcpmgr class from the cache. 205 */ 206 jclass 207 find_class(JNIEnv *env, CC_CLASSMAP_ID id) { 208 209 jclass *class; 210 211 assert(id >= 0 && id <= CC_CLASSMAP_NUM); 212 213 /* 214 * If the class has not been cached yet, go find it and cache it. 215 */ 216 class = &classMap[id].cl_class; 217 if (*class == NULL) { 218 /* 219 * Check again with the lock held this time. 220 */ 221 (void) mutex_lock(&cmap_lock); 222 if (*class == NULL) { 223 char *name = classMap[id].cl_name; 224 jclass local = (*env)->FindClass(env, name); 225 if (local != NULL) { 226 *class = (*env)->NewGlobalRef(env, local); 227 (*env)->DeleteLocalRef(env, local); 228 } 229 } 230 (void) mutex_unlock(&cmap_lock); 231 } 232 233 return (*class); 234 } 235 236 /* 237 * Get a dhcpmgr class methodid from the cache. 238 */ 239 jmethodID 240 get_methodID(JNIEnv *env, jclass class, CC_METHODMAP_ID id) { 241 242 jmethodID *methodID; 243 244 assert(id >= 0 && id <= CC_METHODMAP_NUM); 245 246 /* 247 * If the methodID has not been cached, go find it and cache it. 248 */ 249 methodID = &methodIDMap[id].mi_methodID; 250 if (*methodID == NULL) { 251 /* 252 * Check again with the lock held this time. 253 */ 254 (void) mutex_lock(&mmap_lock); 255 if (*methodID == NULL) { 256 char *name = methodIDMap[id].mi_name; 257 char *signature = methodIDMap[id].mi_signature; 258 *methodID = (*env)->GetMethodID(env, class, name, 259 signature); 260 } 261 (void) mutex_unlock(&mmap_lock); 262 } 263 264 return (*methodID); 265 }