/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. * * * This file incorporates work covered by the following copyright and * permission notice: * * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.common; import java.io.IOException; import java.util.Vector; import java.util.logging.*; import org.apache.jk.apr.AprImpl; import org.apache.jk.core.Msg; import org.apache.jk.core.MsgContext; import org.apache.jk.core.WorkerEnv; import com.sun.grizzly.util.IntrospectionUtils; import com.sun.grizzly.util.buf.C2BConverter; /* The code is a bit confusing at this moment - the class is used as a Bean, or ant Task, or CLI - i.e. you set properties and call execute. That's different from the rest of jk handlers wich are stateless ( but similar with Coyote-http ). */ /** Handle the shared memory objects. * * @author Costin Manolache */ public class Shm extends JniHandler { String file="/tmp/shm.file"; int size; String host="localhost"; int port=8009; String unixSocket; boolean help=false; boolean unregister=false; boolean reset=false; String dumpFile=null; Vector groups = new Vector(); // Will be dynamic ( getMethodId() ) after things are stable static final int SHM_WRITE_SLOT=2; static final int SHM_RESET=5; static final int SHM_DUMP=6; public Shm() { } /** Scoreboard location */ public void setFile( String f ) { file=f; } /** Copy the scoreboard in a file for debugging * Will also log a lot of information about what's in the scoreboard. */ public void setDump( String dumpFile ) { this.dumpFile=dumpFile; } /** Size. Used only if the scoreboard is to be created. */ public void setSize( int size ) { this.size=size; } /** Set this to get the scoreboard reset. * The shm segment will be destroyed and a new one created, * with the provided size. * * Requires "file" and "size". */ public void setReset(boolean b) { reset=true; } /** Ajp13 host */ public void setHost( String host ) { this.host=host; } /** Mark this instance as belonging to a group */ public void setGroup( String grp ) { groups.addElement( grp ); } /** Ajp13 port */ public void setPort( int port ) { this.port=port; } /** Unix socket where tomcat is listening. * Use it only if tomcat is on the same host, of course */ public void setUnixSocket( String unixSocket ) { this.unixSocket=unixSocket; } /** Set this option to mark the tomcat instance as 'down', so apache will no longer forward messages to it. Note that requests with a session will still try this host first. This can be used to implement gracefull shutdown. Host and port are still required, since they are used to identify tomcat. */ public void setUnregister( boolean unregister ) { this.unregister=true; } public void init() throws IOException { super.initNative( "shm" ); if( apr==null ) return; if( file==null ) { log.severe("No shm file, disabling shared memory"); apr=null; return; } // Set properties and call init. setNativeAttribute( "file", file ); if( size > 0 ) setNativeAttribute( "size", Integer.toString( size ) ); initJkComponent(); } public void resetScoreboard() throws IOException { if( apr==null ) return; MsgContext mCtx=createMsgContext(); Msg msg=(Msg)mCtx.getMsg(0); msg.reset(); msg.appendByte( SHM_RESET ); this.invoke( msg, mCtx ); } public void dumpScoreboard(String fname) throws IOException { if( apr==null ) return; MsgContext mCtx=createMsgContext(); Msg msg=(Msg)mCtx.getMsg(0); C2BConverter c2b=mCtx.getConverter(); msg.reset(); msg.appendByte( SHM_DUMP ); appendString( msg, fname, c2b); this.invoke( msg, mCtx ); } /** Register a tomcat instance * XXX make it more flexible */ public void registerTomcat(String host, int port, String unixDomain) throws IOException { String instanceId=host+":" + port; String slotName="TOMCAT:" + instanceId; MsgContext mCtx=createMsgContext(); Msg msg=(Msg)mCtx.getMsg(0); msg.reset(); C2BConverter c2b=mCtx.getConverter(); msg.appendByte( SHM_WRITE_SLOT ); appendString( msg, slotName, c2b ); int channelCnt=1; if( unixDomain != null ) channelCnt++; // number of groups. 0 means the default lb. msg.appendInt( groups.size() ); for( int i=0; i