Remove Control.Parallel*, now in package parallel
[packages/random.git] / cbits / lockFile.c
1 /*
2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-2004
3 *
4 * $Id: lockFile.c,v 1.5 2005/01/28 13:36:32 simonmar Exp $
5 *
6 * stdin/stout/stderr Runtime Support
7 */
8
9 #if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32))
10
11 #include "HsBase.h"
12 #include "Rts.h"
13 #include "RtsUtils.h"
14
15 typedef struct {
16 dev_t device;
17 ino_t inode;
18 int fd;
19 } Lock;
20
21 static Lock readLock[FD_SETSIZE];
22 static Lock writeLock[FD_SETSIZE];
23
24 static int readLocks = 0;
25 static int writeLocks = 0;
26
27 int
28 lockFile(int fd, int for_writing, int exclusive)
29 {
30 struct stat sb;
31 int i;
32
33 if (fd > FD_SETSIZE) {
34 barf("lockFile: fd out of range");
35 }
36
37 while (fstat(fd, &sb) < 0) {
38 if (errno != EINTR)
39 return -1;
40 }
41
42 if (for_writing) {
43 /* opening a file for writing, check to see whether
44 we don't have any read locks on it already.. */
45 for (i = 0; i < readLocks; i++) {
46 if (readLock[i].inode == sb.st_ino && readLock[i].device == sb.st_dev)
47 return -1;
48 }
49 /* If we're determined that there is only a single
50 writer to the file, check to see whether the file
51 hasn't already been opened for writing..
52 */
53 if (exclusive) {
54 for (i = 0; i < writeLocks; i++) {
55 if (writeLock[i].inode == sb.st_ino && writeLock[i].device == sb.st_dev) {
56 return -1;
57 }
58 }
59 }
60 /* OK, everything is cool lock-wise, record it and leave. */
61 i = writeLocks++;
62 writeLock[i].device = sb.st_dev;
63 writeLock[i].inode = sb.st_ino;
64 writeLock[i].fd = fd;
65 return 0;
66 } else {
67 /* For reading, it's simpler - just check to see
68 that there's no-one writing to the underlying file. */
69 for (i = 0; i < writeLocks; i++) {
70 if (writeLock[i].inode == sb.st_ino && writeLock[i].device == sb.st_dev)
71 return -1;
72 }
73 /* Fit in new entry, reusing an existing table entry, if possible. */
74 for (i = 0; i < readLocks; i++) {
75 if (readLock[i].inode == sb.st_ino && readLock[i].device == sb.st_dev) {
76 return 0;
77 }
78 }
79 i = readLocks++;
80 readLock[i].device = sb.st_dev;
81 readLock[i].inode = sb.st_ino;
82 readLock[i].fd = fd;
83 return 0;
84 }
85
86 }
87
88 int
89 unlockFile(int fd)
90 {
91 int i;
92
93 for (i = 0; i < readLocks; i++)
94 if (readLock[i].fd == fd) {
95 while (++i < readLocks)
96 readLock[i - 1] = readLock[i];
97 readLocks--;
98 return 0;
99 }
100
101 for (i = 0; i < writeLocks; i++)
102 if (writeLock[i].fd == fd) {
103 while (++i < writeLocks)
104 writeLock[i - 1] = writeLock[i];
105 writeLocks--;
106 return 0;
107 }
108 /* Signal that we did not find an entry */
109 return 1;
110 }
111
112 #endif