projects
/
ghc-hetmet.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (from parent 1:
b8ec039
)
FIX #2398: file locking wasn't thread-safe
author
Simon Marlow
<marlowsd@gmail.com>
Fri, 4 Jul 2008 14:46:26 +0000
(14:46 +0000)
committer
Simon Marlow
<marlowsd@gmail.com>
Fri, 4 Jul 2008 14:46:26 +0000
(14:46 +0000)
rts/posix/FileLock.c
patch
|
blob
|
history
diff --git
a/rts/posix/FileLock.c
b/rts/posix/FileLock.c
index
8d25820
..
e871be5
100644
(file)
--- a/
rts/posix/FileLock.c
+++ b/
rts/posix/FileLock.c
@@
-10,6
+10,7
@@
#include "Hash.h"
#include "FileLock.h"
#include "RtsUtils.h"
#include "Hash.h"
#include "FileLock.h"
#include "RtsUtils.h"
+#include "OSThreads.h"
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/stat.h>
@@
-28,6
+29,10
@@
typedef struct {
static HashTable *obj_hash;
static HashTable *fd_hash;
static HashTable *obj_hash;
static HashTable *fd_hash;
+#ifdef THREADED_RTS
+static Mutex file_lock_mutex;
+#endif
+
static int cmpLocks(StgWord w1, StgWord w2)
{
Lock *l1 = (Lock *)w1;
static int cmpLocks(StgWord w1, StgWord w2)
{
Lock *l1 = (Lock *)w1;
@@
-67,6
+72,8
@@
lockFile(int fd, dev_t dev, ino_t ino, int for_writing)
{
Lock key, *lock;
{
Lock key, *lock;
+ ACQUIRE_LOCK(&file_lock_mutex);
+
key.device = dev;
key.inode = ino;
key.device = dev;
key.inode = ino;
@@
-80,16
+87,19
@@
lockFile(int fd, dev_t dev, ino_t ino, int for_writing)
lock->readers = for_writing ? -1 : 1;
insertHashTable(obj_hash, (StgWord)lock, (void *)lock);
insertHashTable(fd_hash, fd, lock);
lock->readers = for_writing ? -1 : 1;
insertHashTable(obj_hash, (StgWord)lock, (void *)lock);
insertHashTable(fd_hash, fd, lock);
+ RELEASE_LOCK(&file_lock_mutex);
return 0;
}
else
{
// single-writer/multi-reader locking:
if (for_writing || lock->readers < 0) {
return 0;
}
else
{
// single-writer/multi-reader locking:
if (for_writing || lock->readers < 0) {
+ RELEASE_LOCK(&file_lock_mutex);
return -1;
}
insertHashTable(fd_hash, fd, lock);
lock->readers++;
return -1;
}
insertHashTable(fd_hash, fd, lock);
lock->readers++;
+ RELEASE_LOCK(&file_lock_mutex);
return 0;
}
}
return 0;
}
}
@@
-99,11
+109,14
@@
unlockFile(int fd)
{
Lock *lock;
{
Lock *lock;
+ ACQUIRE_LOCK(&file_lock_mutex);
+
lock = lookupHashTable(fd_hash, fd);
if (lock == NULL) {
// errorBelch("unlockFile: fd %d not found", fd);
// This is normal: we didn't know when calling unlockFile
// whether this FD referred to a locked file or not.
lock = lookupHashTable(fd_hash, fd);
if (lock == NULL) {
// errorBelch("unlockFile: fd %d not found", fd);
// This is normal: we didn't know when calling unlockFile
// whether this FD referred to a locked file or not.
+ RELEASE_LOCK(&file_lock_mutex);
return 1;
}
return 1;
}
@@
-118,5
+131,7
@@
unlockFile(int fd)
stgFree(lock);
}
removeHashTable(fd_hash, fd, NULL);
stgFree(lock);
}
removeHashTable(fd_hash, fd, NULL);
+
+ RELEASE_LOCK(&file_lock_mutex);
return 0;
}
return 0;
}