ID: 46685 Updated by: [EMAIL PROTECTED] Reported By: scott dot php at scottrix dot co dot uk Status: Feedback Bug Type: Performance problem Operating System: Linux PHP Version: 5.2.6 New Comment:
You can do non blocking operations in php as well. Sorry to insist, but please provide a reproduce case (a script). I'm not saying that your patch is wrong or not necessary, but it may be possible already without changes. Previous Comments: ------------------------------------------------------------------------ [2008-11-26 11:07:31] scott dot php at scottrix dot co dot uk The script is running tests on our webpages over ssl. So it is spending time waiting to receive data from the webserver. The php source code for this waiting for data from the server (over SSL) employs a busy loop on a nonblocking socket (hence the EAGAIN read errors in strace output). ------------------------------------------------------------------------ [2008-11-26 10:56:10] [EMAIL PROTECTED] What are you trying to do, in userland? Any sample scripts? PHP can do multiplexing already and should work with ssl streams as well. ------------------------------------------------------------------------ [2008-11-26 10:50:29] scott dot php at scottrix dot co dot uk OK, so I couldn't find an add attachment button, so here is the patch. ----------------------------------------- --- ext/openssl/xp_ssl.c.orig 2008-11-18 11:34:50.000000000 +0000 +++ ext/openssl/xp_ssl.c 2008-11-18 11:34:40.000000000 +0000 @@ -223,15 +223,31 @@ int retry = 1; do { - nr_bytes = SSL_read(sslsock->ssl_handle, buf, count); + int ssl_read = 0; + if (! SSL_pending(sslsock->ssl_handle) ) { + int ssl_fd = SSL_get_fd(sslsock->ssl_handle); + struct timeval tv = { 1 , 0}; + fd_set fds; + int ret; + + FD_ZERO(&fds); + FD_SET(ssl_fd,&fds); + ret = select((ssl_fd+1),&fds,NULL,NULL,&tv); + if ((ret > 0) && FD_ISSET(ssl_fd,&fds)) ssl_read = 1; + } + else ssl_read = 1; + + if (ssl_read) { + nr_bytes = SSL_read(sslsock->ssl_handle, buf, count); - if (nr_bytes <= 0) { - retry = handle_ssl_error(stream, nr_bytes, 0 TSRMLS_CC); - stream->eof = (retry == 0 && errno != EAGAIN && !SSL_pending(sslsock->ssl_handle)); + if (nr_bytes <= 0) { + retry = handle_ssl_error(stream, nr_bytes, 0 TSRMLS_CC); + stream->eof = (retry == 0 && errno != EAGAIN && !SSL_pending(sslsock->ssl_handle)); - } else { - /* we got the data */ - break; + } else { + /* we got the data */ + break; + } } } while (retry); } @@ -429,6 +445,16 @@ if (n <= 0) { retry = handle_ssl_error(stream, n, 1 TSRMLS_CC); + if (retry) { + int ssl_fd = SSL_get_fd(sslsock->ssl_handle); + struct timeval tv = { 1 , 0}; + fd_set fds; + int ret; + + FD_ZERO(&fds); + FD_SET(ssl_fd,&fds); + ret = select((ssl_fd+1),&fds,NULL,NULL,&tv); + } } else { break; } ----------------------------------------- ------------------------------------------------------------------------ [2008-11-26 10:48:17] scott dot php at scottrix dot co dot uk Description: ------------ We have had some problems with CPU usage using PHP test scripts on some systems at work. Looking into the strace logs it appeared to be in a tight loop doing lots of reads mostly getting an EAGAIN error. Looking into the problem further it seems there are two locations in the file ext/openssl/xp_ssl.c that were causing these "loops". at line 223 (approx): int retry = 1; do { nr_bytes = SSL_read(sslsock->ssl_handle, buf, count); if (nr_bytes <= 0) { retry = handle_ssl_error(stream, nr_bytes, 0 TSRMLS_CC); stream->eof = (retry == 0 && errno != EAGAIN && SSL_pending(sslsock->ssl_handle)); } else { /* we got the data */ break; } } while (retry); and the loop around the lines (429): if (n <= 0) { retry = handle_ssl_error(stream, n, 1 TSRMLS_CC); } else { break; } They both involve SSL connections and I understand that one needs to be very careful using select in this area since the socket is a layer away from the SSL reading etc. However, the openssl code does come with some examples on how to do this and I have created a patch that seemed to help a lot in our case that I thought someone who knows more about php internals would like to look at and maybe incorporate to some extent into future releases. I will hopefully be able to attach the patch once I have submitted the bug. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=46685&edit=1