为什么在调用函数中看不到 putTMVar 的函数中填充了 TMVar?
Why is a TMVar populated in a function with putTMVar not visible from the calling function?
在下面的代码中,我发送了一个 IO (TMVar o)
关闭的记录以填充到一个函数中,然后读取
我认为当函数returns时应该是相同的TMVar
。问题是当我读回它时它是空的并且应用程序只是阻塞。
为什么会这样?
Hook初始化如下:
hook = Hook {
-- other props
hookResult = newEmptyTMVarIO,
}
稍后在 ap:
executeHook :: (Text -> IO ()) -> Node i o -> IO ()
executeHook db =
\case
Fixture {} -> pure ()
Hook
{ hookParent,
hookStatus,
hook,
hookResult, -- IO (TMVar o)
hookChildren
} -> do
input <- db "CALL PARENT LOCK EXECUTE HOOK" >> lockExecuteHook db hookParent
result <- hook input
hr <- hookResult
mtb <- atomically $ isEmptyTMVar hr
db $ "HOOK RESULT PUT EMPTY BEFORE: " <> txt mtb
atomically $ putTMVar hr result -- writes hook result to the TMVar
mt <- atomically $ isEmptyTMVar hr
db $ "HOOK RESULT PUT EMPTY AFTER: " <> txt mt
lockExecuteHook :: (Text -> IO ()) -> Either o (Node i o) -> IO o
lockExecuteHook db parent =
eitherf
parent
(\o -> db "NO PARENT HOOK RETURNING VALUE" >> pure o)
( \case
Fixture {} -> pure ()
hk@Hook
{ hookParent,
hookStatus,
hookResult, -- IO (TMVar o)
hook,
hookChildren,
hookRelease
} -> do
bs <- hookStatus
wantLaunch <- atomically $ tryLock db bs
db $ "HOOK LOCK >>> " <> txt wantLaunch
when
wantLaunch
$ executeHook db hk -- this writes hook result to the TMVar
hr <- hookResult
mt <- atomically $ isEmptyTMVar hr
db $ "READING HOOK !!!!!!!!!!!!!!!!!!!!!!!!!! EMPTY: " <> txt mt
r <- atomically $ readTMVar hr
db "RETURNING FROM LOCK EXECUTE HOOK " >> pure r
)
调试 (db) 输出
CALL PARENT LOCK EXECUTE HOOK
HOOK LOCK >>> True
HOOK RESULT PUT EMPTY BEFORE: True
HOOK RESULT PUT EMPTY AFTER: False
READING HOOK !!!!!!!!!!!!!!!!!!!!!!!!!! EMPTY: True
正如@FyodorSoikin、@DanielWagner 和@chi 在上述评论中指出的那样,它没有按预期工作的原因是 hookResult
没有正确初始化。
将记录字段设置为 IO (TMVar a)
将导致每次读取 hookResult
时都会产生一个新的 TMVar a
,如果将字段设置为 [=15] 也会出现类似的问题=] 使用 newTMVar
。要使这项工作正常,需要在 IO 或 STM 上下文中将 hookResult
设置为 TMVar a
。
eg :: IO (Hook a)
eg = do
v <- newEmptyTMVarIO
pure $ Hook {
-- other props
hookResult = v,
}
在下面的代码中,我发送了一个 IO (TMVar o)
关闭的记录以填充到一个函数中,然后读取
我认为当函数returns时应该是相同的TMVar
。问题是当我读回它时它是空的并且应用程序只是阻塞。
为什么会这样?
Hook初始化如下:
hook = Hook {
-- other props
hookResult = newEmptyTMVarIO,
}
稍后在 ap:
executeHook :: (Text -> IO ()) -> Node i o -> IO ()
executeHook db =
\case
Fixture {} -> pure ()
Hook
{ hookParent,
hookStatus,
hook,
hookResult, -- IO (TMVar o)
hookChildren
} -> do
input <- db "CALL PARENT LOCK EXECUTE HOOK" >> lockExecuteHook db hookParent
result <- hook input
hr <- hookResult
mtb <- atomically $ isEmptyTMVar hr
db $ "HOOK RESULT PUT EMPTY BEFORE: " <> txt mtb
atomically $ putTMVar hr result -- writes hook result to the TMVar
mt <- atomically $ isEmptyTMVar hr
db $ "HOOK RESULT PUT EMPTY AFTER: " <> txt mt
lockExecuteHook :: (Text -> IO ()) -> Either o (Node i o) -> IO o
lockExecuteHook db parent =
eitherf
parent
(\o -> db "NO PARENT HOOK RETURNING VALUE" >> pure o)
( \case
Fixture {} -> pure ()
hk@Hook
{ hookParent,
hookStatus,
hookResult, -- IO (TMVar o)
hook,
hookChildren,
hookRelease
} -> do
bs <- hookStatus
wantLaunch <- atomically $ tryLock db bs
db $ "HOOK LOCK >>> " <> txt wantLaunch
when
wantLaunch
$ executeHook db hk -- this writes hook result to the TMVar
hr <- hookResult
mt <- atomically $ isEmptyTMVar hr
db $ "READING HOOK !!!!!!!!!!!!!!!!!!!!!!!!!! EMPTY: " <> txt mt
r <- atomically $ readTMVar hr
db "RETURNING FROM LOCK EXECUTE HOOK " >> pure r
)
调试 (db) 输出
CALL PARENT LOCK EXECUTE HOOK
HOOK LOCK >>> True
HOOK RESULT PUT EMPTY BEFORE: True
HOOK RESULT PUT EMPTY AFTER: False
READING HOOK !!!!!!!!!!!!!!!!!!!!!!!!!! EMPTY: True
正如@FyodorSoikin、@DanielWagner 和@chi 在上述评论中指出的那样,它没有按预期工作的原因是 hookResult
没有正确初始化。
将记录字段设置为 IO (TMVar a)
将导致每次读取 hookResult
时都会产生一个新的 TMVar a
,如果将字段设置为 [=15] 也会出现类似的问题=] 使用 newTMVar
。要使这项工作正常,需要在 IO 或 STM 上下文中将 hookResult
设置为 TMVar a
。
eg :: IO (Hook a)
eg = do
v <- newEmptyTMVarIO
pure $ Hook {
-- other props
hookResult = v,
}