IORefs and weak pointers

View: New views
6 Messages — Rating Filter:   Alert me  

IORefs and weak pointers

by Patai Gergely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello all,

I wanted to create a weak pointer with an IORef as the key and something
else as the value, but I saw no way to do it through the API provided.
After some experimentation I came up with the following abomination for
a solution:

myWeakRef (IORef (STRef r)) v f =
  IO $ \s -> case mkWeak# r v f s of (# s', w #) -> (# s', Weak w #)

This works perfectly when the code is compiled both with and without
optimisations, but ghci chokes on it with an internal error. So my
question is if I can expect this to work at least this much in the long
run, or is it a hopelessly fragile hack?

Gergely

--
http://www.fastmail.fm - Same, same, but different...

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: IORefs and weak pointers

by John Van Enk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Is the IORef or the value in the IORef your key?

2009/11/2 Patai Gergely <patai_gergely@...>
Hello all,

I wanted to create a weak pointer with an IORef as the key and something
else as the value, but I saw no way to do it through the API provided.
After some experimentation I came up with the following abomination for
a solution:

myWeakRef (IORef (STRef r)) v f =
 IO $ \s -> case mkWeak# r v f s of (# s', w #) -> (# s', Weak w #)

This works perfectly when the code is compiled both with and without
optimisations, but ghci chokes on it with an internal error. So my
question is if I can expect this to work at least this much in the long
run, or is it a hopelessly fragile hack?

Gergely

--
http://www.fastmail.fm - Same, same, but different...

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: IORefs and weak pointers

by Patai Gergely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> Is the IORef or the value in the IORef your key?
I want the IORef itself to be the key. However, that doesn't work with
optimisations turned on (the pointers get wiped out at the first gc), I
guess because they remove the box around the MutVar#. Extracting that
MutVar# seems to solve the problem.

Gergely

--
http://www.fastmail.fm - mmm... Fastmail...

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: IORefs and weak pointers

by Job Vranish :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Could mkWeakPair do what you want?
http://haskell.org/ghc/docs/latest/html/libraries/base/System-Mem-Weak.html#v:mkWeakPair

Or are you trying to do something else?

- Job


2009/11/2 Patai Gergely <patai_gergely@...>
Hello all,

I wanted to create a weak pointer with an IORef as the key and something
else as the value, but I saw no way to do it through the API provided.
After some experimentation I came up with the following abomination for
a solution:

myWeakRef (IORef (STRef r)) v f =
 IO $ \s -> case mkWeak# r v f s of (# s', w #) -> (# s', Weak w #)

This works perfectly when the code is compiled both with and without
optimisations, but ghci chokes on it with an internal error. So my
question is if I can expect this to work at least this much in the long
run, or is it a hopelessly fragile hack?

Gergely

--
http://www.fastmail.fm - Same, same, but different...

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: IORefs and weak pointers

by Patai Gergely :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> Could mkWeakPair do what you want?
> http://haskell.org/ghc/docs/latest/html/libraries/base/System-Mem-Weak.html#v:mkWeakPair
No, it's just a convenience function that doesn't help much, because the
value already refers to the IORef anyway.

Here's a minimal example to illustrate the problem:

import Data.IORef
import Data.Maybe
import System.Mem
import System.Mem.Weak

main = do
  ref <- newIORef 42
  ptr <- mkWeak ref 21 Nothing
  performGC
  print . isNothing =<< deRefWeak ptr
  print =<< readIORef ref

Depending on whether you compile with optimisations, the weak reference
might be reported dead, even though the IORef is alive and kicking.
Switching to mkWeakPair (or just mentioning ref in the value somehow)
doesn't affect that.

> Or are you trying to do something else?
The goal is to create mutable objects whose update codes are tracked by
the main program, but they can be thrown out when all the other
references to the objects are lost. Creating weak pointers with MutVar#s
seems to do the trick, but I'm not confident if it is a solution I can
trust...

Gergely

--
http://www.fastmail.fm - A fast, anti-spam email service.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: IORefs and weak pointers

by Job Vranish :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Wow, this looks like a bug to me. If it's not a bug, then it's horribly  unintuitive.
I extended your example in an effort to figure out what was going on. Apparently weak pointers loath live IORefs:

import Data.IORef
import Data.Maybe
import System.Mem
import System.Mem.Weak

import Control.Monad

data A = A String
data B = B String (IORef Int)
showA (A s) = s
showB (B s _) = s

main = do
 -- works as expected:
 ref <- return $ A "A"
 ptr <- mkWeak ref 21 Nothing
 performGC
 print . isNothing =<< deRefWeak ptr
 print (showA ref)
 
 -- why doesn't this work?
 ref <- liftM (B "B") $ newIORef 42
 ptr <- mkWeak ref 21 Nothing
 performGC
 print . isNothing =<< deRefWeak ptr
 print (showB ref)
 
 -- this works, wtf???
 ref <- liftM (B "B") $ return undefined
 ptr <- mkWeak ref 21 Nothing
 performGC
 print . isNothing =<< deRefWeak ptr
 print (showB ref)


I don't think this is the expected behavior. The docs on Weak pointers don't mention anything like this. I suspect something in the GC is getting confused by the IORef somehow.

- Job



2009/11/2 Patai Gergely <patai_gergely@...>
No, it's just a convenience function that doesn't help much, because the
value already refers to the IORef anyway.

Here's a minimal example to illustrate the problem:

import Data.IORef
import Data.Maybe
import System.Mem
import System.Mem.Weak

main = do
 ref <- newIORef 42
 ptr <- mkWeak ref 21 Nothing
 performGC
 print . isNothing =<< deRefWeak ptr
 print =<< readIORef ref

Depending on whether you compile with optimisations, the weak reference
might be reported dead, even though the IORef is alive and kicking.
Switching to mkWeakPair (or just mentioning ref in the value somehow)
doesn't affect that.

> Or are you trying to do something else?
The goal is to create mutable objects whose update codes are tracked by
the main program, but they can be thrown out when all the other
references to the objects are lost. Creating weak pointers with MutVar#s
seems to do the trick, but I'm not confident if it is a solution I can
trust...

Gergely

--
http://www.fastmail.fm - A fast, anti-spam email service.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe