Skip to content

Commit ecc93fa

Browse files
debug deadlock
1 parent 906da42 commit ecc93fa

2 files changed

Lines changed: 28 additions & 6 deletions

File tree

src/Simplex/Messaging/Agent/Client.hs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ module Simplex.Messaging.Agent.Client
195195
where
196196

197197
import Control.Applicative ((<|>))
198-
import Control.Concurrent (ThreadId, killThread)
198+
import Control.Concurrent (ThreadId, killThread, myThreadId)
199+
import Debug.Trace (traceIO)
199200
import Control.Concurrent.Async (Async, uninterruptibleCancel)
200201
import Control.Concurrent.STM (retry)
201202
import Control.Exception (AsyncException (..), BlockedIndefinitelyOnSTM (..))
@@ -1096,9 +1097,12 @@ getOrCreateConnWorker c@AgentClient {connWorkers, connWorkerSeq} connId = do
10961097

10971098
connWorkerLoop :: AgentClient -> TBQueue ATransmission -> IO ()
10981099
connWorkerLoop AgentClient {processEvent} q = forever $ do
1099-
t <- atomically $ readTBQueue q
1100+
t@(_, connId, _) <- atomically $ readTBQueue q
1101+
tid <- myThreadId
1102+
traceIO $ "CALLBACK fire connId=" <> show connId <> " tid=" <> show tid
11001103
processEvent t `E.catchAny` \e ->
11011104
logError $ "connWorkerLoop error: " <> tshow e
1105+
traceIO $ "CALLBACK done connId=" <> show connId <> " tid=" <> show tid
11021106

11031107
withInvLock :: AgentClient -> ByteString -> Text -> AM a -> AM a
11041108
withInvLock c key name = ExceptT . withInvLock' c key name . runExceptT

src/Simplex/Messaging/Agent/Lock.hs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ module Simplex.Messaging.Agent.Lock
1010
)
1111
where
1212

13+
import Control.Concurrent (myThreadId)
1314
import Control.Monad (void)
1415
import Control.Monad.Except (ExceptT (..), runExceptT)
1516
import Control.Monad.IO.Unlift
1617
import Data.Functor (($>))
1718
import Data.Set (Set)
1819
import qualified Data.Set as S
1920
import Data.Text (Text)
21+
import qualified Data.Text as T
22+
import Debug.Trace (traceIO)
2023
import UnliftIO.Async (forConcurrently)
2124
import qualified UnliftIO.Exception as E
2225
import UnliftIO.STM
@@ -44,15 +47,30 @@ withLock' lock name =
4447
withGetLock :: MonadUnliftIO m => (k -> STM Lock) -> k -> Text -> m a -> m a
4548
withGetLock getLock key name a =
4649
E.bracket
47-
(atomically $ getPutLock getLock key name)
48-
(atomically . takeTMVar)
50+
(do liftIO $ do
51+
tid <- myThreadId
52+
traceIO $ "LOCK acquire " <> T.unpack name <> " tid=" <> show tid
53+
atomically $ getPutLock getLock key name)
54+
(\l -> do
55+
atomically $ takeTMVar l
56+
liftIO $ do
57+
tid <- myThreadId
58+
traceIO $ "LOCK release " <> T.unpack name <> " tid=" <> show tid)
4959
(const a)
5060

5161
withGetLocks :: MonadUnliftIO m => (k -> STM Lock) -> Set k -> Text -> m a -> m a
5262
withGetLocks getLock keys name = E.bracket holdLocks releaseLocks . const
5363
where
54-
holdLocks = forConcurrently (S.toList keys) $ \key -> atomically $ getPutLock getLock key name
55-
releaseLocks = mapM_ (atomically . takeTMVar)
64+
holdLocks = do
65+
liftIO $ do
66+
tid <- myThreadId
67+
traceIO $ "LOCKS acquire " <> T.unpack name <> " (" <> show (S.size keys) <> " keys) tid=" <> show tid
68+
forConcurrently (S.toList keys) $ \key -> atomically $ getPutLock getLock key name
69+
releaseLocks ls = do
70+
mapM_ (atomically . takeTMVar) ls
71+
liftIO $ do
72+
tid <- myThreadId
73+
traceIO $ "LOCKS release " <> T.unpack name <> " (" <> show (S.size keys) <> " keys) tid=" <> show tid
5674

5775
-- getLock and putTMVar can be in one transaction on the assumption that getLock doesn't write in case the lock already exists,
5876
-- and in case it is created and added to some shared resource (we use TMap) it also helps avoid contention for the newly created lock.

0 commit comments

Comments
 (0)