diff options
author | Bojan Smojver <bojan@apache.org> | 2007-05-12 11:47:29 +0000 |
---|---|---|
committer | Bojan Smojver <bojan@apache.org> | 2007-05-12 11:47:29 +0000 |
commit | aa5dcf4e74202d675f1b70f4e53f4bbd7e1a5e14 (patch) | |
tree | 1ecdc972e5df5f9ebc1409a495942e51f85d0e50 /file_io/unix | |
parent | 41efc614ad5d7dff7165aefc4a7626999cad13b6 (diff) | |
download | apr-aa5dcf4e74202d675f1b70f4e53f4bbd7e1a5e14.tar.gz |
Improve thread safety of assorted file_io functions.
Patches by Davi Arnaut.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@537393 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'file_io/unix')
-rw-r--r-- | file_io/unix/buffer.c | 22 | ||||
-rw-r--r-- | file_io/unix/filedup.c | 4 | ||||
-rw-r--r-- | file_io/unix/filestat.c | 1 | ||||
-rw-r--r-- | file_io/unix/open.c | 5 | ||||
-rw-r--r-- | file_io/unix/readwrite.c | 75 | ||||
-rw-r--r-- | file_io/unix/seek.c | 6 |
6 files changed, 41 insertions, 72 deletions
diff --git a/file_io/unix/buffer.c b/file_io/unix/buffer.c index 5e384d21f..cc8474fbe 100644 --- a/file_io/unix/buffer.c +++ b/file_io/unix/buffer.c @@ -24,21 +24,13 @@ APR_DECLARE(apr_status_t) apr_file_buffer_set(apr_file_t *file, { apr_status_t rv; -#if APR_HAS_THREADS - if (file->thlock) { - apr_thread_mutex_lock(file->thlock); - } -#endif - + file_lock(file); + if(file->buffered) { /* Flush the existing buffer */ rv = apr_file_flush(file); if (rv != APR_SUCCESS) { -#if APR_HAS_THREADS - if (file->thlock) { - apr_thread_mutex_unlock(file->thlock); - } -#endif + file_unlock(file); return rv; } } @@ -56,12 +48,8 @@ APR_DECLARE(apr_status_t) apr_file_buffer_set(apr_file_t *file, */ file->buffered = 0; } - -#if APR_HAS_THREADS - if (file->thlock) { - apr_thread_mutex_unlock(file->thlock); - } -#endif + + file_unlock(file); return APR_SUCCESS; } diff --git a/file_io/unix/filedup.c b/file_io/unix/filedup.c index d7a5d7775..3b40eab8c 100644 --- a/file_io/unix/filedup.c +++ b/file_io/unix/filedup.c @@ -55,7 +55,7 @@ static apr_status_t file_dup(apr_file_t **new_file, #if APR_HAS_THREADS if ((*new_file)->buffered && !(*new_file)->thlock && old_file->thlock) { apr_thread_mutex_create(&((*new_file)->thlock), - APR_THREAD_MUTEX_DEFAULT, p); + APR_THREAD_MUTEX_NESTED, p); } #endif /* As above, only create the buffer if we haven't already @@ -133,7 +133,7 @@ APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file, #if APR_HAS_THREADS if (old_file->thlock) { apr_thread_mutex_create(&((*new_file)->thlock), - APR_THREAD_MUTEX_DEFAULT, p); + APR_THREAD_MUTEX_NESTED, p); apr_thread_mutex_destroy(old_file->thlock); } #endif /* APR_HAS_THREADS */ diff --git a/file_io/unix/filestat.c b/file_io/unix/filestat.c index e6f73e6fc..98ef74ec7 100644 --- a/file_io/unix/filestat.c +++ b/file_io/unix/filestat.c @@ -107,7 +107,6 @@ APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo, struct_stat info; if (thefile->buffered) { - /* XXX: flush here is not mutex protected */ apr_status_t rv = apr_file_flush(thefile); if (rv != APR_SUCCESS) return rv; diff --git a/file_io/unix/open.c b/file_io/unix/open.c index f6b1a7cf4..6a712a842 100644 --- a/file_io/unix/open.c +++ b/file_io/unix/open.c @@ -32,7 +32,6 @@ apr_status_t apr_unix_file_cleanup(void *thefile) apr_status_t flush_rv = APR_SUCCESS, rv = APR_SUCCESS; if (file->buffered) { - /* XXX: flush here is not mutex protected */ flush_rv = apr_file_flush(file); } if (close(file->filedes) == 0) { @@ -123,7 +122,7 @@ APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, #if APR_HAS_THREADS if ((flag & APR_BUFFERED) && (flag & APR_XTHREAD)) { rv = apr_thread_mutex_create(&thlock, - APR_THREAD_MUTEX_DEFAULT, pool); + APR_THREAD_MUTEX_NESTED, pool); if (rv) { return rv; } @@ -247,7 +246,7 @@ APR_DECLARE(apr_status_t) apr_os_file_put(apr_file_t **file, if ((*file)->flags & APR_XTHREAD) { apr_status_t rv; rv = apr_thread_mutex_create(&((*file)->thlock), - APR_THREAD_MUTEX_DEFAULT, pool); + APR_THREAD_MUTEX_NESTED, pool); if (rv) { return rv; } diff --git a/file_io/unix/readwrite.c b/file_io/unix/readwrite.c index 412d7c8ba..15fcd8fdf 100644 --- a/file_io/unix/readwrite.c +++ b/file_io/unix/readwrite.c @@ -93,19 +93,9 @@ APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size } if (thefile->buffered) { -#if APR_HAS_THREADS - if (thefile->thlock) { - apr_thread_mutex_lock(thefile->thlock); - } -#endif - + file_lock(thefile); rv = file_read_buffered(thefile, buf, nbytes); - -#if APR_HAS_THREADS - if (thefile->thlock) { - apr_thread_mutex_unlock(thefile->thlock); - } -#endif + file_unlock(thefile); return rv; } else { @@ -163,11 +153,7 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a int blocksize; int size = *nbytes; -#if APR_HAS_THREADS - if (thefile->thlock) { - apr_thread_mutex_lock(thefile->thlock); - } -#endif + file_lock(thefile); if ( thefile->direction == 0 ) { /* Position file pointer for writing at the offset we are @@ -193,11 +179,8 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a size -= blocksize; } -#if APR_HAS_THREADS - if (thefile->thlock) { - apr_thread_mutex_unlock(thefile->thlock); - } -#endif + file_unlock(thefile); + return rv; } else { @@ -243,13 +226,16 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile, const struct iovec *vec, apr_size_t nvec, apr_size_t *nbytes) { + apr_status_t rv; #ifdef HAVE_WRITEV apr_ssize_t bytes; -#endif + + file_lock(thefile); if (thefile->buffered) { - apr_status_t rv = apr_file_flush(thefile); + rv = apr_file_flush(thefile); if (rv != APR_SUCCESS) { + file_unlock(thefile); return rv; } if (thefile->direction == 0) { @@ -263,15 +249,17 @@ APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile, const struct iove } } -#ifdef HAVE_WRITEV if ((bytes = writev(thefile->filedes, vec, nvec)) < 0) { *nbytes = 0; - return errno; + rv = errno; } else { *nbytes = bytes; - return APR_SUCCESS; + rv = APR_SUCCESS; } + + file_unlock(thefile); + return rv; #else /** * The problem with trying to output the entire iovec is that we cannot @@ -319,7 +307,10 @@ APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile) APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile) { + apr_status_t rv = APR_SUCCESS; + if (thefile->buffered) { + file_lock(thefile); if (thefile->direction == 1 && thefile->bufpos) { apr_ssize_t written; @@ -327,16 +318,18 @@ APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile) written = write(thefile->filedes, thefile->buffer, thefile->bufpos); } while (written == -1 && errno == EINTR); if (written == -1) { - return errno; + rv = errno; + } else { + thefile->filePtr += written; + thefile->bufpos = 0; } - thefile->filePtr += written; - thefile->bufpos = 0; } + file_unlock(thefile); } /* There isn't anything to do if we aren't buffering the output * so just return success. */ - return APR_SUCCESS; + return rv; } APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile) @@ -356,21 +349,12 @@ APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile) * 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 + file_lock(thefile); if (thefile->direction == 1) { rv = apr_file_flush(thefile); if (rv) { -#if APR_HAS_THREADS - if (thefile->thlock) { - apr_thread_mutex_unlock(thefile->thlock); - } -#endif + file_unlock(thefile); return rv; } @@ -398,12 +382,7 @@ APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile) } ++str; } - -#if APR_HAS_THREADS - if (thefile->thlock) { - apr_thread_mutex_unlock(thefile->thlock); - } -#endif + file_unlock(thefile); } else { while (str < final) { /* leave room for trailing '\0' */ diff --git a/file_io/unix/seek.c b/file_io/unix/seek.c index 03b0345c8..3e7e33ee4 100644 --- a/file_io/unix/seek.c +++ b/file_io/unix/seek.c @@ -22,7 +22,6 @@ static apr_status_t setptr(apr_file_t *thefile, apr_off_t pos ) apr_status_t rv; if (thefile->direction == 1) { - /* XXX: flush here is not mutex protected */ rv = apr_file_flush(thefile); if (rv) { return rv; @@ -60,6 +59,8 @@ APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t wh int rc = EINVAL; apr_finfo_t finfo; + file_lock(thefile); + switch (where) { case APR_SET: rc = setptr(thefile, *offset); @@ -77,6 +78,9 @@ APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t wh } *offset = thefile->filePtr - thefile->dataRead + thefile->bufpos; + + file_unlock(thefile); + return rc; } else { |