summaryrefslogtreecommitdiff
path: root/file_io/unix
diff options
context:
space:
mode:
authorbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2007-05-12 11:47:29 +0000
committerbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2007-05-12 11:47:29 +0000
commitb9a4cc74de4492eb9750ae95aeee5054ed0b0acf (patch)
tree1ecdc972e5df5f9ebc1409a495942e51f85d0e50 /file_io/unix
parent567718da876063aeb57ae5d884c7799f762e66ec (diff)
downloadlibapr-b9a4cc74de4492eb9750ae95aeee5054ed0b0acf.tar.gz
Improve thread safety of assorted file_io functions.
Patches by Davi Arnaut. git-svn-id: http://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.c22
-rw-r--r--file_io/unix/filedup.c4
-rw-r--r--file_io/unix/filestat.c1
-rw-r--r--file_io/unix/open.c5
-rw-r--r--file_io/unix/readwrite.c75
-rw-r--r--file_io/unix/seek.c6
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 {