Copy forks properly with over-tailed environment

This commit is contained in:
Andrzej Rybczak 2022-03-07 04:42:28 +01:00
parent 13153cc12f
commit 9034e8f572

View File

@ -284,13 +284,19 @@ copyForks es fs size = \case
Forks _ baseIx lref0 forks -> do Forks _ baseIx lref0 forks -> do
EnvRef _ es0 fs0 <- readIORef lref0 EnvRef _ es0 fs0 <- readIORef lref0
let n = size - baseIx let n = size - baseIx
copySmallMutableArray es baseIx es0 0 n -- It might happen that the environment was over-tailed and the size is now
copySmallMutableArray fs baseIx fs0 0 n -- less than the baseIx of the fork. In such case we simply try our luck
copyForks es fs baseIx forks -- with the older fork.
if n <= 0
then copyForks es fs size forks
else do
copySmallMutableArray es baseIx es0 0 n
copySmallMutableArray fs baseIx fs0 0 n
copyForks es fs baseIx forks
type EnvRefStore = IORef (IM.IntMap (IORef EnvRef)) type EnvRefStore = IORef (IM.IntMap (IORef EnvRef))
-- | Relink local environments hiding in the handler. -- | Relink local environments hiding in the handlers.
relinkData relinkData
:: (forall es. Env es -> IO (Env es)) :: (forall es. Env es -> IO (Env es))
-> SmallMutableArray RealWorld Any -> SmallMutableArray RealWorld Any
@ -307,7 +313,7 @@ relinkData relink es fs = \case
>>= writeSmallArray es i . toAny >>= writeSmallArray es i . toAny
relinkData relink es fs i relinkData relink es fs i
-- | Relink local environments hiding in the handler. -- | Relink local environments hiding in the handlers.
relinkEnv :: IORef EnvRef -> ForkIdGen -> EnvRefStore -> Env es -> IO (Env es) relinkEnv :: IORef EnvRef -> ForkIdGen -> EnvRefStore -> Env es -> IO (Env es)
relinkEnv gref gen store (Env forks size _ _) = Env relinkEnv gref gen store (Env forks size _ _) = Env
<$> relinkForks forks <$> relinkForks forks