X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fposix%2FFileLock.c;h=cb36366070c7bbb54b5f9cc8d4891b782049279c;hb=b2bd63f99d643f6b3eb30bb72bb9ae26d4183252;hp=8d258202719dc50c75b1efcd7552688fe535ae33;hpb=7453eaaf0b690420ef2359f022a1838ad697b441;p=ghc-hetmet.git diff --git a/rts/posix/FileLock.c b/rts/posix/FileLock.c index 8d25820..cb36366 100644 --- a/rts/posix/FileLock.c +++ b/rts/posix/FileLock.c @@ -2,17 +2,20 @@ * * (c) The GHC Team, 2007 * - * File locking support as required by Haskell 98 + * File locking support as required by Haskell * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "Hash.h" + #include "FileLock.h" +#include "Hash.h" #include "RtsUtils.h" -#include +#include #include +#include #include typedef struct { @@ -28,6 +31,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; @@ -47,6 +54,9 @@ initFileLocking(void) { obj_hash = allocHashTable_(hashLock, cmpLocks); fd_hash = allocHashTable(); /* ordinary word-based table */ +#ifdef THREADED_RTS + initMutex(&file_lock_mutex); +#endif } static void @@ -60,6 +70,9 @@ freeFileLocking(void) { freeHashTable(obj_hash, freeLock); freeHashTable(fd_hash, NULL); +#ifdef THREADED_RTS + closeMutex(&file_lock_mutex); +#endif } int @@ -67,6 +80,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 +95,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 +117,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 +139,7 @@ unlockFile(int fd) stgFree(lock); } removeHashTable(fd_hash, fd, NULL); + + RELEASE_LOCK(&file_lock_mutex); return 0; }