You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by je...@apache.org on 2004/08/02 11:47:48 UTC
cvs commit: apr/file_io/unix readwrite.c
jerenkrantz 2004/08/02 02:47:48
Modified: . CHANGES
file_io/unix readwrite.c
Log:
Improve apr_file_gets() performance on buffered files by not calling
apr_file_read() on each byte if we don't have to.
(mod_negotiation requests call apr_file_gets() for each line in the map file,
which can get to be quite expensive to have repeated memcpy()'s for one byte!)
Revision Changes Path
1.487 +3 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.486
retrieving revision 1.487
diff -u -u -r1.486 -r1.487
--- CHANGES 1 Aug 2004 00:52:20 -0000 1.486
+++ CHANGES 2 Aug 2004 09:47:48 -0000 1.487
@@ -1,4 +1,7 @@
Changes for APR 1.1 [Deferring these features when 1.0 is rolled out.]
+
+ *) Improve apr_file_gets() performance on buffered files. [Justin Erenkrantz]
+
*) Win32: Fix bug in apr_socket_sendfile that interferred with
Win32 LSPs. PR 23982 [Jan Bilek, Bill Stoddard]
1.90 +55 -11 apr/file_io/unix/readwrite.c
Index: readwrite.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/readwrite.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -u -r1.89 -r1.90
--- readwrite.c 27 Mar 2004 13:11:17 -0000 1.89
+++ readwrite.c 2 Aug 2004 09:47:48 -0000 1.90
@@ -24,9 +24,6 @@
#define USE_WAIT_FOR_IO
#endif
-/* problems:
- * 1) ungetchar not used for buffered files
- */
APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *nbytes)
{
apr_ssize_t rv;
@@ -311,18 +308,65 @@
return APR_SUCCESS;
}
- while (str < final) { /* leave room for trailing '\0' */
- nbytes = 1;
- rv = apr_file_read(thefile, str, &nbytes);
- if (rv != APR_SUCCESS) {
- break;
+ /* If we have an underlying buffer, we can be *much* more efficient
+ * and skip over the apr_file_read calls.
+ */
+ if (thefile->buffered) {
+
+#if APR_HAS_THREADS
+ if (thefile->thlock) {
+ apr_thread_mutex_lock(thefile->thlock);
+ }
+#endif
+
+ if (thefile->direction == 1) {
+ apr_file_flush(thefile);
+ thefile->direction = 0;
+ thefile->bufpos = 0;
+ thefile->dataRead = 0;
+ }
+
+ while (str < final) { /* leave room for trailing '\0' */
+ /* Force ungetc leftover to call apr_file_read. */
+ if (thefile->bufpos < thefile->dataRead &&
+ thefile->ungetchar == -1) {
+ *str = thefile->buffer[thefile->bufpos++];
+ }
+ else {
+ nbytes = 1;
+ rv = apr_file_read(thefile, str, &nbytes);
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+ }
+ if (*str == '\n') {
+ ++str;
+ break;
+ }
+ ++str;
}
- if (*str == '\n') {
+
+#if APR_HAS_THREADS
+ if (thefile->thlock) {
+ apr_thread_mutex_unlock(thefile->thlock);
+ }
+#endif
+ }
+ else {
+ while (str < final) { /* leave room for trailing '\0' */
+ nbytes = 1;
+ rv = apr_file_read(thefile, str, &nbytes);
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+ if (*str == '\n') {
+ ++str;
+ break;
+ }
++str;
- break;
}
- ++str;
}
+
/* We must store a terminating '\0' if we've stored any chars. We can
* get away with storing it if we hit an error first.
*/