From: Simon Marlow Date: Fri, 4 Jul 2008 14:46:26 +0000 (+0000) Subject: FIX #2398: file locking wasn't thread-safe X-Git-Tag: Before_cabalised-GHC~83 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=e345a13029b7654730a4d8f6be730e8b96812a27;hp=b8ec0390d59c80b14ec8f8564a09cfa91a8a2d7a;p=ghc-hetmet.git FIX #2398: file locking wasn't thread-safe --- diff --git a/rts/posix/FileLock.c b/rts/posix/FileLock.c index 8d25820..e871be5 100644 --- a/rts/posix/FileLock.c +++ b/rts/posix/FileLock.c @@ -10,6 +10,7 @@ #include "Hash.h" #include "FileLock.h" #include "RtsUtils.h" +#include "OSThreads.h" #include #include @@ -28,6 +29,10 @@ typedef struct { 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; @@ -67,6 +72,8 @@ lockFile(int fd, dev_t dev, ino_t ino, int for_writing) { Lock key, *lock; + ACQUIRE_LOCK(&file_lock_mutex); + 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); + RELEASE_LOCK(&file_lock_mutex); 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++; + RELEASE_LOCK(&file_lock_mutex); return 0; } } @@ -99,11 +109,14 @@ unlockFile(int fd) { 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. + RELEASE_LOCK(&file_lock_mutex); return 1; } @@ -118,5 +131,7 @@ unlockFile(int fd) stgFree(lock); } removeHashTable(fd_hash, fd, NULL); + + RELEASE_LOCK(&file_lock_mutex); return 0; }