mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
streams/xp_socket: eliminate poll() when MSG_DONTWAIT is available
If there is a zero timeout and MSG_DONTWAIT is available (or the socket is non-blocking), the poll() call is not necessary, and we can just call recv() right away. Before this change: poll([{fd=4, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout) poll([{fd=4, events=POLLIN|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=4, revents=POLLIN}]) recvfrom(4, "HTTP/1.1 301 Moved Permanently\r\n"..., 8192, MSG_DONTWAIT, NULL, NULL) = 348 poll([{fd=4, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 1 ([{fd=4, revents=POLLIN}]) recvfrom(4, "", 1, MSG_PEEK, NULL, NULL) = 0 After this change: recvfrom(4, 0x7ffe0cc719a0, 1, MSG_PEEK|MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) poll([{fd=4, events=POLLIN|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=4, revents=POLLIN}]) recvfrom(4, "HTTP/1.1 301 Moved Permanently\r\n"..., 8192, MSG_DONTWAIT, NULL, NULL) = 348 recvfrom(4, "", 1, MSG_PEEK|MSG_DONTWAIT, NULL, NULL) = 0 The first poll() is replaced by recvfrom(), and the third poll() is omitted completely. ext/openssl/xp_ssl: eliminate poll() when MSG_DONTWAIT is available If there is a zero timeout and MSG_DONTWAIT is available (or the socket is non-blocking), the poll() call is not necessary, and we can just call recv() right away. Closes GH-8092.
This commit is contained in:
parent
7d6821a98a
commit
2d986310f1
6
NEWS
6
NEWS
@ -28,6 +28,9 @@ PHP NEWS
|
||||
- ODBC:
|
||||
. Fixed handling of single-key connection strings. (Calvin Buckley)
|
||||
|
||||
- OpenSSL:
|
||||
. Discard poll calls on socket when no timeout/non blocking/MSG_DONTWAIT. (Max Kellermann)
|
||||
|
||||
- PCRE:
|
||||
. Implemented FR #77726 (Allow null character in regex patterns). (cmb)
|
||||
|
||||
@ -37,6 +40,9 @@ PHP NEWS
|
||||
- Standard:
|
||||
. Deprecated utf8_encode() and utf8_decode(). (Rowan Tommins)
|
||||
|
||||
- Streams:
|
||||
. Discard poll calls on socket when no timeout/non blocking/MSG_DONTWAIT. (Max Kellermann)
|
||||
|
||||
09 Jun 2022, PHP 8.2.0alpha1
|
||||
|
||||
- CLI:
|
||||
|
@ -46,6 +46,10 @@
|
||||
#undef X509_EXTENSIONS
|
||||
#endif
|
||||
|
||||
#ifndef MSG_DONTWAIT
|
||||
# define MSG_DONTWAIT 0
|
||||
#endif
|
||||
|
||||
/* Flags for determining allowed stream crypto methods */
|
||||
#define STREAM_CRYPTO_IS_CLIENT (1<<0)
|
||||
#define STREAM_CRYPTO_METHOD_SSLv2 (1<<1)
|
||||
@ -2395,7 +2399,10 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
|
||||
|
||||
if (sslsock->s.socket == -1) {
|
||||
alive = 0;
|
||||
} else if (php_pollfd_for(sslsock->s.socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) {
|
||||
} else if ((!sslsock->ssl_active && value == 0 && (MSG_DONTWAIT || !sslsock->s.is_blocked)) ||
|
||||
php_pollfd_for(sslsock->s.socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) {
|
||||
/* the poll() call was skipped if the socket is non-blocking (or MSG_DONTWAIT is available) and if the timeout is zero */
|
||||
/* additionally, we don't use this optimization if SSL is active because in that case, we're not using MSG_DONTWAIT */
|
||||
if (sslsock->ssl_active) {
|
||||
int n = SSL_peek(sslsock->ssl_handle, &buf, sizeof(buf));
|
||||
if (n <= 0) {
|
||||
@ -2413,7 +2420,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
|
||||
alive = 0;
|
||||
}
|
||||
}
|
||||
} else if (0 == recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) {
|
||||
} else if (0 == recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK|MSG_DONTWAIT) && php_socket_errno() != EAGAIN) {
|
||||
alive = 0;
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +337,8 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void
|
||||
|
||||
if (sock->socket == -1) {
|
||||
alive = 0;
|
||||
} else if (php_pollfd_for(sock->socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) {
|
||||
} else if ((value == 0 && (MSG_DONTWAIT || !sock->is_blocked)) || php_pollfd_for(sock->socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) {
|
||||
/* the poll() call was skipped if the socket is non-blocking (or MSG_DONTWAIT is available) and if the timeout is zero */
|
||||
#ifdef PHP_WIN32
|
||||
int ret;
|
||||
#else
|
||||
@ -345,7 +346,7 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void
|
||||
#endif
|
||||
int err;
|
||||
|
||||
ret = recv(sock->socket, &buf, sizeof(buf), MSG_PEEK);
|
||||
ret = recv(sock->socket, &buf, sizeof(buf), MSG_PEEK|MSG_DONTWAIT);
|
||||
err = php_socket_errno();
|
||||
if (0 == ret || /* the counterpart did properly shutdown*/
|
||||
(0 > ret && err != EWOULDBLOCK && err != EAGAIN && err != EMSGSIZE)) { /* there was an unrecoverable error */
|
||||
|
Loading…
Reference in New Issue
Block a user