*
* (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 <unistd.h>
+#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <errno.h>
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;
{
obj_hash = allocHashTable_(hashLock, cmpLocks);
fd_hash = allocHashTable(); /* ordinary word-based table */
+#ifdef THREADED_RTS
+ initMutex(&file_lock_mutex);
+#endif
}
static void
{
freeHashTable(obj_hash, freeLock);
freeHashTable(fd_hash, NULL);
+#ifdef THREADED_RTS
+ closeMutex(&file_lock_mutex);
+#endif
}
int
{
Lock key, *lock;
+ ACQUIRE_LOCK(&file_lock_mutex);
+
key.device = dev;
key.inode = ino;
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;
}
}
{
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;
}
stgFree(lock);
}
removeHashTable(fd_hash, fd, NULL);
+
+ RELEASE_LOCK(&file_lock_mutex);
return 0;
}