Skip to content

Commit 4a259a5

Browse files
Add debug code for file lock/unlock
1 parent acf2bef commit 4a259a5

5 files changed

Lines changed: 81 additions & 1 deletion

File tree

libraries/base/GHC/IO/Device.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class RawIO a where
6060

6161

6262
-- | I/O operations required for implementing a 'System.IO.Handle'.
63-
class IODevice a where
63+
class Show a => IODevice a where
6464
-- | @ready dev write msecs@ returns 'True' if the device has data
6565
-- to read (if @write@ is 'False') or space to write new data (if
6666
-- @write@ is 'True'). @msecs@ specifies how long to wait, in
@@ -125,6 +125,9 @@ class IODevice a where
125125
dup2 :: a -> a -> IO a
126126
dup2 _ _ = ioe_unsupportedOperation
127127

128+
showDev :: a -> String
129+
showDev a = show a
130+
128131
ioe_unsupportedOperation :: IO a
129132
ioe_unsupportedOperation = throwIO unsupportedOperation
130133

libraries/base/GHC/IO/FD.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ close fd =
418418
c_closesocket (fromIntegral realFd)
419419
else
420420
#endif
421+
do
422+
-- putsE ("FD calling c_close: " ++ show fd ++ "\n")
421423
c_close (fromIntegral realFd)
422424

423425
-- release the lock *first*, because otherwise if we're preempted

libraries/base/GHC/IO/Handle/Internals.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ mkHandleMVar :: (RawIO dev, IODevice dev, BufferedIO dev, Typeable dev) => dev
667667
mkHandleMVar dev filepath ha_type buffered mb_codec nl other_side =
668668
openTextEncoding mb_codec ha_type $ \ mb_encoder mb_decoder -> do
669669

670+
traceIOE $ "mKHandleMVar fd :" ++ IODevice.showDev dev ++ " : " ++ filepath
670671
let !buf_state = initBufferState ha_type
671672
!bbuf_no_offset <- (Buffered.newBuffer dev buf_state)
672673
!buf_offset <- initHandleOffset
@@ -945,6 +946,12 @@ traceIO s = do
945946
\(p, len) -> c_write 1 (castPtr p) (fromIntegral len)
946947
return ()
947948

949+
traceIOE :: String -> IO ()
950+
traceIOE s = do
951+
_ <- withCStringLen (s ++ "\n") $
952+
\(p, len) -> c_write 2 (castPtr p) (fromIntegral len)
953+
return ()
954+
948955
-- ----------------------------------------------------------------------------
949956
-- Text input/output
950957

libraries/base/System/Posix/Internals.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ puts s = withCAStringLen (s ++ "\n") $ \(p, len) -> do
6262
_ <- c_write 1 (castPtr p) (fromIntegral len)
6363
return ()
6464

65+
putsE :: String -> IO ()
66+
putsE s = withCAStringLen (s ++ "\n") $ \(p, len) -> do
67+
-- In reality should be withCString, but assume ASCII to avoid loop
68+
-- if this is called by GHC.Foreign
69+
_ <- c_write 2 (castPtr p) (fromIntegral len)
70+
return ()
6571

6672
-- ---------------------------------------------------------------------------
6773
-- Types

rts/FileLock.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#include <unistd.h>
1818
#include <errno.h>
1919

20+
#include <sys/stat.h>
21+
#include <sys/syscall.h>
22+
2023
typedef struct {
2124
StgWord64 device;
2225
StgWord64 inode;
@@ -34,6 +37,30 @@ static HashTable *key_hash;
3437
static 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+
3764
STATIC_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
}
@@ -116,6 +168,11 @@ int
116168
unlockFile(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

Comments
 (0)