diff options
author | bojan <bojan@13f79535-47bb-0310-9956-ffa450edef68> | 2007-05-13 05:00:33 +0000 |
---|---|---|
committer | bojan <bojan@13f79535-47bb-0310-9956-ffa450edef68> | 2007-05-13 05:00:33 +0000 |
commit | db36b7dd8992aec53b52811ff48b9e894402c96e (patch) | |
tree | 1c88d43fefea06d797d6232319c930d4db12f18a /file_io | |
parent | d2cb40c630ce9672e0d6455bf7a5293e366157bb (diff) | |
download | libapr-db36b7dd8992aec53b52811ff48b9e894402c96e.tar.gz |
Backport r537393, r537402 and r537405 from the trunk.
Improve thread safety of assorted file_io functions.
Patches by Davi Arnaut.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/branches/0.9.x@537554 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'file_io')
-rw-r--r-- | file_io/unix/filedup.c | 4 | ||||
-rw-r--r-- | file_io/unix/open.c | 4 | ||||
-rw-r--r-- | file_io/unix/readwrite.c | 61 | ||||
-rw-r--r-- | file_io/unix/seek.c | 5 |
4 files changed, 36 insertions, 38 deletions
diff --git a/file_io/unix/filedup.c b/file_io/unix/filedup.c index 82e2aa774..e9c0d1f65 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 @@ -126,7 +126,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/open.c b/file_io/unix/open.c index e459a0516..5a5615203 100644 --- a/file_io/unix/open.c +++ b/file_io/unix/open.c @@ -108,7 +108,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; } @@ -218,7 +218,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 ff69b1051..71fa6d225 100644 --- a/file_io/unix/readwrite.c +++ b/file_io/unix/readwrite.c @@ -43,20 +43,12 @@ APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size apr_uint64_t blocksize; apr_uint64_t size = *nbytes; -#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; } thefile->bufpos = 0; @@ -99,11 +91,9 @@ APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size if (*nbytes) { rv = 0; } -#if APR_HAS_THREADS - if (thefile->thlock) { - apr_thread_mutex_unlock(thefile->thlock); - } -#endif + + file_unlock(thefile); + return rv; } else { @@ -161,11 +151,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 @@ -191,11 +177,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 { @@ -242,12 +225,15 @@ APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile, const struct iove apr_size_t nvec, apr_size_t *nbytes) { #ifdef HAVE_WRITEV + apr_status_t rv; int bytes; -#endif + + file_lock(thefile); if (thefile->buffered) { apr_status_t rv = apr_file_flush(thefile); if (rv != APR_SUCCESS) { + file_unlock(thefile); return rv; } if (thefile->direction == 0) { @@ -262,15 +248,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 *nbytes = vec[0].iov_len; return apr_file_write(thefile, vec[0].iov_base, nbytes); @@ -306,24 +294,29 @@ 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) { - apr_int64_t written = 0; + file_lock(thefile); if (thefile->direction == 1 && thefile->bufpos) { + apr_int64_t written = 0; do { written = write(thefile->filedes, thefile->buffer, thefile->bufpos); } while (written == (apr_int64_t)-1 && errno == EINTR); if (written == (apr_int64_t)-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) diff --git a/file_io/unix/seek.c b/file_io/unix/seek.c index 08ea64a6d..552f8fd1c 100644 --- a/file_io/unix/seek.c +++ b/file_io/unix/seek.c @@ -58,6 +58,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); @@ -75,6 +77,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 { |