> Okay, I suppose I ain't telling any news here, *but*
> *usually* people complained
> about finalizers being never run. I just discovered that my
> finalizers are run
> *too* *early*, probably because of unsafe{Perform,Interleave}IO:
>
> Consider this fragment which will interleave two
> lists/streams (they're
> created using something similiar getChanContents using
> unsafeInterleaveIO, too).
>
> > mergeStreams :: [a] -> [b] -> IO [Either a b]
> > mergeStreams a b = do
> > ch <- newChan
> > t1 <- forkIO (writeList2Chan ch (map Left a))
> > t2 <- forkIO (writeList2Chan ch (map Right b))
> > result <- getChanContents ch
> > addFinalizer result (print "fin!" >> killThread t1 >>
> killThread t2)
> > return result
>
> The finalizer is run after I access the second argument of
> the resulting
> stream, although more items are in the list. Removing the
> addFinalizer statement
> will give the desired behaviour.
> This happens both in 4.08.2 & 5.00.
The finalizer is on the head of the resulting list, so as soon as you
deconstruct the list and keep the tail, the finalizer will run. The
list hasn't been completely constructed at this point because it is
generated lazilly by getChanContents (which behaves like hGetContents,
but for channels).
By the way, we've found that using finalizers on ordinary Haskell values
doesn't work too well. The compiler's optimiser often unboxes data, and
when a finalizer is placed on the box, it often runs before you've
finished with the contents. It is only really safe to put finalizers on
primitive indivisible objects (which is why we have addForeignFinalizer,
mkWeakIORef, and now addMVarFinalizer).
There is almost certainly a way to solve the problem, but we haven't
found a clean one yet.
Cheers,
Simon
_______________________________________________
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs