This function connects to the server and sends enough data to * ensure the child wakes up and processes a new connection. This * permits the MPM to skip the poll when there is only one listening * socket, because it provides a alternate way to unblock an accept() * when the pod is used. */
| 623 | * socket, because it provides a alternate way to unblock an accept() |
| 624 | * when the pod is used. */ |
| 625 | static apr_status_t dummy_connection(ap_pod_t *pod) |
| 626 | { |
| 627 | const char *data; |
| 628 | apr_status_t rv; |
| 629 | apr_socket_t *sock; |
| 630 | apr_pool_t *p; |
| 631 | apr_size_t len; |
| 632 | ap_listen_rec *lp; |
| 633 | |
| 634 | /* create a temporary pool for the socket. pconf stays around too long */ |
| 635 | rv = apr_pool_create(&p, pod->p); |
| 636 | if (rv != APR_SUCCESS) { |
| 637 | return rv; |
| 638 | } |
| 639 | apr_pool_tag(p, "dummy_connection"); |
| 640 | |
| 641 | /* If possible, find a listener which is configured for |
| 642 | * plain-HTTP, not SSL; using an SSL port would either be |
| 643 | * expensive to do correctly (performing a complete SSL handshake) |
| 644 | * or cause log spam by doing incorrectly (simply sending EOF). */ |
| 645 | lp = ap_listeners; |
| 646 | while (lp && lp->protocol && ap_cstr_casecmp(lp->protocol, "http") != 0) { |
| 647 | lp = lp->next; |
| 648 | } |
| 649 | if (!lp) { |
| 650 | lp = ap_listeners; |
| 651 | } |
| 652 | |
| 653 | rv = apr_socket_create(&sock, lp->bind_addr->family, SOCK_STREAM, 0, p); |
| 654 | if (rv != APR_SUCCESS) { |
| 655 | ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00054) |
| 656 | "get socket to connect to listener"); |
| 657 | apr_pool_destroy(p); |
| 658 | return rv; |
| 659 | } |
| 660 | |
| 661 | /* on some platforms (e.g., FreeBSD), the kernel won't accept many |
| 662 | * queued connections before it starts blocking local connects... |
| 663 | * we need to keep from blocking too long and instead return an error, |
| 664 | * because the MPM won't want to hold up a graceful restart for a |
| 665 | * long time |
| 666 | */ |
| 667 | rv = apr_socket_timeout_set(sock, apr_time_from_sec(3)); |
| 668 | if (rv != APR_SUCCESS) { |
| 669 | ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, APLOGNO(00055) |
| 670 | "set timeout on socket to connect to listener"); |
| 671 | apr_socket_close(sock); |
| 672 | apr_pool_destroy(p); |
| 673 | return rv; |
| 674 | } |
| 675 | |
| 676 | rv = apr_socket_connect(sock, lp->bind_addr); |
| 677 | if (rv != APR_SUCCESS) { |
| 678 | int log_level = APLOG_WARNING; |
| 679 | |
| 680 | if (APR_STATUS_IS_TIMEUP(rv)) { |
| 681 | /* probably some server processes bailed out already and there |
| 682 | * is nobody around to call accept and clear out the kernel |
no test coverage detected