unsafePerformIO and cooperative concurrency

Given that unsafePerformIO is (perhaps) to be part of the Haskell' standard, the combination of unsafePerformIO and cooperative concurrency introduces some interesting cases that will probably have to be declared to be undefined in the standard - what happens when you yield or do some I/O inside unsafePerformIO? I guess a concurrent foreign call executed from inside unsafePerformIO doesn't work either? What about a reentrant one? (I know that reentrant foreign calls currently don't work inside unsafePerformIO in Hugs, IIRC it can lead to a segfault). So does this mean that a foreign call that doesn't return an IO type cannot be declared concurrent? Cheers, Simon

Simon Marlow wrote:
Given that unsafePerformIO is (perhaps) to be part of the Haskell' standard,
Is there a ticket for this? I would prefer that unsafePerformIO and friends not be part of the standard. At risk of drifting off-topic, I think it would be better to find examples where unsafePerformIO is needed and used safely, and come up with safe functions for that (but not necessarily as part of the Prime effort). IIRC the darcs code uses it a lot. -- Ashley Yakeley, Seattle WA WWEWDD? http://www.cs.utexas.edu/users/EWD/

Ashley Yakeley
Is there a ticket for this? I would prefer that unsafePerformIO and friends not be part of the standard.
I would prefer otherwise. Every implementation supports it, which proves that it's useful. And it's no less unsafe than FFI. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/

Marcin 'Qrczak' Kowalczyk wrote:
I would prefer otherwise. Every implementation supports it, which proves that it's useful. And it's no less unsafe than FFI.
It's not a matter just of safety, it's a matter of whether its use should be encouraged. FFI is clearly the "right thing" sometimes, unsafePerformIO rarely is. -- Ashley Yakeley, Seattle WA WWEWDD? http://www.cs.utexas.edu/users/EWD/

Ashley Yakeley:
Simon Marlow wrote:
Given that unsafePerformIO is (perhaps) to be part of the Haskell' standard,
Is there a ticket for this? I would prefer that unsafePerformIO and friends not be part of the standard.
Well, you need it for the FFI (for marshalling in pure foreign imports). Plus you can efin eyour own one using the FFI. Manuel
At risk of drifting off-topic, I think it would be better to find examples where unsafePerformIO is needed and used safely, and come up with safe functions for that (but not necessarily as part of the Prime effort). IIRC the darcs code uses it a lot.

On Mon, Apr 24, 2006 at 01:57:57PM +0100, Simon Marlow wrote:
Given that unsafePerformIO is (perhaps) to be part of the Haskell' standard, the combination of unsafePerformIO and cooperative concurrency introduces some interesting cases that will probably have to be declared to be undefined in the standard - what happens when you yield or do some I/O inside unsafePerformIO?
I put a small note on the wiki about this saying behavior should be implementation specific. I don't think we should try to define any particular behavior for unsafePerformIO trickiness. John -- John Meacham - ⑆repetae.net⑆john⑈

It was pointed out that you can't necessarily know what routines to avoid in unsafePerformIO without mandating certain things _don't_ use concurrency, rather than that, how about the following: "Whether an implementation can yield to another thread inside an unsafePerformIO action is implementation dependent, however an implementation should not 'go wrong'" hmm.. better term than 'go wrong'? The intent is calling concurrent routines inside of unsafePerformIO is okay, but they perhaps might not yield to other threads or something like sharing might be lost (but correctness is preserved). I think implementations should be able to handle this. John -- John Meacham - ⑆repetae.net⑆john⑈

On 26 April 2006 01:42, John Meacham wrote:
It was pointed out that you can't necessarily know what routines to avoid in unsafePerformIO without mandating certain things _don't_ use concurrency, rather than that, how about the following:
"Whether an implementation can yield to another thread inside an unsafePerformIO action is implementation dependent, however an implementation should not 'go wrong'"
Better, certainly. I agree that rather than taling about "going wrong" we should say "may not yield". And concurrent foreign calls may not behave concurrently, reentrant foreign calls may fail if they call back to Haskell. One common case (perhaps the only common case) where this happens is hGetContents. The lazy stream returned by hGetContents will not behave in a non-blocking way in a cooperative implementation. I can't decide which demon to blame here: lazy I/O or cooperative concurrency :-) Cheers, Simon

In message <2E9B33CE230409489A7ED37E5E34090F04218DB9@EUR-MSG-20.europe.corp.mic rosoft.com>, "Simon Marlow" writes:
One common case (perhaps the only common case) where this happens is hGetContents. The lazy stream returned by hGetContents will not behave in a non-blocking way in a cooperative implementation. I can't decide which demon to blame here: lazy I/O or cooperative concurrency :-)
Maybe the problem is in combining these demons :-). I mean, maybe the problem is passing an unevaluated thunk containing references to resources of one execution context into another (co-operative) thread. deepSeq'ing the thunk (to force the side effects to take place) in the correct context before allowing access by the other thread should help, I think [but you lose ability to pass functions from one thread to another, which might be worse]. -- Esa Pulkkinen
participants (6)
-
Ashley Yakeley
-
Esa Pulkkinen
-
John Meacham
-
Manuel M T Chakravarty
-
Marcin 'Qrczak' Kowalczyk
-
Simon Marlow