|
74 | 74 |
|
75 | 75 | #include "php_getopt.h" |
76 | 76 |
|
| 77 | +#include "php_poll.h" |
77 | 78 | #ifndef PHP_WIN32 |
78 | | -# define php_select(m, r, w, e, t) select(m, r, w, e, t) |
79 | 79 | # define SOCK_EINVAL EINVAL |
80 | 80 | # define SOCK_EAGAIN EAGAIN |
81 | | -# define SOCK_EINTR EINTR |
82 | 81 | # define SOCK_EADDRINUSE EADDRINUSE |
83 | 82 | #else |
84 | | -# include "win32/select.h" |
85 | 83 | # define SOCK_EINVAL WSAEINVAL |
86 | 84 | # define SOCK_EAGAIN WSAEWOULDBLOCK |
87 | | -# define SOCK_EINTR WSAEINTR |
88 | 85 | # define SOCK_EADDRINUSE WSAEADDRINUSE |
89 | 86 | #endif |
90 | 87 |
|
@@ -117,11 +114,9 @@ static zend_long php_cli_server_workers_max; |
117 | 114 | static zend_string* cli_concat_persistent_zstr_with_char(zend_string *old_str, const char *at, size_t length); |
118 | 115 |
|
119 | 116 | typedef struct php_cli_server_poller { |
120 | | - fd_set rfds, wfds; |
121 | | - struct { |
122 | | - fd_set rfds, wfds; |
123 | | - } active; |
124 | | - php_socket_t max_fd; |
| 117 | + php_poll_ctx *poll_ctx; |
| 118 | + php_poll_event *events; |
| 119 | + int count; |
125 | 120 | } php_cli_server_poller; |
126 | 121 |
|
127 | 122 | typedef struct php_cli_server_request { |
@@ -821,112 +816,48 @@ sapi_module_struct cli_server_sapi_module = { |
821 | 816 |
|
822 | 817 | static void php_cli_server_poller_ctor(php_cli_server_poller *poller) /* {{{ */ |
823 | 818 | { |
824 | | - FD_ZERO(&poller->rfds); |
825 | | - FD_ZERO(&poller->wfds); |
826 | | - poller->max_fd = -1; |
| 819 | + uint32_t flags = PHP_POLL_FLAG_PERSISTENT | PHP_POLL_FLAG_RAW_EVENTS; |
| 820 | + php_poll_register_backends(); |
| 821 | + poller->poll_ctx = php_poll_create(PHP_POLL_BACKEND_AUTO, flags); |
| 822 | + php_poll_init(poller->poll_ctx); |
| 823 | + poller->count = php_poll_get_suitable_max_events(poller->poll_ctx); |
| 824 | + poller->events = pecalloc(poller->count, sizeof(php_poll_event), 1); |
827 | 825 | } /* }}} */ |
828 | 826 |
|
829 | 827 | static void php_cli_server_poller_add(php_cli_server_poller *poller, int mode, php_socket_t fd) /* {{{ */ |
830 | 828 | { |
831 | | - if (mode & POLLIN) { |
832 | | - PHP_SAFE_FD_SET(fd, &poller->rfds); |
833 | | - } |
834 | | - if (mode & POLLOUT) { |
835 | | - PHP_SAFE_FD_SET(fd, &poller->wfds); |
836 | | - } |
837 | | - if (fd > poller->max_fd) { |
838 | | - poller->max_fd = fd; |
839 | | - } |
| 829 | + php_poll_add(poller->poll_ctx, fd, mode, NULL); |
840 | 830 | } /* }}} */ |
841 | 831 |
|
842 | 832 | static void php_cli_server_poller_remove(php_cli_server_poller *poller, int mode, php_socket_t fd) /* {{{ */ |
843 | 833 | { |
844 | | - if (mode & POLLIN) { |
845 | | - PHP_SAFE_FD_CLR(fd, &poller->rfds); |
846 | | - } |
847 | | - if (mode & POLLOUT) { |
848 | | - PHP_SAFE_FD_CLR(fd, &poller->wfds); |
849 | | - } |
850 | | -#ifndef PHP_WIN32 |
851 | | - if (fd == poller->max_fd) { |
852 | | - while (fd > 0) { |
853 | | - fd--; |
854 | | - if (PHP_SAFE_FD_ISSET(fd, &poller->rfds) || PHP_SAFE_FD_ISSET(fd, &poller->wfds)) { |
855 | | - break; |
856 | | - } |
857 | | - } |
858 | | - poller->max_fd = fd; |
859 | | - } |
860 | | -#endif |
| 834 | + /* XXX: Should be modify if mode is different from what was added? */ |
| 835 | + php_poll_remove(poller->poll_ctx, fd); |
861 | 836 | } /* }}} */ |
862 | 837 |
|
863 | 838 | static int php_cli_server_poller_poll(php_cli_server_poller *poller, struct timeval *tv) /* {{{ */ |
864 | 839 | { |
865 | | - memmove(&poller->active.rfds, &poller->rfds, sizeof(poller->rfds)); |
866 | | - memmove(&poller->active.wfds, &poller->wfds, sizeof(poller->wfds)); |
867 | | - return php_select(poller->max_fd + 1, &poller->active.rfds, &poller->active.wfds, NULL, tv); |
| 840 | + struct timespec ts; |
| 841 | + TIMEVAL_TO_TIMESPEC(tv, &ts); |
| 842 | + return php_poll_wait(poller->poll_ctx, poller->events, poller->count, &ts); |
868 | 843 | } /* }}} */ |
869 | 844 |
|
870 | 845 | static zend_result php_cli_server_poller_iter_on_active(php_cli_server_poller *poller, void *opaque, zend_result(*callback)(void *, php_socket_t fd, int events)) /* {{{ */ |
871 | 846 | { |
872 | 847 | zend_result retval = SUCCESS; |
873 | | -#ifdef PHP_WIN32 |
874 | | - struct socket_entry { |
875 | | - SOCKET fd; |
876 | | - int events; |
877 | | - } entries[FD_SETSIZE * 2]; |
878 | | - size_t i; |
879 | | - struct socket_entry *n = entries, *m; |
880 | | - |
881 | | - for (i = 0; i < poller->active.rfds.fd_count; i++) { |
882 | | - n->events = POLLIN; |
883 | | - n->fd = poller->active.rfds.fd_array[i]; |
884 | | - n++; |
885 | | - } |
886 | | - |
887 | | - m = n; |
888 | | - for (i = 0; i < poller->active.wfds.fd_count; i++) { |
889 | | - struct socket_entry *e; |
890 | | - SOCKET fd = poller->active.wfds.fd_array[i]; |
891 | | - for (e = entries; e < m; e++) { |
892 | | - if (e->fd == fd) { |
893 | | - e->events |= POLLOUT; |
| 848 | + for (int i = 0; i < poller->count; i++) { |
| 849 | + int fd = poller->events[i].fd; |
| 850 | + if (poller->events[i].revents & PHP_POLL_READ) { |
| 851 | + if (SUCCESS != callback(opaque, fd, PHP_POLL_READ)) { |
| 852 | + retval = FAILURE; |
894 | 853 | } |
895 | 854 | } |
896 | | - if (e == m) { |
897 | | - assert(n < entries + FD_SETSIZE * 2); |
898 | | - n->events = POLLOUT; |
899 | | - n->fd = fd; |
900 | | - n++; |
901 | | - } |
902 | | - } |
903 | | - |
904 | | - { |
905 | | - struct socket_entry *e = entries; |
906 | | - for (; e < n; e++) { |
907 | | - if (SUCCESS != callback(opaque, e->fd, e->events)) { |
| 855 | + if (poller->events[i].revents & PHP_POLL_WRITE) { |
| 856 | + if (SUCCESS != callback(opaque, fd, PHP_POLL_WRITE)) { |
908 | 857 | retval = FAILURE; |
909 | 858 | } |
910 | 859 | } |
911 | 860 | } |
912 | | - |
913 | | -#else |
914 | | - php_socket_t fd; |
915 | | - const php_socket_t max_fd = poller->max_fd; |
916 | | - |
917 | | - for (fd=0 ; fd<=max_fd ; fd++) { |
918 | | - if (PHP_SAFE_FD_ISSET(fd, &poller->active.rfds)) { |
919 | | - if (SUCCESS != callback(opaque, fd, POLLIN)) { |
920 | | - retval = FAILURE; |
921 | | - } |
922 | | - } |
923 | | - if (PHP_SAFE_FD_ISSET(fd, &poller->active.wfds)) { |
924 | | - if (SUCCESS != callback(opaque, fd, POLLOUT)) { |
925 | | - retval = FAILURE; |
926 | | - } |
927 | | - } |
928 | | - } |
929 | | -#endif |
930 | 861 | return retval; |
931 | 862 | } /* }}} */ |
932 | 863 |
|
@@ -1901,7 +1832,7 @@ static size_t php_cli_server_client_send_through(php_cli_server_client *client, |
1901 | 1832 | if (nbytes_sent < 0) { |
1902 | 1833 | int err = php_socket_errno(); |
1903 | 1834 | if (err == SOCK_EAGAIN) { |
1904 | | - int nfds = php_pollfd_for(client->sock, POLLOUT, &tv); |
| 1835 | + int nfds = php_pollfd_for(client->sock, PHP_POLL_WRITE, &tv); |
1905 | 1836 | if (nfds > 0) { |
1906 | 1837 | continue; |
1907 | 1838 | } else { |
@@ -2090,7 +2021,7 @@ static zend_result php_cli_server_send_error_page(php_cli_server *server, php_cl |
2090 | 2021 | } |
2091 | 2022 |
|
2092 | 2023 | php_cli_server_log_response(client, status, errstr ? errstr : "?"); |
2093 | | - php_cli_server_poller_add(&server->poller, POLLOUT, client->sock); |
| 2024 | + php_cli_server_poller_add(&server->poller, PHP_POLL_WRITE, client->sock); |
2094 | 2025 | if (errstr) { |
2095 | 2026 | pefree(errstr, 1); |
2096 | 2027 | } |
@@ -2203,7 +2134,7 @@ static zend_result php_cli_server_begin_send_static(php_cli_server *server, php_ |
2203 | 2134 | php_cli_server_buffer_append(&client->content_sender.buffer, chunk); |
2204 | 2135 | } |
2205 | 2136 | php_cli_server_log_response(client, 200, NULL); |
2206 | | - php_cli_server_poller_add(&server->poller, POLLOUT, client->sock); |
| 2137 | + php_cli_server_poller_add(&server->poller, PHP_POLL_WRITE, client->sock); |
2207 | 2138 | return SUCCESS; |
2208 | 2139 | } |
2209 | 2140 | /* }}} */ |
@@ -2405,7 +2336,7 @@ static void php_cli_server_client_dtor_wrapper(zval *zv) /* {{{ */ |
2405 | 2336 |
|
2406 | 2337 | shutdown(p->sock, SHUT_RDWR); |
2407 | 2338 | closesocket(p->sock); |
2408 | | - php_cli_server_poller_remove(&p->server->poller, POLLIN | POLLOUT, p->sock); |
| 2339 | + php_cli_server_poller_remove(&p->server->poller, PHP_POLL_READ | PHP_POLL_WRITE, p->sock); |
2409 | 2340 | php_cli_server_client_dtor(p); |
2410 | 2341 | pefree(p, 1); |
2411 | 2342 | } /* }}} */ |
@@ -2575,7 +2506,7 @@ static zend_result php_cli_server_ctor(php_cli_server *server, const char *addr, |
2575 | 2506 |
|
2576 | 2507 | php_cli_server_poller_ctor(&server->poller); |
2577 | 2508 |
|
2578 | | - php_cli_server_poller_add(&server->poller, POLLIN, server_sock); |
| 2509 | + php_cli_server_poller_add(&server->poller, PHP_POLL_READ, server_sock); |
2579 | 2510 |
|
2580 | 2511 | server->host = host; |
2581 | 2512 | server->port = port; |
@@ -2641,10 +2572,10 @@ static zend_result php_cli_server_recv_event_read_request(php_cli_server *server |
2641 | 2572 | if (client->request.request_method == PHP_HTTP_NOT_IMPLEMENTED) { |
2642 | 2573 | return php_cli_server_send_error_page(server, client, 501); |
2643 | 2574 | } |
2644 | | - php_cli_server_poller_remove(&server->poller, POLLIN, client->sock); |
| 2575 | + php_cli_server_poller_remove(&server->poller, PHP_POLL_READ, client->sock); |
2645 | 2576 | return php_cli_server_dispatch(server, client); |
2646 | 2577 | case 0: |
2647 | | - php_cli_server_poller_add(&server->poller, POLLIN, client->sock); |
| 2578 | + php_cli_server_poller_add(&server->poller, PHP_POLL_READ, client->sock); |
2648 | 2579 | return SUCCESS; |
2649 | 2580 | default: ZEND_UNREACHABLE(); |
2650 | 2581 | } |
@@ -2724,14 +2655,14 @@ static zend_result php_cli_server_do_event_for_each_fd_callback(void *_params, p |
2724 | 2655 |
|
2725 | 2656 | zend_hash_index_update_ptr(&server->clients, client_sock, client); |
2726 | 2657 |
|
2727 | | - php_cli_server_poller_add(&server->poller, POLLIN, client->sock); |
| 2658 | + php_cli_server_poller_add(&server->poller, PHP_POLL_READ, client->sock); |
2728 | 2659 | } else { |
2729 | 2660 | php_cli_server_client *client; |
2730 | 2661 | if (NULL != (client = zend_hash_index_find_ptr(&server->clients, fd))) { |
2731 | | - if (event & POLLIN) { |
| 2662 | + if (event & PHP_POLL_READ) { |
2732 | 2663 | params->rhandler(server, client); |
2733 | 2664 | } |
2734 | | - if (event & POLLOUT) { |
| 2665 | + if (event & PHP_POLL_WRITE) { |
2735 | 2666 | params->whandler(server, client); |
2736 | 2667 | } |
2737 | 2668 | } |
@@ -2767,12 +2698,11 @@ static zend_result php_cli_server_do_event_loop(php_cli_server *server) /* {{{ * |
2767 | 2698 | } else if (n == 0) { |
2768 | 2699 | /* do nothing */ |
2769 | 2700 | } else { |
2770 | | - int err = php_socket_errno(); |
2771 | | - if (err != SOCK_EINTR) { |
| 2701 | + php_poll_error err = php_poll_get_error(server->poller.poll_ctx); |
| 2702 | + if (err != PHP_POLL_ERR_INTERRUPTED) { |
2772 | 2703 | if (php_cli_server_log_level >= PHP_CLI_SERVER_LOG_ERROR) { |
2773 | | - char *errstr = php_socket_strerror(err, NULL, 0); |
2774 | | - php_cli_server_logf(PHP_CLI_SERVER_LOG_ERROR, "%s", errstr); |
2775 | | - efree(errstr); |
| 2704 | + const char *errstr = php_poll_error_string(err); |
| 2705 | + php_cli_server_logf(PHP_CLI_SERVER_LOG_ERROR, "Poll error: %s", errstr); |
2776 | 2706 | } |
2777 | 2707 | retval = FAILURE; |
2778 | 2708 | goto out; |
|
0 commit comments