summaryrefslogtreecommitdiff
path: root/file_io
diff options
context:
space:
mode:
authorbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2007-05-13 05:00:33 +0000
committerbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2007-05-13 05:00:33 +0000
commitdb36b7dd8992aec53b52811ff48b9e894402c96e (patch)
tree1c88d43fefea06d797d6232319c930d4db12f18a /file_io
parentd2cb40c630ce9672e0d6455bf7a5293e366157bb (diff)
downloadlibapr-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.c4
-rw-r--r--file_io/unix/open.c4
-rw-r--r--file_io/unix/readwrite.c61
-rw-r--r--file_io/unix/seek.c5
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 {