-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Another problem with weak references and reactive-banana (different behavior in GHC vs GHCJS) #463
Comments
hmm, may be related to issue #454. |
I didn't have time to look at this in detail yet, so just a quick remark: Did you check that the compiled GHC/GHCi version performs at least one garbage collection, so that the versions are doing something comparable? You can use |
I added an explicit call to GHC:
GHCJS:
Note that it stops working, but seems independent of the amount of times I invoke |
I think I have the same problem. module Main where
import Control.Monad (forM, forM_, forever)
import Data.IORef (newIORef, modifyIORef, readIORef)
import Reactive.Banana.Frameworks
hNUM :: Int
hNUM = 5
main :: IO ()
main = do
(reg, run) <- genEvents
handlers <- makeHandlers hNUM reg
network <- compile . forM_ handlers $ \ah -> do
ev <- fromAddHandler ah
reactimate $ print <$> ev
actuate network
forever run
genEvents :: IO (Handler Int -> IO (), IO ())
genEvents = do
handlers <- newIORef []
return ( \h -> modifyIORef handlers (h:)
, length <$> getLine >>= \x -> readIORef handlers >>= mapM_ ($ x)
)
makeHandlers :: Int -> (Handler Int -> IO ()) -> IO [AddHandler Int]
makeHandlers n reg = forM [1..n] $ \i -> do
(ah, fire) <- newAddHandler
reg $ fire . (+i)
return ah To run this I used So this code registers a number of events to Originally, I wanted to post this comment into ghcjs/pull/25 discussion. |
Ok, I'll look into this again, last time I had some trouble reproducing the problem with the latest commits. I hope it's better now. |
After some number of experiments I managed to drastically simplify the example. No dependencies at all! To be honest, I am not sure if this is exactly the same problem as in the previous example, but behaviour of module Main where
import Control.Concurrent (threadDelay)
import System.Mem (performGC)
import System.Mem.Weak (deRefWeak, mkWeak)
data Key = Key (IO Key) | RealKey
instance Show Key where
show (Key _) = "Key ref"
show (RealKey) = "RealKey"
main :: IO ()
main = do
let key = RealKey
key' = Key $ return key
handler <- mkWeak key (print key) Nothing
let loop = do
threadDelay 100000
mcall <- deRefWeak handler
performGC
case mcall of
Nothing -> putStrLn "Dead."
Just c -> putStr "Got: " >> c >> loop
loop
print key' Being compiled with Being compiled with Seems like |
I am sorry for flooding, but this time I think I have found the problem. Though my previous comment shows code with really different behaviour in This time I think the problem is in Now I am really running out of time and continue with what I have at the moment. If anybody have time for this, I think it makes sense to test |
I'm witnessing similar buggy behavior with |
Unfortunately, I was not able to replicate the bug using |
@achirkin i did not, it's in a relatively large application. however, given this clue:
i went looking and these primops are definitely fishy: Line 655 in 3959a93
.slice() will not preserve the __ghcjsArray property:
unless i'm mislead, they should be something like
i'll see if that fixes it. |
here is the change i'm testing: bitonic@7805639 CC @luite |
similar fix for the normal arrays: bitonic/shims@6d55e33 |
@achirkin actually, i've checked and in my application it's never the case that the GC stumbles on an array without |
as predicted the two fixes above do not fix my problem :(. nonetheless, i've opened two prs: #619 and ghcjs/shims#45 . |
Hmm, besides |
@achirkin yes the i also think that not setting the |
@achirkin actually it turns out that that |
@luite once you merge the two prs above this can be closed, however it would be good to have a chat to find out exactly why that was causing trouble. |
@ocharles btw, do you recall which "other" issues there were with weak references? i rely on them quite critically (as do other users, e.g. reflex), and it'd be good to make sure that at least all the known issues are fixed. |
Sorry @bitonic, it's been a loooong time since I looked. But it might be worth re-running my above tests. |
I also ran into (a variation of) this problem. @bitonic 's PRs fix the issue for me. Would be good to get those merged. |
ah thanks for bringing it to my attention again. I'll apply the fix. |
cc @HeinrichApfelmus
The following program exhibits different behavior under GHC and GHCJS:
In
ghc
:In
ghcjs
:In GHCJS it runs printing for 3 events and then stopping - suggesting a garbage collection has occured. In GHCI (and GHC compiled binaries) it counts without interruption (I aborted at 100, which takes 100 seconds).
I am running:
ghcjs-boot 97dea5c4145bf80a1e7cffeb1ecd4d0ecacd5a2f
ghcjs-shims 45f44f5f027ec03264b61b8049951e765cc0b23a
ghcjs 561365ba1667053b5dc5846e2a8edb33eaa3f6dd
@HeinrichApfelmus, I have also tried with the
ghcjs
branch ofreactive-banana
and the same problem occurs with that. I can also note that if I change the definition oftext_
to justthe two programs behave identically. So it seems that by adding that extra
reactimate'
, the dependency graph is different enough to exhibit different GC patterns. It is very strange to me that()
doesn't even get printed, so we seem to be losing almost the entire graph. The click thread is still alive, if we add aprint
statement for every iteration of theforever
loop, you'll see that, but nothing will actually happen otherwise.The text was updated successfully, but these errors were encountered: