Source Code Cross Referenced for Ajp13Connector.java in  » Sevlet-Container » tomcat-connectors » org » apache » ajp » tomcat4 » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Sevlet Container » tomcat connectors » org.apache.ajp.tomcat4 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Copyright 1999-2004 The Apache Software Foundation
0003:         *
0004:         *  Licensed under the Apache License, Version 2.0 (the "License");
0005:         *  you may not use this file except in compliance with the License.
0006:         *  You may obtain a copy of the License at
0007:         *
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         *  Unless required by applicable law or agreed to in writing, software
0011:         *  distributed under the License is distributed on an "AS IS" BASIS,
0012:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         *  See the License for the specific language governing permissions and
0014:         *  limitations under the License.
0015:         */
0016:
0017:        package org.apache.ajp.tomcat4;
0018:
0019:        import java.io.IOException;
0020:        import java.net.InetAddress;
0021:        import java.net.ServerSocket;
0022:        import java.net.Socket;
0023:        import java.security.AccessControlException;
0024:        import java.util.Stack;
0025:        import java.util.Vector;
0026:
0027:        import org.apache.catalina.Connector;
0028:        import org.apache.catalina.Container;
0029:        import org.apache.catalina.Lifecycle;
0030:        import org.apache.catalina.LifecycleException;
0031:        import org.apache.catalina.LifecycleListener;
0032:        import org.apache.catalina.Request;
0033:        import org.apache.catalina.Response;
0034:        import org.apache.catalina.Service;
0035:        import org.apache.catalina.net.DefaultServerSocketFactory;
0036:        import org.apache.catalina.net.ServerSocketFactory;
0037:        import org.apache.catalina.util.LifecycleSupport;
0038:        import org.apache.catalina.util.StringManager;
0039:
0040:        /**
0041:         * Implementation of an Ajp13 connector.
0042:         *
0043:         * @author Kevin Seguin
0044:         * @version $Revision: 1.20 $ $Date: 2004/02/24 08:48:41 $
0045:         */
0046:
0047:        public final class Ajp13Connector implements  Connector, Lifecycle,
0048:                Runnable {
0049:
0050:            // ----------------------------------------------------- Instance Variables
0051:
0052:            /**
0053:             * The accept count for this Connector.
0054:             */
0055:            private int acceptCount = 10;
0056:
0057:            /**
0058:             * The IP address on which to bind, if any.  If <code>null</code>, all
0059:             * addresses on the server will be bound.
0060:             */
0061:            private String address = null;
0062:
0063:            /**
0064:             * The input buffer size we should create on input streams.
0065:             */
0066:            private int bufferSize = 2048;
0067:
0068:            /**
0069:             * The Container used for processing requests received by this Connector.
0070:             */
0071:            protected Container container = null;
0072:
0073:            /**
0074:             * The set of processors that have ever been created.
0075:             */
0076:            private Vector created = new Vector();
0077:
0078:            /**
0079:             * The current number of processors that have been created.
0080:             */
0081:            private int curProcessors = 0;
0082:
0083:            /**
0084:             * The debugging detail level for this component.
0085:             */
0086:            private int debug = 0;
0087:
0088:            /**
0089:             * The server socket factory for this component.
0090:             */
0091:            private ServerSocketFactory factory = null;
0092:
0093:            /**
0094:             * Descriptive information about this Connector implementation.
0095:             */
0096:            private static final String info = "org.apache.catalina.connector.ajp.Ajp13Connector/1.0";
0097:
0098:            /**
0099:             * redirect port.
0100:             */
0101:            private int redirectPort = -1;
0102:
0103:            /**
0104:             * enable DNS lookups.
0105:             */
0106:            private boolean enableLookups = false;
0107:
0108:            /**
0109:             * The lifecycle event support for this component.
0110:             */
0111:            protected LifecycleSupport lifecycle = new LifecycleSupport(this );
0112:
0113:            /**
0114:             * The minimum number of processors to start at initialization time.
0115:             */
0116:            protected int minProcessors = 5;
0117:
0118:            /**
0119:             * The maximum number of processors allowed, or <0 for unlimited.
0120:             */
0121:            private int maxProcessors = 20;
0122:
0123:            /**
0124:             * Timeout value on the incoming connection.
0125:             * Note : a value of 0 means no timeout.
0126:             */
0127:            private int connectionTimeout = -1;
0128:
0129:            /**
0130:             * Linger value to be used on socket close.
0131:             * Note : a value of -1 means no linger used on close.
0132:             */
0133:            private int connectionLinger = -1;
0134:
0135:            /**
0136:             * The port number on which we listen for ajp13 requests.
0137:             */
0138:            private int port = 8009;
0139:
0140:            /**
0141:             * The set of processors that have been created but are not currently
0142:             * being used to process a request.
0143:             */
0144:            private Stack processors = new Stack();
0145:
0146:            /**
0147:             * The request scheme that will be set on all requests received
0148:             * through this connector.
0149:             */
0150:            private String scheme = "http";
0151:
0152:            /**
0153:             * The secure connection flag that will be set on all requests received
0154:             * through this connector.
0155:             */
0156:            private boolean secure = false;
0157:
0158:            /**
0159:             * The server socket through which we listen for incoming TCP connections.
0160:             */
0161:            private ServerSocket serverSocket = null;
0162:
0163:            /**
0164:             * The string manager for this package.
0165:             */
0166:            private StringManager sm = StringManager
0167:                    .getManager(Constants.PACKAGE);
0168:
0169:            /**
0170:             * Has this component been started yet?
0171:             */
0172:            private boolean started = false;
0173:
0174:            /**
0175:             * The shutdown signal to our background thread
0176:             */
0177:            private boolean stopped = false;
0178:
0179:            /**
0180:             * The background thread.
0181:             */
0182:            private Thread thread = null;
0183:
0184:            /**
0185:             * This connector's thread group.
0186:             */
0187:            private ThreadGroup threadGroup = null;
0188:
0189:            /**
0190:             * The name to register for the background thread.
0191:             */
0192:            private String threadName = null;
0193:
0194:            /**
0195:             * A thread that periodically logs debug info if debug > 0.
0196:             */
0197:            private DebugThread debugThread = null;
0198:
0199:            /**
0200:             * The thread synchronization object.
0201:             */
0202:            private Object threadSync = new Object();
0203:
0204:            private Ajp13Logger logger = new Ajp13Logger();
0205:
0206:            /**
0207:             * The service which which the connector is associated
0208:             */
0209:            private Service service = null;
0210:
0211:            private String secret = null;
0212:
0213:            /**
0214:             * Tomcat authentication flag. If true, the authnetication is done by
0215:             * Tomcat, otherwise, it is done by the native webserver.
0216:             */
0217:            private boolean tomcatAuthentication = true;
0218:
0219:            // ------------------------------------------------------------- Properties
0220:
0221:            /**
0222:             * Return the connection timeout for this Connector.
0223:             */
0224:            public int getConnectionTimeout() {
0225:
0226:                return (connectionTimeout);
0227:
0228:            }
0229:
0230:            /**
0231:             * Set the connection timeout for this Connector.
0232:             *
0233:             * @param connectionTimeout The new connection timeout
0234:             */
0235:            public void setConnectionTimeout(int connectionTimeout) {
0236:
0237:                this .connectionTimeout = connectionTimeout;
0238:
0239:            }
0240:
0241:            /**
0242:             * Return the connection linger settings for this Connector.
0243:             */
0244:            public int getConnectionLinger() {
0245:
0246:                return (connectionLinger);
0247:
0248:            }
0249:
0250:            /**
0251:             * Set the connection linger for this Connector.
0252:             *
0253:             * @param connectionLinger The new connection linger
0254:             */
0255:            public void setConnectionLinger(int connectionLinger) {
0256:
0257:                this .connectionLinger = connectionLinger;
0258:
0259:            }
0260:
0261:            public void setSecret(String s) {
0262:                secret = s;
0263:            }
0264:
0265:            public String getSecret() {
0266:                return secret;
0267:            }
0268:
0269:            /**
0270:             * Return the accept count for this Connector.
0271:             */
0272:            public int getAcceptCount() {
0273:
0274:                return (acceptCount);
0275:
0276:            }
0277:
0278:            /**
0279:             * Set the accept count for this Connector.
0280:             *
0281:             * @param count The new accept count
0282:             */
0283:            public void setAcceptCount(int count) {
0284:
0285:                this .acceptCount = count;
0286:
0287:            }
0288:
0289:            /**
0290:             * Return the bind IP address for this Connector.
0291:             */
0292:            public String getAddress() {
0293:
0294:                return (this .address);
0295:
0296:            }
0297:
0298:            /**
0299:             * Set the bind IP address for this Connector.
0300:             *
0301:             * @param address The bind IP address
0302:             */
0303:            public void setAddress(String address) {
0304:
0305:                this .address = address;
0306:
0307:            }
0308:
0309:            /**
0310:             * Is this connector available for processing requests?
0311:             */
0312:            public boolean isAvailable() {
0313:
0314:                return (started);
0315:
0316:            }
0317:
0318:            /**
0319:             * Return the input buffer size for this Connector.
0320:             */
0321:            public int getBufferSize() {
0322:
0323:                return (this .bufferSize);
0324:
0325:            }
0326:
0327:            /**
0328:             * Set the input buffer size for this Connector.
0329:             *
0330:             * @param bufferSize The new input buffer size.
0331:             */
0332:            public void setBufferSize(int bufferSize) {
0333:
0334:                this .bufferSize = bufferSize;
0335:
0336:            }
0337:
0338:            /**
0339:             * Return the Container used for processing requests received by this
0340:             * Connector.
0341:             */
0342:            public Container getContainer() {
0343:
0344:                return (container);
0345:
0346:            }
0347:
0348:            /**
0349:             * Set the Container used for processing requests received by this
0350:             * Connector.
0351:             *
0352:             * @param container The new Container to use
0353:             */
0354:            public void setContainer(Container container) {
0355:
0356:                this .container = container;
0357:
0358:            }
0359:
0360:            /**
0361:             * Return the current number of processors that have been created.
0362:             */
0363:            public int getCurProcessors() {
0364:
0365:                return (curProcessors);
0366:
0367:            }
0368:
0369:            /**
0370:             * Return the debugging detail level for this component.
0371:             */
0372:            public int getDebug() {
0373:
0374:                return (debug);
0375:
0376:            }
0377:
0378:            /**
0379:             * Set the debugging detail level for this component.
0380:             *
0381:             * @param debug The new debugging detail level
0382:             */
0383:            public void setDebug(int debug) {
0384:
0385:                this .debug = debug;
0386:
0387:            }
0388:
0389:            /**
0390:             * Return the "enable DNS lookups" flag.
0391:             */
0392:            public boolean getEnableLookups() {
0393:                return this .enableLookups;
0394:            }
0395:
0396:            /**
0397:             * Set the "enable DNS lookups" flag.
0398:             *
0399:             * @param enableLookups The new "enable DNS lookups" flag value
0400:             */
0401:            public void setEnableLookups(boolean enableLookups) {
0402:                this .enableLookups = enableLookups;
0403:            }
0404:
0405:            /**
0406:             * Return the port number to which a request should be redirected if
0407:             * it comes in on a non-SSL port and is subject to a security constraint
0408:             * with a transport guarantee that requires SSL.
0409:             */
0410:            public int getRedirectPort() {
0411:                return this .redirectPort;
0412:            }
0413:
0414:            /**
0415:             * Set the redirect port number.
0416:             *
0417:             * @param redirectPort The redirect port number (non-SSL to SSL)
0418:             */
0419:            public void setRedirectPort(int redirectPort) {
0420:                this .redirectPort = redirectPort;
0421:            }
0422:
0423:            /**
0424:             * Return the server socket factory used by this Container.
0425:             */
0426:            public ServerSocketFactory getFactory() {
0427:
0428:                if (this .factory == null) {
0429:                    synchronized (this ) {
0430:                        this .factory = new DefaultServerSocketFactory();
0431:                    }
0432:                }
0433:                return (this .factory);
0434:
0435:            }
0436:
0437:            /**
0438:             * Set the server socket factory used by this Container.
0439:             *
0440:             * @param factory The new server socket factory
0441:             */
0442:            public void setFactory(ServerSocketFactory factory) {
0443:
0444:                this .factory = factory;
0445:
0446:            }
0447:
0448:            /**
0449:             * Return descriptive information about this Connector implementation.
0450:             */
0451:            public String getInfo() {
0452:
0453:                return (info);
0454:
0455:            }
0456:
0457:            /**
0458:             * Return the minimum number of processors to start at initialization.
0459:             */
0460:            public int getMinProcessors() {
0461:
0462:                return (minProcessors);
0463:
0464:            }
0465:
0466:            /**
0467:             * Set the minimum number of processors to start at initialization.
0468:             *
0469:             * @param minProcessors The new minimum processors
0470:             */
0471:            public void setMinProcessors(int minProcessors) {
0472:
0473:                this .minProcessors = minProcessors;
0474:
0475:            }
0476:
0477:            /**
0478:             * Return the maximum number of processors allowed, or <0 for unlimited.
0479:             */
0480:            public int getMaxProcessors() {
0481:
0482:                return (maxProcessors);
0483:
0484:            }
0485:
0486:            /**
0487:             * Set the maximum number of processors allowed, or <0 for unlimited.
0488:             *
0489:             * @param maxProcessors The new maximum processors
0490:             */
0491:            public void setMaxProcessors(int maxProcessors) {
0492:
0493:                this .maxProcessors = maxProcessors;
0494:
0495:            }
0496:
0497:            /**
0498:             * Return the port number on which we listen for AJP13 requests.
0499:             */
0500:            public int getPort() {
0501:
0502:                return (this .port);
0503:
0504:            }
0505:
0506:            /**
0507:             * Set the port number on which we listen for AJP13 requests.
0508:             *
0509:             * @param port The new port number
0510:             */
0511:            public void setPort(int port) {
0512:
0513:                this .port = port;
0514:
0515:            }
0516:
0517:            /**
0518:             * Return the scheme that will be assigned to requests received
0519:             * through this connector.  Default value is "http".
0520:             */
0521:            public String getScheme() {
0522:
0523:                return (this .scheme);
0524:
0525:            }
0526:
0527:            /**
0528:             * Set the scheme that will be assigned to requests received through
0529:             * this connector.
0530:             *
0531:             * @param scheme The new scheme
0532:             */
0533:            public void setScheme(String scheme) {
0534:
0535:                this .scheme = scheme;
0536:
0537:            }
0538:
0539:            /**
0540:             * Return the secure connection flag that will be assigned to requests
0541:             * received through this connector.  Default value is "false".
0542:             */
0543:            public boolean getSecure() {
0544:
0545:                return (this .secure);
0546:
0547:            }
0548:
0549:            /**
0550:             * Set the secure connection flag that will be assigned to requests
0551:             * received through this connector.
0552:             *
0553:             * @param secure The new secure connection flag
0554:             */
0555:            public void setSecure(boolean secure) {
0556:
0557:                this .secure = secure;
0558:
0559:            }
0560:
0561:            /**
0562:             * Returns the <code>Service</code> with which we are associated.
0563:             */
0564:            public Service getService() {
0565:                return service;
0566:            }
0567:
0568:            /**
0569:             * Set the <code>Service</code> with which we are associated.
0570:             */
0571:            public void setService(Service service) {
0572:                this .service = service;
0573:            }
0574:
0575:            /**
0576:             * Get the value of the tomcatAuthentication flag.
0577:             */
0578:            public boolean getTomcatAuthentication() {
0579:                return tomcatAuthentication;
0580:            }
0581:
0582:            /**
0583:             * Set the value of the tomcatAuthentication flag.
0584:             */
0585:            public void setTomcatAuthentication(boolean tomcatAuthentication) {
0586:                this .tomcatAuthentication = tomcatAuthentication;
0587:            }
0588:
0589:            // --------------------------------------------------------- Public Methods
0590:
0591:            /**
0592:             * Create (or allocate) and return a Request object suitable for
0593:             * specifying the contents of a Request to the responsible Container.
0594:             */
0595:            public Request createRequest() {
0596:
0597:                Ajp13Request request = new Ajp13Request(this );
0598:                request.setConnector(this );
0599:                return (request);
0600:
0601:            }
0602:
0603:            /**
0604:             * Create (or allocate) and return a Response object suitable for
0605:             * receiving the contents of a Response from the responsible Container.
0606:             */
0607:            public Response createResponse() {
0608:
0609:                Ajp13Response response = new Ajp13Response();
0610:                response.setConnector(this );
0611:                return (response);
0612:
0613:            }
0614:
0615:            /**
0616:             * Invoke a pre-startup initialization. This is used to allow connectors
0617:             * to bind to restricted ports under Unix operating environments.
0618:             * ServerSocket (we start as root and change user? or I miss something?).
0619:             */
0620:            public void initialize() throws LifecycleException {
0621:            }
0622:
0623:            // -------------------------------------------------------- Package Methods
0624:
0625:            /**
0626:             * Recycle the specified Processor so that it can be used again.
0627:             *
0628:             * @param processor The processor to be recycled
0629:             */
0630:            void recycle(Ajp13Processor processor) {
0631:
0632:                synchronized (processors) {
0633:                    if (debug > 0) {
0634:                        logger
0635:                                .log("added processor to available processors, available="
0636:                                        + processors.size());
0637:                    }
0638:                    processors.push(processor);
0639:                }
0640:
0641:            }
0642:
0643:            // -------------------------------------------------------- Private Methods
0644:
0645:            /**
0646:             * Create (or allocate) and return an available processor for use in
0647:             * processing a specific AJP13 request, if possible.  If the maximum
0648:             * allowed processors have already been created and are in use, return
0649:             * <code>null</code> instead.
0650:             */
0651:            private Ajp13Processor createProcessor() {
0652:
0653:                synchronized (processors) {
0654:                    if (processors.size() > 0)
0655:                        return ((Ajp13Processor) processors.pop());
0656:                    if ((maxProcessors > 0) && (curProcessors < maxProcessors))
0657:                        return (newProcessor());
0658:                    else
0659:                        return (null);
0660:                }
0661:
0662:            }
0663:
0664:            /**
0665:             * Create and return a new processor suitable for processing AJP13
0666:             * requests and returning the corresponding responses.
0667:             */
0668:            private Ajp13Processor newProcessor() {
0669:
0670:                Ajp13Processor processor = new Ajp13Processor(this ,
0671:                        curProcessors++, threadGroup);
0672:                if (processor instanceof  Lifecycle) {
0673:                    try {
0674:                        ((Lifecycle) processor).start();
0675:                    } catch (LifecycleException e) {
0676:                        logger.log("newProcessor", e);
0677:                        curProcessors--;
0678:                        return (null);
0679:                    }
0680:                }
0681:                created.addElement(processor);
0682:                return (processor);
0683:
0684:            }
0685:
0686:            /**
0687:             * Open and return the server socket for this Connector.  If an IP
0688:             * address has been specified, the socket will be opened only on that
0689:             * address; otherwise it will be opened on all addresses.
0690:             *
0691:             * @exception IOException if an input/output error occurs
0692:             */
0693:            private ServerSocket open() throws IOException {
0694:
0695:                // Acquire the server socket factory for this Connector
0696:                ServerSocketFactory factory = getFactory();
0697:
0698:                // If no address is specified, open a connection on all addresses
0699:                if (address == null) {
0700:                    logger.log(sm.getString("ajp13Connector.allAddresses"));
0701:                    try {
0702:                        return (factory.createSocket(port, acceptCount));
0703:                    } catch (Exception ex) {
0704:                        ex.printStackTrace();
0705:                        return null;
0706:                    }
0707:                }
0708:
0709:                // Open a server socket on the specified address
0710:                try {
0711:                    InetAddress is = InetAddress.getByName(address);
0712:                    logger.log(sm
0713:                            .getString("ajp13Connector.anAddress", address));
0714:                    return (factory.createSocket(port, acceptCount, is));
0715:                } catch (Exception e) {
0716:                    try {
0717:                        logger.log(sm.getString("ajp13Connector.noAddress",
0718:                                address));
0719:                        return (factory.createSocket(port, acceptCount));
0720:                    } catch (Exception e1) {
0721:                        e1.printStackTrace();
0722:                        return null;
0723:                    }
0724:                }
0725:
0726:            }
0727:
0728:            // ---------------------------------------------- Background Thread Methods
0729:
0730:            /**
0731:             * The background thread that listens for incoming TCP/IP connections and
0732:             * hands them off to an appropriate processor.
0733:             */
0734:            public void run() {
0735:
0736:                // Loop until we receive a shutdown command
0737:                while (!stopped) {
0738:
0739:                    // Accept the next incoming connection from the server socket
0740:                    Socket socket = null;
0741:                    try {
0742:                        if (debug > 0) {
0743:                            logger.log("accepting socket...");
0744:                        }
0745:
0746:                        socket = serverSocket.accept();
0747:
0748:                        if (debug > 0) {
0749:                            logger
0750:                                    .log("accepted socket, assigning to processor.");
0751:                        }
0752:
0753:                        /* Warning :
0754:                         * 
0755:                         * To be able to close more quickly a connection, it's recommanded
0756:                         * to set linger to a small value.
0757:                         * 
0758:                         * AJP13 connection SHOULD be closed under webserver responsability and 
0759:                         * in such case it's safe to close socket on Tomcat side without delay,
0760:                         * which may be also the case for HTTP connectors.
0761:                         * 
0762:                         * I (henri) recommand to set Linger to 0, making socket closed immediatly
0763:                         * so the OS will free faster the underlying io descriptor and resources.
0764:                         * It's very important under heavy load !
0765:                         */
0766:
0767:                        if (connectionLinger < 0)
0768:                            socket.setSoLinger(false, 0);
0769:                        else
0770:                            socket.setSoLinger(true, connectionLinger);
0771:
0772:                        /* We don't need it since it's the native side which 
0773:                         * will set the connection with keep alive
0774:                         * if specified in workers.properties.
0775:                         * 
0776:                         * socket.setKeepAlive(true); 
0777:                         */
0778:
0779:                        /* Warning :
0780:                         * 
0781:                         * AJP13 shouldn't use socket timeout on tomcat site since
0782:                         * when Tomcat close a connection after a timeout is reached
0783:                         * the socket stay in half-closed state until the webserver
0784:                         * try to send a request to tomcat and detect the socket close
0785:                         * when it will try to read the reply.
0786:                         * 
0787:                         * On many Unix platforms the write() call didn't told
0788:                         * webserver that the socket is closed.
0789:                         */
0790:
0791:                        if (connectionTimeout >= 0) {
0792:                            socket.setSoTimeout(connectionTimeout);
0793:                        }
0794:                    } catch (AccessControlException ace) {
0795:                        logger.log("socket accept security exception: "
0796:                                + ace.getMessage());
0797:                        continue;
0798:                    } catch (IOException e) {
0799:                        if (started && !stopped)
0800:                            logger.log("accept: ", e);
0801:                        try {
0802:                            if (serverSocket != null) {
0803:                                serverSocket.close();
0804:                            }
0805:                            if (stopped) {
0806:                                if (debug > 0) {
0807:                                    logger.log("run():  stopped, so breaking");
0808:                                }
0809:                                break;
0810:                            } else {
0811:                                if (debug > 0) {
0812:                                    logger.log("run():  not stopped, "
0813:                                            + "so reopening server socket");
0814:                                }
0815:                                serverSocket = open();
0816:                            }
0817:                        } catch (IOException ex) {
0818:                            // If reopening fails, exit
0819:                            logger.log("socket reopen: ", ex);
0820:                            break;
0821:                        }
0822:                        continue;
0823:                    }
0824:
0825:                    // Hand this socket off to an appropriate processor
0826:                    if (debug > 0) {
0827:                        synchronized (processors) {
0828:                            logger
0829:                                    .log("about to create a processor, available="
0830:                                            + processors.size()
0831:                                            + ", created="
0832:                                            + created.size()
0833:                                            + ", maxProcessors="
0834:                                            + maxProcessors);
0835:                        }
0836:                    }
0837:                    Ajp13Processor processor = createProcessor();
0838:                    if (processor == null) {
0839:                        try {
0840:                            logger.log(sm
0841:                                    .getString("ajp13Connector.noProcessor"));
0842:                            socket.close();
0843:                        } catch (IOException e) {
0844:                            ;
0845:                        }
0846:                        continue;
0847:                    }
0848:                    processor.assign(socket);
0849:
0850:                    // The processor will recycle itself when it finishes
0851:
0852:                }
0853:
0854:                // Notify the threadStop() method that we have shut ourselves down
0855:                synchronized (threadSync) {
0856:                    threadSync.notifyAll();
0857:                }
0858:
0859:            }
0860:
0861:            /**
0862:             * Start the background processing thread.
0863:             */
0864:            private void threadStart() {
0865:
0866:                logger.log(sm.getString("ajp13Connector.starting"));
0867:
0868:                thread = new Thread(threadGroup, this , threadName);
0869:                thread.setDaemon(true);
0870:                thread.start();
0871:
0872:            }
0873:
0874:            /**
0875:             * Stop the background processing thread.
0876:             */
0877:            private void threadStop() {
0878:
0879:                logger.log(sm.getString("ajp13Connector.stopping"));
0880:
0881:                stopped = true;
0882:                synchronized (threadSync) {
0883:                    try {
0884:                        threadSync.wait(5000);
0885:                    } catch (InterruptedException e) {
0886:                        ;
0887:                    }
0888:                }
0889:                thread = null;
0890:
0891:            }
0892:
0893:            // ------------------------------------------------------ Lifecycle Methods
0894:
0895:            /**
0896:             * Add a lifecycle event listener to this component.
0897:             *
0898:             * @param listener The listener to add
0899:             */
0900:            public void addLifecycleListener(LifecycleListener listener) {
0901:
0902:                lifecycle.addLifecycleListener(listener);
0903:
0904:            }
0905:
0906:            /**
0907:             * Get the lifecycle listeners associated with this lifecycle. If this
0908:             * Lifecycle has no listeners registered, a zero-length array is returned.
0909:             */
0910:            public LifecycleListener[] findLifecycleListeners() {
0911:                return null; // FIXME: lifecycle.findLifecycleListeners();
0912:            }
0913:
0914:            /**
0915:             * Remove a lifecycle event listener from this component.
0916:             *
0917:             * @param listener The listener to add
0918:             */
0919:            public void removeLifecycleListener(LifecycleListener listener) {
0920:
0921:                lifecycle.removeLifecycleListener(listener);
0922:
0923:            }
0924:
0925:            /**
0926:             * Begin processing requests via this Connector.
0927:             *
0928:             * @exception LifecycleException if a fatal startup error occurs
0929:             */
0930:            public void start() throws LifecycleException {
0931:
0932:                // Validate and update our current state
0933:                if (started)
0934:                    throw new LifecycleException(sm
0935:                            .getString("ajp13Connector.alreadyStarted"));
0936:
0937:                if (debug > 0) {
0938:                    debugThread = new DebugThread();
0939:                    debugThread.setDaemon(true);
0940:                    debugThread.start();
0941:                }
0942:
0943:                threadName = "Ajp13Connector[" + port + "]";
0944:                threadGroup = new ThreadGroup(threadName);
0945:                threadGroup.setDaemon(true);
0946:                logger.setConnector(this );
0947:                logger.setName(threadName);
0948:                lifecycle.fireLifecycleEvent(START_EVENT, null);
0949:                started = true;
0950:
0951:                // Establish a server socket on the specified port
0952:                try {
0953:                    serverSocket = open();
0954:                } catch (IOException e) {
0955:                    throw new LifecycleException(threadName + ".open", e);
0956:                }
0957:
0958:                // Start our background thread
0959:                threadStart();
0960:
0961:                // Create the specified minimum number of processors
0962:                while (curProcessors < minProcessors) {
0963:                    if ((maxProcessors > 0) && (curProcessors >= maxProcessors))
0964:                        break;
0965:                    Ajp13Processor processor = newProcessor();
0966:                    recycle(processor);
0967:                }
0968:
0969:            }
0970:
0971:            /**
0972:             * Terminate processing requests via this Connector.
0973:             *
0974:             * @exception LifecycleException if a fatal shutdown error occurs
0975:             */
0976:            public void stop() throws LifecycleException {
0977:
0978:                // Validate and update our current state
0979:                if (!started)
0980:                    throw new LifecycleException(sm
0981:                            .getString("ajp13Connector.notStarted"));
0982:                lifecycle.fireLifecycleEvent(STOP_EVENT, null);
0983:                started = false;
0984:
0985:                // Gracefully shut down all processors we have created
0986:                for (int i = created.size() - 1; i >= 0; i--) {
0987:                    Ajp13Processor processor = (Ajp13Processor) created
0988:                            .elementAt(i);
0989:                    if (processor instanceof  Lifecycle) {
0990:                        try {
0991:                            ((Lifecycle) processor).stop();
0992:                        } catch (LifecycleException e) {
0993:                            logger.log("Ajp13Connector.stop", e);
0994:                        }
0995:                    }
0996:                }
0997:
0998:                // Stop our background thread
0999:                threadStop();
1000:
1001:                // Close the server socket we were using
1002:                if (serverSocket != null) {
1003:                    try {
1004:                        serverSocket.close();
1005:                    } catch (IOException e) {
1006:                        ;
1007:                    }
1008:                    serverSocket = null;
1009:                }
1010:
1011:            }
1012:
1013:            /**
1014:             * Debugging thread used to debug thread activity in this
1015:             * connector.
1016:             */
1017:            private class DebugThread extends Thread {
1018:                public void run() {
1019:                    while (true) {
1020:                        try {
1021:                            sleep(60 * 1000);
1022:                        } catch (InterruptedException e) {
1023:                            break;
1024:                        }
1025:                        logger.log("active threads="
1026:                                + threadGroup.activeCount());
1027:                        System.out
1028:                                .println("===================================");
1029:                        System.out.println("Ajp13Connector active threads="
1030:                                + threadGroup.activeCount());
1031:                        threadGroup.list();
1032:                        System.out
1033:                                .println("===================================");
1034:                    }
1035:                }
1036:            }
1037:
1038:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.