1717#include <unistd.h>
1818#include <errno.h>
1919
20+ #include <sys/stat.h>
21+ #include <sys/syscall.h>
22+
2023typedef struct {
2124 StgWord64 device ;
2225 StgWord64 inode ;
@@ -34,6 +37,30 @@ static HashTable *key_hash;
3437static Mutex file_lock_mutex ;
3538#endif
3639
40+ static pid_t gettid (void )
41+ {
42+ return syscall (SYS_gettid );
43+ }
44+
45+ int close (int fd )
46+ {
47+ Lock * lock ;
48+
49+ ACQUIRE_LOCK (& file_lock_mutex );
50+ lock = lookupHashTable (key_hash , (long )fd );
51+ RELEASE_LOCK (& file_lock_mutex );
52+
53+ if (lock != NULL ) {
54+ pid_t pid , tid ;
55+ pid = getpid ();
56+ tid = gettid ();
57+ barf ("close: lock exists: pid %d, tid %d, fd %d\n" , pid , tid , fd );
58+ }
59+
60+ long ret = syscall (SYS_close , fd );
61+ return (int )ret ;
62+ }
63+
3764STATIC_INLINE int cmpLocks (StgWord w1 , StgWord w2 )
3865{
3966 Lock * l1 = (Lock * )w1 ;
@@ -80,6 +107,26 @@ lockFile(StgWord64 id, StgWord64 dev, StgWord64 ino, int for_writing)
80107{
81108 Lock key , * lock ;
82109
110+ int fd = (int )id ;
111+ struct stat buf ;
112+ int retval ;
113+ pid_t pid , tid ;
114+
115+ pid = getpid ();
116+ tid = gettid ();
117+
118+ retval = fstat (fd , & buf );
119+ if (retval == -1 ) {
120+ barf ("lockFile: fstat failed\n" );
121+ } else {
122+ if (ino != 0 && ino != buf .st_ino ) {
123+ barf ("lockFile: pid %d, tid %d, incorrect inode: passed:%lu st_ino:%lu\n" , pid , tid , ino , buf .st_ino );
124+ }
125+ if (dev != 0 && dev != buf .st_dev ) {
126+ barf ("lockFile: pid %d, tid %d, incorrect dev: passed:%lu st_ino:%lu\n" , pid , tid , dev , buf .st_dev );
127+ }
128+ }
129+
83130 ACQUIRE_LOCK (& file_lock_mutex );
84131
85132 key .device = dev ;
@@ -96,18 +143,23 @@ lockFile(StgWord64 id, StgWord64 dev, StgWord64 ino, int for_writing)
96143 insertHashTable_ (obj_hash , (StgWord )lock , (void * )lock , hashLock );
97144 insertHashTable (key_hash , id , lock );
98145 RELEASE_LOCK (& file_lock_mutex );
146+ fprintf (stderr , "lockFile: first lock: pid %d, tid %d, id %lu dev %lu ino %lu write %d\n" , pid , tid , id , dev , ino , for_writing );
99147 return 0 ;
100148 }
101149 else
102150 {
103151 // single-writer/multi-reader locking:
104152 if (for_writing || lock -> readers < 0 ) {
105153 RELEASE_LOCK (& file_lock_mutex );
154+ fprintf (stderr , "lockFile: pid %d, tid %d, already locked, reader/write conflict: "
155+ "id %lu dev %lu ino %lu write %d\n" , pid , tid , id , dev , ino , for_writing );
106156 return -1 ;
107157 }
108158 insertHashTable (key_hash , id , lock );
109159 lock -> readers ++ ;
110160 RELEASE_LOCK (& file_lock_mutex );
161+ fprintf (stderr , "lockFile: pid %d, tid %d, already locked, reader++: "
162+ "id %lu dev %lu ino %lu write %d\n" , pid , tid , id , dev , ino , for_writing );
111163 return 0 ;
112164 }
113165}
116168unlockFile (StgWord64 id )
117169{
118170 Lock * lock ;
171+ int status ;
172+ pid_t pid , tid ;
173+
174+ pid = getpid ();
175+ tid = gettid ();
119176
120177 ACQUIRE_LOCK (& file_lock_mutex );
121178
@@ -125,21 +182,26 @@ unlockFile(StgWord64 id)
125182 // This is normal: we didn't know when calling unlockFile
126183 // whether this FD referred to a locked file or not.
127184 RELEASE_LOCK (& file_lock_mutex );
185+ //fprintf (stderr, "unlockFile: not locked: id %lu\n", id);
128186 return 1 ;
129187 }
130188
131189 if (lock -> readers < 0 ) {
132190 lock -> readers ++ ;
191+ status = 0 ;
133192 } else {
134193 lock -> readers -- ;
194+ status = 1 ;
135195 }
136196
137197 if (lock -> readers == 0 ) {
138198 removeHashTable_ (obj_hash , (StgWord )lock , NULL , hashLock , cmpLocks );
139199 stgFree (lock );
200+ status = 2 ;
140201 }
141202 removeHashTable (key_hash , id , NULL );
142203
143204 RELEASE_LOCK (& file_lock_mutex );
205+ fprintf (stderr , "unlockFile: pid %d, tid %d, unlocked: id %lu, status %d\n" , pid , tid , id , status );
144206 return 0 ;
145207}
0 commit comments