X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fposix%2FFileLock.c;h=7023b9ef67465bd16e43dca2a71c03a05381ef2f;hb=6cf8982ac30be6836a0cdd8be5a6ac1a1a144213;hp=8d258202719dc50c75b1efcd7552688fe535ae33;hpb=7453eaaf0b690420ef2359f022a1838ad697b441;p=ghc-hetmet.git diff --git a/rts/posix/FileLock.c b/rts/posix/FileLock.c index 8d25820..7023b9e 100644 --- a/rts/posix/FileLock.c +++ b/rts/posix/FileLock.c @@ -6,13 +6,16 @@ * * ---------------------------------------------------------------------------*/ +#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; }