PageRenderTime 81ms CodeModel.GetById 9ms RepoModel.GetById 2ms app.codeStats 1ms

/java/org/apache/tomcat/util/net/AprEndpoint.java

https://github.com/enson16855/tomcat
Java | 2410 lines | 1520 code | 283 blank | 607 comment | 409 complexity | df08c18d2ca87283827c555d542e3def MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.tomcat.util.net;
  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.Map;
  21. import java.util.concurrent.ConcurrentHashMap;
  22. import java.util.concurrent.Executor;
  23. import java.util.concurrent.RejectedExecutionException;
  24. import java.util.concurrent.atomic.AtomicInteger;
  25. import org.apache.juli.logging.Log;
  26. import org.apache.juli.logging.LogFactory;
  27. import org.apache.tomcat.jni.Address;
  28. import org.apache.tomcat.jni.Error;
  29. import org.apache.tomcat.jni.File;
  30. import org.apache.tomcat.jni.Library;
  31. import org.apache.tomcat.jni.OS;
  32. import org.apache.tomcat.jni.Poll;
  33. import org.apache.tomcat.jni.Pool;
  34. import org.apache.tomcat.jni.SSL;
  35. import org.apache.tomcat.jni.SSLContext;
  36. import org.apache.tomcat.jni.SSLSocket;
  37. import org.apache.tomcat.jni.Sockaddr;
  38. import org.apache.tomcat.jni.Socket;
  39. import org.apache.tomcat.jni.Status;
  40. import org.apache.tomcat.util.ExceptionUtils;
  41. import org.apache.tomcat.util.net.AbstractEndpoint.Acceptor.AcceptorState;
  42. import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
  43. /**
  44. * APR tailored thread pool, providing the following services:
  45. * <ul>
  46. * <li>Socket acceptor thread</li>
  47. * <li>Socket poller thread</li>
  48. * <li>Sendfile thread</li>
  49. * <li>Worker threads pool</li>
  50. * </ul>
  51. *
  52. * When switching to Java 5, there's an opportunity to use the virtual
  53. * machine's thread pool.
  54. *
  55. * @author Mladen Turk
  56. * @author Remy Maucherat
  57. */
  58. public class AprEndpoint extends AbstractEndpoint<Long> {
  59. // -------------------------------------------------------------- Constants
  60. private static final Log log = LogFactory.getLog(AprEndpoint.class);
  61. // ----------------------------------------------------------------- Fields
  62. /**
  63. * Root APR memory pool.
  64. */
  65. protected long rootPool = 0;
  66. /**
  67. * Server socket "pointer".
  68. */
  69. protected long serverSock = 0;
  70. /**
  71. * APR memory pool for the server socket.
  72. */
  73. protected long serverSockPool = 0;
  74. /**
  75. * SSL context.
  76. */
  77. protected long sslContext = 0;
  78. private final Map<Long,AprSocketWrapper> connections = new ConcurrentHashMap<>();
  79. // ------------------------------------------------------------ Constructor
  80. public AprEndpoint() {
  81. // Need to override the default for maxConnections to align it with what
  82. // was pollerSize (before the two were merged)
  83. setMaxConnections(8 * 1024);
  84. }
  85. // ------------------------------------------------------------- Properties
  86. /**
  87. * Defer accept.
  88. */
  89. protected boolean deferAccept = true;
  90. public void setDeferAccept(boolean deferAccept) { this.deferAccept = deferAccept; }
  91. @Override
  92. public boolean getDeferAccept() { return deferAccept; }
  93. /**
  94. * Size of the sendfile (= concurrent files which can be served).
  95. */
  96. protected int sendfileSize = 1 * 1024;
  97. public void setSendfileSize(int sendfileSize) { this.sendfileSize = sendfileSize; }
  98. public int getSendfileSize() { return sendfileSize; }
  99. /**
  100. * Handling of accepted sockets.
  101. */
  102. protected Handler handler = null;
  103. public void setHandler(Handler handler ) { this.handler = handler; }
  104. public Handler getHandler() { return handler; }
  105. /**
  106. * Poll interval, in microseconds. The smaller the value, the more CPU the poller
  107. * will use, but the more responsive to activity it will be.
  108. */
  109. protected int pollTime = 2000;
  110. public int getPollTime() { return pollTime; }
  111. public void setPollTime(int pollTime) { if (pollTime > 0) { this.pollTime = pollTime; } }
  112. /**
  113. * Use sendfile for sending static files.
  114. */
  115. protected boolean useSendfile = false;
  116. /*
  117. * When the endpoint is created and configured, the APR library will not
  118. * have been initialised. This flag is used to determine if the default
  119. * value of useSendFile should be changed if the APR library indicates it
  120. * supports send file once it has been initialised. If useSendFile is set
  121. * by configuration, that configuration will always take priority.
  122. */
  123. private boolean useSendFileSet = false;
  124. public void setUseSendfile(boolean useSendfile) {
  125. useSendFileSet = true;
  126. this.useSendfile = useSendfile;
  127. }
  128. @Override
  129. public boolean getUseSendfile() { return useSendfile; }
  130. /**
  131. * Allow comet request handling.
  132. */
  133. protected boolean useComet = true;
  134. public void setUseComet(boolean useComet) { this.useComet = useComet; }
  135. @Override
  136. public boolean getUseComet() { return useComet; }
  137. @Override
  138. public boolean getUseCometTimeout() { return false; } // Not supported
  139. @Override
  140. public boolean getUsePolling() { return true; } // Always supported
  141. /**
  142. * Sendfile thread count.
  143. */
  144. protected int sendfileThreadCount = 0;
  145. public void setSendfileThreadCount(int sendfileThreadCount) { this.sendfileThreadCount = sendfileThreadCount; }
  146. public int getSendfileThreadCount() { return sendfileThreadCount; }
  147. /**
  148. * The socket poller.
  149. */
  150. protected Poller poller = null;
  151. public Poller getPoller() {
  152. return poller;
  153. }
  154. /**
  155. * The static file sender.
  156. */
  157. protected Sendfile sendfile = null;
  158. public Sendfile getSendfile() {
  159. return sendfile;
  160. }
  161. /**
  162. * SSL protocols.
  163. */
  164. protected String SSLProtocol = "all";
  165. public String getSSLProtocol() { return SSLProtocol; }
  166. public void setSSLProtocol(String SSLProtocol) { this.SSLProtocol = SSLProtocol; }
  167. /**
  168. * SSL password (if a cert is encrypted, and no password has been provided, a callback
  169. * will ask for a password).
  170. */
  171. protected String SSLPassword = null;
  172. public String getSSLPassword() { return SSLPassword; }
  173. public void setSSLPassword(String SSLPassword) { this.SSLPassword = SSLPassword; }
  174. /**
  175. * SSL cipher suite.
  176. */
  177. protected String SSLCipherSuite = "ALL";
  178. public String getSSLCipherSuite() { return SSLCipherSuite; }
  179. public void setSSLCipherSuite(String SSLCipherSuite) { this.SSLCipherSuite = SSLCipherSuite; }
  180. /**
  181. * SSL certificate file.
  182. */
  183. protected String SSLCertificateFile = null;
  184. public String getSSLCertificateFile() { return SSLCertificateFile; }
  185. public void setSSLCertificateFile(String SSLCertificateFile) { this.SSLCertificateFile = SSLCertificateFile; }
  186. /**
  187. * SSL certificate key file.
  188. */
  189. protected String SSLCertificateKeyFile = null;
  190. public String getSSLCertificateKeyFile() { return SSLCertificateKeyFile; }
  191. public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { this.SSLCertificateKeyFile = SSLCertificateKeyFile; }
  192. /**
  193. * SSL certificate chain file.
  194. */
  195. protected String SSLCertificateChainFile = null;
  196. public String getSSLCertificateChainFile() { return SSLCertificateChainFile; }
  197. public void setSSLCertificateChainFile(String SSLCertificateChainFile) { this.SSLCertificateChainFile = SSLCertificateChainFile; }
  198. /**
  199. * SSL CA certificate path.
  200. */
  201. protected String SSLCACertificatePath = null;
  202. public String getSSLCACertificatePath() { return SSLCACertificatePath; }
  203. public void setSSLCACertificatePath(String SSLCACertificatePath) { this.SSLCACertificatePath = SSLCACertificatePath; }
  204. /**
  205. * SSL CA certificate file.
  206. */
  207. protected String SSLCACertificateFile = null;
  208. public String getSSLCACertificateFile() { return SSLCACertificateFile; }
  209. public void setSSLCACertificateFile(String SSLCACertificateFile) { this.SSLCACertificateFile = SSLCACertificateFile; }
  210. /**
  211. * SSL CA revocation path.
  212. */
  213. protected String SSLCARevocationPath = null;
  214. public String getSSLCARevocationPath() { return SSLCARevocationPath; }
  215. public void setSSLCARevocationPath(String SSLCARevocationPath) { this.SSLCARevocationPath = SSLCARevocationPath; }
  216. /**
  217. * SSL CA revocation file.
  218. */
  219. protected String SSLCARevocationFile = null;
  220. public String getSSLCARevocationFile() { return SSLCARevocationFile; }
  221. public void setSSLCARevocationFile(String SSLCARevocationFile) { this.SSLCARevocationFile = SSLCARevocationFile; }
  222. /**
  223. * SSL verify client.
  224. */
  225. protected String SSLVerifyClient = "none";
  226. public String getSSLVerifyClient() { return SSLVerifyClient; }
  227. public void setSSLVerifyClient(String SSLVerifyClient) { this.SSLVerifyClient = SSLVerifyClient; }
  228. /**
  229. * SSL verify depth.
  230. */
  231. protected int SSLVerifyDepth = 10;
  232. public int getSSLVerifyDepth() { return SSLVerifyDepth; }
  233. public void setSSLVerifyDepth(int SSLVerifyDepth) { this.SSLVerifyDepth = SSLVerifyDepth; }
  234. /**
  235. * SSL allow insecure renegotiation for the the client that does not
  236. * support the secure renegotiation.
  237. */
  238. protected boolean SSLInsecureRenegotiation = false;
  239. public void setSSLInsecureRenegotiation(boolean SSLInsecureRenegotiation) { this.SSLInsecureRenegotiation = SSLInsecureRenegotiation; }
  240. public boolean getSSLInsecureRenegotiation() { return SSLInsecureRenegotiation; }
  241. protected boolean SSLHonorCipherOrder = false;
  242. /**
  243. * Set to <code>true</code> to enforce the <i>server's</i> cipher order
  244. * instead of the default which is to allow the client to choose a
  245. * preferred cipher.
  246. */
  247. public void setSSLHonorCipherOrder(boolean SSLHonorCipherOrder) { this.SSLHonorCipherOrder = SSLHonorCipherOrder; }
  248. public boolean getSSLHonorCipherOrder() { return SSLHonorCipherOrder; }
  249. /**
  250. * Disables compression of the SSL stream. This thwarts CRIME attack
  251. * and possibly improves performance by not compressing uncompressible
  252. * content such as JPEG, etc.
  253. */
  254. protected boolean SSLDisableCompression = false;
  255. /**
  256. * Set to <code>true</code> to disable SSL compression. This thwarts CRIME
  257. * attack.
  258. */
  259. public void setSSLDisableCompression(boolean SSLDisableCompression) { this.SSLDisableCompression = SSLDisableCompression; }
  260. public boolean getSSLDisableCompression() { return SSLDisableCompression; }
  261. /**
  262. * Port in use.
  263. */
  264. @Override
  265. public int getLocalPort() {
  266. long s = serverSock;
  267. if (s == 0) {
  268. return -1;
  269. } else {
  270. long sa;
  271. try {
  272. sa = Address.get(Socket.APR_LOCAL, s);
  273. Sockaddr addr = Address.getInfo(sa);
  274. return addr.port;
  275. } catch (Exception e) {
  276. return -1;
  277. }
  278. }
  279. }
  280. @Override
  281. public String[] getCiphersUsed() {
  282. // TODO : Investigate if it is possible to extract the current list of
  283. // available ciphers. Native code changes will be required.
  284. return new String[] { getSSLCipherSuite() };
  285. }
  286. // --------------------------------------------------------- Public Methods
  287. /**
  288. * Number of keepalive sockets.
  289. */
  290. public int getKeepAliveCount() {
  291. if (poller == null) {
  292. return 0;
  293. }
  294. return poller.getConnectionCount();
  295. }
  296. /**
  297. * Number of sendfile sockets.
  298. */
  299. public int getSendfileCount() {
  300. if (sendfile == null) {
  301. return 0;
  302. }
  303. return sendfile.getSendfileCount();
  304. }
  305. // ----------------------------------------------- Public Lifecycle Methods
  306. /**
  307. * Initialize the endpoint.
  308. */
  309. @Override
  310. public void bind() throws Exception {
  311. // Create the root APR memory pool
  312. try {
  313. rootPool = Pool.create(0);
  314. } catch (UnsatisfiedLinkError e) {
  315. throw new Exception(sm.getString("endpoint.init.notavail"));
  316. }
  317. // Create the pool for the server socket
  318. serverSockPool = Pool.create(rootPool);
  319. // Create the APR address that will be bound
  320. String addressStr = null;
  321. if (getAddress() != null) {
  322. addressStr = getAddress().getHostAddress();
  323. }
  324. int family = Socket.APR_INET;
  325. if (Library.APR_HAVE_IPV6) {
  326. if (addressStr == null) {
  327. if (!OS.IS_BSD && !OS.IS_WIN32 && !OS.IS_WIN64)
  328. family = Socket.APR_UNSPEC;
  329. } else if (addressStr.indexOf(':') >= 0) {
  330. family = Socket.APR_UNSPEC;
  331. }
  332. }
  333. long inetAddress = Address.info(addressStr, family,
  334. getPort(), 0, rootPool);
  335. // Create the APR server socket
  336. serverSock = Socket.create(Address.getInfo(inetAddress).family,
  337. Socket.SOCK_STREAM,
  338. Socket.APR_PROTO_TCP, rootPool);
  339. if (OS.IS_UNIX) {
  340. Socket.optSet(serverSock, Socket.APR_SO_REUSEADDR, 1);
  341. }
  342. // Deal with the firewalls that tend to drop the inactive sockets
  343. Socket.optSet(serverSock, Socket.APR_SO_KEEPALIVE, 1);
  344. // Bind the server socket
  345. int ret = Socket.bind(serverSock, inetAddress);
  346. if (ret != 0) {
  347. throw new Exception(sm.getString("endpoint.init.bind", "" + ret, Error.strerror(ret)));
  348. }
  349. // Start listening on the server socket
  350. ret = Socket.listen(serverSock, getBacklog());
  351. if (ret != 0) {
  352. throw new Exception(sm.getString("endpoint.init.listen", "" + ret, Error.strerror(ret)));
  353. }
  354. if (OS.IS_WIN32 || OS.IS_WIN64) {
  355. // On Windows set the reuseaddr flag after the bind/listen
  356. Socket.optSet(serverSock, Socket.APR_SO_REUSEADDR, 1);
  357. }
  358. // Enable Sendfile by default if it has not been configured but usage on
  359. // systems which don't support it cause major problems
  360. if (!useSendFileSet) {
  361. useSendfile = Library.APR_HAS_SENDFILE;
  362. } else if (useSendfile && !Library.APR_HAS_SENDFILE) {
  363. useSendfile = false;
  364. }
  365. // Initialize thread count default for acceptor
  366. if (acceptorThreadCount == 0) {
  367. // FIXME: Doesn't seem to work that well with multiple accept threads
  368. acceptorThreadCount = 1;
  369. }
  370. // Delay accepting of new connections until data is available
  371. // Only Linux kernels 2.4 + have that implemented
  372. // on other platforms this call is noop and will return APR_ENOTIMPL.
  373. if (deferAccept) {
  374. if (Socket.optSet(serverSock, Socket.APR_TCP_DEFER_ACCEPT, 1) == Status.APR_ENOTIMPL) {
  375. deferAccept = false;
  376. }
  377. }
  378. // Initialize SSL if needed
  379. if (isSSLEnabled()) {
  380. if (SSLCertificateFile == null) {
  381. // This is required
  382. throw new Exception(sm.getString("endpoint.apr.noSslCertFile"));
  383. }
  384. // SSL protocol
  385. int value = SSL.SSL_PROTOCOL_NONE;
  386. if (SSLProtocol == null || SSLProtocol.length() == 0) {
  387. value = SSL.SSL_PROTOCOL_ALL;
  388. } else {
  389. for (String protocol : SSLProtocol.split("\\+")) {
  390. protocol = protocol.trim();
  391. if ("SSLv2".equalsIgnoreCase(protocol)) {
  392. value |= SSL.SSL_PROTOCOL_SSLV2;
  393. } else if ("SSLv3".equalsIgnoreCase(protocol)) {
  394. value |= SSL.SSL_PROTOCOL_SSLV3;
  395. } else if ("TLSv1".equalsIgnoreCase(protocol)) {
  396. value |= SSL.SSL_PROTOCOL_TLSV1;
  397. } else if ("all".equalsIgnoreCase(protocol)) {
  398. value |= SSL.SSL_PROTOCOL_ALL;
  399. } else {
  400. // Protocol not recognized, fail to start as it is safer than
  401. // continuing with the default which might enable more than the
  402. // is required
  403. throw new Exception(sm.getString(
  404. "endpoint.apr.invalidSslProtocol", SSLProtocol));
  405. }
  406. }
  407. }
  408. // Create SSL Context
  409. try {
  410. sslContext = SSLContext.make(rootPool, value, SSL.SSL_MODE_SERVER);
  411. } catch (Exception e) {
  412. // If the sslEngine is disabled on the AprLifecycleListener
  413. // there will be an Exception here but there is no way to check
  414. // the AprLifecycleListener settings from here
  415. throw new Exception(
  416. sm.getString("endpoint.apr.failSslContextMake"), e);
  417. }
  418. if (SSLInsecureRenegotiation) {
  419. boolean legacyRenegSupported = false;
  420. try {
  421. legacyRenegSupported = SSL.hasOp(SSL.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
  422. if (legacyRenegSupported)
  423. SSLContext.setOptions(sslContext, SSL.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
  424. } catch (UnsatisfiedLinkError e) {
  425. // Ignore
  426. }
  427. if (!legacyRenegSupported) {
  428. // OpenSSL does not support unsafe legacy renegotiation.
  429. log.warn(sm.getString("endpoint.warn.noInsecureReneg",
  430. SSL.versionString()));
  431. }
  432. }
  433. // Set cipher order: client (default) or server
  434. if (SSLHonorCipherOrder) {
  435. boolean orderCiphersSupported = false;
  436. try {
  437. orderCiphersSupported = SSL.hasOp(SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
  438. if (orderCiphersSupported)
  439. SSLContext.setOptions(sslContext, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
  440. } catch (UnsatisfiedLinkError e) {
  441. // Ignore
  442. }
  443. if (!orderCiphersSupported) {
  444. // OpenSSL does not support ciphers ordering.
  445. log.warn(sm.getString("endpoint.warn.noHonorCipherOrder",
  446. SSL.versionString()));
  447. }
  448. }
  449. // Disable compression if requested
  450. if (SSLDisableCompression) {
  451. boolean disableCompressionSupported = false;
  452. try {
  453. disableCompressionSupported = SSL.hasOp(SSL.SSL_OP_NO_COMPRESSION);
  454. if (disableCompressionSupported)
  455. SSLContext.setOptions(sslContext, SSL.SSL_OP_NO_COMPRESSION);
  456. } catch (UnsatisfiedLinkError e) {
  457. // Ignore
  458. }
  459. if (!disableCompressionSupported) {
  460. // OpenSSL does not support ciphers ordering.
  461. log.warn(sm.getString("endpoint.warn.noDisableCompression",
  462. SSL.versionString()));
  463. }
  464. }
  465. // List the ciphers that the client is permitted to negotiate
  466. SSLContext.setCipherSuite(sslContext, SSLCipherSuite);
  467. // Load Server key and certificate
  468. SSLContext.setCertificate(sslContext, SSLCertificateFile, SSLCertificateKeyFile, SSLPassword, SSL.SSL_AIDX_RSA);
  469. // Set certificate chain file
  470. SSLContext.setCertificateChainFile(sslContext, SSLCertificateChainFile, false);
  471. // Support Client Certificates
  472. SSLContext.setCACertificate(sslContext, SSLCACertificateFile, SSLCACertificatePath);
  473. // Set revocation
  474. SSLContext.setCARevocation(sslContext, SSLCARevocationFile, SSLCARevocationPath);
  475. // Client certificate verification
  476. value = SSL.SSL_CVERIFY_NONE;
  477. if ("optional".equalsIgnoreCase(SSLVerifyClient)) {
  478. value = SSL.SSL_CVERIFY_OPTIONAL;
  479. } else if ("require".equalsIgnoreCase(SSLVerifyClient)) {
  480. value = SSL.SSL_CVERIFY_REQUIRE;
  481. } else if ("optionalNoCA".equalsIgnoreCase(SSLVerifyClient)) {
  482. value = SSL.SSL_CVERIFY_OPTIONAL_NO_CA;
  483. }
  484. SSLContext.setVerify(sslContext, value, SSLVerifyDepth);
  485. // For now, sendfile is not supported with SSL
  486. if (useSendfile) {
  487. useSendfile = false;
  488. if (useSendFileSet) {
  489. log.warn(sm.getString("endpoint.apr.noSendfileWithSSL"));
  490. }
  491. }
  492. }
  493. }
  494. public long getJniSslContext() {
  495. return sslContext;
  496. }
  497. /**
  498. * Start the APR endpoint, creating acceptor, poller and sendfile threads.
  499. */
  500. @Override
  501. public void startInternal() throws Exception {
  502. if (!running) {
  503. running = true;
  504. paused = false;
  505. // Create worker collection
  506. if (getExecutor() == null) {
  507. createExecutor();
  508. }
  509. initializeConnectionLatch();
  510. // Start poller thread
  511. poller = new Poller();
  512. poller.init();
  513. Thread pollerThread = new Thread(poller, getName() + "-Poller");
  514. pollerThread.setPriority(threadPriority);
  515. pollerThread.setDaemon(true);
  516. pollerThread.start();
  517. // Start sendfile thread
  518. if (useSendfile) {
  519. sendfile = new Sendfile();
  520. sendfile.init();
  521. Thread sendfileThread =
  522. new Thread(sendfile, getName() + "-Sendfile");
  523. sendfileThread.setPriority(threadPriority);
  524. sendfileThread.setDaemon(true);
  525. sendfileThread.start();
  526. }
  527. startAcceptorThreads();
  528. // Start async timeout thread
  529. setAsyncTimeout(new AsyncTimeout());
  530. Thread timeoutThread = new Thread(getAsyncTimeout(), getName() + "-AsyncTimeout");
  531. timeoutThread.setPriority(threadPriority);
  532. timeoutThread.setDaemon(true);
  533. timeoutThread.start();
  534. }
  535. }
  536. /**
  537. * Stop the endpoint. This will cause all processing threads to stop.
  538. */
  539. @Override
  540. public void stopInternal() {
  541. releaseConnectionLatch();
  542. if (!paused) {
  543. pause();
  544. }
  545. if (running) {
  546. running = false;
  547. poller.stop();
  548. getAsyncTimeout().stop();
  549. unlockAccept();
  550. for (AbstractEndpoint.Acceptor acceptor : acceptors) {
  551. long waitLeft = 10000;
  552. while (waitLeft > 0 &&
  553. acceptor.getState() != AcceptorState.ENDED &&
  554. serverSock != 0) {
  555. try {
  556. Thread.sleep(50);
  557. } catch (InterruptedException e) {
  558. // Ignore
  559. }
  560. waitLeft -= 50;
  561. }
  562. if (waitLeft == 0) {
  563. log.warn(sm.getString("endpoint.warn.unlockAcceptorFailed",
  564. acceptor.getThreadName()));
  565. // If the Acceptor is still running force
  566. // the hard socket close.
  567. if (serverSock != 0) {
  568. Socket.shutdown(serverSock, Socket.APR_SHUTDOWN_READ);
  569. serverSock = 0;
  570. }
  571. }
  572. }
  573. try {
  574. poller.destroy();
  575. } catch (Exception e) {
  576. // Ignore
  577. }
  578. poller = null;
  579. connections.clear();
  580. if (useSendfile) {
  581. try {
  582. sendfile.destroy();
  583. } catch (Exception e) {
  584. // Ignore
  585. }
  586. sendfile = null;
  587. }
  588. }
  589. shutdownExecutor();
  590. }
  591. /**
  592. * Deallocate APR memory pools, and close server socket.
  593. */
  594. @Override
  595. public void unbind() throws Exception {
  596. if (running) {
  597. stop();
  598. }
  599. // Destroy pool if it was initialised
  600. if (serverSockPool != 0) {
  601. Pool.destroy(serverSockPool);
  602. serverSockPool = 0;
  603. }
  604. // Close server socket if it was initialised
  605. if (serverSock != 0) {
  606. Socket.close(serverSock);
  607. serverSock = 0;
  608. }
  609. sslContext = 0;
  610. // Close all APR memory pools and resources if initialised
  611. if (rootPool != 0) {
  612. Pool.destroy(rootPool);
  613. rootPool = 0;
  614. }
  615. handler.recycle();
  616. }
  617. // ------------------------------------------------------ Protected Methods
  618. @Override
  619. protected AbstractEndpoint.Acceptor createAcceptor() {
  620. return new Acceptor();
  621. }
  622. /**
  623. * Process the specified connection.
  624. */
  625. protected boolean setSocketOptions(long socket) {
  626. // Process the connection
  627. int step = 1;
  628. try {
  629. // 1: Set socket options: timeout, linger, etc
  630. if (socketProperties.getSoLingerOn() && socketProperties.getSoLingerTime() >= 0)
  631. Socket.optSet(socket, Socket.APR_SO_LINGER, socketProperties.getSoLingerTime());
  632. if (socketProperties.getTcpNoDelay())
  633. Socket.optSet(socket, Socket.APR_TCP_NODELAY, (socketProperties.getTcpNoDelay() ? 1 : 0));
  634. Socket.timeoutSet(socket, socketProperties.getSoTimeout() * 1000);
  635. // 2: SSL handshake
  636. step = 2;
  637. if (sslContext != 0) {
  638. SSLSocket.attach(sslContext, socket);
  639. if (SSLSocket.handshake(socket) != 0) {
  640. if (log.isDebugEnabled()) {
  641. log.debug(sm.getString("endpoint.err.handshake") + ": " + SSL.getLastError());
  642. }
  643. return false;
  644. }
  645. }
  646. } catch (Throwable t) {
  647. ExceptionUtils.handleThrowable(t);
  648. if (log.isDebugEnabled()) {
  649. if (step == 2) {
  650. log.debug(sm.getString("endpoint.err.handshake"), t);
  651. } else {
  652. log.debug(sm.getString("endpoint.err.unexpected"), t);
  653. }
  654. }
  655. // Tell to close the socket
  656. return false;
  657. }
  658. return true;
  659. }
  660. /**
  661. * Allocate a new poller of the specified size.
  662. */
  663. protected long allocatePoller(int size, long pool, int timeout) {
  664. try {
  665. return Poll.create(size, pool, 0, timeout * 1000);
  666. } catch (Error e) {
  667. if (Status.APR_STATUS_IS_EINVAL(e.getError())) {
  668. log.info(sm.getString("endpoint.poll.limitedpollsize", "" + size));
  669. return 0;
  670. } else {
  671. log.error(sm.getString("endpoint.poll.initfail"), e);
  672. return -1;
  673. }
  674. }
  675. }
  676. /**
  677. * Process given socket. This is called when the socket has been
  678. * accepted.
  679. */
  680. protected boolean processSocketWithOptions(long socket) {
  681. try {
  682. // During shutdown, executor may be null - avoid NPE
  683. if (running) {
  684. if (log.isDebugEnabled()) {
  685. log.debug(sm.getString("endpoint.debug.socket",
  686. Long.valueOf(socket)));
  687. }
  688. AprSocketWrapper wrapper =
  689. new AprSocketWrapper(Long.valueOf(socket));
  690. wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
  691. wrapper.setSecure(isSSLEnabled());
  692. connections.put(Long.valueOf(socket), wrapper);
  693. getExecutor().execute(new SocketWithOptionsProcessor(wrapper));
  694. }
  695. } catch (RejectedExecutionException x) {
  696. log.warn("Socket processing request was rejected for:"+socket,x);
  697. return false;
  698. } catch (Throwable t) {
  699. ExceptionUtils.handleThrowable(t);
  700. // This means we got an OOM or similar creating a thread, or that
  701. // the pool and its queue are full
  702. log.error(sm.getString("endpoint.process.fail"), t);
  703. return false;
  704. }
  705. return true;
  706. }
  707. /**
  708. * Process given socket. Called in non-comet mode, typically keep alive
  709. * or upgraded protocol.
  710. */
  711. public boolean processSocket(long socket, SocketStatus status) {
  712. try {
  713. Executor executor = getExecutor();
  714. if (executor == null) {
  715. log.warn(sm.getString("endpoint.warn.noExector",
  716. Long.valueOf(socket), null));
  717. } else {
  718. SocketWrapper<Long> wrapper =
  719. connections.get(Long.valueOf(socket));
  720. // Make sure connection hasn't been closed
  721. if (wrapper != null) {
  722. executor.execute(new SocketProcessor(wrapper, status));
  723. }
  724. }
  725. } catch (RejectedExecutionException x) {
  726. log.warn("Socket processing request was rejected for:"+socket,x);
  727. return false;
  728. } catch (Throwable t) {
  729. ExceptionUtils.handleThrowable(t);
  730. // This means we got an OOM or similar creating a thread, or that
  731. // the pool and its queue are full
  732. log.error(sm.getString("endpoint.process.fail"), t);
  733. return false;
  734. }
  735. return true;
  736. }
  737. @Override
  738. public void processSocket(SocketWrapper<Long> socket, SocketStatus status,
  739. boolean dispatch) {
  740. try {
  741. // Synchronisation is required here as this code may be called as a
  742. // result of calling AsyncContext.dispatch() from a non-container
  743. // thread
  744. synchronized (socket) {
  745. if (waitingRequests.remove(socket)) {
  746. SocketProcessor proc = new SocketProcessor(socket, status);
  747. Executor executor = getExecutor();
  748. if (dispatch && executor != null) {
  749. executor.execute(proc);
  750. } else {
  751. proc.run();
  752. }
  753. }
  754. }
  755. } catch (RejectedExecutionException ree) {
  756. log.warn(sm.getString("endpoint.executor.fail", socket) , ree);
  757. } catch (Throwable t) {
  758. ExceptionUtils.handleThrowable(t);
  759. // This means we got an OOM or similar creating a thread, or that
  760. // the pool and its queue are full
  761. log.error(sm.getString("endpoint.process.fail"), t);
  762. }
  763. }
  764. private void closeSocket(long socket) {
  765. // If not running the socket will be destroyed by
  766. // parent pool or acceptor socket.
  767. // In any case disable double free which would cause JVM core.
  768. connections.remove(Long.valueOf(socket));
  769. // While the connector is running, destroySocket() will call
  770. // countDownConnection(). Once the connector is stopped, the latch is
  771. // removed so it does not matter that destroySocket() does not call
  772. // countDownConnection() in that case
  773. Poller poller = this.poller;
  774. if (poller != null) {
  775. if (!poller.close(socket)) {
  776. destroySocket(socket);
  777. }
  778. }
  779. }
  780. /*
  781. * This method should only be called if there is no chance that the socket
  782. * is currently being used by the Poller. It is generally a bad idea to call
  783. * this directly from a known error condition.
  784. */
  785. private void destroySocket(long socket) {
  786. connections.remove(Long.valueOf(socket));
  787. if (log.isDebugEnabled()) {
  788. String msg = sm.getString("endpoint.debug.destroySocket",
  789. Long.valueOf(socket));
  790. if (log.isTraceEnabled()) {
  791. log.trace(msg, new Exception());
  792. } else {
  793. log.debug(msg);
  794. }
  795. }
  796. // Be VERY careful if you call this method directly. If it is called
  797. // twice for the same socket the JVM will core. Currently this is only
  798. // called from Poller.closePollset() to ensure kept alive connections
  799. // are closed when calling stop() followed by start().
  800. if (socket != 0) {
  801. Socket.destroy(socket);
  802. countDownConnection();
  803. }
  804. }
  805. @Override
  806. protected Log getLog() {
  807. return log;
  808. }
  809. // --------------------------------------------------- Acceptor Inner Class
  810. /**
  811. * The background thread that listens for incoming TCP/IP connections and
  812. * hands them off to an appropriate processor.
  813. */
  814. protected class Acceptor extends AbstractEndpoint.Acceptor {
  815. private final Log log = LogFactory.getLog(AprEndpoint.Acceptor.class);
  816. @Override
  817. public void run() {
  818. int errorDelay = 0;
  819. // Loop until we receive a shutdown command
  820. while (running) {
  821. // Loop if endpoint is paused
  822. while (paused && running) {
  823. state = AcceptorState.PAUSED;
  824. try {
  825. Thread.sleep(50);
  826. } catch (InterruptedException e) {
  827. // Ignore
  828. }
  829. }
  830. if (!running) {
  831. break;
  832. }
  833. state = AcceptorState.RUNNING;
  834. try {
  835. //if we have reached max connections, wait
  836. countUpOrAwaitConnection();
  837. long socket = 0;
  838. try {
  839. // Accept the next incoming connection from the server
  840. // socket
  841. socket = Socket.accept(serverSock);
  842. if (log.isDebugEnabled()) {
  843. long sa = Address.get(Socket.APR_REMOTE, socket);
  844. Sockaddr addr = Address.getInfo(sa);
  845. log.debug(sm.getString("endpoint.apr.remoteport",
  846. Long.valueOf(socket),
  847. Long.valueOf(addr.port)));
  848. }
  849. } catch (Exception e) {
  850. //we didn't get a socket
  851. countDownConnection();
  852. // Introduce delay if necessary
  853. errorDelay = handleExceptionWithDelay(errorDelay);
  854. // re-throw
  855. throw e;
  856. }
  857. // Successful accept, reset the error delay
  858. errorDelay = 0;
  859. if (running && !paused) {
  860. // Hand this socket off to an appropriate processor
  861. if (!processSocketWithOptions(socket)) {
  862. // Close socket right away
  863. closeSocket(socket);
  864. }
  865. } else {
  866. // Close socket right away
  867. // No code path could have added the socket to the
  868. // Poller so use destroySocket()
  869. destroySocket(socket);
  870. }
  871. } catch (Throwable t) {
  872. ExceptionUtils.handleThrowable(t);
  873. if (running) {
  874. String msg = sm.getString("endpoint.accept.fail");
  875. if (t instanceof Error) {
  876. Error e = (Error) t;
  877. if (e.getError() == 233) {
  878. // Not an error on HP-UX so log as a warning
  879. // so it can be filtered out on that platform
  880. // See bug 50273
  881. log.warn(msg, t);
  882. } else {
  883. log.error(msg, t);
  884. }
  885. } else {
  886. log.error(msg, t);
  887. }
  888. }
  889. }
  890. // The processor will recycle itself when it finishes
  891. }
  892. state = AcceptorState.ENDED;
  893. }
  894. }
  895. // -------------------------------------------------- SocketInfo Inner Class
  896. public static class SocketInfo {
  897. public long socket;
  898. public int timeout;
  899. public int flags;
  900. public boolean read() {
  901. return (flags & Poll.APR_POLLIN) == Poll.APR_POLLIN;
  902. }
  903. public boolean write() {
  904. return (flags & Poll.APR_POLLOUT) == Poll.APR_POLLOUT;
  905. }
  906. public static int merge(int flag1, int flag2) {
  907. return ((flag1 & Poll.APR_POLLIN) | (flag2 & Poll.APR_POLLIN))
  908. | ((flag1 & Poll.APR_POLLOUT) | (flag2 & Poll.APR_POLLOUT));
  909. }
  910. @Override
  911. public String toString() {
  912. StringBuilder sb = new StringBuilder();
  913. sb.append("Socket: [");
  914. sb.append(socket);
  915. sb.append("], timeout: [");
  916. sb.append(timeout);
  917. sb.append("], flags: [");
  918. sb.append(flags);
  919. return sb.toString();
  920. }
  921. }
  922. // ---------------------------------------------- SocketTimeouts Inner Class
  923. public class SocketTimeouts {
  924. protected int size;
  925. protected long[] sockets;
  926. protected long[] timeouts;
  927. protected int pos = 0;
  928. public SocketTimeouts(int size) {
  929. this.size = 0;
  930. sockets = new long[size];
  931. timeouts = new long[size];
  932. }
  933. public void add(long socket, long timeout) {
  934. sockets[size] = socket;
  935. timeouts[size] = timeout;
  936. size++;
  937. }
  938. /**
  939. * Removes the specified socket from the poller.
  940. *
  941. * @return The configured timeout for the socket or zero if the socket
  942. * was not in the list of socket timeouts
  943. */
  944. public long remove(long socket) {
  945. long result = 0;
  946. for (int i = 0; i < size; i++) {
  947. if (sockets[i] == socket) {
  948. result = timeouts[i];
  949. sockets[i] = sockets[size - 1];
  950. timeouts[i] = timeouts[size - 1];
  951. size--;
  952. break;
  953. }
  954. }
  955. return result;
  956. }
  957. public long check(long date) {
  958. while (pos < size) {
  959. if (date >= timeouts[pos]) {
  960. long result = sockets[pos];
  961. sockets[pos] = sockets[size - 1];
  962. timeouts[pos] = timeouts[size - 1];
  963. size--;
  964. return result;
  965. }
  966. pos++;
  967. }
  968. pos = 0;
  969. return 0;
  970. }
  971. }
  972. // -------------------------------------------------- SocketList Inner Class
  973. public class SocketList {
  974. protected int size;
  975. protected int pos;
  976. protected long[] sockets;
  977. protected int[] timeouts;
  978. protected int[] flags;
  979. protected SocketInfo info = new SocketInfo();
  980. public SocketList(int size) {
  981. this.size = 0;
  982. pos = 0;
  983. sockets = new long[size];
  984. timeouts = new int[size];
  985. flags = new int[size];
  986. }
  987. public int size() {
  988. return this.size;
  989. }
  990. public SocketInfo get() {
  991. if (pos == size) {
  992. return null;
  993. } else {
  994. info.socket = sockets[pos];
  995. info.timeout = timeouts[pos];
  996. info.flags = flags[pos];
  997. pos++;
  998. return info;
  999. }
  1000. }
  1001. public void clear() {
  1002. size = 0;
  1003. pos = 0;
  1004. }
  1005. public boolean add(long socket, int timeout, int flag) {
  1006. if (size == sockets.length) {
  1007. return false;
  1008. } else {
  1009. for (int i = 0; i < size; i++) {
  1010. if (sockets[i] == socket) {
  1011. flags[i] = SocketInfo.merge(flags[i], flag);
  1012. return true;
  1013. }
  1014. }
  1015. sockets[size] = socket;
  1016. timeouts[size] = timeout;
  1017. flags[size] = flag;
  1018. size++;
  1019. return true;
  1020. }
  1021. }
  1022. public boolean remove(long socket) {
  1023. for (int i = 0; i < size; i++) {
  1024. if (sockets[i] == socket) {
  1025. sockets[i] = sockets[size - 1];
  1026. timeouts[i] = timeouts[size - 1];
  1027. flags[size] = flags[size -1];
  1028. size--;
  1029. return true;
  1030. }
  1031. }
  1032. return false;
  1033. }
  1034. public void duplicate(SocketList copy) {
  1035. copy.size = size;
  1036. copy.pos = pos;
  1037. System.arraycopy(sockets, 0, copy.sockets, 0, size);
  1038. System.arraycopy(timeouts, 0, copy.timeouts, 0, size);
  1039. System.arraycopy(flags, 0, copy.flags, 0, size);
  1040. }
  1041. }
  1042. // ------------------------------------------------------ Poller Inner Class
  1043. public class Poller implements Runnable {
  1044. /**
  1045. * Pointers to the pollers.
  1046. */
  1047. private long[] pollers = null;
  1048. /**
  1049. * Actual poller size.
  1050. */
  1051. private int actualPollerSize = 0;
  1052. /**
  1053. * Amount of spots left in the poller.
  1054. */
  1055. private int[] pollerSpace = null;
  1056. /**
  1057. * Amount of low level pollers in use by this poller.
  1058. */
  1059. private int pollerCount;
  1060. /**
  1061. * Timeout value for the poll call.
  1062. */
  1063. private int pollerTime;
  1064. /**
  1065. * Variable poller timeout that adjusts depending on how many poll sets
  1066. * are in use so that the total poll time across all poll sets remains
  1067. * equal to pollTime.
  1068. */
  1069. private int nextPollerTime;
  1070. /**
  1071. * Root pool.
  1072. */
  1073. private long pool = 0;
  1074. /**
  1075. * Socket descriptors.
  1076. */
  1077. private long[] desc;
  1078. /**
  1079. * List of sockets to be added to the poller.
  1080. */
  1081. private SocketList addList = null;
  1082. /**
  1083. * List of sockets to be closed.
  1084. */
  1085. private SocketList closeList = null;
  1086. /**
  1087. * Structure used for storing timeouts.
  1088. */
  1089. private SocketTimeouts timeouts = null;
  1090. /**
  1091. * Last run of maintain. Maintain will run usually every 5s.
  1092. */
  1093. private long lastMaintain = System.currentTimeMillis();
  1094. /**
  1095. * The number of connections currently inside this Poller. The correct
  1096. * operation of the Poller depends on this figure being correct. If it
  1097. * is not, it is possible that the Poller will enter a wait loop where
  1098. * it waits for the next connection to be added to the Poller before it
  1099. * calls poll when it should still be polling existing connections.
  1100. * Although not necessary at the time of writing this comment, it has
  1101. * been implemented as an AtomicInteger to ensure that it remains
  1102. * thread-safe.
  1103. */
  1104. private AtomicInteger connectionCount = new AtomicInteger(0);
  1105. public int getConnectionCount() { return connectionCount.get(); }
  1106. private volatile boolean pollerRunning = true;
  1107. /**
  1108. * Create the poller. With some versions of APR, the maximum poller size
  1109. * will be 62 (recompiling APR is necessary to remove this limitation).
  1110. */
  1111. protected void init() {
  1112. pool = Pool.create(serverSockPool);
  1113. // Single poller by default
  1114. int defaultPollerSize = getMaxConnections();
  1115. if ((OS.IS_WIN32 || OS.IS_WIN64) && (defaultPollerSize > 1024)) {
  1116. // The maximum per poller to get reasonable performance is 1024
  1117. // Adjust poller size so that it won't reach the limit. This is
  1118. // a limitation of XP / Server 2003 that has been fixed in
  1119. // Vista / Server 2008 onwards.
  1120. actualPollerSize = 1024;
  1121. } else {
  1122. actualPollerSize = defaultPollerSize;
  1123. }
  1124. timeouts = new SocketTimeouts(defaultPollerSize);
  1125. // At the moment, setting the timeout is useless, but it could get
  1126. // used again as the normal poller could be faster using maintain.
  1127. // It might not be worth bothering though.
  1128. long pollset = allocatePoller(actualPollerSize, pool, -1);
  1129. if (pollset == 0 && actualPollerSize > 1024) {
  1130. actualPollerSize = 1024;
  1131. pollset = allocatePoller(actualPollerSize, pool, -1);
  1132. }
  1133. if (pollset == 0) {
  1134. actualPollerSize = 62;
  1135. pollset = allocatePoller(actualPollerSize, pool, -1);
  1136. }
  1137. pollerCount = defaultPollerSize / actualPollerSize;
  1138. pollerTime = pollTime / pollerCount;
  1139. nextPollerTime = pollerTime;
  1140. pollers = new long[pollerCount];
  1141. pollers[0] = pollset;
  1142. for (int i = 1; i < pollerCount; i++) {
  1143. pollers[i] = allocatePoller(actualPollerSize, pool, -1);
  1144. }
  1145. pollerSpace = new int[pollerCount];
  1146. for (int i = 0; i < pollerCount; i++) {
  1147. pollerSpace[i] = actualPollerSize;
  1148. }
  1149. desc = new long[actualPollerSize * 2];
  1150. connectionCount.set(0);
  1151. addList = new SocketList(defaultPollerSize);
  1152. closeList = new SocketList(defaultPollerSize);
  1153. }
  1154. /*
  1155. * This method is synchronized so that it is not possible for a socket
  1156. * to be added to the Poller's addList once this method has completed.
  1157. */
  1158. protected synchronized void stop() {
  1159. pollerRunning = false;
  1160. }
  1161. /**
  1162. * Destroy the poller.
  1163. */
  1164. protected void destroy() {
  1165. // Wait for pollerTime before doing anything, so that the poller
  1166. // threads exit, otherwise parallel destruction of sockets which are
  1167. // still in the poller can cause problems
  1168. try {
  1169. synchronized (this) {
  1170. this.notify();
  1171. this.wait(pollTime / 1000);
  1172. }
  1173. } catch (InterruptedException e) {
  1174. // Ignore
  1175. }
  1176. // Close all sockets in the add queue
  1177. SocketInfo info = addList.get();
  1178. while (info != null) {
  1179. boolean comet =
  1180. connections.get(Long.valueOf(info.socket)).isComet();
  1181. if (!comet || (comet && !processSocket(
  1182. info.socket, SocketStatus.STOP))) {
  1183. // Poller isn't running at this point so use destroySocket()
  1184. // directly
  1185. destroySocket(info.socket);
  1186. }
  1187. info = addList.get();
  1188. }
  1189. addList.clear();
  1190. // Close all sockets still in the poller
  1191. for (int i = 0; i < pollerCount; i++) {
  1192. int rv = Poll.pollset(pollers[i], desc);
  1193. if (rv > 0) {
  1194. for (int n = 0; n < rv; n++) {
  1195. boolean comet = connections.get(
  1196. Long.valueOf(desc[n*2+1])).isComet();
  1197. if (!comet || (comet && !processSocket(
  1198. desc[n*2+1], SocketStatus.STOP))) {
  1199. destroySocket(desc[n*2+1]);
  1200. }
  1201. }
  1202. }
  1203. }
  1204. Pool.destroy(pool);
  1205. connectionCount.set(0);
  1206. }
  1207. /**
  1208. * Add specified socket and associated pool to the poller. The socket
  1209. * will be added to a temporary array, and polled first after a maximum
  1210. * amount of time equal to pollTime (in most cases, latency will be much
  1211. * lower, however). Note: If both read and write are false, the socket
  1212. * will only be checked for timeout; if the socket was already present
  1213. * in the poller, a callback event will be generated and the socket will
  1214. * be removed from the poller.
  1215. *
  1216. * @param socket to add to the poller
  1217. * @param timeout to use for this connection
  1218. * @param read to do read polling
  1219. * @param write to do write polling
  1220. */
  1221. public void add(long socket, int timeout, boolean read, boolean write) {
  1222. add(socket, timeout,
  1223. (read ? Poll.APR_POLLIN : 0) |
  1224. (write ? Poll.APR_POLLOUT : 0));
  1225. }
  1226. private void add(long socket, int timeout, int flags) {
  1227. if (log.isDebugEnabled()) {
  1228. String msg = sm.getString("endpoint.debug.pollerAdd",
  1229. Long.valueOf(socket), Integer.valueOf(timeout),
  1230. Integer.valueOf(flags));
  1231. if (log.isTraceEnabled()) {
  1232. log.trace(msg, new Exception());
  1233. } else {
  1234. log.debug(msg);
  1235. }
  1236. }
  1237. if (timeout <= 0) {
  1238. // Always put a timeout in
  1239. timeout = Integer.MAX_VALUE;
  1240. }
  1241. boolean ok = false;
  1242. synchronized (this) {
  1243. // Add socket to the list. Newly added sockets will wait
  1244. // at most for pollTime before being polled. Don't add the
  1245. // socket once the poller has stopped but destroy it straight
  1246. // away
  1247. if (pollerRunning && addList.add(socket, timeout, flags)) {
  1248. ok = true;
  1249. this.notify();
  1250. }
  1251. }
  1252. if (!ok) {
  1253. // Can't do anything: close the socket right away
  1254. boolean comet = connections.get(
  1255. Long.valueOf(socket)).isComet();
  1256. if (!comet || (comet && !processSocket(
  1257. socket, SocketStatus.ERROR))) {
  1258. closeSocket(socket);
  1259. }
  1260. }
  1261. }
  1262. /**
  1263. * Add specified socket to one of the pollers. Must only be called from
  1264. * {@link Poller#run()}.
  1265. */
  1266. private boolean addToPoller(long socket, int events) {
  1267. int rv = -1;
  1268. for (int i = 0; i < pollers.length; i++) {
  1269. if (pollerSpace[i] > 0) {
  1270. rv = Poll.add(pollers[i], socket, events);
  1271. if (rv == Status.APR_SUCCESS) {
  1272. pollerSpace[i]--;
  1273. connectionCount.incrementAndGet();
  1274. return true;
  1275. }
  1276. }
  1277. }
  1278. return false;
  1279. }
  1280. protected boolean close(long socket) {
  1281. if (!pollerRunning) {
  1282. return false;
  1283. }
  1284. synchronized (this) {
  1285. if (!pollerRunning) {
  1286. return false;
  1287. }
  1288. closeList.add(socket, 0, 0);
  1289. this.notify();
  1290. return true;
  1291. }
  1292. }
  1293. /**
  1294. * Remove specified socket from the pollers. Must only be called from
  1295. * {@link Poller#run()}.
  1296. */
  1297. private boolean removeFromPoller(long socket) {
  1298. if (log.isDebugEnabled()) {
  1299. log.debug(sm.getString("endpoint.debug.pollerRemove",
  1300. Long.valueOf(socket)));
  1301. }
  1302. int rv = -1;
  1303. for (int i = 0; i < pollers.length; i++) {
  1304. if (pollerSpace[i] < actualPollerSize) {
  1305. rv = Poll.remove(pollers[i], socket);
  1306. if (rv != Status.APR_NOTFOUND) {
  1307. pollerSpace[i]++;
  1308. connectionCount.decrementAndGet();
  1309. if (log.isDebugEnabled()) {
  1310. log.debug(sm.getString("endpoint.debug.pollerRemoved",
  1311. Long.valueOf(socket)));
  1312. }
  1313. break;
  1314. }
  1315. }
  1316. }
  1317. timeouts.remove(socket);
  1318. return (rv == Status.APR_SUCCESS);
  1319. }
  1320. /**
  1321. * Timeout checks. Must only be called from {@link Poller#run()}.
  1322. */
  1323. private void maintain() {
  1324. long date = System.currentTimeMillis();
  1325. // Maintain runs at most once every 1s, although it will likely get
  1326. // called more
  1327. if ((date - lastMaintain) < 1000L) {
  1328. return;
  1329. } else {
  1330. lastMaintain = date;
  1331. }
  1332. long socket = timeouts.check(date);
  1333. while (socket != 0) {
  1334. if (log.isDebugEnabled()) {
  1335. log.debug(sm.getString("endpoint.debug.socketTimeout",
  1336. Long.valueOf(socket)));
  1337. }
  1338. removeFromPoller(socket);
  1339. boolean comet = connections.get(
  1340. Long.valueOf(socket)).isComet();
  1341. if (!comet || (comet && !processSocket(
  1342. socket, SocketStatus.TIMEOUT))) {
  1343. destroySocket(socket);
  1344. }
  1345. socket = timeouts.check(date);
  1346. }
  1347. }
  1348. /**
  1349. * Displays the list of sockets in the pollers.
  1350. */
  1351. @Override
  1352. public String toString() {
  1353. StringBuffer buf = new StringBuffer();
  1354. buf.append("Poller");
  1355. long[] res = new long[actualPollerSize * 2];
  1356. for (int i = 0; i < pollers.length; i++) {
  1357. int count = Poll.pollset(pollers[i], res);
  1358. buf.append(" [ ");
  1359. for (int j = 0; j < count; j++) {
  1360. buf.append(desc[2*j+1]).append(" ");
  1361. }
  1362. buf.append("]");
  1363. }
  1364. return buf.toString();
  1365. }
  1366. /**
  1367. * The background thread that listens for incoming TCP/IP connections
  1368. * and hands them off to an appropriate processor.
  1369. */
  1370. @Override
  1371. public void run() {
  1372. int maintain = 0;
  1373. SocketList localAddList = new SocketList(getMaxConnections());
  1374. SocketList localCloseList = new SocketList(getMaxConnections());
  1375. // Loop until we receive a shutdown command
  1376. while (pollerRunning) {
  1377. // Loop if endpoint is paused
  1378. while (pollerRunning && paused) {
  1379. try {
  1380. Thread.sleep(1000);
  1381. } catch (InterruptedException e) {
  1382. // Ignore
  1383. }
  1384. }
  1385. // Check timeouts if the poller is empty
  1386. while (pollerRunning && connectionCount.get() < 1 &&
  1387. addList.size() < 1 && closeList.size() < 1) {
  1388. // Reset maintain time.
  1389. try {
  1390. if (getSoTimeout() > 0 && pollerRunning) {
  1391. maintain();
  1392. }
  1393. synchronized (this) {
  1394. this.wait(10000);
  1395. }
  1396. } catch (InterruptedException e) {
  1397. // Ignore
  1398. } catch (Throwable t) {
  1399. ExceptionUtils.handleThrowable(t);
  1400. getLog().warn(sm.getString("endpoint.timeout.err"));
  1401. }
  1402. }
  1403. // Don't add or poll if the poller has been stopped
  1404. if (!pollerRunning) {
  1405. break;
  1406. }
  1407. try {
  1408. // Duplicate the add and remove lists so that the syncs are
  1409. // minimised
  1410. if (closeList.size() > 0) {
  1411. synchronized (this) {
  1412. // Duplicate to another list, so that the syncing is
  1413. // minimal
  1414. closeList.duplicate(localCloseList);
  1415. closeList.clear();
  1416. }
  1417. } else {
  1418. localCloseList.clear();
  1419. }
  1420. if (addList.size() > 0) {
  1421. synchronized (this) {
  1422. // Duplicate to another list, so that the syncing is
  1423. // minimal
  1424. addList.duplicate(localAddList);
  1425. addList.clear();
  1426. }
  1427. } else {
  1428. localAddList.clear();
  1429. }
  1430. // Remove sockets
  1431. if (localCloseList.size() > 0) {
  1432. SocketInfo info = localCloseList.get();
  1433. while (info != null) {
  1434. localAddList.remove(info.socket);
  1435. removeFromPoller(info.socket);
  1436. destroySocket(info.socket);
  1437. info = localCloseList.get();
  1438. }
  1439. }
  1440. // Add sockets which are waiting to the poller
  1441. if (localAddList.size() > 0) {
  1442. SocketInfo info = localAddList.get();
  1443. while (info != null) {
  1444. if (log.isDebugEnabled()) {
  1445. log.debug(sm.getString(
  1446. "endpoint.debug.pollerAddDo",
  1447. Long.valueOf(info.socket)));
  1448. }
  1449. timeouts.remove(info.socket);
  1450. AprSocketWrapper wrapper = connections.get(
  1451. Long.valueOf(info.socket));
  1452. if (wrapper == null) {
  1453. continue;
  1454. }
  1455. if (info.read() || info.write()) {
  1456. boolean comet = wrapper.isComet();
  1457. if (comet || wrapper.pollerFlags != 0) {
  1458. removeFromPoller(info.socket);
  1459. }
  1460. wrapper.pollerFlags = wrapper.pollerFlags |
  1461. (info.read() ? Poll.APR_POLLIN : 0) |
  1462. (info.write() ? Poll.APR_POLLOUT : 0);
  1463. if (!addToPoller(info.socket, wrapper.pollerFlags)) {
  1464. // Can't do anything: close the socket right
  1465. // away
  1466. if (!comet || (comet && !processSocket(
  1467. info.socket, SocketStatus.ERROR))) {
  1468. closeSocket(info.socket);
  1469. }
  1470. } else {
  1471. timeouts.add(info.socket,
  1472. System.currentTimeMillis() +
  1473. info.timeout);
  1474. }
  1475. } else {
  1476. // Should never happen.
  1477. closeSocket(info.socket);
  1478. getLog().warn(sm.getString(
  1479. "endpoint.apr.pollAddInvalid", info));
  1480. }
  1481. info = localAddList.get();
  1482. }
  1483. }
  1484. // Poll for the specified interval
  1485. for (int i = 0; i < pollers.length; i++) {
  1486. // Flags to ask to reallocate the pool
  1487. boolean reset = false;
  1488. //ArrayList<Long> skip = null;
  1489. int rv = 0;
  1490. // Iterate on each pollers, but no need to poll empty pollers
  1491. if (pollerSpace[i] < actualPollerSize) {
  1492. rv = Poll.poll(pollers[i], nextPollerTime, desc, true);
  1493. // Reset the nextPollerTime
  1494. nextPollerTime = pollerTime;
  1495. } else {
  1496. // Skipping an empty poll set means skipping a wait
  1497. // time of pollerTime microseconds. If most of the
  1498. // poll sets are skipped then this loop will be
  1499. // tighter than expected which could lead to higher
  1500. // than expected CPU usage. Extending the
  1501. // nextPollerTime ensures that this loop always
  1502. // takes about the same time to execute.
  1503. nextPollerTime += pollerTime;
  1504. }
  1505. if (rv > 0) {
  1506. pollerSpace[i] += rv;
  1507. connectionCount.addAndGet(-rv);
  1508. for (int n = 0; n < rv; n++) {
  1509. long timeout = timeouts.remove(desc[n*2+1]);
  1510. AprSocketWrapper wrapper = connections.get(
  1511. Long.valueOf(desc[n*2+1]));
  1512. if (getLog().isDebugEnabled()) {
  1513. log.debug(sm.getString(
  1514. "endpoint.debug.pollerProcess",
  1515. Long.valueOf(desc[n*2+1]),
  1516. Long.valueOf(desc[n*2])));
  1517. }
  1518. wrapper.pollerFlags = wrapper.pollerFlags & ~((int) desc[n*2]);
  1519. // Check for failed sockets and hand this socket off to a worker
  1520. if (wrapper.isComet()) {
  1521. // Event processes either a read or a write depending on what the poller returns
  1522. if (((desc[n*2] & Poll.APR_POLLHUP) == Poll.APR_POLLHUP)
  1523. || ((desc[n*2] & Poll.APR_POLLERR) == Poll.APR_POLLERR)
  1524. || ((desc[n*2] & Poll.APR_POLLNVAL) == Poll.APR_POLLNVAL)) {
  1525. if (!processSocket(desc[n*2+1], SocketStatus.ERROR)) {
  1526. // Close socket and clear pool
  1527. closeSocket(desc[n*2+1]);
  1528. }
  1529. } else if ((desc[n*2] & Poll.APR_POLLIN) == Poll.APR_POLLIN) {
  1530. if (wrapper.pollerFlags != 0) {
  1531. add(desc[n*2+1], 1, wrapper.pollerFlags);
  1532. }
  1533. if (!processSocket(desc[n*2+1], SocketStatus.OPEN_READ)) {
  1534. // Close socket and clear pool
  1535. closeSocket(desc[n*2+1]);
  1536. }
  1537. } else if ((desc[n*2] & Poll.APR_POLLOUT) == Poll.APR_POLLOUT) {
  1538. if (wrapper.pollerFlags != 0) {
  1539. add(desc[n*2+1], 1, wrapper.pollerFlags);
  1540. }
  1541. if (!processSocket(desc[n*2+1], SocketStatus.OPEN_WRITE)) {
  1542. // Close socket and clear pool
  1543. closeSocket(desc[n*2+1]);
  1544. }
  1545. } else {
  1546. // Unknown event
  1547. getLog().warn(sm.getString(
  1548. "endpoint.apr.pollUnknownEvent",
  1549. Long.valueOf(desc[n*2])));
  1550. if (!processSocket(desc[n*2+1], SocketStatus.ERROR)) {
  1551. // Close socket and clear pool
  1552. closeSocket(desc[n*2+1]);
  1553. }
  1554. }
  1555. } else if (((desc[n*2] & Poll.APR_POLLHUP) == Poll.APR_POLLHUP)
  1556. || ((desc[n*2] & Poll.APR_POLLERR) == Poll.APR_POLLERR)
  1557. || ((desc[n*2] & Poll.APR_POLLNVAL) == Poll.APR_POLLNVAL)) {
  1558. if (wrapper.isAsync() || wrapper.isUpgraded()) {
  1559. // Must be using non-blocking IO for the socket to be in the
  1560. // poller during async processing. Need to trigger error
  1561. // handling. Poller may return error codes plus the flags it
  1562. // was waiting for or it may just return an error code. We
  1563. // could return ASYNC_[WRITE|READ]_ERROR here but if we do,
  1564. // there will be no exception associated with the error in
  1565. // application code. By signalling read/write is possible, a
  1566. // read/write will be attempted, fail and that will trigger
  1567. // an exception the application will see.
  1568. // Check the return flags first, followed by what the socket
  1569. // was registered for
  1570. if ((desc[n*2] & Poll.APR_POLLIN) == Poll.APR_POLLIN) {
  1571. // Error probably occurred during a non-blocking read
  1572. if (!processSocket(desc[n*2+1], SocketStatus.OPEN_READ)) {
  1573. // Close socket and clear pool
  1574. closeSocket(desc[n*2+1]);
  1575. }
  1576. } else if ((desc[n*2] & Poll.APR_POLLOUT) == Poll.APR_POLLOUT) {
  1577. // Error probably occurred during a non-blocking write
  1578. if (!processSocket(desc[n*2+1], SocketStatus.OPEN_WRITE)) {
  1579. // Close socket and clear pool
  1580. closeSocket(desc[n*2+1]);
  1581. }
  1582. } else if ((wrapper.pollerFlags & Poll.APR_POLLIN) == Poll.APR_POLLIN) {
  1583. // Can't tell what was happening when the error occurred but the
  1584. // socket is registered for non-blocking read so use that
  1585. if (!processSocket(desc[n*2+1], SocketStatus.OPEN_READ)) {
  1586. // Close socket and clear pool
  1587. closeSocket(desc[n*2+1]);
  1588. }
  1589. } else if ((wrapper.pollerFlags & Poll.APR_POLLOUT) == Poll.APR_POLLOUT) {
  1590. // Can't tell what was happening when the error occurred but the
  1591. // socket is registered for non-blocking write so use that
  1592. if (!processSocket(desc[n*2+1], SocketStatus.OPEN_WRITE)) {
  1593. // Close socket and clear pool
  1594. closeSocket(desc[n*2+1]);
  1595. }
  1596. } else {
  1597. // Close socket and clear pool
  1598. closeSocket(desc[n*2+1]);
  1599. }
  1600. } else {
  1601. // Close socket and clear pool
  1602. closeSocket(desc[n*2+1]);
  1603. }
  1604. } else if (((desc[n*2] & Poll.APR_POLLIN) == Poll.APR_POLLIN)
  1605. || ((desc[n*2] & Poll.APR_POLLOUT) == Poll.APR_POLLOUT)) {
  1606. boolean error = false;
  1607. if (((desc[n*2] & Poll.APR_POLLIN) == Poll.APR_POLLIN) &&
  1608. !processSocket(desc[n*2+1], SocketStatus.OPEN_READ)) {
  1609. error = true;
  1610. // Close socket and clear pool
  1611. closeSocket(desc[n*2+1]);
  1612. }
  1613. if (!error &&
  1614. ((desc[n*2] & Poll.APR_POLLOUT) == Poll.APR_POLLOUT) &&
  1615. !processSocket(desc[n*2+1], SocketStatus.OPEN_WRITE)) {
  1616. // Close socket and clear pool
  1617. error = true;
  1618. closeSocket(desc[n*2+1]);
  1619. }
  1620. if (!error && wrapper.pollerFlags != 0) {
  1621. // If socket was registered for multiple events but
  1622. // only some of the occurred, re-register for the
  1623. // remaining events.
  1624. // timeout is the value of System.currentTimeMillis() that
  1625. // was set as the point that the socket will timeout. When
  1626. // adding to the poller, the timeout from now in
  1627. // milliseconds is required.
  1628. // So first, subtract the current timestamp
  1629. if (timeout > 0) {
  1630. timeout = timeout - System.currentTimeMillis();
  1631. }
  1632. // If the socket should have already expired by now,
  1633. // re-add it with a very short timeout
  1634. if (timeout <= 0) {
  1635. timeout = 1;
  1636. }
  1637. // Should be impossible but just in case since timeout will
  1638. // be cast to an int.
  1639. if (timeout > Integer.MAX_VALUE) {
  1640. timeout = Integer.MAX_VALUE;
  1641. }
  1642. add(desc[n*2+1], (int) timeout, wrapper.pollerFlags);
  1643. }
  1644. } else {
  1645. // Unknown event
  1646. getLog().warn(sm.getString(
  1647. "endpoint.apr.pollUnknownEvent",
  1648. Long.valueOf(desc[n*2])));
  1649. // Close socket and clear pool
  1650. closeSocket(desc[n*2+1]);
  1651. }
  1652. }
  1653. } else if (rv < 0) {
  1654. int errn = -rv;
  1655. // Any non timeup or interrupted error is critical
  1656. if ((errn != Status.TIMEUP) && (errn != Status.EINTR)) {
  1657. if (errn > Status.APR_OS_START_USERERR) {
  1658. errn -= Status.APR_OS_START_USERERR;
  1659. }
  1660. getLog().error(sm.getString(
  1661. "endpoint.apr.pollError",
  1662. Integer.valueOf(errn),
  1663. Error.strerror(errn)));
  1664. // Destroy and reallocate the poller
  1665. reset = true;
  1666. }
  1667. }
  1668. if (reset) {
  1669. // Reallocate the current poller
  1670. int count = Poll.pollset(pollers[i], desc);
  1671. long newPoller = allocatePoller(actualPollerSize, pool, -1);
  1672. // Don't restore connections for now, since I have not tested it
  1673. pollerSpace[i] = actualPollerSize;
  1674. connectionCount.addAndGet(-count);
  1675. Poll.destroy(pollers[i]);
  1676. pollers[i] = newPoller;
  1677. }
  1678. }
  1679. // Process socket timeouts
  1680. if (getSoTimeout() > 0 && maintain++ > 1000 && pollerRunning) {
  1681. // This works and uses only one timeout mechanism for everything, but the
  1682. // non event poller might be a bit faster by using the old maintain.
  1683. maintain = 0;
  1684. maintain();
  1685. }
  1686. } catch (Throwable t) {
  1687. ExceptionUtils.handleThrowable(t);
  1688. if (maintain == 0) {
  1689. getLog().warn(sm.getString("endpoint.timeout.error"), t);
  1690. } else {
  1691. getLog().warn(sm.getString("endpoint.poll.error"), t);
  1692. }
  1693. }
  1694. }
  1695. synchronized (this) {
  1696. this.notifyAll();
  1697. }
  1698. }
  1699. }
  1700. // ----------------------------------------------- SendfileData Inner Class
  1701. /**
  1702. * SendfileData class.
  1703. */
  1704. public static class SendfileData {
  1705. // File
  1706. public String fileName;
  1707. public long fd;
  1708. public long fdpool;
  1709. // Range information
  1710. public long start;
  1711. public long end;
  1712. // Socket and socket pool
  1713. public long socket;
  1714. // Position
  1715. public long pos;
  1716. // KeepAlive flag
  1717. public boolean keepAlive;
  1718. }
  1719. // --------------------------------------------------- Sendfile Inner Class
  1720. public class Sendfile implements Runnable {
  1721. protected long sendfilePollset = 0;
  1722. protected long pool = 0;
  1723. protected long[] desc;
  1724. protected HashMap<Long, SendfileData> sendfileData;
  1725. protected int sendfileCount;
  1726. public int getSendfileCount() { return sendfileCount; }
  1727. protected ArrayList<SendfileData> addS;
  1728. private volatile boolean sendfileRunning = true;
  1729. /**
  1730. * Create the sendfile poller. With some versions of APR, the maximum
  1731. * poller size will be 62 (recompiling APR is necessary to remove this
  1732. * limitation).
  1733. */
  1734. protected void init() {
  1735. pool = Pool.create(serverSockPool);
  1736. int size = sendfileSize;
  1737. if (size <= 0) {
  1738. size = (OS.IS_WIN32 || OS.IS_WIN64) ? (1 * 1024) : (16 * 1024);
  1739. }
  1740. sendfilePollset = allocatePoller(size, pool, getSoTimeout());
  1741. if (sendfilePollset == 0 && size > 1024) {
  1742. size = 1024;
  1743. sendfilePollset = allocatePoller(size, pool, getSoTimeout());
  1744. }
  1745. if (sendfilePollset == 0) {
  1746. size = 62;
  1747. sendfilePollset = allocatePoller(size, pool, getSoTimeout());
  1748. }
  1749. desc = new long[size * 2];
  1750. sendfileData = new HashMap<>(size);
  1751. addS = new ArrayList<>();
  1752. }
  1753. /**
  1754. * Destroy the poller.
  1755. */
  1756. protected void destroy() {
  1757. sendfileRunning = false;
  1758. // Wait for polltime before doing anything, so that the poller threads
  1759. // exit, otherwise parallel destruction of sockets which are still
  1760. // in the poller can cause problems
  1761. try {
  1762. synchronized (this) {
  1763. this.notify();
  1764. this.wait(pollTime / 1000);
  1765. }
  1766. } catch (InterruptedException e) {
  1767. // Ignore
  1768. }
  1769. // Close any socket remaining in the add queue
  1770. for (int i = (addS.size() - 1); i >= 0; i--) {
  1771. SendfileData data = addS.get(i);
  1772. closeSocket(data.socket);
  1773. }
  1774. // Close all sockets still in the poller
  1775. int rv = Poll.pollset(sendfilePollset, desc);
  1776. if (rv > 0) {
  1777. for (int n = 0; n < rv; n++) {
  1778. closeSocket(desc[n*2+1]);
  1779. }
  1780. }
  1781. Pool.destroy(pool);
  1782. sendfileData.clear();
  1783. }
  1784. /**
  1785. * Add the sendfile data to the sendfile poller. Note that in most cases,
  1786. * the initial non blocking calls to sendfile will return right away, and
  1787. * will be handled asynchronously inside the kernel. As a result,
  1788. * the poller will never be used.
  1789. *
  1790. * @param data containing the reference to the data which should be snet
  1791. * @return true if all the data has been sent right away, and false
  1792. * otherwise
  1793. */
  1794. public boolean add(SendfileData data) {
  1795. // Initialize fd from data given
  1796. try {
  1797. data.fdpool = Socket.pool(data.socket);
  1798. data.fd = File.open
  1799. (data.fileName, File.APR_FOPEN_READ
  1800. | File.APR_FOPEN_SENDFILE_ENABLED | File.APR_FOPEN_BINARY,
  1801. 0, data.fdpool);
  1802. data.pos = data.start;
  1803. // Set the socket to nonblocking mode
  1804. Socket.timeoutSet(data.socket, 0);
  1805. while (true) {
  1806. long nw = Socket.sendfilen(data.socket, data.fd,
  1807. data.pos, data.end - data.pos, 0);
  1808. if (nw < 0) {
  1809. if (!(-nw == Status.EAGAIN)) {
  1810. Pool.destroy(data.fdpool);
  1811. data.socket = 0;
  1812. return false;
  1813. } else {
  1814. // Break the loop and add the socket to poller.
  1815. break;
  1816. }
  1817. } else {
  1818. data.pos = data.pos + nw;
  1819. if (data.pos >= data.end) {
  1820. // Entire file has been sent
  1821. Pool.destroy(data.fdpool);
  1822. // Set back socket to blocking mode
  1823. Socket.timeoutSet(
  1824. data.socket, getSoTimeout() * 1000);
  1825. return true;
  1826. }
  1827. }
  1828. }
  1829. } catch (Exception e) {
  1830. log.warn(sm.getString("endpoint.sendfile.error"), e);
  1831. return false;
  1832. }
  1833. // Add socket to the list. Newly added sockets will wait
  1834. // at most for pollTime before being polled
  1835. synchronized (this) {
  1836. addS.add(data);
  1837. this.notify();
  1838. }
  1839. return false;
  1840. }
  1841. /**
  1842. * Remove socket from the poller.
  1843. *
  1844. * @param data the sendfile data which should be removed
  1845. */
  1846. protected void remove(SendfileData data) {
  1847. int rv = Poll.remove(sendfilePollset, data.socket);
  1848. if (rv == Status.APR_SUCCESS) {
  1849. sendfileCount--;
  1850. }
  1851. sendfileData.remove(new Long(data.socket));
  1852. }
  1853. /**
  1854. * The background thread that listens for incoming TCP/IP connections
  1855. * and hands them off to an appropriate processor.
  1856. */
  1857. @Override
  1858. public void run() {
  1859. long maintainTime = 0;
  1860. // Loop until we receive a shutdown command
  1861. while (sendfileRunning) {
  1862. // Loop if endpoint is paused
  1863. while (sendfileRunning && paused) {
  1864. try {
  1865. Thread.sleep(1000);
  1866. } catch (InterruptedException e) {
  1867. // Ignore
  1868. }
  1869. }
  1870. // Loop if poller is empty
  1871. while (sendfileRunning && sendfileCount < 1 && addS.size() < 1) {
  1872. // Reset maintain time.
  1873. maintainTime = 0;
  1874. try {
  1875. synchronized (this) {
  1876. this.wait();
  1877. }
  1878. } catch (InterruptedException e) {
  1879. // Ignore
  1880. }
  1881. }
  1882. // Don't add or poll if the poller has been stopped
  1883. if (!sendfileRunning) {
  1884. break;
  1885. }
  1886. try {
  1887. // Add socket to the poller
  1888. if (addS.size() > 0) {
  1889. synchronized (this) {
  1890. for (int i = (addS.size() - 1); i >= 0; i--) {
  1891. SendfileData data = addS.get(i);
  1892. int rv = Poll.add(sendfilePollset, data.socket, Poll.APR_POLLOUT);
  1893. if (rv == Status.APR_SUCCESS) {
  1894. sendfileData.put(new Long(data.socket), data);
  1895. sendfileCount++;
  1896. } else {
  1897. getLog().warn(sm.getString(
  1898. "endpoint.sendfile.addfail",
  1899. Integer.valueOf(rv),
  1900. Error.strerror(rv)));
  1901. // Can't do anything: close the socket right away
  1902. closeSocket(data.socket);
  1903. }
  1904. }
  1905. addS.clear();
  1906. }
  1907. }
  1908. maintainTime += pollTime;
  1909. // Pool for the specified interval
  1910. int rv = Poll.poll(sendfilePollset, pollTime, desc, false);
  1911. if (rv > 0) {
  1912. for (int n = 0; n < rv; n++) {
  1913. // Get the sendfile state
  1914. SendfileData state =
  1915. sendfileData.get(new Long(desc[n*2+1]));
  1916. // Problem events
  1917. if (((desc[n*2] & Poll.APR_POLLHUP) == Poll.APR_POLLHUP)
  1918. || ((desc[n*2] & Poll.APR_POLLERR) == Poll.APR_POLLERR)) {
  1919. // Close socket and clear pool
  1920. remove(state);
  1921. // Destroy file descriptor pool, which should close the file
  1922. // Close the socket, as the response would be incomplete
  1923. closeSocket(state.socket);
  1924. continue;
  1925. }
  1926. // Write some data using sendfile
  1927. long nw = Socket.sendfilen(state.socket, state.fd,
  1928. state.pos,
  1929. state.end - state.pos, 0);
  1930. if (nw < 0) {
  1931. // Close socket and clear pool
  1932. remove(state);
  1933. // Close the socket, as the response would be incomplete
  1934. // This will close the file too.
  1935. closeSocket(state.socket);
  1936. continue;
  1937. }
  1938. state.pos = state.pos + nw;
  1939. if (state.pos >= state.end) {
  1940. remove(state);
  1941. if (state.keepAlive) {
  1942. // Destroy file descriptor pool, which should close the file
  1943. Pool.destroy(state.fdpool);
  1944. Socket.timeoutSet(state.socket,
  1945. getSoTimeout() * 1000);
  1946. // If all done put the socket back in the
  1947. // poller for processing of further requests
  1948. getPoller().add(
  1949. state.socket, getKeepAliveTimeout(),
  1950. true, false);
  1951. } else {
  1952. // Close the socket since this is
  1953. // the end of not keep-alive request.
  1954. closeSocket(state.socket);
  1955. }
  1956. }
  1957. }
  1958. } else if (rv < 0) {
  1959. int errn = -rv;
  1960. /* Any non timeup or interrupted error is critical */
  1961. if ((errn != Status.TIMEUP) && (errn != Status.EINTR)) {
  1962. if (errn > Status.APR_OS_START_USERERR) {
  1963. errn -= Status.APR_OS_START_USERERR;
  1964. }
  1965. getLog().error(sm.getString(
  1966. "Unexpected poller error",
  1967. Integer.valueOf(errn),
  1968. Error.strerror(errn)));
  1969. // Handle poll critical failure
  1970. synchronized (this) {
  1971. destroy();
  1972. init();
  1973. }
  1974. continue;
  1975. }
  1976. }
  1977. // Call maintain for the sendfile poller
  1978. if (getSoTimeout() > 0 &&
  1979. maintainTime > 1000000L && sendfileRunning) {
  1980. rv = Poll.maintain(sendfilePollset, desc, false);
  1981. maintainTime = 0;
  1982. if (rv > 0) {
  1983. for (int n = 0; n < rv; n++) {
  1984. // Get the sendfile state
  1985. SendfileData state = sendfileData.get(new Long(desc[n]));
  1986. // Close socket and clear pool
  1987. remove(state);
  1988. // Destroy file descriptor pool, which should close the file
  1989. // Close the socket, as the response would be incomplete
  1990. closeSocket(state.socket);
  1991. }
  1992. }
  1993. }
  1994. } catch (Throwable t) {
  1995. ExceptionUtils.handleThrowable(t);
  1996. getLog().error(sm.getString("endpoint.poll.error"), t);
  1997. }
  1998. }
  1999. synchronized (this) {
  2000. this.notifyAll();
  2001. }
  2002. }
  2003. }
  2004. // ------------------------------------------------ Handler Inner Interface
  2005. /**
  2006. * Bare bones interface used for socket processing. Per thread data is to be
  2007. * stored in the ThreadWithAttributes extra folders, or alternately in
  2008. * thread local fields.
  2009. */
  2010. public interface Handler extends AbstractEndpoint.Handler {
  2011. public SocketState process(SocketWrapper<Long> socket,
  2012. SocketStatus status);
  2013. }
  2014. // --------------------------------- SocketWithOptionsProcessor Inner Class
  2015. /**
  2016. * This class is the equivalent of the Worker, but will simply use in an
  2017. * external Executor thread pool. This will also set the socket options
  2018. * and do the handshake.
  2019. *
  2020. * This is called after an accept().
  2021. */
  2022. protected class SocketWithOptionsProcessor implements Runnable {
  2023. protected SocketWrapper<Long> socket = null;
  2024. public SocketWithOptionsProcessor(SocketWrapper<Long> socket) {
  2025. this.socket = socket;
  2026. }
  2027. @Override
  2028. public void run() {
  2029. synchronized (socket) {
  2030. if (!deferAccept) {
  2031. if (setSocketOptions(socket.getSocket().longValue())) {
  2032. getPoller().add(socket.getSocket().longValue(),
  2033. getSoTimeout(), true, false);
  2034. } else {
  2035. // Close socket and pool
  2036. closeSocket(socket.getSocket().longValue());
  2037. socket = null;
  2038. }
  2039. } else {
  2040. // Process the request from this socket
  2041. if (!setSocketOptions(socket.getSocket().longValue())) {
  2042. // Close socket and pool
  2043. closeSocket(socket.getSocket().longValue());
  2044. socket = null;
  2045. return;
  2046. }
  2047. // Process the request from this socket
  2048. Handler.SocketState state = handler.process(socket,
  2049. SocketStatus.OPEN_READ);
  2050. if (state == Handler.SocketState.CLOSED) {
  2051. // Close socket and pool
  2052. closeSocket(socket.getSocket().longValue());
  2053. socket = null;
  2054. } else if (state == Handler.SocketState.LONG) {
  2055. socket.access();
  2056. if (socket.isAsync()) {
  2057. waitingRequests.add(socket);
  2058. }
  2059. }
  2060. }
  2061. }
  2062. }
  2063. }
  2064. // -------------------------------------------- SocketProcessor Inner Class
  2065. /**
  2066. * This class is the equivalent of the Worker, but will simply use in an
  2067. * external Executor thread pool.
  2068. */
  2069. protected class SocketProcessor implements Runnable {
  2070. private final SocketWrapper<Long> socket;
  2071. private final SocketStatus status;
  2072. public SocketProcessor(SocketWrapper<Long> socket,
  2073. SocketStatus status) {
  2074. this.socket = socket;
  2075. if (status == null) {
  2076. // Should never happen
  2077. throw new NullPointerException();
  2078. }
  2079. this.status = status;
  2080. }
  2081. @Override
  2082. public void run() {
  2083. // Upgraded connections need to allow multiple threads to access the
  2084. // connection at the same time to enable blocking IO to be used when
  2085. // Servlet 3.1 NIO has been configured
  2086. if (socket.isUpgraded() && SocketStatus.OPEN_WRITE == status) {
  2087. synchronized (socket.getWriteThreadLock()) {
  2088. doRun();
  2089. }
  2090. } else {
  2091. synchronized (socket) {
  2092. doRun();
  2093. }
  2094. }
  2095. }
  2096. private void doRun() {
  2097. // Process the request from this socket
  2098. if (socket.getSocket() == null) {
  2099. // Closed in another thread
  2100. return;
  2101. }
  2102. SocketState state = handler.process(socket, status);
  2103. if (state == Handler.SocketState.CLOSED) {
  2104. // Close socket and pool
  2105. closeSocket(socket.getSocket().longValue());
  2106. socket.reset(null, 1);
  2107. } else if (state == Handler.SocketState.LONG) {
  2108. socket.access();
  2109. if (socket.isAsync()) {
  2110. waitingRequests.add(socket);
  2111. }
  2112. } else if (state == Handler.SocketState.ASYNC_END) {
  2113. socket.access();
  2114. SocketProcessor proc = new SocketProcessor(socket,
  2115. SocketStatus.OPEN_READ);
  2116. getExecutor().execute(proc);
  2117. }
  2118. }
  2119. }
  2120. private static class AprSocketWrapper extends SocketWrapper<Long> {
  2121. // This field should only be used by Poller#run()
  2122. private int pollerFlags = 0;
  2123. public AprSocketWrapper(Long socket) {
  2124. super(socket);
  2125. }
  2126. }
  2127. }