FileDocCategorySizeDatePackage
ChannelUn.javaAPI DocApache Tomcat 6.0.1412304Fri Jul 20 04:20:34 BST 2007org.apache.jk.common

ChannelUn

public class ChannelUn extends JniHandler implements org.apache.jk.core.JkChannel
Pass messages using unix domain sockets.
author
Costin Manolache

Fields Summary
static final int
CH_OPEN
static final int
CH_CLOSE
static final int
CH_READ
static final int
CH_WRITE
String
file
org.apache.tomcat.util.threads.ThreadPool
tp
int
socketNote
int
isNote
int
osNote
int
localId
ObjectName
tpOName
ObjectName
rgOName
org.apache.coyote.RequestGroupInfo
global
int
count
int
JMXRequestNote
boolean
running
private static org.apache.juli.logging.Log
log
Constructors Summary
Methods Summary
voidacceptConnections()
Accept incoming connections, dispatch to the thread pool

    
                 
      
        if( apr==null ) return;

        if( log.isDebugEnabled() )
            log.debug("Accepting ajp connections on " + file);
        
        while( running ) {
            try {
                MsgContext ep=this.createMsgContext();

                // blocking - opening a server connection.
                int status=this.open(ep);
                if( status != 0 && status != 2 ) {
                    log.error( "Error acceptin connection on " + file );
                    break;
                }

                //    if( log.isDebugEnabled() )
                //     log.debug("Accepted ajp connections ");
        
                AprConnection ajpConn= new AprConnection(this, ep);
                tp.runIt( ajpConn );
            } catch( Exception ex ) {
                ex.printStackTrace();
            }
        }
    
public voidclose(org.apache.jk.core.MsgContext ep)

        super.nativeDispatch( ep.getMsg(0), ep, CH_CLOSE, 1 );
    
public voiddestroy()

        if( apr==null ) return;
        try {
            if( tp != null )
                tp.shutdown();
            
            //apr.unSocketClose( unixListenSocket,3);
            super.destroyJkComponent();

            if(tpOName != null) {
		Registry.getRegistry(null, null).unregisterComponent(tpOName);
	    }
	    if(rgOName != null) {
		Registry.getRegistry(null, null).unregisterComponent(rgOName);
	    }
        } catch(Exception e) {
            log.error("Error in destroy",e);
        }
    
public intflush(org.apache.jk.core.Msg msg, org.apache.jk.core.MsgContext ep)

	return OK;
    
public java.lang.StringgetChannelName()

        String encodedAddr = "";
        String address = file;
        if (address != null) {
            encodedAddr = "" + address;
            if (encodedAddr.startsWith("/"))
                encodedAddr = encodedAddr.substring(1);
            encodedAddr = URLEncoder.encode(encodedAddr) ;
        }
        return ("jk-" + encodedAddr);
    
public java.lang.StringgetFile()

        return file;
    
public org.apache.tomcat.util.threads.ThreadPoolgetThreadPool()


    /* ==================== Tcp socket options ==================== */

       
        return tp;
    
public voidinit()

    
         
        if( file==null ) {
            log.debug("No file, disabling unix channel");
            return;
            //throw new IOException( "No file for the unix socket channel");
        }
        if( wEnv!=null && wEnv.getLocalId() != 0 ) {
            localId=wEnv.getLocalId();
        }

        if( localId != 0 ) {
            file=file+ localId;
        }
        File socketFile=new File( file );
        if( !socketFile.isAbsolute() ) {
            String home=wEnv.getJkHome();
            if( home==null ) {
                log.debug("No jkhome");
            } else {
                File homef=new File( home );
                socketFile=new File( homef, file );
                log.debug( "Making the file absolute " +socketFile);
            }
        }
        
        if( ! socketFile.exists() ) {
            try {
                FileOutputStream fos=new FileOutputStream(socketFile);
                fos.write( 1 );
                fos.close();
            } catch( Throwable t ) {
                log.error("Attempting to create the file failed, disabling channel" 
                        + socketFile);
                return;
            }
        }
        // The socket file cannot be removed ...
        if (!socketFile.delete()) {
            log.error( "Can't remove socket file " + socketFile);
            return;
        }
        

        super.initNative( "channel.un:" + file );

        if( apr==null || ! apr.isLoaded() ) {
            log.debug("Apr is not available, disabling unix channel ");
            apr=null;
            return;
        }
        
        // Set properties and call init.
        setNativeAttribute( "file", file );
        // unixListenSocket=apr.unSocketListen( file, 10 );

        setNativeAttribute( "listen", "10" );
        // setNativeAttribute( "debug", "10" );

        // Initialize the thread pool and execution chain
        if( next==null && wEnv!=null ) {
            if( nextName!=null ) 
                setNext( wEnv.getHandler( nextName ) );
            if( next==null )
                next=wEnv.getHandler( "dispatch" );
            if( next==null )
                next=wEnv.getHandler( "request" );
        }

        super.initJkComponent();
        JMXRequestNote =wEnv.getNoteId( WorkerEnv.ENDPOINT_NOTE, "requestNote");        
        // Run a thread that will accept connections.
        if( this.domain != null ) {
            try {
                tpOName=new ObjectName(domain + ":type=ThreadPool,name=" + 
				       getChannelName());

                Registry.getRegistry(null, null)
		    .registerComponent(tp, tpOName, null);

		rgOName = new ObjectName
		    (domain+":type=GlobalRequestProcessor,name=" + getChannelName());
		Registry.getRegistry(null, null)
		    .registerComponent(global, rgOName, null);
            } catch (Exception e) {
                log.error("Can't register threadpool" );
            }
        }
        tp.start();
        AprAcceptor acceptAjp=new AprAcceptor(  this );
        tp.runIt( acceptAjp);
        log.info("JK: listening on unix socket: " + file );
        
    
public intinvoke(org.apache.jk.core.Msg msg, org.apache.jk.core.MsgContext ep)

        int type=ep.getType();

        switch( type ) {
        case JkHandler.HANDLE_RECEIVE_PACKET:
            return receive( msg, ep );
        case JkHandler.HANDLE_SEND_PACKET:
            return send( msg, ep );
        case JkHandler.HANDLE_FLUSH:
            return flush( msg, ep );
        }

        // return next.invoke( msg, ep );
        return OK;
    
public booleanisSameAddress(org.apache.jk.core.MsgContext ep)

	return false; // Not supporting shutdown on this channel.
    
public intopen(org.apache.jk.core.MsgContext ep)
Open a connection - since we're listening that will block in accept

        // Will associate a jk_endpoint with ep and call open() on it.
        // jk_channel_un will accept a connection and set the socket info
        // in the endpoint. MsgContext will represent an active connection.
        return super.nativeDispatch( ep.getMsg(0), ep, CH_OPEN, 1 );
    
voidprocessConnection(org.apache.jk.core.MsgContext ep)
Process a single ajp connection.

        if( log.isDebugEnabled() )
            log.debug( "New ajp connection ");
        try {
            MsgAjp recv=new MsgAjp();
            while( running ) {
                int res=this.receive( recv, ep );
                if( res<0 ) {
                    // EOS
                    break;
                }
                ep.setType(0);
                log.debug( "Process msg ");
                int status=next.invoke( recv, ep );
            }
            if( log.isDebugEnabled() )
                log.debug( "Closing un channel");
            try{
                Request req = (Request)ep.getRequest();
                if( req != null ) {
                    ObjectName roname = (ObjectName)ep.getNote(JMXRequestNote);
                    if( roname != null ) {
                        Registry.getRegistry(null, null).unregisterComponent(roname);
                    }
                    req.getRequestProcessor().setGlobalProcessor(null);
                }
            } catch( Exception ee) {
                log.error( "Error, releasing connection",ee);
            }
            this.close( ep );
        } catch( Exception ex ) {
            ex.printStackTrace();
        }
    
public intreceive(org.apache.jk.core.Msg msg, org.apache.jk.core.MsgContext ep)

        int rc=super.nativeDispatch( msg, ep, CH_READ, 1 );

        if( rc!=0 ) {
            log.error("receive error:   " + rc, new Throwable());
            return -1;
        }
        
        msg.processHeader();
        
        if (log.isDebugEnabled())
             log.debug("receive:  total read = " + msg.getLen());

	return msg.getLen();
    
public voidregisterRequest(org.apache.coyote.Request req, org.apache.jk.core.MsgContext ep, int count)

	if(this.domain != null) {
	    try {

		RequestInfo rp=req.getRequestProcessor();
		rp.setGlobalProcessor(global);
		ObjectName roname = new ObjectName
		    (getDomain() + ":type=RequestProcessor,worker="+
		     getChannelName()+",name=JkRequest" +count);
		ep.setNote(JMXRequestNote, roname);
                        
		Registry.getRegistry(null, null).registerComponent( rp, roname, null);
	    } catch( Exception ex ) {
		log.warn("Error registering request");
	    }
	}
    
public intsend(org.apache.jk.core.Msg msg, org.apache.jk.core.MsgContext ep)

        return super.nativeDispatch( msg, ep, CH_WRITE, 0 );
    
public voidsetFile(java.lang.String f)

        file=f;
    
public voidstart()