1 16 17 package org.apache.jk.common; 18 19 import java.io.IOException ; 20 21 import javax.management.ObjectName ; 22 23 import org.apache.commons.modeler.Registry; 24 import org.apache.jk.apr.AprImpl; 25 import org.apache.jk.core.JkHandler; 26 import org.apache.jk.core.Msg; 27 import org.apache.jk.core.MsgContext; 28 import org.apache.jk.core.JkChannel; 29 import org.apache.tomcat.util.buf.ByteChunk; 30 import org.apache.tomcat.util.buf.C2BConverter; 31 import org.apache.tomcat.util.buf.MessageBytes; 32 33 34 48 public class JniHandler extends JkHandler { 49 protected AprImpl apr; 50 51 protected long nativeJkHandlerP; 53 54 protected String jkHome; 55 56 public static final int JK_HANDLE_JNI_DISPATCH=0x15; 58 public static final int JK_HANDLE_SHM_DISPATCH=0x16; 59 60 61 public static final int MSG_NOTE=0; 62 public static final int C2B_NOTE=1; 63 public static final int MB_NOTE=2; 64 private boolean paused = false; 65 66 67 public JniHandler() { 68 } 69 70 72 public void setJkHome( String s ) { 73 jkHome=s; 74 } 75 76 public String getJkHome() { 77 return jkHome; 78 } 79 80 82 public void init() throws IOException { 83 } 85 86 protected void initNative(String nativeComponentName) { 87 apr=(AprImpl)wEnv.getHandler("apr"); 88 if( apr==null ) { 89 try { 93 apr=new AprImpl(); 94 wEnv.addHandler("apr", apr); 95 apr.init(); 96 if( oname != null ) { 97 ObjectName aprname=new ObjectName (oname.getDomain() + 98 ":type=JkHandler, name=apr"); 99 Registry.getRegistry(null, null).registerComponent(apr, aprname, null); 100 } 101 } catch( Throwable t ) { 102 log.debug("Can't load apr", t); 103 apr=null; 104 } 105 } 106 if( apr==null || ! apr.isLoaded() ) { 107 if( log.isDebugEnabled() ) 108 log.debug("No apr, disabling jni proxy "); 109 apr=null; 110 return; 111 } 112 113 try { 114 long xEnv=apr.getJkEnv(); 115 nativeJkHandlerP=apr.getJkHandler(xEnv, nativeComponentName ); 116 117 if( nativeJkHandlerP==0 ) { 118 log.debug("Component not found, creating it " + nativeComponentName ); 119 nativeJkHandlerP=apr.createJkHandler(xEnv, nativeComponentName); 120 } 121 log.debug("Native proxy " + nativeJkHandlerP ); 122 apr.releaseJkEnv(xEnv); 123 } catch( Throwable t ) { 124 apr=null; 125 log.info("Error calling apr ", t); 126 } 127 } 128 129 public void appendString( Msg msg, String s, C2BConverter charsetDecoder) 130 throws IOException 131 { 132 ByteChunk bc=charsetDecoder.getByteChunk(); 133 charsetDecoder.recycle(); 134 charsetDecoder.convert( s ); 135 charsetDecoder.flushBuffer(); 136 msg.appendByteChunk( bc ); 137 } 138 139 public void pause() throws Exception { 140 synchronized(this) { 141 paused = true; 142 } 143 } 144 145 public void resume() throws Exception { 146 synchronized(this) { 147 paused = false; 148 notifyAll(); 149 } 150 } 151 152 153 155 public MsgContext createMsgContext() { 156 if( nativeJkHandlerP==0 || apr==null ) 157 return null; 158 159 synchronized(this) { 160 try{ 161 while(paused) { 162 wait(); 163 } 164 }catch(InterruptedException ie) { 165 } 167 } 168 169 try { 170 MsgContext msgCtx=new MsgContext(); 171 MsgAjp msg=new MsgAjp(); 172 173 msgCtx.setSource( (JkChannel)this ); 174 msgCtx.setWorkerEnv( wEnv ); 175 176 msgCtx.setNext( this ); 177 178 msgCtx.setMsg( MSG_NOTE, msg); 180 C2BConverter c2b=new C2BConverter( "iso-8859-1" ); 181 msgCtx.setNote( C2B_NOTE, c2b ); 182 183 MessageBytes tmpMB= MessageBytes.newInstance(); 184 msgCtx.setNote( MB_NOTE, tmpMB ); 185 return msgCtx; 186 } catch( Exception ex ) { 187 log.error("Can't create endpoint", ex); 188 return null; 189 } 190 } 191 192 public void setNativeAttribute(String name, String val) throws IOException { 193 if( apr==null ) return; 194 195 if( nativeJkHandlerP == 0 ) { 196 log.error( "Unitialized component " + name+ " " + val ); 197 return; 198 } 199 200 long xEnv=apr.getJkEnv(); 201 202 apr.jkSetAttribute( xEnv, nativeJkHandlerP, name, val ); 203 204 apr.releaseJkEnv( xEnv ); 205 } 206 207 public void initJkComponent() throws IOException { 208 if( apr==null ) return; 209 210 if( nativeJkHandlerP == 0 ) { 211 log.error( "Unitialized component " ); 212 return; 213 } 214 215 long xEnv=apr.getJkEnv(); 216 217 apr.jkInit( xEnv, nativeJkHandlerP ); 218 219 apr.releaseJkEnv( xEnv ); 220 } 221 222 public void destroyJkComponent() throws IOException { 223 if( apr==null ) return; 224 225 if( nativeJkHandlerP == 0 ) { 226 log.error( "Unitialized component " ); 227 return; 228 } 229 230 long xEnv=apr.getJkEnv(); 231 232 apr.jkDestroy( xEnv, nativeJkHandlerP ); 233 234 apr.releaseJkEnv( xEnv ); 235 } 236 237 238 239 protected void setNativeEndpoint(MsgContext msgCtx) { 240 long xEnv=apr.getJkEnv(); 241 msgCtx.setJniEnv( xEnv ); 242 243 long epP=apr.createJkHandler(xEnv, "endpoint"); 244 log.debug("create ep " + epP ); 245 if( epP == 0 ) return; 246 apr.jkInit( xEnv, epP ); 247 msgCtx.setJniContext( epP ); 248 249 } 250 251 protected void recycleNative(MsgContext ep) { 252 apr.jkRecycle(ep.getJniEnv(), ep.getJniContext()); 253 } 254 255 258 protected int nativeDispatch( Msg msg, MsgContext ep, int code, int raw ) 259 throws IOException 260 { 261 if( log.isDebugEnabled() ) 262 log.debug( "Sending packet " + code + " " + raw); 263 264 if( raw == 0 ) { 265 msg.end(); 266 267 if( log.isTraceEnabled() ) msg.dump("OUT:" ); 268 } 269 270 long xEnv=ep.getJniEnv(); 273 long nativeContext=ep.getJniContext(); 274 if( nativeContext==0 || xEnv==0 ) { 275 setNativeEndpoint( ep ); 276 xEnv=ep.getJniEnv(); 277 nativeContext=ep.getJniContext(); 278 } 279 280 if( xEnv==0 || nativeContext==0 || nativeJkHandlerP==0 ) { 281 log.error("invokeNative: Null pointer "); 282 return -1; 283 } 284 285 int status=AprImpl.jkInvoke( xEnv, 288 nativeJkHandlerP, 289 nativeContext, 290 code, msg.getBuffer(), 0, msg.getLen(), raw ); 291 292 if( status != 0 && status != 2 ) { 293 log.error( "nativeDispatch: error " + status, new Throwable () ); 294 } 295 296 if( log.isDebugEnabled() ) log.debug( "Sending packet - done " + status); 297 return status; 298 } 299 300 303 public int invoke(Msg msg, MsgContext ep ) 304 throws IOException 305 { 306 long xEnv=ep.getJniEnv(); 307 int type=ep.getType(); 308 309 int status=nativeDispatch(msg, ep, type, 0 ); 310 311 apr.jkRecycle(xEnv, ep.getJniContext()); 312 apr.releaseJkEnv( xEnv ); 313 return status; 314 } 315 316 private static org.apache.commons.logging.Log log= 317 org.apache.commons.logging.LogFactory.getLog( JniHandler.class ); 318 } 319 | Popular Tags |